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

6.7 KiB
Raw Permalink Blame History

XQ-20260414-002 开发思路与改动

问题分析

问题1根因分析

查看 TSTaskListMapper.xmlselectFinishUnionTaskPage 查询:

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.xmlselectFinishUnionTaskPage

当前:

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

注意事项

  1. 自治区账号识别:需要在 Controller 层判断并传递 isAutonomousRegion 参数
  2. 兼容性:确保修改后与现有功能兼容,不要破坏其他业务线的已办查询
  3. 性能:去重查询可能影响性能,如果 BIZSEQID 已建立索引应无大碍
  4. 第3点难点:如果去重逻辑 SQL 难以修改(涉及多表 UNION可以在 Service 层用 Java 代码处理,但会增加内存压力