diff --git a/features/sys_dict_data/api_sys_dict_data.go b/features/sys_dict_data/api_sys_dict_data.go new file mode 100644 index 00000000..05dbb081 --- /dev/null +++ b/features/sys_dict_data/api_sys_dict_data.go @@ -0,0 +1,247 @@ +package sysdictdata + +import ( + "fmt" + "net/http" + "strings" + + "ems.agt/features/sys_dict_data/model" + sysDictDataService "ems.agt/features/sys_dict_data/service" + sysDictTypeService "ems.agt/features/sys_dict_type/service" + "ems.agt/lib/core/utils/ctx" + "ems.agt/lib/core/utils/parse" + "ems.agt/lib/core/vo/result" + "ems.agt/lib/midware" + "ems.agt/lib/services" + "ems.agt/restagent/config" +) + +// 字典类型对应的字典数据信息接口添加到路由 +func Routers() []services.RouterItem { + // 实例化控制层 SysDictDataApi 结构体 + var apis = &SysDictDataApi{ + sysDictDataService: sysDictDataService.NewServiceSysDictData, + sysDictTypeService: sysDictTypeService.NewServiceSysDictType, + } + + rs := [...]services.RouterItem{ + { + Method: "GET", + Pattern: "/dictDatas", + Handler: apis.List, + Middleware: midware.Authorize(nil), + }, + { + Method: "GET", + Pattern: "/dictData/{dictCode}", + Handler: apis.Info, + Middleware: midware.Authorize(nil), + }, + { + Method: "POST", + Pattern: "/dictData", + Handler: apis.Add, + Middleware: midware.Authorize(nil), + }, + { + Method: "PUT", + Pattern: "/dictData", + Handler: apis.Edit, + Middleware: midware.Authorize(nil), + }, + { + Method: "DELETE", + Pattern: "/dictData/{dictCodes}", + Handler: apis.Remove, + Middleware: midware.Authorize(nil), + }, + { + Method: "GET", + Pattern: "/dictData/type/{dictType}", + Handler: apis.DictType, + Middleware: midware.Authorize(nil), + }, + // 添加更多的 Router 对象... + } + + // 生成两组前缀路由 + rsPrefix := []services.RouterItem{} + for _, v := range rs { + path := "/dictDataManage/{apiVersion}" + v.Pattern + // 固定前缀 + v.Pattern = config.DefaultUriPrefix + path + rsPrefix = append(rsPrefix, v) + // 可配置 + v.Pattern = config.UriPrefix + path + rsPrefix = append(rsPrefix, v) + } + return rsPrefix +} + +// 字典类型对应的字典数据信息 +// +// PATH /dictDataManage +type SysDictDataApi struct { + // 字典数据服务 + sysDictDataService *sysDictDataService.ServiceSysDictData + // 字典类型服务 + sysDictTypeService *sysDictTypeService.ServiceSysDictType +} + +// 字典数据列表 +// +// GET /list +func (s *SysDictDataApi) List(w http.ResponseWriter, r *http.Request) { + querys := ctx.QueryMap(r) + data := s.sysDictDataService.SelectDictDataPage(querys) + ctx.JSON(w, 200, result.Ok(data)) +} + +// 字典数据详情 +// +// GET /:dictCode +func (s *SysDictDataApi) Info(w http.ResponseWriter, r *http.Request) { + dictCode := ctx.Param(r, "dictCode") + if dictCode == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + data := s.sysDictDataService.SelectDictDataByCode(dictCode) + if data.DictCode == dictCode { + ctx.JSON(w, 200, result.OkData(data)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 字典数据新增 +// +// POST / +func (s *SysDictDataApi) Add(w http.ResponseWriter, r *http.Request) { + var body model.SysDictData + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.DictCode != "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查字典类型是否存在 + sysDictType := s.sysDictTypeService.SelectDictTypeByType(body.DictType) + if sysDictType.DictType != body.DictType { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问字典类型数据!")) + return + } + + // 检查字典标签唯一 + uniqueDictLabel := s.sysDictDataService.CheckUniqueDictLabel(body.DictType, body.DictLabel, "") + if !uniqueDictLabel { + msg := fmt.Sprintf("数据新增【%s】失败,该字典类型下标签名已存在", body.DictLabel) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + // 检查字典键值唯一 + uniqueDictValue := s.sysDictDataService.CheckUniqueDictValue(body.DictType, body.DictValue, "") + if !uniqueDictValue { + msg := fmt.Sprintf("数据新增【%s】失败,该字典类型下标签值已存在", body.DictValue) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + body.CreateBy = ctx.LoginUserToUserName(r) + insertId := s.sysDictDataService.InsertDictData(body) + if insertId != "" { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 字典类型修改 +// +// PUT / +func (s *SysDictDataApi) Edit(w http.ResponseWriter, r *http.Request) { + var body model.SysDictData + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.DictCode == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查字典类型是否存在 + sysDictType := s.sysDictTypeService.SelectDictTypeByType(body.DictType) + if sysDictType.DictType != body.DictType { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问字典类型数据!")) + return + } + + // 检查字典编码是否存在 + SysDictDataApi := s.sysDictDataService.SelectDictDataByCode(body.DictCode) + if SysDictDataApi.DictCode != body.DictCode { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问字典编码数据!")) + return + } + + // 检查字典标签唯一 + uniqueDictLabel := s.sysDictDataService.CheckUniqueDictLabel(body.DictType, body.DictLabel, body.DictCode) + if !uniqueDictLabel { + msg := fmt.Sprintf("数据修改【%s】失败,该字典类型下标签名已存在", body.DictLabel) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + // 检查字典键值唯一 + uniqueDictValue := s.sysDictDataService.CheckUniqueDictValue(body.DictType, body.DictValue, body.DictCode) + if !uniqueDictValue { + msg := fmt.Sprintf("数据修改【%s】失败,该字典类型下标签值已存在", body.DictValue) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + body.UpdateBy = ctx.LoginUserToUserName(r) + rows := s.sysDictDataService.UpdateDictData(body) + if rows > 0 { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 字典数据删除 +// +// DELETE /:dictCodes +func (s *SysDictDataApi) Remove(w http.ResponseWriter, r *http.Request) { + dictCodes := ctx.Param(r, "dictCodes") + if dictCodes == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(dictCodes, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + ctx.JSON(w, 200, result.Err(nil)) + return + } + rows, err := s.sysDictDataService.DeleteDictDataByCodes(uniqueIDs) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + msg := fmt.Sprintf("删除成功:%d", rows) + ctx.JSON(w, 200, result.OkMsg(msg)) +} + +// 字典数据列表(指定字典类型) +// +// GET /type/:dictType +func (s *SysDictDataApi) DictType(w http.ResponseWriter, r *http.Request) { + dictType := ctx.Param(r, "dictType") + if dictType == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + data := s.sysDictDataService.SelectDictDataByType(dictType) + ctx.JSON(w, 200, result.OkData(data)) +} diff --git a/features/sys_dict_data/model/sys_dict_data.go b/features/sys_dict_data/model/sys_dict_data.go new file mode 100644 index 00000000..7c8cd06a --- /dev/null +++ b/features/sys_dict_data/model/sys_dict_data.go @@ -0,0 +1,31 @@ +package model + +// SysDictData 字典数据对象 sys_dict_data +type SysDictData struct { + // 字典编码 + DictCode string `json:"dictCode"` + // 字典排序 + DictSort int `json:"dictSort"` + // 字典标签 + DictLabel string `json:"dictLabel" binding:"required"` + // 字典键值 + DictValue string `json:"dictValue" binding:"required"` + // 字典类型 + DictType string `json:"dictType" binding:"required"` + // 样式属性(样式扩展) + TagClass string `json:"tagClass"` + // 标签类型(预设颜色) + TagType string `json:"tagType"` + // 状态(0停用 1正常) + Status string `json:"status"` + // 创建者 + CreateBy string `json:"createBy"` + // 创建时间 + CreateTime int64 `json:"createTime"` + // 更新者 + UpdateBy string `json:"updateBy"` + // 更新时间 + UpdateTime int64 `json:"updateTime"` + // 备注 + Remark string `json:"remark"` +} diff --git a/features/sys_dict_data/repo/repo_sys_dict_data.go b/features/sys_dict_data/repo/repo_sys_dict_data.go new file mode 100644 index 00000000..cd6268a6 --- /dev/null +++ b/features/sys_dict_data/repo/repo_sys_dict_data.go @@ -0,0 +1,369 @@ +package repo + +import ( + "fmt" + "strings" + "time" + + "ems.agt/features/sys_dict_data/model" + "ems.agt/lib/core/datasource" + "ems.agt/lib/core/utils/parse" + "ems.agt/lib/log" +) + +// 实例化数据层 RepoSysDictData 结构体 +var NewRepoSysDictData = &RepoSysDictData{ + selectSql: `select + dict_code, dict_sort, dict_label, dict_value, dict_type, tag_class, tag_type, status, create_by, create_time, remark + from sys_dict_data`, + + resultMap: map[string]string{ + "dict_code": "DictCode", + "dict_sort": "DictSort", + "dict_label": "DictLabel", + "dict_value": "DictValue", + "dict_type": "DictType", + "tag_class": "TagClass", + "tag_type": "TagType", + "status": "Status", + "remark": "Remark", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + }, +} + +// RepoSysDictData 字典类型数据表 数据层处理 +type RepoSysDictData struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *RepoSysDictData) convertResultRows(rows []map[string]any) []model.SysDictData { + arr := make([]model.SysDictData, 0) + for _, row := range rows { + sysDictData := model.SysDictData{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + datasource.SetFieldValue(&sysDictData, keyMapper, value) + } + } + arr = append(arr, sysDictData) + } + return arr +} + +// SelectDictDataPage 根据条件分页查询字典数据 +func (r *RepoSysDictData) SelectDictDataPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["dictType"]; ok && v != "" { + conditions = append(conditions, "dict_type = ?") + params = append(params, v) + } + if v, ok := query["dictLabel"]; ok && v != "" { + conditions = append(conditions, "dict_label like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["status"]; ok && v != "" { + conditions = append(conditions, "status = ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from sys_dict_data" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + log.Errorf("total err => %v", err) + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return map[string]any{ + "total": total, + "rows": []model.SysDictData{}, + } + } + + // 分页 + pageNum, pageSize := datasource.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " order by dict_sort asc limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err => %v", err) + } + + // 转换实体 + rows := r.convertResultRows(results) + return map[string]any{ + "total": total, + "rows": rows, + } +} + +// SelectDictDataList 根据条件查询字典数据 +func (r *RepoSysDictData) SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData { + // 查询条件拼接 + var conditions []string + var params []any + if sysDictData.DictLabel != "" { + conditions = append(conditions, "dict_label like concat(?, '%')") + params = append(params, sysDictData.DictLabel) + } + if sysDictData.DictType != "" { + conditions = append(conditions, "dict_type = ?") + params = append(params, sysDictData.DictType) + } + if sysDictData.Status != "" { + conditions = append(conditions, "status = ?") + params = append(params, sysDictData.Status) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + orderSql := " order by dict_sort asc " + querySql := r.selectSql + whereSql + orderSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err => %v", err) + return []model.SysDictData{} + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectDictDataByCodes 根据字典数据编码查询信息 +func (r *RepoSysDictData) SelectDictDataByCodes(dictCodes []string) []model.SysDictData { + placeholder := datasource.KeyPlaceholderByQuery(len(dictCodes)) + querySql := r.selectSql + " where dict_code in (" + placeholder + ")" + parameters := datasource.ConvertIdsSlice(dictCodes) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + log.Errorf("query err => %v", err) + return []model.SysDictData{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// CountDictDataByType 查询字典数据 +func (r *RepoSysDictData) CountDictDataByType(dictType string) int64 { + querySql := "select count(1) as 'total' from sys_dict_data where dict_type = ?" + results, err := datasource.RawDB("", querySql, []any{dictType}) + if err != nil { + log.Errorf("query err => %v", err) + return 0 + } + if len(results) > 0 { + return parse.Number(results[0]["total"]) + } + return 0 +} + +// CheckUniqueDictData 校验字典数据是否唯一 +func (r *RepoSysDictData) CheckUniqueDictData(sysDictData model.SysDictData) string { + // 查询条件拼接 + var conditions []string + var params []any + if sysDictData.DictType != "" { + conditions = append(conditions, "dict_type = ?") + params = append(params, sysDictData.DictType) + } + if sysDictData.DictLabel != "" { + conditions = append(conditions, "dict_label = ?") + params = append(params, sysDictData.DictLabel) + } + if sysDictData.DictValue != "" { + conditions = append(conditions, "dict_value = ?") + params = append(params, sysDictData.DictValue) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } else { + return "" + } + + // 查询数据 + querySql := "select dict_code as 'str' from sys_dict_data " + whereSql + " limit 1" + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err %v", err) + return "" + } + if len(results) > 0 { + return fmt.Sprintf("%v", results[0]["str"]) + } + return "" +} + +// DeleteDictDataByCodes 批量删除字典数据信息 +func (r *RepoSysDictData) DeleteDictDataByCodes(dictCodes []string) int64 { + placeholder := datasource.KeyPlaceholderByQuery(len(dictCodes)) + sql := "delete from sys_dict_data where dict_code in (" + placeholder + ")" + parameters := datasource.ConvertIdsSlice(dictCodes) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + log.Errorf("delete err => %v", err) + return 0 + } + affected, err := results.RowsAffected() + if err != nil { + log.Errorf("delete err => %v", err) + return 0 + } + return affected +} + +// InsertDictData 新增字典数据信息 +func (r *RepoSysDictData) InsertDictData(sysDictData model.SysDictData) string { + // 参数拼接 + params := make(map[string]any) + if sysDictData.DictSort > 0 { + params["dict_sort"] = sysDictData.DictSort + } + if sysDictData.DictLabel != "" { + params["dict_label"] = sysDictData.DictLabel + } + if sysDictData.DictValue != "" { + params["dict_value"] = sysDictData.DictValue + } + 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 + } + if sysDictData.CreateBy != "" { + params["create_by"] = sysDictData.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := datasource.KeyPlaceholderValueByInsert(params) + sql := "insert into sys_dict_data (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + // 执行插入 + results, err := datasource.ExecDB("", sql, values) + if err != nil { + log.Errorf("insert row : %v", err.Error()) + return "" + } + insertId, err := results.LastInsertId() + if err != nil { + log.Errorf("insert row : %v", err.Error()) + return "" + } + return fmt.Sprint(insertId) +} + +// UpdateDictData 修改字典数据信息 +func (r *RepoSysDictData) UpdateDictData(sysDictData model.SysDictData) int64 { + // 参数拼接 + params := make(map[string]any) + if sysDictData.DictSort > 0 { + params["dict_sort"] = sysDictData.DictSort + } + if sysDictData.DictLabel != "" { + params["dict_label"] = sysDictData.DictLabel + } + if sysDictData.DictValue != "" { + params["dict_value"] = sysDictData.DictValue + } + 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 + } + if sysDictData.UpdateBy != "" { + params["update_by"] = sysDictData.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := datasource.KeyValueByUpdate(params) + sql := "update sys_dict_data set " + strings.Join(keys, ",") + " where dict_code = ?" + + // 执行更新 + values = append(values, sysDictData.DictCode) + results, err := datasource.ExecDB("", sql, values) + if err != nil { + log.Errorf("update row : %v", err.Error()) + return 0 + } + affected, err := results.RowsAffected() + if err != nil { + log.Errorf("update err => %v", err) + return 0 + } + return affected +} + +// UpdateDictDataType 同步修改字典类型 +func (r *RepoSysDictData) UpdateDictDataType(oldDictType string, newDictType string) int64 { + // 参数拼接 + params := make([]any, 0) + if oldDictType == "" || newDictType == "" { + return 0 + } + params = append(params, newDictType) + params = append(params, oldDictType) + + // 构建执行语句 + sql := "update sys_dict_data set dict_type = ? where dict_type = ?" + + // 执行更新 + results, err := datasource.ExecDB("", sql, params) + if err != nil { + log.Errorf("update row : %v", err.Error()) + return 0 + } + affected, err := results.RowsAffected() + if err != nil { + log.Errorf("update err => %v", err) + return 0 + } + return affected +} diff --git a/features/sys_dict_data/service/service_sys_dict_data.go b/features/sys_dict_data/service/service_sys_dict_data.go new file mode 100644 index 00000000..624105e2 --- /dev/null +++ b/features/sys_dict_data/service/service_sys_dict_data.go @@ -0,0 +1,111 @@ +package service + +import ( + "errors" + + "ems.agt/features/sys_dict_data/model" + "ems.agt/features/sys_dict_data/repo" + sysDictTypeService "ems.agt/features/sys_dict_type/service" +) + +// 实例化服务层 ServiceSysDictData 结构体 +var NewServiceSysDictData = &ServiceSysDictData{ + sysDictDataRepository: *repo.NewRepoSysDictData, + sysDictTypeService: *sysDictTypeService.NewServiceSysDictType, +} + +// ServiceSysDictData 字典类型数据 服务层处理 +type ServiceSysDictData struct { + // 字典数据服务 + sysDictDataRepository repo.RepoSysDictData + // 字典类型服务 + sysDictTypeService sysDictTypeService.ServiceSysDictType +} + +// SelectDictDataPage 根据条件分页查询字典数据 +func (r *ServiceSysDictData) SelectDictDataPage(query map[string]any) map[string]any { + return r.sysDictDataRepository.SelectDictDataPage(query) +} + +// SelectDictDataList 根据条件查询字典数据 +func (r *ServiceSysDictData) SelectDictDataList(sysDictData model.SysDictData) []model.SysDictData { + return r.sysDictDataRepository.SelectDictDataList(sysDictData) +} + +// SelectDictDataByCode 根据字典数据编码查询信息 +func (r *ServiceSysDictData) SelectDictDataByCode(dictCode string) model.SysDictData { + if dictCode == "" { + return model.SysDictData{} + } + dictCodes := r.sysDictDataRepository.SelectDictDataByCodes([]string{dictCode}) + if len(dictCodes) > 0 { + return dictCodes[0] + } + return model.SysDictData{} +} + +// SelectDictDataByType 根据字典类型查询信息 +func (r *ServiceSysDictData) SelectDictDataByType(dictType string) []model.SysDictData { + return r.sysDictTypeService.DictDataCache(dictType) +} + +// CheckUniqueDictLabel 校验字典标签是否唯一 +func (r *ServiceSysDictData) CheckUniqueDictLabel(dictType, dictLabel, dictCode string) bool { + uniqueId := r.sysDictDataRepository.CheckUniqueDictData(model.SysDictData{ + DictType: dictType, + DictLabel: dictLabel, + }) + if uniqueId == dictCode { + return true + } + return uniqueId == "" +} + +// CheckUniqueDictValue 校验字典键值是否唯一 +func (r *ServiceSysDictData) CheckUniqueDictValue(dictType, dictValue, dictCode string) bool { + uniqueId := r.sysDictDataRepository.CheckUniqueDictData(model.SysDictData{ + DictType: dictType, + DictValue: dictValue, + }) + if uniqueId == dictCode { + return true + } + return uniqueId == "" +} + +// DeleteDictDataByCodes 批量删除字典数据信息 +func (r *ServiceSysDictData) DeleteDictDataByCodes(dictCodes []string) (int64, error) { + // 检查是否存在 + dictDatas := r.sysDictDataRepository.SelectDictDataByCodes(dictCodes) + if len(dictDatas) <= 0 { + return 0, errors.New("没有权限访问字典编码数据!") + } + if len(dictDatas) == len(dictCodes) { + for _, v := range dictDatas { + // 刷新缓存 + r.sysDictTypeService.ClearDictCache(v.DictType) + r.sysDictTypeService.LoadingDictCache(v.DictType) + } + rows := r.sysDictDataRepository.DeleteDictDataByCodes(dictCodes) + return rows, nil + } + return 0, errors.New("删除字典数据信息失败!") +} + +// InsertDictData 新增字典数据信息 +func (r *ServiceSysDictData) InsertDictData(sysDictData model.SysDictData) string { + insertId := r.sysDictDataRepository.InsertDictData(sysDictData) + if insertId != "" { + r.sysDictTypeService.LoadingDictCache(sysDictData.DictType) + } + return insertId +} + +// UpdateDictData 修改字典数据信息 +func (r *ServiceSysDictData) UpdateDictData(sysDictData model.SysDictData) int64 { + rows := r.sysDictDataRepository.UpdateDictData(sysDictData) + if rows > 0 { + r.sysDictTypeService.LoadingDictCache(sysDictData.DictType) + } + return rows +} diff --git a/features/sys_dict_type/api_sys_dict_type.go b/features/sys_dict_type/api_sys_dict_type.go new file mode 100644 index 00000000..480ff01c --- /dev/null +++ b/features/sys_dict_type/api_sys_dict_type.go @@ -0,0 +1,253 @@ +package sysdicttype + +import ( + "fmt" + "net/http" + "strings" + + "ems.agt/features/sys_dict_type/model" + sysDictTypeService "ems.agt/features/sys_dict_type/service" + "ems.agt/lib/core/utils/ctx" + "ems.agt/lib/core/utils/parse" + "ems.agt/lib/core/vo/result" + "ems.agt/lib/midware" + "ems.agt/lib/services" + "ems.agt/restagent/config" +) + +// 字典类型信息接口添加到路由 +func Routers() []services.RouterItem { + // 实例化控制层 SysDictTypeApi 结构体 + var apis = &SysDictTypeApi{ + sysDictTypeService: *sysDictTypeService.NewServiceSysDictType, + } + + rs := [...]services.RouterItem{ + { + Method: "GET", + Pattern: "/dictTypes", + Handler: apis.List, + Middleware: midware.Authorize(nil), + }, + { + Method: "GET", + Pattern: "/dictType/{dictId}", + Handler: apis.Info, + Middleware: midware.Authorize(nil), + }, + { + Method: "POST", + Pattern: "/dictType", + Handler: apis.Add, + Middleware: midware.Authorize(nil), + }, + { + Method: "PUT", + Pattern: "/dictType", + Handler: apis.Edit, + Middleware: midware.Authorize(nil), + }, + { + Method: "DELETE", + Pattern: "/dictType/{dictIds}", + Handler: apis.Remove, + Middleware: midware.Authorize(nil), + }, + { + Method: "PUT", + Pattern: "/dictType/refreshCache", + Handler: apis.RefreshCache, + Middleware: midware.Authorize(nil), + }, + { + Method: "GET", + Pattern: "/dictTypes/optionselect", + Handler: apis.DictOptionselect, + Middleware: midware.Authorize(nil), + }, + // 添加更多的 Router 对象... + } + + // 生成两组前缀路由 + rsPrefix := []services.RouterItem{} + for _, v := range rs { + path := "/dictTypegManage/{apiVersion}" + v.Pattern + // 固定前缀 + v.Pattern = config.DefaultUriPrefix + path + rsPrefix = append(rsPrefix, v) + // 可配置 + v.Pattern = config.UriPrefix + path + rsPrefix = append(rsPrefix, v) + } + return rsPrefix +} + +// 字典类型信息 +// +// PATH /dictTypegManage +type SysDictTypeApi struct { + // 字典类型服务 + sysDictTypeService sysDictTypeService.ServiceSysDictType +} + +// 字典类型列表 +// +// GET /list +func (s *SysDictTypeApi) List(w http.ResponseWriter, r *http.Request) { + querys := ctx.QueryMap(r) + data := s.sysDictTypeService.SelectDictTypePage(querys) + ctx.JSON(w, 200, result.Ok(data)) +} + +// 字典类型信息 +// +// GET /:dictId +func (s *SysDictTypeApi) Info(w http.ResponseWriter, r *http.Request) { + dictId := ctx.Param(r, "dictId") + if dictId == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + data := s.sysDictTypeService.SelectDictTypeByID(dictId) + if data.DictID == dictId { + ctx.JSON(w, 200, result.OkData(data)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 字典类型新增 +// +// POST / +func (s *SysDictTypeApi) Add(w http.ResponseWriter, r *http.Request) { + var body model.SysDictType + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.DictID != "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查字典名称唯一 + uniqueDictName := s.sysDictTypeService.CheckUniqueDictName(body.DictName, "") + if !uniqueDictName { + msg := fmt.Sprintf("字典新增【%s】失败,字典名称已存在", body.DictName) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + // 检查字典类型唯一 + uniqueDictType := s.sysDictTypeService.CheckUniqueDictType(body.DictType, "") + if !uniqueDictType { + msg := fmt.Sprintf("字典新增【%s】失败,字典类型已存在", body.DictType) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + body.CreateBy = ctx.LoginUserToUserName(r) + insertId := s.sysDictTypeService.InsertDictType(body) + if insertId != "" { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 字典类型修改 +// +// PUT / +func (s *SysDictTypeApi) Edit(w http.ResponseWriter, r *http.Request) { + var body model.SysDictType + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.DictID == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查数据是否存在 + dictInfo := s.sysDictTypeService.SelectDictTypeByID(body.DictID) + if dictInfo.DictID != body.DictID { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问字典类型数据!")) + return + } + + // 检查字典名称唯一 + uniqueDictName := s.sysDictTypeService.CheckUniqueDictName(body.DictName, body.DictID) + if !uniqueDictName { + msg := fmt.Sprintf("字典修改【%s】失败,字典名称已存在", body.DictName) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + // 检查字典类型唯一 + uniqueDictType := s.sysDictTypeService.CheckUniqueDictType(body.DictType, body.DictID) + if !uniqueDictType { + msg := fmt.Sprintf("字典修改【%s】失败,字典类型已存在", body.DictType) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + body.UpdateBy = ctx.LoginUserToUserName(r) + rows := s.sysDictTypeService.UpdateDictType(body) + if rows > 0 { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 字典类型删除 +// +// DELETE /:dictIds +func (s *SysDictTypeApi) Remove(w http.ResponseWriter, r *http.Request) { + dictIds := ctx.Param(r, "dictIds") + if dictIds == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(dictIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + ctx.JSON(w, 200, result.Err(nil)) + return + } + rows, err := s.sysDictTypeService.DeleteDictTypeByIDs(uniqueIDs) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + msg := fmt.Sprintf("删除成功:%d", rows) + ctx.JSON(w, 200, result.OkMsg(msg)) +} + +// 字典类型刷新缓存 +// +// PUT /refreshCache +func (s *SysDictTypeApi) RefreshCache(w http.ResponseWriter, r *http.Request) { + s.sysDictTypeService.ResetDictCache() + ctx.JSON(w, 200, result.Ok(nil)) +} + +// 字典类型选择框列表 +// +// GET /getDictOptionselect +func (s *SysDictTypeApi) DictOptionselect(w http.ResponseWriter, r *http.Request) { + data := s.sysDictTypeService.SelectDictTypeList(model.SysDictType{ + Status: "1", + }) + + type labelValue struct { + Label string `json:"label"` + Value string `json:"value"` + } + + // 数据组 + arr := []labelValue{} + for _, v := range data { + arr = append(arr, labelValue{ + Label: v.DictName, + Value: v.DictType, + }) + } + ctx.JSON(w, 200, result.OkData(arr)) +} diff --git a/features/sys_dict_type/model/sys_dict_type.go b/features/sys_dict_type/model/sys_dict_type.go new file mode 100644 index 00000000..0ad0b1ab --- /dev/null +++ b/features/sys_dict_type/model/sys_dict_type.go @@ -0,0 +1,23 @@ +package model + +// SysDictType 字典类型对象 sys_dict_type +type SysDictType struct { + // 字典主键 + DictID string `json:"dictId"` + // 字典名称 + DictName string `json:"dictName" binding:"required"` + // 字典类型 + DictType string `json:"dictType" binding:"required"` + // 状态(0停用 1正常) + Status string `json:"status"` + // 创建者 + CreateBy string `json:"createBy"` + // 创建时间 + CreateTime int64 `json:"createTime"` + // 更新者 + UpdateBy string `json:"updateBy"` + // 更新时间 + UpdateTime int64 `json:"updateTime"` + // 备注 + Remark string `json:"remark"` +} diff --git a/features/sys_dict_type/repo/repo_sys_dict_type.go b/features/sys_dict_type/repo/repo_sys_dict_type.go new file mode 100644 index 00000000..874dac11 --- /dev/null +++ b/features/sys_dict_type/repo/repo_sys_dict_type.go @@ -0,0 +1,330 @@ +package repo + +import ( + "fmt" + "strings" + "time" + + "ems.agt/features/sys_dict_type/model" + "ems.agt/lib/core/datasource" + "ems.agt/lib/core/utils/date" + "ems.agt/lib/core/utils/parse" + "ems.agt/lib/log" +) + +// 实例化数据层 RepoSysDictType 结构体 +var NewRepoSysDictType = &RepoSysDictType{ + selectSql: `select + dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type`, + + resultMap: map[string]string{ + "dict_id": "DictID", + "dict_name": "DictName", + "dict_type": "DictType", + "remark": "Remark", + "status": "Status", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + }, +} + +// RepoSysDictType 字典类型表 数据层处理 +type RepoSysDictType struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *RepoSysDictType) convertResultRows(rows []map[string]any) []model.SysDictType { + arr := make([]model.SysDictType, 0) + for _, row := range rows { + sysDictType := model.SysDictType{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + datasource.SetFieldValue(&sysDictType, keyMapper, value) + } + } + arr = append(arr, sysDictType) + } + return arr +} + +// SelectDictTypePage 根据条件分页查询字典类型 +func (r *RepoSysDictType) SelectDictTypePage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["dictName"]; ok && v != "" { + conditions = append(conditions, "dict_name like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["dictType"]; ok && v != "" { + conditions = append(conditions, "dict_type like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["status"]; ok && v != "" { + conditions = append(conditions, "status = ?") + params = append(params, v) + } + beginTime, ok := query["beginTime"] + if !ok { + beginTime, ok = query["params[beginTime]"] + } + if ok && beginTime != "" { + conditions = append(conditions, "create_time >= ?") + beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) + params = append(params, beginDate.UnixMilli()) + } + endTime, ok := query["endTime"] + if !ok { + endTime, ok = query["params[endTime]"] + } + if ok && endTime != "" { + conditions = append(conditions, "create_time <= ?") + endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) + params = append(params, endDate.UnixMilli()) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from sys_dict_type" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + log.Errorf("total err => %v", err) + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return map[string]any{ + "total": total, + "rows": []model.SysDictType{}, + } + } + + // 分页 + pageNum, pageSize := datasource.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err => %v", err) + } + + // 转换实体 + rows := r.convertResultRows(results) + return map[string]any{ + "total": total, + "rows": rows, + } +} + +// SelectDictTypeList 根据条件查询字典类型 +func (r *RepoSysDictType) SelectDictTypeList(sysDictType model.SysDictType) []model.SysDictType { + // 查询条件拼接 + var conditions []string + var params []any + if sysDictType.DictName != "" { + conditions = append(conditions, "dict_name like concat(?, '%')") + params = append(params, sysDictType.DictName) + } + if sysDictType.DictType != "" { + conditions = append(conditions, "dict_type like concat(?, '%')") + params = append(params, sysDictType.DictType) + } + if sysDictType.Status != "" { + conditions = append(conditions, "status = ?") + params = append(params, sysDictType.Status) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err => %v", err) + return []model.SysDictType{} + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectDictTypeByIDs 根据字典类型ID查询信息 +func (r *RepoSysDictType) SelectDictTypeByIDs(dictIDs []string) []model.SysDictType { + placeholder := datasource.KeyPlaceholderByQuery(len(dictIDs)) + querySql := r.selectSql + " where dict_id in (" + placeholder + ")" + parameters := datasource.ConvertIdsSlice(dictIDs) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + log.Errorf("query err => %v", err) + return []model.SysDictType{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// SelectDictTypeByType 根据字典类型查询信息 +func (r *RepoSysDictType) SelectDictTypeByType(dictType string) model.SysDictType { + querySql := r.selectSql + " where dict_type = ?" + results, err := datasource.RawDB("", querySql, []any{dictType}) + if err != nil { + log.Errorf("query err => %v", err) + return model.SysDictType{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.SysDictType{} +} + +// CheckUniqueDictType 校验字典是否唯一 +func (r *RepoSysDictType) CheckUniqueDictType(sysDictType model.SysDictType) string { + // 查询条件拼接 + var conditions []string + var params []any + if sysDictType.DictName != "" { + conditions = append(conditions, "dict_name = ?") + params = append(params, sysDictType.DictName) + } + if sysDictType.DictType != "" { + conditions = append(conditions, "dict_type = ?") + params = append(params, sysDictType.DictType) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } else { + return "" + } + + // 查询数据 + querySql := "select dict_id as 'str' from sys_dict_type " + whereSql + " limit 1" + results, err := datasource.RawDB("", querySql, params) + if err != nil { + log.Errorf("query err %v", err) + return "" + } + if len(results) > 0 { + return fmt.Sprintf("%v", results[0]["str"]) + } + return "" +} + +// InsertDictType 新增字典类型信息 +func (r *RepoSysDictType) InsertDictType(sysDictType model.SysDictType) string { + // 参数拼接 + params := make(map[string]any) + if sysDictType.DictName != "" { + params["dict_name"] = sysDictType.DictName + } + if sysDictType.DictType != "" { + params["dict_type"] = sysDictType.DictType + } + if sysDictType.Status != "" { + params["status"] = sysDictType.Status + } + if sysDictType.Remark != "" { + params["remark"] = sysDictType.Remark + } + if sysDictType.CreateBy != "" { + params["create_by"] = sysDictType.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := datasource.KeyPlaceholderValueByInsert(params) + sql := "insert into sys_dict_type (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + // 执行插入 + results, err := datasource.ExecDB("", sql, values) + if err != nil { + log.Errorf("insert row : %v", err.Error()) + return "" + } + insertId, err := results.LastInsertId() + if err != nil { + log.Errorf("insert row : %v", err.Error()) + return "" + } + return fmt.Sprint(insertId) +} + +// UpdateDictType 修改字典类型信息 +func (r *RepoSysDictType) UpdateDictType(sysDictType model.SysDictType) int64 { + // 参数拼接 + params := make(map[string]any) + if sysDictType.DictName != "" { + params["dict_name"] = sysDictType.DictName + } + if sysDictType.DictType != "" { + params["dict_type"] = sysDictType.DictType + } + if sysDictType.Status != "" { + params["status"] = sysDictType.Status + } + if sysDictType.Remark != "" { + params["remark"] = sysDictType.Remark + } + if sysDictType.UpdateBy != "" { + params["update_by"] = sysDictType.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := datasource.KeyValueByUpdate(params) + sql := "update sys_dict_type set " + strings.Join(keys, ",") + " where dict_id = ?" + + // 执行更新 + values = append(values, sysDictType.DictID) + results, err := datasource.ExecDB("", sql, values) + if err != nil { + log.Errorf("update row : %v", err.Error()) + return 0 + } + affected, err := results.RowsAffected() + if err != nil { + log.Errorf("update err => %v", err) + return 0 + } + return affected +} + +// DeleteDictTypeByIDs 批量删除字典类型信息 +func (r *RepoSysDictType) DeleteDictTypeByIDs(dictIDs []string) int64 { + placeholder := datasource.KeyPlaceholderByQuery(len(dictIDs)) + sql := "delete from sys_dict_type where dict_id in (" + placeholder + ")" + parameters := datasource.ConvertIdsSlice(dictIDs) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + log.Errorf("delete err => %v", err) + return 0 + } + affected, err := results.RowsAffected() + if err != nil { + log.Errorf("delete err => %v", err) + return 0 + } + return affected +} diff --git a/features/sys_dict_type/service/service_sys_dict_type.go b/features/sys_dict_type/service/service_sys_dict_type.go new file mode 100644 index 00000000..8cbb16b9 --- /dev/null +++ b/features/sys_dict_type/service/service_sys_dict_type.go @@ -0,0 +1,211 @@ +package service + +import ( + "encoding/json" + "errors" + "fmt" + + sysDictDataModel "ems.agt/features/sys_dict_data/model" + sysDictDataRepo "ems.agt/features/sys_dict_data/repo" + sysDictTypeModel "ems.agt/features/sys_dict_type/model" + "ems.agt/features/sys_dict_type/repo" + "ems.agt/lib/core/cache" + "ems.agt/lib/core/constants/cachekey" +) + +// 实例化服务层 ServiceSysDictType 结构体 +var NewServiceSysDictType = &ServiceSysDictType{ + sysDictTypeRepository: *repo.NewRepoSysDictType, + sysDictDataRepository: *sysDictDataRepo.NewRepoSysDictData, +} + +// ServiceSysDictType 字典类型 服务层处理 +type ServiceSysDictType struct { + // 字典类型服务 + sysDictTypeRepository repo.RepoSysDictType + // 字典数据服务 + sysDictDataRepository sysDictDataRepo.RepoSysDictData +} + +// SelectDictTypePage 根据条件分页查询字典类型 +func (r *ServiceSysDictType) SelectDictTypePage(query map[string]any) map[string]any { + return r.sysDictTypeRepository.SelectDictTypePage(query) +} + +// SelectDictTypeList 根据条件查询字典类型 +func (r *ServiceSysDictType) SelectDictTypeList(sysDictType sysDictTypeModel.SysDictType) []sysDictTypeModel.SysDictType { + return r.sysDictTypeRepository.SelectDictTypeList(sysDictType) +} + +// SelectDictTypeByID 根据字典类型ID查询信息 +func (r *ServiceSysDictType) SelectDictTypeByID(dictID string) sysDictTypeModel.SysDictType { + if dictID == "" { + return sysDictTypeModel.SysDictType{} + } + dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{dictID}) + if len(dictTypes) > 0 { + return dictTypes[0] + } + return sysDictTypeModel.SysDictType{} +} + +// SelectDictTypeByType 根据字典类型查询信息 +func (r *ServiceSysDictType) SelectDictTypeByType(dictType string) sysDictTypeModel.SysDictType { + return r.sysDictTypeRepository.SelectDictTypeByType(dictType) +} + +// CheckUniqueDictName 校验字典名称是否唯一 +func (r *ServiceSysDictType) CheckUniqueDictName(dictName, dictID string) bool { + uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(sysDictTypeModel.SysDictType{ + DictName: dictName, + }) + if uniqueId == dictID { + return true + } + return uniqueId == "" +} + +// CheckUniqueDictType 校验字典类型是否唯一 +func (r *ServiceSysDictType) CheckUniqueDictType(dictType, dictID string) bool { + uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(sysDictTypeModel.SysDictType{ + DictType: dictType, + }) + if uniqueId == dictID { + return true + } + return uniqueId == "" +} + +// InsertDictType 新增字典类型信息 +func (r *ServiceSysDictType) InsertDictType(sysDictType sysDictTypeModel.SysDictType) string { + insertId := r.sysDictTypeRepository.InsertDictType(sysDictType) + if insertId != "" { + r.LoadingDictCache(sysDictType.DictType) + } + return insertId +} + +// UpdateDictType 修改字典类型信息 +func (r *ServiceSysDictType) UpdateDictType(sysDictType sysDictTypeModel.SysDictType) int64 { + data := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{sysDictType.DictID}) + if len(data) == 0 { + return 0 + } + // 修改字典类型key时同步更新其字典数据的类型key + oldDictType := data[0].DictType + rows := r.sysDictTypeRepository.UpdateDictType(sysDictType) + if rows > 0 && oldDictType != "" && oldDictType != sysDictType.DictType { + r.sysDictDataRepository.UpdateDictDataType(oldDictType, sysDictType.DictType) + } + // 刷新缓存 + r.ClearDictCache(oldDictType) + r.LoadingDictCache(sysDictType.DictType) + return rows +} + +// DeleteDictTypeByIDs 批量删除字典类型信息 +func (r *ServiceSysDictType) DeleteDictTypeByIDs(dictIDs []string) (int64, error) { + // 检查是否存在 + dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs(dictIDs) + if len(dictTypes) <= 0 { + return 0, errors.New("没有权限访问字典类型数据!") + } + for _, v := range dictTypes { + // 字典类型下级含有数据 + useCount := r.sysDictDataRepository.CountDictDataByType(v.DictType) + if useCount > 0 { + msg := fmt.Sprintf("【%s】存在字典数据,不能删除", v.DictName) + return 0, errors.New(msg) + } + // 清除缓存 + r.ClearDictCache(v.DictType) + } + if len(dictTypes) == len(dictIDs) { + rows := r.sysDictTypeRepository.DeleteDictTypeByIDs(dictIDs) + return rows, nil + } + return 0, errors.New("删除字典数据信息失败!") +} + +// ResetDictCache 重置字典缓存数据 +func (r *ServiceSysDictType) ResetDictCache() { + r.ClearDictCache("*") + r.LoadingDictCache("") +} + +// getCacheKey 组装缓存key +func (r *ServiceSysDictType) getDictCache(dictType string) string { + return cachekey.SYS_DICT_KEY + dictType +} + +// LoadingDictCache 加载字典缓存数据 +func (r *ServiceSysDictType) LoadingDictCache(dictType string) { + sysDictData := sysDictDataModel.SysDictData{ + Status: "1", + } + + // 指定字典类型 + if dictType != "" { + sysDictData.DictType = dictType + // 删除缓存 + key := r.getDictCache(dictType) + cache.DeleteLocal(key) + } + + sysDictDataList := r.sysDictDataRepository.SelectDictDataList(sysDictData) + if len(sysDictDataList) == 0 { + return + } + + // 将字典数据按类型分组 + m := make(map[string][]sysDictDataModel.SysDictData, 0) + for _, v := range sysDictDataList { + key := v.DictType + if item, ok := m[key]; ok { + m[key] = append(item, v) + } else { + m[key] = []sysDictDataModel.SysDictData{v} + } + } + + // 放入缓存 + for k, v := range m { + key := r.getDictCache(k) + values, _ := json.Marshal(v) + cache.SetLocal(key, string(values)) + } +} + +// ClearDictCache 清空字典缓存数据 +func (r *ServiceSysDictType) ClearDictCache(dictType string) bool { + key := r.getDictCache(dictType) + keys := cache.GetLocalKeys(key) + for _, v := range keys { + cache.DeleteLocal(v) + } + return len(keys) > 0 +} + +// DictDataCache 获取字典数据缓存数据 +func (r *ServiceSysDictType) DictDataCache(dictType string) []sysDictDataModel.SysDictData { + data := []sysDictDataModel.SysDictData{} + key := r.getDictCache(dictType) + jsonAny, ok := cache.GetLocal(key) + if jsonAny != nil && ok { + err := json.Unmarshal([]byte(jsonAny.(string)), &data) + if err != nil { + data = []sysDictDataModel.SysDictData{} + } + } else { + data = r.sysDictDataRepository.SelectDictDataList(sysDictDataModel.SysDictData{ + Status: "1", + DictType: dictType, + }) + if len(data) > 0 { + cache.DeleteLocal(key) + values, _ := json.Marshal(data) + cache.SetLocal(key, string(values)) + } + } + return data +} diff --git a/lib/routes/routes.go b/lib/routes/routes.go index 3477e892..2bcdb3e1 100644 --- a/lib/routes/routes.go +++ b/lib/routes/routes.go @@ -19,6 +19,8 @@ import ( "ems.agt/features/security" "ems.agt/features/state" sysconfig "ems.agt/features/sys_config" + sysdictdata "ems.agt/features/sys_dict_data" + sysdicttype "ems.agt/features/sys_dict_type" sysmenu "ems.agt/features/sys_menu" sysrole "ems.agt/features/sys_role" sysuser "ems.agt/features/sys_user" @@ -293,6 +295,16 @@ func init() { Register(v.Method, v.Pattern, v.Handler, v.Middleware) } + // 字典类型信息接口添加到路由 + for _, v := range sysdicttype.Routers() { + Register(v.Method, v.Pattern, v.Handler, v.Middleware) + } + + // 字典类型对应的字典数据信息接口添加到路由 + for _, v := range sysdictdata.Routers() { + Register(v.Method, v.Pattern, v.Handler, v.Middleware) + } + // 菜单接口添加到路由 for _, v := range sysmenu.Routers() { Register(v.Method, v.Pattern, v.Handler, v.Middleware)