Jelajahi Sumber

first commit

longan 1 tahun lalu
melakukan
960cdac116
100 mengubah file dengan 6447 tambahan dan 0 penghapusan
  1. 8 0
      .idea/.gitignore
  2. 9 0
      .idea/lc-fangdaosha.iml
  3. 8 0
      .idea/modules.xml
  4. 6 0
      .idea/vcs.xml
  5. 11 0
      api/v1/enter.go
  6. 70 0
      api/v1/system/base.go
  7. 40 0
      api/v1/system/enter.go
  8. 231 0
      api/v1/system/sys_api.go
  9. 208 0
      api/v1/system/sys_authority.go
  10. 68 0
      api/v1/system/sys_casbin.go
  11. 147 0
      api/v1/system/sys_dictionary.go
  12. 147 0
      api/v1/system/sys_dictionary_detail.go
  13. 31 0
      api/v1/system/sys_jwt_blacklist.go
  14. 278 0
      api/v1/system/sys_menu.go
  15. 542 0
      api/v1/system/sys_user.go
  16. 58 0
      config.yaml
  17. 109 0
      config/config.go
  18. 237 0
      doc/lc-base-frame/casbin_rule.sql
  19. 0 0
      doc/lc-base-frame/jwt_blacklists.sql
  20. 160 0
      doc/lc-base-frame/sys_apis.sql
  21. 4 0
      doc/lc-base-frame/sys_authorities.sql
  22. 1 0
      doc/lc-base-frame/sys_authority_btns.sql
  23. 54 0
      doc/lc-base-frame/sys_authority_menus.sql
  24. 8 0
      doc/lc-base-frame/sys_auto_code_histories.sql
  25. 2 0
      doc/lc-base-frame/sys_auto_codes.sql
  26. 2 0
      doc/lc-base-frame/sys_base_menu_btns.sql
  27. 2 0
      doc/lc-base-frame/sys_base_menu_parameters.sql
  28. 34 0
      doc/lc-base-frame/sys_base_menus.sql
  29. 0 0
      doc/lc-base-frame/sys_chat_gpt_options.sql
  30. 5 0
      doc/lc-base-frame/sys_data_authority_id.sql
  31. 7 0
      doc/lc-base-frame/sys_dictionaries.sql
  32. 29 0
      doc/lc-base-frame/sys_dictionary_details.sql
  33. 1126 0
      doc/lc-base-frame/sys_operation_records.sql
  34. 4 0
      doc/lc-base-frame/sys_user_authority.sql
  35. 2 0
      doc/lc-base-frame/sys_users.sql
  36. 43 0
      global/global.go
  37. 103 0
      go.mod
  38. 745 0
      go.sum
  39. 73 0
      initialize/gorm.go
  40. 23 0
      initialize/other.go
  41. 26 0
      initialize/redis.go
  42. 52 0
      initialize/router.go
  43. 55 0
      main.go
  44. 38 0
      middleware/casbin_rbac.go
  45. 73 0
      middleware/cors.go
  46. 60 0
      middleware/email.go
  47. 61 0
      middleware/error.go
  48. 80 0
      middleware/jwt.go
  49. 93 0
      middleware/limit_ip.go
  50. 27 0
      middleware/loadtls.go
  51. 89 0
      middleware/logger.go
  52. 22 0
      middleware/need_init.go
  53. 135 0
      middleware/operation.go
  54. 28 0
      model/common/request/common.go
  55. 9 0
      model/common/response/common.go
  56. 54 0
      model/common/response/response.go
  57. 21 0
      model/system/request/jwt.go
  58. 14 0
      model/system/request/sys_api.go
  59. 7 0
      model/system/request/sys_authority_btn.go
  60. 13 0
      model/system/request/sys_auto_history.go
  61. 26 0
      model/system/request/sys_casbin.go
  62. 11 0
      model/system/request/sys_chatgpt.go
  63. 11 0
      model/system/request/sys_dictionary.go
  64. 11 0
      model/system/request/sys_dictionary_detail.go
  65. 101 0
      model/system/request/sys_init.go
  66. 27 0
      model/system/request/sys_menu.go
  67. 11 0
      model/system/request/sys_operation_record.go
  68. 61 0
      model/system/request/sys_user.go
  69. 11 0
      model/system/response/sys_api.go
  70. 12 0
      model/system/response/sys_authority.go
  71. 8 0
      model/system/response/sys_captcha.go
  72. 9 0
      model/system/response/sys_casbin.go
  73. 15 0
      model/system/response/sys_menu.go
  74. 20 0
      model/system/response/sys_user.go
  75. 17 0
      model/system/sys_api.go
  76. 23 0
      model/system/sys_authority.go
  77. 8 0
      model/system/sys_authority_btn.go
  78. 19 0
      model/system/sys_authority_menu.go
  79. 42 0
      model/system/sys_base_menu.go
  80. 20 0
      model/system/sys_dictionary.go
  81. 20 0
      model/system/sys_dictionary_detail.go
  82. 10 0
      model/system/sys_jwt_blacklist.go
  83. 10 0
      model/system/sys_menu_btn.go
  84. 24 0
      model/system/sys_operation_record.go
  85. 29 0
      model/system/sys_user.go
  86. 11 0
      model/system/sys_user_authority.go
  87. 11 0
      router/enter.go
  88. 19 0
      router/system/enter.go
  89. 30 0
      router/system/sys_api.go
  90. 25 0
      router/system/sys_authority.go
  91. 18 0
      router/system/sys_base.go
  92. 21 0
      router/system/sys_casbin.go
  93. 24 0
      router/system/sys_dictionary.go
  94. 24 0
      router/system/sys_dictionary_detail.go
  95. 16 0
      router/system/sys_jwt.go
  96. 29 0
      router/system/sys_menu.go
  97. 39 0
      router/system/sys_user.go
  98. 12 0
      service/enter.go
  99. 20 0
      service/system/enter.go
  100. 0 0
      service/system/jwt_black_list.go

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
.idea/lc-fangdaosha.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/lc-base-frame.iml" filepath="$PROJECT_DIR$/.idea/lc-base-frame.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>

+ 11 - 0
api/v1/enter.go

@@ -0,0 +1,11 @@
+package v1
+
+import (
+	"lc-fangdaosha/api/v1/system"
+)
+
+type ApiGroup struct {
+	SystemApiGroup system.ApiGroup
+}
+
+var ApiGroupApp = new(ApiGroup)

+ 70 - 0
api/v1/system/base.go

@@ -0,0 +1,70 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/mojocn/base64Captcha"
+	"github.com/sirupsen/logrus"
+	"go.uber.org/zap"
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/common/response"
+	systemResp "lc-fangdaosha/model/system/response"
+	"time"
+)
+
+// 当开启多服务器部署时,替换下面的配置,使用redis共享存储验证码
+// var store = captcha.NewDefaultRedisStore()
+var store = base64Captcha.DefaultMemStore
+
+type BaseApi struct{}
+
+// Captcha
+// @Tags      Base
+// @Summary   生成验证码
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Success   200  {object}  response.Response{data=systemResp.SysCaptchaResponse,msg=string}  "生成验证码,返回包括随机数id,base64,验证码长度,是否开启验证码"
+// @Router    /base/captcha [post]
+func (b *BaseApi) Captcha(c *gin.Context) {
+	// 判断验证码是否开启
+	openCaptcha := global.Config.Captcha.OpenCaptcha
+	openCaptchaTimeOut := global.Config.Captcha.OpenCaptchaTimeOut // 缓存超时时间
+	key := c.ClientIP()
+	v, ok := global.BlackCache.Get(key)
+	if !ok {
+		global.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut))
+	}
+
+	var oc bool
+	if openCaptcha == 0 || openCaptcha < interfaceToInt(v) {
+		oc = true
+	}
+	// 字符,公式,验证码配置
+	// 生成默认数字的driver
+	driver := base64Captcha.NewDriverDigit(global.Config.Captcha.ImgHeight, global.Config.Captcha.ImgWidth, global.Config.Captcha.KeyLong, 0.7, 80)
+	// cp := base64Captcha.NewCaptcha(driver, store.UseWithCtx(c))   // v8下使用redis
+	cp := base64Captcha.NewCaptcha(driver, store)
+	id, b64s, err := cp.Generate()
+	if err != nil {
+		logrus.Error("验证码获取失败!", zap.Error(err))
+		response.FailWithMessage("验证码获取失败", c)
+		return
+	}
+	response.OkWithDetailed(systemResp.SysCaptchaResponse{
+		CaptchaId:     id,
+		PicPath:       b64s,
+		CaptchaLength: global.Config.Captcha.KeyLong,
+		OpenCaptcha:   oc,
+	}, "验证码获取成功", c)
+}
+
+// 类型转换
+func interfaceToInt(v interface{}) (i int) {
+	switch v := v.(type) {
+	case int:
+		i = v
+	default:
+		i = 0
+	}
+	return
+}

+ 40 - 0
api/v1/system/enter.go

@@ -0,0 +1,40 @@
+package system
+
+import "lc-fangdaosha/service"
+
+type ApiGroup struct {
+	BaseApi
+	AuthorityMenuApi
+	//DBApi
+	JwtApi
+	//SystemApi
+	CasbinApi
+	//AutoCodeApi
+	SystemApiApi
+	AuthorityApi
+	DictionaryApi
+	//OperationRecordApi
+	//AutoCodeHistoryApi
+	DictionaryDetailApi
+	//AuthorityBtnApi
+	//ChatGptApi
+}
+
+var (
+	apiService  = service.ServiceGroupApp.SystemServiceGroup.ApiService
+	jwtService  = service.ServiceGroupApp.SystemServiceGroup.JwtService
+	menuService = service.ServiceGroupApp.SystemServiceGroup.MenuService
+	userService = service.ServiceGroupApp.SystemServiceGroup.UserService
+	//initDBService           = service.ServiceGroupApp.SystemServiceGroup.InitDBService
+	casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
+	//autoCodeService         = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService
+	baseMenuService   = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService
+	authorityService  = service.ServiceGroupApp.SystemServiceGroup.AuthorityService
+	dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService
+	//systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService
+	//operationRecordService  = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
+	//autoCodeHistoryService  = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService
+	dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
+	//authorityBtnService     = service.ServiceGroupApp.SystemServiceGroup.AuthorityBtnService
+	//chatGptService          = service.ServiceGroupApp.SystemServiceGroup.ChatGptService
+)

+ 231 - 0
api/v1/system/sys_api.go

