这份文档只描述后端为了支持前端国际化需要做的改造,不包含前端页面翻译细节。
目标是:
- 后端协议字段保持稳定、语言无关
- 前端掌管最终展示文案
- 后端提供足够稳定的机器可读语义,供前端做 i18n 映射
- 后端保留必要的 fallback 文本和排障信息,但不再主导界面语言
当前已经满足的部分:
type协议值已统一为英文income/expense- 数据库存储中的
type已统一为英文 - 角色和状态字段大多已经是英文稳定值
- API 文档已开始标注协议字段约定
当前仍然缺失的部分:
- 高频业务接口还需要继续补齐专用
errorKey - 高频错误响应还需要继续补齐
errorParams - API 文档还没有完整列出错误键和事件键
后端协议字段必须坚持返回英文稳定值,例如:
income/expenseowner/admin/memberpending/accepted/expiredpending/running/completed/failedinfo/warning/success/error
这些字段不能返回中文展示文案。
前端请求里的协议枚举也必须使用英文标准值。
例如:
- 正确:
expense - 错误:
支出
这类字段属于协议,不属于展示层。后端应严格校验,不再兼容中文别名。
后端不负责最终界面语言,只提供:
- 协议字段
- 稳定错误键
- 稳定事件键
- 业务参数
- fallback message
前端负责:
- 页面文案
- 枚举文案
- 错误文案
- 通知展示文案
建议统一错误响应为:
{
"status": 400,
"errorKey": "record.type_mismatch",
"errorParams": {
"expectedType": "expense"
},
"message": "Record type must match the selected category type",
"path": "/api/records",
"timestamp": "2026-03-16T22:00:00",
"traceId": "TRACE-..."
}对于 MkApiResponse<T> 风格接口,业务失败分支也应遵循同样原则,至少保持:
{
"code": 409,
"errorKey": "budget.duplicate_budget",
"errorParams": {
"year": 2026,
"month": 3
},
"message": "A budget already exists for the same month, type, and category scope",
"traceId": "TRACE-..."
}字段说明:
status:HTTP 状态码语义code:MkApiResponse业务状态码errorKey:稳定、语言无关的错误键errorParams:前端翻译时需要插值的参数message:fallback 文本path:请求路径timestamp:时间戳traceId:排障用
约束:
ApiErrorResponse和MkApiResponse的失败分支都必须带errorKeyerrorParams字段始终返回对象,空值时返回{},不返回nulltraceId必须保留
虽然前端最终不应依赖 message 作为主文案,但仍建议保留:
- 兼容旧前端和调试脚本
- Postman / curl / 日志里可直接阅读
- 当前端尚未配置对应
errorKey翻译时可做 fallback - 联调和排障时更高效
规则应明确为:
- 前端优先使用
errorKey + errorParams message仅作为 fallback
错误键命名统一遵循:
- 全小写
- 使用点分层级
- 命名空间固定
- 一旦发布,不随文案调整而变化
示例:
common.bad_requestauth.invalid_credentialsrecord.type_mismatchledger.invite.already_memberbudget.duplicate_budgetexport.job_not_ready
建议优先覆盖这些高频错误:
common.bad_requestcommon.unauthorizedcommon.forbiddencommon.not_foundcommon.conflictauth.invalid_credentialscategory.invalid_typerecord.invalid_typerecord.type_mismatchledger.invite.already_memberledger.invite.email_mismatchbudget.duplicate_budgetbudget.invalid_periodexport.job_not_ready
通知、预算提醒、导出完成提醒,不应只返回纯文案,而应返回稳定事件语义。
推荐结构:
{
"id": 1,
"type": "warning",
"eventKey": "budget.threshold_reached",
"payload": {
"budgetName": "Coffee",
"threshold": 40
},
"message": "Coffee budget is almost used up",
"read": false,
"createdAt": "2026-03-16T22:00:00"
}说明:
type:UI 风格层级,例如info/warning/success/erroreventKey:业务语义键payload:前端翻译插值参数message:fallback 文本
约束:
eventKey命名规则与errorKey一致payload字段始终返回对象,空值时返回{},不返回nullpayload字段名和类型需要保持稳定
前端处理顺序:
- 优先使用
eventKey + payload - 如果没有对应翻译,则使用
message - 不要直接把
eventKey当展示文案
budget.threshold_reachedbudget.threshold_clearedexport.job_readyexport.job_failedledger.invite_receivedledger.invite_accepted
FRONTEND_API.md 需要继续补充以下内容:
- 哪些字段是协议枚举
- 哪些字段只允许英文标准值
- 哪些错误会返回
errorKey - 哪些接口是
MkApiResponse,其失败分支同样带errorKey - 哪些通知会返回
type + eventKey + payload + message - 哪些字段只是 fallback message
建议按这个顺序做:
- 保持协议字段严格英文
- 给全局错误响应加
errorKey - 给高频错误补
errorParams - 给通知与预算提醒加
eventKey + payload - 更新
FRONTEND_API.md - 再由前端全面切换到 i18n 渲染
这一轮后端不需要做:
- 页面文案翻译
- 日期格式国际化
- 金额格式国际化
- 数字格式国际化
- 前端 locale 切换逻辑
这些都属于前端展示层职责。
后端国际化支持完成的标准应是:
- 协议枚举字段全部语言无关
- 请求协议字段也只接受标准英文值
- 错误响应具备
errorKey - 高频错误具备
errorParams - 通知/提醒具备
eventKey + payload - API 文档明确区分协议字段和展示字段
当前最优先的后端 i18n 支撑项,不是继续调整 type,而是:
- 错误响应
errorKey - 错误参数
errorParams - 通知事件
eventKey + payload
这三项补齐后,前端 i18n 才有稳定的后端语义基础。