Browse Source

Merge branch 'gin-vue-admin_v2_dev' of https://github.com/piexlmax/QMPlus into gin-vue-admin_v2_dev

pixel 4 years ago
parent
commit
1d44c230f4
77 changed files with 5035 additions and 885 deletions
  1. 1 1
      README-zh_CN.md
  2. 1 1
      README.md
  3. 66 1
      server/api/v1/sys_auto_code.go
  4. 17 18
      server/api/v1/sys_captcha.go
  5. 111 0
      server/api/v1/sys_dictionary.go
  6. 111 0
      server/api/v1/sys_dictionary_detail.go
  7. 130 0
      server/api/v1/sys_operation_record.go
  8. 1 2
      server/api/v1/sys_user.go
  9. 6 3
      server/config.yaml
  10. 9 9
      server/config/config.go
  11. 26 0
      server/core/install_plugs.go
  12. 12 12
      server/core/log.go
  13. 7 14
      server/core/server.go
  14. 17 0
      server/core/server_other.go
  15. 19 0
      server/core/server_win.go
  16. 97 0
      server/db/20200708_update_patch.sql
  17. 230 153
      server/db/qmplus.sql
  18. 699 114
      server/docs/docs.go
  19. 698 113
      server/docs/swagger.json
  20. 510 10
      server/docs/swagger.yaml
  21. 6 6
      server/go.mod
  22. 3 0
      server/initialize/db_table.go
  23. 9 11
      server/initialize/plug.go
  24. 3 0
      server/initialize/router.go
  25. 68 0
      server/middleware/operation.go
  26. 4 0
      server/model/request/common.go
  27. 16 0
      server/model/request/sys_autocode.go
  28. 8 0
      server/model/request/sys_dictionary.go
  29. 8 0
      server/model/request/sys_dictionary_detail.go
  30. 8 0
      server/model/request/sys_operation_record.go
  31. 3 0
      server/model/sys_auto_code.go
  32. 16 0
      server/model/sys_dictionary.go
  33. 16 0
      server/model/sys_dictionary_detail.go
  34. 23 0
      server/model/sys_operation_record.go
  35. 16 0
      server/resource/template/fe/api.js.tpl
  36. 71 9
      server/resource/template/fe/table.vue.tpl
  37. 19 0
      server/resource/template/te/api.go.tpl
  38. 12 2
      server/resource/template/te/model.go.tpl
  39. 2 1
      server/resource/template/te/router.go.tpl
  40. 14 3
      server/resource/template/te/service.go.tpl
  41. 4 1
      server/router/exp_customer.go
  42. 4 1
      server/router/sys_authority.go
  43. 7 1
      server/router/sys_auto_code.go
  44. 0 1
      server/router/sys_base.go
  45. 4 1
      server/router/sys_casbin.go
  46. 21 0
      server/router/sys_dictionary.go
  47. 21 0
      server/router/sys_dictionary_detail.go
  48. 22 0
      server/router/sys_operation_record.go
  49. 4 1
      server/router/sys_user.go
  50. 2 2
      server/service/exa_customer.go
  51. 2 2
      server/service/sys_api.go
  52. 17 0
      server/service/sys_auto_code.go
  53. 102 0
      server/service/sys_dictionary.go
  54. 82 0
      server/service/sys_dictionary_detail.go
  55. 90 0
      server/service/sys_operation_record.go
  56. 2 3
      server/service/sys_user.go
  57. 0 55
      server/utils/captcha.go
  58. 4 22
      server/utils/directory.go
  59. 2 2
      server/utils/upload.go
  60. 47 0
      web/src/api/autoCode.js
  61. 84 0
      web/src/api/sysDictionary.js
  62. 84 0
      web/src/api/sysDictionaryDetail.js
  63. 49 0
      web/src/api/sysOperationRecord.js
  64. 3 2
      web/src/store/index.js
  65. 42 0
      web/src/store/module/dictionary.js
  66. 6 0
      web/src/utils/dictionary.js
  67. 9 7
      web/src/utils/request.js
  68. 8 1
      web/src/utils/stringFun.js
  69. 77 78
      web/src/view/layout/screenfull/index.vue
  70. 3 3
      web/src/view/login/login.vue
  71. 128 113
      web/src/view/superAdmin/authority/authority.vue
  72. 250 0
      web/src/view/superAdmin/dictionary/sysDictionary.vue
  73. 256 0
      web/src/view/superAdmin/dictionary/sysDictionaryDetail.vue
  74. 227 0
      web/src/view/superAdmin/operation/sysOperationRecord.vue
  75. 33 2
      web/src/view/systemTools/autoCode/component/fieldDialog.vue
  76. 245 103
      web/src/view/systemTools/autoCode/index.vue
  77. 1 1
      web/src/view/systemTools/system/system.vue

+ 1 - 1
README-zh_CN.md

@@ -145,7 +145,7 @@ swag init
 ## 4. 项目架构
 ### 4.1 系统架构图
 
-![系统架构图](./docs/gin-vue-admin.png)
+![系统架构图](http://qmplusimg.henrongyi.top/gva/gin-vue-admin.png)
 
 ### 4.2 前端详细设计图 (提供者:<a href="https://github.com/baobeisuper">baobeisuper</a>)
 

+ 1 - 1
README.md

@@ -146,7 +146,7 @@ After executing the above command,`docs` will show in `server/`,then open yo
 
 ### 4.1 Architecture Diagram
 
-![Architecture diagram](./docs/gin-vue-admin.png)
+![Architecture diagram](http://qmplusimg.henrongyi.top/gva/gin-vue-admin.png)
 
 ### 4.2 Front-end Detailed Design Diagram (Contributor: <a href="https://github.com/baobeisuper">baobeisuper</a>)
 

+ 66 - 1
server/api/v1/sys_auto_code.go

@@ -2,6 +2,7 @@ package v1
 
 import (
 	"fmt"
+	"gin-vue-admin/global"
 	"gin-vue-admin/global/response"
 	"gin-vue-admin/model"
 	"gin-vue-admin/service"
@@ -34,7 +35,7 @@ func CreateTemp(c *gin.Context) {
 		return
 	}
 	if a.AutoCreateApiToSql {
-		apiList := [5]model.SysApi{
+		apiList := [6]model.SysApi{
 			{
 				Path:        "/" + a.Abbreviation + "/" + "create" + a.StructName,
 				Description: "新增" + a.Description,
@@ -47,6 +48,12 @@ func CreateTemp(c *gin.Context) {
 				ApiGroup:    a.Abbreviation,
 				Method:      "DELETE",
 			},
+			{
+				Path:        "/" + a.Abbreviation + "/" + "delete" + a.StructName+"ByIds",
+				Description: "批量删除" + a.Description,
+				ApiGroup:    a.Abbreviation,
+				Method:      "DELETE",
+			},
 			{
 				Path:        "/" + a.Abbreviation + "/" + "update" + a.StructName,
 				Description: "更新" + a.Description,
@@ -87,3 +94,61 @@ func CreateTemp(c *gin.Context) {
 		os.Remove("./ginvueadmin.zip")
 	}
 }
+
+// @Tags SysApi
+// @Summary 获取当前数据库所有表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getTables [get]
+
+func GetTables(c *gin.Context) {
+	dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
+	err, tables := service.GetTables(dbName)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("查询table失败,%v", err), c)
+	} else {
+		response.OkWithData(gin.H{
+			"tables": tables,
+		}, c)
+	}
+}
+
+// @Tags SysApi
+// @Summary 获取当前所有数据库
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getDatabase [get]
+func GetDB(c *gin.Context) {
+	err, dbs := service.GetDB()
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("查询table失败,%v", err), c)
+	} else {
+		response.OkWithData(gin.H{
+			"dbs": dbs,
+		}, c)
+	}
+}
+
+// @Tags SysApi
+// @Summary 获取当前表所有字段
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getDatabase [get]
+func GetColume(c *gin.Context) {
+	dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
+	tableName := c.Query("tableName")
+	err, columes := service.GetColume(tableName, dbName)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("查询table失败,%v", err), c)
+	} else {
+		response.OkWithData(gin.H{
+			"columes": columes,
+		}, c)
+	}
+}

+ 17 - 18
server/api/v1/sys_captcha.go

@@ -1,14 +1,16 @@
 package v1
 
 import (
+	"fmt"
 	"gin-vue-admin/global"
 	"gin-vue-admin/global/response"
 	resp "gin-vue-admin/model/response"
-	"gin-vue-admin/utils"
-	"github.com/dchest/captcha"
 	"github.com/gin-gonic/gin"
+	"github.com/mojocn/base64Captcha"
 )
 
+var store = base64Captcha.DefaultMemStore
+
 // @Tags base
 // @Summary 生成验证码
 // @Security ApiKeyAuth
@@ -17,20 +19,17 @@ import (
 // @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
 // @Router /base/captcha [post]
 func Captcha(c *gin.Context) {
-	captchaId := captcha.NewLen(global.GVA_CONFIG.Captcha.KeyLong)
-	response.OkDetailed(resp.SysCaptchaResponse{
-		CaptchaId: captchaId,
-		PicPath:   "/base/captcha/" + captchaId + ".png",
-	}, "验证码获取成功", c)
-}
-
-// @Tags base
-// @Summary 生成验证码图片路径
-// @Security ApiKeyAuth
-// @accept application/json
-// @Produce application/json
-// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
-// @Router /base/captcha/:captchaId [get]
-func CaptchaImg(c *gin.Context) {
-	utils.GinCaptchaServeHTTP(c.Writer, c.Request)
+	//字符,公式,验证码配置
+	// 生成默认数字的driver
+	driver := base64Captcha.NewDriverDigit(global.GVA_CONFIG.Captcha.ImgHeight, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.KeyLong, 0.7, 80)
+	cp := base64Captcha.NewCaptcha(driver, store)
+	id, b64s, err := cp.Generate()
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
+	} else {
+		response.OkDetailed(resp.SysCaptchaResponse{
+			CaptchaId: id,
+			PicPath:   b64s,
+		}, "验证码获取成功", c)
+	}
 }

+ 111 - 0
server/api/v1/sys_dictionary.go

@@ -0,0 +1,111 @@
+package v1
+
+import (
+	"fmt"
+	"gin-vue-admin/global/response"
+	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
+	resp "gin-vue-admin/model/response"
+	"gin-vue-admin/service"
+	"github.com/gin-gonic/gin"
+)
+
+// @Tags SysDictionary
+// @Summary 创建SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "创建SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionary/createSysDictionary [post]
+func CreateSysDictionary(c *gin.Context) {
+	var sysDictionary model.SysDictionary
+	_ = c.ShouldBindJSON(&sysDictionary)
+	err := service.CreateSysDictionary(sysDictionary)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("创建失败,%v", err), c)
+	} else {
+		response.OkWithMessage("创建成功", c)
+	}
+}
+
+// @Tags SysDictionary
+// @Summary 删除SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "删除SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysDictionary/deleteSysDictionary [delete]
+func DeleteSysDictionary(c *gin.Context) {
+	var sysDictionary model.SysDictionary
+	_ = c.ShouldBindJSON(&sysDictionary)
+	err := service.DeleteSysDictionary(sysDictionary)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+// @Tags SysDictionary
+// @Summary 更新SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "更新SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysDictionary/updateSysDictionary [put]
+func UpdateSysDictionary(c *gin.Context) {
+	var sysDictionary model.SysDictionary
+	_ = c.ShouldBindJSON(&sysDictionary)
+	err := service.UpdateSysDictionary(&sysDictionary)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("更新失败,%v", err), c)
+	} else {
+		response.OkWithMessage("更新成功", c)
+	}
+}
+
+// @Tags SysDictionary
+// @Summary 用id查询SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "用id查询SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysDictionary/findSysDictionary [get]
+func FindSysDictionary(c *gin.Context) {
+	var sysDictionary model.SysDictionary
+	_ = c.ShouldBindQuery(&sysDictionary)
+	err, resysDictionary := service.GetSysDictionary(sysDictionary.Type, sysDictionary.ID)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("查询失败,%v", err), c)
+	} else {
+		response.OkWithData(gin.H{"resysDictionary": resysDictionary}, c)
+	}
+}
+
+// @Tags SysDictionary
+// @Summary 分页获取SysDictionary列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.SysDictionarySearch true "分页获取SysDictionary列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionary/getSysDictionaryList [get]
+func GetSysDictionaryList(c *gin.Context) {
+	var pageInfo request.SysDictionarySearch
+	_ = c.ShouldBindQuery(&pageInfo)
+	err, list, total := service.GetSysDictionaryInfoList(pageInfo)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
+	} else {
+		response.OkWithData(resp.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     pageInfo.Page,
+			PageSize: pageInfo.PageSize,
+		}, c)
+	}
+}

+ 111 - 0
server/api/v1/sys_dictionary_detail.go

@@ -0,0 +1,111 @@
+package v1
+
+import (
+	"fmt"
+	"gin-vue-admin/global/response"
+	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
+	resp "gin-vue-admin/model/response"
+	"gin-vue-admin/service"
+	"github.com/gin-gonic/gin"
+)
+
+// @Tags SysDictionaryDetail
+// @Summary 创建SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "创建SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
+func CreateSysDictionaryDetail(c *gin.Context) {
+	var sysDictionaryDetail model.SysDictionaryDetail
+	_ = c.ShouldBindJSON(&sysDictionaryDetail)
+	err := service.CreateSysDictionaryDetail(sysDictionaryDetail)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("创建失败,%v", err), c)
+	} else {
+		response.OkWithMessage("创建成功", c)
+	}
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 删除SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "删除SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
+func DeleteSysDictionaryDetail(c *gin.Context) {
+	var sysDictionaryDetail model.SysDictionaryDetail
+	_ = c.ShouldBindJSON(&sysDictionaryDetail)
+	err := service.DeleteSysDictionaryDetail(sysDictionaryDetail)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 更新SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
+func UpdateSysDictionaryDetail(c *gin.Context) {
+	var sysDictionaryDetail model.SysDictionaryDetail
+	_ = c.ShouldBindJSON(&sysDictionaryDetail)
+	err := service.UpdateSysDictionaryDetail(&sysDictionaryDetail)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("更新失败,%v", err), c)
+	} else {
+		response.OkWithMessage("更新成功", c)
+	}
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 用id查询SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
+func FindSysDictionaryDetail(c *gin.Context) {
+	var sysDictionaryDetail model.SysDictionaryDetail
+	_ = c.ShouldBindQuery(&sysDictionaryDetail)
+	err, resysDictionaryDetail := service.GetSysDictionaryDetail(sysDictionaryDetail.ID)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("查询失败,%v", err), c)
+	} else {
+		response.OkWithData(gin.H{"resysDictionaryDetail": resysDictionaryDetail}, c)
+	}
+}
+
+// @Tags SysDictionaryDetail
+// @Summary 分页获取SysDictionaryDetail列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.SysDictionaryDetailSearch true "分页获取SysDictionaryDetail列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
+func GetSysDictionaryDetailList(c *gin.Context) {
+	var pageInfo request.SysDictionaryDetailSearch
+	_ = c.ShouldBindQuery(&pageInfo)
+	err, list, total := service.GetSysDictionaryDetailInfoList(pageInfo)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
+	} else {
+		response.OkWithData(resp.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     pageInfo.Page,
+			PageSize: pageInfo.PageSize,
+		}, c)
+	}
+}

+ 130 - 0
server/api/v1/sys_operation_record.go

@@ -0,0 +1,130 @@
+package v1
+
+import (
+	"fmt"
+	"gin-vue-admin/global/response"
+	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
+	resp "gin-vue-admin/model/response"
+	"gin-vue-admin/service"
+	"github.com/gin-gonic/gin"
+)
+
+// @Tags SysOperationRecord
+// @Summary 创建SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysOperationRecord true "创建SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysOperationRecord/createSysOperationRecord [post]
+func CreateSysOperationRecord(c *gin.Context) {
+	var sysOperationRecord model.SysOperationRecord
+	_ = c.ShouldBindJSON(&sysOperationRecord)
+	err := service.CreateSysOperationRecord(sysOperationRecord)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("创建失败,%v", err), c)
+	} else {
+		response.OkWithMessage("创建成功", c)
+	}
+}
+
+// @Tags SysOperationRecord
+// @Summary 删除SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysOperationRecord true "删除SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
+func DeleteSysOperationRecord(c *gin.Context) {
+	var sysOperationRecord model.SysOperationRecord
+	_ = c.ShouldBindJSON(&sysOperationRecord)
+	err := service.DeleteSysOperationRecord(sysOperationRecord)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+// @Tags SysOperationRecord
+// @Summary 批量删除SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysOperationRecord/deleteSysOperationRecordByIds [delete]
+func DeleteSysOperationRecordByIds(c *gin.Context) {
+	var IDS request.IdsReq
+	_ = c.ShouldBindJSON(&IDS)
+	err := service.DeleteSysOperationRecordByIds(IDS)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
+// @Tags SysOperationRecord
+// @Summary 更新SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysOperationRecord true "更新SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysOperationRecord/updateSysOperationRecord [put]
+func UpdateSysOperationRecord(c *gin.Context) {
+	var sysOperationRecord model.SysOperationRecord
+	_ = c.ShouldBindJSON(&sysOperationRecord)
+	err := service.UpdateSysOperationRecord(&sysOperationRecord)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("更新失败,%v", err), c)
+	} else {
+		response.OkWithMessage("更新成功", c)
+	}
+}
+
+// @Tags SysOperationRecord
+// @Summary 用id查询SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysOperationRecord true "用id查询SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysOperationRecord/findSysOperationRecord [get]
+func FindSysOperationRecord(c *gin.Context) {
+	var sysOperationRecord model.SysOperationRecord
+	_ = c.ShouldBindQuery(&sysOperationRecord)
+	err, resysOperationRecord := service.GetSysOperationRecord(sysOperationRecord.ID)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("查询失败,%v", err), c)
+	} else {
+		response.OkWithData(gin.H{"resysOperationRecord": resysOperationRecord}, c)
+	}
+}
+
+// @Tags SysOperationRecord
+// @Summary 分页获取SysOperationRecord列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.SysOperationRecordSearch true "分页获取SysOperationRecord列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysOperationRecord/getSysOperationRecordList [get]
+func GetSysOperationRecordList(c *gin.Context) {
+	var pageInfo request.SysOperationRecordSearch
+	_ = c.ShouldBindQuery(&pageInfo)
+	err, list, total := service.GetSysOperationRecordInfoList(pageInfo)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
+	} else {
+		response.OkWithData(resp.PageResult{
+			List:     list,
+			Total:    total,
+			Page:     pageInfo.Page,
+			PageSize: pageInfo.PageSize,
+		}, c)
+	}
+}

+ 1 - 2
server/api/v1/sys_user.go