@@ -0,0 +1,231 @@
+package system
+
+import (
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	systemReq "lc-fangdaosha/model/system/request"
+	systemRes "lc-fangdaosha/model/system/response"
+	"lc-fangdaosha/utils"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+type SystemApiApi struct{}
+
+// CreateApi
+// @Tags      SysApi
+// @Summary   创建基础api
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysApi                  true  "api路径, api中文描述, api组, 方法"
+// @Success   200   {object}  response.Response{msg=string}  "创建基础api"
+// @Router    /api/createApi [post]
+func (s *SystemApiApi) CreateApi(c *gin.Context) {
+	var api system.SysApi
+	err := c.ShouldBindJSON(&api)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(api, utils.ApiVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = apiService.CreateApi(api)
+	if err != nil {
+		logrus.Error("创建失败!", zap.Error(err))
+		response.FailWithMessage("创建失败", c)
+		return
+	}
+	response.OkWithMessage("创建成功", c)
+}
+
+// DeleteApi
+// @Tags      SysApi
+// @Summary   删除api
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysApi                  true  "ID"
+// @Success   200   {object}  response.Response{msg=string}  "删除api"
+// @Router    /api/deleteApi [post]
+func (s *SystemApiApi) DeleteApi(c *gin.Context) {
+	var api system.SysApi
+	err := c.ShouldBindJSON(&api)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(api.GVA_MODEL, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = apiService.DeleteApi(api)
+	if err != nil {
+		logrus.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// GetApiList
+// @Tags      SysApi
+// @Summary   分页获取API列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      systemReq.SearchApiParams                               true  "分页获取API列表"
+// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取API列表,返回包括列表,总数,页码,每页数量"
+// @Router    /api/getApiList [post]
+func (s *SystemApiApi) GetApiList(c *gin.Context) {
+	var pageInfo systemReq.SearchApiParams
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := apiService.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc)
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}
+
+// GetApiById
+// @Tags      SysApi
+// @Summary   根据id获取api
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.GetById                                   true  "根据id获取api"
+// @Success   200   {object}  response.Response{data=systemRes.SysAPIResponse}  "根据id获取api,返回包括api详情"
+// @Router    /api/getApiById [post]
+func (s *SystemApiApi) GetApiById(c *gin.Context) {
+	var idInfo request.GetById
+	err := c.ShouldBindJSON(&idInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(idInfo, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	api, err := apiService.GetApiById(idInfo.ID)
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(systemRes.SysAPIResponse{Api: api}, "获取成功", c)
+}
+
+// UpdateApi
+// @Tags      SysApi
+// @Summary   修改基础api
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysApi                  true  "api路径, api中文描述, api组, 方法"
+// @Success   200   {object}  response.Response{msg=string}  "修改基础api"
+// @Router    /api/updateApi [post]
+func (s *SystemApiApi) UpdateApi(c *gin.Context) {
+	var api system.SysApi
+	err := c.ShouldBindJSON(&api)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(api, utils.ApiVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = apiService.UpdateApi(api)
+	if err != nil {
+		logrus.Error("修改失败!", zap.Error(err))
+		response.FailWithMessage("修改失败", c)
+		return
+	}
+	response.OkWithMessage("修改成功", c)
+}
+
+// GetAllApis
+// @Tags      SysApi
+// @Summary   获取所有的Api 不分页
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Success   200  {object}  response.Response{data=systemRes.SysAPIListResponse,msg=string}  "获取所有的Api 不分页,返回包括api列表"
+// @Router    /api/getAllApis [post]
+func (s *SystemApiApi) GetAllApis(c *gin.Context) {
+	apis, err := apiService.GetAllApis()
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(systemRes.SysAPIListResponse{Apis: apis}, "获取成功", c)
+}
+
+// DeleteApisByIds
+// @Tags      SysApi
+// @Summary   删除选中Api
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.IdsReq                 true  "ID"
+// @Success   200   {object}  response.Response{msg=string}  "删除选中Api"
+// @Router    /api/deleteApisByIds [delete]
+func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) {
+	var ids request.IdsReq
+	err := c.ShouldBindJSON(&ids)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = apiService.DeleteApisByIds(ids)
+	if err != nil {
+		logrus.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// FreshCasbin
+// @Tags      SysApi
+// @Summary   刷新casbin缓存
+// @accept    application/json
+// @Produce   application/json
+// @Success   200   {object}  response.Response{msg=string}  "刷新成功"
+// @Router    /api/freshCasbin [get]
+func (s *SystemApiApi) FreshCasbin(c *gin.Context) {
+	err := apiService.FreshCasbin()
+	if err != nil {
+		logrus.Error("刷新失败!", err)
+		response.FailWithMessage("刷新失败", c)
+		return
+	}
+	response.OkWithMessage("刷新成功", c)
+}

+ 208 - 0
api/v1/system/sys_authority.go

@@ -0,0 +1,208 @@
+package system
+
+import (
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	systemReq "lc-fangdaosha/model/system/request"
+	systemRes "lc-fangdaosha/model/system/response"
+	"lc-fangdaosha/utils"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+type AuthorityApi struct{}
+
+// CreateAuthority
+// @Tags      Authority
+// @Summary   创建角色
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysAuthority                                                true  "权限id, 权限名, 父角色id"
+// @Success   200   {object}  response.Response{data=systemRes.SysAuthorityResponse,msg=string}  "创建角色,返回包括系统角色详情"
+// @Router    /authority/createAuthority [post]
+func (a *AuthorityApi) CreateAuthority(c *gin.Context) {
+	var authority system.SysAuthority
+	err := c.ShouldBindJSON(&authority)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	err = utils.Verify(authority, utils.AuthorityVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if authBack, err := authorityService.CreateAuthority(authority); err != nil {
+		logrus.Error("创建失败!", zap.Error(err))
+		response.FailWithMessage("创建失败"+err.Error(), c)
+	} else {
+		_ = menuService.AddMenuAuthority(systemReq.DefaultMenu(), authority.AuthorityId)
+		_ = casbinService.UpdateCasbin(authority.AuthorityId, systemReq.DefaultCasbin())
+		response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "创建成功", c)
+	}
+}
+
+// CopyAuthority
+// @Tags      Authority
+// @Summary   拷贝角色
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      response.SysAuthorityCopyResponse                                  true  "旧角色id, 新权限id, 新权限名, 新父角色id"
+// @Success   200   {object}  response.Response{data=systemRes.SysAuthorityResponse,msg=string}  "拷贝角色,返回包括系统角色详情"
+// @Router    /authority/copyAuthority [post]
+func (a *AuthorityApi) CopyAuthority(c *gin.Context) {
+	var copyInfo systemRes.SysAuthorityCopyResponse
+	err := c.ShouldBindJSON(&copyInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(copyInfo, utils.OldAuthorityVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(copyInfo.Authority, utils.AuthorityVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	authBack, err := authorityService.CopyAuthority(copyInfo)
+	if err != nil {
+		logrus.Error("拷贝失败!", zap.Error(err))
+		response.FailWithMessage("拷贝失败"+err.Error(), c)
+		return
+	}
+	response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c)
+}
+
+// DeleteAuthority
+// @Tags      Authority
+// @Summary   删除角色
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysAuthority            true  "删除角色"
+// @Success   200   {object}  response.Response{msg=string}  "删除角色"
+// @Router    /authority/deleteAuthority [post]
+func (a *AuthorityApi) DeleteAuthority(c *gin.Context) {
+	var authority system.SysAuthority
+	err := c.ShouldBindJSON(&authority)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(authority, utils.AuthorityIdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = authorityService.DeleteAuthority(&authority)
+	if err != nil { // 删除角色之前需要判断是否有用户正在使用此角色
+		logrus.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败"+err.Error(), c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// UpdateAuthority
+// @Tags      Authority
+// @Summary   更新角色信息
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysAuthority                                                true  "权限id, 权限名, 父角色id"
+// @Success   200   {object}  response.Response{data=systemRes.SysAuthorityResponse,msg=string}  "更新角色信息,返回包括系统角色详情"
+// @Router    /authority/updateAuthority [post]
+func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
+	var auth system.SysAuthority
+	err := c.ShouldBindJSON(&auth)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(auth, utils.AuthorityVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	authority, err := authorityService.UpdateAuthority(auth)
+	if err != nil {
+		logrus.Error("更新失败!", zap.Error(err))
+		response.FailWithMessage("更新失败"+err.Error(), c)
+		return
+	}
+	response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authority}, "更新成功", c)
+}
+
+// GetAuthorityList
+// @Tags      Authority
+// @Summary   分页获取角色列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.PageInfo                                        true  "页码, 每页大小"
+// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取角色列表,返回包括列表,总数,页码,每页数量"
+// @Router    /authority/getAuthorityList [post]
+func (a *AuthorityApi) GetAuthorityList(c *gin.Context) {
+	var pageInfo request.PageInfo
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := authorityService.GetAuthorityInfoList(pageInfo)
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败"+err.Error(), c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}
+
+// SetDataAuthority
+// @Tags      Authority
+// @Summary   设置角色资源权限
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysAuthority            true  "设置角色资源权限"
+// @Success   200   {object}  response.Response{msg=string}  "设置角色资源权限"
+// @Router    /authority/setDataAuthority [post]
+func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
+	var auth system.SysAuthority
+	err := c.ShouldBindJSON(&auth)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(auth, utils.AuthorityIdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = authorityService.SetDataAuthority(auth)
+	if err != nil {
+		logrus.Error("设置失败!", zap.Error(err))
+		response.FailWithMessage("设置失败"+err.Error(), c)
+		return
+	}
+	response.OkWithMessage("设置成功", c)
+}

+ 68 - 0
api/v1/system/sys_casbin.go

@@ -0,0 +1,68 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"go.uber.org/zap"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system/request"
+	systemRes "lc-fangdaosha/model/system/response"
+	"lc-fangdaosha/utils"
+)
+
+type CasbinApi struct{}
+
+// UpdateCasbin
+// @Tags      Casbin
+// @Summary   更新角色api权限
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.CasbinInReceive        true  "权限id, 权限模型列表"
+// @Success   200   {object}  response.Response{msg=string}  "更新角色api权限"
+// @Router    /casbin/UpdateCasbin [post]
+func (cas *CasbinApi) UpdateCasbin(c *gin.Context) {
+	var cmr request.CasbinInReceive
+	err := c.ShouldBindJSON(&cmr)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(cmr, utils.AuthorityIdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos)
+	if err != nil {
+		logrus.Error("更新失败!", zap.Error(err))
+		response.FailWithMessage("更新失败", c)
+		return
+	}
+	response.OkWithMessage("更新成功", c)
+}
+
+// GetPolicyPathByAuthorityId
+// @Tags      Casbin
+// @Summary   获取权限列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.CasbinInReceive                                          true  "权限id, 权限模型列表"
+// @Success   200   {object}  response.Response{data=systemRes.PolicyPathResponse,msg=string}  "获取权限列表,返回包括casbin详情列表"
+// @Router    /casbin/getPolicyPathByAuthorityId [post]
+func (cas *CasbinApi) GetPolicyPathByAuthorityId(c *gin.Context) {
+	var casbin request.CasbinInReceive
+	err := c.ShouldBindJSON(&casbin)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(casbin, utils.AuthorityIdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	paths := casbinService.GetPolicyPathByAuthorityId(casbin.AuthorityId)
+	response.OkWithDetailed(systemRes.PolicyPathResponse{Paths: paths}, "获取成功", c)
+}

+ 147 - 0
api/v1/system/sys_dictionary.go

@@ -0,0 +1,147 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	"lc-fangdaosha/model/system/request"
+	"lc-fangdaosha/utils"
+)
+
+type DictionaryApi struct{}
+
+// CreateSysDictionary
+// @Tags      SysDictionary
+// @Summary   创建SysDictionary
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysDictionary           true  "SysDictionary模型"
+// @Success   200   {object}  response.Response{msg=string}  "创建SysDictionary"
+// @Router    /sysDictionary/createSysDictionary [post]
+func (s *DictionaryApi) CreateSysDictionary(c *gin.Context) {
+	var dictionary system.SysDictionary
+	err := c.ShouldBindJSON(&dictionary)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = dictionaryService.CreateSysDictionary(dictionary)
+	if err != nil {
+		logrus.Error("创建失败!", err)
+		response.FailWithMessage("创建失败", c)
+		return
+	}
+	response.OkWithMessage("创建成功", c)
+}
+
+// DeleteSysDictionary
+// @Tags      SysDictionary
+// @Summary   删除SysDictionary
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysDictionary           true  "SysDictionary模型"
+// @Success   200   {object}  response.Response{msg=string}  "删除SysDictionary"
+// @Router    /sysDictionary/deleteSysDictionary [delete]
+func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) {
+	var dictionary system.SysDictionary
+	err := c.ShouldBindJSON(&dictionary)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = dictionaryService.DeleteSysDictionary(dictionary)
+	if err != nil {
+		logrus.Error("删除失败!", err)
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// UpdateSysDictionary
+// @Tags      SysDictionary
+// @Summary   更新SysDictionary
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysDictionary           true  "SysDictionary模型"
+// @Success   200   {object}  response.Response{msg=string}  "更新SysDictionary"
+// @Router    /sysDictionary/updateSysDictionary [put]
+func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) {
+	var dictionary system.SysDictionary
+	err := c.ShouldBindJSON(&dictionary)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = dictionaryService.UpdateSysDictionary(&dictionary)
+	if err != nil {
+		logrus.Error("更新失败!", err)
+		response.FailWithMessage("更新失败", c)
+		return
+	}
+	response.OkWithMessage("更新成功", c)
+}
+
+// FindSysDictionary
+// @Tags      SysDictionary
+// @Summary   用id查询SysDictionary
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  query     system.SysDictionary                                       true  "ID或字典英名"
+// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "用id查询SysDictionary"
+// @Router    /sysDictionary/findSysDictionary [get]
+func (s *DictionaryApi) FindSysDictionary(c *gin.Context) {
+	var dictionary system.SysDictionary
+	err := c.ShouldBindQuery(&dictionary)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	sysDictionary, err := dictionaryService.GetSysDictionary(dictionary.Type, dictionary.ID, dictionary.Status)
+	if err != nil {
+		logrus.Error("字典未创建或未开启!", err)
+		response.FailWithMessage("字典未创建或未开启", c)
+		return
+	}
+	response.OkWithDetailed(gin.H{"resysDictionary": sysDictionary}, "查询成功", c)
+}
+
+// GetSysDictionaryList
+// @Tags      SysDictionary
+// @Summary   分页获取SysDictionary列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  query     request.SysDictionarySearch                             true  "页码, 每页大小, 搜索条件"
+// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量"
+// @Router    /sysDictionary/getSysDictionaryList [get]
+func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) {
+	var pageInfo request.SysDictionarySearch
+	err := c.ShouldBindQuery(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := dictionaryService.GetSysDictionaryInfoList(pageInfo)
+	if err != nil {
+		logrus.Error("获取失败!", err)
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}

+ 147 - 0
api/v1/system/sys_dictionary_detail.go

@@ -0,0 +1,147 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	"lc-fangdaosha/model/system/request"
+	"lc-fangdaosha/utils"
+)
+
+type DictionaryDetailApi struct{}
+
+// CreateSysDictionaryDetail
+// @Tags      SysDictionaryDetail
+// @Summary   创建SysDictionaryDetail
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysDictionaryDetail     true  "SysDictionaryDetail模型"
+// @Success   200   {object}  response.Response{msg=string}  "创建SysDictionaryDetail"
+// @Router    /sysDictionaryDetail/createSysDictionaryDetail [post]
+func (s *DictionaryDetailApi) CreateSysDictionaryDetail(c *gin.Context) {
+	var detail system.SysDictionaryDetail
+	err := c.ShouldBindJSON(&detail)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = dictionaryDetailService.CreateSysDictionaryDetail(detail)
+	if err != nil {
+		logrus.Error("创建失败!", err)
+		response.FailWithMessage("创建失败", c)
+		return
+	}
+	response.OkWithMessage("创建成功", c)
+}
+
+// DeleteSysDictionaryDetail
+// @Tags      SysDictionaryDetail
+// @Summary   删除SysDictionaryDetail
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysDictionaryDetail     true  "SysDictionaryDetail模型"
+// @Success   200   {object}  response.Response{msg=string}  "删除SysDictionaryDetail"
+// @Router    /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
+func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) {
+	var detail system.SysDictionaryDetail
+	err := c.ShouldBindJSON(&detail)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = dictionaryDetailService.DeleteSysDictionaryDetail(detail)
+	if err != nil {
+		logrus.Error("删除失败!", err)
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// UpdateSysDictionaryDetail
+// @Tags      SysDictionaryDetail
+// @Summary   更新SysDictionaryDetail
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysDictionaryDetail     true  "更新SysDictionaryDetail"
+// @Success   200   {object}  response.Response{msg=string}  "更新SysDictionaryDetail"
+// @Router    /sysDictionaryDetail/updateSysDictionaryDetail [put]
+func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) {
+	var detail system.SysDictionaryDetail
+	err := c.ShouldBindJSON(&detail)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = dictionaryDetailService.UpdateSysDictionaryDetail(&detail)
+	if err != nil {
+		logrus.Error("更新失败!", err)
+		response.FailWithMessage("更新失败", c)
+		return
+	}
+	response.OkWithMessage("更新成功", c)
+}
+
+// FindSysDictionaryDetail
+// @Tags      SysDictionaryDetail
+// @Summary   用id查询SysDictionaryDetail
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  query     system.SysDictionaryDetail                                 true  "用id查询SysDictionaryDetail"
+// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "用id查询SysDictionaryDetail"
+// @Router    /sysDictionaryDetail/findSysDictionaryDetail [get]
+func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) {
+	var detail system.SysDictionaryDetail
+	err := c.ShouldBindQuery(&detail)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(detail, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	reSysDictionaryDetail, err := dictionaryDetailService.GetSysDictionaryDetail(detail.ID)
+	if err != nil {
+		logrus.Error("查询失败!", err)
+		response.FailWithMessage("查询失败", c)
+		return
+	}
+	response.OkWithDetailed(gin.H{"reSysDictionaryDetail": reSysDictionaryDetail}, "查询成功", c)
+}
+
+// GetSysDictionaryDetailList
+// @Tags      SysDictionaryDetail
+// @Summary   分页获取SysDictionaryDetail列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  query     request.SysDictionaryDetailSearch                       true  "页码, 每页大小, 搜索条件"
+// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量"
+// @Router    /sysDictionaryDetail/getSysDictionaryDetailList [get]
+func (s *DictionaryDetailApi) GetSysDictionaryDetailList(c *gin.Context) {
+	var pageInfo request.SysDictionaryDetailSearch
+	err := c.ShouldBindQuery(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := dictionaryDetailService.GetSysDictionaryDetailInfoList(pageInfo)
+	if err != nil {
+		logrus.Error("获取失败!", err)
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}

+ 31 - 0
api/v1/system/sys_jwt_blacklist.go

@@ -0,0 +1,31 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"go.uber.org/zap"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+)
+
+type JwtApi struct{}
+
+// JsonInBlacklist
+// @Tags      Jwt
+// @Summary   jwt加入黑名单
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Success   200  {object}  response.Response{msg=string}  "jwt加入黑名单"
+// @Router    /jwt/jsonInBlacklist [post]
+func (j *JwtApi) JsonInBlacklist(c *gin.Context) {
+	token := c.Request.Header.Get("x-token")
+	jwt := system.JwtBlacklist{Jwt: token}
+	err := jwtService.JsonInBlacklist(jwt)
+	if err != nil {
+		logrus.Error("jwt作废失败!", zap.Error(err))
+		response.FailWithMessage("jwt作废失败", c)
+		return
+	}
+	response.OkWithMessage("jwt作废成功", c)
+}

+ 278 - 0
api/v1/system/sys_menu.go

@@ -0,0 +1,278 @@
+package system
+
+import (
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	systemReq "lc-fangdaosha/model/system/request"
+	systemRes "lc-fangdaosha/model/system/response"
+	"lc-fangdaosha/utils"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+type AuthorityMenuApi struct{}
+
+// GetMenu
+// @Tags      AuthorityMenu
+// @Summary   获取用户动态路由
+// @Security  ApiKeyAuth
+// @Produce   application/json
+// @Param     data  body      request.Empty                                                  true  "空"
+// @Success   200   {object}  response.Response{data=systemRes.SysMenusResponse,msg=string}  "获取用户动态路由,返回包括系统菜单详情列表"
+// @Router    /menu/getMenu [post]
+func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
+	menus, err := menuService.GetMenuTree(utils.GetUserAuthorityId(c))
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	if menus == nil {
+		menus = []system.SysMenu{}
+	}
+	response.OkWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取成功", c)
+}
+
+// GetBaseMenuTree
+// @Tags      AuthorityMenu
+// @Summary   获取用户动态路由
+// @Security  ApiKeyAuth
+// @Produce   application/json
+// @Param     data  body      request.Empty                                                      true  "空"
+// @Success   200   {object}  response.Response{data=systemRes.SysBaseMenusResponse,msg=string}  "获取用户动态路由,返回包括系统菜单列表"
+// @Router    /menu/getBaseMenuTree [post]
+func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) {
+	menus, err := menuService.GetBaseMenuTree()
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(systemRes.SysBaseMenusResponse{Menus: menus}, "获取成功", c)
+}
+
+// AddMenuAuthority
+// @Tags      AuthorityMenu
+// @Summary   增加menu和角色关联关系
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      systemReq.AddMenuAuthorityInfo  true  "角色ID"
+// @Success   200   {object}  response.Response{msg=string}   "增加menu和角色关联关系"
+// @Router    /menu/addMenuAuthority [post]
+func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
+	var authorityMenu systemReq.AddMenuAuthorityInfo
+	err := c.ShouldBindJSON(&authorityMenu)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if err := utils.Verify(authorityMenu, utils.AuthorityIdVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if err := menuService.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil {
+		logrus.Error("添加失败!", zap.Error(err))
+		response.FailWithMessage("添加失败", c)
+	} else {
+		response.OkWithMessage("添加成功", c)
+	}
+}
+
+// GetMenuAuthority
+// @Tags      AuthorityMenu
+// @Summary   获取指定角色menu
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.GetAuthorityId                                     true  "角色ID"
+// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "获取指定角色menu"
+// @Router    /menu/getMenuAuthority [post]
+func (a *AuthorityMenuApi) GetMenuAuthority(c *gin.Context) {
+	var param request.GetAuthorityId
+	err := c.ShouldBindJSON(&param)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(param, utils.AuthorityIdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	menus, err := menuService.GetMenuAuthority(&param)
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取失败", c)
+		return
+	}
+	response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
+}
+
+// AddBaseMenu
+// @Tags      Menu
+// @Summary   新增菜单
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysBaseMenu             true  "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
+// @Success   200   {object}  response.Response{msg=string}  "新增菜单"
+// @Router    /menu/addBaseMenu [post]
+func (a *AuthorityMenuApi) AddBaseMenu(c *gin.Context) {
+	var menu system.SysBaseMenu
+	err := c.ShouldBindJSON(&menu)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(menu, utils.MenuVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(menu.Meta, utils.MenuMetaVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = menuService.AddBaseMenu(menu)
+	if err != nil {
+		logrus.Error("添加失败!", zap.Error(err))
+		response.FailWithMessage("添加失败", c)
+		return
+	}
+	response.OkWithMessage("添加成功", c)
+}
+
+// DeleteBaseMenu
+// @Tags      Menu
+// @Summary   删除菜单
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.GetById                true  "菜单id"
+// @Success   200   {object}  response.Response{msg=string}  "删除菜单"
+// @Router    /menu/deleteBaseMenu [post]
+func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) {
+	var menu request.GetById
+	err := c.ShouldBindJSON(&menu)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(menu, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = baseMenuService.DeleteBaseMenu(menu.ID)
+	if err != nil {
+		logrus.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// UpdateBaseMenu
+// @Tags      Menu
+// @Summary   更新菜单
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysBaseMenu             true  "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
+// @Success   200   {object}  response.Response{msg=string}  "更新菜单"
+// @Router    /menu/updateBaseMenu [post]
+func (a *AuthorityMenuApi) UpdateBaseMenu(c *gin.Context) {
+	var menu system.SysBaseMenu
+	err := c.ShouldBindJSON(&menu)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(menu, utils.MenuVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(menu.Meta, utils.MenuMetaVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = baseMenuService.UpdateBaseMenu(menu)
+	if err != nil {
+		logrus.Error("更新失败!", zap.Error(err))
+		response.FailWithMessage("更新失败", c)
+		return
+	}
+	response.OkWithMessage("更新成功", c)
+}
+
+// GetBaseMenuById
+// @Tags      Menu
+// @Summary   根据id获取菜单
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.GetById                                                   true  "菜单id"
+// @Success   200   {object}  response.Response{data=systemRes.SysBaseMenuResponse,msg=string}  "根据id获取菜单,返回包括系统菜单列表"
+// @Router    /menu/getBaseMenuById [post]
+func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
+	var idInfo request.GetById
+	err := c.ShouldBindJSON(&idInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(idInfo, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	menu, err := baseMenuService.GetBaseMenuById(idInfo.ID)
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
+}
+
+// GetMenuList
+// @Tags      Menu
+// @Summary   分页获取基础menu列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.PageInfo                                        true  "页码, 每页大小"
+// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取基础menu列表,返回包括列表,总数,页码,每页数量"
+// @Router    /menu/getMenuList [post]
+func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) {
+	var pageInfo request.PageInfo
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	menuList, total, err := menuService.GetInfoList()
+	if err != nil {
+		logrus.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     menuList,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}

+ 542 - 0
api/v1/system/sys_user.go

@@ -0,0 +1,542 @@
+package system
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/go-redis/redis/v8"
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	systemReq "lc-fangdaosha/model/system/request"
+	systemResp "lc-fangdaosha/model/system/response"
+	"lc-fangdaosha/utils"
+	"strconv"
+	"time"
+)
+
+// Login
+// @Tags     Base
+// @Summary  用户登录
+// @Produce   application/json
+// @Param    data  body      systemReq.Login                                             true  "用户名, 密码, 验证码"
+// @Success  200   {object}  response.Response{data=systemRes.LoginResponse,msg=string}  "返回包括用户信息,token,过期时间"
+// @Router   /base/login [post]
+func (b *BaseApi) Login(c *gin.Context) {
+	//获取登录数据
+	var l systemReq.Login
+	err := c.ShouldBindJSON(&l)
+	key := c.ClientIP()
+
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	//校验数据
+	err = utils.Verify(l, utils.LoginVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	// 判断验证码是否开启
+	openCaptcha := global.Config.Captcha.OpenCaptcha
+	openCaptchaTimeOut := global.Config.Captcha.OpenCaptchaTimeOut // 缓存超时时间
+	v, ok := global.BlackCache.Get(key)
+	if !ok {
+		global.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut))
+	}
+	var oc bool = openCaptcha == 0 || openCaptcha < interfaceToInt(v)
+	if !oc || store.Verify(l.CaptchaId, l.Captcha, true) {
+		u := &system.SysUser{Username: l.Username, Password: l.Password}
+		user, err := userService.Login(u)
+		fmt.Println("user:", user)
+		if err != nil {
+			logrus.Error("登陆失败! 用户名不存在或者密码错误!", err)
+			// 验证码次数+1
+			global.BlackCache.Increment(key, 1)
+			response.FailWithMessage("用户名不存在或者密码错误", c)
+			return
+		}
+		if user.Enable != 1 {
+			logrus.Error("登陆失败! 用户被禁止登录!")
+			// 验证码次数+1
+			global.BlackCache.Increment(key, 1)
+			response.FailWithMessage("用户被禁止登录", c)
+			return
+		}
+		b.TokenNext(c, *user)
+		return
+	}
+	// 验证码次数+1
+	global.BlackCache.Increment(key, 1)
+	response.FailWithMessage("验证码错误", c)
+}
+
+// TokenNext 登录以后签发jwt
+func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
+	j := &utils.JWT{SigningKey: []byte(global.Config.JWT.SigningKey)} // 唯一签名
+	claims := j.CreateClaims(systemReq.BaseClaims{
+		UUID:        user.UUID,
+		ID:          user.ID,
+		NickName:    user.NickName,
+		Username:    user.Username,
+		AuthorityId: user.AuthorityId,
+	})
+	token, err := j.CreateToken(claims)
+	if err != nil {
+		logrus.Error("获取token失败!", err)
+		response.FailWithMessage("获取token失败", c)
+		return
+	}
+	if !global.Config.System.UseMultipoint {
+		response.OkWithDetailed(systemResp.LoginResponse{
+			User:      user,
+			Token:     token,
+			ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
+		}, "登录成功", c)
+		return
+	}
+
+	if jwtStr, err := jwtService.GetRedisJWT(user.Username); err == redis.Nil {
+		if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
+			logrus.Error("设置登录状态失败!", err)
+			response.FailWithMessage("设置登录状态失败", c)
+			return
+		}
+		response.OkWithDetailed(systemResp.LoginResponse{
+			User:      user,
+			Token:     token,
+			ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
+		}, "登录成功", c)
+	} else if err != nil {
+		logrus.Error("设置登录状态失败!", err)
+		response.FailWithMessage("设置登录状态失败", c)
+	} else {
+		var blackJWT system.JwtBlacklist
+		blackJWT.Jwt = jwtStr
+		if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
+			response.FailWithMessage("jwt作废失败", c)
+			return
+		}
+		if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
+			response.FailWithMessage("设置登录状态失败", c)
+			return
+		}
+		response.OkWithDetailed(systemResp.LoginResponse{
+			User:      user,
+			Token:     token,
+			ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
+		}, "登录成功", c)
+	}
+}
+
+// Register
+// @Tags     SysUser
+// @Summary  用户注册账号
+// @Produce   application/json
+// @Param    data  body      systemReq.Register                                            true  "用户名, 昵称, 密码, 角色ID"
+// @Success  200   {object}  response.Response{data=systemRes.SysUserResponse,msg=string}  "用户注册账号,返回包括用户信息"
+// @Router   /user/admin_register [post]
+func (b *BaseApi) Register(c *gin.Context) {
+	var r systemReq.Register
+	err := c.ShouldBindJSON(&r)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(r, utils.RegisterVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	var authorities []system.SysAuthority
+	for _, v := range r.AuthorityIds {
+		authorities = append(authorities, system.SysAuthority{
+			AuthorityId: v,
+		})
+	}
+	user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities, Enable: r.Enable, Phone: r.Phone, Email: r.Email}
+	userReturn, err := userService.Register(*user)
+	if err != nil {
+		logrus.Error("注册失败!", err)
+		response.FailWithDetailed(systemResp.SysUserResponse{User: userReturn}, "注册失败", c)
+		return
+	}
+	response.OkWithDetailed(systemResp.SysUserResponse{User: userReturn}, "注册成功", c)
+}
+
+// ChangePassword
+// @Tags      SysUser
+// @Summary   用户修改密码
+// @Security  ApiKeyAuth
+// @Produce  application/json
+// @Param     data  body      systemReq.ChangePasswordReq    true  "用户名, 原密码, 新密码"
+// @Success   200   {object}  response.Response{msg=string}  "用户修改密码"
+// @Router    /user/changePassword [post]
+func (b *BaseApi) ChangePassword(c *gin.Context) {
+	var req systemReq.ChangePasswordReq
+	err := c.ShouldBindJSON(&req)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(req, utils.ChangePasswordVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	uid := utils.GetUserID(c)
+	u := &system.SysUser{GVA_MODEL: global.GVA_MODEL{ID: uid}, Password: req.Password}
+	_, err = userService.ChangePassword(u, req.NewPassword)
+	if err != nil {
+		logrus.Error("修改失败!", err)
+		response.FailWithMessage("修改失败,原密码与当前账户不符", c)
+		return
+	}
+	response.OkWithMessage("修改成功", c)
+}
+
+// GetUserList
+// @Tags      SysUser
+// @Summary   分页获取用户列表
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.PageInfo                                        true  "页码, 每页大小"
+// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取用户列表,返回包括列表,总数,页码,每页数量"
+// @Router    /user/getUserList [post]
+func (b *BaseApi) GetUserList(c *gin.Context) {
+	var pageInfo request.PageInfo
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := userService.GetUserInfoList(pageInfo)
+	if err != nil {
+		logrus.Error("获取失败!", err)
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}
+
+// SetUserAuthority
+// @Tags      SysUser
+// @Summary   更改用户权限
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      systemReq.SetUserAuth          true  "用户UUID, 角色ID"
+// @Success   200   {object}  response.Response{msg=string}  "设置用户权限"
+// @Router    /user/setUserAuthority [post]
+func (b *BaseApi) SetUserAuthority(c *gin.Context) {
+	var sua systemReq.SetUserAuth
+	err := c.ShouldBindJSON(&sua)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if UserVerifyErr := utils.Verify(sua, utils.SetUserAuthorityVerify); UserVerifyErr != nil {
+		response.FailWithMessage(UserVerifyErr.Error(), c)
+		return
+	}
+	userID := utils.GetUserID(c)
+	err = userService.SetUserAuthority(userID, sua.AuthorityId)
+	if err != nil {
+		logrus.Error("修改失败!", err)
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	claims := utils.GetUserInfo(c)
+	j := &utils.JWT{SigningKey: []byte(global.Config.JWT.SigningKey)} // 唯一签名
+	claims.AuthorityId = sua.AuthorityId
+	if token, err := j.CreateToken(*claims); err != nil {
+		logrus.Error("修改失败!", err)
+		response.FailWithMessage(err.Error(), c)
+	} else {
+		c.Header("new-token", token)
+		c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt.Unix(), 10))
+		response.OkWithMessage("修改成功", c)
+	}
+}
+
+// SetUserAuthorities
+// @Tags      SysUser
+// @Summary   设置用户权限
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      systemReq.SetUserAuthorities   true  "用户UUID, 角色ID"
+// @Success   200   {object}  response.Response{msg=string}  "设置用户权限"
+// @Router    /user/setUserAuthorities [post]
+func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
+	var sua systemReq.SetUserAuthorities
+	err := c.ShouldBindJSON(&sua)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = userService.SetUserAuthorities(sua.ID, sua.AuthorityIds)
+	if err != nil {
+		logrus.Error("修改失败!", err)
+		response.FailWithMessage("修改失败", c)
+		return
+	}
+	response.OkWithMessage("修改成功", c)
+}
+
+// DeleteUser
+// @Tags      SysUser
+// @Summary   删除用户
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      request.GetById                true  "用户ID"
+// @Success   200   {object}  response.Response{msg=string}  "删除用户"
+// @Router    /user/deleteUser [delete]
+func (b *BaseApi) DeleteUser(c *gin.Context) {
+	var reqId request.GetById
+	err := c.ShouldBindJSON(&reqId)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(reqId, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	jwtId := utils.GetUserID(c)
+	if jwtId == uint(reqId.ID) {
+		response.FailWithMessage("删除失败, 自杀失败", c)
+		return
+	}
+	err = userService.DeleteUser(reqId.ID)
+	if err != nil {
+		logrus.Error("删除失败!", err)
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+// SetUserInfo
+// @Tags      SysUser
+// @Summary   设置用户信息
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysUser                                             true  "ID, 用户名, 昵称, 头像链接"
+// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "设置用户信息"
+// @Router    /user/setUserInfo [put]
+func (b *BaseApi) SetUserInfo(c *gin.Context) {
+	var user systemReq.ChangeUserInfo
+	err := c.ShouldBindJSON(&user)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(user, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	if len(user.AuthorityIds) != 0 {
+		err = userService.SetUserAuthorities(user.ID, user.AuthorityIds)
+		if err != nil {
+			logrus.Error("设置失败!", err)
+			response.FailWithMessage("设置失败", c)
+			return
+		}
+	}
+	err = userService.SetUserInfo(system.SysUser{
+		GVA_MODEL: global.GVA_MODEL{
+			ID: user.ID,
+		},
+		NickName:  user.NickName,
+		HeaderImg: user.HeaderImg,
+		Phone:     user.Phone,
+		Email:     user.Email,
+		SideMode:  user.SideMode,
+		Enable:    user.Enable,
+	})
+	if err != nil {
+		logrus.Error("设置失败!", err)
+		response.FailWithMessage("设置失败", c)
+		return
+	}
+	response.OkWithMessage("设置成功", c)
+}
+
+// SetSelfInfo
+// @Tags      SysUser
+// @Summary   设置用户信息
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Param     data  body      system.SysUser                                             true  "ID, 用户名, 昵称, 头像链接"
+// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "设置用户信息"
+// @Router    /user/SetSelfInfo [put]
+func (b *BaseApi) SetSelfInfo(c *gin.Context) {
+	var user systemReq.ChangeUserInfo
+	err := c.ShouldBindJSON(&user)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	user.ID = utils.GetUserID(c)
+	err = userService.SetSelfInfo(system.SysUser{
+		GVA_MODEL: global.GVA_MODEL{
+			ID: user.ID,
+		},
+		NickName:  user.NickName,
+		HeaderImg: user.HeaderImg,
+		Phone:     user.Phone,
+		Email:     user.Email,
+		SideMode:  user.SideMode,
+		Enable:    user.Enable,
+	})
+	if err != nil {
+		logrus.Error("设置失败!", err)
+		response.FailWithMessage("设置失败", c)
+		return
+	}
+	response.OkWithMessage("设置成功", c)
+}
+
+// GetUserInfo
+// @Tags      SysUser
+// @Summary   获取用户信息
+// @Security  ApiKeyAuth
+// @accept    application/json
+// @Produce   application/json
+// @Success   200  {object}  response.Response{data=map[string]interface{},msg=string}  "获取用户信息"
+// @Router    /user/getUserInfo [get]
+func (b *BaseApi) GetUserInfo(c *gin.Context) {
+	uuid := utils.GetUserUuid(c)
+	ReqUser, err := userService.GetUserInfo(uuid)
+	if err != nil {
+		logrus.Error("获取失败!", err)
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c)
+}
+
+// ResetPassword
+// @Tags      SysUser
+// @Summary   重置用户密码
+// @Security  ApiKeyAuth
+// @Produce  application/json
+// @Param     data  body      system.SysUser                 true  "ID"
+// @Success   200   {object}  response.Response{msg=string}  "重置用户密码"
+// @Router    /user/resetPassword [post]
+func (b *BaseApi) ResetPassword(c *gin.Context) {
+	var user system.SysUser
+	err := c.ShouldBindJSON(&user)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = userService.ResetPassword(user.ID)
+	if err != nil {
+		logrus.Error("重置失败!", err)
+		response.FailWithMessage("重置失败"+err.Error(), c)
+		return
+	}
+	response.OkWithMessage("重置成功", c)
+}
+
+// UserIdList 获取用户id,username列表
+func (b *BaseApi) UserIdList(c *gin.Context) {
+	id := utils.GetUserID(c)
+	ids, err := userService.UserId(id)
+	if err != nil {
+		logrus.Error("获取失败!", err)
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(ids, "获取成功", c)
+}
+
+func (b *BaseApi) AddEmails(c *gin.Context) {
+	var emails []systemReq.Email
+	err := c.ShouldBindJSON(&emails)
+	if err != nil {
+		logrus.Error("数据绑定失败", err)
+		response.FailWithMessage("参数绑定失败"+err.Error(), c)
+		return
+	}
+	for i, v := range emails {
+		err = utils.Verify(v, utils.EmailVerify)
+		if err != nil {
+			response.FailWithDetailed(err.Error(), fmt.Sprintf("第%d邮箱格式错误或长度超过50", i+1), c)
+			return
+		}
+	}
+	id := utils.GetUserID(c)
+	result := userService.SetAlarmEmail(id, emails)
+	if result != "" {
+		response.FailWithMessage("邮箱已绑定"+result, c)
+		return
+	}
+	response.Ok(c)
+}
+
+func (b *BaseApi) ConfirmEmail(c *gin.Context) {
+	id := c.Query("id")
+	code := c.Query("code")
+	result := userService.ConfirmEmail(id, code)
+	c.Header("Content-type", "text/html; charset=utf-8")
+	c.Writer.WriteString(result)
+	//response.OkWithData(result, c)
+}
+
+// UnbindEmail 解绑报警邮箱
+func (b *BaseApi) UnbindEmail(c *gin.Context) {
+	uid := utils.GetUserID(c)
+	var emails []systemReq.Email
+	err := c.ShouldBind(&emails)
+	if err != nil {
+		response.FailWithMessage("参数绑定失败", c)
+		return
+	}
+	result := userService.UnbindEmail(uid, emails)
+	if result != "" {
+		response.FailWithMessage(result, c)
+		return
+	}
+	response.Ok(c)
+}
+
+// UserUnbindEmail 解绑报警邮箱
+func (b *BaseApi) UserUnbindEmail(c *gin.Context) {
+	id := c.Query("id")
+	email := c.Query("email")
+	atoi, err := strconv.Atoi(id)
+	if err != nil {
+		logrus.Error(err)
+		return
+	}
+	var emails []systemReq.Email
+	result := userService.UnbindEmail(uint(atoi), append(emails, systemReq.Email{Email: email}))
+	if result != "" {
+		response.FailWithMessage(result, c)
+		return
+	}
+	response.Ok(c)
+}

+ 58 - 0
config.yaml

@@ -0,0 +1,58 @@
+#系统/后台相关
+system:
+  env: public
+  addr: 8889
+  db-type: mysql
+  oss-type: local
+  use-multipoint: false
+  use-redis: true
+  iplimit-count: 15000
+  iplimit-time: 3600
+  router-prefix: ""
+jwt:
+  signing-key: 86e7a688-8d7d-42a5-af86-ec61120601d5
+  expires-time: 100d
+  buffer-time: 1d
+  issuer: qmPlus
+captcha:
+  key-long: 6     #验证码长度
+  img-width: 240  #宽
+  img-height: 80  #高
+  open-captcha: 0 #开启验证码 1关闭,0开启
+  open-captcha-timeout: 3600  #有效期
+logrus:
+mysql:
+  path: 127.0.0.1
+  port: "3306"
+  config: charset=utf8mb4&parseTime=True&loc=Local
+  db-name: lcfns
+  username: root
+  password: root
+  prefix: ""
+  singular: false
+  engine: ""
+  max-idle-conns: 10
+  max-open-conns: 100
+  log-mode: info
+  log-zap: false
+#海康摄像头事件监听服务器,最多配三个,只需修改id,url,ipAddress和portNo
+HttpHostNotificationList:
+  HttpHostNotification:
+    -
+      id: 1
+      url: /event
+      protocolType: HTTP
+      parameterFormatType: XML
+      addressingFormatType: ipaddress
+      ipAddress: 192.168.110.69
+      portNo: 8850
+      httpBroken: true
+      httpAuthenticationMethod: none
+#调用外部接口
+foreign:
+  securityRewindUrl: "http://106.52.134.22:9099"
+#海康摄像头统一配置
+hikvision:
+  user: admin
+  password: kk176@lc
+  streamBaseUrl: "webrtc://106.52.134.22/live/"

+ 109 - 0
config/config.go

@@ -0,0 +1,109 @@
+package config
+
+import (
+	"github.com/sirupsen/logrus"
+	"gopkg.in/yaml.v3"
+	"io/ioutil"
+	"os"
+)
+
+var Config = initConfig()
+
+func initConfig() config {
+	var c config
+	open, err := os.Open("./config.yaml")
+	if err != nil {
+		logrus.Fatal("打开文件读取错误", err)
+	}
+	data, err := ioutil.ReadAll(open)
+	if err != nil {
+		logrus.Fatal("读取配置文件错误", err)
+	}
+	if yaml.Unmarshal(data, &c) != nil {
+		logrus.Fatal("解析配置文件错误", err)
+	}
+	logrus.Info("配置文件读取成功:%+v", c)
+	return c
+}
+
+type config struct {
+	System  System  `mapstructure:"system" json:"system" yaml:"system"`
+	JWT     JWT     `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
+	Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
+	Cors    CORS    `mapstructure:"cors" json:"cors" yaml:"cors"`
+	Mysql   Mysql   `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
+	Redis   Redis   `mapstructure:"redis" json:"redis" yaml:"redis"`
+}
+
+type System struct {
+	Env           string `mapstructure:"env" json:"env" yaml:"env"`                                  // 环境值
+	Addr          int    `mapstructure:"addr" json:"addr" yaml:"addr"`                               // 端口值
+	DbType        string `mapstructure:"db-type" json:"db-type" yaml:"db-type"`                      // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql
+	OssType       string `mapstructure:"oss-type" json:"oss-type" yaml:"oss-type"`                   // Oss类型
+	UseMultipoint bool   `mapstructure:"use-multipoint" json:"use-multipoint" yaml:"use-multipoint"` // 多点登录拦截
+	UseRedis      bool   `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"`                // 使用redis
+	LimitCountIP  int    `mapstructure:"iplimit-count" json:"iplimit-count" yaml:"iplimit-count"`
+	LimitTimeIP   int    `mapstructure:"iplimit-time" json:"iplimit-time" yaml:"iplimit-time"`
+	RouterPrefix  string `mapstructure:"router-prefix" json:"router-prefix" yaml:"router-prefix"`
+}
+
+type JWT struct {
+	SigningKey  string `mapstructure:"signing-key" json:"signing-key" yaml:"signing-key"`    // jwt签名
+	ExpiresTime string `mapstructure:"expires-time" json:"expires-time" yaml:"expires-time"` // 过期时间
+	BufferTime  string `mapstructure:"buffer-time" json:"buffer-time" yaml:"buffer-time"`    // 缓冲时间
+	Issuer      string `mapstructure:"issuer" json:"issuer" yaml:"issuer"`                   // 签发者
+}
+
+type Captcha struct {
+	KeyLong            int `mapstructure:"key-long" json:"key-long" yaml:"key-long"`                                     // 验证码长度
+	ImgWidth           int `mapstructure:"img-width" json:"img-width" yaml:"img-width"`                                  // 验证码宽度
+	ImgHeight          int `mapstructure:"img-height" json:"img-height" yaml:"img-height"`                               // 验证码高度
+	OpenCaptcha        int `mapstructure:"open-captcha" json:"open-captcha" yaml:"open-captcha"`                         // 防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码
+	OpenCaptchaTimeOut int `mapstructure:"open-captcha-timeout" json:"open-captcha-timeout" yaml:"open-captcha-timeout"` // 防爆破验证码超时时间,单位:s(秒)
+}
+
+type CORS struct {
+	Mode      string          `mapstructure:"mode" json:"mode" yaml:"mode"`
+	Whitelist []CORSWhitelist `mapstructure:"whitelist" json:"whitelist" yaml:"whitelist"`
+}
+
+type CORSWhitelist struct {
+	AllowOrigin      string `mapstructure:"allow-origin" json:"allow-origin" yaml:"allow-origin"`
+	AllowMethods     string `mapstructure:"allow-methods" json:"allow-methods" yaml:"allow-methods"`
+	AllowHeaders     string `mapstructure:"allow-headers" json:"allow-headers" yaml:"allow-headers"`
+	ExposeHeaders    string `mapstructure:"expose-headers" json:"expose-headers" yaml:"expose-headers"`
+	AllowCredentials bool   `mapstructure:"allow-credentials" json:"allow-credentials" yaml:"allow-credentials"`
+}
+
+type Mysql struct {
+	GeneralDB `yaml:",inline" mapstructure:",squash"`
+}
+
+func (m *Mysql) Dsn() string {
+	return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config
+}
+
+func (m *Mysql) GetLogMode() string {
+	return m.LogMode
+}
+
+type GeneralDB struct {
+	Path         string `mapstructure:"path" json:"path" yaml:"path"`                               // 服务器地址:端口
+	Port         string `mapstructure:"port" json:"port" yaml:"port"`                               //:端口
+	Config       string `mapstructure:"config" json:"config" yaml:"config"`                         // 高级配置
+	Dbname       string `mapstructure:"db-name" json:"db-name" yaml:"db-name"`                      // 数据库名
+	Username     string `mapstructure:"username" json:"username" yaml:"username"`                   // 数据库用户名
+	Password     string `mapstructure:"password" json:"password" yaml:"password"`                   // 数据库密码
+	Prefix       string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`                         //全局表前缀,单独定义TableName则不生效
+	Singular     bool   `mapstructure:"singular" json:"singular" yaml:"singular"`                   //是否开启全局禁用复数,true表示开启
+	Engine       string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"`        //数据库引擎,默认InnoDB
+	MaxIdleConns int    `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数
+	MaxOpenConns int    `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
+	LogMode      string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"`                   // 是否开启Gorm全局日志
+	LogZap       bool   `mapstructure:"log-zap" json:"log-zap" yaml:"log-zap"`                      // 是否通过zap写入日志文件
+}
+type Redis struct {
+	DB       int    `mapstructure:"db" json:"db" yaml:"db"`                   // redis的哪个数据库
+	Addr     string `mapstructure:"addr" json:"addr" yaml:"addr"`             // 服务器地址:端口
+	Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
+}

+ 237 - 0
doc/lc-base-frame/casbin_rule.sql

@@ -0,0 +1,237 @@
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2045, 'p', '2', '/jwt/jsonInBlacklist', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2051, 'p', '2', '/menu/getMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2044, 'p', '2', '/test', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2046, 'p', '2', '/user/admin_register', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2049, 'p', '2', '/user/changePassword', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2048, 'p', '2', '/user/getUserInfo', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2050, 'p', '2', '/user/setUserAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2047, 'p', '2', '/user/setUserInfo', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2571, 'p', '888', '/api/createApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2572, 'p', '888', '/api/deleteApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2577, 'p', '888', '/api/deleteApisByIds', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2575, 'p', '888', '/api/getAllApis', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2576, 'p', '888', '/api/getApiById', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2574, 'p', '888', '/api/getApiList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2573, 'p', '888', '/api/updateApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2578, 'p', '888', '/authority/copyAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2579, 'p', '888', '/authority/createAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2580, 'p', '888', '/authority/deleteAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2582, 'p', '888', '/authority/getAuthorityList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2583, 'p', '888', '/authority/setDataAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2581, 'p', '888', '/authority/updateAuthority', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2647, 'p', '888', '/authorityBtn/canRemoveAuthorityBtn', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2646, 'p', '888', '/authorityBtn/getAuthorityBtn', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2645, 'p', '888', '/authorityBtn/setAuthorityBtn', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2619, 'p', '888', '/autoCode/createPackage', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2616, 'p', '888', '/autoCode/createPlug', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2613, 'p', '888', '/autoCode/createTemp', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2621, 'p', '888', '/autoCode/delPackage', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2625, 'p', '888', '/autoCode/delSysHistory', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2615, 'p', '888', '/autoCode/getColumn', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2611, 'p', '888', '/autoCode/getDB', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2622, 'p', '888', '/autoCode/getMeta', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2620, 'p', '888', '/autoCode/getPackage', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2624, 'p', '888', '/autoCode/getSysHistory', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2612, 'p', '888', '/autoCode/getTables', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2617, 'p', '888', '/autoCode/installPlugin', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2614, 'p', '888', '/autoCode/preview', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2618, 'p', '888', '/autoCode/pubPlug', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2623, 'p', '888', '/autoCode/rollback', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2652, 'p', '888', '/camera/createCamera', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2653, 'p', '888', '/camera/deleteCamera', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2654, 'p', '888', '/camera/deleteCameraByIds', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2656, 'p', '888', '/camera/findCamera', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2657, 'p', '888', '/camera/getCameraList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2680, 'p', '888', '/camera/rewind', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2658, 'p', '888', '/camera/rewind', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2655, 'p', '888', '/camera/updateCamera', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2585, 'p', '888', '/casbin/getPolicyPathByAuthorityId', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2584, 'p', '888', '/casbin/updateCasbin', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2649, 'p', '888', '/chatGpt/createSK', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2651, 'p', '888', '/chatGpt/deleteSK', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2650, 'p', '888', '/chatGpt/getSK', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2648, 'p', '888', '/chatGpt/getTable', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2608, 'p', '888', '/customer/customer', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2609, 'p', '888', '/customer/customer', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2607, 'p', '888', '/customer/customer', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2606, 'p', '888', '/customer/customer', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2610, 'p', '888', '/customer/customerList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2644, 'p', '888', '/email/emailTest', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2685, 'p', '888', '/event/dictionary', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2683, 'p', '888', '/event/list', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2596, 'p', '888', '/fileUploadAndDownload/breakpointContinue', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2597, 'p', '888', '/fileUploadAndDownload/breakpointContinueFinish', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2600, 'p', '888', '/fileUploadAndDownload/deleteFile', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2601, 'p', '888', '/fileUploadAndDownload/editFileName', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2595, 'p', '888', '/fileUploadAndDownload/findFile', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2602, 'p', '888', '/fileUploadAndDownload/getFileList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2598, 'p', '888', '/fileUploadAndDownload/removeChunk', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2599, 'p', '888', '/fileUploadAndDownload/upload', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2678, 'p', '888', '/gateways/adminSet', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2677, 'p', '888', '/gateways/all', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2681, 'p', '888', '/gateways/delete', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2682, 'p', '888', '/gateways/unbind', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2679, 'p', '888', '/gateways/userSet', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2663, 'p', '888', '/ISAPI/Smart/channels/1/calibrations/FieldDetection', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2664, 'p', '888', '/ISAPI/Smart/channels/1/calibrations/FieldDetection', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2668, 'p', '888', '/ISAPI/Smart/channels/1/calibrations/linedetection', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2669, 'p', '888', '/ISAPI/Smart/channels/1/calibrations/linedetection', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2673, 'p', '888', '/ISAPI/Smart/channels/1/calibrations/regionEntrance', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2674, 'p', '888', '/ISAPI/Smart/channels/1/calibrations/regionEntrance', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2665, 'p', '888', '/ISAPI/Smart/FieldDetection/1', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2666, 'p', '888', '/ISAPI/Smart/FieldDetection/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2662, 'p', '888', '/ISAPI/Smart/FieldDetection/1/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2670, 'p', '888', '/ISAPI/Smart/LineDetection/1', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2671, 'p', '888', '/ISAPI/Smart/LineDetection/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2667, 'p', '888', '/ISAPI/Smart/LineDetection/1/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2675, 'p', '888', '/ISAPI/Smart/regionEntrance/1', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2676, 'p', '888', '/ISAPI/Smart/regionEntrance/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2672, 'p', '888', '/ISAPI/Smart/regionEntrance/1/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2660, 'p', '888', '/ISAPI/System/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2659, 'p', '888', '/ISAPI/System/deviceInfo', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2661, 'p', '888', '/ISAPI/System/Network/mailing/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2559, 'p', '888', '/jwt/jsonInBlacklist', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2586, 'p', '888', '/menu/addBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2594, 'p', '888', '/menu/addMenuAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2588, 'p', '888', '/menu/deleteBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2590, 'p', '888', '/menu/getBaseMenuById', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2592, 'p', '888', '/menu/getBaseMenuTree', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2587, 'p', '888', '/menu/getMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2593, 'p', '888', '/menu/getMenuAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2591, 'p', '888', '/menu/getMenuList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2589, 'p', '888', '/menu/updateBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2684, 'p', '888', '/picture/get', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2642, 'p', '888', '/simpleUploader/checkFileMd5', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2643, 'p', '888', '/simpleUploader/mergeFileMd5', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2641, 'p', '888', '/simpleUploader/upload', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2631, 'p', '888', '/sysDictionary/createSysDictionary', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2632, 'p', '888', '/sysDictionary/deleteSysDictionary', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2634, 'p', '888', '/sysDictionary/findSysDictionary', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2635, 'p', '888', '/sysDictionary/getSysDictionaryList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2633, 'p', '888', '/sysDictionary/updateSysDictionary', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2627, 'p', '888', '/sysDictionaryDetail/createSysDictionaryDetail', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2628, 'p', '888', '/sysDictionaryDetail/deleteSysDictionaryDetail', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2629, 'p', '888', '/sysDictionaryDetail/findSysDictionaryDetail', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2630, 'p', '888', '/sysDictionaryDetail/getSysDictionaryDetailList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2626, 'p', '888', '/sysDictionaryDetail/updateSysDictionaryDetail', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2636, 'p', '888', '/sysOperationRecord/createSysOperationRecord', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2639, 'p', '888', '/sysOperationRecord/deleteSysOperationRecord', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2640, 'p', '888', '/sysOperationRecord/deleteSysOperationRecordByIds', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2637, 'p', '888', '/sysOperationRecord/findSysOperationRecord', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2638, 'p', '888', '/sysOperationRecord/getSysOperationRecordList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2603, 'p', '888', '/system/getServerInfo', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2604, 'p', '888', '/system/getSystemConfig', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2605, 'p', '888', '/system/setSystemConfig', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2686, 'p', '888', '/user/addEmails', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2561, 'p', '888', '/user/admin_register', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2567, 'p', '888', '/user/changePassword', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2687, 'p', '888', '/user/confirm', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2560, 'p', '888', '/user/deleteUser', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2565, 'p', '888', '/user/getUserInfo', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2562, 'p', '888', '/user/getUserList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2570, 'p', '888', '/user/ids', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2569, 'p', '888', '/user/resetPassword', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2564, 'p', '888', '/user/setSelfInfo', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2566, 'p', '888', '/user/setUserAuthorities', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2568, 'p', '888', '/user/setUserAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2563, 'p', '888', '/user/setUserInfo', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (2688, 'p', '888', '/user/unbindEmail', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (95, 'p', '8881', '/api/createApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (98, 'p', '8881', '/api/deleteApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (100, 'p', '8881', '/api/getAllApis', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (97, 'p', '8881', '/api/getApiById', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (96, 'p', '8881', '/api/getApiList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (99, 'p', '8881', '/api/updateApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (101, 'p', '8881', '/authority/createAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (102, 'p', '8881', '/authority/deleteAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (103, 'p', '8881', '/authority/getAuthorityList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (104, 'p', '8881', '/authority/setDataAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (122, 'p', '8881', '/casbin/getPolicyPathByAuthorityId', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (121, 'p', '8881', '/casbin/updateCasbin', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (128, 'p', '8881', '/customer/customer', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (129, 'p', '8881', '/customer/customer', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (126, 'p', '8881', '/customer/customer', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (127, 'p', '8881', '/customer/customer', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (130, 'p', '8881', '/customer/customerList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (119, 'p', '8881', '/fileUploadAndDownload/deleteFile', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (120, 'p', '8881', '/fileUploadAndDownload/editFileName', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (118, 'p', '8881', '/fileUploadAndDownload/getFileList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (117, 'p', '8881', '/fileUploadAndDownload/upload', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (123, 'p', '8881', '/jwt/jsonInBlacklist', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (107, 'p', '8881', '/menu/addBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (109, 'p', '8881', '/menu/addMenuAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (111, 'p', '8881', '/menu/deleteBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (113, 'p', '8881', '/menu/getBaseMenuById', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (108, 'p', '8881', '/menu/getBaseMenuTree', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (105, 'p', '8881', '/menu/getMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (110, 'p', '8881', '/menu/getMenuAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (106, 'p', '8881', '/menu/getMenuList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (112, 'p', '8881', '/menu/updateBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (124, 'p', '8881', '/system/getSystemConfig', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (125, 'p', '8881', '/system/setSystemConfig', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (94, 'p', '8881', '/user/admin_register', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (114, 'p', '8881', '/user/changePassword', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (131, 'p', '8881', '/user/getUserInfo', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (115, 'p', '8881', '/user/getUserList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (116, 'p', '8881', '/user/setUserAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1716, 'p', '9528', '/api/createApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1717, 'p', '9528', '/api/deleteApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1720, 'p', '9528', '/api/getAllApis', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1721, 'p', '9528', '/api/getApiById', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1719, 'p', '9528', '/api/getApiList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1718, 'p', '9528', '/api/updateApi', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1722, 'p', '9528', '/authority/createAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1723, 'p', '9528', '/authority/deleteAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1724, 'p', '9528', '/authority/getAuthorityList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1725, 'p', '9528', '/authority/setDataAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1748, 'p', '9528', '/autoCode/createTemp', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1752, 'p', '9528', '/camera/rewind', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1727, 'p', '9528', '/casbin/getPolicyPathByAuthorityId', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1726, 'p', '9528', '/casbin/updateCasbin', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1745, 'p', '9528', '/customer/customer', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1746, 'p', '9528', '/customer/customer', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1744, 'p', '9528', '/customer/customer', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1743, 'p', '9528', '/customer/customer', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1747, 'p', '9528', '/customer/customerList', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1738, 'p', '9528', '/fileUploadAndDownload/deleteFile', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1739, 'p', '9528', '/fileUploadAndDownload/editFileName', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1740, 'p', '9528', '/fileUploadAndDownload/getFileList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1737, 'p', '9528', '/fileUploadAndDownload/upload', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1750, 'p', '9528', '/gateways/all', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1751, 'p', '9528', '/gateways/userSet', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1757, 'p', '9528', '/ISAPI/Smart/channels/1/calibrations/FieldDetection', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1758, 'p', '9528', '/ISAPI/Smart/channels/1/calibrations/FieldDetection', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1762, 'p', '9528', '/ISAPI/Smart/channels/1/calibrations/linedetection', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1763, 'p', '9528', '/ISAPI/Smart/channels/1/calibrations/linedetection', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1767, 'p', '9528', '/ISAPI/Smart/channels/1/calibrations/regionEntrance', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1768, 'p', '9528', '/ISAPI/Smart/channels/1/calibrations/regionEntrance', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1759, 'p', '9528', '/ISAPI/Smart/FieldDetection/1', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1760, 'p', '9528', '/ISAPI/Smart/FieldDetection/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1756, 'p', '9528', '/ISAPI/Smart/FieldDetection/1/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1764, 'p', '9528', '/ISAPI/Smart/LineDetection/1', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1765, 'p', '9528', '/ISAPI/Smart/LineDetection/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1761, 'p', '9528', '/ISAPI/Smart/LineDetection/1/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1769, 'p', '9528', '/ISAPI/Smart/regionEntrance/1', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1770, 'p', '9528', '/ISAPI/Smart/regionEntrance/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1766, 'p', '9528', '/ISAPI/Smart/regionEntrance/1/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1754, 'p', '9528', '/ISAPI/System/capabilities', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1753, 'p', '9528', '/ISAPI/System/deviceInfo', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1755, 'p', '9528', '/ISAPI/System/Network/mailing/1', 'PUT', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1709, 'p', '9528', '/jwt/jsonInBlacklist', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1728, 'p', '9528', '/menu/addBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1736, 'p', '9528', '/menu/addMenuAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1730, 'p', '9528', '/menu/deleteBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1732, 'p', '9528', '/menu/getBaseMenuById', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1734, 'p', '9528', '/menu/getBaseMenuTree', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1729, 'p', '9528', '/menu/getMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1735, 'p', '9528', '/menu/getMenuAuthority', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1733, 'p', '9528', '/menu/getMenuList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1731, 'p', '9528', '/menu/updateBaseMenu', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1741, 'p', '9528', '/system/getSystemConfig', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1742, 'p', '9528', '/system/setSystemConfig', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1710, 'p', '9528', '/user/admin_register', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1713, 'p', '9528', '/user/changePassword', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1712, 'p', '9528', '/user/getUserInfo', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1711, 'p', '9528', '/user/getUserList', 'POST', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1715, 'p', '9528', '/user/ids', 'GET', '', '', '');
+INSERT INTO `casbin_rule` (`id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5`) VALUES (1714, 'p', '9528', '/user/setUserAuthority', 'POST', '', '', '');

+ 0 - 0
doc/lc-base-frame/jwt_blacklists.sql


+ 160 - 0
doc/lc-base-frame/sys_apis.sql

@@ -0,0 +1,160 @@
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (1, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/jwt/jsonInBlacklist', 'jwt加入黑名单(退出,必选)', 'jwt', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (2, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/deleteUser', '删除用户', '系统用户', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (3, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/admin_register', '用户注册', '系统用户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (4, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/getUserList', '获取用户列表', '系统用户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (5, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/setUserInfo', '设置用户信息', '系统用户', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (6, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/setSelfInfo', '设置自身信息(必选)', '系统用户', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (7, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/getUserInfo', '获取自身信息(必选)', '系统用户', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (8, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/setUserAuthorities', '设置权限组', '系统用户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (9, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/changePassword', '修改密码(建议选择)', '系统用户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (10, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/setUserAuthority', '修改用户角色(必选)', '系统用户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (11, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/user/resetPassword', '重置用户密码', '系统用户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (12, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/createApi', '创建api', 'api', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (13, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/deleteApi', '删除Api', 'api', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (14, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/updateApi', '更新Api', 'api', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (15, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/getApiList', '获取api列表', 'api', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (16, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/getAllApis', '获取所有api', 'api', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (17, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/getApiById', '获取api详细信息', 'api', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (18, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/api/deleteApisByIds', '批量删除api', 'api', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (19, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authority/copyAuthority', '拷贝角色', '角色', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (20, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authority/createAuthority', '创建角色', '角色', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (21, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authority/deleteAuthority', '删除角色', '角色', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (22, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authority/updateAuthority', '更新角色信息', '角色', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (23, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authority/getAuthorityList', '获取角色列表', '角色', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (24, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authority/setDataAuthority', '设置角色资源权限', '角色', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (25, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/casbin/updateCasbin', '更改角色api权限', 'casbin', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (26, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/casbin/getPolicyPathByAuthorityId', '获取权限列表', 'casbin', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (27, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/addBaseMenu', '新增菜单', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (28, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/getMenu', '获取菜单树(必选)', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (29, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/deleteBaseMenu', '删除菜单', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (30, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/updateBaseMenu', '更新菜单', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (31, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/getBaseMenuById', '根据id获取菜单', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (32, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/getMenuList', '分页获取基础menu列表', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (33, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/getBaseMenuTree', '获取用户动态路由', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (34, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/getMenuAuthority', '获取指定角色menu', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (35, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/menu/addMenuAuthority', '增加menu和角色关联关系', '菜单', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (36, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/findFile', '寻找目标文件(秒传)', '分片上传', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (37, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/breakpointContinue', '断点续传', '分片上传', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (38, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/breakpointContinueFinish', '断点续传完成', '分片上传', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (39, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/removeChunk', '上传完成移除文件', '分片上传', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (40, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/upload', '文件上传示例', '文件上传与下载', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (41, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/deleteFile', '删除文件', '文件上传与下载', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (42, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/editFileName', '文件名或者备注编辑', '文件上传与下载', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (43, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/fileUploadAndDownload/getFileList', '获取上传文件列表', '文件上传与下载', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (44, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/system/getServerInfo', '获取服务器信息', '系统服务', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (45, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/system/getSystemConfig', '获取配置文件内容', '系统服务', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (46, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/system/setSystemConfig', '设置配置文件内容', '系统服务', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (47, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/customer/customer', '更新客户', '客户', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (48, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/customer/customer', '创建客户', '客户', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (49, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/customer/customer', '删除客户', '客户', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (50, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/customer/customer', '获取单一客户', '客户', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (51, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/customer/customerList', '获取客户列表', '客户', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (52, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/getDB', '获取所有数据库', '代码生成器', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (53, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/getTables', '获取数据库表', '代码生成器', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (54, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/createTemp', '自动化代码', '代码生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (55, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/preview', '预览自动化代码', '代码生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (56, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/getColumn', '获取所选table的所有字段', '代码生成器', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (57, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/createPlug', '自动创建插件包', '代码生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (58, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/installPlugin', '安装插件', '代码生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (59, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/pubPlug', '打包插件', '代码生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (60, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/createPackage', '生成包(package)', '包(pkg)生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (61, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/getPackage', '获取所有包(package)', '包(pkg)生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (62, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/delPackage', '删除包(package)', '包(pkg)生成器', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (63, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/getMeta', '获取meta信息', '代码生成器历史', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (64, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/rollback', '回滚自动生成代码', '代码生成器历史', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (65, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/getSysHistory', '查询回滚记录', '代码生成器历史', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (66, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/autoCode/delSysHistory', '删除回滚记录', '代码生成器历史', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (67, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionaryDetail/updateSysDictionaryDetail', '更新字典内容', '系统字典详情', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (68, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionaryDetail/createSysDictionaryDetail', '新增字典内容', '系统字典详情', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (69, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionaryDetail/deleteSysDictionaryDetail', '删除字典内容', '系统字典详情', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (70, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionaryDetail/findSysDictionaryDetail', '根据ID获取字典内容', '系统字典详情', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (71, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionaryDetail/getSysDictionaryDetailList', '获取字典内容列表', '系统字典详情', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (72, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionary/createSysDictionary', '新增字典', '系统字典', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (73, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionary/deleteSysDictionary', '删除字典', '系统字典', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (74, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionary/updateSysDictionary', '更新字典', '系统字典', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (75, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionary/findSysDictionary', '根据ID获取字典', '系统字典', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (76, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysDictionary/getSysDictionaryList', '获取字典列表', '系统字典', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (77, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysOperationRecord/createSysOperationRecord', '新增操作记录', '操作记录', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (78, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysOperationRecord/findSysOperationRecord', '根据ID获取操作记录', '操作记录', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (79, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysOperationRecord/getSysOperationRecordList', '获取操作记录列表', '操作记录', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (80, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysOperationRecord/deleteSysOperationRecord', '删除操作记录', '操作记录', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (81, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/sysOperationRecord/deleteSysOperationRecordByIds', '批量删除操作历史', '操作记录', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (82, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/simpleUploader/upload', '插件版分片上传', '断点续传(插件版)', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (83, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/simpleUploader/checkFileMd5', '文件完整度验证', '断点续传(插件版)', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (84, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/simpleUploader/mergeFileMd5', '上传完成合并文件', '断点续传(插件版)', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (85, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/email/emailTest', '发送测试邮件', 'email', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (86, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/email/emailSend', '发送邮件示例', 'email', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (87, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authorityBtn/setAuthorityBtn', '设置按钮权限', '按钮权限', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (88, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authorityBtn/getAuthorityBtn', '获取已有按钮权限', '按钮权限', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (89, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/authorityBtn/canRemoveAuthorityBtn', '删除按钮', '按钮权限', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (90, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/chatGpt/getTable', '通过gpt获取内容', '万用表格', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (91, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/chatGpt/createSK', '录入sk', '万用表格', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (92, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/chatGpt/getSK', '获取sk', '万用表格', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (93, '2023-08-14 16:16:30.769', '2023-08-14 16:16:30.769', NULL, '/chatGpt/deleteSK', '删除sk', '万用表格', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (94, '2023-08-15 09:12:57.647', '2023-08-15 09:12:57.647', '2023-08-30 14:31:45.669', '/eh/createEdgeHost', '新增边缘端主机', '边缘端主机', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (95, '2023-08-15 09:12:57.648', '2023-08-15 09:12:57.648', '2023-08-30 14:31:45.669', '/eh/deleteEdgeHost', '删除边缘端主机', '边缘端主机', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (96, '2023-08-15 09:12:57.649', '2023-08-15 09:12:57.649', '2023-08-30 14:31:45.669', '/eh/deleteEdgeHostByIds', '批量删除边缘端主机', '边缘端主机', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (97, '2023-08-15 09:12:57.649', '2023-08-15 09:12:57.649', '2023-08-30 14:31:45.669', '/eh/updateEdgeHost', '更新边缘端主机', '边缘端主机', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (98, '2023-08-15 09:12:57.650', '2023-08-15 09:12:57.650', '2023-08-30 14:31:45.669', '/eh/findEdgeHost', '根据ID获取边缘端主机', '边缘端主机', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (99, '2023-08-15 09:12:57.651', '2023-08-15 09:12:57.651', '2023-08-30 14:31:45.669', '/eh/getEdgeHostList', '获取边缘端主机列表', '边缘端主机', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (100, '2023-08-15 09:18:30.516', '2023-08-15 09:18:30.516', '2023-08-30 14:31:14.100', '/ec/createEdgeCamera', '新增摄像头', '摄像头', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (101, '2023-08-15 09:18:30.516', '2023-08-15 09:18:30.516', '2023-08-30 14:31:14.100', '/ec/deleteEdgeCamera', '删除摄像头', '摄像头', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (102, '2023-08-15 09:18:30.517', '2023-08-15 09:18:30.517', '2023-08-30 14:31:14.100', '/ec/deleteEdgeCameraByIds', '批量删除摄像头', '摄像头', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (103, '2023-08-15 09:18:30.518', '2023-08-15 09:18:30.518', '2023-08-30 14:31:14.100', '/ec/updateEdgeCamera', '更新摄像头', '摄像头', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (104, '2023-08-15 09:18:30.518', '2023-08-15 09:18:30.518', '2023-08-30 14:31:14.100', '/ec/findEdgeCamera', '根据ID获取摄像头', '摄像头', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (105, '2023-08-15 09:18:30.519', '2023-08-15 09:18:30.519', '2023-08-30 14:31:14.100', '/ec/getEdgeCameraList', '获取摄像头列表', '摄像头', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (106, '2023-08-28 11:12:43.553', '2023-08-28 11:12:43.553', NULL, '/camera/createCamera', '新增摄像头', '摄像头', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (107, '2023-08-28 11:12:43.634', '2023-08-28 11:12:43.634', NULL, '/camera/deleteCamera', '删除摄像头', '摄像头', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (108, '2023-08-28 11:12:43.635', '2023-08-28 11:12:43.635', NULL, '/camera/deleteCameraByIds', '批量删除摄像头', '摄像头', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (109, '2023-08-28 11:12:43.635', '2023-08-28 11:12:43.635', NULL, '/camera/updateCamera', '更新摄像头', '摄像头', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (110, '2023-08-28 11:12:43.636', '2023-08-28 11:12:43.636', NULL, '/camera/findCamera', '根据ID获取摄像头', '摄像头', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (111, '2023-08-28 11:12:43.636', '2023-08-28 11:12:43.636', NULL, '/camera/getCameraList', '获取摄像头列表', '摄像头', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (112, '2023-08-30 11:21:30.151', '2023-08-30 11:21:30.151', '2023-08-30 14:32:55.846', '/edge/createEdge', '新增边缘端', '边缘端', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (113, '2023-08-30 11:21:30.151', '2023-08-30 11:21:30.151', '2023-08-30 14:32:55.846', '/edge/deleteEdge', '删除边缘端', '边缘端', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (114, '2023-08-30 11:21:30.152', '2023-08-30 11:21:30.152', '2023-08-30 14:32:55.846', '/edge/deleteEdgeByIds', '批量删除边缘端', '边缘端', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (115, '2023-08-30 11:21:30.152', '2023-08-30 11:21:30.152', '2023-08-30 14:32:55.846', '/edge/updateEdge', '更新边缘端', '边缘端', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (116, '2023-08-30 11:21:30.153', '2023-08-30 11:21:30.153', '2023-08-30 14:32:55.846', '/edge/findEdge', '根据ID获取边缘端', '边缘端', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (117, '2023-08-30 11:21:30.153', '2023-08-30 11:21:30.153', '2023-08-30 14:32:55.846', '/edge/getEdgeList', '获取边缘端列表', '边缘端', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (118, '2023-08-30 14:35:14.201', '2023-08-30 14:35:14.201', '2023-10-11 11:15:02.484', '/edge/createEdge', '新增项目名', '项目名', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (119, '2023-08-30 14:35:14.202', '2023-08-30 14:35:14.202', '2023-10-11 11:15:31.287', '/edge/deleteEdge', '删除项目名', '项目名', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (120, '2023-08-30 14:35:14.202', '2023-08-30 14:35:14.202', '2023-10-11 11:15:24.151', '/edge/deleteEdgeByIds', '批量删除项目名', '项目名', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (121, '2023-08-30 14:35:14.203', '2023-08-30 14:35:14.203', '2023-10-11 11:15:24.151', '/edge/updateEdge', '更新项目名', '项目名', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (122, '2023-08-30 14:35:14.204', '2023-08-30 14:35:14.204', '2023-10-11 11:15:24.151', '/edge/findEdge', '根据ID获取项目名', '项目名', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (123, '2023-08-30 14:35:14.205', '2023-08-30 14:35:14.205', '2023-10-11 11:15:24.151', '/edge/getEdgeList', '获取项目名列表', '项目名', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (124, '2023-09-06 16:42:07.666', '2023-09-06 16:42:07.666', '2023-10-12 15:27:28.179', '/camera/cameras', '获取摄像头集合', 'app', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (125, '2023-09-20 09:24:45.435', '2023-09-20 09:26:27.728', NULL, '/camera/rewind', '回放', '摄像头', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (126, '2023-09-27 16:59:47.998', '2023-09-27 16:59:47.998', NULL, '/ISAPI/System/deviceInfo', '获取设备信息', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (127, '2023-09-27 21:45:23.869', '2023-09-27 21:45:23.869', NULL, '/ISAPI/System/capabilities', '系统能力', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (128, '2023-09-27 21:46:31.579', '2023-09-27 21:46:31.579', NULL, '/ISAPI/System/Network/mailing/1', '添加邮箱', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (129, '2023-09-27 21:48:59.118', '2023-09-27 21:51:22.338', NULL, '/ISAPI/Smart/FieldDetection/1/capabilities', '查询进入区域参数能力', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (130, '2023-09-27 21:49:34.389', '2023-09-27 21:50:25.668', NULL, '/ISAPI/Smart/channels/1/calibrations/FieldDetection', '查询FieldDetection目标参数', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (131, '2023-09-27 21:51:09.965', '2023-09-27 21:51:09.965', NULL, '/ISAPI/Smart/channels/1/calibrations/FieldDetection', '配置FieldDetection目标参数', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (132, '2023-09-27 21:52:15.697', '2023-09-27 21:52:15.697', NULL, '/ISAPI/Smart/FieldDetection/1', '查询FieldDetection参数', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (133, '2023-09-27 21:52:38.766', '2023-09-27 21:52:38.766', NULL, '/ISAPI/Smart/FieldDetection/1', '配置FieldDetection参数', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (134, '2023-09-27 21:53:29.238', '2023-09-27 21:53:29.238', NULL, '/ISAPI/Smart/LineDetection/1/capabilities', '查询LineDetection能力', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (135, '2023-09-27 21:53:53.848', '2023-09-27 21:53:53.848', NULL, '/ISAPI/Smart/channels/1/calibrations/linedetection', '查询linedetection目标参数', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (136, '2023-09-27 21:54:15.721', '2023-09-27 21:54:15.721', NULL, '/ISAPI/Smart/channels/1/calibrations/linedetection', '配置linedetection目标参数', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (137, '2023-09-27 21:54:39.044', '2023-09-27 21:54:39.044', NULL, '/ISAPI/Smart/LineDetection/1', '查询LineDetection参数', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (138, '2023-09-27 21:55:09.863', '2023-09-27 21:55:09.863', NULL, '/ISAPI/Smart/LineDetection/1', '配置LineDetection参数', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (139, '2023-09-27 21:55:43.498', '2023-09-27 21:55:43.498', NULL, '/ISAPI/Smart/regionEntrance/1/capabilities', '查询regionEntrance能力', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (140, '2023-09-27 21:56:07.032', '2023-09-27 21:56:07.032', NULL, '/ISAPI/Smart/channels/1/calibrations/regionEntrance', '查询regionEntrance目标参数', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (141, '2023-09-27 21:56:31.496', '2023-09-27 21:56:31.496', NULL, '/ISAPI/Smart/channels/1/calibrations/regionEntrance', '配置regionEntrance目标参数', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (142, '2023-09-27 21:56:53.227', '2023-09-27 21:56:53.227', NULL, '/ISAPI/Smart/regionEntrance/1', '查询regionEntrance参数', 'isapi', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (143, '2023-09-27 21:57:13.526', '2023-09-27 21:57:13.526', NULL, '/ISAPI/Smart/regionEntrance/1', '配置regionEntrance参数', 'isapi', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (144, '2023-10-11 11:16:35.567', '2023-10-11 11:20:11.171', NULL, '/gateways/all', '获取设备列表', 'app', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (145, '2023-10-11 11:18:02.988', '2023-10-11 11:18:02.988', NULL, '/gateways/adminSet', '管理员设置信息', 'app', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (146, '2023-10-11 11:18:20.970', '2023-10-11 11:18:20.970', NULL, '/gateways/userSet', '用户设置信息', 'app', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (147, '2023-10-11 16:53:34.767', '2023-10-11 16:53:34.767', NULL, '/camera/rewind', '获取回放视频url', 'app', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (148, '2023-10-11 17:04:20.869', '2023-10-11 17:04:20.869', NULL, '/user/ids', '查询用户id列表', '系统用户', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (149, '2023-10-12 11:41:35.467', '2023-10-12 11:41:35.467', NULL, '/gateways/delete', '删除网关及关联设备', 'app', 'DELETE');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (150, '2023-10-12 14:17:38.125', '2023-10-12 14:17:38.125', NULL, '/gateways/unbind', '解绑网关', 'app', 'PUT');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (151, '2023-10-12 15:56:26.379', '2023-10-12 15:56:26.379', '2023-10-12 15:58:02.240', '111', '11', '1', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (152, '2023-10-12 15:57:30.674', '2023-10-12 15:57:30.674', '2023-10-12 15:58:02.240', '/test', '测试添加api', '1', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (153, '2023-10-12 15:57:46.700', '2023-10-12 15:57:46.700', '2023-10-12 15:58:02.240', '2', '2', '1', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (154, '2023-10-12 16:17:24.864', '2023-10-12 16:23:01.530', NULL, '/test', '测试修改api', '1', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (155, '2023-10-13 10:57:01.356', '2023-10-13 10:57:01.356', NULL, '/event/list', '事件列表', 'app', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (156, '2023-10-13 16:05:49.382', '2023-10-13 16:05:49.382', NULL, '/picture/get', '获取图片', 'app', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (157, '2023-10-13 20:17:51.550', '2023-10-13 20:18:34.496', NULL, '/event/dictionary', '获取事件类型字典', 'app', 'GET');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (158, '2023-10-14 10:05:44.690', '2023-10-14 10:07:19.971', NULL, '/user/addEmails', '添加报警邮箱', 'app', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (159, '2023-10-14 10:06:10.699', '2023-10-14 10:06:10.699', NULL, '/user/confirm', '邮箱确认', 'app', 'POST');
+INSERT INTO `sys_apis` (`id`, `created_at`, `updated_at`, `deleted_at`, `path`, `description`, `api_group`, `method`) VALUES (160, '2023-10-14 16:55:08.167', '2023-10-14 16:55:08.167', NULL, '/user/unbindEmail', '解绑邮箱', 'app', 'PUT');

+ 4 - 0
doc/lc-base-frame/sys_authorities.sql

@@ -0,0 +1,4 @@
+INSERT INTO `sys_authorities` (`created_at`, `updated_at`, `deleted_at`, `authority_id`, `authority_name`, `parent_id`, `default_router`) VALUES ('2023-10-12 16:47:57.841', '2023-10-12 17:13:33.677', NULL, 2, '普通管理员1', 0, 'dashboard');
+INSERT INTO `sys_authorities` (`created_at`, `updated_at`, `deleted_at`, `authority_id`, `authority_name`, `parent_id`, `default_router`) VALUES ('2023-08-14 16:16:30.979', '2023-09-02 09:57:35.499', NULL, 888, '超级管理员', 0, 'dashboard');
+INSERT INTO `sys_authorities` (`created_at`, `updated_at`, `deleted_at`, `authority_id`, `authority_name`, `parent_id`, `default_router`) VALUES ('2023-08-14 16:16:30.979', '2023-08-14 16:16:31.582', NULL, 8881, '普通用户子角色', 888, 'dashboard');
+INSERT INTO `sys_authorities` (`created_at`, `updated_at`, `deleted_at`, `authority_id`, `authority_name`, `parent_id`, `default_router`) VALUES ('2023-08-14 16:16:30.979', '2023-08-14 16:16:31.532', NULL, 9528, '测试角色', 0, 'dashboard');

+ 1 - 0
doc/lc-base-frame/sys_authority_btns.sql

@@ -0,0 +1 @@
+INSERT INTO `sys_authority_btns` (`authority_id`, `sys_menu_id`, `sys_base_menu_btn_id`) VALUES (888, 32, 1);

+ 54 - 0
doc/lc-base-frame/sys_authority_menus.sql

@@ -0,0 +1,54 @@
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (1, 2);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (1, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (1, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (1, 9528);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (2, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (2, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (2, 9528);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (3, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (4, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (4, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (5, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (5, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (6, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (6, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (7, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (7, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (8, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (8, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (8, 9528);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (9, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (9, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (10, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (10, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (11, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (11, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (12, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (13, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (13, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (14, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (14, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (15, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (15, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (16, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (16, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (17, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (17, 8881);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (18, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (19, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (20, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (21, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (22, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (23, 2);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (23, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (24, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (25, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (26, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (27, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (28, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (29, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (30, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (31, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (32, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (33, 888);
+INSERT INTO `sys_authority_menus` (`sys_base_menu_id`, `sys_authority_authority_id`) VALUES (34, 888);

File diff ditekan karena terlalu besar
+ 8 - 0
doc/lc-base-frame/sys_auto_code_histories.sql


+ 2 - 0
doc/lc-base-frame/sys_auto_codes.sql

@@ -0,0 +1,2 @@
+INSERT INTO `sys_auto_codes` (`id`, `created_at`, `updated_at`, `deleted_at`, `package_name`, `label`, `desc`) VALUES (1, '2023-08-15 09:12:49.618', '2023-08-15 09:12:49.618', '2023-08-30 11:05:47.442', 'edge', '', '');
+INSERT INTO `sys_auto_codes` (`id`, `created_at`, `updated_at`, `deleted_at`, `package_name`, `label`, `desc`) VALUES (2, '2023-08-30 11:07:05.917', '2023-08-30 11:07:05.917', NULL, 'app', '', '');

+ 2 - 0
doc/lc-base-frame/sys_base_menu_btns.sql

@@ -0,0 +1,2 @@
+INSERT INTO `sys_base_menu_btns` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `desc`, `sys_base_menu_id`) VALUES (1, '2023-08-30 11:41:03.787', '2023-08-30 11:41:03.787', NULL, '', '', 32);
+INSERT INTO `sys_base_menu_btns` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `desc`, `sys_base_menu_id`) VALUES (2, '2023-08-30 14:41:13.050', '2023-08-30 14:41:13.050', NULL, '', '', 33);

+ 2 - 0
doc/lc-base-frame/sys_base_menu_parameters.sql

@@ -0,0 +1,2 @@
+INSERT INTO `sys_base_menu_parameters` (`id`, `created_at`, `updated_at`, `deleted_at`, `sys_base_menu_id`, `type`, `key`, `value`) VALUES (1, '2023-08-30 14:11:32.999', '2023-08-30 14:11:32.999', NULL, 32, 'query', '', '');
+INSERT INTO `sys_base_menu_parameters` (`id`, `created_at`, `updated_at`, `deleted_at`, `sys_base_menu_id`, `type`, `key`, `value`) VALUES (2, '2023-08-30 14:41:13.050', '2023-08-30 14:41:13.050', NULL, 33, 'query', '', '');

+ 34 - 0
doc/lc-base-frame/sys_base_menus.sql

@@ -0,0 +1,34 @@
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (1, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'dashboard', 'dashboard', 0, 'view/dashboard/index.vue', 1, '', 0, 0, '仪表盘', 'odometer', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (2, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'about', 'about', 0, 'view/about/index.vue', 9, '', 0, 0, '关于我们', 'info-filled', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (3, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'admin', 'superAdmin', 0, 'view/superAdmin/index.vue', 3, '', 0, 0, '超级管理员', 'user', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (4, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'authority', 'authority', 0, 'view/superAdmin/authority/authority.vue', 1, '', 0, 0, '角色管理', 'avatar', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (5, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'menu', 'menu', 0, 'view/superAdmin/menu/menu.vue', 2, '', 1, 0, '菜单管理', 'tickets', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (6, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'api', 'api', 0, 'view/superAdmin/api/api.vue', 3, '', 1, 0, 'api管理', 'platform', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (7, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'user', 'user', 0, 'view/superAdmin/user/user.vue', 4, '', 0, 0, '用户管理', 'coordinate', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (8, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'dictionary', 'dictionary', 0, 'view/superAdmin/dictionary/sysDictionary.vue', 5, '', 0, 0, '字典管理', 'notebook', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (9, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'dictionaryDetail/:id', 'dictionaryDetail', 1, 'view/superAdmin/dictionary/sysDictionaryDetail.vue', 1, 'dictionary', 0, 0, '字典详情-${id}', 'list', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (10, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '3', 'operation', 'operation', 0, 'view/superAdmin/operation/sysOperationRecord.vue', 6, '', 0, 0, '操作历史', 'pie-chart', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (11, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'person', 'person', 1, 'view/person/person.vue', 4, '', 0, 0, '个人信息', 'message', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (12, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'example', 'example', 0, 'view/example/index.vue', 7, '', 0, 0, '示例文件', 'management', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (13, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '12', 'upload', 'upload', 0, 'view/example/upload/upload.vue', 5, '', 0, 0, '媒体库(上传下载)', 'upload', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (14, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '12', 'breakpoint', 'breakpoint', 0, 'view/example/breakpoint/breakpoint.vue', 6, '', 0, 0, '断点续传', 'upload-filled', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (15, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '12', 'customer', 'customer', 0, 'view/example/customer/customer.vue', 7, '', 0, 0, '客户列表(资源示例)', 'avatar', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (16, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'systemTools', 'systemTools', 0, 'view/systemTools/index.vue', 5, '', 0, 0, '系统工具', 'tools', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (17, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'autoCode', 'autoCode', 0, 'view/systemTools/autoCode/index.vue', 1, '', 1, 0, '代码生成器', 'cpu', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (18, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'formCreate', 'formCreate', 0, 'view/systemTools/formCreate/index.vue', 2, '', 1, 0, '表单生成器', 'magic-stick', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (19, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'system', 'system', 0, 'view/systemTools/system/system.vue', 3, '', 0, 0, '系统配置', 'operation', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (20, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'autoCodeAdmin', 'autoCodeAdmin', 0, 'view/systemTools/autoCodeAdmin/index.vue', 1, '', 0, 0, '自动化代码管理', 'magic-stick', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (21, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'autoCodeEdit/:id', 'autoCodeEdit', 1, 'view/systemTools/autoCode/index.vue', 0, '', 0, 0, '自动化代码-${id}', 'magic-stick', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (22, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'autoPkg', 'autoPkg', 0, 'view/systemTools/autoPkg/autoPkg.vue', 0, '', 0, 0, '自动化package', 'folder', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (23, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'https://www.gin-vue-admin.com', 'https://www.gin-vue-admin.com', 0, '/', 0, '', 0, 0, '官方网站', 'home-filled', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (24, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'state', 'state', 0, 'view/system/state.vue', 8, '', 0, 0, '服务器状态', 'cloudy', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (25, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '0', 'plugin', 'plugin', 0, 'view/routerHolder.vue', 6, '', 0, 0, '插件系统', 'cherry', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (26, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '25', 'https://plugin.gin-vue-admin.com/', 'https://plugin.gin-vue-admin.com/', 0, 'https://plugin.gin-vue-admin.com/', 0, '', 0, 0, '插件市场', 'shop', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (27, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '25', 'installPlugin', 'installPlugin', 0, 'view/systemTools/installPlugin/index.vue', 1, '', 0, 0, '插件安装', 'box', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (28, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '25', 'autoPlug', 'autoPlug', 0, 'view/systemTools/autoPlug/autoPlug.vue', 2, '', 0, 0, '插件模板', 'folder', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (29, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '25', 'pubPlug', 'pubPlug', 0, 'view/systemTools/pubPlug/pubPlug.vue', 3, '', 0, 0, '打包插件', 'files', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (30, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '25', 'plugin-email', 'plugin-email', 0, 'plugin/email/view/index.vue', 4, '', 0, 0, '邮件插件', 'message', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (31, '2023-08-14 16:16:31.250', '2023-08-14 16:16:31.250', NULL, 0, '16', 'chatTable', 'chatTable', 0, 'view/chatgpt/chatTable.vue', 6, '', 0, 0, '万用表格', 'chat-dot-square', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (32, '2023-08-16 08:51:08.400', '2023-08-30 14:21:05.322', NULL, 0, '0', 'camera', 'camera', 0, 'view/camera/camera.vue', 0, '', 0, 0, '监控管理', 'camera', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (33, '2023-08-30 14:41:13.050', '2023-08-30 14:45:25.389', NULL, 0, '0', 'edge', 'edge', 0, 'view/edge/edge.vue', 0, '', 0, 0, '项目', 'aim', 0);
+INSERT INTO `sys_base_menus` (`id`, `created_at`, `updated_at`, `deleted_at`, `menu_level`, `parent_id`, `path`, `name`, `hidden`, `component`, `sort`, `active_name`, `keep_alive`, `default_menu`, `title`, `icon`, `close_tab`) VALUES (34, '2023-09-02 09:56:43.237', '2023-09-02 09:56:43.237', NULL, 0, '0', 'monitor', 'monitor', 0, 'view/monitor/monitor.vue', 9, '', 0, 0, '视频监测', 'camera', 0);

+ 0 - 0
doc/lc-base-frame/sys_chat_gpt_options.sql


+ 5 - 0
doc/lc-base-frame/sys_data_authority_id.sql

@@ -0,0 +1,5 @@
+INSERT INTO `sys_data_authority_id` (`sys_authority_authority_id`, `data_authority_id_authority_id`) VALUES (888, 888);
+INSERT INTO `sys_data_authority_id` (`sys_authority_authority_id`, `data_authority_id_authority_id`) VALUES (888, 8881);
+INSERT INTO `sys_data_authority_id` (`sys_authority_authority_id`, `data_authority_id_authority_id`) VALUES (888, 9528);
+INSERT INTO `sys_data_authority_id` (`sys_authority_authority_id`, `data_authority_id_authority_id`) VALUES (9528, 8881);
+INSERT INTO `sys_data_authority_id` (`sys_authority_authority_id`, `data_authority_id_authority_id`) VALUES (9528, 9528);

+ 7 - 0
doc/lc-base-frame/sys_dictionaries.sql

@@ -0,0 +1,7 @@
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (1, '2023-08-14 16:16:31.066', '2023-08-14 16:16:31.091', NULL, '性别', 'gender', 1, '性别字典');
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (2, '2023-08-14 16:16:31.066', '2023-08-14 16:16:31.130', NULL, '数据库int类型', 'int', 1, 'int类型对应的数据库类型');
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (3, '2023-08-14 16:16:31.066', '2023-08-14 16:16:31.148', NULL, '数据库时间日期类型', 'time.Time', 1, '数据库时间日期类型');
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (4, '2023-08-14 16:16:31.066', '2023-08-14 16:16:31.174', NULL, '数据库浮点型', 'float64', 1, '数据库浮点型');
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (5, '2023-08-14 16:16:31.066', '2023-08-14 16:16:31.199', NULL, '数据库字符串', 'string', 1, '数据库字符串');
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (6, '2023-08-14 16:16:31.066', '2023-08-14 16:16:31.224', NULL, '数据库bool类型', 'bool', 1, '数据库bool类型');
+INSERT INTO `sys_dictionaries` (`id`, `created_at`, `updated_at`, `deleted_at`, `name`, `type`, `status`, `desc`) VALUES (7, '2023-10-13 14:06:17.312', '2023-10-13 14:06:17.312', NULL, '事件类型', 'eventType', 1, '报警事件类型');

+ 29 - 0
doc/lc-base-frame/sys_dictionary_details.sql

@@ -0,0 +1,29 @@
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (1, '2023-08-14 16:16:31.092', '2023-08-14 16:16:31.092', NULL, '男', 1, 1, 1, 1);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (2, '2023-08-14 16:16:31.092', '2023-08-14 16:16:31.092', NULL, '女', 2, 1, 2, 1);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (3, '2023-08-14 16:16:31.130', '2023-08-14 16:16:31.130', NULL, 'smallint', 1, 1, 1, 2);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (4, '2023-08-14 16:16:31.130', '2023-08-14 16:16:31.130', NULL, 'mediumint', 2, 1, 2, 2);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (5, '2023-08-14 16:16:31.130', '2023-08-14 16:16:31.130', NULL, 'int', 3, 1, 3, 2);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (6, '2023-08-14 16:16:31.130', '2023-08-14 16:16:31.130', NULL, 'bigint', 4, 1, 4, 2);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (7, '2023-08-14 16:16:31.149', '2023-08-14 16:16:31.149', NULL, 'date', 0, 1, 0, 3);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (8, '2023-08-14 16:16:31.149', '2023-08-14 16:16:31.149', NULL, 'time', 1, 1, 1, 3);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (9, '2023-08-14 16:16:31.149', '2023-08-14 16:16:31.149', NULL, 'year', 2, 1, 2, 3);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (10, '2023-08-14 16:16:31.149', '2023-08-14 16:16:31.149', NULL, 'datetime', 3, 1, 3, 3);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (11, '2023-08-14 16:16:31.149', '2023-08-14 16:16:31.149', NULL, 'timestamp', 5, 1, 5, 3);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (12, '2023-08-14 16:16:31.175', '2023-08-14 16:16:31.175', NULL, 'float', 0, 1, 0, 4);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (13, '2023-08-14 16:16:31.175', '2023-08-14 16:16:31.175', NULL, 'double', 1, 1, 1, 4);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (14, '2023-08-14 16:16:31.175', '2023-08-14 16:16:31.175', NULL, 'decimal', 2, 1, 2, 4);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (15, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'char', 0, 1, 0, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (16, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'varchar', 1, 1, 1, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (17, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'tinyblob', 2, 1, 2, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (18, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'tinytext', 3, 1, 3, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (19, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'text', 4, 1, 4, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (20, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'blob', 5, 1, 5, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (21, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'mediumblob', 6, 1, 6, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (22, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'mediumtext', 7, 1, 7, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (23, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'longblob', 8, 1, 8, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (24, '2023-08-14 16:16:31.199', '2023-08-14 16:16:31.199', NULL, 'longtext', 9, 1, 9, 5);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (25, '2023-08-14 16:16:31.225', '2023-08-14 16:16:31.225', NULL, 'tinyint', 0, 1, 0, 6);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (26, '2023-10-13 14:08:06.925', '2023-10-13 14:08:06.925', NULL, '遮盖报警', 1, 1, 1, 7);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (27, '2023-10-13 14:08:24.151', '2023-10-13 14:08:24.151', NULL, '进入区域', 2, 1, 2, 7);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (28, '2023-10-13 14:08:40.068', '2023-10-13 14:08:40.068', NULL, '区域入侵', 3, 1, 3, 7);
+INSERT INTO `sys_dictionary_details` (`id`, `created_at`, `updated_at`, `deleted_at`, `label`, `value`, `status`, `sort`, `sys_dictionary_id`) VALUES (29, '2023-10-13 14:08:55.249', '2023-10-13 14:08:55.249', NULL, '越界侦测', 4, 1, 4, 7);

File diff ditekan karena terlalu besar
+ 1126 - 0
doc/lc-base-frame/sys_operation_records.sql


+ 4 - 0
doc/lc-base-frame/sys_user_authority.sql

@@ -0,0 +1,4 @@
+INSERT INTO `sys_user_authority` (`sys_user_id`, `sys_authority_authority_id`) VALUES (1, 888);
+INSERT INTO `sys_user_authority` (`sys_user_id`, `sys_authority_authority_id`) VALUES (1, 8881);
+INSERT INTO `sys_user_authority` (`sys_user_id`, `sys_authority_authority_id`) VALUES (1, 9528);
+INSERT INTO `sys_user_authority` (`sys_user_id`, `sys_authority_authority_id`) VALUES (2, 888);

File diff ditekan karena terlalu besar
+ 2 - 0
doc/lc-base-frame/sys_users.sql


+ 43 - 0
global/global.go

@@ -0,0 +1,43 @@
+package global
+
+import (
+	"github.com/redis/go-redis/v9"
+	"github.com/songzhibin97/gkit/cache/local_cache"
+	"golang.org/x/sync/singleflight"
+	"gorm.io/gorm"
+	"lc-fangdaosha/config"
+	"time"
+)
+
+var (
+	Db                      *gorm.DB
+	GVA_REDIS               *redis.Client
+	BlackCache              local_cache.Cache
+	Config                  = config.Config
+	GVA_Concurrency_Control = &singleflight.Group{}
+)
+
+type GVA_MODEL struct {
+	ID        uint           `gorm:"primarykey"` // 主键ID
+	CreatedAt time.Time      // 创建时间
+	UpdatedAt time.Time      // 更新时间
+	DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间
+}
+
+type DateTimeString time.Time
+
+const DateTimeFormatCN = "2006-01-02 15:04:05"
+
+func (t *DateTimeString) UnmarshalJSON(data []byte) (err error) {
+	now, err := time.ParseInLocation(`"`+DateTimeFormatCN+`"`, string(data), time.Local)
+	*t = DateTimeString(now)
+	return
+}
+
+func (t *DateTimeString) MarshalJSON() ([]byte, error) {
+	b := make([]byte, 0, len(DateTimeFormatCN)+2)
+	b = append(b, '"')
+	b = time.Time(*t).AppendFormat(b, DateTimeFormatCN)
+	b = append(b, '"')
+	return b, nil
+}

+ 103 - 0
go.mod

@@ -0,0 +1,103 @@
+module lc-fangdaosha
+
+go 1.20
+
+require (
+	github.com/casbin/casbin/v2 v2.77.2
+	github.com/casbin/gorm-adapter/v3 v3.20.0
+	github.com/flipped-aurora/gin-vue-admin/server v0.0.0-20231014055930-232aaad09094
+	github.com/gin-gonic/gin v1.9.1
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/go-sql-driver/mysql v1.7.1
+	github.com/gofrs/uuid/v5 v5.0.0
+	github.com/golang-jwt/jwt/v4 v4.5.0
+	github.com/mojocn/base64Captcha v1.3.5
+	github.com/redis/go-redis/v9 v9.2.1
+	github.com/sirupsen/logrus v1.9.3
+	github.com/songzhibin97/gkit v1.2.11
+	github.com/unrolled/secure v1.13.0
+	github.com/xhit/go-simple-mail/v2 v2.16.0
+	go.uber.org/zap v1.26.0
+	golang.org/x/crypto v0.14.0
+	golang.org/x/sync v0.4.0
+	gopkg.in/yaml.v3 v3.0.1
+	gorm.io/driver/mysql v1.5.2
+	gorm.io/gorm v1.25.5
+)
+
+require (
+	github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
+	github.com/bytedance/sonic v1.9.1 // indirect
+	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+	github.com/dustin/go-humanize v1.0.1 // indirect
+	github.com/fsnotify/fsnotify v1.6.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/glebarez/go-sqlite v1.21.1 // indirect
+	github.com/glebarez/sqlite v1.8.0 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.14.0 // indirect
+	github.com/go-test/deep v1.1.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
+	github.com/golang-sql/sqlexp v0.1.0 // indirect
+	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
+	github.com/golang/snappy v0.0.1 // indirect
+	github.com/google/uuid v1.3.0 // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/jackc/pgpassfile v1.0.0 // indirect
+	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+	github.com/jackc/pgx/v5 v5.3.1 // indirect
+	github.com/jinzhu/inflection v1.0.0 // indirect
+	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/compress v1.13.6 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.4 // indirect
+	github.com/leodido/go-urn v1.2.4 // indirect
+	github.com/magiconair/properties v1.8.7 // indirect
+	github.com/mattn/go-isatty v0.0.19 // indirect
+	github.com/microsoft/go-mssqldb v1.1.0 // indirect
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/montanaflynn/stats v0.7.0 // indirect
+	github.com/pelletier/go-toml/v2 v2.0.8 // indirect
+	github.com/qiniu/qmgo v1.1.8 // indirect
+	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
+	github.com/robfig/cron/v3 v3.0.1 // indirect
+	github.com/spf13/afero v1.9.5 // indirect
+	github.com/spf13/cast v1.5.1 // indirect
+	github.com/spf13/jwalterweatherman v1.1.0 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/spf13/viper v1.16.0 // indirect
+	github.com/subosito/gotenv v1.4.2 // indirect
+	github.com/tidwall/gjson v1.14.4 // indirect
+	github.com/tidwall/match v1.1.1 // indirect
+	github.com/tidwall/pretty v1.2.0 // indirect
+	github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.11 // indirect
+	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
+	github.com/xdg-go/scram v1.1.2 // indirect
+	github.com/xdg-go/stringprep v1.0.4 // indirect
+	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
+	go.mongodb.org/mongo-driver v1.12.1 // indirect
+	go.uber.org/multierr v1.10.0 // indirect
+	golang.org/x/arch v0.3.0 // indirect
+	golang.org/x/image v0.5.0 // indirect
+	golang.org/x/net v0.10.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
+	google.golang.org/protobuf v1.30.0 // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gorm.io/driver/postgres v1.5.2 // indirect
+	gorm.io/driver/sqlserver v1.5.1 // indirect
+	gorm.io/plugin/dbresolver v1.4.1 // indirect
+	modernc.org/libc v1.24.1 // indirect
+	modernc.org/mathutil v1.5.0 // indirect
+	modernc.org/memory v1.6.0 // indirect
+	modernc.org/sqlite v1.23.0 // indirect
+)

+ 745 - 0
go.sum

@@ -0,0 +1,745 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/agiledragon/gomonkey/v2 v2.2.0 h1:QJWqpdEhGV/JJy70sZ/LDnhbSlMrqHAWHcNOjz1kyuI=
+github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
+github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
+github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
+github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3jM=
+github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk=
+github.com/casbin/gorm-adapter/v3 v3.20.0 h1:VpGKTlL56xIkhNUOC07bnzwjA/xqfVOAbkt6sniVxMo=
+github.com/casbin/gorm-adapter/v3 v3.20.0/go.mod h1:pvTTuyP2Es8VPHLyUssGtvOb3ETYD2tG7TfT5K8X2Sg=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
+github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/flipped-aurora/gin-vue-admin/server v0.0.0-20231014055930-232aaad09094 h1:uqUWj6saMMAMvuy/CJK1NcfENMXjan/kQbvrEvLw+4c=
+github.com/flipped-aurora/gin-vue-admin/server v0.0.0-20231014055930-232aaad09094/go.mod h1:rXcid1oL4HO8NpnK0FDKxxZiz9Jry9yc2+y2vwzUa9o=
+github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
+github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
+github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY=
+github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E=
+github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc=
+github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
+github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
+github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
+github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
+github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
+github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
+github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
+github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
+github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
+github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
+github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
+github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
+github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
+github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
+github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
+github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
+github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
+github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
+github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
+github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/microsoft/go-mssqldb v1.1.0 h1:jsV+tpvcPTbNNKW0o3kiCD69kOHICsfjZ2VcVu2lKYc=
+github.com/microsoft/go-mssqldb v1.1.0/go.mod h1:LzkFdl4z2Ck+Hi+ycGOTbL56VEfgoyA2DvYejrNGbRk=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
+github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
+github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
+github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU=
+github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
+github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
+github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/qiniu/qmgo v1.1.8 h1:E64M+P59aqQpXKI24ClVtluYkLaJLkkeD2hTVhrdMks=
+github.com/qiniu/qmgo v1.1.8/go.mod h1:QvZkzWNEv0buWPx0kdZsSs6URhESVubacxFPlITmvB8=
+github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
+github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
+github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/songzhibin97/gkit v1.2.11 h1:O8+l6eLMrZ2yNbT6Vohc6ggWnH5zt4P8/3ZEkf8jUL4=
+github.com/songzhibin97/gkit v1.2.11/go.mod h1:axjYsiJWnn/kf/uGiUr9JPHRlt2CQrqfq/fPZ3xIY+M=
+github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
+github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
+github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
+github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
+github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
+github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
+github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
+github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
+github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
+github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
+github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
+github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM=
+github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
+github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk=
+github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
+github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
+github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
+github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
+github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
+github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
+github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
+github.com/xhit/go-simple-mail/v2 v2.16.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
+github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.mongodb.org/mongo-driver v1.11.6/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
+go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE=
+go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
+go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
+golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
+golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
+golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
+gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
+gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
+gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
+gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
+gorm.io/driver/sqlserver v1.5.1 h1:wpyW/pR26U94uaujltiFGXY7fd2Jw5hC9PB1ZF/Y5s4=
+gorm.io/driver/sqlserver v1.5.1/go.mod h1:AYHzzte2msKTmYBYsSIq8ZUsznLJwBdkB2wpI+kt0nM=
+gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
+gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
+gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
+gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
+gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
+gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/plugin/dbresolver v1.4.1 h1:Ug4LcoPhrvqq71UhxtF346f+skTYoCa/nEsdjvHwEzk=
+gorm.io/plugin/dbresolver v1.4.1/go.mod h1:CTbCtMWhsjXSiJqiW2R8POvJ2cq18RVOl4WGyT5nhNc=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
+modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
+modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
+modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
+modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
+modernc.org/sqlite v1.23.0 h1:MWTFBI5H1WLnXpNBh/BTruBVqzzoh28DA0iOnlkkRaM=
+modernc.org/sqlite v1.23.0/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

+ 73 - 0
initialize/gorm.go

@@ -0,0 +1,73 @@
+package initialize
+
+import (
+	"fmt"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm/logger"
+	"gorm.io/gorm/schema"
+	"log"
+	"os"
+	"time"
+
+	"lc-fangdaosha/global"
+
+	"gorm.io/gorm"
+)
+
+func Gorm() *gorm.DB {
+	m := global.Config.Mysql
+	fmt.Println("mysql配置:", m)
+	if m.Dbname == "" {
+		return nil
+	}
+	mysqlConfig := mysql.Config{
+		DSN:                       m.Dsn(), // DSN data source name
+		DefaultStringSize:         191,     // string 类型字段的默认长度
+		SkipInitializeWithVersion: false,   // 根据版本自动配置
+	}
+	if db, err := gorm.Open(mysql.New(mysqlConfig), config(m.Prefix, m.Singular)); err != nil {
+		log.Fatalln("29:", err)
+		return nil
+	} else {
+		db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
+		sqlDB, _ := db.DB()
+		sqlDB.SetMaxIdleConns(m.MaxIdleConns)
+		sqlDB.SetMaxOpenConns(m.MaxOpenConns)
+		return db
+	}
+}
+
+type DBBASE interface {
+	GetLogMode() string
+}
+
+func config(prefix string, singular bool) *gorm.Config {
+	config := &gorm.Config{
+		NamingStrategy: schema.NamingStrategy{
+			TablePrefix:   prefix,
+			SingularTable: singular,
+		},
+		DisableForeignKeyConstraintWhenMigrating: true,
+	}
+	_default := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{
+		SlowThreshold: 200 * time.Millisecond,
+		LogLevel:      logger.Warn,
+		Colorful:      true,
+	})
+	var logMode DBBASE
+	logMode = &global.Config.Mysql
+
+	switch logMode.GetLogMode() {
+	case "silent", "Silent":
+		config.Logger = _default.LogMode(logger.Silent)
+	case "error", "Error":
+		config.Logger = _default.LogMode(logger.Error)
+	case "warn", "Warn":
+		config.Logger = _default.LogMode(logger.Warn)
+	case "info", "Info":
+		config.Logger = _default.LogMode(logger.Info)
+	default:
+		config.Logger = _default.LogMode(logger.Info)
+	}
+	return config
+}

+ 23 - 0
initialize/other.go

@@ -0,0 +1,23 @@
+package initialize
+
+import (
+	"github.com/songzhibin97/gkit/cache/local_cache"
+
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/utils"
+)
+
+func OtherInit() {
+	dr, err := utils.ParseDuration(global.Config.JWT.ExpiresTime)
+	if err != nil {
+		panic(err)
+	}
+	_, err = utils.ParseDuration(global.Config.JWT.BufferTime)
+	if err != nil {
+		panic(err)
+	}
+	//创建缓存,配置过期时间
+	global.BlackCache = local_cache.NewCache(
+		local_cache.SetDefaultExpire(dr),
+	)
+}

+ 26 - 0
initialize/redis.go

@@ -0,0 +1,26 @@
+package initialize
+
+import (
+	"context"
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/global"
+
+	"github.com/redis/go-redis/v9"
+	"go.uber.org/zap"
+)
+
+func Redis() {
+	redisCfg := global.Config.Redis
+	client := redis.NewClient(&redis.Options{
+		Addr:     redisCfg.Addr,
+		Password: redisCfg.Password, // no password set
+		DB:       redisCfg.DB,       // use default DB
+	})
+	pong, err := client.Ping(context.Background()).Result()
+	if err != nil {
+		logrus.Error("redis connect ping failed, err:", zap.Error(err))
+	} else {
+		logrus.Info("redis connect ping response:", zap.String("pong", pong))
+		global.GVA_REDIS = client
+	}
+}

+ 52 - 0
initialize/router.go

@@ -0,0 +1,52 @@
+package initialize
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/middleware"
+	"lc-fangdaosha/router"
+	"net/http"
+)
+
+func Routers() *gin.Engine {
+	Router := gin.Default()
+	systemRouter := router.RouterGroupApp.System
+	//Router.StaticFS(global.Config.Local.StorePath, http.Dir(global.Config.Local.StorePath))
+
+	//docs.SwaggerInfo.BasePath = global.Config.System.RouterPrefix
+	//Router.GET(global.Config.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
+
+	PublicGroup := Router.Group(global.Config.System.RouterPrefix)
+	{
+		PublicGroup.GET("/health", func(c *gin.Context) {
+			c.JSON(http.StatusOK, "ok")
+		})
+	}
+	{
+		systemRouter.InitBaseRouter(PublicGroup)
+		//systemRouter.InitMenuRouter(PublicGroup)
+	}
+
+	PrivateGroup := Router.Group(global.Config.System.RouterPrefix)
+	PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
+	//系统层
+	{
+		systemRouter.InitApiRouter(PrivateGroup, PublicGroup)
+		systemRouter.InitJwtRouter(PrivateGroup)
+		systemRouter.InitUserRouter(PrivateGroup, PublicGroup)
+		systemRouter.InitMenuRouter(PrivateGroup)
+		//systemRouter.InitSystemRouter(PrivateGroup)
+		systemRouter.InitCasbinRouter(PrivateGroup)
+		//systemRouter.InitAutoCodeRouter(PrivateGroup)
+		systemRouter.InitAuthorityRouter(PrivateGroup)
+		systemRouter.InitSysDictionaryRouter(PrivateGroup)
+		//systemRouter.InitAutoCodeHistoryRouter(PrivateGroup)
+		//systemRouter.InitSysOperationRecordRouter(PrivateGroup)
+		systemRouter.InitSysDictionaryDetailRouter(PrivateGroup)
+		//systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup)
+		//systemRouter.InitChatGptRouter(PrivateGroup)
+	}
+	logrus.Info("router register success")
+	return Router
+}

+ 55 - 0
main.go

@@ -0,0 +1,55 @@
+package main
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/initialize"
+	"lc-fangdaosha/service/system"
+	"net/http"
+	"os"
+	"time"
+)
+
+func main() {
+	logrus.SetLevel(logrus.DebugLevel)
+	logrus.SetOutput(os.Stdout)
+	logrus.SetReportCaller(true)
+	initialize.OtherInit() //初始化缓存
+	//initialize.Redis()
+	global.Db = initialize.Gorm() //初始化数据库orm
+	if global.Db != nil {
+		// 程序结束前关闭数据库链接
+		db, _ := global.Db.DB()
+		defer db.Close()
+	}
+	if global.Config.System.UseMultipoint || global.Config.System.UseRedis {
+		// 初始化redis服务
+		initialize.Redis()
+	}
+	// 从db加载jwt黑名单数据
+	if global.Db != nil {
+		system.LoadAll()
+	}
+	Router := initialize.Routers()
+	address := fmt.Sprintf(":%d", global.Config.System.Addr)
+
+	s := initServer(address, Router)
+	logrus.Error(s.ListenAndServe().Error())
+}
+
+type server interface {
+	ListenAndServe() error
+}
+
+func initServer(address string, router *gin.Engine) server {
+	return &http.Server{
+		Addr:           address,
+		Handler:        router,
+		ReadTimeout:    20 * time.Second,
+		WriteTimeout:   20 * time.Second,
+		MaxHeaderBytes: 1 << 20,
+	}
+}

+ 38 - 0
middleware/casbin_rbac.go

@@ -0,0 +1,38 @@
+package middleware
+
+import (
+	"strconv"
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/service"
+	"lc-fangdaosha/utils"
+)
+
+var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
+
+// CasbinHandler 拦截器
+func CasbinHandler() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		if global.Config.System.Env != "develop" {
+			waitUse, _ := utils.GetClaims(c)
+			//获取请求的PATH
+			path := c.Request.URL.Path
+			obj := strings.TrimPrefix(path, global.Config.System.RouterPrefix)
+			// 获取请求方法
+			act := c.Request.Method
+			// 获取用户的角色
+			sub := strconv.Itoa(int(waitUse.AuthorityId))
+			e := casbinService.Casbin() // 判断策略中是否存在
+			success, _ := e.Enforce(sub, obj, act)
+			if !success {
+				response.FailWithDetailed(gin.H{}, "权限不足", c)
+				c.Abort()
+				return
+			}
+		}
+		c.Next()
+	}
+}

+ 73 - 0
middleware/cors.go

@@ -0,0 +1,73 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"lc-fangdaosha/config"
+	"lc-fangdaosha/global"
+	"net/http"
+)
+
+// Cors 直接放行所有跨域请求并放行所有 OPTIONS 方法
+func Cors() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		method := c.Request.Method
+		origin := c.Request.Header.Get("Origin")
+		c.Header("Access-Control-Allow-Origin", origin)
+		c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
+		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
+		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type, New-Token, New-Expires-At")
+		c.Header("Access-Control-Allow-Credentials", "true")
+
+		// 放行所有OPTIONS方法
+		if method == "OPTIONS" {
+			c.AbortWithStatus(http.StatusNoContent)
+		}
+		// 处理请求
+		c.Next()
+	}
+}
+
+// CorsByRules 按照配置处理跨域请求
+func CorsByRules() gin.HandlerFunc {
+	// 放行全部
+	if global.Config.Cors.Mode == "allow-all" {
+		return Cors()
+	}
+	return func(c *gin.Context) {
+		whitelist := checkCors(c.GetHeader("origin"))
+
+		// 通过检查, 添加请求头
+		if whitelist != nil {
+			c.Header("Access-Control-Allow-Origin", whitelist.AllowOrigin)
+			c.Header("Access-Control-Allow-Headers", whitelist.AllowHeaders)
+			c.Header("Access-Control-Allow-Methods", whitelist.AllowMethods)
+			c.Header("Access-Control-Expose-Headers", whitelist.ExposeHeaders)
+			if whitelist.AllowCredentials {
+				c.Header("Access-Control-Allow-Credentials", "true")
+			}
+		}
+
+		// 严格白名单模式且未通过检查,直接拒绝处理请求
+		if whitelist == nil && global.Config.Cors.Mode == "strict-whitelist" && !(c.Request.Method == "GET" && c.Request.URL.Path == "/health") {
+			c.AbortWithStatus(http.StatusForbidden)
+		} else {
+			// 非严格白名单模式,无论是否通过检查均放行所有 OPTIONS 方法
+			if c.Request.Method == http.MethodOptions {
+				c.AbortWithStatus(http.StatusNoContent)
+			}
+		}
+
+		// 处理请求
+		c.Next()
+	}
+}
+
+func checkCors(currentOrigin string) *config.CORSWhitelist {
+	for _, whitelist := range global.Config.Cors.Whitelist {
+		// 遍历配置中的跨域头,寻找匹配项
+		if currentOrigin == whitelist.AllowOrigin {
+			return &whitelist
+		}
+	}
+	return nil
+}

+ 60 - 0
middleware/email.go

@@ -0,0 +1,60 @@
+package middleware
+
+import (
+	"bytes"
+	"github.com/sirupsen/logrus"
+	"io"
+	"strconv"
+	"time"
+
+	"lc-fangdaosha/utils"
+	utils2 "lc-fangdaosha/utils"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"lc-fangdaosha/model/system"
+	"lc-fangdaosha/service"
+)
+
+var userService = service.ServiceGroupApp.SystemServiceGroup.UserService
+
+func ErrorToEmail() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		var username string
+		claims, _ := utils2.GetClaims(c)
+		if claims.Username != "" {
+			username = claims.Username
+		} else {
+			id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id"))
+			user, err := userService.FindUserById(id)
+			if err != nil {
+				username = "Unknown"
+			}
+			username = user.Username
+		}
+		body, _ := io.ReadAll(c.Request.Body)
+		// 再重新写回请求体body中,ioutil.ReadAll会清空c.Request.Body中的数据
+		c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
+		record := system.SysOperationRecord{
+			Ip:     c.ClientIP(),
+			Method: c.Request.Method,
+			Path:   c.Request.URL.Path,
+			Agent:  c.Request.UserAgent(),
+			Body:   string(body),
+		}
+		now := time.Now()
+
+		c.Next()
+
+		latency := time.Since(now)
+		status := c.Writer.Status()
+		record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
+		str := "接收到的请求为" + record.Body + "\n" + "请求方式为" + record.Method + "\n" + "报错信息如下" + record.ErrorMessage + "\n" + "耗时" + latency.String() + "\n"
+		if status != 200 {
+			subject := username + "" + record.Ip + "调用了" + record.Path + "报错了"
+			if err := utils.ErrorToEmail(subject, str); err != nil {
+				logrus.Error("ErrorToEmail Failed, err:", zap.Error(err))
+			}
+		}
+	}
+}

+ 61 - 0
middleware/error.go

@@ -0,0 +1,61 @@
+package middleware
+
+import (
+	"github.com/sirupsen/logrus"
+	"net"
+	"net/http"
+	"net/http/httputil"
+	"os"
+	"runtime/debug"
+	"strings"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+// GinRecovery recover掉项目可能出现的panic,并使用zap记录相关日志
+func GinRecovery(stack bool) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		defer func() {
+			if err := recover(); err != nil {
+				// Check for a broken connection, as it is not really a
+				// condition that warrants a panic stack trace.
+				var brokenPipe bool
+				if ne, ok := err.(*net.OpError); ok {
+					if se, ok := ne.Err.(*os.SyscallError); ok {
+						if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
+							brokenPipe = true
+						}
+					}
+				}
+
+				httpRequest, _ := httputil.DumpRequest(c.Request, false)
+				if brokenPipe {
+					logrus.Error(c.Request.URL.Path,
+						zap.Any("error", err),
+						zap.String("request", string(httpRequest)),
+					)
+					// If the connection is dead, we can't write a status to it.
+					_ = c.Error(err.(error)) // nolint: errcheck
+					c.Abort()
+					return
+				}
+
+				if stack {
+					logrus.Error("[Recovery from panic]",
+						zap.Any("error", err),
+						zap.String("request", string(httpRequest)),
+						zap.String("stack", string(debug.Stack())),
+					)
+				} else {
+					logrus.Error("[Recovery from panic]",
+						zap.Any("error", err),
+						zap.String("request", string(httpRequest)),
+					)
+				}
+				c.AbortWithStatus(http.StatusInternalServerError)
+			}
+		}()
+		c.Next()
+	}
+}

+ 80 - 0
middleware/jwt.go

@@ -0,0 +1,80 @@
+package middleware
+
+import (
+	"errors"
+	"github.com/golang-jwt/jwt/v4"
+	"github.com/sirupsen/logrus"
+	"strconv"
+	"time"
+
+	"lc-fangdaosha/utils"
+
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/common/response"
+	"lc-fangdaosha/model/system"
+	"lc-fangdaosha/service"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService
+
+func JWTAuth() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
+		token := c.Request.Header.Get("x-token")
+		if token == "" {
+			response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
+			c.Abort()
+			return
+		}
+		if jwtService.IsBlacklist(token) {
+			response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
+			c.Abort()
+			return
+		}
+		j := utils.NewJWT()
+		// parseToken 解析token包含的信息
+		claims, err := j.ParseToken(token)
+		if err != nil {
+			if errors.Is(err, utils.TokenExpired) {
+				response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
+				c.Abort()
+				return
+			}
+			response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+			c.Abort()
+			return
+		}
+
+		// 已登录用户被管理员禁用 需要使该用户的jwt失效 此处比较消耗性能 如果需要 请自行打开
+		// 用户被删除的逻辑 需要优化 此处比较消耗性能 如果需要 请自行打开
+
+		//if user, err := userService.FindUserByUuid(claims.UUID.String()); err != nil || user.Enable == 2 {
+		//	_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: token})
+		//	response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
+		//	c.Abort()
+		//}
+		if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime {
+			dr, _ := utils.ParseDuration(global.Config.JWT.ExpiresTime)
+			claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(dr))
+			newToken, _ := j.CreateTokenByOldToken(token, *claims)
+			newClaims, _ := j.ParseToken(newToken)
+			c.Header("new-token", newToken)
+			c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt.Unix(), 10))
+			if global.Config.System.UseMultipoint {
+				RedisJwtToken, err := jwtService.GetRedisJWT(newClaims.Username)
+				if err != nil {
+					logrus.Error("get redis jwt failed", zap.Error(err))
+				} else { // 当之前的取成功时才进行拉黑操作
+					_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken})
+				}
+				// 无论如何都要记录当前的活跃状态
+				_ = jwtService.SetRedisJWT(newToken, newClaims.Username)
+			}
+		}
+		c.Set("claims", claims)
+		c.Next()
+	}
+}

+ 93 - 0
middleware/limit_ip.go

@@ -0,0 +1,93 @@
+package middleware
+
+import (
+	"context"
+	"errors"
+	"github.com/sirupsen/logrus"
+	"net/http"
+	"time"
+
+	"go.uber.org/zap"
+
+	"github.com/gin-gonic/gin"
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/common/response"
+)
+
+type LimitConfig struct {
+	// GenerationKey 根据业务生成key 下面CheckOrMark查询生成
+	GenerationKey func(c *gin.Context) string
+	// 检查函数,用户可修改具体逻辑,更加灵活
+	CheckOrMark func(key string, expire int, limit int) error
+	// Expire key 过期时间
+	Expire int
+	// Limit 周期时间
+	Limit int
+}
+
+func (l LimitConfig) LimitWithTime() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		if err := l.CheckOrMark(l.GenerationKey(c), l.Expire, l.Limit); err != nil {
+			c.JSON(http.StatusOK, gin.H{"code": response.ERROR, "msg": err})
+			c.Abort()
+			return
+		} else {
+			c.Next()
+		}
+	}
+}
+
+// DefaultGenerationKey 默认生成key
+func DefaultGenerationKey(c *gin.Context) string {
+	return "GVA_Limit" + c.ClientIP()
+}
+
+func DefaultCheckOrMark(key string, expire int, limit int) (err error) {
+	// 判断是否开启redis
+	if global.GVA_REDIS == nil {
+		return err
+	}
+	if err = SetLimitWithTime(key, limit, time.Duration(expire)*time.Second); err != nil {
+		logrus.Error("limit", zap.Error(err))
+	}
+	return err
+}
+
+func DefaultLimit() gin.HandlerFunc {
+	return LimitConfig{
+		GenerationKey: DefaultGenerationKey,
+		CheckOrMark:   DefaultCheckOrMark,
+		Expire:        global.Config.System.LimitTimeIP,
+		Limit:         global.Config.System.LimitCountIP,
+	}.LimitWithTime()
+}
+
+// SetLimitWithTime 设置访问次数
+func SetLimitWithTime(key string, limit int, expiration time.Duration) error {
+	count, err := global.GVA_REDIS.Exists(context.Background(), key).Result()
+	if err != nil {
+		return err
+	}
+	if count == 0 {
+		pipe := global.GVA_REDIS.TxPipeline()
+		pipe.Incr(context.Background(), key)
+		pipe.Expire(context.Background(), key, expiration)
+		_, err = pipe.Exec(context.Background())
+		return err
+	} else {
+		// 次数
+		if times, err := global.GVA_REDIS.Get(context.Background(), key).Int(); err != nil {
+			return err
+		} else {
+			if times >= limit {
+				if t, err := global.GVA_REDIS.PTTL(context.Background(), key).Result(); err != nil {
+					return errors.New("请求太过频繁,请稍后再试")
+				} else {
+					return errors.New("请求太过频繁, 请 " + t.String() + " 秒后尝试")
+				}
+			} else {
+				return global.GVA_REDIS.Incr(context.Background(), key).Err()
+			}
+		}
+	}
+}

+ 27 - 0
middleware/loadtls.go

@@ -0,0 +1,27 @@
+package middleware
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/unrolled/secure"
+)
+
+// 用https把这个中间件在router里面use一下就好
+
+func LoadTls() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		middleware := secure.New(secure.Options{
+			SSLRedirect: true,
+			SSLHost:     "localhost:443",
+		})
+		err := middleware.Process(c.Writer, c.Request)
+		if err != nil {
+			// 如果出现错误,请不要继续
+			fmt.Println(err)
+			return
+		}
+		// 继续往下处理
+		c.Next()
+	}
+}

+ 89 - 0
middleware/logger.go

@@ -0,0 +1,89 @@
+package middleware
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"io"
+	"strings"
+	"time"
+
+	"github.com/gin-gonic/gin"
+)
+
+// LogLayout 日志layout
+type LogLayout struct {
+	Time      time.Time
+	Metadata  map[string]interface{} // 存储自定义原数据
+	Path      string                 // 访问路径
+	Query     string                 // 携带query
+	Body      string                 // 携带body数据
+	IP        string                 // ip地址
+	UserAgent string                 // 代理
+	Error     string                 // 错误
+	Cost      time.Duration          // 花费时间
+	Source    string                 // 来源
+}
+
+type Logger struct {
+	// Filter 用户自定义过滤
+	Filter func(c *gin.Context) bool
+	// FilterKeyword 关键字过滤(key)
+	FilterKeyword func(layout *LogLayout) bool
+	// AuthProcess 鉴权处理
+	AuthProcess func(c *gin.Context, layout *LogLayout)
+	// 日志处理
+	Print func(LogLayout)
+	// Source 服务唯一标识
+	Source string
+}
+
+func (l Logger) SetLoggerMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		start := time.Now()
+		path := c.Request.URL.Path
+		query := c.Request.URL.RawQuery
+		var body []byte
+		if l.Filter != nil && !l.Filter(c) {
+			body, _ = c.GetRawData()
+			// 将原body塞回去
+			c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
+		}
+		c.Next()
+		cost := time.Since(start)
+		layout := LogLayout{
+			Time:      time.Now(),
+			Path:      path,
+			Query:     query,
+			IP:        c.ClientIP(),
+			UserAgent: c.Request.UserAgent(),
+			Error:     strings.TrimRight(c.Errors.ByType(gin.ErrorTypePrivate).String(), "\n"),
+			Cost:      cost,
+			Source:    l.Source,
+		}
+		if l.Filter != nil && !l.Filter(c) {
+			layout.Body = string(body)
+		}
+		if l.AuthProcess != nil {
+			// 处理鉴权需要的信息
+			l.AuthProcess(c, &layout)
+		}
+		if l.FilterKeyword != nil {
+			// 自行判断key/value 脱敏等
+			l.FilterKeyword(&layout)
+		}
+		// 自行处理日志
+		l.Print(layout)
+	}
+}
+
+func DefaultLogger() gin.HandlerFunc {
+	return Logger{
+		Print: func(layout LogLayout) {
+			// 标准输出,k8s做收集
+			v, _ := json.Marshal(layout)
+			fmt.Println(string(v))
+		},
+		Source: "GVA",
+	}.SetLoggerMiddleware()
+}

+ 22 - 0
middleware/need_init.go

@@ -0,0 +1,22 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/common/response"
+)
+
+// 处理跨域请求,支持options访问
+func NeedInit() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		if global.Db == nil {
+			response.OkWithDetailed(gin.H{
+				"needInit": true,
+			}, "前往初始化数据库", c)
+			c.Abort()
+		} else {
+			c.Next()
+		}
+		// 处理请求
+	}
+}

+ 135 - 0
middleware/operation.go

@@ -0,0 +1,135 @@
+package middleware
+
+import (
+	"bytes"
+	"encoding/json"
+	"github.com/sirupsen/logrus"
+	"io"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"lc-fangdaosha/utils"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"lc-fangdaosha/model/system"
+	"lc-fangdaosha/service"
+)
+
+var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
+
+var respPool sync.Pool
+
+func init() {
+	respPool.New = func() interface{} {
+		return make([]byte, 1024)
+	}
+}
+
+func OperationRecord() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		var body []byte
+		var userId int
+		if c.Request.Method != http.MethodGet {
+			var err error
+			body, err = io.ReadAll(c.Request.Body)
+			if err != nil {
+				logrus.Error("read body from request error:", zap.Error(err))
+			} else {
+				c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
+			}
+		} else {
+			query := c.Request.URL.RawQuery
+			query, _ = url.QueryUnescape(query)
+			split := strings.Split(query, "&")
+			m := make(map[string]string)
+			for _, v := range split {
+				kv := strings.Split(v, "=")
+				if len(kv) == 2 {
+					m[kv[0]] = kv[1]
+				}
+			}
+			body, _ = json.Marshal(&m)
+		}
+		claims, _ := utils.GetClaims(c)
+		if claims.BaseClaims.ID != 0 {
+			userId = int(claims.BaseClaims.ID)
+		} else {
+			id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
+			if err != nil {
+				userId = 0
+			}
+			userId = id
+		}
+		record := system.SysOperationRecord{
+			Ip:     c.ClientIP(),
+			Method: c.Request.Method,
+			Path:   c.Request.URL.Path,
+			Agent:  c.Request.UserAgent(),
+			Body:   string(body),
+			UserID: userId,
+		}
+
+		// 上传文件时候 中间件日志进行裁断操作
+		if strings.Contains(c.GetHeader("Content-Type"), "multipart/form-data") {
+			if len(record.Body) > 1024 {
+				// 截断
+				newBody := respPool.Get().([]byte)
+				copy(newBody, record.Body)
+				record.Body = string(newBody)
+				defer respPool.Put(newBody[:0])
+			}
+		}
+
+		writer := responseBodyWriter{
+			ResponseWriter: c.Writer,
+			body:           &bytes.Buffer{},
+		}
+		c.Writer = writer
+		now := time.Now()
+
+		c.Next()
+
+		latency := time.Since(now)
+		record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
+		record.Status = c.Writer.Status()
+		record.Latency = latency
+		record.Resp = writer.body.String()
+
+		if strings.Contains(c.Writer.Header().Get("Pragma"), "public") ||
+			strings.Contains(c.Writer.Header().Get("Expires"), "0") ||
+			strings.Contains(c.Writer.Header().Get("Cache-Control"), "must-revalidate, post-check=0, pre-check=0") ||
+			strings.Contains(c.Writer.Header().Get("Content-Type"), "application/force-download") ||
+			strings.Contains(c.Writer.Header().Get("Content-Type"), "application/octet-stream") ||
+			strings.Contains(c.Writer.Header().Get("Content-Type"), "application/vnd.ms-excel") ||
+			strings.Contains(c.Writer.Header().Get("Content-Type"), "application/download") ||
+			strings.Contains(c.Writer.Header().Get("Content-Disposition"), "attachment") ||
+			strings.Contains(c.Writer.Header().Get("Content-Transfer-Encoding"), "binary") {
+			if len(record.Resp) > 1024 {
+				// 截断
+				newBody := respPool.Get().([]byte)
+				copy(newBody, record.Resp)
+				record.Resp = string(newBody)
+				defer respPool.Put(newBody[:0])
+			}
+		}
+
+		if err := operationRecordService.CreateSysOperationRecord(record); err != nil {
+			logrus.Error("create operation record error:", zap.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)
+}

+ 28 - 0
model/common/request/common.go

@@ -0,0 +1,28 @@
+package request
+
+// PageInfo 分页请求
+type PageInfo struct {
+	Page     int    `json:"page" form:"page"`         // 页码
+	PageSize int    `json:"pageSize" form:"pageSize"` // 每页大小
+	Keyword  string `json:"keyword" form:"keyword"`   //关键字
+}
+
+// GetById Find by id structure
+type GetById struct {
+	ID int `json:"id" form:"id"` // 主键ID
+}
+
+func (r *GetById) Uint() uint {
+	return uint(r.ID)
+}
+
+type IdsReq struct {
+	Ids []int `json:"ids" form:"ids"`
+}
+
+// GetAuthorityId Get role by id structure
+type GetAuthorityId struct {
+	AuthorityId uint `json:"authorityId" form:"authorityId"` // 角色ID
+}
+
+type Empty struct{}

+ 9 - 0
model/common/response/common.go

@@ -0,0 +1,9 @@
+package response
+
+// PageResult 公共分页响应结构体
+type PageResult struct {
+	List     interface{} `json:"list"`
+	Total    int64       `json:"total"`
+	Page     int         `json:"page"`
+	PageSize int         `json:"pageSize"`
+}

+ 54 - 0
model/common/response/response.go

@@ -0,0 +1,54 @@
+package response
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+type Response struct {
+	Code int         `json:"code"`
+	Data interface{} `json:"data"`
+	Msg  string      `json:"msg"`
+}
+
+const (
+	ERROR   = 7
+	SUCCESS = 0
+)
+
+func result(code int, data interface{}, msg string, c *gin.Context) {
+	// 开始时间
+	c.JSON(http.StatusOK, Response{
+		code,
+		data,
+		msg,
+	})
+}
+
+func Ok(c *gin.Context) {
+	result(SUCCESS, map[string]interface{}{}, "操作成功", c)
+}
+
+func OkWithMessage(message string, c *gin.Context) {
+	result(SUCCESS, map[string]interface{}{}, message, c)
+}
+
+func OkWithData(data interface{}, c *gin.Context) {
+	result(SUCCESS, data, "查询成功", c)
+}
+
+func OkWithDetailed(data interface{}, message string, c *gin.Context) {
+	result(SUCCESS, data, message, c)
+}
+
+func Fail(c *gin.Context) {
+	result(ERROR, map[string]interface{}{}, "操作失败", c)
+}
+
+func FailWithMessage(message string, c *gin.Context) {
+	result(ERROR, map[string]interface{}{}, message, c)
+}
+
+func FailWithDetailed(data interface{}, message string, c *gin.Context) {
+	result(ERROR, data, message, c)
+}

+ 21 - 0
model/system/request/jwt.go

@@ -0,0 +1,21 @@
+package request
+
+import (
+	"github.com/gofrs/uuid/v5"
+	jwt "github.com/golang-jwt/jwt/v4"
+)
+
+// Custom claims structure
+type CustomClaims struct {
+	BaseClaims
+	BufferTime int64
+	jwt.RegisteredClaims
+}
+
+type BaseClaims struct {
+	UUID        uuid.UUID
+	ID          uint
+	Username    string
+	NickName    string
+	AuthorityId uint
+}

+ 14 - 0
model/system/request/sys_api.go

@@ -0,0 +1,14 @@
+package request
+
+import (
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/system"
+)
+
+// api分页条件查询及排序结构体
+type SearchApiParams struct {
+	system.SysApi
+	request.PageInfo
+	OrderKey string `json:"orderKey"` // 排序
+	Desc     bool   `json:"desc"`     // 排序方式:升序false(默认)|降序true
+}

+ 7 - 0
model/system/request/sys_authority_btn.go

@@ -0,0 +1,7 @@
+package request
+
+type SysAuthorityBtnReq struct {
+	MenuID      uint   `json:"menuID"`
+	AuthorityId uint   `json:"authorityId"`
+	Selected    []uint `json:"selected"`
+}

+ 13 - 0
model/system/request/sys_auto_history.go

@@ -0,0 +1,13 @@
+package request
+
+import "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
+
+type SysAutoHistory struct {
+	request.PageInfo
+}
+
+// GetById Find by id structure
+type RollBack struct {
+	ID          int  `json:"id" form:"id"`                   // 主键ID
+	DeleteTable bool `json:"deleteTable" form:"deleteTable"` // 是否删除表
+}

+ 26 - 0
model/system/request/sys_casbin.go

@@ -0,0 +1,26 @@
+package request
+
+// Casbin info structure
+type CasbinInfo struct {
+	Path   string `json:"path"`   // 路径
+	Method string `json:"method"` // 方法
+}
+
+// Casbin structure for input parameters
+type CasbinInReceive struct {
+	AuthorityId uint         `json:"authorityId"` // 权限id
+	CasbinInfos []CasbinInfo `json:"casbinInfos"`
+}
+
+func DefaultCasbin() []CasbinInfo {
+	return []CasbinInfo{
+		{Path: "/menu/getMenu", Method: "POST"},
+		{Path: "/jwt/jsonInBlacklist", Method: "POST"},
+		{Path: "/base/login", Method: "POST"},
+		{Path: "/user/admin_register", Method: "POST"},
+		{Path: "/user/changePassword", Method: "POST"},
+		{Path: "/user/setUserAuthority", Method: "POST"},
+		{Path: "/user/setUserInfo", Method: "PUT"},
+		{Path: "/user/getUserInfo", Method: "GET"},
+	}
+}

+ 11 - 0
model/system/request/sys_chatgpt.go

@@ -0,0 +1,11 @@
+package request
+
+import (
+	"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
+	"github.com/flipped-aurora/gin-vue-admin/server/model/system"
+)
+
+type ChatGptRequest struct {
+	system.ChatGpt
+	request.PageInfo
+}

+ 11 - 0
model/system/request/sys_dictionary.go

@@ -0,0 +1,11 @@
+package request
+
+import (
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/system"
+)
+
+type SysDictionarySearch struct {
+	system.SysDictionary
+	request.PageInfo
+}

+ 11 - 0
model/system/request/sys_dictionary_detail.go

@@ -0,0 +1,11 @@
+package request
+
+import (
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/system"
+)
+
+type SysDictionaryDetailSearch struct {
+	system.SysDictionaryDetail
+	request.PageInfo
+}

+ 101 - 0
model/system/request/sys_init.go

@@ -0,0 +1,101 @@
+package request
+
+import (
+	"fmt"
+
+	"github.com/flipped-aurora/gin-vue-admin/server/config"
+)
+
+type InitDB struct {
+	DBType   string `json:"dbType"`                    // 数据库类型
+	Host     string `json:"host"`                      // 服务器地址
+	Port     string `json:"port"`                      // 数据库连接端口
+	UserName string `json:"userName"`                  // 数据库用户名
+	Password string `json:"password"`                  // 数据库密码
+	DBName   string `json:"dbName" binding:"required"` // 数据库名
+	DBPath   string `json:"dbPath"`                    // sqlite数据库文件路径
+}
+
+// MysqlEmptyDsn msyql 空数据库 建库链接
+// Author SliverHorn
+func (i *InitDB) MysqlEmptyDsn() string {
+	if i.Host == "" {
+		i.Host = "127.0.0.1"
+	}
+	if i.Port == "" {
+		i.Port = "3306"
+	}
+	return fmt.Sprintf("%s:%s@tcp(%s:%s)/", i.UserName, i.Password, i.Host, i.Port)
+}
+
+// PgsqlEmptyDsn pgsql 空数据库 建库链接
+// Author SliverHorn
+func (i *InitDB) PgsqlEmptyDsn() string {
+	if i.Host == "" {
+		i.Host = "127.0.0.1"
+	}
+	if i.Port == "" {
+		i.Port = "5432"
+	}
+	return "host=" + i.Host + " user=" + i.UserName + " password=" + i.Password + " port=" + i.Port + " dbname=" + "postgres" + " " + "sslmode=disable TimeZone=Asia/Shanghai"
+}
+
+// SqliteEmptyDsn sqlite 空数据库 建库链接
+// Author Kafumio
+func (i *InitDB) SqliteEmptyDsn() string {
+	return i.DBPath + "\\" + i.DBName + ".db"
+}
+
+// ToMysqlConfig 转换 config.Mysql
+// Author [SliverHorn](https://github.com/SliverHorn)
+func (i *InitDB) ToMysqlConfig() config.Mysql {
+	return config.Mysql{
+		GeneralDB: config.GeneralDB{
+			Path:         i.Host,
+			Port:         i.Port,
+			Dbname:       i.DBName,
+			Username:     i.UserName,
+			Password:     i.Password,
+			MaxIdleConns: 10,
+			MaxOpenConns: 100,
+			LogMode:      "error",
+			Config:       "charset=utf8mb4&parseTime=True&loc=Local",
+		},
+	}
+}
+
+// ToPgsqlConfig 转换 config.Pgsql
+// Author [SliverHorn](https://github.com/SliverHorn)
+func (i *InitDB) ToPgsqlConfig() config.Pgsql {
+	return config.Pgsql{
+		GeneralDB: config.GeneralDB{
+			Path:         i.Host,
+			Port:         i.Port,
+			Dbname:       i.DBName,
+			Username:     i.UserName,
+			Password:     i.Password,
+			MaxIdleConns: 10,
+			MaxOpenConns: 100,
+			LogMode:      "error",
+			Config:       "sslmode=disable TimeZone=Asia/Shanghai",
+		},
+	}
+}
+
+// ToSqliteConfig 转换 config.Sqlite
+// Author [Kafumio](https://github.com/Kafumio)
+func (i *InitDB) ToSqliteConfig() config.Sqlite {
+	return config.Sqlite{
+		GeneralDB: config.GeneralDB{
+			Path:         i.DBPath,
+			Port:         i.Port,
+			Dbname:       i.DBName,
+			Username:     i.UserName,
+			Password:     i.Password,
+			MaxIdleConns: 10,
+			MaxOpenConns: 100,
+			LogMode:      "error",
+			Config:       "",
+		},
+	}
+}

+ 27 - 0
model/system/request/sys_menu.go

@@ -0,0 +1,27 @@
+package request
+
+import (
+	"lc-fangdaosha/global"
+	"lc-fangdaosha/model/system"
+)
+
+// Add menu authority info structure
+type AddMenuAuthorityInfo struct {
+	Menus       []system.SysBaseMenu `json:"menus"`
+	AuthorityId uint                 `json:"authorityId"` // 角色ID
+}
+
+func DefaultMenu() []system.SysBaseMenu {
+	return []system.SysBaseMenu{{
+		GVA_MODEL: global.GVA_MODEL{ID: 1},
+		ParentId:  "0",
+		Path:      "dashboard",
+		Name:      "dashboard",
+		Component: "view/dashboard/index.vue",
+		Sort:      1,
+		Meta: system.Meta{
+			Title: "仪表盘",
+			Icon:  "setting",
+		},
+	}}
+}

+ 11 - 0
model/system/request/sys_operation_record.go

@@ -0,0 +1,11 @@
+package request
+
+import (
+	"lc-fangdaosha/model/common/request"
+	"lc-fangdaosha/model/system"
+)
+
+type SysOperationRecordSearch struct {
+	system.SysOperationRecord
+	request.PageInfo
+}

+ 61 - 0
model/system/request/sys_user.go

@@ -0,0 +1,61 @@
+package request
+
+import (
+	"github.com/flipped-aurora/gin-vue-admin/server/model/system"
+)
+
+// Register User register structure
+type Register struct {
+	Username     string `json:"userName" example:"用户名"`
+	Password     string `json:"passWord" example:"密码"`
+	NickName     string `json:"nickName" example:"昵称"`
+	HeaderImg    string `json:"headerImg" example:"头像链接"`
+	AuthorityId  uint   `json:"authorityId" swaggertype:"string" example:"int 角色id"`
+	Enable       int    `json:"enable" swaggertype:"string" example:"int 是否启用"`
+	AuthorityIds []uint `json:"authorityIds" swaggertype:"string" example:"[]uint 角色id"`
+	Phone        string `json:"phone" example:"电话号码"`
+	Email        string `json:"email" example:"电子邮箱"`
+}
+
+// User login structure
+type Login struct {
+	Username  string `json:"username"`  // 用户名
+	Password  string `json:"password"`  // 密码
+	Captcha   string `json:"captcha"`   // 验证码
+	CaptchaId string `json:"captchaId"` // 验证码ID
+}
+
+// Modify password structure
+type ChangePasswordReq struct {
+	ID          uint   `json:"-"`           // 从 JWT 中提取 user id,避免越权
+	Password    string `json:"password"`    // 密码
+	NewPassword string `json:"newPassword"` // 新密码
+}
+
+// Modify  user's auth structure
+type SetUserAuth struct {
+	AuthorityId uint `json:"authorityId"` // 角色ID
+}
+
+// Modify  user's auth structure
+type SetUserAuthorities struct {
+	ID           uint
+	AuthorityIds []uint `json:"authorityIds"` // 角色ID
+}
+
+type ChangeUserInfo struct {
+	ID           uint                  `gorm:"primarykey"`                                                                           // 主键ID
+	NickName     string                `json:"nickName" gorm:"default:系统用户;comment:用户昵称"`                                            // 用户昵称
+	Phone        string                `json:"phone"  gorm:"comment:用户手机号"`                                                          // 用户手机号
+	AuthorityIds []uint                `json:"authorityIds" gorm:"-"`                                                                // 角色ID
+	Email        string                `json:"email"  gorm:"comment:用户邮箱"`                                                           // 用户邮箱
+	HeaderImg    string                `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
+	SideMode     string                `json:"sideMode"  gorm:"comment:用户侧边主题"`                                                      // 用户侧边主题
+	Enable       int                   `json:"enable" gorm:"comment:冻结用户"`                                                           //冻结用户
+	Authorities  []system.SysAuthority `json:"-" gorm:"many2many:sys_user_authority;"`
+}
+
+type Email struct {
+	ID    uint   `json:"id"`
+	Email string `json:"email"`
+}

+ 11 - 0
model/system/response/sys_api.go

@@ -0,0 +1,11 @@
+package response
+
+import "lc-fangdaosha/model/system"
+
+type SysAPIResponse struct {
+	Api system.SysApi `json:"api"`
+}
+
+type SysAPIListResponse struct {
+	Apis []system.SysApi `json:"apis"`
+}

+ 12 - 0
model/system/response/sys_authority.go

@@ -0,0 +1,12 @@
+package response
+
+import "lc-fangdaosha/model/system"
+
+type SysAuthorityResponse struct {
+	Authority system.SysAuthority `json:"authority"`
+}
+
+type SysAuthorityCopyResponse struct {
+	Authority      system.SysAuthority `json:"authority"`
+	OldAuthorityId uint                `json:"oldAuthorityId"` // 旧角色ID
+}

+ 8 - 0
model/system/response/sys_captcha.go

@@ -0,0 +1,8 @@
+package response
+
+type SysCaptchaResponse struct {
+	CaptchaId     string `json:"captchaId"`
+	PicPath       string `json:"picPath"`
+	CaptchaLength int    `json:"captchaLength"`
+	OpenCaptcha   bool   `json:"openCaptcha"`
+}

+ 9 - 0
model/system/response/sys_casbin.go

@@ -0,0 +1,9 @@
+package response
+
+import (
+	"lc-fangdaosha/model/system/request"
+)
+
+type PolicyPathResponse struct {
+	Paths []request.CasbinInfo `json:"paths"`
+}

+ 15 - 0
model/system/response/sys_menu.go

@@ -0,0 +1,15 @@
+package response
+
+import "lc-fangdaosha/model/system"
+
+type SysMenusResponse struct {
+	Menus []system.SysMenu `json:"menus"`
+}
+
+type SysBaseMenusResponse struct {
+	Menus []system.SysBaseMenu `json:"menus"`
+}
+
+type SysBaseMenuResponse struct {
+	Menu system.SysBaseMenu `json:"menu"`
+}

+ 20 - 0
model/system/response/sys_user.go

@@ -0,0 +1,20 @@
+package response
+
+import (
+	"lc-fangdaosha/model/system"
+)
+
+type SysUserResponse struct {
+	User system.SysUser `json:"user"`
+}
+
+type LoginResponse struct {
+	User      system.SysUser `json:"user"`
+	Token     string         `json:"token"`
+	ExpiresAt int64          `json:"expiresAt"`
+}
+
+type IdName struct {
+	Id       int    `json:"id"`
+	UserName string `json:"userName"`
+}

+ 17 - 0
model/system/sys_api.go

@@ -0,0 +1,17 @@
+package system
+
+import (
+	"lc-fangdaosha/global"
+)
+
+type SysApi struct {
+	global.GVA_MODEL
+	Path        string `json:"path" gorm:"comment:api路径"`             // api路径
+	Description string `json:"description" gorm:"comment:api中文描述"`    // api中文描述
+	ApiGroup    string `json:"apiGroup" gorm:"comment:api组"`          // api组
+	Method      string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE
+}
+
+func (SysApi) TableName() string {
+	return "sys_apis"
+}

+ 23 - 0
model/system/sys_authority.go

@@ -0,0 +1,23 @@
+package system
+
+import (
+	"time"
+)
+
+type SysAuthority struct {
+	CreatedAt       time.Time       // 创建时间
+	UpdatedAt       time.Time       // 更新时间
+	DeletedAt       *time.Time      `sql:"index"`
+	AuthorityId     uint            `json:"authorityId" gorm:"not null;unique;primary_key;comment:角色ID;size:90"` // 角色ID
+	AuthorityName   string          `json:"authorityName" gorm:"comment:角色名"`                                    // 角色名
+	ParentId        *uint           `json:"parentId" gorm:"comment:父角色ID"`                                       // 父角色ID
+	DataAuthorityId []*SysAuthority `json:"dataAuthorityId" gorm:"many2many:sys_data_authority_id;"`
+	Children        []SysAuthority  `json:"children" gorm:"-"`
+	SysBaseMenus    []SysBaseMenu   `json:"menus" gorm:"many2many:sys_authority_menus;"`
+	Users           []SysUser       `json:"-" gorm:"many2many:sys_user_authority;"`
+	DefaultRouter   string          `json:"defaultRouter" gorm:"comment:默认菜单;default:dashboard"` // 默认菜单(默认dashboard)
+}
+
+func (SysAuthority) TableName() string {
+	return "sys_authorities"
+}

+ 8 - 0
model/system/sys_authority_btn.go

@@ -0,0 +1,8 @@
+package system
+
+type SysAuthorityBtn struct {
+	AuthorityId      uint           `gorm:"comment:角色ID"`
+	SysMenuID        uint           `gorm:"comment:菜单ID"`
+	SysBaseMenuBtnID uint           `gorm:"comment:菜单按钮ID"`
+	SysBaseMenuBtn   SysBaseMenuBtn ` gorm:"comment:按钮详情"`
+}

+ 19 - 0
model/system/sys_authority_menu.go

@@ -0,0 +1,19 @@
+package system
+
+type SysMenu struct {
+	SysBaseMenu
+	MenuId      string                 `json:"menuId" gorm:"comment:菜单ID"`
+	AuthorityId uint                   `json:"-" gorm:"comment:角色ID"`
+	Children    []SysMenu              `json:"children" gorm:"-"`
+	Parameters  []SysBaseMenuParameter `json:"parameters" gorm:"foreignKey:SysBaseMenuID;references:MenuId"`
+	Btns        map[string]uint        `json:"btns" gorm:"-"`
+}
+
+type SysAuthorityMenu struct {
+	MenuId      string `json:"menuId" gorm:"comment:菜单ID;column:sys_base_menu_id"`
+	AuthorityId string `json:"-" gorm:"comment:角色ID;column:sys_authority_authority_id"`
+}
+
+func (s SysAuthorityMenu) TableName() string {
+	return "sys_authority_menus"
+}

+ 42 - 0
model/system/sys_base_menu.go

@@ -0,0 +1,42 @@
+package system
+
+import (
+	"lc-fangdaosha/global"
+)
+
+type SysBaseMenu struct {
+	global.GVA_MODEL
+	MenuLevel     uint                                       `json:"-"`
+	ParentId      string                                     `json:"parentId" gorm:"comment:父菜单ID"`     // 父菜单ID
+	Path          string                                     `json:"path" gorm:"comment:路由path"`        // 路由path
+	Name          string                                     `json:"name" gorm:"comment:路由name"`        // 路由name
+	Hidden        bool                                       `json:"hidden" gorm:"comment:是否在列表隐藏"`     // 是否在列表隐藏
+	Component     string                                     `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
+	Sort          int                                        `json:"sort" gorm:"comment:排序标记"`          // 排序标记
+	Meta          `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
+	SysAuthoritys []SysAuthority                             `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
+	Children      []SysBaseMenu                              `json:"children" gorm:"-"`
+	Parameters    []SysBaseMenuParameter                     `json:"parameters"`
+	MenuBtn       []SysBaseMenuBtn                           `json:"menuBtn"`
+}
+
+type Meta struct {
+	ActiveName  string `json:"activeName" gorm:"comment:高亮菜单"`
+	KeepAlive   bool   `json:"keepAlive" gorm:"comment:是否缓存"`           // 是否缓存
+	DefaultMenu bool   `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
+	Title       string `json:"title" gorm:"comment:菜单名"`                // 菜单名
+	Icon        string `json:"icon" gorm:"comment:菜单图标"`                // 菜单图标
+	CloseTab    bool   `json:"closeTab" gorm:"comment:自动关闭tab"`         // 自动关闭tab
+}
+
+type SysBaseMenuParameter struct {
+	global.GVA_MODEL
+	SysBaseMenuID uint
+	Type          string `json:"type" gorm:"comment:地址栏携带参数为params还是query"` // 地址栏携带参数为params还是query
+	Key           string `json:"key" gorm:"comment:地址栏携带参数的key"`            // 地址栏携带参数的key
+	Value         string `json:"value" gorm:"comment:地址栏携带参数的值"`            // 地址栏携带参数的值
+}
+
+func (SysBaseMenu) TableName() string {
+	return "sys_base_menus"
+}

+ 20 - 0
model/system/sys_dictionary.go

@@ -0,0 +1,20 @@
+// 自动生成模板SysDictionary
+package system
+
+import (
+	"lc-fangdaosha/global"
+)
+
+// 如果含有time.Time 请自行import time包
+type SysDictionary struct {
+	global.GVA_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"`
+}
+
+func (SysDictionary) TableName() string {
+	return "sys_dictionaries"
+}

+ 20 - 0
model/system/sys_dictionary_detail.go

@@ -0,0 +1,20 @@
+// 自动生成模板SysDictionaryDetail
+package system
+
+import (
+	"lc-fangdaosha/global"
+)
+
+// 如果含有time.Time 请自行import time包
+type SysDictionaryDetail struct {
+	global.GVA_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:关联标记"` // 关联标记
+}
+
+func (SysDictionaryDetail) TableName() string {
+	return "sys_dictionary_details"
+}

+ 10 - 0
model/system/sys_jwt_blacklist.go

@@ -0,0 +1,10 @@
+package system
+
+import (
+	"lc-fangdaosha/global"
+)
+
+type JwtBlacklist struct {
+	global.GVA_MODEL
+	Jwt string `gorm:"type:text;comment:jwt"`
+}

+ 10 - 0
model/system/sys_menu_btn.go

@@ -0,0 +1,10 @@
+package system
+
+import "lc-fangdaosha/global"
+
+type SysBaseMenuBtn struct {
+	global.GVA_MODEL
+	Name          string `json:"name" gorm:"comment:按钮关键key"`
+	Desc          string `json:"desc" gorm:"按钮备注"`
+	SysBaseMenuID uint   `json:"sysBaseMenuID" gorm:"comment:菜单ID"`
+}

+ 24 - 0
model/system/sys_operation_record.go

@@ -0,0 +1,24 @@
+// 自动生成模板SysOperationRecord
+package system
+
+import (
+	"time"
+
+	"lc-fangdaosha/global"
+)
+
+// 如果含有time.Time 请自行import time包
+type SysOperationRecord struct {
+	global.GVA_MODEL
+	Ip           string        `json:"ip" form:"ip" gorm:"column:ip;comment:请求ip"`                                   // 请求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:延迟" swaggertype:"string"` // 延迟
+	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:"type:text;column:body;comment:请求Body"`                 // 请求Body
+	Resp         string        `json:"resp" form:"resp" gorm:"type:text;column:resp;comment:响应Body"`                 // 响应Body
+	UserID       int           `json:"user_id" form:"user_id" gorm:"column:user_id;comment:用户id"`                    // 用户id
+	User         SysUser       `json:"user"`
+}

+ 29 - 0
model/system/sys_user.go

@@ -0,0 +1,29 @@
+package system
+
+import (
+	"github.com/gofrs/uuid/v5"
+	"lc-fangdaosha/global"
+)
+
+type SysUser struct {
+	global.GVA_MODEL
+	UUID        uuid.UUID           `json:"uuid" gorm:"index;comment:用户UUID"`                                                     // 用户UUID
+	Username    string              `json:"userName" gorm:"index;comment:用户登录名"`                                                  // 用户登录名
+	Password    string              `json:"-"  gorm:"comment:用户登录密码"`                                                             // 用户登录密码
+	NickName    string              `json:"nickName" gorm:"default:系统用户;comment:用户昵称"`                                            // 用户昵称
+	SideMode    string              `json:"sideMode" gorm:"default:dark;comment:用户侧边主题"`                                          // 用户侧边主题
+	HeaderImg   string              `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
+	BaseColor   string              `json:"baseColor" gorm:"default:#fff;comment:基础颜色"`                                           // 基础颜色
+	ActiveColor string              `json:"activeColor" gorm:"default:#1890ff;comment:活跃颜色"`                                      // 活跃颜色
+	AuthorityId uint                `json:"authorityId" gorm:"default:888;comment:用户角色ID"`                                        // 用户角色ID
+	Authority   SysAuthority        `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
+	Authorities []SysAuthority      `json:"authorities" gorm:"many2many:sys_user_authority;"`
+	Phone       string              `json:"phone"  gorm:"comment:用户手机号"`                     // 用户手机号
+	Email       string              `json:"email"  gorm:"comment:用户邮箱"`                      // 用户邮箱
+	Enable      int                 `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结
+	Devices     map[string][]string `json:"devices" yaml:"devices" gorm:"-"`                 //用户拥有的设备,key为边缘端mac地址表示一个项目,[]string为这个边缘端下的摄像头ip集合
+}
+
+func (SysUser) TableName() string {
+	return "sys_users"
+}

+ 11 - 0
model/system/sys_user_authority.go

@@ -0,0 +1,11 @@
+package system
+
+// SysUserAuthority 是 sysUser 和 sysAuthority 的连接表
+type SysUserAuthority struct {
+	SysUserId               uint `gorm:"column:sys_user_id"`
+	SysAuthorityAuthorityId uint `gorm:"column:sys_authority_authority_id"`
+}
+
+func (s *SysUserAuthority) TableName() string {
+	return "sys_user_authority"
+}

+ 11 - 0
router/enter.go

@@ -0,0 +1,11 @@
+package router
+
+import (
+	"lc-fangdaosha/router/system"
+)
+
+type RouterGroup struct {
+	System system.RouterGroup
+}
+
+var RouterGroupApp = new(RouterGroup)

+ 19 - 0
router/system/enter.go

@@ -0,0 +1,19 @@
+package system
+
+type RouterGroup struct {
+	ApiRouter
+	JwtRouter
+	//SysRouter
+	BaseRouter
+	//InitRouter
+	MenuRouter
+	UserRouter
+	CasbinRouter
+	//AutoCodeRouter
+	AuthorityRouter
+	DictionaryRouter
+	//OperationRecordRouter
+	DictionaryDetailRouter
+	//AuthorityBtnRouter
+	//ChatGptRouter
+}

+ 30 - 0
router/system/sys_api.go

@@ -0,0 +1,30 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type ApiRouter struct{}
+
+func (s *ApiRouter) InitApiRouter(Router, PubPouter *gin.RouterGroup) {
+	apiRouter := Router.Group("api").Use(middleware.OperationRecord())
+	apiRouterWithoutRecord := Router.Group("api")
+	apiPubRouterWithoutRecord := PubPouter.Group("api")
+	apiRouterApi := v1.ApiGroupApp.SystemApiGroup.SystemApiApi
+	{
+		apiRouter.POST("createApi", apiRouterApi.CreateApi)               // 创建Api
+		apiRouter.POST("deleteApi", apiRouterApi.DeleteApi)               // 删除Api
+		apiRouter.POST("getApiById", apiRouterApi.GetApiById)             // 获取单条Api消息
+		apiRouter.POST("updateApi", apiRouterApi.UpdateApi)               // 更新api
+		apiRouter.DELETE("deleteApisByIds", apiRouterApi.DeleteApisByIds) // 删除选中api
+	}
+	{
+		apiRouterWithoutRecord.POST("getAllApis", apiRouterApi.GetAllApis) // 获取所有api
+		apiRouterWithoutRecord.POST("getApiList", apiRouterApi.GetApiList) // 获取Api列表
+	}
+	{
+		apiPubRouterWithoutRecord.GET("freshCasbin", apiRouterApi.FreshCasbin)
+	}
+}

+ 25 - 0
router/system/sys_authority.go

@@ -0,0 +1,25 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type AuthorityRouter struct{}
+
+func (s *AuthorityRouter) InitAuthorityRouter(Router *gin.RouterGroup) {
+	authorityRouter := Router.Group("authority").Use(middleware.OperationRecord())
+	authorityRouterWithoutRecord := Router.Group("authority")
+	authorityApi := v1.ApiGroupApp.SystemApiGroup.AuthorityApi
+	{
+		authorityRouter.POST("createAuthority", authorityApi.CreateAuthority)   // 创建角色
+		authorityRouter.POST("deleteAuthority", authorityApi.DeleteAuthority)   // 删除角色
+		authorityRouter.PUT("updateAuthority", authorityApi.UpdateAuthority)    // 更新角色
+		authorityRouter.POST("copyAuthority", authorityApi.CopyAuthority)       // 拷贝角色
+		authorityRouter.POST("setDataAuthority", authorityApi.SetDataAuthority) // 设置角色资源权限
+	}
+	{
+		authorityRouterWithoutRecord.POST("getAuthorityList", authorityApi.GetAuthorityList) // 获取角色列表
+	}
+}

+ 18 - 0
router/system/sys_base.go

@@ -0,0 +1,18 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+)
+
+type BaseRouter struct{}
+
+func (s *BaseRouter) InitBaseRouter(Router *gin.RouterGroup) (R gin.IRoutes) {
+	baseRouter := Router.Group("base")
+	baseApi := v1.ApiGroupApp.SystemApiGroup
+	{
+		baseRouter.POST("login", baseApi.Login)
+		baseRouter.POST("captcha", baseApi.Captcha)
+	}
+	return baseRouter
+}

+ 21 - 0
router/system/sys_casbin.go

@@ -0,0 +1,21 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type CasbinRouter struct{}
+
+func (s *CasbinRouter) InitCasbinRouter(Router *gin.RouterGroup) {
+	casbinRouter := Router.Group("casbin").Use(middleware.OperationRecord())
+	casbinRouterWithoutRecord := Router.Group("casbin")
+	casbinApi := v1.ApiGroupApp.SystemApiGroup.CasbinApi
+	{
+		casbinRouter.POST("updateCasbin", casbinApi.UpdateCasbin)
+	}
+	{
+		casbinRouterWithoutRecord.POST("getPolicyPathByAuthorityId", casbinApi.GetPolicyPathByAuthorityId)
+	}
+}

+ 24 - 0
router/system/sys_dictionary.go

@@ -0,0 +1,24 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type DictionaryRouter struct{}
+
+func (s *DictionaryRouter) InitSysDictionaryRouter(Router *gin.RouterGroup) {
+	sysDictionaryRouter := Router.Group("sysDictionary").Use(middleware.OperationRecord())
+	sysDictionaryRouterWithoutRecord := Router.Group("sysDictionary")
+	sysDictionaryApi := v1.ApiGroupApp.SystemApiGroup.DictionaryApi
+	{
+		sysDictionaryRouter.POST("createSysDictionary", sysDictionaryApi.CreateSysDictionary)   // 新建SysDictionary
+		sysDictionaryRouter.DELETE("deleteSysDictionary", sysDictionaryApi.DeleteSysDictionary) // 删除SysDictionary
+		sysDictionaryRouter.PUT("updateSysDictionary", sysDictionaryApi.UpdateSysDictionary)    // 更新SysDictionary
+	}
+	{
+		sysDictionaryRouterWithoutRecord.GET("findSysDictionary", sysDictionaryApi.FindSysDictionary)       // 根据ID获取SysDictionary
+		sysDictionaryRouterWithoutRecord.GET("getSysDictionaryList", sysDictionaryApi.GetSysDictionaryList) // 获取SysDictionary列表
+	}
+}

+ 24 - 0
router/system/sys_dictionary_detail.go

@@ -0,0 +1,24 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type DictionaryDetailRouter struct{}
+
+func (s *DictionaryDetailRouter) InitSysDictionaryDetailRouter(Router *gin.RouterGroup) {
+	dictionaryDetailRouter := Router.Group("sysDictionaryDetail").Use(middleware.OperationRecord())
+	dictionaryDetailRouterWithoutRecord := Router.Group("sysDictionaryDetail")
+	sysDictionaryDetailApi := v1.ApiGroupApp.SystemApiGroup.DictionaryDetailApi
+	{
+		dictionaryDetailRouter.POST("createSysDictionaryDetail", sysDictionaryDetailApi.CreateSysDictionaryDetail)   // 新建SysDictionaryDetail
+		dictionaryDetailRouter.DELETE("deleteSysDictionaryDetail", sysDictionaryDetailApi.DeleteSysDictionaryDetail) // 删除SysDictionaryDetail
+		dictionaryDetailRouter.PUT("updateSysDictionaryDetail", sysDictionaryDetailApi.UpdateSysDictionaryDetail)    // 更新SysDictionaryDetail
+	}
+	{
+		dictionaryDetailRouterWithoutRecord.GET("findSysDictionaryDetail", sysDictionaryDetailApi.FindSysDictionaryDetail)       // 根据ID获取SysDictionaryDetail
+		dictionaryDetailRouterWithoutRecord.GET("getSysDictionaryDetailList", sysDictionaryDetailApi.GetSysDictionaryDetailList) // 获取SysDictionaryDetail列表
+	}
+}

+ 16 - 0
router/system/sys_jwt.go

@@ -0,0 +1,16 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+)
+
+type JwtRouter struct{}
+
+func (s *JwtRouter) InitJwtRouter(Router *gin.RouterGroup) {
+	jwtRouter := Router.Group("jwt")
+	jwtApi := v1.ApiGroupApp.SystemApiGroup.JwtApi
+	{
+		jwtRouter.POST("jsonInBlacklist", jwtApi.JsonInBlacklist) // jwt加入黑名单
+	}
+}

+ 29 - 0
router/system/sys_menu.go

@@ -0,0 +1,29 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type MenuRouter struct{}
+
+func (s *MenuRouter) InitMenuRouter(Router *gin.RouterGroup) (R gin.IRoutes) {
+	menuRouter := Router.Group("menu").Use(middleware.OperationRecord())
+	menuRouterWithoutRecord := Router.Group("menu")
+	authorityMenuApi := v1.ApiGroupApp.SystemApiGroup.AuthorityMenuApi
+	{
+		menuRouter.POST("addBaseMenu", authorityMenuApi.AddBaseMenu)           // 新增菜单
+		menuRouter.POST("addMenuAuthority", authorityMenuApi.AddMenuAuthority) //	增加menu和角色关联关系
+		menuRouter.POST("deleteBaseMenu", authorityMenuApi.DeleteBaseMenu)     // 删除菜单
+		menuRouter.POST("updateBaseMenu", authorityMenuApi.UpdateBaseMenu)     // 更新菜单
+	}
+	{
+		menuRouterWithoutRecord.POST("getMenu", authorityMenuApi.GetMenu)                   // 获取菜单树
+		menuRouterWithoutRecord.POST("getMenuList", authorityMenuApi.GetMenuList)           // 分页获取基础menu列表
+		menuRouterWithoutRecord.POST("getBaseMenuTree", authorityMenuApi.GetBaseMenuTree)   // 获取用户动态路由
+		menuRouterWithoutRecord.POST("getMenuAuthority", authorityMenuApi.GetMenuAuthority) // 获取指定角色menu
+		menuRouterWithoutRecord.POST("getBaseMenuById", authorityMenuApi.GetBaseMenuById)   // 根据id获取菜单
+	}
+	return menuRouter
+}

+ 39 - 0
router/system/sys_user.go

@@ -0,0 +1,39 @@
+package system
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "lc-fangdaosha/api/v1"
+	"lc-fangdaosha/middleware"
+)
+
+type UserRouter struct{}
+
+func (s *UserRouter) InitUserRouter(Router, PubRouter *gin.RouterGroup) {
+	userRouter := Router.Group("user").Use(middleware.OperationRecord())
+	userRouterWithoutRecord := Router.Group("user")
+	baseApi := v1.ApiGroupApp.SystemApiGroup.BaseApi
+	{
+		userRouter.POST("admin_register", baseApi.Register)               // 管理员注册账号
+		userRouter.POST("changePassword", baseApi.ChangePassword)         // 用户修改密码
+		userRouter.POST("setUserAuthority", baseApi.SetUserAuthority)     // 设置用户权限
+		userRouter.DELETE("deleteUser", baseApi.DeleteUser)               // 删除用户
+		userRouter.PUT("setUserInfo", baseApi.SetUserInfo)                // 设置用户信息
+		userRouter.PUT("setSelfInfo", baseApi.SetSelfInfo)                // 设置自身信息
+		userRouter.POST("setUserAuthorities", baseApi.SetUserAuthorities) // 设置用户权限组
+		userRouter.POST("resetPassword", baseApi.ResetPassword)           // 设置用户权限组
+		userRouter.POST("addEmails", baseApi.AddEmails)
+		userRouter.POST("unbindEmail", baseApi.UnbindEmail)
+	}
+	{
+		userRouterWithoutRecord.POST("getUserList", baseApi.GetUserList) // 分页获取用户列表
+		userRouterWithoutRecord.GET("getUserInfo", baseApi.GetUserInfo)  // 获取自身信息
+		userRouter.GET("ids", baseApi.UserIdList)
+	}
+
+	//无需认证
+	userPubGroup := PubRouter.Group("user")
+	{
+		userPubGroup.GET("confirm", baseApi.ConfirmEmail)
+		userPubGroup.GET("userUnbindEmail", baseApi.UserUnbindEmail)
+	}
+}

+ 12 - 0
service/enter.go

@@ -0,0 +1,12 @@
+package service
+
+import (
+	"lc-fangdaosha/service/system"
+)
+
+type ServiceGroup struct {
+	SystemServiceGroup system.ServiceGroup
+	//ExampleServiceGroup example.ServiceGroup
+}
+
+var ServiceGroupApp = new(ServiceGroup)

+ 20 - 0
service/system/enter.go

@@ -0,0 +1,20 @@
+package system
+
+type ServiceGroup struct {
+	JwtService
+	ApiService
+	MenuService
+	UserService
+	CasbinService
+	//InitDBService
+	//AutoCodeService
+	BaseMenuService
+	AuthorityService
+	DictionaryService
+	//SystemConfigService
+	//AutoCodeHistoryService
+	OperationRecordService
+	DictionaryDetailService
+	//AuthorityBtnService
+	//ChatGptService
+}

+ 0 - 0
service/system/jwt_black_list.go


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini