修复气站用户配送点归属展示
This commit is contained in:
@@ -11,19 +11,30 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// gasUserListItem 在用户主档上附加当前气站服务关系中的配送点归属。
|
||||
type gasUserListItem struct {
|
||||
models.UserAccount
|
||||
DeliveryBasicID uint64 `gorm:"column:delivery_basic_id" json:"delivery_basic_id"`
|
||||
}
|
||||
|
||||
// scopedUserList 将用户列表与当前气站唯一有效服务关系绑定,避免返回跨站归属。
|
||||
func scopedUserList(databaseService *gorm.DB, gasBasicID uint64) *gorm.DB {
|
||||
return common.ActiveRecords(databaseService.Model(&models.UserAccount{})).
|
||||
Select("user_account.*, user_service_relation.delivery_basic_id AS delivery_basic_id").
|
||||
Joins("JOIN user_service_relation ON user_service_relation.user_account_id = user_account.id AND user_service_relation.status <> ?", common.StatusArchived).
|
||||
Where("user_service_relation.gas_basic_id = ?", gasBasicID)
|
||||
}
|
||||
|
||||
func ListUser(ctx *gin.Context) {
|
||||
station, ok := currentGas(ctx)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
page, size := common.PageSize(ctx)
|
||||
var list []models.UserAccount
|
||||
var list []gasUserListItem
|
||||
var total int64
|
||||
query := common.ApplyKeywordFilter(ctx,
|
||||
common.ActiveRecords(impl.DBService.Model(&models.UserAccount{})).
|
||||
Joins("JOIN user_service_relation ON user_service_relation.user_account_id = user_account.id AND user_service_relation.status <> ?",
|
||||
common.StatusArchived).
|
||||
Where("user_service_relation.gas_basic_id = ?", station.ID),
|
||||
scopedUserList(impl.DBService, station.ID),
|
||||
&models.UserAccount{})
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
infra.Response.Error(ctx, err)
|
||||
|
||||
32
backend/api/internal/logic/gas/user_test.go
Normal file
32
backend/api/internal/logic/gas/user_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package gas
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// TestScopedUserListIncludesDeliveryRelation 验证用户列表带出当前气站服务关系的配送点主键。
|
||||
func TestScopedUserListIncludesDeliveryRelation(t *testing.T) {
|
||||
connection, _, err := sqlmock.New()
|
||||
if err != nil {
|
||||
t.Fatalf("create SQL mock: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = connection.Close() })
|
||||
databaseService, err := gorm.Open(postgres.New(postgres.Config{Conn: connection}), &gorm.Config{DryRun: true})
|
||||
if err != nil {
|
||||
t.Fatalf("open GORM database: %v", err)
|
||||
}
|
||||
|
||||
statement := scopedUserList(databaseService, 42).
|
||||
Find(&[]gasUserListItem{}).Statement.SQL.String()
|
||||
if !strings.Contains(statement, "user_service_relation.delivery_basic_id AS delivery_basic_id") {
|
||||
t.Fatalf("user list must select delivery relation, got: %s", statement)
|
||||
}
|
||||
if !strings.Contains(statement, "user_service_relation.gas_basic_id =") {
|
||||
t.Fatalf("user list must keep gas scope, got: %s", statement)
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
- 复用 5173 的账户摘要组件和头像组合式逻辑,在新建、详情、编辑页显示头像选择与预览。
|
||||
- 启用工作人员与用户列表的受保护头像缩略图,替代头像存储路径文本。
|
||||
- 用户账户列表从当前气站服务关系带出配送点归属,修复配送点唯一标识显示为空。
|
||||
- 从基础信息表单移除头像文本输入框,保存时仅在选择新头像或恢复默认头像后提交头像字段。
|
||||
- 新增工作人员、用户头像读取路由,查询始终附加当前气站或服务关系范围。
|
||||
- 将更新请求的头像字段改为可选指针,未修改头像时不更新数据库列。
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
- `/staff/add` 顶部显示账户摘要与头像选择区,布局和交互参考 5173。
|
||||
- 工作人员与用户列表显示 32 像素圆形头像;无头像或加载失败时回退默认头像。
|
||||
- 用户账户列表以“所属配送点”为列名并显示配送点业务名称,唯一标识仅用于悬停查看和复制。
|
||||
- 工作人员与用户的详情、编辑页可安全读取现有头像。
|
||||
- 普通资料编辑不会误清空头像;主动恢复默认头像仍会提交空值。
|
||||
|
||||
@@ -30,7 +32,10 @@
|
||||
- `frontend/gas_admin/src/views/resource/ResourceRecordPage.vue`:启用头像摘要、过滤文本字段、接入上传载荷与未保存检测。
|
||||
- `frontend/gas_admin/src/api/avatar.ts`:使用气站 API 前缀读取受保护头像。
|
||||
- `frontend/gas_admin/src/views/shared/protected-list-avatar-loader.ts`:开放工作人员与用户缩略图渲染。
|
||||
- `frontend/gas_admin/src/api/resources.ts`:用户账户的配送点关系列表以业务名称为主展示,并保留唯一标识复制能力。
|
||||
- `frontend/gas_admin/scripts/check-resource-pages.mjs`:新增用户账户配送点名称展示的静态回归检查。
|
||||
- `backend/api/internal/logic/gas/staff.go`、`user.go`:新增范围受限头像读取并保护头像更新语义。
|
||||
- `backend/api/internal/logic/gas/user_test.go`:校验用户列表携带配送点关系且保留气站范围。
|
||||
- `backend/api/internal/routers/gas_business.go`、`gas_test.go`:注册并校验头像路由。
|
||||
|
||||
## 验证结果
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 功能:静态检查气站管理端全部标准资源是否具备独立记录页配置。
|
||||
* 版本:v1.2.0
|
||||
* 版本:v1.3.0
|
||||
*/
|
||||
import { readFileSync, existsSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
@@ -83,6 +83,13 @@ for (const marker of [
|
||||
if (!listSource.includes('recordEditReason(record)')) {
|
||||
fail('合同列表缺少编辑禁用原因提示');
|
||||
}
|
||||
if (
|
||||
!resourceSource.includes(
|
||||
"relation('delivery_basic_identity', '/delivery_basic', true, { label: '所属配送点', listLabel: '所属配送点', listRelationNameOnly: true, showIdentityCopy: true })",
|
||||
)
|
||||
) {
|
||||
fail('用户账户列表未按文档以所属配送点名称为主展示');
|
||||
}
|
||||
|
||||
const createCount = listResources.filter((item) => createModes.has(item.mode)).length;
|
||||
console.log(
|
||||
|
||||
@@ -513,7 +513,7 @@ const gasOverrides: ResourceUiDefinition[] = [
|
||||
{ name: '重置密码', resource: '/staff_account/:identity/password', method: 'PUT', fields: [f('password', { required: true })] },
|
||||
]),
|
||||
define('staff_credential', '工作人员资质', 'writable', [relation('staff_account_identity', '/staff_account', true, { staffRelation: { roles: 'context', lockPrefilled: true, showIdentityCopy: true } }), f('credential_type', { required: true }), f('credential_no'), f('expired_at')]),
|
||||
define('user_account', '用户账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('name', { required: true }), f('phone'), f('avatar'), f('real_name'), relation('delivery_basic_identity', '/delivery_basic', true)], 'list', [
|
||||
define('user_account', '用户账户', 'writable', [f('username', { required: true }), f('password', { required: true }), f('name', { required: true }), f('phone'), f('avatar'), f('real_name'), relation('delivery_basic_identity', '/delivery_basic', true, { label: '所属配送点', listLabel: '所属配送点', listRelationNameOnly: true, showIdentityCopy: true })], 'list', [
|
||||
{ name: '重置密码', resource: '/user_account/:identity/password', method: 'PUT', fields: [f('password', { required: true })] },
|
||||
]),
|
||||
define('user_address', '用户地址', 'writable', [relation('user_account_identity', '/user_account', true), f('address', { required: true }), f('longitude'), f('latitude'), f('is_default')]),
|
||||
|
||||
Reference in New Issue
Block a user