Files
junhong_cmp_fiber/docs/7月迭代/基础设施/系统配置.md
2026-07-13 12:01:18 +09:00

217 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 基础设施系统配置tb_system_config
> 被依赖:需求 02H5流程配置、需求 09C端支付限制
---
## 一、设计目标
将散落在代码里的"写死配置"提取到数据库,平台管理员可通过后台页面修改,无需重新部署。
---
## 二、数据库
```sql
-- 迁移文件YYYYMMDD_create_tb_system_config.sql
CREATE TABLE tb_system_config (
id BIGSERIAL PRIMARY KEY,
config_key VARCHAR(100) NOT NULL, -- 唯一键格式module.group.name
config_value TEXT NOT NULL DEFAULT '', -- 值string/number/json字符串
value_type VARCHAR(20) NOT NULL DEFAULT 'string', -- string | int | bool | json
module VARCHAR(50) NOT NULL DEFAULT 'general', -- 所属模块(便于按模块查询)
description TEXT, -- 中文说明(前端展示用)
is_readonly BOOLEAN NOT NULL DEFAULT FALSE, -- 是否只读(代码内部,不允许后台改)
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uq_system_config_key UNIQUE (config_key)
);
COMMENT ON TABLE tb_system_config IS '系统全局配置表';
-- 初始化数据
INSERT INTO tb_system_config (config_key, config_value, value_type, module, description) VALUES
-- C端支付限制需求9
('c2b.payment.card_allowed_methods', '["alipay","wallet"]', 'json', 'c2b.payment', '卡资产C端允许的支付方式alipay/wechat/wallet'),
('c2b.payment.device_allowed_methods', '["wechat","wallet"]', 'json', 'c2b.payment', '设备C端允许的支付方式'),
-- H5流程顺序需求2per-asset 覆盖,此处是全局默认)
-- 注意per-asset 的 realname_policy 已在 iot_card.realname_policy 字段存储
-- 此处仅存"H5绑定手机后的默认流程"
('h5.flow.default_realname_policy', 'after_order', 'string', 'h5.flow', 'H5新用户默认实名策略none/before_order/after_order');
```
---
## 三、Model
```go
// internal/model/system_config.go
// SystemConfig 系统全局配置模型
type SystemConfig struct {
ID uint `gorm:"column:id;primaryKey" json:"id"`
ConfigKey string `gorm:"column:config_key;uniqueIndex;not null" json:"config_key"`
ConfigValue string `gorm:"column:config_value;type:text;not null;default:''" json:"config_value"`
ValueType string `gorm:"column:value_type;type:varchar(20);not null;default:'string'" json:"value_type"`
Module string `gorm:"column:module;type:varchar(50);not null;default:'general';index" json:"module"`
Description string `gorm:"column:description;type:text" json:"description"`
IsReadonly bool `gorm:"column:is_readonly;not null;default:false" json:"is_readonly"`
Creator uint `gorm:"column:creator;not null;default:0" json:"creator"`
Updater uint `gorm:"column:updater;not null;default:0" json:"updater"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
}
func (SystemConfig) TableName() string { return "tb_system_config" }
```
---
## 四、Store
```go
// internal/store/postgres/system_config_store.go
type SystemConfigStore struct {
db *gorm.DB
}
func (s *SystemConfigStore) GetByKey(ctx context.Context, key string) (*model.SystemConfig, error)
func (s *SystemConfigStore) GetByModule(ctx context.Context, module string) ([]model.SystemConfig, error)
func (s *SystemConfigStore) UpdateValue(ctx context.Context, key string, value string, updaterID uint) error
func (s *SystemConfigStore) BatchGet(ctx context.Context, keys []string) (map[string]*model.SystemConfig, error)
```
---
## 五、配置读取辅助包
业务代码不直接操作 Store通过辅助函数读取带 Redis 缓存5分钟TTL
```go
// pkg/sysconfig/config.go
// GetString 读取字符串配置,返回默认值
func GetString(ctx context.Context, key string, defaultVal string) string
// GetStringSlice 读取 JSON 数组配置
func GetStringSlice(ctx context.Context, key string) ([]string, error)
// GetBool 读取布尔配置
func GetBool(ctx context.Context, key string, defaultVal bool) bool
// InvalidateCache 更新配置后清缓存(在 UpdateValue 后调用)
func InvalidateCache(ctx context.Context, key string)
```
Redis Key`sys:config:{config_key}`TTL 5分钟。
业务代码用法:
```go
// 读取卡的允许支付方式
allowedMethods, _ := sysconfig.GetStringSlice(ctx, "c2b.payment.card_allowed_methods")
// 返回 ["alipay","wallet"]
```
---
## 六、API 设计
### 6.1 获取配置列表
```
GET /admin/system/config?module=c2b.payment
```
响应:
```json
{
"code": 0,
"data": {
"list": [
{
"config_key": "c2b.payment.card_allowed_methods",
"config_value": "[\"alipay\",\"wallet\"]",
"value_type": "json",
"description": "卡资产C端允许的支付方式",
"is_readonly": false,
"updated_at": "2026-07-11T10:00:00Z"
}
]
}
}
```
### 6.2 更新配置
```
PUT /admin/system/config/{config_key}
```
请求体:
```json
{
"config_value": "[\"alipay\",\"wallet\",\"wechat\"]"
}
```
权限:仅平台超管可操作。
### DTO
```go
// internal/model/dto/system_config_dto.go
// SystemConfigListRequest 配置列表查询请求
type SystemConfigListRequest struct {
Module string `query:"module" description:"按模块过滤(可选)"`
}
// SystemConfigItem 配置项响应
type SystemConfigItem struct {
ConfigKey string `json:"config_key"`
ConfigValue string `json:"config_value"`
ValueType string `json:"value_type" description:"值类型 (string/int/bool/json)"`
Module string `json:"module"`
Description string `json:"description"`
IsReadonly bool `json:"is_readonly"`
UpdatedAt time.Time `json:"updated_at"`
}
// UpdateSystemConfigRequest 更新配置请求
type UpdateSystemConfigRequest struct {
ConfigValue string `json:"config_value" validate:"required" description:"新配置值"`
}
```
---
## 七、前端对接
### 页面:系统设置 > 系统配置
**初期可以做一个通用的 Key-Value 管理页面,按 module 分组展示。**
调用流程:
1. 进入页面 → `GET /admin/system/config`(不传 module = 返回全部)
2. 按 module 分组展示,`is_readonly=true` 的配置只读
3. 修改某项 → `PUT /admin/system/config/{config_key}`body: `{config_value}`
4. 修改成功后提示"配置已更新约5分钟后生效"Redis 缓存 TTL
**C端支付限制配置展示建议**(针对 `c2b.payment` 模块):
不要让后台用户手动填 JSON前端渲染成 CheckboxGroup
```
卡资产允许支付方式:
☑ 支付宝 ☑ 钱包 ☐ 微信
设备允许支付方式:
☐ 支付宝 ☑ 钱包 ☑ 微信
```
前端把选中项序列化成 `["alipay","wallet"]` 提交。