6.7 KiB
6.7 KiB
XQ-20260414-002 开发思路与改动
问题分析
问题1根因分析
查看 TSTaskListMapper.xml 的 selectFinishUnionTaskPage 查询:
SELECT DISTINCT ta.TASKLISTID, ta.WORKFLOWID, ...
FROM TSTaskList ta
LEFT JOIN TShwfProcessNode n ON ta.WorkflowID = n.processid
WHERE ta.BUSSTATUS = 2
AND ta.WORKFLOWID IN (
SELECT DISTINCT WORKFLOWID FROM tsopinion tso
<where>
<if test="customParamMap.childUnitSwitch != null and customParamMap.childUnitSwitch != ''">
-- 有 childUnitSwitch 时的过滤逻辑
</if>
-- 注意:如果 childUnitSwitch 为空或不存在,整个 WHERE 块不生效
-- 导致子查询返回 tsopinion 表中所有 WORKFLOWID
</where>
)
根本原因:当 childUnitSwitch 参数不存在时,子查询没有任何过滤条件,返回 tsopinion 表中所有 WORKFLOWID,导致已办列表显示全自治区的记录。
问题2根因分析
查询结果中每条 TASKLIST 记录会对应 TShwfProcessNode 表中的多个节点记录(每个环节一个),而 DISTINCT 无法将同一业务的多条记录合并成一条。
解决方案
修复1: 已办列表按机构范围过滤
修改文件: TaskController.java (第280行附近 finishTaskUnionPage 方法)
当前逻辑:
if (customParamMap != null && customParamMap.containsKey("childUnitSwitch")) {
// 只有当 childUnitSwitch 存在时才设置机构过滤参数
}
修改后逻辑:
// 获取当前用户机构信息
String myOrgNumber = StringUtils.clearRegionZero(curUser.getRegionID());
if (StringUtils.isNotBlank(myOrgNumber)) {
customParamMap.put("myOrgNumber", myOrgNumber);
customParamMap.put("myOrgNumberLike", myOrgNumber + "%");
// 判断是否为自治区账号(机构等级为1)
Map<String, String> orgParams = new HashMap<>();
orgParams.put("deleted", "0");
orgParams.put("unittype", "1");
orgParams.put("orgNumber", myOrgNumber);
OrgUnits org = aicorgService.queryByOrgNumberMap(orgParams);
boolean isAutonomousRegion = org != null && org.getOrgLevel() != null && org.getOrgLevel() == 1;
// 设置是否查看下级单位标志
// childUnitSwitch = "1" 表示查看下级
// childUnitSwitch 不传或为 "0" 表示不查看下级
// 但自治区账号即使不查看下级,也应该能看到本级数据
if (customParamMap.containsKey("childUnitSwitch")) {
// 前端明确传了 childUnitSwitch,使用前端值
} else {
// 前端没传,默认不查看下级(childUnitSwitch = "0")
customParamMap.put("childUnitSwitch", "0");
}
}
同步修改 Mapper XML: 确保当 childUnitSwitch = "0" 时,也要有机构过滤逻辑(不仅仅是 "1" 时)。
修复2: 每笔业务只显示一条记录
方案: 在外层查询使用 GROUP BY BIZSEQID,选择每个业务最新的一条记录。
修改文件: TSTaskListMapper.xml 的 selectFinishUnionTaskPage
当前:
SELECT * FROM (
(select DISTINCT ta.TASKLISTID, ta.WORKFLOWID, ta.BIZSEQID, ...
from TSTaskList ta
LEFT JOIN TShwfProcessNode n on ta.WorkflowID = n.processid
where ...)
) m
ORDER BY m.LAUPTIME DESC
修改后:
SELECT m.* FROM (
SELECT * FROM (
(select ... from TSTaskList ... UNION all select ... from tsrevtasklist ...)
) sub
GROUP BY sub.BIZSEQID
HAVING sub.LAUPTIME = MAX(sub.LAUPTIME) -- 取每笔业务最新的一条
) m
ORDER BY m.LAUPTIME DESC
或者使用窗口函数:
SELECT * FROM (
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY t.BIZSEQID ORDER BY t.LAUPTIME DESC) as rn
FROM (
(select ... from TSTaskList ta ... UNION all select ... from tsrevtasklist ...)
) t
) tt
WHERE tt.rn = 1
ORDER BY tt.LAUPTIME DESC
具体代码改动
1. TaskController.java 修改(约第290行)
在 finishTaskUnionPage 方法中,修改机构过滤逻辑:
// 原有代码(只处理 childUnitSwitch 存在时):
// if (customParamMap != null && customParamMap.containsKey("childUnitSwitch")) {
// 修改为:无条件设置机构参数
if (customParamMap != null) {
String myOrgNumber = StringUtils.clearRegionZero(curUser.getRegionID());
if (StringUtils.isNotBlank(myOrgNumber)) {
customParamMap.put("myOrgNumber", myOrgNumber);
customParamMap.put("myOrgNumberLike", myOrgNumber + "%");
}
// 确保 childUnitSwitch 有值(前端没传时默认为"0")
if (!customParamMap.containsKey("childUnitSwitch")) {
customParamMap.put("childUnitSwitch", "0");
}
}
2. TSTaskListMapper.xml 修改(约第580-790行)
2.1 修改子查询逻辑:
当 childUnitSwitch = "0"(不查看下级)时,也需要按机构过滤:
<when test='customParamMap.childUnitSwitch eq "0"'>
and (
tso.HANDLERID = #{customParamMap.userId}
or exists(select 1 from CXAICORG.T_USERS tu
left join CXAICORG.T_ORGUNITS torg on tu.ORGUNITID = torg.ORGUNITID
where tso.HANDLERID = tu.USERID
and torg.ORGNUMBER = #{customParamMap.myOrgNumber})
)
</when>
2.2 添加自治区账号特殊处理:
当机构等级为1(自治区)时,不过滤:
<when test='customParamMap.childUnitSwitch eq "0"'>
<choose>
<when test="customParamMap.isAutonomousRegion != null and customParamMap.isAutonomousRegion == true">
<!-- 自治区账号,不过滤,返回所有 -->
</when>
<otherwise>
and (
tso.HANDLERID = #{customParamMap.userId}
or exists(select 1 from CXAICORG.T_USERS tu
left join CXAICORG.T_ORGUNITS torg on tu.ORGUNITID = torg.ORGUNITID
where tso.HANDLERID = tu.USERID
and torg.ORGNUMBER = #{customParamMap.myOrgNumber})
)
</otherwise>
</choose>
</when>
2.3 去重逻辑:
在外层包装查询结果,按 BIZSEQID 分组取最新:
SELECT * FROM (
SELECT m.*,
ROW_NUMBER() OVER (PARTITION BY m.BIZSEQID ORDER BY m.LAUPTIME DESC) as rn
FROM (
<!-- 现有的 UNION ALL 查询 -->
) m
) mm
WHERE mm.rn = 1
ORDER BY mm.LAUPTIME DESC
注意事项
- 自治区账号识别:需要在 Controller 层判断并传递
isAutonomousRegion参数 - 兼容性:确保修改后与现有功能兼容,不要破坏其他业务线的已办查询
- 性能:去重查询可能影响性能,如果 BIZSEQID 已建立索引应无大碍
- 第3点难点:如果去重逻辑 SQL 难以修改(涉及多表 UNION),可以在 Service 层用 Java 代码处理,但会增加内存压力