package service import ( "context" "cms-api/internal/dao" "cms-api/internal/model" "encoding/json" "regexp" "strconv" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" ) type sConfig struct{} func Config() *sConfig { return &sConfig{} } // GetByKey 根据配置键获取配置 func (s *sConfig) GetByKey(ctx context.Context, key string) (*model.SiteConfig, error) { return dao.Config.GetByKey(ctx, key) } // GetValue 获取配置值 func (s *sConfig) GetValue(ctx context.Context, key string, defaultValue ...interface{}) interface{} { config, err := s.GetByKey(ctx, key) if err != nil || config == nil { if len(defaultValue) > 0 { return defaultValue[0] } return nil } // 根据配置类型转换值 switch config.ConfigType { case "number": return gconv.Int(config.ConfigValue) case "boolean": return gconv.Bool(config.ConfigValue) case "json", "array": var result interface{} if err := json.Unmarshal([]byte(config.ConfigValue), &result); err == nil { return result } return config.ConfigValue default: return config.ConfigValue } } // GetString 获取字符串配置值 func (s *sConfig) GetString(ctx context.Context, key string, defaultValue ...string) string { value := s.GetValue(ctx, key) if value == nil { if len(defaultValue) > 0 { return defaultValue[0] } return "" } return gconv.String(value) } // GetInt 获取整数配置值 func (s *sConfig) GetInt(ctx context.Context, key string, defaultValue ...int) int { value := s.GetValue(ctx, key) if value == nil { if len(defaultValue) > 0 { return defaultValue[0] } return 0 } return gconv.Int(value) } // GetBool 获取布尔配置值 func (s *sConfig) GetBool(ctx context.Context, key string, defaultValue ...bool) bool { value := s.GetValue(ctx, key) if value == nil { if len(defaultValue) > 0 { return defaultValue[0] } return false } return gconv.Bool(value) } // List 获取配置列表 func (s *sConfig) List(ctx context.Context, req *model.ConfigListRequest) (*model.PageResponse, error) { var ( page = req.Page pageSize = req.PageSize ) if page <= 0 { page = 1 } if pageSize <= 0 { pageSize = 20 } // 设置分页参数 req.Page = page req.PageSize = pageSize // 获取列表 configs, total, err := dao.Config.List(ctx, req) if err != nil { return nil, err } return &model.PageResponse{ List: configs, Total: total, Page: page, PageSize: pageSize, TotalPages: (total + pageSize - 1) / pageSize, }, nil } // GetByGroup 根据分组获取配置 func (s *sConfig) GetByGroup(ctx context.Context, groupName string) ([]*model.SiteConfig, error) { return dao.Config.GetByGroup(ctx, groupName) } // GetGroups 获取所有配置分组 func (s *sConfig) GetGroups(ctx context.Context) ([]string, error) { return dao.Config.GetGroups(ctx) } // Create 创建配置 func (s *sConfig) Create(ctx context.Context, req *model.CreateConfigRequest) error { // 检查配置键是否存在 existConfig, err := dao.Config.GetByKey(ctx, req.ConfigKey) if err != nil { return err } if existConfig != nil { return gerror.New("配置键已存在") } // 验证配置值格式 if err := s.validateConfigValue(req.ConfigValue, req.ConfigType); err != nil { return err } // 创建配置 config := &model.SiteConfig{ ConfigKey: req.ConfigKey, ConfigValue: req.ConfigValue, ConfigType: req.ConfigType, GroupName: req.GroupName, Description: req.Description, SortOrder: req.SortOrder, IsSystem: req.IsSystem, CreatedAt: gtime.Now(), UpdatedAt: gtime.Now(), } _, err = dao.Config.Create(ctx, config) return err } // Update 更新配置 func (s *sConfig) Update(ctx context.Context, key string, req *model.UpdateConfigRequest) error { // 检查配置是否存在 config, err := s.GetByKey(ctx, key) if err != nil { return err } if config == nil { return gerror.New("配置不存在") } // 验证配置值格式 if err := s.validateConfigValue(req.ConfigValue, req.ConfigType); err != nil { return err } // 更新配置 updateData := g.Map{ "config_value": req.ConfigValue, "config_type": req.ConfigType, "group_name": req.GroupName, "description": req.Description, "sort_order": req.SortOrder, "is_system": req.IsSystem, "updated_at": gtime.Now(), } return dao.Config.UpdateByKey(ctx, key, updateData) } // UpdateValue 更新配置值 func (s *sConfig) UpdateValue(ctx context.Context, key string, value interface{}) error { // 检查配置是否存在 config, err := s.GetByKey(ctx, key) if err != nil { return err } if config == nil { return gerror.New("配置不存在") } // 转换值为字符串 var valueStr string switch config.ConfigType { case "json", "array": if jsonBytes, err := json.Marshal(value); err == nil { valueStr = string(jsonBytes) } else { return gerror.New("配置值格式错误") } default: valueStr = gconv.String(value) } // 验证配置值格式 if err := s.validateConfigValue(valueStr, config.ConfigType); err != nil { return err } // 更新配置值 return dao.Config.UpdateValue(ctx, key, valueStr) } // BatchUpdate 批量更新配置 func (s *sConfig) BatchUpdate(ctx context.Context, req *model.BatchUpdateConfigRequest) error { for key, value := range req.Configs { if err := s.UpdateValue(ctx, key, value); err != nil { g.Log().Error(ctx, "批量更新配置失败, 键:", key, "错误:", err) // 继续更新其他配置,不中断整个过程 } } return nil } // Delete 删除配置 func (s *sConfig) Delete(ctx context.Context, key string) error { // 检查配置是否存在 config, err := s.GetByKey(ctx, key) if err != nil { return err } if config == nil { return gerror.New("配置不存在") } // 检查是否为系统配置 if config.IsSystem == 1 { return gerror.New("系统配置不能删除") } return dao.Config.DeleteByKey(ctx, key) } // InitDefaultConfigs 初始化默认配置 func (s *sConfig) InitDefaultConfigs(ctx context.Context) error { defaultConfigs := []model.SiteConfig{ { ConfigKey: "site_name", ConfigValue: "企业官网CMS系统", ConfigType: "string", GroupName: "基础设置", Description: "网站名称", SortOrder: 1, IsSystem: 1, }, { ConfigKey: "site_title", ConfigValue: "企业官网CMS系统 - 专业的内容管理平台", ConfigType: "string", GroupName: "基础设置", Description: "网站标题", SortOrder: 2, IsSystem: 1, }, { ConfigKey: "site_description", ConfigValue: "专业的企业官网内容管理系统,提供完整的内容发布和管理功能", ConfigType: "string", GroupName: "基础设置", Description: "网站描述", SortOrder: 3, IsSystem: 1, }, { ConfigKey: "site_keywords", ConfigValue: "企业官网,CMS,内容管理,新闻发布", ConfigType: "string", GroupName: "基础设置", Description: "网站关键词", SortOrder: 4, IsSystem: 1, }, { ConfigKey: "contact_phone", ConfigValue: "400-123-4567", ConfigType: "string", GroupName: "联系方式", Description: "联系电话", SortOrder: 1, IsSystem: 0, }, { ConfigKey: "contact_email", ConfigValue: "contact@example.com", ConfigType: "string", GroupName: "联系方式", Description: "联系邮箱", SortOrder: 2, IsSystem: 0, }, { ConfigKey: "contact_address", ConfigValue: "北京市朝阳区xxx大厦xxx室", ConfigType: "string", GroupName: "联系方式", Description: "联系地址", SortOrder: 3, IsSystem: 0, }, { ConfigKey: "upload_max_size", ConfigValue: "10485760", ConfigType: "number", GroupName: "上传设置", Description: "最大上传文件大小(字节)", SortOrder: 1, IsSystem: 1, }, { ConfigKey: "allowed_file_types", ConfigValue: `["jpg","jpeg","png","gif","pdf","doc","docx","xls","xlsx"]`, ConfigType: "array", GroupName: "上传设置", Description: "允许上传的文件类型", SortOrder: 2, IsSystem: 1, }, } for _, config := range defaultConfigs { // 检查配置是否已存在 existConfig, err := dao.Config.GetByKey(ctx, config.ConfigKey) if err != nil { continue } if existConfig != nil { continue // 跳过已存在的配置 } // 创建配置 config.CreatedAt = gtime.Now() config.UpdatedAt = gtime.Now() dao.Config.Create(ctx, &config) } return nil } // validateConfigValue 验证配置值格式 func (s *sConfig) validateConfigValue(value, configType string) error { switch configType { case "number": if _, err := strconv.ParseFloat(value, 64); err != nil { return gerror.New("配置值必须是数字") } case "boolean": if value != "true" && value != "false" && value != "1" && value != "0" { return gerror.New("配置值必须是布尔值") } case "json", "array": var temp interface{} if err := json.Unmarshal([]byte(value), &temp); err != nil { return gerror.New("配置值必须是有效的JSON格式") } } return nil } // isNumeric 检查字符串是否为数字 func (s *sConfig) isNumeric(str string) bool { matched, _ := regexp.MatchString(`^-?\d+(\.\d+)?$`, str) return matched } // GetPublicConfigs 获取公开配置(前台可访问) func (s *sConfig) GetPublicConfigs(ctx context.Context) (map[string]interface{}, error) { // 定义公开配置键 publicKeys := []string{ "site_name", "site_title", "site_description", "site_keywords", "contact_phone", "contact_email", "contact_address", } result := make(map[string]interface{}) for _, key := range publicKeys { value := s.GetValue(ctx, key) if value != nil { result[key] = value } } return result, nil }