Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Elij4h
gin-vue-admin
提交
76ccbcc2
G
gin-vue-admin
项目概览
Elij4h
/
gin-vue-admin
与 Fork 源项目一致
Fork自
FLIPPED-AURORA / gin-vue-admin
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gin-vue-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
76ccbcc2
编写于
4月 26, 2020
作者:
R
rainyan
提交者:
GitHub
4月 26, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #72 from flipped-aurora/gin-vue-admin_v2_dev
Gin vue admin v2 dev
上级
bb26fafa
ab6b15b9
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
235 addition
and
203 deletion
+235
-203
server/Dockerfile
server/Dockerfile
+16
-21
server/api/v1/exa_file_upload_download.go
server/api/v1/exa_file_upload_download.go
+2
-3
server/api/v1/sys_user.go
server/api/v1/sys_user.go
+1
-6
server/config.yaml
server/config.yaml
+5
-2
server/config/config.go
server/config/config.go
+2
-0
server/initialize/mysql.go
server/initialize/mysql.go
+3
-1
server/utils/upload.go
server/utils/upload.go
+8
-12
web/src/view/example/upload/upload.vue
web/src/view/example/upload/upload.vue
+128
-106
web/src/view/login/login.vue
web/src/view/login/login.vue
+70
-52
未找到文件。
server/Dockerfile
浏览文件 @
76ccbcc2
FROM
centos:7.6.1810
FROM
golang:alpine as builder
RUN
apk add
--update
--no-cache
yarn make g++
# 设置go mod proxy 国内代理
ENV
GOPROXY=https://goproxy.cn,https://goproxy.io,direct \
# 设置golang path
GO111MODULE=on \
ENV
GOPROXY=https://goproxy.io GOPATH=/gopath PATH="${PATH}:/usr/local/go/bin"
CGO_ENABLED=1
# 定义使用的Golang 版本
WORKDIR
/go/src/gin-vue-admin
ARG
GO_VERSION=1.13.3
RUN
go
env
-w
GOPROXY
=
https://goproxy.cn,https://goproxy.io,direct
COPY
. .
RUN
go
env
&&
go list
&&
go build
-v
-a
-ldflags
"-extldflags
\"
-static
\"
"
-o
gvadmin .
# 安装 golang 1.13.3
WORKDIR
/app
RUN
yum
install
-y
wget
&&
\
COPY
--from=builder /go/src/gin-vue-admin/gvadmin .
yum
install
-y
wqy-microhei-fonts wqy-zenhei-fonts
&&
\
COPY
--from=builder /go/src/gin-vue-admin/db.db .
wget
"https://dl.google.com/go/go
$GO_VERSION
.linux-amd64.tar.gz"
&&
\
COPY
--from=builder /go/src/gin-vue-admin/config.yaml .
rm
-rf
/usr/local/go
&&
\
COPY
--from=builder /go/src/gin-vue-admin/resource ./resource
tar
-C
/usr/local
-xzf
"go
$GO_VERSION
.linux-amd64.tar.gz"
&&
\
rm
-rf
*
.tar.gz
&&
\
go version
&&
go
env
;
WORKDIR
$GOPATH
COPY
. gin-vue
RUN
cd
gin-vue
&&
go build
-o
app
;
EXPOSE
8888
EXPOSE
8888
CMD
["gin-vue/app"]
CMD
["gvadmin/app"]
\ No newline at end of file
server/api/v1/exa_file_upload_download.go
浏览文件 @
76ccbcc2
...
@@ -27,7 +27,7 @@ func UploadFile(c *gin.Context) {
...
@@ -27,7 +27,7 @@ func UploadFile(c *gin.Context) {
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"上传文件失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"上传文件失败,%v"
,
err
),
c
)
}
else
{
}
else
{
//文件上传后拿到文件路径
//文件上传后拿到文件路径
err
,
filePath
,
key
:=
utils
.
Upload
(
header
,
USER_HEADER_BUCKET
,
USER_HEADER_IMG_PATH
)
err
,
filePath
,
key
:=
utils
.
Upload
(
header
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"接收返回值失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"接收返回值失败,%v"
,
err
),
c
)
}
else
{
}
else
{
...
@@ -45,7 +45,6 @@ func UploadFile(c *gin.Context) {
...
@@ -45,7 +45,6 @@ func UploadFile(c *gin.Context) {
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"修改数据库链接失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"修改数据库链接失败,%v"
,
err
),
c
)
}
else
{
}
else
{
response
.
OkDetailed
(
resp
.
ExaFileResponse
{
File
:
file
},
"上传成功"
,
c
)
response
.
OkDetailed
(
resp
.
ExaFileResponse
{
File
:
file
},
"上传成功"
,
c
)
}
}
}
}
}
}
...
@@ -65,7 +64,7 @@ func DeleteFile(c *gin.Context) {
...
@@ -65,7 +64,7 @@ func DeleteFile(c *gin.Context) {
if
err
!=
nil
{
if
err
!=
nil
{
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"删除失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"删除失败,%v"
,
err
),
c
)
}
else
{
}
else
{
err
=
utils
.
DeleteFile
(
USER_HEADER_BUCKET
,
f
.
Key
)
err
=
utils
.
DeleteFile
(
f
.
Key
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"删除失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"删除失败,%v"
,
err
),
c
)
...
...
server/api/v1/sys_user.go
浏览文件 @
76ccbcc2
...
@@ -18,11 +18,6 @@ import (
...
@@ -18,11 +18,6 @@ import (
"time"
"time"
)
)
const
(
USER_HEADER_IMG_PATH
string
=
"http://qmplusimg.henrongyi.top"
USER_HEADER_BUCKET
string
=
"qm-plus-img"
)
// @Tags Base
// @Tags Base
// @Summary 用户注册账号
// @Summary 用户注册账号
// @Produce application/json
// @Produce application/json
...
@@ -172,7 +167,7 @@ func UploadHeaderImg(c *gin.Context) {
...
@@ -172,7 +167,7 @@ func UploadHeaderImg(c *gin.Context) {
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"上传文件失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"上传文件失败,%v"
,
err
),
c
)
}
else
{
}
else
{
//文件上传后拿到文件路径
//文件上传后拿到文件路径
err
,
filePath
,
_
:=
utils
.
Upload
(
header
,
USER_HEADER_BUCKET
,
USER_HEADER_IMG_PATH
)
err
,
filePath
,
_
:=
utils
.
Upload
(
header
)
if
err
!=
nil
{
if
err
!=
nil
{
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"接收返回值失败,%v"
,
err
),
c
)
response
.
FailWithMessage
(
fmt
.
Sprintf
(
"接收返回值失败,%v"
,
err
),
c
)
}
else
{
}
else
{
...
...
server/config.yaml
浏览文件 @
76ccbcc2
...
@@ -17,17 +17,20 @@ mysql:
...
@@ -17,17 +17,20 @@ mysql:
config
:
'
charset=utf8&parseTime=True&loc=Local'
config
:
'
charset=utf8&parseTime=True&loc=Local'
max-idle-conns
:
10
max-idle-conns
:
10
max-open-conns
:
10
max-open-conns
:
10
log-mode
:
true
log-mode
:
false
#sqlite 配置
#sqlite 配置
sqlite
:
sqlite
:
path
:
db.db
path
:
db.db
log-mode
:
true
log-mode
:
true
config
:
'
loc=Asia/Shanghai'
config
:
'
loc=Asia/Shanghai'
# oss configuration
# oss configuration
qiniu
:
qiniu
:
access-key
:
'
25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
access-key
:
'
25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
secret-key
:
'
pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
secret-key
:
'
pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
bucket
:
'
qm-plus-img'
img-path
:
'
http://qmplusimg.henrongyi.top'
# redis configuration
# redis configuration
redis
:
redis
:
addr
:
'
127.0.0.1:6379'
addr
:
'
127.0.0.1:6379'
...
...
server/config/config.go
浏览文件 @
76ccbcc2
...
@@ -46,6 +46,8 @@ type Redis struct {
...
@@ -46,6 +46,8 @@ type Redis struct {
type
Qiniu
struct
{
type
Qiniu
struct
{
AccessKey
string
`mapstructure:"access-key" json:"accessKey" yaml:"access-key"`
AccessKey
string
`mapstructure:"access-key" json:"accessKey" yaml:"access-key"`
SecretKey
string
`mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
SecretKey
string
`mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
Bucket
string
`mapstructure:"bucket" json:"bucket" yaml:"bucket"`
ImgPath
string
`mapstructure:"img-path" json:"imgPath" yaml:"img-path"`
}
}
type
Captcha
struct
{
type
Captcha
struct
{
...
...
server/initialize/mysql.go
浏览文件 @
76ccbcc2
...
@@ -4,13 +4,15 @@ import (
...
@@ -4,13 +4,15 @@ import (
"gin-vue-admin/global"
"gin-vue-admin/global"
"github.com/jinzhu/gorm"
"github.com/jinzhu/gorm"
_
"github.com/jinzhu/gorm/dialects/mysql"
_
"github.com/jinzhu/gorm/dialects/mysql"
"os"
)
)
//初始化数据库并产生数据库全局变量
//初始化数据库并产生数据库全局变量
func
Mysql
()
{
func
Mysql
()
{
admin
:=
global
.
GVA_CONFIG
.
Mysql
admin
:=
global
.
GVA_CONFIG
.
Mysql
if
db
,
err
:=
gorm
.
Open
(
"mysql"
,
admin
.
Username
+
":"
+
admin
.
Password
+
"@("
+
admin
.
Path
+
")/"
+
admin
.
Dbname
+
"?"
+
admin
.
Config
);
err
!=
nil
{
if
db
,
err
:=
gorm
.
Open
(
"mysql"
,
admin
.
Username
+
":"
+
admin
.
Password
+
"@("
+
admin
.
Path
+
")/"
+
admin
.
Dbname
+
"?"
+
admin
.
Config
);
err
!=
nil
{
global
.
GVA_LOG
.
Error
(
"DEFAULTDB数据库启动异常"
,
err
)
global
.
GVA_LOG
.
Error
(
"MySQL启动异常"
,
err
)
os
.
Exit
(
0
)
}
else
{
}
else
{
global
.
GVA_DB
=
db
global
.
GVA_DB
=
db
global
.
GVA_DB
.
DB
()
.
SetMaxIdleConns
(
admin
.
MaxIdleConns
)
global
.
GVA_DB
.
DB
()
.
SetMaxIdleConns
(
admin
.
MaxIdleConns
)
...
...
server/utils/upload.go
浏览文件 @
76ccbcc2
...
@@ -10,15 +10,12 @@ import (
...
@@ -10,15 +10,12 @@ import (
"time"
"time"
)
)
var
accessKey
string
=
global
.
GVA_CONFIG
.
Qiniu
.
AccessKey
// 你在七牛云的accessKey 这里是我个人测试号的key 仅供测试使用 恳请大家不要乱传东西
var
secretKey
string
=
global
.
GVA_CONFIG
.
Qiniu
.
SecretKey
// 你在七牛云的secretKey 这里是我个人测试号的key 仅供测试使用 恳请大家不要乱传东西
// 接收两个参数 一个文件流 一个 bucket 你的七牛云标准空间的名字
// 接收两个参数 一个文件流 一个 bucket 你的七牛云标准空间的名字
func
Upload
(
file
*
multipart
.
FileHeader
,
bucket
string
,
urlPath
string
)
(
err
error
,
path
string
,
key
string
)
{
func
Upload
(
file
*
multipart
.
FileHeader
)
(
err
error
,
path
string
,
key
string
)
{
putPolicy
:=
storage
.
PutPolicy
{
putPolicy
:=
storage
.
PutPolicy
{
Scope
:
b
ucket
,
Scope
:
global
.
GVA_CONFIG
.
Qiniu
.
B
ucket
,
}
}
mac
:=
qbox
.
NewMac
(
accessKey
,
s
ecretKey
)
mac
:=
qbox
.
NewMac
(
global
.
GVA_CONFIG
.
Qiniu
.
AccessKey
,
global
.
GVA_CONFIG
.
Qiniu
.
S
ecretKey
)
upToken
:=
putPolicy
.
UploadToken
(
mac
)
upToken
:=
putPolicy
.
UploadToken
(
mac
)
cfg
:=
storage
.
Config
{}
cfg
:=
storage
.
Config
{}
// 空间对应的机房
// 空间对应的机房
...
@@ -43,16 +40,15 @@ func Upload(file *multipart.FileHeader, bucket string, urlPath string) (err erro
...
@@ -43,16 +40,15 @@ func Upload(file *multipart.FileHeader, bucket string, urlPath string) (err erro
fileKey
:=
fmt
.
Sprintf
(
"%d%s"
,
time
.
Now
()
.
Unix
(),
file
.
Filename
)
// 文件名格式 自己可以改 建议保证唯一性
fileKey
:=
fmt
.
Sprintf
(
"%d%s"
,
time
.
Now
()
.
Unix
(),
file
.
Filename
)
// 文件名格式 自己可以改 建议保证唯一性
err
=
formUploader
.
Put
(
context
.
Background
(),
&
ret
,
upToken
,
fileKey
,
f
,
dataLen
,
&
putExtra
)
err
=
formUploader
.
Put
(
context
.
Background
(),
&
ret
,
upToken
,
fileKey
,
f
,
dataLen
,
&
putExtra
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
err
)
global
.
GVA_LOG
.
Error
(
"upload file fail:"
,
err
)
//qmlog.QMLog.Info(err)
return
err
,
""
,
""
return
err
,
""
,
""
}
}
return
err
,
url
Path
+
"/"
+
ret
.
Key
,
ret
.
Key
return
err
,
global
.
GVA_CONFIG
.
Qiniu
.
Img
Path
+
"/"
+
ret
.
Key
,
ret
.
Key
}
}
func
DeleteFile
(
bucket
string
,
key
string
)
error
{
func
DeleteFile
(
key
string
)
error
{
mac
:=
qbox
.
NewMac
(
accessKey
,
s
ecretKey
)
mac
:=
qbox
.
NewMac
(
global
.
GVA_CONFIG
.
Qiniu
.
AccessKey
,
global
.
GVA_CONFIG
.
Qiniu
.
S
ecretKey
)
cfg
:=
storage
.
Config
{
cfg
:=
storage
.
Config
{
// 是否使用https域名进行资源管理
// 是否使用https域名进行资源管理
UseHTTPS
:
false
,
UseHTTPS
:
false
,
...
@@ -61,7 +57,7 @@ func DeleteFile(bucket string, key string) error {
...
@@ -61,7 +57,7 @@ func DeleteFile(bucket string, key string) error {
// 如果没有特殊需求,默认不需要指定
// 如果没有特殊需求,默认不需要指定
//cfg.Zone=&storage.ZoneHuabei
//cfg.Zone=&storage.ZoneHuabei
bucketManager
:=
storage
.
NewBucketManager
(
mac
,
&
cfg
)
bucketManager
:=
storage
.
NewBucketManager
(
mac
,
&
cfg
)
err
:=
bucketManager
.
Delete
(
b
ucket
,
key
)
err
:=
bucketManager
.
Delete
(
global
.
GVA_CONFIG
.
Qiniu
.
B
ucket
,
key
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Println
(
err
)
fmt
.
Println
(
err
)
return
err
return
err
...
...
web/src/view/example/upload/upload.vue
浏览文件 @
76ccbcc2
<
template
>
<
template
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
>
<div
v-loading.fullscreen.lock=
"fullscreenLoading"
>
<div
class=
"upload"
>
<div
class=
"upload"
>
<el-upload
<el-upload
:action=
"`$
{path}/fileUploadAndDownload/upload`"
:action=
"`$
{path}/fileUploadAndDownload/upload`"
:before-upload="checkFile"
:before-upload="checkFile"
:headers="{'x-token':token}"
:headers="{ 'x-token': token }"
:on-error="uploadError"
:on-error="uploadError"
:on-success="uploadSuccess"
:on-success="uploadSuccess"
:show-file-list="false"
:show-file-list="false"
>
>
<el-button
size=
"small"
type=
"primary"
>
点击上传
</el-button>
<el-button
size=
"small"
type=
"primary"
>
点击上传
</el-button>
<div
class=
"el-upload__tip"
slot=
"tip"
>
只能上传jpg/png文件,且不超过500kb
</div>
<div
class=
"el-upload__tip"
slot=
"tip"
>
</el-upload>
只能上传jpg/png文件,且不超过500kb
<el-table
:data=
"tableData"
border
stripe
>
</div>
<el-table-column
label=
"预览"
width=
"100"
>
</el-upload>
<template
slot-scope=
"scope"
>
<el-table
:data=
"tableData"
border
stripe
>
<img
:alt=
"scope.row.alt"
:src=
"scope.row.url"
height=
"80"
width=
"80"
/>
<el-table-column
label=
"预览"
width=
"100"
>
</
template
>
<template
slot-scope=
"scope"
>
</el-table-column>
<img
<el-table-column
label=
"日期"
prop=
"UpdatedAt"
width=
"180"
>
:alt=
"scope.row.alt"
<
template
slot-scope=
"scope"
>
:src=
"scope.row.url"
<div>
{{
scope
.
row
.
UpdatedAt
|
formatDate
}}
</div>
height=
"80"
</
template
>
width=
"80"
</el-table-column>
/>
<el-table-column
label=
"文件名"
prop=
"name"
width=
"180"
></el-table-column>
</
template
>
<el-table-column
label=
"链接"
prop=
"url"
></el-table-column>
</el-table-column>
<el-table-column
label=
"标签"
prop=
"tag"
width=
"100"
>
<el-table-column
label=
"日期"
prop=
"UpdatedAt"
width=
"180"
>
<
template
slot-scope=
"scope"
>
<
template
slot-scope=
"scope"
>
<el-tag
<div>
{{
scope
.
row
.
UpdatedAt
|
formatDate
}}
</div>
:type=
"scope.row.tag === 'jpg' ? 'primary' : 'success'"
</
template
>
disable-transitions
</el-table-column>
>
{{
scope
.
row
.
tag
}}
</el-tag>
<el-table-column
</
template
>
label=
"文件名"
</el-table-column>
prop=
"name"
<el-table-column
label=
"操作"
width=
"100"
>
width=
"180"
<
template
slot-scope=
"scope"
>
></el-table-column>
<el-button
@
click=
"downloadFile(scope.row)"
size=
"small"
type=
"text"
>
下载
</el-button>
<el-table-column
label=
"链接"
prop=
"url"
></el-table-column>
<el-button
@
click=
"deleteFile(scope.row)"
size=
"small"
type=
"text"
>
删除
</el-button>
<el-table-column
label=
"标签"
prop=
"tag"
width=
"100"
>
</
template
>
<
template
slot-scope=
"scope"
>
</el-table-column>
<el-tag
</el-table>
:type=
"scope.row.tag === 'jpg' ? 'primary' : 'success'"
<el-pagination
disable-transitions
:current-page=
"page"
>
{{
scope
.
row
.
tag
}}
</el-tag
:page-size=
"pageSize"
>
:page-sizes=
"[10, 30, 50, 100]"
</
template
>
:style=
"{float:'right',padding:'20px'}"
</el-table-column>
:total=
"total"
<el-table-column
label=
"操作"
width=
"100"
>
@
current-change=
"handleCurrentChange"
<
template
slot-scope=
"scope"
>
@
size-change=
"handleSizeChange"
<el-button
@
click=
"downloadFile(scope.row)"
size=
"small"
type=
"text"
layout=
"total, sizes, prev, pager, next, jumper"
>
下载
</el-button
></el-pagination>
>
<el-button
@
click=
"deleteFile(scope.row)"
size=
"small"
type=
"text"
>
删除
</el-button
>
</
template
>
</el-table-column>
</el-table>
<el-pagination
:current-page=
"page"
:page-size=
"pageSize"
:page-sizes=
"[10, 30, 50, 100]"
:style=
"{ float: 'right', padding: '20px' }"
:total=
"total"
@
current-change=
"handleCurrentChange"
@
size-change=
"handleSizeChange"
layout=
"total, sizes, prev, pager, next, jumper"
></el-pagination>
</div>
</div>
</div>
</div>
</template>
</template>
<
script
>
<
script
>
const
path
=
process
.
env
.
VUE_APP_BASE_API
const
path
=
process
.
env
.
VUE_APP_BASE_API
;
import
{
mapGetters
}
from
'
vuex
'
import
{
mapGetters
}
from
"
vuex
"
;
import
infoList
from
'
@/components/mixins/infoList
'
import
infoList
from
"
@/components/mixins/infoList
"
;
import
{
getFileList
,
deleteFile
}
from
'
@/api/fileUploadAndDownload
'
import
{
getFileList
,
deleteFile
}
from
"
@/api/fileUploadAndDownload
"
;
import
{
downloadImage
}
from
'
@/utils/downloadImg
'
import
{
downloadImage
}
from
"
@/utils/downloadImg
"
;
import
{
formatTimeToStr
}
from
'
@/utils/data
'
import
{
formatTimeToStr
}
from
"
@/utils/data
"
;
export
default
{
export
default
{
name
:
'
Upload
'
,
name
:
"
Upload
"
,
mixins
:
[
infoList
],
mixins
:
[
infoList
],
data
()
{
data
()
{
return
{
return
{
fullscreenLoading
:
false
,
fullscreenLoading
:
false
,
listApi
:
getFileList
,
listApi
:
getFileList
,
path
:
path
,
path
:
path
,
tableData
:
[]
tableData
:
[]
,
}
}
;
},
},
computed
:
{
computed
:
{
...
mapGetters
(
'
user
'
,
[
'
userInfo
'
,
'
token
'
])
...
mapGetters
(
"
user
"
,
[
"
userInfo
"
,
"
token
"
]),
},
},
filters
:
{
filters
:
{
formatDate
:
function
(
time
)
{
formatDate
:
function
(
time
)
{
if
(
time
!=
null
&&
time
!=
''
)
{
if
(
time
!=
null
&&
time
!=
""
)
{
var
date
=
new
Date
(
time
)
var
date
=
new
Date
(
time
)
;
return
formatTimeToStr
(
date
,
'
yyyy-MM-dd hh:mm:ss
'
)
return
formatTimeToStr
(
date
,
"
yyyy-MM-dd hh:mm:ss
"
);
}
else
{
}
else
{
return
''
return
""
;
}
}
}
}
,
},
},
methods
:
{
methods
:
{
async
deleteFile
(
row
)
{
async
deleteFile
(
row
)
{
this
.
$confirm
(
'
此操作将永久文件, 是否继续?
'
,
'
提示
'
,
{
this
.
$confirm
(
"
此操作将永久文件, 是否继续?
"
,
"
提示
"
,
{
confirmButtonText
:
'
确定
'
,
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
'
取消
'
,
cancelButtonText
:
"
取消
"
,
type
:
'
warning
'
type
:
"
warning
"
,
})
})
.
then
(
async
()
=>
{
.
then
(
async
()
=>
{
const
res
=
await
deleteFile
(
row
)
const
res
=
await
deleteFile
(
row
)
;
if
(
res
.
code
==
0
)
{
if
(
res
.
code
==
0
)
{
this
.
$message
({
this
.
$message
({
type
:
'
success
'
,
type
:
"
success
"
,
message
:
'
删除成功!
'
message
:
"
删除成功!
"
,
})
})
;
this
.
getTableData
()
this
.
getTableData
()
;
}
}
})
})
.
catch
(()
=>
{
.
catch
(()
=>
{
this
.
$message
({
this
.
$message
({
type
:
'
info
'
,
type
:
"
info
"
,
message
:
'
已取消删除
'
message
:
"
已取消删除
"
,
})
})
;
})
})
;
},
},
checkFile
(
file
)
{
checkFile
(
file
)
{
this
.
fullscreenLoading
=
true
this
.
fullscreenLoading
=
true
;
const
isJPG
=
file
.
type
===
'
image/jpeg
'
const
isJPG
=
file
.
type
===
"
image/jpeg
"
;
const
isPng
=
file
.
type
===
'
image/png
'
const
isPng
=
file
.
type
===
"
image/png
"
;
const
isLt2M
=
file
.
size
/
1024
/
1024
<
2
const
isLt2M
=
file
.
size
/
1024
/
1024
<
2
;
if
(
!
isJPG
&&
!
isPng
)
{
if
(
!
isJPG
&&
!
isPng
)
{
this
.
$message
.
error
(
'
上传头像图片只能是 JPG或png 格式!
'
)
this
.
$message
.
error
(
"
上传头像图片只能是 JPG或png 格式!
"
);
this
.
fullscreenLoading
=
false
this
.
fullscreenLoading
=
false
;
}
}
if
(
!
isLt2M
)
{
if
(
!
isLt2M
)
{
this
.
$message
.
error
(
'
上传头像图片大小不能超过 2MB!
'
)
this
.
$message
.
error
(
"
上传头像图片大小不能超过 2MB!
"
);
this
.
fullscreenLoading
=
false
this
.
fullscreenLoading
=
false
;
}
}
return
(
isPng
||
isJPG
)
&&
isLt2M
return
(
isPng
||
isJPG
)
&&
isLt2M
;
},
},
uploadSuccess
(
res
)
{
uploadSuccess
(
res
)
{
this
.
$message
({
this
.
fullscreenLoading
=
false
;
type
:
'
success
'
,
message
:
'
上传成功
'
})
if
(
res
.
code
==
0
)
{
if
(
res
.
code
==
0
)
{
this
.
getTableData
()
this
.
$message
({
type
:
"
success
"
,
message
:
"
上传成功
"
,
});
if
(
res
.
code
==
0
)
{
this
.
getTableData
();
}
}
else
{
this
.
$message
({
type
:
"
warning
"
,
message
:
res
.
msg
,
});
}
}
this
.
fullscreenLoading
=
false
},
},
uploadError
()
{
uploadError
()
{
this
.
$message
({
this
.
$message
({
type
:
'
error
'
,
type
:
"
error
"
,
message
:
'
上传失败
'
message
:
"
上传失败
"
,
})
});
this
.
fullscreenLoading
=
false
this
.
fullscreenLoading
=
false
;
},
},
downloadFile
(
row
)
{
downloadFile
(
row
)
{
downloadImage
(
row
.
url
,
row
.
name
)
downloadImage
(
row
.
url
,
row
.
name
);
}
},
},
created
()
{
this
.
getTableData
();
},
},
created
(){
};
this
.
getTableData
()
</
script
>
}
}
</
script
>
\ No newline at end of file
web/src/view/login/login.vue
浏览文件 @
76ccbcc2
...
@@ -3,19 +3,31 @@
...
@@ -3,19 +3,31 @@
<vue-particle-line></vue-particle-line>
<vue-particle-line></vue-particle-line>
<el-main
class=
"login-box"
>
<el-main
class=
"login-box"
>
<h1
class=
"title-1"
>
<h1
class=
"title-1"
>
<img
class=
"logo"
:src=
"require('@/assets/logo.png')"
alt=
""
srcset=
""
>
<img
class=
"logo"
:src=
"require('@/assets/logo.png')"
alt=
""
srcset=
""
/>
</h1>
</h1>
<el-form
:model=
"loginForm"
:rules=
"rules"
ref=
"loginForm"
>
<el-form
:model=
"loginForm"
:rules=
"rules"
ref=
"loginForm"
@
keyup.enter.native=
"submitForm"
>
<el-form-item
prop=
"username"
>
<el-form-item
prop=
"username"
>
<el-input
placeholder=
"请输入用户名"
v-model=
"loginForm.username"
></el-input>
<el-input
placeholder=
"请输入用户名"
v-model=
"loginForm.username"
></el-input>
</el-form-item>
</el-form-item>
<el-form-item
prop=
"password"
>
<el-form-item
prop=
"password"
>
<el-input
<el-input
:type=
"lock
==='lock'?'password':
'text'"
:type=
"lock
=== 'lock' ? 'password' :
'text'"
placeholder=
"请输入密码"
placeholder=
"请输入密码"
v-model=
"loginForm.password"
v-model=
"loginForm.password"
>
>
<i
:class=
"'el-input__icon el-icon-' + lock"
@
click=
"changeLock"
slot=
"suffix"
></i>
<i
:class=
"'el-input__icon el-icon-' + lock"
@
click=
"changeLock"
slot=
"suffix"
></i>
</el-input>
</el-input>
</el-form-item>
</el-form-item>
<el-form-item
style=
"position:relative"
>
<el-form-item
style=
"position:relative"
>
...
@@ -25,7 +37,13 @@
...
@@ -25,7 +37,13 @@
placeholder=
"请输入验证码"
placeholder=
"请输入验证码"
maxlength=
"10"
maxlength=
"10"
/>
/>
<img
v-if=
"picPath"
:src=
"path + picPath"
alt=
"请输入验证码"
@
click=
"loginVefify()"
class=
"vPic"
>
<img
v-if=
"picPath"
:src=
"path + picPath"
alt=
"请输入验证码"
@
click=
"loginVefify()"
class=
"vPic"
/>
</el-form-item>
</el-form-item>
<el-form-item>
<el-form-item>
<el-button
@
click=
"submitForm"
style=
"width:100%"
>
登 录
</el-button>
<el-button
@
click=
"submitForm"
style=
"width:100%"
>
登 录
</el-button>
...
@@ -37,79 +55,79 @@
...
@@ -37,79 +55,79 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
{
mapActions
}
from
'
vuex
'
import
{
mapActions
}
from
"
vuex
"
;
import
{
captcha
}
from
'
@/api/user
'
import
{
captcha
}
from
"
@/api/user
"
;
const
path
=
process
.
env
.
VUE_APP_BASE_API
const
path
=
process
.
env
.
VUE_APP_BASE_API
;
export
default
{
export
default
{
name
:
'
Login
'
,
name
:
"
Login
"
,
data
()
{
data
()
{
const
checkUsername
=
(
rule
,
value
,
callback
)
=>
{
const
checkUsername
=
(
rule
,
value
,
callback
)
=>
{
if
(
value
.
length
<
5
||
value
.
length
>
12
)
{
if
(
value
.
length
<
5
||
value
.
length
>
12
)
{
return
callback
(
new
Error
(
'
请输入正确的用户名
'
))
return
callback
(
new
Error
(
"
请输入正确的用户名
"
));
}
else
{
}
else
{
callback
()
callback
()
;
}
}
}
}
;
const
checkPassword
=
(
rule
,
value
,
callback
)
=>
{
const
checkPassword
=
(
rule
,
value
,
callback
)
=>
{
if
(
value
.
length
<
6
||
value
.
length
>
12
)
{
if
(
value
.
length
<
6
||
value
.
length
>
12
)
{
return
callback
(
new
Error
(
'
请输入正确的密码
'
))
return
callback
(
new
Error
(
"
请输入正确的密码
"
));
}
else
{
}
else
{
callback
()
callback
()
;
}
}
}
}
;
return
{
return
{
lock
:
'
lock
'
,
lock
:
"
lock
"
,
loginForm
:
{
loginForm
:
{
username
:
''
,
username
:
""
,
password
:
''
,
password
:
""
,
captcha
:
''
,
captcha
:
""
,
captchaId
:
''
,
captchaId
:
""
,
},
},
rules
:
{
rules
:
{
username
:
[{
validator
:
checkUsername
,
trigger
:
'
blur
'
}],
username
:
[{
validator
:
checkUsername
,
trigger
:
"
blur
"
}],
password
:
[{
validator
:
checkPassword
,
trigger
:
'
blur
'
}]
password
:
[{
validator
:
checkPassword
,
trigger
:
"
blur
"
}],
},
},
path
:
path
,
path
:
path
,
logVerify
:
''
,
logVerify
:
""
,
picPath
:
''
picPath
:
""
,
}
}
;
},
},
created
()
{
created
()
{
this
.
loginVefify
()
this
.
loginVefify
()
;
},
},
methods
:
{
methods
:
{
...
mapActions
(
'
user
'
,
[
'
LoginIn
'
]),
...
mapActions
(
"
user
"
,
[
"
LoginIn
"
]),
async
login
()
{
async
login
()
{
await
this
.
LoginIn
(
this
.
loginForm
)
await
this
.
LoginIn
(
this
.
loginForm
)
;
},
},
async
submitForm
()
{
async
submitForm
()
{
this
.
$refs
.
loginForm
.
validate
(
async
v
=>
{
this
.
$refs
.
loginForm
.
validate
(
async
(
v
)
=>
{
if
(
v
)
{
if
(
v
)
{
this
.
login
()
this
.
login
()
;
this
.
loginVefify
()
this
.
loginVefify
()
;
}
else
{
}
else
{
this
.
$message
({
this
.
$message
({
type
:
'
error
'
,
type
:
"
error
"
,
message
:
'
请正确填写登录信息
'
,
message
:
"
请正确填写登录信息
"
,
showClose
:
true
showClose
:
true
,
})
})
;
this
.
loginVefify
()
this
.
loginVefify
()
;
return
false
return
false
;
}
}
})
})
;
},
},
changeLock
()
{
changeLock
()
{
this
.
lock
===
'
lock
'
?
(
this
.
lock
=
'
unlock
'
)
:
(
this
.
lock
=
'
lock
'
)
this
.
lock
===
"
lock
"
?
(
this
.
lock
=
"
unlock
"
)
:
(
this
.
lock
=
"
lock
"
);
},
},
loginVefify
()
{
loginVefify
()
{
captcha
({}).
then
(
ele
=>
{
captcha
({}).
then
(
(
ele
)
=>
{
this
.
picPath
=
ele
.
data
.
picPath
this
.
picPath
=
ele
.
data
.
picPath
;
this
.
loginForm
.
captchaId
=
ele
.
data
.
captchaId
this
.
loginForm
.
captchaId
=
ele
.
data
.
captchaId
;
})
})
;
}
}
,
}
}
,
}
}
;
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
scoped
lang=
"scss"
>
...
@@ -121,16 +139,16 @@ export default {
...
@@ -121,16 +139,16 @@ export default {
position
:
absolute
;
position
:
absolute
;
left
:
50%
;
left
:
50%
;
margin-left
:
-22vw
;
margin-left
:
-22vw
;
top
:
5vh
;
top
:
5vh
;
.logo
{
.logo
{
height
:
35vh
;
height
:
35vh
;
width
:
35vh
;
width
:
35vh
;
}
}
}
}
.vPic
{
.vPic
{
position
:
absolute
;
position
:
absolute
;
right
:
10px
;
right
:
10px
;
bottom
:
0px
;
// 适配ie
bottom
:
0px
;
// 适配ie
}
}
}
}
</
style
>
</
style
>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录