commit
This commit is contained in:
+52
-4
@@ -22,6 +22,7 @@ import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.Static;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -92,14 +93,23 @@ public class ProposalSecondedController {
|
||||
ta.actorId taskActorUserId,
|
||||
ta.actorName taskActorName,
|
||||
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
|
||||
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
|
||||
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke,
|
||||
CASE
|
||||
WHEN t.taskState = 10 THEN 1
|
||||
WHEN t.taskState = 99 AND dt.id IS NOT NULL AND ft.id IS NULL AND ps.isAgree IS NULL THEN 1
|
||||
ELSE 0
|
||||
END AS canAudit,
|
||||
IF(t.taskState = 99, 1, 0) AS abandonedSecondTask
|
||||
FROM
|
||||
wf_process_task t
|
||||
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
|
||||
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
|
||||
LEFT JOIN wf_process_task dt ON dt.processInstanceId = ins.id AND dt.taskName = 'delegation' AND dt.taskState = 10
|
||||
LEFT JOIN wf_process_task ft ON ft.processInstanceId = ins.id AND ft.taskName = 'delegation' AND ft.taskState = 20
|
||||
LEFT JOIN proposal_info info ON info.id = ins.businessNo
|
||||
LEFT JOIN proposal_second ps ON ps.proposalId = info.id AND ps.seconderId = ta.actorId AND ps.mode = 1
|
||||
LEFT JOIN proposal_type type on type.id = info.typeId
|
||||
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
|
||||
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
|
||||
@@ -116,7 +126,20 @@ public class ProposalSecondedController {
|
||||
if (approval) {
|
||||
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
|
||||
} else {
|
||||
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
// 未附议列表包含两类数据:
|
||||
// 1. second 仍在进行中的正常受邀附议待办;
|
||||
// 2. second 已因人数达标被系统废弃,但 delegation 团长审核还未办理,此时允许受邀人补审并写入流程记录。
|
||||
cnd.and(new Static("""
|
||||
(
|
||||
t.taskState = 10
|
||||
OR (
|
||||
t.taskState = 99
|
||||
AND dt.id IS NOT NULL
|
||||
AND ft.id IS NULL
|
||||
AND ps.isAgree IS NULL
|
||||
)
|
||||
)
|
||||
"""));
|
||||
}
|
||||
ProposalSearchParam.buildSearch(cnd, pageForm);
|
||||
cnd.groupBy("t.id");
|
||||
@@ -145,11 +168,25 @@ public class ProposalSecondedController {
|
||||
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN proposal_info info ON info.id = ins.businessNo
|
||||
LEFT JOIN proposal_second ps ON ps.proposalId = info.id AND ps.seconderId = ta.actorId AND ps.mode = 1
|
||||
LEFT JOIN wf_process_task dt ON dt.processInstanceId = ins.id AND dt.taskName = 'delegation' AND dt.taskState = 10
|
||||
LEFT JOIN wf_process_task ft ON ft.processInstanceId = ins.id AND ft.taskName = 'delegation' AND ft.taskState = 20
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("t.taskName", "=", "second");
|
||||
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
// 待办数量与列表口径保持一致:正常待办 + delegation 未审前可补审的废弃 second 任务。
|
||||
cnd.and(new Static("""
|
||||
(
|
||||
t.taskState = 10
|
||||
OR (
|
||||
t.taskState = 99
|
||||
AND dt.id IS NOT NULL
|
||||
AND ft.id IS NULL
|
||||
AND ps.isAgree IS NULL
|
||||
)
|
||||
)
|
||||
"""));
|
||||
cnd.andEX("info.sessionId", "=", sessionId);
|
||||
|
||||
/* if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
|
||||
@@ -167,10 +204,21 @@ public class ProposalSecondedController {
|
||||
@ApiOperation("修改提案附议信息")
|
||||
@SLog(tag = "提案管理系统-附议提案", msg = "修改提案附议信息")
|
||||
public Result updateInfo(@Param("proposalId") String proposalId,
|
||||
@Param("taskId") Long taskId,
|
||||
@Param("taskActorUserId") String taskActorUserId,
|
||||
@Param("opinion") String opinion,
|
||||
@Param("submitType") Integer submitType) {
|
||||
return proposalSecondedService.updateInviteSecondInfo(proposalId, taskActorUserId, opinion, submitType);
|
||||
/*
|
||||
* 参数说明:
|
||||
* proposalId:提案ID,用于定位 proposal_second 业务附议记录。
|
||||
* taskId:second 流程任务ID。正常待办先由前端执行流程任务,再调用本接口同步业务记录;
|
||||
* 如果 second 已被系统废弃但 delegation 还未审核,本接口会用该 taskId 补写流程审批记录。
|
||||
* taskActorUserId:受邀附议人用户ID,必须与 proposal_second.seconderId 和任务参与人一致。
|
||||
* opinion:受邀附议意见,写入业务表;废弃任务补审时也写入流程任务变量。
|
||||
* submitType:提交类型,1 表示同意,20 表示不同意。
|
||||
* 返回值:Result,code=0 表示保存成功;废弃任务补审成功时,流程记录和业务附议记录都会同步完成。
|
||||
*/
|
||||
return proposalSecondedService.updateInviteSecondInfo(proposalId, taskId, taskActorUserId, opinion, submitType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -10,12 +10,13 @@ public interface ProposalSecondedService extends BaseService<ProposalSecond> {
|
||||
* 保存受邀附议办理结果,并在受邀附议同意人数达到配置数量时自动推进到团长审核。
|
||||
*
|
||||
* @param proposalId 提案ID
|
||||
* @param taskId second 流程任务ID;正常待办提交后用于业务记录同步,废弃任务补审时用于写入流程审批记录
|
||||
* @param taskActorUserId 受邀附议办理人ID
|
||||
* @param opinion 附议意见
|
||||
* @param submitType 提交类型
|
||||
* @return 处理结果
|
||||
*/
|
||||
Result updateInviteSecondInfo(String proposalId, String taskActorUserId, String opinion, Integer submitType);
|
||||
Result updateInviteSecondInfo(String proposalId, Long taskId, String taskActorUserId, String opinion, Integer submitType);
|
||||
|
||||
/**
|
||||
* 保存主动附议结果。
|
||||
|
||||
+95
-1
@@ -3,13 +3,17 @@ package com.budwk.app.zhgh.democratic.proposal.service.impl;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.flow.constant.FlowConst;
|
||||
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.entity.ProcessTaskActor;
|
||||
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
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;
|
||||
@@ -40,7 +44,11 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl<ProposalSecond>
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result updateInviteSecondInfo(String proposalId, String taskActorUserId, String opinion, Integer submitType) {
|
||||
public Result updateInviteSecondInfo(String proposalId, Long taskId, String taskActorUserId, String opinion, Integer submitType) {
|
||||
if (!ObjectUtil.equals(taskActorUserId, SecurityUtil.getUserId())) {
|
||||
return Result.error("只能办理当前登录人的受邀附议任务");
|
||||
}
|
||||
|
||||
ProposalSecond proposalSecond = dao().fetch(
|
||||
ProposalSecond.class,
|
||||
Cnd.where(ProposalSecond::getProposalId, "=", proposalId)
|
||||
@@ -50,6 +58,18 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl<ProposalSecond>
|
||||
if (proposalSecond == null) {
|
||||
return Result.error("未查询到附议记录");
|
||||
}
|
||||
if (proposalSecond.getIsAgree() != null) {
|
||||
return Result.error("该受邀附议已办理,请勿重复提交");
|
||||
}
|
||||
|
||||
ProcessTask secondTask = taskId == null ? null : dao().fetch(ProcessTask.class, taskId);
|
||||
if (secondTask != null && ProcessTaskStateEnum.ABANDON.getCode().equals(secondTask.getTaskState())) {
|
||||
Result supplementResult = supplementAbandonedSecondTask(proposalId, secondTask, taskActorUserId, opinion, submitType);
|
||||
if (supplementResult.getCode() != 0) {
|
||||
return supplementResult;
|
||||
}
|
||||
}
|
||||
|
||||
proposalSecond.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode()));
|
||||
proposalSecond.setOpinion(opinion);
|
||||
proposalSecond.setSecondedTime(DateUtil.date());
|
||||
@@ -119,6 +139,80 @@ public class ProposalSecondedServiceImpl extends BaseServiceImpl<ProposalSecond>
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* delegation 团长审核未办理前,允许受邀人补审已经被系统废弃的 second 会签任务。
|
||||
* 这里不能再调用流程引擎执行任务,因为引擎只允许执行 DOING 状态任务;补审只负责把废弃任务补写成
|
||||
* FINISHED 审批记录,并保存本次附议意见,不再触发流程继续流转。
|
||||
*/
|
||||
private Result supplementAbandonedSecondTask(String proposalId, ProcessTask secondTask, String taskActorUserId, String opinion, Integer submitType) {
|
||||
if (!"second".equals(secondTask.getTaskName())) {
|
||||
return Result.error("当前任务不是受邀附议任务");
|
||||
}
|
||||
|
||||
ProcessInstance processInstance = dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", proposalId));
|
||||
if (processInstance == null || !ObjectUtil.equals(processInstance.getId(), secondTask.getProcessInstanceId())) {
|
||||
return Result.error("未查询到提案流程信息");
|
||||
}
|
||||
|
||||
int taskActorCount = dao().count(
|
||||
ProcessTaskActor.class,
|
||||
Cnd.where(ProcessTaskActor::getProcessTaskId, "=", secondTask.getId())
|
||||
.and(ProcessTaskActor::getActorId, "=", taskActorUserId)
|
||||
);
|
||||
if (taskActorCount == 0) {
|
||||
return Result.error("当前用户不是该受邀附议任务办理人");
|
||||
}
|
||||
|
||||
int delegationDoneCount = dao().count(
|
||||
ProcessTask.class,
|
||||
Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId())
|
||||
.and(ProcessTask::getTaskName, "=", "delegation")
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())
|
||||
);
|
||||
if (delegationDoneCount > 0) {
|
||||
return Result.error("团长已审核,不能再补充受邀附议");
|
||||
}
|
||||
|
||||
int delegationDoingCount = dao().count(
|
||||
ProcessTask.class,
|
||||
Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId())
|
||||
.and(ProcessTask::getTaskName, "=", "delegation")
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.DOING.getCode())
|
||||
);
|
||||
if (delegationDoingCount == 0) {
|
||||
return Result.error("当前提案不在团长审核待办阶段,不能补充受邀附议");
|
||||
}
|
||||
|
||||
Dict taskVariable = FlowUtil.variableToDict(secondTask.getVariable());
|
||||
taskVariable.put(FlowConst.SUBMIT_TYPE, submitType);
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "opinion", opinion);
|
||||
fillTaskOperatorInfo(taskActorUserId, taskVariable);
|
||||
FlowUtil.addUserInfoToArgs(taskActorUserId, taskVariable);
|
||||
|
||||
secondTask.setTaskState(ProcessTaskStateEnum.FINISHED.getCode());
|
||||
secondTask.setOperator(taskActorUserId);
|
||||
secondTask.setFinishTime(DateUtil.date());
|
||||
secondTask.setUpdatedAt(System.currentTimeMillis());
|
||||
secondTask.setUpdatedBy(taskActorUserId);
|
||||
secondTask.setVariable(JSONUtil.toJsonStr(taskVariable));
|
||||
dao().update(secondTask, "taskState|operator|finishTime|updatedAt|updatedBy|variable");
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 补写流程记录时,补齐与 /flow/common/executeTask 正常审批一致的任务表单用户信息。
|
||||
* 这些字段用于审批记录展示和后续导出模板读取,避免补审记录只有意见、没有办理人组织信息。
|
||||
*/
|
||||
private void fillTaskOperatorInfo(String taskActorUserId, Dict taskVariable) {
|
||||
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", taskActorUserId));
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "userName", user == null ? "" : user.getUsername());
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "loginName", user == null ? "" : user.getLoginname());
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitId", user == null ? "" : user.getUnitId());
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", user == null ? "" : user.getUnitName());
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionId", user == null ? "" : user.getUnionId());
|
||||
taskVariable.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionName", user == null ? "" : user.getUnionName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 只按受邀附议记录判断是否达到配置的附议人数。
|
||||
* 一旦满足配置数量,就用系统自动执行一个仍处于办理中的 second 任务来触发流程引擎会签合并,
|
||||
|
||||
+33
-13
@@ -275,7 +275,7 @@ layout("/layouts/platform.html"){
|
||||
|
||||
showAuditButton: function (row) {
|
||||
if (this.activeTab === "inviteSeconded") {
|
||||
return row.taskState === 10
|
||||
return row.canAudit === 1
|
||||
}
|
||||
return row.count === 0
|
||||
},
|
||||
@@ -287,13 +287,19 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
},
|
||||
|
||||
openAudit: async function (row) {
|
||||
openAudit: function (row) {
|
||||
if (this.activeTab === "positiveSeconded") {
|
||||
var validatePass = await this.validateCanSeconded(row.id)
|
||||
if (!validatePass) {
|
||||
return
|
||||
}
|
||||
this.validateCanSeconded(row.id).then((validatePass) => {
|
||||
if (validatePass) {
|
||||
this.openAuditForm(row)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.openAuditForm(row)
|
||||
},
|
||||
|
||||
openAuditForm: function (row) {
|
||||
this.$set(this, "row", row)
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$set(this, "showApprovalForm", true)
|
||||
@@ -314,7 +320,6 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
handleTaskAction: function (val) {
|
||||
@@ -335,6 +340,17 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
|
||||
handleInviteSeconded: function (val) {
|
||||
if (this.row.abandonedSecondTask === 1) {
|
||||
this.updateSecond(val).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.guava.index()
|
||||
this.$message.success(res.msg)
|
||||
this.doSearch()
|
||||
this.listInviteSecondedTodoCount()
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
@@ -342,18 +358,22 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.updateSecond(val)
|
||||
this.$refs.guava.index()
|
||||
this.$message.success(res.msg)
|
||||
this.doSearch()
|
||||
this.listInviteSecondedTodoCount()
|
||||
this.updateSecond(val).then((updateRes) => {
|
||||
if (updateRes.code === 0) {
|
||||
this.$refs.guava.index()
|
||||
this.$message.success(res.msg)
|
||||
this.doSearch()
|
||||
this.listInviteSecondedTodoCount()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
updateSecond: function (submitType) {
|
||||
this.$axios.post("/platform/proposal/seconded/updateInfo", {
|
||||
return this.$axios.post("/platform/proposal/seconded/updateInfo", {
|
||||
proposalId: this.row.id,
|
||||
taskId: this.row.taskId,
|
||||
taskActorUserId: this.row.taskActorUserId,
|
||||
opinion: this.formData.tf_opinion,
|
||||
submitType: submitType,
|
||||
|
||||
+37
-17
@@ -245,7 +245,7 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
showApprovalButton(row) {
|
||||
if (this.activeTab === "inviteSeconded") {
|
||||
return row.taskState === 10
|
||||
return row.canAudit === 1
|
||||
}
|
||||
return row.count === 0
|
||||
},
|
||||
@@ -255,13 +255,19 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
async onApproval(row) {
|
||||
onApproval(row) {
|
||||
if (this.activeTab === "positiveSeconded") {
|
||||
const validatePass = await this.validateCanSeconded(row.id)
|
||||
if (!validatePass) {
|
||||
return
|
||||
}
|
||||
this.validateCanSeconded(row.id).then((validatePass) => {
|
||||
if (validatePass) {
|
||||
this.openApprovalForm(row)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.openApprovalForm(row)
|
||||
},
|
||||
|
||||
openApprovalForm(row) {
|
||||
this.$set(this, "row", row)
|
||||
this.$set(this, "showApprovalForm", true)
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
@@ -294,9 +300,8 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
},
|
||||
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate()
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
@@ -309,12 +314,23 @@ layout("/layouts/platform_h5.html"){
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
}).catch(() => {
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleInviteSeconded(val) {
|
||||
if (this.row.abandonedSecondTask === 1) {
|
||||
this.updateSecond(val).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.proposalInfoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
this.listInviteSecondedTodoCount()
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
@@ -322,11 +338,14 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.proposalInfoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
this.updateSecond(val)
|
||||
this.listInviteSecondedTodoCount()
|
||||
this.updateSecond(val).then((updateRes) => {
|
||||
if (updateRes.code === 0) {
|
||||
this.$refs.proposalInfoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
this.listInviteSecondedTodoCount()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -346,8 +365,9 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
|
||||
updateSecond(submitType) {
|
||||
this.$axios.post("/platform/proposal/seconded/updateInfo", {
|
||||
return this.$axios.post("/platform/proposal/seconded/updateInfo", {
|
||||
proposalId: this.row.id,
|
||||
taskId: this.row.taskId,
|
||||
taskActorUserId: this.row.taskActorUserId,
|
||||
opinion: this.formData.tf_opinion,
|
||||
submitType: submitType,
|
||||
|
||||
Reference in New Issue
Block a user