Browse Source

Merge branches 'develop' and 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev

QM303176530 4 years ago
parent
commit
466d7814b1

+ 8 - 3
README.md

@@ -12,8 +12,11 @@
 
 [English](./README-en.md) | 简体中文
 
-[gitee地址](https://gitee.com/pixelmax/gin-vue-admin)|
-[github地址](https://github.com/flipped-aurora/gin-vue-admin)
+[gitee地址:https://gitee.com/pixelmax/gin-vue-admin](https://gitee.com/pixelmax/gin-vue-admin)
+
+[github地址:https://github.com/flipped-aurora/gin-vue-admin](https://github.com/flipped-aurora/gin-vue-admin)
+
+[vue3版本分支地址:https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop](https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop)
 
 # 项目文档
 [在线文档](https://www.gin-vue-admin.com/) : https://www.gin-vue-admin.com/
@@ -72,7 +75,7 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm
 - node版本 > v8.6.0
 - golang版本 >= v1.14
 - IDE推荐:Goland
-- gormv2版本初始化数据库可以利用批量创建功能,这里已经写好初始化代码,需要在main.go内打开 initialize.Data() 的注释即可
+- 初始化项目: 不同版本数据库初始化不通 参见https://www.gin-vue-admin.com/docs/server#1-%E5%88%9D%E5%A7%8B%E5%8C%96server%E9%A1%B9%E7%9B%AE
 - 替换掉项目中的七牛云公钥,私钥,仓名和默认url地址,以免发生测试文件数据错乱
 ```
 
@@ -160,6 +163,8 @@ npm run serve
 
 ### 2.2 server端
 
+使用 goland等编辑工具,打开server目录,不可以打开 gin-vue-admin跟目录
+
 ```bash
 # 使用 go.mod
 

+ 3 - 1
server/Makefile

@@ -1,11 +1,13 @@
 .PHONY: all build run gotool clean help
 
-BINARY="server"
+BINARY="gin-vue-admin"
 GVA = "gva"
 
 all: check gva initdb run
 
 gva:
+	go env -w GO111MODULE=on
+    go env -w GOPROXY=https://goproxy.io,direct
 	go build -o ${GVA} cmd/main.go
 
 initdb:

+ 5 - 5
server/api/v1/sys_user.go

@@ -50,11 +50,11 @@ func tokenNext(c *gin.Context, user model.SysUser) {
 		NickName:    user.NickName,
 		Username:    user.Username,
 		AuthorityId: user.AuthorityId,
-		BufferTime:  60 * 60 * 24, // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失
+		BufferTime:  global.GVA_CONFIG.JWT.BufferTime, // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失
 		StandardClaims: jwt.StandardClaims{
-			NotBefore: time.Now().Unix() - 1000,       // 签名生效时间
-			ExpiresAt: time.Now().Unix() + 60*60*24*7, // 过期时间 7天
-			Issuer:    "qmPlus",                       // 签名的发行者
+			NotBefore: time.Now().Unix() - 1000,                              // 签名生效时间
+			ExpiresAt: time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime, // 过期时间 7天  配置文件
+			Issuer:    "qmPlus",                                              // 签名的发行者
 		},
 	}
 	token, err := j.CreateToken(claims)
@@ -240,7 +240,7 @@ func DeleteUser(c *gin.Context) {
 func SetUserInfo(c *gin.Context) {
 	var user model.SysUser
 	_ = c.ShouldBindJSON(&user)
-	if err := utils.Verify(user, utils.SetUserVerify); err != nil {
+	if err := utils.Verify(user, utils.IdVerify); err != nil {
 		response.FailWithMessage(err.Error(), c)
 		return
 	}

+ 1 - 12
server/cmd/datas/authority_menus.go

@@ -41,17 +41,9 @@ var AuthorityMenus = []SysAuthorityMenus{
 	{"888", 27},
 	{"888", 28},
 	{"888", 29},
-	{"888", 30},
-	{"888", 31},
-	{"888", 32},
-	{"888", 33},
 	{"8881", 1},
 	{"8881", 2},
 	{"8881", 8},
-	{"8881", 17},
-	{"8881", 18},
-	{"8881", 19},
-	{"8881", 20},
 	{"9528", 1},
 	{"9528", 2},
 	{"9528", 3},
@@ -64,13 +56,10 @@ var AuthorityMenus = []SysAuthorityMenus{
 	{"9528", 10},
 	{"9528", 11},
 	{"9528", 12},
-	{"9528", 13},
 	{"9528", 14},
 	{"9528", 15},
+	{"9528", 16},
 	{"9528", 17},
-	{"9528", 18},
-	{"9528", 19},
-	{"9528", 20},
 }
 
 func InitSysAuthorityMenus(db *gorm.DB) {

+ 21 - 25
server/cmd/datas/menus.go

@@ -20,35 +20,31 @@ var BaseMenus = []model.SysBaseMenu{
 	{GVA_MODEL: global.GVA_MODEL{ID: 7, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "user", Name: "user", Component: "view/superAdmin/user/user.vue", Sort: 4, Meta: model.Meta{Title: "用户管理", Icon: "coordinate"}},
 	{GVA_MODEL: global.GVA_MODEL{ID: 8, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: true, ParentId: "0", Path: "person", Name: "person", Component: "view/person/person.vue", Sort: 4, Meta: model.Meta{Title: "个人信息", Icon: "message-solid"}},
 	{GVA_MODEL: global.GVA_MODEL{ID: 9, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "0", Path: "example", Name: "example", Component: "view/example/index.vue", Sort: 6, Meta: model.Meta{Title: "示例文件", Icon: "s-management"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 10, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "table", Name: "table", Component: "view/example/table/table.vue", Sort: 1, Meta: model.Meta{Title: "表格示例", Icon: "s-order"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 11, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "form", Name: "form", Component: "view/example/form/form.vue", Sort: 2, Meta: model.Meta{Title: "表单示例", Icon: "document"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 12, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "rte", Name: "rte", Component: "view/example/rte/rte.vue", Sort: 3, Meta: model.Meta{Title: "富文本编辑器", Icon: "reading"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 13, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "excel", Name: "excel", Component: "view/example/excel/excel.vue", Sort: 4, Meta: model.Meta{Title: "excel导入导出", Icon: "s-marketing"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 14, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: model.Meta{Title: "上传下载", Icon: "upload"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 15, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: model.Meta{Title: "断点续传", Icon: "upload"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 16, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "customer", Name: "customer", Component: "view/example/customer/customer.vue", Sort: 7, Meta: model.Meta{Title: "客户列表(资源示例)", Icon: "s-custom"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 17, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "0", Path: "systemTools", Name: "systemTools", Component: "view/systemTools/index.vue", Sort: 5, Meta: model.Meta{Title: "系统工具", Icon: "s-cooperation"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 18, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "17", Path: "autoCode", Name: "autoCode", Component: "view/systemTools/autoCode/index.vue", Sort: 1, Meta: model.Meta{Title: "代码生成器", Icon: "cpu", KeepAlive: true}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 19, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "17", Path: "formCreate", Name: "formCreate", Component: "view/systemTools/formCreate/index.vue", Sort: 2, Meta: model.Meta{Title: "表单生成器", Icon: "magic-stick", KeepAlive: true}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 20, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "17", Path: "system", Name: "system", Component: "view/systemTools/system/system.vue", Sort: 3, Meta: model.Meta{Title: "系统配置", Icon: "s-operation"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 21, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "0", Path: "iconList", Name: "iconList", Component: "view/iconList/index.vue", Sort: 2, Meta: model.Meta{Title: "图标集合", Icon: "star-on"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 22, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "dictionary", Name: "dictionary", Component: "view/superAdmin/dictionary/sysDictionary.vue", Sort: 5, Meta: model.Meta{Title: "字典管理", Icon: "notebook-2"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 23, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: true, ParentId: "3", Path: "dictionaryDetail/:id", Name: "dictionaryDetail", Component: "view/superAdmin/dictionary/sysDictionaryDetail.vue", Sort: 1, Meta: model.Meta{Title: "字典详情", Icon: "s-order"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 24, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: model.Meta{Title: "操作历史", Icon: "time"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 25, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "simpleUploader", Name: "simpleUploader", Component: "view/example/simpleUploader/simpleUploader", Sort: 6, Meta: model.Meta{Title: "断点续传(插件版)", Icon: "upload"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 26, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Hidden: false, Component: "/", Sort: 0, Meta: model.Meta{Title: "官方网站", Icon: "s-home"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 27, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "state", Name: "state", Hidden: false, Component: "view/system/state.vue", Sort: 6, Meta: model.Meta{Title: "服务器状态", Icon: "cloudy"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 28, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "workflow", Name: "workflow", Hidden: false, Component: "view/workflow/index.vue", Sort: 5, Meta: model.Meta{Title: "工作流功能", Icon: "phone"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 29, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "28", Path: "workflowCreate", Name: "workflowCreate", Hidden: false, Component: "view/workflow/workflowCreate/workflowCreate.vue", Sort: 0, Meta: model.Meta{Title: "工作流绘制", Icon: "circle-plus"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 30, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "28", Path: "workflowProcess", Name: "workflowProcess", Hidden: false, Component: "view/workflow/workflowProcess/workflowProcess.vue", Sort: 0, Meta: model.Meta{Title: "工作流列表", Icon: "s-cooperation"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 31, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "28", Path: "workflowUse", Name: "workflowUse", Hidden: true, Component: "view/workflow/workflowUse/workflowUse.vue", Sort: 0, Meta: model.Meta{Title: "使用工作流", Icon: "video-play"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 32, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "28", Path: "started", Name: "started", Hidden: false, Component: "view/workflow/userList/started.vue", Sort: 0, Meta: model.Meta{Title: "我发起的", Icon: "s-order"}},
-	{GVA_MODEL: global.GVA_MODEL{ID: 33, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "28", Path: "need", Name: "need", Hidden: false, Component: "view/workflow/userList/need.vue", Sort: 0, Meta: model.Meta{Title: "我的待办", Icon: "s-platform"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 10, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "excel", Name: "excel", Component: "view/example/excel/excel.vue", Sort: 4, Meta: model.Meta{Title: "excel导入导出", Icon: "s-marketing"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 11, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "upload", Name: "upload", Component: "view/example/upload/upload.vue", Sort: 5, Meta: model.Meta{Title: "上传下载", Icon: "upload"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 12, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "breakpoint", Name: "breakpoint", Component: "view/example/breakpoint/breakpoint.vue", Sort: 6, Meta: model.Meta{Title: "断点续传", Icon: "upload"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 13, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "customer", Name: "customer", Component: "view/example/customer/customer.vue", Sort: 7, Meta: model.Meta{Title: "客户列表(资源示例)", Icon: "s-custom"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 14, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "0", Path: "systemTools", Name: "systemTools", Component: "view/systemTools/index.vue", Sort: 5, Meta: model.Meta{Title: "系统工具", Icon: "s-cooperation"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 15, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "14", Path: "autoCode", Name: "autoCode", Component: "view/systemTools/autoCode/index.vue", Sort: 1, Meta: model.Meta{Title: "代码生成器", Icon: "cpu", KeepAlive: true}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 16, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "14", Path: "formCreate", Name: "formCreate", Component: "view/systemTools/formCreate/index.vue", Sort: 2, Meta: model.Meta{Title: "表单生成器", Icon: "magic-stick", KeepAlive: true}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 17, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "14", Path: "system", Name: "system", Component: "view/systemTools/system/system.vue", Sort: 3, Meta: model.Meta{Title: "系统配置", Icon: "s-operation"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 18, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "dictionary", Name: "dictionary", Component: "view/superAdmin/dictionary/sysDictionary.vue", Sort: 5, Meta: model.Meta{Title: "字典管理", Icon: "notebook-2"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 19, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: true, ParentId: "3", Path: "dictionaryDetail/:id", Name: "dictionaryDetail", Component: "view/superAdmin/dictionary/sysDictionaryDetail.vue", Sort: 1, Meta: model.Meta{Title: "字典详情", Icon: "s-order"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 20, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: model.Meta{Title: "操作历史", Icon: "time"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 21, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "simpleUploader", Name: "simpleUploader", Component: "view/example/simpleUploader/simpleUploader", Sort: 6, Meta: model.Meta{Title: "断点续传(插件版)", Icon: "upload"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 22, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Hidden: false, Component: "/", Sort: 0, Meta: model.Meta{Title: "官方网站", Icon: "s-home"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 23, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "state", Name: "state", Hidden: false, Component: "view/system/state.vue", Sort: 6, Meta: model.Meta{Title: "服务器状态", Icon: "cloudy"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 24, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "workflow", Name: "workflow", Hidden: false, Component: "view/workflow/index.vue", Sort: 5, Meta: model.Meta{Title: "工作流功能", Icon: "phone"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 25, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "24", Path: "workflowCreate", Name: "workflowCreate", Hidden: false, Component: "view/workflow/workflowCreate/workflowCreate.vue", Sort: 0, Meta: model.Meta{Title: "工作流绘制", Icon: "circle-plus"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 26, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "24", Path: "workflowProcess", Name: "workflowProcess", Hidden: false, Component: "view/workflow/workflowProcess/workflowProcess.vue", Sort: 0, Meta: model.Meta{Title: "工作流列表", Icon: "s-cooperation"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 27, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "24", Path: "workflowUse", Name: "workflowUse", Hidden: true, Component: "view/workflow/workflowUse/workflowUse.vue", Sort: 0, Meta: model.Meta{Title: "使用工作流", Icon: "video-play"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 28, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "24", Path: "started", Name: "started", Hidden: false, Component: "view/workflow/userList/started.vue", Sort: 0, Meta: model.Meta{Title: "我发起的", Icon: "s-order"}},
+	{GVA_MODEL: global.GVA_MODEL{ID: 29, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "24", Path: "need", Name: "need", Hidden: false, Component: "view/workflow/userList/need.vue", Sort: 0, Meta: model.Meta{Title: "我的待办", Icon: "s-platform"}},
 }
 
 func InitSysBaseMenus(db *gorm.DB) {
 	if err := db.Transaction(func(tx *gorm.DB) error {
-		if tx.Where("id IN ?", []int{1, 27}).Find(&[]model.SysBaseMenu{}).RowsAffected == 2 {
+		if tx.Where("id IN ?", []int{1, 23}).Find(&[]model.SysBaseMenu{}).RowsAffected == 2 {
 			color.Danger.Println("sys_base_menus表的初始数据已存在!")
 			return nil
 		}

+ 3 - 1
server/config.yaml

@@ -3,6 +3,8 @@
 # jwt configuration
 jwt:
   signing-key: 'qmPlus'
+  expires-time: 604800
+  buffer-time: 86400
 
 # zap logger configuration
 zap:
@@ -60,7 +62,7 @@ mysql:
   max-idle-conns: 10
   max-open-conns: 100
   log-mode: false
-  log-zap: false
+  log-zap: ""
 
 # local configuration
 local:

+ 1 - 1
server/config/gorm.go

@@ -9,5 +9,5 @@ type Mysql struct {
 	MaxIdleConns int    `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
 	MaxOpenConns int    `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
 	LogMode      bool   `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"`
-	LogZap       bool   `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"`
+	LogZap       string `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"`
 }

+ 3 - 1
server/config/jwt.go

@@ -1,5 +1,7 @@
 package config
 
 type JWT struct {
-	SigningKey string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"`
+	SigningKey  string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"`
+	ExpiresTime int64  `mapstructure:"expires-time" json:"expiresTime" yaml:"expires-time"`
+	BufferTime  int64  `mapstructure:"buffer-time" json:"bufferTime" yaml:"buffer-time"`
 }

+ 2 - 2
server/go.mod

@@ -54,7 +54,7 @@ require (
 	gopkg.in/ini.v1 v1.55.0 // indirect
 	gopkg.in/yaml.v2 v2.3.0 // indirect
 	gorm.io/driver/mysql v0.3.0
-	gorm.io/gorm v1.20.5
+	gorm.io/gorm v1.20.9
 )
 
-replace github.com/casbin/gorm-adapter/v3 => github.com/casbin/gorm-adapter/v3 v3.0.2
+replace github.com/casbin/gorm-adapter/v3 => github.com/casbin/gorm-adapter/v3 v3.0.2

+ 42 - 19
server/initialize/gorm.go

@@ -2,6 +2,7 @@ package initialize
 
 import (
 	"gin-vue-admin/global"
+	"gin-vue-admin/initialize/internal"
 	"gin-vue-admin/model"
 	"go.uber.org/zap"
 	"gorm.io/driver/mysql"
@@ -10,7 +11,11 @@ import (
 	"os"
 )
 
-// Gorm 初始化数据库并产生数据库全局变量
+//@author: SliverHorn
+//@function: Gorm
+//@description: 初始化数据库并产生数据库全局变量
+//@return: *gorm.DB
+
 func Gorm() *gorm.DB {
 	switch global.GVA_CONFIG.System.DbType {
 	case "mysql":
@@ -20,7 +25,12 @@ func Gorm() *gorm.DB {
 	}
 }
 
-// MysqlTables 注册数据库表专用
+// MysqlTables
+//@author: SliverHorn
+//@function: MysqlTables
+//@description: 注册数据库表专用
+//@param: db *gorm.DB
+
 func MysqlTables(db *gorm.DB) {
 	err := db.AutoMigrate(
 		model.SysUser{},
@@ -52,7 +62,12 @@ func MysqlTables(db *gorm.DB) {
 	global.GVA_LOG.Info("register table success")
 }
 
-// GormMysql 初始化Mysql数据库
+//
+//@author: SliverHorn
+//@function: GormMysql
+//@description: 初始化Mysql数据库
+//@return: *gorm.DB
+
 func GormMysql() *gorm.DB {
 	m := global.GVA_CONFIG.Mysql
 	dsn := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
@@ -76,23 +91,31 @@ func GormMysql() *gorm.DB {
 	}
 }
 
-// gormConfig 根据配置决定是否开启日志
+//@author: SliverHorn
+//@function: gormConfig
+//@description: 根据配置决定是否开启日志
+//@param: mod bool
+//@return: *gorm.Config
+
 func gormConfig(mod bool) *gorm.Config {
-	if global.GVA_CONFIG.Mysql.LogZap {
-		return &gorm.Config{
-			Logger:                                   Default.LogMode(logger.Info),
-			DisableForeignKeyConstraintWhenMigrating: true,
-		}
-	}
-	if mod {
-		return &gorm.Config{
-			Logger:                                   logger.Default.LogMode(logger.Info),
-			DisableForeignKeyConstraintWhenMigrating: true,
-		}
-	} else {
-		return &gorm.Config{
-			Logger:                                   logger.Default.LogMode(logger.Silent),
-			DisableForeignKeyConstraintWhenMigrating: true,
+	var config = &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
+	switch global.GVA_CONFIG.Mysql.LogZap {
+	case "silent", "Silent":
+		config.Logger = internal.Default.LogMode(logger.Silent)
+	case "error", "Error":
+		config.Logger = internal.Default.LogMode(logger.Error)
+	case "warn", "Warn":
+		config.Logger = internal.Default.LogMode(logger.Warn)
+	case "info", "Info":
+		config.Logger = internal.Default.LogMode(logger.Info)
+	case "zap", "Zap":
+		config.Logger = internal.Default.LogMode(logger.Info)
+	default:
+		if mod {
+			config.Logger = internal.Default.LogMode(logger.Info)
+			break
 		}
+		config.Logger = internal.Default.LogMode(logger.Silent)
 	}
+	return config
 }

+ 182 - 0
server/initialize/internal/logger.go

@@ -0,0 +1,182 @@
+package internal
+
+import (
+	"context"
+	"fmt"
+	"gin-vue-admin/global"
+	"go.uber.org/zap"
+	"gorm.io/gorm/logger"
+	"gorm.io/gorm/utils"
+	"io/ioutil"
+	"log"
+	"os"
+	"time"
+)
+
+// writer log writer interface
+type writer interface {
+	Printf(string, ...interface{})
+}
+
+type config struct {
+	SlowThreshold time.Duration
+	Colorful      bool
+	LogLevel      logger.LogLevel
+}
+
+var (
+	Discard = New(log.New(ioutil.Discard, "", log.LstdFlags), config{})
+	Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), config{
+		SlowThreshold: 200 * time.Millisecond,
+		LogLevel:      logger.Warn,
+		Colorful:      true,
+	})
+	Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()}
+)
+
+func New(writer writer, config config) logger.Interface {
+	var (
+		infoStr      = "%s\n[info] "
+		warnStr      = "%s\n[warn] "
+		errStr       = "%s\n[error] "
+		traceStr     = "%s\n[%.3fms] [rows:%v] %s"
+		traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s"
+		traceErrStr  = "%s %s\n[%.3fms] [rows:%v] %s"
+	)
+
+	if config.Colorful {
+		infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset
+		warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset
+		errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset
+		traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
+		traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s" + logger.Reset
+		traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
+	}
+
+	return &customLogger{
+		writer:       writer,
+		config:       config,
+		infoStr:      infoStr,
+		warnStr:      warnStr,
+		errStr:       errStr,
+		traceStr:     traceStr,
+		traceWarnStr: traceWarnStr,
+		traceErrStr:  traceErrStr,
+	}
+}
+
+type customLogger struct {
+	writer
+	config
+	infoStr, warnStr, errStr            string
+	traceStr, traceErrStr, traceWarnStr string
+}
+
+// LogMode log mode
+func (c *customLogger) LogMode(level logger.LogLevel) logger.Interface {
+	newLogger := *c
+	newLogger.LogLevel = level
+	return &newLogger
+}
+
+// Info print info
+func (c *customLogger) Info(ctx context.Context, message string, data ...interface{}) {
+	if c.LogLevel >= logger.Info {
+		c.Printf(c.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
+	}
+}
+
+// Warn print warn messages
+func (c *customLogger) Warn(ctx context.Context, message string, data ...interface{}) {
+	if c.LogLevel >= logger.Warn {
+		c.Printf(c.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
+	}
+}
+
+// Error print error messages
+func (c *customLogger) Error(ctx context.Context, message string, data ...interface{}) {
+	if c.LogLevel >= logger.Error {
+		c.Printf(c.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
+	}
+}
+
+// Trace print sql message
+func (c *customLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
+	if c.LogLevel > 0 {
+		elapsed := time.Since(begin)
+		switch {
+		case err != nil && c.LogLevel >= logger.Error:
+			sql, rows := fc()
+			if rows == -1 {
+				c.Printf(c.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
+			} else {
+				c.Printf(c.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
+			}
+		case elapsed > c.SlowThreshold && c.SlowThreshold != 0 && c.LogLevel >= logger.Warn:
+			sql, rows := fc()
+			slowLog := fmt.Sprintf("SLOW SQL >= %v", c.SlowThreshold)
+			if rows == -1 {
+				c.Printf(c.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
+			} else {
+				c.Printf(c.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
+			}
+		case c.LogLevel >= logger.Info:
+			sql, rows := fc()
+			if rows == -1 {
+				c.Printf(c.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
+			} else {
+				c.Printf(c.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
+			}
+		}
+	}
+}
+
+func (c *customLogger) Printf(message string, data ...interface{}) {
+	if global.GVA_CONFIG.Mysql.LogZap != "" {
+		switch len(data) {
+		case 0:
+			global.GVA_LOG.Info(message)
+		case 1:
+			global.GVA_LOG.Info("gorm", zap.Any("src", data[0]))
+		case 2:
+			global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]))
+		case 3:
+			global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]))
+		case 4:
+			global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]), zap.Any("sql", data[3]))
+		}
+		return
+	}
+	switch len(data) {
+	case 0:
+		c.writer.Printf(message, "")
+	case 1:
+		c.writer.Printf(message, data[0])
+	case 2:
+		c.writer.Printf(message, data[0], data[1])
+	case 3:
+		c.writer.Printf(message, data[0], data[1], data[2])
+	case 4:
+		c.writer.Printf(message, data[0], data[1], data[2], data[3])
+	case 5:
+		c.writer.Printf(message, data[0], data[1], data[2], data[3], data[4])
+	}
+}
+
+type traceRecorder struct {
+	logger.Interface
+	BeginAt      time.Time
+	SQL          string
+	RowsAffected int64
+	Err          error
+}
+
+func (t traceRecorder) New() *traceRecorder {
+	return &traceRecorder{Interface: t.Interface, BeginAt: time.Now()}
+}
+
+func (t *traceRecorder) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
+	t.BeginAt = begin
+	t.SQL, t.RowsAffected = fc()
+	t.Err = err
+}

+ 0 - 150
server/initialize/logger.go

@@ -1,150 +0,0 @@
-package initialize
-
-import (
-	"context"
-	"fmt"
-	"gin-vue-admin/global"
-	"go.uber.org/zap"
-	"gorm.io/gorm/logger"
-	"gorm.io/gorm/utils"
-	"io/ioutil"
-	"log"
-	"os"
-	"time"
-)
-
-var (
-	Discard = New(log.New(ioutil.Discard, "", log.LstdFlags), GormConfig{})
-	Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), GormConfig{
-		SlowThreshold: 200 * time.Millisecond,
-		LogLevel:      logger.Warn,
-		Colorful:      true,
-	})
-	Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()}
-)
-
-type traceRecorder struct {
-	logger.Interface
-	BeginAt      time.Time
-	SQL          string
-	RowsAffected int64
-	Err          error
-}
-
-func New(writer Writer, config GormConfig) logger.Interface {
-	var (
-		infoStr      = "%s\n[info] "
-		warnStr      = "%s\n[warn] "
-		errStr       = "%s\n[error] "
-		traceStr     = "%s\n[%.3fms] [rows:%v] %s"
-		traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s"
-		traceErrStr  = "%s %s\n[%.3fms] [rows:%v] %s"
-	)
-
-	if config.Colorful {
-		infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset
-		warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset
-		errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset
-		traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
-		traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s" + logger.Reset
-		traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
-	}
-
-	return &GormLogger{
-		Writer:       writer,
-		GormConfig:   config,
-		infoStr:      infoStr,
-		warnStr:      warnStr,
-		errStr:       errStr,
-		traceStr:     traceStr,
-		traceWarnStr: traceWarnStr,
-		traceErrStr:  traceErrStr,
-	}
-}
-
-// Writer log writer interface
-type Writer interface {
-	Printf(string, ...interface{})
-}
-
-type GormConfig struct {
-	SlowThreshold time.Duration
-	Colorful      bool
-	LogLevel      logger.LogLevel
-}
-
-type GormLogger struct {
-	Writer
-	GormConfig
-	infoStr, warnStr, errStr            string
-	traceStr, traceErrStr, traceWarnStr string
-}
-
-func (g *GormLogger) LogMode(level logger.LogLevel) logger.Interface {
-	newLogger := *g
-	newLogger.LogLevel = level
-	return &newLogger
-}
-
-func (g *GormLogger) Info(ctx context.Context, message string, data ...interface{}) {
-	if g.LogLevel >= logger.Info {
-		g.Printf(g.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
-	}
-}
-
-func (g *GormLogger) Warn(ctx context.Context, message string, data ...interface{}) {
-	if g.LogLevel >= logger.Warn {
-		g.Printf(g.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
-	}
-}
-
-func (g *GormLogger) Error(ctx context.Context, message string, data ...interface{}) {
-	if g.LogLevel >= logger.Error {
-		g.Printf(g.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
-	}
-}
-
-func (g *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
-	if g.LogLevel > 0 {
-		elapsed := time.Since(begin)
-		switch {
-		case err != nil && g.LogLevel >= logger.Error:
-			sql, rows := fc()
-			if rows == -1 {
-				g.Printf(g.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
-			} else {
-				g.Printf(g.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
-			}
-		case elapsed > g.SlowThreshold && g.SlowThreshold != 0 && g.LogLevel >= logger.Warn:
-			sql, rows := fc()
-			slowLog := fmt.Sprintf("SLOW SQL >= %v", g.SlowThreshold)
-			if rows == -1 {
-				g.Printf(g.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
-			} else {
-				g.Printf(g.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
-			}
-		case g.LogLevel >= logger.Info:
-			sql, rows := fc()
-			if rows == -1 {
-				g.Printf(g.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
-			} else {
-				g.Printf(g.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
-			}
-		}
-	}
-}
-
-func (g *GormLogger) Printf(message string, data ...interface{}) {
-	switch len(data) {
-	case 0:
-		global.GVA_LOG.Info(message)
-	case 1:
-		global.GVA_LOG.Info("gorm", zap.Any("src", data[0]))
-	case 2:
-		global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]))
-	case 3:
-		global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]))
-	case 4:
-		global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]), zap.Any("sql", data[3]))
-	}
-}

+ 1 - 1
server/middleware/jwt.go

@@ -47,7 +47,7 @@ func JWTAuth() gin.HandlerFunc {
 			c.Abort()
 		}
 		if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
-			claims.ExpiresAt = time.Now().Unix() + 60*60*24*7
+			claims.ExpiresAt = time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime
 			newToken, _ := j.CreateToken(*claims)
 			newClaims, _ := j.ParseToken(newToken)
 			c.Header("new-token", newToken)

+ 1 - 1
server/model/sys_workflow.go

@@ -110,7 +110,7 @@ type WorkflowNode struct {
 	Cycle             string         `json:"cycle" gorm:"comment:循环时间"`
 	Duration          string         `json:"duration" gorm:"comment:持续时间"`
 	HideIcon          bool           `json:"hideIcon" gorm:"comment:是否隐藏图标"`
-	DueDate           time.Time      `json:"dueDate" gorm:"comment:到期时间"`
+	DueDate           *time.Time     `json:"dueDate" gorm:"comment:到期时间"`
 	AssignType        string         `json:"assignType" gorm:"comment:审批类型"`
 	AssignValue       string         `json:"assignValue" gorm:"comment:审批类型值"`
 	Success           bool           `json:"success" gorm:"comment:是否成功"`

+ 1 - 1
server/service/jwt_black_list.go

@@ -49,7 +49,7 @@ func GetRedisJWT(userName string) (err error, redisJWT string) {
 
 func SetRedisJWT(jwt string, userName string) (err error) {
 	// 此处过期时间等于jwt过期时间
-	timer := 60 * 60 * 24 * 7 * time.Second
+	timer := time.Duration(global.GVA_CONFIG.JWT.ExpiresTime) * time.Second
 	err = global.GVA_REDIS.Set(userName, jwt, timer).Err()
 	return err
 }

+ 0 - 2
server/utils/verify.go

@@ -6,12 +6,10 @@ var (
 	MenuVerify             = Rules{"Path": {NotEmpty()}, "ParentId": {NotEmpty()}, "Name": {NotEmpty()}, "Component": {NotEmpty()}, "Sort": {Ge("0")}}
 	MenuMetaVerify         = Rules{"Title": {NotEmpty()}}
 	LoginVerify            = Rules{"CaptchaId": {NotEmpty()}, "Captcha": {NotEmpty()}, "Username": {NotEmpty()}, "Password": {NotEmpty()}}
-	SetUserVerify          = Rules{"ID": {NotEmpty()}, "Username": {NotEmpty()}, "NickName": {NotEmpty()}, "HeaderImg": {NotEmpty()}}
 	RegisterVerify         = Rules{"Username": {NotEmpty()}, "NickName": {NotEmpty()}, "Password": {NotEmpty()}, "AuthorityId": {NotEmpty()}}
 	PageInfoVerify         = Rules{"Page": {NotEmpty()}, "PageSize": {NotEmpty()}}
 	CustomerVerify         = Rules{"CustomerName": {NotEmpty()}, "CustomerPhoneData": {NotEmpty()}}
 	AutoCodeVerify         = Rules{"Abbreviation": {NotEmpty()}, "StructName": {NotEmpty()}, "PackageName": {NotEmpty()}, "Fields": {NotEmpty()}}
-	WorkFlowVerify         = Rules{"WorkflowNickName": {NotEmpty()}, "WorkflowName": {NotEmpty()}, "WorkflowDescription": {NotEmpty()}, "WorkflowStepInfo": {NotEmpty()}}
 	AuthorityVerify        = Rules{"AuthorityId": {NotEmpty()}, "AuthorityName": {NotEmpty()}, "ParentId": {NotEmpty()}}
 	AuthorityIdVerify      = Rules{"AuthorityId": {NotEmpty()}}
 	OldAuthorityVerify     = Rules{"OldAuthorityId": {NotEmpty()}}

+ 0 - 1
web/debug.log

@@ -1 +0,0 @@
-[1110/113210.377:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)

+ 58 - 41
web/package-lock.json

@@ -8846,12 +8846,8 @@
         "highlight.js": {
             "version": "9.15.10",
             "resolved": "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.15.10.tgz",
-            "integrity": "sha1-exjtdckDSMBF7vntCMoTGaIhmtI="
-        },
-        "highlight.js-async-webpack": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/highlight.js-async-webpack/-/highlight.js-async-webpack-1.0.4.tgz",
-            "integrity": "sha1-wGtnv5nwSQRdYrdW5YVbCRLsYWw="
+            "integrity": "sha1-exjtdckDSMBF7vntCMoTGaIhmtI=",
+            "dev": true
         },
         "hmac-drbg": {
             "version": "1.0.1",
@@ -10230,15 +10226,6 @@
                 "object-visit": "^1.0.0"
             }
         },
-        "mavon-editor": {
-            "version": "2.7.7",
-            "resolved": "https://registry.npmjs.org/mavon-editor/-/mavon-editor-2.7.7.tgz",
-            "integrity": "sha512-lXnYe+dztKepbv8bi2nedRqG/AwyUDF8gmkv9lHD3fpVJ1+pzAS6YILRIryKCvO9qPIOPEThHsda2DxtlzRsZA==",
-            "requires": {
-                "highlight.js": "^9.11.0",
-                "highlight.js-async-webpack": "^1.0.4"
-            }
-        },
         "md5.js": {
             "version": "1.3.5",
             "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -10929,6 +10916,12 @@
             "resolved": "https://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz",
             "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
         },
+        "numericjs": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/numericjs/-/numericjs-1.2.6.tgz",
+            "integrity": "sha1-wNryXEvLIuBDv4NEP5856LM2eYs=",
+            "dev": true
+        },
         "oauth-sign": {
             "version": "0.9.0",
             "resolved": "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz",
@@ -12443,6 +12436,53 @@
                 "unpipe": "1.0.0"
             }
         },
+        "raw-loader": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-3.1.0.tgz",
+            "integrity": "sha512-lzUVMuJ06HF4rYveaz9Tv0WRlUMxJ0Y1hgSkkgg+50iEdaI0TthyEDe08KIHb0XsF6rn8WYTqPCaGTZg3sX+qA==",
+            "dev": true,
+            "requires": {
+                "loader-utils": "^1.1.0",
+                "schema-utils": "^2.0.1"
+            },
+            "dependencies": {
+                "ajv": {
+                    "version": "6.12.6",
+                    "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+                    "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+                    "dev": true,
+                    "requires": {
+                        "fast-deep-equal": "^3.1.1",
+                        "fast-json-stable-stringify": "^2.0.0",
+                        "json-schema-traverse": "^0.4.1",
+                        "uri-js": "^4.2.2"
+                    }
+                },
+                "ajv-keywords": {
+                    "version": "3.5.2",
+                    "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+                    "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+                    "dev": true
+                },
+                "fast-deep-equal": {
+                    "version": "3.1.3",
+                    "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+                    "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+                    "dev": true
+                },
+                "schema-utils": {
+                    "version": "2.7.1",
+                    "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+                    "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+                    "dev": true,
+                    "requires": {
+                        "@types/json-schema": "^7.0.5",
+                        "ajv": "^6.12.4",
+                        "ajv-keywords": "^3.5.2"
+                    }
+                }
+            }
+        },
         "read-pkg": {
             "version": "5.2.0",
             "resolved": "https://registry.npm.taobao.org/read-pkg/download/read-pkg-5.2.0.tgz",
@@ -14898,9 +14938,9 @@
             }
         },
         "vue-loader-v16": {
-            "version": "npm:vue-loader@16.0.0-beta.9",
-            "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.9.tgz",
-            "integrity": "sha512-mu9pg6554GbXDSO8LlxkQM6qUJzUkb/A0FJc9LgRqnU9MCnhzEXwCt1Zx5NObvFpzs2mH2dH/uUCDwL8Qaz9sA==",
+            "version": "npm:vue-loader@16.1.1",
+            "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.1.tgz",
+            "integrity": "sha512-wz/+HFg/3SBayHWAlZXARcnDTl3VOChrfW9YnxvAweiuyKX/7IGx1ad/4yJHmwhgWlOVYMAbTiI7GV8G33PfGQ==",
             "dev": true,
             "optional": true,
             "requires": {
@@ -14993,15 +15033,6 @@
                 "vue": "^2.5.21"
             }
         },
-        "vue-quill-editor": {
-            "version": "3.0.6",
-            "resolved": "https://registry.npmjs.org/vue-quill-editor/-/vue-quill-editor-3.0.6.tgz",
-            "integrity": "sha512-g20oSZNWg8Hbu41Kinjd55e235qVWPLfg4NvsLW6d+DhgBTFbEuMpcWlUdrD6qT3+Noim6DRu18VLM9lVShXOQ==",
-            "requires": {
-                "object-assign": "^4.1.1",
-                "quill": "^1.3.4"
-            }
-        },
         "vue-router": {
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.3.tgz",
@@ -15532,20 +15563,6 @@
             "integrity": "sha1-f4RzvIOd/YdgituV1+sHUhFXikI=",
             "dev": true
         },
-        "wfd-gva": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/wfd-gva/-/wfd-gva-1.0.4.tgz",
-            "integrity": "sha512-m08qHdhUFUbj7IzJWOoxhN9VAJKzx/QbkTi+XXIHrX24UGovy4XvwmOrWrna+3rHkq60xszHMy1U/MQflNCPlA==",
-            "requires": {
-                "@antv/dom-util": "2.0.2",
-                "@antv/g-canvas": "^0.4.12",
-                "@antv/g6": "3.5.2",
-                "@antv/matrix-util": "2.0.7",
-                "@antv/util": "~2.0.9",
-                "element-ui": "2.12.0",
-                "vue": "^2.6.10"
-            }
-        },
         "which": {
             "version": "1.3.1",
             "resolved": "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz",

+ 0 - 2
web/package.json

@@ -13,7 +13,6 @@
         "core-js": "^3.6.5",
         "echarts": "^4.7.0",
         "element-ui": "^2.12.0",
-        "mavon-editor": "^2.7.7",
         "node-sass": "^4.14.1",
         "path": "^0.12.7",
         "qs": "^6.8.0",
@@ -25,7 +24,6 @@
         "timeline-vuejs": "1.1.1",
         "vue": "^2.6.10",
         "vue-particle-line": "^0.1.4",
-        "vue-quill-editor": "^3.0.6",
         "vue-router": "^3.1.3",
         "vue-simple-uploader": "^0.7.4",
         "vuescroll": "^4.14.4",

+ 0 - 19
web/src/main.js

@@ -9,28 +9,9 @@ Vue.use(ElementUI);
 // 引入封装的router
 import router from '@/router/index'
 
-// canvas背景插件
-import vueParticleLine from 'vue-particle-line'
-import 'vue-particle-line/dist/vue-particle-line.css'
-Vue.use(vueParticleLine)
-
 // time line css
 import '../node_modules/timeline-vuejs/dist/timeline-vuejs.css'
 
-// 富文本插件
-import VueQuillEditor from 'vue-quill-editor'
-import 'quill/dist/quill.core.css'
-import 'quill/dist/quill.snow.css'
-import 'quill/dist/quill.bubble.css'
-
-Vue.use(VueQuillEditor)
-
-// markdown插件
-import mavonEditor from 'mavon-editor'
-import 'mavon-editor/dist/css/index.css'
-
-Vue.use(mavonEditor)
-
 import '@/permission'
 import { store } from '@/store/index'
 Vue.config.productionTip = false

+ 3 - 0
web/src/permission.js

@@ -1,5 +1,6 @@
 import router from './router'
 import { store } from '@/store/index'
+import getPageTitle from '@/utils/page'
 
 let asyncRouterFlag = 0
 
@@ -8,6 +9,8 @@ const whiteList = ['login']
 router.beforeEach(async(to, from, next) => {
     const token = store.getters['user/token']
         // 在白名单中的判断情况
+        //修改网页标签名称
+    document.title = getPageTitle(to.meta.title)
     if (whiteList.indexOf(to.name) > -1) {
         if (token) {
             next({ path: '/layout/dashboard' })

+ 1 - 0
web/src/store/module/user.js

@@ -46,6 +46,7 @@ export const user = {
                 } else {
                     router.push({ path: '/layout/dashboard' })
                 }
+                return true
             }
         },
         async LoginOut({ commit }) {

+ 8 - 0
web/src/utils/page.js

@@ -0,0 +1,8 @@
+const title = 'GIN-VUE-ADMIN'
+
+export default function getPageTitle(pageTitle) {
+    if (pageTitle) {
+        return `${pageTitle} - ${title}`
+    }
+    return `${title}`
+}

+ 0 - 187
web/src/view/example/form/form.vue

@@ -1,187 +0,0 @@
-<template>
-  <div>
-    <el-form :model="form" label-width="80px" ref="form">
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">活动名称</label></el-col>
-        <el-col  :span="10" :xs="14"><el-input v-model="form.name"></el-input></el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">活动区域</label></el-col>
-        <el-col  :span="10" :xs="14">
-           <el-select placeholder="请选择活动区域" v-model="form.region">
-            <el-option label="上海" value="shanghai"></el-option>
-            <el-option label="北京" value="beijing"></el-option>
-           </el-select>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">活动时间</label></el-col>
-        <el-col  :span="10" :xs="18">
-           <el-col :span="11">
-          <el-date-picker placeholder="选择日期" style="width: 100%;" type="date" v-model="form.date1"></el-date-picker>
-        </el-col>
-        <el-col :span="2" class="line">——</el-col>
-        <el-col :span="11">
-          <el-time-picker placeholder="选择时间" style="width: 100%;" v-model="form.date2"></el-time-picker>
-        </el-col>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">即时配送</label></el-col>
-        <el-col  :span="10" :xs="14"><el-switch v-model="form.delivery"></el-switch></el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">活动性质</label></el-col>
-        <el-col  :span="10" :xs="14">
-          <el-checkbox-group v-model="form.type">
-            <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
-            <el-checkbox label="地推活动" name="type"></el-checkbox>
-            <el-checkbox label="线下主题活动" name="type"></el-checkbox>
-            <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
-          </el-checkbox-group>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">特殊资源</label></el-col>
-        <el-col  :span="10" :xs="14">
-          <el-radio-group v-model="form.resource">
-            <el-radio label="线上品牌商赞助"></el-radio>
-            <el-radio label="线下场地免费"></el-radio>
-          </el-radio-group>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">活动形式</label></el-col>
-        <el-col  :span="10" :xs="14"><el-input type="textarea" v-model="form.desc"></el-input></el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">穿梭框</label></el-col>
-        <el-col  :span="20" :xs="24">
-          <el-transfer
-            :data="data"
-            :filter-method="filterMethod"
-            filter-placeholder="请输入城市拼音"
-            filterable
-            v-model="value"
-          ></el-transfer>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col  :span="3" :xs="6"><label for="">活动时间</label></el-col>
-        <el-col  :span="10"><el-input v-model="form.name"></el-input></el-col>
-      </el-row>
-      <el-row type="flex" justify="center">
-        <el-col :span="13">
-          <el-button @click="onSubmit" type="primary">立即创建</el-button>
-          <el-button>取消</el-button>
-        </el-col>
-        
-      </el-row>
-
-      <!-- <el-form-item label="活动名称">
-        <el-input v-model="form.name"></el-input>
-      </el-form-item>
-      <el-form-item>
-        <el-select label="活动区域" placeholder="请选择活动区域" v-model="form.region">
-          <el-option label="上海" value="shanghai"></el-option>
-          <el-option label="北京" value="beijing"></el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="活动时间">
-        <el-col :span="11">
-          <el-date-picker placeholder="选择日期" style="width: 100%;" type="date" v-model="form.date1"></el-date-picker>
-        </el-col>
-        <el-col :span="2" class="line" style="text-align: center">——</el-col>
-        <el-col :span="11">
-          <el-time-picker placeholder="选择时间" style="width: 100%;" v-model="form.date2"></el-time-picker>
-        </el-col>
-      </el-form-item>
-      <el-form-item label="即时配送">
-        <el-switch v-model="form.delivery"></el-switch>
-      </el-form-item>
-      <el-form-item label="活动性质">
-        <el-checkbox-group v-model="form.type">
-          <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
-          <el-checkbox label="地推活动" name="type"></el-checkbox>
-          <el-checkbox label="线下主题活动" name="type"></el-checkbox>
-          <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
-        </el-checkbox-group>
-      </el-form-item>
-      <el-form-item label="特殊资源">
-        <el-radio-group v-model="form.resource">
-          <el-radio label="线上品牌商赞助"></el-radio>
-          <el-radio label="线下场地免费"></el-radio>
-        </el-radio-group>
-      </el-form-item>
-      <el-form-item label="活动形式">
-        <el-input type="textarea" v-model="form.desc"></el-input>
-      </el-form-item>
-      <el-form-item label="穿梭框">
-        <el-transfer
-          :data="data"
-          :filter-method="filterMethod"
-          filter-placeholder="请输入城市拼音"
-          filterable
-          v-model="value"
-        ></el-transfer>
-      </el-form-item>
-      <el-form-item>
-        <el-button @click="onSubmit" type="primary">立即创建</el-button>
-        <el-button>取消</el-button>
-      </el-form-item> -->
-    </el-form>
-  </div>
-</template>
-<script>
-export default {
-  data() {
-    const generateData = () => {
-      const data = []
-      const cities = ['上海', '北京', '广州', '深圳', '南京', '西安', '成都']
-      const pinyin = [
-        'shanghai',
-        'beijing',
-        'guangzhou',
-        'shenzhen',
-        'nanjing',
-        'xian',
-        'chengdu'
-      ]
-      cities.forEach((city, index) => {
-        data.push({
-          label: city,
-          key: index,
-          pinyin: pinyin[index]
-        })
-      })
-      return data
-    }
-    return {
-      form: {
-        name: '',
-        region: '',
-        date1: '',
-        date2: '',
-        delivery: false,
-        type: [],
-        resource: '',
-        desc: ''
-      },
-      data: generateData(),
-      value: [],
-     
-    }
-  },
-  methods: {
-       filterMethod(query, item) {
-        return item.pinyin.indexOf(query) > -1
-      },
-    onSubmit() {
-      this.$message({
-        message: '创建成功',
-        type: 'success'
-      })
-    }
-  }
-}
-</script>

+ 0 - 53
web/src/view/example/rte/rte.vue

@@ -1,53 +0,0 @@
-<template>
-  <div>
-    <h1>富文本编辑器</h1>
-    <div class="edit_container">
-      <quill-editor
-              :options="editorOption"
-              @blur="onEditorBlur($event)"
-              @change="onEditorChange($event)"
-              @focus="onEditorFocus($event)"
-              ref="myQuillEditor"
-              v-model="content"
-      ></quill-editor>
-      <el-button  plain @click="saveHtml">保存</el-button>
-    </div>
-    <h1>markdown编辑器</h1>
-    <div class="edit">
-      <mavon-editor v-model="model.content"></mavon-editor>
-      <el-button type="primary" size="small" @click="submit">发表</el-button>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'App',
-  data() {
-    return {
-      content: `<p>hello world</p>`,
-      editorOption: {},
-      model:{
-        content:''
-      }
-    }
-  },
-  computed: {
-    editor() {
-      return this.$refs.myQuillEditor.quill
-    }
-  },
-  methods: {
-    // onEditorReady(editor) { // 准备编辑器
-
-    // },
-    onEditorBlur() {}, // 失去焦点事件
-    onEditorFocus() {}, // 获得焦点事件
-    onEditorChange() {}, // 内容改变事件
-    saveHtml() {
-      console.log(this.content)
-    }, // 保存方法
-    submit(){}
-  }
-}
-</script>

+ 0 - 115
web/src/view/example/table/table.vue

@@ -1,115 +0,0 @@
-// table 纯前端示例
-<template>
-  <div>
-    <el-table
-      :data="tableData"
-      @selection-change="handleSelectionChange"
-      border
-      ref="multipleTable"
-      stripe
-      style="width: 100%"
-      tooltip-effect="dark"
-    >
-      <el-table-column type="selection" width="55"></el-table-column>
-      <el-table-column label="日期" width="120">
-        <template slot-scope="scope">{{ scope.row.date }}</template>
-      </el-table-column>
-      <el-table-column label="姓名" prop="name" width="120"></el-table-column>
-      <el-table-column label="年龄" prop="age" width="120"></el-table-column>
-      <el-table-column label="住址" prop="address" min-width="200" show-overflow-tooltip></el-table-column>
-      <el-table-column label="是否禁用" prop="switch" width="180">
-        <template slot-scope="scope">
-          <el-switch active-text="开启" inactive-text="禁用" v-model="scope.row.switch"></el-switch>
-        </template>
-      </el-table-column>
-      <el-table-column label="按钮组" width="200">
-        <template slot-scope="scope" >
-            <el-button type="text" size="small" @click="toggleSelection([scope.row])">按钮1</el-button>
-            <el-button type="text" size="small" @click="toggleSelection([scope.row])">按钮2</el-button>
-            <el-button type="text" size="small" @click="toggleSelection([scope.row])">按钮3</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div style="margin-top: 20px">
-      <el-button @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button>
-      <el-button @click="toggleSelection()">取消选择</el-button>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'Table',
-  data() {
-    return {
-      tableData: [
-        {
-          date: '2016-05-03',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:true
-        },
-        {
-          date: '2016-05-02',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:true
-        },
-        {
-          date: '2016-05-04',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:true
-        },
-        {
-          date: '2016-05-01',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:false
-        },
-        {
-          date: '2016-05-08',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:true
-        },
-        {
-          date: '2016-05-06',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:true
-        },
-        {
-          date: '2016-05-07',
-          name: '王小虎',
-          age: 12,
-          address: '上海市普陀区金沙江路 1518 弄',
-          switch:false
-        }
-      ],
-      multipleSelection: []
-    }
-  },
-
-  methods: {
-    toggleSelection(rows) {
-      if (rows) {
-        rows.forEach(row => {
-          this.$refs.multipleTable.toggleRowSelection(row)
-        })
-      } else {
-        this.$refs.multipleTable.clearSelection()
-      }
-    },
-    handleSelectionChange(val) {
-      this.multipleSelection = val
-    }
-  }
-}
-</script>

+ 13 - 19
web/src/view/login/login.vue

@@ -20,14 +20,9 @@
           @keyup.enter.native="submitForm"
         >
           <el-form-item prop="username">
-            <el-input
-              placeholder="请输入用户名"
-              v-model="loginForm.username"
-            >
-            <i
-                class="el-input__icon el-icon-user"
-                slot="suffix"
-              ></i></el-input>
+            <el-input placeholder="请输入用户名" v-model="loginForm.username">
+              <i class="el-input__icon el-icon-user" slot="suffix"></i
+            ></el-input>
           </el-form-item>
           <el-form-item prop="password">
             <el-input
@@ -42,12 +37,12 @@
               ></i>
             </el-input>
           </el-form-item>
-          <el-form-item style="position:relative">
+          <el-form-item style="position: relative">
             <el-input
               v-model="loginForm.captcha"
               name="logVerify"
               placeholder="请输入验证码"
-              style="width:60%"
+              style="width: 60%"
             />
             <div class="vPic">
               <img
@@ -61,7 +56,7 @@
             </div>
           </el-form-item>
           <el-form-item>
-            <el-button type="primary" @click="submitForm" style="width:100%"
+            <el-button type="primary" @click="submitForm" style="width: 100%"
               >登 录</el-button
             >
           </el-form-item>
@@ -83,9 +78,7 @@
             ><img src="@/assets/video.png" class="link-icon"
           /></a>
         </div>
-        <div class="copyright">
-          Copyright &copy; {{ curYear }} 💖flipped-aurora
-        </div>
+        <div class="copyright">Copyright &copy; {{ curYear }} 💖flipped-aurora</div>
       </div>
     </div>
   </div>
@@ -135,13 +128,15 @@ export default {
   methods: {
     ...mapActions("user", ["LoginIn"]),
     async login() {
-      await this.LoginIn(this.loginForm);
+      return await this.LoginIn(this.loginForm);
     },
     async submitForm() {
       this.$refs.loginForm.validate(async (v) => {
         if (v) {
-          this.login();
-          this.loginVefify();
+          const flag = await this.login();
+          if (!flag) {
+            this.loginVefify();
+          }
         } else {
           this.$message({
             type: "error",
@@ -167,6 +162,5 @@ export default {
 </script>
 
 <style scoped lang="scss">
-@import '@/style/login.scss';
-
+@import "@/style/login.scss";
 </style>

+ 29 - 11
web/src/view/person/person.vue

@@ -4,13 +4,11 @@
       <el-col :span="6">
         <div class="fl-left avatar-box">
           <div class="user-card">
-            <el-avatar
-              class="user-avatar"
-              :size="160"
-              :src="userInfo.headerImg"
-              shape="square"
-              @click.native="openChooseImg"
-            ></el-avatar>
+              <div class="user-headpic-update" :style="{ 'background-image': 'url(' + userInfo.headerImg + ')','background-repeat':'no-repeat','background-size':'cover' }" >
+              <span class="update" @click="openChooseImg">
+                <i class="el-icon-edit"></i>
+                重新上传</span>
+              </div>
             <div class="user-personality">
               <p class="nickname">{{userInfo.nickName}}</p>
               <p class="person-info">这个家伙很懒,什么都没有留下</p>
@@ -18,7 +16,7 @@
             <div class="user-information">
               <ul>
                 <li>
-                  <i class="el-icon-user"></i>资深前端工程师
+                   <i class="el-icon-user"></i>{{userInfo.nickName}}
                 </li>
                 <li>
                   <i class="el-icon-data-analysis"></i>北京反转极光科技有限公司-技术部-前端事业群
@@ -216,9 +214,6 @@ export default {
   box-shadow: -2px 0 20px -16px;
   width: 80%;
   height: 100%;
-  .user-avatar{
-    cursor: pointer;
-  }
   .user-card {
     min-height: calc(90vh - 200px);
     padding: 30px 20px;
@@ -282,4 +277,27 @@ export default {
     }
   }
 }
+.user-headpic-update{
+    width: 120px;
+    height: 120px;
+    line-height: 120px;
+    margin: 0 auto;
+    display: flex;
+    justify-content: center;
+    border-radius: 20px;
+     &:hover{
+      color: #fff;
+      background: linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
+      background-blend-mode: multiply,multiply;
+      .update{
+        color:#fff ;
+      }
+    }
+    .update{
+      height: 120px;
+      width: 120px;
+      text-align: center;
+      color:transparent;
+    }
+  }
 </style>

+ 0 - 1
web/src/view/superAdmin/user/user.vue

@@ -69,7 +69,6 @@
         </el-form-item>
         <el-form-item label="用户角色" label-width="80px" prop="authorityId">
           <el-cascader
-            @change="changeAuthority(scope.row)"
             v-model="userInfo.authorityId"
             :options="authOptions"
             :show-all-levels="false"