feat: 优化web
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
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 ¶mService{
|
||||
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), ¶ms); 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")
|
||||
}
|
||||
Reference in New Issue
Block a user