diff --git a/docs/操作日志_财务结算周期时间展示修复_20260817.md b/docs/操作日志_财务结算周期时间展示修复_20260817.md new file mode 100644 index 0000000..64d7b4b --- /dev/null +++ b/docs/操作日志_财务结算周期时间展示修复_20260817.md @@ -0,0 +1,48 @@ +# 财务结算周期时间展示修复操作日志 + +操作时间:2026-08-17 + +操作类型:修改 + +影响模块:平台总后台、财务管理、财务结算 + +## 操作前状态 + +- 结算开始时间和结束时间虽已声明为日期时间字段,但通用展示逻辑只格式化名称以 `_at` 结尾的字段。 +- `period_start`、`period_end` 因字段名不匹配而直接显示 RFC3339 原文,并在列表中出现 `T` 和省略号。 + +## 具体操作 + +1. 通用字段展示增加基于 `field.type === 'datetime'` 的日期时间格式化。 +2. 结算周期统一显示为 `YYYY-MM-DD HH:mm:ss`,不修改后端时间值和时区处理规则。 +3. 增加静态展示契约,防止非 `_at` 日期时间字段再次回显原始字符串。 +4. 结算主体类型改为气站、配送点、工作人员三类中文枚举,并联动相应主体下拉。 +5. 切换主体类型时清空原主体,防止跨类型标识误提交。 + +## 行为变化 + +- 修改前:`2026-06-01T09:00:00...`。 +- 修改后:`2026-06-01 09:00:00`。 +- 仅改变展示格式,不改变结算周期、接口字段、保存值或结算流程。 +- 新建和编辑结算单不再要求手工输入主体类型编码。 + +## 代码变更 + +- `frontend/platform_admin/src/api/resource-display.ts`:日期时间改为按字段类型统一格式化。 +- `frontend/platform_admin/src/api/resources.ts`:补齐结算主体类型枚举和三类动态关系。 +- `frontend/platform_admin/scripts/check-resource-display-contracts.mjs`:增加日期时间类型格式化契约。 +- `docs/项目文档_平台资源中文展示统一_v1.0.md`:记录 v1.14 变更。 + +## 验证结果 + +- `pnpm resource-display-contracts:check`:通过。 +- `pnpm contract:check`:通过,48 个资源契约一致。 +- 修改文件定向 Biome lint:无错误;保留 `resource-display.ts` 既有的 `hasOwnProperty` 建议性警告。 +- `pnpm type:check`:通过。 +- `pnpm build`:通过,TypeScript 类型检查及 Vite 生产构建完成,共转换 2621 个模块。 +- 补齐结算主体联动后再次执行资源契约、48 资源契约、定向 lint、类型检查和生产构建:全部通过,仍仅有既有建议性警告。 + +## 风险评估 + +- 影响所有已声明为 `datetime` 的字段,输出格式与现有 `_at` 日期时间字段保持一致。 +- 不新增文档未规定的自然月、固定周期或时区转换规则。 diff --git a/docs/项目文档_平台资源中文展示统一_v1.0.md b/docs/项目文档_平台资源中文展示统一_v1.0.md index 1938b0f..39fc6cb 100644 --- a/docs/项目文档_平台资源中文展示统一_v1.0.md +++ b/docs/项目文档_平台资源中文展示统一_v1.0.md @@ -76,3 +76,5 @@ frontend/platform_admin/ - v1.11:退款审核新增“退款商品”,商城退款读取成交快照,气体配送退款通过原订单项读取产品名称,并汇总退款数量。 - v1.12:退款审核补齐空值业务文案、审核人名称、支付单号和钱包归属摘要,UUID 统一降级为复制信息。 - v1.13:修正固定 Mock 退款误把气站账号写为平台审核人的数据错误,并在重复初始化时幂等修复历史记录;退款审核人由接口稳定返回平台账号名称。 +- v1.14:日期时间统一按字段类型格式化,财务结算周期完整显示为 `YYYY-MM-DD HH:mm:ss`,不再回显带 `T` 的截断 RFC3339 文本。 +- v1.15:财务结算主体类型改为气站、配送点、工作人员中文枚举,并按类型联动对应主体资源,切换类型时清空旧主体。 diff --git a/frontend/platform_admin/scripts/check-resource-display-contracts.mjs b/frontend/platform_admin/scripts/check-resource-display-contracts.mjs index 382a4d3..06210ea 100644 --- a/frontend/platform_admin/scripts/check-resource-display-contracts.mjs +++ b/frontend/platform_admin/scripts/check-resource-display-contracts.mjs @@ -316,6 +316,23 @@ assertIncludes( 'hasResourceFieldLabel', '详情必须提供未知字段中文契约检查', ); +assertIncludes( + display, + "field.type === 'datetime'", + '日期时间必须按字段类型统一格式化,不能依赖 `_at` 字段名后缀', +); +for (const settlementContract of [ + "{ label: '气站', value: 'gas' }", + "{ label: '配送点', value: 'delivery' }", + "{ label: '工作人员', value: 'staff' }", + "resources: { gas: '/gas_basic', delivery: '/delivery_basic', staff: '/staff_account' }", +]) { + assertIncludes( + resources, + settlementContract, + `财务结算缺少主体类型联动契约:${settlementContract}`, + ); +} assertIncludes( detailPage, '!hasResourceFieldLabel(props.definition, actualKey)', diff --git a/frontend/platform_admin/src/api/resource-display.ts b/frontend/platform_admin/src/api/resource-display.ts index eae6e3a..e887942 100644 --- a/frontend/platform_admin/src/api/resource-display.ts +++ b/frontend/platform_admin/src/api/resource-display.ts @@ -513,6 +513,11 @@ export function displayResourceField( ? numericValue.toFixed(field.displayPrecision) : String(value); } + // 日期时间应以字段类型为准,避免 period_start 等非 `_at` 字段回显原始 RFC3339 文本。 + if (field.type === 'datetime') { + const date = dayjs(String(value)); + return date.isValid() ? date.format('YYYY-MM-DD HH:mm:ss') : String(value); + } if (field.type === 'identity' && typeof value === 'string') { return relationLabel(field, value, relationOptions, row); } diff --git a/frontend/platform_admin/src/api/resources.ts b/frontend/platform_admin/src/api/resources.ts index b80cd6b..392ccb9 100644 --- a/frontend/platform_admin/src/api/resources.ts +++ b/frontend/platform_admin/src/api/resources.ts @@ -850,12 +850,22 @@ export const resources: ResourceUiDefinition[] = [ }), f('amount'), f('paid_at'), ]), - define('fin_settlement', '财务结算', 'writable', [f('settlement_no', { required: true }), f('subject_type', { required: true }), f('subject_identity', { + define('fin_settlement', '财务结算', 'writable', [f('settlement_no', { required: true }), f('subject_type', { + required: true, + type: 'select', + options: [ + { label: '气站', value: 'gas' }, + { label: '配送点', value: 'delivery' }, + { label: '工作人员', value: 'staff' }, + ], + unknownValueLabel: '未知结算主体类型', + }), f('subject_identity', { required: true, type: 'identity', label: '结算主体', listRelationNameOnly: true, displayRelationLabel: true, showIdentityCopy: true, dynamicRelation: { parentKey: 'subject_type', parentLabel: '结算主体类型', - resources: { gas: '/gas_basic', delivery: '/delivery_basic' }, + resources: { gas: '/gas_basic', delivery: '/delivery_basic', staff: '/staff_account' }, + parentChangeMessage: '结算主体类型已变更,请重新选择结算主体', }, }), f('period_start', { required: true }), f('period_end', { required: true })]), define('fin_reconciliation', '财务对账', 'readonly', [