diff --git a/server/api/v1/sys_user.go b/server/api/v1/sys_user.go index 1d5d07a853613c34cff8b6bf2fb6316bafd578db..c018af9e371989c8182eafc8d3f17441c909e54b 100644 --- a/server/api/v1/sys_user.go +++ b/server/api/v1/sys_user.go @@ -216,6 +216,11 @@ func DeleteUser(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } + jwtId := getUserID(c) + if jwtId == uint(reqId.Id) { + response.FailWithMessage("删除失败, 自杀失败", c) + return + } if err := service.DeleteUser(reqId.Id); err != nil { global.GVA_LOG.Error("删除失败!", zap.Any("err", err)) response.FailWithMessage("删除失败", c) diff --git a/server/core/server.go b/server/core/server.go index cd77b1ed31eb4fd9460b6cbbe0761f6be1b7fcf3..8ea4d4509d6c89195365c4505c02d97493157669 100644 --- a/server/core/server.go +++ b/server/core/server.go @@ -30,7 +30,7 @@ func RunWindowsServer() { fmt.Printf(` 欢迎使用 Gin-Vue-Admin - 当前版本:V2.3.6 + 当前版本:V2.3.7 默认自动化文档地址:http://127.0.0.1%s/swagger/index.html 默认前端文件运行地址:http://127.0.0.1:8080 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee diff --git a/server/initialize/router.go b/server/initialize/router.go index bd9079638ab8de9ffeec43396584bb8c0206eb07..a995e59b9dcce307f3bd2d259907c6f3b6418893 100644 --- a/server/initialize/router.go +++ b/server/initialize/router.go @@ -24,25 +24,31 @@ func Routers() *gin.Engine { Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) global.GVA_LOG.Info("register swagger handler") // 方便统一添加路由组前缀 多服务器上线使用 - ApiGroup := Router.Group("") - router.InitUserRouter(ApiGroup) // 注册用户路由 - router.InitBaseRouter(ApiGroup) // 注册基础功能路由 不做鉴权 - router.InitMenuRouter(ApiGroup) // 注册menu路由 - router.InitAuthorityRouter(ApiGroup) // 注册角色路由 - router.InitApiRouter(ApiGroup) // 注册功能api路由 - router.InitFileUploadAndDownloadRouter(ApiGroup) // 文件上传下载功能路由 - router.InitSimpleUploaderRouter(ApiGroup) // 断点续传(插件版) - router.InitCasbinRouter(ApiGroup) // 权限相关路由 - router.InitJwtRouter(ApiGroup) // jwt相关路由 - router.InitSystemRouter(ApiGroup) // system相关路由 - router.InitCustomerRouter(ApiGroup) // 客户路由 - router.InitAutoCodeRouter(ApiGroup) // 创建自动化代码 - router.InitSysDictionaryDetailRouter(ApiGroup) // 字典详情管理 - router.InitSysDictionaryRouter(ApiGroup) // 字典管理 - router.InitSysOperationRecordRouter(ApiGroup) // 操作记录 - router.InitEmailRouter(ApiGroup) // 邮件相关路由 - router.InitWorkflowProcessRouter(ApiGroup) // 工作流创建相关接口 - + PublicGroup := Router.Group("") + { + router.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权 + } + PrivateGroup := Router.Group("") + PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + { + router.InitApiRouter(PrivateGroup) // 注册功能api路由 + router.InitJwtRouter(PrivateGroup) // jwt相关路由 + router.InitUserRouter(PrivateGroup) // 注册用户路由 + router.InitMenuRouter(PrivateGroup) // 注册menu路由 + router.InitEmailRouter(PrivateGroup) // 邮件相关路由 + router.InitSystemRouter(PrivateGroup) // system相关路由 + router.InitCasbinRouter(PrivateGroup) // 权限相关路由 + router.InitWorkflowRouter(PrivateGroup) // 工作流相关路由 + router.InitCustomerRouter(PrivateGroup) // 客户路由 + router.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码 + router.InitAuthorityRouter(PrivateGroup) // 注册角色路由 + router.InitSimpleUploaderRouter(PrivateGroup) // 断点续传(插件版) + router.InitSysDictionaryRouter(PrivateGroup) // 字典管理 + router.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 + router.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 + router.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 + router.InitWorkflowProcessRouter(PrivateGroup) // 工作流创建相关接口 + } global.GVA_LOG.Info("router register success") return Router } diff --git a/server/middleware/jwt.go b/server/middleware/jwt.go index 3ceeef61c0b8a221e27ea456c253e678aabf1ae6..5db9a9e256c56d268a2422771a2e200792a400c2 100644 --- a/server/middleware/jwt.go +++ b/server/middleware/jwt.go @@ -42,6 +42,7 @@ func JWTAuth() gin.HandlerFunc { return } if err, _ = service.FindUserByUuid(claims.UUID.String()); err != nil { + _ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: token}) response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c) c.Abort() } diff --git a/server/middleware/operation.go b/server/middleware/operation.go index 41bcb883c958af2c62e176e89f0322f0ab3f68d7..3c4ea2b63d70a091d440b19ad8b29dc1d08a3192 100644 --- a/server/middleware/operation.go +++ b/server/middleware/operation.go @@ -11,7 +11,6 @@ import ( "io/ioutil" "net/http" "strconv" - "strings" "time" ) @@ -31,7 +30,7 @@ func OperationRecord() gin.HandlerFunc { if claims, ok := c.Get("claims"); ok { waitUse := claims.(*request.CustomClaims) userId = int(waitUse.ID) - }else { + } else { id, err := strconv.Atoi(c.Request.Header.Get("x-user-id")) if err != nil { userId = 0 @@ -46,10 +45,11 @@ func OperationRecord() gin.HandlerFunc { Body: string(body), UserID: userId, } - values := c.Request.Header.Values("content-type") - if len(values) >0 && strings.Contains(values[0], "boundary") { - record.Body = "file" - } + // 存在某些未知错误 TODO + //values := c.Request.Header.Values("content-type") + //if len(values) >0 && strings.Contains(values[0], "boundary") { + // record.Body = "file" + //} writer := responseBodyWriter{ ResponseWriter: c.Writer, body: &bytes.Buffer{}, diff --git a/server/router/exa_simple_uploader.go b/server/router/exa_simple_uploader.go index 7197d638836209fd197a7bf8fd24756409037d99..b1dbd379956bbab4a2f48c23e2b8bb288c168f89 100644 --- a/server/router/exa_simple_uploader.go +++ b/server/router/exa_simple_uploader.go @@ -2,14 +2,11 @@ package router import ( "gin-vue-admin/api/v1" - "gin-vue-admin/middleware" "github.com/gin-gonic/gin" ) func InitSimpleUploaderRouter(Router *gin.RouterGroup) { - ApiRouter := Router.Group("simpleUploader"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()) + ApiRouter := Router.Group("simpleUploader") { ApiRouter.POST("upload", v1.SimpleUploaderUpload) // 上传功能 ApiRouter.GET("checkFileMd5", v1.CheckFileMd5) // 文件完整度验证 diff --git a/server/router/exp_customer.go b/server/router/exp_customer.go index d099248c4fb5bcf065525f60df7e3867e827fda1..b0ae657b9b3977e9c8b449a2e4e103f55c55abaa 100644 --- a/server/router/exp_customer.go +++ b/server/router/exp_customer.go @@ -7,10 +7,7 @@ import ( ) func InitCustomerRouter(Router *gin.RouterGroup) { - ApiRouter := Router.Group("customer"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()). - Use(middleware.OperationRecord()) + ApiRouter := Router.Group("customer").Use(middleware.OperationRecord()) { ApiRouter.POST("customer", v1.CreateExaCustomer) // 创建客户 ApiRouter.PUT("customer", v1.UpdateExaCustomer) // 更新客户 diff --git a/server/router/exp_file_upload_and_download.go b/server/router/exp_file_upload_and_download.go index b0ad0328becadeec26410fd23bd7d1cc9e90bdf0..de141d8cd5206cd82e32f3d9e64d14a751d9511d 100644 --- a/server/router/exp_file_upload_and_download.go +++ b/server/router/exp_file_upload_and_download.go @@ -7,7 +7,6 @@ import ( func InitFileUploadAndDownloadRouter(Router *gin.RouterGroup) { FileUploadAndDownloadGroup := Router.Group("fileUploadAndDownload") - // .Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) { FileUploadAndDownloadGroup.POST("/upload", v1.UploadFile) // 上传文件 FileUploadAndDownloadGroup.POST("/getFileList", v1.GetFileList) // 获取上传文件列表 diff --git a/server/router/sys_api.go b/server/router/sys_api.go index b5d29988b73e182081a90c75c46a9092bf16ccbb..8bb7f2d402acd67e9214b85c506881d9a258bccd 100644 --- a/server/router/sys_api.go +++ b/server/router/sys_api.go @@ -7,7 +7,7 @@ import ( ) func InitApiRouter(Router *gin.RouterGroup) { - ApiRouter := Router.Group("api").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + ApiRouter := Router.Group("api").Use(middleware.OperationRecord()) { ApiRouter.POST("createApi", v1.CreateApi) // 创建Api ApiRouter.POST("deleteApi", v1.DeleteApi) // 删除Api diff --git a/server/router/sys_authority.go b/server/router/sys_authority.go index 6ecfca4cb75321c95a4def467fcc91895e20d434..ccbdd3358f51a1df3e5fe11698b026ae79296ba2 100644 --- a/server/router/sys_authority.go +++ b/server/router/sys_authority.go @@ -7,10 +7,7 @@ import ( ) func InitAuthorityRouter(Router *gin.RouterGroup) { - AuthorityRouter := Router.Group("authority"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()). - Use(middleware.OperationRecord()) + AuthorityRouter := Router.Group("authority").Use(middleware.OperationRecord()) { AuthorityRouter.POST("createAuthority", v1.CreateAuthority) // 创建角色 AuthorityRouter.POST("deleteAuthority", v1.DeleteAuthority) // 删除角色 diff --git a/server/router/sys_auto_code.go b/server/router/sys_auto_code.go index 762a1b9d58938bcdd9ba3240fae0e3c5d13f2e2c..77526d739e15fe3c6c3d2c2db67f1cb29df35cab 100644 --- a/server/router/sys_auto_code.go +++ b/server/router/sys_auto_code.go @@ -2,14 +2,11 @@ package router import ( "gin-vue-admin/api/v1" - "gin-vue-admin/middleware" "github.com/gin-gonic/gin" ) func InitAutoCodeRouter(Router *gin.RouterGroup) { - AutoCodeRouter := Router.Group("autoCode"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()) + AutoCodeRouter := Router.Group("autoCode") { AutoCodeRouter.POST("createTemp", v1.CreateTemp) // 创建自动化代码 AutoCodeRouter.GET("getTables", v1.GetTables) // 获取对应数据库的表 diff --git a/server/router/sys_casbin.go b/server/router/sys_casbin.go index c0f5d2e3a554ec472ab6c385395ba24b30d40dc0..6896af8ac74b63c4884c43b7881a828f71a39852 100644 --- a/server/router/sys_casbin.go +++ b/server/router/sys_casbin.go @@ -7,10 +7,7 @@ import ( ) func InitCasbinRouter(Router *gin.RouterGroup) { - CasbinRouter := Router.Group("casbin"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()). - Use(middleware.OperationRecord()) + CasbinRouter := Router.Group("casbin").Use(middleware.OperationRecord()) { CasbinRouter.POST("updateCasbin", v1.UpdateCasbin) CasbinRouter.POST("getPolicyPathByAuthorityId", v1.GetPolicyPathByAuthorityId) diff --git a/server/router/sys_dictionary.go b/server/router/sys_dictionary.go index 459947598ac91e0a427246ad6f07462b65b50d93..c9007642c2b02dd14e1e69c8e9fd38b56ea411c3 100644 --- a/server/router/sys_dictionary.go +++ b/server/router/sys_dictionary.go @@ -7,10 +7,7 @@ import ( ) func InitSysDictionaryRouter(Router *gin.RouterGroup) { - SysDictionaryRouter := Router.Group("sysDictionary"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()). - Use(middleware.OperationRecord()) + SysDictionaryRouter := Router.Group("sysDictionary").Use(middleware.OperationRecord()) { SysDictionaryRouter.POST("createSysDictionary", v1.CreateSysDictionary) // 新建SysDictionary SysDictionaryRouter.DELETE("deleteSysDictionary", v1.DeleteSysDictionary) // 删除SysDictionary diff --git a/server/router/sys_dictionary_detail.go b/server/router/sys_dictionary_detail.go index 1f17fd3bc8335e3ff2e7bffb45faea50870811ab..b324b32202e8da4756d6b5ebf97e60b4259b0e7d 100644 --- a/server/router/sys_dictionary_detail.go +++ b/server/router/sys_dictionary_detail.go @@ -7,10 +7,7 @@ import ( ) func InitSysDictionaryDetailRouter(Router *gin.RouterGroup) { - SysDictionaryDetailRouter := Router.Group("sysDictionaryDetail"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()). - Use(middleware.OperationRecord()) + SysDictionaryDetailRouter := Router.Group("sysDictionaryDetail").Use(middleware.OperationRecord()) { SysDictionaryDetailRouter.POST("createSysDictionaryDetail", v1.CreateSysDictionaryDetail) // 新建SysDictionaryDetail SysDictionaryDetailRouter.DELETE("deleteSysDictionaryDetail", v1.DeleteSysDictionaryDetail) // 删除SysDictionaryDetail diff --git a/server/router/sys_email.go b/server/router/sys_email.go index 6d201cf05261e75bcfb082abc3289c9ca1374d2e..5f215dd738de2983906b9f037fbe83a0cc7f38fe 100644 --- a/server/router/sys_email.go +++ b/server/router/sys_email.go @@ -7,7 +7,7 @@ import ( ) func InitEmailRouter(Router *gin.RouterGroup) { - UserRouter := Router.Group("email").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + UserRouter := Router.Group("email").Use(middleware.OperationRecord()) { UserRouter.POST("emailTest", v1.EmailTest) // 发送测试邮件 } diff --git a/server/router/sys_jwt.go b/server/router/sys_jwt.go index 0241fc3c1a609a9b35b3774f979a6da640ccf12c..f2a33caff25283e38815d1ebac544a43543b3cdd 100644 --- a/server/router/sys_jwt.go +++ b/server/router/sys_jwt.go @@ -7,7 +7,7 @@ import ( ) func InitJwtRouter(Router *gin.RouterGroup) { - ApiRouter := Router.Group("jwt").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + ApiRouter := Router.Group("jwt").Use(middleware.OperationRecord()) { ApiRouter.POST("jsonInBlacklist", v1.JsonInBlacklist) // jwt加入黑名单 } diff --git a/server/router/sys_menu.go b/server/router/sys_menu.go index 48609046b6050c3b8745b51c2270c402de7596da..3fdc177363691891e531bad4efbe8a4abf2fa2ca 100644 --- a/server/router/sys_menu.go +++ b/server/router/sys_menu.go @@ -7,7 +7,7 @@ import ( ) func InitMenuRouter(Router *gin.RouterGroup) (R gin.IRoutes) { - MenuRouter := Router.Group("menu").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) + MenuRouter := Router.Group("menu").Use(middleware.OperationRecord()) { MenuRouter.POST("getMenu", v1.GetMenu) // 获取菜单树 MenuRouter.POST("getMenuList", v1.GetMenuList) // 分页获取基础menu列表 diff --git a/server/router/sys_operation_record.go b/server/router/sys_operation_record.go index 59ffff5903457ae0d97b0a5c1572406d35285310..972ecbb19996267a4324beb579cb2eae4451729f 100644 --- a/server/router/sys_operation_record.go +++ b/server/router/sys_operation_record.go @@ -7,15 +7,13 @@ import ( ) func InitSysOperationRecordRouter(Router *gin.RouterGroup) { - SysOperationRecordRouter := Router.Group("sysOperationRecord"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()) + SysOperationRecordRouter := Router.Group("sysOperationRecord").Use(middleware.OperationRecord()) { - SysOperationRecordRouter.POST("createSysOperationRecord", v1.CreateSysOperationRecord) // 新建SysOperationRecord - SysOperationRecordRouter.DELETE("deleteSysOperationRecord", v1.DeleteSysOperationRecord) // 删除SysOperationRecord + SysOperationRecordRouter.POST("createSysOperationRecord", v1.CreateSysOperationRecord) // 新建SysOperationRecord + SysOperationRecordRouter.DELETE("deleteSysOperationRecord", v1.DeleteSysOperationRecord) // 删除SysOperationRecord SysOperationRecordRouter.DELETE("deleteSysOperationRecordByIds", v1.DeleteSysOperationRecordByIds) // 批量删除SysOperationRecord - SysOperationRecordRouter.GET("findSysOperationRecord", v1.FindSysOperationRecord) // 根据ID获取SysOperationRecord - SysOperationRecordRouter.GET("getSysOperationRecordList", v1.GetSysOperationRecordList) // 获取SysOperationRecord列表 + SysOperationRecordRouter.GET("findSysOperationRecord", v1.FindSysOperationRecord) // 根据ID获取SysOperationRecord + SysOperationRecordRouter.GET("getSysOperationRecordList", v1.GetSysOperationRecordList) // 获取SysOperationRecord列表 } } diff --git a/server/router/sys_system.go b/server/router/sys_system.go index 2c80e90a843a46ccb895b05d358138f60326134e..d6c2e5a42c15090ef5cc0db2c6035b3a7fa42312 100644 --- a/server/router/sys_system.go +++ b/server/router/sys_system.go @@ -7,7 +7,7 @@ import ( ) func InitSystemRouter(Router *gin.RouterGroup) { - SystemRouter := Router.Group("system").Use(middleware.JWTAuth(), middleware.CasbinHandler()) + SystemRouter := Router.Group("system").Use(middleware.OperationRecord()) { SystemRouter.POST("getSystemConfig", v1.GetSystemConfig) // 获取配置文件内容 SystemRouter.POST("setSystemConfig", v1.SetSystemConfig) // 设置配置文件内容 diff --git a/server/router/sys_user.go b/server/router/sys_user.go index 12d49a30fa60fc5c207b05721f1acc4ab0a62681..d6d22a8ab3de50943f1155c07c47fa573b19c7d9 100644 --- a/server/router/sys_user.go +++ b/server/router/sys_user.go @@ -7,10 +7,7 @@ import ( ) func InitUserRouter(Router *gin.RouterGroup) { - UserRouter := Router.Group("user"). - Use(middleware.JWTAuth()). - Use(middleware.CasbinHandler()). - Use(middleware.OperationRecord()) + UserRouter := Router.Group("user").Use(middleware.OperationRecord()) { UserRouter.POST("register", v1.Register) UserRouter.POST("changePassword", v1.ChangePassword) // 修改密码 diff --git a/server/router/sys_workflow.go b/server/router/sys_workflow.go new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/server/service/sys_auto_code.go b/server/service/sys_auto_code.go index afeca1ebf6c4d9f333f02b1ef79b476f094eb247..d6fdf0b3e92e012028742a56594f12f3bf820cb5 100644 --- a/server/service/sys_auto_code.go +++ b/server/service/sys_auto_code.go @@ -209,7 +209,6 @@ func addAutoMoveFile(data *tplData) { } } - //@author: [piexlmax](https://github.com/piexlmax) //@author: [SliverHorn](https://github.com/SliverHorn) //@function: CreateApi @@ -259,14 +258,13 @@ func AutoCreateApi(a *model.AutoCodeStruct) (err error) { err = global.GVA_DB.Transaction(func(tx *gorm.DB) error { for _, v := range apiList { var api model.SysApi - if err := tx.Where("path = ? AND method = ?", v.Path, v.Method).First(&api).Error; err != nil { - return err - } - if err := tx.Create(&v).Error; err != nil { // 遇到错误时回滚事务 - return err + if errors.Is(tx.Where("path = ? AND method = ?", v.Path, v.Method).First(&api).Error, gorm.ErrRecordNotFound) { + if err := tx.Create(&v).Error; err != nil { // 遇到错误时回滚事务 + return err + } } } return nil }) return err -} \ No newline at end of file +} diff --git a/server/utils/breakpoint_continue.go b/server/utils/breakpoint_continue.go index 05fb99cbf5406f7e29b1a5f4fa45dee3ef8913ac..7dbe7eb603ecf7854a196db7bbb6273fa0eda52c 100644 --- a/server/utils/breakpoint_continue.go +++ b/server/utils/breakpoint_continue.go @@ -14,6 +14,12 @@ import ( const breakpointDir = "./breakpointDir/" const finishDir = "./fileDir/" +//@author: [piexlmax](https://github.com/piexlmax) +//@function: BreakPointContinue +//@description: 断点续传 +//@param: content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string +//@return: error, string + func BreakPointContinue(content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string) (error, string) { path := breakpointDir + fileMd5 + "/" err := os.MkdirAll(path, os.ModePerm) @@ -25,6 +31,12 @@ func BreakPointContinue(content []byte, fileName string, contentNumber int, cont } +//@author: [piexlmax](https://github.com/piexlmax) +//@function: CheckMd5 +//@description: 检查Md5 +//@param: content []byte, chunkMd5 string +//@return: CanUpload bool + func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) { fileMd5 := MD5V(content) if fileMd5 == chunkMd5 { @@ -34,6 +46,12 @@ func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) { } } +//@author: [piexlmax](https://github.com/piexlmax) +//@function: makeFileContent +//@description: 创建切片内容 +//@param: content []byte, fileName string, FileDir string, contentNumber int +//@return: error, string + func makeFileContent(content []byte, fileName string, FileDir string, contentNumber int) (error, string) { path := FileDir + fileName + "_" + strconv.Itoa(contentNumber) f, err := os.Create(path) @@ -49,6 +67,12 @@ func makeFileContent(content []byte, fileName string, FileDir string, contentNum return nil, path } +//@author: [piexlmax](https://github.com/piexlmax) +//@function: makeFileContent +//@description: 创建切片文件 +//@param: fileName string, FileMd5 string +//@return: error, string + func MakeFile(fileName string, FileMd5 string) (error, string) { rd, err := ioutil.ReadDir(breakpointDir + FileMd5) if err != nil { @@ -68,6 +92,12 @@ func MakeFile(fileName string, FileMd5 string) (error, string) { return nil, finishDir + fileName } +//@author: [piexlmax](https://github.com/piexlmax) +//@function: RemoveChunk +//@description: 移除切片 +//@param: FileMd5 string +//@return: error + func RemoveChunk(FileMd5 string) error { err := os.RemoveAll(breakpointDir + FileMd5) return err diff --git a/server/utils/cmd_Task.go b/server/utils/cmd_Task.go index b32fef23643dab8d0194ac35f160e398a809cd4e..06454da0fff11c0e18383135e99e4ca91552fefa 100644 --- a/server/utils/cmd_Task.go +++ b/server/utils/cmd_Task.go @@ -2,25 +2,32 @@ package utils import ( "bytes" + "context" "fmt" "io" "os" "os/exec" - "path/filepath" "runtime" "sync" ) +//@author: [songzhibin97](https://github.com/songzhibin97) +//@interface_name: RunTask +//@description: Task接口 + type RunTask interface { AddTask() RunTask() } -// T: Task任务 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@struct_name: T +//@description: Task任务 + type T struct { sync.Mutex - // ch: 获取事件channel + // 获取事件channel ch chan struct{} closeChan chan struct{} @@ -28,14 +35,25 @@ type T struct { // 记录process对象 p *os.Process - // f: 执行任务 + // 执行任务 f func(chan struct{}) error } -// NewT: 实例化方法 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@function: NewT +//@description: T的实例化方法 +//@return: *T + func NewT() *T { return newT(nil) } + +//@author: [songzhibin97](https://github.com/songzhibin97) +//@function: newT +//@description: +//@param: f func(chan struct{}) error +//@return: *T + func newT(f func(chan struct{}) error) *T { t := &T{ Mutex: sync.Mutex{}, @@ -49,6 +67,11 @@ func newT(f func(chan struct{}) error) *T { return t } +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: *T +//@function: AddTask +//@description: 添加任务 + func (t *T) AddTask() { if len(t.ch) == 1 { return @@ -60,10 +83,14 @@ func (t *T) AddTask() { // 直接丢弃这次任务 return } - fmt.Println("::::发送任务->>>>>>>>") t.ch <- struct{}{} } +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: *T +//@function: RunTask +//@description: 启动任务 + func (t *T) RunTask() { fmt.Println("进入") // 这里做的make 是用于关闭上一个执行的任务 @@ -72,10 +99,10 @@ func (t *T) RunTask() { go t.f(ch) for { _, ok := <-t.ch - ch <- struct{}{} if !ok { return } + ch <- struct{}{} // 等待上一个关闭 <-t.closeChan go t.f(ch) @@ -83,23 +110,19 @@ func (t *T) RunTask() { } -// DefaultF: 默认的StartFunction -func (t *T) DefaultF(ch chan struct{}) error { +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: t *T +//@function: DefaultF +//@description: 默认的StartFunction +//@param: ch chan struct{} +//@return: error +func (t *T) DefaultF(ch chan struct{}) error { var buildCmd *exec.Cmd var cmd *exec.Cmd - // 判断是否有makefile - _, err := os.Stat(filepath.Join("Makefile")) - if runtime.GOOS != "windows" && err == nil { - _, err := exec.LookPath("make") - if err == nil { - cmd = exec.Command("make", "run") - goto makefile - } - } // 检测系统是否有编译环境 - _, err = exec.LookPath("go") + _, err := exec.LookPath("go") if err != nil { return err } @@ -107,58 +130,75 @@ func (t *T) DefaultF(ch chan struct{}) error { switch runtime.GOOS { case "windows": - buildCmd = exec.Command("go", "build", "-o", "gva.exe", "main.go") + buildCmd = exec.Command("go", "build", "-o", "server.exe", "main.go") default: - buildCmd = exec.Command("go", "build", "-o", "gva", "main.go") + buildCmd = exec.Command("go", "build", "-o", "server", "main.go") } + //cmd = exec.Command("go", "run", "main.go") err = buildCmd.Run() if err != nil { return err } fmt.Println("build 执行完成") - // 执行 - switch runtime.GOOS { case "windows": - cmd = exec.Command("gva.exe") + cmd = exec.Command("server.exe") default: - cmd = exec.Command("./gva") + cmd = exec.Command("./server") } -makefile: + // 开始执行任务 - t.echo(cmd) + ctx, cancel := context.WithCancel(context.Background()) + err = t.echo(cmd, ctx) <-ch // 回收资源 - err = cmd.Process.Kill() - fmt.Println("kill err", err) + fmt.Println("pid:", t.p.Pid, "->Kill") + err = t.p.Kill() + cancel() // 发送关闭完成信号 t.closeChan <- struct{}{} return err } -// echo: 封装回显 -func (t *T) echo(cmd *exec.Cmd) error { +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: t *T +//@function: echo +//@description: 封装回显 +//@param: cmd *exec.Cmd, ctx context.Context +//@return: error + +func (t *T) echo(cmd *exec.Cmd, ctx context.Context) error { var stdoutBuf bytes.Buffer stdoutIn, _ := cmd.StdoutPipe() - var errStdout, errStderr error + var errStdout error stdout := io.MultiWriter(os.Stdout, &stdoutBuf) err := cmd.Start() if err != nil { return err } - go func() { + go func(ctx context.Context) { _, errStdout = io.Copy(stdout, stdoutIn) - }() + select { + case <-ctx.Done(): + return + default: + } + }(ctx) t.p = cmd.Process fmt.Println("pid", t.p.Pid) go func() { _ = cmd.Wait() - if errStdout != nil || errStderr != nil { + if errStdout != nil { fmt.Printf("failed to capture stdout or stderr\n") } - outStr := string(stdoutBuf.Bytes()) - fmt.Printf("\nout:\n%s\n", outStr) + fmt.Printf("%s\n", string(stdoutBuf.Bytes())) + select { + case <-ctx.Done(): + //_ = os.Stdout.Close() + return + default: + } }() return nil } diff --git a/server/utils/cmd_monitor.go b/server/utils/cmd_monitor.go index d95e35b7e2ce6a122f4ab759aace8f956250f28e..5f7fa59d39f93669a3eadd70887575e35595055b 100644 --- a/server/utils/cmd_monitor.go +++ b/server/utils/cmd_monitor.go @@ -9,17 +9,31 @@ import ( "path/filepath" ) -// Watch: 监控对象 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@struct_name: Watch +//@description: 监控对象 + type Watch struct { *fsnotify.Watcher } +//@author: [songzhibin97](https://github.com/songzhibin97) +//@function: NewWatch +//@description: Watch的实例化方法 +//@return: *Watch + func NewWatch() *Watch { obj, _ := fsnotify.NewWatcher() return &Watch{obj} } -// Watch: 监控对象 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: w *Watch +//@function: Watch +//@description: 监控对象 +//@param: path string, t *T +//@return: error + func (w *Watch) Watch(path string, t *T) error { // 先转化为绝对路径 path, err := filepath.Abs(path) @@ -81,7 +95,13 @@ func (w *Watch) Watch(path string, t *T) error { } -// watchDir: 处理监控目录 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: w *Watch +//@function: watchDir +//@description: 处理监控目录 +//@param: path string +//@return: error + func (w *Watch) watchDir(path string) error { // 先将自己添加到监控 err := w.Add(path) @@ -113,7 +133,13 @@ func (w *Watch) watchDir(path string) error { return err } -// watchDir: 处理监控单文件 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: w *Watch +//@function: watchDir +//@description: 处理监控单文件 +//@param: path string +//@return: error + func (w *Watch) watchFile(path string) error { var err error if chickPower(path) { @@ -122,14 +148,24 @@ func (w *Watch) watchFile(path string) error { return err } -// chickPower: 判断是否在可控范围内 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@function: chickPower +//@description: 判断是否在可控范围内 +//@param: path string +//@return: error + func chickPower(name string) bool { name = filepath.Ext(name) - fmt.Println(name) return name == ".go" || name == ".yaml" } -// addTask: 偏函数 简化发送任务 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@object: w *Watch +//@function: addTask +//@description: 偏函数 简化发送任务 +//@param: path string +//@return: error + func (w *Watch) addTask(t *T, name string) { if chickPower(name) { fmt.Println("Add Task->>>>>>") diff --git a/server/utils/directory.go b/server/utils/directory.go index caf51e04097c4b261a4aa899dffc3515202c438f..216bfd2a908aa004a8bb1189c3bb3ebfbca55458 100644 --- a/server/utils/directory.go +++ b/server/utils/directory.go @@ -6,11 +6,11 @@ import ( "os" ) -// @title PathExists -// @description 文件目录是否存在 -// @auth (2020/04/05 20:22) -// @param path string -// @return err error +//@author: [piexlmax](https://github.com/piexlmax) +//@function: PathExists +//@description: 文件目录是否存在 +//@param: path string +//@return: bool, error func PathExists(path string) (bool, error) { _, err := os.Stat(path) @@ -23,11 +23,11 @@ func PathExists(path string) (bool, error) { return false, err } -// @title createDir -// @description 批量创建文件夹 -// @auth (2020/04/05 20:22) -// @param dirs string -// @return err error +//@author: [piexlmax](https://github.com/piexlmax) +//@function: CreateDir +//@description: 批量创建文件夹 +//@param: dirs ...string +//@return: err error func CreateDir(dirs ...string) (err error) { for _, v := range dirs { diff --git a/server/utils/email.go b/server/utils/email.go index 309dfdbe015909d900da4a35bc5dcd1b0b5c5bd5..19642274921adc78eaf2f48e76b6d8f67d05d665 100644 --- a/server/utils/email.go +++ b/server/utils/email.go @@ -11,12 +11,23 @@ import ( "github.com/jordan-wright/email" ) +//@author: [maplepie](https://github.com/maplepie) +//@function: Email +//@description: Email发送方法 +//@param: subject string, body string +//@return: error + func Email(subject string, body string) error { to := strings.Split(global.GVA_CONFIG.Email.To, ",") return send(to, subject, body) } -// ErrorToEmail Error 发送邮件 +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: ErrorToEmail +//@description: 给email中间件错误发送邮件到指定邮箱 +//@param: subject string, body string +//@return: error + func ErrorToEmail(subject string, body string) error { to := strings.Split(global.GVA_CONFIG.Email.To, ",") if to[len(to)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除 @@ -25,11 +36,23 @@ func ErrorToEmail(subject string, body string) error { return send(to, subject, body) } +//@author: [maplepie](https://github.com/maplepie) +//@function: EmailTest +//@description: Email测试方法 +//@param: subject string, body string +//@return: error + func EmailTest(subject string, body string) error { to := []string{global.GVA_CONFIG.Email.From} return send(to, subject, body) } +//@author: [maplepie](https://github.com/maplepie) +//@function: send +//@description: Email发送方法 +//@param: subject string, body string +//@return: error + func send(to []string, subject string, body string) error { from := global.GVA_CONFIG.Email.From nickname := global.GVA_CONFIG.Email.Nickname diff --git a/server/utils/file_operations.go b/server/utils/file_operations.go index 39f71d59dac569bdd895c8eb78031dfb1e6a97e4..04b0413758597200176f1be5ec5d6fc18657f718 100644 --- a/server/utils/file_operations.go +++ b/server/utils/file_operations.go @@ -5,9 +5,12 @@ import ( "path/filepath" ) -// FileMove: 文件移动供外部调用 -// src: 源位置 绝对路径相对路径都可以 -// dst: 目标位置 绝对路径相对路径都可以 dst 必须为文件夹 +//@author: [songzhibin97](https://github.com/songzhibin97) +//@function: FileMove +//@description: 文件移动供外部调用 +//@param: src string, dst string(src: 源位置,绝对路径or相对路径, dst: 目标位置,绝对路径or相对路径,必须为文件夹) +//@return: err error + func FileMove(src string, dst string) (err error) { if dst == "" { return nil diff --git a/server/utils/fmt_plus.go b/server/utils/fmt_plus.go index 9fca8882315d56b000608eba8d415fffd5e97019..b31c3f0eb7224320b88230e20e185539d9492575 100644 --- a/server/utils/fmt_plus.go +++ b/server/utils/fmt_plus.go @@ -6,7 +6,12 @@ import ( "strings" ) -// 利用反射将结构体转化为map +//@author: [piexlmax](https://github.com/piexlmax) +//@function: StructToMap +//@description: 利用反射将结构体转化为map +//@param: obj interface{} +//@return: map[string]interface{} + func StructToMap(obj interface{}) map[string]interface{} { obj1 := reflect.TypeOf(obj) obj2 := reflect.ValueOf(obj) @@ -18,7 +23,12 @@ func StructToMap(obj interface{}) map[string]interface{} { return data } -//将数组格式化为字符串 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: ArrayToString +//@description: 将数组格式化为字符串 +//@param: array []interface{} +//@return: string + func ArrayToString(array []interface{}) string { return strings.Replace(strings.Trim(fmt.Sprint(array), "[]"), " ", ",", -1) } diff --git a/server/utils/md5.go b/server/utils/md5.go index a81eb2c5099d71d48983af1a7288b4a9c8d40cd7..59ac0e142247b93127c691e5882208fd3082f7d1 100644 --- a/server/utils/md5.go +++ b/server/utils/md5.go @@ -5,6 +5,12 @@ import ( "encoding/hex" ) +//@author: [piexlmax](https://github.com/piexlmax) +//@function: MD5V +//@description: md5加密 +//@param: str []byte +//@return: string + func MD5V(str []byte) string { h := md5.New() h.Write(str) diff --git a/server/utils/rotatelogs_unix.go b/server/utils/rotatelogs_unix.go index f2759d8fe5a239d30533e9beb9309c890b8a651a..30a57750a39faf8f07c6d7eb6faa34c99617d40d 100644 --- a/server/utils/rotatelogs_unix.go +++ b/server/utils/rotatelogs_unix.go @@ -11,7 +11,11 @@ import ( "time" ) -// GetWriteSyncer zap logger中加入file-rotatelogs +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: GetWriteSyncer +//@description: zap logger中加入file-rotatelogs +//@return: zapcore.WriteSyncer, error + func GetWriteSyncer() (zapcore.WriteSyncer, error) { fileWriter, err := zaprotatelogs.New( path.Join(global.GVA_CONFIG.Zap.Director, "%Y-%m-%d.log"), diff --git a/server/utils/rotatelogs_windows.go b/server/utils/rotatelogs_windows.go index 6c7a3742fae08a2123152090eec56f1252bf4f3d..0639ba667f44cc08059e353267d0ff4407ed6835 100644 --- a/server/utils/rotatelogs_windows.go +++ b/server/utils/rotatelogs_windows.go @@ -9,7 +9,11 @@ import ( "time" ) -// GetWriteSyncer zap logger中加入file-rotatelogs +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: GetWriteSyncer +//@description: zap logger中加入file-rotatelogs +//@return: zapcore.WriteSyncer, error + func GetWriteSyncer() (zapcore.WriteSyncer, error) { fileWriter, err := zaprotatelogs.New( path.Join(global.GVA_CONFIG.Zap.Director, "%Y-%m-%d.log"), diff --git a/server/utils/server.go b/server/utils/server.go index 1ea79ee62ab6c76a6ec30f7516622eebe86a6622..3558cf5eac32a4b78f14aae4eb9209979a18168c 100644 --- a/server/utils/server.go +++ b/server/utils/server.go @@ -50,7 +50,11 @@ type Disk struct { UsedPercent int `json:"usedPercent"` } -// InitOS OS信息 +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: InitCPU +//@description: OS信息 +//@return: o Os, err error + func InitOS() (o Os) { o.GOOS = runtime.GOOS o.NumCPU = runtime.NumCPU() @@ -60,7 +64,11 @@ func InitOS() (o Os) { return o } -// InitCPU CPU信息 +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: InitCPU +//@description: CPU信息 +//@return: c Cpu, err error + func InitCPU() (c Cpu, err error) { if cores, err := cpu.Counts(false); err != nil { return c, err @@ -75,7 +83,11 @@ func InitCPU() (c Cpu, err error) { return c, nil } -// InitRAM ARM信息 +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: InitRAM +//@description: ARM信息 +//@return: r Rrm, err error + func InitRAM() (r Rrm, err error) { if u, err := mem.VirtualMemory(); err != nil{ return r, err @@ -87,7 +99,11 @@ func InitRAM() (r Rrm, err error) { return r, nil } -// InitDisk 硬盘信息 +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: InitDisk +//@description: 硬盘信息 +//@return: d Disk, err error + func InitDisk() (d Disk, err error) { if u, err := disk.Usage("/"); err != nil{ return d, err diff --git a/server/utils/upload/local.go b/server/utils/upload/local.go index d60ff928af3053604d67f5cc91c2b8aa90e618b2..a081fa26304283005b0f382272d52c2c4aa662e5 100644 --- a/server/utils/upload/local.go +++ b/server/utils/upload/local.go @@ -14,8 +14,16 @@ import ( type Local struct{} -// UploadFile 上传文件 -func (l Local) UploadFile(file *multipart.FileHeader) (string, string, error) { +//@author: [piexlmax](https://github.com/piexlmax) +//@author: [ccfish86](https://github.com/ccfish86) +//@author: [SliverHorn](https://github.com/SliverHorn) +//@object: *Local +//@function: UploadFile +//@description: 上传文件 +//@param: file *multipart.FileHeader +//@return: string, string, error + +func (*Local) UploadFile(file *multipart.FileHeader) (string, string, error) { // 读取文件后缀 ext := path.Ext(file.Filename) // 读取文件名并加密 @@ -55,8 +63,16 @@ func (l Local) UploadFile(file *multipart.FileHeader) (string, string, error) { return p, filename, nil } -// DeleteFile 删除文件 -func (l Local) DeleteFile(key string) error { +//@author: [piexlmax](https://github.com/piexlmax) +//@author: [ccfish86](https://github.com/ccfish86) +//@author: [SliverHorn](https://github.com/SliverHorn) +//@object: *Local +//@function: DeleteFile +//@description: 删除文件 +//@param: key string +//@return: error + +func (*Local) DeleteFile(key string) error { p := global.GVA_CONFIG.Local.Path + "/" + key if strings.Contains(p, global.GVA_CONFIG.Local.Path) { if err := os.Remove(p); err != nil { diff --git a/server/utils/upload/qiniu.go b/server/utils/upload/qiniu.go index 4658dfef2a23b9110e448c4fc35c7329cce36dea..0bb0c5e1511199fa83bb9e4036479581b8df2f38 100644 --- a/server/utils/upload/qiniu.go +++ b/server/utils/upload/qiniu.go @@ -14,7 +14,15 @@ import ( type Qiniu struct{} -// Upload 上传文件 +//@author: [piexlmax](https://github.com/piexlmax) +//@author: [ccfish86](https://github.com/ccfish86) +//@author: [SliverHorn](https://github.com/SliverHorn) +//@object: *Qiniu +//@function: UploadFile +//@description: 上传文件 +//@param: file *multipart.FileHeader +//@return: string, string, error + func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) { putPolicy := storage.PutPolicy{Scope: global.GVA_CONFIG.Qiniu.Bucket} mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey) @@ -39,7 +47,15 @@ func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) { return global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key, nil } -// DeleteFile 删除文件 +//@author: [piexlmax](https://github.com/piexlmax) +//@author: [ccfish86](https://github.com/ccfish86) +//@author: [SliverHorn](https://github.com/SliverHorn) +//@object: *Qiniu +//@function: DeleteFile +//@description: 删除文件 +//@param: key string +//@return: error + func (*Qiniu) DeleteFile(key string) error { mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey) cfg := qiniuConfig() @@ -51,7 +67,13 @@ func (*Qiniu) DeleteFile(key string) error { return nil } -// config 根据配置文件进行返回七牛云的配置 +//@author: [SliverHorn](https://github.com/SliverHorn) +//@object: *Qiniu +//@function: qiniuConfig +//@description: 根据配置文件进行返回七牛云的配置 +//@param: key string +//@return: error + func qiniuConfig() *storage.Config { cfg := storage.Config{ UseHTTPS: global.GVA_CONFIG.Qiniu.UseHTTPS, diff --git a/server/utils/upload/upload.go b/server/utils/upload/upload.go index 4bf25f07e14cdc492c5cd5ee4cf117620450f14a..79a8a9599cb7c13932c3e09a96d2af305222771a 100644 --- a/server/utils/upload/upload.go +++ b/server/utils/upload/upload.go @@ -5,13 +5,23 @@ import ( "mime/multipart" ) -var Oss OSS +//@author: [ccfish86](https://github.com/ccfish86) +//@author: [SliverHorn](https://github.com/SliverHorn) +//@interface_name: OSS +//@description: OSS接口 type OSS interface { UploadFile(file *multipart.FileHeader) (string, string, error) DeleteFile(key string) error } +//@author: [ccfish86](https://github.com/ccfish86) +//@author: [SliverHorn](https://github.com/SliverHorn) +//@function: NewOss +//@description: OSS接口 +//@description: OSS的实例化方法 +//@return: OSS + func NewOss() OSS { switch global.GVA_CONFIG.System.OssType { case "local": diff --git a/server/utils/upload_file_local.go b/server/utils/upload_file_local.go deleted file mode 100644 index be7f9ece0ac6f812ec3ffd3b9bdfb7a596aaa3c7..0000000000000000000000000000000000000000 --- a/server/utils/upload_file_local.go +++ /dev/null @@ -1,54 +0,0 @@ -package utils - -import ( - "gin-vue-admin/global" - "go.uber.org/zap" - "io" - "mime/multipart" - "os" - "path" - "strings" - "time" -) - -func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, key string) { - // 读取文件后缀 - ext := path.Ext(file.Filename) - // 读取文件名并加密 - fileName := strings.TrimSuffix(file.Filename, ext) - fileName = MD5V([]byte(fileName)) - // 拼接新文件名 - lastName := fileName + "_" + time.Now().Format("20060102150405") + ext - // 读取全局变量的定义路径 - savePath := global.GVA_CONFIG.Local.Path - // 尝试创建此路径 - err = os.MkdirAll(savePath, os.ModePerm) - if err != nil { - global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err)) - return err, "", "" - } - // 拼接路径和文件名 - dst := savePath + "/" + lastName - // 下面为上传逻辑 - // 打开文件 defer 关闭 - src, err := file.Open() - if err != nil { - global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err)) - return err, "", "" - } - defer src.Close() - // 创建文件 defer 关闭 - out, err := os.Create(dst) - if err != nil { - global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err)) - return err, "", "" - } - defer out.Close() - // 传输(拷贝)文件 - _, err = io.Copy(out, src) - if err != nil { - global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err)) - return err, "", "" - } - return nil, dst, lastName -} diff --git a/server/utils/upload_remote.go b/server/utils/upload_remote.go deleted file mode 100644 index 681b81c974459177d0404be9ef77ce707bb8ef23..0000000000000000000000000000000000000000 --- a/server/utils/upload_remote.go +++ /dev/null @@ -1,67 +0,0 @@ -package utils - -import ( - "context" - "fmt" - "gin-vue-admin/global" - "github.com/qiniu/api.v7/v7/auth/qbox" - "github.com/qiniu/api.v7/v7/storage" - "go.uber.org/zap" - "mime/multipart" - "time" -) - -// 接收两个参数 一个文件流 一个 bucket 你的七牛云标准空间的名字 -func UploadRemote(file *multipart.FileHeader) (err error, path string, key string) { - putPolicy := storage.PutPolicy{ - Scope: global.GVA_CONFIG.Qiniu.Bucket, - } - mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey) - upToken := putPolicy.UploadToken(mac) - cfg := storage.Config{} - // 空间对应的机房 - cfg.Zone = &storage.ZoneHuadong - // 是否使用https域名 - cfg.UseHTTPS = false - // 上传是否使用CDN上传加速 - cfg.UseCdnDomains = false - formUploader := storage.NewFormUploader(&cfg) - ret := storage.PutRet{} - putExtra := storage.PutExtra{ - Params: map[string]string{ - "x:name": "github logo", - }, - } - f, e := file.Open() - if e != nil { - fmt.Println(e) - return e, "", "" - } - dataLen := file.Size - fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename) // 文件名格式 自己可以改 建议保证唯一性 - err = formUploader.Put(context.Background(), &ret, upToken, fileKey, f, dataLen, &putExtra) - if err != nil { - global.GVA_LOG.Error("upload file fail:", zap.Any("err", err)) - return err, "", "" - } - return err, global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key -} - -func DeleteFile(key string) error { - - mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey) - cfg := storage.Config{ - // 是否使用https域名进行资源管理 - UseHTTPS: false, - } - // 指定空间所在的区域,如果不指定将自动探测 - // 如果没有特殊需求,默认不需要指定 - // cfg.Zone=&storage.ZoneHuabei - bucketManager := storage.NewBucketManager(mac, &cfg) - err := bucketManager.Delete(global.GVA_CONFIG.Qiniu.Bucket, key) - if err != nil { - fmt.Println(err) - return err - } - return nil -} diff --git a/server/utils/validator.go b/server/utils/validator.go index 11962694ef6e34e7cbea6effa44ccf9cb98f22ea..43cc6c697c75e5e5c1e0dbed84517591aa8e4c83 100644 --- a/server/utils/validator.go +++ b/server/utils/validator.go @@ -13,7 +13,12 @@ type RulesMap map[string]Rules var CustomizeMap = make(map[string]Rules) -// 注册自定义规则方案建议在路由初始化层即注册 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: RegisterRule +//@description: 注册自定义规则方案建议在路由初始化层即注册 +//@param: key string, rule Rules +//@return: err error + func RegisterRule(key string, rule Rules) (err error) { if CustomizeMap[key] != nil { return errors.New(key + "已注册,无法重复注册") @@ -23,42 +28,83 @@ func RegisterRule(key string, rule Rules) (err error) { } } -// 非空 不能为其对应类型的0值 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: NotEmpty +//@description: 非空 不能为其对应类型的0值 +//@param: key string, rule Rules +//@return: err error + func NotEmpty() string { return "notEmpty" } -// 小于入参(<) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Lt +//@description: 小于入参(<) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@param: mark string +//@return: string + func Lt(mark string) string { return "lt=" + mark } -// 小于等于入参(<=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Le +//@description: 小于等于入参(<=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@param: mark string +//@return: string + func Le(mark string) string { return "le=" + mark } -// 等于入参(==) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Eq +//@description: 等于入参(==) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@param: mark string +//@return: string + func Eq(mark string) string { return "eq=" + mark } -// 不等于入参(!=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Ne +//@description: 不等于入参(!=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@param: mark string +//@return: string + func Ne(mark string) string { return "ne=" + mark } -// 大于等于入参(>=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Ge +//@description: 大于等于入参(>=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@param: mark string +//@return: string + func Ge(mark string) string { return "ge=" + mark } -// 大于入参(>) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Gt +//@description: 大于入参(>) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较 +//@param: mark string +//@return: string + func Gt(mark string) string { return "gt=" + mark } -// 校验方法 接收两个参数 入参实例,规则map +// +//@author: [piexlmax](https://github.com/piexlmax) +//@function: Verify +//@description: 校验方法 +//@param: st interface{}, roleMap Rules(入参实例,规则map) +//@return: err error + func Verify(st interface{}, roleMap Rules) (err error) { compareMap := map[string]bool{ "lt": true, @@ -99,7 +145,12 @@ func Verify(st interface{}, roleMap Rules) (err error) { return nil } -// 长度和数字的校验方法 根据类型自动校验 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: compareVerify +//@description: 长度和数字的校验方法 根据类型自动校验 +//@param: value reflect.Value, VerifyStr string +//@return: bool + func compareVerify(value reflect.Value, VerifyStr string) bool { switch value.Kind() { case reflect.String, reflect.Slice, reflect.Array: @@ -115,7 +166,12 @@ func compareVerify(value reflect.Value, VerifyStr string) bool { } } -// 非空校验 +//@author: [piexlmax](https://github.com/piexlmax) +//@function: isBlank +//@description: 非空校验 +//@param: value reflect.Value +//@return: bool + func isBlank(value reflect.Value) bool { switch value.Kind() { case reflect.String: @@ -134,6 +190,12 @@ func isBlank(value reflect.Value) bool { return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface()) } +//@author: [piexlmax](https://github.com/piexlmax) +//@function: compare +//@description: 比较函数 +//@param: value interface{}, VerifyStr string +//@return: bool + func compare(value interface{}, VerifyStr string) bool { VerifyStrArr := strings.Split(VerifyStr, "=") val := reflect.ValueOf(value) diff --git a/server/utils/verify.go b/server/utils/verify.go index 78a25ae9e1efb1126507ad9062b18bbdfa8692d6..8332291f133287380d68603c6004e4887860d176 100644 --- a/server/utils/verify.go +++ b/server/utils/verify.go @@ -13,7 +13,6 @@ var ( AutoCodeVerify = Rules{"Abbreviation": {NotEmpty()}, "StructName": {NotEmpty()}, "PackageName": {NotEmpty()}, "Fields": {NotEmpty()}} WorkFlowVerify = Rules{"WorkflowNickName": {NotEmpty()}, "WorkflowName": {NotEmpty()}, "WorkflowDescription": {NotEmpty()}, "WorkflowStepInfo": {NotEmpty()}} AuthorityVerify = Rules{"AuthorityId": {NotEmpty()}, "AuthorityName": {NotEmpty()}, "ParentId": {NotEmpty()}} - DictionaryVerify = Rules{"Type": {NotEmpty()}, "ID": {NotEmpty()}} AuthorityIdVerify = Rules{"AuthorityId": {NotEmpty()}} OldAuthorityVerify = Rules{"OldAuthorityId": {NotEmpty()}} ChangePasswordVerify = Rules{"Username": {NotEmpty()}, "Password": {NotEmpty()}, "NewPassword": {NotEmpty()}} diff --git a/server/utils/zipfiles.go b/server/utils/zipfiles.go index 1242cbfbb1f3a58d73dcadbdd576714667675e24..aed53c951031e56a0b7c221af4e6c6398a253af7 100644 --- a/server/utils/zipfiles.go +++ b/server/utils/zipfiles.go @@ -7,6 +7,12 @@ import ( "strings" ) +//@author: [piexlmax](https://github.com/piexlmax) +//@function: ZipFiles +//@description: 压缩文件 +//@param: filename string, files []string, oldform, newform string +//@return: error + func ZipFiles(filename string, files []string, oldform, newform string) error { newZipFile, err := os.Create(filename) diff --git a/web/src/main.js b/web/src/main.js index 0e6cca6ff92da2e63b49299ec8c460ebcf17efc5..c1cdb6fadc9acec08bd30f5492e0f9285d4a07c9 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -66,7 +66,7 @@ Vue.prototype.$echarts = echarts; console.log(` 欢迎使用 Gin-Vue-Admin - 当前版本:V2.3.6 + 当前版本:V2.3.7 默认自动化文档地址:http://127.0.0.1%s/swagger/index.html 默认前端文件运行地址:http://127.0.0.1:8080 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee