aiccs-api/devdoc/XQ-20260414-002_开发思路与改动.md

210 lines
6.7 KiB
Markdown
Raw Permalink Normal View History

# 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 代码处理,但会增加内存压力