wsm-xispeak-收集后反馈流程

删除关联流程
This commit is contained in:
wsm
2026-05-15 16:39:11 +08:00
parent e2e3b913d8
commit 5a629c9088
16 changed files with 634 additions and 117 deletions
@@ -9,6 +9,14 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
@@ -16,12 +24,10 @@ import org.jeecg.common.system.vo.SelectTreeModel;
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.demo.bgpartymatter.entity.BgPartymatter;
import org.jeecg.modules.bg.xispeak.dto.BgXiSpeakBpmSaveDTO;
import org.flowable.engine.RuntimeService;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.tasktask.entity.TaskTask;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
@@ -48,12 +54,12 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
@Tag(name="习总书记重要讲话指示批示情况")
@RestController
@RequestMapping("/bg/xispeak/bgXiSpeak")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Slf4j
public class BgXiSpeakController extends JeecgController<BgXiSpeak, IBgXiSpeakService>{
@Autowired
private IBgXiSpeakService bgXiSpeakService;
/**
private final IBgXiSpeakService bgXiSpeakService;
private final RuntimeService runtimeService;
/**
* 分页列表查询
*
* @param bgXiSpeak
@@ -66,9 +72,9 @@ public class BgXiSpeakController extends JeecgController<BgXiSpeak, IBgXiSpeakSe
@Operation(summary="习总书记重要讲话指示批示情况-分页列表查询")
@GetMapping(value = "/rootList")
public Result<IPage<BgXiSpeak>> queryPageList(BgXiSpeak bgXiSpeak,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
String hasQuery = req.getParameter("hasQuery");
if(hasQuery != null && "true".equals(hasQuery)){
QueryWrapper<BgXiSpeak> queryWrapper = QueryGenerator.initQueryWrapper(bgXiSpeak, req.getParameterMap());
@@ -223,7 +229,59 @@ public class BgXiSpeakController extends JeecgController<BgXiSpeak, IBgXiSpeakSe
bgXiSpeakService.updateBgXiSpeak(bgXiSpeak);
return Result.OK("编辑成功!");
}
/**
* 保存业务数据同时更新流程变量jsonData
* @param dto
* @return
*/
@AutoLog(value = "保存业务数据同时更新流程变量jsonData")
@Operation(summary="保存业务数据同时更新流程变量jsonData")
@PostMapping(value = "/saveBpmForm")
public Result<String> saveBpmForm(@RequestBody BgXiSpeakBpmSaveDTO dto) {
if (dto == null || dto.getFormData() == null || oConvertUtils.isEmpty(dto.getFormData().getId())) {
return Result.error("表单数据不存在");
}
if (oConvertUtils.isEmpty(dto.getProcessInstanceId())) {
return Result.error("流程实例ID不能为空");
}
String varField = oConvertUtils.isEmpty(dto.getVarField()) ? "json_data" : dto.getVarField();
bgXiSpeakService.updateById(dto.getFormData());
Object existingVar = runtimeService.getVariable(dto.getProcessInstanceId(), varField);
JSONObject mergedJson = new JSONObject();
if (existingVar instanceof String) {
try {
mergedJson = JSONObject.parseObject((String) existingVar);
} catch (Exception e) {
log.warn("解析原有流程变量json_data失败,将使用空对象", e);
}
}
if (mergedJson == null) {
mergedJson = new JSONObject();
}
JSONObject formDataJson = (JSONObject) JSON.toJSON(dto.getFormData());
if (formDataJson != null) {
mergedJson.putAll(formDataJson);
}
runtimeService.setVariable(dto.getProcessInstanceId(), varField, mergedJson.toJSONString());
return Result.OK("保存成功");
}
/**
* 保存业务数据同时更新流程变量jsonData
* @param id
* @return
*/
@AutoLog(value = "根据传入的业务表单id撤回所有在运行的流程")
@Operation(summary="根据传入的业务表单id撤回所有在运行的流程")
@PostMapping(value = "/withDrawXiSpeak")
public Result<String> withDrawXiSpeak(@RequestParam("id") String id) {
if(bgXiSpeakService.withDrawXiSpeak(id)){
return Result.OK("删除流程成功");
}
return Result.error("id为" + id + "的xispeak表单删除相关流程失败");
}
/**
* 通过id删除
*
@@ -0,0 +1,23 @@
package org.jeecg.modules.bg.xispeak.dto;
import java.io.Serializable;
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "BgXiSpeak BPM form save DTO")
public class BgXiSpeakBpmSaveDTO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "Process instance id")
private String processInstanceId;
@Schema(description = "Process variable name")
private String varField;
@Schema(description = "BgXiSpeak form data")
private BgXiSpeak formData;
}
@@ -131,6 +131,7 @@ public class BgXiSpeak implements Serializable {
/**完成状态(0推进中,1已完成)*/
@Excel(name = "完成状态(0推进中,1已完成)", width = 15)
@Schema(description = "完成状态(0推进中,1已完成)")
@Dict( dicCode = "db_status")
private java.lang.Integer completionStatus;
/**落实部门id*/
@Excel(name = "落实部门id", width = 15, dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")
@@ -5,71 +5,80 @@ import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.exception.JeecgBootException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.List;
/**
* @Description: 习总书记重要讲话指示批示情况
* @Author: jeecg-boot
* @Date: 2026-04-16
* @Date: 2026-04-16
* @Version: V1.0
*/
public interface IBgXiSpeakService extends IService<BgXiSpeak> {
/**根节点父ID的值*/
public static final String ROOT_PID_VALUE = "0";
/**树节点有子节点状态值*/
public static final String HASCHILD = "1";
/**树节点无子节点状态值*/
public static final String NOCHILD = "0";
/**
* 根节点父ID的值
*/
public static final String ROOT_PID_VALUE = "0";
/**
* 新增节点
*
* @param bgXiSpeak
*/
void addBgXiSpeak(BgXiSpeak bgXiSpeak);
/**
* 修改节点
*
* @param bgXiSpeak
* @throws JeecgBootException
*/
void updateBgXiSpeak(BgXiSpeak bgXiSpeak) throws JeecgBootException;
/**
* 删除节点
*
* @param id
* @throws JeecgBootException
*/
void deleteBgXiSpeak(String id) throws JeecgBootException;
/**
* 树节点有子节点状态值
*/
public static final String HASCHILD = "1";
/**
* 查询所有数据,无分页
*
* @param queryWrapper
* @return List<BgXiSpeak>
*/
/**
* 树节点无子节点状态值
*/
public static final String NOCHILD = "0";
/**
* 新增节点
*
* @param bgXiSpeak
*/
void addBgXiSpeak(BgXiSpeak bgXiSpeak);
/**
* 修改节点
*
* @param bgXiSpeak
* @throws JeecgBootException
*/
void updateBgXiSpeak(BgXiSpeak bgXiSpeak) throws JeecgBootException;
/**
* 删除节点
*
* @param id
* @throws JeecgBootException
*/
void deleteBgXiSpeak(String id) throws JeecgBootException;
/**
* 查询所有数据,无分页
*
* @param queryWrapper
* @return List<BgXiSpeak>
*/
List<BgXiSpeak> queryTreeListNoPage(QueryWrapper<BgXiSpeak> queryWrapper);
/**
* 【vue3专用】根据父级编码加载分类字典的数据
*
* @param parentCode
* @return
*/
List<SelectTreeModel> queryListByCode(String parentCode);
/**
* 【vue3专用】根据父级编码加载分类字典的数据
*
* @param parentCode
* @return
*/
List<SelectTreeModel> queryListByCode(String parentCode);
/**
* 【vue3专用】根据pid查询子节点集合
*
* @param pid
* @return
*/
List<SelectTreeModel> queryListByPid(String pid);
/**
* 【vue3专用】根据pid查询子节点集合
*
* @param pid
* @return
*/
List<SelectTreeModel> queryListByPid(String pid);
BgXiSpeak getByIdForUpdate(String id);
BgXiSpeak getByIdForUpdate(String id);
boolean withDrawXiSpeak(String id);
}
@@ -1,18 +1,26 @@
package org.jeecg.modules.bg.xispeak.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.jeecg.common.exception.JeecgBootException;
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.mapper.BgXiSpeakMapper;
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
import org.jeecg.modules.tasktask.entity.TaskTask;
import org.jeecg.modules.tasktask.service.impl.TaskTaskServiceImpl;
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.stream.Collectors;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -23,8 +31,14 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
* @Version: V1.0
*/
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class BgXiSpeakServiceImpl extends ServiceImpl<BgXiSpeakMapper, BgXiSpeak> implements IBgXiSpeakService {
private final TaskTaskServiceImpl taskTaskServiceImpl;
private final RuntimeService runtimeService;
@Override
public void addBgXiSpeak(BgXiSpeak bgXiSpeak) {
//新增时设置hasChild为0
@@ -222,4 +236,48 @@ public class BgXiSpeakServiceImpl extends ServiceImpl<BgXiSpeakMapper, BgXiSpeak
.eq(BgXiSpeak::getId, id)
.last("for update"));
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean withDrawXiSpeak(String id) {
// 1. 【查询用】锁住并查询业务数据,带 for update
LambdaQueryWrapper<TaskTask> queryWrapper = new LambdaQueryWrapper<TaskTask>()
.eq(TaskTask::getBusinessId, id)
.last("for update"); // 只有查询才能加这个
List<TaskTask> taskTaskList = taskTaskServiceImpl.list(queryWrapper);
if (taskTaskList == null || taskTaskList.isEmpty()) {
log.warn("XiSpeak表单删除流程时 {} 未找到关联的tasktask表单数据", id);
return false;
}
// 2. 提取并去重流程实例 ID
List<String> taskTaskProcIdList = taskTaskList.stream()
.map(TaskTask::getProcessInstId)
.filter(org.apache.commons.lang3.StringUtils::isNotBlank)
.distinct()
.toList();
// 3. 循环处理流程引擎中的数据
for (String procId : taskTaskProcIdList) {
long count = runtimeService.createProcessInstanceQuery()
.processInstanceId(procId)
.count();
if (count > 0) {
String delReason = "删除xispeak表单关联的tasktask表单中流程id为" + procId + "的流程";
runtimeService.deleteProcessInstance(procId, delReason);
log.info("成功中止运行中的流程实例: {}", procId);
}
}
// 4. 【核心修改:删除用】重新创建一个干净的 Wrapper,绝不能带 for update
LambdaQueryWrapper<TaskTask> deleteWrapper = new LambdaQueryWrapper<TaskTask>()
.eq(TaskTask::getBusinessId, id); // 不要加 .last("for update")
taskTaskServiceImpl.remove(deleteWrapper); // 使用干净的 Wrapper 执行删除
return true;
}
}