diff --git a/features/cm/ne.go b/features/cm/ne.go index 363875e..300a88a 100644 --- a/features/cm/ne.go +++ b/features/cm/ne.go @@ -449,6 +449,17 @@ func ExportCmFromNF(w http.ResponseWriter, r *http.Request) { etcListIMS, config.GetYamlConfig().OMC.Backup, neTypeLower) } + case "mme": + if ipType == global.IsIPv4 { + scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User, + neInfo.Ip, config.GetYamlConfig().NE.EtcDir, + neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower) + } else { + scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User, + neInfo.Ip, config.GetYamlConfig().NE.EtcDir, + neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower) + } + default: if ipType == global.IsIPv4 { scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User, diff --git a/features/sys_config/service/repo_sys_config.go b/features/sys_config/service/repo_sys_config.go index 488d7c9..5b8ecdb 100644 --- a/features/sys_config/service/repo_sys_config.go +++ b/features/sys_config/service/repo_sys_config.go @@ -181,7 +181,11 @@ func (r *RepoSysConfig) SelectConfigValueByKey(configKey string) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } @@ -226,7 +230,11 @@ func (r *RepoSysConfig) CheckUniqueConfig(sysConfig model.SysConfig) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/features/sys_dict_data/repo/repo_sys_dict_data.go b/features/sys_dict_data/repo/repo_sys_dict_data.go index cd6268a..6ae2631 100644 --- a/features/sys_dict_data/repo/repo_sys_dict_data.go +++ b/features/sys_dict_data/repo/repo_sys_dict_data.go @@ -215,7 +215,11 @@ func (r *RepoSysDictData) CheckUniqueDictData(sysDictData model.SysDictData) str return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/features/sys_dict_type/repo/repo_sys_dict_type.go b/features/sys_dict_type/repo/repo_sys_dict_type.go index 874dac1..5e88e99 100644 --- a/features/sys_dict_type/repo/repo_sys_dict_type.go +++ b/features/sys_dict_type/repo/repo_sys_dict_type.go @@ -227,7 +227,11 @@ func (r *RepoSysDictType) CheckUniqueDictType(sysDictType model.SysDictType) str return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/features/sys_menu/service/repo_sys_menu.go b/features/sys_menu/service/repo_sys_menu.go index af809a1..eae567d 100644 --- a/features/sys_menu/service/repo_sys_menu.go +++ b/features/sys_menu/service/repo_sys_menu.go @@ -469,7 +469,11 @@ func (r *RepoSysMenu) CheckUniqueMenu(sysMenu model.SysMenu) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/features/sys_role/service/repo_sys_role.go b/features/sys_role/service/repo_sys_role.go index 7f61e8a..5997d67 100644 --- a/features/sys_role/service/repo_sys_role.go +++ b/features/sys_role/service/repo_sys_role.go @@ -356,7 +356,11 @@ func (r *RepoSysRole) CheckUniqueRole(sysRole model.SysRole) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/features/sys_user/service/repo_sys_user.go b/features/sys_user/service/repo_sys_user.go index 93c7781..1dff7c8 100644 --- a/features/sys_user/service/repo_sys_user.go +++ b/features/sys_user/service/repo_sys_user.go @@ -572,7 +572,11 @@ func (r *RepoSysUser) CheckUniqueUser(sysUser sysUserModel.SysUser) string { log.Errorf("query err %v", err) } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/features/ue/ue.go b/features/ue/ue.go index 7f77458..2be1c86 100644 --- a/features/ue/ue.go +++ b/features/ue/ue.go @@ -57,6 +57,19 @@ type ImsUEInfo struct { Activetime string `json:"activeTime"` } +// N3iwfUEInfo N3IWF在线用户信息 +type N3iwfUEInfo struct { + IMSI string `json:"imsi"` + + NAI string `json:"nai"` + RegState int `json:"regState"` + Activetime string `json:"activeTime"` +} + +type N3iwfUEData struct { + Data []N3iwfUEInfo `json:"data"` +} + var ( UriNBInfo = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/nbInfo" UriUEInfo = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/ueInfo" diff --git a/restagent/config/config.go b/restagent/config/config.go index 4df8dfc..91711ed 100644 --- a/restagent/config/config.go +++ b/restagent/config/config.go @@ -109,15 +109,16 @@ type YamlConfig struct { } `yaml:"mml"` NE struct { - Addr string `yaml:"addr"` - Port uint16 `yaml:"port"` - User string `yaml:"user"` - EtcDir string `yaml:"etcdir"` - BinDir string `yaml:"bindir"` - OmcDir string `yaml:"omcdir"` - ScpDir string `yaml:"scpdir"` - LicenseDir string `yaml:"licensedir"` - EtcListIMS string `yaml:"etcListIMS"` + Addr string `yaml:"addr"` + Port uint16 `yaml:"port"` + User string `yaml:"user"` + EtcDir string `yaml:"etcdir"` + BinDir string `yaml:"bindir"` + OmcDir string `yaml:"omcdir"` + ScpDir string `yaml:"scpdir"` + LicenseDir string `yaml:"licensedir"` + EtcListIMS string `yaml:"etcListIMS"` + EtcListDefault string `yaml:"etcListDefault"` } `yaml:"ne"` Auth struct { diff --git a/restagent/etc/restconf.yaml b/restagent/etc/restconf.yaml index 803d1bf..ddbd183 100644 --- a/restagent/etc/restconf.yaml +++ b/restagent/etc/restconf.yaml @@ -37,12 +37,15 @@ webServer: database: type: mysql user: root + # password: "1000omc@kp!" + # host: "192.168.2.219" + # port: 33066 + # name: omc_db + backup: d:/local.git/ems.agt/restagent/database password: "root@1234" host: "192.168.2.162" port: 3306 name: "omc_db" - backup: d:/local.git/ems.agt/restagent/database - # Redis 缓存数据,数据源声明全小写 redis: dataSource: diff --git a/restagent/makefile b/restagent/makefile index c59a48d..542a0bb 100644 --- a/restagent/makefile +++ b/restagent/makefile @@ -1,7 +1,7 @@ # Makefile for rest agent project PROJECT = OMC -VERSION = 2.2311.7 +VERSION = 2.2311.8 PLATFORM = amd64 ARMPLATFORM = aarch64 BUILDDIR = ../../build diff --git a/src/app.go b/src/app.go index 78b6ddf..a97474e 100644 --- a/src/app.go +++ b/src/app.go @@ -11,7 +11,7 @@ import ( "ems.agt/src/modules/common" "ems.agt/src/modules/crontask" "ems.agt/src/modules/monitor" - netelement "ems.agt/src/modules/net_element" + networkelement "ems.agt/src/modules/network_element" "ems.agt/src/modules/system" "ems.agt/src/modules/trace" @@ -117,7 +117,7 @@ func initModulesRoute(app *gin.Engine) { // 系统模块 system.Setup(app) // 网元模块 - netelement.Setup(app) + networkelement.Setup(app) // 跟踪模块 trace.Setup(app) // 调度任务模块--暂无接口 diff --git a/src/framework/constants/roledatascope/roledatascope.go b/src/framework/constants/roledatascope/roledatascope.go index 52c6350..c18cc89 100644 --- a/src/framework/constants/roledatascope/roledatascope.go +++ b/src/framework/constants/roledatascope/roledatascope.go @@ -18,12 +18,3 @@ const ( // 仅本人数据权限 SELF = "5" ) - -// 系统角色数据范围映射 -var RoleDataScope = map[string]string{ - ALL: "全部数据权限", - CUSTOM: "自定数据权限", - DEPT: "部门数据权限", - DEPT_AND_CHILD: "部门及以下数据权限", - SELF: "仅本人数据权限", -} diff --git a/src/framework/i18n/i18n.go b/src/framework/i18n/i18n.go index fceca21..d6d959f 100644 --- a/src/framework/i18n/i18n.go +++ b/src/framework/i18n/i18n.go @@ -36,6 +36,26 @@ func LoadLocaleData(language string) []localeItem { return localeData } +// ValueKey 值转换键 +func ValueKey(language, value string) string { + key := value + if value == "" { + return key + } + arr, ok := localeMap[language] + if !ok || len(arr) == 0 { + arr = LoadLocaleData(language) + } + + for _, v := range arr { + if v.Value == value { + key = v.Key + break + } + } + return key +} + // TKey 翻译键 func TKey(language, key string) string { value := key diff --git a/src/framework/middleware/collectlogs/operate_log.go b/src/framework/middleware/collectlogs/operate_log.go index 3c22e46..65da37d 100644 --- a/src/framework/middleware/collectlogs/operate_log.go +++ b/src/framework/middleware/collectlogs/operate_log.go @@ -7,6 +7,7 @@ import ( "time" "ems.agt/src/framework/constants/common" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/parse" "ems.agt/src/framework/vo/result" @@ -96,6 +97,7 @@ var maskProperties []string = []string{ func OperateLog(options Options) gin.HandlerFunc { return func(c *gin.Context) { c.Set("startTime", time.Now()) + language := ctx.AcceptLanguage(c) // 函数名 funcName := c.HandlerName() @@ -108,7 +110,7 @@ func OperateLog(options Options) gin.HandlerFunc { // 获取登录用户信息 loginUser, err := ctx.LoginUser(c) if err != nil { - c.JSON(401, result.CodeMsg(401, "无效身份授权")) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error()))) c.Abort() // 停止执行后续的处理函数 return } diff --git a/src/framework/middleware/pre_authorize.go b/src/framework/middleware/pre_authorize.go index 3fd8988..4ded217 100644 --- a/src/framework/middleware/pre_authorize.go +++ b/src/framework/middleware/pre_authorize.go @@ -1,10 +1,9 @@ package middleware import ( - "fmt" - AdminConstants "ems.agt/src/framework/constants/admin" commonConstants "ems.agt/src/framework/constants/common" + "ems.agt/src/framework/i18n" ctxUtils "ems.agt/src/framework/utils/ctx" tokenUtils "ems.agt/src/framework/utils/token" "ems.agt/src/framework/vo/result" @@ -23,10 +22,12 @@ import ( // 同时匹配其中权限 "matchPerms": {"xxx"}, func PreAuthorize(options map[string][]string) gin.HandlerFunc { return func(c *gin.Context) { + language := ctxUtils.AcceptLanguage(c) + // 获取请求头标识信息 tokenStr := ctxUtils.Authorization(c) if tokenStr == "" { - c.JSON(401, result.CodeMsg(401, "无效身份授权")) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, "app.common.err401"))) c.Abort() // 停止执行后续的处理函数 return } @@ -42,7 +43,7 @@ func PreAuthorize(options map[string][]string) gin.HandlerFunc { // 获取缓存的用户信息 loginUser := tokenUtils.LoginUser(claims) if loginUser.UserID == "" { - c.JSON(401, result.CodeMsg(401, "无效身份授权")) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, "app.common.err401"))) c.Abort() // 停止执行后续的处理函数 return } @@ -60,7 +61,7 @@ func PreAuthorize(options map[string][]string) gin.HandlerFunc { perms := loginUser.Permissions verifyOk := verifyRolePermission(roles, perms, options) if !verifyOk { - msg := fmt.Sprintf("无权访问 %s %s", c.Request.Method, c.Request.RequestURI) + msg := i18n.TTemplate(language, "app.common.err403", map[string]any{"method": c.Request.Method, "requestURI": c.Request.RequestURI}) c.JSON(403, result.CodeMsg(403, msg)) c.Abort() // 停止执行后续的处理函数 return diff --git a/src/framework/middleware/rate_limit.go b/src/framework/middleware/rate_limit.go index dd5b85a..3390622 100644 --- a/src/framework/middleware/rate_limit.go +++ b/src/framework/middleware/rate_limit.go @@ -6,6 +6,7 @@ import ( "time" "ems.agt/src/framework/constants/cachekey" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/redis" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/ip2region" @@ -42,6 +43,8 @@ type LimitOption struct { // 以便获取登录用户信息,无用户信息时默认为 GLOBAL func RateLimit(option LimitOption) gin.HandlerFunc { return func(c *gin.Context) { + language := ctx.AcceptLanguage(c) + // 初始可选参数数据 if option.Time < 5 { option.Time = 5 @@ -66,7 +69,7 @@ func RateLimit(option LimitOption) gin.HandlerFunc { if err != nil { c.JSON(401, result.Err(map[string]any{ "code": 401, - "msg": err.Error(), + "msg": i18n.TKey(language, err.Error()), })) c.Abort() // 停止执行后续的处理函数 return @@ -91,7 +94,7 @@ func RateLimit(option LimitOption) gin.HandlerFunc { if rateCount >= option.Count { // 访问过于频繁,请稍候再试 - c.JSON(200, result.ErrMsg("Visits are too frequent. Please try again later")) + c.JSON(200, i18n.TKey(language, "app.common.rateLimitTip")) c.Abort() // 停止执行后续的处理函数 return } diff --git a/src/framework/utils/ctx/ctx.go b/src/framework/utils/ctx/ctx.go index 8539e63..ff9efe0 100644 --- a/src/framework/utils/ctx/ctx.go +++ b/src/framework/utils/ctx/ctx.go @@ -82,13 +82,13 @@ func UaOsBrowser(c *gin.Context) (string, string) { userAgent := c.GetHeader("user-agent") uaInfo := ua.Info(userAgent) - browser := "Unknown Unknown" + browser := "app.common.noUaOsBrowser" bName, bVersion := uaInfo.Browser() if bName != "" && bVersion != "" { browser = bName + " " + bVersion } - os := "Unknown Unknown" + os := "app.common.noUaOsBrowser" bos := uaInfo.OS() if bos != "" { os = bos @@ -116,7 +116,8 @@ func LoginUser(c *gin.Context) (vo.LoginUser, error) { if exists { return value.(vo.LoginUser), nil } - return vo.LoginUser{}, fmt.Errorf("invalid login user information") + // 登录用户信息无效 + return vo.LoginUser{}, fmt.Errorf("app.common.noLoginUser") } // LoginUserToUserID 登录用户信息-用户ID diff --git a/src/framework/utils/file/file.go b/src/framework/utils/file/file.go index 50ace0a..831250e 100644 --- a/src/framework/utils/file/file.go +++ b/src/framework/utils/file/file.go @@ -294,3 +294,20 @@ func ChunkMergeFile(identifier, originalFileName, subPath string) (string, error urlPath := filepath.Join(prefix, filePath, fileName) return filepath.ToSlash(urlPath), nil } + +// ParseUploadFileDir 得到上传资源目录 +// +// subPath 子路径,默认 UploadSubPath.DEFAULT +func ParseUploadFileDir(subPath string) string { + _, dir := resourceUpload() + filePath := filepath.Join(subPath, date.ParseDatePath(time.Now())) + return filepath.Join(dir, filePath) +} + +// ParseUploadFilePath 本地资源路径 +// +// filePath 上传文件路径 +func ParseUploadFilePath(filePath string) string { + prefix, dir := resourceUpload() + return strings.Replace(filePath, prefix, dir, 1) +} diff --git a/src/framework/utils/ip2region/ip2region.go b/src/framework/utils/ip2region/ip2region.go index ff041ca..b62890c 100644 --- a/src/framework/utils/ip2region/ip2region.go +++ b/src/framework/utils/ip2region/ip2region.go @@ -43,7 +43,7 @@ func RegionSearchByIp(ip string) (string, int, int64) { ip = ClientIP(ip) if ip == LOCAT_HOST { // "0|0|0|内网IP|内网IP" - return "0|0|0|Intranet IP|Intranet IP", 0, 0 + return "0|0|0|app.common.noIPregion|app.common.noIPregion", 0, 0 } tStart := time.Now() region, err := searcher.SearchByStr(ip) @@ -60,19 +60,19 @@ func RegionSearchByIp(ip string) (string, int, int64) { func RealAddressByIp(ip string) string { ip = ClientIP(ip) if ip == LOCAT_HOST { - return "Intranet IP" // 内网IP + return "app.common.noIPregion" // 内网IP } region, err := searcher.SearchByStr(ip) if err != nil { logger.Errorf("failed to SearchIP(%s): %s\n", ip, err) - return "unknown" // 未知 + return "app.common.unknown" // 未知 } parts := strings.Split(region, "|") province := parts[2] city := parts[3] if province == "0" && city != "0" { if city == "内网IP" { - return "Intranet IP" // 内网IP + return "app.common.noIPregion" // 内网IP } return city } diff --git a/src/modules/common/controller/account.go b/src/modules/common/controller/account.go index 07831e8..15eeeef 100644 --- a/src/modules/common/controller/account.go +++ b/src/modules/common/controller/account.go @@ -4,8 +4,10 @@ import ( "ems.agt/src/framework/config" commonConstants "ems.agt/src/framework/constants/common" tokenConstants "ems.agt/src/framework/constants/token" - ctxUtils "ems.agt/src/framework/utils/ctx" + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" tokenUtils "ems.agt/src/framework/utils/token" + "ems.agt/src/framework/vo" "ems.agt/src/framework/vo/result" libAccount "ems.agt/src/lib_features/account" commonModel "ems.agt/src/modules/common/model" @@ -34,15 +36,16 @@ type AccountController struct { // // POST /login func (s *AccountController) Login(c *gin.Context) { + language := ctx.AcceptLanguage(c) var loginBody commonModel.LoginBody if err := c.ShouldBindJSON(&loginBody); err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 当前请求信息 - ipaddr, location := ctxUtils.IPAddrLocation(c) - os, browser := ctxUtils.UaOsBrowser(c) + ipaddr, location := ctx.IPAddrLocation(c) + os, browser := ctx.UaOsBrowser(c) // 校验验证码 err := s.accountService.ValidateCaptcha( @@ -51,19 +54,19 @@ func (s *AccountController) Login(c *gin.Context) { ) // 根据错误信息,创建系统访问记录 if err != nil { - msg := err.Error() + " " + loginBody.Code + msg := i18n.TKey(language, err.Error()) s.sysLogLoginService.CreateSysLogLogin( - loginBody.Username, commonConstants.STATUS_NO, msg, + loginBody.Username, commonConstants.STATUS_NO, msg+loginBody.Code, ipaddr, location, os, browser, ) - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, result.ErrMsg(msg)) return } // 登录用户信息 loginUser, err := s.accountService.LoginByUsername(loginBody.Username, loginBody.Password) if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) return } @@ -75,8 +78,9 @@ func (s *AccountController) Login(c *gin.Context) { } else { s.accountService.UpdateLoginDateAndIP(&loginUser) // 登录成功 + msg := i18n.TKey(language, "app.common.loginSuccess") s.sysLogLoginService.CreateSysLogLogin( - loginBody.Username, commonConstants.STATUS_YES, "Login Successful", + loginBody.Username, commonConstants.STATUS_YES, msg, ipaddr, location, os, browser, ) } @@ -93,9 +97,10 @@ func (s *AccountController) Login(c *gin.Context) { // // GET /getInfo func (s *AccountController) Info(c *gin.Context) { - loginUser, err := ctxUtils.LoginUser(c) + language := ctx.AcceptLanguage(c) + loginUser, err := ctx.LoginUser(c) if err != nil { - c.JSON(401, result.CodeMsg(401, err.Error())) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error()))) return } @@ -103,6 +108,12 @@ func (s *AccountController) Info(c *gin.Context) { isAdmin := config.IsAdmin(loginUser.UserID) roles, perms := s.accountService.RoleAndMenuPerms(loginUser.UserID, isAdmin) + loginUser.User.NickName = i18n.TKey(language, loginUser.User.NickName) + loginUser.User.Remark = i18n.TKey(language, loginUser.User.Remark) + loginUser.User.Dept.DeptName = i18n.TKey(language, loginUser.User.Dept.DeptName) + for ri := range loginUser.User.Roles { + loginUser.User.Roles[ri].RoleName = i18n.TKey(language, loginUser.User.Roles[ri].RoleName) + } c.JSON(200, result.OkData(map[string]any{ "user": loginUser.User, "roles": roles, @@ -114,11 +125,25 @@ func (s *AccountController) Info(c *gin.Context) { // // GET /getRouters func (s *AccountController) Router(c *gin.Context) { - userID := ctxUtils.LoginUserToUserID(c) + userID := ctx.LoginUserToUserID(c) // 前端路由,管理员拥有所有 isAdmin := config.IsAdmin(userID) buildMenus := s.accountService.RouteMenus(userID, isAdmin) + + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + var converI18n func(language string, arr *[]vo.Router) + converI18n = func(language string, arr *[]vo.Router) { + for i := range *arr { + (*arr)[i].Meta.Title = i18n.TKey(language, (*arr)[i].Meta.Title) + if len((*arr)[i].Children) > 0 { + converI18n(language, &(*arr)[i].Children) + } + } + } + converI18n(language, &buildMenus) + c.JSON(200, result.OkData(buildMenus)) } @@ -126,21 +151,25 @@ func (s *AccountController) Router(c *gin.Context) { // // POST /logout func (s *AccountController) Logout(c *gin.Context) { - tokenStr := ctxUtils.Authorization(c) + language := ctx.AcceptLanguage(c) + msg := i18n.TKey(language, "app.common.logoutSuccess") + tokenStr := ctx.Authorization(c) if tokenStr != "" { // 存在token时记录退出信息 userName := tokenUtils.Remove(tokenStr) if userName != "" { // 当前请求信息 - ipaddr, location := ctxUtils.IPAddrLocation(c) - os, browser := ctxUtils.UaOsBrowser(c) + ipaddr, location := ctx.IPAddrLocation(c) + os, browser := ctx.UaOsBrowser(c) + // 创建系统访问记录 退出成功 + s.sysLogLoginService.CreateSysLogLogin( - userName, commonConstants.STATUS_YES, "Exit successful", + userName, commonConstants.STATUS_YES, msg, ipaddr, location, os, browser, ) } } - c.JSON(200, result.OkMsg("Exit successful")) + c.JSON(200, result.OkMsg(msg)) } diff --git a/src/modules/common/controller/common.go b/src/modules/common/controller/common.go index 3ce0851..4ba3776 100644 --- a/src/modules/common/controller/common.go +++ b/src/modules/common/controller/common.go @@ -57,5 +57,15 @@ func (s *CommontController) I18n(c *gin.Context) { // GET /sys-conf func (s *CommontController) SysConfig(c *gin.Context) { data := s.commontService.SystemConfigInfo() + + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *map[string]string) { + for k, v := range *arr { + (*arr)[k] = i18n.TKey(language, v) + } + } + converI18n(language, &data) + c.JSON(200, result.OkData(data)) } diff --git a/src/modules/common/controller/file.go b/src/modules/common/controller/file.go index c160867..352fee7 100644 --- a/src/modules/common/controller/file.go +++ b/src/modules/common/controller/file.go @@ -7,6 +7,8 @@ import ( "strings" "ems.agt/src/framework/constants/uploadsubpath" + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/vo/result" @@ -25,9 +27,10 @@ type FileController struct{} // // GET /download/:filePath func (s *FileController) Download(c *gin.Context) { + language := ctx.AcceptLanguage(c) filePath := c.Param("filePath") if len(filePath) < 8 { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // base64解析出地址 @@ -68,16 +71,17 @@ func (s *FileController) Download(c *gin.Context) { // // POST /upload func (s *FileController) Upload(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 上传的文件 formFile, err := c.FormFile("file") if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 子路径 subPath := c.PostForm("subPath") if _, ok := uploadsubpath.UploadSubpath[subPath]; !ok { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -101,6 +105,7 @@ func (s *FileController) Upload(c *gin.Context) { // // POST /chunkCheck func (s *FileController) ChunkCheck(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 唯一标识 Identifier string `json:"identifier" binding:"required"` @@ -109,7 +114,7 @@ func (s *FileController) ChunkCheck(c *gin.Context) { } err := c.ShouldBindJSON(&body) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -126,6 +131,7 @@ func (s *FileController) ChunkCheck(c *gin.Context) { // // POST /chunkMerge func (s *FileController) ChunkMerge(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 唯一标识 Identifier string `json:"identifier" binding:"required"` @@ -136,11 +142,11 @@ func (s *FileController) ChunkMerge(c *gin.Context) { } err := c.ShouldBindJSON(&body) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } if _, ok := uploadsubpath.UploadSubpath[body.SubPath]; !ok { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -164,6 +170,7 @@ func (s *FileController) ChunkMerge(c *gin.Context) { // // POST /chunkUpload func (s *FileController) ChunkUpload(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 切片编号 index := c.PostForm("index") // 切片唯一标识 @@ -171,7 +178,7 @@ func (s *FileController) ChunkUpload(c *gin.Context) { // 上传的文件 formFile, err := c.FormFile("file") if index == "" || identifier == "" || err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } diff --git a/src/modules/common/controller/register.go b/src/modules/common/controller/register.go index 97526d0..484a47f 100644 --- a/src/modules/common/controller/register.go +++ b/src/modules/common/controller/register.go @@ -2,7 +2,8 @@ package controller import ( commonConstants "ems.agt/src/framework/constants/common" - ctxUtils "ems.agt/src/framework/utils/ctx" + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/regular" "ems.agt/src/framework/vo/result" commonModel "ems.agt/src/modules/common/model" @@ -32,32 +33,33 @@ type RegisterController struct { // // GET /register func (s *RegisterController) Register(c *gin.Context) { + language := ctx.AcceptLanguage(c) var registerBody commonModel.RegisterBody if err := c.ShouldBindJSON(®isterBody); err != nil { - c.JSON(400, result.ErrMsg("parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 判断必传参数 if !regular.ValidUsername(registerBody.Username) { // 账号不能以数字开头,可包含大写小写字母,数字,且不少于5位 - c.JSON(200, result.ErrMsg("The account cannot start with a number and can contain uppercase and lowercase letters, numbers, and no less than 5 digits")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "register.errUsername"))) return } if !regular.ValidPassword(registerBody.Password) { // 登录密码至少包含大小写字母、数字、特殊符号,且不少于6位 - c.JSON(200, result.ErrMsg("The login password should contain at least uppercase and lowercase letters, numbers, special symbols, and no less than 6 digits")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "register.errPasswd"))) return } if registerBody.Password != registerBody.ConfirmPassword { // 用户确认输入密码不一致 - c.JSON(200, result.ErrMsg("The user confirmed that the input password is inconsistent")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "register.errPasswdNotEq"))) return } // 当前请求信息 - ipaddr, location := ctxUtils.IPAddrLocation(c) - os, browser := ctxUtils.UaOsBrowser(c) + ipaddr, location := ctx.IPAddrLocation(c) + os, browser := ctx.UaOsBrowser(c) // 校验验证码 err := s.registerService.ValidateCaptcha( @@ -77,13 +79,13 @@ func (s *RegisterController) Register(c *gin.Context) { userID, err := s.registerService.ByUserName(registerBody.Username, registerBody.Password, registerBody.UserType) if err == nil { - msg := registerBody.Username + " registered success " + userID + msg := i18n.TTemplate(language, "register.successMsg", map[string]any{"name": registerBody.Username, "id": userID}) s.sysLogLoginService.CreateSysLogLogin( registerBody.Username, commonConstants.STATUS_YES, msg, ipaddr, location, os, browser, ) // 注册成功 - c.JSON(200, result.OkMsg("registered success")) + c.JSON(200, result.OkMsg(i18n.TKey(language, "register.success"))) return } c.JSON(200, result.ErrMsg(err.Error())) diff --git a/src/modules/common/service/account.impl.go b/src/modules/common/service/account.impl.go index b9d96e3..31e9571 100644 --- a/src/modules/common/service/account.impl.go +++ b/src/modules/common/service/account.impl.go @@ -45,18 +45,18 @@ func (s *AccountImpl) ValidateCaptcha(code, uuid string) error { } if code == "" || uuid == "" { // 验证码信息错误 - return fmt.Errorf("captcha message error") + return fmt.Errorf("captcha.err") } verifyKey := cachekey.CAPTCHA_CODE_KEY + uuid captcha, _ := redis.Get("", verifyKey) if captcha == "" { // 验证码已失效 - return fmt.Errorf("captcha is no longer valid") + return fmt.Errorf("captcha.errValid") } redis.Del("", verifyKey) if captcha != code { // 验证码错误 - return fmt.Errorf("captcha error") + return fmt.Errorf("captcha.err") } return nil } @@ -74,14 +74,14 @@ func (s *AccountImpl) LoginByUsername(username, password string) (vo.LoginUser, // 查询用户登录账号 sysUser := s.sysUserService.SelectUserByUserName(username) if sysUser.UserName != username { - return loginUser, fmt.Errorf("user does not exist or wrong password") + return loginUser, fmt.Errorf("login.errNameOrPasswd") } if sysUser.DelFlag == common.STATUS_YES { // 对不起,您的账号已被删除 - return loginUser, fmt.Errorf("sorry, your account has been deleted") + return loginUser, fmt.Errorf("login.errDelFlag") } if sysUser.Status == common.STATUS_NO { - return loginUser, fmt.Errorf("sorry, your account has been disabled") + return loginUser, fmt.Errorf("login.errStatus") } // 检验用户密码 @@ -89,7 +89,7 @@ func (s *AccountImpl) LoginByUsername(username, password string) (vo.LoginUser, if !compareBool { redis.SetByExpire("", retrykey, retryCount+1, lockTime) // 用户不存在或密码错误 - return loginUser, fmt.Errorf("user does not exist or wrong password") + return loginUser, fmt.Errorf("login.errNameOrPasswd") } else { // 清除错误记录次数 s.ClearLoginRecordCache(username) @@ -136,9 +136,13 @@ func (s *AccountImpl) ClearLoginRecordCache(username string) bool { // passwordRetryCount 密码重试次数 func (s *AccountImpl) passwordRetryCount(username string) (string, int64, time.Duration, error) { + // 从数据库配置获取登录次数和错误锁定时间 + maxRetryCountStr := s.sysConfigService.SelectConfigValueByKey("sys.user.maxRetryCount") + lockTimeStr := s.sysConfigService.SelectConfigValueByKey("sys.user.lockTime") + // 验证登录次数和错误锁定时间 - maxRetryCount := config.Get("user.password.maxRetryCount").(int) - lockTime := config.Get("user.password.lockTime").(int) + maxRetryCount := parse.Number(maxRetryCountStr) + lockTime := parse.Number(lockTimeStr) // 验证缓存记录次数 retrykey := cachekey.PWD_ERR_CNT_KEY + username retryCount, err := redis.Get("", retrykey) @@ -147,9 +151,9 @@ func (s *AccountImpl) passwordRetryCount(username string) (string, int64, time.D } // 是否超过错误值 retryCountInt64 := parse.Number(retryCount) - if retryCountInt64 >= int64(maxRetryCount) { - // 密码输入错误 %d 次,帐户锁定 %d 分钟 - errorMsg := fmt.Errorf("password entered incorrectly %d times, account locked for %d minutes", maxRetryCount, lockTime) + if retryCountInt64 >= maxRetryCount { + // 密码输入错误多次,帐户已被锁定 + errorMsg := fmt.Errorf("login.errRetryPasswd") return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, errorMsg } return retrykey, retryCountInt64, time.Duration(lockTime) * time.Minute, nil diff --git a/src/modules/common/service/commont.go b/src/modules/common/service/commont.go index 5dc1e65..e8be8db 100644 --- a/src/modules/common/service/commont.go +++ b/src/modules/common/service/commont.go @@ -3,5 +3,5 @@ package service // 通用请求 服务层接口 type ICommont interface { // SystemConfigInfo 系统配置信息 - SystemConfigInfo() map[string]any + SystemConfigInfo() map[string]string } diff --git a/src/modules/common/service/commont.impl.go b/src/modules/common/service/commont.impl.go index 4197298..3756a16 100644 --- a/src/modules/common/service/commont.impl.go +++ b/src/modules/common/service/commont.impl.go @@ -19,8 +19,8 @@ type CommontImpl struct { } // SystemConfigInfo 系统配置信息 -func (s *CommontImpl) SystemConfigInfo() map[string]any { - infoMap := map[string]any{} +func (s *CommontImpl) SystemConfigInfo() map[string]string { + infoMap := map[string]string{} // 获取LOGO类型 logoType := s.sysConfigService.SelectConfigValueByKey("sys.logo.type") infoMap["logoType"] = logoType diff --git a/src/modules/crontask/processor/backupEtcFromNE/backupEtcFromNE.go b/src/modules/crontask/processor/backupEtcFromNE/backupEtcFromNE.go index e602061..d4327c8 100644 --- a/src/modules/crontask/processor/backupEtcFromNE/backupEtcFromNE.go +++ b/src/modules/crontask/processor/backupEtcFromNE/backupEtcFromNE.go @@ -108,6 +108,17 @@ func (s *BarProcessor) Execute(data any) (any, error) { etcListIMS, config.GetYamlConfig().OMC.Backup, neTypeLower) } + case "mme": + if ipType == global.IsIPv4 { + scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User, + neInfo.Ip, config.GetYamlConfig().NE.EtcDir, + neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower) + } else { + scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User, + neInfo.Ip, config.GetYamlConfig().NE.EtcDir, + neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower) + } + default: if ipType == global.IsIPv4 { scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User, diff --git a/src/modules/monitor/controller/monitor.go b/src/modules/monitor/controller/monitor.go index 2c2d2e2..6f714b0 100644 --- a/src/modules/monitor/controller/monitor.go +++ b/src/modules/monitor/controller/monitor.go @@ -1,6 +1,8 @@ package controller import ( + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/vo/result" "ems.agt/src/modules/monitor/service" @@ -24,6 +26,7 @@ type MonitorController struct { // // GET /load func (s *MonitorController) Load(c *gin.Context) { + language := ctx.AcceptLanguage(c) var querys struct { // 数据类型all/load/cpu/memory/io/network Type string `form:"type" binding:"required,oneof=all load cpu memory io network"` @@ -40,7 +43,7 @@ func (s *MonitorController) Load(c *gin.Context) { } err := c.ShouldBindQuery(&querys) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } diff --git a/src/modules/monitor/controller/sys_cache.go b/src/modules/monitor/controller/sys_cache.go index b4815b4..9d4395d 100644 --- a/src/modules/monitor/controller/sys_cache.go +++ b/src/modules/monitor/controller/sys_cache.go @@ -2,7 +2,9 @@ package controller import ( "ems.agt/src/framework/constants/cachekey" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/redis" + "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/vo/result" "ems.agt/src/modules/monitor/model" @@ -48,9 +50,10 @@ func (s *SysCacheController) Names(c *gin.Context) { // // GET /getKeys/:cacheName func (s *SysCacheController) Keys(c *gin.Context) { + language := ctx.AcceptLanguage(c) cacheName := c.Param("cacheName") if cacheName == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } caches := []model.SysCache{} @@ -68,10 +71,11 @@ func (s *SysCacheController) Keys(c *gin.Context) { // // GET /getValue/:cacheName/:cacheKey func (s *SysCacheController) Value(c *gin.Context) { + language := ctx.AcceptLanguage(c) cacheName := c.Param("cacheName") cacheKey := c.Param("cacheKey") if cacheName == "" || cacheKey == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -88,9 +92,10 @@ func (s *SysCacheController) Value(c *gin.Context) { // // DELETE /clearCacheName/:cacheName func (s *SysCacheController) ClearCacheName(c *gin.Context) { + language := ctx.AcceptLanguage(c) cacheName := c.Param("cacheName") if cacheName == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -111,10 +116,11 @@ func (s *SysCacheController) ClearCacheName(c *gin.Context) { // // DELETE /clearCacheKey/:cacheName/:cacheKey func (s *SysCacheController) ClearCacheKey(c *gin.Context) { + language := ctx.AcceptLanguage(c) cacheName := c.Param("cacheName") cacheKey := c.Param("cacheKey") if cacheName == "" || cacheKey == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } diff --git a/src/modules/monitor/controller/sys_job.go b/src/modules/monitor/controller/sys_job.go index 095c7b3..7927c48 100644 --- a/src/modules/monitor/controller/sys_job.go +++ b/src/modules/monitor/controller/sys_job.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/utils/parse" @@ -41,6 +42,18 @@ type SysJobController struct { func (s *SysJobController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.sysJobService.SelectJobPage(querys) + + rows := data["rows"].([]model.SysJob) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysJob) { + for i := range *arr { + (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -48,14 +61,18 @@ func (s *SysJobController) List(c *gin.Context) { // // GET /:jobId func (s *SysJobController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) jobId := c.Param("jobId") if jobId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysJobService.SelectJobById(jobId) if data.JobID == jobId { + // 处理多语言 + data.JobName = i18n.TKey(language, data.JobName) + data.Remark = i18n.TKey(language, data.Remark) c.JSON(200, result.OkData(data)) return } @@ -66,17 +83,18 @@ func (s *SysJobController) Info(c *gin.Context) { // // POST / func (s *SysJobController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysJob err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.JobID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查cron表达式格式 if parse.CronExpression(body.CronExpression) == 0 { // 调度任务新增【%s】失败,Cron表达式不正确 - msg := fmt.Sprintf("Scheduling task add [%s] fails with incorrect Cron expression", body.JobName) + msg := i18n.TTemplate(language, "job.errCronExpression", map[string]any{"name": body.JobName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -84,7 +102,7 @@ func (s *SysJobController) Add(c *gin.Context) { // 检查任务调用传入参数是否json格式 if body.TargetParams != "" { // 调度任务新增【%s】失败,任务传入参数json字符串不正确 - msg := fmt.Sprintf("Scheduling task add [%s] failed, task incoming parameter json string is incorrect", body.JobName) + msg := i18n.TTemplate(language, "job.errTargetParams", map[string]any{"name": body.JobName}) if len(body.TargetParams) < 7 { c.JSON(200, result.ErrMsg(msg)) return @@ -99,7 +117,7 @@ func (s *SysJobController) Add(c *gin.Context) { uniqueJob := s.sysJobService.CheckUniqueJobName(body.JobName, body.JobGroup, "") if !uniqueJob { // 调度任务新增【%s】失败,同任务组内有相同任务名称 - msg := fmt.Sprintf("Scheduling tasks with new [%s] failures, with the same task name in the same task group", body.JobName) + msg := i18n.TTemplate(language, "job.errJobExists", map[string]any{"name": body.JobName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -117,17 +135,18 @@ func (s *SysJobController) Add(c *gin.Context) { // // PUT / func (s *SysJobController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysJob err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.JobID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查cron表达式格式 if parse.CronExpression(body.CronExpression) == 0 { // 调度任务修改【%s】失败,Cron表达式不正确 - msg := fmt.Sprintf("Scheduling task modification [%s] fails with incorrect Cron expression", body.JobName) + msg := i18n.TTemplate(language, "job.errCronExpression", map[string]any{"name": body.JobName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -135,7 +154,7 @@ func (s *SysJobController) Edit(c *gin.Context) { // 检查任务调用传入参数是否json格式 if body.TargetParams != "" { // 调度任务修改【%s】失败,任务传入参数json字符串不正确 - msg := fmt.Sprintf("Scheduling task modification [%s] failed, task incoming parameter json string is not correct", body.JobName) + msg := i18n.TTemplate(language, "job.errTargetParams", map[string]any{"name": body.JobName}) if len(body.TargetParams) < 7 { c.JSON(200, result.ErrMsg(msg)) return @@ -150,7 +169,7 @@ func (s *SysJobController) Edit(c *gin.Context) { uniqueJob := s.sysJobService.CheckUniqueJobName(body.JobName, body.JobGroup, body.JobID) if !uniqueJob { // 调度任务修改【%s】失败,同任务组内有相同任务名称 - msg := fmt.Sprintf("Scheduling task modification [%s] failed with the same task name in the same task group", body.JobName) + msg := i18n.TTemplate(language, "job.errJobExists", map[string]any{"name": body.JobName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -168,9 +187,10 @@ func (s *SysJobController) Edit(c *gin.Context) { // // DELETE /:jobIds func (s *SysJobController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) jobIds := c.Param("jobIds") if jobIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -185,7 +205,7 @@ func (s *SysJobController) Remove(c *gin.Context) { c.JSON(200, result.ErrMsg(err.Error())) return } - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -193,6 +213,7 @@ func (s *SysJobController) Remove(c *gin.Context) { // // PUT /changeStatus func (s *SysJobController) Status(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 任务ID JobId string `json:"jobId" binding:"required"` @@ -201,7 +222,7 @@ func (s *SysJobController) Status(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -209,14 +230,14 @@ func (s *SysJobController) Status(c *gin.Context) { job := s.sysJobService.SelectJobById(body.JobId) if job.JobID != body.JobId { // 没有可访问调度任务数据! - c.JSON(200, result.ErrMsg("No accessible scheduling task data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "job.noData"))) return } // 与旧值相等不变更 if job.Status == body.Status { // 变更状态与旧值相等! - c.JSON(200, result.ErrMsg("Change status equals old value!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "job.statusEq"))) return } @@ -235,9 +256,10 @@ func (s *SysJobController) Status(c *gin.Context) { // // PUT /run/:jobId func (s *SysJobController) Run(c *gin.Context) { + language := ctx.AcceptLanguage(c) jobId := c.Param("jobId") if jobId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -245,7 +267,7 @@ func (s *SysJobController) Run(c *gin.Context) { job := s.sysJobService.SelectJobById(jobId) if job.JobID != jobId { // 没有可访问调度任务数据! - c.JSON(200, result.ErrMsg("No accessible scheduling task data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "job.noData"))) return } @@ -269,30 +291,38 @@ func (s *SysJobController) ResetQueueJob(c *gin.Context) { // // POST /export func (s *SysJobController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.sysJobService.SelectJobPage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysJob) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysJob) { + for i := range *arr { + (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("job_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "JobID", - "B1": "JobName", - "C1": "JobGroupName", - "D1": "InvokeTarget", - "E1": "TargetParams", - "F1": "CronExpression", - "G1": "MisfirePolicy", - "H1": "Concurrent", - "I1": "Status", - "J1": "Remark", + "A1": i18n.TKey(language, "job.export.jobID"), + "B1": i18n.TKey(language, "job.export.jobName"), + "C1": i18n.TKey(language, "job.export.jobGroupName"), + "D1": i18n.TKey(language, "job.export.invokeTarget"), + "E1": i18n.TKey(language, "job.export.targetParams"), + "F1": i18n.TKey(language, "job.export.cronExpression"), + "G1": i18n.TKey(language, "job.export.status"), + "H1": i18n.TKey(language, "job.export.remark"), } // 读取任务组名字典数据 dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group") @@ -304,24 +334,15 @@ func (s *SysJobController) Export(c *gin.Context) { sysJobGroup := "" for _, v := range dictSysJobGroup { if row.JobGroup == v.DictValue { - sysJobGroup = v.DictLabel + sysJobGroup = i18n.TKey(language, v.DictLabel) break } } - misfirePolicy := "Abandon execution" - if row.MisfirePolicy == "1" { - misfirePolicy = "Execute immediately" - } else if row.MisfirePolicy == "2" { - misfirePolicy = "Execute once" - } - concurrent := "prohibit" - if row.Concurrent == "1" { - concurrent = "allow" - } + // 状态 - statusValue := "fail" + statusValue := i18n.TKey(language, "dictData.fail") if row.Status == "1" { - statusValue = "successes" + statusValue = i18n.TKey(language, "dictData.success") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.JobID, @@ -330,10 +351,8 @@ func (s *SysJobController) Export(c *gin.Context) { "D" + idx: row.InvokeTarget, "E" + idx: row.TargetParams, "F" + idx: row.CronExpression, - "G" + idx: misfirePolicy, - "H" + idx: concurrent, - "I" + idx: statusValue, - "J" + idx: row.Remark, + "G" + idx: statusValue, + "H" + idx: row.Remark, }) } diff --git a/src/modules/monitor/controller/sys_job_log.go b/src/modules/monitor/controller/sys_job_log.go index 0e92095..ac942e0 100644 --- a/src/modules/monitor/controller/sys_job_log.go +++ b/src/modules/monitor/controller/sys_job_log.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/date" "ems.agt/src/framework/utils/file" @@ -40,17 +41,42 @@ type SysJobLogController struct { func (s *SysJobLogController) List(c *gin.Context) { // 查询参数转换map querys := ctx.QueryMap(c) - list := s.sysJobLogService.SelectJobLogPage(querys) - c.JSON(200, result.Ok(list)) + data := s.sysJobLogService.SelectJobLogPage(querys) + + language := ctx.AcceptLanguage(c) + + // 反查多语言key + querys["jobName"] = i18n.ValueKey(language, querys["jobName"].(string)) + dataI18n := s.sysJobLogService.SelectJobLogPage(querys) + totalI18n := parse.Number(dataI18n["total"]) + if totalI18n != 0 { + rows := data["rows"].([]model.SysJobLog) + total := parse.Number(data["total"]) + rowsI18n := dataI18n["rows"].([]model.SysJobLog) + data["rows"] = append(rows, rowsI18n...) + data["total"] = total + totalI18n + } + + rows := data["rows"].([]model.SysJobLog) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysJobLog) { + for i := range *arr { + (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) + } + } + converI18n(language, &rows) + + c.JSON(200, result.Ok(data)) } // 调度任务日志信息 // // GET /:jobLogId func (s *SysJobLogController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) jobLogId := c.Param("jobLogId") if jobLogId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysJobLogService.SelectJobLogById(jobLogId) @@ -65,9 +91,10 @@ func (s *SysJobLogController) Info(c *gin.Context) { // // DELETE /:jobLogIds func (s *SysJobLogController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) jobLogIds := c.Param("jobLogIds") if jobLogIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -81,7 +108,7 @@ func (s *SysJobLogController) Remove(c *gin.Context) { rows := s.sysJobLogService.DeleteJobLogByIds(uniqueIDs) if rows > 0 { // 删除成功:%d - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) return } @@ -113,18 +140,27 @@ func (s *SysJobLogController) Export(c *gin.Context) { } rows := data["rows"].([]model.SysJobLog) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysJobLog) { + for i := range *arr { + (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("jobLog_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "JobLogID", - "B1": "JobName", - "C1": "JobGroupName", - "D1": "InvokeTarget", - "E1": "TargetParams", - "F1": "JobMsg", - "G1": "Status", - "H1": "Time", + "A1": i18n.TKey(language, "job.export.jobLogID"), + "B1": i18n.TKey(language, "job.export.jobName"), + "C1": i18n.TKey(language, "job.export.jobGroupName"), + "D1": i18n.TKey(language, "job.export.invokeTarget"), + "E1": i18n.TKey(language, "job.export.targetParams"), + "F1": i18n.TKey(language, "job.export.jobID"), + "G1": i18n.TKey(language, "job.export.jobLogStatus"), + "H1": i18n.TKey(language, "job.export.jobLogTime"), } // 读取任务组名字典数据 dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group") @@ -136,14 +172,14 @@ func (s *SysJobLogController) Export(c *gin.Context) { sysJobGroup := "" for _, v := range dictSysJobGroup { if row.JobGroup == v.DictValue { - sysJobGroup = v.DictLabel + sysJobGroup = i18n.TKey(language, v.DictLabel) break } } // 状态 - statusValue := "Fail" + statusValue := i18n.TKey(language, "dictData.fail") if row.Status == "1" { - statusValue = "Success" + statusValue = i18n.TKey(language, "dictData.success") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.JobLogID, diff --git a/src/modules/monitor/controller/sys_user_online.go b/src/modules/monitor/controller/sys_user_online.go index dcd0107..1c9232c 100644 --- a/src/modules/monitor/controller/sys_user_online.go +++ b/src/modules/monitor/controller/sys_user_online.go @@ -6,7 +6,9 @@ import ( "strings" "ems.agt/src/framework/constants/cachekey" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/redis" + "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/vo" "ems.agt/src/framework/vo/result" "ems.agt/src/modules/monitor/model" @@ -110,9 +112,10 @@ func (s *SysUserOnlineController) List(c *gin.Context) { // // DELETE /:tokenId func (s *SysUserOnlineController) ForceLogout(c *gin.Context) { + language := ctx.AcceptLanguage(c) tokenId := c.Param("tokenId") if tokenId == "" || tokenId == "*" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } diff --git a/src/modules/monitor/monitor.go b/src/modules/monitor/monitor.go index 80a3663..737809d 100644 --- a/src/modules/monitor/monitor.go +++ b/src/modules/monitor/monitor.go @@ -80,18 +80,18 @@ func Setup(router *gin.Engine) { ) sysJobLogGroup.DELETE("/:jobLogIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task Log", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJobLog", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysJobLog.Remove, ) sysJobLogGroup.DELETE("/clean", repeat.RepeatSubmit(5), middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task Log", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJobLog", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysJobLog.Clean, ) sysJobLogGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task Log", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJobLog", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysJobLog.Export, ) } @@ -109,39 +109,39 @@ func Setup(router *gin.Engine) { ) sysJobGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysJob.Add, ) sysJobGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysJob.Edit, ) sysJobGroup.DELETE("/:jobIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysJob.Remove, ) sysJobGroup.PUT("/changeStatus", repeat.RepeatSubmit(5), middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:changeStatus"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysJob.Status, ) sysJobGroup.PUT("/run/:jobId", repeat.RepeatSubmit(10), middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:changeStatus"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysJob.Run, ) sysJobGroup.PUT("/resetQueueJob", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:changeStatus"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysJob.ResetQueueJob, ) sysJobGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"monitor:job:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Scheduling Task", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysJob", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysJob.Export, ) } diff --git a/src/modules/monitor/repository/sys_job.impl.go b/src/modules/monitor/repository/sys_job.impl.go index 19ab059..19040fa 100644 --- a/src/modules/monitor/repository/sys_job.impl.go +++ b/src/modules/monitor/repository/sys_job.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -210,7 +209,11 @@ func (r *SysJobImpl) CheckUniqueJob(sysJob model.SysJob) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/src/modules/system/controller/sys_config.go b/src/modules/system/controller/sys_config.go index e5dd936..190815a 100644 --- a/src/modules/system/controller/sys_config.go +++ b/src/modules/system/controller/sys_config.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/utils/parse" @@ -36,6 +37,19 @@ type SysConfigController struct { func (s *SysConfigController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.sysConfigService.SelectConfigPage(querys) + + rows := data["rows"].([]model.SysConfig) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysConfig) { + for i := range *arr { + (*arr)[i].ConfigName = i18n.TKey(language, (*arr)[i].ConfigName) + (*arr)[i].ConfigValue = i18n.TKey(language, (*arr)[i].ConfigValue) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -43,13 +57,19 @@ func (s *SysConfigController) List(c *gin.Context) { // // GET /:configId func (s *SysConfigController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) configId := c.Param("configId") if configId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } + data := s.sysConfigService.SelectConfigById(configId) if data.ConfigID == configId { + // 处理多语言 + data.ConfigName = i18n.TKey(language, data.ConfigName) + data.ConfigValue = i18n.TKey(language, data.ConfigValue) + data.Remark = i18n.TKey(language, data.Remark) c.JSON(200, result.OkData(data)) return } @@ -60,10 +80,11 @@ func (s *SysConfigController) Info(c *gin.Context) { // // POST / func (s *SysConfigController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysConfig err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.ConfigID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -71,7 +92,7 @@ func (s *SysConfigController) Add(c *gin.Context) { uniqueConfigKey := s.sysConfigService.CheckUniqueConfigKey(body.ConfigKey, "") if !uniqueConfigKey { // 参数配置新增【%s】失败,参数键名已存在 - msg := fmt.Sprintf("Parameter configuration add [%s] failed, parameter key name already exists", body.ConfigKey) + msg := i18n.TTemplate(language, "config.errKeyExists", map[string]any{"name": body.ConfigKey}) c.JSON(200, result.ErrMsg(msg)) return } @@ -89,10 +110,11 @@ func (s *SysConfigController) Add(c *gin.Context) { // // PUT / func (s *SysConfigController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysConfig err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.ConfigID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -100,7 +122,7 @@ func (s *SysConfigController) Edit(c *gin.Context) { uniqueConfigKey := s.sysConfigService.CheckUniqueConfigKey(body.ConfigKey, body.ConfigID) if !uniqueConfigKey { // 参数配置修改【%s】失败,参数键名已存在 - msg := fmt.Sprintf("Parameter configuration modification [%s] failed, parameter key name already exists", body.ConfigKey) + msg := i18n.TTemplate(language, "config.errKeyExists", map[string]any{"name": body.ConfigKey}) c.JSON(200, result.ErrMsg(msg)) return } @@ -109,7 +131,7 @@ func (s *SysConfigController) Edit(c *gin.Context) { config := s.sysConfigService.SelectConfigById(body.ConfigID) if config.ConfigID != body.ConfigID { // 没有可访问参数配置数据! - c.JSON(200, result.ErrMsg("There is no accessible parameter configuration data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "config.noData"))) return } @@ -126,9 +148,10 @@ func (s *SysConfigController) Edit(c *gin.Context) { // // DELETE /:configIds func (s *SysConfigController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) configIds := c.Param("configIds") if configIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -140,10 +163,10 @@ func (s *SysConfigController) Remove(c *gin.Context) { } rows, err := s.sysConfigService.DeleteConfigByIds(uniqueIDs) if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) return } - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -159,9 +182,10 @@ func (s *SysConfigController) RefreshCache(c *gin.Context) { // // GET /configKey/:configKey func (s *SysConfigController) ConfigKey(c *gin.Context) { + language := ctx.AcceptLanguage(c) configKey := c.Param("configKey") if configKey == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } key := s.sysConfigService.SelectConfigValueByKey(configKey) @@ -176,33 +200,45 @@ func (s *SysConfigController) ConfigKey(c *gin.Context) { // // POST /export func (s *SysConfigController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.sysConfigService.SelectConfigPage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysConfig) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysConfig) { + for i := range *arr { + (*arr)[i].ConfigName = i18n.TKey(language, (*arr)[i].ConfigName) + (*arr)[i].ConfigValue = i18n.TKey(language, (*arr)[i].ConfigValue) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("config_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "ConfigID", - "B1": "ConfigName", - "C1": "ConfigKey", - "D1": "ConfigValue", - "E1": "Type", + "A1": i18n.TKey(language, "config..export.id"), + "B1": i18n.TKey(language, "config..export.name"), + "C1": i18n.TKey(language, "config..export.key"), + "D1": i18n.TKey(language, "config..export.value"), + "E1": i18n.TKey(language, "config..export.type"), + "F1": i18n.TKey(language, "config..export.remark"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) - typeValue := "clogged" + typeValue := i18n.TKey(language, "dictData.no") if row.ConfigType == "Y" { - typeValue = "be" + typeValue = i18n.TKey(language, "dictData.yes") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.ConfigID, @@ -210,6 +246,7 @@ func (s *SysConfigController) Export(c *gin.Context) { "C" + idx: row.ConfigKey, "D" + idx: row.ConfigValue, "E" + idx: typeValue, + "F" + idx: row.Remark, }) } @@ -227,12 +264,13 @@ func (s *SysConfigController) Export(c *gin.Context) { // // PUT /changeConfigValue func (s *SysConfigController) ConfigValue(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { Key string `json:"key" binding:"required"` Value string `json:"value" binding:"required"` } if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -240,14 +278,14 @@ func (s *SysConfigController) ConfigValue(c *gin.Context) { info := s.sysConfigService.SelectConfigByKey(body.Key) if info.ConfigKey != body.Key { // 无效 key - c.JSON(200, result.ErrMsg("Invalid key")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "config.errKey"))) return } // 与旧值相等不变更 if info.ConfigValue == body.Value { // 变更状态与旧值相等! - c.JSON(200, result.ErrMsg("The change status is equal to the old value!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "config.errValueEq"))) return } info.ConfigValue = body.Value diff --git a/src/modules/system/controller/sys_dept.go b/src/modules/system/controller/sys_dept.go index db5f078..dedbddf 100644 --- a/src/modules/system/controller/sys_dept.go +++ b/src/modules/system/controller/sys_dept.go @@ -1,11 +1,12 @@ package controller import ( - "fmt" "strings" "ems.agt/src/framework/constants/common" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" + "ems.agt/src/framework/vo" "ems.agt/src/framework/vo/result" "ems.agt/src/modules/system/model" "ems.agt/src/modules/system/service" @@ -31,6 +32,7 @@ type SysDeptController struct { // // GET /list func (s *SysDeptController) List(c *gin.Context) { + language := ctx.AcceptLanguage(c) var querys struct { // 部门ID DeptID string `json:"deptId"` @@ -43,7 +45,7 @@ func (s *SysDeptController) List(c *gin.Context) { } err := c.ShouldBindQuery(&querys) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -55,6 +57,15 @@ func (s *SysDeptController) List(c *gin.Context) { } dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") data := s.sysDeptService.SelectDeptList(SysDeptController, dataScopeSQL) + + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysDept) { + for i := range *arr { + (*arr)[i].DeptName = i18n.TKey(language, (*arr)[i].DeptName) + } + } + converI18n(language, &data) + c.JSON(200, result.OkData(data)) } @@ -62,13 +73,16 @@ func (s *SysDeptController) List(c *gin.Context) { // // GET /:deptId func (s *SysDeptController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) deptId := c.Param("deptId") if deptId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysDeptService.SelectDeptById(deptId) if data.DeptID == deptId { + // 处理多语言 + data.DeptName = i18n.TKey(language, data.DeptName) c.JSON(200, result.OkData(data)) return } @@ -79,10 +93,11 @@ func (s *SysDeptController) Info(c *gin.Context) { // // POST / func (s *SysDeptController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysDept err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.DeptID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -91,18 +106,18 @@ func (s *SysDeptController) Add(c *gin.Context) { deptParent := s.sysDeptService.SelectDeptById(body.ParentID) if deptParent.DeptID != body.ParentID { // 没有可访问部门数据! - c.JSON(200, result.ErrMsg("There is no accessible sectoral data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dept.noData"))) return } if deptParent.Status == common.STATUS_NO { // 上级部门【%s】停用,不允许新增 - msg := fmt.Sprintf("Upper division [%s] deactivated, no new additions allowed", deptParent.DeptName) + msg := i18n.TTemplate(language, "dept.errParentStatus", map[string]any{"name": deptParent.DeptName}) c.JSON(200, result.ErrMsg(msg)) return } if deptParent.DelFlag == common.STATUS_YES { // 上级部门【%s】已删除,不允许新增 - msg := fmt.Sprintf("The parent department [%s] has been deleted and is not allowed to be added", deptParent.DeptName) + msg := i18n.TTemplate(language, "dept.errParentDelFlag", map[string]any{"name": deptParent.DeptName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -115,7 +130,7 @@ func (s *SysDeptController) Add(c *gin.Context) { uniqueDeptName := s.sysDeptService.CheckUniqueDeptName(body.DeptName, body.ParentID, "") if !uniqueDeptName { // 部门新增【%s】失败,部门名称已存在 - msg := fmt.Sprintf("Department add [%s] failed, department name already exists", body.DeptName) + msg := i18n.TTemplate(language, "dept.errNameExists", map[string]any{"name": body.DeptName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -133,17 +148,18 @@ func (s *SysDeptController) Add(c *gin.Context) { // // PUT / func (s *SysDeptController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysDept err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.DeptID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 上级部门不能选自己 if body.DeptID == body.ParentID { // 部门修改【%s】失败,上级部门不能是自己 - msg := fmt.Sprintf("Departmental modification [%s] failed, the parent department cannot be itself", body.DeptName) + msg := i18n.TTemplate(language, "dept.errParentID", map[string]any{"name": body.DeptName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -152,7 +168,7 @@ func (s *SysDeptController) Edit(c *gin.Context) { deptInfo := s.sysDeptService.SelectDeptById(body.DeptID) if deptInfo.DeptID != body.DeptID { // 没有可访问部门数据! - c.JSON(200, result.ErrMsg("There is no accessible sectoral data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dept.noData"))) return } // 父级ID不为0是要检查 @@ -160,7 +176,7 @@ func (s *SysDeptController) Edit(c *gin.Context) { deptParent := s.sysDeptService.SelectDeptById(body.ParentID) if deptParent.DeptID != body.ParentID { // 没有可访问部门数据! - c.JSON(200, result.ErrMsg("There is no accessible sectoral data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dept.noData"))) return } } @@ -169,7 +185,7 @@ func (s *SysDeptController) Edit(c *gin.Context) { uniqueDeptName := s.sysDeptService.CheckUniqueDeptName(body.DeptName, body.ParentID, body.DeptID) if !uniqueDeptName { // 部门修改【%s】失败,部门名称已存在 - msg := fmt.Sprintf("Department modification [%s] failed, department name already exists", body.DeptName) + msg := i18n.TTemplate(language, "dept.errNameExists", map[string]any{"name": body.DeptName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -179,7 +195,7 @@ func (s *SysDeptController) Edit(c *gin.Context) { hasChild := s.sysDeptService.HasChildByDeptId(body.DeptID) if hasChild > 0 { // 该部门包含未停用的子部门数量:%d - msg := fmt.Sprintf("Number of subsectors not deactivated included in this sector: %d", hasChild) + msg := i18n.TTemplate(language, "dept.errHasChildUse", map[string]any{"num": hasChild}) c.JSON(200, result.ErrMsg(msg)) return } @@ -198,9 +214,10 @@ func (s *SysDeptController) Edit(c *gin.Context) { // // DELETE /:deptId func (s *SysDeptController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) deptId := c.Param("deptId") if deptId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -208,7 +225,7 @@ func (s *SysDeptController) Remove(c *gin.Context) { dept := s.sysDeptService.SelectDeptById(deptId) if dept.DeptID != deptId { // 没有可访问部门数据! - c.JSON(200, result.ErrMsg("There is no accessible sectoral data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dept.noData"))) return } @@ -216,7 +233,7 @@ func (s *SysDeptController) Remove(c *gin.Context) { hasChild := s.sysDeptService.HasChildByDeptId(deptId) if hasChild > 0 { // 不允许删除,存在子部门数:%d - msg := fmt.Sprintf("Deletion not allowed, number of subsectors present: %d", hasChild) + msg := i18n.TTemplate(language, "dept.errHasChildUse", map[string]any{"num": hasChild}) c.JSON(200, result.ErrMsg(msg)) return } @@ -225,7 +242,7 @@ func (s *SysDeptController) Remove(c *gin.Context) { existUser := s.sysDeptService.CheckDeptExistUser(deptId) if existUser > 0 { // 不允许删除,部门已分配给用户数:%d - msg := fmt.Sprintf("Deletions are not allowed and the department has been assigned to the number of users: %d", existUser) + msg := i18n.TTemplate(language, "dept.errHasUserUse", map[string]any{"num": existUser}) c.JSON(200, result.ErrMsg(msg)) return } @@ -233,7 +250,7 @@ func (s *SysDeptController) Remove(c *gin.Context) { rows := s.sysDeptService.DeleteDeptById(deptId) if rows > 0 { // 删除成功:%d - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) return } @@ -244,9 +261,10 @@ func (s *SysDeptController) Remove(c *gin.Context) { // // GET /list/exclude/:deptId func (s *SysDeptController) ExcludeChild(c *gin.Context) { + language := ctx.AcceptLanguage(c) deptId := c.Param("deptId") if deptId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -265,6 +283,7 @@ func (s *SysDeptController) ExcludeChild(c *gin.Context) { } } if !(dept.DeptID == deptId || hasAncestor) { + dept.DeptName = i18n.TKey(language, dept.DeptName) filtered = append(filtered, dept) } } @@ -275,6 +294,7 @@ func (s *SysDeptController) ExcludeChild(c *gin.Context) { // // GET /treeSelect func (s *SysDeptController) TreeSelect(c *gin.Context) { + language := ctx.AcceptLanguage(c) var querys struct { // 部门ID DeptID string `json:"deptId"` @@ -287,7 +307,7 @@ func (s *SysDeptController) TreeSelect(c *gin.Context) { } err := c.ShouldBindQuery(&querys) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -298,23 +318,50 @@ func (s *SysDeptController) TreeSelect(c *gin.Context) { Status: querys.Status, } dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") - data := s.sysDeptService.SelectDeptTreeSelect(SysDeptController, dataScopeSQL) - c.JSON(200, result.OkData(data)) + deptTreeSelect := s.sysDeptService.SelectDeptTreeSelect(SysDeptController, dataScopeSQL) + + // 闭包函数处理多语言 + var converI18n func(language string, arr *[]vo.TreeSelect) + converI18n = func(language string, arr *[]vo.TreeSelect) { + for i := range *arr { + (*arr)[i].Label = i18n.TKey(language, (*arr)[i].Label) + if len((*arr)[i].Children) > 0 { + converI18n(language, &(*arr)[i].Children) + } + } + } + converI18n(language, &deptTreeSelect) + + c.JSON(200, result.OkData(deptTreeSelect)) } // 部门树结构列表(指定角色) // // GET /roleDeptTreeSelect/:roleId func (s *SysDeptController) RoleDeptTreeSelect(c *gin.Context) { + language := ctx.AcceptLanguage(c) roleId := c.Param("roleId") if roleId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") deptTreeSelect := s.sysDeptService.SelectDeptTreeSelect(model.SysDept{}, dataScopeSQL) checkedKeys := s.sysDeptService.SelectDeptListByRoleId(roleId) + + // 闭包函数处理多语言 + var converI18n func(language string, arr *[]vo.TreeSelect) + converI18n = func(language string, arr *[]vo.TreeSelect) { + for i := range *arr { + (*arr)[i].Label = i18n.TKey(language, (*arr)[i].Label) + if len((*arr)[i].Children) > 0 { + converI18n(language, &(*arr)[i].Children) + } + } + } + converI18n(language, &deptTreeSelect) + c.JSON(200, result.OkData(map[string]any{ "depts": deptTreeSelect, "checkedKeys": checkedKeys, diff --git a/src/modules/system/controller/sys_dict_data.go b/src/modules/system/controller/sys_dict_data.go index f4b391e..96ecd1e 100644 --- a/src/modules/system/controller/sys_dict_data.go +++ b/src/modules/system/controller/sys_dict_data.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/utils/parse" @@ -39,6 +40,21 @@ type SysDictDataController struct { func (s *SysDictDataController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.sysDictDataService.SelectDictDataPage(querys) + + rows := data["rows"].([]model.SysDictData) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysDictData) { + for i := range *arr { + if strings.Contains((*arr)[i].DictType, "i18n") { + continue + } + (*arr)[i].DictLabel = i18n.TKey(language, (*arr)[i].DictLabel) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -46,13 +62,19 @@ func (s *SysDictDataController) List(c *gin.Context) { // // GET /:dictCode func (s *SysDictDataController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) dictCode := c.Param("dictCode") if dictCode == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysDictDataService.SelectDictDataByCode(dictCode) if data.DictCode == dictCode { + // 处理多语言 + if !strings.Contains(data.DictType, "i18n") { + data.DictLabel = i18n.TKey(language, data.DictLabel) + data.Remark = i18n.TKey(language, data.Remark) + } c.JSON(200, result.OkData(data)) return } @@ -63,10 +85,11 @@ func (s *SysDictDataController) Info(c *gin.Context) { // // POST / func (s *SysDictDataController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysDictData err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.DictCode != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -74,7 +97,7 @@ func (s *SysDictDataController) Add(c *gin.Context) { sysDictType := s.sysDictTypeService.SelectDictTypeByType(body.DictType) if sysDictType.DictType != body.DictType { // 没有可访问字典类型数据! - c.JSON(200, result.ErrMsg("There is no accessible dictionary type data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dictType.noData"))) return } @@ -82,16 +105,7 @@ func (s *SysDictDataController) Add(c *gin.Context) { uniqueDictLabel := s.sysDictDataService.CheckUniqueDictLabel(body.DictType, body.DictLabel, "") if !uniqueDictLabel { // 数据新增【%s】失败,该字典类型下标签名已存在 - msg := fmt.Sprintf("Data addition [%s] failed, tag name already exists under this dictionary type", body.DictLabel) - c.JSON(200, result.ErrMsg(msg)) - return - } - - // 检查字典键值唯一 - uniqueDictValue := s.sysDictDataService.CheckUniqueDictValue(body.DictType, body.DictValue, "") - if !uniqueDictValue { - // 数据新增【%s】失败,该字典类型下标签值已存在 - msg := fmt.Sprintf("Data addition [%s] failed, tagged value already exists under this dictionary type", body.DictValue) + msg := i18n.TTemplate(language, "dictType.errLabelExists", map[string]any{"name": body.DictLabel}) c.JSON(200, result.ErrMsg(msg)) return } @@ -109,10 +123,11 @@ func (s *SysDictDataController) Add(c *gin.Context) { // // PUT / func (s *SysDictDataController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysDictData err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.DictCode == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -120,7 +135,7 @@ func (s *SysDictDataController) Edit(c *gin.Context) { sysDictType := s.sysDictTypeService.SelectDictTypeByType(body.DictType) if sysDictType.DictType != body.DictType { // 没有可访问字典类型数据! - c.JSON(200, result.ErrMsg("There is no accessible dictionary type data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dictType.noData"))) return } @@ -128,7 +143,7 @@ func (s *SysDictDataController) Edit(c *gin.Context) { SysDictDataController := s.sysDictDataService.SelectDictDataByCode(body.DictCode) if SysDictDataController.DictCode != body.DictCode { // 没有可访问字典编码数据! - c.JSON(200, result.ErrMsg("There is no accessible dictionary-encoded data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dictData.noData"))) return } @@ -136,16 +151,7 @@ func (s *SysDictDataController) Edit(c *gin.Context) { uniqueDictLabel := s.sysDictDataService.CheckUniqueDictLabel(body.DictType, body.DictLabel, body.DictCode) if !uniqueDictLabel { // 数据修改【%s】失败,该字典类型下标签名已存在 - msg := fmt.Sprintf("Data modification [%s] failed, tag name already exists under this dictionary type", body.DictLabel) - c.JSON(200, result.ErrMsg(msg)) - return - } - - // 检查字典键值唯一 - uniqueDictValue := s.sysDictDataService.CheckUniqueDictValue(body.DictType, body.DictValue, body.DictCode) - if !uniqueDictValue { - // 数据修改【%s】失败,该字典类型下标签值已存在 - msg := fmt.Sprintf("Data modification [%s] failed, tagged value already exists under this dictionary type", body.DictValue) + msg := i18n.TTemplate(language, "dictType.errLabelExists", map[string]any{"name": body.DictLabel}) c.JSON(200, result.ErrMsg(msg)) return } @@ -163,9 +169,10 @@ func (s *SysDictDataController) Edit(c *gin.Context) { // // DELETE /:dictCodes func (s *SysDictDataController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) dictCodes := c.Param("dictCodes") if dictCodes == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -181,7 +188,7 @@ func (s *SysDictDataController) Remove(c *gin.Context) { return } // 删除成功:%d - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -189,13 +196,24 @@ func (s *SysDictDataController) Remove(c *gin.Context) { // // GET /type/:dictType func (s *SysDictDataController) DictType(c *gin.Context) { + language := ctx.AcceptLanguage(c) dictType := c.Param("dictType") if dictType == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysDictDataService.SelectDictDataByType(dictType) + + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysDictData) { + for i := range *arr { + (*arr)[i].DictLabel = i18n.TKey(language, (*arr)[i].DictLabel) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &data) + c.JSON(200, result.OkData(data)) } @@ -203,34 +221,47 @@ func (s *SysDictDataController) DictType(c *gin.Context) { // // POST /export func (s *SysDictDataController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.sysDictDataService.SelectDictDataPage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysDictData) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysDictData) { + for i := range *arr { + if strings.Contains((*arr)[i].DictType, "i18n") { + continue + } + (*arr)[i].DictLabel = i18n.TKey(language, (*arr)[i].DictLabel) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("dict_data_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "DictCode", - "B1": "DictSort", - "C1": "DictLabel", - "D1": "DictValue", - "E1": "DictType", - "F1": "Status", + "A1": i18n.TKey(language, "dictData.export.code"), + "B1": i18n.TKey(language, "dictData.export.sort"), + "C1": i18n.TKey(language, "dictData.export.label"), + "D1": i18n.TKey(language, "dictData.export.value"), + "E1": i18n.TKey(language, "dictData.export.type"), + "F1": i18n.TKey(language, "dictData.export.status"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) - statusValue := "deactivate" + statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { - statusValue = "normalcy" + statusValue = i18n.TKey(language, "dictData.normal") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.DictCode, diff --git a/src/modules/system/controller/sys_dict_type.go b/src/modules/system/controller/sys_dict_type.go index 7f3bb3b..80b83a2 100644 --- a/src/modules/system/controller/sys_dict_type.go +++ b/src/modules/system/controller/sys_dict_type.go @@ -38,6 +38,18 @@ type SysDictTypeController struct { func (s *SysDictTypeController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.sysDictTypeService.SelectDictTypePage(querys) + + rows := data["rows"].([]model.SysDictType) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysDictType) { + for i := range *arr { + (*arr)[i].DictName = i18n.TKey(language, (*arr)[i].DictName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -45,13 +57,17 @@ func (s *SysDictTypeController) List(c *gin.Context) { // // GET /:dictId func (s *SysDictTypeController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) dictId := c.Param("dictId") if dictId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysDictTypeService.SelectDictTypeByID(dictId) if data.DictID == dictId { + // 处理多语言 + data.DictName = i18n.TKey(language, data.DictName) + data.Remark = i18n.TKey(language, data.Remark) c.JSON(200, result.OkData(data)) return } @@ -62,10 +78,11 @@ func (s *SysDictTypeController) Info(c *gin.Context) { // // POST / func (s *SysDictTypeController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysDictType err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.DictID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -73,7 +90,7 @@ func (s *SysDictTypeController) Add(c *gin.Context) { uniqueDictName := s.sysDictTypeService.CheckUniqueDictName(body.DictName, "") if !uniqueDictName { // 字典新增【%s】失败,字典名称已存在 - msg := fmt.Sprintf("Dictionary add [%s] failed, dictionary name already exists", body.DictName) + msg := i18n.TTemplate(language, "dictType.errNameExists", map[string]any{"name": body.DictName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -82,7 +99,7 @@ func (s *SysDictTypeController) Add(c *gin.Context) { uniqueDictType := s.sysDictTypeService.CheckUniqueDictType(body.DictType, "") if !uniqueDictType { // 字典新增【%s】失败,字典类型已存在 - msg := fmt.Sprintf("Dictionary add [%s] failed, dictionary type already exists", body.DictType) + msg := i18n.TTemplate(language, "dictType.errTypeExists", map[string]any{"name": body.DictName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -100,10 +117,11 @@ func (s *SysDictTypeController) Add(c *gin.Context) { // // PUT / func (s *SysDictTypeController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysDictType err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.DictID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -111,7 +129,7 @@ func (s *SysDictTypeController) Edit(c *gin.Context) { dictInfo := s.sysDictTypeService.SelectDictTypeByID(body.DictID) if dictInfo.DictID != body.DictID { // 没有可访问字典类型数据! - c.JSON(200, result.ErrMsg("There is no accessible dictionary type data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "dictType.noData"))) return } @@ -119,7 +137,7 @@ func (s *SysDictTypeController) Edit(c *gin.Context) { uniqueDictName := s.sysDictTypeService.CheckUniqueDictName(body.DictName, body.DictID) if !uniqueDictName { // 字典修改【%s】失败,字典名称已存在 - msg := fmt.Sprintf("Dictionary modification [%s] failed, dictionary name already exists", body.DictName) + msg := i18n.TTemplate(language, "dictType.errNameExists", map[string]any{"name": body.DictName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -128,7 +146,7 @@ func (s *SysDictTypeController) Edit(c *gin.Context) { uniqueDictType := s.sysDictTypeService.CheckUniqueDictType(body.DictType, body.DictID) if !uniqueDictType { // 字典修改【%s】失败,字典类型已存在 - msg := fmt.Sprintf("Dictionary modification [%s] failed, dictionary type already exists", body.DictType) + msg := i18n.TTemplate(language, "dictType.errTypeExists", map[string]any{"name": body.DictName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -146,9 +164,10 @@ func (s *SysDictTypeController) Edit(c *gin.Context) { // // DELETE /:dictIds func (s *SysDictTypeController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) dictIds := c.Param("dictIds") if dictIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -163,7 +182,7 @@ func (s *SysDictTypeController) Remove(c *gin.Context) { c.JSON(200, result.ErrMsg(err.Error())) return } - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -189,11 +208,12 @@ func (s *SysDictTypeController) DictOptionselect(c *gin.Context) { Value string `json:"value"` } + language := ctx.AcceptLanguage(c) // 数据组 arr := []labelValue{} for _, v := range data { arr = append(arr, labelValue{ - Label: v.DictName, + Label: i18n.TKey(language, v.DictName), Value: v.DictType, }) } @@ -204,32 +224,42 @@ func (s *SysDictTypeController) DictOptionselect(c *gin.Context) { // // POST /export func (s *SysDictTypeController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.sysDictTypeService.SelectDictTypePage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysDictType) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysDictType) { + for i := range *arr { + (*arr)[i].DictName = i18n.TKey(language, (*arr)[i].DictName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("dict_type_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "DictID", - "B1": "DictName", - "C1": "DictType", - "D1": "Status", + "A1": i18n.TKey(language, "dictType.export.id"), + "B1": i18n.TKey(language, "dictType.export.name"), + "C1": i18n.TKey(language, "dictType.export.type"), + "D1": i18n.TKey(language, "dictType.export.status"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) - statusValue := "deactivate" + statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { - statusValue = "normalcy" + statusValue = i18n.TKey(language, "dictData.normal") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.DictID, diff --git a/src/modules/system/controller/sys_log_login.go b/src/modules/system/controller/sys_log_login.go index ab7b5f1..4494103 100644 --- a/src/modules/system/controller/sys_log_login.go +++ b/src/modules/system/controller/sys_log_login.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/date" "ems.agt/src/framework/utils/file" @@ -40,6 +41,19 @@ type SysLogLoginController struct { func (s *SysLogLoginController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.sysLogLoginService.SelectSysLogLoginPage(querys) + + rows := data["rows"].([]model.SysLogLogin) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysLogLogin) { + for i := range *arr { + (*arr)[i].LoginLocation = i18n.TKey(language, (*arr)[i].LoginLocation) + (*arr)[i].OS = i18n.TKey(language, (*arr)[i].OS) + (*arr)[i].Browser = i18n.TKey(language, (*arr)[i].Browser) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -47,9 +61,10 @@ func (s *SysLogLoginController) List(c *gin.Context) { // // DELETE /:infoIds func (s *SysLogLoginController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) infoIds := c.Param("infoIds") if infoIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -62,7 +77,7 @@ func (s *SysLogLoginController) Remove(c *gin.Context) { } rows := s.sysLogLoginService.DeleteSysLogLoginByIds(uniqueIDs) if rows > 0 { - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) return } @@ -85,9 +100,10 @@ func (s *SysLogLoginController) Clean(c *gin.Context) { // // PUT /unlock/:userName func (s *SysLogLoginController) Unlock(c *gin.Context) { + language := ctx.AcceptLanguage(c) userName := c.Param("userName") if userName == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } ok := s.accountService.ClearLoginRecordCache(userName) @@ -95,45 +111,56 @@ func (s *SysLogLoginController) Unlock(c *gin.Context) { c.JSON(200, result.Ok(nil)) return } - c.JSON(200, result.ErrMsg("unlatched")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errUnlock"))) } // 导出系统登录日志信息 // // POST /export func (s *SysLogLoginController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.sysLogLoginService.SelectSysLogLoginPage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysLogLogin) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysLogLogin) { + for i := range *arr { + (*arr)[i].LoginLocation = i18n.TKey(language, (*arr)[i].LoginLocation) + (*arr)[i].OS = i18n.TKey(language, (*arr)[i].OS) + (*arr)[i].Browser = i18n.TKey(language, (*arr)[i].Browser) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("sys_log_login_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "ID", - "B1": "UserName", - "C1": "Status", - "D1": "IP", - "E1": "Location", - "F1": "Browser", - "G1": "OS", - "H1": "Msg", - "I1": "Time", + "A1": i18n.TKey(language, "log.login.export.id"), + "B1": i18n.TKey(language, "log.login.export.userName"), + "C1": i18n.TKey(language, "log.login.export.status"), + "D1": i18n.TKey(language, "log.login.export.ip"), + "E1": i18n.TKey(language, "log.login.export.location"), + "F1": i18n.TKey(language, "log.login.export.browser"), + "G1": i18n.TKey(language, "log.login.export.os"), + "H1": i18n.TKey(language, "log.login.export.msg"), + "I1": i18n.TKey(language, "log.login.export.time"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) // 状态 - statusValue := "fail" + statusValue := i18n.TKey(language, "dictData.fail") if row.Status == "1" { - statusValue = "successes" + statusValue = i18n.TKey(language, "dictData.success") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.LoginID, diff --git a/src/modules/system/controller/sys_log_operate.go b/src/modules/system/controller/sys_log_operate.go index 37e2e3e..ffedb36 100644 --- a/src/modules/system/controller/sys_log_operate.go +++ b/src/modules/system/controller/sys_log_operate.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/date" "ems.agt/src/framework/utils/file" @@ -36,6 +37,18 @@ type SysLogOperateController struct { func (s *SysLogOperateController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.SysLogOperateService.SelectSysLogOperatePage(querys) + + rows := data["rows"].([]model.SysLogOperate) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysLogOperate) { + for i := range *arr { + (*arr)[i].Title = i18n.TKey(language, (*arr)[i].Title) + (*arr)[i].OperLocation = i18n.TKey(language, (*arr)[i].OperLocation) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -43,9 +56,10 @@ func (s *SysLogOperateController) List(c *gin.Context) { // // DELETE /:operIds func (s *SysLogOperateController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) operIds := c.Param("operIds") if operIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -58,7 +72,7 @@ func (s *SysLogOperateController) Remove(c *gin.Context) { } rows := s.SysLogOperateService.DeleteSysLogOperateByIds(uniqueIDs) if rows > 0 { - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) return } @@ -81,36 +95,46 @@ func (s *SysLogOperateController) Clean(c *gin.Context) { // // POST /export func (s *SysLogOperateController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.SysLogOperateService.SelectSysLogOperatePage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysLogOperate) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysLogOperate) { + for i := range *arr { + (*arr)[i].Title = i18n.TKey(language, (*arr)[i].Title) + (*arr)[i].OperLocation = i18n.TKey(language, (*arr)[i].OperLocation) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("sys_log_operate_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "ID", - "B1": "Title", - "C1": "BusinessType", - "D1": "Method", - "E1": "RequestMethod", - "F1": "OperatorType", - "G1": "OperName", - "H1": "DeptName", - "I1": "URL", - "J1": "IP", - "K1": "Location", - "L1": "Param", - "M1": "Msg", - "N1": "Status", - "O1": "CostTime (ms)", - "P1": "OperTime", + "A1": i18n.TKey(language, "log.operate.export.id"), + "B1": i18n.TKey(language, "log.operate.export.title"), + "C1": i18n.TKey(language, "log.operate.export.businessType"), + "D1": i18n.TKey(language, "log.operate.export.method"), + "E1": i18n.TKey(language, "log.operate.export.requestMethod"), + "F1": i18n.TKey(language, "log.operate.export.operatorType"), + "G1": i18n.TKey(language, "log.operate.export.operName"), + "H1": i18n.TKey(language, "log.operate.export.deptName"), + "I1": i18n.TKey(language, "log.operate.export.url"), + "J1": i18n.TKey(language, "log.operate.export.ip"), + "K1": i18n.TKey(language, "log.operate.export.location"), + "L1": i18n.TKey(language, "log.operate.export.param"), + "M1": i18n.TKey(language, "log.operate.export.msg"), + "N1": i18n.TKey(language, "log.operate.export.status"), + "O1": i18n.TKey(language, "log.operate.export.costTime"), + "P1": i18n.TKey(language, "log.operate.export.operTime"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) @@ -121,9 +145,9 @@ func (s *SysLogOperateController) Export(c *gin.Context) { // 操作类别 operatorType := "" // 状态 - statusValue := "fail" + statusValue := i18n.TKey(language, "dictData.fail") if row.Status == "1" { - statusValue = "success" + statusValue = i18n.TKey(language, "dictData.success") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.OperID, diff --git a/src/modules/system/controller/sys_menu.go b/src/modules/system/controller/sys_menu.go index 27427a2..47bacdb 100644 --- a/src/modules/system/controller/sys_menu.go +++ b/src/modules/system/controller/sys_menu.go @@ -1,13 +1,13 @@ package controller import ( - "fmt" - "ems.agt/src/framework/config" "ems.agt/src/framework/constants/common" "ems.agt/src/framework/constants/menu" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/regular" + "ems.agt/src/framework/vo" "ems.agt/src/framework/vo/result" "ems.agt/src/modules/system/model" "ems.agt/src/modules/system/service" @@ -46,6 +46,21 @@ func (s *SysMenuController) List(c *gin.Context) { userId = "*" } data := s.sysMenuService.SelectMenuList(query, userId) + + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + var converI18n func(language string, arr *[]model.SysMenu) + converI18n = func(language string, arr *[]model.SysMenu) { + for i := range *arr { + (*arr)[i].MenuName = i18n.TKey(language, (*arr)[i].MenuName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + if len((*arr)[i].Children) > 0 { + converI18n(language, &(*arr)[i].Children) + } + } + } + converI18n(language, &data) + c.JSON(200, result.OkData(data)) } @@ -53,13 +68,17 @@ func (s *SysMenuController) List(c *gin.Context) { // // GET /:menuId func (s *SysMenuController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) menuId := c.Param("menuId") if menuId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysMenuService.SelectMenuById(menuId) if data.MenuID == menuId { + // 处理多语言 + data.MenuName = i18n.TKey(language, data.MenuName) + data.Remark = i18n.TKey(language, data.Remark) c.JSON(200, result.OkData(data)) return } @@ -70,10 +89,11 @@ func (s *SysMenuController) Info(c *gin.Context) { // // POST / func (s *SysMenuController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysMenu err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.MenuID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -82,7 +102,7 @@ func (s *SysMenuController) Add(c *gin.Context) { uniqueNenuPath := s.sysMenuService.CheckUniqueMenuPath(body.Path, body.ParentID, "") if !uniqueNenuPath { // 菜单新增【%s】失败,菜单路由地址已存在 - msg := fmt.Sprintf("Menu add [%s] failed, menu routing address already exists", body.MenuName) + msg := i18n.TTemplate(language, "menu.errPathExists", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -92,15 +112,15 @@ func (s *SysMenuController) Add(c *gin.Context) { uniqueNenuName := s.sysMenuService.CheckUniqueMenuName(body.MenuName, body.ParentID, "") if !uniqueNenuName { // 菜单新增【%s】失败,菜单名称已存在 - msg := fmt.Sprintf("Menu add [%s] failed, menu name already exists", body.MenuName) + msg := i18n.TTemplate(language, "menu.errNameExists", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } // 外链菜单需要符合网站http(s)开头 if body.IsFrame == common.STATUS_NO && !regular.ValidHttp(body.Path) { - // 菜单新增【%s】失败,非内部地址必须以http(s)://开头 - msg := fmt.Sprintf("Menu adds [%s] failure, non-internal addresses must start with http(s)://", body.MenuName) + // 操作菜单【{name}】失败,非内部地址请以http(s)://开头 + msg := i18n.TTemplate(language, "menu.errFramePath", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -118,17 +138,18 @@ func (s *SysMenuController) Add(c *gin.Context) { // // PUT / func (s *SysMenuController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysMenu err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.MenuID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 上级菜单不能选自己 if body.MenuID == body.ParentID { // 菜单修改【%s】失败,上级菜单不能选择自己 - msg := fmt.Sprintf("Menu modification [%s] fails, the parent menu cannot select itself", body.MenuName) + msg := i18n.TTemplate(language, "menu.errPathExists", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -136,21 +157,22 @@ func (s *SysMenuController) Edit(c *gin.Context) { // 检查数据是否存在 menuInfo := s.sysMenuService.SelectMenuById(body.MenuID) if menuInfo.MenuID != body.MenuID { - // 没有可访问菜单数据 - c.JSON(200, result.ErrMsg("No accessible menu data")) + // 没有可访问菜单数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "menu.noData"))) return } // 父级ID不为0是要检查 if body.ParentID != "0" { menuParent := s.sysMenuService.SelectMenuById(body.ParentID) if menuParent.MenuID != body.ParentID { - c.JSON(200, result.ErrMsg("No accessible menu data")) + // 没有可访问菜单数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "menu.noData"))) return } // 禁用菜单时检查父菜单是否使用 if body.Status == common.STATUS_YES && menuParent.Status == common.STATUS_NO { // 上级菜单未启用! - c.JSON(200, result.ErrMsg("The parent menu is not enabled!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "menu.errParentStatus"))) return } } @@ -160,7 +182,7 @@ func (s *SysMenuController) Edit(c *gin.Context) { uniqueNenuPath := s.sysMenuService.CheckUniqueMenuPath(body.Path, body.ParentID, body.MenuID) if !uniqueNenuPath { // 菜单修改【%s】失败,菜单路由地址已存在 - msg := fmt.Sprintf("Menu modification [%s] failed, menu routing address already exists", body.MenuName) + msg := i18n.TTemplate(language, "menu.errPathExists", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -170,7 +192,7 @@ func (s *SysMenuController) Edit(c *gin.Context) { uniqueNenuName := s.sysMenuService.CheckUniqueMenuName(body.MenuName, body.ParentID, body.MenuID) if !uniqueNenuName { // 菜单修改【%s】失败,菜单名称已存在 - msg := fmt.Sprintf("Menu modification [%s] failed, menu name already exists", body.MenuName) + msg := i18n.TTemplate(language, "menu.errNameExists", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -178,7 +200,7 @@ func (s *SysMenuController) Edit(c *gin.Context) { // 外链菜单需要符合网站http(s)开头 if body.IsFrame == common.STATUS_NO && !regular.ValidHttp(body.Path) { // 菜单修改【%s】失败,非内部地址必须以http(s)://开头 - msg := fmt.Sprintf("Menu change [%s] failed, non-internal address must start with http(s)://", body.MenuName) + msg := i18n.TTemplate(language, "menu.errFramePath", map[string]any{"name": body.MenuName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -187,8 +209,8 @@ func (s *SysMenuController) Edit(c *gin.Context) { if body.Status == common.STATUS_NO { hasStatus := s.sysMenuService.HasChildByMenuIdAndStatus(body.MenuID, common.STATUS_YES) if hasStatus > 0 { - // 不允许禁用,存在使用子菜单数:%d - msg := fmt.Sprintf("Disabling is not allowed, number of submenus present for use: %d", hasStatus) + // 操作菜单【%s】失败,存在使用子菜单数:%d + msg := i18n.TTemplate(language, "menu.errHasChildUse", map[string]any{"name": body.MenuName, "num": hasStatus}) c.JSON(200, result.ErrMsg(msg)) return } @@ -207,9 +229,10 @@ func (s *SysMenuController) Edit(c *gin.Context) { // // DELETE /:menuId func (s *SysMenuController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) menuId := c.Param("menuId") if menuId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -217,7 +240,7 @@ func (s *SysMenuController) Remove(c *gin.Context) { menu := s.sysMenuService.SelectMenuById(menuId) if menu.MenuID != menuId { // 没有可访问菜单数据! - c.JSON(200, result.ErrMsg("There is no accessible menu data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "menu.noData"))) return } @@ -225,7 +248,7 @@ func (s *SysMenuController) Remove(c *gin.Context) { hasChild := s.sysMenuService.HasChildByMenuIdAndStatus(menuId, "") if hasChild > 0 { // 不允许删除,存在子菜单数:%d - msg := fmt.Sprintf("Deletion not allowed, number of submenus present: %d", hasChild) + msg := i18n.TTemplate(language, "menu.errHasChildUse", map[string]any{"name": menu.MenuName, "num": hasChild}) c.JSON(200, result.ErrMsg(msg)) return } @@ -234,14 +257,14 @@ func (s *SysMenuController) Remove(c *gin.Context) { existRole := s.sysMenuService.CheckMenuExistRole(menuId) if existRole > 0 { // 不允许删除,菜单已分配给角色数:%d - msg := fmt.Sprintf("Deletion not allowed, number of roles assigned to the menu: %d", existRole) + msg := i18n.TTemplate(language, "menu.errHasRoleUse", map[string]any{"name": menu.MenuName, "num": existRole}) c.JSON(200, result.ErrMsg(msg)) return } rows := s.sysMenuService.DeleteMenuById(menuId) if rows > 0 { - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) return } @@ -265,6 +288,20 @@ func (s *SysMenuController) TreeSelect(c *gin.Context) { userId = "*" } data := s.sysMenuService.SelectMenuTreeSelectByUserId(query, userId) + + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + var converI18n func(language string, arr *[]vo.TreeSelect) + converI18n = func(language string, arr *[]vo.TreeSelect) { + for i := range *arr { + (*arr)[i].Label = i18n.TKey(language, (*arr)[i].Label) + if len((*arr)[i].Children) > 0 { + converI18n(language, &(*arr)[i].Children) + } + } + } + converI18n(language, &data) + c.JSON(200, result.OkData(data)) } @@ -273,9 +310,10 @@ func (s *SysMenuController) TreeSelect(c *gin.Context) { // // GET /roleMenuTreeSelect/:roleId func (s *SysMenuController) RoleMenuTreeSelect(c *gin.Context) { + language := ctx.AcceptLanguage(c) roleId := c.Param("roleId") if roleId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -293,6 +331,19 @@ func (s *SysMenuController) RoleMenuTreeSelect(c *gin.Context) { } menuTreeSelect := s.sysMenuService.SelectMenuTreeSelectByUserId(query, userId) checkedKeys := s.sysMenuService.SelectMenuListByRoleId(roleId) + + // 闭包函数处理多语言 + var converI18n func(language string, arr *[]vo.TreeSelect) + converI18n = func(language string, arr *[]vo.TreeSelect) { + for i := range *arr { + (*arr)[i].Label = i18n.TKey(language, (*arr)[i].Label) + if len((*arr)[i].Children) > 0 { + converI18n(language, &(*arr)[i].Children) + } + } + } + converI18n(language, &menuTreeSelect) + c.JSON(200, result.OkData(map[string]any{ "menus": menuTreeSelect, "checkedKeys": checkedKeys, diff --git a/src/modules/system/controller/sys_post.go b/src/modules/system/controller/sys_post.go index fd97121..65ca408 100644 --- a/src/modules/system/controller/sys_post.go +++ b/src/modules/system/controller/sys_post.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/utils/parse" @@ -36,6 +37,18 @@ type SysPostController struct { func (s *SysPostController) List(c *gin.Context) { querys := ctx.QueryMap(c) data := s.sysPostService.SelectPostPage(querys) + + rows := data["rows"].([]model.SysPost) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysPost) { + for i := range *arr { + (*arr)[i].PostName = i18n.TKey(language, (*arr)[i].PostName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -43,13 +56,17 @@ func (s *SysPostController) List(c *gin.Context) { // // GET /:postId func (s *SysPostController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) postId := c.Param("postId") if postId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysPostService.SelectPostById(postId) if data.PostID == postId { + // 处理多语言 + data.PostName = i18n.TKey(language, data.PostName) + data.Remark = i18n.TKey(language, data.Remark) c.JSON(200, result.OkData(data)) return } @@ -60,10 +77,11 @@ func (s *SysPostController) Info(c *gin.Context) { // // POST / func (s *SysPostController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysPost err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.PostID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -71,7 +89,7 @@ func (s *SysPostController) Add(c *gin.Context) { uniqueuPostName := s.sysPostService.CheckUniquePostName(body.PostName, "") if !uniqueuPostName { // 岗位新增【%s】失败,岗位名称已存在 - msg := fmt.Sprintf("Job addition [%s] failed, job name already exists", body.PostName) + msg := i18n.TTemplate(language, "post.errNameExists", map[string]any{"name": body.PostName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -80,7 +98,7 @@ func (s *SysPostController) Add(c *gin.Context) { uniquePostCode := s.sysPostService.CheckUniquePostCode(body.PostCode, "") if !uniquePostCode { // 岗位新增【%s】失败,岗位编码已存在 - msg := fmt.Sprintf("Job addition [%s] failed, job code already exists", body.PostCode) + msg := i18n.TTemplate(language, "post.errCodeExists", map[string]any{"name": body.PostCode}) c.JSON(200, result.ErrMsg(msg)) return } @@ -98,10 +116,11 @@ func (s *SysPostController) Add(c *gin.Context) { // // PUT / func (s *SysPostController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysPost err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.PostID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -109,7 +128,7 @@ func (s *SysPostController) Edit(c *gin.Context) { post := s.sysPostService.SelectPostById(body.PostID) if post.PostID != body.PostID { // 没有可访问岗位数据! - c.JSON(200, result.ErrMsg("There is no accessible post data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "post.noData"))) return } @@ -117,7 +136,7 @@ func (s *SysPostController) Edit(c *gin.Context) { uniqueuPostName := s.sysPostService.CheckUniquePostName(body.PostName, body.PostID) if !uniqueuPostName { // 岗位修改【%s】失败,岗位名称已存在 - msg := fmt.Sprintf("Post modification [%s] failed, post name already exists", body.PostName) + msg := i18n.TTemplate(language, "post.errNameExists", map[string]any{"name": body.PostName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -126,7 +145,7 @@ func (s *SysPostController) Edit(c *gin.Context) { uniquePostCode := s.sysPostService.CheckUniquePostCode(body.PostCode, body.PostID) if !uniquePostCode { // 岗位修改【%s】失败,岗位编码已存在 - msg := fmt.Sprintf("Post modification [%s] failed, post code already exists", body.PostCode) + msg := i18n.TTemplate(language, "post.errCodeExists", map[string]any{"name": body.PostCode}) c.JSON(200, result.ErrMsg(msg)) return } @@ -144,9 +163,10 @@ func (s *SysPostController) Edit(c *gin.Context) { // // DELETE /:postIds func (s *SysPostController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) postIds := c.Param("postIds") if postIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -161,7 +181,7 @@ func (s *SysPostController) Remove(c *gin.Context) { c.JSON(200, result.ErrMsg(err.Error())) return } - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -169,33 +189,43 @@ func (s *SysPostController) Remove(c *gin.Context) { // // POST /export func (s *SysPostController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) data := s.sysPostService.SelectPostPage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysPost) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysPost) { + for i := range *arr { + (*arr)[i].PostName = i18n.TKey(language, (*arr)[i].PostName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("post_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "PostID", - "B1": "PostCode", - "C1": "PostName", - "D1": "PostSort", - "E1": "Status", + "A1": i18n.TKey(language, "post.export.id"), + "B1": i18n.TKey(language, "post.export.code"), + "C1": i18n.TKey(language, "post.export.name"), + "D1": i18n.TKey(language, "post.export.sort"), + "E1": i18n.TKey(language, "post.export.status"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) - statusValue := "deactivate" + statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { - statusValue = "normalcy" + statusValue = i18n.TKey(language, "dictData.normal") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.PostID, diff --git a/src/modules/system/controller/sys_profile.go b/src/modules/system/controller/sys_profile.go index 195c981..e094102 100644 --- a/src/modules/system/controller/sys_profile.go +++ b/src/modules/system/controller/sys_profile.go @@ -1,11 +1,10 @@ package controller import ( - "fmt" - "ems.agt/src/framework/config" "ems.agt/src/framework/constants/admin" "ems.agt/src/framework/constants/uploadsubpath" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/crypto" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" @@ -46,9 +45,10 @@ type SysProfileController struct { // // GET / func (s *SysProfileController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) loginUser, err := ctx.LoginUser(c) if err != nil { - c.JSON(401, result.CodeMsg(401, err.Error())) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error()))) return } @@ -56,20 +56,26 @@ func (s *SysProfileController) Info(c *gin.Context) { roleGroup := []string{} roles := s.sysRoleService.SelectRoleListByUserId(loginUser.UserID) for _, role := range roles { - roleGroup = append(roleGroup, role.RoleName) + roleGroup = append(roleGroup, i18n.TKey(language, role.RoleName)) } isAdmin := config.IsAdmin(loginUser.UserID) if isAdmin { - roleGroup = append(roleGroup, "Administrator") + roleGroup = append(roleGroup, i18n.TKey(language, "role.admin")) } // 查询用户所属岗位组 postGroup := []string{} posts := s.sysPostService.SelectPostListByUserId(loginUser.UserID) for _, post := range posts { - postGroup = append(postGroup, post.PostName) + postGroup = append(postGroup, i18n.TKey(language, post.PostName)) } + loginUser.User.NickName = i18n.TKey(language, loginUser.User.NickName) + loginUser.User.Remark = i18n.TKey(language, loginUser.User.Remark) + loginUser.User.Dept.DeptName = i18n.TKey(language, loginUser.User.Dept.DeptName) + for ri := range loginUser.User.Roles { + loginUser.User.Roles[ri].RoleName = i18n.TKey(language, loginUser.User.Roles[ri].RoleName) + } c.JSON(200, result.OkData(map[string]any{ "user": loginUser.User, "roleGroup": parse.RemoveDuplicates(roleGroup), @@ -81,6 +87,7 @@ func (s *SysProfileController) Info(c *gin.Context) { // // PUT / func (s *SysProfileController) UpdateProfile(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 昵称 NickName string `json:"nickName" binding:"required"` @@ -93,14 +100,14 @@ func (s *SysProfileController) UpdateProfile(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.Sex == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 登录用户信息 loginUser, err := ctx.LoginUser(c) if err != nil { - c.JSON(401, result.CodeMsg(401, err.Error())) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error()))) return } userId := loginUser.UserID @@ -112,13 +119,13 @@ func (s *SysProfileController) UpdateProfile(c *gin.Context) { uniquePhone := s.sysUserService.CheckUniquePhone(body.PhoneNumber, userId) if !uniquePhone { // 修改用户【%s】失败,手机号码已存在 - msg := fmt.Sprintf("Failed to modify user [%s], cell phone number already exists", userName) + msg := i18n.TTemplate(language, "user.errPhoneExists", map[string]any{"name": userName}) c.JSON(200, result.ErrMsg(msg)) return } } else { // 修改用户【%s】失败,手机号码格式错误 - msg := fmt.Sprintf("Failed to modify user [%s], wrong format of cell phone number", userName) + msg := i18n.TTemplate(language, "user.errPhoneFormat", map[string]any{"name": userName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -130,13 +137,13 @@ func (s *SysProfileController) UpdateProfile(c *gin.Context) { uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, userId) if !uniqueEmail { // 修改用户【%s】失败,邮箱已存在 - msg := fmt.Sprintf("Failed to modify user [%s], mailbox already exists", userName) + msg := i18n.TTemplate(language, "user.errEmailExists", map[string]any{"name": userName}) c.JSON(200, result.ErrMsg(msg)) return } } else { // 修改用户【%s】失败,邮箱格式错误 - msg := fmt.Sprintf("Failed to modify user [%s], mailbox format error", userName) + msg := i18n.TTemplate(language, "user.errEmailFormat", map[string]any{"name": userName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -169,14 +176,14 @@ func (s *SysProfileController) UpdateProfile(c *gin.Context) { c.JSON(200, result.Ok(nil)) return } - // 上传图片异常 - c.JSON(200, result.ErrMsg("Upload Image Exception")) + c.JSON(200, result.Err(nil)) } // 个人重置密码 // // PUT /updatePwd func (s *SysProfileController) UpdatePwd(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 旧密码 OldPassword string `json:"oldPassword" binding:"required"` @@ -185,14 +192,14 @@ func (s *SysProfileController) UpdatePwd(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 登录用户信息 loginUser, err := ctx.LoginUser(c) if err != nil { - c.JSON(401, result.CodeMsg(401, err.Error())) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error()))) return } userId := loginUser.UserID @@ -202,7 +209,7 @@ func (s *SysProfileController) UpdatePwd(c *gin.Context) { user := s.sysUserService.SelectUserById(userId) if user.UserID != userId { // 没有可访问用户数据! - c.JSON(200, result.ErrMsg("There is no accessible user data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.noData"))) return } @@ -210,13 +217,13 @@ func (s *SysProfileController) UpdatePwd(c *gin.Context) { oldCompare := crypto.BcryptCompare(body.OldPassword, user.Password) if !oldCompare { // 修改密码失败,旧密码错误 - c.JSON(200, result.ErrMsg("Failed to change password, old password is wrong")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.errPasswdOld"))) return } newCompare := crypto.BcryptCompare(body.NewPassword, user.Password) if newCompare { // 新密码不能与旧密码相同 - c.JSON(200, result.ErrMsg("The new password cannot be the same as the old one")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.errPasswdEqOld"))) return } @@ -238,9 +245,10 @@ func (s *SysProfileController) UpdatePwd(c *gin.Context) { // // POST /avatar func (s *SysProfileController) Avatar(c *gin.Context) { + language := ctx.AcceptLanguage(c) formFile, err := c.FormFile("file") if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -254,7 +262,7 @@ func (s *SysProfileController) Avatar(c *gin.Context) { // 登录用户信息 loginUser, err := ctx.LoginUser(c) if err != nil { - c.JSON(401, result.CodeMsg(401, err.Error())) + c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error()))) return } diff --git a/src/modules/system/controller/sys_role.go b/src/modules/system/controller/sys_role.go index dc94a1c..c27e25a 100644 --- a/src/modules/system/controller/sys_role.go +++ b/src/modules/system/controller/sys_role.go @@ -7,7 +7,7 @@ import ( "time" "ems.agt/src/framework/constants/admin" - "ems.agt/src/framework/constants/roledatascope" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/utils/parse" @@ -21,8 +21,9 @@ import ( // 实例化控制层 SysRoleController 结构体 var NewSysRole = &SysRoleController{ - sysRoleService: service.NewSysRoleImpl, - sysUserService: service.NewSysUserImpl, + sysRoleService: service.NewSysRoleImpl, + sysUserService: service.NewSysUserImpl, + sysDictDataService: service.NewSysDictDataImpl, } // 角色信息 @@ -33,6 +34,8 @@ type SysRoleController struct { sysRoleService service.ISysRole // 用户服务 sysUserService service.ISysUser + // 字典数据服务 + sysDictDataService service.ISysDictData } // 角色列表 @@ -42,6 +45,18 @@ func (s *SysRoleController) List(c *gin.Context) { querys := ctx.QueryMap(c) dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL) + + rows := data["rows"].([]model.SysRole) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysRole) { + for i := range *arr { + (*arr)[i].RoleName = i18n.TKey(language, (*arr)[i].RoleName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -49,13 +64,16 @@ func (s *SysRoleController) List(c *gin.Context) { // // GET /:roleId func (s *SysRoleController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) roleId := c.Param("roleId") if roleId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } data := s.sysRoleService.SelectRoleById(roleId) if data.RoleID == roleId { + data.RoleName = i18n.TKey(language, data.RoleName) + data.Remark = i18n.TKey(language, data.Remark) c.JSON(200, result.OkData(data)) return } @@ -66,10 +84,11 @@ func (s *SysRoleController) Info(c *gin.Context) { // // POST / func (s *SysRoleController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysRole err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.RoleID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -77,7 +96,7 @@ func (s *SysRoleController) Add(c *gin.Context) { uniqueRoleName := s.sysRoleService.CheckUniqueRoleName(body.RoleName, "") if !uniqueRoleName { // 角色新增【%s】失败,角色名称已存在 - msg := fmt.Sprintf("Character addition [%s] failed, character name already exists", body.RoleName) + msg := i18n.TTemplate(language, "role.errNameExists", map[string]any{"name": body.RoleName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -86,7 +105,7 @@ func (s *SysRoleController) Add(c *gin.Context) { uniqueRoleKey := s.sysRoleService.CheckUniqueRoleKey(body.RoleKey, "") if !uniqueRoleKey { // 角色新增【%s】失败,角色键值已存在 - msg := fmt.Sprintf("Character addition [%s] failed, character key already exists", body.RoleName) + msg := i18n.TTemplate(language, "role.errKeyExists", map[string]any{"name": body.RoleName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -104,17 +123,18 @@ func (s *SysRoleController) Add(c *gin.Context) { // // PUT / func (s *SysRoleController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysRole err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.RoleID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员角色 if body.RoleID == admin.ROLE_ID { // 不允许操作管理员角色 - c.JSON(200, result.ErrMsg("The administrator role is not allowed to operate")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateRole"))) return } @@ -122,15 +142,16 @@ func (s *SysRoleController) Edit(c *gin.Context) { role := s.sysRoleService.SelectRoleById(body.RoleID) if role.RoleID != body.RoleID { // 没有可访问角色数据! - c.JSON(200, result.ErrMsg("There is no accessible role data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "role.noData"))) return } // 判断角色名称是否唯一 uniqueRoleName := s.sysRoleService.CheckUniqueRoleName(body.RoleName, body.RoleID) if !uniqueRoleName { - // 角色修改【%s】失败,角色名称已存在 - msg := fmt.Sprintf("Character modification [%s] failed, character name already exists", body.RoleName) + // 操作角色【%s】失败,角色名称已存在 + // msg := fmt.Sprintf("Character modification [%s] failed, character name already exists", body.RoleName) + msg := i18n.TTemplate(language, "role.errNameExists", map[string]any{"name": body.RoleName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -139,7 +160,8 @@ func (s *SysRoleController) Edit(c *gin.Context) { uniqueRoleKey := s.sysRoleService.CheckUniqueRoleKey(body.RoleKey, body.RoleID) if !uniqueRoleKey { // 角色修改【%s】失败,角色键值已存在 - msg := fmt.Sprintf("Character modification [%s] failed, character key already exists", body.RoleName) + // msg := fmt.Sprintf("Character modification [%s] failed, character key already exists", body.RoleName) + msg := i18n.TTemplate(language, "role.errKeyExists", map[string]any{"name": body.RoleName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -157,9 +179,10 @@ func (s *SysRoleController) Edit(c *gin.Context) { // // DELETE /:roleIds func (s *SysRoleController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) roleIds := c.Param("roleIds") if roleIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -173,7 +196,7 @@ func (s *SysRoleController) Remove(c *gin.Context) { for _, id := range uniqueIDs { if id == admin.ROLE_ID { // 不允许操作管理员角色 - c.JSON(200, result.ErrMsg("The administrator role is not allowed to operate")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateRole"))) return } } @@ -182,7 +205,7 @@ func (s *SysRoleController) Remove(c *gin.Context) { c.JSON(200, result.ErrMsg(err.Error())) return } - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -190,6 +213,7 @@ func (s *SysRoleController) Remove(c *gin.Context) { // // PUT /changeStatus func (s *SysRoleController) Status(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 角色ID RoleID string `json:"roleId" binding:"required"` @@ -198,14 +222,14 @@ func (s *SysRoleController) Status(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员角色 if body.RoleID == admin.ROLE_ID { // 不允许操作管理员角色 - c.JSON(200, result.ErrMsg("The administrator role is not allowed to operate")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateRole"))) return } @@ -213,14 +237,14 @@ func (s *SysRoleController) Status(c *gin.Context) { role := s.sysRoleService.SelectRoleById(body.RoleID) if role.RoleID != body.RoleID { // 没有可访问角色数据! - c.JSON(200, result.ErrMsg("There is no accessible role data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "role.noData"))) return } // 与旧值相等不变更 if role.Status == body.Status { // 变更状态与旧值相等! - c.JSON(200, result.ErrMsg("The change status is equal to the old value!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "role.statusEq"))) return } @@ -243,6 +267,7 @@ func (s *SysRoleController) Status(c *gin.Context) { // // PUT /dataScope func (s *SysRoleController) DataScope(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 角色ID RoleID string `json:"roleId"` @@ -255,14 +280,14 @@ func (s *SysRoleController) DataScope(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员角色 if body.RoleID == admin.ROLE_ID { // 不允许操作管理员角色 - c.JSON(200, result.ErrMsg("The administrator role is not allowed to operate")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateRole"))) return } @@ -270,7 +295,7 @@ func (s *SysRoleController) DataScope(c *gin.Context) { role := s.sysRoleService.SelectRoleById(body.RoleID) if role.RoleID != body.RoleID { // 没有可访问角色数据! - c.JSON(200, result.ErrMsg("There is no accessible role data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "role.noData"))) return } @@ -295,10 +320,11 @@ func (s *SysRoleController) DataScope(c *gin.Context) { // // GET /authUser/allocatedList func (s *SysRoleController) AuthUserAllocatedList(c *gin.Context) { + language := ctx.AcceptLanguage(c) querys := ctx.QueryMap(c) roleId, ok := querys["roleId"] if !ok || roleId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -306,7 +332,7 @@ func (s *SysRoleController) AuthUserAllocatedList(c *gin.Context) { role := s.sysRoleService.SelectRoleById(roleId.(string)) if role.RoleID != roleId { // 没有可访问角色数据! - c.JSON(200, result.ErrMsg("There is no accessible role data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "role.noData"))) return } @@ -319,6 +345,7 @@ func (s *SysRoleController) AuthUserAllocatedList(c *gin.Context) { // // PUT /authUser/checked func (s *SysRoleController) AuthUserChecked(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { // 角色ID RoleID string `json:"roleId" binding:"required"` @@ -329,7 +356,7 @@ func (s *SysRoleController) AuthUserChecked(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -344,7 +371,7 @@ func (s *SysRoleController) AuthUserChecked(c *gin.Context) { // 检查是否存在 role := s.sysRoleService.SelectRoleById(body.RoleID) if role.RoleID != body.RoleID { - c.JSON(200, result.ErrMsg("There is no accessible role data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "role.noData"))) return } @@ -365,41 +392,56 @@ func (s *SysRoleController) AuthUserChecked(c *gin.Context) { // // POST /export func (s *SysRoleController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysRole) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysRole) { + for i := range *arr { + (*arr)[i].RoleName = i18n.TKey(language, (*arr)[i].RoleName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("role_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "RoleID", - "B1": "RoleName", - "C1": "RoleKey", - "D1": "RoleSort", - "E1": "DataScope", - "F1": "Status", + "A1": i18n.TKey(language, "role.export.id"), + "B1": i18n.TKey(language, "role.export.name"), + "C1": i18n.TKey(language, "role.export.key"), + "D1": i18n.TKey(language, "role.export.sort"), + "E1": i18n.TKey(language, "role.export.dataScope"), + "F1": i18n.TKey(language, "role.export.status"), } + // 读取系统角色数据范围字典数据 + dictSysRoleDatascope := s.sysDictDataService.SelectDictDataByType("sys_role_datascope") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) // 数据范围 - dataScope := "Empty" - if v, ok := roledatascope.RoleDataScope[row.DataScope]; ok { - dataScope = v + dataScope := row.DataScope + for _, v := range dictSysRoleDatascope { + if row.DataScope == v.DictValue { + dataScope = i18n.TKey(language, v.DictLabel) + break + } } // 角色状态 - statusValue := "deactivate" + statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { - statusValue = "normalcy" + statusValue = i18n.TKey(language, "dictData.normal") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.RoleID, diff --git a/src/modules/system/controller/sys_user.go b/src/modules/system/controller/sys_user.go index c8de6f2..f656f23 100644 --- a/src/modules/system/controller/sys_user.go +++ b/src/modules/system/controller/sys_user.go @@ -8,6 +8,8 @@ import ( "ems.agt/src/framework/config" "ems.agt/src/framework/constants/admin" + "ems.agt/src/framework/constants/common" + "ems.agt/src/framework/i18n" "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/date" "ems.agt/src/framework/utils/file" @@ -27,6 +29,7 @@ var NewSysUser = &SysUserController{ sysRoleService: service.NewSysRoleImpl, sysPostService: service.NewSysPostImpl, sysDictDataService: service.NewSysDictDataImpl, + sysConfigService: service.NewSysConfigImpl, } // 用户信息 @@ -41,6 +44,8 @@ type SysUserController struct { sysPostService service.ISysPost // 字典数据服务 sysDictDataService service.ISysDictData + // 参数配置服务 + sysConfigService service.ISysConfig } // 用户信息列表 @@ -50,6 +55,22 @@ func (s *SysUserController) List(c *gin.Context) { querys := ctx.QueryMap(c) dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u") data := s.sysUserService.SelectUserPage(querys, dataScopeSQL) + + rows := data["rows"].([]model.SysUser) + // 闭包函数处理多语言 + language := ctx.AcceptLanguage(c) + converI18n := func(language string, arr *[]model.SysUser) { + for i := range *arr { + (*arr)[i].NickName = i18n.TKey(language, (*arr)[i].NickName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + (*arr)[i].Dept.DeptName = i18n.TKey(language, (*arr)[i].Dept.DeptName) + for ri := range (*arr)[i].Roles { + (*arr)[i].Roles[ri].RoleName = i18n.TKey(language, (*arr)[i].Roles[ri].RoleName) + } + } + } + converI18n(language, &rows) + c.JSON(200, result.Ok(data)) } @@ -57,11 +78,13 @@ func (s *SysUserController) List(c *gin.Context) { // // GET /:userId func (s *SysUserController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) userId := c.Param("userId") if userId == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } + // 查询系统角色列表 dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") roles := s.sysRoleService.SelectRoleList(model.SysRole{}, dataScopeSQL) @@ -77,9 +100,27 @@ func (s *SysUserController) Info(c *gin.Context) { roles = rolesFilter } + // 闭包函数处理多语言 + converI18nRoles := func(language string, arr *[]model.SysRole) { + for i := range *arr { + (*arr)[i].RoleName = i18n.TKey(language, (*arr)[i].RoleName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18nRoles(language, &roles) + // 查询系统岗位列表 posts := s.sysPostService.SelectPostList(model.SysPost{}) + // 闭包函数处理多语言 + converI18nPosts := func(language string, arr *[]model.SysPost) { + for i := range *arr { + (*arr)[i].PostName = i18n.TKey(language, (*arr)[i].PostName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + } + } + converI18nPosts(language, &posts) + // 新增用户时,用户ID为0 if userId == "0" { c.JSON(200, result.OkData(map[string]any{ @@ -95,10 +136,18 @@ func (s *SysUserController) Info(c *gin.Context) { // 检查用户是否存在 user := s.sysUserService.SelectUserById(userId) if user.UserID != userId { - c.JSON(200, result.ErrMsg("There is no accessible user data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.noData"))) return } + // 处理多语言 + user.NickName = i18n.TKey(language, user.NickName) + user.Remark = i18n.TKey(language, user.Remark) + user.Dept.DeptName = i18n.TKey(language, user.Dept.DeptName) + for ri := range user.Roles { + user.Roles[ri].RoleName = i18n.TKey(language, user.Roles[ri].RoleName) + } + // 角色ID组 roleIds := make([]string, 0) for _, r := range user.Roles { @@ -125,10 +174,11 @@ func (s *SysUserController) Info(c *gin.Context) { // // POST / func (s *SysUserController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.UserID != "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -137,7 +187,7 @@ func (s *SysUserController) Add(c *gin.Context) { Password string `json:"password" binding:"required"` } if err := c.ShouldBindBodyWith(&bodyPassword, binding.JSON); err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } body.Password = bodyPassword.Password @@ -146,7 +196,8 @@ func (s *SysUserController) Add(c *gin.Context) { uniqueUserName := s.sysUserService.CheckUniqueUserName(body.UserName, "") if !uniqueUserName { // 新增用户【%s】失败,登录账号已存在 - msg := fmt.Sprintf("Failed to add user [%s], login account already exists", body.UserName) + // msg := fmt.Sprintf("Failed to add user [%s], login account already exists", body.UserName) + msg := i18n.TTemplate(language, "user.errNameExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -157,13 +208,15 @@ func (s *SysUserController) Add(c *gin.Context) { uniquePhone := s.sysUserService.CheckUniquePhone(body.PhoneNumber, "") if !uniquePhone { // 新增用户【%s】失败,手机号码已存在 - msg := fmt.Sprintf("Failed to add user [%s], cell phone number already exists", body.UserName) + // msg := fmt.Sprintf("Failed to add user [%s], cell phone number already exists", body.UserName) + msg := i18n.TTemplate(language, "user.errPhoneExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } else { // 新增用户【%s】失败,手机号码格式错误 - msg := fmt.Sprintf("Failed to add user [%s], wrong format of cell phone number", body.UserName) + // msg := fmt.Sprintf("Failed to add user [%s], wrong format of cell phone number", body.UserName) + msg := i18n.TTemplate(language, "user.errPhoneFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -175,13 +228,15 @@ func (s *SysUserController) Add(c *gin.Context) { uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, "") if !uniqueEmail { // 新增用户【%s】失败,邮箱已存在 - msg := fmt.Sprintf("Failed to add user [%s], mailbox already exists", body.UserName) + // msg := fmt.Sprintf("Failed to add user [%s], mailbox already exists", body.UserName) + msg := i18n.TTemplate(language, "user.errEmailExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } else { // 新增用户【%s】失败,邮箱格式错误 - msg := fmt.Sprintf("Failed to add user [%s], mailbox format error", body.UserName) + // msg := fmt.Sprintf("Failed to add user [%s], mailbox format error", body.UserName) + msg := i18n.TTemplate(language, "user.errEmailFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -200,24 +255,25 @@ func (s *SysUserController) Add(c *gin.Context) { // // POST / func (s *SysUserController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body model.SysUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.UserID == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员用户 if config.IsAdmin(body.UserID) { // 不允许操作管理员用户 - c.JSON(200, result.ErrMsg("Administrator users are not allowed to operate")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateAdmin"))) return } user := s.sysUserService.SelectUserById(body.UserID) if user.UserID != body.UserID { // 没有可访问用户数据! - c.JSON(200, result.ErrMsg("There is no accessible user data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.noData"))) return } @@ -225,7 +281,8 @@ func (s *SysUserController) Edit(c *gin.Context) { uniqueUserName := s.sysUserService.CheckUniqueUserName(body.UserName, body.UserID) if !uniqueUserName { // 修改用户【%s】失败,登录账号已存在 - msg := fmt.Sprintf("Failed to modify user [%s], login account already exists", body.UserName) + // msg := fmt.Sprintf("Failed to modify user [%s], login account already exists", body.UserName) + msg := i18n.TTemplate(language, "user.errNameExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -236,13 +293,15 @@ func (s *SysUserController) Edit(c *gin.Context) { uniquePhone := s.sysUserService.CheckUniquePhone(body.PhoneNumber, body.UserID) if !uniquePhone { // 修改用户【%s】失败,手机号码已存在 - msg := fmt.Sprintf("Failed to modify user [%s], cell phone number already exists", body.UserName) + // msg := fmt.Sprintf("Failed to modify user [%s], cell phone number already exists", body.UserName) + msg := i18n.TTemplate(language, "user.errPhoneExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } else { // 修改用户【%s】失败,手机号码格式错误 - msg := fmt.Sprintf("Failed to modify user [%s], wrong format of cell phone number", body.UserName) + // msg := fmt.Sprintf("Failed to modify user [%s], wrong format of cell phone number", body.UserName) + msg := i18n.TTemplate(language, "user.errPhoneFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -254,13 +313,15 @@ func (s *SysUserController) Edit(c *gin.Context) { uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, body.UserID) if !uniqueEmail { // 修改用户【%s】失败,邮箱已存在 - msg := fmt.Sprintf("Failed to modify user [%s], mailbox already exists", body.UserName) + // msg := fmt.Sprintf("Failed to modify user [%s], mailbox already exists", body.UserName) + msg := i18n.TTemplate(language, "user.errEmailExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } else { // 修改用户【%s】失败,邮箱格式错误 - msg := fmt.Sprintf("Failed to modify user [%s], mailbox format error", body.UserName) + // msg := fmt.Sprintf("Failed to modify user [%s], mailbox format error", body.UserName) + msg := i18n.TTemplate(language, "user.errEmailFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } @@ -283,9 +344,10 @@ func (s *SysUserController) Edit(c *gin.Context) { // // DELETE /:userIds func (s *SysUserController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) userIds := c.Param("userIds") if userIds == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 @@ -295,13 +357,23 @@ func (s *SysUserController) Remove(c *gin.Context) { c.JSON(200, result.Err(nil)) return } + + // 检查是否管理员用户 + for _, id := range uniqueIDs { + if config.IsAdmin(id) { + // 不允许操作管理员用户 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateAdmin"))) + return + } + } + rows, err := s.sysUserService.DeleteUserByIds(uniqueIDs) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return } // 删除成功:%d - msg := fmt.Sprintf("Deleted successfully: %d", rows) + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } @@ -309,31 +381,32 @@ func (s *SysUserController) Remove(c *gin.Context) { // // PUT /resetPwd func (s *SysUserController) ResetPwd(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { UserID string `json:"userId" binding:"required"` Password string `json:"password" binding:"required"` } if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员用户 if config.IsAdmin(body.UserID) { - // 不允许操作管理员用户 - c.JSON(200, result.ErrMsg("Administrator users are not allowed to operate")) + // 不允许操作内置用户 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.errOperateAdmin"))) return } user := s.sysUserService.SelectUserById(body.UserID) if user.UserID != body.UserID { // 没有可访问用户数据! - c.JSON(200, result.ErrMsg("There is no accessible user data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.noData"))) return } if !regular.ValidPassword(body.Password) { // 登录密码至少包含大小写字母、数字、特殊符号,且不少于6位 - c.JSON(200, result.ErrMsg("Login password contains at least upper and lower case letters, numbers, special symbols, and not less than 6 digits")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.errPasswd"))) return } @@ -355,12 +428,13 @@ func (s *SysUserController) ResetPwd(c *gin.Context) { // // PUT /changeStatus func (s *SysUserController) Status(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { UserID string `json:"userId" binding:"required"` Status string `json:"status" binding:"required"` } if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -368,14 +442,14 @@ func (s *SysUserController) Status(c *gin.Context) { user := s.sysUserService.SelectUserById(body.UserID) if user.UserID != body.UserID { // 没有可访问用户数据! - c.JSON(200, result.ErrMsg("There is no accessible user data!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.noData"))) return } // 与旧值相等不变更 if user.Status == body.Status { // 变更状态与旧值相等! - c.JSON(200, result.ErrMsg("The change status is equal to the old value!")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.statusEq"))) return } @@ -397,33 +471,47 @@ func (s *SysUserController) Status(c *gin.Context) { // // POST /export func (s *SysUserController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u") data := s.sysUserService.SelectUserPage(querys, dataScopeSQL) if data["total"].(int64) == 0 { // 导出数据记录为空 - c.JSON(200, result.ErrMsg("Export data record is empty")) + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } rows := data["rows"].([]model.SysUser) + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]model.SysUser) { + for i := range *arr { + (*arr)[i].NickName = i18n.TKey(language, (*arr)[i].NickName) + (*arr)[i].Remark = i18n.TKey(language, (*arr)[i].Remark) + (*arr)[i].Dept.DeptName = i18n.TKey(language, (*arr)[i].Dept.DeptName) + for ri := range (*arr)[i].Roles { + (*arr)[i].Roles[ri].RoleName = i18n.TKey(language, (*arr)[i].Roles[ri].RoleName) + } + } + } + converI18n(language, &rows) + // 导出文件名称 fileName := fmt.Sprintf("user_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli()) // 第一行表头标题 headerCells := map[string]string{ - "A1": "UserID", - "B1": "UserName", - "C1": "NickName", - "D1": "Email", - "E1": "PhoneNumber", - "F1": "UserSex", - "G1": "Status", - "H1": "DeptID", - "I1": "DeptName", - "J1": "DeptLeader", - "K1": "LoginIP", - "L1": "LoginDate", + "A1": i18n.TKey(language, "user.export.id"), + "B1": i18n.TKey(language, "user.export.name"), + "C1": i18n.TKey(language, "user.export.nick"), + "D1": i18n.TKey(language, "user.export.email"), + "E1": i18n.TKey(language, "user.export.phone"), + "F1": i18n.TKey(language, "user.export.sex"), + "G1": i18n.TKey(language, "user.export.status"), + "H1": i18n.TKey(language, "user.export.deptID"), + "I1": i18n.TKey(language, "user.export.deptName"), + "J1": i18n.TKey(language, "user.export.deptLeader"), + "K1": i18n.TKey(language, "user.export.loginIP"), + "L1": i18n.TKey(language, "user.export.loginDate"), } // 读取用户性别字典数据 dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex") @@ -432,17 +520,17 @@ func (s *SysUserController) Export(c *gin.Context) { for i, row := range rows { idx := strconv.Itoa(i + 2) // 用户性别 - sysUserSex := "unknown" + sysUserSex := row.Sex for _, v := range dictSysUserSex { if row.Sex == v.DictValue { - sysUserSex = v.DictLabel + sysUserSex = i18n.TKey(language, v.DictLabel) break } } // 帐号状态 - statusValue := "deactivate" + statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { - statusValue = "normalcy" + statusValue = i18n.TKey(language, "dictData.normal") } dataCells = append(dataCells, map[string]any{ "A" + idx: row.UserID, @@ -475,11 +563,13 @@ func (s *SysUserController) Export(c *gin.Context) { // GET /importTemplate func (s *SysUserController) Template(c *gin.Context) { fileName := fmt.Sprintf("user_import_template_%d.xlsx", time.Now().UnixMilli()) - asserPath := "assets/template/excel/user_import_template.xlsx" + + // 多语言处理 + language := ctx.AcceptLanguage(c) + asserPath := fmt.Sprintf("assets/template/excel/user_import_template_%s.xlsx", language) // 从 embed.FS 中读取默认配置文件内容 assetsDir := config.GetAssetsDirFS() - // 读取内嵌文件 fileData, err := assetsDir.ReadFile(asserPath) if err != nil { @@ -499,12 +589,13 @@ func (s *SysUserController) Template(c *gin.Context) { // // POST /importData func (s *SysUserController) ImportData(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 允许进行更新 updateSupport := c.PostForm("updateSupport") // 上传的文件 formFile, err := c.FormFile("file") if err != nil || updateSupport == "" { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -525,6 +616,152 @@ func (s *SysUserController) ImportData(c *gin.Context) { // 获取操作人名称 operName := ctx.LoginUserToUserName(c) isUpdateSupport := parse.Boolean(updateSupport) - message := s.sysUserService.ImportUser(rows, isUpdateSupport, operName) + + // 读取默认初始密码 + initPassword := s.sysConfigService.SelectConfigValueByKey("sys.user.initPassword") + // 读取用户性别字典数据 + dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex") + + // 导入记录 + successNum := 0 + failureNum := 0 + successMsgArr := []string{} + failureMsgArr := []string{} + mustItemArr := []string{"B", "C"} + for _, row := range rows { + // 检查必填列 + ownItem := true + for _, item := range mustItemArr { + if v, ok := row[item]; !ok || v == "" { + ownItem = false + break + } + } + if !ownItem { + mustItemArrStr := strings.Join(mustItemArr, "、") + failureNum++ + // 表格中必填列表项, + msg := i18n.TTemplate(language, "user.import.mustItem", map[string]any{"text": mustItemArrStr}) + failureMsgArr = append(failureMsgArr, msg) + continue + } + + // 用户性别转值 + sysUserSex := "0" + for _, v := range dictSysUserSex { + label := i18n.TKey(language, v.DictLabel) + if row["F"] == label { + sysUserSex = v.DictValue + break + } + } + sysUserStatus := common.STATUS_NO + if row["G"] == "Normal" { + sysUserStatus = common.STATUS_YES + } + + // 构建用户实体信息 + newSysUser := model.SysUser{ + UserType: "sys", + Password: initPassword, + DeptID: row["H"], + UserName: row["B"], + NickName: row["C"], + PhoneNumber: row["E"], + Email: row["D"], + Status: sysUserStatus, + Sex: sysUserSex, + } + + // 检查手机号码格式并判断是否唯一 + if newSysUser.PhoneNumber != "" { + if regular.ValidMobile(newSysUser.PhoneNumber) { + uniquePhone := s.sysUserService.CheckUniquePhone(newSysUser.PhoneNumber, "") + if !uniquePhone { + // 用户编号:%s 手机号码 %s 已存在 + msg := i18n.TTemplate(language, "user.import.phoneExist", map[string]any{"id": row["A"], "phone": newSysUser.PhoneNumber}) + failureNum++ + failureMsgArr = append(failureMsgArr, msg) + continue + } + } else { + // 用户编号:%s 手机号码 %s 格式错误 + msg := i18n.TTemplate(language, "user.import.phoneFormat", map[string]any{"id": row["A"], "phone": newSysUser.PhoneNumber}) + failureNum++ + failureMsgArr = append(failureMsgArr, msg) + continue + } + } + + // 检查邮箱格式并判断是否唯一 + if newSysUser.Email != "" { + if regular.ValidEmail(newSysUser.Email) { + uniqueEmail := s.sysUserService.CheckUniqueEmail(newSysUser.Email, "") + if !uniqueEmail { + // 用户编号:%s 用户邮箱 %s 已存在 + msg := i18n.TTemplate(language, "user.import.emailExist", map[string]any{"id": row["A"], "email": newSysUser.Email}) + failureNum++ + failureMsgArr = append(failureMsgArr, msg) + continue + } + } else { + // 用户编号:%s 用户邮箱 %s 格式错误 + msg := i18n.TTemplate(language, "user.import.emailFormat", map[string]any{"id": row["A"], "email": newSysUser.Email}) + failureNum++ + failureMsgArr = append(failureMsgArr, msg) + continue + } + } + + // 验证是否存在这个用户 + userInfo := s.sysUserService.SelectUserByUserName(newSysUser.UserName) + if userInfo.UserName != newSysUser.UserName { + newSysUser.CreateBy = operName + insertId := s.sysUserService.InsertUser(newSysUser) + if insertId != "" { + // 用户编号:%s 登录名称 %s 导入成功 + msg := i18n.TTemplate(language, "user.import.success", map[string]any{"id": row["A"], "name": newSysUser.UserName}) + successNum++ + successMsgArr = append(successMsgArr, msg) + } else { + // 用户编号:%s 登录名称 %s 导入失败 + msg := i18n.TTemplate(language, "user.import.fail", map[string]any{"id": row["A"], "email": newSysUser.UserName}) + failureNum++ + failureMsgArr = append(failureMsgArr, msg) + } + continue + } + + // 如果用户已存在 同时 是否更新支持 + if userInfo.UserName == newSysUser.UserName && isUpdateSupport { + newSysUser.UserID = userInfo.UserID + newSysUser.UpdateBy = operName + rows := s.sysUserService.UpdateUser(newSysUser) + if rows > 0 { + // 用户编号:%s 登录名称 %s 更新成功 + msg := i18n.TTemplate(language, "user.import.successUpdate", map[string]any{"id": row["A"], "email": newSysUser.UserName}) + successNum++ + successMsgArr = append(successMsgArr, msg) + } else { + // 用户编号:%s 登录名称 %s 更新失败 + msg := i18n.TTemplate(language, "user.import.failUpdate", map[string]any{"id": row["A"], "email": newSysUser.UserName}) + failureNum++ + failureMsgArr = append(failureMsgArr, msg) + } + continue + } + } + + message := "" + if failureNum > 0 { + // 很抱歉,导入失败!共 %d 条数据格式不正确,错误如下: + msg := i18n.TTemplate(language, "user.import.failTip", map[string]any{"num": failureNum}) + message = strings.Join(append([]string{msg}, failureMsgArr...), "
") + } else { + // 恭喜您,数据已全部导入成功!共 %d 条,数据如下: + msg := i18n.TTemplate(language, "user.import.successTip", map[string]any{"num": failureNum}) + message = strings.Join(append([]string{msg}, successMsgArr...), "
") + } + c.JSON(200, result.OkMsg(message)) } diff --git a/src/modules/system/repository/sys_config.impl.go b/src/modules/system/repository/sys_config.impl.go index fa5543e..90d0d3d 100644 --- a/src/modules/system/repository/sys_config.impl.go +++ b/src/modules/system/repository/sys_config.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -186,7 +185,11 @@ func (r *SysConfigImpl) SelectConfigValueByKey(configKey string) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } @@ -231,7 +234,11 @@ func (r *SysConfigImpl) CheckUniqueConfig(sysConfig model.SysConfig) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } @@ -303,9 +310,7 @@ func (r *SysConfigImpl) UpdateConfig(sysConfig model.SysConfig) int64 { if sysConfig.ConfigType != "" { params["config_type"] = sysConfig.ConfigType } - if sysConfig.Remark != "" { - params["remark"] = sysConfig.Remark - } + params["remark"] = sysConfig.Remark if sysConfig.UpdateBy != "" { params["update_by"] = sysConfig.UpdateBy params["update_time"] = time.Now().UnixMilli() diff --git a/src/modules/system/repository/sys_dept.impl.go b/src/modules/system/repository/sys_dept.impl.go index e5698bc..550d0eb 100644 --- a/src/modules/system/repository/sys_dept.impl.go +++ b/src/modules/system/repository/sys_dept.impl.go @@ -226,7 +226,11 @@ func (r *SysDeptImpl) CheckUniqueDept(sysDept model.SysDept) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/src/modules/system/repository/sys_dict_data.impl.go b/src/modules/system/repository/sys_dict_data.impl.go index 0664cb0..055762a 100644 --- a/src/modules/system/repository/sys_dict_data.impl.go +++ b/src/modules/system/repository/sys_dict_data.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -220,7 +219,11 @@ func (r *SysDictDataImpl) CheckUniqueDictData(sysDictData model.SysDictData) str return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } @@ -314,18 +317,12 @@ func (r *SysDictDataImpl) UpdateDictData(sysDictData model.SysDictData) int64 { if sysDictData.DictType != "" { params["dict_type"] = sysDictData.DictType } - if sysDictData.TagClass != "" { - params["tag_class"] = sysDictData.TagClass - } - if sysDictData.TagType != "" { - params["tag_type"] = sysDictData.TagType - } if sysDictData.Status != "" { params["status"] = sysDictData.Status } - if sysDictData.Remark != "" { - params["remark"] = sysDictData.Remark - } + params["tag_class"] = sysDictData.TagClass + params["tag_type"] = sysDictData.TagType + params["remark"] = sysDictData.Remark if sysDictData.UpdateBy != "" { params["update_by"] = sysDictData.UpdateBy params["update_time"] = time.Now().UnixMilli() diff --git a/src/modules/system/repository/sys_dict_type.impl.go b/src/modules/system/repository/sys_dict_type.impl.go index e34ab7b..0dd63b2 100644 --- a/src/modules/system/repository/sys_dict_type.impl.go +++ b/src/modules/system/repository/sys_dict_type.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -232,7 +231,11 @@ func (r *SysDictTypeImpl) CheckUniqueDictType(sysDictType model.SysDictType) str return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } @@ -298,9 +301,7 @@ func (r *SysDictTypeImpl) UpdateDictType(sysDictType model.SysDictType) int64 { if sysDictType.Status != "" { params["status"] = sysDictType.Status } - if sysDictType.Remark != "" { - params["remark"] = sysDictType.Remark - } + params["remark"] = sysDictType.Remark if sysDictType.UpdateBy != "" { params["update_by"] = sysDictType.UpdateBy params["update_time"] = time.Now().UnixMilli() diff --git a/src/modules/system/repository/sys_menu.impl.go b/src/modules/system/repository/sys_menu.impl.go index 5b62288..72975c0 100644 --- a/src/modules/system/repository/sys_menu.impl.go +++ b/src/modules/system/repository/sys_menu.impl.go @@ -468,7 +468,11 @@ func (r *SysMenuImpl) CheckUniqueMenu(sysMenu model.SysMenu) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/src/modules/system/repository/sys_post.impl.go b/src/modules/system/repository/sys_post.impl.go index d1dcda5..184c98b 100644 --- a/src/modules/system/repository/sys_post.impl.go +++ b/src/modules/system/repository/sys_post.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -212,9 +211,7 @@ func (r *SysPostImpl) UpdatePost(sysPost model.SysPost) int64 { if sysPost.Status != "" { params["status"] = sysPost.Status } - if sysPost.Remark != "" { - params["remark"] = sysPost.Remark - } + params["remark"] = sysPost.Remark if sysPost.UpdateBy != "" { params["update_by"] = sysPost.UpdateBy params["update_time"] = time.Now().UnixMilli() @@ -317,7 +314,11 @@ func (r *SysPostImpl) CheckUniquePost(sysPost model.SysPost) string { logger.Errorf("query err %v", err) } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/src/modules/system/repository/sys_role.impl.go b/src/modules/system/repository/sys_role.impl.go index f417976..719ee4e 100644 --- a/src/modules/system/repository/sys_role.impl.go +++ b/src/modules/system/repository/sys_role.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -296,9 +295,7 @@ func (r *SysRoleImpl) InsertRole(sysRole model.SysRole) string { if sysRole.Status != "" { params["status"] = sysRole.Status } - if sysRole.Remark != "" { - params["remark"] = sysRole.Remark - } + params["remark"] = sysRole.Remark if sysRole.CreateBy != "" { params["create_by"] = sysRole.CreateBy params["create_time"] = time.Now().UnixMilli() @@ -374,7 +371,11 @@ func (r *SysRoleImpl) CheckUniqueRole(sysRole model.SysRole) string { return "" } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/src/modules/system/repository/sys_user.impl.go b/src/modules/system/repository/sys_user.impl.go index 0442150..05d47c9 100644 --- a/src/modules/system/repository/sys_user.impl.go +++ b/src/modules/system/repository/sys_user.impl.go @@ -1,7 +1,6 @@ package repository import ( - "fmt" "strings" "time" @@ -558,7 +557,11 @@ func (r *SysUserImpl) CheckUniqueUser(sysUser model.SysUser) string { logger.Errorf("query err %v", err) } if len(results) > 0 { - return fmt.Sprintf("%v", results[0]["str"]) + v, ok := results[0]["str"].(string) + if ok { + return v + } + return "" } return "" } diff --git a/src/modules/system/service/sys_config.impl.go b/src/modules/system/service/sys_config.impl.go index eff1a2f..6fbfd19 100644 --- a/src/modules/system/service/sys_config.impl.go +++ b/src/modules/system/service/sys_config.impl.go @@ -93,13 +93,13 @@ func (r *SysConfigImpl) DeleteConfigByIds(configIds []string) (int64, error) { // 检查是否存在 configs := r.sysConfigRepository.SelectConfigByIds(configIds) if len(configs) <= 0 { - return 0, fmt.Errorf("there is no accessible parameter configuration data") + return 0, fmt.Errorf("config.noData") } for _, config := range configs { // 检查是否为内置参数 if config.ConfigType == "Y" { - // 【%s】 配置参数属于内置参数,禁止删除! - return 0, fmt.Errorf("[%s] Configuration parameters are built-in parameters and their deletion is prohibited", config.ConfigID) + // 操作含有内置参数,禁止删除! + return 0, fmt.Errorf("config.errType") } // 清除缓存 r.clearConfigCache(config.ConfigKey) @@ -109,7 +109,7 @@ func (r *SysConfigImpl) DeleteConfigByIds(configIds []string) (int64, error) { return rows, nil } // 删除参数配置信息失败! - return 0, fmt.Errorf("failed to delete parameter configuration information") + return 0, fmt.Errorf("config.errDelete") } // ResetConfigCache 重置参数缓存数据 diff --git a/src/modules/system/service/sys_user.go b/src/modules/system/service/sys_user.go index 23fd5fb..cc38da5 100644 --- a/src/modules/system/service/sys_user.go +++ b/src/modules/system/service/sys_user.go @@ -39,7 +39,4 @@ type ISysUser interface { // CheckUniqueEmail 校验email是否唯一 CheckUniqueEmail(email, userId string) bool - - // ImportUser 导入用户数据 - ImportUser(rows []map[string]string, isUpdateSupport bool, operName string) string } diff --git a/src/modules/system/service/sys_user.impl.go b/src/modules/system/service/sys_user.impl.go index b69fd03..aceeeda 100644 --- a/src/modules/system/service/sys_user.impl.go +++ b/src/modules/system/service/sys_user.impl.go @@ -2,11 +2,8 @@ package service import ( "fmt" - "strings" "ems.agt/src/framework/constants/admin" - "ems.agt/src/framework/constants/common" - "ems.agt/src/framework/utils/regular" "ems.agt/src/modules/system/model" "ems.agt/src/modules/system/repository" ) @@ -16,8 +13,6 @@ var NewSysUserImpl = &SysUserImpl{ sysUserRepository: repository.NewSysUserImpl, sysUserRoleRepository: repository.NewSysUserRoleImpl, sysUserPostRepository: repository.NewSysUserPostImpl, - sysDictDataService: NewSysDictDataImpl, - sysConfigService: NewSysConfigImpl, } // SysUserImpl 用户 服务层处理 @@ -28,10 +23,6 @@ type SysUserImpl struct { sysUserRoleRepository repository.ISysUserRole // 用户与岗位服务 sysUserPostRepository repository.ISysUserPost - // 字典数据服务 - sysDictDataService ISysDictData - // 参数配置服务 - sysConfigService ISysConfig } // SelectUserPage 根据条件分页查询用户列表 @@ -185,149 +176,3 @@ func (r *SysUserImpl) CheckUniqueEmail(email, userId string) bool { } return uniqueId == "" } - -// ImportUser 导入用户数据 -func (r *SysUserImpl) ImportUser(rows []map[string]string, isUpdateSupport bool, operName string) string { - // 读取默认初始密码 - initPassword := r.sysConfigService.SelectConfigValueByKey("sys.user.initPassword") - // 读取用户性别字典数据 - dictSysUserSex := r.sysDictDataService.SelectDictDataByType("sys_user_sex") - - // 导入记录 - successNum := 0 - failureNum := 0 - successMsgArr := []string{} - failureMsgArr := []string{} - mustItemArr := []string{"B", "C"} - for _, row := range rows { - // 检查必填列 - ownItem := true - for _, item := range mustItemArr { - if v, ok := row[item]; !ok || v == "" { - ownItem = false - break - } - } - if !ownItem { - mustItemArrStr := strings.Join(mustItemArr, "、") - failureNum++ - // 表格中必填列表项, - failureMsgArr = append(failureMsgArr, fmt.Sprintf("Required list items in the form, %s}", mustItemArrStr)) - continue - } - - // 用户性别转值 - sysUserSex := "0" - for _, v := range dictSysUserSex { - if row["F"] == v.DictLabel { - sysUserSex = v.DictValue - break - } - } - sysUserStatus := common.STATUS_NO - if row["G"] == "Normal" { - sysUserStatus = common.STATUS_YES - } - - // 构建用户实体信息 - newSysUser := model.SysUser{ - UserType: "sys", - Password: initPassword, - DeptID: row["H"], - UserName: row["B"], - NickName: row["C"], - PhoneNumber: row["E"], - Email: row["D"], - Status: sysUserStatus, - Sex: sysUserSex, - } - - // 检查手机号码格式并判断是否唯一 - if newSysUser.PhoneNumber != "" { - if regular.ValidMobile(newSysUser.PhoneNumber) { - uniquePhone := r.CheckUniquePhone(newSysUser.PhoneNumber, "") - if !uniquePhone { - // 用户编号:%s 手机号码 %s 已存在 - msg := fmt.Sprintf("UserID: %s PhoneNumber: %s pre-existing", row["A"], row["E"]) - failureNum++ - failureMsgArr = append(failureMsgArr, msg) - continue - } - } else { - // 用户编号:%s 手机号码 %s 格式错误 - msg := fmt.Sprintf("UserID: %s PhoneNumber: %s formatting error", row["A"], row["E"]) - failureNum++ - failureMsgArr = append(failureMsgArr, msg) - continue - } - } - - // 检查邮箱格式并判断是否唯一 - if newSysUser.Email != "" { - if regular.ValidEmail(newSysUser.Email) { - uniqueEmail := r.CheckUniqueEmail(newSysUser.Email, "") - if !uniqueEmail { - // 用户编号:%s 用户邮箱 %s 已存在 - msg := fmt.Sprintf("UserID: %s Email: %s pre-existing", row["A"], row["D"]) - failureNum++ - failureMsgArr = append(failureMsgArr, msg) - continue - } - } else { - // 用户编号:%s 用户邮箱 %s 格式错误 - msg := fmt.Sprintf("UserID: %s Email: %s formatting error", row["A"], row["D"]) - failureNum++ - failureMsgArr = append(failureMsgArr, msg) - continue - } - } - - // 验证是否存在这个用户 - userInfo := r.sysUserRepository.SelectUserByUserName(newSysUser.UserName) - if userInfo.UserName != newSysUser.UserName { - newSysUser.CreateBy = operName - insertId := r.InsertUser(newSysUser) - if insertId != "" { - // 用户编号:%s 登录名称 %s 导入成功 - msg := fmt.Sprintf("UserID: %s UserName: %s import successfully", row["A"], row["B"]) - successNum++ - successMsgArr = append(successMsgArr, msg) - } else { - // 用户编号:%s 登录名称 %s 导入失败 - msg := fmt.Sprintf("UserID: %s UserName: %s import failure", row["A"], row["B"]) - failureNum++ - failureMsgArr = append(failureMsgArr, msg) - } - continue - } - - // 如果用户已存在 同时 是否更新支持 - if userInfo.UserName == newSysUser.UserName && isUpdateSupport { - newSysUser.UserID = userInfo.UserID - newSysUser.UpdateBy = operName - rows := r.UpdateUser(newSysUser) - if rows > 0 { - // 用户编号:%s 登录名称 %s 更新成功 - msg := fmt.Sprintf("UserID: %s UserName: %s Update Successful", row["A"], row["B"]) - successNum++ - successMsgArr = append(successMsgArr, msg) - } else { - // 用户编号:%s 登录名称 %s 更新失败 - msg := fmt.Sprintf("UserID: %s UserName: %s Update Failed", row["A"], row["B"]) - failureNum++ - failureMsgArr = append(failureMsgArr, msg) - } - continue - } - } - - if failureNum > 0 { - // 很抱歉,导入失败!共 %d 条数据格式不正确,错误如下: - failureMsgArr = append([]string{fmt.Sprintf("Sorry, the import failed! A total of %d entries were formatted incorrectly with the following error:", failureNum)}, failureMsgArr...) - return strings.Join(failureMsgArr, "
") - } - - // 恭喜您,数据已全部导入成功!共 %d 条,数据如下: - successMsgArr = append([]string{fmt.Sprintf("Congratulations, the data has been imported successfully! Total %d entries, data below:", successNum)}, successMsgArr...) - return strings.Join(successMsgArr, "
") -} diff --git a/src/modules/system/system.go b/src/modules/system/system.go index 4355022..5838cdb 100644 --- a/src/modules/system/system.go +++ b/src/modules/system/system.go @@ -31,34 +31,34 @@ func Setup(router *gin.Engine) { ) sysConfigGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:config:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Parameter Configuration", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysConfig", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysConfig.Add, ) sysConfigGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:config:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Parameter Configuration", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysConfig", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysConfig.Edit, ) sysConfigGroup.DELETE("/:configIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:config:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Parameter Configuration", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysConfig", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysConfig.Remove, ) sysConfigGroup.PUT("/refreshCache", repeat.RepeatSubmit(5), middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:config:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Parameter Configuration", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysConfig", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysConfig.RefreshCache, ) sysConfigGroup.GET("/configKey/:configKey", controller.NewSysConfig.ConfigKey) sysConfigGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:config:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Parameter Configuration", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysConfig", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysConfig.Export, ) sysConfigGroup.PUT("/changeValue", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:config:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Parameter Configuration", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysConfig", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysConfig.ConfigValue, ) } @@ -76,17 +76,17 @@ func Setup(router *gin.Engine) { ) sysDeptGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dept:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Sectoral", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDept", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysDept.Add, ) sysDeptGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dept:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Sectoral", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDept", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysDept.Edit, ) sysDeptGroup.DELETE("/:deptId", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dept:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Sectoral", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDept", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysDept.Remove, ) sysDeptGroup.GET("/list/exclude/:deptId", @@ -116,17 +116,17 @@ func Setup(router *gin.Engine) { ) sysDictDataGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Data", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictData", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysDictData.Add, ) sysDictDataGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Data", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictData", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysDictData.Edit, ) sysDictDataGroup.DELETE("/:dictCodes", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Data", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictData", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysDictData.Remove, ) sysDictDataGroup.GET("/type/:dictType", @@ -135,7 +135,7 @@ func Setup(router *gin.Engine) { ) sysDictDataGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Type", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictData", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysDictData.Export, ) } @@ -153,22 +153,22 @@ func Setup(router *gin.Engine) { ) sysDictTypeGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Type", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictType", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysDictType.Add, ) sysDictTypeGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Type", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictType", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysDictType.Edit, ) sysDictTypeGroup.DELETE("/:dictIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Type", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictType", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysDictType.Remove, ) sysDictTypeGroup.PUT("/refreshCache", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Type", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictType", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysDictType.RefreshCache, ) sysDictTypeGroup.GET("/getDictOptionselect", @@ -177,7 +177,7 @@ func Setup(router *gin.Engine) { ) sysDictTypeGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:dict:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Dictionary Type", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysDictType", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysDictType.Export, ) } @@ -195,17 +195,17 @@ func Setup(router *gin.Engine) { ) sysMenuGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:menu:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Menu", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysMenu", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysMenu.Add, ) sysMenuGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:menu:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Menu", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysMenu", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysMenu.Edit, ) sysMenuGroup.DELETE("/:menuId", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:menu:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Menu", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysMenu", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysMenu.Remove, ) sysMenuGroup.GET("/treeSelect", @@ -218,34 +218,6 @@ func Setup(router *gin.Engine) { ) } - // 通知公告信息 - sysNoticeGroup := router.Group("/system/notice") - { - sysNoticeGroup.GET("/list", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:notice:list"}}), - controller.NewSysNotice.List, - ) - sysNoticeGroup.GET("/:noticeId", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:notice:query"}}), - controller.NewSysNotice.Info, - ) - sysNoticeGroup.POST("", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:notice:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Notice", collectlogs.BUSINESS_TYPE_INSERT)), - controller.NewSysNotice.Add, - ) - sysNoticeGroup.PUT("", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:notice:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Notice", collectlogs.BUSINESS_TYPE_UPDATE)), - controller.NewSysNotice.Edit, - ) - sysNoticeGroup.DELETE("/:noticeIds", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:notice:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Notice", collectlogs.BUSINESS_TYPE_DELETE)), - controller.NewSysNotice.Remove, - ) - } - // 岗位信息 sysPostGroup := router.Group("/system/post") { @@ -259,17 +231,17 @@ func Setup(router *gin.Engine) { ) sysPostGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:post:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Post", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysPost", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysPost.Add, ) sysPostGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:post:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Post", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysPost", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysPost.Edit, ) sysPostGroup.DELETE("/:postIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:post:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Post", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysPost", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysPost.Remove, ) sysPostGroup.POST("/export", @@ -291,12 +263,12 @@ func Setup(router *gin.Engine) { ) sysProfileGroup.PUT("/updatePwd", middleware.PreAuthorize(nil), - collectlogs.OperateLog(collectlogs.OptionNew("Personal", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysProfile", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysProfile.UpdatePwd, ) sysProfileGroup.POST("/avatar", middleware.PreAuthorize(nil), - collectlogs.OperateLog(collectlogs.OptionNew("Personal Avatar", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysProfileAvatar", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysProfile.Avatar, ) } @@ -314,29 +286,29 @@ func Setup(router *gin.Engine) { ) sysRoleGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:role:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysRole.Add, ) sysRoleGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:role:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysRole.Edit, ) sysRoleGroup.DELETE("/:roleIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:role:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysRole.Remove, ) sysRoleGroup.PUT("/changeStatus", repeat.RepeatSubmit(5), middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:role:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysRole.Status, ) sysRoleGroup.PUT("/dataScope", repeat.RepeatSubmit(5), middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysRole.DataScope, ) sysRoleGroup.GET("/authUser/allocatedList", @@ -345,12 +317,12 @@ func Setup(router *gin.Engine) { ) sysRoleGroup.PUT("/authUser/checked", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_GRANT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_GRANT)), controller.NewSysRole.AuthUserChecked, ) sysRoleGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Role", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysRole", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysRole.Export, ) } @@ -368,33 +340,33 @@ func Setup(router *gin.Engine) { ) sysUserGroup.POST("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:add"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysUser.Add, ) sysUserGroup.PUT("", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysUser.Edit, ) sysUserGroup.DELETE("/:userIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysUser.Remove, ) sysUserGroup.PUT("/resetPwd", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:resetPwd"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysUser.ResetPwd, ) sysUserGroup.PUT("/changeStatus", repeat.RepeatSubmit(5), middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:edit"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_UPDATE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewSysUser.Status, ) sysUserGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysUser.Export, ) sysUserGroup.GET("/importTemplate", @@ -403,60 +375,60 @@ func Setup(router *gin.Engine) { ) sysUserGroup.POST("/importData", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:user:import"}}), - collectlogs.OperateLog(collectlogs.OptionNew("User", collectlogs.BUSINESS_TYPE_INSERT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysUser", collectlogs.BUSINESS_TYPE_INSERT)), controller.NewSysUser.ImportData, ) } // 操作日志记录信息 - sysOperLogGroup := router.Group("/system/log/operate") + sysLogOperGroup := router.Group("/system/log/operate") { - sysOperLogGroup.GET("/list", + sysLogOperGroup.GET("/list", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:operate:list"}}), controller.NewSysLogOperate.List, ) - sysOperLogGroup.DELETE("/:operIds", + sysLogOperGroup.DELETE("/:operIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:operate:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Operation", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogOper", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysLogOperate.Remove, ) - sysOperLogGroup.DELETE("/clean", + sysLogOperGroup.DELETE("/clean", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:operate:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Operation", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogOper", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysLogOperate.Clean, ) - sysOperLogGroup.POST("/export", + sysLogOperGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:operate:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("Operation", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogOper", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysLogOperate.Export, ) } // 系统登录日志信息 - sysLogininforGroup := router.Group("/system/log/login") + sysLogLoginGroup := router.Group("/system/log/login") { - sysLogininforGroup.GET("/list", + sysLogLoginGroup.GET("/list", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:login:list"}}), controller.NewSysLogLogin.List, ) - sysLogininforGroup.DELETE("/:loginIds", + sysLogLoginGroup.DELETE("/:loginIds", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:login:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("System Login", collectlogs.BUSINESS_TYPE_DELETE)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogLogin", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewSysLogLogin.Remove, ) - sysLogininforGroup.DELETE("/clean", + sysLogLoginGroup.DELETE("/clean", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:login:remove"}}), - collectlogs.OperateLog(collectlogs.OptionNew("System Login", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogLogin", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysLogLogin.Clean, ) - sysLogininforGroup.PUT("/unlock/:userName", + sysLogLoginGroup.PUT("/unlock/:userName", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:login:unlock"}}), - collectlogs.OperateLog(collectlogs.OptionNew("System Login", collectlogs.BUSINESS_TYPE_CLEAN)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogLogin", collectlogs.BUSINESS_TYPE_CLEAN)), controller.NewSysLogLogin.Unlock, ) - sysLogininforGroup.POST("/export", + sysLogLoginGroup.POST("/export", middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:log:login:export"}}), - collectlogs.OperateLog(collectlogs.OptionNew("System Login", collectlogs.BUSINESS_TYPE_EXPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysLogLogin", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSysLogLogin.Export, ) } diff --git a/src/modules/trace/controller/tcpdump.go b/src/modules/trace/controller/tcpdump.go index a94039d..6924de5 100644 --- a/src/modules/trace/controller/tcpdump.go +++ b/src/modules/trace/controller/tcpdump.go @@ -6,9 +6,11 @@ import ( "ems.agt/src/framework/cmd" "ems.agt/src/framework/config" + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" "ems.agt/src/framework/utils/ssh" "ems.agt/src/framework/vo/result" - netElementService "ems.agt/src/modules/net_element/service" + netElementService "ems.agt/src/modules/network_element/service" traceService "ems.agt/src/modules/trace/service" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" @@ -34,6 +36,7 @@ type TcpdumpController struct { // // POST /ne func (s *TcpdumpController) NeTask(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { NeType string `json:"neType" binding:"required"` // 网元类型 NeId string `json:"neId" binding:"required"` // 网元ID @@ -43,7 +46,7 @@ func (s *TcpdumpController) NeTask(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -51,7 +54,7 @@ func (s *TcpdumpController) NeTask(c *gin.Context) { neInfo := s.NeInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) if neInfo.NeId != body.NeId { // 找不到 %s %s 对应网元信息 - msg := fmt.Sprintf("Cannot find %s %s network element information.", body.NeType, body.NeId) + msg := i18n.TTemplate(language, "trace.tcpdump.noData", map[string]any{"type": body.NeType, "id": body.NeId}) c.JSON(200, result.ErrMsg(msg)) return } @@ -79,6 +82,7 @@ func (s *TcpdumpController) NeTask(c *gin.Context) { // // POST /download func (s *TcpdumpController) Download(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { NeType string `json:"neType" binding:"required"` // 网元类型 NeId string `json:"neId" binding:"required"` // 网元ID @@ -86,7 +90,7 @@ func (s *TcpdumpController) Download(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -94,7 +98,7 @@ func (s *TcpdumpController) Download(c *gin.Context) { neInfo := s.NeInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) if neInfo.NeId != body.NeId { // 找不到 %s %s 对应网元信息 - msg := fmt.Sprintf("Cannot find %s %s network element information.", body.NeType, body.NeId) + msg := i18n.TTemplate(language, "trace.tcpdump.noData", map[string]any{"type": body.NeType, "id": body.NeId}) c.JSON(200, result.ErrMsg(msg)) return } @@ -114,6 +118,7 @@ func (s *TcpdumpController) Download(c *gin.Context) { // // POST /neUPF func (s *TcpdumpController) NeUPFTask(c *gin.Context) { + language := ctx.AcceptLanguage(c) var body struct { NeType string `json:"neType" binding:"required"` // 网元类型 NeId string `json:"neId" binding:"required"` // 网元ID @@ -123,14 +128,14 @@ func (s *TcpdumpController) NeUPFTask(c *gin.Context) { } err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil { - c.JSON(400, result.CodeMsg(400, "parameter error")) + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查网元信息 neInfo := s.NeInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) if neInfo.NeId != body.NeId { - msg := fmt.Sprintf("找不到 %s %s 对应网元信息", body.NeType, body.NeId) + msg := i18n.TTemplate(language, "trace.tcpdump.noData", map[string]any{"type": body.NeType, "id": body.NeId}) c.JSON(200, result.ErrMsg(msg)) return } diff --git a/src/modules/trace/service/tcpdump.impl.go b/src/modules/trace/service/tcpdump.impl.go index 2b81dda..6b8c005 100644 --- a/src/modules/trace/service/tcpdump.impl.go +++ b/src/modules/trace/service/tcpdump.impl.go @@ -5,18 +5,18 @@ import ( "net" "time" - netElementService "ems.agt/src/modules/net_element/service" + neService "ems.agt/src/modules/network_element/service" ) // 实例化服务层 TcpdumpImpl 结构体 var NewTcpdumpImpl = &TcpdumpImpl{ - neInfoService: netElementService.NewNeInfoImpl, + neInfoService: neService.NewNeInfoImpl, } // 通用请求 服务层处理 type TcpdumpImpl struct { // 网元信息服务 - neInfoService netElementService.INeInfo + neInfoService neService.INeInfo } // UPFTelnetStart UPF进行telnet抓包 diff --git a/src/modules/trace/trace.go b/src/modules/trace/trace.go index 14556e1..66b4e9f 100644 --- a/src/modules/trace/trace.go +++ b/src/modules/trace/trace.go @@ -18,17 +18,17 @@ func Setup(router *gin.Engine) { { tcpdumpGroup.POST("/ne", middleware.PreAuthorize(nil), - collectlogs.OperateLog(collectlogs.OptionNew("Signaling Grab", collectlogs.BUSINESS_TYPE_OTHER)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.tcpdump", collectlogs.BUSINESS_TYPE_OTHER)), controller.NewTcpdump.NeTask, ) tcpdumpGroup.POST("/neUPF", middleware.PreAuthorize(nil), - collectlogs.OperateLog(collectlogs.OptionNew("Signaling Grab", collectlogs.BUSINESS_TYPE_OTHER)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.tcpdump", collectlogs.BUSINESS_TYPE_OTHER)), controller.NewTcpdump.NeUPFTask, ) tcpdumpGroup.POST("/download", middleware.PreAuthorize(nil), - collectlogs.OperateLog(collectlogs.OptionNew("Signaling Grab", collectlogs.BUSINESS_TYPE_IMPORT)), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.tcpdump", collectlogs.BUSINESS_TYPE_IMPORT)), controller.NewTcpdump.Download, ) }