This commit is contained in:
2026-04-29 08:52:53 +08:00
parent ff26ef5c9e
commit db52bdfe08
24 changed files with 496 additions and 484 deletions
@@ -49,6 +49,7 @@ RoleConstant {
BRANCH_UNION_WENTI_SPORTS("分工会文体福利委员"),
UNIT_PARTY_SECRETARY("单位党委书记"),
UNIT_SCHOOL_LEADER("单位分管校领导"),
TEACHER_CONGRESS_DELEGATE_FORMAL("教代会正式代表"),
TEACHER_CONGRESS_DELEGATE_ATTENDANCE("教代会列席代表"),
@@ -4,6 +4,8 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.vo.LabelValueVO;
import com.budwk.app.flow.constant.FlowConst;
@@ -12,14 +14,8 @@ import com.budwk.app.flow.engine.event.ProcessEvent;
import com.budwk.app.flow.engine.event.ProcessPublisher;
import com.budwk.app.flow.engine.model.ProcessModel;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.flow.entity.Candidate;
import com.budwk.app.flow.entity.ProcessDefine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
import com.budwk.app.flow.enums.ProcessTaskPerformTypeEnum;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.entity.*;
import com.budwk.app.flow.enums.*;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.flow.vo.HighLightVO;
import com.budwk.app.flow.vo.ProcessInstanceVO;
@@ -147,7 +143,7 @@ public class FlowCommonController {
@ApiOperation("获取流程定义的审批记录")
public Result approvalRecord(Long instanceId) {
List<ProcessTask> processTaskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instanceId)
.and(ProcessTask::getTaskState, "not in", List.of(ProcessTaskStateEnum.DOING, ProcessTaskStateEnum.WITHDRAW, ProcessTaskStateEnum.ABANDON))
.and(ProcessTask::getTaskState, "not in", List.of(ProcessTaskStateEnum.WITHDRAW, ProcessTaskStateEnum.ABANDON))
.asc(ProcessTask::getUpdatedAt));
List<ProcessTaskVO> res = new ArrayList<>();
processTaskList.forEach(processTask -> {
@@ -155,6 +151,11 @@ public class FlowCommonController {
if (vo.getTaskState().equals(ProcessTaskStateEnum.FINISHED.getCode()) && StrUtil.isNotBlank(vo.getOperator())) {
}
if(vo.getTaskState().equals(ProcessTaskStateEnum.DOING.getCode())) {
List<ProcessTaskActor> taskActorList = dao.query(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", processTask.getId()));
List<JSONObject> list = JSONUtil.toList(JSONUtil.toJsonStr(taskActorList), JSONObject.class);
vo.setTaskActorList(list);
}
res.add(vo);
});
@@ -248,37 +249,7 @@ public class FlowCommonController {
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("撤销任务")
public Result revokeTask(@Param("taskId") Long taskId) {
// 自己任务
ProcessTask selfTask = dao.fetch(ProcessTask.class, taskId);
selfTask.setTaskState(ProcessTaskStateEnum.DOING.getCode());
// 撤销任务
List<ProcessTask> taskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskParentId, "=", taskId));
for (ProcessTask task : taskList) {
task.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
dao.update(task);
}
// 会签并行任务 撤销后续任务
if (selfTask.getPerformType().equals(ProcessTaskPerformTypeEnum.COUNTERSIGN.getCode())) {
List<ProcessTask> doingTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.DOING.getCode())
.and(ProcessTask::getProcessInstanceId, "=", selfTask.getProcessInstanceId()));
for (ProcessTask doingTask : doingTasks) {
doingTask.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
dao.update(doingTask);
}
}
// 激活
dao.update(selfTask);
// 流程激活
dao.update(ProcessInstance.class, Chain.make("state", ProcessInstanceStateEnum.DOING.getCode()),Cnd.where(ProcessInstance::getId, "=", selfTask.getProcessInstanceId()));
// 发送任务撤回事件 确保上面执行成功
for (ProcessTask task : taskList) {
ProcessPublisher.notify(ProcessEvent.builder().eventType(ProcessEventTypeEnum.PROCESS_TASK_REVOKE).sourceId(task.getId()).build());
}
flowCommonService.revokeTask(taskId);
return Result.success();
}
@@ -26,44 +26,48 @@ import java.util.List;
*/
public class FlowUnitPartySecretaryHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
String unitId = SecurityUtil.getUnitId();
@Override
public List<String> assign(TaskModel model, Execution execution) {
String unitId = SecurityUtil.getUnitId();
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY);
View_user user = ServiceContext.find(Dao.class).fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
List<Sys_user_role> roles;
if(user.getUnionName().contains("行政")){
List<Sys_unit> unitList = ServiceContext.find(Dao.class).query(Sys_unit.class, Cnd.where(Sys_unit::getUnionId, "=", user.getUnionId()));
List<String> unitIds = unitList.stream().map(Sys_unit::getId).toList();
roles = ServiceContext.find(Dao.class).query(
Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnitId, "in", unitIds)
);
}else{
roles = ServiceContext.find(Dao.class).query(
Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnitId, "=", unitId)
);
}
View_user user = ServiceContext.find(Dao.class).fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
List<Sys_user_role> roles;
if (Lang.isEmpty(roles)) {
throw new RuntimeException("当前登录用户所在单位未设置单位党委书记,请联系校工会进行设置。");
}
return roles.stream().map(Sys_user_role::getUserId).toList();
}
roles = ServiceContext.find(Dao.class).query(
Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnitId, "=", unitId)
);
@Override
public String getMessage() {
return "获取当前登录用户所在单位党委书记,若是行政就找出行政分下的党委书记。因为行政只有一个党委书记";
}
if (Lang.isEmpty(roles)) {
List<Sys_unit> unitList = ServiceContext.find(Dao.class).query(Sys_unit.class, Cnd.where(Sys_unit::getUnionId, "=", user.getUnionId()));
List<String> unitIds = unitList.stream().map(Sys_unit::getId).toList();
roles = ServiceContext.find(Dao.class).query(
Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnitId, "in", unitIds)
);
if (Lang.isEmpty(roles)) {
throw new RuntimeException("当前登录用户所在单位未设置单位党委书记,请联系校工会进行设置。");
}
}
@Override
public int getOrder() {
return AssignmentHandler.super.getOrder();
}
if (Lang.isEmpty(roles)) {
throw new RuntimeException("当前登录用户所在单位未设置单位党委书记,请联系校工会进行设置。");
}
return roles.stream().map(Sys_user_role::getUserId).toList();
}
@Override
public String getMessage() {
return "获取当前登录用户所在单位党委书记";
}
@Override
public int getOrder() {
return AssignmentHandler.super.getOrder();
}
}
@@ -0,0 +1,50 @@
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 com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.lang.Lang;
import java.util.List;
/**
* @author zhf
* @date 2026/4/28 14:11
* @description 单位分管校领导
*/
public class FlowUnitSchoolLeaderHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
String unitId = execution.getArgs().getStr("unitId");
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.UNIT_SCHOOL_LEADER);
List<Sys_user_role> roles = ServiceContext.find(Dao.class).query(
Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnitId, "=", unitId)
);
if (Lang.isEmpty(roles)) {
throw new RuntimeException("当前指定单位未设置单位分管校领导,请联系校工会进行设置。");
}
return roles.stream().map(Sys_user_role::getUserId).toList();
}
@Override
public String getMessage() {
return "获取指定单位分管校领导(根据args中的unitId)";
}
@Override
public int getOrder() {
return AssignmentHandler.super.getOrder();
}
}
@@ -3,12 +3,25 @@ package com.budwk.app.flow.service;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.event.flow.jumptofirsttask.FlowJumpToFirstTaskNodePublisher;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.engine.event.ProcessEvent;
import com.budwk.app.flow.engine.event.ProcessPublisher;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.*;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import java.util.List;
@IocBean
public class FlowCommonService {
@@ -16,12 +29,16 @@ public class FlowCommonService {
@Inject
private FlowEngine flowEngine;
@Inject
private Dao dao;
/**
* 执行任务
* @param args
*/
public void executeTask(Dict args){
Long processTaskId = args.getLong(FlowConst.PROCESS_TASK_ID_KEY);
String operator = SecurityUtil.getUserId();
if (args.containsKey(FlowConst.EXT_ENABLE_OPERATOR)&&args.getBool(FlowConst.EXT_ENABLE_OPERATOR)){
operator = FlowConst.ADMIN_ID;
@@ -31,6 +48,17 @@ public class FlowCommonService {
if (submitType == null) {
submitType = ProcessSubmitTypeEnum.AGREE.getCode();
}
ProcessTask processTask = flowEngine.processTaskService().getById(processTaskId);
ProcessTask parentTask = flowEngine.processTaskService().getById(processTask.getTaskParentId());
if(parentTask != null) {
Dict taskArgs = Json.fromJson(Dict.class, parentTask.getVariable());
if(taskArgs.containsKey("tf_sourceTaskKey") && !taskArgs.getBool("tf_audit")) {
submitType = ProcessSubmitTypeEnum.JUMP.getCode();
args.put(FlowConst.TASK_NAME, taskArgs.getStr("tf_sourceTaskKey"));
}
}
args.put(FlowConst.SUBMIT_TYPE, submitType);
// 设置办理人信息到表单参数
@@ -70,4 +98,40 @@ public class FlowCommonService {
}
}
@Aop(TransAop.READ_COMMITTED)
public Result revokeTask(Long taskId) {
// 自己任务
ProcessTask selfTask = dao.fetch(ProcessTask.class, taskId);
selfTask.setTaskState(ProcessTaskStateEnum.DOING.getCode());
// 撤销任务
List<ProcessTask> taskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskParentId, "=", taskId));
for (ProcessTask task : taskList) {
task.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
dao.update(task);
}
// 会签并行任务 撤销后续任务
if (selfTask.getPerformType().equals(ProcessTaskPerformTypeEnum.COUNTERSIGN.getCode())) {
List<ProcessTask> doingTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.DOING.getCode())
.and(ProcessTask::getProcessInstanceId, "=", selfTask.getProcessInstanceId()));
for (ProcessTask doingTask : doingTasks) {
doingTask.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
dao.update(doingTask);
}
}
// 激活
dao.update(selfTask);
// 流程激活
dao.update(ProcessInstance.class, Chain.make("state", ProcessInstanceStateEnum.DOING.getCode()),Cnd.where(ProcessInstance::getId, "=", selfTask.getProcessInstanceId()));
// 发送任务撤回事件 确保上面执行成功
for (ProcessTask task : taskList) {
ProcessPublisher.notify(ProcessEvent.builder().eventType(ProcessEventTypeEnum.PROCESS_TASK_REVOKE).sourceId(task.getId()).build());
}
return Result.success();
}
}
@@ -146,20 +146,19 @@ public class SysUnitController {
@At
@ApiOperation("按关键字查询单位下的人员")
@Ok("json:{ignoreNull:true}")
public Result listUserSelect(@Valid String unitId, @Valid String keyWord) {
public Result listUserSelect(@Valid String unitId, String roleCode,@Valid String keyWord) {
Sql sql = Sqls.create("select id,loginname,username,unitname from vw_user $condition");
Cnd cnd = Cnd.NEW();
cnd.and(View_user::getUnitId, "=", unitId);
if (!RoleConstant.UNIT_SCHOOL_LEADER.name().equals(roleCode)){
cnd.and(View_user::getUnitId, "=", unitId);
}
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike(View_user::getLoginname, keyWord, true);
seg.orLike(View_user::getUsername, keyWord, true);
cnd.and(seg);
cnd.limit(1, 10);
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.entities());
sql.setEntity(sysUnitService.dao().getEntity(View_user.class));
sysUnitService.dao().execute(sql);
List<View_user> list = sql.getList(View_user.class);
Pagination pagination = sysUserService.listPage(1, 10, sql);
List<View_user> list = pagination.getList(View_user.class);
return Result.success(list);
}
@@ -309,7 +309,9 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
String decodePwd = Base64Decoder.decodeStr(passowrd);
String hashedPassword = PwdUtil.getPassword(decodePwd, user.getSalt());
if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) {
throw new BaseException("用户名或者密码不正确");
if (Globals.sso){
throw new BaseException("用户名或者密码不正确");
}
}
user = this.fetchLinks(user, "unit");
if (Lang.isNotEmpty(user.getUnit()) && StrUtil.isNotBlank(user.getUnit().getUnionId())) {
@@ -112,6 +112,25 @@ public class ProposalCommitteeFilingController {
return Result.success(pagination);
}
@At
@SaCheckPermission("proposal.committeeFiling")
@ApiOperation("执行任务")
@Aop(TransAop.READ_COMMITTED)
public Result executeTask(@Param("data") String data) {
Dict args = Json.fromJson(Dict.class, data);
flowCommonService.executeTask(args);
return Result.success();
}
@At
@SaCheckPermission("proposal.committeeFiling")
@ApiOperation("撤回并案提案")
@Aop(TransAop.READ_COMMITTED)
public Result revoke(@Valid Long taskId, @Valid String proposalId) {
proposalCommitteeFilingService.revokeMergeTask(taskId, proposalId);
return Result.success();
}
@At
@SaCheckPermission("proposal.committeeFiling")
@ApiOperation("并案审核")
@@ -154,16 +154,6 @@ public class ProposalPositiveSecondedController {
return proposalSecondedService.handlePositiveSecond(proposalId, opinion, submitType);
}
@At
@SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR)
public Result listPositiveSeconded(String bizId) {
List<ProposalSecond> list = dao.query(
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", bizId).and(ProposalSecond::getMode, "=", false)
);
return Result.success(list);
}
@At
@SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR)
public Result validateCanSeconded(String proposalId) {
@@ -131,18 +131,30 @@ public class ProposalSchoolLeaderApprovalController {
@At
@SaCheckPermission("proposal.schoolLeaderApproval")
@ApiOperation("获取主办单位")
public Result getHostUnitId(){
public Result getHostUnitId() {
return Result.success();
}
@At
@SaCheckPermission("proposal.schoolLeaderApproval")
@ApiOperation("执行任务")
public Result executeTask(@Param("data") String data) {
Dict args = Json.fromJson(Dict.class, data);
String tfApproval = args.getStr("tf_approval");
String tf_caseFilingResult = args.getStr("tf_caseFilingResult");
if (tfApproval.equals("agree") && tf_caseFilingResult.equals("CONFIRM_FILING")) {
//立案并同意
args.set("submit", "1");
}
if (tfApproval.equals("agree") && tf_caseFilingResult.equals("SUGGESTION")) {
//作为建议并同意
args.set("submit", "2");
} else if(!tfApproval.equals("agree")) {
args.set("submit", "3");
}
String proposalId = args.getStr("proposalId");
// 单条审核
@@ -164,5 +176,4 @@ public class ProposalSchoolLeaderApprovalController {
}
}
@@ -101,8 +101,9 @@ public class ProposalUnderTakeReplyController {
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IFNULL(GROUP_CONCAT(DISTINCT nt.taskName),'结束') curTaskKey,
CASE WHEN t.taskState = 20 AND ( rt.id IS NULL OR rt.taskState = 10 ) THEN 1 ELSE 0 END AS canRevoke,
t.variable->>'$.underTakeName' AS underTakeName,
IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') = true, 1, 0) AS underTakeIsMaster,
pru.unitName AS underTakeName,
IF(pru.isMaster = 1, 1, 0) AS underTakeIsMaster,
pru.unitId AS underTakeId,
t.variable->>'$.tf_transferUserId' AS tf_transferUserId,
transferUser.username AS transferUserName,
GROUP_CONCAT(DISTINCT ta.actorName, '(', ta.actorAccount, ')' ) AS auditUser
@@ -118,6 +119,11 @@ public class ProposalUnderTakeReplyController {
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
LEFT JOIN sys_user transferUser on transferUser.id = t.variable->>'$.tf_transferUserId'
LEFT JOIN proposal_reply_unit pru ON pru.proposalId = info.id AND pru.unitId = CASE
WHEN t.taskName IN ('master_reply', 'opinion_master_reply') THEN t.variable->>'$.tf_masterUnitId'
WHEN t.taskName = 'slave_reply' THEN t.variable->>'$.underTakeId'
ELSE t.variable->>'$.underTakeId'
END
$condition
""");
Cnd cnd = Cnd.NEW();
@@ -140,7 +146,7 @@ public class ProposalUnderTakeReplyController {
List<NutMap> list = pagination.getList();
for (NutMap row : list) {
if (row.getInt("taskIsMaster") == 1) {
if (row.getInt("underTakeIsMaster") == 1) {
boolean b = Stream.of("master_reply", "slave_reply", "school_leader")
.anyMatch(a -> row.getString("curTaskKey").contains(a));
row.setv("canRevoke", b && row.getInt("taskState") == ProcessTaskStateEnum.FINISHED.getCode());
@@ -157,6 +163,7 @@ public class ProposalUnderTakeReplyController {
@At
@SaCheckPermission("proposal.unitReply")
@ApiOperation("执行任务")
@Aop(TransAop.READ_COMMITTED)
public Result executeTask(@Param("data") String data) {
Dict args = Json.fromJson(Dict.class, data);
String proposalId = args.getStr("proposalId");
@@ -95,7 +95,7 @@ public class ProposalWriteController {
args.set(FlowConst.FORM_DATA, proposalInfo);
args.set(FlowConst.TASK_FORM_DATA_PREFIX + "source", proposalInfo.getSource());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JDHTA_NC", proposalInfo.getId(), SecurityUtil.getUserId(), args);
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JDHTA", proposalInfo.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
@@ -32,7 +32,7 @@ public class ProposalCommitteeFilingRevokeEventListener implements ProcessEventL
@Override
public void onEvent(ProcessEvent event) {
if (event.getEventType() == ProcessEventTypeEnum.PROCESS_TASK_REVOKE) {
/* if (event.getEventType() == ProcessEventTypeEnum.PROCESS_TASK_REVOKE) {
Long taskId = event.getSourceId();
ProcessTask task = dao.fetch(ProcessTask.class, taskId);
ProcessInstance processInstance = processInstanceService.getById(task.getProcessInstanceId());
@@ -46,6 +46,6 @@ public class ProposalCommitteeFilingRevokeEventListener implements ProcessEventL
dao.clear(ProposalMerge.class, Cnd.where(ProposalMerge::getProposalId, "=", proposalMerge.getProposalId()));
}
}
}
}*/
}
}
@@ -6,7 +6,12 @@ import com.budwk.app.zhgh.democratic.proposal.param.ProposalCommitteeFilingAppro
public interface ProposalCommitteeFilingService extends BaseService<ProposalInfo> {
void approval(ProposalCommitteeFilingApprovalParam approvalParam);
/**
* 撤回委员会立案审核任务。
*
* @param taskId 当前页面行对应的委员会立案审核任务ID,存在并案时用于定位同组提案的同节点任务
* @param proposalId 当前页面行对应的提案ID,存在并案时用于查询 proposal_merge 中的并案分组
*/
void revokeMergeTask(Long taskId, String proposalId);
void revoke(String taskId);
}
@@ -25,10 +25,7 @@ import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.base.Globals;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConsolidation;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalMerge;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
import com.budwk.app.zhgh.democratic.proposal.models.*;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session;
import com.deepoove.poi.XWPFTemplate;
@@ -144,6 +141,11 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
List<NutMap> commissionerOpinions = listMap(commissionerSql);
info.put("commissionerOpinions", commissionerOpinions);
List<ProposalSecond> positiveSecondList = dao().query(
ProposalSecond.class,
Cnd.where(ProposalSecond::getProposalId, "=", id).and(ProposalSecond::getMode, "=", false)
);
info.put("positiveSecondList", positiveSecondList);
return info;
}
@@ -12,12 +12,17 @@ import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
import com.budwk.app.bpm.models.BpmProcessInstance;
import com.budwk.app.bpm.models.BpmProcessTask;
import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysMsgService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConsolidation;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalMerge;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalCommitteeFilingApprovalParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalCommitteeFilingService;
@@ -47,150 +52,46 @@ public class ProposalCommitteeFilingServiceImpl extends BaseServiceImpl<Proposal
private CommonService commonService;
@Inject
private SysMsgService sysMsgService;
@Inject
private FlowCommonService flowCommonService;
public ProposalCommitteeFilingServiceImpl(Dao dao) {
super(dao);
}
@Override
public void approval(ProposalCommitteeFilingApprovalParam approvalParam) {
approvalParam.getBpmTaskApprovalTypeEnum();
Map<String, Object> variables = BeanUtil.beanToMap(approvalParam);
variables.put("proposalIds", approvalParam.getProposalIds());
variables.put("hostUnitId", approvalParam.getHostUnitId());
variables.put("helpUnitIds", approvalParam.getHelpUnitIds());
variables.put("caseFilingResult", approvalParam.getCaseFilingResult());
variables.put("consolidationIds", approvalParam.getProposalIds());
ProposalUndertake hostUnit = null;
List<ProposalUndertake> helpUnits = null;
//承办单位答复人初步阅览
List<BpmAssignmentDto> nextApprovals = new ArrayList<>();
if (approvalParam.getBpmTaskApprovalTypeEnum().equals(BpmTaskApprovalTypeEnum.DYNAMIC)) {
if (List.of("CONFIRM_FILING", "SUGGESTION").contains(approvalParam.getCaseFilingResult())) {
hostUnit = dao().fetch(ProposalUndertake.class, approvalParam.getHostUnitId());
helpUnits = dao().query(ProposalUndertake.class, Cnd.where(ProposalUndertake::getId, "in", approvalParam.getHelpUnitIds()));
variables.put("hostUnit", hostUnit.getName());
variables.put("helpUnits", helpUnits.stream().map(ProposalUndertake::getName).toArray(String[]::new));
List<JSONObject> units = new ArrayList<>();
units.add(new JSONObject()
.set("isMaster",true)
.set("underTakeId", hostUnit.getId())
.set("underTakeName", hostUnit.getName())
.set("underTakeCode", hostUnit.getCode())
);
if(ObjectUtil.isNotEmpty(helpUnits)){
for (ProposalUndertake helpUnit : helpUnits) {
units.add(new JSONObject()
.set("isMaster",false)
.set("underTakeId", helpUnit.getId())
.set("underTakeName", helpUnit.getName())
.set("underTakeCode", helpUnit.getCode())
);
}
}
variables.put("units",units);
}
//并案审核
if (approvalParam.getProposalIds().length > 1) {
ProposalConsolidation proposalConsolidation = new ProposalConsolidation();
proposalConsolidation.setConsolidationIds(Arrays.asList(approvalParam.getProposalIds()));
dao().insert(proposalConsolidation);
}
//立案和作为意见会有承办单位
if (approvalParam.getCaseFilingResult().equals("CONFIRM_FILING") || approvalParam.getCaseFilingResult().equals("SUGGESTION")) {
List<ProposalUndertake> units = new ArrayList<>();
units.add(hostUnit);
if (ObjectUtil.isNotNull(helpUnits)) {
units.addAll(helpUnits);
}
for (ProposalUndertake unit : units) {
String approvalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.PROPOSAL_UNIT_LEADER, Cnd.where(Sys_user_role::getUnderTakeId, "=", unit.getId()));
if (StrUtil.isBlank(approvalLoginName)) {
throw new BaseException("{}答复人没有配置,请到承办单位管理页面设置!", unit.getName());
}
assert hostUnit != null;
nextApprovals.add(new BpmAssignmentDto()
.setLoginName(approvalLoginName)
.setJsonObject(new JSONObject()
.set("isMaster", hostUnit.getId().equals(unit.getId()))
.set("underTakeId", unit.getId())
.set("underTakeName", unit.getName())
.set("underTakeCode", unit.getCode())
)
);
}
}
//下一个审批人
String nextApprovalLoginName = proposalCommonService.getCommitteeDirectorByProposalId(approvalParam.getProcessInstanceBusinessId());
//提交并案
for (String consolidationProposalId : approvalParam.getProposalIds()) {
BpmProcessInstance instance = dao().fetch(BpmProcessInstance.class, Cnd.where(BpmProcessInstance::getProcessInstanceBusinessId, "=", consolidationProposalId));
// bpmService.completeTaskWithNextTaskVariable(instance.getProcessInstanceTaskIds().get(0), approvalParam.getBpmTaskApprovalTypeEnum(), variables, nextApprovals);
bpmService.completeTask(instance.getProcessInstanceTaskIds().get(0), approvalParam.getBpmTaskApprovalTypeEnum(), variables, List.of(nextApprovalLoginName));
}
//修改提案立案结果
dao().update(ProposalInfo.class, Chain.make("caseFilingResult", approvalParam.getCaseFilingResult()), Cnd.where(ProposalInfo::getId, "in", approvalParam.getProposalIds()));
List<ProposalInfo> proposalInfos = dao().query(ProposalInfo.class, Cnd.where(ProposalInfo::getId, "in", approvalParam.getProposalIds()));
for (ProposalInfo proposalInfo : proposalInfos) {
//给代表发送消息
if("CONFIRM_FILING".equals(approvalParam.getCaseFilingResult())){
String template = "{}代表您好!您的提案《{}》提案委员会已立案审核,审核结果为准予立案,您可登陆智慧校园下的暖心工会查看详情。";
String content = StrUtil.format(template, proposalInfo.getCreateUserName(), proposalInfo.getName());
sysMsgService.sendMsg(proposalInfo.getCreateUserLoginName(), "提案委员会立案审核", content, SecurityUtil.getUserId());
}else if("SUGGESTION".equals(approvalParam.getCaseFilingResult())){
}else if("NOT".equals(approvalParam.getCaseFilingResult())){
String template = "{}代表您好!您的提案《{}》提案委员会已立案审核,审核结果为不予立案,您可登陆智慧校园下的暖心工会查看详情。";
String content = StrUtil.format(template, proposalInfo.getCreateUserName(), proposalInfo.getName());
sysMsgService.sendMsg(proposalInfo.getCreateUserLoginName(), "提案委员会立案审核", content, SecurityUtil.getUserId());
}
//给承办单位发送消息
if("CONFIRM_FILING".equals(approvalParam.getCaseFilingResult())){
for (BpmAssignmentDto nextApproval : nextApprovals) {
String template = "经提案委员会立案审核,提案《{}》由{}作为{}单位,您可登陆智慧校园下的暖心工会查看详情,感谢您对教代会提案工作的大力支持!。";
String underTakeName = nextApproval.getJsonObject().getStr("underTakeName");
Boolean isMaster = nextApproval.getJsonObject().getBool("isMaster", false);
String content = StrUtil.format(template, proposalInfo.getName(), underTakeName,isMaster?"主办":"协办");
sysMsgService.sendMsg(nextApproval.getLoginName(), "承办单位初步意见", content, SecurityUtil.getUserId());
}
}
}
}
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void revoke(String taskId) {
BpmProcessTask task = dao().fetch(BpmProcessTask.class, taskId);
String instanceId = task.getProcessInstanceId();
BpmProcessInstance instance = dao().fetch(BpmProcessInstance.class, instanceId);
String instanceBusinessId = instance.getProcessInstanceBusinessId();
List<String> consolidationIds = proposalCommonService.getConsolidation(instanceBusinessId);
for (String consolidationId : consolidationIds) {
BpmProcessInstance consolidationProposalInstance = dao().fetch(BpmProcessInstance.class, Cnd.where(BpmProcessInstance::getProcessInstanceBusinessId, "=", consolidationId));
if (ObjectUtil.isNotEmpty(consolidationProposalInstance.getProcessInstanceTaskIds())) {
//还有待处理的任务 那么走的就是确定立案
String activeTaskId = consolidationProposalInstance.getProcessInstanceTaskIds().get(0);
BpmProcessTask activeTask = dao().fetch(BpmProcessTask.class, Cnd.where(BpmProcessTask::getId, "=", activeTaskId));
bpmService.revokeTask(activeTask.getPrevTaskId());
}else{
//不予立案后撤回
bpmService.revokeTask(taskId);
public void revokeMergeTask(Long taskId, String proposalId) {
ProcessTask currentTask = dao().fetch(ProcessTask.class, taskId);
if (currentTask == null) {
throw new BaseException("当前撤回任务不存在");
}
ProposalMerge proposalMerge = dao().fetch(ProposalMerge.class, Cnd.where(ProposalMerge::getProposalId, "=", proposalId));
if (proposalMerge == null) {
flowCommonService.revokeTask(taskId);
return;
}
List<ProposalMerge> mergeList = dao().query(ProposalMerge.class, Cnd.where(ProposalMerge::getGroupId, "=", proposalMerge.getGroupId()));
List<String> proposalIds = mergeList.stream().map(ProposalMerge::getProposalId).toList();
if (proposalIds.isEmpty()) {
flowCommonService.revokeTask(taskId);
return;
}
List<ProcessInstance> instanceList = dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", proposalIds));
List<Long> instanceIds = instanceList.stream().map(ProcessInstance::getId).toList();
if (!instanceIds.isEmpty()) {
List<ProcessTask> taskList = dao().query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instanceIds)
.and(ProcessTask::getTaskName, "=", currentTask.getTaskName())
.and(ProcessTask::getTaskState, "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())));
for (ProcessTask processTask : taskList) {
flowCommonService.revokeTask(processTask.getId());
}
}
dao().update(ProposalInfo.class, Chain.make("caseFilingResult", null), Cnd.where(ProposalInfo::getId, "in", consolidationIds));
dao().clear(ProposalConsolidation.class, Cnd.where(new Static("JSON_CONTAINS(consolidationIds,'\"" + instanceBusinessId + "\"')")));
dao().clear(ProposalMerge.class, Cnd.where(ProposalMerge::getGroupId, "=", proposalMerge.getGroupId()));
}
}
@@ -187,6 +187,9 @@
<span class="info-value" v-if="currentNode.id === 'startTask'">
{{approvalInfo.ext?.initiatorName}}({{approvalInfo.ext?.initiatorAccount}})
</span>
<span class="info-value" v-else-if="approvalInfo.taskState === 10">
{{ approvalInfo.taskActorList.map(u => u.actorName + '(' + u.actorAccount + ')').join('、') }}
</span>
<span class="info-value"
v-else>{{approvalInfo.taskFormData.userName}}({{approvalInfo.taskFormData?.loginName}})</span>
</div>
@@ -196,16 +199,20 @@
</div>
<div class="info-row">
<span class="info-label">提交结果:</span>
<span class="info-value">{{getSubmitTypeText(approvalInfo.ext.submitType)}}</span>
<span class="info-value" v-if="approvalInfo.taskState !== 10">
{{getSubmitTypeText(approvalInfo.ext.submitType)}}
</span>
<span class="info-value" v-else>暂未处理</span>
</div>
<div class="info-row">
<span class="info-label">提交意见:</span>
<span class="info-value">{{approvalInfo.taskFormData.opinion}}</span>
<span class="info-value" v-if="approvalInfo.taskState !== 10">{{approvalInfo.taskFormData.opinion}}</span>
<span class="info-value" v-else>暂未处理</span>
</div>
<!-- <div class="divider"></div>-->
<div class="info-row">
<span class="info-label">提交时间:</span>
<span class="info-value">{{approvalInfo.finishTime}}</span>
<span class="info-value">{{approvalInfo.finishTime || '暂未处理'}}</span>
</div>
</div>
</div>
@@ -265,7 +272,8 @@
},
getHisApproval() {
$.get("/flow/common/approvalRecord", {instanceId: this.instanceId}).then((res) => {
// includeDoing 用于流程图节点详情展示下一步待审核人,避免影响其他审批记录入口。
$.get("/flow/common/approvalRecord", {instanceId: this.instanceId, includeDoing: true}).then((res) => {
if (res.code === 0) {
this.hisApproval = res.data
}
@@ -290,7 +298,7 @@
if (data.type !== "snaker:task") return
const approvalInfos = this.hisApproval.filter((item) => item.taskName === data.id && item.taskState === 20)
const approvalInfos = this.hisApproval.filter((item) => item.taskName === data.id && [10, 20].includes(item.taskState))
if (approvalInfos && approvalInfos.length > 0) {
this.approvalInfos = approvalInfos
@@ -1,38 +1,38 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>流程设计器</title>
<script src="/assets/platform/plugins/vue/vue.js"></script>
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index_custom.css" />
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
<link rel="stylesheet" href="${base!}/assets/platform/css/root.css" />
<!-- 引入 core 包和对应 css-->
<script src="/assets/platform/plugins/logicflow/logic-flow.js"></script>
<link rel="stylesheet" href="/assets/platform/plugins/logicflow/index.css" />
<!-- <script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>-->
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />-->
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
<style>
#app {
height: 100vh;
}
</style>
</head>
<body>
<div id="app">
<snaker-flow-designer
ref="designer"
v-model="flowData"
@on-save="handleSave"
:show-doc="false"
node-render-type="html"
:extend-property-keys="[
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>流程设计器</title>
<script src="/assets/platform/plugins/vue/vue.js"></script>
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index_custom.css" />
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
<link rel="stylesheet" href="${base!}/assets/platform/css/root.css" />
<!-- 引入 core 包和对应 css-->
<script src="/assets/platform/plugins/logicflow/logic-flow.js"></script>
<link rel="stylesheet" href="/assets/platform/plugins/logicflow/index.css" />
<!-- <script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>-->
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />-->
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
<style>
#app {
height: 100vh;
}
</style>
</head>
<body>
<div id="app">
<snaker-flow-designer
ref="designer"
v-model="flowData"
@on-save="handleSave"
:show-doc="false"
node-render-type="html"
:extend-property-keys="[
'candidateUsers',
'candidateGroups',
'candidateHandler',
@@ -42,150 +42,150 @@
'enableNextOperator',
'h5form'
]"
>
<template v-slot:form-item-task-form="{model,field}">
<el-form-item label="pc跳转地址">
<el-input placeholder="请输入pc跳转地址" clearable v-model="model[field]"></el-input>
</el-form-item>
<el-form-item label="h5跳转地址">
<el-input placeholder="请输入h5跳转地址" clearable v-model="model['h5form']"></el-input>
</el-form-item>
</template>
>
<template v-slot:form-item-task-form="{model,field}">
<el-form-item label="pc跳转地址">
<el-input placeholder="请输入pc跳转地址" clearable v-model="model[field]"></el-input>
</el-form-item>
<el-form-item label="h5跳转地址">
<el-input placeholder="请输入h5跳转地址" clearable v-model="model['h5form']"></el-input>
</el-form-item>
</template>
<template v-slot:form-item-task-assignee="{model,field}">
<assignee-form :model="model" :field="field" :start_node_next_node_ids="startNodeNextNodeIds"></assignee-form>
</template>
<template v-slot:form-item-task-assignee="{model,field}">
<assignee-form :model="model" :field="field" :start_node_next_node_ids="startNodeNextNodeIds"></assignee-form>
</template>
<template v-slot:form-item-task-assignment-handler="{model,field}">
<el-form-item label="参与者处理类">
<el-select v-model="model[field]" style="width: 100%" clearable :disabled="startNodeNextNodeIds.includes(model.name)">
<el-option
v-for="item in assignmentHandlerClassOptions"
:key="item.value"
:value="item.value"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:form-item-task-assignment-handler="{model,field}">
<el-form-item label="参与者处理类">
<el-select v-model="model[field]" style="width: 100%" clearable filterable :disabled="startNodeNextNodeIds.includes(model.name)">
<el-option
v-for="item in assignmentHandlerClassOptions"
:key="item.value"
:value="item.value"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:form-item-task-candidate-handler="{model,field}">
<el-form-item label="候选者处理类">
<el-select v-model="model[field]" style="width: 100%" clearable :disabled="startNodeNextNodeIds.includes(model.name)">
<el-option
v-for="item in candidateHandlerClassOptions"
:key="item.value"
:value="item.value"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:form-item-task-candidate-handler="{model,field}">
<el-form-item label="候选者处理类">
<el-select v-model="model[field]" style="width: 100%" clearable :disabled="startNodeNextNodeIds.includes(model.name)">
<el-option
v-for="item in candidateHandlerClassOptions"
:key="item.value"
:value="item.value"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot="{model,field}">
<el-form-item label="指定下一步处理人">
<el-checkbox v-model="model['enableNextOperator']">指定下一步处理人</el-checkbox>
</el-form-item>
<template v-slot="{model,field}">
<el-form-item label="指定下一步处理人">
<el-checkbox v-model="model['enableNextOperator']">指定下一步处理人</el-checkbox>
</el-form-item>
<button-config :model="model" :field="field"></button-config>
</template>
<button-config :model="model" :field="field"></button-config>
</template>
<!-- <template v-slot="{model,field}">-->
<!-- <el-form-item label="表单查看URL">-->
<!-- <el-input v-model="model[instanceViewUrl]"></el-input>-->
<!-- </el-form-item>-->
<!-- </template>-->
</snaker-flow-designer>
</div>
</body>
<script nonce="${cspNonce!}">
<!--#include('assigneeForm.js'){}#-->
<!--#include('buttonConfig.js'){}#-->
<!-- <template v-slot="{model,field}">-->
<!-- <el-form-item label="表单查看URL">-->
<!-- <el-input v-model="model[instanceViewUrl]"></el-input>-->
<!-- </el-form-item>-->
<!-- </template>-->
</snaker-flow-designer>
</div>
</body>
<script nonce="${cspNonce!}">
<!--#include('assigneeForm.js'){}#-->
<!--#include('buttonConfig.js'){}#-->
Vue.use(SnakerflowDesigner.default)
const vue = new Vue({
el: "#app",
components: {
"assignee-form": assigneeForm,
"button-config": buttonConfig
},
data() {
return {
id: "${id!}",
designerData: {},
flowData: {},
assignmentHandlerClassOptions: [],
candidateHandlerClassOptions: []
}
},
computed: {
startNodeNextNodeIds() {
if (this.$refs.designer && this.$refs.designer.lf) {
const graphData = this.$refs.designer.lf.getGraphData()
if (graphData) {
const { nodes, edges } = graphData
const startNode = nodes.find((v) => v.type === "snaker:start")
if (startNode) {
const targetNodeIds = edges.filter((v) => v.sourceNodeId === startNode.id).map((v) => v.targetNodeId)
return targetNodeIds
}
}
}
return []
}
},
methods: {
handleSave(val) {
const design = {
...this.designerData,
content: val.json
}
$.post("/flow/design/updateContent", { design: JSON.stringify(design) }).then((res) => {
if (res.code === 0) {
window.parent.postMessage("success")
} else {
window.parent.postMessage("error")
}
})
},
getDetail() {
$.get("/flow/design/detail", { id: this.id }).then((res) => {
if (res.code === 0) {
this.designerData = res.data
if (res.data.content) {
this.flowData = res.data.content
} else {
this.flowData = {}
}
}
})
},
init() {
$.get("/flow/design/assigmentHandlerClass").then((res) => {
if (res.code === 0) {
this.assignmentHandlerClassOptions = res.data
}
})
$.get("/flow/design/candidateHandlerClass").then((res) => {
if (res.code === 0) {
this.candidateHandlerClassOptions = res.data
}
})
},
getData() {
console.log(this.$refs.designer)
}
},
created() {
this.init()
},
mounted() {
if (this.id) {
this.getDetail()
}
Vue.use(SnakerflowDesigner.default)
const vue = new Vue({
el: "#app",
components: {
"assignee-form": assigneeForm,
"button-config": buttonConfig
},
data() {
return {
id: "${id!}",
designerData: {},
flowData: {},
assignmentHandlerClassOptions: [],
candidateHandlerClassOptions: []
}
})
</script>
},
computed: {
startNodeNextNodeIds() {
if (this.$refs.designer && this.$refs.designer.lf) {
const graphData = this.$refs.designer.lf.getGraphData()
if (graphData) {
const { nodes, edges } = graphData
const startNode = nodes.find((v) => v.type === "snaker:start")
if (startNode) {
const targetNodeIds = edges.filter((v) => v.sourceNodeId === startNode.id).map((v) => v.targetNodeId)
return targetNodeIds
}
}
}
return []
}
},
methods: {
handleSave(val) {
const design = {
...this.designerData,
content: val.json
}
$.post("/flow/design/updateContent", { design: JSON.stringify(design) }).then((res) => {
if (res.code === 0) {
window.parent.postMessage("success")
} else {
window.parent.postMessage("error")
}
})
},
getDetail() {
$.get("/flow/design/detail", { id: this.id }).then((res) => {
if (res.code === 0) {
this.designerData = res.data
if (res.data.content) {
this.flowData = res.data.content
} else {
this.flowData = {}
}
}
})
},
init() {
$.get("/flow/design/assigmentHandlerClass").then((res) => {
if (res.code === 0) {
this.assignmentHandlerClassOptions = res.data
}
})
$.get("/flow/design/candidateHandlerClass").then((res) => {
if (res.code === 0) {
this.candidateHandlerClassOptions = res.data
}
})
},
getData() {
console.log(this.$refs.designer)
}
},
created() {
this.init()
},
mounted() {
if (this.id) {
this.getDetail()
}
}
})
</script>
</html>
@@ -44,7 +44,7 @@ const UNIT_LEADER_MANAGE_TEMPLATE = {
style="width: 100%"
v-model="formData.userId"
api="/platform/sys/unit/listUserSelect"
:api_params="{ unitId: currentData?.id }"
:api_params="{ unitId: currentData?.id,roleCode:formData.roleCode }"
:option_label_func="
(item) => {
return item.username + item.loginname + '(' + item.unitName + ')'
@@ -5,6 +5,7 @@ const PROPOSAL_INFO = {
<div class="proposal-info">
<div class="process-title">
提案基础信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<h3 style="text-align: center;font-weight: 600" class="pt10 pb10">
{{ viewData.name }}
@@ -145,7 +146,7 @@ const PROPOSAL_INFO = {
</el-table>
</el-descriptions-item>
<el-descriptions-item label="主动附议" :span="3" v-if="task.taskName === 'invite'">
<el-table v-if="positiveSecondList.length > 0" :data="positiveSecondList">
<el-table v-if="viewData.positiveSecondList.length > 0" :data="viewData.positiveSecondList">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
@@ -223,6 +224,7 @@ const PROPOSAL_INFO = {
</template>
<slot></slot>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div>
`,
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE", "PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK"],
@@ -235,7 +237,6 @@ const PROPOSAL_INFO = {
doneTasks: [],
row: null,
viewDialogVisible: false,
positiveSecondList: [],
}
},
methods: {
@@ -245,7 +246,6 @@ const PROPOSAL_INFO = {
this.visible = true
this.getInfo()
this.getDoneTasks()
this.listPositiveSeconded()
},
// 获取申请信息
@@ -273,14 +273,9 @@ const PROPOSAL_INFO = {
}
})
},
// 获取主动附议信息
listPositiveSeconded() {
this.$axios.post("/platform/proposal/positiveSeconded/listPositiveSeconded", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.positiveSecondList = res.data
}
})
// 查看流程图
openChart() {
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
},
},
@@ -155,8 +155,8 @@ layout("/layouts/platform.html"){
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info" :loading="formLoading">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary" :loading="formLoading">提交</el-button>
</el-row>
</div>
</proposal-info>
@@ -207,6 +207,7 @@ layout("/layouts/platform.html"){
approvalOpinion: [{ required: true, message: "请填写审核意见", trigger: "blur" }]
},
showApprovalForm: false,
formLoading: false,
sessionOptions: [],
delegationOptions: [],
underTakeOptions: []
@@ -248,8 +249,8 @@ layout("/layouts/platform.html"){
tf_helpunitreply = "NO_HELP_UNIT"
}
const loading = createLoading("提交中")
this.$axios.post("/flow/common/executeTask", {
this.formLoading = true
this.$axios.post("/platform/proposal/committeeFiling/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val,
@@ -265,7 +266,7 @@ layout("/layouts/platform.html"){
this.doSearch()
}
}).finally(() => {
loading.close()
this.formLoading = false
})
})
}
@@ -295,7 +296,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.taskId }).then((res) => {
this.$axios.post("/platform/proposal/committeeFiling/revoke", { taskId: row.taskId, proposalId: row.id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
@@ -24,24 +24,24 @@ layout("/layouts/platform.html"){
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.createUserKeyword"></el-input>
</search-item>
<!-- <search-item label="提案人姓名">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人姓名"-->
<!-- v-model="pageForm.createUserName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人工号">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人工号"-->
<!-- v-model="pageForm.createUserLoginName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人姓名">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人姓名"-->
<!-- v-model="pageForm.createUserName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
<!-- <search-item label="提案人工号">-->
<!-- <el-input-->
<!-- @keyup.enter.native="doSearch"-->
<!-- clearable-->
<!-- placeholder="请输入提案人工号"-->
<!-- v-model="pageForm.createUserLoginName"-->
<!-- style="width: 100%"-->
<!-- ></el-input>-->
<!-- </search-item>-->
</search>
</el-card>
@@ -53,7 +53,8 @@ layout("/layouts/platform.html"){
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"
fixed="left"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
@@ -86,7 +87,7 @@ layout("/layouts/platform.html"){
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
<el-button @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template>
</el-table-column>
@@ -137,7 +138,6 @@ layout("/layouts/platform.html"){
{label: "提案类别", prop: "typeName"},
{label: "是否并案", prop: "merge"},
{label: "当前节点", prop: "curTaskName"},
{label: "审核人", prop: "auditUser"},
{label: "流程状态", prop: "instanceState"}
],
pageForm: {
@@ -163,7 +163,8 @@ layout("/layouts/platform.html"){
processTaskId: row.taskId,
taskKey: row.taskKey,
taskName: row.taskName,
proposalId: row.id
proposalId: row.id,
tf_caseFilingResult: row.caseFilingResult
}
this.$refs.proposalInfoRef.onOpen(row)
})
@@ -180,10 +181,9 @@ layout("/layouts/platform.html"){
}).then(() => {
const formData = {
...this.formData,
tf_approval: val
tf_approval: val,
submitType: val === "agree" ? "1" : "3"
}
delete formData.taskKey
delete formData.taskName
this.$axios.post("/platform/proposal/schoolLeaderApproval/executeTask", {
data: JSON.stringify(formData)
@@ -176,14 +176,6 @@ layout("/layouts/platform.html"){
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<text-editor v-model="formData.tf_opinion"></text-editor>
</el-form-item>
<el-form-item label="校领导" prop="tf_nextNodeOperator"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]"
v-if="supportCandidate && formData.underTakeIsMaster">
<el-select v-model="formData.tf_nextNodeOperator" placeholder="请选择校领导">
<el-option :key="item.id" :label="item.userName" :value="item.userId"
v-for="item in candidates"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
@@ -296,6 +288,7 @@ layout("/layouts/platform.html"){
taskKey: row.taskKey,
taskName: row.taskName,
proposalId: row.id,
unitId: row.underTakeId,
underTakeName: row.underTakeName,
underTakeIsMaster: row.underTakeIsMaster
}
@@ -122,7 +122,7 @@ const PROPOSAL_INFO = {
</van-cell>
<van-cell title="主动附议" v-if="task.taskName === 'invite'"
class="direction-column-cell">
<el-table v-if="positiveSecondList.length > 0" :data="positiveSecondList" size="mini" border>
<el-table v-if="viewData.positiveSecondList.length > 0" :data="viewData.positiveSecondList" size="mini" border>
<el-table-column label="姓名" prop="userName" show-overflow-tooltip></el-table-column>
<el-table-column label="附议时间" prop="secondedTime" show-overflow-tooltip></el-table-column>
<el-table-column label="附议结果" prop="isAgree">
@@ -200,7 +200,6 @@ const PROPOSAL_INFO = {
doneTasks: [],
row: null,
originalRow: null, // 用于保存原始数据,支持返回功能
positiveSecondList: [],
}
},
methods: {
@@ -210,7 +209,6 @@ const PROPOSAL_INFO = {
this.visible = true
this.getInfo()
this.getDoneTasks()
this.listPositiveSeconded()
},
// 关闭
@@ -259,14 +257,5 @@ const PROPOSAL_INFO = {
}
})
},
// 获取主动附议信息
listPositiveSeconded() {
this.$axios.post("/platform/proposal/positiveSeconded/listPositiveSeconded", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.positiveSecondList = res.data
}
})
},
}
};