From 4f85bb08e272fe375794781bc6e215435d61d4fc Mon Sep 17 00:00:00 2001 From: zhouhefeng Date: Fri, 30 Oct 2026 15:50:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=8F=E8=B4=B9=E6=8F=90=E6=A1=88=E6=95=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../budwk/app/base/constant/RoleConstant.java | 1 + .../FlowSchoolUnionFinanceHandler.java | 54 ++++++ .../transact/ProposalMineController.java | 10 +- .../service/common/ProposalCommonService.java | 10 ++ .../common/ProposalCommonServiceImpl.java | 42 +++++ .../components/plugins/h5/TableList.vue | 156 +++++++++++++++++- .../resources/views/layouts/platform_h5.html | 2 +- .../reimbursement/mine/index.html | 2 +- .../proposal/transact/mine/index.html | 3 +- 9 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/budwk/app/flow/handler/FlowSchoolUnionFinanceHandler.java diff --git a/src/main/java/com/budwk/app/base/constant/RoleConstant.java b/src/main/java/com/budwk/app/base/constant/RoleConstant.java index 4cf5a21..f71712e 100644 --- a/src/main/java/com/budwk/app/base/constant/RoleConstant.java +++ b/src/main/java/com/budwk/app/base/constant/RoleConstant.java @@ -19,6 +19,7 @@ RoleConstant { SCHOOL_UNION_ADMIN("校工会管理员"), SCHOOL_UNION_CHAIRMAN("校工会主席"), SCHOOL_UNION_VICE_CHAIRMAN("校工会副主席"), + SCHOOL_UNION_FINANCE("校工会财务"), SCHOOL_OFFICE_DIRECTOR("校工会办公室主任"), SCHOOL_UNION_WELFARE_ADMIN("校工会福利管理员"), SCHOOL_UNION_MEMBER_ADMIN("校工会会员管理员"), diff --git a/src/main/java/com/budwk/app/flow/handler/FlowSchoolUnionFinanceHandler.java b/src/main/java/com/budwk/app/flow/handler/FlowSchoolUnionFinanceHandler.java new file mode 100644 index 0000000..02cc802 --- /dev/null +++ b/src/main/java/com/budwk/app/flow/handler/FlowSchoolUnionFinanceHandler.java @@ -0,0 +1,54 @@ +package com.budwk.app.flow.handler; + +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.flow.engine.AssignmentHandler; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.model.TaskModel; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; + +import java.util.List; + +/** + * 为流程任务分配拥有校工会财务角色的用户。 + */ +public class FlowSchoolUnionFinanceHandler implements AssignmentHandler { + + /** + * 按校工会财务角色查询参与者,并去除重复的用户 ID。 + * + * @param model 当前流程任务模型,无需额外传入人员参数 + * @param execution 当前流程执行上下文,无需额外传入业务参数 + * @return 用户 ID 列表;未配置角色或角色用户时返回空列表 + */ + @Override + public List assign(TaskModel model, Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + Sql sql = Sqls.create(""" + SELECT + userRole.userId + FROM + `sys_user_role` userRole + LEFT JOIN sys_role role ON role.id = userRole.roleId + WHERE + role.`code` = @roleCode + GROUP BY + userRole.userId + """).setParam("roleCode", RoleConstant.SCHOOL_UNION_FINANCE.name()); + sql.setCallback(Sqls.callback.strList()); + dao.execute(sql); + return sql.getList(String.class); + } + + /** + * 返回流程设计器中展示的参与者处理类名称。 + * + * @return 流程设计器下拉选项名称 + */ + @Override + public String getMessage() { + return "获取校工会财务"; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java index d77483a..eb8ef4b 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java @@ -229,14 +229,18 @@ public class ProposalMineController { } + /** + * 删除当前用户可删除的提案。 + * + * @param id 提案 ID;仅允许删除本人未发起流程或退回发起节点的提案 + * @return Result,成功时返回成功结果,不满足删除条件时返回原因 + */ @At @SaCheckPermission("proposal.mine") @Aop(TransAop.READ_COMMITTED) @SLog(tag = "提案管理系统-我的提案", msg = "删除提案") public Result delete(@Valid String id) { - dao.delete(ProposalInfo.class, id); - flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id); - return Result.success(); + return proposalCommonService.deleteMine(id, SecurityUtil.getUserId()); } @At diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java index 3ee2de7..640c151 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java @@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.service.common; import com.budwk.app.base.service.BaseService; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.param.ExportTableColumns; +import com.budwk.app.base.result.Result; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam; @@ -19,6 +20,15 @@ import java.util.Set; public interface ProposalCommonService extends BaseService { + /** + * 删除当前用户尚未发起流程或已退回发起节点的提案。 + * + * @param id 待删除的提案 ID + * @param userId 当前登录用户 ID,用于核对提案创建人 + * @return Result,删除成功返回 success;提案不存在、非本人或流程不允许删除时返回错误信息 + */ + Result deleteMine(String id, String userId); + /** * 按页面允许的字段白名单添加排序条件,避免前端字段直接进入SQL。 * diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java index 4d17889..2705a85 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java @@ -17,6 +17,7 @@ import com.budwk.app.base.exception.BaseException; import com.budwk.app.base.param.ExportTableColumns; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.base.utils.CommonDownloadUtil; import com.budwk.app.base.utils.PageUtil; @@ -52,6 +53,7 @@ import com.deepoove.poi.config.Configure; import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; import lombok.extern.slf4j.Slf4j; import org.ddr.poi.html.HtmlRenderPolicy; +import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.dao.FieldFilter; @@ -62,6 +64,7 @@ import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.dao.util.cri.Static; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.ioc.aop.Aop; import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.Strings; @@ -184,6 +187,45 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp super(dao); } + /** + * 仅允许创建人删除草稿或退回发起节点的提案,并清理其 WF 流程。 + * + * @param id 待删除的提案 ID + * @param userId 当前登录用户 ID,用于核对提案创建人 + * @return Result,删除成功返回 success;提案不存在、非本人或流程不允许删除时返回错误信息 + */ + @Override + @Aop(TransAop.READ_COMMITTED) + public Result deleteMine(String id, String userId) { + if (StrUtil.isBlank(id) || StrUtil.isBlank(userId)) { + return Result.error("提案不存在或无权删除"); + } + ProposalInfo proposal = dao().fetch(ProposalInfo.class, id); + if (proposal == null || !Objects.equals(proposal.getCreatedBy(), userId)) { + return Result.error("提案不存在或无权删除"); + } + + List instances = dao().query(ProcessInstance.class, + Cnd.where(ProcessInstance::getBusinessNo, "=", id)); + // 一个提案出现多个流程实例时无法安全判断当前节点,拒绝删除并保留数据。 + if (instances.size() > 1) { + return Result.error("提案流程数据异常,无法删除"); + } + if (!instances.isEmpty()) { + ProcessInstance instance = instances.get(0); + List tasks = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null); + // 存在并行任务时,只有所有活动任务均位于发起节点才允许删除。 + if (!Objects.equals(instance.getState(), ProcessInstanceStateEnum.DOING.getCode()) + || tasks.isEmpty() || tasks.stream().anyMatch(task -> !Objects.equals(task.getTaskName(), "startTask"))) { + return Result.error("仅未提交或退回发起节点的提案可以删除"); + } + } + + dao().delete(ProposalInfo.class, id); + flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id); + return Result.success(); + } + /** * 分页查询提案综合列表。 * 普通查询不关联历史任务表;仅在 origins 包含 answer 且 commonKeyword 非空时, diff --git a/src/main/resources/static/components/plugins/h5/TableList.vue b/src/main/resources/static/components/plugins/h5/TableList.vue index 364e5e8..c128f65 100644 --- a/src/main/resources/static/components/plugins/h5/TableList.vue +++ b/src/main/resources/static/components/plugins/h5/TableList.vue @@ -10,7 +10,7 @@ :finished="tableFinished" finished-text="没有更多了" @load="onLoad"> -
+
@@ -36,6 +36,12 @@
+ +
{{ overflowText }}
+ +
+ +