字典与参数配置
# 字典与参数配置
# 目的
分别维护平台公共标准/模板、平台自用参数及租户独立配置。租户显式复制指定版本后得到自己的副本;平台更新、停用或删除模板都不覆盖既有副本,也没有「租户找不到就读平台值」的隐式回退。
| 数据 | 管理者与用途 |
|---|---|
| 公共标准字典 | 平台统一发布,租户可显式读取启用选项;内置标准只读 |
| 字典模板 | 平台维护初始内容,租户选择明确版本复制后独立维护 |
| 平台业务参数 | 独立平台表,供平台业务使用,支持敏感值隐藏;租户不能读取 |
| 租户默认参数模板 | 仅公开默认值,供租户显式版本复制,不承载秘密 |
| 租户字典/参数 | 当前租户独立CRUD,不影响其他租户或平台目录 |
业务状态机枚举仍由代码维护,不从可编辑字典决定登录、订单或任务的合法状态。复制内置选项也不会修改核心状态机。
# 前置条件
显式迁移到当前 schema v29,启动匹配的API和前端;目录扩展由v28追加,迁移不自动扩大旧套餐。租户套餐需开通 infra.configuration,角色按需分配 infra:dict:read/create/update/delete 和 infra:config:read/create/update/delete。保留的 tenant_admin 仍受套餐上限限制。
平台使用独立的 platform:infra:dict:*、platform:infra:config:*、platform:infra:config-template:* 权限。读取和写入分别校验;只读角色没有写按钮。平台「平台基础设施」组提供公共字典与模板、平台业务参数、租户默认参数模板入口;租户仍在「基础设施」组管理自己的副本。
在外层仓库执行。连接参数由本机环境提供,不写入命令或提交到仓库:
bash scripts/fago.sh migrate
bash scripts/fago.sh api
# 在前端终端运行;与已配置的API代理配合。
bash scripts/web.sh dev
成功时重新读取本人导航可见已授权页面。套餐降级、租户停用或会话/权限撤销后,旧页面不能继续读写;数据保留,重新开通后可继续管理。
# 步骤与规则
# 1. 平台发布字典
进入「公共字典与模板」,新建编码、名称、类别及状态。kind 为 standard 或 template,编码和类别创建后固定;内置 common.status 可查看,在线接口不能改内容、类别、启停或删除。
下面创建租户复制模板,示例为开发环境明文。生产走统一JWE,解密后的合同相同:
POST /api/platform/v1/infra/dictionaries
Origin: http://127.0.0.1:5174
X-App-Request: platform
Authorization: Bearer <平台操作者提供的access>
Content-Type: application/json
{"code":"sales.priority","name":"销售优先级模板","kind":"template","status":"enabled"}
成功响应给出父版本和条目数:
{"code":0,"data":{"id":"10","code":"sales.priority","name":"销售优先级模板","kind":"template","status":"enabled","version":1,"builtin":false,"itemCount":0},"message":"ok","requestId":"req_dictionary"}
点击「条目」新增、编辑或删除项。平台条目没有独立可写版本,每次修改提交父字典版本并推进整个模板版本。下面成功后父版本为2,再次发送版本1会冲突:
POST /api/platform/v1/infra/dictionaries/sales.priority/items
Origin: http://127.0.0.1:5174
X-App-Request: platform
Authorization: Bearer <平台操作者提供的access>
Content-Type: application/json
{"code":"high","label":"高","status":"enabled","sortOrder":10,"version":1}
成功返回 {"code":0,"data":null,"message":"ok","requestId":"req_item"}。重新读取 GET /api/platform/v1/infra/dictionaries/sales.priority 取得新父版本再写下一项。读取失败不解锁写入,不能沿用上次列表或详情的保存资格。
平台目录编码在删除后仍保留,不能删除再创建同编码以改变既有来源。模板项变更与父版本、操作审计同事务;MySQL复制使用父子当前读,不能形成「新父版本、旧条目」的混合副本。
# 2. 租户复制与独立维护
租户新建字典时可选择已启用的全局模板,提交刚读取的编码和版本。不填写模板则手工创建空字典;旧 templateId 不是合同字段。
POST /api/admin/v1/infra/dictionaries
Origin: http://127.0.0.1:5174
X-App-Request: admin
Authorization: Bearer <租户操作者提供的access>
Content-Type: application/json
{"code":"sales.priority","name":"本租户销售优先级","templateCode":"sales.priority","templateVersion":2}
成功返回独立租户ID和复制来源。后续平台发布版本3不会覆盖该字典,旧版本复制请求返回409001,不能自动升级成另一个版本:
{"code":0,"data":{"id":"20","code":"sales.priority","name":"本租户销售优先级","source":"tenant","templateCode":"sales.priority","version":1,"templateVersion":2},"message":"ok","requestId":"req_copy"}
租户「条目」窗口按条目自己的 version 管理;编码创建后不可改,不能跨父字典移动。GET /api/admin/v1/infra/dictionaries/{id}/options 只返回启用项,管理列表可以查看禁用项。仍有有效条目时删除字典返回409003,先删条目再删字典;租户软删除后可重新创建同编码,与平台目录永久保留编码的规则不同。
需要显式读取平台公共标准时,用独立路径,不能把它当成租户字典缺省回退:
GET /api/admin/v1/infra/public-dictionaries/common.status/options
Origin: http://127.0.0.1:5174
X-App-Request: admin
Authorization: Bearer <租户操作者提供的access>
该接口要求当前租户字典读取权限和套餐能力,只接受已启用 standard,仅返回启用选项。响应项为 {"code":"enabled","label":"启用","status":"enabled","sortOrder":10},不伪造租户条目ID。
# 3. 平台私有参数与敏感值
进入「平台业务参数」新建参数,创建时确定敏感性。平台和租户可以有同编码参数,互不继承或覆盖。所有管理响应对敏感值都返回 value: null,不返回原文、长度或尾部;hasValue 只表示已设置,空字符串也算已设置。
POST /api/platform/v1/infra/configs
Origin: http://127.0.0.1:5174
X-App-Request: platform
Authorization: Bearer <平台操作者提供的access>
Content-Type: application/json
{"code":"business.channel_key","name":"平台业务渠道材料","sensitive":true,"value":"<操作者提供的合成或实际业务值>"}
创建/列表/详情/更新的敏感值合同一致:
{"code":0,"data":{"id":"30","code":"business.channel_key","name":"平台业务渠道材料","value":null,"sensitive":true,"hasValue":true,"version":1},"message":"ok","requestId":"req_parameter"}
编辑前必须成功读取当前详情;网络失败、关闭或旧详情晚到不能解锁保存。默认只改名称,省略或传 null 保留敏感原值。只有勾选替换才发送新值;发送后清理输入,失败不自动重试秘密,也不会把清空后的输入当成主动清空。敏感性创建后不可更改。
PUT /api/platform/v1/infra/configs/30
Origin: http://127.0.0.1:5174
X-App-Request: platform
Authorization: Bearer <平台操作者提供的access>
Content-Type: application/json
{"code":"business.channel_key","name":"只修改平台参数名称","sensitive":true,"version":1}
租户参数走 /api/admin/v1/infra/configs/{id}。租户更新只提交名称、原来的 sensitive、当前版本及需要替换的值,不能重交编码或来源;普通公开值更新必须显式提供 value,空字符串是合法主动清空。平台编码虽可在更新中重交,也必须与原值一致。
# 4. 公开默认参数模板
进入「租户默认参数模板」维护公开默认值。模板没有敏感标记,value 必须显式提供,空字符串合法,缺失或 null 拒绝。不得把秘密放入模板跨租户传播。
POST /api/platform/v1/infra/config-templates
Origin: http://127.0.0.1:5174
X-App-Request: platform
Authorization: Bearer <平台操作者提供的access>
Content-Type: application/json
{"code":"business.page_size","name":"分页默认值","value":"50","status":"enabled"}
成功返回 {"code":0,"data":{"id":"40","code":"business.page_size","name":"分页默认值","value":"50","status":"enabled","version":1},"message":"ok","requestId":"req_default"}。租户读取已启用的 GET /api/admin/v1/infra/config-templates 后显式复制,不同时传值或敏感标记:
POST /api/admin/v1/infra/configs
Origin: http://127.0.0.1:5174
X-App-Request: admin
Authorization: Bearer <租户操作者提供的access>
Content-Type: application/json
{"code":"business.page_size","name":"本租户分页大小","templateCode":"business.page_size","templateVersion":1}
此后租户自行改成100也不会回写平台;平台改成20、停用或删除模板均不影响该副本。已停用/删除模板不能继续新复制。
# 参数与入口
编码为小写字母开头的1–64位字母、数字、点、下划线或短横线;名称最多100字符,值最多4096个UTF-8字节。条目排序为0–1000000整数。列表使用 pageNo/pageSize/keyword,每页最多100,不接受任意租户选择器。
每租户最多1000个有效字典、每字典1000条有效项、1000个有效参数;平台最多100个有效字典/标准、每份1000项、1000个有效业务参数及100个有效默认模板。超过上限拒绝,不静默截断或自动覆盖。
| 范围 | 完整根路径与主要接口 |
|---|---|
| 平台字典 | /api/platform/v1/infra/dictionaries:GET列表、POST创建;/{code} GET/PUT/DELETE;/{code}/items POST;/{code}/items/{itemCode} PUT/DELETE |
| 平台参数 | /api/platform/v1/infra/configs:GET/POST;/{id} GET/PUT/DELETE |
| 公开默认模板 | /api/platform/v1/infra/config-templates:GET/POST;/{code} GET/PUT/DELETE |
| 租户模板读取 | /api/admin/v1/infra/dictionary-templates、/api/admin/v1/infra/config-templates GET |
| 租户字典 | /api/admin/v1/infra/dictionaries GET/POST;/{id} PUT/DELETE;/{id}/items GET/POST;/{id}/items/{itemId} PUT/DELETE |
| 租户参数 | /api/admin/v1/infra/configs GET/POST;/{id} GET/PUT/DELETE |
创建版本为0或省略;更新必须当前正版本。删除在查询参数带 version 并发送空JSON对象,例如 DELETE /api/platform/v1/infra/configs/30?version=2,正文 {};来源头与其他写入一致。条目删除使用父字典版本,成功后重新读取父版本。
服务模块原值读取分别用 ResolveConfig / ResolvePlatformConfig 窄入口,另需本域 infra:config:use / platform:infra:config:use,没有原值HTTP路由。不自动跨域查找。
# 失败处理
版本冲突返回HTTP409,必须刷新核对后重新编辑,不自动换版本覆盖:
HTTP/1.1 409 Conflict
Content-Type: application/json
{"code":409001,"data":null,"message":"记录已变更,请重试","requestId":"req_conflict"}
编码重复为409002;内置保护、容量或删除状态不允许为409003;不存在、跨租户或已删除统一404001。未知JSON字段为400001,参数不合法为400002,权限不足为403001。数据库或审计失败为503001,整个业务与审计回滚,不保留半份模板或副本。敏感替换结果不确定时先核对资源版本,不盲目自动重发秘密。
# 边界
参数原值保存在业务数据库,敏感隐藏不是静态加密,备份也需按敏感数据保护。审计只记录编码、身份、版本、状态和来源元数据,公开值也不入审计。HTTP共用认证、当前主库权限、Origin、生产JWE与脱敏出口。
auth.、security.、database.、redis.、encryption. 前缀保留,不作为业务参数或默认模板编辑。数据库连接、加密材料、登录和安全策略继续用部署配置或专用页面。平台目录控制锁不反向锁租户;租户复制在当前版本检查与完整副本、操作审计的同一事务内提交。
没有隐式继承、缺省回退、自动同步租户副本或在线修改核心枚举;达梦v29与生产容量/恢复尚未认证。
# 关联
部署参数见 配置与环境,安全设置见 租户与安全策略,平台任务见 定时任务与恢复,来源与导航见 菜单与路由。实际双库/并发/升级/协议验证及剩余边界见 M5增量实施记录。