210 lines
6.7 KiB
Markdown
210 lines
6.7 KiB
Markdown
# 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
|
||
<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` 方法)
|
||
|
||
**当前逻辑**:
|
||
```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<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`
|
||
|
||
**当前**:
|
||
```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
|
||
<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(自治区)时,不过滤:
|
||
|
||
```xml
|
||
<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 分组取最新:
|
||
|
||
```xml
|
||
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
|
||
```
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. **自治区账号识别**:需要在 Controller 层判断并传递 `isAutonomousRegion` 参数
|
||
2. **兼容性**:确保修改后与现有功能兼容,不要破坏其他业务线的已办查询
|
||
3. **性能**:去重查询可能影响性能,如果 BIZSEQID 已建立索引应无大碍
|
||
4. **第3点难点**:如果去重逻辑 SQL 难以修改(涉及多表 UNION),可以在 Service 层用 Java 代码处理,但会增加内存压力
|