Files
nl_cms-api/internal/service/config.go
2025-07-29 12:45:07 +08:00

413 lines
9.7 KiB
Go

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
}