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

210 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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