6.7 KiB
配置驱动应用的后台管理方案建议
本文用于整理当前这类“配置驱动型地图游戏应用”的后台管理建议,面向:
- PostgreSQL 数据库
- Go 中间层
- 后台管理系统
- 客户端静态配置发布
目标是解决一个核心问题:
配置文件会越来越大,如何在后台可维护、可复用、可审核、可发布、可回滚。
1. 总体原则
最稳的方案不是“数据库直接存一大份 game.json 给客户端读”,而是:
数据库管理编辑态,发布时编译成运行态静态配置文件。
也就是两套形态:
编辑态
- 存在 PostgreSQL
- 适合后台表单编辑
- 支持版本管理
- 支持对象复用
- 支持审核、比对、回滚
运行态
- 由 Go 中间层装配生成
- 输出为静态 JSON
- 上传到 OSS/CDN
- 客户端只读取发布后的静态配置
这条路线最适合当前项目。
2. 不建议的做法
不建议把后台做成:
- 一张表里存一个超大的
jsonb - 后台直接编辑整份
game.json - 客户端通过 API 动态拼装所有配置
这样后面会遇到这些问题:
- 配置复用困难
- diff 难看
- 回滚困难
- 审核困难
- 局部编辑体验差
- 客户端运行态不稳定
3. 推荐的核心对象
建议后台和数据库先固定这 5 个核心对象:
Map
地图底座。
负责:
- 瓦片资源
- meta 信息
- 磁偏角
- 初始视角
Playfield
玩法空间对象定义。
负责:
- KML 来源
- 控制点覆盖信息
- 区域对象
- 危险区
- 采集物
- 起终点信息
说明:
Playfield是上位概念course只是其中一种特化形式
GameMode
玩法模板。
负责:
- 顺序赛
- 积分赛
- 后续幽灵赛、迷雾赛、金币赛等
也就是:
game.modesessionpunchscoringguidancevisibilityfinishtelemetryfeedback
ResourcePack
资源包。
负责:
- 音效 profile
- 文创内容
- 图标
- HUD 主题
- 动效 profile
Event
最终活动实例。
负责引用:
- 一个
Map - 一个
Playfield - 一个
GameMode - 一个
ResourcePack
并允许少量活动级覆盖。
一句话:
Event = Map + Playfield + GameMode + ResourcePack + EventOverrides
4. 数据库建模建议
建议每个核心对象都分成:
- 主表
- version 表
4.1 主表
主表存稳定元信息:
idslugnamestatuscurrent_version_idcreated_atupdated_at
4.2 version 表
version 表存每个版本的具体内容:
idparent_idversion_noschema_versioncontent_jsonbcreated_bycreated_atchange_note
4.3 推荐表
建议至少有:
mapsmap_versionsplayfieldsplayfield_versionsgame_modesgame_mode_versionsresource_packsresource_pack_versionseventsevent_versions
5. 为什么要做版本表
版本表的价值非常大:
- 支持草稿
- 支持发布版
- 支持 diff
- 支持回滚
- 支持审计
- 支持多人协作
如果没有版本表,后面后台管理一定会越来越难维护。
6. JSONB 的使用建议
推荐策略是:
- 稳定字段结构化
- 变化快的配置内容放
jsonb
例如主表中:
slugnamestatus
放结构化列。
而玩法具体配置、资源清单、覆盖字段,放在 content_jsonb。
这样兼顾:
- 查询效率
- 结构灵活性
- 配置扩展性
7. 后台编辑方式建议
后台不要直接给运营一个大 JSON 编辑框作为主要方式。
推荐做法:
- 地图编辑页
- Playfield 编辑页
- 玩法规则页
- 资源包页
- 活动编排页
按模块表单化编辑。
最后由 Go 中间层负责装配成最终配置 JSON。
也就是:
后台是“编辑结构化对象”,不是“手工拼最终运行文件”。
8. 发布机制建议
发布时建议按下面流程:
- 后台选定某个
Event Version - Go 中间层读取它引用的:
Map VersionPlayfield VersionGameMode VersionResourcePack Version
- 做装配
- 做校验
- 生成最终运行态 JSON
- 上传 OSS/CDN
- 记录一条 release
客户端只读:
- 已发布的静态配置 URL
不要让客户端直接查数据库 API 动态拼。
9. 推荐增加 Release 层
建议增加:
event_releases
字段例如:
idevent_idevent_version_idrelease_nomanifest_urlpublished_bypublished_atstatus
它的作用:
- 一键回滚
- 客户端锁定某次 release
- 管理历史发布记录
- 灰度验证
10. Go 中间层建议职责
Go 中间层不要只做 CRUD。
建议它至少承担这 4 类职责:
10.1 校验
- schema 校验
- 引用存在校验
- 字段完整性校验
- 规则约束校验
10.2 装配
把:
MapPlayfieldGameModeResourcePackEvent Overrides
装配成最终配置结构。
10.3 发布
- 生成最终静态 JSON
- 上传到 OSS/CDN
- 记录 release
10.4 对比与预览
- 给后台显示 diff
- 给发布前做预览
一句话:
Go 中间层本质上是配置编译器。
11. 校验建议
建议尽量做强校验。
至少包括:
- schemaVersion 合法
- 引用对象存在
- KML 路径存在
- 地图 meta 存在
- 玩法字段完整
以及玩法特定约束,例如:
- 顺序赛必须有 start / finish
- 积分赛 control set 需要 score 或可派生 score
punch.radiusMeters > 0skip.radiusMeters > punch.radiusMeters
这样能把很多错误挡在发布前。
12. 和当前静态目录的关系
当前你已经有类似目录:
map/kml/event/
这很好,可以继续保留。
建议把它理解成:
- 数据库 = 编辑态
- 这些目录 = 发布产物态
也就是后台发布后,Go 中间层继续生成:
event/classic-sequential.jsonevent/score-o.jsonmap/...kml/...
客户端保持现有读取方式不变。
13. 推荐的后续实施顺序
建议按这个顺序落地:
第一步
先建 5 个核心对象模型:
MapPlayfieldGameModeResourcePackEvent
第二步
为每个对象补版本表。
第三步
Go 中间层实现“装配成最终 JSON”。
第四步
实现“发布到 OSS/CDN”。
第五步
后台逐步从 JSON 编辑过渡到模块化表单编辑。
14. 一句话总结
这类配置驱动应用最稳的后台方案是:
PostgreSQL 管结构化、可版本化的编辑态对象;Go 中间层负责校验、装配和发布;客户端只消费发布后的静态 JSON。
这样才能做到:
- 可复用
- 可扩展
- 可审核
- 可回滚
- 可稳定运行