commit
This commit is contained in:
+37
-6
@@ -265,6 +265,7 @@ public class ProposalMineController {
|
||||
Cnd cnd = Cnd.where("t1.sessionId", "=", sessionId);
|
||||
cnd.andEX("t1.delegationId", "=", delegationId);
|
||||
cnd.and("t1.roleId", "=", "72e24b5b4c4f4e90a6641e6af8487e42");
|
||||
cnd.and("t1.delFlag", "!=", 1);
|
||||
cnd.and("t1.loginName", "!=", SecurityUtil.getUserLoginname());
|
||||
|
||||
if (isInvite) {
|
||||
@@ -286,11 +287,33 @@ public class ProposalMineController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 邀请当前提案所属教代会届次内的正式代表参与附议。
|
||||
*
|
||||
* @param seconders 附议人工号数组,数组中的每个工号必须属于当前提案届次的有效正式代表
|
||||
* @param proposalId 提案ID,用于确定流程实例及可信的教代会届次
|
||||
* @return Result;邀请成功返回 success,提案不存在、代表信息无效或人数不足时返回错误信息
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission("proposal.mine")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "提案", msg = "邀请附议人")
|
||||
public Result inviteSeconder(@Param("seconders") String[] seconders, @Valid String proposalId) {
|
||||
if (seconders == null || seconders.length == 0) {
|
||||
return Result.error("请选择附议人");
|
||||
}
|
||||
ProposalInfo proposalInfo = dao.fetch(ProposalInfo.class, proposalId);
|
||||
if (proposalInfo == null || StrUtil.isBlank(proposalInfo.getSessionId())) {
|
||||
return Result.error("提案信息不存在");
|
||||
}
|
||||
List<String> requestedLoginNames = List.of(seconders).stream()
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
if (requestedLoginNames.isEmpty()) {
|
||||
return Result.error("请选择附议人");
|
||||
}
|
||||
|
||||
// 查询已经邀请的附议人
|
||||
ProcessInstance processInstance = dao.fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", proposalId));
|
||||
|
||||
@@ -319,11 +342,7 @@ public class ProposalMineController {
|
||||
|
||||
ProposalConfig proposalConfig = dao.fetch(ProposalConfig.class, Cnd.NEW());
|
||||
|
||||
if (tasks.size() + seconders.length < proposalConfig.getSeconderNum()) {
|
||||
return Result.error("至少邀请" + proposalConfig.getSeconderNum() + "个附议人");
|
||||
}
|
||||
|
||||
|
||||
// 必须使用提案自身的届次查询,不能只按工号匹配,否则同一代表的历史届次记录会污染代表团等快照信息。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t1.id,
|
||||
@@ -340,8 +359,20 @@ public class ProposalMineController {
|
||||
LEFT JOIN teacher_congress_delegation t2 ON t2.id = t1.delegationId
|
||||
$condition
|
||||
""");
|
||||
sql.setCondition(Cnd.where("t1.loginName", "in", seconders).groupBy("t1.loginName"));
|
||||
Cnd seconderCnd = Cnd.where("t1.sessionId", "=", proposalInfo.getSessionId())
|
||||
.and("t1.loginName", "in", requestedLoginNames)
|
||||
.and("t1.roleId", "=", "72e24b5b4c4f4e90a6641e6af8487e42")
|
||||
.and("t1.delFlag", "!=", 1);
|
||||
sql.setCondition(seconderCnd);
|
||||
List<NutMap> list = proposalCommonService.listMap(sql);
|
||||
// 每个工号在当前届次必须且只能匹配一条有效代表记录,防止无效工号或重复基础数据进入流程。
|
||||
if (list.size() != requestedLoginNames.size()) {
|
||||
return Result.error("部分附议人不属于当前提案届次或代表信息重复,请重新选择");
|
||||
}
|
||||
if (tasks.size() + list.size() < proposalConfig.getSeconderNum()) {
|
||||
return Result.error("至少邀请" + proposalConfig.getSeconderNum() + "个附议人");
|
||||
}
|
||||
|
||||
// 附议人ID
|
||||
List<String> userIds = list.stream().map(item -> item.getString("userId")).toList();
|
||||
// 获取正在执行的任务(邀请附议人||提案附议)
|
||||
|
||||
+37
-3
@@ -45,6 +45,7 @@ import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
@@ -76,14 +77,24 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
throw new BaseException("没有进行中的流程任务");
|
||||
}
|
||||
|
||||
String proposalId = StrUtil.trim(args.getStr("proposalId"));
|
||||
if (StrUtil.isBlank(proposalId) || dao().fetch(ProposalInfo.class, proposalId) == null) {
|
||||
throw new BaseException("提案信息不存在");
|
||||
}
|
||||
args.put("proposalId", proposalId);
|
||||
validateAndNormalizeCaseFilingCode(args);
|
||||
|
||||
String proposalId = args.getStr("proposalId");
|
||||
List<String> proposalIds = proposalCommonService.mergeProposal(proposalId);
|
||||
if (ObjectUtil.isEmpty(proposalIds)) {
|
||||
proposalIds = List.of(proposalId);
|
||||
}
|
||||
|
||||
/*
|
||||
* 先同步 proposal_info 和承办单位,再执行 WF 流转,使查看页面及下一节点读取到的都是本次最新数据。
|
||||
* 当前方法处于同一事务中,后续流程执行失败时这里的业务数据会一并回滚。
|
||||
*/
|
||||
syncCommitteeFilingUnitData(proposalIds, args);
|
||||
|
||||
/*
|
||||
* 并案场景下,同一个节点会在每条提案实例上各有一条待办。
|
||||
* 这里统一按 taskName 找出整组正在办理中的任务,逐条执行,确保并案提案的流程状态保持一致。
|
||||
@@ -97,8 +108,6 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
cloneArgs.put(FlowConst.PROCESS_TASK_ID_KEY, executeTask.getId());
|
||||
flowCommonService.executeTask(cloneArgs);
|
||||
}
|
||||
|
||||
syncCommitteeFilingUnitData(proposalIds, args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,8 +119,10 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
private void validateAndNormalizeCaseFilingCode(Dict args) {
|
||||
String caseFilingResultKey = FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingResult";
|
||||
String caseFilingCodeKey = FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingCode";
|
||||
String caseFilingTypeKey = FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingType";
|
||||
if (!"CONFIRM_FILING".equals(args.getStr(caseFilingResultKey))) {
|
||||
args.put(caseFilingCodeKey, "");
|
||||
args.put(caseFilingTypeKey, "");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -139,6 +150,7 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
.add("caseFilingResult", caseFilingResult)
|
||||
.add("caseFilingType", caseFilingType),
|
||||
Cnd.where(ProposalInfo::getId, "in", proposalIds));
|
||||
verifyCommitteeFilingUnitData(proposalIds, caseFilingCode, caseFilingResult, caseFilingType);
|
||||
|
||||
dao().clear(ProposalReplyUnit.class, Cnd.where(ProposalReplyUnit::getProposalId, "in", proposalIds));
|
||||
if (!List.of("CONFIRM_FILING", "SUGGESTION").contains(caseFilingResult)) {
|
||||
@@ -175,6 +187,28 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验本次立案字段是否已同步到全部提案,避免流程变量更新成功但 info 基础信息仍保留旧值。
|
||||
*/
|
||||
private void verifyCommitteeFilingUnitData(List<String> proposalIds, String caseFilingCode,
|
||||
String caseFilingResult, String caseFilingType) {
|
||||
List<ProposalInfo> proposalInfos = dao().query(ProposalInfo.class,
|
||||
Cnd.where(ProposalInfo::getId, "in", proposalIds));
|
||||
if (proposalInfos.size() != new LinkedHashSet<>(proposalIds).size()) {
|
||||
throw new BaseException("部分提案信息不存在,无法同步立案结果");
|
||||
}
|
||||
boolean syncFailed = proposalInfos.stream().anyMatch(proposalInfo ->
|
||||
!Objects.equals(StrUtil.nullToDefault(proposalInfo.getCaseFilingCode(), ""),
|
||||
StrUtil.nullToDefault(caseFilingCode, ""))
|
||||
|| !Objects.equals(StrUtil.nullToDefault(proposalInfo.getCaseFilingResult(), ""),
|
||||
StrUtil.nullToDefault(caseFilingResult, ""))
|
||||
|| !Objects.equals(StrUtil.nullToDefault(proposalInfo.getCaseFilingType(), ""),
|
||||
StrUtil.nullToDefault(caseFilingType, "")));
|
||||
if (syncFailed) {
|
||||
throw new BaseException("立案结果同步失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个提案可以配置多个主办单位和多个协办单位。
|
||||
* 这里按页面提交顺序逐条生成承办单位记录,兼容多主办的业务场景。
|
||||
|
||||
+1
@@ -95,6 +95,7 @@ public class SuggestionBoxMineController {
|
||||
}
|
||||
cnd.andEX("YEAR(info.submitTime)", "=", year);
|
||||
cnd.desc("info.submitTime");
|
||||
cnd.groupBy("info.id");
|
||||
sql.setCondition(cnd);
|
||||
Pagination<NutMap> pagination = suggestionBoxService.listPageMap(pageNumber, pageSize, sql);
|
||||
return Result.success(pagination);
|
||||
|
||||
Reference in New Issue
Block a user