@@ -10,7 +10,6 @@ import (
 	resp "gin-vue-admin/model/response"
 	"gin-vue-admin/service"
 	"gin-vue-admin/utils"
-	"github.com/dchest/captcha"
 	"github.com/dgrijalva/jwt-go"
 	"github.com/gin-gonic/gin"
 	"github.com/go-redis/redis"
@@ -67,7 +66,7 @@ func Login(c *gin.Context) {
 		response.FailWithMessage(UserVerifyErr.Error(), c)
 		return
 	}
-	if captcha.VerifyString(L.CaptchaId, L.Captcha) {
+	if store.Verify(L.CaptchaId, L.Captcha, true) {
 		U := &model.SysUser{Username: L.Username, Password: L.Password}
 		if err, user := service.Login(U); err != nil {
 			response.FailWithMessage(fmt.Sprintf("用户名密码错误或%v", err), c)

+ 6 - 3
server/config.yaml

@@ -26,11 +26,14 @@ sqlite:
     config: 'loc=Asia/Shanghai'
 
 # oss configuration
+
+# 请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址
 qiniu:
     access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
     secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
     bucket: 'qm-plus-img'
     img-path: 'http://qmplusimg.henrongyi.top'
+
 # redis configuration
 redis:
     addr: '127.0.0.1:6379'
@@ -46,9 +49,9 @@ system:
 
 # captcha configuration
 captcha:
-    key-long: 4
-    img-width: 120
-    img-height: 40
+    key-long: 6
+    img-width: 240
+    img-height: 80
 
 # logger configuration
 log:

+ 9 - 9
server/config/config.go

@@ -1,15 +1,15 @@
 package config
 
 type Server struct {
-	Mysql   Mysql   `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
-	Sqlite  Sqlite  `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
-	Qiniu   Qiniu   `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
-	Casbin  Casbin  `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
-	Redis   Redis   `mapstructure:"redis" json:"redis" yaml:"redis"`
-	System  System  `mapstructure:"system" json:"system" yaml:"system"`
-	JWT     JWT     `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
-	Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
-	Log     Log     `mapstructure:"log" json:"log" yaml:"log"`
+	Mysql     Mysql     `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
+	Sqlite    Sqlite    `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
+	Qiniu     Qiniu     `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
+	Casbin    Casbin    `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
+	Redis     Redis     `mapstructure:"redis" json:"redis" yaml:"redis"`
+	System    System    `mapstructure:"system" json:"system" yaml:"system"`
+	JWT       JWT       `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
+	Captcha   Captcha   `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
+	Log       Log       `mapstructure:"log" json:"log" yaml:"log"`
 }
 
 type System struct {

+ 26 - 0
server/core/install_plugs.go

@@ -0,0 +1,26 @@
+package core
+
+import (
+	"fmt"
+	"gin-vue-admin/global"
+	"gin-vue-admin/initialize"
+	"gin-vue-admin/middleware"
+	"github.com/gin-gonic/gin"
+	"github.com/piexlmax/gvaplug"
+)
+
+func InstallPlugs(route *gin.Engine) {
+	GvaPlugsGroupBase := route.Group("") // 纯净路由 插件可通用 传递给插件的0号位置 为了不让插件的自动路由出问题 这里建议为 ""
+	/**安装一个插件需要的步骤 start**/
+	GvaPlugsGroupMiddle := route.Group("") // 携带中间件的路由 传递给插件的1号位置 为了不让插件的自动路由出问题 这里建议为 ""
+	GvaPlugsGroupMiddle.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	// 插件安装 暂时只是后台功能 添加model 添加路由 添加对数据库的操作  详细插件测试模板可看https://github.com/piexlmax/gvaplug  此处不建议投入生产
+	err := initialize.InstallPlug(global.GVA_DB, [2]*gin.RouterGroup{
+		GvaPlugsGroupBase,
+		GvaPlugsGroupMiddle,
+	}, gvaplug.GvaPlug{SomeConfig: "插件给用户提供的配置区域"})
+	if err != nil {
+		panic(fmt.Sprintf("插件安装失败: %v", err))
+	}
+	/**安装一个插件需要的步骤 end**/
+}

+ 12 - 12
server/core/log.go

@@ -5,6 +5,7 @@ import (
 	"gin-vue-admin/config"
 	"gin-vue-admin/global"
 	"gin-vue-admin/utils"
+	"github.com/gin-gonic/gin"
 	rotatelogs "github.com/lestrrat/go-file-rotatelogs"
 	oplogging "github.com/op/go-logging"
 	"io"
@@ -30,26 +31,25 @@ func init() {
 	}
 	logger := oplogging.MustGetLogger(module)
 	var backends []oplogging.Backend
-	backends = registerStdout(c, backends)
-	backends = registerFile(c, backends)
-
+	registerStdout(c, &backends)
+	if fileWriter := registerFile(c, &backends); fileWriter != nil {
+		gin.DefaultWriter = io.MultiWriter(fileWriter, os.Stdout)
+	}
 	oplogging.SetBackend(backends...)
 	global.GVA_LOG = logger
 }
 
-func registerStdout(c config.Log, backends []oplogging.Backend) []oplogging.Backend {
+func registerStdout(c config.Log, backends *[]oplogging.Backend) {
 	if c.Stdout != "" {
 		level, err := oplogging.LogLevel(c.Stdout)
 		if err != nil {
 			fmt.Println(err)
 		}
-		backends = append(backends, createBackend(os.Stdout, c, level))
+		*backends = append(*backends, createBackend(os.Stdout, c, level))
 	}
-
-	return backends
 }
 
-func registerFile(c config.Log, backends []oplogging.Backend) []oplogging.Backend {
+func registerFile(c config.Log, backends *[]oplogging.Backend) io.Writer {
 	if c.File != "" {
 		if ok, _ := utils.PathExists(logDir); !ok {
 			// directory not exist
@@ -67,16 +67,16 @@ func registerFile(c config.Log, backends []oplogging.Backend) []oplogging.Backen
 		)
 		if err != nil {
 			fmt.Println(err)
-			return backends
 		}
 		level, err := oplogging.LogLevel(c.File)
 		if err != nil {
 			fmt.Println(err)
 		}
-		backends = append(backends, createBackend(fileWriter, c, level))
-	}
+		*backends = append(*backends, createBackend(fileWriter, c, level))
 
-	return backends
+		return fileWriter
+	}
+	return nil
 }
 
 func createBackend(w io.Writer, c config.Log, level oplogging.Level) oplogging.Backend {

+ 7 - 14
server/core/server.go

@@ -4,10 +4,13 @@ import (
 	"fmt"
 	"gin-vue-admin/global"
 	"gin-vue-admin/initialize"
-	"net/http"
 	"time"
 )
 
+type server interface {
+	ListenAndServe() error
+}
+
 func RunWindowsServer() {
 	if global.GVA_CONFIG.System.UseMultipoint {
 		// 初始化redis服务
@@ -16,21 +19,11 @@ func RunWindowsServer() {
 	Router := initialize.Routers()
 	Router.Static("/form-generator", "./resource/page")
 
-	// 插件安装 暂时只是后台功能 添加model 添加路由 添加对数据库的操作  详细插件测试模板可看https://github.com/piexlmax/gvaplug  此处不建议投入生产
-	//err := initialize.InstallPlug(global.GVA_DB, Router, gvaplug.GvaPlug{})
-	//if err != nil {
-	//	panic(fmt.Sprintf("插件安装失败: %v", err))
-	//}
+	//InstallPlugs(Router)
 	// end 插件描述
 
 	address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
-	s := &http.Server{
-		Addr:           address,
-		Handler:        Router,
-		ReadTimeout:    10 * time.Second,
-		WriteTimeout:   10 * time.Second,
-		MaxHeaderBytes: 1 << 20,
-	}
+	s := initServer(address, Router)
 	// 保证文本顺序输出
 	// In order to ensure that the text order output can be deleted
 	time.Sleep(10 * time.Microsecond)
@@ -39,6 +32,6 @@ func RunWindowsServer() {
 	fmt.Printf(`欢迎使用 Gin-Vue-Admin
 	默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
 	默认前端文件运行地址:http://127.0.0.1:8080
-`, s.Addr)
+`, address)
 	global.GVA_LOG.Error(s.ListenAndServe())
 }

+ 17 - 0
server/core/server_other.go

@@ -0,0 +1,17 @@
+// +build !windows
+
+package core
+
+import (
+	"github.com/fvbock/endless"
+	"github.com/gin-gonic/gin"
+	"time"
+)
+
+func initServer(address string, router *gin.Engine) server {
+	s := endless.NewServer(address, router)
+	s.ReadHeaderTimeout = 10 * time.Millisecond
+	s.WriteTimeout = 10 * time.Second
+	s.MaxHeaderBytes = 1 << 20
+	return s
+}

+ 19 - 0
server/core/server_win.go

@@ -0,0 +1,19 @@
+// +build windows
+
+package core
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"time"
+)
+
+func initServer(address string, router *gin.Engine) server {
+	return &http.Server{
+		Addr:           address,
+		Handler:        router,
+		ReadTimeout:    10 * time.Second,
+		WriteTimeout:   10 * time.Second,
+		MaxHeaderBytes: 1 << 20,
+	}
+}

+ 97 - 0
server/db/20200708_update_patch.sql

@@ -0,0 +1,97 @@
+INSERT INTO `sys_base_menus` VALUES (52, '2020-06-29 13:31:17', '2020-07-07 16:05:34', NULL, 0, 3, 'operation', 'operation', 0, 'view/superAdmin/operation/sysOperationRecord.vue', '操作历史', 'time', NULL, 6, 0, 0);
+
+
+INSERT INTO `sys_dictionaries` VALUES (3, '2020-07-05 15:27:31', '2020-07-05 15:27:31', NULL, '数据库int类型', 'int', 1, 'int类型对应的数据库类型');
+INSERT INTO `sys_dictionaries` VALUES (4, '2020-07-05 15:33:07', '2020-07-05 16:07:18', NULL, '数据库时间日期类型', 'time.Time', 1, '数据库时间日期类型');
+INSERT INTO `sys_dictionaries` VALUES (5, '2020-07-05 15:34:23', '2020-07-05 15:52:45', NULL, '数据库浮点型', 'float64', 1, '数据库浮点型');
+INSERT INTO `sys_dictionaries` VALUES (6, '2020-07-05 15:35:05', '2020-07-05 15:35:05', NULL, '数据库字符串', 'string', 1, '数据库字符串');
+INSERT INTO `sys_dictionaries` VALUES (7, '2020-07-05 15:36:48', '2020-07-05 15:36:48', NULL, '数据库bool类型', 'bool', 1, '数据库bool类型');
+
+
+INSERT INTO `sys_dictionary_details` VALUES (12, '2020-07-05 15:31:41', '2020-07-05 15:31:41', NULL, 'smallint', 1, 1, 1, 3);
+INSERT INTO `sys_dictionary_details` VALUES (13, '2020-07-05 15:31:52', '2020-07-05 15:31:52', NULL, 'mediumint', 2, 1, 2, 3);
+INSERT INTO `sys_dictionary_details` VALUES (14, '2020-07-05 15:32:04', '2020-07-05 15:32:04', NULL, 'int', 3, 1, 3, 3);
+INSERT INTO `sys_dictionary_details` VALUES (15, '2020-07-05 15:32:11', '2020-07-05 15:32:11', NULL, 'bigint', 4, 1, 4, 3);
+INSERT INTO `sys_dictionary_details` VALUES (19, '2020-07-05 15:33:16', '2020-07-05 15:33:16', NULL, 'data', 0, 1, 0, 4);
+INSERT INTO `sys_dictionary_details` VALUES (20, '2020-07-05 15:33:21', '2020-07-05 15:33:21', NULL, 'time', 1, 1, 1, 4);
+INSERT INTO `sys_dictionary_details` VALUES (21, '2020-07-05 15:33:25', '2020-07-05 15:33:25', NULL, 'year', 2, 1, 2, 4);
+INSERT INTO `sys_dictionary_details` VALUES (22, '2020-07-05 15:33:35', '2020-07-05 15:33:35', NULL, 'datetime', 3, 1, 3, 4);
+INSERT INTO `sys_dictionary_details` VALUES (23, '2020-07-05 15:33:42', '2020-07-05 15:33:42', NULL, 'timestamp', 5, 1, 5, 4);
+INSERT INTO `sys_dictionary_details` VALUES (24, '2020-07-05 15:34:30', '2020-07-05 15:34:30', NULL, 'float', 0, 1, 0, 5);
+INSERT INTO `sys_dictionary_details` VALUES (25, '2020-07-05 15:34:35', '2020-07-05 15:34:35', NULL, 'double', 1, 1, 1, 5);
+INSERT INTO `sys_dictionary_details` VALUES (26, '2020-07-05 15:34:41', '2020-07-05 15:34:41', NULL, 'decimal', 2, 1, 2, 5);
+INSERT INTO `sys_dictionary_details` VALUES (27, '2020-07-05 15:37:45', '2020-07-05 15:37:45', NULL, 'tinyint', 0, 1, 0, 7);
+INSERT INTO `sys_dictionary_details` VALUES (28, '2020-07-05 15:53:25', '2020-07-05 15:53:25', NULL, 'char', 0, 1, 0, 6);
+INSERT INTO `sys_dictionary_details` VALUES (29, '2020-07-05 15:53:29', '2020-07-05 15:53:29', NULL, 'varchar', 1, 1, 1, 6);
+INSERT INTO `sys_dictionary_details` VALUES (30, '2020-07-05 15:53:35', '2020-07-05 15:53:35', NULL, 'tinyblob', 2, 1, 2, 6);
+INSERT INTO `sys_dictionary_details` VALUES (31, '2020-07-05 15:53:40', '2020-07-05 15:53:40', NULL, 'tinytext', 3, 1, 3, 6);
+INSERT INTO `sys_dictionary_details` VALUES (32, '2020-07-05 15:53:48', '2020-07-05 15:53:48', NULL, 'text', 4, 1, 4, 6);
+INSERT INTO `sys_dictionary_details` VALUES (33, '2020-07-05 15:53:55', '2020-07-05 15:53:55', NULL, 'blob', 5, 1, 5, 6);
+INSERT INTO `sys_dictionary_details` VALUES (34, '2020-07-05 15:54:02', '2020-07-05 15:54:02', NULL, 'mediumblob', 6, 1, 6, 6);
+INSERT INTO `sys_dictionary_details` VALUES (35, '2020-07-05 15:54:09', '2020-07-05 15:54:09', NULL, 'mediumtext', 7, 1, 7, 6);
+INSERT INTO `sys_dictionary_details` VALUES (36, '2020-07-05 15:54:16', '2020-07-05 15:54:16', NULL, 'longblob', 8, 1, 8, 6);
+INSERT INTO `sys_dictionary_details` VALUES (37, '2020-07-05 15:54:24', '2020-07-05 15:54:24', NULL, 'longtext', 9, 1, 9, 6);
+
+
+
+
+INSERT INTO `sys_apis` VALUES (91, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/createSysOperationRecord', '新增操作记录', 'sysOperationRecord', 'POST');
+INSERT INTO `sys_apis` VALUES (92, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/deleteSysOperationRecord', '删除操作记录', 'sysOperationRecord', 'DELETE');
+INSERT INTO `sys_apis` VALUES (93, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/updateSysOperationRecord', '更新操作记录', 'sysOperationRecord', 'PUT');
+INSERT INTO `sys_apis` VALUES (94, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/findSysOperationRecord', '根据ID获取操作记录', 'sysOperationRecord', 'GET');
+INSERT INTO `sys_apis` VALUES (95, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/getSysOperationRecordList', '获取操作记录列表', 'sysOperationRecord', 'GET');
+INSERT INTO `sys_apis` VALUES (96, '2020-07-05 14:34:20', '2020-07-05 14:34:20', NULL, NULL, '/autoCode/getTables', '获取数据库表', 'autoCode', 'GET');
+INSERT INTO `sys_apis` VALUES (97, '2020-07-05 15:02:07', '2020-07-05 15:02:07', NULL, NULL, '/autoCode/getDB', '获取所有数据库', 'autoCode', 'GET');
+INSERT INTO `sys_apis` VALUES (98, '2020-07-05 16:32:08', '2020-07-05 16:32:08', NULL, NULL, '/autoCode/getColume', '获取所选table的所有字段', 'autoCode', 'GET');
+INSERT INTO `sys_apis` VALUES (99, '2020-07-07 15:59:53', '2020-07-07 15:59:53', NULL, NULL, '/sysOperationRecord/deleteSysOperationRecordByIds', '批量删除操作历史', 'sysOperationRecord', 'DELETE');
+
+
+
+
+
+-- ----------------------------
+-- Table structure for sys_operation_records
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_operation_records`;
+CREATE TABLE `sys_operation_records`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `created_at` datetime(0) NULL DEFAULT NULL,
+  `updated_at` datetime(0) NULL DEFAULT NULL,
+  `deleted_at` datetime(0) NULL DEFAULT NULL,
+  `ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '请求ip',
+  `method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '请求方法',
+  `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '请求路由',
+  `status` int(11) NULL DEFAULT NULL COMMENT '状态',
+  `latency` bigint(20) NULL DEFAULT NULL,
+  `agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
+  `error_message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
+  `body` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '请求Body',
+  `user_id` int(11) NULL DEFAULT NULL COMMENT '用户id',
+  `resp` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '响应Body',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sys_operation_records_deleted_at`(`deleted_at`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 342 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
+
+
+
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/createSysOperationRecord', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/deleteSysOperationRecord', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/updateSysOperationRecord', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/findSysOperationRecord', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/getSysOperationRecordList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/deleteSysOperationRecordByIds', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/getTables', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/getDB', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/getColume', 'GET', '', '', '');
+
+
+INSERT INTO `sys_authority_menus` VALUES ('888', 52);
+
+
+-- 2020/07/08版本更新补丁
+-- 增加了共自动化用的字典
+-- 增加了操作记录 menu
+-- 增加了操作记录相关api
+-- 增加了操作记录表
+-- 增加了角色和操作记录关联api
+-- 增加了角色和menu关联记录

+ 230 - 153
server/db/qmplus.sql

@@ -11,7 +11,7 @@
  Target Server Version : 50644
  File Encoding         : 65001
 
- Date: 11/06/2020 09:29:47
+ Date: 08/07/2020 10:08:22
 */
 
 SET NAMES utf8mb4;
@@ -57,7 +57,7 @@ INSERT INTO `casbin_rule` VALUES ('p', '8881', '/menu/updateBaseMenu', 'POST', '
 INSERT INTO `casbin_rule` VALUES ('p', '8881', '/menu/getBaseMenuById', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '8881', '/user/changePassword', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '8881', '/user/uploadHeaderImg', 'POST', '', '', '');
-INSERT INTO `casbin_rule` VALUES ('p', '8881', '/user/deleteUser', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '8881', '/user/getInfoList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '8881', '/user/getUserList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '8881', '/user/setUserAuthority', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '8881', '/fileUploadAndDownload/upload', 'POST', '', '', '');
@@ -96,7 +96,7 @@ INSERT INTO `casbin_rule` VALUES ('p', '9528', '/menu/updateBaseMenu', 'POST', '
 INSERT INTO `casbin_rule` VALUES ('p', '9528', '/menu/getBaseMenuById', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '9528', '/user/changePassword', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '9528', '/user/uploadHeaderImg', 'POST', '', '', '');
-INSERT INTO `casbin_rule` VALUES ('p', '9528', '/user/deleteUser', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '9528', '/user/getInfoList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '9528', '/user/getUserList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '9528', '/user/setUserAuthority', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '9528', '/fileUploadAndDownload/upload', 'POST', '', '', '');
@@ -138,9 +138,10 @@ INSERT INTO `casbin_rule` VALUES ('p', '888', '/menu/updateBaseMenu', 'POST', ''
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/menu/getBaseMenuById', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/changePassword', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/uploadHeaderImg', 'POST', '', '', '');
-INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/deleteUser', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/getInfoList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/getUserList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/setUserAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/user/deleteUser', 'DELETE', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/fileUploadAndDownload/upload', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/fileUploadAndDownload/getFileList', 'POST', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/fileUploadAndDownload/deleteFile', 'POST', '', '', '');
@@ -156,6 +157,25 @@ INSERT INTO `casbin_rule` VALUES ('p', '888', '/customer/customer', 'DELETE', ''
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/customer/customer', 'GET', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/customer/customerList', 'GET', '', '', '');
 INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/createTemp', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/getTables', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/getDB', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/autoCode/getColume', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionaryDetail/createSysDictionaryDetail', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionaryDetail/deleteSysDictionaryDetail', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionaryDetail/updateSysDictionaryDetail', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionaryDetail/findSysDictionaryDetail', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionaryDetail/getSysDictionaryDetailList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionary/createSysDictionary', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionary/deleteSysDictionary', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionary/updateSysDictionary', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionary/findSysDictionary', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysDictionary/getSysDictionaryList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/createSysOperationRecord', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/deleteSysOperationRecord', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/updateSysOperationRecord', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/findSysOperationRecord', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/getSysOperationRecordList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/deleteSysOperationRecordByIds', 'DELETE', '', '', '');
 
 -- ----------------------------
 -- Table structure for exa_customers
@@ -166,21 +186,18 @@ CREATE TABLE `exa_customers`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `customer_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户名',
-  `customer_phone_data` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户手机号',
-  `sys_user_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '管理ID',
-  `sys_user_authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '管理角色ID',
+  `customer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '客户名',
+  `customer_phone_data` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户电话',
+  `sys_user_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '负责员工id',
+  `sys_user_authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '负责员工角色',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_exa_customers_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
 
 -- ----------------------------
 -- Records of exa_customers
 -- ----------------------------
 INSERT INTO `exa_customers` VALUES (1, '2020-02-25 18:01:48', '2020-04-10 12:29:29', NULL, '测试客户', '1761111111', 10, '888');
-INSERT INTO `exa_customers` VALUES (2, '2020-04-10 12:25:53', '2020-04-10 12:25:53', '2020-04-10 13:43:56', 'test', '123123123', 10, '888');
-INSERT INTO `exa_customers` VALUES (3, '2020-04-10 13:44:12', '2020-04-10 13:44:12', '2020-04-10 13:44:13', '123123', '123123', 10, '888');
-INSERT INTO `exa_customers` VALUES (4, '2020-04-10 13:47:10', '2020-04-10 13:47:10', '2020-04-10 13:47:12', '22222222', '222222222222222', 10, '888');
 
 -- ----------------------------
 -- Table structure for exa_file_chunks
@@ -191,9 +208,9 @@ CREATE TABLE `exa_file_chunks`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `exa_file_id` int(10) UNSIGNED NULL DEFAULT NULL,
-  `file_chunk_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
-  `file_chunk_number` int(11) NULL DEFAULT NULL,
+  `exa_file_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '文件id',
+  `file_chunk_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '切片路径',
+  `file_chunk_number` int(11) NULL DEFAULT NULL COMMENT '切片标号',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_exa_file_chunks_deleted_at`(`deleted_at`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
@@ -208,9 +225,9 @@ CREATE TABLE `exa_file_upload_and_downloads`  (
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
   `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件名',
-  `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件地址\r\n',
-  `tag` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件标签\r\n',
-  `key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '编号',
+  `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件URL',
+  `tag` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件类型',
+  `key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标记',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_file_upload_and_downloads_deleted_at`(`deleted_at`) USING BTREE,
   INDEX `idx_exa_file_upload_and_downloads_deleted_at`(`deleted_at`) USING BTREE
@@ -231,11 +248,11 @@ CREATE TABLE `exa_files`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
-  `file_md5` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
-  `file_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
-  `chunk_total` int(11) NULL DEFAULT NULL,
-  `is_finish` tinyint(1) NULL DEFAULT NULL,
+  `file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件名',
+  `file_md5` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件md5',
+  `file_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件路径',
+  `chunk_total` int(11) NULL DEFAULT NULL COMMENT '切片总数',
+  `is_finish` tinyint(1) NULL DEFAULT NULL COMMENT '是否完整',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_exa_files_deleted_at`(`deleted_at`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
@@ -249,60 +266,10 @@ CREATE TABLE `jwt_blacklists`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `jwt` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
+  `jwt` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'jwt',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_jwt_blacklists_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 51 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-
--- ----------------------------
--- Records of jwt_blacklists
--- ----------------------------
-INSERT INTO `jwt_blacklists` VALUES (3, '2019-12-28 18:29:05', '2019-12-28 18:29:05', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MTMzNzM2LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc1Mjc5MzZ9.T7ikGw-lgAAQlfMne7zPIF-PlfQMg37uBCYJ24Y_B38');
-INSERT INTO `jwt_blacklists` VALUES (4, '2019-12-28 18:31:02', '2019-12-28 18:31:02', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MTMzODUzLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc1MjgwNTN9.tDzUm4KNFeJCErNfZGfuF2tcuolga2f_2dE0nTl_UZU');
-INSERT INTO `jwt_blacklists` VALUES (5, '2019-12-28 18:31:25', '2019-12-28 18:31:25', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MTMzODcwLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc1MjgwNzB9.mspXy9sqQO_5PusPReLalodo_ybWRKxb3Ownf2r2HxE');
-INSERT INTO `jwt_blacklists` VALUES (6, '2019-12-30 14:20:10', '2019-12-30 14:20:10', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkxNTc2LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODU3NzZ9.AR2KYShboFKsHTjwohxEkA3lytttfZqRH849sl2fNdw');
-INSERT INTO `jwt_blacklists` VALUES (7, '2019-12-30 14:21:14', '2019-12-30 14:21:14', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkxNjE2LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODU4MTZ9.h8zbDVHM_QbBI-ejGXeQpw0S9oYHJyP4U-TwsVFus9Q');
-INSERT INTO `jwt_blacklists` VALUES (8, '2019-12-30 14:21:57', '2019-12-30 14:21:57', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkxNjgxLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODU4ODF9.CSjolDGVpU0g7YG6TaPAlWAMdhtvnBhAi-XYYWZ6RLo');
-INSERT INTO `jwt_blacklists` VALUES (9, '2019-12-30 14:25:01', '2019-12-30 14:25:01', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkxODIyLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODYwMjJ9.Y_s22Vh5J2ah6Kh1nZQQ8XIQspbT4I7tzc_YJqWrRWM');
-INSERT INTO `jwt_blacklists` VALUES (10, '2019-12-30 14:29:26', '2019-12-30 14:29:26', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkyMTU0LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODYzNTR9.4HJdx-sfYE5TUUefdwi3yZ6dY_jG7WwEC_55WuGawY8');
-INSERT INTO `jwt_blacklists` VALUES (11, '2019-12-30 14:43:43', '2019-12-30 14:43:43', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkyMTcwLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODYzNzB9.YEhupQVwjMVBB2eAcAoGG-vJczoxuUyn6KR-tDWU86I');
-INSERT INTO `jwt_blacklists` VALUES (12, '2019-12-30 14:55:13', '2019-12-30 14:55:13', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkzMDI3LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODcyMjd9.r_sE_Z31cFdS2nCf3iyQjuiZe0Z3HPR07wKBGlUHsnk');
-INSERT INTO `jwt_blacklists` VALUES (13, '2019-12-30 14:58:31', '2019-12-30 14:58:31', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkzNzY2LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODc5NjZ9.dYFlmyIKQZjzTCKu56wCmxXiW6zOayN_YgygCcvCyLk');
-INSERT INTO `jwt_blacklists` VALUES (14, '2019-12-30 14:58:38', '2019-12-30 14:58:38', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkzOTEwLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODgxMTB9.pPmzsHU4UceZuPFT_G-SDdxe6FD3MuL47HkovpI-_0c');
-INSERT INTO `jwt_blacklists` VALUES (15, '2019-12-30 14:58:58', '2019-12-30 14:58:58', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4MjkzOTE4LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1Nzc2ODgxMTh9.irf98R0belbXtb8x9SxsvuhiYsbHMPbHbFDxaaH0z6Q');
-INSERT INTO `jwt_blacklists` VALUES (16, '2020-01-06 16:32:31', '2020-01-06 16:32:31', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTAzMjk5LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTc0OTl9.jgLfjvek7sQyuZ2TABQvLOyu_ifNw_KYzfY3VTLL4fw');
-INSERT INTO `jwt_blacklists` VALUES (17, '2020-01-06 16:33:08', '2020-01-06 16:33:08', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA0MzU4LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTg1NTh9.89r6xHZUBDjfmNpmF02RjQXYTBGUiJvOEDP8pydNt-A');
-INSERT INTO `jwt_blacklists` VALUES (18, '2020-01-06 16:33:18', '2020-01-06 16:33:18', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA0MzkyLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTg1OTJ9.6Yv9ZYhN-TH9H4SoZEAkjevKVX0vLHL1lVQGFpfBr2U');
-INSERT INTO `jwt_blacklists` VALUES (19, '2020-01-06 16:36:06', '2020-01-06 16:36:06', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA0NDA5LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTg2MDl9._9zRRK76XH_KgrW1X9P5GTLW9dwfIixB4QUsC7M3RHA');
-INSERT INTO `jwt_blacklists` VALUES (20, '2020-01-06 16:44:06', '2020-01-06 16:44:06', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA0NTcxLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTg3NzF9.5ki0TZooCorK81xWpYa-OO3RR-Bpp5am_uNCNPh4250');
-INSERT INTO `jwt_blacklists` VALUES (21, '2020-01-06 16:45:50', '2020-01-06 16:45:50', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1MDUwLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTkyNTB9.A0n5faE0X0TyRb_1RvAQBLooY-peapPTD0LnJD03Ul0');
-INSERT INTO `jwt_blacklists` VALUES (22, '2020-01-06 16:46:24', '2020-01-06 16:46:24', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1MTU0LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTkzNTR9.VtqTOJ-MQY2K3w4tM7HgT0z73CEOd3CDqmYqKCjXxnc');
-INSERT INTO `jwt_blacklists` VALUES (23, '2020-01-06 16:47:20', '2020-01-06 16:47:20', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1MTg3LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTkzODd9.fwL1QakF30SHSaGDkPo3weIg0l7kiAGwNq_fKsFxquc');
-INSERT INTO `jwt_blacklists` VALUES (24, '2020-01-06 16:47:57', '2020-01-06 16:47:57', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1MjQ0LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk0NDR9.VoKdA0-brmUlQ5bYufIdMWrS-cCQ2ARm7_jeVtfvCpc');
-INSERT INTO `jwt_blacklists` VALUES (25, '2020-01-06 16:49:08', '2020-01-06 16:49:08', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1Mjg1LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk0ODV9.a8-zmyIlJJGdonhXAzNvNH9C-nMa-Voq4bhTbiVKJzE');
-INSERT INTO `jwt_blacklists` VALUES (26, '2020-01-06 16:49:32', '2020-01-06 16:49:32', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1MzUyLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk1NTJ9.l4e3rjtrDgRsqnQwizJ-ZXVUVM8ywSJcNJkkEVYbdzU');
-INSERT INTO `jwt_blacklists` VALUES (27, '2020-01-06 16:49:58', '2020-01-06 16:49:58', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1Mzc3LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk1Nzd9.mXUPYvmXbntrdywpBNM0j9sP991cwfhc9b0KvUM4dG4');
-INSERT INTO `jwt_blacklists` VALUES (28, '2020-01-06 16:50:56', '2020-01-06 16:50:56', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1NDExLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk2MTF9.Z21e8nWHKV5XvYg61CZCz3nMK25m_FmlxncxGMpMS0k');
-INSERT INTO `jwt_blacklists` VALUES (29, '2020-01-06 16:52:03', '2020-01-06 16:52:03', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1NDY0LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk2NjR9.qzptIyCcL_SPm6TGwXML8Rih3qYqj9GLUpWzTpSPPuI');
-INSERT INTO `jwt_blacklists` VALUES (30, '2020-01-06 16:52:36', '2020-01-06 16:52:36', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1NTI3LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk3Mjd9.D9e8qbx44CLX0ZInwNlIqTGS_sSE069TRIDkQAk7tVY');
-INSERT INTO `jwt_blacklists` VALUES (31, '2020-01-06 16:54:35', '2020-01-06 16:54:35', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1NTY1LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk3NjV9.D4EZmVAJ96kxcyIfWkT_LA81t1JCuQZcYmQkkoNhtPo');
-INSERT INTO `jwt_blacklists` VALUES (32, '2020-01-06 16:55:40', '2020-01-06 16:55:40', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1NjgzLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk4ODN9.SJL2fFMbe5VL2YWBzMlrhxbBIJhIHTUeodkEpgH1Xgo');
-INSERT INTO `jwt_blacklists` VALUES (33, '2020-01-06 16:57:28', '2020-01-06 16:57:28', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1NzU4LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgyOTk5NTh9.6y12UkOeW7vz7gGTcYaN3Y-2Ut2QmjgU9WEuy_pneGM');
-INSERT INTO `jwt_blacklists` VALUES (34, '2020-01-06 16:59:02', '2020-01-06 16:59:02', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1ODU1LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgzMDAwNTV9.G0q9X7Ld3cN_BO-K219b7tFAHgtpiAwqLPoxVNKsEl8');
-INSERT INTO `jwt_blacklists` VALUES (35, '2020-01-06 16:59:26', '2020-01-06 16:59:26', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTc4OTA1OTQ2LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1NzgzMDAxNDZ9.cmBgWiztsnh7zF3OUNIDQKv8wzGJF7fllUv-4LlYxu8');
-INSERT INTO `jwt_blacklists` VALUES (36, '2020-03-21 14:46:14', '2020-03-21 14:46:14', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg1Mzc3ODY3LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODQ3NzIwNjd9.DLhWhD1FdcWLyFLcXQynKJnenbVHrSiKhlDGFRzgo5k');
-INSERT INTO `jwt_blacklists` VALUES (37, '2020-03-31 14:24:35', '2020-03-31 14:24:35', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg2MTM4MTA4LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODU1MzIzMDh9.Ro2F2dZLfOk2Z_OPRbweOuCpchr6HlHfQIF5qjfc8y4');
-INSERT INTO `jwt_blacklists` VALUES (38, '2020-04-01 16:07:57', '2020-04-01 16:07:57', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg2MjQwNzQyLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODU2MzQ5NDJ9.9qaOFu7D5cq4vxTfLi4pyO_JGcKjVAEJIcoStJWJlYg');
-INSERT INTO `jwt_blacklists` VALUES (39, '2020-04-15 16:30:41', '2020-04-15 16:30:41', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3MDk1Njg5LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY0ODk4ODl9.-cNmRAyqhylZlzakwoFY08x7RnjI3CiWTiQc_Iabb-c');
-INSERT INTO `jwt_blacklists` VALUES (40, '2020-04-15 16:39:26', '2020-04-15 16:39:26', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ0MjUwLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5Mzg0NTB9.smVP-Rl1EkAuUVqXW7z0mpxA5O86vXj0oH4FukG-NVA');
-INSERT INTO `jwt_blacklists` VALUES (41, '2020-04-15 17:08:06', '2020-04-15 17:08:06', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ0NzgxLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5Mzg5ODF9.OMZ08Y8aPuj40-NGEQ402LyRFBpkLWzzaqD3_tvj1h8');
-INSERT INTO `jwt_blacklists` VALUES (42, '2020-04-15 17:08:28', '2020-04-15 17:08:28', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ2NDk0LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5NDA2OTR9.9lsoTbZrwhZ8kMXiH-Ta3A4h_yp7SwLj57mo_u5mrk4');
-INSERT INTO `jwt_blacklists` VALUES (43, '2020-04-15 17:10:24', '2020-04-15 17:10:24', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ2NTE1LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5NDA3MTV9.5SrUrUmd4YhzlGmSpA9xJW_wbjV6yI6ty_NriIceOQo');
-INSERT INTO `jwt_blacklists` VALUES (44, '2020-04-15 17:11:43', '2020-04-15 17:11:43', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ2NjI5LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5NDA4Mjl9.SFiomEpOshboOe0JGDa1HlJt5aQIF7IeyOsoDwl1o8E');
-INSERT INTO `jwt_blacklists` VALUES (45, '2020-04-15 17:12:54', '2020-04-15 17:12:54', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ2NzE4LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5NDA5MTh9.xrwEknZQN2J3poarMTQvb7mX1Icicz2_f60kw36g9og');
-INSERT INTO `jwt_blacklists` VALUES (46, '2020-04-15 17:14:47', '2020-04-15 17:14:47', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NTQ2Nzg5LCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODY5NDA5ODl9.3jbdl1N0KA8ExFMWXHi3ha4aESKq8yDKDgpSH4Xdsnk');
-INSERT INTO `jwt_blacklists` VALUES (47, '2020-04-22 12:04:20', '2020-04-22 12:04:20', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg3NjE2MTYwLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODcwMTAzNjB9.jRHlnfXuJhp4hBE-QqCZ-lodzwK67IBkDI2xteB0OQw');
-INSERT INTO `jwt_blacklists` VALUES (48, '2020-04-22 12:12:17', '2020-04-22 12:12:17', NULL, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVVUlEIjoiY2UwZDY2ODUtYzE1Zi00MTI2LWE1YjQtODkwYmM5ZDIzNTZkIiwiSUQiOjEwLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsIkF1dGhvcml0eUlkIjoiODg4IiwiZXhwIjoxNTg4MTMzMjQyLCJpc3MiOiJxbVBsdXMiLCJuYmYiOjE1ODc1Mjc0NDJ9.WJ59uRUxXJ7-rUH07mE6jCfnwgfvQnpPaLU5vJ_VhWM');
+) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
 
 -- ----------------------------
 -- Table structure for sys_apis
@@ -313,22 +280,22 @@ CREATE TABLE `sys_apis`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `authority_id` int(10) UNSIGNED NULL DEFAULT NULL,
-  `path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'api路径',
-  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'api中文描述',
-  `api_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'api组',
-  `method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'POST' COMMENT '方法',
+  `authority_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '角色id',
+  `path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由path',
+  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由描述',
+  `api_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由分组',
+  `method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'POST' COMMENT '请求方法',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_apis_deleted_at`(`deleted_at`) USING BTREE,
   INDEX `idx_sys_apis_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 48 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
 
 -- ----------------------------
 -- Records of sys_apis
 -- ----------------------------
 INSERT INTO `sys_apis` VALUES (1, '2019-09-28 11:23:49', '2019-09-28 17:06:16', NULL, NULL, '/base/login', '用户登录', 'base', 'POST');
 INSERT INTO `sys_apis` VALUES (2, '2019-09-28 11:32:46', '2019-09-28 17:06:11', NULL, NULL, '/base/register', '用户注册', 'base', 'POST');
-INSERT INTO `sys_apis` VALUES (3, '2019-09-28 11:33:41', '2020-05-09 17:43:15', NULL, NULL, '/api/createApi', '创建api', 'api', 'POST');
+INSERT INTO `sys_apis` VALUES (3, '2019-09-28 11:33:41', '2020-05-10 16:33:48', NULL, NULL, '/api/createApi', '创建api', 'api', 'POST');
 INSERT INTO `sys_apis` VALUES (4, '2019-09-28 14:09:04', '2019-09-28 17:05:59', NULL, NULL, '/api/getApiList', '获取api列表', 'api', 'POST');
 INSERT INTO `sys_apis` VALUES (5, '2019-09-28 14:15:50', '2019-09-28 17:05:53', NULL, NULL, '/api/getApiById', '获取api详细信息', 'api', 'POST');
 INSERT INTO `sys_apis` VALUES (7, '2019-09-28 14:19:26', '2019-09-28 17:05:44', NULL, NULL, '/api/deleteApi', '删除Api', 'api', 'POST');
@@ -348,7 +315,7 @@ INSERT INTO `sys_apis` VALUES (21, '2019-09-30 15:28:05', '2019-09-30 15:28:05',
 INSERT INTO `sys_apis` VALUES (22, '2019-09-30 15:28:21', '2019-09-30 15:28:21', NULL, NULL, '/menu/getBaseMenuById', '根据id获取菜单', 'menu', 'POST');
 INSERT INTO `sys_apis` VALUES (23, '2019-09-30 15:29:19', '2019-09-30 15:29:19', NULL, NULL, '/user/changePassword', '修改密码', 'user', 'POST');
 INSERT INTO `sys_apis` VALUES (24, '2019-09-30 15:29:33', '2019-09-30 15:29:33', NULL, NULL, '/user/uploadHeaderImg', '上传头像', 'user', 'POST');
-INSERT INTO `sys_apis` VALUES (25, '2019-09-30 15:30:00', '2020-05-06 16:03:47', NULL, NULL, '/user/deleteUser', '删除用户', 'user', 'DELETE');
+INSERT INTO `sys_apis` VALUES (25, '2019-09-30 15:30:00', '2019-09-30 15:30:00', NULL, NULL, '/user/getInfoList', '分页获取用户列表', 'user', 'POST');
 INSERT INTO `sys_apis` VALUES (28, '2019-10-09 15:15:17', '2019-10-09 15:17:07', NULL, NULL, '/user/getUserList', '获取用户列表', 'user', 'POST');
 INSERT INTO `sys_apis` VALUES (29, '2019-10-09 23:01:40', '2019-10-09 23:01:40', NULL, NULL, '/user/setUserAuthority', '修改用户角色', 'user', 'POST');
 INSERT INTO `sys_apis` VALUES (30, '2019-10-26 20:14:38', '2019-10-26 20:14:38', NULL, NULL, '/fileUploadAndDownload/upload', '文件上传示例', 'fileUploadAndDownload', 'POST');
@@ -369,15 +336,35 @@ INSERT INTO `sys_apis` VALUES (44, '2020-03-12 14:36:54', '2020-03-12 14:56:50',
 INSERT INTO `sys_apis` VALUES (45, '2020-03-29 23:01:28', '2020-03-29 23:01:28', NULL, NULL, '/autoCode/createTemp', '自动化代码', 'autoCode', 'POST');
 INSERT INTO `sys_apis` VALUES (46, '2020-04-15 12:46:58', '2020-04-15 12:46:58', NULL, NULL, '/authority/updateAuthority', '更新角色信息', 'authority', 'PUT');
 INSERT INTO `sys_apis` VALUES (47, '2020-04-20 15:14:25', '2020-04-20 15:14:25', NULL, NULL, '/authority/copyAuthority', '拷贝角色', 'authority', 'POST');
+INSERT INTO `sys_apis` VALUES (64, '2020-05-10 16:44:25', '2020-05-10 16:44:25', NULL, NULL, '/user/deleteUser', '删除用户', 'user', 'DELETE');
+INSERT INTO `sys_apis` VALUES (81, '2020-06-23 18:40:50', '2020-06-23 18:40:50', NULL, NULL, '/sysDictionaryDetail/createSysDictionaryDetail', '新增字典内容', 'sysDictionaryDetail', 'POST');
+INSERT INTO `sys_apis` VALUES (82, '2020-06-23 18:40:50', '2020-06-23 18:40:50', NULL, NULL, '/sysDictionaryDetail/deleteSysDictionaryDetail', '删除字典内容', 'sysDictionaryDetail', 'DELETE');
+INSERT INTO `sys_apis` VALUES (83, '2020-06-23 18:40:50', '2020-06-23 18:40:50', NULL, NULL, '/sysDictionaryDetail/updateSysDictionaryDetail', '更新字典内容', 'sysDictionaryDetail', 'PUT');
+INSERT INTO `sys_apis` VALUES (84, '2020-06-23 18:40:50', '2020-06-23 18:40:50', NULL, NULL, '/sysDictionaryDetail/findSysDictionaryDetail', '根据ID获取字典内容', 'sysDictionaryDetail', 'GET');
+INSERT INTO `sys_apis` VALUES (85, '2020-06-23 18:40:50', '2020-06-23 18:40:50', NULL, NULL, '/sysDictionaryDetail/getSysDictionaryDetailList', '获取字典内容列表', 'sysDictionaryDetail', 'GET');
+INSERT INTO `sys_apis` VALUES (86, '2020-06-23 18:48:13', '2020-06-23 18:48:13', NULL, NULL, '/sysDictionary/createSysDictionary', '新增字典', 'sysDictionary', 'POST');
+INSERT INTO `sys_apis` VALUES (87, '2020-06-23 18:48:13', '2020-06-23 18:48:13', NULL, NULL, '/sysDictionary/deleteSysDictionary', '删除字典', 'sysDictionary', 'DELETE');
+INSERT INTO `sys_apis` VALUES (88, '2020-06-23 18:48:13', '2020-06-23 18:48:13', NULL, NULL, '/sysDictionary/updateSysDictionary', '更新字典', 'sysDictionary', 'PUT');
+INSERT INTO `sys_apis` VALUES (89, '2020-06-23 18:48:13', '2020-06-23 18:48:13', NULL, NULL, '/sysDictionary/findSysDictionary', '根据ID获取字典', 'sysDictionary', 'GET');
+INSERT INTO `sys_apis` VALUES (90, '2020-06-23 18:48:13', '2020-06-23 18:48:13', NULL, NULL, '/sysDictionary/getSysDictionaryList', '获取字典列表', 'sysDictionary', 'GET');
+INSERT INTO `sys_apis` VALUES (91, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/createSysOperationRecord', '新增操作记录', 'sysOperationRecord', 'POST');
+INSERT INTO `sys_apis` VALUES (92, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/deleteSysOperationRecord', '删除操作记录', 'sysOperationRecord', 'DELETE');
+INSERT INTO `sys_apis` VALUES (93, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/updateSysOperationRecord', '更新操作记录', 'sysOperationRecord', 'PUT');
+INSERT INTO `sys_apis` VALUES (94, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/findSysOperationRecord', '根据ID获取操作记录', 'sysOperationRecord', 'GET');
+INSERT INTO `sys_apis` VALUES (95, '2020-06-29 13:21:35', '2020-06-29 13:21:35', NULL, NULL, '/sysOperationRecord/getSysOperationRecordList', '获取操作记录列表', 'sysOperationRecord', 'GET');
+INSERT INTO `sys_apis` VALUES (96, '2020-07-05 14:34:20', '2020-07-05 14:34:20', NULL, NULL, '/autoCode/getTables', '获取数据库表', 'autoCode', 'GET');
+INSERT INTO `sys_apis` VALUES (97, '2020-07-05 15:02:07', '2020-07-05 15:02:07', NULL, NULL, '/autoCode/getDB', '获取所有数据库', 'autoCode', 'GET');
+INSERT INTO `sys_apis` VALUES (98, '2020-07-05 16:32:08', '2020-07-05 16:32:08', NULL, NULL, '/autoCode/getColume', '获取所选table的所有字段', 'autoCode', 'GET');
+INSERT INTO `sys_apis` VALUES (99, '2020-07-07 15:59:53', '2020-07-07 15:59:53', NULL, NULL, '/sysOperationRecord/deleteSysOperationRecordByIds', '批量删除操作历史', 'sysOperationRecord', 'DELETE');
 
 -- ----------------------------
 -- Table structure for sys_authorities
 -- ----------------------------
 DROP TABLE IF EXISTS `sys_authorities`;
 CREATE TABLE `sys_authorities`  (
-  `authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色ID',
+  `authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色id',
   `authority_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色名',
-  `parent_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '父角色ID',
+  `parent_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '父角色',
   `created_at` datetime(0) NULL DEFAULT NULL,
   `updated_at` datetime(0) NULL DEFAULT NULL,
   `deleted_at` datetime(0) NULL DEFAULT NULL,
@@ -389,17 +376,17 @@ CREATE TABLE `sys_authorities`  (
 -- ----------------------------
 -- Records of sys_authorities
 -- ----------------------------
-INSERT INTO `sys_authorities` VALUES ('888', '普通用户', '0', '2020-04-04 11:44:56', '2020-05-09 17:41:29', NULL);
-INSERT INTO `sys_authorities` VALUES ('8881', '普通用户子角色', '888', '2020-04-04 11:44:56', '2020-05-09 17:41:29', NULL);
-INSERT INTO `sys_authorities` VALUES ('9528', '测试角色', '0', '2020-04-04 11:44:56', '2020-05-09 17:41:29', NULL);
+INSERT INTO `sys_authorities` VALUES ('888', '普通用户', '0', '2020-04-04 11:44:56', '2020-06-13 16:07:37', NULL);
+INSERT INTO `sys_authorities` VALUES ('8881', '普通用户子角色', '888', '2020-04-04 11:44:56', '2020-04-24 10:16:42', NULL);
+INSERT INTO `sys_authorities` VALUES ('9528', '测试角色', '0', '2020-04-04 11:44:56', '2020-04-24 10:16:42', NULL);
 
 -- ----------------------------
 -- Table structure for sys_authority_menus
 -- ----------------------------
 DROP TABLE IF EXISTS `sys_authority_menus`;
 CREATE TABLE `sys_authority_menus`  (
-  `sys_authority_authority_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '角色ID',
-  `sys_base_menu_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '菜单ID',
+  `sys_authority_authority_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '角色id',
+  `sys_base_menu_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '菜单id',
   PRIMARY KEY (`sys_authority_authority_id`, `sys_base_menu_id`) USING BTREE,
   INDEX `sys_authority_authority_id`(`sys_authority_authority_id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
@@ -427,7 +414,9 @@ INSERT INTO `sys_authority_menus` VALUES ('888', 38);
 INSERT INTO `sys_authority_menus` VALUES ('888', 40);
 INSERT INTO `sys_authority_menus` VALUES ('888', 41);
 INSERT INTO `sys_authority_menus` VALUES ('888', 42);
-INSERT INTO `sys_authority_menus` VALUES ('888', 45);
+INSERT INTO `sys_authority_menus` VALUES ('888', 50);
+INSERT INTO `sys_authority_menus` VALUES ('888', 51);
+INSERT INTO `sys_authority_menus` VALUES ('888', 52);
 INSERT INTO `sys_authority_menus` VALUES ('8881', 1);
 INSERT INTO `sys_authority_menus` VALUES ('8881', 2);
 INSERT INTO `sys_authority_menus` VALUES ('8881', 18);
@@ -465,56 +454,58 @@ CREATE TABLE `sys_base_menus`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `menu_level` int(10) UNSIGNED NULL DEFAULT NULL,
-  `parent_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '父菜单ID',
-  `path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由path',
-  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由name',
+  `menu_level` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '菜单等级(暂未使用)',
+  `parent_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '父菜单id',
+  `path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单path(路由path',
+  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单name(路由name',
   `hidden` tinyint(1) NULL DEFAULT NULL COMMENT '是否在列表隐藏',
-  `component` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '对应前端文件路径',
-  `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单名',
-  `icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单图标',
-  `nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
-  `sort` int(255) NULL DEFAULT NULL COMMENT '排序标记',
-  `keep_alive` tinyint(1) NULL DEFAULT NULL COMMENT '是否缓存',
-  `default_menu` tinyint(1) NULL DEFAULT NULL COMMENT '是否是基础路由(开发中)',
+  `component` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '组件位置',
+  `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '显示名字',
+  `icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '显示图标',
+  `nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单别名',
+  `sort` int(255) NULL DEFAULT NULL COMMENT '排序',
+  `keep_alive` tinyint(1) NULL DEFAULT NULL COMMENT '是否缓存菜单内容',
+  `default_menu` tinyint(1) NULL DEFAULT NULL COMMENT '默认菜单(暂未使用)',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_base_menus_deleted_at`(`deleted_at`) USING BTREE,
   INDEX `idx_sys_base_menus_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 48 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 54 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
 
 -- ----------------------------
 -- Records of sys_base_menus
 -- ----------------------------
-INSERT INTO `sys_base_menus` VALUES (1, '2019-09-19 22:05:18', '2020-05-09 17:41:51', NULL, 0, 0, 'dashboard', 'dashboard', 0, 'view/dashboard/index.vue', '仪表盘', 'setting', '仪表盘', 1, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (2, '2019-09-19 22:06:17', '2020-05-09 17:41:29', NULL, 0, 0, 'about', 'about', 0, 'view/about/index.vue', '关于我们', 'info', '测试菜单', 7, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (3, '2019-09-19 22:06:38', '2020-05-09 17:41:29', NULL, 0, 0, 'admin', 'superAdmin', 0, 'view/superAdmin/index.vue', '超级管理员', 'user-solid', '超级管理员', 3, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (4, '2019-09-19 22:11:53', '2020-05-09 17:41:29', NULL, 0, 3, 'authority', 'authority', 0, 'view/superAdmin/authority/authority.vue', '角色管理', 's-custom', '角色管理', 1, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (5, '2019-09-19 22:13:18', '2020-05-09 17:41:29', NULL, 0, 3, 'menu', 'menu', 0, 'view/superAdmin/menu/menu.vue', '菜单管理', 's-order', '菜单管理', 2, 1, 0);
-INSERT INTO `sys_base_menus` VALUES (6, '2019-09-19 22:13:36', '2020-05-09 17:41:29', NULL, 0, 3, 'api', 'api', 0, 'view/superAdmin/api/api.vue', 'api管理', 's-platform', 'api管理', 3, 1, 0);
-INSERT INTO `sys_base_menus` VALUES (17, '2019-10-09 15:12:29', '2020-05-09 17:41:29', NULL, 0, 3, 'user', 'user', 0, 'view/superAdmin/user/user.vue', '用户管理', 'coordinate', '用户管理', 4, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (18, '2019-10-15 22:27:22', '2020-05-09 17:41:29', NULL, 0, 0, 'person', 'person', 1, 'view/person/person.vue', '个人信息', 'user-solid', '个人信息', 4, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (19, '2019-10-20 11:14:42', '2020-05-09 17:41:29', NULL, 0, 0, 'example', 'example', 0, 'view/example/index.vue', '示例文件', 's-management', '示例文件', 6, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (20, '2019-10-20 11:18:11', '2020-05-09 17:41:29', NULL, 0, 19, 'table', 'table', 0, 'view/example/table/table.vue', '表格示例', 's-order', '表格示例', 1, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (21, '2019-10-20 11:19:52', '2020-05-09 17:41:29', NULL, 0, 19, 'form', 'form', 0, 'view/example/form/form.vue', '表单示例', 'document', '表单示例', 2, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (22, '2019-10-20 11:22:19', '2020-05-09 17:41:29', NULL, 0, 19, 'rte', 'rte', 0, 'view/example/rte/rte.vue', '富文本编辑器', 'reading', '富文本编辑器', 3, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (23, '2019-10-20 11:23:39', '2020-05-09 17:41:29', NULL, 0, 19, 'excel', 'excel', 0, 'view/example/excel/excel.vue', 'excel导入导出', 's-marketing', 'excel导入导出', 4, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (26, '2019-10-20 11:27:02', '2020-05-09 17:41:29', NULL, 0, 19, 'upload', 'upload', 0, 'view/example/upload/upload.vue', '上传下载', 'upload', '上传下载', 5, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (33, '2020-02-17 16:20:47', '2020-05-09 17:41:29', NULL, 0, 19, 'breakpoint', 'breakpoint', 0, 'view/example/breakpoint/breakpoint.vue', '断点续传', 'upload', '断点续传', 6, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (34, '2020-02-24 19:48:37', '2020-05-09 17:41:29', NULL, 0, 19, 'customer', 'customer', 0, 'view/example/customer/customer.vue', '客户列表(资源示例)', 's-custom', '客户列表(资源示例)', 7, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (38, '2020-03-29 21:31:03', '2020-05-09 17:41:29', NULL, 0, 0, 'systemTools', 'systemTools', 0, 'view/systemTools/index.vue', '系统工具', 's-cooperation', '系统工具', 5, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (40, '2020-03-29 21:35:10', '2020-05-09 17:41:29', NULL, 0, 38, 'autoCode', 'autoCode', 0, 'view/systemTools/autoCode/index.vue', '代码生成器', 'cpu', '代码生成器', 1, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (41, '2020-03-29 21:36:26', '2020-05-09 17:41:29', NULL, 0, 38, 'formCreate', 'formCreate', 0, 'view/systemTools/formCreate/index.vue', '表单生成器', 'magic-stick', '表单生成器', 2, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (42, '2020-04-02 14:19:36', '2020-05-09 17:41:29', NULL, 0, 38, 'system', 'system', 0, 'view/systemTools/system/system.vue', '系统配置', 's-operation', '系统配置', 3, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (45, '2020-04-29 17:19:34', '2020-05-09 17:42:23', NULL, 0, 0, 'iconList', 'iconList', 0, 'view/iconList/index.vue', '图标集合', 'star-on', NULL, 2, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (47, '2020-05-20 16:01:08', '2020-05-20 16:01:08', '2020-05-20 16:01:20', 0, 0, 'testtest/:id', 'testtest', 0, '阿瑟东', 'a\'s\'d', 'user-solid', NULL, 123, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (1, '2019-09-19 22:05:18', '2020-05-30 15:43:06', NULL, 0, 0, 'dashboard', 'dashboard', 0, 'view/dashboard/index.vue', '仪表盘', 'setting', '仪表盘', 1, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (2, '2019-09-19 22:06:17', '2020-05-10 21:31:50', NULL, 0, 0, 'about', 'about', 0, 'view/about/index.vue', '关于我们', 'info', '测试菜单', 7, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (3, '2019-09-19 22:06:38', '2020-04-24 10:16:43', NULL, 0, 0, 'admin', 'superAdmin', 0, 'view/superAdmin/index.vue', '超级管理员', 'user-solid', '超级管理员', 3, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (4, '2019-09-19 22:11:53', '2020-05-30 15:43:25', NULL, 0, 3, 'authority', 'authority', 0, 'view/superAdmin/authority/authority.vue', '角色管理', 's-custom', '角色管理', 1, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (5, '2019-09-19 22:13:18', '2020-04-30 17:45:27', NULL, 0, 3, 'menu', 'menu', 0, 'view/superAdmin/menu/menu.vue', '菜单管理', 's-order', '菜单管理', 2, 1, 0);
+INSERT INTO `sys_base_menus` VALUES (6, '2019-09-19 22:13:36', '2020-04-24 10:16:43', NULL, 0, 3, 'api', 'api', 0, 'view/superAdmin/api/api.vue', 'api管理', 's-platform', 'api管理', 3, 1, 0);
+INSERT INTO `sys_base_menus` VALUES (17, '2019-10-09 15:12:29', '2020-04-24 10:16:43', NULL, 0, 3, 'user', 'user', 0, 'view/superAdmin/user/user.vue', '用户管理', 'coordinate', '用户管理', 4, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (18, '2019-10-15 22:27:22', '2020-05-10 21:31:36', NULL, 0, 0, 'person', 'person', 1, 'view/person/person.vue', '个人信息', 'message-solid', '个人信息', 4, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (19, '2019-10-20 11:14:42', '2020-04-24 10:16:43', NULL, 0, 0, 'example', 'example', 0, 'view/example/index.vue', '示例文件', 's-management', '示例文件', 6, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (20, '2019-10-20 11:18:11', '2020-04-24 10:16:42', NULL, 0, 19, 'table', 'table', 0, 'view/example/table/table.vue', '表格示例', 's-order', '表格示例', 1, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (21, '2019-10-20 11:19:52', '2020-04-24 10:16:43', NULL, 0, 19, 'form', 'form', 0, 'view/example/form/form.vue', '表单示例', 'document', '表单示例', 2, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (22, '2019-10-20 11:22:19', '2020-04-24 10:16:43', NULL, 0, 19, 'rte', 'rte', 0, 'view/example/rte/rte.vue', '富文本编辑器', 'reading', '富文本编辑器', 3, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (23, '2019-10-20 11:23:39', '2020-04-24 10:16:43', NULL, 0, 19, 'excel', 'excel', 0, 'view/example/excel/excel.vue', 'excel导入导出', 's-marketing', 'excel导入导出', 4, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (26, '2019-10-20 11:27:02', '2020-04-24 10:16:43', NULL, 0, 19, 'upload', 'upload', 0, 'view/example/upload/upload.vue', '上传下载', 'upload', '上传下载', 5, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (33, '2020-02-17 16:20:47', '2020-04-24 10:16:43', NULL, 0, 19, 'breakpoint', 'breakpoint', 0, 'view/example/breakpoint/breakpoint.vue', '断点续传', 'upload', '断点续传', 6, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (34, '2020-02-24 19:48:37', '2020-04-24 10:16:43', NULL, 0, 19, 'customer', 'customer', 0, 'view/example/customer/customer.vue', '客户列表(资源示例)', 's-custom', '客户列表(资源示例)', 7, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (38, '2020-03-29 21:31:03', '2020-04-24 10:16:43', NULL, 0, 0, 'systemTools', 'systemTools', 0, 'view/systemTools/index.vue', '系统工具', 's-cooperation', '系统工具', 5, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (40, '2020-03-29 21:35:10', '2020-05-03 21:38:49', NULL, 0, 38, 'autoCode', 'autoCode', 0, 'view/systemTools/autoCode/index.vue', '代码生成器', 'cpu', '代码生成器', 1, 1, 0);
+INSERT INTO `sys_base_menus` VALUES (41, '2020-03-29 21:36:26', '2020-05-03 21:38:43', NULL, 0, 38, 'formCreate', 'formCreate', 0, 'view/systemTools/formCreate/index.vue', '表单生成器', 'magic-stick', '表单生成器', 2, 1, 0);
+INSERT INTO `sys_base_menus` VALUES (42, '2020-04-02 14:19:36', '2020-04-24 10:16:43', NULL, 0, 38, 'system', 'system', 0, 'view/systemTools/system/system.vue', '系统配置', 's-operation', '系统配置', 3, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (45, '2020-04-29 17:19:34', '2020-07-04 18:27:22', NULL, 0, 0, 'iconList', 'iconList', 0, 'view/iconList/index.vue', '图标集合', 'star-on', NULL, 2, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (50, '2020-06-24 19:49:54', '2020-06-28 20:34:47', NULL, 0, 3, 'dictionary', 'dictionary', 0, 'view/superAdmin/dictionary/sysDictionary.vue', '字典管理', 'notebook-2', NULL, 5, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (51, '2020-06-24 19:51:33', '2020-06-28 20:35:04', NULL, 0, 3, 'dictionaryDetail/:id', 'dictionaryDetail', 1, 'view/superAdmin/dictionary/sysDictionaryDetail.vue', '字典详情', 's-order', NULL, 1, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (52, '2020-06-29 13:31:17', '2020-07-07 16:05:34', NULL, 0, 3, 'operation', 'operation', 0, 'view/superAdmin/operation/sysOperationRecord.vue', '操作历史', 'time', NULL, 6, 0, 0);
 
 -- ----------------------------
 -- Table structure for sys_data_authority_id
 -- ----------------------------
 DROP TABLE IF EXISTS `sys_data_authority_id`;
 CREATE TABLE `sys_data_authority_id`  (
-  `sys_authority_authority_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '角色ID',
-  `data_authority_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '资源角色ID',
+  `sys_authority_authority_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '角色id',
+  `data_authority_id` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL COMMENT '拥有的资源角色id',
   PRIMARY KEY (`sys_authority_authority_id`, `data_authority_id`) USING BTREE,
   INDEX `sys_authority_authority_id`(`sys_authority_authority_id`) USING BTREE,
   INDEX `data_authority_id`(`data_authority_id`) USING BTREE
@@ -526,9 +517,6 @@ CREATE TABLE `sys_data_authority_id`  (
 INSERT INTO `sys_data_authority_id` VALUES ('888', '888');
 INSERT INTO `sys_data_authority_id` VALUES ('888', '8881');
 INSERT INTO `sys_data_authority_id` VALUES ('888', '9528');
-INSERT INTO `sys_data_authority_id` VALUES ('88822', '888');
-INSERT INTO `sys_data_authority_id` VALUES ('88822', '8881');
-INSERT INTO `sys_data_authority_id` VALUES ('88822', '9528');
 INSERT INTO `sys_data_authority_id` VALUES ('888222', '888');
 INSERT INTO `sys_data_authority_id` VALUES ('888222', '8881');
 INSERT INTO `sys_data_authority_id` VALUES ('888222', '9528');
@@ -538,6 +526,101 @@ INSERT INTO `sys_data_authority_id` VALUES ('8883', '9528');
 INSERT INTO `sys_data_authority_id` VALUES ('9528', '8881');
 INSERT INTO `sys_data_authority_id` VALUES ('9528', '9528');
 
+-- ----------------------------
+-- Table structure for sys_dictionaries
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dictionaries`;
+CREATE TABLE `sys_dictionaries`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `created_at` datetime(0) NULL DEFAULT NULL,
+  `updated_at` datetime(0) NULL DEFAULT NULL,
+  `deleted_at` datetime(0) NULL DEFAULT NULL,
+  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '字典名(中)',
+  `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '字典名(英)',
+  `status` tinyint(1) NULL DEFAULT NULL COMMENT '状态',
+  `desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sys_dictionaries_deleted_at`(`deleted_at`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+
+-- ----------------------------
+-- Records of sys_dictionaries
+-- ----------------------------
+INSERT INTO `sys_dictionaries` VALUES (2, '2020-06-24 20:44:00', '2020-06-24 20:44:00', NULL, '性别', 'sex', 1, '性别字典');
+INSERT INTO `sys_dictionaries` VALUES (3, '2020-07-05 15:27:31', '2020-07-05 15:27:31', NULL, '数据库int类型', 'int', 1, 'int类型对应的数据库类型');
+INSERT INTO `sys_dictionaries` VALUES (4, '2020-07-05 15:33:07', '2020-07-05 16:07:18', NULL, '数据库时间日期类型', 'time.Time', 1, '数据库时间日期类型');
+INSERT INTO `sys_dictionaries` VALUES (5, '2020-07-05 15:34:23', '2020-07-05 15:52:45', NULL, '数据库浮点型', 'float64', 1, '数据库浮点型');
+INSERT INTO `sys_dictionaries` VALUES (6, '2020-07-05 15:35:05', '2020-07-05 15:35:05', NULL, '数据库字符串', 'string', 1, '数据库字符串');
+INSERT INTO `sys_dictionaries` VALUES (7, '2020-07-05 15:36:48', '2020-07-05 15:36:48', NULL, '数据库bool类型', 'bool', 1, '数据库bool类型');
+
+-- ----------------------------
+-- Table structure for sys_dictionary_details
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dictionary_details`;
+CREATE TABLE `sys_dictionary_details`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `created_at` datetime(0) NULL DEFAULT NULL,
+  `updated_at` datetime(0) NULL DEFAULT NULL,
+  `deleted_at` datetime(0) NULL DEFAULT NULL,
+  `label` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '展示值',
+  `value` int(11) NULL DEFAULT NULL COMMENT '字典值',
+  `status` tinyint(1) NULL DEFAULT NULL COMMENT '启用状态',
+  `sort` int(11) NULL DEFAULT NULL COMMENT '排序标记',
+  `sys_dictionary_id` int(11) NULL DEFAULT NULL COMMENT '关联标记',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sys_dictionary_details_deleted_at`(`deleted_at`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+
+-- ----------------------------
+-- Records of sys_dictionary_details
+-- ----------------------------
+INSERT INTO `sys_dictionary_details` VALUES (12, '2020-07-05 15:31:41', '2020-07-05 15:31:41', NULL, 'smallint', 1, 1, 1, 3);
+INSERT INTO `sys_dictionary_details` VALUES (13, '2020-07-05 15:31:52', '2020-07-05 15:31:52', NULL, 'mediumint', 2, 1, 2, 3);
+INSERT INTO `sys_dictionary_details` VALUES (14, '2020-07-05 15:32:04', '2020-07-05 15:32:04', NULL, 'int', 3, 1, 3, 3);
+INSERT INTO `sys_dictionary_details` VALUES (15, '2020-07-05 15:32:11', '2020-07-05 15:32:11', NULL, 'bigint', 4, 1, 4, 3);
+INSERT INTO `sys_dictionary_details` VALUES (19, '2020-07-05 15:33:16', '2020-07-05 15:33:16', NULL, 'data', 0, 1, 0, 4);
+INSERT INTO `sys_dictionary_details` VALUES (20, '2020-07-05 15:33:21', '2020-07-05 15:33:21', NULL, 'time', 1, 1, 1, 4);
+INSERT INTO `sys_dictionary_details` VALUES (21, '2020-07-05 15:33:25', '2020-07-05 15:33:25', NULL, 'year', 2, 1, 2, 4);
+INSERT INTO `sys_dictionary_details` VALUES (22, '2020-07-05 15:33:35', '2020-07-05 15:33:35', NULL, 'datetime', 3, 1, 3, 4);
+INSERT INTO `sys_dictionary_details` VALUES (23, '2020-07-05 15:33:42', '2020-07-05 15:33:42', NULL, 'timestamp', 5, 1, 5, 4);
+INSERT INTO `sys_dictionary_details` VALUES (24, '2020-07-05 15:34:30', '2020-07-05 15:34:30', NULL, 'float', 0, 1, 0, 5);
+INSERT INTO `sys_dictionary_details` VALUES (25, '2020-07-05 15:34:35', '2020-07-05 15:34:35', NULL, 'double', 1, 1, 1, 5);
+INSERT INTO `sys_dictionary_details` VALUES (26, '2020-07-05 15:34:41', '2020-07-05 15:34:41', NULL, 'decimal', 2, 1, 2, 5);
+INSERT INTO `sys_dictionary_details` VALUES (27, '2020-07-05 15:37:45', '2020-07-05 15:37:45', NULL, 'tinyint', 0, 1, 0, 7);
+INSERT INTO `sys_dictionary_details` VALUES (28, '2020-07-05 15:53:25', '2020-07-05 15:53:25', NULL, 'char', 0, 1, 0, 6);
+INSERT INTO `sys_dictionary_details` VALUES (29, '2020-07-05 15:53:29', '2020-07-05 15:53:29', NULL, 'varchar', 1, 1, 1, 6);
+INSERT INTO `sys_dictionary_details` VALUES (30, '2020-07-05 15:53:35', '2020-07-05 15:53:35', NULL, 'tinyblob', 2, 1, 2, 6);
+INSERT INTO `sys_dictionary_details` VALUES (31, '2020-07-05 15:53:40', '2020-07-05 15:53:40', NULL, 'tinytext', 3, 1, 3, 6);
+INSERT INTO `sys_dictionary_details` VALUES (32, '2020-07-05 15:53:48', '2020-07-05 15:53:48', NULL, 'text', 4, 1, 4, 6);
+INSERT INTO `sys_dictionary_details` VALUES (33, '2020-07-05 15:53:55', '2020-07-05 15:53:55', NULL, 'blob', 5, 1, 5, 6);
+INSERT INTO `sys_dictionary_details` VALUES (34, '2020-07-05 15:54:02', '2020-07-05 15:54:02', NULL, 'mediumblob', 6, 1, 6, 6);
+INSERT INTO `sys_dictionary_details` VALUES (35, '2020-07-05 15:54:09', '2020-07-05 15:54:09', NULL, 'mediumtext', 7, 1, 7, 6);
+INSERT INTO `sys_dictionary_details` VALUES (36, '2020-07-05 15:54:16', '2020-07-05 15:54:16', NULL, 'longblob', 8, 1, 8, 6);
+INSERT INTO `sys_dictionary_details` VALUES (37, '2020-07-05 15:54:24', '2020-07-05 15:54:24', NULL, 'longtext', 9, 1, 9, 6);
+
+-- ----------------------------
+-- Table structure for sys_operation_records
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_operation_records`;
+CREATE TABLE `sys_operation_records`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `created_at` datetime(0) NULL DEFAULT NULL,
+  `updated_at` datetime(0) NULL DEFAULT NULL,
+  `deleted_at` datetime(0) NULL DEFAULT NULL,
+  `ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '请求ip',
+  `method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '请求方法',
+  `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '请求路由',
+  `status` int(11) NULL DEFAULT NULL COMMENT '状态',
+  `latency` bigint(20) NULL DEFAULT NULL,
+  `agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
+  `error_message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
+  `body` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '请求Body',
+  `user_id` int(11) NULL DEFAULT NULL COMMENT '用户id',
+  `resp` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '响应Body',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sys_operation_records_deleted_at`(`deleted_at`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 342 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
+
 -- ----------------------------
 -- Table structure for sys_users
 -- ----------------------------
@@ -547,12 +630,12 @@ CREATE TABLE `sys_users`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `uuid` varbinary(255) NULL DEFAULT NULL COMMENT '用户UUID',
+  `uuid` varbinary(255) NULL DEFAULT NULL COMMENT 'uuid',
   `nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'QMPlusUser' COMMENT '用户昵称',
   `header_img` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'http://www.henrongyi.top/avatar/lufu.jpg' COMMENT '用户头像',
-  `authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '888' COMMENT '用户角色ID',
-  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户登录名',
-  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户登录密码',
+  `authority_id` double NULL DEFAULT 888 COMMENT '用户角色',
+  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '登录用户名',
+  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '登录密码',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_users_deleted_at`(`deleted_at`) USING BTREE,
   INDEX `idx_sys_users_deleted_at`(`deleted_at`) USING BTREE
@@ -561,8 +644,8 @@ CREATE TABLE `sys_users`  (
 -- ----------------------------
 -- Records of sys_users
 -- ----------------------------
-INSERT INTO `sys_users` VALUES (10, '2019-09-13 17:23:46', '2020-05-06 16:09:15', NULL, 0x63653064363638352D633135662D343132362D613562342D383930626339643233353664, '超级管理员', 'http://qmplusimg.henrongyi.top/15887525450B978439-F04A-4a09-A8D3-DE7DE2677142.png', '888', 'admin', 'e10adc3949ba59abbe56e057f20f883e');
-INSERT INTO `sys_users` VALUES (11, '2019-09-13 17:27:29', '2020-05-09 17:43:44', NULL, 0x66643665663739622D393434632D343838382D383337372D616265326432363038383538, 'QMPlusUser', 'http://qmplusimg.henrongyi.top/1572075907logo.png', '9528', 'a303176530', '3ec063004a6f31642261936a379fde3d');
+INSERT INTO `sys_users` VALUES (10, '2019-09-13 17:23:46', '2020-06-26 21:17:50', NULL, 0x63653064363638352D633135662D343132362D613562342D383930626339643233353664, '超级管理员', 'http://qmplusimg.henrongyi.top/1571627762timg.jpg', 888, 'admin', 'e10adc3949ba59abbe56e057f20f883e');
+INSERT INTO `sys_users` VALUES (11, '2019-09-13 17:27:29', '2019-09-13 17:27:29', NULL, 0x66643665663739622D393434632D343838382D383337372D616265326432363038383538, 'QMPlusUser', 'http://qmplusimg.henrongyi.top/1572075907logo.png', 9528, 'a303176530', '3ec063004a6f31642261936a379fde3d');
 
 -- ----------------------------
 -- Table structure for sys_workflow_step_infos
@@ -573,13 +656,13 @@ CREATE TABLE `sys_workflow_step_infos`  (
   `created_at` timestamp(0) NULL DEFAULT NULL,
   `updated_at` timestamp(0) NULL DEFAULT NULL,
   `deleted_at` timestamp(0) NULL DEFAULT NULL,
-  `workflow_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '所属工作流ID',
-  `is_strat` tinyint(1) NULL DEFAULT NULL COMMENT '是否是开始节点',
-  `step_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '工作流节点名称',
-  `step_no` double NULL DEFAULT NULL COMMENT '步骤id (第几步',
-  `step_authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作者级别id',
-  `is_end` tinyint(1) NULL DEFAULT NULL COMMENT '是否是完结流节点',
-  `sys_workflow_id` int(10) UNSIGNED NULL DEFAULT NULL,
+  `workflow_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '节点id',
+  `is_strat` tinyint(1) NULL DEFAULT NULL COMMENT '是否是开始节点',
+  `step_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '步骤name',
+  `step_no` double NULL DEFAULT NULL COMMENT '第几步',
+  `step_authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '可操作者角色',
+  `is_end` tinyint(1) NULL DEFAULT NULL COMMENT '是否是结尾',
+  `sys_workflow_id` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '关联工作流id',
   PRIMARY KEY (`id`) USING BTREE,
   INDEX `idx_workflow_step_infos_deleted_at`(`deleted_at`) USING BTREE,
   INDEX `idx_sys_workflow_step_infos_deleted_at`(`deleted_at`) USING BTREE
@@ -591,21 +674,15 @@ CREATE TABLE `sys_workflow_step_infos`  (
 DROP TABLE IF EXISTS `sys_workflows`;
 CREATE TABLE `sys_workflows`  (
   `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `created_at` timestamp(0) NULL DEFAULT NULL,
-  `updated_at` timestamp(0) NULL DEFAULT NULL,
-  `deleted_at` timestamp(0) NULL DEFAULT NULL,
+  `created_at` datetime(0) NULL DEFAULT NULL,
+  `updated_at` datetime(0) NULL DEFAULT NULL,
+  `deleted_at` datetime(0) NULL DEFAULT NULL,
   `workflow_nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '工作流中文名称',
   `workflow_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '工作流英文名称',
   `workflow_description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '工作流描述',
   PRIMARY KEY (`id`) USING BTREE,
-  INDEX `idx_workflows_deleted_at`(`deleted_at`) USING BTREE,
   INDEX `idx_sys_workflows_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-
--- ----------------------------
--- Records of sys_workflows
--- ----------------------------
-INSERT INTO `sys_workflows` VALUES (8, '2019-12-09 15:20:21', '2019-12-09 15:20:21', NULL, '测试改版1', 'test', '123123');
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
 
 -- ----------------------------
 -- View structure for authority_menu

File diff suppressed because it is too large
+ 699 - 114
server/docs/docs.go


File diff suppressed because it is too large
+ 698 - 113
server/docs/swagger.json


+ 510 - 10
server/docs/swagger.yaml

@@ -53,6 +53,10 @@ definitions:
     properties:
       accessKey:
         type: string
+      bucket:
+        type: string
+      imgPath:
+        type: string
       secretKey:
         type: string
     type: object
@@ -123,6 +127,10 @@ definitions:
     properties:
       abbreviation:
         type: string
+      autoCreateApiToSql:
+        type: boolean
+      description:
+        type: string
       fields:
         items:
           $ref: '#/definitions/model.Field'
@@ -131,6 +139,8 @@ definitions:
         type: string
       structName:
         type: string
+      tableName:
+        type: string
     type: object
   model.ExaCustomer:
     properties:
@@ -161,10 +171,20 @@ definitions:
     properties:
       columnName:
         type: string
+      comment:
+        type: string
+      dataType:
+        type: string
+      dataTypeLong:
+        type: string
+      fieldDesc:
+        type: string
       fieldJson:
         type: string
       fieldName:
         type: string
+      fieldSearchType:
+        type: string
       fieldType:
         type: string
     type: object
@@ -237,6 +257,60 @@ definitions:
       title:
         type: string
     type: object
+  model.SysDictionary:
+    properties:
+      desc:
+        type: string
+      name:
+        type: string
+      status:
+        type: boolean
+      sysDictionaryDetails:
+        items:
+          $ref: '#/definitions/model.SysDictionaryDetail'
+        type: array
+      type:
+        type: string
+    type: object
+  model.SysDictionaryDetail:
+    properties:
+      label:
+        type: string
+      sort:
+        type: integer
+      status:
+        type: boolean
+      sysDictionaryID:
+        type: integer
+      value:
+        type: integer
+    type: object
+  model.SysOperationRecord:
+    properties:
+      agent:
+        type: string
+      body:
+        type: string
+      error_message:
+        type: string
+      ip:
+        type: string
+      latency:
+        type: string
+      method:
+        type: string
+      path:
+        type: string
+      resp:
+        type: string
+      status:
+        type: integer
+      user:
+        $ref: '#/definitions/model.SysUser'
+        type: object
+      user_id:
+        type: integer
+    type: object
   model.SysUser:
     properties:
       authority:
@@ -385,13 +459,79 @@ definitions:
       uuid:
         type: string
     type: object
+  request.SysDictionaryDetailSearch:
+    properties:
+      label:
+        type: string
+      page:
+        type: integer
+      pageSize:
+        type: integer
+      sort:
+        type: integer
+      status:
+        type: boolean
+      sysDictionaryID:
+        type: integer
+      value:
+        type: integer
+    type: object
+  request.SysDictionarySearch:
+    properties:
+      desc:
+        type: string
+      name:
+        type: string
+      page:
+        type: integer
+      pageSize:
+        type: integer
+      status:
+        type: boolean
+      sysDictionaryDetails:
+        items:
+          $ref: '#/definitions/model.SysDictionaryDetail'
+        type: array
+      type:
+        type: string
+    type: object
+  request.SysOperationRecordSearch:
+    properties:
+      agent:
+        type: string
+      body:
+        type: string
+      error_message:
+        type: string
+      ip:
+        type: string
+      latency:
+        type: string
+      method:
+        type: string
+      page:
+        type: integer
+      pageSize:
+        type: integer
+      path:
+        type: string
+      resp:
+        type: string
+      status:
+        type: integer
+      user:
+        $ref: '#/definitions/model.SysUser'
+        type: object
+      user_id:
+        type: integer
+    type: object
   response.SysAuthorityCopyResponse:
     properties:
       authority:
         $ref: '#/definitions/model.SysAuthority'
         type: object
       oldAuthorityId:
-        type: integer
+        type: string
     type: object
 info:
   contact: {}
@@ -704,24 +844,24 @@ paths:
       summary: 自动代码模板
       tags:
       - SysApi
-  /base/captcha:
-    post:
+  /autoCode/getDatabase:
+    get:
       consumes:
       - application/json
       produces:
       - application/json
       responses:
         "200":
-          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          description: '{"success":true,"data":{},"msg":"创建成功"}'
           schema:
             type: string
       security:
       - ApiKeyAuth: []
-      summary: 生成验证码
+      summary: 获取当前表所有字段
       tags:
-      - base
-  /base/captcha/:
-    get:
+      - SysApi
+  /base/captcha:
+    post:
       consumes:
       - application/json
       produces:
@@ -733,7 +873,7 @@ paths:
             type: string
       security:
       - ApiKeyAuth: []
-      summary: 生成验证码图片路径
+      summary: 生成验证码
       tags:
       - base
   /base/login:
@@ -1327,6 +1467,366 @@ paths:
       summary: 更新菜单
       tags:
       - menu
+  /sysDictionary/createSysDictionary:
+    post:
+      consumes:
+      - application/json
+      parameters:
+      - description: 创建SysDictionary
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionary'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 创建SysDictionary
+      tags:
+      - SysDictionary
+  /sysDictionary/deleteSysDictionary:
+    delete:
+      consumes:
+      - application/json
+      parameters:
+      - description: 删除SysDictionary
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionary'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"删除成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 删除SysDictionary
+      tags:
+      - SysDictionary
+  /sysDictionary/findSysDictionary:
+    get:
+      consumes:
+      - application/json
+      parameters:
+      - description: 用id查询SysDictionary
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionary'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"查询成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 用id查询SysDictionary
+      tags:
+      - SysDictionary
+  /sysDictionary/getSysDictionaryList:
+    get:
+      consumes:
+      - application/json
+      parameters:
+      - description: 分页获取SysDictionary列表
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/request.SysDictionarySearch'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 分页获取SysDictionary列表
+      tags:
+      - SysDictionary
+  /sysDictionary/updateSysDictionary:
+    put:
+      consumes:
+      - application/json
+      parameters:
+      - description: 更新SysDictionary
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionary'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"更新成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 更新SysDictionary
+      tags:
+      - SysDictionary
+  /sysDictionaryDetail/createSysDictionaryDetail:
+    post:
+      consumes:
+      - application/json
+      parameters:
+      - description: 创建SysDictionaryDetail
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionaryDetail'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 创建SysDictionaryDetail
+      tags:
+      - SysDictionaryDetail
+  /sysDictionaryDetail/deleteSysDictionaryDetail:
+    delete:
+      consumes:
+      - application/json
+      parameters:
+      - description: 删除SysDictionaryDetail
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionaryDetail'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"删除成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 删除SysDictionaryDetail
+      tags:
+      - SysDictionaryDetail
+  /sysDictionaryDetail/findSysDictionaryDetail:
+    get:
+      consumes:
+      - application/json
+      parameters:
+      - description: 用id查询SysDictionaryDetail
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionaryDetail'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"查询成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 用id查询SysDictionaryDetail
+      tags:
+      - SysDictionaryDetail
+  /sysDictionaryDetail/getSysDictionaryDetailList:
+    get:
+      consumes:
+      - application/json
+      parameters:
+      - description: 分页获取SysDictionaryDetail列表
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/request.SysDictionaryDetailSearch'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 分页获取SysDictionaryDetail列表
+      tags:
+      - SysDictionaryDetail
+  /sysDictionaryDetail/updateSysDictionaryDetail:
+    put:
+      consumes:
+      - application/json
+      parameters:
+      - description: 更新SysDictionaryDetail
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysDictionaryDetail'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"更新成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 更新SysDictionaryDetail
+      tags:
+      - SysDictionaryDetail
+  /sysOperationRecord/createSysOperationRecord:
+    post:
+      consumes:
+      - application/json
+      parameters:
+      - description: 创建SysOperationRecord
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysOperationRecord'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 创建SysOperationRecord
+      tags:
+      - SysOperationRecord
+  /sysOperationRecord/deleteSysOperationRecord:
+    delete:
+      consumes:
+      - application/json
+      parameters:
+      - description: 删除SysOperationRecord
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysOperationRecord'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"删除成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 删除SysOperationRecord
+      tags:
+      - SysOperationRecord
+  /sysOperationRecord/findSysOperationRecord:
+    get:
+      consumes:
+      - application/json
+      parameters:
+      - description: 用id查询SysOperationRecord
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysOperationRecord'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"查询成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 用id查询SysOperationRecord
+      tags:
+      - SysOperationRecord
+  /sysOperationRecord/getSysOperationRecordList:
+    get:
+      consumes:
+      - application/json
+      parameters:
+      - description: 分页获取SysOperationRecord列表
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/request.SysOperationRecordSearch'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"获取成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 分页获取SysOperationRecord列表
+      tags:
+      - SysOperationRecord
+  /sysOperationRecord/updateSysOperationRecord:
+    put:
+      consumes:
+      - application/json
+      parameters:
+      - description: 更新SysOperationRecord
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/model.SysOperationRecord'
+          type: object
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: '{"success":true,"data":{},"msg":"更新成功"}'
+          schema:
+            type: string
+      security:
+      - ApiKeyAuth: []
+      summary: 更新SysOperationRecord
+      tags:
+      - SysOperationRecord
   /system/ReloadSystem:
     post:
       parameters:
@@ -1417,7 +1917,7 @@ paths:
         name: data
         required: true
         schema:
-          $ref: '#/definitions/request.SetUserAuth'
+          $ref: '#/definitions/request.GetById'
           type: object
       produces:
       - application/json

+ 6 - 6
server/go.mod

@@ -6,16 +6,16 @@ require (
 	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
 	github.com/casbin/casbin v1.9.1
 	github.com/casbin/gorm-adapter v1.0.0
-	github.com/dchest/captcha v0.0.0-20170622155422-6a29415a8364
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
 	github.com/fsnotify/fsnotify v1.4.9
+	github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
 	github.com/gin-gonic/gin v1.6.3
 	github.com/go-openapi/spec v0.19.7 // indirect
 	github.com/go-openapi/swag v0.19.8 // indirect
 	github.com/go-playground/validator/v10 v10.3.0 // indirect
 	github.com/go-redis/redis v6.15.7+incompatible
-	github.com/go-sql-driver/mysql v1.5.0 // indirect
+	github.com/go-sql-driver/mysql v1.5.0
 	github.com/golang/protobuf v1.4.2 // indirect
 	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
 	github.com/jinzhu/gorm v1.9.12
@@ -26,14 +26,15 @@ require (
 	github.com/lib/pq v1.3.0 // indirect
 	github.com/mailru/easyjson v0.7.1 // indirect
 	github.com/mitchellh/mapstructure v1.2.2 // indirect
+	github.com/mojocn/base64Captcha v1.3.1
 	github.com/onsi/ginkgo v1.7.0 // indirect
 	github.com/onsi/gomega v1.4.3 // indirect
 	github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
 	github.com/pelletier/go-toml v1.6.0 // indirect
-	github.com/piexlmax/gvaplug v0.0.5
+	github.com/piexlmax/gvaplug v0.0.8
 	github.com/pkg/errors v0.9.1 // indirect
-	github.com/qiniu/api.v7 v7.2.5+incompatible
-	github.com/qiniu/x v7.0.8+incompatible // indirect
+	github.com/qiniu/api.v7/v7 v7.4.1
+	github.com/qiniu/x v1.10.5
 	github.com/satori/go.uuid v1.2.0
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/spf13/cast v1.3.1 // indirect
@@ -51,5 +52,4 @@ require (
 	google.golang.org/protobuf v1.24.0 // indirect
 	gopkg.in/ini.v1 v1.55.0 // indirect
 	gopkg.in/yaml.v2 v2.3.0 // indirect
-	qiniupkg.com/x v7.0.8+incompatible // indirect
 )

+ 3 - 0
server/initialize/db_table.go

@@ -15,10 +15,13 @@ func DBTables() {
 		model.JwtBlacklist{},
 		model.SysWorkflow{},
 		model.SysWorkflowStepInfo{},
+		model.SysDictionary{},
+		model.SysDictionaryDetail{},
 		model.ExaFileUploadAndDownload{},
 		model.ExaFile{},
 		model.ExaFileChunk{},
 		model.ExaCustomer{},
+		model.SysOperationRecord{},
 	)
 	global.GVA_LOG.Debug("register table success")
 }

+ 9 - 11
server/initialize/plug.go

@@ -6,20 +6,18 @@ import (
 )
 
 type Plug interface {
-	InitRouter(*gin.Engine) error
+	InitRouter([2]*gin.RouterGroup) error
 	InitModel(*gorm.DB) error
 }
 
-func InstallPlug(db *gorm.DB, router *gin.Engine, p ...Plug) (err error) {
-	for _, v := range p {
-		err = v.InitModel(db)
-		if err != nil {
-			return err
-		}
-		err = v.InitRouter(router)
-		if err != nil {
-			return err
-		}
+func InstallPlug(db *gorm.DB, router [2]*gin.RouterGroup, p Plug) (err error) {
+	err = p.InitModel(db)
+	if err != nil {
+		return err
+	}
+	err = p.InitRouter(router)
+	if err != nil {
+		return err
 	}
 	return nil
 }

+ 3 - 0
server/initialize/router.go

@@ -35,6 +35,9 @@ func Routers() *gin.Engine {
 	router.InitSystemRouter(ApiGroup)                // system相关路由
 	router.InitCustomerRouter(ApiGroup)              // 客户路由
 	router.InitAutoCodeRouter(ApiGroup)              // 创建自动化代码
+	router.InitSysDictionaryDetailRouter(ApiGroup)   // 字典详情管理
+	router.InitSysDictionaryRouter(ApiGroup)         // 字典管理
+	router.InitSysOperationRecordRouter(ApiGroup)    // 操作记录
 	global.GVA_LOG.Info("router register success")
 	return Router
 }

+ 68 - 0
server/middleware/operation.go

@@ -0,0 +1,68 @@
+package middleware
+
+import (
+	"bytes"
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	"gin-vue-admin/service"
+	"github.com/gin-gonic/gin"
+	"io/ioutil"
+	"net/http"
+	"strconv"
+	"time"
+)
+
+func OperationRecord() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		var body []byte
+		if c.Request.Method != http.MethodGet {
+			var err error
+			body, err = ioutil.ReadAll(c.Request.Body)
+			if err != nil {
+				global.GVA_LOG.Error("read body from request error:", err)
+			} else {
+				c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
+			}
+		}
+		userId, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
+		if err != nil {
+			userId = 0
+		}
+		record := model.SysOperationRecord{
+			Ip:     c.ClientIP(),
+			Method: c.Request.Method,
+			Path:   c.Request.URL.Path,
+			Agent:  c.Request.UserAgent(),
+			Body:   string(body),
+			UserId: userId,
+		}
+		writer := responseBodyWriter{
+			ResponseWriter: c.Writer,
+			body:           &bytes.Buffer{},
+		}
+		c.Writer = writer
+		now := time.Now()
+
+		c.Next()
+
+		latency := time.Now().Sub(now)
+		record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
+		record.Status = c.Writer.Status()
+		record.Latency = latency
+		record.Resp = writer.body.String()
+
+		if err := service.CreateSysOperationRecord(record); err != nil {
+			global.GVA_LOG.Error("create operation record error:", err)
+		}
+	}
+}
+
+type responseBodyWriter struct {
+	gin.ResponseWriter
+	body *bytes.Buffer
+}
+
+func (r responseBodyWriter) Write(b []byte) (int, error) {
+	r.body.Write(b)
+	return r.ResponseWriter.Write(b)
+}

+ 4 - 0
server/model/request/common.go

@@ -10,3 +10,7 @@ type PageInfo struct {
 type GetById struct {
 	Id float64 `json:"id" form:"id"`
 }
+
+type IdsReq struct {
+	Ids []int `json:"ids" form:"ids"`
+}

+ 16 - 0
server/model/request/sys_autocode.go

@@ -0,0 +1,16 @@
+package request
+
+type DBReq struct {
+	Database string `json:"database";gorm:"column:database"`
+}
+
+type TableReq struct {
+	TableName string `json:"tableName"`
+}
+
+type ColumeReq struct {
+	ColumeName    string `json:"columeName";gorm:"column:colume_name"`
+	DataType      string `json:"dataType";gorm:"column:data_type"`
+	DataTypeLong  string `json:"dataTypeLong";gorm:"column:data_type_long"`
+	ColumeComment string `json:"columeComment";gorm:"column:colume_comment"`
+}

+ 8 - 0
server/model/request/sys_dictionary.go

@@ -0,0 +1,8 @@
+package request
+
+import "gin-vue-admin/model"
+
+type SysDictionarySearch struct{
+    model.SysDictionary
+    PageInfo
+}

+ 8 - 0
server/model/request/sys_dictionary_detail.go

@@ -0,0 +1,8 @@
+package request
+
+import "gin-vue-admin/model"
+
+type SysDictionaryDetailSearch struct{
+    model.SysDictionaryDetail
+    PageInfo
+}

+ 8 - 0
server/model/request/sys_operation_record.go

@@ -0,0 +1,8 @@
+package request
+
+import "gin-vue-admin/model"
+
+type SysOperationRecordSearch struct {
+	model.SysOperationRecord
+	PageInfo
+}

+ 3 - 0
server/model/sys_auto_code.go

@@ -3,6 +3,7 @@ package model
 // 初始版本自动化代码工具
 type AutoCodeStruct struct {
 	StructName         string  `json:"structName"`
+	TableName          string  `json:"tableName"`
 	PackageName        string  `json:"packageName"`
 	Abbreviation       string  `json:"abbreviation"`
 	Description        string  `json:"description"`
@@ -15,6 +16,8 @@ type Field struct {
 	FieldDesc       string `json:"fieldDesc"`
 	FieldType       string `json:"fieldType"`
 	FieldJson       string `json:"fieldJson"`
+	DataType        string `json:"dataType"`
+	DataTypeLong    string `json:"dataTypeLong"`
 	Comment         string `json:"comment"`
 	ColumnName      string `json:"columnName"`
 	FieldSearchType string `json:"fieldSearchType"`

+ 16 - 0
server/model/sys_dictionary.go

@@ -0,0 +1,16 @@
+// 自动生成模板SysDictionary
+package model
+
+import (
+	"github.com/jinzhu/gorm"
+)
+
+// 如果含有time.Time 请自行import time包
+type SysDictionary struct {
+	gorm.Model
+	Name                 string                `json:"name" form:"name" gorm:"column:name;comment:'字典名(中)'"`
+	Type                 string                `json:"type" form:"type" gorm:"column:type;comment:'字典名(英)'"`
+	Status               *bool                 `json:"status" form:"status" gorm:"column:status;comment:'状态'"`
+	Desc                 string                `json:"desc" form:"desc" gorm:"column:desc;comment:'描述'"`
+	SysDictionaryDetails []SysDictionaryDetail `json:"sysDictionaryDetails" form:"sysDictionaryDetails"`
+}

+ 16 - 0
server/model/sys_dictionary_detail.go

@@ -0,0 +1,16 @@
+// 自动生成模板SysDictionaryDetail
+package model
+
+import (
+	"github.com/jinzhu/gorm"
+)
+
+// 如果含有time.Time 请自行import time包
+type SysDictionaryDetail struct {
+      gorm.Model
+      Label  string `json:"label" form:"label" gorm:"column:label;comment:'展示值'"`
+      Value  int `json:"value" form:"value" gorm:"column:value;comment:'字典值'"`
+      Status  *bool `json:"status" form:"status" gorm:"column:status;comment:'启用状态'"`
+      Sort  int `json:"sort" form:"sort" gorm:"column:sort;comment:'排序标记'"`
+      SysDictionaryID  int `json:"sysDictionaryID" form:"sysDictionaryID" gorm:"column:sys_dictionary_id;comment:'关联标记'"` 
+}

+ 23 - 0
server/model/sys_operation_record.go

@@ -0,0 +1,23 @@
+// 自动生成模板SysOperationRecord
+package model
+
+import (
+	"github.com/jinzhu/gorm"
+	"time"
+)
+
+// 如果含有time.Time 请自行import time包
+type SysOperationRecord struct {
+	gorm.Model
+	Ip           string        `json:"ip" form:"ip" gorm:"column:ip;comment:'请求ip'"`
+	Method       string        `json:"method" form:"method" gorm:"column:method;comment:''"`
+	Path         string        `json:"path" form:"path" gorm:"column:path;comment:''"`
+	Status       int           `json:"status" form:"status" gorm:"column:status;comment:''"`
+	Latency      time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:''"`
+	Agent        string        `json:"agent" form:"agent" gorm:"column:agent;comment:''"`
+	ErrorMessage string        `json:"error_message" form:"error_message" gorm:"column:error_message;comment:''"`
+	Body         string        `json:"body" form:"body" gorm:"column:body;comment:'请求Body'"`
+	Resp         string        `json:"resp" form:"resp" gorm:"column:resp;comment:'响应Body'"`
+	UserId       int           `json:"user_id" form:"user_id" gorm:"column:user_id;comment:''"`
+	User         SysUser       `json:"user"`
+}

+ 16 - 0
server/resource/template/fe/api.js.tpl

@@ -33,6 +33,22 @@ export const create{{.StructName}} = (data) => {
      })
  }
 
+// @Tags {{.StructName}}
+// @Summary 删除{{.StructName}}
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除{{.StructName}}"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /{{.Abbreviation}}/delete{{.StructName}} [delete]
+ export const delete{{.StructName}}ByIds = (data) => {
+     return service({
+         url: "/{{.Abbreviation}}/delete{{.StructName}}ByIds",
+         method: 'delete',
+         data
+     })
+ }
+
 // @Tags {{.StructName}}
 // @Summary 更新{{.StructName}}
 // @Security ApiKeyAuth

+ 71 - 9
server/resource/template/fe/table.vue.tpl

@@ -2,23 +2,46 @@
   <div>
     <div class="search-term">
       <el-form :inline="true" :model="searchInfo" class="demo-form-inline">
-           {{- range .Fields}}
-              {{- if .FieldSearchType}}
+           {{- range .Fields}}  {{- if .FieldSearchType}} {{- if eq .FieldType "bool" }}
+            <el-form-item label="{{.FieldDesc}}" prop="{{.FieldJson}}">
+            <el-select v-model="searchInfo.{{.FieldJson}}" clear placeholder="请选择">
+                <el-option
+                    key="true"
+                    label="是"
+                    value="true">
+                </el-option>
+                <el-option
+                    key="false"
+                    label="否"
+                    value="false">
+                </el-option>
+            </el-select>
+            </el-form-item>
+                  {{- else }}
         <el-form-item label="{{.FieldDesc}}">
           <el-input placeholder="搜索条件" v-model="searchInfo.{{.FieldJson}}"></el-input>
-        </el-form-item>
-              {{ end }}
-           {{ end }}
+        </el-form-item> {{ end }} {{ end }}  {{ end }}
         <el-form-item>
           <el-button @click="onSubmit" type="primary">查询</el-button>
         </el-form-item>
         <el-form-item>
-          <el-button @click="openDialog" type="primary">新增api</el-button>
+          <el-button @click="openDialog" type="primary">新增{{.Description}}</el-button>
+        </el-form-item>
+        <el-form-item>
+          <el-popover placement="top" v-model="deleteVisible" width="160">
+            <p>确定要删除吗?</p>
+              <div style="text-align: right; margin: 0">
+                <el-button @click="deleteVisible = false" size="mini" type="text">取消</el-button>
+                <el-button @click="onDelete" size="mini" type="primary">确定</el-button>
+              </div>
+            <el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">批量删除</el-button>
+          </el-popover>
         </el-form-item>
       </el-form>
     </div>
     <el-table
       :data="tableData"
+      @selection-change="handleSelectionChange"
       border
       ref="multipleTable"
       stripe
@@ -29,8 +52,11 @@
     <el-table-column label="日期" width="180">
          <template slot-scope="scope">{{ "{{scope.row.CreatedAt|formatDate}}" }}</template>
     </el-table-column>
-    {{range .Fields}}
-     <el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120"></el-table-column>
+    {{range .Fields}}  {{- if eq .FieldType "bool" }}
+    <el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120">
+         <template slot-scope="scope">{{ "{{scope.row."}}{{.FieldJson}}{{"|formatBoolean}}" }}</template>
+    </el-table-column> {{- else }}
+    <el-table-column label="{{.FieldDesc}}" prop="{{.FieldJson}}" width="120"></el-table-column> {{ end }}
     {{ end }}
       <el-table-column label="按钮组">
         <template slot-scope="scope">
@@ -72,6 +98,7 @@
 import {
     create{{.StructName}},
     delete{{.StructName}},
+    delete{{.StructName}}ByIds,
     update{{.StructName}},
     find{{.StructName}},
     get{{.StructName}}List
@@ -88,6 +115,8 @@ export default {
       dialogFormVisible: false,
       visible: false,
       type: "",
+      deleteVisible: false,
+      multipleSelection: [],
       formData: {
         {{range .Fields}}{{.FieldJson}}:null,{{ end }}
       }
@@ -101,6 +130,13 @@ export default {
       } else {
         return "";
       }
+    },
+    formatBoolean: function(bool) {
+      if (bool != null) {
+        return bool ? "是" :"否";
+      } else {
+        return "";
+      }
     }
   },
   methods: {
@@ -108,8 +144,31 @@ export default {
       onSubmit() {
         this.page = 1
         this.pageSize = 10
+        {{- range .Fields}} {{- if eq .FieldType "bool" }}      
+        if (this.searchInfo.{{.FieldJson}}==""){
+          this.searchInfo.{{.FieldJson}}=null
+        } {{ end }} {{ end }}    
         this.getTableData()
       },
+      handleSelectionChange(val) {
+        this.multipleSelection = val
+      },
+      async onDelete() {
+        const ids = []
+        this.multipleSelection &&
+          this.multipleSelection.map(item => {
+            ids.push(item.ID)
+          })
+        const res = await delete{{.StructName}}ByIds({ ids })
+        if (res.code == 0) {
+          this.$message({
+            type: 'success',
+            message: '删除成功'
+          })
+          this.deleteVisible = false
+          this.getTableData()
+        }
+      },
     async update{{.StructName}}(row) {
       const res = await find{{.StructName}}({ ID: row.ID });
       this.type = "update";
@@ -149,8 +208,11 @@ export default {
           res = await create{{.StructName}}(this.formData);
           break;
       }
-
       if (res.code == 0) {
+        this.$message({
+          type:"success",
+          message:"创建/更改成功"
+        })
         this.closeDialog();
         this.getTableData();
       }

+ 19 - 0
server/resource/template/te/api.go.tpl

@@ -48,6 +48,25 @@ func Delete{{.StructName}}(c *gin.Context) {
 	}
 }
 
+// @Tags {{.StructName}}
+// @Summary 批量删除{{.StructName}}
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "批量删除{{.StructName}}"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /{{.Abbreviation}}/delete{{.StructName}}ByIds [delete]
+func Delete{{.StructName}}ByIds(c *gin.Context) {
+	var IDS request.IdsReq
+    _ = c.ShouldBindJSON(&IDS)
+	err := service.Delete{{.StructName}}ByIds(IDS)
+	if err != nil {
+		response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
+	} else {
+		response.OkWithMessage("删除成功", c)
+	}
+}
+
 // @Tags {{.StructName}}
 // @Summary 更新{{.StructName}}
 // @Security ApiKeyAuth

+ 12 - 2
server/resource/template/te/model.go.tpl

@@ -7,6 +7,16 @@ import (
 
 // 如果含有time.Time 请自行import time包
 type {{.StructName}} struct {
-      gorm.Model {{range .Fields}}
-      {{.FieldName}}  {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:'{{.Comment}}'"`{{ end }}
+      gorm.Model {{- range .Fields}}
+            {{- if eq .FieldType "bool" }}
+      {{.FieldName}}  *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:'{{.Comment}}'{{- if .DataType -}};type:{{.DataType}}{{- if .DataTypeLong -}}({{.DataTypeLong}}){{- end -}}{{- end -}}"`
+            {{- else }}
+      {{.FieldName}}  {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"column:{{.ColumnName}};comment:'{{.Comment}}'{{- if .DataType -}};type:{{.DataType}}{{- if .DataTypeLong -}}({{.DataTypeLong}}){{- end -}}{{- end -}}"`
+            {{- end }}  {{- end }} 
 }
+
+{{ if .TableName }}
+func ({{.StructName}}) TableName() string {
+  return "{{.TableName}}"
+}
+{{ end }}

+ 2 - 1
server/resource/template/te/router.go.tpl

@@ -7,10 +7,11 @@ import (
 )
 
 func Init{{.StructName}}Router(Router *gin.RouterGroup) {
-	{{.StructName}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	{{.StructName}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()).Use(middleware.OperationRecord())
 	{
 		{{.StructName}}Router.POST("create{{.StructName}}", v1.Create{{.StructName}})   // 新建{{.StructName}}
 		{{.StructName}}Router.DELETE("delete{{.StructName}}", v1.Delete{{.StructName}}) // 删除{{.StructName}}
+		{{.StructName}}Router.DELETE("delete{{.StructName}}ByIds", v1.Delete{{.StructName}}ByIds) // 批量删除{{.StructName}}
 		{{.StructName}}Router.PUT("update{{.StructName}}", v1.Update{{.StructName}})    // 更新{{.StructName}}
 		{{.StructName}}Router.GET("find{{.StructName}}", v1.Find{{.StructName}})        // 根据ID获取{{.StructName}}
 		{{.StructName}}Router.GET("get{{.StructName}}List", v1.Get{{.StructName}}List)  // 获取{{.StructName}}列表

+ 14 - 3
server/resource/template/te/service.go.tpl

@@ -28,6 +28,17 @@ func Delete{{.StructName}}({{.Abbreviation}} model.{{.StructName}}) (err error)
 	return err
 }
 
+// @title    Delete{{.StructName}}ByIds
+// @description   delete {{.StructName}}s
+// @auth                     (2020/04/05  20:22)
+// @param     {{.Abbreviation}}               model.{{.StructName}}
+// @return                    error
+
+func Delete{{.StructName}}ByIds(ids request.IdsReq) (err error) {
+	err = global.GVA_DB.Delete(&[]model.{{.StructName}}{},"id in (?)",ids.Ids).Error
+	return err
+}
+
 // @title    Update{{.StructName}}
 // @description   update a {{.StructName}}
 // @param     {{.Abbreviation}}          *model.{{.StructName}}
@@ -61,7 +72,7 @@ func Get{{.StructName}}InfoList(info request.{{.StructName}}Search) (err error,
 	limit := info.PageSize
 	offset := info.PageSize * (info.Page - 1)
     // 创建db
-	db := global.GVA_DB
+	db := global.GVA_DB.Model(&model.{{.StructName}}{})
     var {{.Abbreviation}}s []model.{{.StructName}}
     // 如果有条件搜索 下方会自动创建搜索语句
         {{- range .Fields}}
@@ -71,7 +82,7 @@ func Get{{.StructName}}InfoList(info request.{{.StructName}}Search) (err error,
         db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }})
     }
                 {{- else if eq .FieldType "bool" }}
-    if info.{{.FieldName}} != 0 {
+    if info.{{.FieldName}} != nil {
         db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }})
     }
                 {{- else if eq .FieldType "int" }}
@@ -89,7 +100,7 @@ func Get{{.StructName}}InfoList(info request.{{.StructName}}Search) (err error,
                 {{- end }}
         {{- end }}
     {{- end }}
-	err = db.Find(&{{.Abbreviation}}s).Count(&total).Error
+	err = db.Count(&total).Error
 	err = db.Limit(limit).Offset(offset).Find(&{{.Abbreviation}}s).Error
 	return err, {{.Abbreviation}}s, total
 }

+ 4 - 1
server/router/exp_customer.go

@@ -7,7 +7,10 @@ import (
 )
 
 func InitCustomerRouter(Router *gin.RouterGroup) {
-	ApiRouter := Router.Group("customer").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	ApiRouter := Router.Group("customer").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
 	{
 		ApiRouter.POST("customer", v1.CreateExaCustomer)     // 创建客户
 		ApiRouter.PUT("customer", v1.UpdateExaCustomer)      // 更新客户

+ 4 - 1
server/router/sys_authority.go

@@ -7,7 +7,10 @@ import (
 )
 
 func InitAuthorityRouter(Router *gin.RouterGroup) {
-	AuthorityRouter := Router.Group("authority").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	AuthorityRouter := Router.Group("authority").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
 	{
 		AuthorityRouter.POST("createAuthority", v1.CreateAuthority)   // 创建角色
 		AuthorityRouter.POST("deleteAuthority", v1.DeleteAuthority)   // 删除角色

+ 7 - 1
server/router/sys_auto_code.go

@@ -7,8 +7,14 @@ import (
 )
 
 func InitAutoCodeRouter(Router *gin.RouterGroup) {
-	AutoCodeRouter := Router.Group("autoCode").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	AutoCodeRouter := Router.Group("autoCode").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
 	{
 		AutoCodeRouter.POST("createTemp", v1.CreateTemp) // 创建自动化代码
+		AutoCodeRouter.GET("getTables", v1.GetTables)    // 获取对应数据库的表
+		AutoCodeRouter.GET("getDB", v1.GetDB)            // 获取数据库
+		AutoCodeRouter.GET("getColume", v1.GetColume)    // 获取指定表所有字段信息
 	}
 }

+ 0 - 1
server/router/sys_base.go

@@ -11,7 +11,6 @@ func InitBaseRouter(Router *gin.RouterGroup) (R gin.IRoutes) {
 		BaseRouter.POST("register", v1.Register)
 		BaseRouter.POST("login", v1.Login)
 		BaseRouter.POST("captcha", v1.Captcha)
-		BaseRouter.GET("captcha/:captchaId", v1.CaptchaImg)
 	}
 	return BaseRouter
 }

+ 4 - 1
server/router/sys_casbin.go

@@ -7,7 +7,10 @@ import (
 )
 
 func InitCasbinRouter(Router *gin.RouterGroup) {
-	CasbinRouter := Router.Group("casbin").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	CasbinRouter := Router.Group("casbin").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
 	{
 		CasbinRouter.POST("updateCasbin", v1.UpdateCasbin)
 		CasbinRouter.POST("getPolicyPathByAuthorityId", v1.GetPolicyPathByAuthorityId)

+ 21 - 0
server/router/sys_dictionary.go

@@ -0,0 +1,21 @@
+package router
+
+import (
+	"gin-vue-admin/api/v1"
+	"gin-vue-admin/middleware"
+	"github.com/gin-gonic/gin"
+)
+
+func InitSysDictionaryRouter(Router *gin.RouterGroup) {
+	SysDictionaryRouter := Router.Group("sysDictionary").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
+	{
+		SysDictionaryRouter.POST("createSysDictionary", v1.CreateSysDictionary)   // 新建SysDictionary
+		SysDictionaryRouter.DELETE("deleteSysDictionary", v1.DeleteSysDictionary) // 删除SysDictionary
+		SysDictionaryRouter.PUT("updateSysDictionary", v1.UpdateSysDictionary)    // 更新SysDictionary
+		SysDictionaryRouter.GET("findSysDictionary", v1.FindSysDictionary)        // 根据ID获取SysDictionary
+		SysDictionaryRouter.GET("getSysDictionaryList", v1.GetSysDictionaryList)  // 获取SysDictionary列表
+	}
+}

+ 21 - 0
server/router/sys_dictionary_detail.go

@@ -0,0 +1,21 @@
+package router
+
+import (
+	"gin-vue-admin/api/v1"
+	"gin-vue-admin/middleware"
+	"github.com/gin-gonic/gin"
+)
+
+func InitSysDictionaryDetailRouter(Router *gin.RouterGroup) {
+	SysDictionaryDetailRouter := Router.Group("sysDictionaryDetail").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
+	{
+		SysDictionaryDetailRouter.POST("createSysDictionaryDetail", v1.CreateSysDictionaryDetail)   // 新建SysDictionaryDetail
+		SysDictionaryDetailRouter.DELETE("deleteSysDictionaryDetail", v1.DeleteSysDictionaryDetail) // 删除SysDictionaryDetail
+		SysDictionaryDetailRouter.PUT("updateSysDictionaryDetail", v1.UpdateSysDictionaryDetail)    // 更新SysDictionaryDetail
+		SysDictionaryDetailRouter.GET("findSysDictionaryDetail", v1.FindSysDictionaryDetail)        // 根据ID获取SysDictionaryDetail
+		SysDictionaryDetailRouter.GET("getSysDictionaryDetailList", v1.GetSysDictionaryDetailList)  // 获取SysDictionaryDetail列表
+	}
+}

+ 22 - 0
server/router/sys_operation_record.go

@@ -0,0 +1,22 @@
+package router
+
+import (
+	"gin-vue-admin/api/v1"
+	"gin-vue-admin/middleware"
+	"github.com/gin-gonic/gin"
+)
+
+func InitSysOperationRecordRouter(Router *gin.RouterGroup) {
+	SysOperationRecordRouter := Router.Group("sysOperationRecord").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler())
+	{
+		SysOperationRecordRouter.POST("createSysOperationRecord", v1.CreateSysOperationRecord)   // 新建SysOperationRecord
+		SysOperationRecordRouter.DELETE("deleteSysOperationRecord", v1.DeleteSysOperationRecord) // 删除SysOperationRecord
+		SysOperationRecordRouter.DELETE("deleteSysOperationRecordByIds", v1.DeleteSysOperationRecordByIds) // 批量删除SysOperationRecord
+		SysOperationRecordRouter.PUT("updateSysOperationRecord", v1.UpdateSysOperationRecord)    // 更新SysOperationRecord
+		SysOperationRecordRouter.GET("findSysOperationRecord", v1.FindSysOperationRecord)        // 根据ID获取SysOperationRecord
+		SysOperationRecordRouter.GET("getSysOperationRecordList", v1.GetSysOperationRecordList)  // 获取SysOperationRecord列表
+
+	}
+}

+ 4 - 1
server/router/sys_user.go

@@ -7,7 +7,10 @@ import (
 )
 
 func InitUserRouter(Router *gin.RouterGroup) {
-	UserRouter := Router.Group("user").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	UserRouter := Router.Group("user").
+		Use(middleware.JWTAuth()).
+		Use(middleware.CasbinHandler()).
+		Use(middleware.OperationRecord())
 	{
 		UserRouter.POST("changePassword", v1.ChangePassword)     // 修改密码
 		UserRouter.POST("uploadHeaderImg", v1.UploadHeaderImg)   // 上传头像

+ 2 - 2
server/service/exa_customer.go

@@ -61,7 +61,7 @@ func GetExaCustomer(id uint) (err error, customer model.ExaCustomer) {
 func GetCustomerInfoList(sysUserAuthorityID string, info request.PageInfo) (err error, list interface{}, total int) {
 	limit := info.PageSize
 	offset := info.PageSize * (info.Page - 1)
-	db := global.GVA_DB
+	db := global.GVA_DB.Model(&model.ExaCustomer{})
 	var a model.SysAuthority
 	a.AuthorityId = sysUserAuthorityID
 	err, auth := GetAuthorityInfo(a)
@@ -70,7 +70,7 @@ func GetCustomerInfoList(sysUserAuthorityID string, info request.PageInfo) (err
 		dataId = append(dataId, v.AuthorityId)
 	}
 	var CustomerList []model.ExaCustomer
-	err = db.Where("sys_user_authority_id in (?)", dataId).Find(&CustomerList).Count(&total).Error
+	err = db.Where("sys_user_authority_id in (?)", dataId).Count(&total).Error
 	if err != nil {
 		return err, CustomerList, total
 	} else {

+ 2 - 2
server/service/sys_api.go

@@ -49,7 +49,7 @@ func DeleteApi(api model.SysApi) (err error) {
 func GetAPIInfoList(api model.SysApi, info request.PageInfo, order string, desc bool) (err error, list interface{}, total int) {
 	limit := info.PageSize
 	offset := info.PageSize * (info.Page - 1)
-	db := global.GVA_DB
+	db := global.GVA_DB.Model(&model.SysApi{})
 	var apiList []model.SysApi
 
 	if api.Path != "" {
@@ -68,7 +68,7 @@ func GetAPIInfoList(api model.SysApi, info request.PageInfo, order string, desc
 		db = db.Where("api_group = ?", api.ApiGroup)
 	}
 
-	err = db.Find(&apiList).Count(&total).Error
+	err = db.Count(&total).Error
 
 	if err != nil {
 		return err, apiList, total

+ 17 - 0
server/service/sys_auto_code.go

@@ -1,7 +1,9 @@
 package service
 
 import (
+	"gin-vue-admin/global"
 	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
 	"gin-vue-admin/utils"
 	"io/ioutil"
 	"os"
@@ -115,3 +117,18 @@ func GetAllTplFile(pathName string, fileList []string) ([]string, error) {
 	}
 	return fileList, err
 }
+
+func GetTables(dbName string) (err error, TableNames []request.TableReq) {
+	err = global.GVA_DB.Raw("select table_name as table_name from information_schema.tables where table_schema = ?", dbName).Scan(&TableNames).Error
+	return err, TableNames
+}
+
+func GetDB() (err error, DBNames []request.DBReq) {
+	err = global.GVA_DB.Raw("SELECT SCHEMA_NAME AS `database` FROM INFORMATION_SCHEMA.SCHEMATA;").Scan(&DBNames).Error
+	return err, DBNames
+}
+
+func GetColume(tableName string, dbName string) (err error, Columes []request.ColumeReq) {
+	err = global.GVA_DB.Raw("SELECT COLUMN_NAME colume_name,DATA_TYPE data_type,CASE DATA_TYPE WHEN 'longtext' THEN c.CHARACTER_MAXIMUM_LENGTH WHEN 'varchar' THEN c.CHARACTER_MAXIMUM_LENGTH WHEN 'double' THEN CONCAT_WS( ',', c.NUMERIC_PRECISION, c.NUMERIC_SCALE ) WHEN 'decimal' THEN CONCAT_WS( ',', c.NUMERIC_PRECISION, c.NUMERIC_SCALE ) WHEN 'int' THEN c.NUMERIC_PRECISION WHEN 'bigint' THEN c.NUMERIC_PRECISION ELSE '' END AS data_type_long,COLUMN_COMMENT colume_comment FROM INFORMATION_SCHEMA.COLUMNS c WHERE table_name = ? AND table_schema = ?", tableName, dbName).Scan(&Columes).Error
+	return err, Columes
+}

+ 102 - 0
server/service/sys_dictionary.go

@@ -0,0 +1,102 @@
+package service
+
+import (
+	"errors"
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
+)
+
+// @title    CreateSysDictionary
+// @description   create a SysDictionary
+// @param     sysDictionary               model.SysDictionary
+// @auth                     (2020/04/05  20:22)
+// @return    err             error
+
+func CreateSysDictionary(sysDictionary model.SysDictionary) (err error) {
+	if (!global.GVA_DB.First(&model.SysDictionary{}, "type = ?", sysDictionary.Type).RecordNotFound()) {
+		return errors.New("存在相同的type,不允许创建")
+	}
+	err = global.GVA_DB.Create(&sysDictionary).Error
+	return err
+}
+
+// @title    DeleteSysDictionary
+// @description   delete a SysDictionary
+// @auth                     (2020/04/05  20:22)
+// @param     sysDictionary               model.SysDictionary
+// @return                    error
+
+func DeleteSysDictionary(sysDictionary model.SysDictionary) (err error) {
+	err = global.GVA_DB.Delete(sysDictionary).Related(&sysDictionary.SysDictionaryDetails).Delete(&sysDictionary.SysDictionaryDetails).Error
+	return err
+}
+
+// @title    UpdateSysDictionary
+// @description   update a SysDictionary
+// @param     sysDictionary          *model.SysDictionary
+// @auth                     (2020/04/05  20:22)
+// @return                    error
+
+func UpdateSysDictionary(sysDictionary *model.SysDictionary) (err error) {
+	var dict model.SysDictionary
+	sysDictionaryMap := map[string]interface{}{
+		"Name":   sysDictionary.Name,
+		"Type":   sysDictionary.Type,
+		"Status": sysDictionary.Status,
+		"Desc":   sysDictionary.Desc,
+	}
+	db := global.GVA_DB.Where("id = ?", sysDictionary.ID).First(&dict)
+	if dict.Type == sysDictionary.Type {
+		err = db.Updates(sysDictionaryMap).Error
+	} else {
+		if (!global.GVA_DB.First(&model.SysDictionary{}, "type = ?", sysDictionary.Type).RecordNotFound()) {
+			return errors.New("存在相同的type,不允许创建")
+		} else {
+			err = db.Updates(sysDictionaryMap).Error
+		}
+	}
+	return err
+}
+
+// @title    GetSysDictionary
+// @description   get the info of a SysDictionary
+// @auth                     (2020/04/05  20:22)
+// @param     id              uint
+// @return                    error
+// @return    SysDictionary        SysDictionary
+
+func GetSysDictionary(Type string, Id uint) (err error, sysDictionary model.SysDictionary) {
+	err = global.GVA_DB.Where("type = ? OR id = ?", Type, Id).Preload("SysDictionaryDetails").First(&sysDictionary).Error
+	return
+}
+
+// @title    GetSysDictionaryInfoList
+// @description   get SysDictionary list by pagination, 分页获取用户列表
+// @auth                     (2020/04/05  20:22)
+// @param     info            PageInfo
+// @return                    error
+
+func GetSysDictionaryInfoList(info request.SysDictionarySearch) (err error, list interface{}, total int) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	// 创建db
+	db := global.GVA_DB.Model(&model.SysDictionary{})
+	var sysDictionarys []model.SysDictionary
+	// 如果有条件搜索 下方会自动创建搜索语句
+	if info.Name != "" {
+		db = db.Where("name LIKE ?", "%"+info.Name+"%")
+	}
+	if info.Type != "" {
+		db = db.Where("type LIKE ?", "%"+info.Type+"%")
+	}
+	if info.Status != nil {
+		db = db.Where("status = ?", info.Status)
+	}
+	if info.Desc != "" {
+		db = db.Where("desc LIKE ?", "%"+info.Desc+"%")
+	}
+	err = db.Count(&total).Error
+	err = db.Limit(limit).Offset(offset).Find(&sysDictionarys).Error
+	return err, sysDictionarys, total
+}

+ 82 - 0
server/service/sys_dictionary_detail.go

@@ -0,0 +1,82 @@
+package service
+
+import (
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
+)
+
+// @title    CreateSysDictionaryDetail
+// @description   create a SysDictionaryDetail
+// @param     sysDictionaryDetail               model.SysDictionaryDetail
+// @auth                     (2020/04/05  20:22)
+// @return    err             error
+
+func CreateSysDictionaryDetail(sysDictionaryDetail model.SysDictionaryDetail) (err error) {
+	err = global.GVA_DB.Create(&sysDictionaryDetail).Error
+	return err
+}
+
+// @title    DeleteSysDictionaryDetail
+// @description   delete a SysDictionaryDetail
+// @auth                     (2020/04/05  20:22)
+// @param     sysDictionaryDetail               model.SysDictionaryDetail
+// @return                    error
+
+func DeleteSysDictionaryDetail(sysDictionaryDetail model.SysDictionaryDetail) (err error) {
+	err = global.GVA_DB.Delete(sysDictionaryDetail).Error
+	return err
+}
+
+// @title    UpdateSysDictionaryDetail
+// @description   update a SysDictionaryDetail
+// @param     sysDictionaryDetail          *model.SysDictionaryDetail
+// @auth                     (2020/04/05  20:22)
+// @return                    error
+
+func UpdateSysDictionaryDetail(sysDictionaryDetail *model.SysDictionaryDetail) (err error) {
+	err = global.GVA_DB.Save(sysDictionaryDetail).Error
+	return err
+}
+
+// @title    GetSysDictionaryDetail
+// @description   get the info of a SysDictionaryDetail
+// @auth                     (2020/04/05  20:22)
+// @param     id              uint
+// @return                    error
+// @return    SysDictionaryDetail        SysDictionaryDetail
+
+func GetSysDictionaryDetail(id uint) (err error, sysDictionaryDetail model.SysDictionaryDetail) {
+	err = global.GVA_DB.Where("id = ?", id).First(&sysDictionaryDetail).Error
+	return
+}
+
+// @title    GetSysDictionaryDetailInfoList
+// @description   get SysDictionaryDetail list by pagination, 分页获取用户列表
+// @auth                     (2020/04/05  20:22)
+// @param     info            PageInfo
+// @return                    error
+
+func GetSysDictionaryDetailInfoList(info request.SysDictionaryDetailSearch) (err error, list interface{}, total int) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	// 创建db
+	db := global.GVA_DB.Model(&model.SysDictionaryDetail{})
+	var sysDictionaryDetails []model.SysDictionaryDetail
+	// 如果有条件搜索 下方会自动创建搜索语句
+	if info.Label != "" {
+		db = db.Where("label LIKE ?", "%"+info.Label+"%")
+	}
+	if info.Value != 0 {
+		db = db.Where("value = ?", info.Value)
+	}
+	if info.Status != nil {
+		db = db.Where("status = ?", info.Status)
+	}
+	if info.SysDictionaryID != 0 {
+		db = db.Where("sys_dictionary_id = ?", info.SysDictionaryID)
+	}
+	err = db.Count(&total).Error
+	err = db.Limit(limit).Offset(offset).Find(&sysDictionaryDetails).Error
+	return err, sysDictionaryDetails, total
+}

+ 90 - 0
server/service/sys_operation_record.go

@@ -0,0 +1,90 @@
+package service
+
+import (
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	"gin-vue-admin/model/request"
+)
+
+// @title    CreateSysOperationRecord
+// @description   create a SysOperationRecord
+// @param     sysOperationRecord               model.SysOperationRecord
+// @auth                     (2020/04/05  20:22)
+// @return    err             error
+
+func CreateSysOperationRecord(sysOperationRecord model.SysOperationRecord) (err error) {
+	err = global.GVA_DB.Create(&sysOperationRecord).Error
+	return err
+}
+
+// @title    DeleteSysOperationRecord
+// @description   delete SysOperationRecords
+// @auth                     (2020/04/05  20:22)
+// @param     sysOperationRecord               request.IdsReq
+// @return                    error
+
+func DeleteSysOperationRecordByIds(ids request.IdsReq) (err error) {
+	err = global.GVA_DB.Delete(&[]model.SysOperationRecord{},"id in (?)",ids.Ids).Error
+	return err
+}
+
+// @title    DeleteSysOperationRecord
+// @description   delete a SysOperationRecord
+// @auth                     (2020/04/05  20:22)
+// @param     sysOperationRecord               model.SysOperationRecord
+// @return                    error
+
+func DeleteSysOperationRecord(sysOperationRecord model.SysOperationRecord) (err error) {
+	err = global.GVA_DB.Delete(sysOperationRecord).Error
+	return err
+}
+
+// @title    UpdateSysOperationRecord
+// @description   update a SysOperationRecord
+// @param     sysOperationRecord          *model.SysOperationRecord
+// @auth                     (2020/04/05  20:22)
+// @return                    error
+
+func UpdateSysOperationRecord(sysOperationRecord *model.SysOperationRecord) (err error) {
+	err = global.GVA_DB.Save(sysOperationRecord).Error
+	return err
+}
+
+// @title    GetSysOperationRecord
+// @description   get the info of a SysOperationRecord
+// @auth                     (2020/04/05  20:22)
+// @param     id              uint
+// @return                    error
+// @return    SysOperationRecord        SysOperationRecord
+
+func GetSysOperationRecord(id uint) (err error, sysOperationRecord model.SysOperationRecord) {
+	err = global.GVA_DB.Where("id = ?", id).First(&sysOperationRecord).Error
+	return
+}
+
+// @title    GetSysOperationRecordInfoList
+// @description   get SysOperationRecord list by pagination, 分页获取用户列表
+// @auth                     (2020/04/05  20:22)
+// @param     info            PageInfo
+// @return                    error
+
+func GetSysOperationRecordInfoList(info request.SysOperationRecordSearch) (err error, list interface{}, total int) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	// 创建db
+	db := global.GVA_DB.Model(&model.SysOperationRecord{})
+	var sysOperationRecords []model.SysOperationRecord
+	// 如果有条件搜索 下方会自动创建搜索语句
+	if info.Method != "" {
+		db = db.Where("method = ?", info.Method)
+	}
+	if info.Path != "" {
+		db = db.Where("path LIKE ?", "%"+info.Path+"%")
+	}
+	if info.Status != 0 {
+		db = db.Where("status = ?", info.Status)
+	}
+	err = db.Count(&total).Error
+	err = db.Order("id desc").Limit(limit).Offset(offset).Preload("User").Find(&sysOperationRecords).Error
+	return err, sysOperationRecords, total
+}

+ 2 - 3
server/service/sys_user.go

@@ -56,7 +56,6 @@ func Login(u *model.SysUser) (err error, userInter *model.SysUser) {
 
 func ChangePassword(u *model.SysUser, newPassword string) (err error, userInter *model.SysUser) {
 	var user model.SysUser
-	// TODO:后期修改jwt+password模式
 	u.Password = utils.MD5V([]byte(u.Password))
 	err = global.GVA_DB.Where("username = ? AND password = ?", u.Username, u.Password).First(&user).Update("password", utils.MD5V([]byte(newPassword))).Error
 	return err, u
@@ -73,9 +72,9 @@ func ChangePassword(u *model.SysUser, newPassword string) (err error, userInter
 func GetUserInfoList(info request.PageInfo) (err error, list interface{}, total int) {
 	limit := info.PageSize
 	offset := info.PageSize * (info.Page - 1)
-	db := global.GVA_DB
+	db := global.GVA_DB.Model(&model.SysUser{})
 	var userList []model.SysUser
-	err = db.Find(&userList).Count(&total).Error
+	err = db.Count(&total).Error
 	err = db.Limit(limit).Offset(offset).Preload("Authority").Find(&userList).Error
 	return err, userList, total
 }

+ 0 - 55
server/utils/captcha.go

@@ -1,55 +0,0 @@
-package utils
-
-import (
-	"bytes"
-	"fmt"
-	"gin-vue-admin/global"
-	"github.com/dchest/captcha"
-	"net/http"
-	"path"
-	"strings"
-	"time"
-)
-
-// 这里需要自行实现captcha 的gin模式
-func GinCaptchaServeHTTP(w http.ResponseWriter, r *http.Request) {
-	dir, file := path.Split(r.URL.Path)
-	ext := path.Ext(file)
-	id := file[:len(file)-len(ext)]
-	if ext == "" || id == "" {
-		http.NotFound(w, r)
-		return
-	}
-	fmt.Println("reload : " + r.FormValue("reload"))
-	if r.FormValue("reload") != "" {
-		captcha.Reload(id)
-	}
-	lang := strings.ToLower(r.FormValue("lang"))
-	download := path.Base(dir) == "download"
-	if Serve(w, r, id, ext, lang, download, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.ImgHeight) == captcha.ErrNotFound {
-		http.NotFound(w, r)
-	}
-}
-
-func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool, width, height int) error {
-	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
-	w.Header().Set("Pragma", "no-cache")
-	w.Header().Set("Expires", "0")
-	var content bytes.Buffer
-	switch ext {
-	case ".png":
-		w.Header().Set("Content-Type", "image/png")
-		_ = captcha.WriteImage(&content, id, width, height)
-	case ".wav":
-		w.Header().Set("Content-Type", "audio/x-wav")
-		_ = captcha.WriteAudio(&content, id, lang)
-	default:
-		return captcha.ErrNotFound
-	}
-
-	if download {
-		w.Header().Set("Content-Type", "application/octet-stream")
-	}
-	http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes()))
-	return nil
-}

+ 4 - 22
server/utils/directory.go

@@ -1,8 +1,8 @@
 package utils
 
 import (
+	"gin-vue-admin/global"
 	"os"
-	"path/filepath"
 )
 
 // @title    PathExists
@@ -32,33 +32,15 @@ func CreateDir(dirs ...string) (err error) {
 	for _, v := range dirs {
 		exist, err := PathExists(v)
 		if err != nil {
-			// log.L.Info(fmt.Sprintf("get dir error![%v]\n", err))
 			return err
 		}
-		if exist {
-			// log.L.Info(fmt.Sprintf("has dir![%v]\n"+_dir))
-		} else {
-			// log.L.Info(fmt.Sprintf("no dir![%v]\n"+_dir))
-			// 创建文件夹
+		if !exist {
+			global.GVA_LOG.Debug("create directory ", v)
 			err = os.MkdirAll(v, os.ModePerm)
 			if err != nil {
-				// log.L.Error(fmt.Sprintf("mkdir error![%v]\n",err))
-			} else {
-				// log.L.Info("mkdir success!\n")
+				global.GVA_LOG.Error("create directory", v, " error:", err)
 			}
 		}
 	}
 	return err
 }
-
-// @title cwd
-// @description 获取当前工作目录
-// @return string
-
-func CWD() string {
-	path, err := os.Executable()
-	if err != nil {
-		return ""
-	}
-	return filepath.Dir(path)
-}

+ 2 - 2
server/utils/upload.go

@@ -4,8 +4,8 @@ import (
 	"context"
 	"fmt"
 	"gin-vue-admin/global"
-	"github.com/qiniu/api.v7/auth/qbox"
-	"github.com/qiniu/api.v7/storage"
+	"github.com/qiniu/api.v7/v7/auth/qbox"
+	"github.com/qiniu/api.v7/v7/storage"
 	"mime/multipart"
 	"time"
 )

+ 47 - 0
web/src/api/autoCode.js

@@ -18,4 +18,51 @@ export const createTemp = (data) => {
         data,
         responseType: 'blob'
     })
+}
+
+
+// @Tags SysApi
+// @Summary 获取当前所有数据库
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getDatabase [get]
+export const getDB = () => {
+    return service({
+        url: "/autoCode/getDB",
+        method: 'get',
+    })
+}
+
+
+
+// @Tags SysApi
+// @Summary 获取当前数据库所有表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getTables [get]
+export const getTable = (params) => {
+    return service({
+        url: "/autoCode/getTables",
+        method: 'get',
+        params,
+    })
+}
+
+// @Tags SysApi
+// @Summary 获取当前数据库所有表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/getColume [get]
+export const getColume = (params) => {
+    return service({
+        url: "/autoCode/getColume",
+        method: 'get',
+        params,
+    })
 }

+ 84 - 0
web/src/api/sysDictionary.js

@@ -0,0 +1,84 @@
+import service from '@/utils/request'
+
+// @Tags SysDictionary
+// @Summary 创建SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "创建SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionary/createSysDictionary [post]
+export const createSysDictionary = (data) => {
+     return service({
+         url: "/sysDictionary/createSysDictionary",
+         method: 'post',
+         data
+     })
+ }
+
+
+// @Tags SysDictionary
+// @Summary 删除SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "删除SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysDictionary/deleteSysDictionary [delete]
+ export const deleteSysDictionary = (data) => {
+     return service({
+         url: "/sysDictionary/deleteSysDictionary",
+         method: 'delete',
+         data
+     })
+ }
+
+// @Tags SysDictionary
+// @Summary 更新SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "更新SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysDictionary/updateSysDictionary [put]
+ export const updateSysDictionary = (data) => {
+     return service({
+         url: "/sysDictionary/updateSysDictionary",
+         method: 'put',
+         data
+     })
+ }
+
+
+// @Tags SysDictionary
+// @Summary 用id查询SysDictionary
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionary true "用id查询SysDictionary"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysDictionary/findSysDictionary [get]
+ export const findSysDictionary = (params) => {
+     return service({
+         url: "/sysDictionary/findSysDictionary",
+         method: 'get',
+         params
+     })
+ }
+
+
+// @Tags SysDictionary
+// @Summary 分页获取SysDictionary列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.PageInfo true "分页获取SysDictionary列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionary/getSysDictionaryList [get]
+ export const getSysDictionaryList = (params) => {
+     return service({
+         url: "/sysDictionary/getSysDictionaryList",
+         method: 'get',
+         params
+     })
+ }

+ 84 - 0
web/src/api/sysDictionaryDetail.js

@@ -0,0 +1,84 @@
+import service from '@/utils/request'
+
+// @Tags SysDictionaryDetail
+// @Summary 创建SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "创建SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
+export const createSysDictionaryDetail = (data) => {
+     return service({
+         url: "/sysDictionaryDetail/createSysDictionaryDetail",
+         method: 'post',
+         data
+     })
+ }
+
+
+// @Tags SysDictionaryDetail
+// @Summary 删除SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "删除SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
+ export const deleteSysDictionaryDetail = (data) => {
+     return service({
+         url: "/sysDictionaryDetail/deleteSysDictionaryDetail",
+         method: 'delete',
+         data
+     })
+ }
+
+// @Tags SysDictionaryDetail
+// @Summary 更新SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
+ export const updateSysDictionaryDetail = (data) => {
+     return service({
+         url: "/sysDictionaryDetail/updateSysDictionaryDetail",
+         method: 'put',
+         data
+     })
+ }
+
+
+// @Tags SysDictionaryDetail
+// @Summary 用id查询SysDictionaryDetail
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
+ export const findSysDictionaryDetail = (params) => {
+     return service({
+         url: "/sysDictionaryDetail/findSysDictionaryDetail",
+         method: 'get',
+         params
+     })
+ }
+
+
+// @Tags SysDictionaryDetail
+// @Summary 分页获取SysDictionaryDetail列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.PageInfo true "分页获取SysDictionaryDetail列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
+ export const getSysDictionaryDetailList = (params) => {
+     return service({
+         url: "/sysDictionaryDetail/getSysDictionaryDetailList",
+         method: 'get',
+         params
+     })
+ }

+ 49 - 0
web/src/api/sysOperationRecord.js

@@ -0,0 +1,49 @@
+import service from '@/utils/request'
+
+// @Tags SysOperationRecord
+// @Summary 删除SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.SysOperationRecord true "删除SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
+export const deleteSysOperationRecord = (data) => {
+    return service({
+        url: "/sysOperationRecord/deleteSysOperationRecord",
+        method: 'delete',
+        data
+    })
+}
+
+// @Tags SysOperationRecord
+// @Summary 批量删除SysOperationRecord
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "删除SysOperationRecord"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
+export const deleteSysOperationRecordByIds = (data) => {
+    return service({
+        url: "/sysOperationRecord/deleteSysOperationRecordByIds",
+        method: 'delete',
+        data
+    })
+}
+
+// @Tags SysOperationRecord
+// @Summary 分页获取SysOperationRecord列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.PageInfo true "分页获取SysOperationRecord列表"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /sysOperationRecord/getSysOperationRecordList [get]
+export const getSysOperationRecordList = (params) => {
+    return service({
+        url: "/sysOperationRecord/getSysOperationRecordList",
+        method: 'get',
+        params
+    })
+}

+ 3 - 2
web/src/store/index.js

@@ -4,7 +4,7 @@ import VuexPersistence from 'vuex-persist'
 
 import { user } from "@/store/module/user"
 import { router } from "@/store/module/router"
-
+import { dictionary } from "@/store/module/dictionary"
 Vue.use(Vuex)
 
 
@@ -16,7 +16,8 @@ const vuexLocal = new VuexPersistence({
 export const store = new Vuex.Store({
     modules: {
         user,
-        router
+        router,
+        dictionary
     },
     plugins: [vuexLocal.plugin]
 })

+ 42 - 0
web/src/store/module/dictionary.js

@@ -0,0 +1,42 @@
+import { findSysDictionary } from '@/api/sysDictionary'
+
+export const dictionary = {
+    namespaced: true,
+    state: {
+        dictionaryMap: {},
+    },
+    mutations: {
+        setDictionaryMap(state, dictionaryMap) {
+            state.dictionaryMap = { ...state.dictionaryMap, ...dictionaryMap }
+        },
+
+    },
+    actions: {
+        // 从后台获取动态路由
+        async getDictionary({ commit, state }, type) {
+            if (state.dictionaryMap[type]) {
+                return state.dictionaryMap[type]
+            } else {
+                const res = await findSysDictionary({ type })
+                if (res.code == 0) {
+                    const dictionaryMap = {}
+                    const dict = []
+                    res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.map(item => {
+                        dict.push({
+                            label: item.label,
+                            value: item.value
+                        })
+                    })
+                    dictionaryMap[res.data.resysDictionary.type] = dict
+                    commit("setDictionaryMap", dictionaryMap)
+                    return state.dictionaryMap[type]
+                }
+            }
+        }
+    },
+    getters:{
+        getDictionary(state){
+            return state.dictionaryMap
+        }
+    }
+}

+ 6 - 0
web/src/utils/dictionary.js

@@ -0,0 +1,6 @@
+import { store } from '@/store/index'
+//  获取字典方法 使用示例 getDict('sex').then(res)  或者 async函数下 const res = await getDict('sex')
+export const getDict = async (type) => {
+    await store.dispatch("dictionary/getDictionary", type)
+    return store.getters["dictionary/getDictionary"][type]
+}

+ 9 - 7
web/src/utils/request.js

@@ -21,21 +21,23 @@ const showLoading = () => {
 }
 
 const closeLoading = () => {
-        acitveAxios--
-        if (acitveAxios <= 0) {
-            clearTimeout(timer)
-            loadingInstance && loadingInstance.close()
-        }
+    acitveAxios--
+    if (acitveAxios <= 0) {
+        clearTimeout(timer)
+        loadingInstance && loadingInstance.close()
     }
-    //http request 拦截器
+}
+//http request 拦截器
 service.interceptors.request.use(
     config => {
         showLoading()
         const token = store.getters['user/token']
+        const user = store.getters['user/userInfo']
         config.data = JSON.stringify(config.data);
         config.headers = {
             'Content-Type': 'application/json',
-            'x-token': token
+            'x-token': token,
+            'x-user-id':user.ID
         }
         return config;
     },

+ 8 - 1
web/src/utils/stringFun.js

@@ -10,4 +10,11 @@ export const toUpperCase = (str) => {
 export const toSQLLine = (str) => {
     if (str=="ID") return "ID"
     return str.replace(/([A-Z])/g,"_$1").toLowerCase();
-  }
+  }
+
+  // 下划线转换驼峰
+  export const  toHump = (name) => {
+    return name.replace(/\_(\w)/g, function(all, letter){
+        return letter.toUpperCase();
+    });
+}

+ 77 - 78
web/src/view/layout/screenfull/index.vue

@@ -1,6 +1,6 @@
 <template>
-    <div  @click="click">
-        <!-- <svg
+  <div @click="click">
+    <!-- <svg
             t="1508738709248"
             class="screenfull-svg"
             viewBox="0 0 1024 1024"
@@ -25,90 +25,89 @@
                     d="M333.590658 594.033341 167.8171 759.804852 64.218604 655.67219 64.218604 958.270996 366.342596 958.502263 262.234493 855.071589 428.421466 688.86108Z"
                     p-id="2073"/>
         </svg> -->
-        <svg 
-        t="1590133227479" 
-        class="screenfull-svg"
-        viewBox="0 0 1024 1024" 
-        version="1.1" 
-        width="20" 
-        height="20" 
-        xmlns="http://www.w3.org/2000/svg"  
-        v-if="isShow"
-        >
-                <path id="svg_1" d="m928.512,959.744a32,32 0 0 1 -32,-32l0,-256a32,32 0 0 1 64,0l0,256a32,32 0 0 1 -32,32z"/>
-                <path id="svg_2" d="m960.512,927.744a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32zm-864.768,-863.488a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z"/>
-                <path id="svg_3" d="m63.744,96.256a32,32 0 0 1 32,-32l256,0a32,32 0 0 1 0,64l-256,0a32,32 0 0 1 -32,-32z"/>
-                <path id="svg_4" d="m958.030718,91.777575a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32z"/>
-                <path id="svg_5" d="m926.030718,59.777575a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z"/>
-                <path id="svg_6" d="m940.622718,69.250038a32,32 0 0 1 0,45.248l-247.936,247.936a32,32 0 0 1 -45.248,-45.248l247.936,-247.936a31.936,31.936 0 0 1 45.248,0z"/>
-                <path id="svg_7" d="m61.649508,930.478492a32,32 0 0 1 32,-32l256,0a32,32 0 0 1 0,64l-256,0a32,32 0 0 1 -32,-32z"/>
-                <path id="svg_8" d="m93.649508,962.478492a32,32 0 0 1 -32,-32l0,-256a32,32 0 0 1 64,0l0,256a32,32 0 0 1 -32,32z"/>
-                <path id="svg_9" d="m79.121508,945.070492a32,32 0 0 1 0,-45.248l247.936,-247.936a32,32 0 0 1 45.248,45.248l-247.936,247.936a32,32 0 0 1 -45.248,0z"/>
-        </svg>
-        <svg 
-            t="1590133734869"  
-            class="screenfull-svg" 
-            viewBox="0 0 1024 1024"
-            version="1.1" 
-            xmlns="http://www.w3.org/2000/svg" 
-            p-id="1862" 
-            xmlns:xlink="http://www.w3.org/1999/xlink" 
-            width="20" 
-            height="20" 
-            v-else
-            >
-                <path d="M928.512 959.744a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1863"></path>
-                <path d="M960.512 927.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32zM95.744 64.256a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z" fill="" p-id="1864"></path>
-                <path d="M63.744 96.256a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1865"></path>
-                <path d="M384.064 671.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32z" fill="" p-id="1866"></path>
-                <path d="M352.064 639.744a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z" fill="" p-id="1867"></path>
-                <path d="M366.656 657.216a32 32 0 0 1 0 45.248L118.72 950.4a32 32 0 0 1-45.248-45.248l247.936-247.936a31.936 31.936 0 0 1 45.248 0z" fill="" p-id="1868"></path>
-                <path d="M639.616 352.512a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1869"></path>
-                <path d="M671.616 384.512a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1870"></path>
-                <path d="M657.088 367.104a32 32 0 0 1 0-45.248l247.936-247.936a32 32 0 0 1 45.248 45.248l-247.936 247.936a32 32 0 0 1-45.248 0z" fill="" p-id="1871"></path>
-        </svg>
-    </div>
+    <svg t="1590133227479" class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" width="20" height="20" xmlns="http://www.w3.org/2000/svg"
+      v-if="isShow">
+      <path id="svg_1" d="m928.512,959.744a32,32 0 0 1 -32,-32l0,-256a32,32 0 0 1 64,0l0,256a32,32 0 0 1 -32,32z" />
+      <path id="svg_2"
+        d="m960.512,927.744a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32zm-864.768,-863.488a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z" />
+      <path id="svg_3" d="m63.744,96.256a32,32 0 0 1 32,-32l256,0a32,32 0 0 1 0,64l-256,0a32,32 0 0 1 -32,-32z" />
+      <path id="svg_4" d="m958.030718,91.777575a32,32 0 0 1 -32,32l-256,0a32,32 0 0 1 0,-64l256,0a32,32 0 0 1 32,32z" />
+      <path id="svg_5" d="m926.030718,59.777575a32,32 0 0 1 32,32l0,256a32,32 0 0 1 -64,0l0,-256a32,32 0 0 1 32,-32z" />
+      <path id="svg_6"
+        d="m940.622718,69.250038a32,32 0 0 1 0,45.248l-247.936,247.936a32,32 0 0 1 -45.248,-45.248l247.936,-247.936a31.936,31.936 0 0 1 45.248,0z" />
+      <path id="svg_7" d="m61.649508,930.478492a32,32 0 0 1 32,-32l256,0a32,32 0 0 1 0,64l-256,0a32,32 0 0 1 -32,-32z" />
+      <path id="svg_8" d="m93.649508,962.478492a32,32 0 0 1 -32,-32l0,-256a32,32 0 0 1 64,0l0,256a32,32 0 0 1 -32,32z" />
+      <path id="svg_9"
+        d="m79.121508,945.070492a32,32 0 0 1 0,-45.248l247.936,-247.936a32,32 0 0 1 45.248,45.248l-247.936,247.936a32,32 0 0 1 -45.248,0z" />
+    </svg>
+    <svg t="1590133734869" class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1862"
+      xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" v-else>
+      <path d="M928.512 959.744a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1863"></path>
+      <path
+        d="M960.512 927.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32zM95.744 64.256a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z"
+        fill="" p-id="1864"></path>
+      <path d="M63.744 96.256a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1865"></path>
+      <path d="M384.064 671.744a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32z" fill="" p-id="1866"></path>
+      <path d="M352.064 639.744a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256a32 32 0 0 1 32-32z" fill="" p-id="1867"></path>
+      <path d="M366.656 657.216a32 32 0 0 1 0 45.248L118.72 950.4a32 32 0 0 1-45.248-45.248l247.936-247.936a31.936 31.936 0 0 1 45.248 0z" fill=""
+        p-id="1868"></path>
+      <path d="M639.616 352.512a32 32 0 0 1 32-32h256a32 32 0 0 1 0 64h-256a32 32 0 0 1-32-32z" fill="" p-id="1869"></path>
+      <path d="M671.616 384.512a32 32 0 0 1-32-32v-256a32 32 0 0 1 64 0v256a32 32 0 0 1-32 32z" fill="" p-id="1870"></path>
+      <path d="M657.088 367.104a32 32 0 0 1 0-45.248l247.936-247.936a32 32 0 0 1 45.248 45.248l-247.936 247.936a32 32 0 0 1-45.248 0z" fill=""
+        p-id="1871"></path>
+    </svg>
+  </div>
 </template>
 <script>
-import screenfull from 'screenfull'  //引入screenfull
+import screenfull from 'screenfull' //引入screenfull
 export default {
-    name: 'Screenfull',
-    props: {
-        width: {
-            type: Number,
-            default: 22
-        },
-        height: {
-            type: Number,
-            default: 22
-        },
-        fill: {
-            type: String,
-            default: '#48576a'
-        }
+  name: 'Screenfull',
+  props: {
+    width: {
+      type: Number,
+      default: 22,
+    },
+    height: {
+      type: Number,
+      default: 22,
     },
-    data(){
-        return {
-            isShow:true
-        }
+    fill: {
+      type: String,
+      default: '#48576a',
     },
-    methods: {
-        click () {
-            if (screenfull.isEnabled) {
-                this.isShow  = !this.isShow
-                screenfull.toggle()
-            }
-        }
+  },
+  data() {
+    return {
+      isShow: true,
+    }
+  },
+  mounted() {
+    if (screenfull.isEnabled) {
+      screenfull.on('change', this.changeFullShow)
     }
+  },
+  methods: {
+    click() {
+      if (screenfull.isEnabled) {
+        screenfull.toggle()
+      }
+    },
+    changeFullShow() {
+      this.isShow = !screenfull.isFullscreen
+    },
+  },
+  destroyed() {
+    screenfull.off('change', this.changeFullShow)
+  },
 }
 </script>
 <style scoped>
 .screenfull-svg {
-    width: 20px;
-    height: 20px;
-    cursor: pointer;
-    fill: #606266;
-    vertical-align: middle;
-    margin-right: 15px;
+  width: 20px;
+  height: 20px;
+  cursor: pointer;
+  fill: #606266;
+  vertical-align: middle;
+  margin-right: 15px;
 }
-</style>
+</style>

+ 3 - 3
web/src/view/login/login.vue

@@ -52,7 +52,9 @@
             <div class="vPic">
               <img
                 v-if="picPath"
-                :src="path + picPath"
+                :src="picPath"
+                width="100%"
+                height="100%"
                 alt="请输入验证码"
                 @click="loginVefify()"
               />
@@ -92,7 +94,6 @@
 <script>
 import { mapActions } from "vuex";
 import { captcha } from "@/api/user";
-const path = process.env.VUE_APP_BASE_API;
 export default {
   name: "Login",
   data() {
@@ -123,7 +124,6 @@ export default {
         username: [{ validator: checkUsername, trigger: "blur" }],
         password: [{ validator: checkPassword, trigger: "blur" }],
       },
-      path: path,
       logVerify: "",
       picPath: "",
     };

+ 128 - 113
web/src/view/superAdmin/authority/authority.vue

@@ -94,50 +94,58 @@ import {
   createAuthority,
   updateAuthority,
   copyAuthority
-} from '@/api/authority'
+} from "@/api/authority";
 
-import Menus from '@/view/superAdmin/authority/components/menus'
-import Apis from '@/view/superAdmin/authority/components/apis'
-import Datas from '@/view/superAdmin/authority/components/datas'
+import Menus from "@/view/superAdmin/authority/components/menus";
+import Apis from "@/view/superAdmin/authority/components/apis";
+import Datas from "@/view/superAdmin/authority/components/datas";
 
-import infoList from '@/components/mixins/infoList'
+import infoList from "@/components/mixins/infoList";
 export default {
-  name: 'Authority',
+  name: "Authority",
   mixins: [infoList],
   data() {
+    var mustUint = (rule, value, callback) => {
+      if (!(/^[0-9]*[1-9][0-9]*$/).test(value)){
+       return  callback(new Error("请输入正整数"));
+      } 
+      return  callback()
+    };
+
     return {
       AuthorityOption: [
         {
-          authorityId: '0',
-          authorityName: '根角色'
+          authorityId: "0",
+          authorityName: "根角色"
         }
       ],
       listApi: getAuthorityList,
       drawer: false,
-      dialogType: 'add',
+      dialogType: "add",
       activeRow: {},
       activeUserId: 0,
-      dialogTitle: '新增角色',
+      dialogTitle: "新增角色",
       dialogFormVisible: false,
       apiDialogFlag: false,
       copyForm: {},
       form: {
-        authorityId: '',
-        authorityName: '',
-        parentId: '0'
+        authorityId: "",
+        authorityName: "",
+        parentId: "0"
       },
       rules: {
         authorityId: [
-          { required: true, message: '请输入角色ID', trigger: 'blur' }
+          { required: true, message: "请输入角色ID", trigger: "blur" },
+          {validator: mustUint, trigger: 'blur'  }
         ],
         authorityName: [
-          { required: true, message: '请输入角色名', trigger: 'blur' }
+          { required: true, message: "请输入角色名", trigger: "blur" }
         ],
         parentId: [
-          { required: true, message: '请选择请求方式', trigger: 'blur' }
+          { required: true, message: "请选择请求方式", trigger: "blur" }
         ]
       }
-    }
+    };
   },
   components: {
     Menus,
@@ -146,150 +154,151 @@ export default {
   },
   methods: {
     autoEnter(activeName, oldActiveName) {
-      const paneArr = ['menus', 'apis', 'datas']
+      const paneArr = ["menus", "apis", "datas"];
       if (oldActiveName) {
         if (this.$refs[paneArr[oldActiveName]].needConfirm) {
-          this.$refs[paneArr[oldActiveName]].enterAndNext()
-          this.$refs[paneArr[oldActiveName]].needConfirm = false
+          this.$refs[paneArr[oldActiveName]].enterAndNext();
+          this.$refs[paneArr[oldActiveName]].needConfirm = false;
         }
       }
     },
     // 拷贝角色
     copyAuthority(row) {
-      this.setOptions()
-      this.dialogTitle = '拷贝角色'
-      this.dialogType = 'copy'
+      this.setOptions();
+      this.dialogTitle = "拷贝角色";
+      this.dialogType = "copy";
       for (let k in this.form) {
-        this.form[k] = row[k]
+        this.form[k] = row[k];
       }
-      this.copyForm = row
-      this.dialogFormVisible = true
+      this.copyForm = row;
+      this.dialogFormVisible = true;
     },
     opdendrawer(row) {
-      this.drawer = true
-      this.activeRow = row
+      this.drawer = true;
+      this.activeRow = row;
     },
     // 删除角色
     deleteAuth(row) {
-      this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
+      this.$confirm("此操作将永久删除该角色, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
       })
         .then(async () => {
-          const res = await deleteAuthority({ authorityId: row.authorityId })
+          const res = await deleteAuthority({ authorityId: row.authorityId });
           if (res.code == 0) {
             this.$message({
-              type: 'success',
-              message: '删除成功!'
-            })
-            this.getTableData()
+              type: "success",
+              message: "删除成功!"
+            });
+            this.getTableData();
           }
         })
         .catch(() => {
           this.$message({
-            type: 'info',
-            message: '已取消删除'
-          })
-        })
+            type: "info",
+            message: "已取消删除"
+          });
+        });
     },
     // 初始化表单
     initForm() {
       if (this.$refs.authorityForm) {
-        this.$refs.authorityForm.resetFields()
+        this.$refs.authorityForm.resetFields();
       }
       this.form = {
-        authorityId: '',
-        authorityName: '',
-        parentId: '0'
-      }
+        authorityId: "",
+        authorityName: "",
+        parentId: "0"
+      };
     },
     // 关闭窗口
     closeDialog() {
-      this.initForm()
-      this.dialogFormVisible = false
-      this.apiDialogFlag = false
+      this.initForm();
+      this.dialogFormVisible = false;
+      this.apiDialogFlag = false;
     },
     // 确定弹窗
 
     async enterDialog() {
-      if (this.form.authorityId == '0') {
+      if (this.form.authorityId == "0") {
         this.$message({
-          type: 'error',
-          message: '角色id不能为0'
-        })
-        return false
+          type: "error",
+          message: "角色id不能为0"
+        });
+        return false;
       }
       this.$refs.authorityForm.validate(async valid => {
         if (valid) {
           switch (this.dialogType) {
-            case 'add':
+            case "add":
               {
-                const res = await createAuthority(this.form)
+                const res = await createAuthority(this.form);
                 if (res.code == 0) {
                   this.$message({
-                    type: 'success',
-                    message: '添加成功!'
-                  })
-                  this.getTableData()
-                  this.closeDialog()
+                    type: "success",
+                    message: "添加成功!"
+                  });
+                  this.getTableData();
+                  this.closeDialog();
                 }
               }
-              break
-            case 'edit':
+              break;
+            case "edit":
               {
-                const res = await updateAuthority(this.form)
+                const res = await updateAuthority(this.form);
                 if (res.code == 0) {
                   this.$message({
-                    type: 'success',
-                    message: '添加成功!'
-                  })
-                  this.getTableData()
-                  this.closeDialog()
+                    type: "success",
+                    message: "添加成功!"
+                  });
+                  this.getTableData();
+                  this.closeDialog();
                 }
               }
-              break
-            case 'copy': {
+              break;
+            case "copy": {
               const data = {
                 authority: {
-                  authorityId: 'string',
-                  authorityName: 'string',
+                  authorityId: "string",
+                  authorityName: "string",
                   datauthorityId: [],
-                  parentId: 'string'
+                  parentId: "string"
                 },
                 oldAuthorityId: 0
-              }
-              data.authority.authorityId = this.form.authorityId
-              data.authority.authorityName = this.form.authorityName
-              data.authority.parentId = this.form.parentId
-              data.authority.dataAuthorityId = this.copyForm.dataAuthorityId
-              data.oldAuthorityId = this.copyForm.authorityId
-              const res = await copyAuthority(data)
+              };
+              data.authority.authorityId = this.form.authorityId;
+              data.authority.authorityName = this.form.authorityName;
+              data.authority.parentId = this.form.parentId;
+              data.authority.dataAuthorityId = this.copyForm.dataAuthorityId;
+              data.oldAuthorityId = this.copyForm.authorityId;
+              const res = await copyAuthority(data);
               if (res.code == 0) {
                 this.$message({
-                  type: 'success',
-                  message: '复制成功!'
-                })
-                this.getTableData()
+                  type: "success",
+                  message: "复制成功!"
+                });
+                this.getTableData();
               }
             }
           }
 
-          this.initForm()
-          this.dialogFormVisible = false
+          this.initForm();
+          this.dialogFormVisible = false;
         }
-      })
+      });
     },
     setOptions() {
       this.AuthorityOption = [
         {
-          authorityId: '0',
-          authorityName: '根角色'
+          authorityId: "0",
+          authorityName: "根角色"
         }
-      ]
-      this.setAuthorityOptions(this.tableData, this.AuthorityOption, false)
+      ];
+      this.setAuthorityOptions(this.tableData, this.AuthorityOption, false);
     },
     setAuthorityOptions(AuthorityData, optionsData, disabled) {
+      this.form.authorityId = String(this.form.authorityId);
       AuthorityData &&
         AuthorityData.map(item => {
           if (item.children && item.children.length) {
@@ -298,52 +307,58 @@ export default {
               authorityName: item.authorityName,
               disabled: disabled || item.authorityId == this.form.authorityId,
               children: []
-            }
+            };
             this.setAuthorityOptions(
               item.children,
               option.children,
               disabled || item.authorityId == this.form.authorityId
-            )
-            optionsData.push(option)
+            );
+            optionsData.push(option);
           } else {
             const option = {
               authorityId: item.authorityId,
               authorityName: item.authorityName,
               disabled: disabled || item.authorityId == this.form.authorityId
-            }
-            optionsData.push(option)
+            };
+            optionsData.push(option);
           }
-        })
+        });
     },
     // 增加角色
     addAuthority(parentId) {
-      this.initForm()
-      this.dialogTitle = '新增角色'
-      this.dialogType = 'add'
-      this.form.parentId = parentId
-      this.setOptions()
-      this.dialogFormVisible = true
+      this.initForm();
+      this.dialogTitle = "新增角色";
+      this.dialogType = "add";
+      this.form.parentId = parentId;
+      this.setOptions();
+      this.dialogFormVisible = true;
     },
     // 编辑角色
     editAuthority(row) {
-      this.setOptions()
-      this.dialogTitle = '编辑角色'
-      this.dialogType = 'edit'
+      this.setOptions();
+      this.dialogTitle = "编辑角色";
+      this.dialogType = "edit";
       for (let key in this.form) {
-        this.form[key] = row[key]
+        this.form[key] = row[key];
       }
-      this.setOptions()
-      this.dialogFormVisible = true
+      this.setOptions();
+      this.dialogFormVisible = true;
     }
   },
   async created() {
-    this.pageSize = 999
-    await this.getTableData()
+    this.pageSize = 999;
+    await this.getTableData();
   }
-}
+};
 </script>
 <style lang="scss">
 .authority {
+  .el-input-number {
+    margin-left: 15px;
+    span {
+      display: none;
+    }
+  }
   .button-box {
     padding: 10px 20px;
     .el-button {

+ 250 - 0
web/src/view/superAdmin/dictionary/sysDictionary.vue

@@ -0,0 +1,250 @@
+<template>
+  <div>
+    <div class="search-term">
+      <el-form :inline="true" :model="searchInfo" class="demo-form-inline">
+        <el-form-item label="字典名(中)">
+          <el-input placeholder="搜索条件" v-model="searchInfo.name"></el-input>
+        </el-form-item>    
+        <el-form-item label="字典名(英)">
+          <el-input placeholder="搜索条件" v-model="searchInfo.type"></el-input>
+        </el-form-item>    
+            <el-form-item label="状态" prop="status">
+            <el-select v-model="searchInfo.status" clear placeholder="请选择">
+                <el-option
+                    key="true"
+                    label="是"
+                    value="true">
+                </el-option>
+                <el-option
+                    key="false"
+                    label="否"
+                    value="false">
+                </el-option>
+            </el-select>
+            </el-form-item>   
+        <el-form-item label="描述">
+          <el-input placeholder="搜索条件" v-model="searchInfo.desc"></el-input>
+        </el-form-item>    
+        <el-form-item>
+          <el-button @click="onSubmit" type="primary">查询</el-button>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="openDialog" type="primary">新增字典</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <el-table
+      :data="tableData"
+      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="180">
+         <template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
+    </el-table-column>
+    
+    <el-table-column label="字典名(中)" prop="name" width="120"></el-table-column> 
+    
+    <el-table-column label="字典名(英)" prop="type" width="120"></el-table-column> 
+    
+    <el-table-column label="状态" prop="status" width="120">
+         <template slot-scope="scope">{{scope.row.status|formatBoolean}}</template>
+    </el-table-column>
+    
+    <el-table-column label="描述" prop="desc" width="280"></el-table-column> 
+    
+      <el-table-column label="按钮组">
+        <template slot-scope="scope">
+          <el-button @click="toDetile(scope.row)" size="small" type="success">详情</el-button>
+          <el-button @click="updateSysDictionary(scope.row)" size="small" type="primary">变更</el-button>
+          <el-popover placement="top" width="160" v-model="scope.row.visible">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin: 0">
+              <el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
+              <el-button type="primary" size="mini" @click="deleteSysDictionary(scope.row)">确定</el-button>
+            </div>
+            <el-button type="danger" icon="el-icon-delete" size="mini" slot="reference">删除</el-button>
+          </el-popover>
+        </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>
+
+    <el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
+      <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
+      <el-form-item label="字典名(中)" prop="name">
+        <el-input v-model="formData.name" placeholder="请输入字典名(中)" clearable :style="{width: '100%'}"></el-input>
+      </el-form-item>
+      <el-form-item label="字典名(英)" prop="type">
+        <el-input v-model="formData.type" placeholder="请输入字典名(英)" clearable :style="{width: '100%'}"></el-input>
+      </el-form-item>
+      <el-form-item label="状态" prop="status" required>
+        <el-switch v-model="formData.status" active-text="开启" inactive-text="停用"></el-switch>
+      </el-form-item>
+      <el-form-item label="描述" prop="desc">
+        <el-input v-model="formData.desc" placeholder="请输入描述" clearable :style="{width: '100%'}"></el-input>
+      </el-form-item>
+    </el-form>
+      
+      <div class="dialog-footer" slot="footer">
+        <el-button @click="closeDialog">取 消</el-button>
+        <el-button @click="enterDialog" type="primary">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <div style="margin-top:40px;color:red">获取字典且缓存方法已在前端utils/dictionary 已经封装完成 不必自己书写 使用方法查看文件内注释</div>
+  </div>
+</template>
+
+<script>
+import {
+    createSysDictionary,
+    deleteSysDictionary,
+    updateSysDictionary,
+    findSysDictionary,
+    getSysDictionaryList
+} from "@/api/sysDictionary";  //  此处请自行替换地址
+import { formatTimeToStr } from "@/utils/data";
+import infoList from "@/components/mixins/infoList";
+export default {
+  name: "SysDictionary",
+  mixins: [infoList],
+  data() {
+    return {
+      listApi: getSysDictionaryList,
+      dialogFormVisible: false,
+      visible: false,
+      type: "",
+      formData: {
+        name:null,type:null,status:true,desc:null
+      },
+      rules: {
+        name: [{
+          required: true,
+          message: '请输入字典名(中)',
+          trigger: 'blur'
+        }],
+        type: [{
+          required: true,
+          message: '请输入字典名(英)',
+          trigger: 'blur'
+        }],
+        desc: [{
+          required: true,
+          message: '请输入描述',
+          trigger: 'blur'
+        }],
+      },
+    };
+  },
+  filters: {
+    formatDate: function(time) {
+      if (time != null && time != "") {
+        var date = new Date(time);
+        return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
+      } else {
+        return "";
+      }
+    },
+    formatBoolean: function(bool) {
+      if (bool != null) {
+        return bool ? "是" :"否";
+      } else {
+        return "";
+      }
+    }
+  },
+  methods: {
+      toDetile(row){
+        this.$router.push({
+          name:"dictionaryDetail",
+          params:{
+            id:row.ID
+          }
+        })
+      },
+      //条件搜索前端看此方法
+      onSubmit() {
+        this.page = 1
+        this.pageSize = 10        
+        if (this.searchInfo.status==""){
+          this.searchInfo.status=null
+        }       
+        this.getTableData()
+      },
+    async updateSysDictionary(row) {
+      const res = await findSysDictionary({ ID: row.ID });
+      this.type = "update";
+      if (res.code == 0) {
+        this.formData = res.data.resysDictionary;
+        this.dialogFormVisible = true;
+      }
+    },
+    closeDialog() {
+      this.dialogFormVisible = false;
+      this.formData = {
+          name:null,
+          type:null,
+          status:true,
+          desc:null,
+      };
+    },
+    async deleteSysDictionary(row) {
+      this.visible = false;
+      const res = await deleteSysDictionary({ ID: row.ID });
+      if (res.code == 0) {
+        this.$message({
+          type: "success",
+          message: "删除成功"
+        });
+        this.getTableData();
+      }
+    },
+    async enterDialog() {
+      this.$refs['elForm'].validate(async valid => {
+        if (!valid) return
+        let res;
+        switch (this.type) {
+          case "create":
+            res = await createSysDictionary(this.formData);
+            break;
+          case "update":
+            res = await updateSysDictionary(this.formData);
+            break;
+          default:
+            res = await createSysDictionary(this.formData);
+            break;
+        }
+         if (res.code == 0) {
+        this.closeDialog();
+        this.getTableData();
+      }
+      })
+     
+    },
+    openDialog() {
+      this.type = "create";
+      this.dialogFormVisible = true;
+    }
+  },
+  async created() {
+    this.getTableData();
+  }
+};
+</script>
+
+<style>
+</style>

+ 256 - 0
web/src/view/superAdmin/dictionary/sysDictionaryDetail.vue

@@ -0,0 +1,256 @@
+<template>
+  <div>
+    <div class="search-term">
+      <el-form :inline="true" :model="searchInfo" class="demo-form-inline">
+        <el-form-item label="展示值">
+          <el-input placeholder="搜索条件" v-model="searchInfo.label"></el-input>
+        </el-form-item>
+        <el-form-item label="字典值">
+          <el-input placeholder="搜索条件" v-model="searchInfo.value"></el-input>
+        </el-form-item>
+        <el-form-item label="启用状态" prop="status">
+          <el-select v-model="searchInfo.status" placeholder="请选择">
+            <el-option key="true" label="是" value="true"></el-option>
+            <el-option key="false" label="否" value="false"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="onSubmit" type="primary">查询</el-button>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="openDialog" type="primary">新增字典项</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <el-table
+      :data="tableData"
+      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="180">
+        <template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
+      </el-table-column>
+
+      <el-table-column label="展示值" prop="label" width="120"></el-table-column>
+
+      <el-table-column label="字典值" prop="value" width="120"></el-table-column>
+
+      <el-table-column label="启用状态" prop="status" width="120">
+        <template slot-scope="scope">{{scope.row.status|formatBoolean}}</template>
+      </el-table-column>
+
+      <el-table-column label="排序标记" prop="sort" width="120"></el-table-column>
+
+      <el-table-column label="按钮组">
+        <template slot-scope="scope">
+          <el-button @click="updateSysDictionaryDetail(scope.row)" size="small" type="primary">变更</el-button>
+          <el-popover placement="top" width="160" v-model="scope.row.visible">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin: 0">
+              <el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
+              <el-button type="primary" size="mini" @click="deleteSysDictionaryDetail(scope.row)">确定</el-button>
+            </div>
+            <el-button type="danger" icon="el-icon-delete" size="mini" slot="reference">删除</el-button>
+          </el-popover>
+        </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>
+
+    <el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
+      <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="110px">
+        <el-form-item label="展示值" prop="label">
+          <el-input
+            v-model="formData.label"
+            placeholder="请输入展示值"
+            clearable
+            :style="{width: '100%'}"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="字典值" prop="value">
+          <el-input-number
+            v-model.number="formData.value"
+            step-strictly
+            :step="1"
+            placeholder="请输入字典值"
+            clearable
+            :style="{width: '100%'}"
+          ></el-input-number>
+        </el-form-item>
+        <el-form-item label="启用状态" prop="status" required>
+          <el-switch v-model="formData.status" active-text="开启" inactive-text="停用"></el-switch>
+        </el-form-item>
+        <el-form-item label="排序标记" prop="sort">
+          <el-input-number v-model.number="formData.sort" placeholder="排序标记"></el-input-number>
+        </el-form-item>
+      </el-form>
+      <div class="dialog-footer" slot="footer">
+        <el-button @click="closeDialog">取 消</el-button>
+        <el-button @click="enterDialog" type="primary">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  createSysDictionaryDetail,
+  deleteSysDictionaryDetail,
+  updateSysDictionaryDetail,
+  findSysDictionaryDetail,
+  getSysDictionaryDetailList
+} from "@/api/sysDictionaryDetail"; //  此处请自行替换地址
+import { formatTimeToStr } from "@/utils/data";
+import infoList from "@/components/mixins/infoList";
+
+export default {
+  name: "SysDictionaryDetail",
+  mixins: [infoList],
+  data() {
+    return {
+      listApi: getSysDictionaryDetailList,
+      dialogFormVisible: false,
+      visible: false,
+      type: "",
+      formData: {
+        label: null,
+        value: null,
+        status: true,
+        sort: null
+      },
+      rules: {
+        label: [
+          {
+            required: true,
+            message: "请输入展示值",
+            trigger: "blur"
+          }
+        ],
+        value: [
+          {
+            required: true,
+            message: "请输入字典值",
+            trigger: "blur"
+          }
+        ],
+        sort: [
+          {
+            required: true,
+            message: "排序标记",
+            trigger: "blur"
+          }
+        ]
+      }
+    };
+  },
+  filters: {
+    formatDate: function(time) {
+      if (time != null && time != "") {
+        var date = new Date(time);
+        return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
+      } else {
+        return "";
+      }
+    },
+    formatBoolean: function(bool) {
+      if (bool != null) {
+        return bool ? "是" : "否";
+      } else {
+        return "";
+      }
+    }
+  },
+  methods: {
+    //条件搜索前端看此方法
+    onSubmit() {
+      this.page = 1;
+      this.pageSize = 10;
+      if (this.searchInfo.status == "") {
+        this.searchInfo.status = null;
+      }
+      this.getTableData();
+    },
+    async updateSysDictionaryDetail(row) {
+      const res = await findSysDictionaryDetail({ ID: row.ID });
+      this.type = "update";
+      if (res.code == 0) {
+        this.formData = res.data.resysDictionaryDetail;
+        this.dialogFormVisible = true;
+      }
+    },
+    closeDialog() {
+      this.dialogFormVisible = false;
+      this.formData = {
+        label: null,
+        value: null,
+        status: true,
+        sort: null,
+        sysDictionaryID: ""
+      };
+    },
+    async deleteSysDictionaryDetail(row) {
+      this.visible = false;
+      const res = await deleteSysDictionaryDetail({ ID: row.ID });
+      if (res.code == 0) {
+        this.$message({
+          type: "success",
+          message: "删除成功"
+        });
+        this.getTableData();
+      }
+    },
+    async enterDialog() {
+    this.formData.sysDictionaryID = Number(this.$route.params.id)
+      this.$refs['elForm'].validate(async valid => {
+        if (!valid) return
+        let res;
+        switch (this.type) {
+          case "create":
+            res = await createSysDictionaryDetail(this.formData);
+            break;
+          case "update":
+            res = await updateSysDictionaryDetail(this.formData);
+            break;
+          default:
+            res = await createSysDictionaryDetail(this.formData);
+            break;
+        }
+        if (res.code == 0) {
+          this.$message({
+            type:"success",
+            message:"创建/更改成功"
+          })
+          this.closeDialog();
+          this.getTableData();
+        }
+      })
+      
+    },
+    openDialog() {
+      this.type = "create";
+      this.dialogFormVisible = true;
+    }
+  },
+  created() {
+    this.searchInfo.sysDictionaryID = this.$route.params.id
+    this.getTableData();
+  }
+};
+</script>
+
+<style>
+</style>

+ 227 - 0
web/src/view/superAdmin/operation/sysOperationRecord.vue

@@ -0,0 +1,227 @@
+<template>
+  <div>
+    <div class="search-term">
+      <el-form :inline="true" :model="searchInfo" class="demo-form-inline">
+        <el-form-item label="请求方法">
+          <el-input placeholder="搜索条件" v-model="searchInfo.method"></el-input>
+        </el-form-item>
+        <el-form-item label="请求路径">
+          <el-input placeholder="搜索条件" v-model="searchInfo.path"></el-input>
+        </el-form-item>
+        <el-form-item label="结果状态码">
+          <el-input placeholder="搜索条件" v-model="searchInfo.status"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="onSubmit" type="primary">查询</el-button>
+        </el-form-item>
+        <el-form-item>
+          <el-popover placement="top" v-model="deleteVisible" width="160">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin: 0">
+              <el-button @click="deleteVisible = false" size="mini" type="text">取消</el-button>
+              <el-button @click="onDelete" size="mini" type="primary">确定</el-button>
+            </div>
+            <el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">批量删除</el-button>
+          </el-popover>
+        </el-form-item>
+      </el-form>
+    </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="140">
+        <template slot-scope="scope">
+          <div>{{scope.row.user.userName}}({{scope.row.user.nickName}})</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="日期" width="180">
+        <template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
+      </el-table-column>
+      <el-table-column label="状态码" prop="status" width="120">
+        <template slot-scope="scope">
+          <div>
+            <el-tag type="success">{{ scope.row.status }}</el-tag>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="请求ip" prop="ip" width="120"></el-table-column>
+      <el-table-column label="请求方法" prop="method" width="120"></el-table-column>
+      <el-table-column label="请求路径" prop="path" width="240"></el-table-column>
+      <el-table-column label="请求" prop="path" width="80">
+        <template slot-scope="scope">
+          <div>
+            <el-popover placement="top-start" trigger="hover" v-if="scope.row.body">
+              <div class="popover-box">
+                <pre>{{JSON.parse(scope.row.body)}}</pre>
+              </div>
+              <i class="el-icon-view" slot="reference"></i>
+            </el-popover>
+
+            <span v-else>无</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="响应" prop="path" width="80">
+        <template slot-scope="scope">
+          <div>
+            <el-popover placement="top-start" trigger="hover" v-if="scope.row.resp">
+              <div class="popover-box">
+                <pre>{{JSON.parse(scope.row.resp)}}</pre>
+              </div>
+              <i class="el-icon-view" slot="reference"></i>
+            </el-popover>
+            <span v-else>无</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="按钮组">
+        <template slot-scope="scope">
+          <el-popover placement="top" v-model="scope.row.visible" width="160">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin: 0">
+              <el-button @click="scope.row.visible = false" size="mini" type="text">取消</el-button>
+              <el-button @click="deleteSysOperationRecord(scope.row)" size="mini" type="primary">确定</el-button>
+            </div>
+            <el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">删除</el-button>
+          </el-popover>
+        </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>
+</template>
+
+<script>
+import {
+  deleteSysOperationRecord,
+  getSysOperationRecordList,
+  deleteSysOperationRecordByIds
+} from '@/api/sysOperationRecord' //  此处请自行替换地址
+import { formatTimeToStr } from '@/utils/data'
+import infoList from '@/components/mixins/infoList'
+
+export default {
+  name: 'SysOperationRecord',
+  mixins: [infoList],
+  data() {
+    return {
+      listApi: getSysOperationRecordList,
+      dialogFormVisible: false,
+      visible: false,
+      type: '',
+      deleteVisible: false,
+      multipleSelection: [],
+      formData: {
+        ip: null,
+        method: null,
+        path: null,
+        status: null,
+        latency: null,
+        agent: null,
+        error_message: null,
+        user_id: null
+      }
+    }
+  },
+  filters: {
+    formatDate: function(time) {
+      if (time != null && time != '') {
+        var date = new Date(time)
+        return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
+      } else {
+        return ''
+      }
+    },
+    formatBoolean: function(bool) {
+      if (bool != null) {
+        return bool ? '是' : '否'
+      } else {
+        return ''
+      }
+    }
+  },
+  methods: {
+    //条件搜索前端看此方法
+    onSubmit() {
+      this.page = 1
+      this.pageSize = 10
+      this.getTableData()
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    async onDelete() {
+      const ids = []
+      this.multipleSelection &&
+        this.multipleSelection.map(item => {
+          ids.push(item.ID)
+        })
+      const res = await deleteSysOperationRecordByIds({ ids })
+      if (res.code == 0) {
+        this.$message({
+          type: 'success',
+          message: '删除成功'
+        })
+        this.deleteVisible = false
+        this.getTableData()
+      }
+    },
+    async deleteSysOperationRecord(row) {
+      this.visible = false
+      const res = await deleteSysOperationRecord({ ID: row.ID })
+      if (res.code == 0) {
+        this.$message({
+          type: 'success',
+          message: '删除成功'
+        })
+        this.getTableData()
+      }
+    }
+  },
+  created() {
+    this.getTableData()
+  }
+}
+</script>
+
+<style lang="scss">
+.table-expand {
+  padding-left: 60px;
+  font-size: 0;
+  label {
+    width: 90px;
+    color: #99a9bf;
+    .el-form-item {
+      margin-right: 0;
+      margin-bottom: 0;
+      width: 50%;
+    }
+  }
+}
+.popover-box {
+  background: #112435;
+  color: #f08047;
+  height: 600px;
+  width: 420px;
+  overflow: auto;
+}
+.popover-box::-webkit-scrollbar {
+  display: none; /* Chrome Safari */
+}
+</style>

+ 33 - 2
web/src/view/systemTools/autoCode/component/fieldDialog.vue

@@ -29,7 +29,7 @@
             </el-form-item>
             <el-form-item label="Field数据类型" prop="fieldType">
                 <el-col :span="8">
-            <el-select v-model="dialogMiddle.fieldType" placeholder="请选择field数据类型">
+            <el-select v-model="dialogMiddle.fieldType" placeholder="请选择field数据类型" @change="getDbfdOptions" clearable >
                 <el-option
                     v-for="item in typeOptions"
                     :key="item.value"
@@ -39,9 +39,27 @@
             </el-select>
                 </el-col>
             </el-form-item>
+
+            <el-form-item label="数据库字段类型" prop="dataType">
+                <el-col :span="8">
+            <el-select :disabled="!dialogMiddle.fieldType" v-model="dialogMiddle.dataType" placeholder="请选择数据库字段类型" clearable >
+                <el-option
+                    v-for="item in dbfdOptions"
+                    :key="item.label"
+                    :label="item.label"
+                    :value="item.label">
+                </el-option>
+            </el-select>
+                </el-col>
+            </el-form-item>
+            <el-form-item label="数据库字段长度" prop="dataTypeLong">
+                <el-col :span="6">
+                <el-input :disabled="!dialogMiddle.dataType" v-model="dialogMiddle.dataTypeLong"></el-input>
+                </el-col>
+            </el-form-item>
             <el-form-item label="Field查询条件" prop="fieldSearchType">
                 <el-col :span="8">
-            <el-select v-model="dialogMiddle.fieldSearchType" placeholder="请选择field数据类型">
+            <el-select v-model="dialogMiddle.fieldSearchType" placeholder="请选择Field查询条件" clearable >
                 <el-option
                     v-for="item in typeSearchOptions"
                     :key="item.value"
@@ -55,6 +73,7 @@
     </div>
 </template>
 <script>
+import {getDict} from '@/utils/dictionary'
 export default {
     name:"FieldDialog",
     props:{
@@ -67,6 +86,7 @@ export default {
     },
     data(){
         return{
+            dbfdOptions:[],
             visible:false,
             typeSearchOptions:[
                 {
@@ -122,6 +142,17 @@ export default {
 
         }
     },
+    methods: {
+        async getDbfdOptions(){
+            if(this.dialogMiddle.fieldType){
+                 const res = await getDict(this.dialogMiddle.fieldType)
+                 this.dbfdOptions = res
+            }
+        }
+    },
+    created() {
+        this.getDbfdOptions()
+    },
 }
 </script>
 <style lang="scss">

+ 245 - 103
web/src/view/systemTools/autoCode/index.vue

@@ -1,10 +1,56 @@
 <template>
   <div>
+    <!-- 从数据库直接获取字段 -->
+    <el-collapse v-model="activeNames">
+      <el-collapse-item name="1">
+        <template slot="title">
+          <div :style="{fontSize:'16px',paddingLeft:'20px'}">
+            点这里从现有数据库创建代码
+            <i class="header-icon el-icon-thumb"></i>
+          </div>
+        </template>
+        <el-form ref="getTableForm" :inline="true" :model="dbform" label-width="120px">
+          <el-form-item label="数据库名" prop="structName">
+            <el-select @change="getTable" v-model="dbform.dbName" filterable placeholder="请选择数据库">
+              <el-option
+                v-for="item in dbOptions"
+                :key="item.database"
+                :label="item.database"
+                :value="item.database"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="表名" prop="structName">
+            <el-select
+              v-model="dbform.tableName"
+              :disabled="!dbform.dbName"
+              filterable
+              placeholder="请选择表"
+            >
+              <el-option
+                v-for="item in tableOptions"
+                :key="item.tableName"
+                :label="item.tableName"
+                :value="item.tableName"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button @click="getColume" type="primary">使用此表创建</el-button>
+          </el-form-item>
+        </el-form>
+      </el-collapse-item>
+    </el-collapse>
+
+    <el-divider></el-divider>
     <!-- 初始版本自动化代码工具 -->
     <el-form ref="autoCodeForm" :rules="rules" :model="form" label-width="120px" :inline="true">
       <el-form-item label="Struct名称" prop="structName">
         <el-input v-model="form.structName" placeholder="首字母自动转换大写"></el-input>
       </el-form-item>
+      <el-form-item label="tableName" prop="tableName">
+        <el-input v-model="form.tableName" placeholder="指定表名(非必填)"></el-input>
+      </el-form-item>
       <el-form-item label="Struct简称" prop="abbreviation">
         <el-input v-model="form.abbreviation" placeholder="简称会作为入参对象名和路由group"></el-input>
       </el-form-item>
@@ -23,27 +69,36 @@
       <el-button @click="editAndAddField()" type="primary">新增Field</el-button>
     </div>
     <el-table :data="form.fields" border stripe>
-      <el-table-column type="index" label="序列" width="100">
-      </el-table-column>
-      <el-table-column prop="fieldName" label="Field名">
-      </el-table-column>
-      <el-table-column prop="fieldDesc" label="中文名">
-      </el-table-column>
-      <el-table-column prop="fieldJson" label="FieldJson">
-      </el-table-column>
-      <el-table-column prop="fieldType" label="Field数据类型" width="130">
-      </el-table-column>
-      <el-table-column prop="columnName" label="数据库字段" width="130">
-      </el-table-column>
-      <el-table-column prop="comment" label="数据库字段描述" width="130">
-      </el-table-column>
-      <el-table-column prop="fieldSearchType" label="搜索条件" width="130">
-      </el-table-column>
+      <el-table-column type="index" label="序列" width="100"></el-table-column>
+      <el-table-column prop="fieldName" label="Field名"></el-table-column>
+      <el-table-column prop="fieldDesc" label="中文名"></el-table-column>
+      <el-table-column prop="fieldJson" label="FieldJson"></el-table-column>
+      <el-table-column prop="fieldType" label="Field数据类型" width="130"></el-table-column>
+      <el-table-column prop="dataType" label="数据库字段类型" width="130"></el-table-column>
+      <el-table-column prop="dataTypeLong" label="数据库字段长度" width="130"></el-table-column>
+      <el-table-column prop="columnName" label="数据库字段" width="130"></el-table-column>
+      <el-table-column prop="comment" label="数据库字段描述" width="130"></el-table-column>
+      <el-table-column prop="fieldSearchType" label="搜索条件" width="130"></el-table-column>
       <el-table-column label="操作" width="300">
         <template slot-scope="scope">
-          <el-button size="mini" type="primary" icon="el-icon-edit" @click="editAndAddField(scope.row)">编辑</el-button>
-          <el-button size="mini" type="text" :disabled="scope.$index == 0" @click="moveUpField(scope.$index)">上移</el-button>
-          <el-button size="mini" type="text" :disabled="(scope.$index + 1) == form.fields.length" @click="moveDownField(scope.$index)">下移</el-button>
+          <el-button
+            size="mini"
+            type="primary"
+            icon="el-icon-edit"
+            @click="editAndAddField(scope.row)"
+          >编辑</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            :disabled="scope.$index == 0"
+            @click="moveUpField(scope.$index)"
+          >上移</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            :disabled="(scope.$index + 1) == form.fields.length"
+            @click="moveDownField(scope.$index)"
+          >下移</el-button>
           <el-popover placement="top" v-model="scope.row.visible">
             <p>确定删除吗?</p>
             <div style="text-align: right; margin: 0">
@@ -55,13 +110,14 @@
         </template>
       </el-table-column>
     </el-table>
+    <el-tag type="danger">id , created_at , updated_at , deleted_at 会自动生成请勿重复创建</el-tag>
     <!-- 组件列表 -->
     <div class="button-box clearflex">
       <el-button @click="enterForm" type="primary">生成代码包</el-button>
     </div>
     <!-- 组件弹窗 -->
     <el-dialog title="组件内容" :visible.sync="dialogFlag">
-      <FieldDialog :dialogMiddle="dialogMiddle" ref="fieldDialog" />
+      <FieldDialog v-if="dialogFlag" :dialogMiddle="dialogMiddle" ref="fieldDialog" />
       <div slot="footer" class="dialog-footer">
         <el-button @click="closeDialog">取 消</el-button>
         <el-button type="primary" @click="enterDialog">确 定</el-button>
@@ -71,146 +127,232 @@
 </template>
 <script>
 const fieldTemplate = {
-  fieldName: '',
-  fieldDesc: '',
-  fieldType: '',
-  fieldJson: '',
-  columnName: '',
-  comment:'',
-  fieldSearchType:''
-}
+  fieldName: "",
+  fieldDesc: "",
+  fieldType: "",
+  dataType: "",
+  fieldJson: "",
+  columnName: "",
+  dataTypeLong: "",
+  comment: "",
+  fieldSearchType: ""
+};
+
+import FieldDialog from "@/view/systemTools/autoCode/component/fieldDialog.vue";
+import { toUpperCase, toHump } from "@/utils/stringFun.js";
+import { createTemp, getDB, getTable, getColume } from "@/api/autoCode.js";
+import { getDict } from "@/utils/dictionary";
 
-import FieldDialog from '@/view/systemTools/autoCode/component/fieldDialog.vue'
-import { toUpperCase } from '@/utils/stringFun.js'
-import { createTemp } from '@/api/autoCode.js'
 export default {
-  name: 'autoCode',
+  name: "autoCode",
   data() {
     return {
-      addFlag: '',
+      activeNames: [""],
+      dbform: {
+        dbName: "",
+        tableName: ""
+      },
+      dbOptions: [],
+      tableOptions: [],
+      addFlag: "",
+      fdMap: {},
       form: {
-        structName: '',
-        packageName: '',
-        abbreviation: '',
-        description:'',
+        structName: "",
+        tableName: "",
+        packageName: "",
+        abbreviation: "",
+        description: "",
         autoCreateApiToSql: false,
-        fields: [],
+        fields: []
       },
       rules: {
-        structName: [{ required: true, message: '请输入结构体名称', trigger: 'blur' }],
-        abbreviation: [{ required: true, message: '请输入结构体简称', trigger: 'blur' }],
-        description: [{ required: true, message: '请输入结构体描述', trigger: 'blur' }],
-        packageName: [{ required: true, message: '请输入包名称', trigger: 'blur' }],
+        structName: [
+          { required: true, message: "请输入结构体名称", trigger: "blur" }
+        ],
+        abbreviation: [
+          { required: true, message: "请输入结构体简称", trigger: "blur" }
+        ],
+        description: [
+          { required: true, message: "请输入结构体描述", trigger: "blur" }
+        ],
+        packageName: [
+          {
+            required: true,
+            message: "文件名称:sys_xxxx_xxxx",
+            trigger: "blur"
+          }
+        ]
       },
       dialogMiddle: {},
       bk: {},
-      dialogFlag: false,
-    }
+      dialogFlag: false
+    };
   },
   components: {
-    FieldDialog,
+    FieldDialog
   },
   methods: {
     editAndAddField(item) {
-      this.dialogFlag = true
+      this.dialogFlag = true;
       if (item) {
-        this.addFlag = 'edit'
-        this.bk = JSON.parse(JSON.stringify(item))
-        this.dialogMiddle = item
+        this.addFlag = "edit";
+        this.bk = JSON.parse(JSON.stringify(item));
+        this.dialogMiddle = item;
       } else {
-        this.addFlag = 'add'
-        this.dialogMiddle = JSON.parse(JSON.stringify(fieldTemplate))
+        this.addFlag = "add";
+        this.dialogMiddle = JSON.parse(JSON.stringify(fieldTemplate));
       }
     },
     moveUpField(index) {
       if (index == 0) {
-        return
+        return;
       }
-      const oldUpField = this.form.fields[index - 1]
-      this.form.fields.splice(index - 1, 1)
-      this.form.fields.splice(index, 0, oldUpField)
+      const oldUpField = this.form.fields[index - 1];
+      this.form.fields.splice(index - 1, 1);
+      this.form.fields.splice(index, 0, oldUpField);
     },
     moveDownField(index) {
-      const fCount = this.form.fields.length
+      const fCount = this.form.fields.length;
       if (index == fCount - 1) {
-        return
+        return;
       }
-      const oldDownField = this.form.fields[index + 1]
-      this.form.fields.splice(index + 1, 1)
-      this.form.fields.splice(index, 0, oldDownField)
+      const oldDownField = this.form.fields[index + 1];
+      this.form.fields.splice(index + 1, 1);
+      this.form.fields.splice(index, 0, oldDownField);
     },
     enterDialog() {
-      this.$refs.fieldDialog.$refs.fieldDialogFrom.validate((valid) => {
+      this.$refs.fieldDialog.$refs.fieldDialogFrom.validate(valid => {
         if (valid) {
-          this.dialogMiddle.fieldName = toUpperCase(this.dialogMiddle.fieldName)
-          if (this.addFlag == 'add') {
-            this.form.fields.push(this.dialogMiddle)
+          this.dialogMiddle.fieldName = toUpperCase(
+            this.dialogMiddle.fieldName
+          );
+          if (this.addFlag == "add") {
+            this.form.fields.push(this.dialogMiddle);
           }
-          this.dialogFlag = false
+          this.dialogFlag = false;
         } else {
-          return false
+          return false;
         }
-      })
+      });
     },
     closeDialog() {
-      if (this.addFlag == 'edit') {
-        this.dialogMiddle = this.bk
+      if (this.addFlag == "edit") {
+        this.dialogMiddle = this.bk;
       }
-      this.dialogFlag = false
+      this.dialogFlag = false;
     },
     deleteField(index) {
-      this.form.fields.splice(index, 1)
+      this.form.fields.splice(index, 1);
     },
     async enterForm() {
       if (this.form.fields.length <= 0) {
         this.$message({
-          type: 'error',
-          message: '请填写至少一个field',
-        })
-        return false
+          type: "error",
+          message: "请填写至少一个field"
+        });
+        return false;
       }
-      if(this.form.fields.some(item=>item.fieldName == this.form.structName)){
+      if (
+        this.form.fields.some(item => item.fieldName == this.form.structName)
+      ) {
         this.$message({
-          type: 'error',
-          message: '存在与结构体同名的字段',
-        })
-        return false
+          type: "error",
+          message: "存在与结构体同名的字段"
+        });
+        return false;
       }
-      this.$refs.autoCodeForm.validate(async (valid) => {
+      this.$refs.autoCodeForm.validate(async valid => {
         if (valid) {
-          this.form.structName = toUpperCase(this.form.structName)
+          this.form.structName = toUpperCase(this.form.structName);
           if (this.form.structName == this.form.abbreviation) {
             this.$message({
-              type: 'error',
-              message: 'structName和struct简称不能相同',
-            })
-            return false
+              type: "error",
+              message: "structName和struct简称不能相同"
+            });
+            return false;
           }
-          const data = await createTemp(this.form)
-          const blob = new Blob([data])
-          const fileName = 'ginvueadmin.zip'
-          if ('download' in document.createElement('a')) {
+          const data = await createTemp(this.form);
+          const blob = new Blob([data]);
+          const fileName = "ginvueadmin.zip";
+          if ("download" in document.createElement("a")) {
             // 不是IE浏览器
-            let url = window.URL.createObjectURL(blob)
-            let link = document.createElement('a')
-            link.style.display = 'none'
-            link.href = url
-            link.setAttribute('download', fileName)
-            document.body.appendChild(link)
-            link.click()
-            document.body.removeChild(link) // 下载完成移除元素
-            window.URL.revokeObjectURL(url) // 释放掉blob对象
+            let url = window.URL.createObjectURL(blob);
+            let link = document.createElement("a");
+            link.style.display = "none";
+            link.href = url;
+            link.setAttribute("download", fileName);
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link); // 下载完成移除元素
+            window.URL.revokeObjectURL(url); // 释放掉blob对象
           } else {
             // IE 10+
-            window.navigator.msSaveBlob(blob, fileName)
+            window.navigator.msSaveBlob(blob, fileName);
           }
         } else {
-          return false
+          return false;
         }
-      })
+      });
+    },
+    async getDb() {
+      const res = await getDB();
+      if (res.code == 0) {
+        this.dbOptions = res.data.dbs;
+      }
+    },
+    async getTable() {
+      const res = await getTable({ dbName: this.dbform.dbName });
+      if (res.code == 0) {
+        this.tableOptions = res.data.tables;
+      }
+      this.dbform.tableName = "";
+    },
+    async getColume() {
+      const gormModelList = ["id", "created_at", "updated_at", "deleted_at"];
+      const res = await getColume(this.dbform);
+      if (res.code == 0) {
+        const tbHump = toHump(this.dbform.tableName);
+        this.form.structName = toUpperCase(tbHump);
+        this.form.tableName = this.dbform.tableName;
+        this.form.packageName = tbHump;
+        this.form.abbreviation = tbHump;
+        this.form.description = tbHump + "表";
+        this.form.autoCreateApiToSql = true;
+        this.form.fields = [];
+        res.data.columes &&
+          res.data.columes.map(item => {
+            if (!gormModelList.some(gormfd => gormfd == item.columeName)) {
+              const fbHump = toHump(item.columeName);
+              this.form.fields.push({
+                fieldName: toUpperCase(fbHump),
+                fieldDesc: item.columeComment || fbHump + "字段",
+                fieldType: this.fdMap[item.dataType],
+                dataType: item.dataType,
+                fieldJson: fbHump,
+                dataTypeLong: item.dataTypeLong,
+                columnName: item.columeName,
+                comment: item.columeComment,
+                fieldSearchType: ""
+              });
+            }
+          });
+      }
     },
+    async setFdMap() {
+      const fdTpyes = ["string", "int", "bool", "float64", "time.Time"];
+      fdTpyes.map(async fdtype => {
+        const res = await getDict(fdtype);
+        res.map(item => {
+          this.fdMap[item.label] = fdtype;
+        });
+      });
+    }
   },
-}
+  created() {
+    this.getDb();
+    this.setFdMap();
+  }
+};
 </script>
 <style scope lang="scss">
 .button-box {

+ 1 - 1
web/src/view/systemTools/system/system.vue

@@ -9,7 +9,7 @@
         <el-input v-model="config.system.env"></el-input>
       </el-form-item>
       <el-form-item label="端口值">
-        <el-input v-model="config.system.addr"></el-input>
+        <el-input v-model.number="config.system.addr"></el-input>
       </el-form-item>
       <el-form-item label="数据库类型">
         <el-select v-model="config.system.dbType">

Some files were not shown because too many files changed in this diff