# XQ-20260414-002 开发思路与改动 ## 问题分析 ### 问题1根因分析 查看 `TSTaskListMapper.xml` 的 `selectFinishUnionTaskPage` 查询: ```sql 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 -- 有 childUnitSwitch 时的过滤逻辑 -- 注意:如果 childUnitSwitch 为空或不存在,整个 WHERE 块不生效 -- 导致子查询返回 tsopinion 表中所有 WORKFLOWID ) ``` **根本原因**:当 `childUnitSwitch` 参数不存在时,子查询没有任何过滤条件,返回 tsopinion 表中所有 WORKFLOWID,导致已办列表显示全自治区的记录。 ### 问题2根因分析 查询结果中每条 TASKLIST 记录会对应 TShwfProcessNode 表中的多个节点记录(每个环节一个),而 DISTINCT 无法将同一业务的多条记录合并成一条。 --- ## 解决方案 ### 修复1: 已办列表按机构范围过滤 **修改文件**: `TaskController.java` (第280行附近 `finishTaskUnionPage` 方法) **当前逻辑**: ```java if (customParamMap != null && customParamMap.containsKey("childUnitSwitch")) { // 只有当 childUnitSwitch 存在时才设置机构过滤参数 } ``` **修改后逻辑**: ```java // 获取当前用户机构信息 String myOrgNumber = StringUtils.clearRegionZero(curUser.getRegionID()); if (StringUtils.isNotBlank(myOrgNumber)) { customParamMap.put("myOrgNumber", myOrgNumber); customParamMap.put("myOrgNumberLike", myOrgNumber + "%"); // 判断是否为自治区账号(机构等级为1) Map 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` **当前**: ```sql 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 ``` **修改后**: ```sql 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 ``` 或者使用窗口函数: ```sql 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` 方法中,修改机构过滤逻辑: ```java // 原有代码(只处理 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"`(不查看下级)时,也需要按机构过滤: ```xml 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}) ) ``` **2.2 添加自治区账号特殊处理**: 当机构等级为1(自治区)时,不过滤: ```xml 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}) ) ``` **2.3 去重逻辑**: 在外层包装查询结果,按 BIZSEQID 分组取最新: ```xml SELECT * FROM ( SELECT m.*, ROW_NUMBER() OVER (PARTITION BY m.BIZSEQID ORDER BY m.LAUPTIME DESC) as rn FROM ( ) m ) mm WHERE mm.rn = 1 ORDER BY mm.LAUPTIME DESC ``` --- ## 注意事项 1. **自治区账号识别**:需要在 Controller 层判断并传递 `isAutonomousRegion` 参数 2. **兼容性**:确保修改后与现有功能兼容,不要破坏其他业务线的已办查询 3. **性能**:去重查询可能影响性能,如果 BIZSEQID 已建立索引应无大碍 4. **第3点难点**:如果去重逻辑 SQL 难以修改(涉及多表 UNION),可以在 Service 层用 Java 代码处理,但会增加内存压力