增加根据部门查询表单,查询表单相关的反馈措施数量

This commit is contained in:
wsm
2026-05-21 14:18:48 +08:00
parent 3492728431
commit a84ff0d77c
3 changed files with 129 additions and 20 deletions
@@ -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<BgXiSpeak, IBgXiSpeakService>{
private final IBgXiSpeakService bgXiSpeakService;
private final IBgXiSpeakFeedbackService bgXiSpeakFeedbackService;
private final RuntimeService runtimeService;
/**
* 分页列表查询
@@ -100,22 +102,19 @@ public class BgXiSpeakController extends JeecgController<BgXiSpeak, IBgXiSpeakSe
/**
* 【vue3专用】加载节点的子数据
*
* @param pid
* @param deptIds
* @return
*/
@RequestMapping(value = "/loadTreeChildren", method = RequestMethod.GET)
public Result<List<SelectTreeModel>> loadTreeChildren(@RequestParam(name = "pid") String pid) {
Result<List<SelectTreeModel>> result = new Result<>();
try {
List<SelectTreeModel> 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<IPage<BgXiSpeak>> getRootListWithDept(@RequestParam(name = "dept_ids") String deptIds) {
if(StringUtils.isEmpty(deptIds)){
return Result.error("查询牵头部门为空,请选择用于查询的牵头部门");
}
return result;
List<BgXiSpeak> res = bgXiSpeakService.getRootListWithDept(deptIds);
IPage<BgXiSpeak> pageList = new Page<>(1, 10, res.size());
pageList.setRecords(res);
return Result.OK(pageList);
}
/**
@@ -354,4 +353,45 @@ public class BgXiSpeakController extends JeecgController<BgXiSpeak, IBgXiSpeakSe
return super.importExcel(request, response, BgXiSpeak.class);
}
/**
* 批量查询多个 xispeak 节点下的反馈统计数量
*
* @param ids 逗号分隔的 xispeak 主键 ID 列表
* @return Map&lt;id, {total: 总条数, closed: 已闭环数}&gt;
*/
@Operation(summary="批量查询反馈统计数量")
@GetMapping(value = "/queryFeedbackCounts")
public Result<Map<String, Map<String, Integer>>> queryFeedbackCounts(
@RequestParam(name="ids", required=true) String ids) {
if (oConvertUtils.isEmpty(ids)) {
return Result.OK(new HashMap<>());
}
List<String> idList = Arrays.asList(ids.split(","));
// 一次性查询所有相关 feedback 记录
List<BgXiSpeakFeedback> feedbackList = bgXiSpeakFeedbackService.list(
new LambdaQueryWrapper<BgXiSpeakFeedback>()
.in(BgXiSpeakFeedback::getMainId, idList));
// 初始化结果集
Map<String, Map<String, Integer>> result = new HashMap<>();
for (String id : idList) {
if (oConvertUtils.isNotEmpty(id)) {
Map<String, Integer> counts = new HashMap<>();
counts.put("total", 0);
counts.put("closed", 0);
result.put(id.trim(), counts);
}
}
// 统计
for (BgXiSpeakFeedback fb : feedbackList) {
Map<String, Integer> 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);
}
}
@@ -81,4 +81,8 @@ public interface IBgXiSpeakService extends IService<BgXiSpeak> {
BgXiSpeak getByIdForUpdate(String id);
boolean withDrawXiSpeak(String id);
List<BgXiSpeak> getRootListWithDept(String pid);
void checkAndMarkCompletedByProcessInstId(String processInstanceId);
}
@@ -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<BgXiSpeakMapper, BgXiSpeak
return true;
}
public List<BgXiSpeak> getRootListWithDept(String pid) {
// 1. 这里的参数 pid 实际是前端传过来的部门逗号拼接字符串,将其清洗并转换为 Set
Set<String> deptIdSet = Arrays.stream(pid.split(","))
.map(String::trim)
.filter(oConvertUtils::isNotEmpty)
.collect(Collectors.toSet());
// 2. 初始化 Lambda 查询构造器
LambdaQueryWrapper<BgXiSpeak> 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<TaskTask> qw = new LambdaQueryWrapper<TaskTask>()
.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<TaskTask> allQw = new LambdaQueryWrapper<TaskTask>()
.eq(TaskTask::getBusinessId, businessId);
List<TaskTask> 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);
}
}
}