feat: 优化web
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// SystemParam 系统参数实体
|
||||
// 用于存储系统运行所需的各种配置参数,支持多种数据类型和分组管理
|
||||
type SystemParam struct {
|
||||
// ID 主键,使用 UUID v4 保证全局唯一性,避免自增 ID 带来的信息泄露风险
|
||||
ID string `json:"id" gorm:"column:id;type:varchar(36);primaryKey;not null;comment:主键"`
|
||||
|
||||
// ParamKey 参数键名,全局唯一,用于标识和访问参数值
|
||||
// 命名规范:小写字母 + 下划线,如:site_name, max_upload_size
|
||||
ParamKey string `json:"param_key" gorm:"column:param_key;type:varchar(100);uniqueIndex;not null;comment:参数键"`
|
||||
|
||||
// ParamValue 参数值,存储实际配置内容
|
||||
// 根据 ParamType 不同,可能是字符串、数字、布尔值或 JSON 数组
|
||||
ParamValue string `json:"param_value" gorm:"column:param_value;type:varchar(1000);not null;comment:参数值"`
|
||||
|
||||
// ParamType 参数类型,决定参数的校验规则和展示方式
|
||||
// 可选值:text(文本), number(数字), boolean(布尔), select(下拉选择)
|
||||
ParamType string `json:"param_type" gorm:"column:param_type;type:varchar(20);not null;default:'text';comment:类型:text,number,boolean,select"`
|
||||
|
||||
// ParamGroup 参数分组,用于对参数进行逻辑分组管理
|
||||
// 常见分组:basic(基础), security(安全), business(业务), system(系统)
|
||||
ParamGroup string `json:"param_group" gorm:"column:param_group;type:varchar(50);not null;default:'default';comment:分组"`
|
||||
|
||||
// ParamDesc 参数描述,说明该参数的用途、取值范围、默认值等信息
|
||||
// 建议包含:参数说明、可选值说明、修改影响等
|
||||
ParamDesc string `json:"param_desc" gorm:"column:param_desc;type:varchar(500);comment:描述"`
|
||||
|
||||
// CreatorID 创建人 ID,记录创建该参数的用户标识
|
||||
// 用于审计追踪,定位参数创建者
|
||||
CreatorID string `json:"creator_id" gorm:"column:creator_id;type:varchar(36);not null;default:'';comment:创建人 ID"`
|
||||
|
||||
// CreateTime 创建时间,记录参数创建的时间点
|
||||
// 使用指针类型,可以区分"未设置"和"已设置"状态
|
||||
// 数据库层面使用 CURRENT_TIMESTAMP 自动填充
|
||||
CreateTime *time.Time `json:"create_time" gorm:"column:create_time;type:datetime;default:current_timestamp;comment:创建时间"`
|
||||
|
||||
// LastUpdaterID 最后更新人 ID,记录最后一次修改该参数的用户标识
|
||||
// 用于审计追踪,定位参数修改者
|
||||
LastUpdaterID string `json:"last_updater_id" gorm:"column:last_updater_id;type:varchar(36);not null;default:'';comment:最后更新人 ID"`
|
||||
|
||||
// UpdateTime 最后更新时间,记录参数最后一次修改的时间点
|
||||
// 使用指针类型,可以区分"未设置"和"已设置"状态
|
||||
// 数据库层面使用 ON UPDATE CURRENT_TIMESTAMP 自动更新
|
||||
UpdateTime *time.Time `json:"update_time" gorm:"column:update_time;type:datetime;default:current_timestamp;on update current_timestamp;comment:最后更新时间"`
|
||||
}
|
||||
|
||||
// TableName 指定表名为 system_param
|
||||
// 遵循数据库命名规范:小写字母 + 下划线,复数形式
|
||||
func (SystemParam) TableName() string {
|
||||
return "system_param"
|
||||
}
|
||||
|
||||
// ParamType 参数类型常量
|
||||
// 定义系统支持的参数类型,用于前端展示和后端校验
|
||||
type ParamType string
|
||||
|
||||
const (
|
||||
// ParamTypeText 文本类型,适用于字符串值
|
||||
ParamTypeText ParamType = "text"
|
||||
// ParamTypeNumber 数字类型,适用于整数值
|
||||
ParamTypeNumber ParamType = "number"
|
||||
// ParamTypeBoolean 布尔类型,适用于 true/false 值
|
||||
ParamTypeBoolean ParamType = "boolean"
|
||||
// ParamTypeSelect 下拉选择类型,适用于预定义选项值
|
||||
ParamTypeSelect ParamType = "select"
|
||||
)
|
||||
|
||||
// ParamGroup 参数分组常量
|
||||
// 定义系统参数的逻辑分组,便于分类管理和权限控制
|
||||
type ParamGroup string
|
||||
|
||||
const (
|
||||
// GroupBasic 基础配置分组,包含系统基本信息
|
||||
// 如:站点名称、Logo、联系方式等
|
||||
GroupBasic ParamGroup = "basic"
|
||||
|
||||
// GroupSecurity 安全配置分组,包含安全相关参数
|
||||
// 如:密码策略、登录限制、Token 有效期等
|
||||
GroupSecurity ParamGroup = "security"
|
||||
|
||||
// GroupBusiness 业务配置分组,包含业务逻辑相关参数
|
||||
// 如:订单配置、支付参数、业务开关等
|
||||
GroupBusiness ParamGroup = "business"
|
||||
|
||||
// GroupSystem 系统配置分组,包含系统运行参数
|
||||
// 如:缓存配置、日志级别、性能参数等
|
||||
GroupSystem ParamGroup = "system"
|
||||
|
||||
// GroupDefault 默认分组,未明确分组的参数归入此类
|
||||
GroupDefault ParamGroup = "default"
|
||||
)
|
||||
@@ -0,0 +1,177 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"giter.top/smart/internal/system/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ParamHandler 系统参数 HTTP 处理器
|
||||
type ParamHandler struct {
|
||||
service service.ParamService
|
||||
}
|
||||
|
||||
// NewParamHandler 创建参数处理器实例
|
||||
func NewParamHandler(svc service.ParamService) *ParamHandler {
|
||||
return &ParamHandler{service: svc}
|
||||
}
|
||||
|
||||
// CreateParam 创建系统参数
|
||||
// @Summary 创建系统参数
|
||||
// @Tags 系统参数
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body service.CreateParamRequest true "创建参数请求"
|
||||
// @Success 201 {object} entity.SystemParam
|
||||
// @Router /api/v1/system/params [post]
|
||||
func (h *ParamHandler) CreateParam(c *gin.Context) {
|
||||
var req service.CreateParamRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 从上下文获取用户 ID(实际项目中从 JWT token 解析)
|
||||
creatorID := "system"
|
||||
param, err := h.service.CreateParam(c.Request.Context(), &req, creatorID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusCreated, param)
|
||||
}
|
||||
|
||||
// UpdateParam 更新系统参数
|
||||
// @Summary 更新系统参数
|
||||
// @Tags 系统参数
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "参数 ID"
|
||||
// @Param request body service.UpdateParamRequest true "更新参数请求"
|
||||
// @Success 200 {object} entity.SystemParam
|
||||
// @Router /api/v1/system/params/{id} [put]
|
||||
func (h *ParamHandler) UpdateParam(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var req service.UpdateParamRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 从上下文获取用户 ID
|
||||
lastUpdaterID := "system"
|
||||
param, err := h.service.UpdateParam(c.Request.Context(), id, &req, lastUpdaterID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, param)
|
||||
}
|
||||
|
||||
// DeleteParams 批量删除系统参数
|
||||
// @Summary 批量删除系统参数
|
||||
// @Tags 系统参数
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body []string true "参数 ID 列表"
|
||||
// @Success 204
|
||||
// @Router /api/v1/system/params/batch [delete]
|
||||
func (h *ParamHandler) DeleteParams(c *gin.Context) {
|
||||
var ids []string
|
||||
if err := c.ShouldBindJSON(&ids); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.service.DeleteParams(c.Request.Context(), ids); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// GetParam 获取单个系统参数
|
||||
// @Summary 获取单个系统参数
|
||||
// @Tags 系统参数
|
||||
// @Produce json
|
||||
// @Param id path string true "参数 ID"
|
||||
// @Success 200 {object} entity.SystemParam
|
||||
// @Router /api/v1/system/params/{id} [get]
|
||||
func (h *ParamHandler) GetParam(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
||||
return
|
||||
}
|
||||
|
||||
param, err := h.service.GetParam(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, param)
|
||||
}
|
||||
|
||||
// GetParamByKey 根据键获取系统参数
|
||||
// @Summary 根据键获取系统参数
|
||||
// @Tags 系统参数
|
||||
// @Produce json
|
||||
// @Param key path string true "参数键"
|
||||
// @Success 200 {object} entity.SystemParam
|
||||
// @Router /api/v1/system/params/key/{key} [get]
|
||||
func (h *ParamHandler) GetParamByKey(c *gin.Context) {
|
||||
key := c.Param("key")
|
||||
param, err := h.service.GetParamByKey(c.Request.Context(), key)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, param)
|
||||
}
|
||||
|
||||
// ListParams 获取系统参数列表
|
||||
// @Summary 获取系统参数列表
|
||||
// @Tags 系统参数
|
||||
// @Produce json
|
||||
// @Param group query string false "分组"
|
||||
// @Param param_key query string false "参数键(模糊搜索)"
|
||||
// @Param page query int false "页码" default(1)
|
||||
// @Param page_size query int false "每页数量" default(10)
|
||||
// @Success 200 {object} service.ParamListResponse
|
||||
// @Router /api/v1/system/params [get]
|
||||
func (h *ParamHandler) ListParams(c *gin.Context) {
|
||||
group := c.Query("group")
|
||||
paramKey := c.Query("param_key")
|
||||
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
|
||||
response, err := h.service.ListParams(c.Request.Context(), group, paramKey, page, pageSize)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetAllParams 获取所有系统参数
|
||||
// @Summary 获取所有系统参数
|
||||
// @Tags 系统参数
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]entity.SystemParam
|
||||
// @Router /api/v1/system/params/all [get]
|
||||
func (h *ParamHandler) GetAllParams(c *gin.Context) {
|
||||
params, err := h.service.GetAllParams(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, params)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"giter.top/smart/internal/system/handler"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// SystemRoutes 注册 system 模块的 HTTP 路由。
|
||||
type SystemRoutes struct {
|
||||
paramHandler *handler.ParamHandler
|
||||
}
|
||||
// NewSystemRoutes 构造 system 模块的路由注册器,由 Wire 注入。
|
||||
func NewSystemRoutes( paramHandler *handler.ParamHandler) *SystemRoutes {
|
||||
return &SystemRoutes{
|
||||
paramHandler: paramHandler,
|
||||
}
|
||||
}
|
||||
// TODO 添加注册信息
|
||||
func (s *SystemRoutes) Register(engine *gin.Engine, apiGroup *gin.RouterGroup) {
|
||||
group := apiGroup.Group("/system")
|
||||
s.registerParamRoutes(group)
|
||||
}
|
||||
// 系统参数路由
|
||||
func (s *SystemRoutes) registerParamRoutes(group *gin.RouterGroup) {
|
||||
paramGroup := group.Group("/param")
|
||||
{
|
||||
paramGroup.POST("/create", s.paramHandler.CreateParam)
|
||||
paramGroup.PUT("/update", s.paramHandler.UpdateParam)
|
||||
paramGroup.DELETE("/delete-batch", s.paramHandler.DeleteParams)
|
||||
paramGroup.GET("/get", s.paramHandler.GetParam)
|
||||
paramGroup.GET("/list", s.paramHandler.ListParams)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"giter.top/smart/internal/system/entity"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ErrNotFound 记录未找到
|
||||
var ErrNotFound = errors.New("param not found")
|
||||
|
||||
// ParamRepository 系统参数数据访问层
|
||||
type ParamRepository interface {
|
||||
// Create 创建系统参数
|
||||
Create(ctx context.Context, param *entity.SystemParam) error
|
||||
// Update 更新系统参数
|
||||
Update(ctx context.Context, param *entity.SystemParam) error
|
||||
// Delete 删除系统参数
|
||||
Delete(ctx context.Context, id string) error
|
||||
// DeleteBatch 批量删除
|
||||
DeleteBatch(ctx context.Context, ids []string) error
|
||||
// GetByID 根据 ID 获取
|
||||
GetByID(ctx context.Context, id string) (*entity.SystemParam, error)
|
||||
// GetByKey 根据键获取
|
||||
GetByKey(ctx context.Context, key string) (*entity.SystemParam, error)
|
||||
// List 获取列表(支持分页和筛选)
|
||||
List(ctx context.Context, group string, paramKey string, page, pageSize int) ([]entity.SystemParam, int64, error)
|
||||
// GetAll 获取所有参数(用于缓存)
|
||||
GetAll(ctx context.Context) (map[string]entity.SystemParam, error)
|
||||
// ExistsByKey 检查键是否存在(排除指定 ID)
|
||||
ExistsByKey(ctx context.Context, key string, excludeID string) (bool, error)
|
||||
}
|
||||
|
||||
type paramRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewParamRepository 创建参数仓库实例
|
||||
func NewParamRepository(db *gorm.DB) ParamRepository {
|
||||
return ¶mRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *paramRepository) Create(ctx context.Context, param *entity.SystemParam) error {
|
||||
return r.db.WithContext(ctx).Create(param).Error
|
||||
}
|
||||
|
||||
func (r *paramRepository) Update(ctx context.Context, param *entity.SystemParam) error {
|
||||
return r.db.WithContext(ctx).Save(param).Error
|
||||
}
|
||||
|
||||
func (r *paramRepository) Delete(ctx context.Context, id string) error {
|
||||
return r.db.WithContext(ctx).Where("id = ?", id).Delete(&entity.SystemParam{}).Error
|
||||
}
|
||||
|
||||
func (r *paramRepository) DeleteBatch(ctx context.Context, ids []string) error {
|
||||
return r.db.WithContext(ctx).Where("id IN ?", ids).Delete(&entity.SystemParam{}).Error
|
||||
}
|
||||
|
||||
func (r *paramRepository) GetByID(ctx context.Context, id string) (*entity.SystemParam, error) {
|
||||
var param entity.SystemParam
|
||||
err := r.db.WithContext(ctx).Where("id = ?", id).First(¶m).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return ¶m, nil
|
||||
}
|
||||
|
||||
func (r *paramRepository) GetByKey(ctx context.Context, key string) (*entity.SystemParam, error) {
|
||||
var param entity.SystemParam
|
||||
err := r.db.WithContext(ctx).Where("param_key = ?", key).First(¶m).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return ¶m, nil
|
||||
}
|
||||
|
||||
func (r *paramRepository) List(ctx context.Context, group string, paramKey string, page, pageSize int) ([]entity.SystemParam, int64, error) {
|
||||
var params []entity.SystemParam
|
||||
var total int64
|
||||
query := r.db.WithContext(ctx).Model(&entity.SystemParam{})
|
||||
|
||||
// 应用筛选条件
|
||||
if group != "" {
|
||||
query = query.Where("param_group = ?", group)
|
||||
}
|
||||
if paramKey != "" {
|
||||
query = query.Where("param_key LIKE ?", "%"+paramKey+"%")
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
if pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
err := query.Order("id DESC").Offset(offset).Limit(pageSize).Find(¶ms).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return params, total, nil
|
||||
}
|
||||
|
||||
func (r *paramRepository) GetAll(ctx context.Context) (map[string]entity.SystemParam, error) {
|
||||
var params []entity.SystemParam
|
||||
err := r.db.WithContext(ctx).Find(¶ms).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make(map[string]entity.SystemParam, len(params))
|
||||
for _, param := range params {
|
||||
result[param.ParamKey] = param
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *paramRepository) ExistsByKey(ctx context.Context, key string, excludeID string) (bool, error) {
|
||||
query := r.db.WithContext(ctx).Where("param_key = ?", key)
|
||||
if excludeID != "" {
|
||||
query = query.Where("id != ?", excludeID)
|
||||
}
|
||||
var count int64
|
||||
err := query.Model(&entity.SystemParam{}).Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"giter.top/smart/internal/system/handler"
|
||||
"giter.top/smart/internal/system/repository"
|
||||
"giter.top/smart/internal/system/service"
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
// HandlerProviderSet 处理程序提供者集合
|
||||
var handlerProviderSet = wire.NewSet(
|
||||
handler.NewParamHandler,
|
||||
)
|
||||
|
||||
|
||||
// ServiceProviderSet 服务提供者集合
|
||||
var serviceProviderSet = wire.NewSet(
|
||||
service.NewParamService,
|
||||
)
|
||||
|
||||
|
||||
// RepositoryProviderSet 仓库提供者集合
|
||||
var repositoryProviderSet = wire.NewSet(
|
||||
repository.NewParamRepository,
|
||||
)
|
||||
|
||||
var ProviderSet = wire.NewSet(
|
||||
handlerProviderSet,
|
||||
serviceProviderSet,
|
||||
repositoryProviderSet,
|
||||
NewSystemRoutes,
|
||||
)
|
||||
Reference in New Issue
Block a user