diff --git a/jeecg-boot-module/jeecg-module-flow/pom.xml b/jeecg-boot-module/jeecg-module-flow/pom.xml new file mode 100644 index 0000000..608b87b --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + jeecg-boot-module + org.jeecgframework.boot + ${jeecgProjectVersion} + + + jeecg-module-flow + + + 21 + 21 + UTF-8 + + + + + org.jeecgframework.boot + jeecg-boot-base-core + + + org.jeecgframework.boot + jeecg-system-local-api + + + org.jeecgframework.boot + jeecg-boot-module-bpm-flowable + 3.8.0 + compile + + + org.jeecgframework.boot + jeecg-system-biz + + + + \ No newline at end of file diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/Main.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/Main.java new file mode 100644 index 0000000..28f7a57 --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/Main.java @@ -0,0 +1,17 @@ +package org.jeecg; + +//TIP 要运行代码,请按 或 +// 点击装订区域中的 图标。 +public class Main { + public static void main(String[] args) { + //TIP 当文本光标位于高亮显示的文本处时按 + // 查看 IntelliJ IDEA 建议如何修正。 + System.out.printf("Hello and welcome!"); + + for (int i = 1; i <= 5; i++) { + //TIP 按 开始调试代码。我们已经设置了一个 断点 + // 但您始终可以通过按 添加更多断点。 + System.out.println("i = " + i); + } + } +} \ No newline at end of file diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java new file mode 100644 index 0000000..d9369ef --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java @@ -0,0 +1,33 @@ +package org.jeecg.xispeak; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "flow-biz") +public class XiSpeakConfig { + /** + * 对应 yml 中的 xi-speak 节点 + * Spring 会自动将中划线命名映射为驼峰命名 + */ + private XiSpeakProperties xiSpeak; + + + @Data + public static class XiSpeakProperties { + /** 对应 bg-dept-id */ + private String bgDeptId; + /** 对应 ld-role-id */ + private String ldRoleId; + /** 对应 need-sdw-approve-code */ + private String needSdwApproveCode; + /** 对应 json-data-key */ + private String jsonDataKey; + /** 对应 impl-dept-key */ + private String implDeptKey; + /** 对应impl-dept-collection-used*/ + private String implDeptCollectionUsedKey; + } +} diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java new file mode 100644 index 0000000..dd147da --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java @@ -0,0 +1,129 @@ +package org.jeecg.xispeak; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.util.StringUtils; +import org.flowable.engine.RuntimeService; +import org.jeecg.common.system.api.ISysBaseAPI; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Component("xiSpeakFlow") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class XiSpeakFlow { + + private final XiSpeakConfig xiSpeakConfig; + private final ISysBaseAPI iSysBaseAPI; + private final RuntimeService runtimeService; + + public List getBgDeptLdUserIdList() { + // 1. 安全获取配置,防止 NPE + XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak(); + if (props == null || !StringUtils.hasText(props.getBgDeptId())) { + log.error("流程配置缺失: [flow-biz.xi-speak.bg-dept-id] 未在 YAML 中定义"); + return Collections.emptyList(); + } + + // 2. 调用接口获取数据 + log.info("正在查询部门: {} 下的角色: {} 的用户列表", props.getBgDeptId(), props.getLdRoleId()); + List userList = iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi( + props.getBgDeptId(), + props.getLdRoleId() + ); + log.info("查询到的用户为: {}", userList); + return userList; + } + + public Integer getNeedSdwApproval(Object jsonData) { + XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak(); + if (jsonData == null || org.apache.commons.lang.StringUtils.isBlank(props.getNeedSdwApproveCode())) { + return 0; + } + String codeName = props.getNeedSdwApproveCode(); + if (org.apache.commons.lang.StringUtils.isBlank(codeName)) return 0; + try { + JSONObject data; + if (jsonData instanceof JSONObject) { + data = (JSONObject) jsonData; + } else if (jsonData instanceof String) { + if (org.apache.commons.lang.StringUtils.isBlank((String) jsonData)) { + return 0; + } + data = JSONObject.parseObject((String) jsonData); + } else { + data = JSONObject.parseObject(JSONObject.toJSONString(jsonData)); + } + log.info("needSdwApproval结果为{}", data.getInteger(codeName)); + return data == null ? 0 : data.getInteger(codeName); + } catch (Exception e) { + log.warn("getJsondata parse failed, codeName={}, jsonData={}", codeName, jsonData, e); + return 0; + } + } + + public List getImplDeptLdsList(String deptId) { + return iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(deptId, xiSpeakConfig.getXiSpeak().getLdRoleId()); + } + + public int getListSize(String jsonData){ + if (org.apache.commons.lang3.StringUtils.isEmpty(jsonData)) { + return 0; + } + return Math.toIntExact(Arrays.stream(jsonData.split(",")) + .map(String::trim) + .filter(org.apache.commons.lang3.StringUtils::isNotEmpty) + .count()); + } + +// List getImplDeptWorker(String JG_LOCAL_PROCESS_ID,String deptId){ +// runtimeService.get +// } + + public Integer getImplDeptNums(String jsonData) { + String codeName = xiSpeakConfig.getXiSpeak().getImplDeptKey(); + if (jsonData == null || org.apache.commons.lang.StringUtils.isEmpty(codeName)) { + return 0; + } + + // 1. 统一转成 JSONObject + JSONObject json; + json = JSON.parseObject((String) jsonData); + + if (json == null || !json.containsKey(codeName)) { + return 0; + } + + // 2. 获取原始对象进行兼容性处理 + Object value = json.get(codeName); + if (value == null) { + return 0; + } + + List resultList = new ArrayList<>(); + + if (value instanceof Collection) { + // 情况 A: 本身就是集合/JSON数组 + resultList.addAll(json.getJSONArray(codeName).toJavaList(String.class)); + } else if (value instanceof String) { + // 情况 B: 是逗号分隔的字符串 "ID1,ID2,ID3" + String str = (String) value; + if (org.apache.commons.lang.StringUtils.isNotEmpty(str)) { + // 使用 split 拆分,并过滤掉空格和空字符串 + String[] split = str.split(","); + for (String s : split) { + if (org.apache.commons.lang.StringUtils.isNotEmpty(s.trim())) { + resultList.add(s.trim()); + } + } + } + } + + return resultList.size(); + } +} diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java new file mode 100644 index 0000000..9d13a44 --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java @@ -0,0 +1,118 @@ +package org.jeecg.modules.extbpm.listener.execution; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression; +import lombok.RequiredArgsConstructor; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals; +import org.jeecg.xispeak.XiSpeakConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Component("AfterSDWApproveHqListener") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class AfterSDWApproveHqListener implements ExecutionListener { + + private static final long serialVersionUID = 1L; + + private final FlowNodeExpression flowNodeExpression; + @Autowired + private RuntimeService runtimeService; + + private final XiSpeakConfig xiSpeakConfig; + + @Override + public void notify(DelegateExecution execution) { + + XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak(); + //RuntimeService runtimeService = SpringContextUtils.getBean(RuntimeService.class); + String mainProcessId = (String)execution.getProcessInstanceId(); + String url = (String)execution.getVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL); + + // 打印主流程里所有的变量名,看看有没有 json_data + Map variables = runtimeService.getVariables(execution.getRootProcessInstanceId()); + log.info("主流程中的所有变量名: " + variables.keySet()); + +// 打印当前执行流的所有变量名 + log.info("当前执行流的所有变量名: " + execution.getVariables().keySet()); + + String bizTitle = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_BIZ_TITLE); + + if(org.apache.commons.lang.StringUtil.isEmpty(url)) { + url = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL); + String mobileUrl = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE); + execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL, url); + execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE, mobileUrl); + } + + // 1. 获取主流程中的 json_data 对象(可能是 String 或 JSONObject) + Object jsonDataObj = (String)runtimeService.getVariable(mainProcessId,props.getJsonDataKey()); + + if (oConvertUtils.isNotEmpty(jsonDataObj)) { + String json_data = jsonDataObj.toString(); + try { + // 2. 调用表达式解析工具获取特定字段的字符串内容 + String jsonStr = flowNodeExpression.getJsondatastring(json_data, props.getImplDeptKey()); + + // 3. 只有当字段存在且内容不为空时,才进行解析 + if (oConvertUtils.isNotEmpty(jsonStr)) { + List deptIds = Arrays.stream(jsonStr.split(",")) + .map(String::trim) // 去掉可能存在的空格 + .filter(s -> !s.isEmpty()) // 过滤掉空字符串 + .collect(Collectors.toList()); + + if (deptIds != null && !deptIds.isEmpty()) { + // 4. 将提取出的 List 存入子流程变量(供多实例 Collection 使用) + execution.setVariable( props.getImplDeptKey(), deptIds); + log.info("子流程变量 deptIdList 注入成功: " + deptIds); + } + } + } catch (Exception e) { + log.error("解析 JSON 字段 pending_depts_id 失败: ", e); + } + } + + //获取主表数据id + String businessKey = (String)runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DATA_ID); + //获取主表的设计表单数据ID + String BPM_DES_DATA_ID = oConvertUtils.getString(runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DES_DATA_ID)); + + //获取主表表名 + String tableName = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_KEY); + execution.setVariable(WorkFlowGlobals.BPM_FORM_KEY, tableName); + + //--update--begin------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题--------- + //log.info("----------传入子流程的数据ID--------------: "+execution.getVariable(WorkFlowGlobals.DATA_ID)); + if(oConvertUtils.isNotEmpty(execution.getVariable(WorkFlowGlobals.DATA_ID))){ + execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID)); + //如果是设计器表单,则还需要设置设计表单数据ID + if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){ + execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID)); + } + }else{ + //未传入id值,则获取主表数据id给子流程【online表单需要】 + execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, businessKey); + //如果是设计器表单,则还需要设置设计表单数据ID + if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){ + execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, BPM_DES_DATA_ID); + } + } + //--update--end------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题--------- + + //子流程实例set业务号和主流程保持一致 + runtimeService.updateBusinessKey(execution.getProcessInstanceId(), businessKey); + } + + + + +} diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml b/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml new file mode 100644 index 0000000..0feb5e8 --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml @@ -0,0 +1,8 @@ +flow-biz: + xi-speak: + bg-dept-id: "2044677604785229826" + ld-role-id: "2044680793306591234" + need-sdw-approve-code: "needSdwApproval" + json-data-key: "json_data" + impl-dept-key: "implDept" + impl-dept-collection-used-key: "impl_dept_id" diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/listener/execution/EmbeddedSubProcessHqStartListener.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/listener/execution/EmbeddedSubProcessHqStartListener.java new file mode 100644 index 0000000..8027061 --- /dev/null +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/listener/execution/EmbeddedSubProcessHqStartListener.java @@ -0,0 +1,117 @@ +package org.jeecg.modules.extbpm.listener.execution; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtil; +import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression; +import com.alibaba.fastjson.JSON; +import lombok.RequiredArgsConstructor; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.jeecg.common.util.SpringContextUtils; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Component("embeddedSubProcessHqStartListener") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class EmbeddedSubProcessHqStartListener implements ExecutionListener { + + private static final long serialVersionUID = 1L; + + private final FlowNodeExpression flowNodeExpression; + @Autowired + private RuntimeService runtimeService; + + @Override + public void notify(DelegateExecution execution) { + + //RuntimeService runtimeService = SpringContextUtils.getBean(RuntimeService.class); + String mainProcessId = (String)execution.getProcessInstanceId(); + String url = (String)execution.getVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL); + + // 打印主流程里所有的变量名,看看有没有 json_data + Map variables = runtimeService.getVariables(execution.getRootProcessInstanceId()); + log.info("主流程中的所有变量名: " + variables.keySet()); + +// 打印当前执行流的所有变量名 + log.info("当前执行流的所有变量名: " + execution.getVariables().keySet()); + + String bizTitle = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_BIZ_TITLE); + + if(org.apache.commons.lang.StringUtil.isEmpty(url)) { + url = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL); + String mobileUrl = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE); + execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL, url); + execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE, mobileUrl); + } + + // 1. 获取主流程中的 json_data 对象(可能是 String 或 JSONObject) + Object jsonDataObj = (String)runtimeService.getVariable(mainProcessId,"json_data"); + + if (oConvertUtils.isNotEmpty(jsonDataObj)) { + String json_data = jsonDataObj.toString(); + try { + // 2. 调用表达式解析工具获取特定字段的字符串内容 + String jsonStr = flowNodeExpression.getJsondatastring(json_data, "implDept"); + + // 3. 只有当字段存在且内容不为空时,才进行解析 + if (oConvertUtils.isNotEmpty(jsonStr)) { + List deptIds = Arrays.stream(jsonStr.split(",")) + .map(String::trim) // 去掉可能存在的空格 + .filter(s -> !s.isEmpty()) // 过滤掉空字符串 + .collect(Collectors.toList()); + + if (deptIds != null && !deptIds.isEmpty()) { + // 4. 将提取出的 List 存入子流程变量(供多实例 Collection 使用) + execution.setVariable("pending_depts_id", deptIds); + log.info("子流程变量 deptIdList 注入成功: " + deptIds); + } + } + } catch (Exception e) { + log.error("解析 JSON 字段 pending_depts_id 失败: ", e); + } + } + + //获取主表数据id + String businessKey = (String)runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DATA_ID); + //获取主表的设计表单数据ID + String BPM_DES_DATA_ID = oConvertUtils.getString(runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DES_DATA_ID)); + + //获取主表表名 + String tableName = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_KEY); + execution.setVariable(WorkFlowGlobals.BPM_FORM_KEY, tableName); + + //--update--begin------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题--------- + //log.info("----------传入子流程的数据ID--------------: "+execution.getVariable(WorkFlowGlobals.DATA_ID)); + if(oConvertUtils.isNotEmpty(execution.getVariable(WorkFlowGlobals.DATA_ID))){ + execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID)); + //如果是设计器表单,则还需要设置设计表单数据ID + if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){ + execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID)); + } + }else{ + //未传入id值,则获取主表数据id给子流程【online表单需要】 + execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, businessKey); + //如果是设计器表单,则还需要设置设计表单数据ID + if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){ + execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, BPM_DES_DATA_ID); + } + } + //--update--end------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题--------- + + //子流程实例set业务号和主流程保持一致 + runtimeService.updateBusinessKey(execution.getProcessInstanceId(), businessKey); + } + + + + +} diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/listener/execution/SubProcessSelectUserListener.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/listener/execution/SubProcessSelectUserListener.java new file mode 100644 index 0000000..7a57642 --- /dev/null +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/listener/execution/SubProcessSelectUserListener.java @@ -0,0 +1,61 @@ +package org.jeecg.modules.extbpm.listener.execution; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals; +import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@Slf4j +@Component("subProcessSelectUserListener") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class SubProcessSelectUserListener implements ExecutionListener { + + private final FlowNodeExpression flowNodeExpression; + + @Autowired + private RuntimeService runtimeService; + + @Override + public void notify(DelegateExecution execution) { + + String mainProcessId = (String) execution.getProcessInstanceId(); + String url = (String)execution.getVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL); + + // 打印主流程里所有的变量名,看看有没有 json_data + Map variables = runtimeService.getVariables(execution.getRootProcessInstanceId()); + log.info("主流程中的所有变量名: " + variables.keySet()); + + // 打印当前执行流的所有变量名 + log.info("当前执行流的所有变量名: " + execution.getVariables().keySet()); + + // 1. 获取原生组件选中的处理人 (假设 Key 为 assigneeUserIdList) + Object selectedValue = execution.getVariable("assigneeUserIdList"); + + List list = new ArrayList<>(); + if (selectedValue instanceof String) { + // 如果是逗号分隔的字符串,拆分 + list = Arrays.asList(((String) selectedValue).split(",")); + } else if (selectedValue instanceof List) { + list = (List) selectedValue; + } + + // 2. 如果没选人,给个默认值防止报错,或者抛出业务异常 + if (list.isEmpty()) { + throw new RuntimeException("请选择下一步处理人!"); + } + + // 3. 关键:将这个 List 存入局部变量,供下一节点的 Multi-instance 读取 + // 使用 setVariableLocal 确保并行子流程互不干扰 + execution.setVariableLocal("internal_collection", list); + } +} diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/WorkFlowGlobals.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/WorkFlowGlobals.java index 5c01be9..ca0ec91 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/WorkFlowGlobals.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/WorkFlowGlobals.java @@ -201,4 +201,10 @@ public final class WorkFlowGlobals { * 流程信号启动类型:按钮触发 */ public static String START_BUTTON_EVENT = "buttonEvent"; + + /** + * 用于加载json_data字段的键名 + */ + public static String JSON_DATA = "json_data"; + public static String PENDING_DEPTS_ID = "pending_depts_id"; } diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java index 49a65ca..7f131af 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java @@ -1,6 +1,7 @@ package org.jeecg.modules.extbpm.process.common.expression; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -81,6 +82,144 @@ public class FlowNodeExpression { } } + /** + * 根据字段名称在json_data内查询对应list或set的长度 + * ${flowNodeExpression.getJsonDataSizeByCodeName(json_data,"pending_depts_id")} + * + * @param jsonData + * @param codeName + * @return + */ + public Integer getJsonDataSizeByCodeNameStr(Object jsonData, String codeName){ + if (jsonData == null || StringUtils.isEmpty(codeName)) { + return 0; + } + + // 1. 统一转成 JSONObject + JSONObject json; + if (jsonData instanceof String) { + json = JSON.parseObject((String) jsonData); + } else if (jsonData instanceof JSONObject) { + json = (JSONObject) jsonData; + } else { + return 0; + } + + if (json == null || !json.containsKey(codeName)) { + return 0; + } + + // 2. 获取原始对象进行兼容性处理 + Object value = json.get(codeName); + if (value == null) { + return 0; + } + + List resultList = new ArrayList<>(); + + if (value instanceof Collection) { + // 情况 A: 本身就是集合/JSON数组 + resultList.addAll(json.getJSONArray(codeName).toJavaList(String.class)); + } else if (value instanceof String) { + // 情况 B: 是逗号分隔的字符串 "ID1,ID2,ID3" + String str = (String) value; + if (StringUtils.isNotEmpty(str)) { + // 使用 split 拆分,并过滤掉空格和空字符串 + String[] split = str.split(","); + for (String s : split) { + if (StringUtils.isNotEmpty(s.trim())) { + resultList.add(s.trim()); + } + } + } + } + + return resultList.size(); + } + + /** + * 根据字段名称在json_data内查询对应list或set的长度 + * ${flowNodeExpression.getJsonDataSizeByCodeName(json_data,"pending_depts_id")} + * + * @param jsonData + * @param codeName + * @return + */ + public Integer getJsonDataSizeByCodeNameObj(Object jsonData, String codeName){ + if (jsonData == null || StringUtils.isEmpty(codeName)) { + return 0; + } + + // 1. 统一转成 JSONObject + JSONObject json; + if (jsonData instanceof String) { + json = JSON.parseObject((String) jsonData); + } else if (jsonData instanceof JSONObject) { + json = (JSONObject) jsonData; + } else { + return 0; + } + + if (json == null || !json.containsKey(codeName)) { + return 0; + } + + // 2. 获取原始对象进行兼容性处理 + Object value = json.get(codeName); + if (value == null) { + return 0; + } + + List resultList = new ArrayList<>(); + + if (value instanceof Collection) { + // 情况 A: 本身就是集合/JSON数组 + resultList.addAll(json.getJSONArray(codeName).toJavaList(String.class)); + } else if (value instanceof String) { + // 情况 B: 是逗号分隔的字符串 "ID1,ID2,ID3" + String str = (String) value; + if (StringUtils.isNotEmpty(str)) { + // 使用 split 拆分,并过滤掉空格和空字符串 + String[] split = str.split(","); + for (String s : split) { + if (StringUtils.isNotEmpty(s.trim())) { + resultList.add(s.trim()); + } + } + } + } + + return resultList.size(); + } + + /** + * 优雅地从 JSON 对象中提取 List + */ + private List getListFromJsonByCodeName(JSONObject json, String key) { + if (json == null || !json.containsKey(key)) { + return Collections.emptyList(); + } + Object value = json.get(key); + if (value == null) { + return Collections.emptyList(); + } + + // 如果本身就是 JSONArray(Collection 子类) + if (value instanceof Collection) { + return ((JSONArray) value).toJavaList(String.class); + } + + // 如果是逗号分隔的字符串 + if (value instanceof String && StringUtils.isNotBlank((String) value)) { + return Arrays.stream(((String) value).split(",")) + .map(String::trim) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toList()); + } + + return Collections.emptyList(); + } + /** * 根据字段名称取json_data查询对应业务表单的数据 * ${flowNodeExpression.getJsondatastring(jsonData,'supDeptleaderid')} @@ -90,7 +229,19 @@ public class FlowNodeExpression { * @return roleId */ public List getUsersListByJson(Object jsonData, String deptKeyName, String roleId) { - return ISysBaseAPI.getUsersListByJsonLocalAPI(jsonData,deptKeyName,roleId); + return ISysBaseAPI.getUsersListByJsonLocalAPI(jsonData, deptKeyName, roleId); + } + + /** + * 根据部门id角色id获取用户列表 + * ${flowNodeExpression.getUsersListByDeptIdAndRoleId(deptId,roleId)} + * + * @param deptId + * @param roleId + * @return roleId + */ + public List getUsersListByDeptIdAndRoleId(String deptId, String roleId) { + return sysbase.getUsersListByDeptIdAndRoleIdLocalApi(deptId, roleId); } /** diff --git a/jeecg-module-supervision/pom.xml b/jeecg-module-supervision/pom.xml index 75ddea8..d8a8670 100644 --- a/jeecg-module-supervision/pom.xml +++ b/jeecg-module-supervision/pom.xml @@ -21,6 +21,10 @@ org.jeecgframework.boot jeecg-boot-module-bpm-flowable + + org.jeecgframework.boot + jeecg-system-local-api + diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/Main.java b/jeecg-module-supervision/src/main/java/org/jeecg/Main.java new file mode 100644 index 0000000..28f7a57 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/Main.java @@ -0,0 +1,17 @@ +package org.jeecg; + +//TIP 要运行代码,请按 或 +// 点击装订区域中的 图标。 +public class Main { + public static void main(String[] args) { + //TIP 当文本光标位于高亮显示的文本处时按 + // 查看 IntelliJ IDEA 建议如何修正。 + System.out.printf("Hello and welcome!"); + + for (int i = 1; i <= 5; i++) { + //TIP 按 开始调试代码。我们已经设置了一个 断点 + // 但您始终可以通过按 添加更多断点。 + System.out.println("i = " + i); + } + } +} \ No newline at end of file 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 0ea5505..522c319 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 @@ -21,6 +21,7 @@ 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.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/feedback/BgXiSpeakFeedbackController.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/feedback/BgXiSpeakFeedbackController.java new file mode 100644 index 0000000..0492c00 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/controller/feedback/BgXiSpeakFeedbackController.java @@ -0,0 +1,168 @@ +package org.jeecg.modules.bg.xispeak.controller.feedback; + +import java.util.Arrays; +import java.util.List; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; +import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService; + +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.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + +/** + * @Description: 习总书记重要讲话反馈表 + * @Author: jeecg-boot + * @Date: 2026-04-28 + * @Version: V1.0 + */ +@Tag(name="习总书记重要讲话反馈表") +@RestController +@RequestMapping("/bg/xispeak/bgXiSpeak") +@Slf4j +public class BgXiSpeakFeedbackController extends JeecgController { + @Autowired + private IBgXiSpeakFeedbackService bgXiSpeakFeedbackService; + + /** + * 分页列表查询 + * + * @param bgXiSpeakFeedback + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @Operation(summary="习总书记重要讲话反馈表-分页列表查询") + @GetMapping(value = "/listBgXiSpeakFeedbackByMainId") + public Result> queryPageList(BgXiSpeakFeedback bgXiSpeakFeedback, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(bgXiSpeakFeedback, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = bgXiSpeakFeedbackService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param bgXiSpeakFeedback + * @return + */ + @AutoLog(value = "习总书记重要讲话反馈表-添加") + @Operation(summary="习总书记重要讲话反馈表-添加") + @PostMapping(value = "/addBgXiSpeakFeedback") + public Result add(@RequestBody BgXiSpeakFeedback bgXiSpeakFeedback) { + bgXiSpeakFeedbackService.save(bgXiSpeakFeedback); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param bgXiSpeakFeedback + * @return + */ + @AutoLog(value = "习总书记重要讲话反馈表-编辑") + @Operation(summary="习总书记重要讲话反馈表-编辑") + @PostMapping(value = "/editBgXiSpeakFeedback") + public Result edit(@RequestBody BgXiSpeakFeedback bgXiSpeakFeedback) { + bgXiSpeakFeedbackService.updateById(bgXiSpeakFeedback); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "习总书记重要讲话反馈表-通过id删除") + @Operation(summary="习总书记重要讲话反馈表-通过id删除") + @DeleteMapping(value = "/deleteBgXiSpeakFeedback") + public Result delete(@RequestParam(name="id",required=true) String id) { + bgXiSpeakFeedbackService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "习总书记重要讲话反馈表-批量删除") + @Operation(summary="习总书记重要讲话反馈表-批量删除") + @DeleteMapping(value = "/deleteBatchBgXiSpeakFeedback") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.bgXiSpeakFeedbackService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @Operation(summary="习总书记重要讲话反馈表-通过id查询") + @GetMapping(value = "/queryBgXiSpeakFeedbackById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + BgXiSpeakFeedback bgXiSpeakFeedback = bgXiSpeakFeedbackService.getById(id); + if(bgXiSpeakFeedback==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(bgXiSpeakFeedback); + } + + /** + * 导出excel + * + * @param request + * @param bgXiSpeakFeedback + */ + @RequestMapping(value = "/exportBgXiSpeakFeedback") + public ModelAndView exportXls(HttpServletRequest request, BgXiSpeakFeedback bgXiSpeakFeedback) { + return super.exportXls(request, bgXiSpeakFeedback, BgXiSpeakFeedback.class, "习总书记重要讲话反馈表"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importBgXiSpeakFeedback", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response, @PathVariable("mainId") String mainId) { + return super.importExcel(request, response, BgXiSpeakFeedback.class); + } + +} \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java index 9a2e4aa..511c5b8 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java @@ -157,4 +157,12 @@ public class BgXiSpeak implements Serializable { @Excel(name = "督办次数", width = 15) @Schema(description = "督办次数") private java.lang.Integer supervisionCount; + /**dw领导userId字段*/ + @Excel(name = "领导userId字段", width = 15) + @Schema(description = "领导userId字段") + private java.lang.String sdwLeaderList; + /**dw领导userId字段*/ + @Excel(name = "是否需要sdw审批", width = 15) + @Schema(description = "是否需要sdw审批") + private java.lang.Integer needSdwApproval; } diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java new file mode 100644 index 0000000..2fe8368 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java @@ -0,0 +1,84 @@ +package org.jeecg.modules.bg.xispeak.entity; + +import java.io.Serializable; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: 习总书记重要讲话反馈表 + * @Author: jeecg-boot + * @Date: 2026-04-28 + * @Version: V1.0 + */ +@Data +@TableName("bg_xi_speak_feedback") +@Schema(description="习总书记重要讲话反馈表") +public class BgXiSpeakFeedback implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; + /**所属部门*/ + @Schema(description = "所属部门") + private java.lang.String sysOrgCode; + /**反馈部门id*/ + @Excel(name = "反馈部门id", width = 15) + @Schema(description = "反馈部门id") + private java.lang.String responDeptid; + /**反馈部门名称*/ + @Excel(name = "反馈部门名称", width = 15) + @Schema(description = "反馈部门名称") + private java.lang.String responDeptname; + /**反馈人id*/ + @Excel(name = "反馈人id", width = 15) + @Schema(description = "反馈人id") + private java.lang.String responPersonid; + /**反馈人姓名*/ + @Excel(name = "反馈人姓名", width = 15) + @Schema(description = "反馈人姓名") + private java.lang.String responPersonname; + /**反馈时间*/ + @Excel(name = "反馈时间", width = 15, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "反馈时间") + private java.util.Date responTime; + /**落实情况*/ + @Excel(name = "落实情况", width = 15) + @Schema(description = "落实情况") + private java.lang.String implStatus; + /**完成状态*/ + @Excel(name = "完成状态", width = 15) + @Schema(description = "完成状态") + private java.lang.String completionStatus; + /**外键*/ + @Excel(name = "外键", width = 15) + @Schema(description = "外键") + private java.lang.String mainId; +} \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/mapper/BgXiSpeakFeedbackMapper.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/mapper/BgXiSpeakFeedbackMapper.java new file mode 100644 index 0000000..93d2b74 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/mapper/BgXiSpeakFeedbackMapper.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.bg.xispeak.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; + +/** + * @Description: 习总书记重要讲话反馈表 + * @Author: jeecg-boot + * @Date: 2026-04-28 + * @Version: V1.0 + */ +@Mapper +public interface BgXiSpeakFeedbackMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java new file mode 100644 index 0000000..3861ba1 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.bg.xispeak.service; + +import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 习总书记重要讲话反馈表 + * @Author: jeecg-boot + * @Date: 2026-04-28 + * @Version: V1.0 + */ +public interface IBgXiSpeakFeedbackService extends IService { + +} \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java new file mode 100644 index 0000000..d68a1e7 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.bg.xispeak.service.impl; + +import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; +import org.jeecg.modules.bg.xispeak.mapper.BgXiSpeakFeedbackMapper; +import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 习总书记重要讲话反馈表 + * @Author: jeecg-boot + * @Date: 2026-04-28 + * @Version: V1.0 + */ +@Service +public class BgXiSpeakFeedbackServiceImpl extends ServiceImpl implements IBgXiSpeakFeedbackService { + +} \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/bgpartymatter/service/impl/BgPartymatterServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/bgpartymatter/service/impl/BgPartymatterServiceImpl.java index 262ed29..43c2c68 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/bgpartymatter/service/impl/BgPartymatterServiceImpl.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/bgpartymatter/service/impl/BgPartymatterServiceImpl.java @@ -7,7 +7,6 @@ import org.jeecg.modules.demo.bgpartymatter.entity.BgPartymatterFeedback; import org.jeecg.modules.demo.bgpartymatter.mapper.BgPartymatterFeedbackMapper; import org.jeecg.modules.demo.bgpartymatter.mapper.BgPartymatterMapper; import org.jeecg.modules.demo.bgpartymatter.service.IBgPartymatterService; -import org.jeecg.modules.test.mapper.TestSonTableMapper; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/controller/TaskListController.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/controller/TaskListController.java new file mode 100644 index 0000000..09af75d --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/controller/TaskListController.java @@ -0,0 +1,546 @@ +package org.jeecg.modules.demo.tasklist.controller; + +import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.HashMap; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import org.jeecg.modules.demo.tasklist.entity.TaskList; +import org.jeecg.modules.demo.tasklist.vo.TaskListPage; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskListReq; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskListGroupReq; +import org.jeecg.modules.demo.tasklist.vo.MoveTaskListReq; +import org.jeecg.modules.demo.tasklist.vo.AddCollaboratorReq; +import org.jeecg.modules.demo.tasklist.vo.CollaboratorVO; +import org.jeecg.modules.demo.tasklist.service.ITaskListService; +import org.jeecg.modules.demo.tasklist.service.ITaskListDetialService; +import org.jeecg.modules.demo.tasklist.service.ITaskListPermissionService; +import org.jeecg.modules.demo.tasklist.service.ITaskListFavoriteService; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +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 com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + + + /** + * @Description: 任务清单表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Tag(name="任务清单表") +@RestController +@RequestMapping("/tasklist/taskList") +@Slf4j +public class TaskListController { + @Autowired + private ITaskListService taskListService; + @Autowired + private ITaskListDetialService taskListDetialService; + @Autowired + private ITaskListPermissionService taskListPermissionService; + @Autowired + private ITaskListFavoriteService taskListFavoriteService; + + /** + * 分页列表查询 + * + * @param taskList + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "任务清单表-分页列表查询") + @Operation(summary="任务清单表-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(TaskList taskList, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(taskList, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = taskListService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param taskListPage + * @return + */ + @AutoLog(value = "任务清单表-添加") + @Operation(summary="任务清单表-添加") + @RequiresPermissions("tasklist:task_list:add") + @PostMapping(value = "/add") + public Result add(@RequestBody TaskListPage taskListPage) { + TaskList taskList = new TaskList(); + BeanUtils.copyProperties(taskListPage, taskList); + taskListService.saveMain(taskList, taskListPage.getTaskListDetialList(),taskListPage.getTaskListPermissionList(),taskListPage.getTaskListFavoriteList()); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param taskListPage + * @return + */ + @AutoLog(value = "任务清单表-编辑") + @Operation(summary="任务清单表-编辑") + @RequiresPermissions("tasklist:task_list:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody TaskListPage taskListPage) { + TaskList taskList = new TaskList(); + BeanUtils.copyProperties(taskListPage, taskList); + TaskList taskListEntity = taskListService.getById(taskList.getId()); + if(taskListEntity==null) { + return Result.error("未找到对应数据"); + } + taskListService.updateMain(taskList, taskListPage.getTaskListDetialList(),taskListPage.getTaskListPermissionList(),taskListPage.getTaskListFavoriteList()); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "任务清单表-通过id删除") + @Operation(summary="任务清单表-通过id删除") + @RequiresPermissions("tasklist:task_list:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + taskListService.delMain(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "任务清单表-批量删除") + @Operation(summary="任务清单表-批量删除") + @RequiresPermissions("tasklist:task_list:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.taskListService.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "任务清单表-通过id查询") + @Operation(summary="任务清单表-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + TaskList taskList = taskListService.getById(id); + if(taskList==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(taskList); + + } + + @AutoLog(value = "任务清单表-新建任务清单") + @Operation(summary = "新建任务清单") + @PostMapping(value = "/addTaskList") + public Result addTaskList(@RequestBody CreateTaskListReq req) { + try { + String id = taskListService.createTaskList(req); + return Result.OK("创建成功!", id); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-新建任务清单分组") + @Operation(summary = "新建任务清单分组") + @PostMapping(value = "/addTaskListGroup") + public Result addTaskListGroup(@RequestBody CreateTaskListGroupReq req) { + try { + String id = taskListService.createTaskListGroup(req); + return Result.OK("创建成功!", id); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-拖拽移动任务清单") + @Operation(summary = "拖拽移动任务清单") + @PostMapping(value = "/moveTaskList") + public Result moveTaskList(@RequestBody MoveTaskListReq req) { + try { + taskListService.moveTaskList(req); + return Result.OK("移动成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-拖拽移动分组") + @Operation(summary = "拖拽移动分组") + @PostMapping(value = "/moveGroup") + public Result moveGroup(@RequestBody Map params) { + try { + String groupId = (String) params.get("groupId"); + Integer sortOrder = params.get("sortOrder") != null ? ((Number) params.get("sortOrder")).intValue() : null; + taskListService.moveGroup(groupId, sortOrder); + return Result.OK("移动成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-获取当前用户收藏列表") + @Operation(summary = "获取当前用户收藏列表") + @GetMapping(value = "/myFavorites") + public Result> myFavorites() { + List list = taskListService.getMyFavorites(); + return Result.OK(list); + } + + @AutoLog(value = "任务清单表-删除任务清单") + @Operation(summary = "删除任务清单(所有者操作)") + @PostMapping(value = "/deleteTaskList") + public Result deleteTaskList(@RequestBody Map params) { + try { + taskListService.deleteTaskList(params.get("id")); + return Result.OK("删除成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-移除收藏") + @Operation(summary = "从收藏栏移除") + @PostMapping(value = "/removeFavorite") + public Result removeFavorite(@RequestBody Map params) { + try { + taskListService.removeFavorite(params.get("favoriteId")); + return Result.OK("移除成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-添加到收藏") + @Operation(summary = "添加清单到收藏栏") + @PostMapping(value = "/addToFavorites") + public Result addToFavorites(@RequestBody Map params) { + try { + taskListService.addToFavorites(params.get("taskListId"), params.get("pid")); + return Result.OK("添加成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-移除分组") + @Operation(summary = "从收藏栏移除分组及子项") + @PostMapping(value = "/removeFavoriteGroup") + public Result removeFavoriteGroup(@RequestBody Map params) { + try { + taskListService.removeFavoriteGroup(params.get("groupId")); + return Result.OK("移除成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-重命名分组") + @Operation(summary = "重命名任务清单分组") + @PostMapping(value = "/renameGroup") + public Result renameGroup(@RequestBody Map params) { + try { + taskListService.renameGroup(params.get("groupId"), params.get("newName")); + return Result.OK("重命名成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-重命名清单") + @Operation(summary = "重命名任务清单") + @PostMapping(value = "/renameTaskList") + public Result renameTaskList(@RequestBody Map params) { + try { + taskListService.renameTaskList(params.get("taskListId"), params.get("newName")); + return Result.OK("重命名成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-获取我所有的清单") + @Operation(summary = "获取我所有的清单") + @GetMapping(value = "/myOwnLists") + public Result> myOwnLists() { + List list = taskListService.getMyOwnLists(); + return Result.OK(list); + } + + @AutoLog(value = "任务清单表-获取所有清单") + @Operation(summary = "获取所有清单") + @GetMapping(value = "/allLists") + public Result> getAllLists() { + return Result.OK(taskListService.getAllLists()); + } + + @AutoLog(value = "任务清单表-获取我协作的清单") + @Operation(summary = "获取我协作的清单") + @GetMapping(value = "/myCollabLists") + public Result> myCollabLists() { + List list = taskListService.getMyCollabLists(); + return Result.OK(list); + } + + @AutoLog(value = "任务清单表-获取协作人列表") + @Operation(summary = "获取清单协作人列表") + @GetMapping(value = "/getCollaborators") + public Result> getCollaborators(@RequestParam(name="taskListId", required=true) String taskListId) { + List list = taskListService.getCollaborators(taskListId); + return Result.OK(list); + } + + @AutoLog(value = "任务清单表-添加协作人") + @Operation(summary = "添加协作人") + @PostMapping(value = "/addCollaborator") + public Result addCollaborator(@RequestBody AddCollaboratorReq req) { + try { + taskListService.addCollaborator(req); + return Result.OK("添加成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-移除协作人") + @Operation(summary = "移除协作人") + @PostMapping(value = "/removeCollaborator") + public Result removeCollaborator(@RequestBody Map params) { + try { + taskListService.removeCollaborator(params.get("permissionId")); + return Result.OK("移除成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-修改协作人权限") + @Operation(summary = "修改协作人权限") + @PostMapping(value = "/updateCollaboratorPermission") + public Result updateCollaboratorPermission(@RequestBody Map params) { + try { + taskListService.updateCollaboratorPermission(params.get("permissionId"), params.get("permission")); + return Result.OK("修改成功!"); + } catch (RuntimeException e) { + return Result.error(e.getMessage()); + } + } + + @AutoLog(value = "任务清单表-获取当前用户对清单的权限") + @Operation(summary = "获取当前用户对清单的权限") + @GetMapping(value = "/getMyPermission") + public Result getMyPermission(@RequestParam(name="taskListId", required=true) String taskListId) { + String permission = taskListService.getMyPermission(taskListId); + return Result.OK("查询成功", permission); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "任务清单详情表通过主表ID查询") + @Operation(summary="任务清单详情表主表ID查询") + @GetMapping(value = "/queryTaskListDetialByMainId") + public Result> queryTaskListDetialListByMainId(@RequestParam(name="id",required=true) String id) { + List taskListDetialList = taskListDetialService.selectByMainId(id); + return Result.OK(taskListDetialList); + } + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "任务清单权限表通过主表ID查询") + @Operation(summary="任务清单权限表主表ID查询") + @GetMapping(value = "/queryTaskListPermissionByMainId") + public Result> queryTaskListPermissionListByMainId(@RequestParam(name="id",required=true) String id) { + List taskListPermissionList = taskListPermissionService.selectByMainId(id); + return Result.OK(taskListPermissionList); + } + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "任务清单收藏表通过主表ID查询") + @Operation(summary="任务清单收藏表主表ID查询") + @GetMapping(value = "/queryTaskListFavoriteByMainId") + public Result> queryTaskListFavoriteListByMainId(@RequestParam(name="id",required=true) String id) { + List taskListFavoriteList = taskListFavoriteService.selectByMainId(id); + return Result.OK(taskListFavoriteList); + } + + /** + * 导出excel + * + * @param request + * @param taskList + */ + @RequiresPermissions("tasklist:task_list:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, TaskList taskList) { + + // Step.1 组装查询条件查询数据 + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(taskList, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + //配置选中数据查询条件 + String selections = request.getParameter("selections"); + if(oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + queryWrapper.in("id",selectionList); + } + //Step.2 获取导出数据 + List taskListList = taskListService.list(queryWrapper); + + // Step.3 组装pageList + List pageList = new ArrayList(); + for (TaskList main : taskListList) { + TaskListPage vo = new TaskListPage(); + BeanUtils.copyProperties(main, vo); + List taskListDetialList = taskListDetialService.selectByMainId(main.getId()); + vo.setTaskListDetialList(taskListDetialList); + List taskListPermissionList = taskListPermissionService.selectByMainId(main.getId()); + vo.setTaskListPermissionList(taskListPermissionList); + List taskListFavoriteList = taskListFavoriteService.selectByMainId(main.getId()); + vo.setTaskListFavoriteList(taskListFavoriteList); + pageList.add(vo); + } + + // Step.4 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + mv.addObject(NormalExcelConstants.FILE_NAME, "任务清单表列表"); + mv.addObject(NormalExcelConstants.CLASS, TaskListPage.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("任务清单表数据", "导出人:"+sysUser.getRealname(), "任务清单表")); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("tasklist:task_list:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List list = ExcelImportUtil.importExcel(file.getInputStream(), TaskListPage.class, params); + for (TaskListPage page : list) { + TaskList po = new TaskList(); + BeanUtils.copyProperties(page, po); + taskListService.saveMain(po, page.getTaskListDetialList(),page.getTaskListPermissionList(),page.getTaskListFavoriteList()); + } + return Result.OK("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + log.error(e.getMessage(),e); + return Result.error("文件导入失败:"+e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.OK("文件导入失败!"); + } + + @AutoLog(value = "任务清单表-我负责的任务") + @Operation(summary = "获取当前用户负责的任务") + @GetMapping(value = "/myResponsibleTasks") + public Result> myResponsibleTasks() { + List list = taskListService.myResponsibleTasks(); + return Result.OK(list); + } + + @AutoLog(value = "任务清单表-我关注的任务") + @Operation(summary = "获取当前用户关注的任务") + @GetMapping(value = "/myFollowedTasks") + public Result> myFollowedTasks() { + List list = taskListService.myFollowedTasks(); + return Result.OK(list); + } + + @AutoLog(value = "任务清单表-获取当前用户密级") + @Operation(summary = "获取当前用户密级") + @GetMapping(value = "/getCurrentUserSecurityLevel") + public Result getCurrentUserSecurityLevel() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + Integer level = loginUser.getUserSecurityLevel(); + if (level == null) { + level = 3; + } + return Result.OK("查询成功", level); + } + +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/controller/TaskListDetialController.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/controller/TaskListDetialController.java new file mode 100644 index 0000000..1e862c2 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/controller/TaskListDetialController.java @@ -0,0 +1,135 @@ +package org.jeecg.modules.demo.tasklist.controller; + +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import org.jeecg.modules.demo.tasklist.service.ITaskListDetialService; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskReq; +import org.jeecg.modules.demo.tasklist.vo.MoveTaskReq; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import lombok.extern.slf4j.Slf4j; +import java.util.List; +import java.util.Map; + +@Slf4j +@RestController +@RequestMapping("/tasklist/taskListDetial") +public class TaskListDetialController { + + @Autowired + private ITaskListDetialService taskListDetialService; + + @PostMapping(value = "/add") + public Result add(@RequestBody CreateTaskReq req) { + try { + TaskListDetial result = taskListDetialService.createTask(req); + return Result.OK(result); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @PostMapping(value = "/edit") + public Result edit(@RequestBody TaskListDetial task) { + try { + taskListDetialService.editTask(task); + return Result.OK("编辑成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id") String id) { + try { + taskListDetialService.deleteTask(id); + return Result.OK("删除成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @GetMapping(value = "/listByMainId") + public Result> listByMainId(@RequestParam(name = "mainId") String mainId) { + List list = taskListDetialService.queryTopLevelByMainId(mainId); + return Result.OK(list); + } + + @GetMapping(value = "/listAllByMainId") + public Result> listAllByMainId(@RequestParam(name = "mainId") String mainId) { + List list = taskListDetialService.queryAllByMainId(mainId); + return Result.OK(list); + } + + @PostMapping(value = "/toggleStatus") + public Result toggleStatus(@RequestBody Map body) { + try { + String id = body.get("id"); + taskListDetialService.toggleStatus(id); + return Result.OK("操作成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @PostMapping(value = "/moveTask") + public Result moveTask(@RequestBody MoveTaskReq req) { + try { + taskListDetialService.moveTask(req); + return Result.OK("移动成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @PostMapping(value = "/moveTaskGroup") + public Result moveTaskGroup(@RequestBody Map params) { + try { + String taskGroupId = (String) params.get("taskGroupId"); + Integer targetSortOrder = params.get("targetSortOrder") != null ? ((Number) params.get("targetSortOrder")).intValue() : null; + taskListDetialService.moveTaskGroup(taskGroupId, targetSortOrder); + return Result.OK("移动成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @PostMapping(value = "/follow") + public Result follow(@RequestBody Map body) { + try { + String id = body.get("id"); + taskListDetialService.followTask(id); + return Result.OK("关注成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @PostMapping(value = "/unfollow") + public Result unfollow(@RequestBody Map body) { + try { + String id = body.get("id"); + taskListDetialService.unfollowTask(id); + return Result.OK("取消关注成功"); + } catch (RuntimeException e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + + @GetMapping(value = "/loadSubTasks") + public Result> loadSubTasks( + @RequestParam(name = "parentTaskId") String parentTaskId, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize) { + List list = taskListDetialService.loadSubTasks(parentTaskId, pageNo, pageSize); + return Result.OK(list); + } +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskList.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskList.java new file mode 100644 index 0000000..9cf95b5 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskList.java @@ -0,0 +1,87 @@ +package org.jeecg.modules.demo.tasklist.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableField; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: 任务清单表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Schema(description="任务清单表") +@Data +@TableName("task_list") +public class TaskList implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; + /**所属部门*/ + @Schema(description = "所属部门") + private java.lang.String sysOrgCode; + /**清单名称*/ + @Excel(name = "清单名称", width = 15) + @Schema(description = "清单名称") + private java.lang.String tasklistName; + /**删除标识*/ + @Excel(name = "删除标识", width = 15) + @Schema(description = "删除标识") + @TableLogic + private java.lang.String delFlag; + + @TableField(exist = false) + @Schema(description = "所有者名称") + private java.lang.String ownerName; + + @TableField(exist = false) + @Schema(description = "协作者名称") + private java.lang.String collaboratorNames; + + /**密级: 1=非密, 2=内部, 3=秘密, 4=机密*/ + @Excel(name = "密级", width = 15) + @Schema(description = "密级:1=非密,2=内部,3=秘密,4=机密") + private java.lang.Integer secretLevel; + + /**密级文本*/ + @Excel(name = "密级文本", width = 15) + @Schema(description = "密级文本") + private java.lang.String secretText; + + @TableField(exist = false) + @Schema(description = "创建时间字符串") + private java.lang.String createTimeStr; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListDetial.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListDetial.java new file mode 100644 index 0000000..22c0933 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListDetial.java @@ -0,0 +1,172 @@ +package org.jeecg.modules.demo.tasklist.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableField; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: 任务清单详情表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Schema(description="任务清单详情表") +@Data +@TableName("task_list_detial") +public class TaskListDetial implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + + @TableField(exist = false) + @Schema(description = "创建人名称") + private java.lang.String createByName; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; + /**所属部门*/ + @Schema(description = "所属部门") + private java.lang.String sysOrgCode; + /**主表ID*/ + @Schema(description = "主表ID") + private java.lang.String mainId; + /**父节点ID*/ + @Excel(name = "父节点ID", width = 15) + @Schema(description = "父节点ID") + private java.lang.String pid; + /**是否有子节点*/ + @Excel(name = "是否有子节点", width = 15) + @Schema(description = "是否有子节点") + private java.lang.String hasChild; + /**排序号*/ + @Excel(name = "排序号", width = 15) + @Schema(description = "排序号") + private java.lang.Integer sortOrder; + /**任务名称*/ + @Excel(name = "任务名称", width = 15) + @Schema(description = "任务名称") + private java.lang.String taskName; + /**任务描述*/ + @Excel(name = "任务描述", width = 15) + @Schema(description = "任务描述") + private java.lang.String taskDesc; + /**优先级*/ + @Excel(name = "优先级", width = 15, dicCode = "task_priority") + @Schema(description = "优先级") + private java.lang.String priority; + /**完成状态*/ + @Excel(name = "完成状态", width = 15) + @Schema(description = "完成状态") + private java.lang.Integer taskStatus; + /**负责人ID*/ + @Excel(name = "负责人ID", width = 15) + @Schema(description = "负责人ID") + private java.lang.String assigneeId; + /**负责人*/ + @Excel(name = "负责人", width = 15) + @Schema(description = "负责人") + private java.lang.String assigneeName; + /**关注人ID*/ + @Excel(name = "关注人ID", width = 15) + @Schema(description = "关注人ID") + private java.lang.String followersId; + /**关注人*/ + @Excel(name = "关注人", width = 15) + @Schema(description = "关注人") + private java.lang.String followersName; + /**分配人ID*/ + @Excel(name = "分配人ID", width = 15) + @Schema(description = "分配人ID") + private java.lang.String assignId; + /**分配人*/ + @Excel(name = "分配人", width = 15) + @Schema(description = "分配人") + private java.lang.String assignName; + /**开始时间*/ + @Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "开始时间") + private java.util.Date startTime; + /**结束时间*/ + @Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "结束时间") + private java.util.Date endTime; + /**完成时间*/ + @Excel(name = "完成时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "完成时间") + private java.util.Date completeTime; + /**类型*/ + @Excel(name = "类型", width = 15) + @Schema(description = "类型") + private java.lang.String type; + /**子任务数*/ + @Excel(name = "子任务数", width = 15) + @Schema(description = "子任务数") + private java.lang.Integer subTaskCount; + /**子任务完成数*/ + @Excel(name = "子任务完成数", width = 15) + @Schema(description = "子任务完成数") + private java.lang.Integer completedSubTaskCount; + /**参与人ID*/ + @Excel(name = "参与人ID", width = 15) + @Schema(description = "参与人ID") + private java.lang.String participantId; + /**参与人*/ + @Excel(name = "参与人", width = 15) + @Schema(description = "参与人") + private java.lang.String participantName; + /**其他事项说明*/ + @Excel(name = "其他事项说明", width = 15) + @Schema(description = "其他事项说明") + private java.lang.String remark; + /**是否默认分组*/ + @Excel(name = "是否默认分组", width = 15, dicCode = "is_default") + @Schema(description = "是否默认分组(1=是,0=否)") + private java.lang.Integer isDefault; + /**来源清单名称*/ + @TableField(exist = false) + @Schema(description = "来源清单名称") + private java.lang.String listName; + /**当前用户对清单的权限*/ + @TableField(exist = false) + @Schema(description = "当前用户对该清单的权限(1=所有者,2=可编辑,3=只读)") + private java.lang.String myPermission; + /**删除标识*/ + @Excel(name = "删除标识", width = 15) + @Schema(description = "删除标识") + @TableLogic + private java.lang.String delFlag; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListFavorite.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListFavorite.java new file mode 100644 index 0000000..6ecd951 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListFavorite.java @@ -0,0 +1,98 @@ +package org.jeecg.modules.demo.tasklist.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableField; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: 任务清单收藏表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Schema(description="任务清单收藏表") +@Data +@TableName("task_list_favorite") +public class TaskListFavorite implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; + /**所属部门*/ + @Schema(description = "所属部门") + private java.lang.String sysOrgCode; + /**主表ID*/ + @Schema(description = "主表ID") + private java.lang.String mainId; + /**任务清单(分组)名称*/ + @Excel(name = "任务清单(分组)名称", width = 15) + @Schema(description = "任务清单(分组)名称") + private java.lang.String tasklistName; + /**用户ID*/ + @Excel(name = "用户ID", width = 15) + @Schema(description = "用户ID") + private java.lang.String userId; + /**类型(0是分组,1是清单)*/ + @Excel(name = "类型(0是分组,1是清单)", width = 15) + @Schema(description = "类型(0是分组,1是清单)") + private java.lang.String type; + /**父节点ID*/ + @Excel(name = "父节点ID", width = 15) + @Schema(description = "父节点ID") + private java.lang.String pid; + /**是否有子节点*/ + @Excel(name = "是否有子节点", width = 15) + @Schema(description = "是否有子节点") + private java.lang.String hasChild; + /**排序*/ + @Excel(name = "排序", width = 15) + @Schema(description = "排序") + private java.lang.Integer sortOrder; + /**删除标识*/ + @Excel(name = "删除标识", width = 15) + @Schema(description = "删除标识") + @TableLogic + private java.lang.String delFlag; + + @TableField(exist = false) + @Schema(description = "清单密级") + private java.lang.Integer secretLevel; + + @TableField(exist = false) + @Schema(description = "清单密级文本") + private java.lang.String secretText; + + @TableField(exist = false) + @Schema(description = "当前用户对该清单的权限") + private java.lang.String permission; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/entity/TestMainTable.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListPermission.java similarity index 56% rename from jeecg-module-supervision/src/main/java/org/jeecg/modules/test/entity/TestMainTable.java rename to jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListPermission.java index 603e89f..5a0959d 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/entity/TestMainTable.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/entity/TaskListPermission.java @@ -1,8 +1,6 @@ -package org.jeecg.modules.test.entity; +package org.jeecg.modules.demo.tasklist.entity; import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.util.Date; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -14,52 +12,60 @@ import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecg.common.aspect.annotation.Dict; - +import java.util.Date; import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; /** - * @Description: test + * @Description: 任务清单权限表 * @Author: jeecg-boot - * @Date: 2026-04-03 + * @Date: 2026-04-24 * @Version: V1.0 */ -@Schema(description="test") +@Schema(description="任务清单权限表") @Data -@TableName("test_main_table") -public class TestMainTable implements Serializable { +@TableName("task_list_permission") +public class TaskListPermission implements Serializable { private static final long serialVersionUID = 1L; /**主键*/ @TableId(type = IdType.ASSIGN_ID) @Schema(description = "主键") - private String id; + private java.lang.String id; /**创建人*/ @Schema(description = "创建人") - private String createBy; + private java.lang.String createBy; /**创建日期*/ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @Schema(description = "创建日期") - private Date createTime; + private java.util.Date createTime; /**更新人*/ @Schema(description = "更新人") - private String updateBy; + private java.lang.String updateBy; /**更新日期*/ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @Schema(description = "更新日期") - private Date updateTime; + private java.util.Date updateTime; /**所属部门*/ @Schema(description = "所属部门") - private String sysOrgCode; - /**a字段*/ - @Excel(name = "a字段", width = 15) - @Schema(description = "a字段") - private String fieldA; - /**b字段*/ - @Excel(name = "b字段", width = 15) - @Schema(description = "b字段") - private String fieldB; - @TableLogic(value = "0", delval = "1") - private int delFlag = 0; + private java.lang.String sysOrgCode; + /**主表ID*/ + @Schema(description = "主表ID") + private java.lang.String mainId; + /**用户ID*/ + @Excel(name = "用户ID", width = 15) + @Schema(description = "用户ID") + private java.lang.String userId; + /**权限类型*/ + @Excel(name = "权限类型", width = 15, dicCode = "collaboration_permission") + @Dict(dicCode = "collaboration_permission") + @Schema(description = "权限类型") + private java.lang.String permission; + /**删除标识*/ + @Excel(name = "删除标识", width = 15) + @Schema(description = "删除标识") + @TableLogic + private java.lang.String delFlag; } diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListDetialMapper.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListDetialMapper.java new file mode 100644 index 0000000..70f26e6 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListDetialMapper.java @@ -0,0 +1,63 @@ +package org.jeecg.modules.demo.tasklist.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface TaskListDetialMapper extends BaseMapper { + + boolean deleteByMainId(@Param("mainId") String mainId); + + List selectByMainId(@Param("mainId") String mainId); + + void shiftSortOrderUp(@Param("mainId") String mainId, @Param("pid") String pid, @Param("fromSort") Integer fromSort); + + void shiftSortOrderDown(@Param("mainId") String mainId, @Param("pid") String pid, @Param("fromSort") Integer fromSort); + + Integer getMaxSortOrder(@Param("mainId") String mainId, @Param("pid") String pid); + + int appendFollower(@Param("taskId") String taskId, @Param("userId") String userId, @Param("userName") String userName); + + int removeFollower(@Param("taskId") String taskId, @Param("userId") String userId, @Param("userName") String userName); + + int toggleTaskStatus(@Param("taskId") String taskId, @Param("updateBy") String updateBy, @Param("newStatus") Integer newStatus, @Param("completeTime") java.util.Date completeTime); + + List selectAllByMainId(@Param("mainId") String mainId); + + List selectTopLevelByMainId(@Param("mainId") String mainId); + + List selectSubTasksByPage(@Param("parentId") String parentId, @Param("offset") Integer offset, @Param("pageSize") Integer pageSize); + + void updatePidAndSort(@Param("id") String id, @Param("pid") String pid, @Param("sortOrder") Integer sortOrder); + + List selectChildrenByPid(@Param("pid") String pid); + + void resetPidToNull(@Param("pid") String pid, @Param("mainId") String mainId); + + void incrementSubTaskCount(@Param("parentId") String parentId); + + void decrementSubTaskCount(@Param("parentId") String parentId); + + void incrementCompletedSubTaskCount(@Param("parentId") String parentId); + + void decrementCompletedSubTaskCount(@Param("parentId") String parentId); + + void updateHasChild(@Param("parentId") String parentId, @Param("hasChild") String hasChild); + + void shiftSortOrderUpForGroup(@Param("mainId") String mainId, @Param("fromSort") Integer fromSort); + + void shiftSortOrderDownForGroup(@Param("mainId") String mainId, @Param("fromSort") Integer fromSort); + + Integer getMaxSortOrderForGroup(@Param("mainId") String mainId); + + void updateSortOrder(@Param("id") String id, @Param("sortOrder") Integer sortOrder); + + Integer countChildrenByPid(@Param("pid") String pid); + + List selectByAssigneeId(@Param("assigneeId") String assigneeId, @Param("userId") String userId); + + List selectByFollowersId(@Param("followersId") String followersId, @Param("userId") String userId); + + void appendAssigner(@Param("taskId") String taskId, @Param("userId") String userId, @Param("userName") String userName); +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListFavoriteMapper.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListFavoriteMapper.java new file mode 100644 index 0000000..c305012 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListFavoriteMapper.java @@ -0,0 +1,49 @@ +package org.jeecg.modules.demo.tasklist.mapper; + +import java.util.List; +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: 任务清单收藏表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +public interface TaskListFavoriteMapper extends BaseMapper { + + /** + * 通过主表id删除子表数据 + * + * @param mainId 主表id + * @return boolean + */ + public boolean deleteByMainId(@Param("mainId") String mainId); + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List + */ + public List selectByMainId(@Param("mainId") String mainId); + + Integer selectMaxSortOrder(@Param("userId") String userId, @Param("pid") String pid); + + Integer selectMaxSortOrderByType(@Param("userId") String userId, @Param("pid") String pid, @Param("type") String type); + + void shiftSortOrderUp(@Param("userId") String userId, @Param("pid") String pid, @Param("fromSort") Integer fromSort); + + void shiftSortOrderDown(@Param("userId") String userId, @Param("pid") String pid, @Param("fromSort") Integer fromSort); + + void shiftSortOrderUpByType(@Param("userId") String userId, @Param("type") String type, @Param("fromSort") Integer fromSort); + + void shiftSortOrderDownByType(@Param("userId") String userId, @Param("type") String type, @Param("fromSort") Integer fromSort); + + Integer countChildrenByPid(@Param("userId") String userId, @Param("pid") String pid); + + void updatePidAndSort(@Param("id") String id, @Param("pid") String pid, @Param("sortOrder") Integer sortOrder); + + void updateSortOrder(@Param("id") String id, @Param("sortOrder") Integer sortOrder); +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListMapper.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListMapper.java new file mode 100644 index 0000000..ee19690 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListMapper.java @@ -0,0 +1,28 @@ +package org.jeecg.modules.demo.tasklist.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.demo.tasklist.entity.TaskList; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 任务清单表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +public interface TaskListMapper extends BaseMapper { + + /** + * 查询当前用户可见的所有清单(包含部门、所有者、协作者、任务负责人/参与人维度) + * @param userId 当前用户ID + * @param userSecLevel 当前用户密级 + * @param orgCode 当前用户部门编码 + * @return 可见清单列表 + */ + List selectVisibleLists(@Param("userId") String userId, + @Param("userSecLevel") Integer userSecLevel, + @Param("orgCode") String orgCode); + +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/TestSonTableMapper.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListPermissionMapper.java similarity index 52% rename from jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/TestSonTableMapper.java rename to jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListPermissionMapper.java index ee502e6..65a6d86 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/TestSonTableMapper.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/TaskListPermissionMapper.java @@ -1,17 +1,17 @@ -package org.jeecg.modules.test.mapper; +package org.jeecg.modules.demo.tasklist.mapper; import java.util.List; -import org.jeecg.modules.test.entity.TestSonTable; +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; /** - * @Description: test + * @Description: 任务清单权限表 * @Author: jeecg-boot - * @Date: 2026-04-03 + * @Date: 2026-04-24 * @Version: V1.0 */ -public interface TestSonTableMapper extends BaseMapper { +public interface TaskListPermissionMapper extends BaseMapper { /** * 通过主表id删除子表数据 @@ -25,7 +25,7 @@ public interface TestSonTableMapper extends BaseMapper { * 通过主表id查询子表数据 * * @param mainId 主表id - * @return List + * @return List */ - public List selectByMainId(@Param("mainId") String mainId); + public List selectByMainId(@Param("mainId") String mainId); } diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListDetialMapper.xml b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListDetialMapper.xml new file mode 100644 index 0000000..9225906 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListDetialMapper.xml @@ -0,0 +1,192 @@ + + + + + + DELETE FROM task_list_detial WHERE main_id = #{mainId} + + + + + + UPDATE task_list_detial + SET sort_order = sort_order + 1 + WHERE main_id = #{mainId} AND del_flag = '0' + AND (pid = #{pid} OR (#{pid} IS NULL AND pid IS NULL)) + AND sort_order >= #{fromSort} + + + + UPDATE task_list_detial + SET sort_order = sort_order - 1 + WHERE main_id = #{mainId} AND del_flag = '0' + AND (pid = #{pid} OR (#{pid} IS NULL AND pid IS NULL)) + AND sort_order > #{fromSort} + + + + + + UPDATE task_list_detial + SET followers_id = CONCAT(IFNULL(followers_id, ''), ',', #{userId}), + followers_name = CONCAT(IFNULL(followers_name, ''), ',', #{userName}) + WHERE id = #{taskId} AND del_flag = '0' + AND (followers_id IS NULL OR followers_id NOT LIKE CONCAT('%', #{userId}, '%')) + + + + UPDATE task_list_detial + SET followers_id = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', followers_id, ','), CONCAT(',', #{userId}, ','), ',')), + followers_name = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', followers_name, ','), CONCAT(',', #{userName}, ','), ',')) + WHERE id = #{taskId} AND del_flag = '0' + + + + UPDATE task_list_detial + SET task_status = #{newStatus}, + complete_time = #{completeTime}, + update_by = #{updateBy}, update_time = NOW() + WHERE id = #{taskId} AND del_flag = '0' + + + + + + + + + + UPDATE task_list_detial + SET pid = #{pid}, sort_order = #{sortOrder} + WHERE id = #{id} + + + + + + UPDATE task_list_detial + SET pid = NULL + WHERE pid = #{pid} AND main_id = #{mainId} AND del_flag = '0' + + + + UPDATE task_list_detial SET sub_task_count = IFNULL(sub_task_count, 0) + 1, has_child = '1' + WHERE id = #{parentId} + + + + UPDATE task_list_detial SET sub_task_count = GREATEST(IFNULL(sub_task_count, 1) - 1, 0) + WHERE id = #{parentId} + + + + UPDATE task_list_detial SET completed_sub_task_count = IFNULL(completed_sub_task_count, 0) + 1 + WHERE id = #{parentId} + + + + UPDATE task_list_detial SET completed_sub_task_count = GREATEST(IFNULL(completed_sub_task_count, 1) - 1, 0) + WHERE id = #{parentId} + + + + UPDATE task_list_detial SET has_child = #{hasChild} WHERE id = #{parentId} + + + + UPDATE task_list_detial + SET sort_order = sort_order + 1 + WHERE main_id = #{mainId} AND del_flag = '0' + AND type = '0' + AND (pid IS NULL OR pid = '') + AND sort_order >= #{fromSort} + + + + UPDATE task_list_detial + SET sort_order = sort_order - 1 + WHERE main_id = #{mainId} AND del_flag = '0' + AND type = '0' + AND (pid IS NULL OR pid = '') + AND sort_order > #{fromSort} + + + + + + UPDATE task_list_detial SET sort_order = #{sortOrder} WHERE id = #{id} + + + + + + + + + + UPDATE task_list_detial + SET assign_id = TRIM(BOTH ',' FROM CONCAT(IFNULL(assign_id, ''), ',', #{userId})), + assign_name = TRIM(BOTH ',' FROM CONCAT(IFNULL(assign_name, ''), ',', #{userName})) + WHERE id = #{taskId} AND del_flag = '0' + AND (assign_id IS NULL OR assign_id NOT LIKE CONCAT('%', #{userId}, '%')) + + + diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListFavoriteMapper.xml b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListFavoriteMapper.xml new file mode 100644 index 0000000..3cdcd29 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListFavoriteMapper.xml @@ -0,0 +1,81 @@ + + + + + + DELETE + FROM task_list_favorite + WHERE + main_id = #{mainId} + + + + + + + + + UPDATE task_list_favorite + SET sort_order = sort_order + 1 + WHERE user_id = #{userId} AND del_flag = '0' + AND (pid = #{pid} OR (#{pid} IS NULL AND pid IS NULL)) + AND sort_order >= #{fromSort} + + + + UPDATE task_list_favorite + SET sort_order = sort_order - 1 + WHERE user_id = #{userId} AND del_flag = '0' + AND (pid = #{pid} OR (#{pid} IS NULL AND pid IS NULL)) + AND sort_order > #{fromSort} + + + + UPDATE task_list_favorite + SET sort_order = sort_order + 1 + WHERE user_id = #{userId} AND del_flag = '0' + AND type = #{type} + AND pid IS NULL + AND sort_order >= #{fromSort} + + + + UPDATE task_list_favorite + SET sort_order = sort_order - 1 + WHERE user_id = #{userId} AND del_flag = '0' + AND type = #{type} + AND pid IS NULL + AND sort_order > #{fromSort} + + + + + + UPDATE task_list_favorite + SET pid = #{pid}, sort_order = #{sortOrder} + WHERE id = #{id} + + + UPDATE task_list_favorite SET sort_order = #{sortOrder} WHERE id = #{id} + + diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListMapper.xml b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListMapper.xml new file mode 100644 index 0000000..d6aac66 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListMapper.xml @@ -0,0 +1,55 @@ + + + + + + + diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/xml/TestSonTableMapper.xml b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListPermissionMapper.xml similarity index 53% rename from jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/xml/TestSonTableMapper.xml rename to jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListPermissionMapper.xml index 87ca9ba..e620060 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/xml/TestSonTableMapper.xml +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/mapper/xml/TaskListPermissionMapper.xml @@ -1,16 +1,16 @@ - + DELETE - FROM test_son_table + FROM task_list_permission WHERE - main_table_id = #{mainId} + main_id = #{mainId} - SELECT * - FROM test_son_table + FROM task_list_permission WHERE - main_table_id = #{mainId} + main_id = #{mainId} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListDetialService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListDetialService.java new file mode 100644 index 0000000..7e23910 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListDetialService.java @@ -0,0 +1,43 @@ +package org.jeecg.modules.demo.tasklist.service; + +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskReq; +import org.jeecg.modules.demo.tasklist.vo.MoveTaskReq; + +public interface ITaskListDetialService extends IService { + + List selectByMainId(String mainId); + + TaskListDetial createTask(CreateTaskReq req); + + void editTask(TaskListDetial task); + + void deleteTask(String taskId); + + List queryAllByMainId(String mainId); + + List queryTopLevelByMainId(String mainId); + + void toggleStatus(String taskId); + + void moveTask(MoveTaskReq req); + + void moveTaskGroup(String taskGroupId, Integer targetSortOrder); + + /** + * 纯排序重算:将任务/分组移到同级第 targetPosition 个位置 + * 不包含权限校验和副作用处理,由调用方负责 + */ + void reorderTaskItem(String movedId, String mainId, String pid, + Integer targetPosition, String newPid, boolean isGroup); + + void followTask(String taskId); + + void unfollowTask(String taskId); + + List loadSubTasks(String parentTaskId, Integer pageNo, Integer pageSize); + + void ensureDefaultGroup(String mainId); +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListFavoriteService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListFavoriteService.java new file mode 100644 index 0000000..154c7e6 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListFavoriteService.java @@ -0,0 +1,45 @@ +package org.jeecg.modules.demo.tasklist.service; + +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: 任务清单收藏表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +public interface ITaskListFavoriteService extends IService { + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List + */ + public List selectByMainId(String mainId); + + Integer getMaxSortOrder(String userId, String pid); + + Integer getMaxSortOrderByType(String userId, String pid, String type); + + void shiftSortOrderUp(String userId, String pid, Integer fromSort); + + void shiftSortOrderDown(String userId, String pid, Integer fromSort); + + void shiftSortOrderUpByType(String userId, String type, Integer fromSort); + + void shiftSortOrderDownByType(String userId, String type, Integer fromSort); + + Integer countChildren(String userId, String pid); + + void updatePidAndSort(String favoriteId, String pid, Integer sortOrder); + + /** + * 纯排序重算:将指定记录移到同级第 targetPosition 个位置 + * 不包含权限校验和副作用处理,由调用方负责 + */ + void reorderItem(String movedId, String userId, String pid, String type, + Integer targetPosition, String newPid); +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListPermissionService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListPermissionService.java new file mode 100644 index 0000000..35895f0 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListPermissionService.java @@ -0,0 +1,22 @@ +package org.jeecg.modules.demo.tasklist.service; + +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: 任务清单权限表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +public interface ITaskListPermissionService extends IService { + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List + */ + public List selectByMainId(String mainId); +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListService.java new file mode 100644 index 0000000..9d35c89 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/ITaskListService.java @@ -0,0 +1,100 @@ +package org.jeecg.modules.demo.tasklist.service; + +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import org.jeecg.modules.demo.tasklist.entity.TaskList; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskListReq; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskListGroupReq; +import org.jeecg.modules.demo.tasklist.vo.MoveTaskListReq; +import org.jeecg.modules.demo.tasklist.vo.AddCollaboratorReq; +import org.jeecg.modules.demo.tasklist.vo.CollaboratorVO; +import com.baomidou.mybatisplus.extension.service.IService; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: 任务清单表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +public interface ITaskListService extends IService { + + /** + * 添加一对多 + * + * @param taskList + * @param taskListDetialList + * @param taskListPermissionList + * @param taskListFavoriteList + */ + public void saveMain(TaskList taskList,List taskListDetialList,List taskListPermissionList,List taskListFavoriteList) ; + + /** + * 修改一对多 + * + * @param taskList + * @param taskListDetialList + * @param taskListPermissionList + * @param taskListFavoriteList + */ + public void updateMain(TaskList taskList,List taskListDetialList,List taskListPermissionList,List taskListFavoriteList); + + /** + * 删除一对多 + * + * @param id + */ + public void delMain (String id); + + /** + * 批量删除一对多 + * + * @param idList + */ + public void delBatchMain (Collection idList); + + String createTaskList(CreateTaskListReq req); + + String createTaskListGroup(CreateTaskListGroupReq req); + + void moveTaskList(MoveTaskListReq req); + + void moveGroup(String groupId, Integer sortOrder); + + List getMyFavorites(); + + void deleteTaskList(String taskListId); + + void removeFavorite(String favoriteId); + + void removeFavoriteGroup(String groupId); + + void renameGroup(String groupId, String newName); + + void renameTaskList(String taskListId, String newName); + + List getMyOwnLists(); + + List getAllLists(); + + List getMyCollabLists(); + + List getCollaborators(String taskListId); + + void addCollaborator(AddCollaboratorReq req); + + void removeCollaborator(String permissionId); + + void updateCollaboratorPermission(String permissionId, String newPermission); + + String getMyPermission(String taskListId); + + void addToFavorites(String taskListId, String pid); + + List myResponsibleTasks(); + + List myFollowedTasks(); +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListDetialServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListDetialServiceImpl.java new file mode 100644 index 0000000..46a7149 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListDetialServiceImpl.java @@ -0,0 +1,629 @@ +package org.jeecg.modules.demo.tasklist.service.impl; + +import org.jeecg.modules.demo.tasklist.entity.TaskList; +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import org.jeecg.modules.demo.tasklist.mapper.TaskListDetialMapper; +import org.jeecg.modules.demo.tasklist.mapper.TaskListMapper; +import org.jeecg.modules.demo.tasklist.mapper.TaskListPermissionMapper; +import org.jeecg.modules.demo.tasklist.service.ITaskListDetialService; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskReq; +import org.jeecg.modules.demo.tasklist.vo.MoveTaskReq; +import org.jeecg.common.system.api.ISysBaseAPI; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.common.util.oConvertUtils; +import org.apache.shiro.SecurityUtils; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import java.util.Set; + +@Service +public class TaskListDetialServiceImpl extends ServiceImpl implements ITaskListDetialService { + + @Autowired + private TaskListDetialMapper taskListDetialMapper; + @Autowired + private TaskListMapper taskListMapper; + @Autowired + private TaskListPermissionMapper taskListPermissionMapper; + @Autowired + private ISysBaseAPI sysBaseAPI; + + @Override + public List selectByMainId(String mainId) { + return taskListDetialMapper.selectByMainId(mainId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public TaskListDetial createTask(CreateTaskReq req) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + String permission = getPermission(req.getMainId(), userId); + if (permission == null) { + throw new RuntimeException("无权限在此清单中创建任务"); + } + if ("3".equals(permission)) { + throw new RuntimeException("可阅读者无法创建任务"); + } + + if ("1".equals(req.getType()) && oConvertUtils.isEmpty(req.getPid())) { + ensureDefaultGroup(req.getMainId()); + TaskListDetial defaultGroup = findDefaultGroup(req.getMainId()); + if (defaultGroup != null) { + req.setPid(defaultGroup.getId()); + } + } + + TaskListDetial entity = new TaskListDetial(); + entity.setMainId(req.getMainId()); + entity.setTaskName(req.getTaskName()); + entity.setTaskDesc(req.getTaskDesc()); + entity.setPriority(req.getPriority()); + entity.setType(req.getType() != null ? req.getType() : "1"); + entity.setPid(normalizePid(req.getPid())); + entity.setTaskStatus(0); + entity.setSubTaskCount(0); + entity.setCompletedSubTaskCount(0); + entity.setHasChild("0"); + entity.setDelFlag("0"); + entity.setSysOrgCode(loginUser.getOrgCode()); + + if ("1".equals(req.getType()) && oConvertUtils.isNotEmpty(req.getAssigneeId())) { + entity.setAssigneeId(req.getAssigneeId()); + entity.setAssigneeName(translateUserIdsToNames(req.getAssigneeId())); + entity.setAssignId(userId); + entity.setAssignName(loginUser.getRealname()); + } + + if (req.getStartTime() != null) { + entity.setStartTime(req.getStartTime()); + } + if (req.getEndTime() != null) { + entity.setEndTime(req.getEndTime()); + } + + if (req.getSortOrder() != null) { + taskListDetialMapper.shiftSortOrderUp(req.getMainId(), normalizePid(req.getPid()), req.getSortOrder()); + entity.setSortOrder(req.getSortOrder()); + } else { + Integer maxSort = taskListDetialMapper.getMaxSortOrder(req.getMainId(), normalizePid(req.getPid())); + entity.setSortOrder(maxSort + 1); + } + + taskListDetialMapper.insert(entity); + + if ("1".equals(entity.getType()) && oConvertUtils.isNotEmpty(entity.getPid())) { + TaskListDetial parent = taskListDetialMapper.selectById(entity.getPid()); + if (parent != null && "1".equals(parent.getType())) { + taskListDetialMapper.incrementSubTaskCount(parent.getId()); + } + } + + return entity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void editTask(TaskListDetial task) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListDetial existing = taskListDetialMapper.selectById(task.getId()); + if (existing == null) { + throw new RuntimeException("任务不存在"); + } + + String permission = getPermission(existing.getMainId(), userId); + if (permission == null) { + throw new RuntimeException("无权限编辑此任务"); + } + if ("3".equals(permission)) { + String assigneeId = existing.getAssigneeId(); + if (oConvertUtils.isEmpty(assigneeId) || !assigneeId.contains(userId)) { + throw new RuntimeException("可阅读者只能编辑自己负责的任务"); + } + task.setAssigneeId(existing.getAssigneeId()); + task.setAssigneeName(existing.getAssigneeName()); + } + + TaskList taskListEntity = taskListMapper.selectById(existing.getMainId()); + if (taskListEntity != null) { + Integer listSecLevel = taskListEntity.getSecretLevel(); + if (listSecLevel == null) { + listSecLevel = 1; + } + if (task.getAssigneeId() != null) { + String filtered = filterUsersBySecLevel(task.getAssigneeId(), listSecLevel); + if (!Objects.equals(filtered, task.getAssigneeId())) { + log.warn(String.format("editTask 密级过滤: 清单[%s] 负责人 原始[%s] 过滤后[%s]", + taskListEntity.getId(), task.getAssigneeId(), filtered)); + } + task.setAssigneeId(filtered); + if (oConvertUtils.isEmpty(filtered)) { + task.setAssigneeName(""); + } + } + if (task.getParticipantId() != null) { + String filtered = filterUsersBySecLevel(task.getParticipantId(), listSecLevel); + if (!Objects.equals(filtered, task.getParticipantId())) { + log.warn(String.format("editTask 密级过滤: 清单[%s] 参与人 原始[%s] 过滤后[%s]", + taskListEntity.getId(), task.getParticipantId(), filtered)); + } + task.setParticipantId(filtered); + if (oConvertUtils.isEmpty(filtered)) { + task.setParticipantName(""); + } + } + if (task.getFollowersId() != null) { + String filtered = filterUsersBySecLevel(task.getFollowersId(), listSecLevel); + if (!Objects.equals(filtered, task.getFollowersId())) { + log.warn(String.format("editTask 密级过滤: 清单[%s] 关注人 原始[%s] 过滤后[%s]", + taskListEntity.getId(), task.getFollowersId(), filtered)); + } + task.setFollowersId(filtered); + if (oConvertUtils.isEmpty(filtered)) { + task.setFollowersName(""); + } + } + } + + if (task.getAssigneeId() != null) { + if (oConvertUtils.isNotEmpty(task.getAssigneeId()) && oConvertUtils.isEmpty(task.getAssigneeName())) { + task.setAssigneeName(translateUserIdsToNames(task.getAssigneeId())); + } + if (oConvertUtils.isEmpty(task.getAssigneeId())) { + task.setAssigneeName(""); + } + } + + if (task.getParticipantId() != null) { + if (oConvertUtils.isNotEmpty(task.getParticipantId()) && oConvertUtils.isEmpty(task.getParticipantName())) { + task.setParticipantName(translateUserIdsToNames(task.getParticipantId())); + } + if (oConvertUtils.isEmpty(task.getParticipantId())) { + task.setParticipantName(""); + } + } + + if (task.getFollowersId() != null) { + if (oConvertUtils.isNotEmpty(task.getFollowersId()) && oConvertUtils.isEmpty(task.getFollowersName())) { + task.setFollowersName(translateUserIdsToNames(task.getFollowersId())); + } + if (oConvertUtils.isEmpty(task.getFollowersId())) { + task.setFollowersName(""); + } + } + boolean clearStartTime = task.getStartTime() == null && existing.getStartTime() != null; + boolean clearEndTime = task.getEndTime() == null && existing.getEndTime() != null; + + taskListDetialMapper.updateById(task); + + if (clearStartTime || clearEndTime) { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("id", task.getId()); + if (clearStartTime) uw.set("start_time", null); + if (clearEndTime) uw.set("end_time", null); + taskListDetialMapper.update(null, uw); + } + + taskListDetialMapper.appendAssigner(task.getId(), userId, loginUser.getRealname()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteTask(String taskId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListDetial existing = taskListDetialMapper.selectById(taskId); + if (existing == null) { + throw new RuntimeException("任务不存在"); + } + + String permission = getPermission(existing.getMainId(), userId); + if (permission == null) { + throw new RuntimeException("无权限删除此任务"); + } + if ("3".equals(permission)) { + throw new RuntimeException("可阅读者无法删除任务"); + } + + if ("0".equals(existing.getType()) && existing.getIsDefault() != null && existing.getIsDefault() == 1) { + throw new RuntimeException("默认分组不能删除"); + } + + if ("0".equals(existing.getType())) { + taskListDetialMapper.resetPidToNull(taskId, existing.getMainId()); + } + + List children = taskListDetialMapper.selectChildrenByPid(taskId); + for (TaskListDetial child : children) { + deleteTaskRecursive(child); + } + + taskListDetialMapper.deleteById(taskId); + + if (oConvertUtils.isNotEmpty(existing.getPid())) { + TaskListDetial parent = taskListDetialMapper.selectById(existing.getPid()); + if (parent != null && "1".equals(parent.getType())) { + taskListDetialMapper.decrementSubTaskCount(parent.getId()); + if (existing.getTaskStatus() != null && existing.getTaskStatus() == 1) { + taskListDetialMapper.decrementCompletedSubTaskCount(parent.getId()); + } + Integer childCount = taskListDetialMapper.countChildrenByPid(parent.getId()); + if (childCount == null || childCount == 0) { + taskListDetialMapper.updateHasChild(parent.getId(), "0"); + } + } + } + } + + private void deleteTaskRecursive(TaskListDetial task) { + List children = taskListDetialMapper.selectChildrenByPid(task.getId()); + for (TaskListDetial child : children) { + deleteTaskRecursive(child); + } + taskListDetialMapper.deleteById(task.getId()); + } + + @Override + public List queryAllByMainId(String mainId) { + List list = taskListDetialMapper.selectAllByMainId(mainId); + fillCreateByName(list); + return list; + } + + @Override + public List queryTopLevelByMainId(String mainId) { + List list = taskListDetialMapper.selectTopLevelByMainId(mainId); + fillCreateByName(list); + return list; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void toggleStatus(String taskId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListDetial existing = taskListDetialMapper.selectById(taskId); + if (existing == null) { + throw new RuntimeException("任务不存在"); + } + + String permission = getPermission(existing.getMainId(), userId); + if (permission == null) { + throw new RuntimeException("无权限操作此任务"); + } + if ("3".equals(permission)) { + String assigneeId = existing.getAssigneeId(); + if (oConvertUtils.isEmpty(assigneeId) || !assigneeId.contains(userId)) { + throw new RuntimeException("可阅读者只能操作自己负责的任务"); + } + } + + int oldStatus = existing.getTaskStatus() != null ? existing.getTaskStatus() : 0; + int newStatus = oldStatus == 0 ? 1 : 0; + java.util.Date completeTime = oldStatus == 0 ? new java.util.Date() : null; + + taskListDetialMapper.toggleTaskStatus(taskId, loginUser.getUsername(), newStatus, completeTime); + + if (oConvertUtils.isNotEmpty(existing.getPid())) { + TaskListDetial parent = taskListDetialMapper.selectById(existing.getPid()); + if (parent != null && "1".equals(parent.getType())) { + if (oldStatus == 0) { + taskListDetialMapper.incrementCompletedSubTaskCount(parent.getId()); + } else { + taskListDetialMapper.decrementCompletedSubTaskCount(parent.getId()); + } + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void moveTask(MoveTaskReq req) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListDetial task = taskListDetialMapper.selectById(req.getTaskId()); + if (task == null) { + throw new RuntimeException("任务不存在"); + } + + String permission = getPermission(task.getMainId(), userId); + if (permission == null) { + throw new RuntimeException("无权限移动此任务"); + } + if ("3".equals(permission)) { + throw new RuntimeException("可阅读者无法移动任务"); + } + + String oldPid = normalizePid(task.getPid()); + String newPid = normalizePid(req.getTargetPid()); + + boolean pidChanged = (oldPid == null && newPid != null) || (oldPid != null && !oldPid.equals(newPid)); + + // 调用纯排序方法 + reorderTaskItem(req.getTaskId(), task.getMainId(), oldPid, req.getTargetSortOrder(), newPid, false); + + // 仅在 pid 变更时更新父子计数 + if (pidChanged) { + // 清除旧父任务的副作用 + if (oConvertUtils.isNotEmpty(oldPid)) { + TaskListDetial oldParent = taskListDetialMapper.selectById(oldPid); + if (oldParent != null && "1".equals(oldParent.getType())) { + taskListDetialMapper.decrementSubTaskCount(oldPid); + Integer childCount = taskListDetialMapper.countChildrenByPid(oldPid); + if (childCount == null || childCount == 0) { + taskListDetialMapper.updateHasChild(oldPid, "0"); + } + } + } + + // 设置新父任务的副作用 + if (oConvertUtils.isNotEmpty(newPid)) { + TaskListDetial newParent = taskListDetialMapper.selectById(newPid); + if (newParent != null && "1".equals(newParent.getType())) { + taskListDetialMapper.incrementSubTaskCount(newPid); + } + taskListDetialMapper.updateHasChild(newPid, "1"); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void moveTaskGroup(String taskGroupId, Integer targetSortOrder) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListDetial group = taskListDetialMapper.selectById(taskGroupId); + if (group == null || !"0".equals(group.getType())) { + throw new RuntimeException("分组不存在"); + } + String mainId = group.getMainId(); + + String permission = getPermission(mainId, userId); + if (permission == null || "3".equals(permission)) { + throw new RuntimeException("无权限移动此分组"); + } + + reorderTaskItem(taskGroupId, mainId, null, targetSortOrder, null, true); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void reorderTaskItem(String movedId, String mainId, String pid, + Integer targetPosition, String newPid, boolean isGroup) { + TaskListDetial moved = taskListDetialMapper.selectById(movedId); + if (moved == null) { + throw new RuntimeException("记录不存在"); + } + + // 当 newPid 有值时使用 newPid(跨组移动),否则使用 pid(同组内移动) + // 关键:newPid="" 表示拖到根级别,此时应设为 null + String effectiveNewPid; + if (newPid != null) { + effectiveNewPid = newPid.isEmpty() ? null : newPid; + } else { + effectiveNewPid = pid; + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(TaskListDetial::getMainId, mainId); + query.eq(TaskListDetial::getDelFlag, "0"); + if (isGroup) { + query.eq(TaskListDetial::getType, "0"); + query.and(w -> w.isNull(TaskListDetial::getPid).or().eq(TaskListDetial::getPid, "")); + } else { + if (effectiveNewPid != null) { + query.eq(TaskListDetial::getPid, effectiveNewPid); + } else { + query.isNull(TaskListDetial::getPid); + } + } + query.ne(TaskListDetial::getId, movedId); + query.orderByAsc(TaskListDetial::getSortOrder); + List siblings = taskListDetialMapper.selectList(query); + + int pos = targetPosition != null ? targetPosition : siblings.size() + 1; + pos = Math.max(1, Math.min(pos, siblings.size() + 1)); + + int sort = 1; + for (int i = 0; i < siblings.size(); i++) { + if (sort == pos) { + sort++; + } + TaskListDetial sibling = siblings.get(i); + if (!sibling.getSortOrder().equals(sort)) { + taskListDetialMapper.updateSortOrder(sibling.getId(), sort); + } + sort++; + } + + taskListDetialMapper.updatePidAndSort(movedId, effectiveNewPid, pos); + } + + @Override + public void followTask(String taskId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + String userName = loginUser.getRealname(); + taskListDetialMapper.appendFollower(taskId, userId, userName); + } + + @Override + public void unfollowTask(String taskId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + String userName = loginUser.getRealname(); + taskListDetialMapper.removeFollower(taskId, userId, userName); + } + + @Override + public List loadSubTasks(String parentTaskId, Integer pageNo, Integer pageSize) { + if (pageNo == null || pageNo < 1) pageNo = 1; + if (pageSize == null || pageSize < 1) pageSize = 20; + int offset = (pageNo - 1) * pageSize; + List list = taskListDetialMapper.selectSubTasksByPage(parentTaskId, offset, pageSize); + fillCreateByName(list); + return list; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void ensureDefaultGroup(String mainId) { + TaskListDetial defaultGroup = findDefaultGroup(mainId); + if (defaultGroup == null) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + TaskListDetial group = new TaskListDetial(); + group.setMainId(mainId); + group.setTaskName("默认分组"); + group.setType("0"); + group.setPid(null); + group.setSortOrder(0); + group.setIsDefault(1); + group.setHasChild("0"); + group.setSubTaskCount(0); + group.setCompletedSubTaskCount(0); + group.setDelFlag("0"); + taskListDetialMapper.insert(group); + } + } + + private TaskListDetial findDefaultGroup(String mainId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(TaskListDetial::getMainId, mainId); + query.eq(TaskListDetial::getType, "0"); + query.eq(TaskListDetial::getIsDefault, 1); + query.last("LIMIT 1"); + TaskListDetial result = taskListDetialMapper.selectOne(query); + if (result != null) { + return result; + } + + query = new LambdaQueryWrapper<>(); + query.eq(TaskListDetial::getMainId, mainId); + query.eq(TaskListDetial::getType, "0"); + query.isNull(TaskListDetial::getIsDefault); + query.orderByAsc(TaskListDetial::getSortOrder); + query.last("LIMIT 1"); + result = taskListDetialMapper.selectOne(query); + if (result != null) { + result.setIsDefault(1); + taskListDetialMapper.updateById(result); + } + return result; + } + + private String getPermission(String mainId, String userId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(TaskListPermission::getMainId, mainId); + query.eq(TaskListPermission::getUserId, userId); + TaskListPermission perm = taskListPermissionMapper.selectOne(query); + return perm != null ? perm.getPermission() : null; + } + + private String normalizePid(String pid) { + return oConvertUtils.isNotEmpty(pid) ? pid : null; + } + + private void fillCreateByName(List list) { + if (list == null || list.isEmpty()) { + return; + } + for (TaskListDetial task : list) { + if (oConvertUtils.isNotEmpty(task.getCreateBy())) { + List users = sysBaseAPI.queryUsersByUsernames(task.getCreateBy()); + if (users != null && !users.isEmpty()) { + task.setCreateByName(users.get(0).getString("realname")); + } + } + if (oConvertUtils.isNotEmpty(task.getAssigneeId()) && oConvertUtils.isEmpty(task.getAssigneeName())) { + task.setAssigneeName(translateUserIdsToNames(task.getAssigneeId())); + } + if (oConvertUtils.isNotEmpty(task.getParticipantId()) && oConvertUtils.isEmpty(task.getParticipantName())) { + task.setParticipantName(translateUserIdsToNames(task.getParticipantId())); + } + if (oConvertUtils.isNotEmpty(task.getFollowersId()) && oConvertUtils.isEmpty(task.getFollowersName())) { + task.setFollowersName(translateUserIdsToNames(task.getFollowersId())); + } + } + } + + private String translateUserIdsToNames(String ids) { + if (oConvertUtils.isEmpty(ids)) { + return null; + } + String[] idArr = ids.split(","); + StringBuilder names = new StringBuilder(); + for (String id : idArr) { + if (oConvertUtils.isNotEmpty(id)) { + LoginUser user = sysBaseAPI.getUserById(id.trim()); + if (user != null) { + if (names.length() > 0) { + names.append(","); + } + names.append(user.getRealname()); + } + } + } + return names.length() > 0 ? names.toString() : null; + } + + private String mergeIds(String existingIds, String newIds) { + Set idSet = new LinkedHashSet<>(); + if (oConvertUtils.isNotEmpty(existingIds)) { + for (String id : existingIds.split(",")) { + String trimmed = id.trim(); + if (oConvertUtils.isNotEmpty(trimmed)) { + idSet.add(trimmed); + } + } + } + if (oConvertUtils.isNotEmpty(newIds)) { + for (String id : newIds.split(",")) { + String trimmed = id.trim(); + if (oConvertUtils.isNotEmpty(trimmed)) { + idSet.add(trimmed); + } + } + } + return idSet.isEmpty() ? null : String.join(",", idSet); + } + + private String filterUsersBySecLevel(String userIds, Integer listSecLevel) { + if (oConvertUtils.isEmpty(userIds)) return userIds; + if (listSecLevel == null) { + listSecLevel = 1; + } + String[] ids = userIds.split(","); + java.util.List validIds = new java.util.ArrayList<>(); + for (String id : ids) { + LoginUser user = sysBaseAPI.getUserById(id.trim()); + if (user == null) { + continue; + } + Integer userSecLevel = user.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + if (userSecLevel > listSecLevel) { + validIds.add(id.trim()); + } + } + return String.join(",", validIds); + } +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListFavoriteServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListFavoriteServiceImpl.java new file mode 100644 index 0000000..c758fbd --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListFavoriteServiceImpl.java @@ -0,0 +1,122 @@ +package org.jeecg.modules.demo.tasklist.service.impl; + +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import org.jeecg.modules.demo.tasklist.mapper.TaskListFavoriteMapper; +import org.jeecg.modules.demo.tasklist.service.ITaskListFavoriteService; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.transaction.annotation.Transactional; + +/** + * @Description: 任务清单收藏表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Service +public class TaskListFavoriteServiceImpl extends ServiceImpl implements ITaskListFavoriteService { + + @Autowired + private TaskListFavoriteMapper taskListFavoriteMapper; + + @Override + public List selectByMainId(String mainId) { + return taskListFavoriteMapper.selectByMainId(mainId); + } + + @Override + public Integer getMaxSortOrder(String userId, String pid) { + Integer max = taskListFavoriteMapper.selectMaxSortOrder(userId, pid); + return max != null ? max : 0; + } + + @Override + public Integer getMaxSortOrderByType(String userId, String pid, String type) { + Integer max = taskListFavoriteMapper.selectMaxSortOrderByType(userId, pid, type); + return max != null ? max : 0; + } + + @Override + public void shiftSortOrderUp(String userId, String pid, Integer fromSort) { + taskListFavoriteMapper.shiftSortOrderUp(userId, pid, fromSort); + } + + @Override + public void shiftSortOrderDown(String userId, String pid, Integer fromSort) { + taskListFavoriteMapper.shiftSortOrderDown(userId, pid, fromSort); + } + + @Override + public void shiftSortOrderUpByType(String userId, String type, Integer fromSort) { + taskListFavoriteMapper.shiftSortOrderUpByType(userId, type, fromSort); + } + + @Override + public void shiftSortOrderDownByType(String userId, String type, Integer fromSort) { + taskListFavoriteMapper.shiftSortOrderDownByType(userId, type, fromSort); + } + + @Override + public Integer countChildren(String userId, String pid) { + return taskListFavoriteMapper.countChildrenByPid(userId, pid); + } + + @Override + public void updatePidAndSort(String favoriteId, String pid, Integer sortOrder) { + taskListFavoriteMapper.updatePidAndSort(favoriteId, pid, sortOrder); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void reorderItem(String movedId, String userId, String pid, String type, + Integer targetPosition, String newPid) { + TaskListFavorite moved = taskListFavoriteMapper.selectById(movedId); + if (moved == null) { + throw new RuntimeException("记录不存在"); + } + + // 当 newPid 有值时使用 newPid(跨组移动),否则使用 pid(同组内移动) + // 关键:newPid="" 表示拖到根级别(无分组),此时应设为 null + String effectiveNewPid; + if (newPid != null) { + effectiveNewPid = newPid.isEmpty() ? null : newPid; + } else { + effectiveNewPid = pid; + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(TaskListFavorite::getUserId, userId); + query.eq(TaskListFavorite::getDelFlag, "0"); + if (type != null) { + query.eq(TaskListFavorite::getType, type); + } + if (effectiveNewPid != null) { + query.eq(TaskListFavorite::getPid, effectiveNewPid); + } else { + query.isNull(TaskListFavorite::getPid); + } + query.ne(TaskListFavorite::getId, movedId); + query.orderByAsc(TaskListFavorite::getSortOrder); + List siblings = taskListFavoriteMapper.selectList(query); + + int pos = targetPosition != null ? targetPosition : siblings.size() + 1; + pos = Math.max(1, Math.min(pos, siblings.size() + 1)); + + int sort = 1; + for (int i = 0; i < siblings.size(); i++) { + if (sort == pos) { + sort++; + } + TaskListFavorite sibling = siblings.get(i); + if (!sibling.getSortOrder().equals(sort)) { + taskListFavoriteMapper.updateSortOrder(sibling.getId(), sort); + } + sort++; + } + + taskListFavoriteMapper.updatePidAndSort(movedId, effectiveNewPid, pos); + } +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListPermissionServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListPermissionServiceImpl.java new file mode 100644 index 0000000..fc6a148 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListPermissionServiceImpl.java @@ -0,0 +1,27 @@ +package org.jeecg.modules.demo.tasklist.service.impl; + +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import org.jeecg.modules.demo.tasklist.mapper.TaskListPermissionMapper; +import org.jeecg.modules.demo.tasklist.service.ITaskListPermissionService; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: 任务清单权限表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Service +public class TaskListPermissionServiceImpl extends ServiceImpl implements ITaskListPermissionService { + + @Autowired + private TaskListPermissionMapper taskListPermissionMapper; + + @Override + public List selectByMainId(String mainId) { + return taskListPermissionMapper.selectByMainId(mainId); + } +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListServiceImpl.java new file mode 100644 index 0000000..0a5d63b --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/service/impl/TaskListServiceImpl.java @@ -0,0 +1,862 @@ +package org.jeecg.modules.demo.tasklist.service.impl; + +import org.jeecg.modules.demo.tasklist.entity.TaskList; +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import org.jeecg.modules.demo.tasklist.mapper.TaskListDetialMapper; +import org.jeecg.modules.demo.tasklist.mapper.TaskListPermissionMapper; +import org.jeecg.modules.demo.tasklist.mapper.TaskListFavoriteMapper; +import org.jeecg.modules.demo.tasklist.mapper.TaskListMapper; +import org.jeecg.modules.demo.tasklist.service.ITaskListService; +import org.jeecg.modules.demo.tasklist.service.ITaskListFavoriteService; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskListReq; +import org.jeecg.modules.demo.tasklist.vo.CreateTaskListGroupReq; +import org.jeecg.modules.demo.tasklist.vo.MoveTaskListReq; +import org.jeecg.modules.demo.tasklist.vo.AddCollaboratorReq; +import org.jeecg.modules.demo.tasklist.vo.CollaboratorVO; +import org.jeecg.common.system.api.ISysBaseAPI; +import org.jeecg.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.util.oConvertUtils; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Collection; +import java.util.Objects; + +/** + * @Description: 任务清单表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Service +public class TaskListServiceImpl extends ServiceImpl implements ITaskListService { + + @Autowired + private TaskListMapper taskListMapper; + @Autowired + private TaskListDetialMapper taskListDetialMapper; + @Autowired + private TaskListPermissionMapper taskListPermissionMapper; + @Autowired + private TaskListFavoriteMapper taskListFavoriteMapper; + @Autowired + private ITaskListFavoriteService taskListFavoriteService; + @Autowired + private ISysBaseAPI sysBaseAPI; + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(TaskList taskList, List taskListDetialList,List taskListPermissionList,List taskListFavoriteList) { + taskListMapper.insert(taskList); + if(taskListDetialList!=null && taskListDetialList.size()>0) { + for(TaskListDetial entity:taskListDetialList) { + //外键设置 + entity.setMainId(taskList.getId()); + taskListDetialMapper.insert(entity); + } + } + if(taskListPermissionList!=null && taskListPermissionList.size()>0) { + for(TaskListPermission entity:taskListPermissionList) { + //外键设置 + entity.setMainId(taskList.getId()); + taskListPermissionMapper.insert(entity); + } + } + if(taskListFavoriteList!=null && taskListFavoriteList.size()>0) { + for(TaskListFavorite entity:taskListFavoriteList) { + //外键设置 + entity.setMainId(taskList.getId()); + taskListFavoriteMapper.insert(entity); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(TaskList taskList,List taskListDetialList,List taskListPermissionList,List taskListFavoriteList) { + taskListMapper.updateById(taskList); + + //1.先删除子表数据 + taskListDetialMapper.deleteByMainId(taskList.getId()); + taskListPermissionMapper.deleteByMainId(taskList.getId()); + taskListFavoriteMapper.deleteByMainId(taskList.getId()); + + //2.子表数据重新插入 + if(taskListDetialList!=null && taskListDetialList.size()>0) { + for(TaskListDetial entity:taskListDetialList) { + //外键设置 + entity.setMainId(taskList.getId()); + taskListDetialMapper.insert(entity); + } + } + if(taskListPermissionList!=null && taskListPermissionList.size()>0) { + for(TaskListPermission entity:taskListPermissionList) { + //外键设置 + entity.setMainId(taskList.getId()); + taskListPermissionMapper.insert(entity); + } + } + if(taskListFavoriteList!=null && taskListFavoriteList.size()>0) { + for(TaskListFavorite entity:taskListFavoriteList) { + //外键设置 + entity.setMainId(taskList.getId()); + taskListFavoriteMapper.insert(entity); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + taskListDetialMapper.deleteByMainId(id); + taskListPermissionMapper.deleteByMainId(id); + taskListFavoriteMapper.deleteByMainId(id); + taskListMapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for(Serializable id:idList) { + taskListDetialMapper.deleteByMainId(id.toString()); + taskListPermissionMapper.deleteByMainId(id.toString()); + taskListFavoriteMapper.deleteByMainId(id.toString()); + taskListMapper.deleteById(id); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String createTaskList(CreateTaskListReq req) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + Integer userSecLevel = loginUser.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + + if (req.getSecretLevel() != null && req.getSecretLevel() >= userSecLevel) { + throw new RuntimeException("您无权创建该密级的清单"); + } + + if (oConvertUtils.isNotEmpty(req.getPid())) { + TaskListFavorite groupFav = taskListFavoriteMapper.selectById(req.getPid()); + if (groupFav == null || !"0".equals(groupFav.getType()) || !userId.equals(groupFav.getUserId())) { + throw new RuntimeException("目标分组不存在或无权限"); + } + } + + TaskList taskList = new TaskList(); + taskList.setTasklistName(req.getTasklistName()); + taskList.setSecretLevel(req.getSecretLevel()); + taskList.setSecretText(getSecretText(req.getSecretLevel())); + taskListMapper.insert(taskList); + + TaskListDetial defaultGroup = new TaskListDetial(); + defaultGroup.setMainId(taskList.getId()); + defaultGroup.setTaskName("默认分组"); + defaultGroup.setType("0"); + defaultGroup.setPid(null); + defaultGroup.setSortOrder(0); + defaultGroup.setIsDefault(1); + defaultGroup.setHasChild("0"); + defaultGroup.setSubTaskCount(0); + defaultGroup.setCompletedSubTaskCount(0); + defaultGroup.setDelFlag("0"); + taskListDetialMapper.insert(defaultGroup); + + TaskListPermission permission = new TaskListPermission(); + permission.setMainId(taskList.getId()); + permission.setUserId(userId); + permission.setPermission("1"); + taskListPermissionMapper.insert(permission); + + if (oConvertUtils.isNotEmpty(req.getPid())) { + TaskListFavorite parentFav = new TaskListFavorite(); + parentFav.setId(req.getPid()); + parentFav.setHasChild("1"); + taskListFavoriteMapper.updateById(parentFav); + } + + return taskList.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String createTaskListGroup(CreateTaskListGroupReq req) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + Integer sortOrder = 1; + taskListFavoriteMapper.shiftSortOrderUpByType(userId, "0", sortOrder); + + TaskListFavorite favorite = new TaskListFavorite(); + favorite.setMainId(null); + favorite.setUserId(userId); + favorite.setType("0"); + favorite.setPid(null); + favorite.setHasChild("0"); + favorite.setSortOrder(sortOrder); + favorite.setTasklistName(req.getTasklistName()); + taskListFavoriteMapper.insert(favorite); + + return favorite.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void moveTaskList(MoveTaskListReq req) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListFavorite favorite = taskListFavoriteMapper.selectById(req.getFavoriteId()); + if (favorite == null || !userId.equals(favorite.getUserId())) { + throw new RuntimeException("无权限操作此记录"); + } + if ("0".equals(favorite.getType())) { + throw new RuntimeException("分组不支持移动操作"); + } + + String oldPid = normalizePid(favorite.getPid()); + + String newPid = null; + if (req.getTargetGroupId() != null) { + if (oConvertUtils.isNotEmpty(req.getTargetGroupId())) { + TaskListFavorite targetGroup = taskListFavoriteMapper.selectById(req.getTargetGroupId()); + if (targetGroup == null || !"0".equals(targetGroup.getType()) || !userId.equals(targetGroup.getUserId())) { + throw new RuntimeException("目标分组不存在或无权限"); + } + newPid = normalizePid(req.getTargetGroupId()); + } else { + newPid = ""; + } + } + + // 调用纯排序方法 + taskListFavoriteService.reorderItem(req.getFavoriteId(), userId, oldPid, "1", req.getSortOrder(), newPid); + + // 维护旧父节点 hasChild + if (oConvertUtils.isNotEmpty(oldPid) && !oldPid.equals(newPid)) { + Integer remainCount = taskListFavoriteService.countChildren(userId, oldPid); + if (remainCount == null || remainCount == 0) { + TaskListFavorite oldParent = new TaskListFavorite(); + oldParent.setId(oldPid); + oldParent.setHasChild("0"); + taskListFavoriteMapper.updateById(oldParent); + } + } + + // 维护新父节点 hasChild + if (oConvertUtils.isNotEmpty(newPid)) { + TaskListFavorite newParent = new TaskListFavorite(); + newParent.setId(newPid); + newParent.setHasChild("1"); + taskListFavoriteMapper.updateById(newParent); + } + } + + @Override + public List getMyFavorites() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + Integer userSecLevel = loginUser.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + + QueryWrapper query = new QueryWrapper<>(); + query.eq("user_id", userId); + query.eq("del_flag", "0"); + query.orderByAsc("type"); + query.orderByAsc("sort_order"); + List favorites = taskListFavoriteMapper.selectList(query); + + List mainIds = new java.util.ArrayList<>(); + for (TaskListFavorite fav : favorites) { + if ("1".equals(fav.getType()) && fav.getMainId() != null) { + mainIds.add(fav.getMainId()); + } + } + + java.util.Map listMap = new java.util.HashMap<>(); + if (!mainIds.isEmpty()) { + List lists = taskListMapper.selectBatchIds(mainIds); + for (TaskList tl : lists) { + listMap.put(tl.getId(), tl); + } + } + + List result = new java.util.ArrayList<>(); + for (TaskListFavorite fav : favorites) { + if ("1".equals(fav.getType()) && fav.getMainId() != null) { + TaskList tl = listMap.get(fav.getMainId()); + if (tl == null) continue; + + Integer listSecLevel = tl.getSecretLevel() != null ? tl.getSecretLevel() : 1; + if (userSecLevel <= listSecLevel) { + continue; + } + fav.setTasklistName(tl.getTasklistName()); + fav.setSecretLevel(tl.getSecretLevel()); + fav.setSecretText(tl.getSecretText()); + + LambdaQueryWrapper permQuery = new LambdaQueryWrapper<>(); + permQuery.eq(TaskListPermission::getMainId, fav.getMainId()); + permQuery.eq(TaskListPermission::getUserId, userId); + TaskListPermission perm = taskListPermissionMapper.selectOne(permQuery); + if (perm != null) { + fav.setPermission(perm.getPermission()); + } + result.add(fav); + } else { + result.add(fav); + } + } + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteTaskList(String taskListId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + LambdaQueryWrapper permCheck = new LambdaQueryWrapper<>(); + permCheck.eq(TaskListPermission::getMainId, taskListId); + permCheck.eq(TaskListPermission::getUserId, userId); + permCheck.eq(TaskListPermission::getPermission, "1"); + Long count = taskListPermissionMapper.selectCount(permCheck); + if (count == 0) { + throw new RuntimeException("仅所有者可删除任务清单"); + } + + taskListMapper.deleteById(taskListId); + + LambdaQueryWrapper detailQuery = new LambdaQueryWrapper<>(); + detailQuery.eq(TaskListDetial::getMainId, taskListId); + taskListDetialMapper.delete(detailQuery); + + LambdaQueryWrapper permQuery = new LambdaQueryWrapper<>(); + permQuery.eq(TaskListPermission::getMainId, taskListId); + taskListPermissionMapper.delete(permQuery); + + LambdaQueryWrapper favQuery = new LambdaQueryWrapper<>(); + favQuery.eq(TaskListFavorite::getMainId, taskListId); + List favs = taskListFavoriteMapper.selectList(favQuery); + for (TaskListFavorite fav : favs) { + String favUserId = fav.getUserId(); + taskListFavoriteMapper.deleteById(fav.getId()); + if (fav.getPid() != null) { + Integer remainCount = taskListFavoriteService.countChildren(favUserId, fav.getPid()); + if (remainCount == 0) { + TaskListFavorite parentUpdate = new TaskListFavorite(); + parentUpdate.setId(fav.getPid()); + parentUpdate.setHasChild("0"); + taskListFavoriteMapper.updateById(parentUpdate); + } + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeFavorite(String favoriteId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListFavorite fav = taskListFavoriteMapper.selectById(favoriteId); + if (fav == null || !userId.equals(fav.getUserId())) { + throw new RuntimeException("无权限操作此记录"); + } + + taskListFavoriteMapper.deleteById(favoriteId); + + if (fav.getPid() != null) { + Integer remainCount = taskListFavoriteService.countChildren(userId, fav.getPid()); + if (remainCount == 0) { + TaskListFavorite parentUpdate = new TaskListFavorite(); + parentUpdate.setId(fav.getPid()); + parentUpdate.setHasChild("0"); + taskListFavoriteMapper.updateById(parentUpdate); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeFavoriteGroup(String groupId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListFavorite groupFav = taskListFavoriteMapper.selectById(groupId); + if (groupFav == null || !userId.equals(groupFav.getUserId()) || !"0".equals(groupFav.getType())) { + throw new RuntimeException("分组不存在或无权限"); + } + + taskListFavoriteMapper.deleteById(groupId); + + LambdaQueryWrapper childQuery = new LambdaQueryWrapper<>(); + childQuery.eq(TaskListFavorite::getPid, groupId); + childQuery.eq(TaskListFavorite::getUserId, userId); + List children = taskListFavoriteMapper.selectList(childQuery); + for (TaskListFavorite child : children) { + taskListFavoriteMapper.deleteById(child.getId()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void renameGroup(String groupId, String newName) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListFavorite groupFav = taskListFavoriteMapper.selectById(groupId); + if (groupFav == null || !userId.equals(groupFav.getUserId()) || !"0".equals(groupFav.getType())) { + throw new RuntimeException("分组不存在或无权限"); + } + + groupFav.setTasklistName(newName); + taskListFavoriteMapper.updateById(groupFav); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void moveGroup(String groupId, Integer sortOrder) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskListFavorite group = taskListFavoriteMapper.selectById(groupId); + if (group == null || !userId.equals(group.getUserId()) || !"0".equals(group.getType())) { + throw new RuntimeException("分组不存在或无权限"); + } + + taskListFavoriteService.reorderItem(groupId, userId, null, "0", sortOrder, null); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void renameTaskList(String taskListId, String newName) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + TaskList taskList = taskListMapper.selectById(taskListId); + if (taskList == null) { + throw new RuntimeException("清单不存在"); + } + + LambdaQueryWrapper permQuery = new LambdaQueryWrapper<>(); + permQuery.eq(TaskListPermission::getMainId, taskListId); + permQuery.eq(TaskListPermission::getUserId, userId); + permQuery.in(TaskListPermission::getPermission, "1", "2"); + boolean hasPermission = taskListPermissionMapper.exists(permQuery); + + if (!hasPermission) { + throw new RuntimeException("清单不存在或无权限"); + } + + taskList.setTasklistName(newName); + taskListMapper.updateById(taskList); + + LambdaQueryWrapper favQuery = new LambdaQueryWrapper<>(); + favQuery.eq(TaskListFavorite::getMainId, taskListId); + List favs = taskListFavoriteMapper.selectList(favQuery); + for (TaskListFavorite fav : favs) { + fav.setTasklistName(newName); + taskListFavoriteMapper.updateById(fav); + } + } + + @Override + public List getMyOwnLists() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + Integer userSecLevel = loginUser.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + final Integer finalUserSecLevel = userSecLevel; + + LambdaQueryWrapper permQuery = new LambdaQueryWrapper<>(); + permQuery.eq(TaskListPermission::getUserId, userId); + permQuery.eq(TaskListPermission::getPermission, "1"); + List perms = taskListPermissionMapper.selectList(permQuery); + + List mainIds = perms.stream().map(TaskListPermission::getMainId).collect(java.util.stream.Collectors.toList()); + if (mainIds.isEmpty()) { + return java.util.Collections.emptyList(); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(TaskList::getId, mainIds); + query.and(w -> w.lt(TaskList::getSecretLevel, finalUserSecLevel).or().isNull(TaskList::getSecretLevel)); + query.orderByAsc(TaskList::getCreateTime); + return enrichListSummaries(taskListMapper.selectList(query)); + } + + @Override + public List getAllLists() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + Integer userSecLevel = loginUser.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + String orgCode = loginUser.getOrgCode(); + + List lists = taskListMapper.selectVisibleLists(userId, userSecLevel, orgCode); + return enrichListSummaries(lists); + } + + @Override + public List getMyCollabLists() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + Integer userSecLevel = loginUser.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + final Integer finalUserSecLevel = userSecLevel; + + LambdaQueryWrapper permQuery = new LambdaQueryWrapper<>(); + permQuery.eq(TaskListPermission::getUserId, userId); + permQuery.ne(TaskListPermission::getPermission, "1"); + List perms = taskListPermissionMapper.selectList(permQuery); + + List mainIds = perms.stream().map(TaskListPermission::getMainId).collect(java.util.stream.Collectors.toList()); + if (mainIds.isEmpty()) { + return java.util.Collections.emptyList(); + } + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(TaskList::getId, mainIds); + query.and(w -> w.lt(TaskList::getSecretLevel, finalUserSecLevel).or().isNull(TaskList::getSecretLevel)); + query.orderByAsc(TaskList::getCreateTime); + return enrichListSummaries(taskListMapper.selectList(query)); + } + + private String normalizePid(String pid) { + return oConvertUtils.isNotEmpty(pid) ? pid : null; + } + + private List enrichListSummaries(List lists) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + for (TaskList list : lists) { + if (list.getCreateTime() != null) { + list.setCreateTimeStr(sdf.format(list.getCreateTime())); + } + + LambdaQueryWrapper ownerQuery = new LambdaQueryWrapper<>(); + ownerQuery.eq(TaskListPermission::getMainId, list.getId()); + ownerQuery.eq(TaskListPermission::getPermission, "1"); + TaskListPermission owner = taskListPermissionMapper.selectOne(ownerQuery); + if (owner != null) { + LoginUser ownerUser = sysBaseAPI.getUserById(owner.getUserId()); + if (ownerUser != null) { + list.setOwnerName(ownerUser.getRealname()); + } + } + + LambdaQueryWrapper collabQuery = new LambdaQueryWrapper<>(); + collabQuery.eq(TaskListPermission::getMainId, list.getId()); + collabQuery.ne(TaskListPermission::getPermission, "1"); + List collabs = taskListPermissionMapper.selectList(collabQuery); + if (!collabs.isEmpty()) { + List collabUserIds = collabs.stream().map(TaskListPermission::getUserId).collect(java.util.stream.Collectors.toList()); + List collabNames = new java.util.ArrayList<>(); + for (String collabUserId : collabUserIds) { + LoginUser collabUser = sysBaseAPI.getUserById(collabUserId); + if (collabUser != null && collabUser.getRealname() != null) { + collabNames.add(collabUser.getRealname()); + } + } + list.setCollaboratorNames(String.join(", ", collabNames)); + } + } + return lists; + } + + @Override + public List getCollaborators(String taskListId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(TaskListPermission::getMainId, taskListId); + query.orderByAsc(TaskListPermission::getCreateTime); + List perms = taskListPermissionMapper.selectList(query); + + List result = new java.util.ArrayList<>(); + for (TaskListPermission perm : perms) { + CollaboratorVO vo = new CollaboratorVO(); + vo.setPermissionId(perm.getId()); + vo.setUserId(perm.getUserId()); + vo.setPermission(perm.getPermission()); + LoginUser user = sysBaseAPI.getUserById(perm.getUserId()); + if (user != null) { + vo.setUsername(user.getRealname()); + } + result.add(vo); + } + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void addCollaborator(AddCollaboratorReq req) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String currentUserId = loginUser.getId(); + + LambdaQueryWrapper ownerCheck = new LambdaQueryWrapper<>(); + ownerCheck.eq(TaskListPermission::getMainId, req.getTaskListId()); + ownerCheck.eq(TaskListPermission::getUserId, currentUserId); + ownerCheck.eq(TaskListPermission::getPermission, "1"); + Long ownerCount = taskListPermissionMapper.selectCount(ownerCheck); + if (ownerCount == 0) { + throw new RuntimeException("仅所有者可添加协作人"); + } + + if (!"2".equals(req.getPermission()) && !"3".equals(req.getPermission())) { + throw new RuntimeException("权限类型无效,仅支持可阅读(2)或可编辑(3)"); + } + + TaskList taskList = taskListMapper.selectById(req.getTaskListId()); + if (taskList == null) { + throw new RuntimeException("清单不存在"); + } + + LoginUser targetUser = sysBaseAPI.getUserById(req.getUserId()); + if (targetUser == null) { + throw new RuntimeException("用户不存在"); + } + + Integer targetUserSecLevel = targetUser.getUserSecurityLevel(); + Integer listSecLevel = taskList.getSecretLevel(); + if (listSecLevel == null) { + listSecLevel = 1; + } + if (targetUserSecLevel == null) { + targetUserSecLevel = 3; + } + + if (targetUserSecLevel <= listSecLevel) { + throw new RuntimeException("该用户密级不足,无法添加为协作人"); + } + + LambdaQueryWrapper existCheck = new LambdaQueryWrapper<>(); + existCheck.eq(TaskListPermission::getMainId, req.getTaskListId()); + existCheck.eq(TaskListPermission::getUserId, req.getUserId()); + Long existCount = taskListPermissionMapper.selectCount(existCheck); + if (existCount > 0) { + throw new RuntimeException("该用户已是协作人"); + } + + TaskListPermission permission = new TaskListPermission(); + permission.setMainId(req.getTaskListId()); + permission.setUserId(req.getUserId()); + permission.setPermission(req.getPermission()); + taskListPermissionMapper.insert(permission); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeCollaborator(String permissionId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String currentUserId = loginUser.getId(); + + TaskListPermission perm = taskListPermissionMapper.selectById(permissionId); + if (perm == null) { + throw new RuntimeException("权限记录不存在"); + } + if ("1".equals(perm.getPermission())) { + throw new RuntimeException("不能移除所有者"); + } + + LambdaQueryWrapper ownerCheck = new LambdaQueryWrapper<>(); + ownerCheck.eq(TaskListPermission::getMainId, perm.getMainId()); + ownerCheck.eq(TaskListPermission::getUserId, currentUserId); + ownerCheck.eq(TaskListPermission::getPermission, "1"); + Long ownerCount = taskListPermissionMapper.selectCount(ownerCheck); + if (ownerCount == 0) { + throw new RuntimeException("仅所有者可移除协作人"); + } + + taskListPermissionMapper.deleteById(permissionId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCollaboratorPermission(String permissionId, String newPermission) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String currentUserId = loginUser.getId(); + + TaskListPermission perm = taskListPermissionMapper.selectById(permissionId); + if (perm == null) { + throw new RuntimeException("权限记录不存在"); + } + if ("1".equals(perm.getPermission())) { + throw new RuntimeException("不能修改所有者权限"); + } + if (!"2".equals(newPermission) && !"3".equals(newPermission)) { + throw new RuntimeException("权限类型无效"); + } + + LambdaQueryWrapper ownerCheck = new LambdaQueryWrapper<>(); + ownerCheck.eq(TaskListPermission::getMainId, perm.getMainId()); + ownerCheck.eq(TaskListPermission::getUserId, currentUserId); + ownerCheck.eq(TaskListPermission::getPermission, "1"); + Long ownerCount = taskListPermissionMapper.selectCount(ownerCheck); + if (ownerCount == 0) { + throw new RuntimeException("仅所有者可修改协作人权限"); + } + + TaskListPermission update = new TaskListPermission(); + update.setId(permissionId); + update.setPermission(newPermission); + taskListPermissionMapper.updateById(update); + } + + @Override + public String getMyPermission(String taskListId) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(TaskListPermission::getMainId, taskListId); + query.eq(TaskListPermission::getUserId, userId); + TaskListPermission perm = taskListPermissionMapper.selectOne(query); + return perm != null ? perm.getPermission() : null; + } + + @Override + public void addToFavorites(String taskListId, String pid) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = loginUser.getId(); + Integer userSecLevel = loginUser.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + + TaskList taskList = taskListMapper.selectById(taskListId); + if (taskList == null) { + throw new RuntimeException("清单不存在"); + } + + Integer listSecLevel = taskList.getSecretLevel(); + if (listSecLevel == null) { + listSecLevel = 1; + } + if (userSecLevel <= listSecLevel) { + throw new RuntimeException("您无权收藏该密级的清单"); + } + + LambdaQueryWrapper existCheck = new LambdaQueryWrapper<>(); + existCheck.eq(TaskListFavorite::getMainId, taskListId); + existCheck.eq(TaskListFavorite::getUserId, userId); + existCheck.eq(TaskListFavorite::getType, "1"); + existCheck.eq(TaskListFavorite::getDelFlag, "0"); + TaskListFavorite existFav = taskListFavoriteMapper.selectOne(existCheck); + if (existFav != null) { + throw new RuntimeException("该清单已在收藏中"); + } + + LambdaQueryWrapper reactivateCheck = new LambdaQueryWrapper<>(); + reactivateCheck.eq(TaskListFavorite::getMainId, taskListId); + reactivateCheck.eq(TaskListFavorite::getUserId, userId); + reactivateCheck.eq(TaskListFavorite::getType, "1"); + reactivateCheck.eq(TaskListFavorite::getDelFlag, "1"); + TaskListFavorite softDeletedFav = taskListFavoriteMapper.selectOne(reactivateCheck); + if (softDeletedFav != null) { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("id", softDeletedFav.getId()); + uw.set("del_flag", "0"); + taskListFavoriteMapper.update(null, uw); + if (softDeletedFav.getPid() != null) { + TaskListFavorite parentUpdate = new TaskListFavorite(); + parentUpdate.setId(softDeletedFav.getPid()); + parentUpdate.setHasChild("1"); + taskListFavoriteMapper.updateById(parentUpdate); + } + return; + } + + String normalizedPid = oConvertUtils.isNotEmpty(pid) ? pid : null; + if (normalizedPid != null) { + TaskListFavorite groupFav = taskListFavoriteMapper.selectById(normalizedPid); + if (groupFav == null || !"0".equals(groupFav.getType()) || !userId.equals(groupFav.getUserId())) { + throw new RuntimeException("目标分组不存在或无权限"); + } + } + + Integer maxSort = taskListFavoriteService.getMaxSortOrderByType(userId, normalizedPid, "1"); + TaskListFavorite favorite = new TaskListFavorite(); + favorite.setMainId(taskListId); + favorite.setUserId(userId); + favorite.setType("1"); + favorite.setPid(normalizedPid); + favorite.setHasChild("0"); + favorite.setSortOrder(maxSort + 1); + favorite.setTasklistName(taskList.getTasklistName()); + taskListFavoriteMapper.insert(favorite); + + if (normalizedPid != null) { + TaskListFavorite parentFav = new TaskListFavorite(); + parentFav.setId(normalizedPid); + parentFav.setHasChild("1"); + taskListFavoriteMapper.updateById(parentFav); + } + } + + @Override + public List myResponsibleTasks() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + return taskListDetialMapper.selectByAssigneeId(loginUser.getId(), loginUser.getId()); + } + + @Override + public List myFollowedTasks() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + return taskListDetialMapper.selectByFollowersId(loginUser.getId(), loginUser.getId()); + } + + private String getSecretText(Integer level) { + if (level == null) return "非密"; + switch (level) { + case 1: return "非密"; + case 2: return "内部"; + case 3: return "秘密"; + case 4: return "机密"; + default: return "非密"; + } + } + + private String filterUsersBySecLevel(String userIds, Integer listSecLevel) { + if (oConvertUtils.isEmpty(userIds)) return userIds; + if (listSecLevel == null) { + listSecLevel = 1; + } + String[] ids = userIds.split(","); + java.util.List validIds = new java.util.ArrayList<>(); + for (String id : ids) { + LoginUser user = sysBaseAPI.getUserById(id.trim()); + if (user == null) { + continue; + } + Integer userSecLevel = user.getUserSecurityLevel(); + if (userSecLevel == null) { + userSecLevel = 3; + } + if (userSecLevel > listSecLevel) { + validIds.add(id.trim()); + } + } + return String.join(",", validIds); + } + +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/AddCollaboratorReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/AddCollaboratorReq.java new file mode 100644 index 0000000..abf7262 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/AddCollaboratorReq.java @@ -0,0 +1,18 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "添加协作人请求") +public class AddCollaboratorReq { + + @Schema(description = "清单ID") + private String taskListId; + + @Schema(description = "被添加的用户ID") + private String userId; + + @Schema(description = "权限类型: 2=可编辑 3=可阅读") + private String permission; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CollaboratorVO.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CollaboratorVO.java new file mode 100644 index 0000000..58f5d83 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CollaboratorVO.java @@ -0,0 +1,21 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "协作人信息") +public class CollaboratorVO { + + @Schema(description = "权限记录ID") + private String permissionId; + + @Schema(description = "用户ID") + private String userId; + + @Schema(description = "用户姓名") + private String username; + + @Schema(description = "权限类型: 1=所有者 2=可编辑 3=可阅读") + private String permission; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskListGroupReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskListGroupReq.java new file mode 100644 index 0000000..cd0f242 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskListGroupReq.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "创建任务清单分组请求") +public class CreateTaskListGroupReq { + + @Schema(description = "分组名称") + private String tasklistName; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskListReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskListReq.java new file mode 100644 index 0000000..d59e601 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskListReq.java @@ -0,0 +1,21 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "创建任务清单请求") +public class CreateTaskListReq { + + @Schema(description = "清单名称") + private String tasklistName; + + @Schema(description = "父分组ID(可选,不传则放在根级别)") + private String pid; + + @Schema(description = "目标排序位置(可选,不传则追加到末尾)") + private Integer sortOrder; + + @Schema(description = "密级:1=非密,2=内部,3=秘密,4=机密") + private Integer secretLevel; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskReq.java new file mode 100644 index 0000000..c735048 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/CreateTaskReq.java @@ -0,0 +1,45 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +@Data +@Schema(description = "创建任务请求") +public class CreateTaskReq { + + @Schema(description = "所属清单ID") + private String mainId; + + @Schema(description = "任务名称") + private String taskName; + + @Schema(description = "任务描述") + private String taskDesc; + + @Schema(description = "优先级") + private String priority; + + @Schema(description = "类型:0=任务分组,1=普通任务") + private String type; + + @Schema(description = "父节点ID(分组ID或父任务ID,为空则归入默认分组)") + private String pid; + + @Schema(description = "负责人ID") + private String assigneeId; + + @Schema(description = "开始时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date startTime; + + @Schema(description = "结束时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date endTime; + + @Schema(description = "排序号(指定则在指定位置插入)") + private Integer sortOrder; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/MoveTaskListReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/MoveTaskListReq.java new file mode 100644 index 0000000..2316e76 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/MoveTaskListReq.java @@ -0,0 +1,18 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "拖拽移动任务清单请求") +public class MoveTaskListReq { + + @Schema(description = "被移动的清单对应的 favorite 记录ID") + private String favoriteId; + + @Schema(description = "目标分组ID(null 或空字符串表示移动到根级别)") + private String targetGroupId; + + @Schema(description = "目标位置排序号(可选,不传则追加到末尾)") + private Integer sortOrder; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/MoveTaskReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/MoveTaskReq.java new file mode 100644 index 0000000..a842689 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/MoveTaskReq.java @@ -0,0 +1,18 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "拖拽移动任务请求") +public class MoveTaskReq { + + @Schema(description = "任务ID") + private String taskId; + + @Schema(description = "目标父节点ID(分组ID或父任务ID,为空表示移入默认分组)") + private String targetPid; + + @Schema(description = "目标位置排序号(可选,不传则追加到末尾)") + private Integer targetSortOrder; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/SubTaskPageReq.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/SubTaskPageReq.java new file mode 100644 index 0000000..4a32552 --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/SubTaskPageReq.java @@ -0,0 +1,18 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import lombok.Data; +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@Schema(description = "子任务分页请求") +public class SubTaskPageReq { + + @Schema(description = "父任务ID") + private String parentTaskId; + + @Schema(description = "页码,默认1") + private Integer pageNo = 1; + + @Schema(description = "每页条数,默认20") + private Integer pageSize = 20; +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/TaskListPage.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/TaskListPage.java new file mode 100644 index 0000000..16f911a --- /dev/null +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/tasklist/vo/TaskListPage.java @@ -0,0 +1,82 @@ +package org.jeecg.modules.demo.tasklist.vo; + +import java.util.List; +import org.jeecg.modules.demo.tasklist.entity.TaskList; +import org.jeecg.modules.demo.tasklist.entity.TaskListDetial; +import org.jeecg.modules.demo.tasklist.entity.TaskListPermission; +import org.jeecg.modules.demo.tasklist.entity.TaskListFavorite; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecgframework.poi.excel.annotation.ExcelEntity; +import org.jeecgframework.poi.excel.annotation.ExcelCollection; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import java.util.Date; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: 任务清单表 + * @Author: jeecg-boot + * @Date: 2026-04-24 + * @Version: V1.0 + */ +@Data +@Schema(description="任务清单表") +public class TaskListPage { + + /**主键*/ + @Schema(description = "主键") + private java.lang.String id; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; + /**所属部门*/ + @Schema(description = "所属部门") + private java.lang.String sysOrgCode; + /**清单名称*/ + @Excel(name = "清单名称", width = 15) + @Schema(description = "清单名称") + private java.lang.String tasklistName; + /**删除标识*/ + @Excel(name = "删除标识", width = 15) + @Schema(description = "删除标识") + private java.lang.String delFlag; + + @ExcelCollection(name="任务清单详情表") + @Schema(description = "任务清单详情表") + private List taskListDetialList; + @ExcelCollection(name="任务清单权限表") + @Schema(description = "任务清单权限表") + private List taskListPermissionList; + /**密级: 1=非密, 2=内部, 3=秘密, 4=机密*/ + @Excel(name = "密级", width = 15) + @Schema(description = "密级:1=非密,2=内部,3=秘密,4=机密") + private java.lang.Integer secretLevel; + + /**密级文本*/ + @Excel(name = "密级文本", width = 15) + @Schema(description = "密级文本") + private java.lang.String secretText; + + @ExcelCollection(name="任务清单收藏表") + @Schema(description = "任务清单收藏表") + private List taskListFavoriteList; + +} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/controller/TestMainTableController.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/controller/TestMainTableController.java deleted file mode 100644 index 5cf41b6..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/controller/TestMainTableController.java +++ /dev/null @@ -1,270 +0,0 @@ -package org.jeecg.modules.test.controller; - -import java.io.UnsupportedEncodingException; -import java.io.IOException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.HashMap; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.jeecgframework.poi.excel.ExcelImportUtil; -import org.jeecgframework.poi.excel.def.NormalExcelConstants; -import org.jeecgframework.poi.excel.entity.ExportParams; -import org.jeecgframework.poi.excel.entity.ImportParams; -import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; -import org.jeecg.common.system.vo.LoginUser; -import org.apache.shiro.SecurityUtils; -import org.jeecg.common.api.vo.Result; -import org.jeecg.common.system.query.QueryGenerator; -import org.jeecg.common.system.query.QueryRuleEnum; -import org.jeecg.common.util.oConvertUtils; -import org.jeecg.modules.test.entity.TestSonTable; -import org.jeecg.modules.test.entity.TestMainTable; -import org.jeecg.modules.test.vo.TestMainTablePage; -import org.jeecg.modules.test.service.ITestMainTableService; -import org.jeecg.modules.test.service.ITestSonTableService; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; -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 com.alibaba.fastjson.JSON; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import org.jeecg.common.aspect.annotation.AutoLog; -import org.apache.shiro.authz.annotation.RequiresPermissions; - - - /** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -@Tag(name="test") -@RestController -@RequestMapping("/test/testMainTable") -@Slf4j -public class TestMainTableController { - @Autowired - private ITestMainTableService testMainTableService; - @Autowired - private ITestSonTableService testSonTableService; - - /** - * 分页列表查询 - * - * @param testMainTable - * @param pageNo - * @param pageSize - * @param req - * @return - */ - //@AutoLog(value = "test-分页列表查询") - @Operation(summary="test-分页列表查询") - @GetMapping(value = "/list") - public Result> queryPageList(TestMainTable testMainTable, - @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, - @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, - HttpServletRequest req) { - QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(testMainTable, req.getParameterMap()); - Page page = new Page(pageNo, pageSize); - IPage pageList = testMainTableService.page(page, queryWrapper); - return Result.OK(pageList); - } - - /** - * 添加 - * - * @param testMainTablePage - * @return - */ - @AutoLog(value = "test-添加") - @Operation(summary="test-添加") - @RequiresPermissions("test:test_main_table:add") - @PostMapping(value = "/add") - public Result add(@RequestBody TestMainTablePage testMainTablePage) { - TestMainTable testMainTable = new TestMainTable(); - BeanUtils.copyProperties(testMainTablePage, testMainTable); - testMainTableService.saveMain(testMainTable, testMainTablePage.getTestSonTableList()); - return Result.OK("添加成功!"); - } - - /** - * 编辑 - * - * @param testMainTablePage - * @return - */ - @AutoLog(value = "test-编辑") - @Operation(summary="test-编辑") - @RequiresPermissions("test:test_main_table:edit") - @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) - public Result edit(@RequestBody TestMainTablePage testMainTablePage) { - TestMainTable testMainTable = new TestMainTable(); - BeanUtils.copyProperties(testMainTablePage, testMainTable); - TestMainTable testMainTableEntity = testMainTableService.getById(testMainTable.getId()); - if(testMainTableEntity==null) { - return Result.error("未找到对应数据"); - } - testMainTableService.updateMain(testMainTable, testMainTablePage.getTestSonTableList()); - return Result.OK("编辑成功!"); - } - - /** - * 通过id删除 - * - * @param id - * @return - */ - @AutoLog(value = "test-通过id删除") - @Operation(summary="test-通过id删除") - @RequiresPermissions("test:test_main_table:delete") - @DeleteMapping(value = "/delete") - public Result delete(@RequestParam(name="id",required=true) String id) { - testMainTableService.delMain(id); - return Result.OK("删除成功!"); - } - - /** - * 批量删除 - * - * @param ids - * @return - */ - @AutoLog(value = "test-批量删除") - @Operation(summary="test-批量删除") - @RequiresPermissions("test:test_main_table:deleteBatch") - @DeleteMapping(value = "/deleteBatch") - public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { - this.testMainTableService.delBatchMain(Arrays.asList(ids.split(","))); - return Result.OK("批量删除成功!"); - } - - /** - * 通过id查询 - * - * @param id - * @return - */ - //@AutoLog(value = "test-通过id查询") - @Operation(summary="test-通过id查询") - @GetMapping(value = "/queryById") - public Result queryById(@RequestParam(name="id",required=true) String id) { - TestMainTable testMainTable = testMainTableService.getById(id); - if(testMainTable==null) { - return Result.error("未找到对应数据"); - } - return Result.OK(testMainTable); - - } - - /** - * 通过id查询 - * - * @param id - * @return - */ - //@AutoLog(value = "test通过主表ID查询") - @Operation(summary="test主表ID查询") - @GetMapping(value = "/queryTestSonTableByMainId") - public Result> queryTestSonTableListByMainId(@RequestParam(name="id",required=true) String id) { - List testSonTableList = testSonTableService.selectByMainId(id); - return Result.OK(testSonTableList); - } - - /** - * 导出excel - * - * @param request - * @param testMainTable - */ - @RequiresPermissions("test:test_main_table:exportXls") - @RequestMapping(value = "/exportXls") - public ModelAndView exportXls(HttpServletRequest request, TestMainTable testMainTable) { - - // Step.1 组装查询条件查询数据 - QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(testMainTable, request.getParameterMap()); - LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); - - //配置选中数据查询条件 - String selections = request.getParameter("selections"); - if(oConvertUtils.isNotEmpty(selections)) { - List selectionList = Arrays.asList(selections.split(",")); - queryWrapper.in("id",selectionList); - } - //Step.2 获取导出数据 - List testMainTableList = testMainTableService.list(queryWrapper); - - // Step.3 组装pageList - List pageList = new ArrayList(); - for (TestMainTable main : testMainTableList) { - TestMainTablePage vo = new TestMainTablePage(); - BeanUtils.copyProperties(main, vo); - List testSonTableList = testSonTableService.selectByMainId(main.getId()); - vo.setTestSonTableList(testSonTableList); - pageList.add(vo); - } - - // Step.4 AutoPoi 导出Excel - ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); - mv.addObject(NormalExcelConstants.FILE_NAME, "test列表"); - mv.addObject(NormalExcelConstants.CLASS, TestMainTablePage.class); - mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("test数据", "导出人:"+sysUser.getRealname(), "test")); - mv.addObject(NormalExcelConstants.DATA_LIST, pageList); - return mv; - } - - /** - * 通过excel导入数据 - * - * @param request - * @param response - * @return - */ - @RequiresPermissions("test:test_main_table:importExcel") - @RequestMapping(value = "/importExcel", method = RequestMethod.POST) - public Result importExcel(HttpServletRequest request, HttpServletResponse response) { - MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; - Map fileMap = multipartRequest.getFileMap(); - for (Map.Entry entity : fileMap.entrySet()) { - // 获取上传文件对象 - MultipartFile file = entity.getValue(); - ImportParams params = new ImportParams(); - params.setTitleRows(2); - params.setHeadRows(1); - params.setNeedSave(true); - try { - List list = ExcelImportUtil.importExcel(file.getInputStream(), TestMainTablePage.class, params); - for (TestMainTablePage page : list) { - TestMainTable po = new TestMainTable(); - BeanUtils.copyProperties(page, po); - testMainTableService.saveMain(po, page.getTestSonTableList()); - } - return Result.OK("文件导入成功!数据行数:" + list.size()); - } catch (Exception e) { - log.error(e.getMessage(),e); - return Result.error("文件导入失败:"+e.getMessage()); - } finally { - try { - file.getInputStream().close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return Result.OK("文件导入失败!"); - } - -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/entity/TestSonTable.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/entity/TestSonTable.java deleted file mode 100644 index 4dd3db8..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/entity/TestSonTable.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.jeecg.modules.test.entity; - -import java.io.Serializable; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableLogic; -import org.jeecg.common.constant.ProvinceCityArea; -import org.jeecg.common.util.SpringContextUtils; -import lombok.Data; -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.format.annotation.DateTimeFormat; -import org.jeecgframework.poi.excel.annotation.Excel; -import java.util.Date; -import io.swagger.v3.oas.annotations.media.Schema; -import java.io.UnsupportedEncodingException; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -@Schema(description="test") -@Data -@TableName("test_son_table") -public class TestSonTable implements Serializable { - private static final long serialVersionUID = 1L; - - /**主键*/ - @TableId(type = IdType.ASSIGN_ID) - @Schema(description = "主键") - private String id; - /**创建人*/ - @Schema(description = "创建人") - private String createBy; - /**创建日期*/ - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - @Schema(description = "创建日期") - private Date createTime; - /**更新人*/ - @Schema(description = "更新人") - private String updateBy; - /**更新日期*/ - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - @Schema(description = "更新日期") - private Date updateTime; - /**所属部门*/ - @Schema(description = "所属部门") - private String sysOrgCode; - /**字段c*/ - @Excel(name = "字段c", width = 15) - @Schema(description = "字段c") - private String fieldC; - /**主表id*/ - @Schema(description = "主表id") - private String mainTableId; - @TableLogic(value = "0", delval = "1") - private int delFlag = 0; -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/TestMainTableMapper.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/TestMainTableMapper.java deleted file mode 100644 index bf1dbc7..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/TestMainTableMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.jeecg.modules.test.mapper; - -import java.util.List; - -import org.apache.ibatis.annotations.Param; -import org.jeecg.modules.test.entity.TestMainTable; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -public interface TestMainTableMapper extends BaseMapper { - -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/xml/TestMainTableMapper.xml b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/xml/TestMainTableMapper.xml deleted file mode 100644 index 3954740..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/mapper/xml/TestMainTableMapper.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/ITestMainTableService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/ITestMainTableService.java deleted file mode 100644 index e84b5be..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/ITestMainTableService.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.jeecg.modules.test.service; - -import org.jeecg.modules.test.entity.TestSonTable; -import org.jeecg.modules.test.entity.TestMainTable; -import com.baomidou.mybatisplus.extension.service.IService; -import java.io.Serializable; -import java.util.Collection; -import java.util.List; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -public interface ITestMainTableService extends IService { - - /** - * 添加一对多 - * - * @param testMainTable - * @param testSonTableList - */ - public void saveMain(TestMainTable testMainTable,List testSonTableList) ; - - /** - * 修改一对多 - * - * @param testMainTable - * @param testSonTableList - */ - public void updateMain(TestMainTable testMainTable,List testSonTableList); - - /** - * 删除一对多 - * - * @param id - */ - public void delMain (String id); - - /** - * 批量删除一对多 - * - * @param idList - */ - public void delBatchMain (Collection idList); - -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/ITestSonTableService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/ITestSonTableService.java deleted file mode 100644 index c171ce5..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/ITestSonTableService.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.jeecg.modules.test.service; - -import org.jeecg.modules.test.entity.TestSonTable; -import com.baomidou.mybatisplus.extension.service.IService; -import java.util.List; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -public interface ITestSonTableService extends IService { - - /** - * 通过主表id查询子表数据 - * - * @param mainId 主表id - * @return List - */ - public List selectByMainId(String mainId); -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/impl/TestMainTableServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/impl/TestMainTableServiceImpl.java deleted file mode 100644 index 4b49b82..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/impl/TestMainTableServiceImpl.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.jeecg.modules.test.service.impl; - -import org.jeecg.common.aspect.annotation.CascadeDelete; -import org.jeecg.common.aspect.annotation.SonTable; -import org.jeecg.modules.test.entity.TestMainTable; -import org.jeecg.modules.test.entity.TestSonTable; -import org.jeecg.modules.test.mapper.TestSonTableMapper; -import org.jeecg.modules.test.mapper.TestMainTableMapper; -import org.jeecg.modules.test.service.ITestMainTableService; -import org.springframework.stereotype.Service; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; -import java.io.Serializable; -import java.util.List; -import java.util.Collection; -import org.jeecg.common.aspect.annotation.AutoLog; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -@Service -public class TestMainTableServiceImpl extends ServiceImpl implements ITestMainTableService { - - @Autowired - private TestMainTableMapper testMainTableMapper; - @Autowired - private TestSonTableMapper testSonTableMapper; - - @Override - @Transactional(rollbackFor = Exception.class) - public void saveMain(TestMainTable testMainTable, List testSonTableList) { - testMainTableMapper.insert(testMainTable); - if(testSonTableList!=null && testSonTableList.size()>0) { - for(TestSonTable entity:testSonTableList) { - //外键设置 - entity.setMainTableId(testMainTable.getId()); - testSonTableMapper.insert(entity); - } - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateMain(TestMainTable testMainTable,List testSonTableList) { - testMainTableMapper.updateById(testMainTable); - - //1.先删除子表数据 - testSonTableMapper.deleteByMainId(testMainTable.getId()); - - //2.子表数据重新插入 - if(testSonTableList!=null && testSonTableList.size()>0) { - for(TestSonTable entity:testSonTableList) { - //外键设置 - entity.setMainTableId(testMainTable.getId()); - testSonTableMapper.insert(entity); - } - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - @CascadeDelete(sons = { - // 配置子表1:Mapper类 + 子表中关联主表的字段名 - @SonTable(mapper = TestSonTableMapper.class, joinColumn = "main_table_id"), - }) - public void delMain(String id) { - testMainTableMapper.deleteById(id); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void delBatchMain(Collection idList) { - for(Serializable id:idList) { - testSonTableMapper.deleteByMainId(id.toString()); - testMainTableMapper.deleteById(id); - } - } - -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/impl/TestSonTableServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/impl/TestSonTableServiceImpl.java deleted file mode 100644 index 3bfc3c6..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/service/impl/TestSonTableServiceImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.jeecg.modules.test.service.impl; - -import org.jeecg.modules.test.entity.TestSonTable; -import org.jeecg.modules.test.mapper.TestSonTableMapper; -import org.jeecg.modules.test.service.ITestSonTableService; -import org.springframework.stereotype.Service; -import java.util.List; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -@Service -public class TestSonTableServiceImpl extends ServiceImpl implements ITestSonTableService { - - @Autowired - private TestSonTableMapper testSonTableMapper; - - @Override - public List selectByMainId(String mainId) { - return testSonTableMapper.selectByMainId(mainId); - } -} diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/vo/TestMainTablePage.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/vo/TestMainTablePage.java deleted file mode 100644 index 0e73f8f..0000000 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/test/vo/TestMainTablePage.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.jeecg.modules.test.vo; - -import java.util.List; -import org.jeecg.modules.test.entity.TestMainTable; -import org.jeecg.modules.test.entity.TestSonTable; -import lombok.Data; -import org.jeecgframework.poi.excel.annotation.Excel; -import org.jeecgframework.poi.excel.annotation.ExcelEntity; -import org.jeecgframework.poi.excel.annotation.ExcelCollection; -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.format.annotation.DateTimeFormat; -import java.util.Date; -import org.jeecg.common.aspect.annotation.Dict; -import org.jeecg.common.constant.ProvinceCityArea; -import org.jeecg.common.util.SpringContextUtils; - -import io.swagger.v3.oas.annotations.media.Schema; - -/** - * @Description: test - * @Author: jeecg-boot - * @Date: 2026-04-03 - * @Version: V1.0 - */ -@Data -@Schema(description="test") -public class TestMainTablePage { - - /**主键*/ - @Schema(description = "主键") - private String id; - /**创建人*/ - @Schema(description = "创建人") - private String createBy; - /**创建日期*/ - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - @Schema(description = "创建日期") - private Date createTime; - /**更新人*/ - @Schema(description = "更新人") - private String updateBy; - /**更新日期*/ - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - @Schema(description = "更新日期") - private Date updateTime; - /**所属部门*/ - @Schema(description = "所属部门") - private String sysOrgCode; - /**a字段*/ - @Excel(name = "a字段", width = 15) - @Schema(description = "a字段") - private String fieldA; - /**b字段*/ - @Excel(name = "b字段", width = 15) - @Schema(description = "b字段") - private String fieldB; - - @ExcelCollection(name="test") - @Schema(description = "test") - private List testSonTableList; - -} diff --git a/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java b/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java index 4215f69..d56b809 100644 --- a/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java +++ b/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java @@ -564,4 +564,6 @@ public interface ISysBaseAPI extends CommonAPI { String updateBusinessId(String businessId, List deliverablesList); List getUsersListByJsonLocalAPI(Object jsonData, String deptKeyName, String roleId); + + List getUsersListByDeptIdAndRoleIdLocalApi(String deptId, String roleId); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java index 78e66cb..62eb120 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java @@ -545,10 +545,10 @@ public class SysUserController { */ @RequestMapping(value = "/queryUserByDeptAndROle", method = RequestMethod.GET) @Operation(summary = "根据角色ID,部门ID以及用户密级查询当前用户列表", description = "原生用户查询逻辑加上密级筛选以及角色筛选") // 2. 接口描述 - public Result> queryUserByDeptAndROle(DeptRoleVO deptRoleVO + public Result> queryUserByDeptAndROle(DeptRoleVO deptRoleVO ) { try { - List sysUserList = sysUserService.queryUserByDeptAndROle( + List sysUserList = sysUserService.queryUserByDeptAndROle( deptRoleVO.getDeptId(), deptRoleVO.getRoleId(), deptRoleVO.getSecretLevel() diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java index 5e1b815..bdc0ca4 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java @@ -495,5 +495,5 @@ public interface ISysUserService extends IService { */ void updatePasswordNotBindPhone(String oldPassword, String password, String username); - List queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel); + List queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java index fdb6601..efe4b70 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java @@ -2100,6 +2100,7 @@ public class SysBaseApiImpl implements ISysBaseAPI { return ""; } + @Override public List getUsersListByJsonLocalAPI(Object jsonData, String deptKeyName, String roleId) { if (jsonData == null || StringUtils.isEmpty(deptKeyName) || StringUtils.isEmpty(roleId)) { return Collections.emptyList(); @@ -2126,7 +2127,21 @@ public class SysBaseApiImpl implements ISysBaseAPI { return Collections.emptyList(); } - List sysUserList = sysUserService.queryUserByDeptAndROle( + List sysUserList = sysUserService.queryUserByDeptAndROle( + deptId, + roleId, + UserSecretLevel.SECRET_LEVEL_NONE + ); + + return Optional.ofNullable(sysUserList) + .orElse(Collections.emptyList()) + .stream() + .collect(Collectors.toList()); + } + + @Override + public List getUsersListByDeptIdAndRoleIdLocalApi(String deptId, String roleId){ + List sysUserList = sysUserService.queryUserByDeptAndROle( deptId, roleId, UserSecretLevel.SECRET_LEVEL_NONE @@ -2135,7 +2150,6 @@ public class SysBaseApiImpl implements ISysBaseAPI { return Optional.ofNullable(sysUserList) .orElse(Collections.emptyList()) .stream() - .map(SysUser::getUsername) .collect(Collectors.toList()); } } \ No newline at end of file diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java index d7749e1..6fdd585 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java @@ -2416,7 +2416,7 @@ public class SysUserServiceImpl extends ServiceImpl impl } @Override - public List queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel){ - return sysUserMapper.queryUserByDeptAndROle(deptId,roleId,secretLevel); + public List queryUserByDeptAndROle(@NotBlank(message = "deptId不为空") String deptId, @NotBlank(message = "角色id不为空") String roleId, @NotBlank(message = "secretLevel不为空") Integer secretLevel){ + return sysUserMapper.queryUserByDeptAndROle(deptId,roleId,secretLevel).stream().map(SysUser::getUsername).collect(Collectors.toList()) ; } } diff --git a/jeecg-module-system/jeecg-system-start/pom.xml b/jeecg-module-system/jeecg-system-start/pom.xml index 6ecc217..58c1834 100644 --- a/jeecg-module-system/jeecg-system-start/pom.xml +++ b/jeecg-module-system/jeecg-system-start/pom.xml @@ -27,6 +27,10 @@ org.jeecgframework.boot jeecg-module-supervision + + org.jeecgframework.boot + jeecg-module-flow + diff --git a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java index 4629276..dba8ea5 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java +++ b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java @@ -40,6 +40,9 @@ public class JeecgSystemApplication extends SpringBootServletInitializer { "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" + "----------------------------------------------------------"); + // 检查是否有 xiSpeakFlow 这个 Bean + boolean exists = application.containsBean("xiSpeakFlow"); + System.out.println("★★★ xiSpeakFlow 是否加载成功: " + exists); } } \ No newline at end of file