临时备份一次

This commit is contained in:
2026-07-13 12:01:18 +09:00
parent 5cdcdad534
commit 2e130b98f5
17 changed files with 3938 additions and 0 deletions

View File

@@ -0,0 +1,216 @@
# 基础设施系统配置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"]` 提交。