Some checks failed
CI / init (push) Has been cancelled
CI / Frontend node 18.16.0 (push) Has been cancelled
CI / Backend go (1.22) (push) Has been cancelled
CI / devops-test (1.22, 18.16.0) (push) Has been cancelled
CI / release-pr (push) Has been cancelled
CI / release-please (push) Has been cancelled
CI / devops-prod (1.22, 18.x) (push) Has been cancelled
CI / docker (push) Has been cancelled
6.6 KiB
6.6 KiB
系统参数(SysParams)使用规范
适用范围
- 需要读取或写入
sys_params表中的系统参数时,使用本文。 - 需要给某一个固定参数提供独立业务 API,但底层仍保存到
sys_params时,使用本文。
现有落点
- 表结构:
model/system/sys_params.go - Service:
service/system/sys_params.go - API:
api/v1/system/sys_params.go - Router:
router/system/sys_params.go
现有接口
- 实际完整路径 =
<router-prefix>/sysParams/...。 - 如果环境把
router-prefix配成/api,则完整路径就是/api/sysParams/...。 - 当前仓库
config.yaml中router-prefix默认值为空字符串;不要把/api写死为项目事实。 - 这组路由在
initialize/router.go中挂到PrivateGroup,默认需要鉴权。 GET /sysParams/getSysParam?key=xxx:按key读取单条参数。GET /sysParams/getSysParamsList:分页读取参数列表。POST /sysParams/createSysParams:创建参数。PUT /sysParams/updateSysParams:按ID更新参数。DELETE /sysParams/deleteSysParams:按ID删除参数。- 结论:这组接口适合“通用参数管理页”,不适合业务围绕某一个固定参数直接做长期读写。
强制规则
- 后端代码禁止通过 HTTP 反调自己的
/sysParams接口;统一在Service层直接调用service.ServiceGroupApp.SystemServiceGroup.SysParamsService。 API层禁止直接操作global.GVA_DB。Value是字符串存储;简单值可直接存字符串,结构化配置必须由业务Service负责json.Marshal/json.Unmarshal。- 不要把
sys_params的ID暴露给前端,作为某个固定配置的长期主键。 - 固定配置统一按
key识别;key必须稳定、唯一、可读,建议使用<module>.<scene>,例如device.runtimeConfig。 - 参数不存在时必须显式处理:返回业务错误、初始化默认值、或创建后再返回;禁止静默吞掉。
- 通用参数管理页面可以直接调用
/sysParams;具体业务页面优先调用该业务自己的独立 API。 - 参数属于某个业务模块时,落点放到该业务模块;只有平台级通用参数才继续放在
system模块。
代码内直接读取
- 读取动作统一放在
service/<module>。 - 调用入口:
param, err := service.ServiceGroupApp.SystemServiceGroup.SysParamsService.GetSysParam("device.runtimeConfig")
param.Value就是最终存储值。- 如果
Value存的是 JSON,必须先反序列化为业务结构体,再继续使用。
package device
import (
"encoding/json"
"github.com/flipped-aurora/gin-vue-admin/server/service"
)
type RuntimeConfig struct {
Enable bool `json:"enable"`
Mode string `json:"mode"`
}
func (s *DeviceService) GetRuntimeConfig() (RuntimeConfig, error) {
param, err := service.ServiceGroupApp.SystemServiceGroup.SysParamsService.GetSysParam("device.runtimeConfig")
if err != nil {
return RuntimeConfig{}, err
}
var cfg RuntimeConfig
if err = json.Unmarshal([]byte(param.Value), &cfg); err != nil {
return RuntimeConfig{}, err
}
return cfg, nil
}
代码内直接写入
- 当前
SysParamsService没有“按key直接写入”的现成能力。 - 现在只有
CreateSysParams、UpdateSysParams、GetSysParam。 - 这意味着:业务写入固定参数时,必须先按
key查询,再决定create还是update。 - 这段逻辑必须收口到业务
Service,不要放在API,也不要交给前端拼ID。
package device
import (
"encoding/json"
"errors"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/flipped-aurora/gin-vue-admin/server/service"
"gorm.io/gorm"
)
const runtimeConfigKey = "device.runtimeConfig"
func (s *DeviceService) SaveRuntimeConfig(cfg RuntimeConfig) error {
valueBytes, err := json.Marshal(cfg)
if err != nil {
return err
}
sysParamsSvc := service.ServiceGroupApp.SystemServiceGroup.SysParamsService
param, err := sysParamsSvc.GetSysParam(runtimeConfigKey)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return sysParamsSvc.CreateSysParams(&system.SysParams{
Name: "设备运行配置",
Key: runtimeConfigKey,
Value: string(valueBytes),
Desc: "device 模块运行配置",
})
}
return err
}
param.Value = string(valueBytes)
param.Name = "设备运行配置"
param.Desc = "device 模块运行配置"
return sysParamsSvc.UpdateSysParams(param)
}
什么时候必须写独立 API
- 前端只关心某一个固定参数,不应该先查列表、拿
ID、再更新时。 - 参数值是 JSON,需要强类型请求体和响应体时。
- 这个参数有明确业务语义,例如“设备运行配置”“首页配置”“第三方回调配置”时。
- 该参数需要单独做权限控制、默认值处理、字段校验、审计说明时。
独立 API 规范
- 独立 API 仍按
Router → API → Service → GORM → Database分层实现。 - 底层存储仍使用
sys_params;不要因为一个配置项就单独建表,除非它已经演变成独立业务实体。 - 对外接口暴露业务语义,不暴露
sys_params的ID、通用 CRUD 细节。 Service负责固定key、处理 JSON 转换、决定 create/update、处理不存在时的策略。- 参数属于业务模块时,文件落点统一为
model/<module>/request、model/<module>/response、service/<module>、api/v1/<module>、router/<module>。 - 新增业务路由统一注册到
initialize/router_biz.go。
推荐落地方式
- 对外提供两个独立接口即可:一个“获取配置”,一个“保存配置”。
- 接口名使用业务语义,不使用
sysParams命名。 - 示例接口:
GET <router-prefix>/deviceConfig/getRuntimeConfig、PUT <router-prefix>/deviceConfig/updateRuntimeConfig。 GET接口返回业务结构体。PUT接口接收业务结构体。- 底层统一在
service/device中转成sys_params.value的 JSON 字符串。
禁止事项
- 禁止在业务代码里直接写 SQL 操作
sys_params,绕开现有Service分层。 - 禁止在业务
API中直接处理sys_params的ID。 - 禁止让前端把一个固定配置当成“参数管理列表中的某一行”去长期维护。
- 禁止把结构化 JSON 配置直接裸透传为字符串给业务页面,除非该页面本身就是通用参数管理页。