diff --git a/backend/api/internal/logic/platform/platform/account.go b/backend/api/internal/logic/platform/platform/account.go index 95808dc..f05af7b 100644 --- a/backend/api/internal/logic/platform/platform/account.go +++ b/backend/api/internal/logic/platform/platform/account.go @@ -49,6 +49,7 @@ func platformAccountView(account models.PlatformAccount) map[string]any { "identity": account.Identity, "username": account.Username, "display_name": account.DisplayName, "avatar": account.Avatar, "phone": account.Phone, "platform_role_code": account.PlatformRoleCode, "status": account.Status, + "created_at": account.CreatedAt, "updated_at": account.UpdatedAt, } } diff --git a/backend/api/internal/logic/platform/platform/account_test.go b/backend/api/internal/logic/platform/platform/account_test.go new file mode 100644 index 0000000..2e61471 --- /dev/null +++ b/backend/api/internal/logic/platform/platform/account_test.go @@ -0,0 +1,33 @@ +// Package platform 测试平台账户管理的对外展示契约。 +package platform + +import ( + "testing" + "time" + + "git.apinb.com/heqiapp/platforms/backend/api/internal/models" +) + +// TestPlatformAccountViewIncludesAuditTimes 验证账户详情返回真实审计时间且保留空联系电话。 +func TestPlatformAccountViewIncludesAuditTimes(t *testing.T) { + createdAt := time.Date(2026, 8, 17, 9, 30, 0, 0, time.UTC) + updatedAt := createdAt.Add(time.Hour) + account := models.PlatformAccount{ + Entity: models.Entity{ + Identity: "019fcdb4-5c7d-720b-8e20-4850f4ce52b0", + CreatedAt: createdAt, + UpdatedAt: updatedAt, + Status: 1, + }, + Username: "root", DisplayName: "平台根管理员", + PlatformRoleCode: "root", Phone: "", + } + + view := platformAccountView(account) + if view["created_at"] != createdAt || view["updated_at"] != updatedAt { + t.Fatalf("平台账户审计时间未完整返回: %#v", view) + } + if phone, ok := view["phone"].(string); !ok || phone != "" { + t.Fatalf("空联系电话应原样返回给展示层: %#v", view["phone"]) + } +} diff --git a/docs/操作日志_平台账户创建时间与联系电话空值修复_20260817.md b/docs/操作日志_平台账户创建时间与联系电话空值修复_20260817.md new file mode 100644 index 0000000..f2cdf53 --- /dev/null +++ b/docs/操作日志_平台账户创建时间与联系电话空值修复_20260817.md @@ -0,0 +1,43 @@ +# 平台账户创建时间与联系电话空值修复操作日志 + +操作时间:2026-08-17 +操作类型:修改 +影响模块:平台总后台 / 平台管理 / 平台账户详情 + +## 操作前状态 + +- 平台账户专用响应没有返回实体已有的创建时间和更新时间,账户摘要错误显示 `-`。 +- root 初始化账户未填写联系电话,详情使用通用 `-`,业务含义不明确。 + +## 具体操作 + +- `platformAccountView` 补充返回数据库中的 `created_at` 和 `updated_at`。 +- 平台账户联系电话为空时显示“未填写”。 +- 保持 root 初始化联系电话为空,不写入虚假示例号码。 +- 增加后端单元测试和前端静态展示契约。 + +## 操作后状态 + +- 创建时间显示账户的真实数据库时间。 +- 未维护联系电话时显示“未填写”,管理员可通过编辑补充。 + +## 代码变更 + +- `backend/api/internal/logic/platform/platform/account.go`:补充账户审计时间响应字段。 +- `backend/api/internal/logic/platform/platform/account_test.go`:验证审计时间与空联系电话响应。 +- `frontend/platform_admin/src/api/resources.ts`:增加联系电话空值文案。 +- `frontend/platform_admin/scripts/check-resource-display-contracts.mjs`:增加平台账户空值契约。 +- `docs/项目文档_平台资源中文展示统一_v1.0.md`:增加 v1.20 记录。 + +## 验证结果 + +- 后端平台账户测试通过:`go test ./internal/logic/platform/platform`。 +- 资源展示契约检查通过:`pnpm resource-display-contracts:check`。 +- 后端接口契约检查通过:`pnpm contract:check`。 +- Biome 代码检查通过。 +- TypeScript 类型检查通过:`pnpm type:check`。 +- 前端生产构建通过:`pnpm build`。 + +## 风险评估 + +- 仅扩展响应字段并调整空值文案,不改变数据库结构、写入协议或 root 初始化凭据。 diff --git a/docs/项目文档_平台资源中文展示统一_v1.0.md b/docs/项目文档_平台资源中文展示统一_v1.0.md index 0c8d71e..639a2a7 100644 --- a/docs/项目文档_平台资源中文展示统一_v1.0.md +++ b/docs/项目文档_平台资源中文展示统一_v1.0.md @@ -82,3 +82,4 @@ frontend/platform_admin/ - v1.17:内容类型统一显示公告、协议,发布状态统一显示草稿、已发布;新建和编辑改用中文下拉并保留未知值提示。 - v1.18:客服工单用户统一展示可读名称并保留标识复制;分类与优先级统一显示中文,新建和编辑改用中文下拉并保留未知值提示。 - v1.19:客服工单详情的气站、配送点和处理人员统一展示关系名称;未分派、未开始、未完成及未提交结果等空值改用明确业务状态,不再显示裸 `-`。 +- v1.20:平台账户接口补回真实创建时间和更新时间;root 未填写联系电话时显示“未填写”,不生成虚假号码。 diff --git a/frontend/platform_admin/scripts/check-resource-display-contracts.mjs b/frontend/platform_admin/scripts/check-resource-display-contracts.mjs index 063ed7b..ab67612 100644 --- a/frontend/platform_admin/scripts/check-resource-display-contracts.mjs +++ b/frontend/platform_admin/scripts/check-resource-display-contracts.mjs @@ -383,6 +383,11 @@ assertIncludes( '!field.listHidden', '仅用于详情的辅助字段不得扩张标准资源列表', ); +assertIncludes( + resources, + "f('phone', { emptyText: '未填写' })", + '平台账户联系电话为空时必须显示业务文案', +); assertIncludes( detailPage, '!hasResourceFieldLabel(props.definition, actualKey)', diff --git a/frontend/platform_admin/src/api/resources.ts b/frontend/platform_admin/src/api/resources.ts index d0d6ff1..4accb4e 100644 --- a/frontend/platform_admin/src/api/resources.ts +++ b/frontend/platform_admin/src/api/resources.ts @@ -947,7 +947,7 @@ export const resources: ResourceUiDefinition[] = [ f('completed_at', { label: '完成时间', type: 'datetime', listHidden: true, emptyText: '尚未完成' }), f('result', { label: '处理结果', type: 'textarea', listHidden: true, emptyText: '尚未提交处理结果' }), ]), - define('platform_account', '平台账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('display_name'), f('avatar'), f('platform_role_code', { required: true, unknownValueLabel: '未知角色' }), f('phone')]), + define('platform_account', '平台账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('display_name'), f('avatar'), f('platform_role_code', { required: true, unknownValueLabel: '未知角色' }), f('phone', { emptyText: '未填写' })]), define('platform_role', '平台角色', 'writable', [f('role_code', { required: true }), f('name', { required: true }), f('location_scope', { required: true, type: 'select', options: resourceSearchEnumOptions('platform_role', 'location_scope') })], 'list', [ { name: '分配菜单', resource: '/platform_role/:identity/menu', method: 'PUT', fields: [f('menu_identities', { type: 'identity-list', relation: '/platform_menu' })] }, ]),