This commit is contained in:
那些花儿
2025-08-27 12:02:30 +08:00
parent 514889e8e5
commit 1e9e14cc1f
73 changed files with 2506 additions and 3221 deletions
@@ -7,7 +7,7 @@ public interface FlowConst {
// 业务流程号 // 业务流程号
String BUSINESS_NO = "BUSINESS_NO"; String BUSINESS_NO = "BUSINESS_NO";
// 超级管理员ID // 超级管理员ID
String ADMIN_ID = "flow.admin"; String ADMIN_ID = "17a7f8ad3ee947b4a26175049a9c253d";
// 自动执行ID // 自动执行ID
String AUTO_ID = "flow.auto"; String AUTO_ID = "flow.auto";
String PROCESS_NAME_KEY = "name"; String PROCESS_NAME_KEY = "name";
@@ -11,13 +11,13 @@ import lombok.Getter;
@Getter @Getter
public enum ProcessSubmitTypeEnum { public enum ProcessSubmitTypeEnum {
APPLY(0, "发起申请"), APPLY(0, "发起申请"),
AGREE(1, "同意申请"), AGREE(1, "同意"),
REJECT(2, "拒绝申请"), REJECT(2, "拒绝"),
ROLLBACK(3, "退回上一步"), ROLLBACK(3, "退回上一步"),
JUMP(4, "跳转"), JUMP(4, "跳转"),
RE_APPLY(5, "重新提交"), RE_APPLY(5, "重新提交"),
ROLLBACK_TO_OPERATOR(6, "退回发起人"), ROLLBACK_TO_OPERATOR(6, "退回发起人"),
COUNTERSIGN_DISAGREE(20, "拒绝申请"); COUNTERSIGN_DISAGREE(20, "会签不同意");
private final Integer code; private final Integer code;
private final String message; private final String message;
@@ -1,9 +1,18 @@
package com.budwk.app.flow.handler; package com.budwk.app.flow.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.AssignmentHandler; import com.budwk.app.flow.engine.AssignmentHandler;
import com.budwk.app.flow.engine.core.Execution; import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext; import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel; 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.dao.Dao;
import java.util.List; import java.util.List;
@@ -15,7 +24,14 @@ public class FlowFghzxAssignmentHandler implements AssignmentHandler {
@Override @Override
public List<String> assign(TaskModel model, Execution execution) { public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class); Dao dao = ServiceContext.find(Dao.class);
return List.of("17a7f8ad3ee947b4a26175049a9c253d"); SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.BRANCH_UNION_CHAIRMAN);
String unionId = StrUtil.blankToDefault(execution.getArgs().getStr(FlowConst.INITIATOR_UNIT_UNION_ID), SecurityUtil.getUnionId());
Sys_user_role user_role = dao.fetch(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId()).and(Sys_user_role::getUnionId, "=", unionId));
if (user_role == null) {
throw new BaseException("分工会主席没有设置,请联系校工会!", sysRole.getCode());
}
return List.of(user_role.getUserId());
} }
@Override @Override
@@ -401,10 +401,10 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
// 增加是否为第一个任务节点标识 // 增加是否为第一个任务节点标识
execution.getArgs().put(FlowConst.IS_FIRST_TASK_NODE, FlowUtil.isFistTaskName(execution.getProcessModel(), taskModel.getName())); execution.getArgs().put(FlowConst.IS_FIRST_TASK_NODE, FlowUtil.isFistTaskName(execution.getProcessModel(), taskModel.getName()));
//过滤上个任务的表单数据 避免造成污染 每个任务只保存自己的表单数据 //过滤上个任务的表单数据 避免造成污染 每个任务只保存自己的表单数据
List<String> removeKeys = execution.getArgs().keySet().stream().filter(k -> k.startsWith(FlowConst.TASK_FORM_DATA_PREFIX) || k.equals(FlowConst.SUBMIT_TYPE)).toList(); // List<String> removeKeys = execution.getArgs().keySet().stream().filter(k -> k.startsWith(FlowConst.TASK_FORM_DATA_PREFIX) || k.equals(FlowConst.SUBMIT_TYPE)).toList();
for (String key : removeKeys) { // for (String key : removeKeys) {
execution.getArgs().remove(key); // execution.getArgs().remove(key);
} // }
processTask.setVariable(JSONUtil.toJsonStr(execution.getArgs())); processTask.setVariable(JSONUtil.toJsonStr(execution.getArgs()));
processTask.setCreatedAt(now); processTask.setCreatedAt(now);
@@ -1,48 +1,27 @@
package com.budwk.app.zhgh.dayofficework.article.controller; package com.budwk.app.zhgh.dayofficework.article.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.FieldMappingUtil;
import com.budwk.app.base.utils.PageUtil; import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.enums.ProcessTaskStateEnum; import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.zhgh.dayofficework.article.models.Article;
import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam; import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam;
import com.budwk.app.zhgh.dayofficework.article.service.ArticleService; import com.budwk.app.zhgh.dayofficework.article.service.ArticleService;
import com.budwk.app.zhgh.dayofficework.article.vo.ArticlePageVo;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@IocBean @IocBean
@At("/platform/article/branchUnionApproval") @At("/platform/article/branchUnionApproval")
@@ -52,13 +31,6 @@ public class ArticleBranchUnionApprovalController {
@Inject @Inject
private ArticleService articleService; private ArticleService articleService;
@Inject
private BpmService bpmService;
@Inject
private CommonService commonService;
@Inject
private FlowEngine flowEngine;
@At("") @At("")
@Ok("beetl:/platform/zhgh/dayofficework/article/branchUnionApproval/index.html") @Ok("beetl:/platform/zhgh/dayofficework/article/branchUnionApproval/index.html")
@@ -66,13 +38,6 @@ public class ArticleBranchUnionApprovalController {
public void index() { public void index() {
} }
@At("/form")
@Ok("beetl:/platform/zhgh/dayofficework/article/branchUnionApproval/form.html")
@SaCheckLogin
public void form() {
}
@At @At
@SaCheckPermission("article.branchUnionApproval") @SaCheckPermission("article.branchUnionApproval")
@ApiOperation("分页查询") @ApiOperation("分页查询")
@@ -89,7 +54,7 @@ public class ArticleBranchUnionApprovalController {
ins.id AS instanceId, ins.id AS instanceId,
ins.businessNo, ins.businessNo,
ins.state instanceState, ins.state instanceState,
ins.variable instanceVariale, ins.variable instanceVariable,
t.id taskId, t.id taskId,
t.taskName AS taskKey, t.taskName AS taskKey,
t.displayName taskName, t.displayName taskName,
@@ -98,20 +63,24 @@ public class ArticleBranchUnionApprovalController {
t.taskState, t.taskState,
t.finishTime, t.finishTime,
t.taskParentId, t.taskParentId,
t.variable taskVariale t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
wf_process_task t wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN article info ON info.id = ins.businessNo LEFT JOIN article info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id 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
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "f4d62c2d-3947-4c68-b34f-127af89952b0"); cnd.and("t.taskName", "=", "f20544eb-5dcf-4913-a5e1-97dc3ad79e9c");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) { if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
@@ -126,19 +95,10 @@ public class ArticleBranchUnionApprovalController {
} else { } else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} }
cnd.groupBy("t.id");
cnd.desc("t.createdAt");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO); return Result.success(pageVO);
} }
@At
@SaCheckPermission("article.branchUnionApproval")
@Aop(TransAop.READ_COMMITTED)
public Result doApproval(Long taskId, @Param("submitType") Integer submitType) {
Dict args = new Dict();
args.put(FlowConst.SUBMIT_TYPE,submitType);
flowEngine.executeProcessTask(taskId, SecurityUtil.getUserId(), args);
return Result.success();
}
} }
@@ -12,6 +12,7 @@ import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum; import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
import com.budwk.app.bpm.param.BpmTaskApprovalParam; import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService; import com.budwk.app.web.controllers.open.commons.service.CommonService;
@@ -28,6 +29,7 @@ import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.aop.Aop; import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
@@ -48,8 +50,6 @@ public class ArticleClubApprovalController {
private BpmService bpmService; private BpmService bpmService;
@Inject @Inject
private CommonService commonService; private CommonService commonService;
// @Inject
// private SnakerEngine snakerEngine;
@At("") @At("")
@Ok("beetl:/platform/zhgh/dayofficework/article/clubApproval/index.html") @Ok("beetl:/platform/zhgh/dayofficework/article/clubApproval/index.html")
@@ -63,34 +63,49 @@ public class ArticleClubApprovalController {
public Result pageData(@Valid ArticleInfoPageParam pageForm, boolean approval) { public Result pageData(@Valid ArticleInfoPageParam pageForm, boolean approval) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.*, info.id,
inst.id processInstanceId, info.title,
inst.processInstanceNodeId, info.userName,
inst.processInstanceNodeName, info.loginName,
inst.processInstanceTaskIds, info.unitName,
inst.processInstanceStatus, info.unionName,
task.id processInstanceTaskId, info.submitTime,
task.taskStatus processInstanceTaskStatus, ins.id AS instanceId,
COUNT(nt.id) OVER (PARTITION BY task.id) > 0 AS nextTaskIsComplete\s ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN article info ON info.id = ins.businessNo
INNER JOIN article info ON info.id = inst.processInstanceBusinessId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE' 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
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("t.taskName", "=", "3237778f-23a3-462b-8f0a-1fd1db151390");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
cnd.and("nd.nodeCode", "=", 32);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
cnd.desc("t.createdAt");
cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear()); cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear());
cnd.and(Cnd.likeEX("info.title", pageForm.getTitle())); cnd.and(Cnd.likeEX("info.title", pageForm.getTitle()));
@@ -100,35 +115,8 @@ public class ArticleClubApprovalController {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} }
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<ArticleInfoPageVO> pageVO = articleService.listPageVO(pageForm, sql, ArticleInfoPageVO.class); Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO); return Result.success(pageVO);
} }
@At
@SaCheckPermission("article.clubApproval")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "新闻投稿", msg = "协会审核")
@ApiOperation("协会审核")
public Result approval(@Valid @Param("approval") BpmTaskApprovalParam approvalParam) {
approvalParam.getBpmTaskApprovalTypeEnum();
Map<String, Object> variables = BeanUtil.beanToMap(approvalParam);
List<String> assignments = new ArrayList<>();
if (approvalParam.getBpmTaskApprovalTypeEnum().equals(BpmTaskApprovalTypeEnum.PASS)) {
String schoolUnionApprovalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.SCHOOL_UNION_ARTICLE_ADMIN, Cnd.NEW());
assignments.add(schoolUnionApprovalLoginName);
}
bpmService.completeTask(approvalParam.getProcessInstanceTaskId(), approvalParam.getBpmTaskApprovalTypeEnum(), variables, assignments);
return Result.success();
}
@At
@SaCheckPermission("article.clubApproval")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "新闻投稿", msg = "协会撤回")
@ApiOperation("协会撤回")
public Result revoke(@Valid String taskId) {
bpmService.revokeTask(taskId);
return Result.success();
}
} }
@@ -12,6 +12,7 @@ import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.models.BpmProcessInstance; import com.budwk.app.bpm.models.BpmProcessInstance;
import com.budwk.app.bpm.param.BpmTaskApprovalParam; import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -31,6 +32,7 @@ import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.aop.Aop; import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
@@ -67,94 +69,63 @@ public class ArticleExamineController {
public Result pageData(@Valid ArticleInfoPageParam pageForm, boolean approval) { public Result pageData(@Valid ArticleInfoPageParam pageForm, boolean approval) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.*, info.id,
inst.id processInstanceId, info.title,
inst.processInstanceNodeId, info.userName,
inst.processInstanceNodeName, info.loginName,
inst.processInstanceTaskIds, info.unitName,
inst.processInstanceStatus, info.unionName,
task.id processInstanceTaskId, info.submitTime,
task.taskStatus processInstanceTaskStatus, ins.id AS instanceId,
COUNT(nt.id) OVER (PARTITION BY task.id) > 0 AS nextTaskIsComplete\s ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN article info ON info.id = ins.businessNo
INNER JOIN article info ON info.id = inst.processInstanceBusinessId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE' 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
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("t.taskName", "=", "27f618b9-bff8-4382-87c9-d9abd9f5963c");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
cnd.and("nd.nodeCode", "=", 60);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
cnd.desc("t.createdAt");
cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear()); cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear());
cnd.and(Cnd.likeEX("info.title", pageForm.getTitle())); cnd.and(Cnd.likeEX("info.title", pageForm.getTitle()));
cnd.andEX("info.unionId","=",pageForm.getUnionId());
cnd.andEX("info.unitId","=",pageForm.getUnitId());
cnd.andEX("info.origin","=",pageForm.getOrigin());
if(StrUtil.isAllBlank(pageForm.getPageOrderName(),pageForm.getPageOrderBy())){ if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.submitTime"); cnd.desc("info.submitTime");
}else{ } else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} }
cnd.groupBy("t.id");
cnd.desc("t.createdAt");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<ArticleInfoPageVO> pageVO = articleService.listPageVO(pageForm, sql, ArticleInfoPageVO.class); Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO); return Result.success(pageVO);
} }
@At
@SaCheckPermission("article.examine")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "新闻投稿", msg = "新闻审核")
@ApiOperation("新闻审批")
public Result approval(@Valid @Param("approval") BpmTaskApprovalParam approvalParam, @Valid @Param("result") String result, String publishLink) {
approvalParam.getBpmTaskApprovalTypeEnum();
Map<String, Object> variables = BeanUtil.beanToMap(approvalParam);
variables.put("RESULT", result);
variables.put("publishLink", publishLink);
Article article = dao.fetch(Article.class, approvalParam.getProcessInstanceBusinessId());
List<String> assignments = new ArrayList<>();
if (result.equals("BACK_TO_START")) {
String processInstanceId = approvalParam.getProcessInstanceId();
BpmProcessInstance instance = dao.fetch(BpmProcessInstance.class, processInstanceId);
assignments.add(instance.getProcessInstanceInitiatorLoginName());
} else if (result.equals("BACK_TO_UNION")) {
String branchUnionApprovalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.BRANCH_UNION_CHAIRMAN, Cnd.where(Sys_user_role::getUnionId, "=", article.getUnionId()));
if (StrUtil.isBlank(branchUnionApprovalLoginName)) {
return Result.error("分工会未配置审批人,请联系校工会!");
}
assignments.add(branchUnionApprovalLoginName);
} else if (result.equals("BACK_TO_CLUB")) {
String branchClubApprovalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.CLUB_PRESIDENT, Cnd.where(Sys_user_role::getClubId, "=", article.getClubId()));
if (StrUtil.isBlank(branchClubApprovalLoginName)) {
return Result.error("协会未配置审批人,请联系协会!");
}
assignments.add(branchClubApprovalLoginName);
}
bpmService.completeTask(approvalParam.getProcessInstanceTaskId(), approvalParam.getBpmTaskApprovalTypeEnum(), variables, assignments);
return Result.success();
}
@At
@SaCheckPermission("article.examine")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "新闻投稿", msg = "编辑终审撤回")
@ApiOperation("编辑终审撤回")
public Result revoke(@Valid String taskId) {
bpmService.revokeTask(taskId);
return Result.success();
}
} }
@@ -6,6 +6,7 @@ import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.article.models.Article; import com.budwk.app.zhgh.dayofficework.article.models.Article;
import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam; import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam;
@@ -38,6 +39,8 @@ public class ArticleMineController {
@Inject @Inject
private ArticleService articleService; private ArticleService articleService;
@Inject
private FlowEngine flowEngine;
@At("") @At("")
@Ok("beetl:/platform/zhgh/dayofficework/article/mine/index.html") @Ok("beetl:/platform/zhgh/dayofficework/article/mine/index.html")
@@ -61,7 +64,7 @@ public class ArticleMineController {
ins.id AS instanceId, ins.id AS instanceId,
ins.businessNo, ins.businessNo,
ins.state instanceState, ins.state instanceState,
ins.variable instanceVariale, ins.variable instanceVariable,
t.id taskId, t.id taskId,
t.taskName AS taskKey, t.taskName AS taskKey,
t.displayName taskName, t.displayName taskName,
@@ -70,7 +73,9 @@ public class ArticleMineController {
t.taskState, t.taskState,
t.finishTime, t.finishTime,
t.taskParentId, t.taskParentId,
t.variable taskVariale t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId
FROM FROM
article info article info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
@@ -85,56 +90,8 @@ public class ArticleMineController {
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO); return Result.success(pageVO);
// // 获取当前用户发起的流程实例列表
// Page<HistoryOrder> page = new Page<>();
// page.setPageNo(pageForm.getPageNumber());
// page.setPageSize(pageForm.getPageSize());
// QueryFilter queryFilter = new QueryFilter();
//// queryFilter.setProcessId("89032d1a30ee46e79361b503a5d250db");
// queryFilter.setName("XWTG");
//
// List<HistoryOrder> historyOrders = snakerEngine.query().getHistoryOrders(page, queryFilter);
//
// Cnd cnd = Cnd.NEW();
// cnd.and("userId", "=", SecurityUtil.getUserId());
// cnd.andEX("YEAR(submitTime)", "=", pageForm.getYear());
// cnd.and(Cnd.likeEX("title", pageForm.getTitle()));
// cnd.desc("submitTime");
// Pagination<Article> pagination = articleService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
//
// List<Map<String, Object>> list = pagination.getList().stream().map(row -> {
// Map<String, Object> mapBean = BeanUtil.beanToMap(row);
// Optional<HistoryOrder> hisOrder = historyOrders.stream().filter(historyOrder -> historyOrder.getVariableMap().get("businessId").equals(row.getId())).findFirst();
// hisOrder.ifPresent(historyOrder -> mapBean.put("instance", historyOrder));
//
// // 查询任务信息
// if (hisOrder.isPresent()) {
// List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(hisOrder.get().getId()));
// // 待办任务列表
// mapBean.put("activeTasks", tasks);
// // 当前任务节点
// mapBean.put("activeTaskName", tasks.stream().map(Task::getDisplayName).collect(Collectors.joining(",")));
// // 申请的任务列表 只会有一条吧 别搞
// mapBean.put("applyTask", tasks.stream().filter(task -> task.getParentTaskId().equals("start")).findFirst().orElse(null));
// }
// return mapBean;
// }).toList();
//
// Pagination<Map<String, Object>> mapPagination = new Pagination<>(pagination.getPageNo(), pagination.getPageSize(), pagination.getTotalCount(), list);
//
// return Result.success(mapPagination);
} }
@At
@SaCheckPermission("article.mine")
@ApiOperation("撤回")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "新闻投稿", msg = "撤回新闻投稿")
public Result revokeApply(@Valid String id) {
// bpmService.revokeApply(id);
return Result.success();
}
@At @At
@SaCheckPermission("article.mine") @SaCheckPermission("article.mine")
@@ -143,7 +100,7 @@ public class ArticleMineController {
@SLog(tag = "新闻投稿", msg = "删除新闻投稿") @SLog(tag = "新闻投稿", msg = "删除新闻投稿")
public Result delete(@Valid String id) { public Result delete(@Valid String id) {
articleService.delete(id); articleService.delete(id);
// bpmService.deleteInstance(id); flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success(); return Result.success();
} }
@@ -43,19 +43,14 @@ public class ArticleQueryController {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.*, info.*,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.processDefineId instanceProcessDefineId
inst.processInstanceNodeCode,
inst.processInstanceNodeName,
inst.processInstanceTaskIds,
inst.processInstanceStatus
FROM FROM
article info article info
LEFT JOIN bpm_process_instance inst ON inst.processInstanceBusinessId = info.id LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.and("inst.processInstanceNodeCode", "=", 80);
cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear()); cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear());
if (StrUtil.isNotBlank(pageForm.getTitle())) { if (StrUtil.isNotBlank(pageForm.getTitle())) {
cnd.and(Cnd.likeEX("info.title", pageForm.getTitle())); cnd.and(Cnd.likeEX("info.title", pageForm.getTitle()));
@@ -1,46 +1,30 @@
package com.budwk.app.zhgh.dayofficework.article.controller; package com.budwk.app.zhgh.dayofficework.article.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil; import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine; import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.enums.ProcessTaskStateEnum; import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService; import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam; import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam;
import com.budwk.app.zhgh.dayofficework.article.service.ArticleService; import com.budwk.app.zhgh.dayofficework.article.service.ArticleService;
import com.budwk.app.zhgh.dayofficework.article.vo.ArticleInfoPageVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; 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.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@IocBean @IocBean
@At("/platform/article/schoolUnionApproval") @At("/platform/article/schoolUnionApproval")
@@ -63,12 +47,6 @@ public class ArticleSchoolUnionApprovalController {
public void index() { public void index() {
} }
@At("/form")
@Ok("beetl:/platform/zhgh/dayofficework/article/schoolUnionApproval/form.html")
@SaCheckLogin
public void form() {
}
@At @At
@SaCheckPermission("article.schoolUnionApproval") @SaCheckPermission("article.schoolUnionApproval")
@@ -86,7 +64,7 @@ public class ArticleSchoolUnionApprovalController {
ins.id AS instanceId, ins.id AS instanceId,
ins.businessNo, ins.businessNo,
ins.state instanceState, ins.state instanceState,
ins.variable instanceVariale, ins.variable instanceVariable,
t.id taskId, t.id taskId,
t.taskName AS taskKey, t.taskName AS taskKey,
t.displayName taskName, t.displayName taskName,
@@ -95,20 +73,24 @@ public class ArticleSchoolUnionApprovalController {
t.taskState, t.taskState,
t.finishTime, t.finishTime,
t.taskParentId, t.taskParentId,
t.variable taskVariale t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
wf_process_task t wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN article info ON info.id = ins.businessNo LEFT JOIN article info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id 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
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "a29bdec1-e285-41f3-aa2c-2c24fccefea1"); cnd.and("t.taskName", "=", "749b6917-58ba-4564-8701-4bd2491fcb98");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) { if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
@@ -123,22 +105,11 @@ public class ArticleSchoolUnionApprovalController {
} else { } else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} }
cnd.groupBy("t.id");
cnd.desc("t.createdAt");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); Pagination<NutMap> pageVO = articleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO); return Result.success(pageVO);
} }
@At
@SaCheckPermission("article.branchUnionApproval")
@Aop(TransAop.READ_COMMITTED)
public Result doApproval(Long taskId, @Param("submitType") Integer submitType) {
Dict args = new Dict();
// flowEngine.executeProcessTask(taskId, SecurityUtil.getUserId(), args);
args.set(FlowConst.SUBMIT_TYPE, submitType);
flowEngine.executeAndJumpToFirstTaskNode(taskId, SecurityUtil.getUserId(), args);
return Result.success();
}
} }
@@ -1,10 +1,9 @@
package com.budwk.app.zhgh.dayofficework.article.controller; package com.budwk.app.zhgh.dayofficework.article.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
@@ -13,6 +12,7 @@ import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance; import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask; import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum; import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.controllers.open.commons.service.CommonService; import com.budwk.app.web.controllers.open.commons.service.CommonService;
import com.budwk.app.zhgh.club.model.ClubUser; import com.budwk.app.zhgh.club.model.ClubUser;
@@ -53,6 +53,8 @@ public class ArticleWriteController {
private SysClubService sysClubService; private SysClubService sysClubService;
@Inject @Inject
private FlowEngine flowEngine; private FlowEngine flowEngine;
@Inject
private FlowCommonService flowCommonService;
@At("") @At("")
@Ok("beetl:/platform/zhgh/dayofficework/article/write/index.html") @Ok("beetl:/platform/zhgh/dayofficework/article/write/index.html")
@@ -62,24 +64,12 @@ public class ArticleWriteController {
} }
@At
@SaCheckLogin
@Ok("beetl:/platform/zhgh/dayofficework/article/write/index_.html")
public void index_() {
}
@At @At
@SaCheckPermission("article.write") @SaCheckPermission("article.write")
@ApiOperation("保存新闻投稿") @ApiOperation("保存新闻投稿")
@Aop(TransAop.READ_COMMITTED) @Aop(TransAop.READ_COMMITTED)
@SLog(tag = "新闻投稿-新建投稿", msg = "保存投稿")
public Result save(@Param("article") Article article) { public Result save(@Param("article") Article article) {
// dao.insertOrUpdate(article);
// // 启动流程 阻塞在第一个任务节点
// ProcessInstance instance = flowEngine.startProcessInstanceByKey("XWTG", article.getId(), SecurityUtil.getUserId(), null);
// 保存
dao.insertOrUpdate(article); dao.insertOrUpdate(article);
return Result.success(article); return Result.success(article);
} }
@@ -88,43 +78,41 @@ public class ArticleWriteController {
@SaCheckPermission("article.write") @SaCheckPermission("article.write")
@ApiOperation("提交新闻投稿") @ApiOperation("提交新闻投稿")
@Aop(TransAop.READ_COMMITTED) @Aop(TransAop.READ_COMMITTED)
public Result submit(@Param("article") Article article, Long instanceId, Long taskId) { @SLog(tag = "新闻投稿-新建投稿", msg = "提交投稿")
public Result submit(@Param("article") Article article) {
dao.insertOrUpdate(article); dao.insertOrUpdate(article);
if (instanceId == null && taskId == null) { // 开启流程实例
ProcessInstance instance = flowEngine.startProcessInstanceByKey("XWTG", article.getId(), SecurityUtil.getUserId(), null); Dict args = Dict.create();
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), new String[]{}); args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, article);
args.set("origin", article.getOrigin());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("XWTG", article.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) { for (ProcessTask task : doingTaskList) {
Dict args = new Dict(); flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
args.put(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.put("origin", article.getOrigin());
flowEngine.executeProcessTask(task.getId(), FlowConst.AUTO_ID, args);
}
} else {
flowEngine.executeProcessTask(taskId, SecurityUtil.getUserId(), Dict.create().set("origin", article.getOrigin()));
}
return Result.success();
} }
return Result.success(article);
}
@At @At
@SaCheckPermission("article.write") @SaCheckPermission("article.write")
@ApiOperation("撤销新闻投稿")
@Aop(TransAop.READ_COMMITTED) @Aop(TransAop.READ_COMMITTED)
public Result revokeApply(@Param("id") String id) { @ApiOperation("重新提交投稿")
// FlowInstance instance = dao.fetch(FlowInstance.class, Cnd.where(FlowInstance::getBusinessId, "=", id)); @SLog(tag = "新闻投稿-新建投稿", msg = "重新提交投稿")
// BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus()); public Result submitAgain(@Param("article") Article article, @Param("taskId") Long taskId) {
// FlowParams flowParams = FlowParams.build() dao.insertOrUpdate(article);
//// .message(message)
// .flowStatus(BusinessStatusEnum.CANCEL.getStatus()) Dict dict = Dict.create();
// .hisStatus(BusinessStatusEnum.CANCEL.getStatus()) dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
// .handler(SecurityUtil.getUserId()) dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
// .ignore(true); flowCommonService.executeTask(dict);
// taskService.revoke(instance.getId(), flowParams);
return Result.success(); return Result.success();
} }
@At @At
@SaCheckPermission("article.write") @SaCheckPermission("article.write")
@ApiOperation("新闻投稿详情") @ApiOperation("新闻投稿详情")
@@ -24,11 +24,6 @@ public class Article extends BaseModel {
@PrevInsert(uu32 = true) @PrevInsert(uu32 = true)
private String id; private String id;
@Column
@Comment("流程实例ID")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String instanceId;
@Column @Column
@Comment("标题") @Comment("标题")
@ColDefine(type = ColType.VARCHAR, width = 100) @ColDefine(type = ColType.VARCHAR, width = 100)
@@ -0,0 +1,38 @@
package com.budwk.app.zhgh.dayofficework.edu.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
@EqualsAndHashCode(callSuper = true)
@Data
@Table("edu_chapters")
@Comment("理论学习视频章节表")
public class EduChapters extends BaseModel {
@Comment("ID")
@Name
@PrevInsert(uu32 = true)
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Comment("课程ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String courseId;
@Comment("标题")
@ColDefine(type = ColType.VARCHAR, width = 200)
@Column
private String title;
@Comment("排序码")
@ColDefine(type = ColType.INT)
@Column
private Integer sortCode;
}
@@ -0,0 +1,48 @@
package com.budwk.app.zhgh.dayofficework.edu.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
@EqualsAndHashCode(callSuper = true)
@Data
@Table("edu_courses")
@Comment("理论学习课程表")
public class EduCourses extends BaseModel {
@Comment("ID")
@Name
@PrevInsert(uu32 = true)
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Comment("标题")
@ColDefine(type = ColType.VARCHAR, width = 100)
@Column
private String title;
@Comment("描述")
@ColDefine(type = ColType.VARCHAR, width = 500)
@Column
private String description;
@Comment("封面")
@ColDefine(type = ColType.VARCHAR, width = 500)
@Column
private String cover;
@Comment("分类")
@ColDefine(type = ColType.VARCHAR, width = 50)
@Column
private String category;
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
@Column
@Default(value = "0")
private Boolean disabled;
}
@@ -0,0 +1,56 @@
package com.budwk.app.zhgh.dayofficework.edu.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@EqualsAndHashCode(callSuper = true)
@Data
@Table("edu_study_records")
@Comment("理论学习学习记录表")
public class EduStudyRecords extends BaseModel {
@Comment("ID")
@Name
@PrevInsert(uu32 = true)
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String userId;
@Comment("视频ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String videoId;
@Comment("课程ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String courseId;
@Comment("观看时长")
@ColDefine(type = ColType.INT)
@Column
@Default("0")
private Integer watchedDuration;
@Comment("上次观看时间")
@ColDefine(type = ColType.DATETIME)
@Column
private Date lastWatchedTime;
@Comment("是否完成")
@ColDefine(type = ColType.BOOLEAN)
@Column
@Default("0")
private Boolean isCompleted;
}
@@ -0,0 +1,51 @@
package com.budwk.app.zhgh.dayofficework.edu.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
@EqualsAndHashCode(callSuper = true)
@Data
@Table("edu_videos")
@Comment("理论学习视频表")
public class EduVideos extends BaseModel {
@Comment("ID")
@Name
@PrevInsert(uu32 = true)
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Comment("章节ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String chapterId;
@Comment("标题")
@ColDefine(type = ColType.VARCHAR, width = 200)
@Column
private String title;
@Comment("视频地址")
@ColDefine(type = ColType.VARCHAR, width = 500)
@Column
private String url;
@Comment("时长")
@ColDefine(type = ColType.INT)
@Column
@Default("0")
private Integer duration;
@Comment("描述")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String description;
@Comment("排序码")
@ColDefine(type = ColType.INT)
@Column
private Integer sortCode;
}
@@ -43,7 +43,7 @@ public class QsvActivityController {
} }
// 分页查询 //分页查询
@At @At
@SaCheckPermission("qsv.activity") @SaCheckPermission("qsv.activity")
public Result pageData(@Valid PageForm pageForm, Integer year, String title) { public Result pageData(@Valid PageForm pageForm, Integer year, String title) {
@@ -55,7 +55,7 @@ public class QsvActivityController {
} }
// 保存问卷基础信息 //保存问卷基础信息
@At @At
@SaCheckPermission("qsv.activity") @SaCheckPermission("qsv.activity")
@ApiOperation("保存问卷基础信息") @ApiOperation("保存问卷基础信息")
@@ -46,7 +46,6 @@ public class ProposalCommonController {
return Result.success(list); return Result.success(list);
} }
@At @At
@SaCheckLogin @SaCheckLogin
@ApiOperation("查询全部的教代会") @ApiOperation("查询全部的教代会")
@@ -12,6 +12,7 @@ import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.models.BpmProcessTask; import com.budwk.app.bpm.models.BpmProcessTask;
import com.budwk.app.bpm.param.BpmTaskApprovalParam; import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.sys.services.SysMsgService; import com.budwk.app.sys.services.SysMsgService;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -48,14 +49,8 @@ import java.util.Map;
@Api(tags = "提案委员会立案审核") @Api(tags = "提案委员会立案审核")
public class ProposalCommitteeFilingController { public class ProposalCommitteeFilingController {
@Inject
private BaseService baseService;
@Inject
private BpmService bpmService;
@Inject @Inject
private ProposalCommitteeFilingService proposalCommitteeFilingService; private ProposalCommitteeFilingService proposalCommitteeFilingService;
@Inject
private SysMsgService sysMsgService;
@At("") @At("")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/committeeFiling/index.html") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/committeeFiling/index.html")
@@ -64,118 +59,58 @@ public class ProposalCommitteeFilingController {
} }
@At @At
@SaCheckPermission("proposal.committeeFiling") @SaCheckPermission("proposal.delegation")
@ApiOperation("分页列表") @ApiOperation("分页列表")
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) { public Result pageData(@Valid ProposalSearchParam pageForm,boolean approval) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.*, info.*,
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeName, ins.state instanceState,
inst.processInstanceTaskIds, ins.variable instanceVariable,
inst.processInstanceStatus, ins.processDefineId instanceProcessDefineId,
task.id processInstanceTaskId, t.id taskId,
task.taskStatus processInstanceTaskStatus, t.taskName AS taskKey,
COUNT(p.consolidationIds) > 0 AS isConsolidation, t.displayName taskName,
EXISTS ( t.taskType,
SELECT 1 t.performType taskPerformType,
FROM bpm_process_task next_task t.taskState,
WHERE next_task.prevTaskId = task.id t.finishTime,
AND next_task.taskStatus = 'COMPLETE' t.taskParentId,
) AS nextTaskIsComplete t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN proposal_consolidation p ON JSON_CONTAINS(p.consolidationIds, JSON_QUOTE(info.id)) LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("t.taskName", "=", "9846ab38-40c5-4093-bafc-a9b3b443338b");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
cnd.and("nd.nodeCode", "=", 60);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.and(new Static(""" cnd.groupBy("t.id");
NOT EXISTS( cnd.desc("t.createdAt");
SELECT 1
FROM bpm_process_task t2
WHERE t2.processInstanceId = task.processInstanceId
AND t2.processTaskNodeCode = task.processTaskNodeCode
AND t2.createdOn > task.createdOn
)
"""));
cnd.groupBy("info.id");
cnd.groupBy("task.id");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<ProposalInfoPageVO> pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); Pagination pagination = proposalCommitteeFilingService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@At
@SaCheckPermission("proposal.committeeFiling")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案委员会立案审核", msg = "立案")
@ApiOperation("立案")
public Result approval(@Valid @Param("approval") ProposalCommitteeFilingApprovalParam approvalParam) {
proposalCommitteeFilingService.approval(approvalParam);
return Result.success();
}
@At
@SaCheckPermission("proposal.committeeFiling")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案委员会立案审核", msg = "退回提案人")
@ApiOperation("退回提案人")
public Result approvalBack(@Valid BpmTaskApprovalParam approvalParam) {
approvalParam.getBpmTaskApprovalTypeEnum();
Map<String, Object> variables = BeanUtil.beanToMap(approvalParam);
variables.put("caseFilingResult","退回提案人");
bpmService.completeTask(approvalParam.getProcessInstanceTaskId(), approvalParam.getBpmTaskApprovalTypeEnum(), variables, null);
//退回要清空附议人
List<BpmProcessTask> secondedTasks = proposalCommitteeFilingService.dao().query(BpmProcessTask.class, Cnd.where(BpmProcessTask::getProcessInstanceId, "=", approvalParam.getProcessInstanceId()).and(BpmProcessTask::getProcessTaskNodeCode, "=", 20));
for (BpmProcessTask task : secondedTasks) {
proposalCommitteeFilingService.dao().update(BpmProcessTask.class, Chain.make("delFlag", true), Cnd.where(BpmProcessTask::getId, "=", task.getId()));
}
ProposalInfo proposalInfo = baseService.dao().fetch(ProposalInfo.class, approvalParam.getProcessInstanceBusinessId());
String template = "{}代表您好!您的提案《{}》提案委员会已经审核,审核结果为退回提案人重新修改,您可重新编辑提案邀请附议人再次提交,请您登录系统查看详情。";
String content = StrUtil.format(template, proposalInfo.getCreateUserName(), proposalInfo.getName());
sysMsgService.sendMsg(proposalInfo.getCreateUserLoginName(), "提案委员会立案审核", content, SecurityUtil.getUserId());
return Result.success();
}
@At
@SaCheckPermission("proposal.committeeFiling")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案委员会立案审核", msg = "委员会立案撤回")
public Result revoke(@Valid String taskId) {
proposalCommitteeFilingService.revoke(taskId);
return Result.success();
}
@At
@ApiOperation("查询承办单位")
@SaCheckPermission("proposal.committeeFiling")
public Result listUnderTake() {
List<ProposalUndertake> list = baseService.dao().query(ProposalUndertake.class, Cnd.NEW().asc(ProposalUndertake::getCode));
return Result.success(list);
}
} }
@@ -9,6 +9,7 @@ import com.budwk.app.base.service.BaseService;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.param.BpmTaskApprovalParam; import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO; import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
@@ -31,6 +32,7 @@ import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
/** /**
* 团长审核 * 团长审核
@@ -67,74 +69,49 @@ public class ProposalDelegationController {
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeName, ins.state instanceState,
inst.processInstanceTaskIds, ins.variable instanceVariable,
inst.processInstanceStatus, ins.processDefineId instanceProcessDefineId,
task.id processInstanceTaskId, t.id taskId,
task.taskStatus processInstanceTaskStatus, t.taskName AS taskKey,
EXISTS ( t.displayName taskName,
SELECT 1 t.taskType,
FROM bpm_process_task next_task t.performType taskPerformType,
WHERE next_task.prevTaskId = task.id t.taskState,
AND next_task.taskStatus = 'COMPLETE' t.finishTime,
) AS nextTaskIsComplete t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId 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 proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ cnd.and("t.taskName", "=", "93d5ba64-8220-4e62-9783-83422f474b36");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
cnd.and("nd.nodeCode", "=", 30);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
cnd.groupBy("info.id");
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.and(new Static(""" cnd.groupBy("t.id");
NOT EXISTS( cnd.desc("t.createdAt");
SELECT 1
FROM bpm_process_task t2
WHERE t2.processInstanceId = task.processInstanceId
AND t2.processTaskNodeCode = task.processTaskNodeCode
AND t2.createdOn > task.createdOn
)
"""));
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@At
@SaCheckPermission("proposal.delegation")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "团长审核")
@ApiOperation("审核")
public Result approval(@Valid @Param("approval") BpmTaskApprovalParam approvalParam) {
proposalDelegationService.approval(approvalParam);
return Result.success();
}
@At
@SaCheckPermission("proposal.delegation")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "团长审核撤回")
@ApiOperation("撤回")
public Result revoke(@Valid String taskId) {
proposalDelegationService.revokeTask(taskId);
// bpmService.revokeTask(taskId);
return Result.success();
}
} }
@@ -8,12 +8,14 @@ import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService; import com.budwk.app.base.service.BaseService;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO; import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalFeedbackEvaluationParam; import com.budwk.app.zhgh.democratic.proposal.param.ProposalFeedbackEvaluationParam;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalFeedbackEvaluationService; import com.budwk.app.zhgh.democratic.proposal.service.ProposalFeedbackEvaluationService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -30,6 +32,7 @@ import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
@IocBean @IocBean
@At("/platform/proposal/feedbackEvaluation") @At("/platform/proposal/feedbackEvaluation")
@@ -39,9 +42,7 @@ import javax.validation.Valid;
public class ProposalFeedbackEvaluationController { public class ProposalFeedbackEvaluationController {
@Inject @Inject
private BaseService baseService; private ProposalCommonService proposalCommonService;
@Inject
private BpmService bpmService;
@Inject @Inject
private ProposalFeedbackEvaluationService proposalFeedbackEvaluationService; private ProposalFeedbackEvaluationService proposalFeedbackEvaluationService;
@@ -61,63 +62,52 @@ public class ProposalFeedbackEvaluationController {
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeName, ins.state instanceState,
inst.processInstanceTaskIds, ins.variable instanceVariable,
inst.processInstanceStatus, ins.processDefineId instanceProcessDefineId,
task.id processInstanceTaskId, t.id taskId,
task.taskStatus processInstanceTaskStatus, t.taskName AS taskKey,
COUNT(p.consolidationIds) > 0 AS isConsolidation, t.displayName taskName,
COUNT( nt.id ) OVER ( PARTITION BY task.id ) > 0 AS nextTaskIsComplete t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN proposal_consolidation p ON JSON_CONTAINS(p.consolidationIds, JSON_QUOTE(info.id)) LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE'
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ cnd.and("t.taskName", "=", "013a7cf9-20dd-4188-a196-53fd595448e5");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname())));
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
} }
cnd.and("nd.nodeCode", "=", 100);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
sql.setCondition(cnd);
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.groupBy("info.id"); cnd.groupBy("t.id");
cnd.groupBy("task.id"); cnd.desc("t.createdAt");
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); sql.setCondition(cnd);
Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@At
@SaCheckPermission("proposal.feedbackEvaluation")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "反馈评分审核")
@ApiOperation("审核")
public Result approval(@Param("approval") @Valid ProposalFeedbackEvaluationParam param) {
proposalFeedbackEvaluationService.approval(param);
return Result.success();
}
@At
@SaCheckPermission("proposal.feedbackEvaluation")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "反馈评分撤回")
@ApiOperation("撤回")
public Result revoke(@Valid String taskId) {
bpmService.revokeTask(taskId);
return Result.success();
}
} }
@@ -1,24 +1,23 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact; package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil; import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm; import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService; import com.budwk.app.base.service.BaseService;
import com.budwk.app.bpm.dto.BpmAssignmentDto; import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum; import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.bpm.models.BpmProcessInstance; import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.flow.service.ProcessTaskService;
import com.budwk.app.sys.services.SysMsgService; import com.budwk.app.sys.services.SysMsgService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInviteSeconderVO; import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInviteSeconderVO;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
@@ -35,6 +34,7 @@ import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop; import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
@@ -55,9 +55,13 @@ public class ProposalMineController {
@Inject @Inject
private ProposalCommonService proposalCommonService; private ProposalCommonService proposalCommonService;
@Inject @Inject
private BpmService bpmService;
@Inject
private SysMsgService sysMsgService; private SysMsgService sysMsgService;
@Inject
private FlowEngine flowEngine;
@Inject
private ProcessTaskService processTaskService;
@Inject
private FlowCommonService flowCommonService;
@At("") @At("")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/mine/index.html") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/mine/index.html")
@@ -75,58 +79,50 @@ public class ProposalMineController {
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeCode, ins.state instanceState,
inst.processInstanceNodeName, ins.variable instanceVariable,
inst.processInstanceTaskIds, ins.processDefineId instanceProcessDefineId,
inst.processInstanceStatus, t.id taskId,
( t.taskName AS taskKey,
SELECT t.displayName taskName,
count( 1 ) > 0 t.taskType,
FROM t.performType taskPerformType,
bpm_process_task t.taskState,
WHERE t.finishTime,
prevTaskId = ( SELECT id FROM bpm_process_task WHERE processInstanceId = inst.id AND processTaskNodeCode IN ( 10, 40 ) ORDER BY createdAt DESC LIMIT 1 ) t.taskParentId,
AND taskStatus = 'COMPELTE' t.variable taskVariable,
) AS nextTaskIsComplete IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId
FROM FROM
proposal_info info proposal_info info
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
LEFT JOIN bpm_process_instance inst ON inst.processInstanceBusinessId = info.id LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("info.createdBy", "=", SecurityUtil.getUserId());
cnd.and("inst.processInstanceInitiatorLoginName", "=", SecurityUtil.getUserLoginname());
}
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.andEX("info.sessionId", "=", sessionId); cnd.andEX("info.sessionId", "=", sessionId);
cnd.groupBy("info.id"); cnd.groupBy("info.id");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<ProposalInfoPageVO> pagination = proposalCommonService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); Pagination<NutMap> pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@At @At
@SaCheckPermission("proposal.mine") @SaCheckPermission("proposal.mine")
@Aop(TransAop.READ_COMMITTED) @Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "删除提案") @SLog(tag = "提案管理系统-我的提案", msg = "删除提案")
public Result delete(@Valid String id) { public Result delete(@Valid String id) {
dao.delete(ProposalInfo.class, id); dao.delete(ProposalInfo.class, id);
bpmService.deleteInstance(id); flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success();
}
@At
@SaCheckPermission("proposal.mine")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "撤回提案申请")
public Result revokeApply(@Valid String id) {
bpmService.revokeApply(id);
return Result.success(); return Result.success();
} }
@@ -143,37 +139,9 @@ public class ProposalMineController {
public Result listSeconder(@Valid PageForm pageForm, @Valid String proposalId, @Valid String sessionId, public Result listSeconder(@Valid PageForm pageForm, @Valid String proposalId, @Valid String sessionId,
String delegationId, boolean isInvite) { String delegationId, boolean isInvite) {
if (isInvite) { if (isInvite) {
Sql hasInviteSql = Sqls.create(""" // 查询已经邀请的附议人
SELECT
task.id,
JSON_EXTRACT( task.createVariable, '$.loginName' ) AS loginName,
JSON_EXTRACT( task.createVariable, '$.userName' ) AS userName,
JSON_EXTRACT( task.createVariable, '$.unitName' ) AS unitName,
JSON_EXTRACT( task.createVariable, '$.unionName' ) AS unionName,
JSON_EXTRACT( task.createVariable, '$.delegationName' ) AS delegationName,
JSON_EXTRACT( task.createVariable, '$.sex' ) AS sex
FROM
`bpm_process_task` task
INNER JOIN bpm_process_instance inst ON task.processInstanceId = inst.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("inst.processInstanceBusinessId", "=", proposalId);
cnd.and("task.processTaskNodeCode", "=", 20);
cnd.and("task.taskStatus", "!=", BpmProcessTaskStatusEnum.REVOKE.name());
cnd.and("task.delFlag", "=", 0);
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("JSON_EXTRACT( task.createVariable, '$.loginName' )", pageForm.getSearchKeyword());
seg.orLike("JSON_EXTRACT( task.createVariable, '$.userName' )", pageForm.getSearchKeyword());
cnd.and(seg);
}
cnd.andEX("JSON_EXTRACT( task.createVariable, '$.delegationId' )", "=", delegationId);
hasInviteSql.setCondition(cnd);
Pagination<ProposalInviteSeconderVO> pagination = proposalCommonService.listPageVO(pageForm, hasInviteSql, ProposalInviteSeconderVO.class);
return Result.success(pagination);
} else { } else {
// 查询可邀请的附议人
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
t1.loginName, t1.loginName,
@@ -189,7 +157,7 @@ public class ProposalMineController {
"""); """);
Cnd cnd = Cnd.where("t1.sessionId", "=", sessionId); Cnd cnd = Cnd.where("t1.sessionId", "=", sessionId);
cnd.andEX("t1.delegationId", "=", delegationId); cnd.andEX("t1.delegationId", "=", delegationId);
cnd.and("t1.roleId","=","19fb858ae9514ddd999c85306b38bd02"); cnd.and("t1.roleId", "=", "72e24b5b4c4f4e90a6641e6af8487e42");
cnd.and("t1.loginName", "!=", SecurityUtil.getUserLoginname()); cnd.and("t1.loginName", "!=", SecurityUtil.getUserLoginname());
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup(); SqlExpressionGroup seg = new SqlExpressionGroup();
@@ -197,24 +165,11 @@ public class ProposalMineController {
seg.orLike("t1.userName", pageForm.getSearchKeyword()); seg.orLike("t1.userName", pageForm.getSearchKeyword());
cnd.and(seg); cnd.and(seg);
} }
Sql hasInviteSql = Sqls.create("""
SELECT
JSON_EXTRACT( task.createVariable, '$.loginName' ) AS loginName
FROM
`bpm_process_task` task
INNER JOIN bpm_process_instance inst ON task.processInstanceId = inst.id
WHERE inst.processInstanceBusinessId = @proposalId
AND task.processTaskNodeCode = 20
AND task.taskStatus != 'REVOKE'
AND task.delFlag = 0
$condition
""").setParam("proposalId", proposalId);
cnd.and("t1.loginName", "not in", hasInviteSql);
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<ProposalInviteSeconderVO> pagination = proposalCommonService.listPageVO(pageForm, sql, ProposalInviteSeconderVO.class); Pagination<ProposalInviteSeconderVO> pagination = proposalCommonService.listPageVO(pageForm, sql, ProposalInviteSeconderVO.class);
return Result.success(pagination); return Result.success(pagination);
} }
return Result.success();
} }
@At @At
@@ -225,6 +180,7 @@ public class ProposalMineController {
//插入附议人数据 //插入附议人数据
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
t1.id seconderId,
t1.loginName, t1.loginName,
t1.userName, t1.userName,
t1.sex, t1.sex,
@@ -238,36 +194,28 @@ public class ProposalMineController {
$condition $condition
"""); """);
sql.setCondition(Cnd.where("t1.loginName", "in", seconders).groupBy("t1.loginName")); sql.setCondition(Cnd.where("t1.loginName", "in", seconders).groupBy("t1.loginName"));
List<ProposalInviteSeconderVO> seconderVOS = proposalCommonService.listVO(sql, ProposalInviteSeconderVO.class); List<NutMap> list = proposalCommonService.listMap(sql);
// 附议人ID
List<String> userIds = list.stream().map(item -> item.getString("seconderId")).toList();
// 获取流程实例
ProcessInstance processInstance = flowEngine.processInstanceService().fetch(Cnd.where(ProcessInstance::getBusinessNo, "=", proposalId));
// 获取正在执行的任务(邀请附议人||提案附议)
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(processInstance.getId(), null);
List<BpmAssignmentDto> bpmAssignmentDtos = seconderVOS.stream().map(seconderVO -> { if (doingTaskList.stream().anyMatch(task -> task.getTaskName().equals("85b7b9bd-d706-48cb-99a1-ef1370fb1819"))) {
BpmAssignmentDto assignmentDto = new BpmAssignmentDto(); // 完成邀请任务并添加附议人
assignmentDto.setLoginName(seconderVO.getLoginName()); for (ProcessTask task : doingTaskList) {
assignmentDto.setJsonObject(JSONUtil.parseObj(seconderVO)); Dict args = Dict.create();
return assignmentDto; args.set(FlowConst.PROCESS_TASK_ID_KEY, task.getId());
}).toList(); args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.AGREE.getCode());
args.set(FlowConst.NEXT_NODE_OPERATOR, userIds);
BpmProcessInstance processInstance = dao.fetch(BpmProcessInstance.class, Cnd.where(BpmProcessInstance::getProcessInstanceBusinessId, "=", proposalId)); args.set(FlowConst.TASK_FORM_DATA_PREFIX + "seconder", list);
flowCommonService.executeTask(args);
//判断是否为撰写任务 团长退回 委员会退回 // flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
if (List.of(10, 40, 61).contains(processInstance.getProcessInstanceNodeCode())) {
//完成自己的待办
String taskId = processInstance.getProcessInstanceTaskIds().get(0);
bpmService.completeTaskWithNextTaskVariable(taskId, BpmTaskApprovalTypeEnum.PASS, null, bpmAssignmentDtos);
} else if (processInstance.getProcessInstanceNodeCode() == 20) {
//继续添加附议人
BpmProcessInstance instance = dao.fetch(BpmProcessInstance.class, Cnd.where(BpmProcessInstance::getProcessInstanceBusinessId, "=", proposalId));
bpmService.addTaskAssignmentsWithVariable(instance.getId(), processInstance.getProcessInstanceNodeCode(), bpmAssignmentDtos);
} }
} else {
ProposalInfo info = dao.fetch(ProposalInfo.class, proposalId); // 加签
String createUserName = info.getCreateUserName(); processTaskService.addCandidateActor(doingTaskList.get(0).getId(), userIds);
String proposalName = info.getName();
for (ProposalInviteSeconderVO seconderVO : seconderVOS) {
String template = "{}代表,您好,{}代表的提案《{}》邀请您作为附议人,请您登陆智慧校园下的暖心工会系统进行附议,感谢您对教代会提案工作的大力支持!";
String content = StrUtil.format(template, seconderVO.getUserName(), createUserName, proposalName);
sysMsgService.sendMsg(seconderVO.getLoginName(), "提案附议", content, info.getCreateUserId());
} }
return Result.success(); return Result.success();
@@ -1,35 +1,31 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact; package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService; import com.budwk.app.base.vo.LabelValueVO;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.service.ProcessTaskService;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalUnderTakeSchoolLeaderApprovalParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalSchoolLeaderApprovalService; import com.budwk.app.zhgh.democratic.proposal.service.ProposalSchoolLeaderApprovalService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; 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.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
@IocBean @IocBean
@At("/platform/proposal/schoolLeaderApproval") @At("/platform/proposal/schoolLeaderApproval")
@@ -41,9 +37,11 @@ public class ProposalSchoolLeaderApprovalController {
@Inject @Inject
private Dao dao; private Dao dao;
@Inject @Inject
private BaseService baseService;
@Inject
private ProposalSchoolLeaderApprovalService proposalSchoolLeaderApprovalService; private ProposalSchoolLeaderApprovalService proposalSchoolLeaderApprovalService;
@Inject
private ProposalCommonService proposalCommonService;
@Inject
private ProcessTaskService processTaskService;
@At("") @At("")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html")
@@ -54,77 +52,69 @@ public class ProposalSchoolLeaderApprovalController {
@At @At
@SaCheckPermission("proposal.schoolLeaderApproval") @SaCheckPermission("proposal.schoolLeaderApproval")
@ApiOperation("分页列表") @ApiOperation("分页列表")
public Result pageData(@Valid ProposalSearchParam pageForm,boolean approval) { public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
// List<LabelValueVO> vos = processTaskService.jumpAbleTaskNameList(280L);
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.*, info.*,
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeName, ins.state instanceState,
inst.processInstanceTaskIds, ins.variable instanceVariable,
inst.processInstanceStatus, ins.processDefineId instanceProcessDefineId,
task.id processInstanceTaskId, t.id taskId,
task.taskStatus processInstanceTaskStatus, t.taskName AS taskKey,
JSON_EXTRACT(task.createVariable, '$.isMaster') AS isMasterUnderTake, t.displayName taskName,
JSON_EXTRACT(task.createVariable, '$.underTakeName') AS underTakeName, t.taskType,
JSON_EXTRACT(task.createVariable, '$.underTakeId') AS underTakeId, t.performType taskPerformType,
COUNT(p.consolidationIds) > 0 AS isConsolidation, t.taskState,
EXISTS ( t.finishTime,
SELECT 1 t.taskParentId,
FROM bpm_process_task next_task t.variable taskVariable,
WHERE next_task.prevTaskId = task.id IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
AND next_task.taskStatus = 'COMPLETE' IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
) AS nextTaskIsComplete
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN proposal_consolidation p ON JSON_CONTAINS(p.consolidationIds, JSON_QUOTE(info.id)) LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ cnd.and("t.taskName", "=", "04ecf80c-a9d0-4986-8aac-231758d6a7af");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname())));
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
} }
cnd.and("nd.nodeCode", "=", 90);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.groupBy("info.id"); cnd.groupBy("t.id");
cnd.groupBy("task.id"); cnd.desc("t.createdAt");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@At @At
@SaCheckPermission("proposal.schoolLeaderApproval") @SaCheckPermission("proposal.schoolLeaderApproval")
@Aop(TransAop.READ_COMMITTED) @ApiOperation("获取主办单位")
@SLog(tag = "提案", msg = "提案分管领导审核") public Result getHostUnitId(){
@ApiOperation("审核")
public Result approval(@Param("approval") @Valid ProposalUnderTakeSchoolLeaderApprovalParam param) {
proposalSchoolLeaderApprovalService.approval(param);
return Result.success(); return Result.success();
} }
@At
@SaCheckPermission("proposal.schoolLeaderApproval")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "提案分管领导撤回")
@ApiOperation("撤回")
public Result revoke(@Valid String taskId) {
proposalSchoolLeaderApprovalService.revoke(taskId);
return Result.success();
}
} }
@@ -9,6 +9,7 @@ import com.budwk.app.base.service.BaseService;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.param.BpmTaskApprovalParam; import com.budwk.app.bpm.param.BpmTaskApprovalParam;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO; import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
@@ -32,6 +33,7 @@ import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
/** /**
* 附议提案 * 附议提案
@@ -70,49 +72,48 @@ public class ProposalSecondedController {
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeName, ins.state instanceState,
inst.processInstanceTaskIds, ins.variable instanceVariable,
inst.processInstanceStatus, ins.processDefineId instanceProcessDefineId,
task.id processInstanceTaskId, t.id taskId,
task.taskStatus processInstanceTaskStatus, t.taskName AS taskKey,
JSON_EXTRACT( task.createVariable, '$.userName' ) AS seconderName, t.displayName taskName,
COUNT( nt.id ) OVER ( PARTITION BY task.id ) > 0 AS nextTaskIsComplete t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId 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 proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE'
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ cnd.and("t.taskName", "=", "74458b33-ad6e-46c4-b8d9-1aa897142b25");
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
cnd.and("nd.nodeCode", "=", 20);
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
// cnd.and(new Static(""" cnd.groupBy("t.id");
// NOT EXISTS( cnd.desc("t.createdAt");
// SELECT 1
// FROM bpm_process_task t2
// WHERE t2.processInstanceId = task.processInstanceId
// AND t2.processTaskNodeCode = task.processTaskNodeCode
// AND t2.createdOn > task.createdOn
// )
// """));
// cnd.groupBy("task.id");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@@ -1,40 +1,26 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact; package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService; import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.models.BpmProcessTask;
import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalUnderTakeReplyApprovalParam;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalUnderTakeReplyTransferParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalUnderTakeReplyService; import com.budwk.app.zhgh.democratic.proposal.service.ProposalUnderTakeReplyService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; 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.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@IocBean @IocBean
@At("/platform/proposal/unitReply") @At("/platform/proposal/unitReply")
@@ -44,9 +30,7 @@ import java.util.stream.Collectors;
public class ProposalUnderTakeReplyController { public class ProposalUnderTakeReplyController {
@Inject @Inject
private BaseService baseService; private ProposalCommonService proposalCommonService;
@Inject
private BpmService bpmService;
@Inject @Inject
private ProposalUnderTakeReplyService proposalUnderTakeReplyService; private ProposalUnderTakeReplyService proposalUnderTakeReplyService;
@@ -60,199 +44,55 @@ public class ProposalUnderTakeReplyController {
@SaCheckPermission("proposal.unitReply") @SaCheckPermission("proposal.unitReply")
@ApiOperation("分页列表") @ApiOperation("分页列表")
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval, boolean transfer) { public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval, boolean transfer) {
//获取每个实例每个节点每个单位的最新任务ID
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.*, info.*,
type.name AS typeName, type.name AS typeName,
tcs.fullName AS sessionName, tcs.fullName AS sessionName,
tcd.`name` AS delegationName, tcd.`name` AS delegationName,
inst.id processInstanceId, ins.id AS instanceId,
inst.processInstanceNodeId, ins.businessNo,
inst.processInstanceNodeName, ins.state instanceState,
inst.processInstanceTaskIds, ins.variable instanceVariable,
inst.processInstanceStatus, ins.processDefineId instanceProcessDefineId,
task.id processInstanceTaskId, t.id taskId,
task.taskStatus processInstanceTaskStatus, t.taskName AS taskKey,
JSON_EXTRACT(task.createVariable, '$.isMaster') AS isMasterUnderTake, t.displayName taskName,
JSON_EXTRACT(task.createVariable, '$.underTakeName') AS underTakeName, t.taskType,
JSON_EXTRACT(task.createVariable, '$.underTakeId') AS underTakeId, t.performType taskPerformType,
COUNT(p.consolidationIds) > 0 AS isConsolidation, t.taskState,
EXISTS ( t.finishTime,
SELECT 1 t.taskParentId,
FROM bpm_process_task next_task t.variable taskVariable,
WHERE next_task.prevTaskId = task.id IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
AND next_task.taskStatus = 'COMPLETE' IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
) AS nextTaskIsComplete,
EXISTS (
SELECT 1
FROM bpm_process_task next_task
WHERE next_task.id = task.transferAfterTaskId
AND next_task.taskStatus = 'COMPLETE'
) AS nextTransferTaskIsComplete,
CASE
WHEN task.transferAfterTaskId IS NOT NULL AND task.taskStatus = 'TRANSFER' THEN (
SELECT assignmentUserNames
FROM bpm_process_task
WHERE id = task.transferAfterTaskId
)
ELSE NULL
END as underTakeTransferUserName,
task.transferAfterTaskId IS NOT NULL as underTakeReplyIsTransfer
FROM FROM
bpm_process_task task wf_process_task t
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN proposal_consolidation p ON JSON_CONTAINS(p.consolidationIds, JSON_QUOTE(info.id)) LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId 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_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
LEFT JOIN bpm_process_task transferTask on transferTask.id = task.transferAfterTaskId
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("t.taskName", "in", List.of("85cf23da-2dd5-4007-a1e9-bd9bfddc68f0", "c9a1586e-272b-41b8-b438-0be9f9e3781d"));
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); // cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
cnd.and("nd.nodeCode", "=", 80);
if (AuthUtil.hasRole(RoleConstant.PROPOSAL_UNIT_LEADER.name())) {
if (transfer) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.TRANSFER);
} else {
cnd.and(Cnd.exps("transferTask.id", "is", null)
.or("transferTask.taskStatus", "=", BpmProcessTaskStatusEnum.REVOKE.name()));
// cnd.and("task.transferAfterTaskId","is",null);
cnd.and(new Static("""
NOT EXISTS (
SELECT 1
FROM bpm_process_task prev_task
WHERE prev_task.id = task.prevTaskId
AND prev_task.taskStatus = 'TRANSFER'
)
"""));
cnd.and(new Static("""
NOT EXISTS (
SELECT 1
FROM bpm_process_task source_task
WHERE source_task.transferAfterTaskId = task.id
)
"""));
if (approval) { if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
}
} else {
if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE);
} else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE);
}
}
ProposalSearchParam.buildSearch(cnd, pageForm); ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.groupBy("info.id"); cnd.groupBy("t.id");
cnd.groupBy("task.id"); cnd.desc("t.createdAt");
if (!transfer) {
cnd.and(new Static("""
NOT EXISTS(
SELECT 1
FROM bpm_process_task t2
WHERE JSON_EXTRACT(t2.createVariable, '$.underTakeId') = JSON_EXTRACT(task.createVariable, '$.underTakeId')
AND t2.createdOn > task.createdOn
AND t2.taskStatus = 'COMPLETE'
AND t2.processTaskNodeCode = task.processTaskNodeCode
AND t2.processInstanceId = task.processInstanceId
)
"""));
}
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination); return Result.success(pagination);
} }
@At
@SaCheckPermission("proposal.unitReply")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案承办单位答复", msg = "承办单位答复")
@ApiOperation("审核")
public Result approval(@Param("approval") @Valid ProposalUnderTakeReplyApprovalParam param) {
proposalUnderTakeReplyService.approval(param);
return Result.success();
}
@At
@SaCheckPermission("proposal.unitReply")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案承办单位答复", msg = "承办单位答复撤回")
@ApiOperation("撤回")
public Result revoke(@Valid String taskId) {
proposalUnderTakeReplyService.revokeTask(taskId);
return Result.success();
}
@At
@SaCheckPermission("proposal.unitReply")
@ApiOperation("查询本单位可转办用户")
public Result queryTransferUser(@Valid String keyword) {
return Result.success(proposalUnderTakeReplyService.queryTransferUser(keyword));
}
@At
@SaCheckPermission("proposal.unitReply")
@ApiOperation("转办")
@SLog(tag = "提案承办单位答复", msg = "转办")
@Aop(TransAop.READ_COMMITTED)
public Result transfer(@Valid @Param("transfer") ProposalUnderTakeReplyTransferParam param) {
proposalUnderTakeReplyService.transfer(param);
return Result.success();
}
@At
@SaCheckPermission("proposal.unitReply")
@ApiOperation("检查是否可以办理")
public Result checkCanReply(@Valid String taskId) {
String errorMsg = proposalUnderTakeReplyService.checkCanReply(taskId);
BpmProcessTask task = proposalUnderTakeReplyService.dao().fetch(BpmProcessTask.class, taskId);
Sql sql = Sqls.create("""
SELECT
JSON_UNQUOTE(JSON_EXTRACT( createVariable, '$.underTakeName' )) AS underTakeName,
JSON_UNQUOTE(JSON_EXTRACT(extVariable,'$.approvalOpinion')) as approvalOpinion
FROM
bpm_process_task
WHERE
processInstanceId = @processInstanceId
AND processTaskNodeCode = 80
AND taskStatus = 'COMPLETE'
AND JSON_EXTRACT(createVariable,'$.isMaster')= false
""");
sql.setParam("processInstanceId", task.getProcessInstanceId());
List<NutMap> slaveReplyList = proposalUnderTakeReplyService.listMap(sql);
String allSlaveApprovalOpinion = slaveReplyList.stream().map(slave -> slave.getString("underTakeName", "") + "<br/>" + slave.getString("approvalOpinion", "")).collect(Collectors.joining("<br/><br/>"));
NutMap map = NutMap.NEW();
map.put("errMsg", errorMsg);
map.put("allSlaveApprovalOpinion", allSlaveApprovalOpinion);
map.put("task",task);
return Result.success().addData(map);
}
@At
@SaCheckPermission("proposal.unitReply")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案承办单位答复", msg = "承办单位转办撤回")
@ApiOperation("转办撤回")
public Result revokeTransfer(@Valid String taskId) {
proposalUnderTakeReplyService.revokeTransfer(taskId);
return Result.success();
}
} }
@@ -1,15 +1,24 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact; package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.BpmProcessConstant; import com.budwk.app.base.constant.BpmProcessConstant;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.bpm.service.BpmService; import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
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.service.FlowCommonService;
import com.budwk.app.sys.models.Sys_dict; import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService; import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService;
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate; import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -41,7 +50,10 @@ public class ProposalWriteController {
@Inject @Inject
private ProposalWriteService proposalWriteService; private ProposalWriteService proposalWriteService;
@Inject @Inject
private BpmService bpmService; private FlowEngine flowEngine;
@Inject
private FlowCommonService flowCommonService;
@At("") @At("")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/write/index.html") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/write/index.html")
@@ -59,21 +71,51 @@ public class ProposalWriteController {
proposalInfo.setCode(proposalWriteService.generateProposalCode(proposalInfo.getSessionId(),proposalInfo.getDelegationId())); proposalInfo.setCode(proposalWriteService.generateProposalCode(proposalInfo.getSessionId(),proposalInfo.getDelegationId()));
} }
dao.insertOrUpdate(proposalInfo); dao.insertOrUpdate(proposalInfo);
bpmService.startSaveProcessInstance(BpmProcessConstant.PROPOSAL.name(),proposalInfo.getName(),proposalInfo.getId(), null);
return Result.success(proposalInfo); return Result.success(proposalInfo);
} }
@At @At
@SaCheckPermission("proposal.write") @SaCheckPermission("proposal.write")
@Aop(TransAop.READ_COMMITTED) @Aop(TransAop.READ_COMMITTED)
@ApiOperation("保存提案") @ApiOperation("提交提案")
@SLog(tag = "提案管理系统-我的提案", msg = "手动提交提案") @SLog(tag = "提案管理系统-我的提案", msg = "提交提案")
public Result submit(@Param("info") ProposalInfo proposalInfo) { public Result submit(@Param("info") ProposalInfo proposalInfo) {
if (StrUtil.isBlank(proposalInfo.getCode())) {
proposalInfo.setCode(proposalWriteService.generateProposalCode(proposalInfo.getSessionId(),proposalInfo.getDelegationId()));
}
dao.insertOrUpdate(proposalInfo); dao.insertOrUpdate(proposalInfo);
bpmService.startSubmitProcessInstance(BpmProcessConstant.PROPOSAL.name(),proposalInfo.getName(),proposalInfo.getId(), null,null);
// 开启流程实例
Dict args = Dict.create();
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, proposalInfo);
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JDHTA", proposalInfo.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success(proposalInfo); return Result.success(proposalInfo);
} }
@At
@SaCheckPermission("proposal.write")
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("重新提交提案")
@SLog(tag = "提案管理系统-我的提案", msg = "重新提交提案")
public Result submitAgain(@Param("data") SuggestionBox suggestionBox, @Param("taskId") Long taskId) {
dao.insertOrUpdate(suggestionBox);
Dict dict = Dict.create();
dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
flowCommonService.executeTask(dict);
return Result.success();
}
@At @At
@SaCheckPermission("proposal.write") @SaCheckPermission("proposal.write")
@ApiOperation("提案详情") @ApiOperation("提案详情")
@@ -0,0 +1,66 @@
package com.budwk.app.zhgh.democratic.proposal.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
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.zhgh.democratic.proposal.models.ProposalUndertake;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.List;
/**
* 提案主办单位处理人
*/
public class ProposalMasterUnitAssignmentHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
// 主办单位id
String hostUnitId = execution.getArgs().getStr("tf_hostUnitId");
if (StrUtil.isBlank(hostUnitId)) {
throw new BaseException("请选择主办单位");
}
// 获取主办单位
ProposalUndertake undertake = dao.fetch(ProposalUndertake.class, hostUnitId);
if (undertake == null) {
throw new BaseException("主办单位不存在");
}
// 获取负责人
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER);
List<Sys_user_role> sysUserRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId()).and(Sys_user_role::getUnderTakeId, "=", undertake.getId()));
List<String> selectUserIds = sysUserRoles.stream().map(Sys_user_role::getUserId).toList();
if (selectUserIds.isEmpty()) {
throw new BaseException("主办单位没有负责人");
}
return selectUserIds;
}
@Override
public String getMessage() {
return "提案主办单位处理人";
}
@Override
public int getOrder() {
return 200;
}
}
@@ -0,0 +1,49 @@
package com.budwk.app.zhgh.democratic.proposal.handler;
import cn.hutool.core.lang.Dict;
import com.budwk.app.flow.engine.CandidateHandler;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.flow.entity.Candidate;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.lang.util.NutMap;
import java.util.List;
public class ProposalSchoolLeaderCandidateHandler implements CandidateHandler {
@Override
public List<Candidate> handle(TaskModel model) {
Dao dao = ServiceContext.find(Dao.class);
ProposalConfig proposalConfig = dao.fetch(ProposalConfig.class, Cnd.NEW());
List<String> unitIds = proposalConfig.getSchoolLeaderUnitIds();
Sql sql = Sqls.create("select id,username,loginname from vw_user where unitId in (@unitIds)");
sql.setParam("unitIds", unitIds);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
List<NutMap> list = sql.getList(NutMap.class);
List<Candidate> candidates = list.stream().map(item -> Candidate.builder()
.userId(item.getString("id"))
.userName(item.getString("username"))
.ext(Dict.of("loginName", item.getString("loginname")))
.build()
).toList();
return candidates;
}
@Override
public String getMessage() {
return "提案分管校领导";
}
@Override
public int getOrder() {
return 20;
}
}
@@ -0,0 +1,69 @@
package com.budwk.app.zhgh.democratic.proposal.handler;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
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.zhgh.democratic.proposal.models.ProposalConfig;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.ArrayList;
import java.util.List;
/**
* 提案协办单位处理人
*/
public class ProposalSlaveUnitAssignmentHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
List<String> assignee = new ArrayList<>();
// 提案配置
ProposalConfig proposalConfig = dao.fetch(ProposalConfig.class, Cnd.NEW());
// 不需要答复
if (!proposalConfig.getSlaveUnitNeedReply()) {
return assignee;
}
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
// 协办单位id
List<String> helpUnitIds = (List<String>) execution.getArgs().get("tf_helpUnitIds");
if (helpUnitIds != null && !helpUnitIds.isEmpty()) {
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER);
for (String helpUnitId : helpUnitIds) {
ProposalUndertake undertake = dao.fetch(ProposalUndertake.class, helpUnitId);
List<Sys_user_role> sysUserRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId()).and(Sys_user_role::getUnderTakeId, "=", undertake.getId()));
if (sysUserRoles.isEmpty()) {
throw new BaseException(undertake.getName() + "单位没有设置负责人!");
}
assignee.addAll(sysUserRoles.stream().map(Sys_user_role::getUserId).toList());
}
return assignee;
}
return assignee;
}
@Override
public String getMessage() {
return "提案协办单位处理人";
}
@Override
public int getOrder() {
return 210;
}
}
@@ -1,33 +0,0 @@
package com.budwk.app.zhgh.democratic.proposal.handler;
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 java.util.List;
/**
* 承办单位答复人处理类
*/
public class ProposalUnitReplyAssignmentHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
List<String> unitIds = (List<String>)execution.getArgs().get("unitIds");
return List.of();
}
@Override
public String getMessage() {
return "承办单位答复人";
}
@Override
public int getOrder() {
return 20;
}
}
@@ -19,22 +19,6 @@ import org.nutz.json.Json;
public class ProposalApplyInterceptor implements FlowInterceptor { public class ProposalApplyInterceptor implements FlowInterceptor {
@Override @Override
public void intercept(Execution execution) { public void intercept(Execution execution) {
ProposalWriteService writeService = ServiceContext.find(ProposalWriteService.class);
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
ProposalInfo info = Json.fromJson(ProposalInfo.class, formDataStr);
if (StrUtil.isBlank(info.getId())) {
String code = writeService.generateProposalCode(info.getSessionId(), info.getDelegationId());
info.setCode(code);
}
Dao dao = ServiceContext.find(Dao.class);
dao.insertOrUpdate(info);
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(info));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", info.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
} }
} }
@@ -0,0 +1,25 @@
package com.budwk.app.zhgh.democratic.proposal.interceptor;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.Objects;
/**
* 提案分管领导审批拦截器
*/
@IocBean
public class ProposalSchoolLeaderApprovalInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
Integer submitType = execution.getArgs().getInt(FlowConst.SUBMIT_TYPE);
// 退回到承办单位答复 需要设置退回节点及单位ID
if (Objects.equals(submitType, ProcessSubmitTypeEnum.JUMP.getCode())) {
// execution.getArgs().set(FlowConst.TASK_FORM_DATA_PREFIX + "hostUnitId", "da59e22f2a744a128b4f71c037c8d32e");
}
}
}
@@ -97,56 +97,56 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
""").setParam("id", id); """).setParam("id", id);
NutMap nutMap = (NutMap) dao().execute(sql.setCallback(Sqls.callback.map())).getResult(); NutMap nutMap = (NutMap) dao().execute(sql.setCallback(Sqls.callback.map())).getResult();
List<BpmTaskApprovalRecordVo> nodeTasks = bpmService.getNodeTasks(BpmProcessConstant.PROPOSAL, id); // List<BpmTaskApprovalRecordVo> nodeTasks = bpmService.getNodeTasks(BpmProcessConstant.PROPOSAL, id);
nutMap.put("nodeTasks", nodeTasks); // nutMap.put("nodeTasks", nodeTasks);
//
//查询附议人信息 // //查询附议人信息
BpmProcessInstance bpmProcessInstance = dao().fetch(BpmProcessInstance.class, Cnd.where(BpmProcessInstance::getProcessInstanceBusinessId, "=", id)); // BpmProcessInstance bpmProcessInstance = dao().fetch(BpmProcessInstance.class, Cnd.where(BpmProcessInstance::getProcessInstanceBusinessId, "=", id));
BpmProcessTask lastestWriteTask = dao().fetch(BpmProcessTask.class, Cnd.where(BpmProcessTask::getProcessInstanceId, "=", bpmProcessInstance.getId()) // BpmProcessTask lastestWriteTask = dao().fetch(BpmProcessTask.class, Cnd.where(BpmProcessTask::getProcessInstanceId, "=", bpmProcessInstance.getId())
.and(BpmProcessTask::getTaskStatus, "=", BpmProcessTaskStatusEnum.COMPLETE.name()) // .and(BpmProcessTask::getTaskStatus, "=", BpmProcessTaskStatusEnum.COMPLETE.name())
.and(BpmProcessTask::getProcessTaskNodeCode, "in", List.of(10, 40, 61)) // .and(BpmProcessTask::getProcessTaskNodeCode, "in", List.of(10, 40, 61))
.and(BpmProcessTask::getDelFlag, "=", 0) // .and(BpmProcessTask::getDelFlag, "=", 0)
.desc(BpmProcessTask::getEndOn) // .desc(BpmProcessTask::getEndOn)
); // );
//
if (ObjectUtil.isNotEmpty(lastestWriteTask)) { // if (ObjectUtil.isNotEmpty(lastestWriteTask)) {
String lastestWriteTaskId = lastestWriteTask.getId(); // String lastestWriteTaskId = lastestWriteTask.getId();
List<BpmProcessTask> seconderTasks = dao().query(BpmProcessTask.class, Cnd.where(BpmProcessTask::getPrevTaskId, "=", lastestWriteTaskId) // List<BpmProcessTask> seconderTasks = dao().query(BpmProcessTask.class, Cnd.where(BpmProcessTask::getPrevTaskId, "=", lastestWriteTaskId)
.and(BpmProcessTask::getProcessInstanceId, "=", bpmProcessInstance.getId()) // .and(BpmProcessTask::getProcessInstanceId, "=", bpmProcessInstance.getId())
.and(BpmProcessTask::getTaskStatus, "!=", BpmProcessTaskStatusEnum.REVOKE.name()) // .and(BpmProcessTask::getTaskStatus, "!=", BpmProcessTaskStatusEnum.REVOKE.name())
.and(BpmProcessTask::getDelFlag, "=", 0) // .and(BpmProcessTask::getDelFlag, "=", 0)
.asc(BpmProcessTask::getCreatedOn) // .asc(BpmProcessTask::getCreatedOn)
); // );
nutMap.put("seconders", seconderTasks); // nutMap.put("seconders", seconderTasks);
} // }
//
//查询并案的提案 // //查询并案的提案
List<String> consolidationProposalIds = getConsolidation(id); // List<String> consolidationProposalIds = getConsolidation(id);
List<String> otherProposalIds = consolidationProposalIds.stream().filter(proposalId -> !proposalId.equals(id)).toList(); // List<String> otherProposalIds = consolidationProposalIds.stream().filter(proposalId -> !proposalId.equals(id)).toList();
if (ObjectUtil.isNotEmpty(otherProposalIds)) { // if (ObjectUtil.isNotEmpty(otherProposalIds)) {
Sql otherProposalSql = Sqls.create(""" // Sql otherProposalSql = Sqls.create("""
SELECT // SELECT
info.id, // info.id,
info.name, // info.name,
info.code, // info.code,
info.createUserName, // info.createUserName,
type.name AS typeName, // type.name AS typeName,
tcs.fullName AS sessionName, // tcs.fullName AS sessionName,
tcd.`name` AS delegationName // tcd.`name` AS delegationName
FROM // FROM
proposal_info info // proposal_info info
LEFT JOIN proposal_type type on type.id = info.typeId // 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_session tcs ON tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId // LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId
WHERE info.id in (@otherProposalIds) // WHERE info.id in (@otherProposalIds)
""").setParam("otherProposalIds", otherProposalIds); // """).setParam("otherProposalIds", otherProposalIds);
List<NutMap> consolidationProposals = listMap(otherProposalSql); // List<NutMap> consolidationProposals = listMap(otherProposalSql);
nutMap.put("consolidationProposals", consolidationProposals); // nutMap.put("consolidationProposals", consolidationProposals);
nutMap.put("isConsolidation", true); // nutMap.put("isConsolidation", true);
} else { // } else {
nutMap.put("consolidationProposals", null); // nutMap.put("consolidationProposals", null);
nutMap.put("isConsolidation", false); // nutMap.put("isConsolidation", false);
} // }
return nutMap; return nutMap;
} }
@@ -44,7 +44,7 @@ public class SuggestionBoxQueryController {
@At @At
@SaCheckLogin @SaCheckLogin
public Result pageData(Integer pageNumber, Integer pageSize) { public Result pageData(Integer pageNumber, Integer pageSize, String title, Integer year) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
info.id, info.id,
@@ -78,7 +78,8 @@ public class SuggestionBoxQueryController {
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.and("info.createdBy", "=", SecurityUtil.getUserId()); cnd.andEX("YEAR(info.submitTime)", "=", year);
cnd.and(Cnd.likeEX("info.title", title));
cnd.desc("info.submitTime"); cnd.desc("info.submitTime");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<NutMap> pagination = suggestionBoxService.listPageMap(pageNumber, pageSize, sql); Pagination<NutMap> pagination = suggestionBoxService.listPageMap(pageNumber, pageSize, sql);
@@ -79,7 +79,7 @@ public class SuggestionXghController {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) { if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else { } else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
} }
@@ -1,27 +0,0 @@
package com.budwk.app.zhgh.democratic.suggestionBox.interceptor;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
public class SuggestionBoxApplyInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
SuggestionBox suggestionBox = Json.fromJson(SuggestionBox.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
dao.insertOrUpdate(suggestionBox);
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(suggestionBox));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", suggestionBox.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -92,6 +92,10 @@ public class TeacherCongressSessionController {
@SaCheckPermission("tc.prepare.session") @SaCheckPermission("tc.prepare.session")
@ApiOperation(value = "删除届次信息") @ApiOperation(value = "删除届次信息")
public Result delete(@Valid @ApiParam("id") String id) { public Result delete(@Valid @ApiParam("id") String id) {
int count = dao.count(Teacher_congress_session.class, Cnd.NEW());
if (count == 1) {
return Result.error("请勿删除所有届次信息");
}
teacherCongressSessionService.deleteSession(id); teacherCongressSessionService.deleteSession(id);
return Result.success(); return Result.success();
} }
@@ -61,4 +61,14 @@ public class Teacher_congress_session extends BaseModel {
@Default(value = "0") @Default(value = "0")
private Boolean enable; private Boolean enable;
@Column
@Comment("提案开始征集时间")
@ColDefine(type = ColType.DATETIME)
private Date collectStartTime;
@Column
@Comment("提案结束征集时间")
@ColDefine(type = ColType.DATETIME)
private Date collectEndTime;
} }
@@ -677,7 +677,7 @@ td.no-b {
.flow-task-form .el-descriptions-item__label.is-bordered-label { .flow-task-form .el-descriptions-item__label.is-bordered-label {
background: rgb(248, 249, 250) !important; background: rgb(248, 249, 250) !important;
padding: 8px 12px !important; padding: 8px 12px !important;
border: 1px solid rgb(221, 221, 221) !important; /*border: 1px solid rgb(221, 221, 221) !important;*/
text-align: center !important; text-align: center !important;
} }
@@ -0,0 +1,100 @@
<template>
<div>
<!-- 弹窗模式默认 -->
<template v-if="mode === 'dialog'">
<!-- 触发按钮 -->
<!-- <slot name="trigger">-->
<!-- <el-button type="primary" size="small" @click="openDialog">二维码</el-button>-->
<!-- </slot>-->
<!-- 弹出框 -->
<el-dialog
title="二维码"
:visible.sync="dialogVisible"
width="40%"
append-to-body
>
<div class="qrcode-container" style="text-align: center;">
<qrcode :value="url" :options="{ width: 126 }" class="signature-qrcode"></qrcode>
</div>
<template #footer>
<el-button @click="dialogVisible = false">关闭</el-button>
</template>
</el-dialog>
</template>
<!-- 内联模式 -->
<template v-else-if="mode === 'inline'">
<div class="qrcode-inline-container">
<qrcode :value="url" :options="{ width: 126 }" class="signature-qrcode"></qrcode>
</div>
</template>
</div>
</template>
<script>
module.exports = {
name: 'QrCodeDisplay',
props: {
// 二维码内容
url: {
type: String,
required: true
},
// 显示模式:dialog(默认)或 inline
mode: {
type: String,
default: 'dialog',
validator: (value) => ['dialog', 'inline'].includes(value)
},
// 控制弹窗显示(可用于外部 v-model 控制)
value: {
type: Boolean,
default: false
}
},
data() {
return {
dialogVisible: this.value // 初始化为传入的 value
}
},
watch: {
// 同步 v-model 的 value 变化到 dialogVisible
value(newVal) {
this.dialogVisible = newVal
},
// 同步 dialogVisible 状态到外部(实现 v-model
dialogVisible(newVal) {
this.$emit('input', newVal)
}
},
methods: {
openDialog() {
this.dialogVisible = true
}
}
}
</script>
<style scoped>
.signature-qrcode {
display: inline-block;
margin: 0 auto;
}
.qrcode-container {
padding: 20px 0;
}
.qrcode-inline-container {
display: inline-block;
padding: 10px;
border: 1px dashed #ccc;
border-radius: 8px;
}
</style>
@@ -324,6 +324,7 @@
Vue.component("table-tool", httpVueLoader("/components/plugins/sysTableTool/index.vue?v=" + new Date().getTime())) Vue.component("table-tool", httpVueLoader("/components/plugins/sysTableTool/index.vue?v=" + new Date().getTime()))
Vue.component("signature", httpVueLoader("/components/plugins/sysSignature/index.vue?v=" + new Date().getTime())) Vue.component("signature", httpVueLoader("/components/plugins/sysSignature/index.vue?v=" + new Date().getTime()))
Vue.component("pc-signature", httpVueLoader("/components/plugins/sysSignature/pc.vue?v=" + new Date().getTime())) Vue.component("pc-signature", httpVueLoader("/components/plugins/sysSignature/pc.vue?v=" + new Date().getTime()))
Vue.component("qr-code-plus", httpVueLoader("/components/plugins/sysQrCode/index.vue?v=" + new Date().getTime()))
Vue.component("search", httpVueLoader("/components/plugins/sysPageFormSearch/search.vue?v=" + new Date().getTime())) Vue.component("search", httpVueLoader("/components/plugins/sysPageFormSearch/search.vue?v=" + new Date().getTime()))
Vue.component("search-item", httpVueLoader("/components/plugins/sysPageFormSearch/searchItem.vue?v=" + new Date().getTime())) Vue.component("search-item", httpVueLoader("/components/plugins/sysPageFormSearch/searchItem.vue?v=" + new Date().getTime()))
Vue.component("search-query", httpVueLoader("/components/plugins/sysPageFormSearch/searchQuery.vue?v=" + new Date().getTime())) Vue.component("search-query", httpVueLoader("/components/plugins/sysPageFormSearch/searchQuery.vue?v=" + new Date().getTime()))
@@ -1,49 +0,0 @@
<!--#
layout("/layouts/v4/baseLayout.html"){
#-->
<div id="approvalApp" v-cloak>
<snaker-flow
:task_id="taskId"
:instance_id="instanceId"
:business_id="businessId"
:pjax_urls="{
applicationInfo: '/platform/article/write/index_',
taskForm: '/platform/article/write/index_'
}"
:pjax_config="{
push: false,
replace: false,
timeout: 10000
}"
></snaker-flow>
</div>
<script>
new Vue({
el: "#approvalApp",
data() {
return {
taskId: null,
instanceId: null,
businessId: null,
formConfig: {}
}
},
methods: {
handleTaskSubmitted() {},
handleCancel() {
window.history.back()
}
},
created() {
this.taskId = new URLSearchParams(window.location.search).get("taskId")
this.instanceId = new URLSearchParams(window.location.search).get("instanceId")
this.businessId = new URLSearchParams(window.location.search).get("businessId")
}
})
</script>
<!--#
}
#-->
@@ -1,48 +0,0 @@
<div id="article_branch_union_approval_form">
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
<el-form-item label="审批意见" prop="approvalOpinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction"
@cancel="handleCancel">
</snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#article_branch_union_approval_form",
data() {
return {
taskId: GetQueryString("taskId"),
formData: {
approval: "",
approvalOpinion: ""
}
}
},
methods: {
handleTaskAction(val) {
console.log(val)
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify(val)
}).then(res => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.parent.postMessage({
type: "task-complete"
}, "*")
}
})
},
handleCancel(val) {
console.log(val)
}
}
})
</script>
@@ -36,7 +36,7 @@ layout("/layouts/platform.html"){
<el-table-column prop="unitName" label="投稿人单位"></el-table-column> <el-table-column prop="unitName" label="投稿人单位"></el-table-column>
<el-table-column prop="unionName" label="投稿人工会"></el-table-column> <el-table-column prop="unionName" label="投稿人工会"></el-table-column>
<el-table-column prop="submitTime" label="投稿时间"></el-table-column> <el-table-column prop="submitTime" label="投稿时间"></el-table-column>
<el-table-column prop="taskName" label="当前节点"></el-table-column> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态"> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}"> <template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" <enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
@@ -45,17 +45,10 @@ layout("/layouts/platform.html"){
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200px" fixed="right"> <el-table-column label="操作" width="200px" fixed="right">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="onOpen(row.id)" size="mini" type="primary">查看</el-button> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary"> <el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
审核
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -63,27 +56,27 @@ layout("/layouts/platform.html"){
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<el-dialog title="" :visible.sync="showApprovalForm" width="90%"> <template #edit>
<info ref="infoRef"></info> <article-info ref="articleInfoRef">
<el-row type="flex">
<flow-form-button :task_id="taskId"></flow-form-button>
<!-- <el-button plain @click="$refs.guava.index()">取消</el-button>-->
<!-- <el-button type="danger" @click="doApproval('BACK')">退回修改</el-button>-->
<!-- <el-button type="primary" @click="doApproval('PASS')">同意</el-button>-->
</el-row>
</el-dialog>
<template #public>
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<el-row type="flex"> <div class="process-title">
<flow-form-button :task_id="taskId"></flow-form-button> {{formData.taskName}}
</div>
<!-- <el-button plain @click="$refs.guava.index()">取消</el-button>--> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
<!-- <el-button type="danger" @click="doApproval('BACK')">退回修改</el-button>--> class="flow-task-form">
<!-- <el-button type="primary" @click="doApproval('PASS')">同意</el-button>--> <el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</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(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row> </el-row>
</div> </div>
</article-info>
</template> </template>
</guava> </guava>
</div> </div>
@@ -95,51 +88,68 @@ layout("/layouts/platform.html"){
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: { info }, components: {
"article-info": ARTICLE_INFO
},
data() { data() {
return { return {
pageForm: { pageForm: {
approval: false approval: false
}, },
showApprovalForm: false, showApprovalForm: false,
taskId: ""
} }
}, },
methods: { methods: {
onOpen(id) { // 查看
this.$refs.guava.public(() => { openView(row) {
this.$refs.infoRef.onOpen(id) this.$refs.guava.edit(()=>{
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.articleInfoRef.onOpen(row)
}) })
}, },
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo) // 审核
}, openAudit(row) {
doApproval(approvalType) { this.$refs.guava.edit(()=>{
this.formData.bpmTaskApprovalType = approvalType this.showApprovalForm = true
this.$refs.approvalFormRef.validate((valid) => { this.formData = {
if (valid) { processTaskId: row.taskId,
this.$axios taskName: row.curTaskName
.post("/platform/article/branchUnionApproval/approval", { }
approval: JSON.stringify(this.formData) this.$refs.articleInfoRef.onOpen(row)
}) })
.then((res) => { },
// 提交
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index() this.$refs.guava.index()
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
} }
}) })
}
}) })
}, },
openRevoke(taskId) {
// 撤回
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post("/platform/article/branchUnionApproval/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -147,6 +157,7 @@ layout("/layouts/platform.html"){
}) })
}) })
} }
}, },
created() { created() {
this.pageData() this.pageData()
@@ -1,82 +0,0 @@
<div id="article-full-form">
<el-descriptions :column="2" border class="flow-task-form">
<el-descriptions-item label="投稿人姓名">{{ viewData.userName }}</el-descriptions-item>
<el-descriptions-item label="投稿人工号">{{ viewData.loginName }}</el-descriptions-item>
<el-descriptions-item label="投稿人单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item label="投稿人工会">{{ viewData.unionName }}</el-descriptions-item>
<el-descriptions-item label="投稿人联系方式">{{ viewData.mobile }}</el-descriptions-item>
<el-descriptions-item label="稿件修改人联系方式">{{ viewData.mobile2 }}</el-descriptions-item>
<el-descriptions-item label="投稿标题" :span="2">{{ viewData.title }}</el-descriptions-item>
<el-descriptions-item label="投稿说明" :span="2">{{ viewData.excerpt }}</el-descriptions-item>
<el-descriptions-item label="稿件" :span="2">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="task-panel mt10">
<div class="task-panel-header">
{{ task.displayName }}
</div>
<el-descriptions border class="flow-task-form" :column="2" :key="task.id">
<el-descriptions-item label="办理用户">{{ task.operator }}</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
</div>
<script>
new Vue({
el: "#article-full-form",
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
viewData: {},
doneTasks: []
}
},
methods: {
info() {
this.$axios.post("/platform/article/common/info", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instanceId }).then(res => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
}
},
created() {
this.info()
this.getDoneTasks()
}
})
</script>
<style>
.task-panel{
background: white;
border-radius: 4px;
overflow: hidden;
}
.task-panel-header{
background: rgb(250, 250, 250);
border: 1px solid rgb(228, 231, 237);
border-bottom: none;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
}
</style>
@@ -1,8 +1,9 @@
const info = { const ARTICLE_INFO = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<div class=""> <div class="">
<div class="process-title"> <div class="process-title">
基础信息 申请信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div> </div>
<el-descriptions :column="2" border> <el-descriptions :column="2" border>
<el-descriptions-item label="投稿人姓名">{{ viewData.userName }}</el-descriptions-item> <el-descriptions-item label="投稿人姓名">{{ viewData.userName }}</el-descriptions-item>
@@ -18,69 +19,82 @@ const info = {
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
<div> <template v-for="task in doneTasks">
<div v-for="nodeTask in viewData.nodeTasks" :key="nodeTask.id"> <div class="mt10">
<div class="process-title"> <div class="process-title">{{ task.displayName }}</div>
{{nodeTask.nodeName}} <el-descriptions border class="flow-task-form" :column="3" :key="task.id"
</div> v-if="task.ext.isFirstTaskNode">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id" <el-descriptions-item label="申请用户">{{ task.ext.initiatorName
style="margin-bottom: 10px"> }}({{task.ext.initiatorAccount}})
<el-descriptions-item label="审核人">
{{ task.actualOwnerLoginName + '-' + task.actualOwnerUserName}}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="审核时间">{{ task.endOn}}</el-descriptions-item> <el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="审核结果"> <el-descriptions-item label="办理结果">
<div v-if="task.extVariable"> <dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
<el-tag type="success" size="mini" :value="task.ext.submitType"></dict-tag>
v-if="task.extVariable.bpmTaskApprovalType === 'PASS'">同意
</el-tag>
<el-tag type="danger" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'BACK'">退回
</el-tag>
<el-tag type="danger" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'REJECT'">拒绝
</el-tag>
<template v-if="task.extVariable.bpmTaskApprovalType === 'DYNAMIC'">
<el-tag v-if="task.extVariable.RESULT === 'BACK_TO_START'" type="danger"
size="mini">
退回至投稿人
<span v-if="task.extVariable.processAgain===false">不需要重新走流程</span>
<span v-if="task.extVariable.processAgain===true">需要重新走流程</span>
</el-tag>
<el-tag v-if="task.extVariable.RESULT === 'PASS'" type="success" size="mini">同意
</el-tag>
<el-tag v-if="task.extVariable.RESULT === 'BACK_TO_CLUB'" type="danger" size="mini">
退回到协会
</el-tag>
<el-tag v-if="task.extVariable.RESULT === 'BACK_TO_UNION'" type="danger"
size="mini">
退回到分工会
</el-tag>
</template>
</div>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="审核意见" :span="3"> </el-descriptions>
{{ task.extVariable.approvalOpinion}}
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{
task.taskFormData.opinion }}
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
</div> </template>
<slot></slot>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div> </div>
`, `,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() { data() {
return { return {
visible: false, visible: false,
viewData: {} viewData: {},
doneTasks: [],
row: null
} }
}, },
methods: { methods: {
// 打开
onOpen(row) { onOpen(row) {
this.$axios.post("/platform/article/common/info", { id: row.businessKey }).then((res) => { this.row = row
this.visible = true
this.getInfo()
this.getDoneTasks()
},
// 获取申请信息
getInfo() {
this.$axios.post('/platform/article/common/info', {id: this.row.id}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.viewData = res.data this.viewData = res.data
} }
}) })
},
// 获取已办任务审批记录
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
},
// 查看流程图
openChart(){
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId,this.row.instanceId)
} }
} }
} }
@@ -1,31 +1,24 @@
<!--# <!--#
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<div id="app" v-cloak> <div id="app" v-cloak>
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度"> <search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker> <el-date-picker
:clearable="true"
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="年度"
style="width: 100%"
></el-date-picker>
</search-item> </search-item>
<search-item label="标题"> <search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input> <el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item> </search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会" filterable clearable style="width: 100%">
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位:">
<el-select v-model="pageForm.unitId" placeholder="请选择所属单位" filterable clearable style="width: 100%">
<el-option v-for="item in unitOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="投稿来源:">
<el-select v-model="pageForm.origin" placeholder="请选择投稿来源" filterable clearable style="width: 100%">
<el-option v-for="item in dict.type.ARTICLE_ORIGIN" :key="item.code" :label="item.label" :value="item.code"></el-option>
</el-select>
</search-item>
</search> </search>
</el-card> </el-card>
<el-card shadow="never"> <el-card shadow="never">
@@ -42,25 +35,20 @@ layout("/layouts/platform.html"){
<el-table-column prop="userName" label="投稿人姓名"></el-table-column> <el-table-column prop="userName" label="投稿人姓名"></el-table-column>
<el-table-column prop="unitName" label="投稿人单位"></el-table-column> <el-table-column prop="unitName" label="投稿人单位"></el-table-column>
<el-table-column prop="unionName" label="投稿人工会"></el-table-column> <el-table-column prop="unionName" label="投稿人工会"></el-table-column>
<el-table-column prop="clubName" label="投稿人协会"></el-table-column>
<el-table-column prop="origin" label="投稿来源">
<template slot-scope="{row}">{{dict.type.ARTICLE_ORIGIN.find(v=>v.code===row.origin)?.label}}</template>
</el-table-column>
<el-table-column prop="submitTime" label="投稿时间"></el-table-column> <el-table-column prop="submitTime" label="投稿时间"></el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column label="操作" fixed="right"> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="onOpen(row.id)" size="mini" type="primary">查看</el-button> <enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
<el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary"> size="small"></enum-tag>
审核 </template>
</el-table-column>
<el-table-column label="操作" width="200px" fixed="right">
<template slot-scope="{row}">
<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>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -68,31 +56,27 @@ layout("/layouts/platform.html"){
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #public> <template #edit>
<info ref="infoRef"></info> <article-info ref="articleInfoRef">
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div> <div class="process-title">
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px"> {{formData.taskName}}
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> </div>
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
</el-form-item> class="flow-task-form">
<el-form-item label="发布网址" prop="publishLink"> <el-form-item label="审批意见" prop="tf_opinion"
<el-input v-model="formData.publishLink" placeholder="请输入网址" clearable></el-input> :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row type="flex" justify="end"> <el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button> <el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button type="danger" @click="doApproval('BACK_TO_START')">退回到投稿</el-button> <el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起</el-button>
<el-button type="danger" @click="doApproval('BACK_TO_UNION')" <el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
v-if="currentRow.origin === 'ARTICLE_ORIGIN_UNION'">退回到分工会 <el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-button>
<el-button type="danger" @click="doApproval('BACK_TO_CLUB')"
v-if="currentRow.origin === 'ARTICLE_ORIGIN_CLUB'">退回到协会
</el-button>
<el-button type="danger" @click="doApproval('REJECT')">拒绝发布</el-button>
<el-button type="primary" @click="doApproval('PASS')">同意发布</el-button>
</el-row> </el-row>
</div> </div>
</article-info>
</template> </template>
</guava> </guava>
</div> </div>
@@ -104,88 +88,68 @@ layout("/layouts/platform.html"){
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
dicts: ["ARTICLE_ORIGIN"], components: {
components: { info }, "article-info": ARTICLE_INFO
},
data() { data() {
return { return {
pageForm: { pageForm: {
approval: false approval: false
}, },
showApprovalForm: false, showApprovalForm: false,
currentRow: {}
} }
}, },
methods: { methods: {
onOpen(id) { // 查看
openView(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.guava.public(() => { this.$refs.articleInfoRef.onOpen(row)
this.$refs.infoRef.onOpen(id)
}) })
}, },
openApproval(row) {
this.$refs.guava.public(() => { // 审核
this.currentRow = row openAudit(row) {
this.$refs.infoRef.onOpen(row.id) this.$refs.guava.edit(()=>{
this.formData = row.approvalParam
this.showApprovalForm = true this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.articleInfoRef.onOpen(row)
}) })
}, },
// 动态审核 // 提交
doApproval(result) { handleTaskAction(val) {
this.formData.bpmTaskApprovalType = "DYNAMIC" this.$confirm("您确定要提交吗?", "提示", {
if (result === 'BACK_TO_START') { confirmButtonText: "确定",
this.$confirm('请确认投稿人重新提交后是否需要重新走审批流程?', '提示', { cancelButtonText: "取消",
distinguishCancelAndClose: true, type: "warning"
confirmButtonText: '需要',
cancelButtonText: '不需要',
type: 'warning'
}).then(() => { }).then(() => {
this.submitApproval(result, true); this.$axios.post("/flow/common/executeTask", {
}).catch((action) => { data: JSON.stringify({
if (action === 'cancel') { ...this.formData,
this.submitApproval(result, false); submitType: val
}
}) })
} else { }).then((res) => {
this.submitApproval(result, false);
}
},
submitApproval(result, processAgain) {
this.$refs.approvalFormRef.validate((valid) => {
if (valid) {
if(result==="PASS" && (!this.formData.publishLink || this.formData.publishLink.length === 0)){
this.$message.warning("同意发布请填写发布网址")
return
}
this.$axios
.post("/platform/article/examine/approval", {
approval: JSON.stringify(this.formData),
result: result,
processAgain: processAgain,
publishLink: this.formData.publishLink
})
.then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index(); this.$refs.guava.index()
this.$message.success(res.msg); this.$message.success(res.msg)
this.doSearch(); this.doSearch()
} }
}); })
} })
});
}, },
// 撤回
openRevoke(taskId) { onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post("/platform/article/clubApproval/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -193,10 +157,9 @@ layout("/layouts/platform.html"){
}) })
}) })
} }
}, },
created() { created() {
this.$businessTool.listUnit().then((res) => (this.unitOptions = res))
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
this.pageData() this.pageData()
} }
}) })
@@ -36,16 +36,13 @@ layout("/layouts/platform.html"){
<el-table-column label="操作" fixed="right" width="300px"> <el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="onOpen(row.id)" size="mini" type="primary">查看</el-button> <el-button @click="onOpen(row.id)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskKey === 'apply' || !row.instanceId" @click="onEdit(row)" size="mini" <el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onEdit(row)"
type="primary"> size="mini" type="primary">编辑
编辑
</el-button> </el-button>
<el-button v-if="['waiting'].includes(row.flow_status)" size="mini" type="danger" <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
@click="onRevoke(row.id)">撤销
</el-button> </el-button>
<el-button v-if="row.taskKey === 'apply' || !row.instanceId" <el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)"
@click="onDelete(row.id)" size="mini" type="danger"> size="mini" type="danger">删除
删除
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -54,7 +51,7 @@ layout("/layouts/platform.html"){
</el-card> </el-card>
<template #view> <template #view>
<info ref="infoRef"></info> <article-info ref="infoRef"></article-info>
</template> </template>
</guava> </guava>
</div> </div>
@@ -66,49 +63,46 @@ layout("/layouts/platform.html"){
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: { info }, components: {
"article-info": ARTICLE_INFO
},
data() { data() {
return {} return {}
}, },
methods: { methods: {
// 查看
onOpen(id) { onOpen(id) {
this.$refs.guava.view(() => { this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(id) this.$refs.infoRef.onOpen(id)
}) })
}, },
// 编辑
onEdit(row) { onEdit(row) {
window.open("/flow/common/approval/form?taskId=" + (row.taskId || "") + "&instanceId=" + (row.instanceId || "") + "&businessId=" + row.id window.location.href = '/platform/article/write?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id
+ "&defineKey=XWTG")
// $.pjax({
// url: "/platform/article/write?id=" + businessNo + "&taskId=" + taskId + "&instanceId=" + instanceId,
// container: "#sub-app-container-main-content",
// maxCacheLength: 0,
// push: false,
// replace: true,
// fragment: "#sub-app-container-main-content",
// timeout: 8000
// })
}, },
onRevoke(id) { // 撤回
this.$confirm("您确定要撤销申请吗?", "提示", { onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(() => { }).then(() => {
this.$axios.post("/platform/article/write/revokeApply", { id }).then((resp) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((res) => {
this.$message.success(resp.msg) if (res.code === 0) {
this.doSearch() this.$message.success(res.msg)
this.pageData()
}
}) })
}) })
}, },
// 删除
onDelete(id) { onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", { this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(() => { }).then(() => {
this.$axios.post("/platform/article/mine/delete", { id: id }).then((res) => { this.$axios.post("/platform/article/mine/delete", {id: id}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.doSearch() this.doSearch()
this.$message.success(res.msg) this.$message.success(res.msg)
@@ -48,10 +48,9 @@ layout("/layouts/platform.html"){
<el-table-column prop="origin" label="投稿来源"> <el-table-column prop="origin" label="投稿来源">
<template slot-scope="{row}">{{dict.type.ARTICLE_ORIGIN.find(v=>v.code===row.origin)?.label}}</template> <template slot-scope="{row}">{{dict.type.ARTICLE_ORIGIN.find(v=>v.code===row.origin)?.label}}</template>
</el-table-column> </el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="100px"> <el-table-column label="操作" fixed="right" width="100px">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="onOpen(row.id)" size="mini" type="primary">查看</el-button> <el-button @click="onOpen(row)" size="mini" type="primary">查看</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -59,7 +58,7 @@ layout("/layouts/platform.html"){
</el-card> </el-card>
<template #public> <template #public>
<info ref="infoRef"></info> <article-info ref="articleInfoRef"></article-info>
</template> </template>
</guava> </guava>
</div> </div>
@@ -72,7 +71,9 @@ layout("/layouts/platform.html"){
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
dicts: ["ARTICLE_ORIGIN"], dicts: ["ARTICLE_ORIGIN"],
components: { info }, components: {
"article-info": ARTICLE_INFO
},
data() { data() {
return { return {
pageForm: { pageForm: {
@@ -84,9 +85,9 @@ layout("/layouts/platform.html"){
} }
}, },
methods: { methods: {
onOpen(id) { onOpen(row) {
this.$refs.guava.public(() => { this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(id) this.$refs.articleInfoRef.onOpen(row)
}) })
} }
}, },
@@ -36,7 +36,7 @@ layout("/layouts/platform.html"){
<el-table-column prop="unitName" label="投稿人单位"></el-table-column> <el-table-column prop="unitName" label="投稿人单位"></el-table-column>
<el-table-column prop="unionName" label="投稿人工会"></el-table-column> <el-table-column prop="unionName" label="投稿人工会"></el-table-column>
<el-table-column prop="submitTime" label="投稿时间"></el-table-column> <el-table-column prop="submitTime" label="投稿时间"></el-table-column>
<el-table-column prop="taskName" label="当前节点"></el-table-column> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态"> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}"> <template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" <enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
@@ -45,17 +45,10 @@ layout("/layouts/platform.html"){
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200px" fixed="right"> <el-table-column label="操作" width="200px" fixed="right">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="onOpen(row.id)" size="mini" type="primary">查看</el-button> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary"> <el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
审核
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -63,27 +56,27 @@ layout("/layouts/platform.html"){
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<el-dialog title="" :visible.sync="showApprovalForm" width="90%"> <template #edit>
<info ref="infoRef"></info> <article-info ref="articleInfoRef">
<el-row type="flex">
<flow-form-button :task_id="taskId"></flow-form-button>
<!-- <el-button plain @click="$refs.guava.index()">取消</el-button>-->
<!-- <el-button type="danger" @click="doApproval('BACK')">退回修改</el-button>-->
<!-- <el-button type="primary" @click="doApproval('PASS')">同意</el-button>-->
</el-row>
</el-dialog>
<template #public>
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<el-row type="flex"> <div class="process-title">
<flow-form-button :task_id="taskId"></flow-form-button> {{formData.taskName}}
</div>
<!-- <el-button plain @click="$refs.guava.index()">取消</el-button>--> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
<!-- <el-button type="danger" @click="doApproval('BACK')">退回修改</el-button>--> class="flow-task-form">
<!-- <el-button type="primary" @click="doApproval('PASS')">同意</el-button>--> <el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</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(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
</el-row> </el-row>
</div> </div>
</article-info>
</template> </template>
</guava> </guava>
</div> </div>
@@ -95,51 +88,68 @@ layout("/layouts/platform.html"){
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: { info }, components: {
"article-info": ARTICLE_INFO
},
data() { data() {
return { return {
pageForm: { pageForm: {
approval: false approval: false
}, },
showApprovalForm: false, showApprovalForm: false,
taskId: ""
} }
}, },
methods: { methods: {
onOpen(id) { // 查看
this.$refs.guava.public(() => { openView(row) {
this.$refs.infoRef.onOpen(id) this.$refs.guava.edit(()=>{
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.articleInfoRef.onOpen(row)
}) })
}, },
openApproval(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo) // 审核
}, openAudit(row) {
doApproval(approvalType) { this.$refs.guava.edit(()=>{
this.formData.bpmTaskApprovalType = approvalType this.showApprovalForm = true
this.$refs.approvalFormRef.validate((valid) => { this.formData = {
if (valid) { processTaskId: row.taskId,
this.$axios taskName: row.curTaskName
.post("/platform/article/branchUnionApproval/approval", { }
approval: JSON.stringify(this.formData) this.$refs.articleInfoRef.onOpen(row)
}) })
.then((res) => { },
// 提交
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index() this.$refs.guava.index()
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
} }
}) })
}
}) })
}, },
openRevoke(taskId) {
// 撤回
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post("/platform/article/branchUnionApproval/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -147,6 +157,7 @@ layout("/layouts/platform.html"){
}) })
}) })
} }
}, },
created() { created() {
this.pageData() this.pageData()
@@ -64,8 +64,9 @@ layout("/layouts/platform.html"){
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row type="flex" justify="end"> <el-row type="flex" justify="end">
<el-button type="primary" plain @click="doSave">保存</el-button> <el-button type="primary" plain @click="onSave">保存</el-button>
<el-button type="primary" @click="doSubmit">提交</el-button> <el-button type="primary" @click="onSubmit" v-if="!taskId">提交</el-button>
<el-button type="primary" @click="onSubmitAgain" v-else>提交</el-button>
</el-row> </el-row>
</el-card> </el-card>
</div> </div>
@@ -85,9 +86,8 @@ layout("/layouts/platform.html"){
store, store,
data() { data() {
return { return {
id: GetQueryString("id"), bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"), taskId: GetQueryString("taskId"),
instanceId: GetQueryString("instanceId"),
formData: {}, formData: {},
formRules: { formRules: {
title: [{required: true, message: "必填", trigger: ["change", "blur"]}], title: [{required: true, message: "必填", trigger: ["change", "blur"]}],
@@ -102,7 +102,8 @@ layout("/layouts/platform.html"){
} }
}, },
methods: { methods: {
doSave() { // 保存
onSave() {
this.$refs.formRef.validateField(["title"], (errMsg) => { this.$refs.formRef.validateField(["title"], (errMsg) => {
if (errMsg) { if (errMsg) {
this.$message.warning("请填写标题") this.$message.warning("请填写标题")
@@ -117,7 +118,9 @@ layout("/layouts/platform.html"){
}) })
}) })
}, },
doSubmit() {
// 提交
onSubmit() {
this.$refs.formRef.validate((valid) => { this.$refs.formRef.validate((valid) => {
if (valid) { if (valid) {
this.$axios.post("/platform/article/write/submit", { this.$axios.post("/platform/article/write/submit", {
@@ -134,6 +137,26 @@ layout("/layouts/platform.html"){
}) })
}, },
// 重新提交
onSubmitAgain() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/article/write/submitAgain', {
info: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/article/mine'
}
})
})
},
checkPermission() { checkPermission() {
this.$axios.post("/platform/article/write/checkPermission").then((res) => { this.$axios.post("/platform/article/write/checkPermission").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -143,8 +166,8 @@ layout("/layouts/platform.html"){
}, },
init() { init() {
if (this.id) { if (this.bizId) {
this.$axios.post("/platform/article/write/get", {id: this.id}).then((res) => { this.$axios.post("/platform/article/write/get", {id: this.bizId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.formData = res.data this.formData = res.data
} }
@@ -1,183 +0,0 @@
<div id="artile_write">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="2" border>
<el-descriptions-item label="投稿人姓名">{{formData.userName}}</el-descriptions-item>
<el-descriptions-item label="投稿人工号">{{formData.loginName}}</el-descriptions-item>
<el-descriptions-item label="投稿人单位">{{formData.unitName}}</el-descriptions-item>
<el-descriptions-item label="投稿人工会">{{formData.unionName}}</el-descriptions-item>
<el-descriptions-item label="投稿来源" :span="2">
<el-form-item prop="origin" label="投稿来源" label-width="0">
<el-radio-group v-model="formData.origin" size="small">
<el-radio border v-for="item in origins" :label="item.code" :key="item.code">{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="投稿人协会" v-if="formData.origin === 'ARTICLE_ORIGIN_CLUB'">
<el-form-item prop="clubId" label="投稿人协会" v-if="formData.origin === 'ARTICLE_ORIGIN_CLUB'">
<el-select v-model="formData.clubId" placeholder="请选择" style="width: 100%">
<el-option v-for="item in permission?.clubs" :key="item.id" :label="item.clubName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="投稿人联系方式" :span="2">
<el-form-item prop="title" label="投稿标题">
<el-input v-model="formData.title" maxlength="100" show-word-limit placeholder="请输入标题"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="投稿人联系方式" :span="2">
<el-form-item prop="mobile" label="投稿人联系方式">
<el-input v-model="formData.mobile" placeholder="请输入投稿人联系方式"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="修改人联系方式" :span="2">
<el-form-item prop="mobile2" label="修改人联系方式">
<el-input v-model="formData.mobile2" placeholder="请输入修改人联系方式"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="投稿说明" :span="2">
<el-form-item prop="excerpt" label="投稿说明">
<el-input v-model="formData.excerpt" type="textarea" maxlength="500" show-word-limit placeholder="请输入投稿说明"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="稿件" :span="2">
<file-upload
:value.sync="formData.files"
:upload_number="5"
upload_result_category="array"
complete_result
upload_mode="drag"
></file-upload>
</el-descriptions-item>
</el-descriptions>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @save-draft="handleSaveDraft" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#artile_write",
store,
dicts: ["ARTICLE_ORIGIN"],
computed: {
origins() {
if (this.dict?.type?.ARTICLE_ORIGIN && this.permission && this.permission.roles) {
return this.dict.type.ARTICLE_ORIGIN.filter((item) => this.permission && this.permission.roles.includes(item.code))
}
return []
}
},
data() {
return {
id: GetQueryString("businessId"),
taskId: GetQueryString("taskId"),
instanceId: GetQueryString("instanceId"),
formData: {},
formRules: {
title: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
excerpt: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
clubId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
files: [{ required: false, message: "必填", trigger: ["change", "blur"] }],
origin: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
mobile: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
mobile2: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
permission: {}
}
},
methods: {
init() {
if (this.id) {
this.$axios.post("/platform/article/write/get", { id: this.id }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
} else {
const { username, loginname, id, unit, union, mobile } = this.$store.state.user
this.formData = {
userName: username,
loginName: loginname,
userId: id,
unitId: unit?.id,
unitName: unit?.name,
unionId: union?.id,
unionName: union?.name,
mobile: mobile,
mobile2: mobile
}
}
},
checkPermission() {
this.$axios.post("/platform/article/write/checkPermission").then((res) => {
if (res.code === 0) {
this.permission = res.data
}
})
},
handleTaskAction(val) {
console.log(val)
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios
.post("/flow/common/startInstanceAndExecute", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.parent.postMessage(
{
type: "task-complete"
},
"*"
)
}
})
}
})
},
handleSaveDraft() {
this.$message.success("保存成功")
this.$refs.formRef.validateField(["title"], (errMsg) => {
if (errMsg) {
this.$message.warning("请填写标题")
return
}
this.$axios
.post("/flow/common/startInstance", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.parent.postMessage(
{
type: "task-complete"
},
"*"
)
}
})
})
},
handleCancel() {}
},
created() {
this.init()
this.checkPermission()
}
})
</script>
@@ -1,6 +1,6 @@
const basicForm = { const basicForm = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<el-dialog :visible.sync="dialogVisible" title="基础设置"> <el-dialog :visible.sync="dialogVisible" title="基础设置" width="70%">
<div style="overflow-y: auto"> <div style="overflow-y: auto">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="150px"> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="150px">
<el-form-item label="类型" prop="category"> <el-form-item label="类型" prop="category">
@@ -198,7 +198,7 @@ const basicForm = {
`, `,
dicts: ["ACTIVITY_QSV_CATEGORY", "ACTIVITY_QSV_MODE", "ACTIVITY_QSV_REPEAT_MODE", "ACTIVITY_QSV_SCORE_MODE"], dicts: ["ACTIVITY_QSV_CATEGORY", "ACTIVITY_QSV_MODE", "ACTIVITY_QSV_REPEAT_MODE", "ACTIVITY_QSV_SCORE_MODE"],
components: { components: {
"drawer-user-scope": httpVueLoader("/components/plugins/DrawerUserScope.vue") "drawer-user-scope": httpVueLoader("/components/module/activity/DrawerUserScope.vue")
}, },
data() { data() {
return { return {
@@ -31,8 +31,9 @@ layout("/layouts/platform.html"){
</el-table-column> </el-table-column>
<el-table-column label="开始时间" prop="startTime" sortable></el-table-column> <el-table-column label="开始时间" prop="startTime" sortable></el-table-column>
<el-table-column label="结束时间" prop="endTime" sortable></el-table-column> <el-table-column label="结束时间" prop="endTime" sortable></el-table-column>
<el-table-column label="操作" fixed="right" width="300px"> <el-table-column label="操作" fixed="right" width="450px">
<template scope="{row}"> <template scope="{row}">
<el-button size="mini" type="primary" @click="openQrCode(row.id)">二维码</el-button>
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button> <el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
<el-button size="mini" type="primary" @click="openSubject(row.id)">题目设置</el-button> <el-button size="mini" type="primary" @click="openSubject(row.id)">题目设置</el-button>
<el-button size="mini" type="danger" @click="onDelete(row.id)">删除</el-button> <el-button size="mini" type="danger" @click="onDelete(row.id)">删除</el-button>
@@ -48,6 +49,9 @@ layout("/layouts/platform.html"){
</guava> </guava>
<basic-form ref="basicFormRef" @refresh="pageData"></basic-form> <basic-form ref="basicFormRef" @refresh="pageData"></basic-form>
<qr-code-plus :url="signatureAddress" ref="qrCodePlusRef"></qr-code-plus>
</div> </div>
<script> <script>
@@ -62,19 +66,30 @@ layout("/layouts/platform.html"){
"subject-form": subjectForm "subject-form": subjectForm
}, },
data() { data() {
return {} return {
signatureAddress: ''
}
}, },
methods: { methods: {
// 编辑
openEdit(row) { openEdit(row) {
this.$refs.basicFormRef.onOpen(row.id) this.$refs.basicFormRef.onOpen(row.id)
}, },
// 打开二维码
openQrCode(id) {
this.signatureAddress = '?id=' + id
this.$refs.qrCodePlusRef.openDialog()
},
// 题目设置
openSubject(id) { openSubject(id) {
this.$refs.guava.edit() this.$refs.guava.edit(() => {
this.$nextTick(() => {
this.$refs.subjectFormRef.onOpen(id) this.$refs.subjectFormRef.onOpen(id)
}) })
// this.$refs.subjectFormRef.onOpen(id)
}, },
// 删除
onDelete(id) { onDelete(id) {
this.$confirm("您确认删除吗, 是否继续?", "提示", { this.$confirm("您确认删除吗, 是否继续?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
@@ -46,8 +46,7 @@ const subjectForm = {
</div> </div>
<div v-if="subject.type === 'checkbox'"> <div v-if="subject.type === 'checkbox'">
最大选择数: 最大选择数:
<el-input-number v-model="subject.maxMulti" <el-input-number v-model="subject.maxMulti" placeholder="最多可选数量"></el-input-number>
placeholder="最多可选数量"></el-input>
</div> </div>
<!-- <el-input--> <!-- <el-input-->
<!-- v-model="subject.hint"--> <!-- v-model="subject.hint"-->
@@ -22,6 +22,7 @@ const txtImport = {
<p>B.选项B</p> <p>B.选项B</p>
<p>C.选项C</p> <p>C.选项C</p>
<p>D.选项D</p> <p>D.选项D</p>
<p style="margin-top: 10px;"><b>正确答案数量大于1时自动判断为多选题</b></p>
</div> </div>
</div> </div>
<el-button type="text" icon="el-icon-question" size="small">格式说明</el-button> <el-button type="text" icon="el-icon-question" size="small">格式说明</el-button>
@@ -34,17 +35,18 @@ const txtImport = {
v-model="inputText" v-model="inputText"
placeholder="请粘贴题目内容,支持格式如: placeholder="请粘贴题目内容,支持格式如:
1.单选题标题?(A) 1.在()中,中国工人阶级第一次以独立的姿志登上政治舞台。(A)
A.选项A A.五四运动
B.选项B B.五州运动
C.选项C C.二七罢工
D.选项D D.安源路矿工人大要工
2.多选题标题?(ABC) 2.充分调动广大职工群众的( ),积极投身全面推进强国建设、民族复兴的伟大事业。(ABC)
A.选项A A.积极性
B.选项B B.主动性
C.选项C C.创造性
D.选项D" D.创新性
E.先进性"
></textarea> ></textarea>
</div> </div>
<div class="txt-import-action-buttons"> <div class="txt-import-action-buttons">
@@ -1,4 +1,4 @@
const PROPOSAL_INFO_COMPONENT = { const PROPOSAL_INFO = {
name: "ProposalInfo", name: "ProposalInfo",
/*language=HTML*/ /*language=HTML*/
template: ` template: `
@@ -67,265 +67,119 @@ const PROPOSAL_INFO_COMPONENT = {
</el-table> </el-table>
</template> </template>
<div class="process-title">
附议人信息
</div>
<el-table :data="viewData.seconders" size="small">
<el-table-column label="姓名" prop="createVariable.userName"></el-table-column>
<el-table-column label="工号" prop="createVariable.loginName"></el-table-column>
<el-table-column label="单位" prop="createVariable.unitName" show-overflow-tooltip></el-table-column>
<el-table-column label="分工会" prop="createVariable.unionName" show-overflow-tooltip></el-table-column>
<el-table-column label="代表团" prop="createVariable.delegationName"></el-table-column>
<el-table-column label="邀请时间" prop="createdOn"></el-table-column>
<el-table-column label="附议时间" prop="endOn"></el-table-column>
<el-table-column label="附议结果" prop="extVariable.bpmTaskApprovalType">
<template slot-scope="{row}">
<span v-if="row.extVariable && row.extVariable.bpmTaskApprovalType">
<el-tag size="mini" type="success"
v-if="row.extVariable.bpmTaskApprovalType==='PASS'">同意</el-tag>
<el-tag size="mini" type="danger"
v-if="row.extVariable.bpmTaskApprovalType==='REJECT'">拒绝</el-tag>
</span>
</template>
</el-table-column>
<!-- <el-table-column label="签字" prop="extVariable.bpmTaskApprovalType">-->
<!-- <template slot-scope="{row}">-->
<!-- <el-image :src="row.extVariable.approvalSignature" v-if="row.extVariable && row.extVariable.approvalSignature"></el-image>-->
<!-- </template>-->
</el-table-column>
</el-table>
<div>
<div v-for="nodeTask in viewData.nodeTasks" :key="nodeTask.id">
<div class="process-title" v-if="nodeTask.nodeCode !== 20">
{{nodeTask.nodeName}}
</div>
<div v-if="nodeTask.nodeCode === 30">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id" style="margin-bottom: 10px">
<el-descriptions-item label="审核人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="审核结果">
<div v-if="task.extVariable">
<el-tag type="success" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'PASS'">同意
</el-tag>
<el-tag type="danger" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'BACK'">退回重新填写
</el-tag>
<el-tag type="danger" size="mini"
v-if="task.extVariable.bpmTaskApprovalType === 'REJECT'">建议撤销
</el-tag>
</div>
</el-descriptions-item>
<el-descriptions-item label="审核意见" :span="3">{{ task.extVariable.approvalOpinion}}
</el-descriptions-item>
<!-- <el-descriptions-item label="签字" :span="3">-->
<!-- <el-image :src="task.extVariable.approvalSignature"-->
<!-- v-if="task.extVariable && task.extVariable.approvalSignature"-->
<!-- class="signature-image"></el-image>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
</div>
<div v-if="nodeTask.nodeCode === 60">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id">
<el-descriptions-item label="审核人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="审核结果">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="task.extVariable.caseFilingResult">
</dict-tag>
</el-descriptions-item>
<template
v-if="task.extVariable.caseFilingResult!=='NOT' && task.extVariable.caseFilingResult!==''">
<el-descriptions-item label="主办单位" :span="3">{{ task.extVariable.hostUnit}}
</el-descriptions-item>
<el-descriptions-item label="协办单位" :span="3">{{
task.extVariable.helpUnits.join(',')}}
</el-descriptions-item>
</template>
<el-descriptions-item label="审核意见" :span="3">{{ task.extVariable.approvalOpinion}}
</el-descriptions-item>
<!-- <el-descriptions-item label="签字">-->
<!-- <el-image :src="task.extVariable.approvalSignature"-->
<!-- v-if="task.extVariable && task.extVariable.approvalSignature"-->
<!-- class="signature-image"></el-image>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
</div>
<div v-if="nodeTask.nodeCode === 63">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id" style="margin-bottom: 10px">
<el-descriptions-item label="承办单位">
{{ task.createVariable.underTakeName}}
({{ task.createVariable.isMaster ? '主办' : '协办'}})
</el-descriptions-item>
<el-descriptions-item label="审核人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="能否承办" :span="3">
{{task.extVariable.canTake}}
</el-descriptions-item>
<el-descriptions-item label="审核意见" :span="3">{{ task.extVariable.approvalOpinion}}
</el-descriptions-item>
</el-descriptions>
</div>
<div v-if="nodeTask.nodeCode === 70">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id" style="margin-bottom: 10px;">
<el-descriptions-item label="审核人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="审核结果">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="task.extVariable.caseFilingResult">
</dict-tag>
</el-descriptions-item>
<template
v-if="task.extVariable.caseFilingResult!=='NOT' && task.extVariable.caseFilingResult!==''">
<el-descriptions-item label="主办单位" :span="3">{{ task.extVariable.hostUnit}}
</el-descriptions-item>
<el-descriptions-item label="协办单位" :span="3">{{
task.extVariable.helpUnits.join(',')}}
</el-descriptions-item>
</template>
<el-descriptions-item label="审核意见" :span="3">{{ task.extVariable.approvalOpinion}}
</el-descriptions-item>
<!-- <el-descriptions-item label="签字">-->
<!-- <el-image :src="task.extVariable.approvalSignature"-->
<!-- v-if="task.extVariable && task.extVariable.approvalSignature"-->
<!-- class="signature-image"></el-image>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
</div>
<div v-if="nodeTask.nodeCode === 80">
<el-descriptions :column="3" border v-if="!hide_slave" v-for="task in nodeTask.tasks"
:key="task.id" style="margin-bottom: 10px">
<el-descriptions-item label="承办单位">
<span class="text-primary">
{{ task.createVariable.underTakeName}}
({{ task.createVariable.isMaster ? '主办' : '协办'}})
</span>
</el-descriptions-item>
<el-descriptions-item label="答复人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="答复时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="答复内容" :span="3">
<div v-html="task.extVariable.approvalOpinion"></div>
</el-descriptions-item>
</el-descriptions>
<el-descriptions :column="3" border v-if="hide_slave"
v-for="task in nodeTask.tasks.filter(v=>v.createVariable?.isMaster == true)"
:key="task.id" style="margin-bottom: 10px">
<el-descriptions-item label="承办单位">
<span class="text-primary">
{{ task.createVariable.underTakeName}}
({{ task.createVariable.isMaster ? '主办' : '协办'}})
</span>
</el-descriptions-item>
<el-descriptions-item label="答复人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="答复时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="答复内容" :span="3">
<div v-html="task.extVariable.approvalOpinion"></div>
</el-descriptions-item>
</el-descriptions>
</div>
<div v-if="nodeTask.nodeCode === 90">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id" style="margin-bottom: 10px;">
<el-descriptions-item label="承办单位">
{{ task.createVariable.underTakeName}}
({{ task.createVariable.isMaster ? '主办' : '协办'}})
</el-descriptions-item>
<el-descriptions-item label="校领导">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="审批时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="审批结果" :span="3">
<el-tag size="mini" type="success" v-if="task.extVariable.bpmTaskApprovalType==='PASS'">
同意
</el-tag>
<el-tag size="mini" type="danger"
v-if="task.extVariable.bpmTaskApprovalType==='BACK_OTHER_NODE'">退回重新答复
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="审批意见" :span="3">
{{ task.extVariable.approvalOpinion}}
</el-descriptions-item>
<!-- <el-descriptions-item label="签字">-->
<!-- <el-image :src="task.extVariable.approvalSignature"-->
<!-- v-if="task.extVariable && task.extVariable.approvalSignature"-->
<!-- class="signature-image"></el-image>-->
<!-- </el-descriptions-item>-->
</el-descriptions>
</div>
<div v-if="nodeTask.nodeCode === 100">
<el-descriptions :column="3" border v-for="task in nodeTask.tasks" :key="task.id">
<el-descriptions-item label="反馈人">{{ task.actualOwnerLoginName + '-' +
task.actualOwnerUserName}}
</el-descriptions-item>
<el-descriptions-item label="反馈时间">{{ task.endOn}}</el-descriptions-item>
<el-descriptions-item label="反馈结果">{{ task.extVariable.feedBackScore}}
</el-descriptions-item>
<el-descriptions-item label="反馈意见" :span="3">{{ task.extVariable.approvalOpinion}}
</el-descriptions-item>
<!-- <el-descriptions-item label="签字">-->
<!-- <el-image :src="task.extVariable.approvalSignature"-->
<!-- v-if="task.extVariable && task.extVariable.approvalSignature"-->
<!-- class="signature-image"></el-image>-->
<!-- </el-descriptions-item> -->
</el-descriptions>
</div>
</div>
</div>
<el-dialog title="提案详情" :visible.sync="viewDialogVisible" width="1200px" append-to-body top="5vh"> <el-dialog title="提案详情" :visible.sync="viewDialogVisible" width="1200px" append-to-body top="5vh">
<div style="max-height: 80vh;overflow-y: auto"> <div style="max-height: 80vh;overflow-y: auto">
<proposal-info ref="infoDialogRef"></proposal-info> <proposal-info ref="infoDialogRef"></proposal-info>
</div> </div>
</el-dialog> </el-dialog>
</div>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<!--邀请附议人-->
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else-if="task.taskName === '85b7b9bd-d706-48cb-99a1-ef1370fb1819'">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</el-descriptions-item>
<el-descriptions-item label="办理时间" :span="2">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="附议人" :span="3" v-if="task.taskName === '85b7b9bd-d706-48cb-99a1-ef1370fb1819'">
<el-table :data="task?.taskFormData?.seconder">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
</el-table>
</el-descriptions-item>
</el-descriptions>
<!--提案委员会立案-->
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else-if="task.taskName === '9846ab38-40c5-4093-bafc-a9b3b443338b'">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="立案结果">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="task.ext.caseFilingResult"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="主办单位" :span="3">{{task.ext.tf_hostUnitName}}</el-descriptions-item>
<el-descriptions-item label="协办单位" :span="3">{{task?.ext?.tf_helpUnitNames.join('、')}}</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<slot></slot>
</div>
`, `,
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT"], dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT","PROCESS_TASK_SUBMIT_TYPE"],
props:{ props: {
hide_slave:false hide_slave: false
}, },
data() { data() {
return { return {
viewData: {}, viewData: {},
doneTasks: [],
row: null,
viewDialogVisible: false viewDialogVisible: false
} }
}, },
methods: { methods: {
onOpen(id) { // 打开
this.$axios.post("/platform/proposal/common/proposalInfo", { id }).then((res) => { onOpen(row) {
this.row = row
this.visible = true
this.getInfo()
this.getDoneTasks()
},
// 获取申请信息
getInfo() {
this.$axios.post("/platform/proposal/common/proposalInfo", {id: this.row.id}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.viewData = res.data this.viewData = res.data
} }
}) })
}, },
// 查看提案
openView(id) { openView(id) {
this.viewDialogVisible = true this.viewDialogVisible = true
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.infoDialogRef.onOpen(id) this.$refs.infoDialogRef.onOpen(id)
}) })
},
// 获取已办任务审批记录
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
} }
})
},
}, },
style: style:
/*language=CSS*/ /*language=CSS*/
` `
.proposal-info .el-descriptions__body .el-descriptions__table .el-descriptions-item__cell{ .proposal-info .el-descriptions__body .el-descriptions__table .el-descriptions-item__cell {
text-align: left;
} }
` `
} }
@@ -25,24 +25,24 @@ layout("/layouts/platform.html"){
<el-radio border :label="false"></el-radio> <el-radio border :label="false"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="协办单位是否首先答复" prop="slaveUnitFirstReply" v-if="formData.slaveUnitNeedReply"> <!-- <el-form-item label="协办单位是否首先答复" prop="slaveUnitFirstReply" v-if="formData.slaveUnitNeedReply">-->
<span slot="label"> <!-- <span slot="label">-->
协办单位是否首先答复 <!-- 协办单位是否首先答复-->
<el-tooltip content="开启后协办单位答复完成之后主办单位才可答复" placement="right"> <!-- <el-tooltip content="开启后协办单位答复完成之后主办单位才可答复" placement="right">-->
<i class="el-icon-question"></i> <!-- <i class="el-icon-question"></i>-->
</el-tooltip> <!-- </el-tooltip>-->
</span> <!-- </span>-->
<el-radio-group v-model="formData.slaveUnitFirstReply" size="small"> <!-- <el-radio-group v-model="formData.slaveUnitFirstReply" size="small">-->
<el-radio border :label="true"></el-radio> <!-- <el-radio border :label="true">是</el-radio>-->
<el-radio border :label="false"></el-radio> <!-- <el-radio border :label="false">否</el-radio>-->
</el-radio-group> <!-- </el-radio-group>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item label="协办单位领导单位是否需要审批" prop="slaveUnitLeaderNeedApprove"> <!-- <el-form-item label="协办单位领导单位是否需要审批" prop="slaveUnitLeaderNeedApprove">-->
<el-radio-group v-model="formData.slaveUnitLeaderNeedApprove" size="small"> <!-- <el-radio-group v-model="formData.slaveUnitLeaderNeedApprove" size="small">-->
<el-radio border :label="true"></el-radio> <!-- <el-radio border :label="true">是</el-radio>-->
<el-radio border :label="false"></el-radio> <!-- <el-radio border :label="false">否</el-radio>-->
</el-radio-group> <!-- </el-radio-group>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item label="撰写须知" prop="writeRemind"> <el-form-item label="撰写须知" prop="writeRemind">
<text-editor v-model="formData.writeRemind"></text-editor> <text-editor v-model="formData.writeRemind"></text-editor>
</el-form-item> </el-form-item>
@@ -2,17 +2,17 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<style></style> <div id="app">
<div id="app" v-cloak>
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="提案编号"> <search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input> <el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="提案名称"> <search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input> <el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="提案人姓名"> <search-item label="提案人姓名">
<el-input <el-input
@@ -33,8 +33,10 @@ layout("/layouts/platform.html"){
></el-input> ></el-input>
</search-item> </search-item>
<search-item label="教代会"> <search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId"> <el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option> v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select> </el-select>
</search-item> </search-item>
</search> </search>
@@ -42,52 +44,31 @@ layout("/layouts/platform.html"){
<el-card shadow="never"> <el-card shadow="never">
<table-tool> <table-tool>
<el-button @click="openConsolidationApproval" size="small" type="primary" class="mr5">并案审核</el-button> <el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-group v-model="pageForm.approval" @change="$refs.tableRef.clearSelection();doSearch()" size="small">
<el-radio-button :label="true">已审核</el-radio-button> <el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button> <el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group> </el-radio-group>
</table-tool> </table-tool>
<el-table <el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
:data="tableData"
ref="tableRef"
@sort-change="pageOrder"
header-align="center"
style="width: 100%"
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column type="selection" :selectable="(row)=>row.processInstanceTaskStatus==='ACTIVE'"></el-table-column>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column> <el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120" sortable></el-table-column> <el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column> <el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column> <el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName" show-overflow-tooltip></el-table-column> <el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult"> <el-table-column label="代表团" prop="delegationName"></el-table-column>
<template scope="{row}"> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100"> <el-table-column label="操作" fixed="right" width="300px">
<template scope="{row}"> <template slot-scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-tag size="mini" v-else type="danger"></el-tag> <el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</template>
</el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -95,11 +76,13 @@ layout("/layouts/platform.html"){
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #public> <template #edit>
<proposal-info ref="infoRef"></proposal-info> <proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div> <div class="process-title">
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px"> {{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules" label-suffix="">
<el-form-item label="立案结果" prop="caseFilingResult" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> <el-form-item label="立案结果" prop="caseFilingResult" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.caseFilingResult" size="small"> <el-radio-group v-model="formData.caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code" border>{{item.label}}</el-radio> <el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code" border>{{item.label}}</el-radio>
@@ -110,205 +93,102 @@ layout("/layouts/platform.html"){
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult)" v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult),message:'必填',trigger:['change','blur']}]" :rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult),message:'必填',trigger:['change','blur']}]"
> >
<el-select v-model="formData.hostUnitId" clearable filterable style="width: 100%"> <el-select v-model="formData.tf_hostUnitId" filterable clearable style="width: 100%">
<el-option <el-option
v-for="item in underTakeOptions" v-for="item in underTakeOptions"
:label="item.name" :label="item.name"
:value="item.id" :value="item.id"
:key="item.id" :key="item.id"
:disabled="formData && formData.helpUnitIds.includes(item.id)" :disabled="formData && formData.tf_helpUnitIds.includes(item.id)"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="协办单位" v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult)"> <el-form-item label="协办单位" v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.caseFilingResult)">
<el-select v-model="formData.helpUnitIds" clearable filterable multiple style="width: 100%"> <el-select v-model="formData.tf_helpUnitIds" filterable clearable multiple style="width: 100%">
<el-option <el-option
v-for="item in underTakeOptions" v-for="item in underTakeOptions"
:label="item.name" :label="item.name"
:value="item.id" :value="item.id"
:key="item.id" :key="item.id"
:disabled="item.id===formData.hostUnitId" :disabled="item.id===formData.tf_hostUnitId"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> <el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea> <user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
</el-form-item> </el-form-item>
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
</el-form> </el-form>
<el-row type="flex" justify="end"> <el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button> <el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button type="danger" @click="doApproval('BACK')">退回重新填写</el-button> <el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button type="primary" @click="doApproval('PASS')">提交</el-button> <el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row> </el-row>
</div> </div>
</proposal-info>
</template> </template>
<template #edit>
<div class="process-title">并案提案列表</div>
<el-table :data="consolidationProposalTableData" size="small">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120px" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" width="200px"></el-table-column>
<el-table-column label="代表团" prop="delegationName" width="300px"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" width="100px">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100px">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100px">
<template scope="{row}">
<el-link size="mini" type="primary" @click="openViewDialog(row)">查看</el-link>
</template>
</el-table-column>
</el-table>
<div class="process-title">{{consolidationFormData.processInstanceNodeName}}</div>
<el-form :model="consolidationFormData" ref="consolidationFormRef" label-position="left" label-width="80px">
<el-form-item label="立案结果" prop="caseFilingResult" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="consolidationFormData.caseFilingResult" size="small">
<el-radio v-for="item in dict.type.PROPOSAL_CASE_FILING_RESULT" :label="item.code" border>{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="主办单位"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(consolidationFormData.caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(consolidationFormData.caseFilingResult),message:'必填',trigger:['change','blur']}]"
>
<el-select v-model="consolidationFormData.hostUnitId" filterable clearable style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="consolidationFormData && consolidationFormData.helpUnitIds.includes(item.id)"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="协办单位" v-if="['CONFIRM_FILING','SUGGESTION'].includes(consolidationFormData.caseFilingResult)">
<el-select v-model="consolidationFormData.helpUnitIds" filterable clearable multiple style="width: 100%">
<el-option
v-for="item in underTakeOptions"
:label="item.name"
:value="item.id"
:key="item.id"
:disabled="item.id===consolidationFormData.hostUnitId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="consolidationFormData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<pc-signature v-model="consolidationFormData.approvalSignature"></pc-signature>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button>
<el-button type="primary" @click="doConsolidationApproval('PASS')">提交</el-button>
</el-row>
</template>
<el-dialog title="提案详情" :visible.sync="viewDialogVisible" width="1200px" top="50px" append-to-body>
<div style="max-height: 75vh; overflow-y: auto">
<proposal-info ref="infoDialogRef"></proposal-info>
</div>
</el-dialog>
</guava> </guava>
</div> </div>
<script> <script>
<!--#include("../../common/info.js"){}#--> <!--#include('../../common/info.js'){}#-->
const vue = new Vue({
new Vue({
el: "#app", el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
store, store,
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
mixins: [initTableMixins], mixins: [initTableMixins],
components: { components: {
"proposal-info": PROPOSAL_INFO_COMPONENT "proposal-info": PROPOSAL_INFO
}, },
data() { data() {
return { return {
sessionOptions: [],
delegationOptions: [],
underTakeOptions: [],
formData: {
hostUnitIds: null,
helpUnitId: []
},
pageForm: { pageForm: {
approval: false approval: false
}, },
formData: {
tf_hostUnitId: null,
tf_helpUnitIds: []
},
showApprovalForm: false, showApprovalForm: false,
sessionOptions: [],
//并案的提案列表 delegationOptions: [],
consolidationProposalTableData: [], underTakeOptions: []
consolidationFormData: {},
viewDialogVisible: false
} }
}, },
methods: { methods: {
openView(row) { openView(row) {
this.$refs.guava.public(() => { this.$refs.guava.edit(() => {
this.$refs.infoRef.onOpen(row.id)
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
openApproval(row) { openAudit(row) {
this.$refs.guava.public(() => { this.$refs.guava.edit(() => {
this.$refs.infoRef.onOpen(row.id)
this.formData = row.approvalParam
this.$set(this.formData, "caseFilingResult", null)
this.$set(this.formData, "hostUnitId", null)
this.$set(this.formData, "helpUnitIds", [])
this.$set(this.formData, "helpUnitIds", [])
this.$set(this.formData, "approvalOpinion", null)
this.$set(this.formData, "proposalIds", [])
this.showApprovalForm = true this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_hostUnitId: null,
tf_helpUnitIds: []
}
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
doApproval(approvalType) {
if (approvalType === "PASS") {
this.formData.bpmTaskApprovalType = "DYNAMIC"
this.formData.proposalIds = [this.formData.processInstanceBusinessId]
this.$refs.approvalFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/approval", {
approval: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
} else if (approvalType === "BACK") {
if (!this.formData.approvalOpinion) {
this.$message.warning("请填写退回的审核意见")
return
}
this.formData.bpmTaskApprovalType = "DYNAMIC" handleTaskAction(val) {
this.$confirm("您确定要退回到提案人吗?", "提示", { this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "warning"
}).then(() => { }).then(() => {
this.$axios.post(loc() + "/approvalBack", this.formData).then((res) => { this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val,
tf_hostUnitName: this.formData.tf_hostUnitId ? this.underTakeOptions.find(v => v.id === this.formData.tf_hostUnitId)?.name : null,
tf_helpUnitNames: this.formData.tf_helpUnitIds.map(v => this.underTakeOptions.find(v2 => v2.id === v)?.name)
})
}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index() this.$refs.guava.index()
this.$message.success(res.msg) this.$message.success(res.msg)
@@ -316,15 +196,15 @@ layout("/layouts/platform.html"){
} }
}) })
}) })
}
}, },
openRevoke(taskId) {
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post(loc() + "/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -333,71 +213,23 @@ layout("/layouts/platform.html"){
}) })
}, },
//打开并案审核 // 教代会
openConsolidationApproval() {
const selection = this.$refs.tableRef.selection
if (selection.length < 2) {
this.$message.error("并案审核至少需要选择两条提案")
return
}
this.consolidationProposalTableData = selection
this.$refs.guava.edit()
this.consolidationFormData = selection[0].approvalParam
this.$set(this.consolidationFormData, "caseFilingResult", null)
this.$set(this.consolidationFormData, "hostUnitId", null)
this.$set(this.consolidationFormData, "helpUnitIds", [])
this.$set(this.consolidationFormData, "helpUnitIds", [])
this.$set(this.consolidationFormData, "approvalOpinion", null)
this.$set(
this.consolidationFormData,
"proposalIds",
selection.map((v) => v.id)
)
},
openViewDialog(row) {
this.viewDialogVisible = true
this.$nextTick(() => {
this.$refs.infoDialogRef.onOpen(row.id)
})
},
//并案审核
doConsolidationApproval() {
this.consolidationFormData.bpmTaskApprovalType = "DYNAMIC"
this.$refs.consolidationFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/approval", {
approval: JSON.stringify(this.consolidationFormData)
})
.then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$refs.tableRef.clearSelection()
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
//教代会change
async meetingChange(val) { async meetingChange(val) {
this.formData.delegationId = null this.formData.delegationId = null
this.formData.committeeId = null this.formData.committeeId = null
this.delegationOptions = await proposal.getDelegation(val) this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val) this.committeeOptions = await this.getInstitutions(val)
}, },
// 代表团
listDelegation() { listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => { this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.delegationOptions = res.data this.delegationOptions = res.data
} }
}) })
}, },
// 查询开启的教代会
listOpenSession() { listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -411,8 +243,9 @@ layout("/layouts/platform.html"){
}) })
}, },
// 查询承办单位
listUnderTake() { listUnderTake() {
this.$axios.post(loc() + "/listUnderTake").then((res) => { this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.underTakeOptions = res.data this.underTakeOptions = res.data
} }
@@ -420,12 +253,13 @@ layout("/layouts/platform.html"){
} }
}, },
created() { created() {
// this.pageData() this.pageData()
this.listUnderTake()
this.listOpenSession() this.listOpenSession()
this.listUnderTake()
} }
}) })
</script> </script>
<!--# <!--#
} }
#--> #-->
@@ -1,48 +0,0 @@
<div id="suggestion-box-apply-form" v-cloak>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#suggestion-box-apply-form",
store,
data() {
return {
businessId: GetQueryString("businessId"),
formData: {},
formRules: {}
}
},
methods: {
handleTaskAction(val) {
console.log(val)
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
},
handleCancel(val) {
console.log(val)
}
}
})
</script>
@@ -2,15 +2,17 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<guava ref="guava"> <div id="app">
<div id="app"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度"> <search-item label="提案名称">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker> <el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="标题"> <search-item label="教代会">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input> <el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item> </search-item>
</search> </search>
</el-card> </el-card>
@@ -32,49 +34,118 @@ layout("/layouts/platform.html"){
<el-table-column prop="curTaskName" label="当前节点"></el-table-column> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态"> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}"> <template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag> <enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" fixed="right" width="300px"> <el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</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>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div> </div>
</guava> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</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(20)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script> <script>
<!--#include('../../common/info.js'){}#-->
new Vue({ new Vue({
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() { data() {
return { return {
pageDataUrl: "/platform/proposal/delegation/pageData",
pageForm: { pageForm: {
approval: false approval: false
} },
showApprovalForm: false
} }
}, },
methods: { methods: {
openView(row) { openView(row) {
window.open( this.$refs.guava.edit(() => {
"/flow/common/approval/form?taskId=" + this.showApprovalForm = false
row.taskId + this.$refs.proposalInfoRef.onOpen(row)
"&instanceId=" + })
row.instanceId +
"&businessId=" +
row.businessNo +
"&sessionId=" +
row.sessionId
)
}, },
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
onRevoke(row) { onRevoke(row) {
console.log(row) this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
} }
}, },
created() { created() {
@@ -2,20 +2,17 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<style></style> <div id="app">
<div id="app" v-cloak>
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item>
<search-item label="提案名称"> <search-item label="提案名称">
<el-input <el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
v-model="pageForm.searchKeyword" style="width: 100%"></el-input>
placeholder="提案名称"
@keyup.enter.native="doSearch"
clearable
style="width: 100%"
></el-input>
</search-item> </search-item>
<search-item label="提案人姓名"> <search-item label="提案人姓名">
<el-input <el-input
@@ -36,158 +33,152 @@ layout("/layouts/platform.html"){
></el-input> ></el-input>
</search-item> </search-item>
<search-item label="教代会"> <search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId"> <el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option> v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select> </el-select>
</search-item> </search-item>
</search> </search>
</el-card> </el-card>
<el-card shadow="never"> <el-card shadow="never">
<table-tool> <table-tool>
<el-radio-group v-model="pageForm.approval" @change="doSearch" size="small"> <el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button> <el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button> <el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group> </el-radio-group>
</table-tool> </table-tool>
<el-table <el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
:data="tableData" <el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
@sort-change="pageOrder"
size="small"
header-align="center"
style="width: 100%"
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column label="序号" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code"></el-table-column> <el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column> <el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column> <el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column> <el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column> <el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult"> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<template scope="{row}"> <el-table-column prop="taskName" label="承办类型"></el-table-column>
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否并案" prop="isConsolidation"> <el-table-column label="操作" fixed="right" width="300px">
<template scope="{row}"> <template slot-scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-tag size="mini" v-else type="danger"></el-tag> <el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">答复
</template>
</el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName"></el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary">
反馈
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #public>
<proposal-info ref="infoRef"></proposal-info> <template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div> <div class="process-title">
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px"> {{formData.taskName}}
<el-form-item label="反馈评价" prop="feedBackScore" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> </div>
<el-radio-group v-model="formData.feedBackScore"> <el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules" label-suffix="">
<el-radio :label="item.code" border v-for="item in dict.type.PROPOSAL_FEEDBACK_UNIT" :key="item.code" size="small"> <el-form-item label="满意度" prop="tf_feedback" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
{{item.label}} <el-radio-group v-model="formData.tf_feedback" size="small">
</el-radio> <el-radio v-for="item in dict.type.PROPOSAL_FEEDBACK" :key="item.code" :label="item.code" border>{{item.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="反馈内容" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> <el-form-item label="审批意见" prop="tf_opinion"
<el-input type="textarea" v-model="formData.approvalOpinion" max="1000" :rows="5"></el-input> :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
</el-form-item> <user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<pc-signature v-model="formData.approvalSignature"></pc-signature>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-row type="flex" justify="end"> <el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button> <el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button type="primary" @click="doApproval('DYNAMIC')">提交</el-button> <el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row> </el-row>
</div> </div>
</proposal-info>
</template> </template>
</guava> </guava>
</div> </div>
<script> <script>
<!--#include("../../common/info.js"){}#--> <!--#include('../../common/info.js'){}#-->
new Vue({ new Vue({
el: "#app", el: "#app",
store, store,
dicts: ["PROPOSAL_FEEDBACK_UNIT", "PROPOSAL_CASE_FILING_RESULT"], dicts: ["PROPOSAL_FEEDBACK"],
mixins: [initTableMixins], mixins: [initTableMixins],
components: { components: {
"proposal-info": PROPOSAL_INFO_COMPONENT "proposal-info": PROPOSAL_INFO
}, },
data() { data() {
return { return {
pageForm: { pageForm: {
approval: false approval: false
}, },
formData: {},
showApprovalForm: false, showApprovalForm: false,
sessionOptions: [], sessionOptions: [],
delegationOptions: [] delegationOptions: [],
} }
}, },
methods: { methods: {
onOpen(row) { openView(row) {
this.$refs.guava.public(() => { this.$refs.guava.edit(() => {
this.$refs.infoRef.onOpen(row.id)
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
openAudit(row) {
openApproval(row) { this.$refs.guava.edit(() => {
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.formData = row.approvalParam
this.$set(this.formData, "implementState", null)
this.$set(this.formData, "approvalOpinion", null)
this.showApprovalForm = true this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskKey: row.taskKey,
taskName: row.taskName,
}
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
doApproval(approvalType) { handleTaskAction(val) {
this.formData.bpmTaskApprovalType = approvalType this.$confirm("您确定要提交吗?", "提示", {
this.$refs.approvalFormRef.validate((valid) => { confirmButtonText: "确定",
if (valid) { cancelButtonText: "取消",
this.$axios type: "warning"
.post(loc() + "/approval", { }).then(() => {
approval: JSON.stringify(this.formData) const formData = {
}) ...this.formData,
.then((res) => { submitType: val
}
// 不满意
if(this.formData.tf_feedback === 'DISSATISFIED'){
formData.tf_hostUnitId = "da59e22f2a744a128b4f71c037c8d32e"
}
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify(formData)
}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index() this.$refs.guava.index()
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
} }
}) })
}
}) })
}, },
openRevoke(taskId) { // 撤销
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post(loc() + "/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -196,19 +187,24 @@ layout("/layouts/platform.html"){
}) })
}, },
//教代会change // 教代会
async meetingChange(val) { async meetingChange(val) {
this.formData.delegationId = null this.formData.delegationId = null
this.formData.committeeId = null this.formData.committeeId = null
this.listDelegation() this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val)
}, },
// 代表团
listDelegation() { listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => { this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.delegationOptions = res.data this.delegationOptions = res.data
} }
}) })
}, },
// 查询开启的教代会
listOpenSession() { listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -220,16 +216,15 @@ layout("/layouts/platform.html"){
} }
} }
}) })
}, }
del() {},
openView(id) {}
}, },
created() { created() {
this.pageData()
this.listOpenSession() this.listOpenSession()
} }
}) })
</script> </script>
<!--# <!--#
} }
#--> #-->
@@ -28,30 +28,32 @@ layout("/layouts/platform.html"){
<el-table-column label="提案类别" prop="typeName"></el-table-column> <el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column> <el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column> <el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column> <el-table-column prop="taskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="400px"> <el-table-column label="操作" fixed="right" width="400px">
<template scope="{row}"> <template scope="{row}">
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button> <el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
<el-button v-if="[10,40,61].includes(row.processInstanceNodeCode)" size="mini" type="primary" @click="openEdit(row)"> <el-button v-if="row.taskKey === 'startTask' || !row.instanceId" size="mini" type="primary" @click="openEdit(row)">
编辑提案 编辑提案
</el-button> </el-button>
<el-button <el-button
size="mini" size="mini"
type="primary" type="primary"
@click="onOpenInviteSeconder(row)" @click="onOpenInviteSeconder(row)"
v-if="[10,20,40,61].includes(row.processInstanceNodeCode)" v-if="row.taskKey === '85b7b9bd-d706-48cb-99a1-ef1370fb1819' || row.taskKey === '74458b33-ad6e-46c4-b8d9-1aa897142b25'"
> >
邀请附议人 邀请附议人
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" size="mini" type="danger" @click="openRevoke(row)">
v-if="[20].includes(row.processInstanceNodeCode) && !row.nextTaskIsComplete"
size="mini"
type="danger"
@click="openRevoke(row)"
>
撤销 撤销
</el-button> </el-button>
<el-button v-if="[10,40,50,61].includes(row.processInstanceNodeCode)" size="mini" type="danger" @click="del(row.id)"> <!-- v-if="row.taskKey === 'startTask' || !row.instanceId"-->
<el-button size="mini" type="danger" @click="del(row.id)">
删除 删除
</el-button> </el-button>
</template> </template>
@@ -77,7 +79,7 @@ layout("/layouts/platform.html"){
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: { components: {
"proposal-info": PROPOSAL_INFO_COMPONENT, "proposal-info": PROPOSAL_INFO,
"invite-seconder": PROPOSAL_INVITE_SECONDER_COMPONENT "invite-seconder": PROPOSAL_INVITE_SECONDER_COMPONENT
}, },
data() { data() {
@@ -93,7 +95,7 @@ layout("/layouts/platform.html"){
}) })
}, },
openEdit(row) { openEdit(row) {
this.$store.dispatch("pjaxRoute", "/platform/proposal/write?id=" + row.id) window.location.href = '/platform/proposal/write?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id
}, },
openRevoke(row) { openRevoke(row) {
this.$confirm("您确定要撤销申请吗?", "提示", { this.$confirm("您确定要撤销申请吗?", "提示", {
@@ -121,8 +123,8 @@ layout("/layouts/platform.html"){
async meetingChange(val) { async meetingChange(val) {
this.formData.delegationId = null this.formData.delegationId = null
this.formData.committeeId = null this.formData.committeeId = null
this.delegationOptions = await proposal.getDelegation(val) //this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val) //this.committeeOptions = await this.getInstitutions(val)
}, },
listSession() { listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => { this.$axios.post("/platform/proposal/common/listSession").then((res) => {
@@ -69,7 +69,7 @@ const PROPOSAL_INVITE_SECONDER_COMPONENT = {
this.listDelegation() this.listDelegation()
this.pageData() this.pageData()
const { seconderNum } = this.config const {seconderNum} = this.config
this.$alert( this.$alert(
"1)请至少选择<span style='color: orange;font-weight: bold'>" + "1)请至少选择<span style='color: orange;font-weight: bold'>" +
seconderNum + seconderNum +
@@ -82,11 +82,13 @@ const PROPOSAL_INVITE_SECONDER_COMPONENT = {
type: "warning", type: "warning",
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
confirmButtonText: "确定", confirmButtonText: "确定",
callback: () => {} callback: () => {
}
} }
) )
}, },
detail(id) {}, detail(id) {
},
invite() { invite() {
const selection = this.$refs.tableRef.selection const selection = this.$refs.tableRef.selection
if (selection.length === 0) { if (selection.length === 0) {
@@ -100,12 +102,10 @@ const PROPOSAL_INVITE_SECONDER_COMPONENT = {
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios this.$axios.post("/platform/proposal/mine/inviteSeconder", {
.post("/platform/proposal/mine/inviteSeconder", {
proposalId: this.record.id, proposalId: this.record.id,
seconders: JSON.stringify(loginNames) seconders: JSON.stringify(loginNames)
}) }).then((res) => {
.then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.$refs.tableRef.clearSelection() this.$refs.tableRef.clearSelection()
@@ -133,7 +133,7 @@ const PROPOSAL_INVITE_SECONDER_COMPONENT = {
//查询代表团 //查询代表团
listDelegation() { listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.record.sessionId }).then((res) => { this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.record.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.delegationOptions = res.data this.delegationOptions = res.data
} }
@@ -141,7 +141,7 @@ const PROPOSAL_INVITE_SECONDER_COMPONENT = {
}, },
async getConfig() { async getConfig() {
const { code, data } = await this.$axios.post("/platform/proposal/common/config") const {code, data} = await this.$axios.post("/platform/proposal/common/config")
if (code === 0) { if (code === 0) {
this.config = data this.config = data
} }
@@ -2,23 +2,17 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<style></style> <div id="app">
<div id="app" v-cloak>
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="提案编号"> <search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input> <el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="提案名称"> <search-item label="提案名称">
<el-input <el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
v-model="pageForm.name" style="width: 100%"></el-input>
placeholder="提案名称"
@keyup.enter.native="doSearch"
clearable
style="width: 100%"
></el-input>
</search-item> </search-item>
<search-item label="提案人姓名"> <search-item label="提案人姓名">
<el-input <el-input
@@ -39,167 +33,150 @@ layout("/layouts/platform.html"){
></el-input> ></el-input>
</search-item> </search-item>
<search-item label="教代会"> <search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId"> <el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option> v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select> </el-select>
</search-item> </search-item>
</search> </search>
</el-card> </el-card>
<el-card shadow="never"> <el-card shadow="never">
<table-tool> <table-tool>
<el-radio-group v-model="pageForm.approval" @change="doSearch" size="small"> <el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button> <el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button> <el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group> </el-radio-group>
</table-tool> </table-tool>
<el-table <el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
:data="tableData"
@sort-change="pageOrder"
header-align="center"
style="width: 100%"
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column> <el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120" sortable></el-table-column> <el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column> <el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column> <el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column> <el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult"> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<template scope="{row}"> <el-table-column prop="taskName" label="承办类型"></el-table-column>
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100"> <el-table-column label="操作" fixed="right" width="300px">
<template scope="{row}"> <template slot-scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-tag size="mini" v-else type="danger"></el-tag> <el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核
</template>
</el-table-column>
<el-table-column label="是否主办" prop="isMasterUnderTake">
<template scope="{row}">
<el-tag v-if="row.isMasterUnderTake" size="mini" type="success"></el-tag>
<el-tag v-else size="mini" type="info"></el-tag>
</template>
</el-table-column>
<el-table-column label="承办单位" prop="underTakeName" show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button>
<el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary">
审核
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #public>
<proposal-info ref="infoRef" :hide_slave="true"></proposal-info> <template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div> <div class="process-title">
{{formData.taskName}}
<el-alert v-if="formData.isConsolidation" type="success" title="提醒:本提案已并案,您只需审批一次即可!"></el-alert> </div>
<el-divider></el-divider> <el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules" label-suffix="">
<el-form-item label="审批意见" prop="tf_opinion"
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px"> :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-form-item label="承办单位"> <user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
<el-input :value="formData.underTakeName" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="审批意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
</el-form-item>
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>-->
<!-- </el-form-item>-->
</el-form> </el-form>
<el-row type="flex" justify="end"> <el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button> <el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button type="danger" @click="doApproval('BACK_OTHER_NODE')">退回重新答复</el-button> <el-button @click="handleTaskAction(4)" size="small" type="danger">退回重新答复
<el-button type="primary" @click="doApproval('PASS')">同意</el-button> </el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意答复</el-button>
</el-row> </el-row>
</div> </div>
</proposal-info>
</template> </template>
</guava> </guava>
</div> </div>
<script> <script>
<!--#include("../../common/info.js"){}#--> <!--#include('../../common/info.js'){}#-->
const vue = new Vue({ new Vue({
el: "#app", el: "#app",
store, store,
dicts: ["PROPOSAL_CASE_FILING_RESULT"], dicts: ["PROPOSAL_CASE_FILING_RESULT"],
mixins: [initTableMixins], mixins: [initTableMixins],
components: { components: {
"proposal-info": PROPOSAL_INFO_COMPONENT "proposal-info": PROPOSAL_INFO
}, },
data() { data() {
return { return {
sessionOptions: [],
delegationOptions: [],
showApprovalForm: false,
pageForm: { pageForm: {
approval: false approval: false
} },
formData: {},
showApprovalForm: false,
sessionOptions: [],
delegationOptions: [],
} }
}, },
methods: { methods: {
onOpen(row) { openView(row) {
this.$refs.guava.public(() => { this.$refs.guava.edit(() => {
this.$refs.infoRef.onOpen(row.id)
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
openAudit(row) {
openApproval(row) { this.$refs.guava.edit(() => {
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.formData = row.approvalParam
this.$set(this.formData, "implementState", null)
this.$set(this.formData, "approvalOpinion", null)
this.formData.isConsolidation = row.isConsolidation
this.formData.underTakeName = row.underTakeName
this.formData.underTakeId = row.underTakeId
this.showApprovalForm = true this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskKey: row.taskKey,
taskName: row.taskName,
}
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
doApproval(approvalType) { handleTaskAction(val) {
this.formData.bpmTaskApprovalType = approvalType this.$confirm("您确定要提交吗?", "提示", {
this.$refs.approvalFormRef.validate((valid) => { confirmButtonText: "确定",
if (valid) { cancelButtonText: "取消",
this.$axios type: "warning"
.post(loc() + "/approval", { }).then(() => {
approval: JSON.stringify(this.formData) const formData = {
}) ...this.formData,
.then((res) => { submitType: val
}
// 退回
if(val === 4){
formData.taskName = "85cf23da-2dd5-4007-a1e9-bd9bfddc68f0"
formData.tf_hostUnitId = "da59e22f2a744a128b4f71c037c8d32e"
}
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify(formData)
}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index() this.$refs.guava.index()
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
} }
}) })
}
}) })
}, },
openRevoke(taskId) { // 撤销
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post(loc() + "/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -207,20 +184,25 @@ layout("/layouts/platform.html"){
}) })
}) })
}, },
//教代会change
// 教代会
async meetingChange(val) { async meetingChange(val) {
this.formData.delegationId = null this.formData.delegationId = null
this.formData.committeeId = null this.formData.committeeId = null
this.delegationOptions = await proposal.getDelegation(val) this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val) this.committeeOptions = await this.getInstitutions(val)
}, },
// 代表团
listDelegation() { listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => { this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.delegationOptions = res.data this.delegationOptions = res.data
} }
}) })
}, },
// 查询开启的教代会
listOpenSession() { listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -232,16 +214,15 @@ layout("/layouts/platform.html"){
} }
} }
}) })
}, }
del() {},
openView(id) {}
}, },
created() { created() {
this.pageData()
this.listOpenSession() this.listOpenSession()
} }
}) })
</script> </script>
<!--# <!--#
} }
#--> #-->
@@ -1,48 +0,0 @@
<div id="suggestion-box-apply-form" v-cloak>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#suggestion-box-apply-form",
store,
data() {
return {
businessId: GetQueryString("businessId"),
formData: {},
formRules: {}
}
},
methods: {
handleTaskAction(val) {
console.log(val)
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
},
handleCancel(val) {
console.log(val)
}
}
})
</script>
@@ -2,15 +2,17 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<guava ref="guava"> <div id="app">
<div id="app"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度"> <search-item label="提案名称">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker> <el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="标题"> <search-item label="教代会">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input> <el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item> </search-item>
</search> </search>
</el-card> </el-card>
@@ -32,49 +34,117 @@ layout("/layouts/platform.html"){
<el-table-column prop="curTaskName" label="当前节点"></el-table-column> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态"> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}"> <template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag> <enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" fixed="right" width="300px"> <el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</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>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div> </div>
</guava> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=""
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="handleTaskAction(20)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
</el-row>
</div>
</proposal-info>
</template>
</guava>
</div>
<script> <script>
<!--#include('../../common/info.js'){}#-->
new Vue({ new Vue({
el: "#app", el: "#app",
store, store,
mixins: [initTableMixins], mixins: [initTableMixins],
components: {
"proposal-info": PROPOSAL_INFO
},
data() { data() {
return { return {
pageDataUrl: "/platform/proposal/seconded/pageData",
pageForm: { pageForm: {
approval: false approval: false
} },
showApprovalForm: false
} }
}, },
methods: { methods: {
openView(row) { openView(row) {
window.open( this.$refs.guava.edit(() => {
"/flow/common/approval/form?taskId=" + this.showApprovalForm = false
row.taskId + this.$refs.proposalInfoRef.onOpen(row)
"&instanceId=" + })
row.instanceId +
"&businessId=" +
row.businessNo +
"&sessionId=" +
row.sessionId
)
}, },
openAudit(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
}
this.$refs.proposalInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
onRevoke(row) { onRevoke(row) {
console.log(row) this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
} }
}, },
created() { created() {
@@ -2,17 +2,17 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<style></style> <div id="app">
<div id="app" v-cloak>
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<search @search="doSearch"> <search @search="doSearch">
<search-item label="提案编号"> <search-item label="提案编号">
<el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input> <el-input v-model="pageForm.code" placeholder="提案编号" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="提案名称"> <search-item label="提案名称">
<el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable style="width: 100%"></el-input> <el-input v-model="pageForm.name" placeholder="提案名称" @keyup.enter.native="doSearch" clearable
style="width: 100%"></el-input>
</search-item> </search-item>
<search-item label="提案人姓名"> <search-item label="提案人姓名">
<el-input <el-input
@@ -33,261 +33,162 @@ layout("/layouts/platform.html"){
></el-input> ></el-input>
</search-item> </search-item>
<search-item label="教代会"> <search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId"> <el-select @change="meetingChange" clearable filterable placeholder="所属教代会"
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option> v-model="pageForm.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select> </el-select>
</search-item> </search-item>
</search> </search>
</el-card> </el-card>
<el-card shadow="never"> <el-card shadow="never">
<table-tool> <table-tool>
<el-radio-group v-model="pageForm.transfer" @change="doSearch" size="small" v-if="$auth.hasRole('PROPOSAL_UNIT_LEADER')"> <el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">转办</el-radio-button> <el-radio-button :label="true">审核</el-radio-button>
<el-radio-button :label="false">转办</el-radio-button> <el-radio-button :label="false">审核</el-radio-button>
</el-radio-group>
<el-radio-group v-model="pageForm.approval" @change="doSearch" size="small" v-if="!pageForm.transfer" class="ml5">
<el-radio-button :label="true">已答复</el-radio-button>
<el-radio-button :label="false">未答复</el-radio-button>
</el-radio-group> </el-radio-group>
</table-tool> </table-tool>
<el-table <el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
:data="tableData"
@sort-change="pageOrder"
header-align="center"
style="width: 100%"
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column> <el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120px" sortable></el-table-column> <el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column> <el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案" prop="createUserName"></el-table-column> <el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column> <el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult"> <el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<template scope="{row}"> <el-table-column prop="taskName" label="承办类型"></el-table-column>
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag> <el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100px">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success"></el-tag>
<el-tag size="mini" v-else type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column label="承办单位" prop="underTakeName" show-overflow-tooltip></el-table-column>
<el-table-column label="是否主办" prop="isMasterUnderTake" width="100px">
<template scope="{row}">
<el-tag v-if="row.isMasterUnderTake" size="mini" type="success"></el-tag>
<el-tag v-else size="mini" type="info"></el-tag>
</template>
</el-table-column>
<el-table-column label="转办答复人" prop="underTakeTransferUserName" v-if="$auth.hasRole('PROPOSAL_UNIT_LEADER')">
<template scope="{row}">
<span v-if="row.underTakeReplyIsTransfer">{{row.underTakeTransferUserName?.join('') || '-'}}</span>
</template>
</el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="300px"> <el-table-column label="操作" fixed="right" width="300px">
<template scope="{row}"> <template slot-scope="{row}">
<el-button size="mini" type="primary" @click="onOpen(row)">查看</el-button> <el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.processInstanceTaskStatus==='ACTIVE'" @click="openApproval(row)" size="mini" type="primary"> <el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">答复
答复
</el-button> </el-button>
<el-button <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
v-if="row.processInstanceTaskStatus==='ACTIVE' && $auth.hasRole('PROPOSAL_UNIT_LEADER')"
@click="openTransfer(row)"
size="mini"
type="primary"
>
转办答复
</el-button>
<el-button
v-if="row.processInstanceTaskStatus==='COMPLETE' && !row.nextTaskIsComplete"
@click="openRevoke(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回
</el-button>
<el-button
v-if="row.processInstanceTaskStatus==='TRANSFER' && !row.nextTransferTaskIsComplete"
@click="openRevokeTransfer(row.processInstanceTaskId)"
size="mini"
type="danger"
>
撤回转办
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--#include("/layouts/pagination.html"){}#--> <!--#include("/layouts/pagination.html"){}#-->
</el-card> </el-card>
<template #public>
<proposal-info ref="infoRef"></proposal-info> <template #edit>
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<div class="process-title">{{formData.processInstanceNodeName}}</div> <div class="process-title">
{{formData.taskName}}
<el-alert v-if="formData.isConsolidation" type="success" title="提醒:本提案已并案,您只需答复一次即可!"></el-alert> </div>
<el-divider></el-divider> <el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules" label-suffix="">
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
<el-form-item label="承办单位"> <el-form-item label="承办单位">
<el-input :value="formData.underTakeName" disabled></el-input> <el-input :value="formData.underTakeName" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="落实情况" prop="implementState" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> <!-- <el-form-item label="落实情况" prop="implementState" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">-->
<dict-select v-model="formData.implementState" code="PROPOSAL_REPLY_IMPLEMENT"></dict-select> <!-- <dict-select v-model="formData.implementState" code="PROPOSAL_REPLY_IMPLEMENT"></dict-select>-->
<!-- </el-form-item>-->
<el-form-item label="答复内容" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<text-editor v-model="formData.tf_opinion"></text-editor>
</el-form-item> </el-form-item>
<el-form-item label="答复内容" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> <el-form-item label="校领导" prop="tf_nextNodeOperator"
<text-editor v-model="formData.approvalOpinion"></text-editor> :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
</el-form-item> <el-select v-model="formData.tf_nextNodeOperator" placeholder="请选择校领导">
<!-- <el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">--> <el-option :key="item.id" :label="item.userName" :value="item.userId"
<!-- <pc-signature v-model="formData.approvalSignature"></pc-signature>--> v-for="item in candidates"></el-option>
<!-- </el-form-item>-->
</el-form>
<el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button>
<el-button type="primary" @click="doApproval('DYNAMIC')">提交</el-button>
</el-row>
</div>
</template>
<el-dialog title="转办答复" :visible.sync="transferDialogVisible" width="50%">
<el-form :model="transferFormData" ref="transferFormRef" label-position="left" label-width="80px">
<el-form-item label="提案名称">
<el-input :value="transferFormData.name" disabled></el-input>
</el-form-item>
<el-form-item label="转办人" prop="transferUserLoginName" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select
v-model="transferFormData.transferUserLoginName"
remote
:remote-method="queryTransferUser"
filterable
placeholder="可按姓名或工号搜索需要转办的用户"
style="width: 100%"
>
<el-option :key="item.id" :label="item.label" :value="item.loginname" v-for="item in transferUserOptions"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <el-row type="flex" justify="end">
<el-button plain @click="transferDialogVisible=false">取消</el-button> <el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button type="primary" @click="doTransfer">提交</el-button> <el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
</div> </div>
</el-dialog> </proposal-info>
</template>
</guava> </guava>
</div> </div>
<script> <script>
<!--#include("../../common/info.js"){}#--> <!--#include('../../common/info.js'){}#-->
new Vue({ new Vue({
el: "#app", el: "#app",
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
store, store,
dicts: ["PROPOSAL_CASE_FILING_RESULT"],
mixins: [initTableMixins], mixins: [initTableMixins],
components: { components: {
"proposal-info": PROPOSAL_INFO_COMPONENT "proposal-info": PROPOSAL_INFO
}, },
data() { data() {
return { return {
pageForm: {
approval: false
},
formData: {},
showApprovalForm: false,
sessionOptions: [], sessionOptions: [],
delegationOptions: [], delegationOptions: [],
pageForm: { candidates: [],
approval: false, supportCandidate: false
transfer: false
},
showApprovalForm: false,
transferFormData: {},
transferDialogVisible: false,
transferUserOptions: []
} }
}, },
methods: { methods: {
onOpen(row) { openView(row) {
this.$refs.guava.public(() => { this.$refs.guava.edit(() => {
this.$refs.infoRef.onOpen(row.id)
this.showApprovalForm = false this.showApprovalForm = false
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
openAudit(row) {
this.loadCandidates(row.taskId)
//检查能否答复
checkCanReply(taskId) {
return this.$axios.post(loc() + "/checkCanReply", { taskId })
},
openApproval(row) { this.$refs.guava.edit(() => {
this.checkCanReply(row.processInstanceTaskId).then((res) => {
if (res.code === 0) {
if (res.data && res.data.errMsg) {
this.$alert(res.data.errMsg, "提示", {
type: "warning",
dangerouslyUseHTMLString: true,
confirmButtonText: "已线下沟通,开始答复",
cancelButtonText: "关闭",
showCancelButton: true
})
.then(()=>{
this.$refs.guava.public(() => {
this.$refs.infoRef.onOpen(row.id)
this.formData = row.approvalParam
this.$set(this.formData, "implementState", null)
this.formData.isConsolidation = row.isConsolidation
this.formData.underTakeName = row.underTakeName
this.formData.underTakeId = row.underTakeId
this.showApprovalForm = true this.showApprovalForm = true
}) this.formData = {
}) processTaskId: row.taskId,
.catch() taskKey: row.taskKey,
} else { taskName: row.taskName,
this.$refs.guava.public(() => { hostUnitId: null,
this.$refs.infoRef.onOpen(row.id) helpUnitIds: []
this.formData = row.approvalParam
this.$set(this.formData, "implementState", null)
if(row.isMasterUnderTake){
this.$set(this.formData, "approvalOpinion", res.data.allSlaveApprovalOpinion)
}else{
this.$set(this.formData, "approvalOpinion", null)
}
if(res.data?.task?.endOn){
this.$set(this.formData, "approvalOpinion", res.data?.task?.extVariable?.approvalOpinion)
this.$set(this.formData, "implementState", res.data?.task?.extVariable?.implementState)
}
this.formData.isConsolidation = row.isConsolidation
this.formData.underTakeName = row.underTakeName
this.formData.underTakeId = row.underTakeId
this.showApprovalForm = true
})
}
} }
this.$refs.proposalInfoRef.onOpen(row)
}) })
}, },
doApproval(approvalType) { handleTaskAction(val) {
this.formData.bpmTaskApprovalType = approvalType this.$confirm("您确定要提交吗?", "提示", {
this.$refs.approvalFormRef.validate((valid) => { confirmButtonText: "确定",
if (valid) { cancelButtonText: "取消",
this.$axios type: "warning"
.post(loc() + "/approval", { }).then(() => {
approval: JSON.stringify(this.formData) this.$axios.post("/flow/common/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
}) })
.then((res) => { }).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$refs.guava.index() this.$refs.guava.index()
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
} }
}) })
}
}) })
}, },
openRevoke(taskId) { // 撤销
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", { this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "info" type: "info"
}).then(() => { }).then(() => {
this.$axios.post(loc() + "/revoke", { taskId }).then((res) => { this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.doSearch() this.doSearch()
@@ -296,98 +197,36 @@ layout("/layouts/platform.html"){
}) })
}, },
openRevokeTransfer(taskId) {
this.$confirm("您确定要撤回转办吗?", "提示", { // 加载候选人列表
confirmButtonText: "确定", loadCandidates(taskId) {
cancelButtonText: "取消", $.get("/flow/common/candidate", {taskId}).then((res) => {
type: "info"
}).then(() => {
this.$axios.post(loc() + "/revokeTransfer", { taskId }).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.candidates = res.data.candidates
this.doSearch() this.supportCandidate = res.data.support
}
})
})
},
//打开转办答复
openTransfer(row) {
// this.checkCanReply(row.processInstanceTaskId).then((res) => {
// if (res.code === 0) {
// if (res.data && res.data.errMsg) {
// this.$alert(res.data.errMsg, "提示", {
// type: "warning"
// })
// .then()
// .catch()
// } else {
// this.transferFormData = {
// name: row.name,
// proposalId: row.id,
// underTakeId: row.underTakeId,
// processInstanceId: row.processInstanceId,
// processInstanceTaskId: row.processInstanceTaskId,
// transferUserLoginName: null
// }
// this.transferDialogVisible = true
// }
// }
// })
this.transferFormData = {
name: row.name,
proposalId: row.id,
underTakeId: row.underTakeId,
processInstanceId: row.processInstanceId,
processInstanceTaskId: row.processInstanceTaskId,
transferUserLoginName: null
}
this.transferDialogVisible = true
},
//搜索转办人
queryTransferUser(keyword) {
if (keyword) {
this.$axios.post(loc() + "/queryTransferUser", { keyword }).then((res) => {
if (res.code === 0) {
this.transferUserOptions = res.data
}
})
}
},
doTransfer() {
this.$refs.transferFormRef.validate((valid) => {
if (valid) {
this.$axios
.post(loc() + "/transfer", {
transfer: JSON.stringify(this.transferFormData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.transferDialogVisible = false
this.doSearch()
}
})
} }
}) })
}, },
//教代会change
// 教代会
async meetingChange(val) { async meetingChange(val) {
this.formData.delegationId = null this.formData.delegationId = null
this.formData.committeeId = null this.formData.committeeId = null
this.delegationOptions = await proposal.getDelegation(val) this.delegationOptions = await proposal.getDelegation(val)
this.committeeOptions = await this.getInstitutions(val) this.committeeOptions = await this.getInstitutions(val)
}, },
// 代表团
listDelegation() { listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => { this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.pageForm.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.delegationOptions = res.data this.delegationOptions = res.data
} }
}) })
}, },
// 查询开启的教代会
listOpenSession() { listOpenSession() {
this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -399,16 +238,15 @@ layout("/layouts/platform.html"){
} }
} }
}) })
}, }
del() {},
openView(id) {}
}, },
created() { created() {
this.pageData()
this.listOpenSession() this.listOpenSession()
} }
}) })
</script> </script>
<!--# <!--#
} }
#--> #-->
@@ -34,21 +34,26 @@ layout("/layouts/platform.html"){
v-model="formData.sessionId" v-model="formData.sessionId"
style="width: 100%" style="width: 100%"
> >
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option> <el-option :key="item.id" :label="item.fullName" :value="item.id"
v-for="item in sessionOptions"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="所属代表团" prop="delegationId"> <el-form-item label="所属代表团" prop="delegationId">
<el-select clearable filterable placeholder="所属代表团" v-model="formData.delegationId" style="width: 100%" disabled> <el-select clearable filterable placeholder="所属代表团" v-model="formData.delegationId"
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option> style="width: 100%" disabled>
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="所属委员会" prop="committeeId" v-if="formData.mannerCode=='W03'"> <el-form-item label="所属委员会" prop="committeeId" v-if="formData.mannerCode=='W03'">
<el-select clearable filterable placeholder="所属委员会" v-model="formData.committeeId" style="width: 100%"> <el-select clearable filterable placeholder="所属委员会" v-model="formData.committeeId"
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in committeeOptions"></el-option> style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in committeeOptions"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -76,7 +81,8 @@ layout("/layouts/platform.html"){
<el-col :span="12"> <el-col :span="12">
<el-form-item label="提案方式" prop="source"> <el-form-item label="提案方式" prop="source">
<el-select v-model="formData.source" style="width: 100%"> <el-select v-model="formData.source" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.code" v-for="item in sourceOptions"></el-option> <el-option :key="item.code" :label="item.name" :value="item.code"
v-for="item in sourceOptions"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -86,7 +92,8 @@ layout("/layouts/platform.html"){
<el-col :span="12"> <el-col :span="12">
<el-form-item label="提案类别" prop="typeId"> <el-form-item label="提案类别" prop="typeId">
<el-select v-model="formData.typeId" style="width: 100%"> <el-select v-model="formData.typeId" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.id" v-for="item in typeOptions"></el-option> <el-option :key="item.code" :label="item.name" :value="item.id"
v-for="item in typeOptions"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -111,7 +118,8 @@ layout("/layouts/platform.html"){
<text-editor v-model="formData.brief" key="brief" placeholder="提案内容和依据"></text-editor> <text-editor v-model="formData.brief" key="brief" placeholder="提案内容和依据"></text-editor>
</el-form-item> </el-form-item>
<el-form-item label="改进建议和措施" prop="measures"> <el-form-item label="改进建议和措施" prop="measures">
<text-editor v-model="formData.measures" key="measures" placeholder="改进建议和措施"></text-editor> <text-editor v-model="formData.measures" key="measures"
placeholder="改进建议和措施"></text-editor>
</el-form-item> </el-form-item>
<el-form-item label="附件上传" prop="files"> <el-form-item label="附件上传" prop="files">
<file-upload <file-upload
@@ -123,14 +131,14 @@ layout("/layouts/platform.html"){
></file-upload> ></file-upload>
</el-form-item> </el-form-item>
<!--# if(@auth.getPrincipalProperty('loginname')!='20130316'){ #-->
<el-form-item label="电子签名" prop="signature"> <el-form-item label="电子签名" prop="signature">
<pc-signature v-model="formData.signature"></pc-signature> <pc-signature v-model="formData.signature"></pc-signature>
</el-form-item> </el-form-item>
<!--# } #-->
</el-form> </el-form>
<el-row justify="end" type="flex" v-if="showButton"> <el-row justify="end" type="flex" v-if="showButton">
<el-button @click="doSave" type="primary">保存到我的提案</el-button> <el-button @click="onSave" type="primary">保存</el-button>
<el-button type="primary" @click="onSubmit" v-if="!taskId">提交</el-button>
<el-button type="primary" @click="onSubmitAgain" v-else>提交</el-button>
</el-row> </el-row>
</template> </template>
</el-card> </el-card>
@@ -152,6 +160,9 @@ layout("/layouts/platform.html"){
mixins: [initTableMixins], mixins: [initTableMixins],
data() { data() {
return { return {
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: {}, formData: {},
sessionOptions: [], sessionOptions: [],
sourceOptions: [], sourceOptions: [],
@@ -159,22 +170,22 @@ layout("/layouts/platform.html"){
committeeOptions: [], committeeOptions: [],
typeOptions: [], typeOptions: [],
formRules: { formRules: {
createUserName: [{ required: true, message: "请填写提案人", trigger: ["blur", "change"] }], createUserName: [{required: true, message: "请填写提案人", trigger: ["blur", "change"]}],
createTime: [{ required: true, message: "请填写提案时间", trigger: ["blur", "change"] }], createTime: [{required: true, message: "请填写提案时间", trigger: ["blur", "change"]}],
name: [{ required: true, message: "请填写提案名称", trigger: ["blur", "change"] }], name: [{required: true, message: "请填写提案名称", trigger: ["blur", "change"]}],
source: [{ required: true, message: "请选择提案方式", trigger: ["blur", "change"] }], source: [{required: true, message: "请选择提案方式", trigger: ["blur", "change"]}],
delegationId: [{ required: true, message: "请选择所属代表团", trigger: ["blur", "change"] }], delegationId: [{required: true, message: "请选择所属代表团", trigger: ["blur", "change"]}],
sessionId: [{ required: true, message: "请选择所属教代会", trigger: ["blur", "change"] }], sessionId: [{required: true, message: "请选择所属教代会", trigger: ["blur", "change"]}],
committeeId: [{ required: true, message: "请选择所属委员会", trigger: ["blur", "change"] }], committeeId: [{required: true, message: "请选择所属委员会", trigger: ["blur", "change"]}],
typeId: [{ required: true, message: "请选择提案类别", trigger: ["blur", "change"] }], typeId: [{required: true, message: "请选择提案类别", trigger: ["blur", "change"]}],
implementUnitId: [{ required: false, message: "请选择建以落实部门", trigger: ["blur", "change"] }], implementUnitId: [{required: false, message: "请选择建以落实部门", trigger: ["blur", "change"]}],
sign: [{ required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"] }], sign: [{required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"]}],
excerpt: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], excerpt: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
brief: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], brief: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
measures: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], measures: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
unitName: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], unitName: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
mobile: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], mobile: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
signature: [{ required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"] }] signature: [{required: false, message: "请扫描二维码进行签字", trigger: ["blur", "change"]}]
}, },
proposalConfig: {}, proposalConfig: {},
noticeDialogVisible: false, noticeDialogVisible: false,
@@ -183,7 +194,7 @@ layout("/layouts/platform.html"){
} }
}, },
methods: { methods: {
async doSave() { async onSave() {
const valid = await this.$refs["addForm"].validate() const valid = await this.$refs["addForm"].validate()
if (valid) { if (valid) {
if (!this.formData.name || this.formData.name.trim().length < 1) { if (!this.formData.name || this.formData.name.trim().length < 1) {
@@ -195,41 +206,53 @@ layout("/layouts/platform.html"){
return return
} }
this.$axios.post(loc() + "/save", { info: JSON.stringify(this.formData) }).then((res) => { this.$axios.post("/platform/proposal/write/save", {info: JSON.stringify(this.formData)}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$message.success(res.msg) this.$message.success(res.msg)
this.formData = res.data this.formData = res.data
this.$store.dispatch("pjaxRoute", "/platform/proposal/mine") window.location.href = '/platform/proposal/mine'
} }
}) })
} }
}, },
async doSubmit() {
const valid = await this.$refs["addForm"].validate()
if (valid) {
const confirm = await this.$confirm("确定要提交此提案吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
})
if ("confirm" === confirm) {
let data = clone(this.formData)
if (data.files) {
data.files = JSON.stringify(data.files)
}
const resp = await this.$axios.post(loc() + "/doSubmit", {
data: JSON.stringify(data)
})
if (resp.code === 0) {
this.$message.success(resp.msg)
// location.href = "/platform/proposal/transact/compose"
} else {
this.notifyWarning(resp.msg)
}
}
}
},
// 提交
onSubmit() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/proposal/write/submit', {info: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/proposal/mine'
}
})
})
},
// 重新提交
onSubmitAgain() {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post('/platform/proposal/write/submitAgain', {
info: JSON.stringify(this.formData),
taskId: GetQueryString("taskId")
}).then(res => {
if (res.code === 0) {
this.$message.success("提交成功")
window.location.href = '/platform/proposal/mine'
}
})
})
},
// 获取提案类别
listProposalType() { listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => { this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -238,6 +261,7 @@ layout("/layouts/platform.html"){
}) })
}, },
// 获取配置
getProposalConfig() { getProposalConfig() {
return this.$axios.post("/platform/proposal/common/config").then((res) => { return this.$axios.post("/platform/proposal/common/config").then((res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -255,13 +279,17 @@ layout("/layouts/platform.html"){
// this.delegationOptions = await proposal.getDelegation(val) // this.delegationOptions = await proposal.getDelegation(val)
// this.committeeOptions = await this.getInstitutions(val) // this.committeeOptions = await this.getInstitutions(val)
}, },
// 获取代表团
listDelegation() { listDelegation() {
return this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.formData.sessionId }).then((res) => { return this.$axios.post("/platform/proposal/common/listDelegation", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.delegationOptions = res.data this.delegationOptions = res.data
} }
}) })
}, },
// 查询开启的教代会
listOpenSession(isModify = false) { listOpenSession(isModify = false) {
this.$axios.post("/platform/proposal/common/listOpenSession").then(async (res) => { this.$axios.post("/platform/proposal/common/listOpenSession").then(async (res) => {
if (res.code === 0) { if (res.code === 0) {
@@ -278,7 +306,7 @@ layout("/layouts/platform.html"){
//查询自己有权限的撰写方式 //查询自己有权限的撰写方式
listSource() { listSource() {
return this.$axios.post("/platform/proposal/write/listSource", { sessionId: this.formData.sessionId }).then((res) => { return this.$axios.post("/platform/proposal/write/listSource", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.sourceOptions = res.data this.sourceOptions = res.data
} }
@@ -287,7 +315,7 @@ layout("/layouts/platform.html"){
//查询自己有权限的代表团 //查询自己有权限的代表团
searchMineDelegation() { searchMineDelegation() {
return this.$axios.post("/platform/proposal/write/searchMineDelegation", { sessionId: this.formData.sessionId }).then((res) => { return this.$axios.post("/platform/proposal/write/searchMineDelegation", {sessionId: this.formData.sessionId}).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.$set(this.formData, "delegationId", res.data) this.$set(this.formData, "delegationId", res.data)
} }
@@ -295,22 +323,14 @@ layout("/layouts/platform.html"){
}, },
init() { init() {
const id = GetQueryString("id") if (this.bizId) {
if (id) { this.$axios.post("/platform/proposal/write/detail", {id: this.bizId}).then((res) => {
this.$axios.post(loc() + "/detail", { id }).then((res) => {
if (res.code === 0) { if (res.code === 0) {
this.formData = res.data this.formData = res.data
this.listOpenSession(true) this.listOpenSession(true)
} }
}) })
} else { } else {
this.$confirm('本届提案征集已结束!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
this.showButton = false
// this.noticeDialogVisible = true // this.noticeDialogVisible = true
this.listOpenSession(false) this.listOpenSession(false)
this.$set(this.formData, "createUserId", this.$store.state.user.id) this.$set(this.formData, "createUserId", this.$store.state.user.id)
@@ -88,8 +88,8 @@ const SUGGESTION_INFO = {
}, },
// 查看流程图 // 查看流程图
openChart(){ openChart() {
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId,this.row.instanceId) this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
} }
} }
@@ -5,26 +5,43 @@ layout("/layouts/platform.html"){
<div id="app" v-cloak> <div id="app" v-cloak>
<el-card shadow="never"> <el-card shadow="never">
<snaker-start slot="header" label="意见箱" define_key="JYXC"></snaker-start> <snaker-start slot="header" label="意见箱" define_key="JYXC"></snaker-start>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" <el-form :model="formData" ref="formRef" :rules="formRules" label-width="130px">
class="flow-task-form"> <el-row>
<el-descriptions :column="2" border> <el-col :span="12">
<el-descriptions-item label="姓名">{{formData.userName}}</el-descriptions-item> <el-form-item label="姓名" prop="userName">
<el-descriptions-item label="工号">{{formData.loginName}}</el-descriptions-item> <el-input v-model="formData.userName" readonly></el-input>
<el-descriptions-item label="单位">{{formData.unitName}}</el-descriptions-item> </el-form-item>
<el-descriptions-item label="工会">{{formData.unionName}}</el-descriptions-item> </el-col>
<el-descriptions-item label="标题" :span="2"> <el-col :span="12">
<el-form-item label="工号" prop="loginName">
<el-input v-model="formData.loginName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="单位" prop="unitName">
<el-input v-model="formData.unitName" readonly></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工会" prop="unionName">
<el-input v-model="formData.unionName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="title" label="标题"> <el-form-item prop="title" label="标题">
<el-input v-model="formData.title" maxlength="100" show-word-limit <el-input v-model="formData.title" maxlength="100" show-word-limit
placeholder="请输入标题"></el-input> placeholder="请输入标题"></el-input>
</el-form-item> </el-form-item>
</el-descriptions-item>
<el-descriptions-item label="填写意见建议内容" :span="2"> <el-form-item prop="content" label="意见建议内容">
<el-form-item prop="content" label="填写意见建议内容">
<el-input v-model="formData.content" type="textarea" maxlength="500" show-word-limit <el-input v-model="formData.content" type="textarea" maxlength="500" show-word-limit
rows="5"
placeholder="请输入内容"></el-input> placeholder="请输入内容"></el-input>
</el-form-item> </el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form> </el-form>
<el-row type="flex" justify="end" class="mt20"> <el-row type="flex" justify="end" class="mt20">
<el-button type="primary" plain @click="onSave">保存</el-button> <el-button type="primary" plain @click="onSave">保存</el-button>
@@ -39,10 +39,8 @@ layout("/layouts/platform.html"){
<el-table-column label="操作" fixed="right" width="200px"> <el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button> <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 v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">审核</el-button>
</el-button> <el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -13,6 +13,7 @@ layout("/layouts/platform.html"){
formData="yyyy" formData="yyyy"
type="year" type="year"
placeholder="选择年份" placeholder="选择年份"
clearable
></el-date-picker> ></el-date-picker>
</search-item> </search-item>
<search-item label="届数"> <search-item label="届数">
@@ -41,7 +42,8 @@ layout("/layouts/platform.html"){
<i class="fa fa-circle" :class="row.enable ? 'text-success' : 'text-danger'" style="margin-left: 5px"></i> <i class="fa fa-circle" :class="row.enable ? 'text-success' : 'text-danger'" style="margin-left: 5px"></i>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="collectStartTime" label="提案征集开始时间"></el-table-column>
<el-table-column prop="collectEndTime" label="提案征集结束时间"></el-table-column>
<el-table-column label="操作" width="200"> <el-table-column label="操作" width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="primary" @click="openEdit(scope.row.id)">编辑</el-button> <el-button size="mini" type="primary" @click="openEdit(scope.row.id)">编辑</el-button>
@@ -53,7 +55,7 @@ layout("/layouts/platform.html"){
</el-card> </el-card>
<el-dialog :title="formData.id ? '编辑':'新增'" :visible.sync="dialogFormVisible" width="60%" :close-on-click-modal="false"> <el-dialog :title="formData.id ? '编辑':'新增'" :visible.sync="dialogFormVisible" width="60%" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" size="small" label-width="120px" :rules="formRules"> <el-form :model="formData" ref="formRef" size="small" label-width="140px" :rules="formRules">
<el-form-item prop="year" label="年份"> <el-form-item prop="year" label="年份">
<el-date-picker <el-date-picker
style="width: 100%" style="width: 100%"
@@ -94,6 +96,27 @@ layout("/layouts/platform.html"){
延用上一次教代会的组织机构及代表信息,包含【筹备领导小组;资格审查小组;主席团;执行委员会;专门委员会;代表团;教代会代表】。 延用上一次教代会的组织机构及代表信息,包含【筹备领导小组;资格审查小组;主席团;执行委员会;专门委员会;代表团;教代会代表】。
</div> </div>
</el-form-item> </el-form-item>
<el-form-item prop="collectStartTime" label="提案征集开始时间">
<el-date-picker
style="width: 100%"
v-model="formData.collectStartTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择时间"
></el-date-picker>
</el-form-item>
<el-form-item prop="collectEndTime" label="提案征集结束时间">
<el-date-picker
style="width: 100%"
v-model="formData.collectEndTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择时间"
></el-date-picker>
</el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button> <el-button @click="dialogFormVisible = false">取 消</el-button>
@@ -115,7 +138,9 @@ layout("/layouts/platform.html"){
c: [{ required: true, message: "必填", trigger: ["change", "blur"] }], c: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
enable: [{ required: true, message: "必填", trigger: ["change", "blur"] }], enable: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
description: [{ required: true, message: "必填", trigger: ["change", "blur"] }], description: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
isExtend: [{ required: true, message: "必填", trigger: ["change", "blur"] }] isExtend: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
collectStartTime: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
collectEndTime: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
} }
} }
}, },