Files
2026-04-23 18:58:13 +08:00

272 lines
7.5 KiB
Go

package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"giter.top/smart/internal/system/entity"
"giter.top/smart/internal/system/repository"
"giter.top/smart/pkg/utils/id"
"github.com/redis/go-redis/v9"
)
// ErrInvalidParam 参数无效
var ErrInvalidParam = errors.New("invalid param")
// ParamService 系统参数业务逻辑层
type ParamService interface {
// CreateParam 创建系统参数
CreateParam(ctx context.Context, req *CreateParamRequest, creatorID string) (*entity.SystemParam, error)
// UpdateParam 更新系统参数
UpdateParam(ctx context.Context, id string, req *UpdateParamRequest, lastUpdaterID string) (*entity.SystemParam, error)
// DeleteParam 删除系统参数
DeleteParam(ctx context.Context, id string) error
// DeleteParams 批量删除
DeleteParams(ctx context.Context, ids []string) error
// GetParam 获取单个参数
GetParam(ctx context.Context, id string) (*entity.SystemParam, error)
// GetParamByKey 根据键获取参数
GetParamByKey(ctx context.Context, key string) (*entity.SystemParam, error)
// ListParams 获取参数列表
ListParams(ctx context.Context, group string, paramKey string, page, pageSize int) (*ParamListResponse, error)
// GetAllParams 获取所有参数(用于缓存)
GetAllParams(ctx context.Context) (map[string]entity.SystemParam, error)
// GetParamValue 获取参数值(便捷方法)
GetParamValue(ctx context.Context, key string) (string, error)
// GetParamValueWithDefault 获取参数值,不存在则返回默认值
GetParamValueWithDefault(ctx context.Context, key string, defaultValue string) string
}
// CreateParamRequest 创建参数请求
type CreateParamRequest struct {
ParamKey string `json:"param_key" binding:"required,max=100"`
ParamValue string `json:"param_value" binding:"required"`
ParamType string `json:"param_type" binding:"required,oneof=text number boolean select"`
ParamGroup string `json:"param_group" binding:"required,max:50"`
ParamDesc string `json:"param_desc" max:"500"`
}
// UpdateParamRequest 更新参数请求
type UpdateParamRequest struct {
ParamValue string `json:"param_value"`
ParamType string `json:"param_type" binding:"omitempty,oneof=text number boolean select"`
ParamDesc string `json:"param_desc" max:"500"`
}
// ParamListResponse 参数列表响应
type ParamListResponse struct {
Items []entity.SystemParam `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalPages int `json:"total_pages"`
}
type paramService struct {
repo repository.ParamRepository
cache redis.UniversalClient
cacheKey string
}
// NewParamService 创建参数服务实例(与 cache.NewRedisClient 返回的 redis.UniversalClient 一致,便于 Wire 注入)
func NewParamService(repo repository.ParamRepository, cacheClient redis.UniversalClient) ParamService {
return &paramService{
repo: repo,
cache: cacheClient,
cacheKey: "system:params:*",
}
}
func (s *paramService) CreateParam(ctx context.Context, req *CreateParamRequest, creatorID string) (*entity.SystemParam, error) {
// 生成唯一 ID (UUID v7)
id := id.New()
// 检查键是否已存在
exists, err := s.repo.ExistsByKey(ctx, req.ParamKey, "")
if err != nil {
return nil, fmt.Errorf("检查参数键失败:%w", err)
}
if exists {
return nil, fmt.Errorf("参数键 %s 已存在", req.ParamKey)
}
param := &entity.SystemParam{
ID: id,
ParamKey: req.ParamKey,
ParamValue: req.ParamValue,
ParamType: req.ParamType,
ParamGroup: req.ParamGroup,
ParamDesc: req.ParamDesc,
CreatorID: creatorID,
LastUpdaterID: creatorID,
}
if err := s.repo.Create(ctx, param); err != nil {
return nil, fmt.Errorf("创建参数失败:%w", err)
}
// 刷新缓存
s.refreshCache(ctx)
return param, nil
}
func (s *paramService) UpdateParam(ctx context.Context, id string, req *UpdateParamRequest, lastUpdaterID string) (*entity.SystemParam, error) {
// 获取现有参数
param, err := s.repo.GetByID(ctx, id)
if err != nil {
if errors.Is(err, repository.ErrNotFound) {
return nil, fmt.Errorf("参数不存在")
}
return nil, fmt.Errorf("获取参数失败:%w", err)
}
// 更新字段
if req.ParamValue != "" {
param.ParamValue = req.ParamValue
}
if req.ParamType != "" {
param.ParamType = req.ParamType
}
if req.ParamDesc != "" {
param.ParamDesc = req.ParamDesc
}
param.LastUpdaterID = lastUpdaterID
if err := s.repo.Update(ctx, param); err != nil {
return nil, fmt.Errorf("更新参数失败:%w", err)
}
// 刷新缓存
s.refreshCache(ctx)
return param, nil
}
func (s *paramService) DeleteParam(ctx context.Context, id string) error {
if err := s.repo.Delete(ctx, id); err != nil {
return fmt.Errorf("删除参数失败:%w", err)
}
// 刷新缓存
s.refreshCache(ctx)
return nil
}
func (s *paramService) DeleteParams(ctx context.Context, ids []string) error {
if len(ids) == 0 {
return nil
}
if err := s.repo.DeleteBatch(ctx, ids); err != nil {
return fmt.Errorf("批量删除参数失败:%w", err)
}
// 刷新缓存
s.refreshCache(ctx)
return nil
}
func (s *paramService) GetParam(ctx context.Context, id string) (*entity.SystemParam, error) {
param, err := s.repo.GetByID(ctx, id)
if err != nil {
if errors.Is(err, repository.ErrNotFound) {
return nil, fmt.Errorf("参数不存在")
}
return nil, err
}
return param, nil
}
func (s *paramService) GetParamByKey(ctx context.Context, key string) (*entity.SystemParam, error) {
param, err := s.repo.GetByKey(ctx, key)
if err != nil {
if errors.Is(err, repository.ErrNotFound) {
return nil, fmt.Errorf("参数 %s 不存在", key)
}
return nil, err
}
return param, nil
}
func (s *paramService) ListParams(ctx context.Context, group string, paramKey string, page, pageSize int) (*ParamListResponse, error) {
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
items, total, err := s.repo.List(ctx, group, paramKey, page, pageSize)
if err != nil {
return nil, fmt.Errorf("获取参数列表失败:%w", err)
}
totalPages := int(total) / pageSize
if int(total)%pageSize != 0 {
totalPages++
}
return &ParamListResponse{
Items: items,
Total: total,
Page: page,
PageSize: pageSize,
TotalPages: totalPages,
}, nil
}
func (s *paramService) GetAllParams(ctx context.Context) (map[string]entity.SystemParam, error) {
// 先从缓存获取
if s.cache != nil {
cached := s.cache.Get(ctx, "system:params:all").Val()
if cached != "" {
var params map[string]entity.SystemParam
if err := json.Unmarshal([]byte(cached), &params); err == nil {
return params, nil
} else {
return nil, fmt.Errorf("解析缓存数据失败:%w", err)
}
}
}
// 缓存未命中,从数据库获取
params, err := s.repo.GetAll(ctx)
if err != nil {
return nil, err
}
// 写入缓存
if s.cache != nil {
data, _ := json.Marshal(params)
s.cache.Set(ctx, "system:params:all", string(data), 0) // 0 表示永不过期
}
return params, nil
}
func (s *paramService) GetParamValue(ctx context.Context, key string) (string, error) {
param, err := s.GetParamByKey(ctx, key)
if err != nil {
return "", err
}
return param.ParamValue, nil
}
func (s *paramService) GetParamValueWithDefault(ctx context.Context, key string, defaultValue string) string {
value, err := s.GetParamValue(ctx, key)
if err != nil {
return defaultValue
}
return value
}
// refreshCache 刷新缓存
func (s *paramService) refreshCache(ctx context.Context) {
if s.cache == nil {
return
}
// 删除缓存,让下次请求重新构建
s.cache.Del(ctx, "system:params:all")
}