diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/BgXiSpeakController.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/BgXiSpeakController.java index 06c578d..bd686b4 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/BgXiSpeakController.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/BgXiSpeakController.java @@ -1,8 +1,6 @@ package org.jeecg.modules.bg.xispeak.controller; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -17,12 +15,15 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.system.vo.SelectTreeModel; import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak; +import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService; +import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService; import org.jeecg.modules.bg.xispeak.dto.BgXiSpeakBpmSaveDTO; import org.flowable.engine.RuntimeService; @@ -58,6 +59,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions; @Slf4j public class BgXiSpeakController extends JeecgController{ private final IBgXiSpeakService bgXiSpeakService; + private final IBgXiSpeakFeedbackService bgXiSpeakFeedbackService; private final RuntimeService runtimeService; /** * 分页列表查询 @@ -100,22 +102,19 @@ public class BgXiSpeakController extends JeecgController> loadTreeChildren(@RequestParam(name = "pid") String pid) { - Result> result = new Result<>(); - try { - List ls = bgXiSpeakService.queryListByPid(pid); - result.setResult(ls); - result.setSuccess(true); - } catch (Exception e) { - e.printStackTrace(); - result.setMessage(e.getMessage()); - result.setSuccess(false); + @RequestMapping(value = "/getRootListWithDept", method = RequestMethod.GET) + public Result> getRootListWithDept(@RequestParam(name = "dept_ids") String deptIds) { + + if(StringUtils.isEmpty(deptIds)){ + return Result.error("查询牵头部门为空,请选择用于查询的牵头部门"); } - return result; + List res = bgXiSpeakService.getRootListWithDept(deptIds); + IPage pageList = new Page<>(1, 10, res.size()); + pageList.setRecords(res); + return Result.OK(pageList); } /** @@ -354,4 +353,45 @@ public class BgXiSpeakController extends JeecgController>> queryFeedbackCounts( + @RequestParam(name="ids", required=true) String ids) { + if (oConvertUtils.isEmpty(ids)) { + return Result.OK(new HashMap<>()); + } + List idList = Arrays.asList(ids.split(",")); + // 一次性查询所有相关 feedback 记录 + List feedbackList = bgXiSpeakFeedbackService.list( + new LambdaQueryWrapper() + .in(BgXiSpeakFeedback::getMainId, idList)); + // 初始化结果集 + Map> result = new HashMap<>(); + for (String id : idList) { + if (oConvertUtils.isNotEmpty(id)) { + Map counts = new HashMap<>(); + counts.put("total", 0); + counts.put("closed", 0); + result.put(id.trim(), counts); + } + } + // 统计 + for (BgXiSpeakFeedback fb : feedbackList) { + Map counts = result.get(fb.getMainId()); + if (counts != null) { + counts.put("total", counts.get("total") + 1); + if ("1".equals(fb.getCompletionStatus())) { + counts.put("closed", counts.get("closed") + 1); + } + } + } + return Result.OK(result); + } + } diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java index c946791..0ff70f6 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java @@ -81,4 +81,8 @@ public interface IBgXiSpeakService extends IService { BgXiSpeak getByIdForUpdate(String id); boolean withDrawXiSpeak(String id); + + List getRootListWithDept(String pid); + + void checkAndMarkCompletedByProcessInstId(String processInstanceId); } diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java index 93d9c94..6c87ef0 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java @@ -16,10 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; + +import java.util.*; import java.util.stream.Collectors; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -280,4 +278,71 @@ public class BgXiSpeakServiceImpl extends ServiceImpl getRootListWithDept(String pid) { + + // 1. 这里的参数 pid 实际是前端传过来的部门逗号拼接字符串,将其清洗并转换为 Set + Set deptIdSet = Arrays.stream(pid.split(",")) + .map(String::trim) + .filter(oConvertUtils::isNotEmpty) + .collect(Collectors.toSet()); + + // 2. 初始化 Lambda 查询构造器 + LambdaQueryWrapper lq = new LambdaQueryWrapper<>(); + + // 3. 【只查根节点】固定查询条件为父节点是 "0" + lq.eq(BgXiSpeak::getPid, "0"); + + // 4. 核心:只有当 deptIdSet 不为空时,才拼接多部门完全包含的逻辑 + if (deptIdSet != null && !deptIdSet.isEmpty()) { + // 使用 and(...) 动态包裹,实现各个 FIND_IN_SET 之间用 AND 连接 + lq.and(wrapper -> { + for (String deptId : deptIdSet) { + // {0} 占位符会被 MyBatis-Plus 自动预编译替换,保障 SQL 安全 + wrapper.apply("FIND_IN_SET({0}, impl_dept)", deptId); + } + }); + } + + // 5. 执行查询并返回列表(这里假设你在 ServiceImpl 中,可以直接调用 baseMapper 或 this.list) + return this.list(lq); + } + + @Override + public void checkAndMarkCompletedByProcessInstId(String processInstanceId) { + if (oConvertUtils.isEmpty(processInstanceId)) { + return; + } + LambdaQueryWrapper qw = new LambdaQueryWrapper() + .eq(TaskTask::getProcessInstId, processInstanceId) + .last("limit 1"); + TaskTask taskTask = taskTaskServiceImpl.getOne(qw, false); + if (taskTask == null || oConvertUtils.isEmpty(taskTask.getBusinessId())) { + return; + } + String businessId = taskTask.getBusinessId(); + LambdaQueryWrapper allQw = new LambdaQueryWrapper() + .eq(TaskTask::getBusinessId, businessId); + List allTaskList = taskTaskServiceImpl.list(allQw); + if (allTaskList == null || allTaskList.isEmpty()) { + return; + } + for (TaskTask tt : allTaskList) { + if (oConvertUtils.isNotEmpty(tt.getProcessInstId())) { + long running = runtimeService.createProcessInstanceQuery() + .processInstanceId(tt.getProcessInstId()) + .count(); + if (running > 0) { + return; + } + } + } + BgXiSpeak entity = this.getById(businessId); + if (entity != null && (entity.getCompletionStatus() == null || entity.getCompletionStatus() != 1)) { + entity.setCompletionStatus(1); + this.updateById(entity); + log.info("业务表单 {} 的所有流程已结束,完成状态已更新为已完成", businessId); + } + } }