diff --git a/pom.xml b/pom.xml
index d94b5b69..4ee8f7b7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
jar
com.budwk
- zhgh_hdc
+ mini
5.6.0-plus
2.6.0-SNAPSHOT
diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java
index 349fded1..a2d1d7dd 100644
--- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java
+++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java
@@ -108,9 +108,10 @@ public class ProposalSecondedController {
Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "second");
- if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
+ /* if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
- }
+ }*/
+ cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
@@ -151,9 +152,10 @@ public class ProposalSecondedController {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
cnd.andEX("info.sessionId", "=", sessionId);
- if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
+ /* if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
- }
+ }*/
+ cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
sql.setCondition(cnd);
return Result.success(baseService.count(sql));
diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java
index d7c86a0c..6a05049b 100644
--- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java
+++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java
@@ -7,7 +7,7 @@ import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond;
public interface ProposalSecondedService extends BaseService {
/**
- * 保存受邀附议办理结果,并在“受邀附议 + 主动附议”总同意人数达到 2 人时自动推进到团长审核。
+ * 保存受邀附议办理结果,并在受邀附议同意人数达到配置数量时自动推进到团长审核。
*
* @param proposalId 提案ID
* @param taskActorUserId 受邀附议办理人ID
@@ -18,7 +18,8 @@ public interface ProposalSecondedService extends BaseService {
Result updateInviteSecondInfo(String proposalId, String taskActorUserId, String opinion, Integer submitType);
/**
- * 保存主动附议结果,并在“受邀附议 + 主动附议”总同意人数达到 2 人时自动推进到团长审核。
+ * 保存主动附议结果。
+ * 主动附议只记录业务附议人信息,不参与工作流会签统计,也不触发流程自动推进。
*
* @param proposalId 提案ID
* @param opinion 附议意见
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 960daa0a..79a816d8 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
@@ -1,6 +1,7 @@
package com.budwk.app.zhgh.democratic.proposal.service.common;
import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -15,6 +16,7 @@ import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.engine.util.FlowUtil;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
+import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.vo.ProcessTaskVO;
import com.budwk.app.sys.models.Sys_dict;
@@ -143,7 +145,9 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp
List positiveSecondList = dao().query(
ProposalSecond.class,
- Cnd.where(ProposalSecond::getProposalId, "=", id).and(ProposalSecond::getMode, "=", false)
+ Cnd.where(ProposalSecond::getProposalId, "=", id)
+ .and(ProposalSecond::getMode, "=", false)
+ .asc(ProposalSecond::getSecondedTime)
);
info.put("positiveSecondList", positiveSecondList);
return info;
@@ -217,6 +221,20 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp
// 按任务节点分组
Map> taskGroups = doneTaskVos.stream().collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName));
+ // 主动附议不进入工作流,但 Word 模板的附议人明细仍使用“提案附议”分组渲染。
+ // 这里把 proposal_second 中的主动附议业务记录转换成模板可识别的任务数据,和受邀附议一起导出。
+ List positiveSecondList = dao().query(
+ ProposalSecond.class,
+ Cnd.where(ProposalSecond::getProposalId, "=", id)
+ .and(ProposalSecond::getMode, "=", false)
+ .asc(ProposalSecond::getSecondedTime)
+ );
+ if (Lang.isNotEmpty(positiveSecondList)) {
+ List proposalSecondTasks = taskGroups.computeIfAbsent("提案附议", key -> new ArrayList<>());
+ for (ProposalSecond positiveSecond : positiveSecondList) {
+ proposalSecondTasks.add(buildPositiveSecondTaskVO(processInstance.getId(), positiveSecond));
+ }
+ }
docData.putAll(taskGroups);
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
@@ -238,6 +256,37 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp
}
}
+ /**
+ * 将主动附议业务记录转换成 Word 模板已支持的流程任务结构。
+ *
+ * @param processInstanceId 流程实例 ID,用于保持导出数据与当前提案流程关联
+ * @param positiveSecond 主动附议记录,包含附议人、附议时间、附议意见和附议结果
+ * @return ProcessTaskVO,放入“提案附议”模板分组后可复用现有 Word 表格渲染
+ */
+ private ProcessTaskVO buildPositiveSecondTaskVO(Long processInstanceId, ProposalSecond positiveSecond) {
+ ProcessTaskVO taskVO = new ProcessTaskVO();
+ taskVO.setProcessInstanceId(processInstanceId);
+ taskVO.setTaskName("second");
+ taskVO.setDisplayName("提案附议");
+ taskVO.setTaskState(ProcessTaskStateEnum.FINISHED.getCode());
+ taskVO.setOperator(positiveSecond.getSeconderId());
+ taskVO.setFinishTime(positiveSecond.getSecondedTime());
+
+ Dict variable = Dict.create();
+ variable.put(FlowConst.SUBMIT_TYPE, Boolean.TRUE.equals(positiveSecond.getIsAgree())
+ ? ProcessSubmitTypeEnum.AGREE.getCode()
+ : ProcessSubmitTypeEnum.COUNTERSIGN_DISAGREE.getCode());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "userName", positiveSecond.getUserName());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "loginName", positiveSecond.getLoginName());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", positiveSecond.getUnitName());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionName", positiveSecond.getUnionName());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "delegationName", positiveSecond.getDelegationName());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "opinion", positiveSecond.getOpinion());
+ variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "secondedMode", "主动附议");
+ taskVO.setVariable(Json.toJson(variable));
+ return taskVO;
+ }
+
@Override
public void exportProposalFeedBackAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) {
if (id == null || id.isEmpty()) {
diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalExportServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalExportServiceImpl.java
index 8264bc23..1d970bac 100644
--- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalExportServiceImpl.java
+++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalExportServiceImpl.java
@@ -19,6 +19,7 @@ import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.web.commons.base.Globals;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
+import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalExportService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
@@ -196,24 +197,7 @@ public class ProposalExportServiceImpl extends BaseServiceImpl imp
list.get(i).put("brief", HtmlUtil.cleanHtmlTag(list.get(i).getString("brief")));
list.get(i).put("measures", HtmlUtil.cleanHtmlTag(list.get(i).getString("measures")));
- // 流程实例
- ProcessInstance instance = dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", list.get(i).getString("id")));
-
- // 查询附议人信息
- ProcessTask inviteTask = dao().fetch(ProcessTask.class,
- Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId())
- .and(ProcessTask::getTaskName, "=", "invite")
- .and(ProcessTask::getTaskState, "in",
- List.of(ProcessTaskStateEnum.DOING.getCode(), ProcessTaskStateEnum.FINISHED.getCode()))
- .desc(ProcessTask::getCreatedAt));
-
- if (inviteTask != null) {
- NutMap variable = Json.fromJson(NutMap.class, inviteTask.getVariable());
- List seconders = variable.getAsList(FlowConst.TASK_FORM_DATA_PREFIX + "seconder", NutMap.class);
- if (Lang.isNotEmpty(seconders)) {
- list.get(i).put("secondedUserNames", seconders.stream().map(v -> v.getString("userName")).collect(Collectors.joining(",")));
- }
- }
+ list.get(i).put("secondedUserNames", buildSecondedUserNames(list.get(i).getString("id")));
}
List exportEntities = new ArrayList<>();
@@ -225,7 +209,7 @@ public class ProposalExportServiceImpl extends BaseServiceImpl imp
exportEntities.add(new ExcelExportEntity("代表建议措施", "measures", 40));
exportEntities.add(new ExcelExportEntity("提案人", "createUserName", 20));
exportEntities.add(new ExcelExportEntity("提案人电话", "mobile", 20));
- exportEntities.add(new ExcelExportEntity("附议人(两名)", "secondedUserNames", 20));
+ exportEntities.add(new ExcelExportEntity("附议人", "secondedUserNames", 20));
exportEntities.add(new ExcelExportEntity("提案单位", "unitName", 20));
// exportEntities.add(new ExcelExportEntity("拟交办单位", "", 20));
@@ -239,6 +223,30 @@ public class ProposalExportServiceImpl extends BaseServiceImpl imp
CommonDownloadUtil.download(title + ".xlsx", workbook, response);
}
+ /**
+ * 汇总表附议人统一从 proposal_second 获取。
+ * 邀请附议和主动附议都会写入该表,这里只负责导出附议人姓名,不再依赖流程任务变量。
+ *
+ * @param proposalId 提案 ID
+ * @return 附议人姓名字符串,多个附议人用逗号分隔;无附议人时返回空字符串
+ */
+ private String buildSecondedUserNames(String proposalId) {
+ List seconds = dao().query(
+ ProposalSecond.class,
+ Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
+ .asc(ProposalSecond::getInviteTime)
+ .asc(ProposalSecond::getSecondedTime)
+ );
+ if (Lang.isEmpty(seconds)) {
+ return "";
+ }
+ return seconds.stream()
+ .map(ProposalSecond::getUserName)
+ .filter(StrUtil::isNotBlank)
+ .distinct()
+ .collect(Collectors.joining(","));
+ }
+
@Override
public void exportProposalRegisterSummaryAsExcel(ProposalQueryComprehensiveParam pageForm, HttpServletResponse response) {
Sql sql = exportComprehensiveSql(pageForm);
diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSecondedServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSecondedServiceImpl.java
index c16d8561..f8c17722 100644
--- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSecondedServiceImpl.java
+++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSecondedServiceImpl.java
@@ -12,6 +12,7 @@ import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.sys.views.View_user;
+import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalSecondedService;
@@ -44,6 +45,7 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
.and(ProposalSecond::getSeconderId, "=", taskActorUserId)
+ .and(ProposalSecond::getMode, "=", true)
);
if (proposalSecond == null) {
return Result.error("未查询到附议记录");
@@ -113,15 +115,13 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl
seconded.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode()));
dao().insert(seconded);
- if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode())) {
- autoAdvanceToDelegationWhenEnoughSeconders(proposalId);
- }
+ // 主动附议只做业务留痕,不参与 second 会签统计,也不触发流程自动流转。
return Result.success();
}
/**
- * 统一按 proposal_second 里的“同意附议”人数判断是否已满足 2 人附议。
- * 一旦满足 2 人,就用系统自动执行一个仍处于办理中的 second 任务来触发流程引擎会签合并,
+ * 只按受邀附议记录判断是否达到配置的附议人数。
+ * 一旦满足配置数量,就用系统自动执行一个仍处于办理中的 second 任务来触发流程引擎会签合并,
* 这样 second 节点会自动废弃其余未办任务,并按流程定义流转到 delegation 节点。
*/
private void autoAdvanceToDelegationWhenEnoughSeconders(String proposalId) {
@@ -130,12 +130,18 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl
return;
}
+ ProposalConfig proposalConfig = dao().fetch(ProposalConfig.class, Cnd.NEW());
+ if (proposalConfig == null || proposalConfig.getSeconderNum() == null) {
+ return;
+ }
+
long agreeCount = dao().count(
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
+ .and(ProposalSecond::getMode, "=", true)
.and(ProposalSecond::getIsAgree, "=", true)
);
- if (agreeCount < 2) {
+ if (agreeCount < proposalConfig.getSeconderNum()) {
return;
}
int mergedCompletedCount = (int) Math.max(agreeCount - 1, 0);
@@ -145,8 +151,8 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl
return;
}
- // 当前流程仍停留在 second 会签节点时,把“已同意附议人数”桥接到会签变量里。
- // 这样系统自动完成一个 second 任务后,会签节点会按“累计 2 个同意”直接合并到团长审核。
+ // 当前流程仍停留在 second 会签节点时,把“受邀同意附议人数”桥接到会签变量里。
+ // 这样系统自动完成一个 second 任务后,会签节点会按配置的受邀附议人数合并到团长审核。
String prefix = FlowConst.COUNTERSIGN_VARIABLE_PREFIX + "second_";
Dict instanceVariable = Dict.create();
instanceVariable.put(prefix + FlowConst.NR_OF_COMPLETED_INSTANCES, mergedCompletedCount);
diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/common/info.js b/src/main/resources/views/platform/zhgh/democratic/proposal/common/info.js
index 167b1509..ebc917a5 100644
--- a/src/main/resources/views/platform/zhgh/democratic/proposal/common/info.js
+++ b/src/main/resources/views/platform/zhgh/democratic/proposal/common/info.js
@@ -146,7 +146,8 @@ const PROPOSAL_INFO = {
-
+