package controller import ( "fmt" "strconv" "strings" "time" "be.ems/src/framework/config" "be.ems/src/framework/constants/admin" "be.ems/src/framework/constants/common" "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/regular" "be.ems/src/framework/vo/result" "be.ems/src/modules/system/model" "be.ems/src/modules/system/service" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" ) // 实例化控制层 SysUserController 结构体 var NewSysUser = &SysUserController{ sysUserService: service.NewSysUserImpl, sysRoleService: service.NewSysRoleImpl, sysPostService: service.NewSysPostImpl, sysDictDataService: service.NewSysDictDataImpl, sysConfigService: service.NewSysConfigImpl, } // 用户信息 // // PATH /system/user type SysUserController struct { // 用户服务 sysUserService service.ISysUser // 角色服务 sysRoleService service.ISysRole // 岗位服务 sysPostService service.ISysPost // 字典数据服务 sysDictDataService service.ISysDictData // 参数配置服务 sysConfigService service.ISysConfig } // 用户信息列表 // // GET /list 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)) } // 用户信息详情 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 查询系统角色列表 dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") roles := s.sysRoleService.SelectRoleList(model.SysRole{}, dataScopeSQL) // 不是系统指定管理员需要排除其角色 if !config.IsAdmin(userId) { rolesFilter := make([]model.SysRole, 0) for _, r := range roles { if r.RoleID != admin.ROLE_ID { rolesFilter = append(rolesFilter, r) } } 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{ "user": map[string]any{}, "roleIds": []string{}, "postIds": []string{}, "roles": roles, "posts": posts, })) return } // 检查用户是否存在 user := s.sysUserService.SelectUserById(userId) if user.UserID != userId { 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 { roleIds = append(roleIds, r.RoleID) } // 岗位ID组 postIds := make([]string, 0) userPosts := s.sysPostService.SelectPostListByUserId(userId) for _, p := range userPosts { postIds = append(postIds, p.PostID) } c.JSON(200, result.OkData(map[string]any{ "user": user, "roleIds": roleIds, "postIds": postIds, "roles": roles, "posts": posts, })) } // 用户信息新增 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 密码单独取,避免序列化输出 var bodyPassword struct { Password string `json:"password" binding:"required"` } if err := c.ShouldBindBodyWith(&bodyPassword, binding.JSON); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } body.Password = bodyPassword.Password // 检查用户登录账号是否唯一 uniqueUserName := s.sysUserService.CheckUniqueUserName(body.UserName, "") if !uniqueUserName { // 新增用户【%s】失败,登录账号已存在 // 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 } // 检查手机号码格式并判断是否唯一 if body.PhoneNumber != "" { if regular.ValidMobile(body.PhoneNumber) { 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 := 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 := i18n.TTemplate(language, "user.errPhoneFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } // 检查邮箱格式并判断是否唯一 if body.Email != "" { if regular.ValidEmail(body.Email) { uniqueEmail := s.sysUserService.CheckUniqueEmail(body.Email, "") if !uniqueEmail { // 新增用户【%s】失败,邮箱已存在 // 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 := i18n.TTemplate(language, "user.errEmailFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } body.CreateBy = ctx.LoginUserToUserName(c) insertId := s.sysUserService.InsertUser(body) if insertId != "" { c.JSON(200, result.Ok(nil)) return } c.JSON(200, result.Err(nil)) } // 用户信息修改 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员用户 if config.IsAdmin(body.UserID) { // 不允许操作管理员用户 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(i18n.TKey(language, "user.noData"))) return } // 检查用户登录账号是否唯一 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 := i18n.TTemplate(language, "user.errNameExists", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } // 检查手机号码格式并判断是否唯一 if body.PhoneNumber != "" { if regular.ValidMobile(body.PhoneNumber) { 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 := 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 := i18n.TTemplate(language, "user.errPhoneFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } // 检查邮箱格式并判断是否唯一 if body.Email != "" { if regular.ValidEmail(body.Email) { 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 := 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 := i18n.TTemplate(language, "user.errEmailFormat", map[string]any{"name": body.UserName}) c.JSON(200, result.ErrMsg(msg)) return } } body.UserName = "" // 忽略修改登录用户名称 body.Password = "" // 忽略修改密码 body.LoginIP = "" // 忽略登录IP body.LoginDate = 0 // 忽略登录时间 body.UpdateBy = ctx.LoginUserToUserName(c) rows := s.sysUserService.UpdateUserAndRolePost(body) if rows > 0 { c.JSON(200, result.Ok(nil)) return } c.JSON(200, result.Err(nil)) } // 用户信息删除 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 ids := strings.Split(userIds, ",") uniqueIDs := parse.RemoveDuplicates(ids) if len(uniqueIDs) <= 0 { 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 := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) c.JSON(200, result.OkMsg(msg)) } // 用户重置密码 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 检查是否管理员用户 if config.IsAdmin(body.UserID) { // 不允许操作内置用户 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(i18n.TKey(language, "user.noData"))) return } if !regular.ValidPassword(body.Password) { // 登录密码至少包含大小写字母、数字、特殊符号,且不少于6位 c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.errPasswd"))) return } userName := ctx.LoginUserToUserName(c) info := model.SysUser{ UserID: body.UserID, Password: body.Password, UpdateBy: userName, } rows := s.sysUserService.UpdateUser(info) if rows > 0 { c.JSON(200, result.Ok(nil)) return } c.JSON(200, result.Err(nil)) } // 用户状态修改 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 检查是否存在 user := s.sysUserService.SelectUserById(body.UserID) if user.UserID != body.UserID { // 没有可访问用户数据! c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.noData"))) return } // 与旧值相等不变更 if user.Status == body.Status { // 变更状态与旧值相等! c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.statusEq"))) return } userName := ctx.LoginUserToUserName(c) info := model.SysUser{ UserID: body.UserID, Status: body.Status, UpdateBy: userName, } rows := s.sysUserService.UpdateUser(info) if rows > 0 { c.JSON(200, result.Ok(nil)) return } c.JSON(200, result.Err(nil)) } // 用户信息列表导出 // // POST /export func (s *SysUserController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 // querys := ctx.BodyJSONMap(c) querys := map[string]any{ "pageNum": 1, "pageSize": 1000, } dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u") data := s.sysUserService.SelectUserPage(querys, dataScopeSQL) if data["total"].(int64) == 0 { // 导出数据记录为空 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": 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.role"), "E1": i18n.TKey(language, "user.export.deptName"), "F1": i18n.TKey(language, "user.export.loginIP"), "G1": i18n.TKey(language, "user.export.loginDate"), "H1": i18n.TKey(language, "user.export.status"), // "F1": i18n.TKey(language, "user.export.sex"), // "E1": i18n.TKey(language, "user.export.phone"), // "D1": i18n.TKey(language, "user.export.email"), // "I1": i18n.TKey(language, "user.export.deptID"), // "K1": i18n.TKey(language, "user.export.deptLeader"), } // 读取用户性别字典数据 // dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) // 用户性别 // sysUserSex := row.Sex // for _, v := range dictSysUserSex { // if row.Sex == v.DictValue { // sysUserSex = i18n.TKey(language, v.DictLabel) // break // } // } // 帐号状态 statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { statusValue = i18n.TKey(language, "dictData.normal") } // 用户角色, 默认导出首个 userRole := "" if len(row.Roles) > 0 { userRole = i18n.TKey(language, row.Roles[0].RoleName) } dataCells = append(dataCells, map[string]any{ "A" + idx: row.UserID, "B" + idx: row.UserName, "C" + idx: row.NickName, "D" + idx: userRole, "E" + idx: row.Dept.DeptName, "F" + idx: row.LoginIP, "G" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS), "H" + idx: statusValue, // "E" + idx: row.PhoneNumber, // "F" + idx: sysUserSex, // "D" + idx: row.Email, // "I" + idx: row.Dept.DeptID, // "K" + idx: row.Dept.Leader, }) } // 导出数据表格 saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "") if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return } c.FileAttachment(saveFilePath, fileName) } // 用户信息列表导入模板下载 // // GET /importTemplate func (s *SysUserController) Template(c *gin.Context) { fileName := fmt.Sprintf("user_import_template_%d.xlsx", time.Now().UnixMilli()) // 多语言处理 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 { c.String(500, "Failed to read file") return } // 设置响应头 c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName)) c.Header("Content-Type", "application/octet-stream") // 返回响应体 c.Data(200, "application/octet-stream", fileData) } // 用户信息列表导入 // // 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, i18n.TKey(language, "app.common.err400"))) return } // 保存表格文件 filePath, err := file.TransferExeclUploadFile(formFile) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return } // 读取表格数据 rows, err := file.ReadSheet(filePath, "") if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return } // 获取操作人名称 operName := ctx.LoginUserToUserName(c) isUpdateSupport := parse.Boolean(updateSupport) // 读取默认初始密码 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"] == "正常" || row["G"] == "Normal" { sysUserStatus = common.STATUS_YES } // 用户角色 拿编号 sysUserRole := "" if v, ok := row["H"]; ok && v != "" { sysUserRole = strings.SplitN(v, "-", 2)[0] if sysUserRole == "1" { sysUserRole = "" } } // 构建用户实体信息 newSysUser := model.SysUser{ UserType: "sys", Password: initPassword, DeptID: row["I"], UserName: row["B"], NickName: row["C"], PhoneNumber: row["E"], Email: row["D"], Status: sysUserStatus, Sex: sysUserSex, RoleIDs: []string{sysUserRole}, } // 检查手机号码格式并判断是否唯一 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"], "name": 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"], "name": newSysUser.UserName}) successNum++ successMsgArr = append(successMsgArr, msg) } else { // 用户编号:%s 登录名称 %s 更新失败 msg := i18n.TTemplate(language, "user.import.failUpdate", map[string]any{"id": row["A"], "name": 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": successNum}) message = strings.Join(append([]string{msg}, successMsgArr...), "
") } c.JSON(200, result.OkMsg(message)) }