From 7f594eb608731cb10da0d49a49405d421b710ee9 Mon Sep 17 00:00:00 2001 From: czl231 <3286836406@qq.com> Date: Mon, 10 Aug 2026 21:06:12 +0800 Subject: [PATCH] fix(platform): constrain delivery account role --- .../logic/platform/delivery/account.go | 21 ++++++++-- .../logic/platform/delivery/delivery_test.go | 8 ++++ docs/操作日志_配送点账户角色约束_20260810.md | 41 +++++++++++++++++++ .../src/views/shared/CrudListPage.vue | 10 +++-- 4 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 docs/操作日志_配送点账户角色约束_20260810.md diff --git a/backend/api/internal/logic/platform/delivery/account.go b/backend/api/internal/logic/platform/delivery/account.go index 541e7d3..26cffe3 100644 --- a/backend/api/internal/logic/platform/delivery/account.go +++ b/backend/api/internal/logic/platform/delivery/account.go @@ -12,17 +12,30 @@ import ( "gorm.io/gorm" ) +// deliveryAdminRoleCode 是配送点管理后台当前唯一允许的登录角色编码。 +const deliveryAdminRoleCode = "admin" + +// newDeliveryAccount 构造平台创建的配送点登录账号,并固定其权限身份。 +func newDeliveryAccount(deliveryBasicID uint64, request accountRequest, passwordHash string) models.DeliveryAccount { + return models.DeliveryAccount{ + Entity: common.NewEntity(common.StatusEnable), + DeliveryBasicID: deliveryBasicID, + Username: request.Username, + DisplayName: request.DisplayName, + PasswordHash: passwordHash, + RoleCode: deliveryAdminRoleCode, + } +} + type accountRequest struct { Username string `json:"username" binding:"required,max=64"` Password string `json:"password" binding:"required"` DisplayName string `json:"display_name" binding:"max=64"` - RoleCode string `json:"role_code" binding:"max=64"` DeliveryBasicIdentity string `json:"delivery_basic_identity"` } type accountUpdateRequest struct { DisplayName string `json:"display_name" binding:"max=64"` - RoleCode string `json:"role_code" binding:"max=64"` DeliveryBasicIdentity string `json:"delivery_basic_identity"` } @@ -64,7 +77,7 @@ func CreateDeliveryAccount(ctx *gin.Context) { infra.Response.Error(ctx, err) return } - account := models.DeliveryAccount{Entity: common.NewEntity(common.StatusEnable), DeliveryBasicID: deliveryBasicID, Username: request.Username, DisplayName: request.DisplayName, PasswordHash: hash, RoleCode: request.RoleCode} + account := newDeliveryAccount(deliveryBasicID, request, hash) if err := impl.DBService.Create(&account).Error; err != nil { infra.Response.Error(ctx, err) return @@ -83,5 +96,5 @@ func UpdateDeliveryAccount(ctx *gin.Context) { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } - common.UpdateAllowedByIdentity(ctx, &models.DeliveryAccount{}, gin.H{"delivery_basic_id": deliveryBasicID, "display_name": request.DisplayName, "role_code": request.RoleCode}, []string{"delivery_basic_id", "display_name", "role_code"}) + common.UpdateAllowedByIdentity(ctx, &models.DeliveryAccount{}, gin.H{"delivery_basic_id": deliveryBasicID, "display_name": request.DisplayName}, []string{"delivery_basic_id", "display_name"}) } diff --git a/backend/api/internal/logic/platform/delivery/delivery_test.go b/backend/api/internal/logic/platform/delivery/delivery_test.go index 6c239ed..8f09427 100644 --- a/backend/api/internal/logic/platform/delivery/delivery_test.go +++ b/backend/api/internal/logic/platform/delivery/delivery_test.go @@ -36,3 +36,11 @@ func TestRestoreDeliveryBasicAddress(t *testing.T) { t.Fatalf("配送点详情地址未正确恢复:%#v", restored) } } + +// TestNewDeliveryAccountUsesAdminRole 验证平台创建配送点账号时固定后台唯一支持的角色编码。 +func TestNewDeliveryAccountUsesAdminRole(t *testing.T) { + account := newDeliveryAccount(9, accountRequest{Username: "delivery-admin", DisplayName: "配送点管理员"}, "password-hash") + if account.RoleCode != "admin" { + t.Fatalf("配送点管理员角色编码必须为 admin,实际为 %q", account.RoleCode) + } +} diff --git a/docs/操作日志_配送点账户角色约束_20260810.md b/docs/操作日志_配送点账户角色约束_20260810.md new file mode 100644 index 0000000..266169b --- /dev/null +++ b/docs/操作日志_配送点账户角色约束_20260810.md @@ -0,0 +1,41 @@ +# 配送点账户角色约束操作日志 + +操作时间:2026-08-10 + +操作类型:修改 + +影响模块:平台总后台配送点管理、平台配送点账户接口 + +## 操作前状态 + +`/organization/delivery-basic` 页面的“账户管理”弹窗允许自由输入角色编码,平台接口也会原样保存。配送点后台登录与鉴权仅接受 `admin`,因此可能创建无法登录的账号。 + +## 具体操作 + +- 配送点账户表单固定只读显示“配送点管理员”,不向用户暴露内部编码 `admin`。 +- 平台创建配送点账号时由服务端强制写入 `admin`。 +- 平台编辑配送点账号时不再更新角色编码。 +- 增加角色编码回归测试。 + +## 操作后状态 + +平台总后台新建配送点账号不再产生无效角色;编辑账号不会意外改变权限身份。气站账户及其他资源的账户管理行为保持不变。 + +## 代码变更 + +- `frontend/platform_admin/src/views/shared/CrudListPage.vue`:配送点固定角色只读展示与提交。 +- `backend/api/internal/logic/platform/delivery/account.go`:创建强制角色、编辑禁止改角色。 +- `backend/api/internal/logic/platform/delivery/delivery_test.go`:新增角色约束测试。 + +## 验证结果 + +- `go test ./internal/logic/platform/delivery`:通过。 +- `pnpm.cmd type:check`:通过。 +- `pnpm.cmd contract:check`:通过,48 个资源契约一致。 +- `pnpm.cmd build`:通过。 +- `pnpm.cmd lint`:命令通过;仓库已有 116 个警告和 12 个提示,本次未引入阻断错误。 + +## 风险评估 + +- 历史非 `admin` 账号不会自动迁移,需后续核查后单独修复。 +- 接口仍兼容携带 `role_code` 的旧客户端,但服务端不再采纳该字段。 diff --git a/frontend/platform_admin/src/views/shared/CrudListPage.vue b/frontend/platform_admin/src/views/shared/CrudListPage.vue index 9fd9a38..886a7dd 100644 --- a/frontend/platform_admin/src/views/shared/CrudListPage.vue +++ b/frontend/platform_admin/src/views/shared/CrudListPage.vue @@ -152,7 +152,9 @@ - + + + @@ -674,10 +676,12 @@ async function loadManagedAccounts() { } function resetAccountForm(row?: Row) { + // 配送点账户使用服务端唯一支持的管理员角色,避免生成无法登录的账号。 + const fixedRoleCode = props.definition.accountManagement?.resource === '/delivery_account' ? 'admin' : undefined; accountForm.username = row?.username ?? ''; accountForm.password = ''; accountForm.display_name = row?.display_name ?? ''; - accountForm.role_code = row?.role_code ?? ''; + accountForm.role_code = fixedRoleCode ?? row?.role_code ?? ''; } function openAccountCreate() { @@ -712,7 +716,7 @@ async function saveAccount() { try { const payload: Record = { display_name: String(accountForm.display_name ?? '').trim(), - role_code: String(accountForm.role_code ?? '').trim(), + role_code: management.resource === '/delivery_account' ? 'admin' : String(accountForm.role_code ?? '').trim(), [management.relationKey]: ownerIdentity, }; if (!accountEditingIdentity.value) {