fix: 修复用户管理页面所属机构字段显示及列表过滤逻辑

1. 前端所属机构字段改为使用后端返回的平铺 tenantName 字段
   - users.ts: 添加 tenantName, tenantCode, tenantType, tenantIsSuper 平铺字段
   - Index.vue: 表格列和详情 Drawer 使用 record.tenantName/detailData.tenantName

2. 后端修复机构用户 (org) 过滤逻辑
   - SysUserServiceImpl: case "org" 分支增加 getOrgTenantIds() 调用,传递 orgTenantIdsFilter 参数
   - SysUserMapper.xml: 增加 orgTenantIdsFilter 参数处理,使用 IN 查询过滤

3. 后端修复公众 (public) 和评委 (judge) 用户过滤逻辑
   - 数据库中 public 租户的 tenant_type='platform',judge 租户的 tenant_type='other'
   - case "public"/"judge" 改为传递 tenantCodeFilter 参数,按租户 code 过滤
   - SysUserMapper.xml: 增加 tenantCodeFilter 参数处理

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
zhonghua 2026-04-02 20:06:09 +08:00
parent d19d7d9a2c
commit c5fad30849
5 changed files with 75 additions and 6 deletions

View File

@ -96,11 +96,22 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
switch (userType) {
case "platform" -> params.put("isSuperTenantFilter", 1);
case "org" -> {
// 排除超管公众评委租户
// 此逻辑较复杂通过 filterTenantId tenantType 筛选
// 排除超管公众评委租户使用 org 租户 ID 列表过滤
List<Long> orgTenantIds = getOrgTenantIds();
if (orgTenantIds.isEmpty()) {
// 如果没有机构租户返回空结果
return new PageResult<>(List.of(), 0L, page, pageSize);
}
params.put("orgTenantIdsFilter", orgTenantIds);
}
case "judge" -> {
// 按租户 code='judge' 过滤因为 judge 租户的 tenant_type 可能是 other
params.put("tenantCodeFilter", "judge");
}
case "public" -> {
// 按租户 code='public' 过滤因为 public 租户的 tenant_type=platform不是 public
params.put("tenantCodeFilter", "public");
}
case "judge" -> params.put("tenantTypeFilter", "judge_pool");
case "public" -> params.put("tenantTypeFilter", "public");
}
}
if (filterTenantId != null) {
@ -127,6 +138,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return PageResult.from(result);
}
/**
* 获取机构租户 ID 列表排除超管公众评委
*/
private List<Long> getOrgTenantIds() {
List<SysTenant> tenants = tenantMapper.selectList(
new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getValidState, 1));
return tenants.stream()
.filter(t -> t.getIsSuper() == 0 && !"public".equals(t.getCode()) && !"judge".equals(t.getCode()))
.map(SysTenant::getId)
.toList();
}
@Override
public Map<String, Object> getStats() {
List<SysTenant> tenants = tenantMapper.selectList(

View File

@ -51,6 +51,17 @@
<if test="params.filterTenantId != null">
AND u.tenant_id = #{params.filterTenantId}
</if>
<!-- 机构租户 ID 列表过滤(排除超管、公众、评委) -->
<if test="params.orgTenantIdsFilter != null and params.orgTenantIdsFilter.size() > 0">
AND u.tenant_id IN
<foreach collection="params.orgTenantIdsFilter" item="tenantId" open="(" separator="," close=")">
#{tenantId}
</foreach>
</if>
<!-- 按租户 code 过滤(用于 public、judge 等固定租户) -->
<if test="params.tenantCodeFilter != null and params.tenantCodeFilter != ''">
AND t.code = #{params.tenantCodeFilter}
</if>
<!-- 超管按 userType 过滤时,映射到租户类型 -->
<if test="params.tenantTypeFilter != null and params.tenantTypeFilter != ''">
AND t.tenant_type = #{params.tenantTypeFilter}

View File

@ -308,3 +308,32 @@ public → tenant.code = 'public'
**验证结果:**
- 后端重启成功,编译无错误
- 前端 HMR 热更新生效,无新增 TS 错误
### 2026-04-02 — 机构用户过滤逻辑修复
**问题:**
- 前端点击"机构"统计卡片时,后端 `findAll(userType=org)` 返回 0 条数据,与统计接口返回不一致
- 原因:`case "org"` 分支没有设置任何过滤参数Mapper XML 中也没有对应的处理逻辑
**改动2 个文件):**
- `backend/.../SysUserServiceImpl.java``findAll()` 方法:`case "org"` 分支增加调用 `getOrgTenantIds()` 获取机构租户 ID 列表,传递 `orgTenantIdsFilter` 参数;新增 `getOrgTenantIds()` 私有方法
- `backend/.../SysUserMapper.xml``selectUserPage` 增加 `<if test="params.orgTenantIdsFilter != null">` 条件,使用 `<foreach>` 遍历 ID 列表进行 `IN` 查询
**验证结果:**
- 后端编译成功Maven 编译无错误
- 机构用户列表查询应正确排除超管、公众、评委租户
### 2026-04-02 — 公众/评委用户过滤逻辑修复
**问题:**
- 前端点击"公众"卡片时,传递 `userType=public`,但返回空数据(统计显示 9 条)
- 原因:后端 `case "public"``tenant_type = 'public'` 过滤,但数据库中 public 租户的 `tenant_type = 'platform'`(不是 `'public'`
- 同理,`case "judge"` 按 `tenant_type = 'judge_pool'` 过滤,但 judge 租户的 `tenant_type = 'other'`
**改动2 个文件):**
- `backend/.../SysUserServiceImpl.java``findAll()` 方法:`case "public"` 和 `case "judge"` 改为传递 `tenantCodeFilter` 参数(值分别为 `"public"``"judge"`),按租户 code 过滤而非 tenant_type
- `backend/.../SysUserMapper.xml``selectUserPage` 增加 `<if test="params.tenantCodeFilter != null">` 条件,使用 `t.code = #{params.tenantCodeFilter}` 过滤
**验证结果:**
- 后端编译成功
- 公众/评委用户列表查询应按租户 code 正确过滤

View File

@ -38,6 +38,12 @@ export interface User {
modifier?: number;
createTime?: string;
modifyTime?: string;
// 平铺的租户字段(后端直接返回)
tenantName?: string;
tenantCode?: string;
tenantType?: string;
tenantIsSuper?: number;
// 兼容嵌套对象(详情接口可能返回)
tenant?: UserTenant;
roles?: Array<{
id: number;

View File

@ -84,7 +84,7 @@
<template v-else-if="column.key === 'tenantName'">
{{ getUserTypeKey(record) === 'platform' || getUserTypeKey(record) === 'public'
? '-'
: record.tenant?.name || '-' }}
: record.tenantName || '-' }}
</template>
<template v-else-if="column.key === 'phone'">
{{ record.phone || '-' }}
@ -140,7 +140,7 @@
<a-descriptions-item label="邮箱">{{ detailData.email || '-' }}</a-descriptions-item>
<a-descriptions-item label="城市">{{ detailData.city || '-' }}</a-descriptions-item>
<a-descriptions-item label="性别">{{ genderLabel(detailData.gender) }}</a-descriptions-item>
<a-descriptions-item label="所属机构">{{ detailData.tenant?.name || '-' }}</a-descriptions-item>
<a-descriptions-item label="所属机构">{{ detailData.tenantName || '-' }}</a-descriptions-item>
<a-descriptions-item label="用户类型">
<a-tag :color="getUserTypeTag(detailData).color">{{ getUserTypeTag(detailData).label }}</a-tag>
</a-descriptions-item>