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) {