This commit is contained in:
那些花儿
2025-08-01 14:45:20 +08:00
parent fc0d86c812
commit d4ba5aa689
81 changed files with 6051 additions and 3117 deletions
+1
View File
@@ -1,3 +1,4 @@
**/wangEditor/*.js
**/nprogress/*.js
**/assets/platform/plugins/**
**/views/*.js
@@ -260,7 +260,6 @@ public class FlowCommonController {
flowEngine.executeProcessTask(processTaskId, operator, args);
} else if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.RE_APPLY.getCode())) {
// 重新提交
// args.put(FlowConst.FORM_DATA, args.getStr(FlowConst.FORM_DATA));
flowEngine.executeProcessTask(processTaskId, operator, args);
} else {
// 默认执行
@@ -89,6 +89,7 @@ public class FlowEngineImpl implements FlowEngine {
}
// 2. 将流程定义文件转成流程模型
ProcessModel processModel = processDefineService.processDefineToModel(processDefine);
// 3. 根据流程定义对象创建流程实例
ProcessInstance processInstance = processInstanceService.createProcessInstance(processDefine, businessKey, operator, args, parentId, parentNodeName);
args.set(FlowConst.PROCESS_INSTANCE_ID_KEY, processInstance.getId());
@@ -28,6 +28,7 @@ public class CountersignHandler implements IHandler {
boolean isMerged = false;
String countersignType = taskModel.getExt().get("countersignType","PARALLEL");
String countersignCompletionCondition = taskModel.getExt().get("countersignCompletionCondition","");
countersignCompletionCondition = taskModel.getCountersignCompletionCondition();
String prefix = FlowConst.COUNTERSIGN_VARIABLE_PREFIX +taskModel.getName()+"_";
// 会签办理人列表
List<String> operatorList = Convert.toList(String.class,execution.getArgs().get(prefix+FlowConst.COUNTERSIGN_OPERATOR_LIST));
@@ -460,7 +460,7 @@ public class ProcessInstanceServiceImpl extends BaseServiceImpl<ProcessInstance>
addVariable.put(prefix + FlowConst.NR_OF_COMPLETED_INSTANCES, execution.getArgs().get(prefix + FlowConst.NR_OF_COMPLETED_INSTANCES));
// 更新会签操作人列表countersignOperatorList
addVariable.put(prefix + FlowConst.COUNTERSIGN_OPERATOR_LIST, taskActors);
ProcessInstanceService processInstanceService = SpringUtil.getBean(ProcessInstanceService.class);
ProcessInstanceService processInstanceService = ServiceContext.find(ProcessInstanceService.class);
processInstanceService.addVariable(processInstanceId, addVariable);
}
@@ -7,7 +7,6 @@ import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.service.impl.BaseServiceImpl;
@@ -15,6 +14,7 @@ import com.budwk.app.base.vo.LabelValueVO;
import com.budwk.app.flow.constant.FlowConst;
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.event.ProcessEvent;
import com.budwk.app.flow.engine.event.ProcessPublisher;
import com.budwk.app.flow.engine.model.CustomModel;
@@ -179,13 +179,10 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
// 增加是否为第一个任务节点标识
execution.getArgs().put(FlowConst.IS_FIRST_TASK_NODE, FlowUtil.isFistTaskName(execution.getProcessModel(), taskModel.getName()));
//过滤上个任务的表单数据 避免造成污染 每个任务只保存自己的表单数据
Dict cleanArgs = Dict.create();
execution.getArgs().forEach((k, v) -> {
if (!k.startsWith(FlowConst.TASK_FORM_DATA_PREFIX)) {
cleanArgs.set(k, v);
}
});
execution.setArgs(cleanArgs);
List<String> removeKeys = execution.getArgs().keySet().stream().filter(k -> k.startsWith(FlowConst.TASK_FORM_DATA_PREFIX) || k.equals(FlowConst.SUBMIT_TYPE) || k.startsWith(FlowConst.COUNTERSIGN_VARIABLE_PREFIX)).toList();
for (String key : removeKeys) {
execution.getArgs().remove(key);
}
processTask.setVariable(JSONUtil.toJsonStr(execution.getArgs()));
processTask.setCreatedAt(now);
@@ -367,6 +364,7 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
}
@Override
@Aop(TransAop.READ_COMMITTED)
public List<ProcessTask> createCountersignTask(TaskModel taskModel, Execution execution) {
List<ProcessTask> processTaskList = new ArrayList<>();
List<String> taskActors = getTaskActors(taskModel, execution);
@@ -399,7 +397,15 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
processTask.setTaskState(ProcessTaskStateEnum.DOING.getCode());
processTask.setTaskType(taskModel.getTaskType().getCode());
processTask.setProcessInstanceId(execution.getProcessInstanceId());
// 增加是否为第一个任务节点标识
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) || k.startsWith(FlowConst.COUNTERSIGN_VARIABLE_PREFIX)).toList();
for (String key : removeKeys) {
execution.getArgs().remove(key);
}
processTask.setVariable(JSONUtil.toJsonStr(execution.getArgs()));
processTask.setCreatedAt(now);
processTask.setUpdatedAt(now);
@@ -414,7 +420,7 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
processTaskList.add(processTask);
addTaskActor(processTask.getId(), CollectionUtil.newArrayList(taskActor));
});
ProcessInstanceService processInstanceService = SpringUtil.getBean(ProcessInstanceService.class);
ProcessInstanceService processInstanceService = ServiceContext.find(ProcessInstanceService.class);
// 更新会签变量到流程实例参数中
processInstanceService.updateCountersignVariable(taskModel, execution, taskActors);
return processTaskList;
@@ -1,247 +0,0 @@
//package com.budwk.app.snakerflow;
//
//import cn.hutool.core.util.StrUtil;
//import org.apache.commons.beanutils.BeanUtils;
//import org.apache.commons.beanutils.PropertyUtils;
//import org.snaker.engine.entity.*;
//import org.snaker.engine.model.*;
//
//import java.beans.PropertyDescriptor;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//public class SnakerHelper {
//
// private static final Map<Class<? extends NodeModel>, String> mapper = new HashMap<Class<? extends NodeModel>, String>();
//
// static {
// mapper.put(TaskModel.class, "task");
// mapper.put(CustomModel.class, "custom");
// mapper.put(DecisionModel.class, "decision");
// mapper.put(EndModel.class, "end");
// mapper.put(ForkModel.class, "fork");
// mapper.put(JoinModel.class, "join");
// mapper.put(StartModel.class, "start");
// mapper.put(SubProcessModel.class, "subprocess");
// }
//
// public static String getStateJson(ProcessModel model, List<Task> activeTasks, List<HistoryTask> historyTasks) {
// StringBuffer buffer = new StringBuffer();
// buffer.append("{'activeRects':{'rects':[");
// if (activeTasks != null && activeTasks.size() > 0) {
// for (Task task : activeTasks) {
// buffer.append("{'paths':[],'name':'");
// buffer.append(task.getTaskName());
// buffer.append("'},");
// }
// buffer.deleteCharAt(buffer.length() - 1);
// }
// buffer.append("]}, 'historyRects':{'rects':[");
// if (historyTasks != null && historyTasks.size() > 0) {
// for (HistoryTask historyTask : historyTasks) {
// NodeModel parentModel = model.getNode(historyTask.getTaskName());
// if (parentModel == null) continue;
// buffer.append("{'name':'").append(parentModel.getName()).append("','paths':[");
// buffer.append("]},");
// }
// buffer.deleteCharAt(buffer.length() - 1);
// }
// buffer.append("]}}");
// return buffer.toString();
// }
//
// public static String getModelJson(ProcessModel model) {
// StringBuffer buffer = new StringBuffer();
// List<TransitionModel> tms = new ArrayList<TransitionModel>();
// for (NodeModel node : model.getNodes()) {
// for (TransitionModel tm : node.getOutputs()) {
// tms.add(tm);
// }
// }
// buffer.append("{");
// buffer.append(getNodeJson(model.getNodes()));
// buffer.append(getPathJson(tms));
// buffer.append("props:{props:{name:{name:'name',value:'");
// buffer.append(convert(model.getName()));
// buffer.append("'},displayName:{name:'displayName',value:'");
// buffer.append(convert(model.getDisplayName()));
// buffer.append("'},expireTime:{name:'expireTime',value:'");
// buffer.append(convert(model.getExpireTime()));
// buffer.append("'},instanceUrl:{name:'instanceUrl',value:'");
// buffer.append(convert(model.getInstanceUrl()));
// buffer.append("'},instanceNoClass:{name:'instanceNoClass',value:'");
// buffer.append(convert(model.getInstanceNoClass()));
// buffer.append("'}}}}");
// return buffer.toString();
// }
//
// public static String getNodeJson(List<NodeModel> nodes) {
// StringBuffer buffer = new StringBuffer();
// buffer.append("states: {");
// for (NodeModel node : nodes) {
// buffer.append(node.getName());
// buffer.append(getBase(node));
// buffer.append(getLayout(node));
// buffer.append(getProperty(node));
// buffer.append(",");
// }
// buffer.deleteCharAt(buffer.length() - 1);
// buffer.append("},");
// return buffer.toString();
// }
//
// public static String getPathJson(List<TransitionModel> tms) {
// StringBuffer buffer = new StringBuffer();
// buffer.append("paths:{");
// for (TransitionModel tm : tms) {
// buffer.append(tm.getName());
// buffer.append(":{from:'");
// buffer.append(tm.getSource().getName());
// buffer.append("',to:'");
// buffer.append(tm.getTarget().getName());
// buffer.append("', dots:[");
// if (StrUtil.isNotEmpty(tm.getG())) {
// String[] bendpoints = tm.getG().split(";");
// for (String bendpoint : bendpoints) {
// buffer.append("{");
// String[] xy = bendpoint.split(",");
// buffer.append("x:").append(getNumber(xy[0]));
// buffer.append(",y:").append(xy[1]);
// buffer.append("},");
// }
// buffer.deleteCharAt(buffer.length() - 1);
// }
// buffer.append("],text:{text:'");
// buffer.append(tm.getDisplayName());
// buffer.append("'},textPos:{");
// if (StrUtil.isNotEmpty(tm.getOffset())) {
// String[] values = tm.getOffset().split(",");
// buffer.append("x:").append(values[0]).append(",");
// buffer.append("y:").append(values[1]);
// }
// buffer.append("}, props:{name:{value:'" + tm.getName() + "'},expr:{value:'" + tm.getExpr() + "'}}}");
// buffer.append(",");
// }
// buffer.deleteCharAt(buffer.length() - 1);
// buffer.append("},");
// return buffer.toString();
// }
//
// private static String getBase(NodeModel node) {
// String buffer = ":{type:'" +
// mapper.get(node.getClass()) +
// "',text:{text:'" +
// node.getDisplayName() +
// "'},";
// return buffer;
// }
//
// private static String getProperty(NodeModel node) {
// StringBuffer buffer = new StringBuffer();
// buffer.append("props:{");
// try {
// PropertyDescriptor[] beanProperties = PropertyUtils.getPropertyDescriptors(node);
// for (PropertyDescriptor propertyDescriptor : beanProperties) {
// if (propertyDescriptor.getReadMethod() == null || propertyDescriptor.getWriteMethod() == null)
// continue;
// String name = propertyDescriptor.getName();
// String value = "";
// if (propertyDescriptor.getPropertyType() == String.class) {
// value = BeanUtils.getProperty(node, name);
// } else {
// continue;
// }
// if (value == null || value.equals("")) continue;
// buffer.append(name);
// buffer.append(":{value:'");
// buffer.append(convert(value));
// buffer.append("'},");
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// buffer.deleteCharAt(buffer.length() - 1);
// buffer.append("}}");
// return buffer.toString();
// }
//
// private static String getLayout(NodeModel node) {
// StringBuffer buffer = new StringBuffer();
// buffer.append("attr:{");
// String[] values = node.getLayout().split(",");
// buffer.append("x:").append(getNumber(values[0])).append(",");
// buffer.append("y:").append(values[1]).append(",");
// if ("-1".equals(values[2])) {
// if (node instanceof TaskModel || node instanceof CustomModel || node instanceof SubProcessModel) {
// values[2] = "100";
// } else {
// values[2] = "50";
// }
// }
// if ("-1".equals(values[3])) {
// values[3] = "50";
// }
// buffer.append("width:").append(values[2]).append(",");
// buffer.append("height:").append(values[3]);
// buffer.append("},");
// return buffer.toString();
// }
//
// private static String convert(String value) {
// if (StrUtil.isEmpty(value))
// return "";
// if (value.indexOf("'") != -1) {
// value = value.replaceAll("'", "#1");
// }
// if (value.indexOf("\"") != -1) {
// value = value.replaceAll("\"", "#2");
// }
// if (value.indexOf("\r\n") != -1) {
// value = value.replaceAll("\r\n", "#3");
// }
// if (value.indexOf("\n") != -1) {
// value = value.replaceAll("\n", "#4");
// }
// if (value.indexOf(">") != -1) {
// value = value.replaceAll(">", "#5");
// }
// if (value.indexOf("<") != -1) {
// value = value.replaceAll("<", "#6");
// }
// if (value.indexOf("&amp;") != -1) {
// value = value.replaceAll("&amp;", "#7");
// }
// return value;
// }
//
// public static String convertXml(String value) {
// if (value.indexOf("#1") != -1) {
// value = value.replaceAll("#1", "'");
// }
// if (value.indexOf("#2") != -1) {
// value = value.replaceAll("#2", "\"");
// }
// if (value.indexOf("#5") != -1) {
// value = value.replaceAll("#5", "&gt;");
// }
// if (value.indexOf("#6") != -1) {
// value = value.replaceAll("#6", "&lt;");
// }
// if (value.indexOf("&") != -1) {
// value = value.replaceAll("#7", "&amp;");
// }
// return value;
// }
//
// private static int getNumber(String value) {
// if (value == null) return 0;
// try {
// return Integer.parseInt(value) + 180;
// } catch (Exception e) {
// return 0;
// }
// }
//
//}
@@ -1,41 +0,0 @@
//package com.budwk.app.snakerflow.config;
//
//import org.nutz.ioc.loader.annotation.Inject;
//import org.nutz.ioc.loader.annotation.IocBean;
//import org.nutz.lang.Mirror;
//import org.snaker.engine.SnakerEngine;
//import org.snaker.engine.cfg.Configuration;
//import org.snaker.engine.core.SnakerEngineImpl;
//import org.snaker.engine.impl.JuelExpression;
//import org.snaker.engine.impl.SimpleContext;
//import org.snaker.nutz.access.NutzAccess;
//import org.snaker.nutz.access.NutzTransactionInterceptor;
//
//import javax.sql.DataSource;
//
//@IocBean
//public class SnakerEngineConfig {
//
// @Inject
// private DataSource dataSource;
//
// @IocBean
// public SnakerEngine snakerEngine() {
// SimpleContext ctx = new SimpleContext();
// ctx.put(NutzAccess.class.getName(), NutzAccess.class);
// ctx.put(JuelExpression.class.getName(), JuelExpression.class);
//
//// ctx.put(NutzTransactionInterceptor.class.getName(), NutzTransactionInterceptor.class);
//
// // 初始化配置
// Configuration configuration = new Configuration(ctx);
//
//// Mirror.me(configuration).setValue(configuration, "interceptor", ctx.find(NutzTransactionInterceptor.class));
// configuration.initAccessDBObject(dataSource);
//
//
// SnakerEngine engine = configuration.buildSnakerEngine();
// return engine;
// }
//
//}
@@ -1,16 +0,0 @@
//package com.budwk.app.snakerflow.config;
//
//import cn.hutool.extra.expression.ExpressionUtil;
//import org.snaker.engine.Expression;
//
//import java.util.Map;
//
//public class SnakerExpression implements Expression {
// @Override
// public <T> T eval(Class<T> T, String expr, Map<String, Object> args) {
//
// Object eval = ExpressionUtil.eval(expr, args);
//
// return null;
// }
//}
@@ -1,357 +0,0 @@
//package com.budwk.app.snakerflow.controller;
//
//import cn.dev33.satoken.annotation.SaCheckLogin;
//import cn.hutool.core.util.StrUtil;
//import cn.hutool.json.JSONObject;
//import com.budwk.app.base.page.Pagination;
//import com.budwk.app.base.result.Result;
//import com.budwk.app.snakerflow.SnakerHelper;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.nutz.aop.interceptor.ioc.TransAop;
//import org.nutz.dao.Dao;
//import org.nutz.dao.Sqls;
//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.IocBean;
//import org.nutz.lang.util.NutMap;
//import org.nutz.mvc.annotation.At;
//import org.nutz.mvc.annotation.Ok;
//import org.nutz.mvc.annotation.Param;
//import org.snaker.engine.SnakerEngine;
//import org.snaker.engine.access.Page;
//import org.snaker.engine.access.QueryFilter;
//import org.snaker.engine.entity.HistoryTask;
//import org.snaker.engine.entity.Order;
//import org.snaker.engine.entity.Process;
//import org.snaker.engine.entity.Task;
//import org.snaker.engine.helper.AssertHelper;
//import org.snaker.engine.helper.StreamHelper;
//import org.snaker.engine.model.ProcessModel;
//import org.snaker.engine.model.TaskModel;
//import org.snaker.engine.model.TransitionModel;
//
//import javax.servlet.http.HttpServletRequest;
//import java.io.IOException;
//import java.io.InputStream;
//import java.nio.charset.StandardCharsets;
//import java.util.*;
//
//import static org.snaker.engine.access.QueryFilter.DESC;
//
//@IocBean
//@At("/flow/define")
//@Ok("json:full")
//@Slf4j
//public class SankerFlowDefineController {
//
// @Inject
// private SnakerEngine snakerEngine;
// @Inject
// private Dao dao;
//
// @At("")
// @Ok("beetl:/platform/flow/definition/index.html")
// @SaCheckLogin
// public void index() {
// }
//
// @At("/designer")
// @Ok("beetl:/platform/flow/definition/designer.html")
// @SaCheckLogin
// public void designer(HttpServletRequest request) {
// request.setAttribute("processId", request.getParameter("processId"));
// }
//
// @At("/designer2")
// @Ok("beetl:/platform/flow/designer.html")
// @SaCheckLogin
// public void designer2(HttpServletRequest request) {
// request.setAttribute("processId", request.getParameter("processId"));
// }
//
//
// @At("/diagram")
// @Ok("beetl:/platform/flow/diagram.html")
// @SaCheckLogin
// public void diagram(HttpServletRequest request) {
// request.setAttribute("processId", request.getParameter("processId"));
// request.setAttribute("orderId", request.getParameter("orderId"));
// }
//
//
// @At
// @SaCheckLogin
// @ApiOperation("获取流程定义分页列表")
// public Result pageData(Integer pageNumber, Integer pageSize, String displayName, String name) {
// QueryFilter filter = new QueryFilter();
// if (StrUtil.isNotEmpty(displayName)) {
// filter.setDisplayName(displayName);
// }
// if (StrUtil.isNotEmpty(name)) {
// filter.setName(name);
// }
// filter.orderBy("create_Time").order(DESC);
// Page<Process> page = new Page<>();
// page.setPageNo(pageNumber);
// page.setPageSize(pageSize);
// snakerEngine.process().getProcesss(page, filter);
// List<Process> result = page.getResult();
// Pagination<Process> pagination = new Pagination<>(pageNumber, pageSize, (int) page.getTotalCount(), result);
// return Result.success(pagination);
// }
//
//
// @At
// @SaCheckLogin
// @ApiOperation("新增流程定义")
// public Result insert(){
//
// return null;
// }
//
//
//
//
//
// @At
// @SaCheckLogin
// @ApiOperation("保存流程定义")
// @Aop(TransAop.READ_COMMITTED)
// public Result saveProcessXml(String model, String id, boolean xmlHeader) {
// InputStream input = null;
// try {
// String xml = "";
// if (!xmlHeader) {
// xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
// }
// xml = xml + SnakerHelper.convertXml(model);
// input = StreamHelper.getStreamFromString(xml);
// if (StrUtil.isNotEmpty(id) && !id.equals("undefined")) {
// snakerEngine.process().redeploy(id, input);
// } else {
// snakerEngine.process().deploy(input);
// }
// } catch (Exception e) {
// log.error("", e);
// return Result.error("保存失败:" + e.getMessage());
// } finally {
// if (input != null) {
// try {
// input.close();
// } catch (IOException ignored) {
// }
// }
// }
// return Result.success();
// }
//
// @At("/getXml")
// @SaCheckLogin
// @ApiOperation("获取流程定义")
// public Result getProcessXml(String id) {
// Process process = snakerEngine.process().getProcessById(id);
// if (process != null) {
// byte[] bytes = process.getDBContent();
// return Result.success().addData(new String(bytes, StandardCharsets.UTF_8));
// }
// return Result.success();
// }
//
// @At("/process/modelJson")
// @ApiOperation(value = "根据流程定义名称获取流程定义json", tags = "流程引擎-流程")
// @SaCheckLogin
// public Result getProcessJson(String processId) {
// if (StrUtil.isBlank(processId)) {
// return Result.success();
// }
// Process process = snakerEngine.process().getProcessById(processId);
// if (Objects.isNull(process)) {
// return Result.success();
// }
// ProcessModel processModel = process.getModel();
// if (Objects.isNull(processModel)) {
// return Result.success();
// }
// String modelJson = SnakerHelper.getModelJson(processModel);
// return Result.success().addData(modelJson);
// }
//
// @At("/process/json")
// @SaCheckLogin
// @ApiOperation(value = "流程定义+流程状态")
// public Result getProcessStateJson(String processId, String orderId) {
// if (StrUtil.isBlank(processId)) {
// processId = snakerEngine.query().getHistOrder(orderId).getProcessId();
// }
// Process process = snakerEngine.process().getProcessById(processId);
// AssertHelper.notNull(process);
// ProcessModel model = process.getModel();
// Map<String, String> jsonMap = new HashMap<>();
// if (model != null) {
// String modelJson = SnakerHelper.getModelJson(model);
// jsonMap.put("process", SnakerHelper.getModelJson(model));
// }
//
// if (StrUtil.isNotEmpty(orderId)) {
// List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
// List<HistoryTask> historyTasks = snakerEngine.query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
// jsonMap.put("state", SnakerHelper.getStateJson(model, tasks, historyTasks));
// }
// return Result.success(jsonMap);
// }
//
//
// @At
// @SaCheckLogin
// @ApiOperation("取消部署")
// public Result undeploy(String id) {
// snakerEngine.process().undeploy(id);
// return Result.success();
// }
//
// @At
// @SaCheckLogin
// @ApiOperation("发布流程")
// public Result publish(String id) {
// InputStream inputStream = null;
// try {
// Process process = snakerEngine.process().getProcessById(id);
// byte[] bytes = process.getDBContent();
// String xml = new String(bytes, StandardCharsets.UTF_8);
// inputStream = StreamHelper.getStreamFromString(xml);
// snakerEngine.process().redeploy(id, inputStream);
// return Result.success();
// } catch (Exception e) {
// return Result.error("发布失败:" + e.getMessage());
// } finally {
// if (inputStream != null) {
// try {
// inputStream.close();
// } catch (IOException ignored) {
// }
// }
// }
// }
//
// @At
// @SaCheckLogin
// @ApiOperation("删除流程定义")
// public Result delete(String id) {
// snakerEngine.process().cascadeRemove(id);
// return Result.success();
// }
//
//
// @At
// @SaCheckLogin
// @ApiOperation("获取流程定义+流程状态")
// public Object getProcessJson(String processId, String orderId) {
// if (StrUtil.isBlank(processId)) {
// processId = snakerEngine.query().getHistOrder(orderId).getProcessId();
// }
// Process process = snakerEngine.process().getProcessById(processId);
// AssertHelper.notNull(process);
// ProcessModel model = process.getModel();
// Map<String, String> jsonMap = new HashMap<>();
// if (model != null) {
// jsonMap.put("process", SnakerHelper.getModelJson(model));
// }
//
// if (StrUtil.isNotEmpty(orderId)) {
// List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
// List<HistoryTask> historyTasks = snakerEngine.query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
// jsonMap.put("state", SnakerHelper.getStateJson(model, tasks, historyTasks));
// }
// return jsonMap;
// }
//
//
// @At(value = "/flow/task/tip", top = true)
// @SaCheckLogin
// public Result taskTip(String orderId, String taskName) {
// List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
// StringBuilder builder = new StringBuilder();
// String createTime = StrUtil.EMPTY;
// String finishTime = StrUtil.EMPTY;
// boolean find = false;
// for (Task task : tasks) {
// if (task.getTaskName().equalsIgnoreCase(taskName)) {
// String[] actors = snakerEngine.query().getTaskActorsByTaskId(task.getId());
// for (String actor : actors) {
//// SysUser sysUser = sysUserService.getById(Long.valueOf(actor));
//// String nickName = sysUser.getNickName();
//// builder.append(nickName).append(",");
// builder.append(actor);
// find = true;
// }
// createTime = task.getCreateTime();
// }
// }
// if (!find) {
// List<HistoryTask> historyTasks = snakerEngine.query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
// for (HistoryTask task : historyTasks) {
// if (task.getTaskName().equalsIgnoreCase(taskName)) {
// String[] actors = snakerEngine.query().getHistoryTaskActorsByTaskId(task.getId());
// for (String actor : actors) {
//// SysUser sysUser = sysUserService.getById(Long.valueOf(actor));
//// String nickName = sysUser.getNickName();
//// builder.append(nickName).append(",");
// builder.append(actor);
// }
// createTime = task.getCreateTime();
// finishTime = task.getFinishTime();
// }
// }
// }
// if (!builder.isEmpty()) {
// builder.deleteCharAt(builder.length() - 1);
// }
// Map<String, String> data = new HashMap<>();
// data.put("actors", builder.toString());
// data.put("createTime", createTime);
// data.put("finishTime", finishTime);
// return Result.success(data);
// }
//
// @At(value = "/flow/instance/info", top = true)
// @SaCheckLogin
// @ApiOperation("流程实例信息")
// public Result instanceStatus(@Param("instanceId") String instanceId) {
// Sql sql = Sqls.create("""
// SELECT
// o.order_State AS orderState,
// p.display_Name AS processName,
// concat(t.display_Name) AS currentTaskName\s
// FROM
// wf_hist_order o
// LEFT JOIN wf_process p ON p.id = o.process_Id
// LEFT JOIN wf_task t ON t.order_Id = o.id
// WHERE o.id = @instanceId
// """);
// sql.setParam("instanceId", instanceId);
// sql.setCallback(Sqls.callback.map());
// dao.execute(sql);
// NutMap result = (NutMap) sql.getResult();
// return Result.success(result);
// }
//
// @At(value = "/flow/task/info", top = true)
// @SaCheckLogin
// @ApiOperation("任务信息")
// public Result taskInfo(@Param("taskId") String taskId) {
// Task task = snakerEngine.query().getTask(taskId);
// return Result.success(task);
// }
//
// @At(value = "/flow/task/next", top = true)
// @ApiOperation("获取可执行的流向任务")
// @SaCheckLogin
// public Result taskNext(@Param("taskId") String taskId) {
//
// return Result.success();
// }
//
//
//}
@@ -1,19 +0,0 @@
//package com.budwk.app.snakerflow.controller;
//
//import cn.dev33.satoken.annotation.SaCheckLogin;
//import io.swagger.annotations.ApiOperation;
//import org.nutz.mvc.annotation.At;
//import org.nutz.mvc.annotation.Ok;
//
//@At("/flow/common")
//public class SnakerFlowCommonController {
//
// @ApiOperation("通用审批页面")
// @At("/approval")
// @SaCheckLogin
// @Ok("beetl:/platform/flow/approval.html")
// public void approval() {
//
// }
//
//}
@@ -0,0 +1,108 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.engine.FlowEngine;
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.service.ProposalWriteService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
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.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
@IocBean
@At("/platform/proposal/apply")
@Ok("json:full")
@Api("撰写提案")
public class ProposalApplyControllerX {
@Inject
private FlowEngine flowEngine;
@Inject
private ProposalWriteService proposalWriteService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/apply/index.html")
@SaCheckLogin
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/apply/form.html")
@SaCheckLogin
public void form() {
}
@At
@SaCheckLogin
public Result pageData(Integer pageNumber, Integer pageSize) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.name AS typeName,
tcs.fullName AS sessionName,
tcd.`name` AS delegationName,
ins.id AS instanceId,
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 taskVariale,
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') AS startTaskId
FROM
proposal_info info
LEFT JOIN proposal_type type on type.id = info.typeId
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
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
""");
Cnd cnd = Cnd.NEW();
cnd.and("info.createdBy", "=", SecurityUtil.getUserId());
cnd.desc("info.createdAt");
sql.setCondition(cnd);
Pagination<NutMap> pagination = proposalWriteService.listPageMap(pageNumber, pageSize, sql);
return Result.success(pagination);
}
@At
@SaCheckLogin
public Result info(String id) {
ProposalInfo info = proposalWriteService.fetch(id);
return Result.success(info);
}
@At
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("删除")
public Result delete(@Param("id") String id) {
proposalWriteService.delete(id);
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
return Result.success();
}
}
@@ -1,14 +1,18 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.result.Result;
import com.budwk.app.base.service.BaseService;
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.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.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
@@ -26,11 +30,13 @@ import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.util.List;
/**
* 团长审核
@@ -42,99 +48,78 @@ import javax.validation.Valid;
@Api(tags = "提案-办理-团长审核")
public class ProposalDelegationController {
@Inject
private BaseService baseService;
@Inject
private ProposalCommonService proposalCommonService;
@Inject
private ProposalDelegationService proposalDelegationService;
@Inject
private BpmService bpmService;
@At("")
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/delegation/index.html")
@SaCheckPermission("proposal.delegation")
@SaCheckLogin
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/delegation/form.html")
@SaCheckLogin
public void form() {
}
@At
@SaCheckPermission("proposal.delegation")
@ApiOperation("分页列表")
public Result pageData(@Valid ProposalSearchParam pageForm,boolean approval) {
@SaCheckPermission("proposal.seconded")
@SaCheckLogin
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.name AS typeName,
tcs.fullName AS sessionName,
tcd.`name` AS delegationName,
inst.id processInstanceId,
inst.processInstanceNodeId,
inst.processInstanceNodeName,
inst.processInstanceTaskIds,
inst.processInstanceStatus,
task.id processInstanceTaskId,
task.taskStatus processInstanceTaskStatus,
EXISTS (
SELECT 1
FROM bpm_process_task next_task
WHERE next_task.prevTaskId = task.id
AND next_task.taskStatus = 'COMPLETE'
) AS nextTaskIsComplete
SELECT
info.*,
type.name AS typeName,
tcs.fullName AS sessionName,
tcd.`name` AS delegationName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
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
bpm_process_task task
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId
LEFT JOIN proposal_type type on type.id = info.typeId
LEFT JOIN teacher_congress_session tcs ON tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
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
""");
Cnd cnd = Cnd.NEW();
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname())));
}
cnd.and("nd.nodeCode", "=", 30);
cnd.and("t.taskName", "=", "93d5ba64-8220-4e62-9783-83422f474b36");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE);
cnd.groupBy("info.id");
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE);
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
ProposalSearchParam.buildSearch(cnd, pageForm);
cnd.and(new Static("""
NOT EXISTS(
SELECT 1
FROM bpm_process_task t2
WHERE t2.processInstanceId = task.processInstanceId
AND t2.processTaskNodeCode = task.processTaskNodeCode
AND t2.createdOn > task.createdOn
)
"""));
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.createdAt");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class);
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();
Pagination<NutMap> pageVO = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
}
@@ -0,0 +1,150 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.validation.Valid;
import java.util.List;
@IocBean
@At("/platform/proposal/invite")
@Ok("json:full")
@Api("邀请附议人")
public class ProposalInviteController {
@Inject
private FlowEngine flowEngine;
@Inject
private ProposalCommonService proposalCommonService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/invite/index.html")
@SaCheckLogin
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/invite/form.html")
@SaCheckLogin
public void form() {
}
@At
@SaCheckPermission("proposal.seconded")
@SaCheckLogin
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.name AS typeName,
tcs.fullName AS sessionName,
tcd.`name` AS delegationName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
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
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
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
""");
Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "85b7b9bd-d706-48cb-99a1-ef1370fb1819");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.createdAt");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pageVO = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
@At
@SaCheckPermission("proposal.seconded")
@SaCheckLogin
@ApiOperation("查询附议人")
public Result listSeconder(@Valid PageForm pageForm, @Valid String proposalId, @Valid String sessionId,
String delegationId, boolean isInvite){
Sql sql = Sqls.create("""
SELECT
t1.userId,
t1.loginName,
t1.userName,
t1.sex,
t1.unitName,
t1.unionName,
t2.NAME AS delegationName
FROM
teacher_congress_delegate t1
LEFT JOIN teacher_congress_delegation t2 ON t2.id = t1.delegationId
$condition
""");
Cnd cnd = Cnd.where("t1.sessionId", "=", sessionId);
cnd.andEX("t1.delegationId", "=", delegationId);
cnd.and("t1.roleId","=","72e24b5b4c4f4e90a6641e6af8487e42");
cnd.and("t1.loginName", "!=", SecurityUtil.getUserLoginname());
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("t1.loginName", pageForm.getSearchKeyword());
seg.orLike("t1.userName", pageForm.getSearchKeyword());
cnd.and(seg);
}
sql.setCondition(cnd);
Pagination<NutMap> pageVO = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
}
@@ -1,19 +1,23 @@
package com.budwk.app.zhgh.democratic.proposal.controller.transact;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.result.Result;
import com.budwk.app.base.service.BaseService;
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.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.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalSecondedService;
import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService;
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -27,11 +31,13 @@ import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.util.List;
/**
* 附议提案
@@ -46,84 +52,76 @@ public class ProposalSecondedController {
@Inject
private Dao dao;
@Inject
private BaseService baseService;
@Inject
private ProposalCommonService proposalCommonService;
@Inject
private BpmService bpmService;
@Inject
private ProposalSecondedService proposalSecondedService;
@At("")
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/seconded/index.html")
@SaCheckPermission("proposal.seconded")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/democratic/proposal/transact/seconded/form.html")
@SaCheckPermission("proposal.seconded")
public void form() {
}
@At
@SaCheckPermission("proposal.seconded")
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.name AS typeName,
tcs.fullName AS sessionName,
tcd.`name` AS delegationName,
inst.id processInstanceId,
inst.processInstanceNodeId,
inst.processInstanceNodeName,
inst.processInstanceTaskIds,
inst.processInstanceStatus,
task.id processInstanceTaskId,
task.taskStatus processInstanceTaskStatus,
JSON_EXTRACT( task.createVariable, '$.userName' ) AS seconderName,
COUNT( nt.id ) OVER ( PARTITION BY task.id ) > 0 AS nextTaskIsComplete
SELECT
info.*,
type.name AS typeName,
tcs.fullName AS sessionName,
tcd.`name` AS delegationName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
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
bpm_process_task task
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId
INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId
LEFT JOIN proposal_type type on type.id = info.typeId
LEFT JOIN teacher_congress_session tcs ON tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId
LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE'
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN proposal_info info ON info.id = ins.businessNo
LEFT JOIN proposal_type type on type.id = info.typeId
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
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
""");
Cnd cnd = Cnd.NEW();
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname())));
}
cnd.and("nd.nodeCode", "=", 20);
if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE);
} else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE);
}
ProposalSearchParam.buildSearch(cnd, pageForm);
// cnd.and(new Static("""
// NOT EXISTS(
// 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);
Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class);
return Result.success(pagination);
}
cnd.and("t.taskName", "=", "74458b33-ad6e-46c4-b8d9-1aa897142b25");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
@At
@SaCheckPermission("proposal.seconded")
@ApiOperation("附议")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "提案", msg = "提案人附议")
public Result approval(@Valid @Param("approval") BpmTaskApprovalParam approvalParam) {
proposalSecondedService.approval(approvalParam);
return Result.success();
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.createdAt");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pageVO = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
}
@@ -0,0 +1,37 @@
package com.budwk.app.zhgh.democratic.proposal.controller.view;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import io.swagger.annotations.Api;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@IocBean
@At("/platform/proposal/view")
@Ok("json:full")
@Api("提案查看")
public class ProposalViewController {
@Inject
private Dao dao;
@At("/index")
@SaCheckLogin
@Ok("beetl:/platform/zhgh/democratic/proposal/view/index.html")
public void index(){
}
@At("/info")
@SaCheckLogin
public Result info(String id) {
ProposalInfo info = dao.fetch(ProposalInfo.class, id);
return Result.success(info);
}
}
@@ -0,0 +1,30 @@
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.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
/**
* 提案申请拦截器
*/
public class ProposalApplyInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
ProposalInfo info = Json.fromJson(ProposalInfo.class, formDataStr);
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));
}
}
File diff suppressed because one or more lines are too long
@@ -517,7 +517,7 @@ module.exports = {
top: 64px;
left: 0;
right: 0;
z-index: 1000;
z-index: 19000;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
@@ -1,7 +1,7 @@
<template>
<div class="snaker-task-action" v-if="!loading || taskInfo">
<!-- 指定下一节点处理人 -->
<div class="next-handler-section" v-if="!isFirstTaskNodeOrNew && supportCandidate">
<div class="next-handler-section" v-if="supportSpecifyNextHandler && candidates.length > 0">
<el-checkbox v-model="specifyNextHandler" @change="onSpecifyNextHandlerChange">指定下一节点处理人</el-checkbox>
<div class="handler-select-wrapper" v-if="specifyNextHandler">
<el-select v-model="selectedHandler" placeholder="请选择处理人" clearable filterable class="handler-select">
@@ -14,32 +14,44 @@
</div>
<!-- 第一个任务节点或新申请显示提交保存草稿取消 -->
<template v-if="isFirstTaskNodeOrNew">
<el-button type="primary" @click="handleSubmit" :loading="actionLoading" icon="el-icon-upload2">提交</el-button>
<!-- 保存草稿只在流程未发起时显示 -->
<el-button @click="handleSaveDraft" v-if="!actionLoading && show_save_draft && !instanceId" icon="el-icon-document">保存草稿</el-button>
<el-button @click="handleCancel" :loading="actionLoading" v-if="show_cancel" icon="el-icon-close">取消</el-button>
<!-- <template v-if="isFirstTaskNodeOrNew">-->
<!-- <el-button type="primary" @click="handleSubmit" :loading="actionLoading" icon="el-icon-upload2">提交</el-button>-->
<!-- &lt;!&ndash; 保存草稿只在流程未发起时显示 &ndash;&gt;-->
<!-- <el-button @click="handleSaveDraft" v-if="!actionLoading && show_save_draft && !instanceId" icon="el-icon-document">保存草稿</el-button>-->
<!-- <el-button @click="handleCancel" :loading="actionLoading" v-if="show_cancel" icon="el-icon-close">取消</el-button>-->
<!-- </template>-->
<!-- &lt;!&ndash; 其他任务节点显示审批按钮 &ndash;&gt;-->
<!-- <template v-else>-->
<!-- &lt;!&ndash; 会签任务按钮 &ndash;&gt;-->
<!-- <template v-if="is_countersign_task">-->
<!-- <el-button type="primary" @click="handleAction('AGREE')" :loading="actionLoading" icon="el-icon-check">同意</el-button>-->
<!-- <el-button type="danger" plain @click="handleAction('COUNTERSIGN_DISAGREE')" :loading="actionLoading" icon="el-icon-close">-->
<!-- 不同意-->
<!-- </el-button>-->
<!-- </template>-->
<!-- &lt;!&ndash; 普通任务按钮 &ndash;&gt;-->
<!-- <template v-else>-->
<!-- <el-button type="primary" @click="handleAction('AGREE')" :loading="actionLoading" icon="el-icon-check">同意</el-button>-->
<!-- <el-button type="danger" plain @click="handleAction('REJECT')" :loading="actionLoading" icon="el-icon-close">拒绝</el-button>-->
<!-- <el-button @click="handleAction('ROLLBACK')" :loading="actionLoading" icon="el-icon-back">退回上一步</el-button>-->
<!-- <el-button @click="handleAction('ROLLBACK_TO_OPERATOR')" :loading="actionLoading" icon="el-icon-d-arrow-left">退回发起人</el-button>-->
<!-- <el-button @click="handleAction('JUMP')" :loading="actionLoading" icon="el-icon-position">跳转</el-button>-->
<!-- </template>-->
<!-- </template>-->
<!--没有流程实例的时候-->
<template v-if="!instanceId">
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="handleSaveDraft">保存</el-button>
</template>
<!-- 其他任务节点显示审批按钮 -->
<template v-else>
<!-- 会签任务按钮 -->
<template v-if="is_countersign_task">
<el-button type="primary" @click="handleAction('AGREE')" :loading="actionLoading" icon="el-icon-check">同意</el-button>
<el-button type="danger" plain @click="handleAction('COUNTERSIGN_DISAGREE')" :loading="actionLoading" icon="el-icon-close">
不同意
</el-button>
</template>
<!-- 普通任务按钮 -->
<template v-else>
<el-button type="primary" @click="handleAction('AGREE')" :loading="actionLoading" icon="el-icon-check">同意</el-button>
<el-button type="danger" plain @click="handleAction('REJECT')" :loading="actionLoading" icon="el-icon-close">拒绝</el-button>
<el-button @click="handleAction('ROLLBACK')" :loading="actionLoading" icon="el-icon-back">退回上一步</el-button>
<el-button @click="handleAction('ROLLBACK_TO_OPERATOR')" :loading="actionLoading" icon="el-icon-d-arrow-left">退回发起人</el-button>
<el-button @click="handleAction('JUMP')" :loading="actionLoading" icon="el-icon-position">跳转</el-button>
</template>
</template>
<el-row type="flex" justify="end">
<el-button v-for="item in buttons" @click="handleAction(item.value)" :type="item.theme" :icon="item.icon" size="medium" :key="item.value">
{{ item.replacementText || item.originalText }}
</el-button>
</el-row>
</div>
<!-- 加载状态 -->
@@ -51,18 +63,7 @@
<script>
module.exports = {
name: "SnakerFlowTaskFormAction",
props: {
// 是否显示保存草稿按钮
show_save_draft: {
type: Boolean,
default: true
},
// 是否显示取消按钮
show_cancel: {
type: Boolean,
default: true
}
},
props: {},
data() {
return {
// 加载状态
@@ -116,6 +117,19 @@ module.exports = {
// 有任务ID但是任务信息中标识为第一个节点
return this.taskInfo && this.taskInfo.ext && this.taskInfo.ext.isFirstTaskNode
},
// 审批按钮配置
buttons() {
if (this.taskInfo) {
return this.taskInfo.taskModel.ext.buttonConfig.filter((v) => v.visible)
}
return []
},
// 是否支持选择下一步处理人
supportSpecifyNextHandler() {
return this.taskInfo && this.taskInfo.taskModel.ext.enableNextOperator
}
},
mounted() {
@@ -71,7 +71,7 @@
<script src="${base!}/assets/platform/plugins/form-create/form-create.min.js"></script>
<script src="${base!}/assets/platform/plugins/form-create/index.umd.js"></script>
<!-- <script src="${base!}/assets/platform/plugins/snaker/SnakerflowDesigner.umd.min.js"></script>-->
<!-- <script src="${base!}/assets/platform/plugins/snaker/SnakerflowDesigner.umd.min.js"></script>-->
<script src="${base!}/components/plugins/sysDict/DictData.js"></script>
<script src="${base!}/assets/platform/js/util/commonUtil.js"></script>
@@ -101,6 +101,11 @@
Vue.use(FcDesigner.formCreate)
</script>
<!--广播频道-->
<script type="text/javascript">
window.GlobalBroadcastChannel = new BroadcastChannel("zhgh-global-channel")
</script>
<!--ws-->
<script type="text/javascript">
class WebSocketPubSub {
@@ -334,12 +339,17 @@
Vue.component("excel-import", httpVueLoader("/components/plugins/sysImport/excelImport.vue?v=" + new Date().getTime()))
Vue.component("flow-form-button", httpVueLoader("/components/plugins/flowable/formButton.vue?v=" + new Date().getTime()))
Vue.component("snaker-flow", httpVueLoader("/components/plugins/snaker/snakerFlow.vue?v=" + new Date().getTime()))
Vue.component("snaker-flow-task-form-action", httpVueLoader("/components/plugins/snaker/snakerFlowTaskFormAction.vue?v=" + new Date().getTime()))
Vue.component("snaker-flow-history-approval", httpVueLoader("/components/plugins/snaker/snakerFlowHisApproval.vue?v=" + new Date().getTime()))
Vue.component(
"snaker-flow-task-form-action",
httpVueLoader("/components/plugins/snaker/snakerFlowTaskFormAction.vue?v=" + new Date().getTime())
)
Vue.component(
"snaker-flow-history-approval",
httpVueLoader("/components/plugins/snaker/snakerFlowHisApproval.vue?v=" + new Date().getTime())
)
</script>
<style>
.v4-header {
background-color: rgb(0, 109, 185);
box-shadow: 0 2px 10px rgba(0, 109, 185, 0.3);
@@ -347,9 +357,11 @@
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
position: fixed;
top: 0;
z-index: 100;
left: 0;
right: 0;
z-index: 20000;
overflow: hidden;
}
@@ -555,6 +567,10 @@
<i class="fa fa-th-large"></i>
应用中心
</a>
<a href="/platform/v4/serv" data-pjax class="v4-nav-item">
<i class="fa fa-th-large"></i>
服务中心
</a>
<a href="/flow/todoCenter" data-pjax class="v4-nav-item">
<i class="fa fa-th-large"></i>
待办中心
@@ -573,6 +589,7 @@
</div>
</div>
</header>
<div style="height: 64px"></div>
<main class="v4-content">
<!-- 页面内容区域 -->
@@ -1280,6 +1280,7 @@ layout("/layouts/v4/baseLayout.html"){
:key="activity.id"
:class="['v4-home-carousel-item', { active: currentIndex === index }]"
:style="{ backgroundImage: 'url(' + activity.cover + ')' }"
@click="enterActivity(activity)"
>
<div class="v4-home-carousel-info">
<div class="v4-home-carousel-title">{{activity.name}}</div>
@@ -1832,6 +1833,12 @@ layout("/layouts/v4/baseLayout.html"){
clearInterval(this.timer)
this.startTimer()
},
// 活动点击
enterActivity(act) {
window.open(act.url)
},
// 日历相关方法
prevMonth() {
if (this.currentMonth === 0) {
@@ -0,0 +1,18 @@
<!--#
layout("/layouts/v4/baseLayout.html"){
#-->
<div id="v4-home-app"></div>
<script>
var app = new Vue({
el: "#v4-home-app",
data() {
return {}
}
})
</script>
<!--#
}
#-->
@@ -120,11 +120,11 @@ layout("/layouts/platform.html"){
},
listCategory() {
// this.$axios.get("/platform/warmFlow/category/list").then((res) => {
// if (res.code === 0) {
// this.categoryOptions = res.data
// }
// })
this.$axios.post("/flow/category/list").then((res) => {
if (res.code === 0) {
this.categoryOptions = res.data
}
})
}
},
created() {
@@ -1,5 +1,5 @@
const assigneeForm = {
template: /*language=HTML*/`
var assigneeForm = {
template: /*language=HTML*/ `
<el-form-item label="参与者">
<div>
<!-- 模式选择 -->
@@ -148,15 +148,14 @@ const assigneeForm = {
this.assigneeText = this.model["assigneeText"] || ""
this.assigneeMode = this.model["assigneeMode"] || "manual"
if(this.assigneeMode === "initiator"){
if (this.assigneeMode === "initiator") {
this.assignee = "initiator"
this.assigneeText = "流程发起人"
}
if(this.assigneeMode === "manual"){
if (this.assigneeMode === "manual") {
this.manualInput = value || ""
}
},
handleModeChange() {
@@ -181,7 +180,7 @@ const assigneeForm = {
loadSelectUsers() {
let userIds = this.model[this.field].split(",")
$.get("/flow/design/assigneeEcho", { userIds: JSON.stringify(userIds) }).then(res => {
$.get("/flow/design/assigneeEcho", { userIds: JSON.stringify(userIds) }).then((res) => {
if (res.code === 0) {
this.selectedUsers = res.data
this.loadUsers()
@@ -192,7 +191,7 @@ const assigneeForm = {
loadUsers() {
$.get("/flow/design/assigneePage", {
...this.pageForm
}).then(res => {
}).then((res) => {
if (res.code === 0) {
this.userList = res.data.list
this.pageForm.totalCount = res.data.totalCount
@@ -207,19 +206,18 @@ const assigneeForm = {
// 设置表格选中数据
setTableSelection() {
// 如果当前表格中有该用户,选中TA
this.userList.forEach(row => {
const exist = this.selectedUsers.map(item => item.id).includes(row.id)
this.userList.forEach((row) => {
const exist = this.selectedUsers.map((item) => item.id).includes(row.id)
if (exist) {
this.$refs.userTableRef.toggleRowSelection(row, true)
}
})
},
confirmSelection() {
const selection = this.$refs.userTableRef.selection
this.assignee = selection.map(item => item.id).join(",")
this.assigneeText = selection.map(item => item.username).join(",")
this.assignee = selection.map((item) => item.id).join(",")
this.assigneeText = selection.map((item) => item.username).join(",")
this.updateModelValue()
this.dialogVisible = false
},
@@ -251,4 +249,4 @@ const assigneeForm = {
this.loadUsers()
}
}
}
}
@@ -0,0 +1,120 @@
var buttonConfig = {
template: /*language=HTML*/ `
<el-form-item label="按钮配置">
{{model}}
<el-table :data="model['buttonConfig']" style="width: 100%" border>
<!-- <el-table-column prop="value" label="值" width="120">-->
<!-- <template slot-scope="{ row }">-->
<!-- <el-input v-model="row.value" disabled></el-input>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column prop="originalText" label="原始文本" width="100"></el-table-column>
<el-table-column prop="replacementText" label="替换文本">
<template slot-scope="{ row }">
<el-input v-model="row.replacementText" :disabled="row.disabled"></el-input>
</template>
</el-table-column>
<el-table-column prop="theme" label="主题">
<template slot-scope="{ row }">
<el-select v-model="row.theme" placeholder="请选择" :disabled="row.disabled">
<el-option label="primary" value="primary"></el-option>
<el-option label="success" value="success"></el-option>
<el-option label="warning" value="warning"></el-option>
<el-option label="danger" value="danger"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="icon" label="图标" width="100">
<template slot-scope="{ row }">
<el-input v-model="row.icon" placeholder="请输入图标名称" :disabled="row.disabled"></el-input>
</template>
</el-table-column>
<el-table-column prop="visible" label="是否可见" width="100">
<template slot-scope="{ row }">
<el-switch v-model="row.visible" :disabled="row.disabled"></el-switch>
</template>
</el-table-column>
</el-table>
</el-form-item>
`,
props: {
model: {
type: Object,
required: true
}
// field: {
// type: String,
// required: true
// }
},
data() {
return {
tableData: [],
button: {},
defaultConfig: [
{ value: 0, originalText: "发起申请" },
{ value: 1, originalText: "同意申请" },
{ value: 2, originalText: "拒绝申请" },
{ value: 3, originalText: "退回上一步" },
{ value: 4, originalText: "跳转" },
{ value: 5, originalText: "重新提交" },
{ value: 6, originalText: "退回发起人" },
{ value: 20, originalText: "会签拒绝申请" }
]
}
},
watch: {
"model.buttonConfig": {
handler(val) {
this.$set(this.model, "buttonConfig", val)
},
deep: true
},
"model.performType": {
handler(val) {
if (val === "ALL") {
// 会签只有同意不同意
this.$set(this.model, "buttonConfig", [
{ value: 1, originalText: "同意", visible: true, disabled: true },
{ value: 20, originalText: "不同意", visible: true, disabled: true }
])
} else {
// 普通任务
// const visibleConfigs = this.model.buttonConfig.filter((item) => item.visible)
// if (visibleConfigs.length) {
// this.$set(this.model, "buttonConfig", visibleConfigs)
// } else {
// this.$set(this.model, "buttonConfig", [
// { value: 1, originalText: "同意", visible: true, disabled: false },
// { value: 2, originalText: "拒绝", visible: true, disabled: false },
// { value: 3, originalText: "退回上一步", visible: true, disabled: false },
// { value: 4, originalText: "跳转", visible: true, disabled: false },
// { value: 6, originalText: "退回发起人", visible: true, disabled: false }
// ])
// }
}
},
deep: true
},
"model.name": {
handler(val) {
if (val === "startTask") {
// 申请只有发起申请
this.$set(this.model, "buttonConfig", [{ value: 0, originalText: "提交", visible: true, disabled: false }])
}
},
deep: true,
immediate: true
}
},
methods: {
init() {
if (this.model["buttonConfig"] === undefined) {
this.$set(this.model, "buttonConfig", this.defaultConfig)
}
}
},
created() {
this.init()
}
}
@@ -35,7 +35,9 @@
'candidateGroups',
'candidateHandler',
'assigneeText',
'assigneeMode'
'assigneeMode',
'buttonConfig',
'enableNextOperator'
]"
>
<!-- <template v-slot:form-item-task-form="{model,field}">-->
@@ -74,6 +76,14 @@
</el-form-item>
</template>
<template v-slot="{model,field}">
<el-form-item label="指定下一步处理人">
<el-checkbox v-model="model['enableNextOperator']">指定下一步处理人</el-checkbox>
</el-form-item>
<button-config :model="model" :field="field"></button-config>
</template>
<!-- <template v-slot="{model,field}">-->
<!-- <el-form-item label="表单查看URL">-->
<!-- <el-input v-model="model[instanceViewUrl]"></el-input>-->
@@ -84,12 +94,14 @@
</body>
<script>
<!--#include('assigneeForm.js'){}#-->
<!--#include('buttonConfig.js'){}#-->
Vue.use(SnakerflowDesigner.default)
const vue = new Vue({
el: "#app",
components: {
"assignee-form": assigneeForm
"assignee-form": assigneeForm,
"button-config": buttonConfig
},
data() {
return {
@@ -204,11 +204,11 @@ layout("/layouts/platform.html"){
},
listCategory() {
// this.$axios.get("/platform/warmFlow/category/list").then((res) => {
// if (res.code === 0) {
// this.categoryOptions = res.data
// }
// })
this.$axios.post("/flow/category/list").then((res) => {
if (res.code === 0) {
this.categoryOptions = res.data
}
})
}
},
created() {
@@ -1,89 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="名称">
<el-input v-model="pageForm.flowName" placeholder="名称" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button type="primary" @click="onAdd" size="small" icon="el-icon-plus">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column prop="flowName" label="流程定义名称"></el-table-column>
<el-table-column prop="flowCode" label="流程定义编码"></el-table-column>
<el-table-column prop="categoryName" label="流程分类"></el-table-column>
<el-table-column prop="version" label="版本号"></el-table-column>
<el-table-column prop="activityStatus" label="激活状态">
<template slot-scope="{row}">
<el-tag size="mini" v-if="row.activityStatus===1" type="success">激活</el-tag>
<el-tag size="mini" v-else-if="row.activityStatus===0" type="info">挂起</el-tag>
</template>
</el-table-column>
<el-table-column prop="isPublish" label="发布状态">
<template slot-scope="{row}">
<el-tag size="mini" v-if="row.isPublish===0" type="info">未发布</el-tag>
<el-tag size="mini" v-else-if="row.isPublish===1" type="success">已发布</el-tag>
<el-tag size="mini" v-else-if="row.isPublish===9" type="info">失效</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="250px">
<template slot-scope="{row}">
<el-button type="text" size="mini" @click="onDesign(row)">设计</el-button>
<el-button type="text" size="mini" @click="onView(row)">查看</el-button>
<el-button v-if="row.isPublish !== 1" type="text" size="mini" @click="onPublish(row)">发布</el-button>
<el-button type="text" size="mini" @click="onDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</guava>
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="800px">
<el-form :model="formData" ref="formRef" label-width="120px">
<el-form-item label="流程定义名称" prop="flowName" :rules="{ required: true, message: '请输入流程定义名称', trigger: 'blur' }">
<el-input v-model="formData.flowName" placeholder="请输入流程定义名称"></el-input>
</el-form-item>
<el-form-item label="流程定义编码" prop="flowCode" :rules="{ required: true, message: '请输入流程定义编码', trigger: 'blur' }">
<el-input v-model="formData.flowCode" placeholder="请输入流程定义编码"></el-input>
</el-form-item>
<el-form-item label="流程分类" prop="categoryId">
<el-select v-model="formData.categoryId" placeholder="请选择流程分类" clearable>
<el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
dialogVisible: false
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -1,195 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.design-dialog .el-dialog__body {
padding: 0;
}
</style>
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="是否发布">
<el-select v-model="pageForm.isPublish" placeholder="请选择是否发布" clearable style="width: 100%">
<el-option label="全部" :value="null"></el-option>
<el-option label="已发布" :value="true"></el-option>
<el-option label="未发布" :value="false"></el-option>
</el-select>
</search-item>
<search-item label="名称">
<el-input v-model="pageForm.flowName" placeholder="名称" clearable></el-input>
</search-item>
<search-item label="编码">
<el-input v-model="pageForm.flowCode" placeholder="编码" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button type="primary" @click="onAdd" size="small" icon="el-icon-plus">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column prop="flowName" label="流程定义名称"></el-table-column>
<el-table-column prop="flowCode" label="流程定义编码"></el-table-column>
<el-table-column prop="categoryName" label="流程分类">
<template slot-scope="{row}">{{categoryOptions.find(item => item.id === row.category)?.categoryName}}</template>
</el-table-column>
<el-table-column prop="version" label="版本号"></el-table-column>
<el-table-column prop="activityStatus" label="激活状态">
<template slot-scope="{row}">
<el-tag size="mini" v-if="row.activityStatus===1" type="success">激活</el-tag>
<el-tag size="mini" v-else-if="row.activityStatus===0" type="info">挂起</el-tag>
</template>
</el-table-column>
<el-table-column prop="isPublish" label="发布状态">
<template slot-scope="{row}">
<el-tag size="mini" v-if="row.isPublish===0" type="info">未发布</el-tag>
<el-tag size="mini" v-else-if="row.isPublish===1" type="success">已发布</el-tag>
<el-tag size="mini" v-else-if="row.isPublish===9" type="info">失效</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="250px">
<template slot-scope="{row}">
<el-button v-if="row.isPublish !== 1" type="text" size="mini" @click="onDesign(row)">设计</el-button>
<el-button type="text" size="mini" @click="onView(row)">查看</el-button>
<el-button v-if="row.isPublish !== 1" type="text" size="mini" @click="onPublish(row)">发布</el-button>
<el-button type="text" size="mini" @click="onDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</guava>
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="800px">
<el-form :model="formData" ref="formRef" label-width="120px">
<el-form-item label="流程定义名称" prop="flowName" :rules="{ required: true, message: '请输入流程定义名称', trigger: 'blur' }">
<el-input v-model="formData.flowName" placeholder="请输入流程定义名称"></el-input>
</el-form-item>
<el-form-item label="流程定义编码" prop="flowCode" :rules="{ required: true, message: '请输入流程定义编码', trigger: 'blur' }">
<el-input v-model="formData.flowCode" placeholder="请输入流程定义编码"></el-input>
</el-form-item>
<el-form-item label="流程分类" prop="category" :rules="{ required: true, message: '请选择流程分类', trigger: 'change' }">
<el-select v-model="formData.category" placeholder="请选择流程分类" clearable>
<el-option v-for="item in categoryOptions" :key="item.id" :label="item.categoryName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</el-dialog>
<el-dialog title="流程设计" :visible.sync="designVisible" fullscreen class="design-dialog">
<div style="height: calc(100vh - 55px); width: 100%">
<iframe v-if="designVisible" :src="designUrl" frameborder="0" height="100%" style="height: 100%; width: inherit"></iframe>
</div>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
dialogVisible: false,
categoryOptions: [],
designVisible: false,
designUrl: null
}
},
methods: {
onAdd() {
this.formData = {}
this.dialogVisible = true
},
onDesign(row, disabled = false) {
this.designVisible = true
this.iframeLoaded()
this.designUrl = "/warm-flow-ui/index.html?id=" + row.id + "&disabled=" + disabled
},
iframeLoaded() {
// iframe监听组件内设计器保存事件
window.onmessage = (event) => {
switch (event.data.method) {
case "close":
close()
break
}
}
},
onDelete(row) {
this.$confirm("是否确认删除流程定义编码为【" + row.flowCode + "】版本为【" + row.version + "】的数据项?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/warmFlow/definition/delete", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.message)
this.pageData()
}
})
})
},
onView(row) {},
// 发布
onPublish(row) {
this.$confirm(
"是否确认发布流程定义编码为【" + row.flowCode + "】版本为【" + row.version + "】的数据项?,发布后会将已发布流程定义改为失效!",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(() => {
this.$axios.post("/platform/warmFlow/definition/publish", { id: row.id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.message)
this.pageData()
}
})
})
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/warmFlow/definition/" + (this.formData.id ? "update" : "insert"), this.formData).then((res) => {
if (res.code === 0) {
this.dialogVisible = false
this.$message.success(res.message)
this.pageData()
}
})
}
})
},
listCategory() {
this.$axios.get("/platform/warmFlow/category/list").then((res) => {
if (res.code === 0) {
this.categoryOptions = res.data
}
})
}
},
created() {
this.pageData()
this.listCategory()
}
})
</script>
<!--#
}
#-->
@@ -1,586 +0,0 @@
<!--#
layout("/layouts/v4/baseLayout.html"){
#-->
<div id="app" v-cloak>
<div class="task-todo-center">
<!-- 统计数据区域 -->
<el-row :gutter="20" class="statistics-section">
<el-col :span="8">
<el-card shadow="hover" class="stat-card">
<div class="stat-content">
<div class="stat-icon todo-icon">
<i class="el-icon-s-claim"></i>
</div>
<div class="stat-info">
<div class="stat-value">{{todoCount}}</div>
<div class="stat-label">待办任务</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="stat-card">
<div class="stat-content">
<div class="stat-icon done-icon">
<i class="el-icon-finished"></i>
</div>
<div class="stat-info">
<div class="stat-value">{{doneCount}}</div>
<div class="stat-label">已办任务</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="stat-card">
<div class="stat-content">
<div class="stat-icon started-icon">
<i class="el-icon-s-promotion"></i>
</div>
<div class="stat-info">
<div class="stat-value">{{startedCount}}</div>
<div class="stat-label">我发起的</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 搜索筛选区域 -->
<el-card shadow="never" class="filter-section">
<el-form :inline="true" :model="searchForm" class="search-form">
<el-form-item>
<el-input v-model="searchForm.keyword" placeholder="请输入关键词搜索" prefix-icon="el-icon-search" clearable></el-input>
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.processType" placeholder="所有流程类型" clearable>
<el-option v-for="type in processTypes" :key="type.value" :label="type.label" :value="type.value"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search">搜索</el-button>
<el-button @click="reset">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 任务列表区域 -->
<el-card shadow="never" class="task-section">
<div slot="header" class="task-header">
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane label="待办任务" name="todo"></el-tab-pane>
<el-tab-pane label="已办任务" name="done"></el-tab-pane>
<el-tab-pane label="我发起的" name="started"></el-tab-pane>
</el-tabs>
</div>
<!-- 表格展示 -->
<el-table
v-loading="loading"
:data="tasks"
style="width: 100%"
:key="activeTab"
:header-cell-style="{backgroundColor: '#f5f7fa'}"
:row-class-name="tableRowClassName"
>
<el-table-column prop="processInstanceName" label="流程名称" min-width="180" show-overflow-tooltip>
<template slot-scope="{row}">
<span class="task-title">{{row.instance_ext?.instanceName}}</span>
</template>
</el-table-column>
<el-table-column prop="node_name" label="任务节点" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">
<div v-if="activeTab === 'todo'">{{scope.row.node_name}}</div>
<div v-else-if="activeTab === 'done'">{{scope.row.node_name}}</div>
<div v-else-if="activeTab === 'started'">{{scope.row.assigneeInfo}}</div>
</template>
</el-table-column>
<el-table-column prop="processDefinitionName" label="流程类型" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">{{scope.row.processDefinitionName || scope.row.processType}}</template>
</el-table-column>
<el-table-column prop="instance_ext.initiatorUserName" label="申请人" min-width="120">
<template slot-scope="{row}">{{row.instance_ext?.initiatorUserName}} ({{row.instance_ext?.initiatorLoginName}})</template>
</el-table-column>
<el-table-column label="时间" min-width="180">
<template slot-scope="scope">
<div v-if="activeTab === 'todo'">
<i class="el-icon-time"></i>
{{scope.row.create_time}}
</div>
<div v-else-if="activeTab === 'done'">
<i class="el-icon-check"></i>
{{scope.row.update_time}}
</div>
<div v-else-if="activeTab === 'started'">
<i class="el-icon-s-promotion"></i>
{{scope.row.create_time}}
</div>
</template>
</el-table-column>
<el-table-column v-if="activeTab === 'started'" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row)" size="small" effect="light">{{scope.row.status || '进行中'}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="250" fixed="right">
<template slot-scope="scope">
<el-button v-if="activeTab === 'todo'" type="primary" size="mini" @click="handleTask(scope.row)">处理</el-button>
<el-button type="info" size="mini" @click="viewTaskDetail(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!-- 空状态展示 -->
<el-empty v-if="tasks.length === 0" :description="getEmptyText()"></el-empty>
<!-- 分页 -->
<div class="pagination-container" v-if="tasks.length > 0">
<el-pagination
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-size="pageSize"
layout="prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</el-card>
<!-- 任务详情对话框 -->
<el-dialog title="任务详情" :visible.sync="dialogVisible" width="600px" :close-on-click-modal="false">
<div v-if="currentTask" class="task-detail">
<el-descriptions :column="1" border>
<el-descriptions-item label="流程名称">{{currentTask.processInstanceName || currentTask.title}}</el-descriptions-item>
<el-descriptions-item label="任务名称">{{currentTask.taskName || '-'}}</el-descriptions-item>
<el-descriptions-item label="流程类型">{{currentTask.processDefinitionName || currentTask.processType}}</el-descriptions-item>
<el-descriptions-item label="申请人">{{currentTask.applyUserName || '-'}}</el-descriptions-item>
<el-descriptions-item label="申请部门">{{currentTask.applyUserUnitId || '-'}}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{currentTask.createTime}}</el-descriptions-item>
<el-descriptions-item v-if="currentTask.description" label="任务描述">
<div class="description-content">{{currentTask.description}}</div>
</el-descriptions-item>
<el-descriptions-item v-if="currentTask.taskMobileFormUrl" label="表单链接">
<el-link type="primary" :href="currentTask.taskMobileFormUrl" target="_blank">点击查看详细表单</el-link>
</el-descriptions-item>
</el-descriptions>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button v-if="activeTab === 'todo'" type="primary" @click="handleTask(currentTask)">处理任务</el-button>
</span>
</el-dialog>
</div>
</div>
<style>
.task-todo-center {
padding: 20px;
}
/* 统计卡片样式 */
.statistics-section {
margin-bottom: 20px;
}
.stat-card {
border: none;
height: 100%;
}
.stat-card .el-card__body {
padding: 20px;
}
.stat-content {
display: flex;
align-items: center;
}
.stat-icon {
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
font-size: 28px;
}
.todo-icon {
background-color: rgba(64, 158, 255, 0.1);
color: #409eff;
}
.done-icon {
background-color: rgba(103, 194, 58, 0.1);
color: #67c23a;
}
.started-icon {
background-color: rgba(230, 162, 60, 0.1);
color: #e6a23c;
}
.stat-info {
flex: 1;
}
.stat-value {
font-size: 28px;
font-weight: 600;
line-height: 1.2;
margin-bottom: 5px;
}
.stat-label {
font-size: 14px;
color: #909399;
}
/* 搜索区域样式 */
.filter-section {
margin-bottom: 20px;
}
.filter-section .el-card__body {
padding: 15px 20px;
}
.search-form {
display: flex;
flex-wrap: wrap;
}
.search-form .el-form-item {
margin-bottom: 0;
margin-right: 15px;
}
/* 任务列表区域样式 */
.task-section .el-card__header {
padding: 0;
border-bottom: none;
}
/* 优化后的 tabs 样式 */
.task-header .el-tabs__header {
margin: 0;
padding: 0 20px;
background-color: #fff;
}
.task-header .el-tabs__nav-wrap::after {
height: 1px;
background-color: #ebeef5;
}
.task-header .el-tabs__item {
height: 50px;
line-height: 50px;
font-size: 15px;
color: #606266;
padding: 0 20px;
transition: all 0.3s;
}
.task-header .el-tabs__item.is-active {
color: #409eff;
font-weight: 500;
}
.task-header .el-tabs__active-bar {
height: 3px;
border-radius: 3px;
}
.task-title {
font-weight: 500;
color: #303133;
}
/* 表格行样式 */
.el-table .hover-row {
background-color: #f5f7fa;
}
/* 优化后的分页样式 */
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: center;
padding: 10px 0;
}
.pagination-container .el-pagination {
padding: 0;
font-weight: normal;
display: flex;
align-items: center;
}
.pagination-container .el-pagination .btn-prev,
.pagination-container .el-pagination .btn-next {
background-color: #f4f6f8;
color: #606266;
border-radius: 4px;
padding: 0 10px;
height: 32px;
line-height: 32px;
margin: 0 5px;
}
.pagination-container .el-pagination .btn-prev:hover,
.pagination-container .el-pagination .btn-next:hover {
color: var(--color-primary);
background-color: #ecf5ff;
}
.pagination-container .el-pagination .el-pager li {
background-color: #f4f6f8;
color: #606266;
border-radius: 4px;
min-width: 32px;
height: 32px;
line-height: 32px;
margin: 0 3px;
font-weight: normal;
transition: all 0.3s;
}
.pagination-container .el-pagination .el-pager li:hover {
color: var(--color-primary);
background-color: #ecf5ff;
}
.pagination-container .el-pagination .el-pager li.active {
background-color: var(--color-primary);
color: #fff;
font-weight: bold;
}
.pagination-container .el-pagination .el-pagination__jump {
margin-left: 15px;
color: #606266;
}
.pagination-container .el-pagination .el-pagination__editor.el-input {
width: 50px;
margin: 0 5px;
}
.pagination-container .el-pagination .el-pagination__editor.el-input .el-input__inner {
height: 28px;
border-radius: 4px;
}
/* 任务详情样式 */
.task-detail .el-descriptions {
margin-bottom: 20px;
}
.description-content {
background-color: #f5f7fa;
padding: 10px;
border-radius: 4px;
white-space: pre-wrap;
}
</style>
<script>
new Vue({
el: "#app",
data() {
return {
// 统计数据
todoCount: 0,
doneCount: 0,
startedCount: 0,
// 搜索表单
searchForm: {
keyword: "",
processType: ""
},
// 流程类型选项
processTypes: [],
// 任务列表
tasks: [],
loading: false,
// 分页
currentPage: 1,
pageSize: 10,
total: 0,
// 标签页
activeTab: "todo",
// 当前任务
currentTask: null,
dialogVisible: false
}
},
computed: {
totalPages() {
return Math.ceil(this.total / this.pageSize)
}
},
created() {
this.initData()
},
methods: {
// 初始化数据
async initData() {
await Promise.all([this.getStatistics(), this.getProcessTypes(), this.getTasks()])
},
// 获取统计数据
async getStatistics() {
try {
const res = await $.post("/platform/warmFlow/todoCenter/statistics")
if (res.code === 0) {
const { todoCount, doneCount, startedCount } = res.data
this.todoCount = todoCount
this.doneCount = doneCount
this.startedCount = startedCount
}
} catch (error) {
this.$message.error("获取统计数据失败")
console.error("获取统计数据失败:", error)
}
},
// 获取流程类型
async getProcessTypes() {
try {
const res = await $.post("/platform/workflow/todoCenter/process/types")
if (res.code === 0) {
this.processTypes = res.data
}
} catch (error) {
this.$message.error("获取流程类型失败")
console.error("获取流程类型失败:", error)
}
},
// 获取任务列表
async getTasks() {
this.loading = true
try {
const params = {
page: this.currentPage,
pageSize: this.pageSize,
type: this.activeTab,
keyword: this.searchForm.keyword,
processType: this.searchForm.processType
}
const res = await $.post("/platform/warmFlow/todoCenter/" + this.activeTab, params)
if (res.code === 0) {
this.tasks = res.data.list
this.total = res.data.totalCount
this.dialogVisible = false
}
} catch (error) {
this.$message.error("获取任务列表失败")
console.error("获取任务列表失败:", error)
} finally {
this.loading = false
}
},
// 处理标签页点击
handleTabClick(tab) {
this.activeTab = tab.name
this.currentPage = 1
this.getTasks()
},
// 搜索
search() {
this.currentPage = 1
this.getTasks()
this.getStatistics()
},
// 重置搜索
reset() {
this.searchForm = {
keyword: "",
processType: ""
}
this.search()
},
// 处理页码变化
handleCurrentChange(val) {
this.currentPage = val
this.getTasks()
},
// 查看任务详情
viewTaskDetail(task) {
this.currentTask = task
this.dialogVisible = true
},
// 处理任务
async handleTask(task) {
if (!task) return
// 如果有表单链接,直接跳转
if (task.taskMobileFormUrl) {
window.open(task.taskMobileFormUrl, "_blank")
return
}
},
// 获取状态对应的类型
getStatusType(task) {
if (!task.status) return "info"
switch (task.status) {
case "审批中":
return "primary"
case "已完成":
return "success"
case "已通过":
return "success"
case "已拒绝":
return "danger"
default:
return "info"
}
},
// 获取空状态文本
getEmptyText() {
switch (this.activeTab) {
case "todo":
return "您当前没有需要办理的任务,辛苦了"
case "done":
return "您当前没有已办理的任务记录"
case "started":
return "您当前没有发起的流程"
default:
return "暂无数据"
}
},
// 表格行类名
tableRowClassName({ row, rowIndex }) {
return ""
}
}
})
</script>
<!--#
}
#-->
@@ -1,115 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="流程实例">
<el-button size="small" type="primary" icon="el-icon-plus" @click="onOpen">新增</el-button>
</table-tool>
<el-table
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
ref="tableRef"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
>
<el-table-column
:key="column.prop"
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
></el-table-column>
<el-table-column label="操作" width="150px" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="onEdit(scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="onDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogVisible" width="60%">
<el-form ref="formRef" :model="formData" label-width="80px">
<el-form-item label="名称" prop="name" :rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
<el-input v-model="formData.name" maxlength="100" placeholder="请输入名称" show-word-limit></el-input></el-input>
</el-form-item>
<el-form-item label="表达式" prop="expression" :rules="[{ required: true, message: '请输入表达式', trigger: 'blur' }]">
<el-input v-model="formData.expression" maxlength="255" placeholder="请输入表达式" show-word-limit></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="onSave">保存</el-button>
</div>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{ label: "名称", prop: "name" },
{ label: "表达式", prop: "expression" },
{ label: "创建时间", prop: "createdBy" }
],
dialogVisible: false
}
},
methods: {
onSave() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/workflow/expression/" + (this.formData.id ? "update" : "save"), this.formData).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.pageData()
}
})
}
})
},
onOpen() {
this.dialogVisible = true
this.formData = {}
},
onEdit(row) {
this.dialogVisible = true
this.formData = { ...row }
},
onDelete(id){
this.$confirm('确定要删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$axios.post('/platform/workflow/expression/delete', {id}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
}).catch(() => {})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -1,48 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>1流程设计器 - JeecgBoot低代码平台</title>
</head>
<body>
<div id="app" style="padding-top: 1px">
<vue-bpmn-designer ref="FlowDesigner" :is-add="true" token="" style="overflow: hidden"></vue-bpmn-designer>
</div>
</body>
<script>
window._CONFIG = {
domianURL: "http://localhost:8080/"
}
</script>
<script src="https://api3.boot.jeecg.com/desflow/vue/polyfill.min.js?v=1749544752.10"></script>
<script src="https://api3.boot.jeecg.com/desflow/vue/vue.min.js?v=1749544752.10"></script>
<script src="https://api3.boot.jeecg.com/desflow/moment/moment-with-locales.min.js?v=1749544752.10"></script>
<script src="https://api3.boot.jeecg.com/desflow/antd/antd-with-locales.js?v=1749544752.10"></script>
<link rel="stylesheet" href="https://api3.boot.jeecg.com/desflow/antd/antd.css?v=1749544752.10" />
<link rel="stylesheet" href="https://api3.boot.jeecg.com/desflow/lib/index.css?v=1749544752.10" />
<script src="/assets/platform/plugins/bpmn-designer/index.umd.min.js?v=1.0.1"></script>
<script>
new Vue({
el: "#app",
data() {
return {
processId: "${modelId!}",
category: "${category!}"
}
},
methods: {},
mounted: function () {
console.log(this.processId)
this.$refs.FlowDesigner.show({
processId: this.processId,
typeid: this.category
})
console.log(this.processId)
}
})
</script>
<script></script>
</html>
@@ -1,229 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="流程定义">
<el-button size="small" type="primary" icon="el-icon-plus" @click="openDesigner()">新建流程模型</el-button>
</table-tool>
<el-table
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
ref="tableRef"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
>
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
<el-table-column
:key="column.prop"
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='deploymentId'">
<el-tag v-if="row.deploymentId" size="mini">已部署</el-tag>
<el-tag v-else size="mini">未部署</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="400px" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="openDesigner(scope.row)">设计</el-button>
<el-button size="mini" type="primary" @click="deploy(scope.row.id)">部署</el-button>
<el-button size="mini" type="info" @click="showHistory(scope.row)">历史版本</el-button>
<el-button size="mini" type="danger" @click="onDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog title="流程设计" :visible.sync="dialogVisible" fullscreen>
<div style="height: calc(100vh - 115px)">
<iframe
:src="designerUrl"
v-if="dialogVisible"
frameborder="0"
scrolling="auto"
allowtransparency="true"
allowfullscreen="true"
width="100%"
height="100%"
></iframe>
</div>
</el-dialog>
<!-- 历史版本对话框 -->
<el-dialog title="历史版本" :visible.sync="historyDialogVisible" width="60%">
<el-table :data="historyVersions" style="width: 100%" v-loading="historyLoading">
<el-table-column label="版本号" prop="version" width="100" align="center"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="创建时间" prop="createTime" width="180"></el-table-column>
<el-table-column label="最后更新时间" prop="lastUpdateTime" width="180"></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="viewHistoryXml(scope.row)">查看XML</el-button>
<el-button size="mini" type="success" @click="restoreVersion(scope.row)" :disabled="currentModel.version === scope.row.version">恢复</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- 查看XML对话框 -->
<el-dialog title="模型XML" :visible.sync="xmlDialogVisible" width="80%">
<pre v-if="modelXml" style="max-height: 500px; overflow: auto;">{{ modelXml }}</pre>
<div v-else>加载中...</div>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
tableColumns: [
{ label: "名称", prop: "name" },
{ label: "Key", prop: "key" },
{ label: "分类", prop: "category" },
{ label: "是否部署", prop: "deploymentId" },
{ label: "版本", prop: "version" },
{ label: "创建时间", prop: "createTime" }
],
dialogVisible: false,
designerUrl: "/platform/workflow/process/definition' + modelId",
historyDialogVisible: false,
historyVersions: [],
historyLoading: false,
currentModel: {},
xmlDialogVisible: false,
modelXml: ""
}
},
methods: {
openDesigner(row = null) {
this.dialogVisible = true
if (row) {
this.designerUrl = "/platform/workflow/designer?modelId=" + row.id + "&category=" + row.category
} else {
this.designerUrl = "/platform/workflow/designer?modelId=&category="
}
},
deploy(modelId) {
this.$confirm("确定要部署吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$axios.post("/platform/workflow/model/deploy", { modelId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
.catch(() => {})
},
onDelete(modelId) {
this.$confirm("确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$axios.post("/platform/workflow/model/delete", { modelId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
.catch(() => {})
},
// 显示历史版本
showHistory(row) {
this.currentModel = row;
this.historyDialogVisible = true;
this.historyLoading = true;
// 调用后端接口获取历史版本
this.$axios.get("/platform/workflow/model/history", {
params: { modelKey: row.key }
}).then(res => {
if (res.code === 0) {
this.historyVersions = res.data;
} else {
this.$message.error(res.msg || "获取历史版本失败");
}
this.historyLoading = false;
}).catch(() => {
this.historyLoading = false;
this.$message.error("获取历史版本失败");
});
},
// 查看历史版本XML
viewHistoryXml(row) {
this.xmlDialogVisible = true;
this.modelXml = "加载中...";
this.$axios.get("/platform/workflow/model/history/xml", {
params: { modelId: row.id }
}).then(res => {
this.modelXml = res.data;
}).catch(() => {
this.modelXml = "加载失败";
this.$message.error("获取模型XML失败");
});
},
// 恢复历史版本
restoreVersion(row) {
this.$confirm('确定要恢复到版本'+row.version+'吗?', "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
// 获取历史版本的XML
this.$axios.get("/platform/workflow/model/history/xml", {
params: { modelId: row.id }
}).then(xml => {
// 使用历史版本的XML保存为新版本
this.$axios.post("/platform/workflow/model/save", {
modelId: this.currentModel.id,
processName: this.currentModel.name,
processKey: this.currentModel.key,
category: this.currentModel.category,
bpmnXml: xml
}).then(res => {
if (res.success) {
this.$message.success("版本恢复成功");
this.historyDialogVisible = false;
this.pageData();
} else {
this.$message.error(res.msg || "版本恢复失败");
}
}).catch(() => {
this.$message.error("版本恢复失败");
});
}).catch(() => {
this.$message.error("获取历史版本XML失败");
});
}).catch(() => {});
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -1,123 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="流程定义"></table-tool>
<el-table
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
ref="tableRef"
row-key="id"
style="width: 100%"
v-loading="tableLoading"
>
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
<el-table-column
:key="column.prop"
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
:width="column.width"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template scope="{row}" v-if="column.prop=='suspended'">
<el-tag v-if="row.suspended" size="mini" type="info">已挂起</el-tag>
<el-tag v-else size="mini" type="success">已激活</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200px" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="openVersion(scope.row)">版本管理</el-button>
<el-button size="mini" type="primary" @click="openNodeConfig(scope.row)">配置</el-button>
<!-- <el-button size="mini" type="primary" @click="activate(scope.row.id)">激活</el-button>-->
<!-- <el-button size="mini" type="danger" @click="suspend(scope.row.id)">挂起</el-button>-->
<!-- <el-button size="mini" type="danger" @click="onDelete(scope.row.deploymentId)">删除</el-button>-->
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog title="流程设计" :visible.sync="dialogVisible" width="80%">
<iframe
:src="designerUrl"
frameborder="0"
scrolling="auto"
allowtransparency="true"
allowfullscreen="true"
width="100%"
height="600px"
></iframe>
</el-dialog>
<process-version ref="versionRef"></process-version>
<node-config ref="nodeConfigRef"></node-config>
</div>
<script>
<!--#include('processVersion.js'){}#-->
<!--#include('nodeConfig.js'){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"process-version": processVersion,
"node-config": nodeConfig
},
data() {
return {
tableColumns: [
{ label: "ID", prop: "id" },
{ label: "名称", prop: "name" },
{ label: "Key", prop: "key" },
{ label: "分类", prop: "category" },
{ label: "状态", prop: "suspended" },
{ label: "版本", prop: "version" },
{ label: "创建时间", prop: "createTime" }
],
dialogVisible: false,
designerUrl: ""
}
},
methods: {
openVersion(row) {
this.$refs.versionRef.onOpen(row.key)
},
openNodeConfig(row){
this.$refs.nodeConfigRef.onOpen(row.id)
},
deploy(modelId) {
this.$confirm("确定要部署吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$axios.post("/platform/workflow/process/definition/deploy", { modelId }).then((res) => {
if (res.code === 0) {
this.$message.success("部署成功")
this.pageData()
}
})
})
.catch(() => {})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -1,93 +0,0 @@
const nodeConfig = {
template: /*language=HTML*/ `
<el-dialog title="节点配置" :visible.sync="visible" fullscreen append-to-body>
<el-table :data="tableData" border>
<el-table-column prop="nodeName" label="节点名称" />
<el-table-column prop="nodeId" label="节点编码" />
<el-table-column prop="pcFormUrl" label="PC表单地址" />
<el-table-column prop="mobileFormUrl" label="移动端表单地址" />
<el-table-column prop="allowSelectNextUser" label="选择下一步处理人" />
<el-table-column prop="allowSelectCcUser" label="是否允许选择抄送人" />
<el-table-column prop="allowTransfer" label="是否允许转办" />
<el-table-column prop="allowReject" label="是否允许驳回" />
<el-table-column label="操作" width="150px">
<template slot-scope="scope">
<el-button type="text" @click="onEdit(scope.row)">配置</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog title="节点配置" :visible.sync="editVisible" width="700px" append-to-body>
<el-form ref="form" :model="formData" label-width="150px">
<el-form-item label="节点名称">
<el-input v-model="formData.nodeName" readonly />
</el-form-item>
<el-form-item label="节点编码">
<el-input v-model="formData.nodeId" readonly />
</el-form-item>
<el-form-item label="PC表单地址" prop="pcFormUrl">
<el-input v-model="formData.pcFormUrl" />
</el-form-item>
<el-form-item label="移动端表单地址" prop="mobileFormUrl">
<el-input v-model="formData.mobileFormUrl" />
</el-form-item>
<el-form-item label="选择下一步处理人" prop="allowSelectNextUser">
<el-switch v-model="formData.allowSelectNextUser" />
</el-form-item>
<el-form-item label="是否允许选择抄送人" prop="allowSelectCcUser">
<el-switch v-model="formData.allowSelectCcUser" />
</el-form-item>
<el-form-item label="是否允许转办" prop="allowTransfer">
<el-switch v-model="formData.allowTransfer" />
</el-form-item>
<el-form-item label="是否允许驳回" prop="allowReject">
<el-switch v-model="formData.allowReject" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<el-button type="primary" @click="onSave">确 定</el-button>
</span>
</el-dialog>
</el-dialog>
`,
data() {
return {
visible: false,
title: "标题",
processDefinitionId: null,
tableData: [],
editVisible: false,
formData: {}
}
},
methods: {
onOpen(processDefinitionId) {
this.visible = true
this.processDefinitionId = processDefinitionId
this.loadData()
},
loadData() {
this.$axios.post("/platform/workflow/process/definition/userTasksConfig/" + this.processDefinitionId).then((res) => {
if (res.code === 0) {
this.tableData = res.data
}
})
},
onEdit(row) {
this.editVisible = true
this.formData = { ...row }
},
onSave() {
this.$axios.post("/platform/workflow/process/definition/saveUserTasksConfig", this.formData).then(res => {
if (res.code === 0) {
this.$message.success("保存成功")
this.editVisible = false
this.loadData()
}
})
}
}
}
@@ -1,153 +0,0 @@
const processVersion = {
template: /*language=HTML*/ `
<el-dialog title="版本信息" :visible.sync="visible" fullscreen>
<el-table :data="tableData">
<el-table-column label="序号" type="index" width="80px"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="key" prop="key"></el-table-column>
<el-table-column label="版本" prop="version"></el-table-column>
<el-table-column label="状态" prop="suspended">
<template slot-scope="scope">
<el-tag v-if="scope.row.suspended" size="mini" type="info">挂起</el-tag>
<el-tag v-else size="mini" type="success">激活</el-tag>
</template>
</el-table-column>
<el-table-column label="部署状态" prop="deploymentValid">
<template slot-scope="scope">
<el-tag v-if="scope.row.deploymentValid" size="mini" type="success">有效</el-tag>
<el-tag v-else size="mini" type="danger">无效</el-tag>
</template>
</el-table-column>
<el-table-column label="部署时间" prop="deploymentTime">
<template slot-scope="scope">
{{ scope.row.deploymentTime ? new Date(scope.row.deploymentTime).toLocaleString() : '' }}
</template>
</el-table-column>
<el-table-column label="操作" width="300px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="openDiagram(scope.row.id)">流程图</el-button>
<el-button size="mini" type="text" v-if="scope.row.suspended" @click="activate(scope.row.id)">
激活
</el-button>
<el-button size="mini" type="text" v-if="!scope.row.suspended" @click="suspend(scope.row.id)">
挂起
</el-button>
<el-button size="mini" type="text" @click="onDelete(scope.row.deploymentId)">删除</el-button>
<el-button size="mini" type="text" v-if="!scope.row.deploymentValid" @click="cleanupInvalidDefinition(scope.row.id)">清理</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog title="流程图" :visible.sync="diagramVisible" width="70%" append-to-body>
<img :src="diagramUrl" alt="">
</el-dialog>
</el-dialog>
`,
data() {
return {
visible: false,
tableData: [],
processKey: null,
diagramVisible: false,
diagramUrl: null
}
},
methods: {
onOpen(processKey) {
this.visible = true
this.processKey = processKey
this.loadData()
},
loadData() {
this.$axios.post("/platform/workflow/process/definition/versions", { processKey: this.processKey }).then((res) => {
if (res.code === 0) {
this.tableData = res.data
}
})
},
activate(processDefinitionId) {
this.$confirm("确定要激活吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/workflow/process/definition/activate/" + processDefinitionId).then((res) => {
if (res.code === 0) {
this.$message.success("激活成功")
this.loadData()
}
})
})
},
suspend(processDefinitionId) {
this.$confirm("确定要挂起吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/workflow/process/definition/suspend/" + processDefinitionId).then((res) => {
if (res.code === 0) {
this.$message.success("挂起成功")
this.loadData()
}
})
})
},
onDelete(deploymentId) {
this.$confirm("确定要删除吗?删除后将无法恢复", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
// 添加级联删除选项
this.$confirm("是否级联删除?(级联删除会同时删除相关的流程实例)", "提示", {
confirmButtonText: "是",
cancelButtonText: "否",
type: "warning"
}).then(() => {
// 级联删除
this.$axios.post("/platform/workflow/process/definition/delete/" + deploymentId + "?cascade=true").then((res) => {
if (res.code === 0) {
this.$message.success("删除成功")
this.loadData()
} else {
this.$message.error(res.msg || "删除失败")
}
})
}).catch(() => {
// 非级联删除
this.$axios.post("/platform/workflow/process/definition/delete/" + deploymentId + "?cascade=false").then((res) => {
if (res.code === 0) {
this.$message.success("删除成功")
this.loadData()
} else {
this.$message.error(res.msg || "删除失败")
}
})
})
})
},
cleanupInvalidDefinition(processDefinitionId) {
this.$confirm("确定要清理此无效流程定义吗?此操作将从数据库中删除此记录。", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/workflow/process/definition/cleanup/" + processDefinitionId).then((res) => {
if (res.code === 0) {
this.$message.success("清理成功")
this.loadData()
}
})
})
},
openDiagram(processDefinitionId) {
this.diagramVisible = true
this.diagramUrl = "/platform/workflow/process/definition/diagram/" + processDefinitionId
}
}
}
@@ -1,578 +0,0 @@
<!--#
layout("/layouts/v4/baseLayout.html"){
#-->
<div id="app" v-cloak>
<div class="task-todo-center">
<!-- 统计数据区域 -->
<el-row :gutter="20" class="statistics-section">
<el-col :span="8">
<el-card shadow="hover" class="stat-card">
<div class="stat-content">
<div class="stat-icon todo-icon">
<i class="el-icon-s-claim"></i>
</div>
<div class="stat-info">
<div class="stat-value">{{todoCount}}</div>
<div class="stat-label">待办任务</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="stat-card">
<div class="stat-content">
<div class="stat-icon done-icon">
<i class="el-icon-finished"></i>
</div>
<div class="stat-info">
<div class="stat-value">{{doneCount}}</div>
<div class="stat-label">已办任务</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" class="stat-card">
<div class="stat-content">
<div class="stat-icon started-icon">
<i class="el-icon-s-promotion"></i>
</div>
<div class="stat-info">
<div class="stat-value">{{startedCount}}</div>
<div class="stat-label">我发起的</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 搜索筛选区域 -->
<el-card shadow="never" class="filter-section">
<el-form :inline="true" :model="searchForm" class="search-form">
<el-form-item>
<el-input v-model="searchForm.keyword" placeholder="请输入关键词搜索" prefix-icon="el-icon-search" clearable></el-input>
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.category" placeholder="所有流程类型" clearable>
<el-option v-for="type in processTypes" :key="type.value" :label="type.label" :value="type.value"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search">搜索</el-button>
<el-button @click="reset">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 任务列表区域 -->
<el-card shadow="never" class="task-section">
<div slot="header" class="task-header">
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane label="待办任务" name="todo"></el-tab-pane>
<el-tab-pane label="已办任务" name="done"></el-tab-pane>
<el-tab-pane label="我发起的" name="started"></el-tab-pane>
</el-tabs>
</div>
<!-- 表格展示 -->
<el-table
v-loading="loading"
:data="tasks"
style="width: 100%"
:key="activeTab"
:header-cell-style="{backgroundColor: '#f5f7fa'}"
:row-class-name="tableRowClassName"
>
<el-table-column prop="processInstanceName" label="流程名称" min-width="180" show-overflow-tooltip>
<template slot-scope="scope">
<span class="task-title">{{scope.row.processInstanceName || scope.row.title}}</span>
</template>
</el-table-column>
<el-table-column prop="taskName" label="任务节点" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="processDefinitionName" label="流程类型" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">{{scope.row.processDefinitionName || scope.row.processType}}</template>
</el-table-column>
<el-table-column prop="applyUserName" label="申请人" min-width="120"></el-table-column>
<el-table-column label="时间" min-width="180">
<template slot-scope="scope">
<div v-if="activeTab === 'todo'">
<i class="el-icon-time"></i>
{{scope.row.createTime}}
</div>
<div v-else-if="activeTab === 'done'">
<i class="el-icon-check"></i>
{{scope.row.endTime}}
</div>
<div v-else-if="activeTab === 'started'">
<i class="el-icon-s-promotion"></i>
{{scope.row.startTime}}
</div>
</template>
</el-table-column>
<el-table-column v-if="activeTab === 'started'" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="getStatusType(scope.row)" size="small" effect="light">{{scope.row.status || '进行中'}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="250" fixed="right">
<template slot-scope="scope">
<el-button v-if="activeTab === 'todo'" type="primary" size="mini" @click="handleTask(scope.row)">处理</el-button>
<el-button type="info" size="mini" @click="viewTaskDetail(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!-- 空状态展示 -->
<el-empty v-if="tasks.length === 0" :description="getEmptyText()"></el-empty>
<!-- 分页 -->
<div class="pagination-container" v-if="tasks.length > 0">
<el-pagination
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-size="pageSize"
layout="prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</el-card>
<!-- 任务详情对话框 -->
<el-dialog title="任务详情" :visible.sync="dialogVisible" width="600px" :close-on-click-modal="false">
<div v-if="currentTask" class="task-detail">
<el-descriptions :column="1" border>
<el-descriptions-item label="流程名称">{{currentTask.processInstanceName || currentTask.title}}</el-descriptions-item>
<el-descriptions-item label="任务名称">{{currentTask.taskName || '-'}}</el-descriptions-item>
<el-descriptions-item label="流程类型">{{currentTask.processDefinitionName || currentTask.processType}}</el-descriptions-item>
<el-descriptions-item label="申请人">{{currentTask.applyUserName || '-'}}</el-descriptions-item>
<el-descriptions-item label="申请部门">{{currentTask.applyUserUnitId || '-'}}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{currentTask.createTime}}</el-descriptions-item>
<el-descriptions-item v-if="currentTask.description" label="任务描述">
<div class="description-content">{{currentTask.description}}</div>
</el-descriptions-item>
<el-descriptions-item v-if="currentTask.taskMobileFormUrl" label="表单链接">
<el-link type="primary" :href="currentTask.taskMobileFormUrl" target="_blank">点击查看详细表单</el-link>
</el-descriptions-item>
</el-descriptions>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button v-if="activeTab === 'todo'" type="primary" @click="handleTask(currentTask)">处理任务</el-button>
</span>
</el-dialog>
</div>
</div>
<style>
.task-todo-center {
padding: 20px;
}
/* 统计卡片样式 */
.statistics-section {
margin-bottom: 20px;
}
.stat-card {
border: none;
height: 100%;
}
.stat-card .el-card__body {
padding: 20px;
}
.stat-content {
display: flex;
align-items: center;
}
.stat-icon {
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
font-size: 28px;
}
.todo-icon {
background-color: rgba(64, 158, 255, 0.1);
color: #409eff;
}
.done-icon {
background-color: rgba(103, 194, 58, 0.1);
color: #67c23a;
}
.started-icon {
background-color: rgba(230, 162, 60, 0.1);
color: #e6a23c;
}
.stat-info {
flex: 1;
}
.stat-value {
font-size: 28px;
font-weight: 600;
line-height: 1.2;
margin-bottom: 5px;
}
.stat-label {
font-size: 14px;
color: #909399;
}
/* 搜索区域样式 */
.filter-section {
margin-bottom: 20px;
}
.filter-section .el-card__body {
padding: 15px 20px;
}
.search-form {
display: flex;
flex-wrap: wrap;
}
.search-form .el-form-item {
margin-bottom: 0;
margin-right: 15px;
}
/* 任务列表区域样式 */
.task-section .el-card__header {
padding: 0;
border-bottom: none;
}
/* 优化后的 tabs 样式 */
.task-header .el-tabs__header {
margin: 0;
padding: 0 20px;
background-color: #fff;
}
.task-header .el-tabs__nav-wrap::after {
height: 1px;
background-color: #ebeef5;
}
.task-header .el-tabs__item {
height: 50px;
line-height: 50px;
font-size: 15px;
color: #606266;
padding: 0 20px;
transition: all 0.3s;
}
.task-header .el-tabs__item.is-active {
color: #409eff;
font-weight: 500;
}
.task-header .el-tabs__active-bar {
height: 3px;
border-radius: 3px;
}
.task-title {
font-weight: 500;
color: #303133;
}
/* 表格行样式 */
.el-table .hover-row {
background-color: #f5f7fa;
}
/* 优化后的分页样式 */
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: center;
padding: 10px 0;
}
.pagination-container .el-pagination {
padding: 0;
font-weight: normal;
display: flex;
align-items: center;
}
.pagination-container .el-pagination .btn-prev,
.pagination-container .el-pagination .btn-next {
background-color: #f4f6f8;
color: #606266;
border-radius: 4px;
padding: 0 10px;
height: 32px;
line-height: 32px;
margin: 0 5px;
}
.pagination-container .el-pagination .btn-prev:hover,
.pagination-container .el-pagination .btn-next:hover {
color: var(--color-primary);
background-color: #ecf5ff;
}
.pagination-container .el-pagination .el-pager li {
background-color: #f4f6f8;
color: #606266;
border-radius: 4px;
min-width: 32px;
height: 32px;
line-height: 32px;
margin: 0 3px;
font-weight: normal;
transition: all 0.3s;
}
.pagination-container .el-pagination .el-pager li:hover {
color: var(--color-primary);
background-color: #ecf5ff;
}
.pagination-container .el-pagination .el-pager li.active {
background-color: var(--color-primary);
color: #fff;
font-weight: bold;
}
.pagination-container .el-pagination .el-pagination__jump {
margin-left: 15px;
color: #606266;
}
.pagination-container .el-pagination .el-pagination__editor.el-input {
width: 50px;
margin: 0 5px;
}
.pagination-container .el-pagination .el-pagination__editor.el-input .el-input__inner {
height: 28px;
border-radius: 4px;
}
/* 任务详情样式 */
.task-detail .el-descriptions {
margin-bottom: 20px;
}
.description-content {
background-color: #f5f7fa;
padding: 10px;
border-radius: 4px;
white-space: pre-wrap;
}
</style>
<script>
new Vue({
el: "#app",
data() {
return {
// 统计数据
todoCount: 0,
doneCount: 0,
startedCount: 0,
// 搜索表单
searchForm: {
keyword: "",
category: ""
},
// 流程类型选项
processTypes: [],
// 任务列表
tasks: [],
loading: false,
// 分页
currentPage: 1,
pageSize: 10,
total: 0,
// 标签页
activeTab: "todo",
// 当前任务
currentTask: null,
dialogVisible: false
}
},
computed: {
totalPages() {
return Math.ceil(this.total / this.pageSize)
}
},
created() {
this.initData()
},
methods: {
// 初始化数据
async initData() {
await Promise.all([this.getStatistics(), this.getProcessTypes(), this.getTasks()])
},
// 获取统计数据
async getStatistics() {
try {
const res = await $.post("/platform/warmFlow/todoCenter/statistics")
if (res.code === 0) {
const { todoCount, doneCount, startedCount } = res.data
this.todoCount = todoCount
this.doneCount = doneCount
this.startedCount = startedCount
}
} catch (error) {
this.$message.error("获取统计数据失败")
console.error("获取统计数据失败:", error)
}
},
// 获取流程类型
async getProcessTypes() {
try {
const res = await $.post("/platform/warmFlow/todoCenter/category")
if (res.code === 0) {
this.processTypes = res.data
}
} catch (error) {
this.$message.error("获取流程类型失败")
console.error("获取流程类型失败:", error)
}
},
// 获取任务列表
async getTasks() {
this.loading = true
try {
const params = {
page: this.currentPage,
pageSize: this.pageSize,
type: this.activeTab,
keyword: this.searchForm.keyword,
category: this.searchForm.category
}
const res = await $.post("/platform/warmFlow/todoCenter/" + this.activeTab, params)
if (res.code === 0) {
this.tasks = res.data.list
this.total = res.data.totalCount
this.dialogVisible = false
}
} catch (error) {
this.$message.error("获取任务列表失败")
console.error("获取任务列表失败:", error)
} finally {
this.loading = false
}
},
// 处理标签页点击
handleTabClick(tab) {
this.activeTab = tab.name
this.currentPage = 1
this.getTasks()
},
// 搜索
search() {
this.currentPage = 1
this.getTasks()
this.getStatistics()
},
// 重置搜索
reset() {
this.searchForm = {
keyword: "",
category: ""
}
this.search()
},
// 处理页码变化
handleCurrentChange(val) {
this.currentPage = val
this.getTasks()
},
// 查看任务详情
viewTaskDetail(task) {
this.currentTask = task
this.dialogVisible = true
},
// 处理任务
async handleTask(task) {
if (!task) return
// 如果有表单链接,直接跳转
if (task.taskMobileFormUrl) {
window.open(task.taskMobileFormUrl, "_blank")
return
}
},
// 获取状态对应的类型
getStatusType(task) {
if (!task.status) return "info"
switch (task.status) {
case "审批中":
return "primary"
case "已完成":
return "success"
case "已通过":
return "success"
case "已拒绝":
return "danger"
default:
return "info"
}
},
// 获取空状态文本
getEmptyText() {
switch (this.activeTab) {
case "todo":
return "您当前没有需要办理的任务,辛苦了"
case "done":
return "您当前没有已办理的任务记录"
case "started":
return "您当前没有发起的流程"
default:
return "暂无数据"
}
},
// 表格行类名
tableRowClassName({ row, rowIndex }) {
return ""
}
}
})
</script>
<!--#
}
#-->
@@ -102,13 +102,6 @@
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
// 发送完成消息
window.parent.postMessage(
{
type: "task-complete"
},
"*"
)
}
})
})
@@ -0,0 +1,309 @@
<div id="proposal-transact-apply-form">
<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="姓名">
<el-form-item>
<el-input :value="formData.createUserName" disabled></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="工号">
<el-form-item>
<el-input :value="formData.createUserLoginName" disabled></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="单位">{{formData.unitName}}</el-descriptions-item>
<el-descriptions-item label="联系电话">
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="formData.mobile" clearable placeholder="联系电话"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属教代会">
<el-form-item label="所属教代会" prop="sessionId">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="formData.sessionId" style="width: 100%">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属代表团">
<el-form-item label="所属代表团" prop="delegationId">
<el-select clearable filterable placeholder="所属代表团" v-model="formData.delegationId" 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-form-item>
</el-descriptions-item>
<el-descriptions-item label="所属委员会" v-if="formData.mannerCode=='W03'" :span="2">
<el-form-item label="所属委员会" prop="committeeId">
<el-select clearable filterable placeholder="所属委员会" v-model="formData.committeeId" style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in committeeOptions"></el-option>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案名称" :span="2">
<el-form-item label="提案名称" prop="name">
<el-input maxlength="100" placeholder="提案名称" v-model="formData.name"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案方式" :span="2">
<el-form-item label="提案方式" prop="source">
<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-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案类别" :span="2">
<el-form-item label="提案类别" prop="typeId">
<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-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案摘要" :span="2">
<el-form-item label="提案摘要" prop="excerpt">
<span slot="label">
提案摘要
<el-tooltip content="请简述提案内容和依据、改进建议和措施摘要" placement="right">
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-input
v-model="formData.excerpt"
type="textarea"
autosize
:autosize="{ minRows: 4, maxRows: 4}"
placeholder="提案摘要"
></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案内容和依据" :span="2">
<el-form-item label="提案内容和依据" prop="brief">
<text-editor v-model="formData.brief" key="brief" placeholder="提案内容和依据"></text-editor>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案改进建议和措施" :span="2">
<el-form-item label="改进建议和措施" prop="measures">
<text-editor v-model="formData.measures" key="measures" placeholder="改进建议和措施"></text-editor>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="提案附件" :span="2">
<el-form-item label="附件上传" prop="files">
<file-upload
:value.sync="formData.files"
:upload_number="5"
upload_result_category="array"
upload_mode="drag"
complete_result
></file-upload>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @save-draft="handleSaveDraft"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#proposal-transact-apply-form",
store,
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
formData: {},
sessionOptions: [],
sourceOptions: [],
delegationOptions: [],
committeeOptions: [],
typeOptions: [],
formRules: {
createUserName: [{ required: true, message: "请填写提案人", trigger: ["blur", "change"] }],
createTime: [{ required: true, message: "请填写提案时间", trigger: ["blur", "change"] }],
name: [{ required: true, message: "请填写提案名称", trigger: ["blur", "change"] }],
source: [{ required: true, message: "请选择提案方式", trigger: ["blur", "change"] }],
delegationId: [{ required: true, message: "请选择所属代表团", trigger: ["blur", "change"] }],
sessionId: [{ required: true, message: "请选择所属教代会", trigger: ["blur", "change"] }],
committeeId: [{ required: true, message: "请选择所属委员会", trigger: ["blur", "change"] }],
typeId: [{ required: true, message: "请选择提案类别", trigger: ["blur", "change"] }],
implementUnitId: [{ required: false, message: "请选择建以落实部门", trigger: ["blur", "change"] }],
sign: [{ required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"] }],
excerpt: [{ required: true, message: "请填写", trigger: ["blur", "change"] }],
brief: [{ required: true, message: "请填写", trigger: ["blur", "change"] }],
measures: [{ required: true, message: "请填写", trigger: ["blur", "change"] }],
unitName: [{ required: true, message: "请填写", trigger: ["blur", "change"] }],
mobile: [{ required: true, message: "请填写", trigger: ["blur", "change"] }],
signature: [{ required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"] }]
}
}
},
methods: {
handleTaskAction(val) {
console.log(val)
this.$refs.formRef.validate((valid) => {
if (valid) {
if (!this.instanceId) {
this.handleApply(val)
} else {
this.handleReApply(val)
}
}
})
},
// 提交申请
handleApply(val) {
this.$axios
.post("/flow/common/startInstanceAndExecute", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.GlobalBroadcastChannel.postMessage({
type: "task-complete"
})
window.location.href = "/platform/proposal/apply/index"
}
})
},
// 重新提交申请
handleReApply(val) {
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
processTaskId: val.taskId,
processInstanceId: val.instanceId,
submitType: val.submitType,
f_data: JSON.stringify(this.formData)
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.GlobalBroadcastChannel.postMessage({
type: "task-complete"
})
}
})
},
// 保存申请
handleSaveDraft(val) {
this.$refs.formRef.validateField(["excerpt"], (errMsg) => {
if (errMsg) {
return
}
this.$axios
.post("/flow/common/startInstance", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.location.href = "/platform/proposal/apply/index"
}
})
})
},
// 教代会change
async meetingChange(val) {
this.formData.delegationId = null
this.formData.committeeId = null
this.listDelegation()
this.searchMineDelegation()
// this.delegationOptions = await proposal.getDelegation(val)
// this.committeeOptions = await this.getInstitutions(val)
},
// 查询开启的教代会
listOpenSession(isModify = false) {
this.$axios.post("/platform/proposal/common/listOpenSession").then(async (res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions.length === 0) {
this.$message.error("没有教代会信息")
return
}
if (!isModify && this.sessionOptions && this.sessionOptions.length) {
this.$set(this.formData, "sessionId", this.sessionOptions[0].id)
await this.searchMineDelegation()
}
await this.listDelegation()
await this.listSource()
}
})
},
// 查询代表团
listDelegation() {
return this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.formData.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
//查询自己有权限的撰写方式
listSource() {
return this.$axios.post("/platform/proposal/write/listSource", { sessionId: this.formData.sessionId }).then((res) => {
if (res.code === 0) {
this.sourceOptions = res.data
}
})
},
//查询自己有权限的代表团
searchMineDelegation() {
return this.$axios.post("/platform/proposal/write/searchMineDelegation", { sessionId: this.formData.sessionId }).then((res) => {
if (res.code === 0) {
this.$set(this.formData, "delegationId", res.data)
}
})
},
// 获取提案类型
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
})
},
// 初始化
init() {
this.listProposalType()
if (this.businessId) {
this.$axios.post("/platform/proposal/apply/info", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.formData = res.data
this.listOpenSession(true)
}
})
} else {
this.listOpenSession(false)
this.$set(this.formData, "createUserId", this.$store.state.user.id)
this.$set(this.formData, "createUserName", this.$store.state.user.username)
this.$set(this.formData, "createUserLoginName", this.$store.state.user.loginname)
this.$set(this.formData, "createTime", this.$moment().format("YYYY-MM-DD"))
this.$set(this.formData, "mobile", this.$store.state.user.mobile)
this.$set(this.formData, "unitName", this.$store.state.user.unit?.name)
}
}
},
created() {
this.init()
}
})
</script>
@@ -0,0 +1,104 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker>
</search-item>
<search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></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="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 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="300px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskKey === 'startTask'" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
<el-button @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/proposal/apply/pageData"
}
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?" + "instanceId=" + (row.instanceId || "") + "&businessId=" + row.id)
},
onEdit(row) {
window.open(
"/flow/common/approval/form?taskId=" + (row.taskId || "") + "&instanceId=" + (row.instanceId || "") + "&businessId=" + row.id
)
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/proposal/apply/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,48 @@
<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>
@@ -0,0 +1,88 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker>
</search-item>
<search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></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="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 prop="curTaskName" 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="300px">
<template slot-scope="{row}">
<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>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/proposal/delegation/pageData",
pageForm: {
approval: false
}
}
},
methods: {
openView(row) {
window.open(
"/flow/common/approval/form?taskId=" +
row.taskId +
"&instanceId=" +
row.instanceId +
"&businessId=" +
row.businessNo +
"&sessionId=" +
row.sessionId
)
},
onRevoke(row) {
console.log(row)
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,153 @@
<div id="proposal-transact-apply-form">
<div>
<el-row type="flex" style="column-gap: 10px">
<el-col :span="6">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入工号或者姓名查询" clearable></el-input>
</el-col>
<el-col :span="6">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in delegationOptions"></el-option>
</el-select>
</el-col>
<el-col :span="4">
<el-button icon="el-icon-search" type="primary" @click="doSearch">查询</el-button>
</el-col>
</el-row>
<el-divider class="mt10 mb10"></el-divider>
<table-tool>
<el-radio-group v-model="pageForm.isInvite" @change="doSearch" size="small" style="margin-left: 5px">
<el-radio-button :label="true">已邀请</el-radio-button>
<el-radio-button :label="false">可邀请</el-radio-button>
</el-radio-group>
</table-tool>
<el-table
:data="tableData"
ref="tableRef"
@sort-change="pageOrder"
size="small"
header-align="center"
style="width: 100%"
:row-key="getRowKey"
>
<el-table-column type="selection" reserve-selection v-if="!pageForm.isInvite"></el-table-column>
<el-table-column label="序号" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<!-- <el-table-column label="操作" width="150px">-->
<!-- <template scope="{row}">-->
<!-- <el-button size="mini" type="primary" @click="invite(row)">邀请</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
<snaker-flow-task-form-action @task-action="handleTaskAction"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#proposal-transact-apply-form",
store,
mixins: [initTableMixins],
data() {
return {
businessId: GetQueryString("businessId"),
sessionId: GetQueryString("sessionId"),
instanceId: GetQueryString("instanceId"),
secondedNum: 0,
pageForm: {
isInvite: false
},
config: {},
delegationOptions: []
}
},
methods: {
getRowKey(val) {
return val.loginName + this.pageForm.isInvite
},
// 数据查询
pageData() {
this.$axios
.post("/platform/proposal/invite/listSeconder", {
...this.pageForm,
sessionId: this.sessionId,
proposalId: this.businessId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
//查询代表团
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
// 获取配置
async getConfig() {
const { code, data } = await this.$axios.post("/platform/proposal/common/config")
if (code === 0) {
this.config = data
}
},
handleTaskAction(val) {
console.log(val)
this.invite(val)
},
// 邀请
invite(val) {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.warning("请先选择附议人后再提交")
return
}
const loginNames = selection.map((s) => s.loginName)
const userName = selection.map((s) => s.userName)
this.$confirm("您确定要邀请" + userName.join("、") + "代表附议吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
tf_nextNodeOperator: selection.map((s) => s.userId),
tf_proposalId: this.businessId,
tf_seconders: JSON.stringify(selection)
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
})
}
},
created() {
debugger
this.getConfig()
this.listDelegation()
this.pageData()
}
})
</script>
@@ -0,0 +1,88 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker>
</search-item>
<search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></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="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 prop="curTaskName" 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="300px">
<template slot-scope="{row}">
<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>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/proposal/invite/pageData",
pageForm: {
approval: false
}
}
},
methods: {
openView(row) {
window.open(
"/flow/common/approval/form?taskId=" +
row.taskId +
"&instanceId=" +
row.instanceId +
"&businessId=" +
row.businessNo +
"&sessionId=" +
row.sessionId
)
},
onRevoke(row) {
console.log(row)
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,48 @@
<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>
@@ -0,0 +1,88 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker>
</search-item>
<search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></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="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 prop="curTaskName" 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="300px">
<template slot-scope="{row}">
<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>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/proposal/seconded/pageData",
pageForm: {
approval: false
}
}
},
methods: {
openView(row) {
window.open(
"/flow/common/approval/form?taskId=" +
row.taskId +
"&instanceId=" +
row.instanceId +
"&businessId=" +
row.businessNo +
"&sessionId=" +
row.sessionId
)
},
onRevoke(row) {
console.log(row)
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,170 @@
<div id="proposal-view">
<!-- <el-form ref="formRef" label-width="0" label-suffix="" class="flow-task-form">-->
<el-descriptions :column="2" border class="flow-task-form">
<el-descriptions-item label="提案名称" :span="2">{{ viewData.name }}</el-descriptions-item>
<el-descriptions-item label="提案编号">{{ viewData.code }}</el-descriptions-item>
<el-descriptions-item label="提案人">{{viewData.createUserName }}</el-descriptions-item>
<el-descriptions-item label="提案时间">{{ viewData.createTime }}</el-descriptions-item>
<el-descriptions-item label="教代会届次">{{ viewData.sessionName || '暂无' }}</el-descriptions-item>
<el-descriptions-item label="提案人单位">{{ viewData.unitName }}</el-descriptions-item>
<el-descriptions-item :label="viewData.mannerCode!=='W03'?'代表团名称':'委员会名称'">
{{ viewData.mannerCode !== 'W03' ? viewData.delegationName : viewData.committeeName }}
</el-descriptions-item>
<el-descriptions-item label="提案类别">{{viewData.typeName}}</el-descriptions-item>
<el-descriptions-item label="立案结果" :span="2">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="viewData.caseFilingResult"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="提案摘要" :span="2">
<div class="text-left">{{viewData.excerpt}}</div>
</el-descriptions-item>
<el-descriptions-item label="提案内容" :span="2">
<div class="text-left" v-html="viewData.brief"></div>
</el-descriptions-item>
<el-descriptions-item label="改进建议和措施" :span="2">
<div class="text-left" v-html="viewData.measures"></div>
</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="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>-->
<!-- <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>-->
<!-- </div>-->
<!-- </template>-->
<!-- 首先按 taskParentId 分组 -->
<template v-for="(group, parentId) in groupTasksByParentId(doneTasks)">
<div class="task-panel mt10" :key="parentId">
<!-- 显示主任务(parentId 为 0 或没有子任务的任务) -->
<template v-if="parentId === '0' || !group.children.length">
<div class="task-panel-header">{{ group.mainTask.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3">
<el-descriptions-item label="申请用户">
{{ group.mainTask.ext.initiatorName }}({{group.mainTask.ext.initiatorAccount}})
</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ group.mainTask.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="group.mainTask.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
</template>
<!-- 显示子任务 -->
<template v-for="(task, index) in group.children">
<div class="task-panel-header" :key="task.id" v-if="index === 0 || task.displayName !== group.children[index-1].displayName">
{{ task.displayName }}
</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id">
<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="办理意见">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</template>
</div>
</template>
</div>
<script>
new Vue({
el: "#proposal-view",
store,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
viewData: {},
doneTasks: []
}
},
methods: {
info() {
this.$axios.post("/platform/proposal/view/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
}
})
},
groupTasksByParentId(tasks) {
const groups = {}
// 首先找出所有主任务(taskParentId 为 0 的任务)
tasks.forEach((task) => {
const parentId = task.taskParentId || "0"
if (!groups[parentId]) {
groups[parentId] = {
mainTask: null,
children: []
}
}
if (parentId === "0") {
groups[parentId].mainTask = task
} else {
// 如果是子任务,尝试找到对应的主任务
if (!groups[parentId].mainTask) {
const mainTask = tasks.find((t) => t.id === task.taskParentId)
if (mainTask) {
groups[parentId].mainTask = mainTask
}
}
groups[parentId].children.push(task)
}
})
return groups
}
},
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;
}
</style>
@@ -0,0 +1,96 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<el-select v-model="sessionId" placeholder="请选择教代会" style="width: 100%">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-card>
<el-card shadow="never">
<el-row :gutter="20">
<el-col :span="24">
<div id="delegationNumChart"></div>
</el-col>
</el-row>
</el-card>
</div>
<script>
let delegationChart = null
new Vue({
el: "#app",
components: {},
data() {
return {
sessionId: null,
sessionOptions: []
}
},
methods: {
sessionChange() {
this.pageForm.delegationId = null
this.delegationOptions = []
this.renderDelegationChart()
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions.length > 0) {
this.sessionId = this.sessionOptions[0].id
this.renderDelegationChart()
}
}
})
},
renderDelegationChart() {
this.$axios.post("/platform/teacherCongress/dashboard/listDelegationCount", { sessionId: this.sessionId }).then((res) => {
if (res.code === 0) {
if (!delegationChart) {
delegationChart = new G2Plot.Column("delegationNumChart", {
data: res.data,
xField: "name",
yField: "delegateCount",
label: {
position: "middle",
style: {
fill: "#FFFFFF",
opacity: 0.6
}
},
xAxis: {
label: {
autoHide: true,
autoRotate: false
}
},
meta: {
name: {
alias: "类别"
},
num: {
alias: "人数"
}
}
})
delegationChart.render()
} else {
delegationChart.changeData(res.data)
}
}
})
}
},
mounted() {
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,136 @@
var AddForm = {
template: `
<el-dialog title="新增代表" :visible.sync="dialogFormVisible" width="1000px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
<el-form-item prop="sessionId" label="届次">
<el-select v-model="formData.sessionId"
style="width: 100%"
placeholder="代表所属教代会"
@change="sessionChange">
<el-option v-for="item in sessionOptions"
:key="item.id"
:label="item.fullName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="delegationId" label="代表团">
<el-select v-model="formData.delegationId" filterable @change="delegationChange" clearable style="width: 100%">
<el-option v-for="i in delegationOptions"
:label="i.name"
:key="i.id"
:value="i.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="roleId" label="代表类型">
<el-select v-model="formData.roleId" filterable style="width: 100%">
<el-option v-for="i in roleOptions"
:label="i.name"
:key="i.id"
:value="i.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userIds" label="用户">
<user-select v-model="formData.userIds"
v-if="dialogFormVisible"
api="/platform/teacherCongress/delegate/manage/publicUser"
:api_params="{sessionId:formData.sessionId,delegationId:formData.delegationId}"
api_input_key_name="keyWord"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
:multiple="true"
style="width: 100%"></user-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
formData: {
userIds: [],
sessionId: null,
delegationId: null,
roleId: null
},
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
delegationId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
roleId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
userIds: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: [],
delegationOptions: [],
roleOptions: []
}
},
methods: {
onOpen(sessionId) {
if (!sessionId) {
return
}
this.formData = {
userIds: [],
sessionId: sessionId,
delegationId: null,
roleId: null
}
this.listSession()
this.listDelegation(sessionId)
this.listRole()
this.dialogFormVisible = true
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
listDelegation(sessionId) {
this.$axios.post("/platform/teacherCongress/common/listDelegation", { sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/teacherCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
sessionChange(sessionId) {
this.listDelegation(sessionId)
this.formData.userIds = []
},
delegationChange() {
this.formData.userIds = []
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/teacherCongress/delegate/manage/insert", { data: JSON.stringify(this.formData) }).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh")
}
})
}
})
}
},
created() {}
}
@@ -0,0 +1,185 @@
var AdjustForm = {
template:
/*language=HTML*/
`
<el-dialog title="代表调整" :visible.sync="dialogFormVisible" width="65%" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
<el-row type="flex" justify="space-between">
<el-form-item prop="sessionId" label="届次">
<el-select v-model="formData.sessionId"
style="width: 100%"
placeholder="代表所属教代会"
@change="sessionChange">
<el-option v-for="item in sessionOptions"
:key="item.id"
:label="item.fullName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userId" label="用户">
<user-select v-model="formData.userId"
ref="userSelectRef"
v-if="dialogFormVisible"
api="/platform/teacherCongress/delegate/manage/adjustUserList"
:api_params="{sessionId:formData.sessionId}"
api_input_key_name="keyWord"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
></user-select>
<el-button icon="el-icon-plus" type="primary" @click="move">添加到待调整列表</el-button>
</el-form-item>
</el-row>
<el-form-item prop="users" label="待调整用户">
<el-table :data="formData.users" size="small">
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex" width="50"></el-table-column>
<el-table-column label="所属工会" prop="unionName" show-overflow-tooltip></el-table-column>
<el-table-column label="所属单位" prop="unitName" show-overflow-tooltip></el-table-column>
<el-table-column label="代表团">
<template slot-scope="scope">
<el-form-item :prop="'users.'+scope.$index+'.delegationId'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select v-model="scope.row.delegationId" filterable>
<el-option v-for="d in delegationOptions" :label="d.name" :value="d.id"
:key="d.id"></el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="代表身份">
<template slot-scope="scope">
<el-form-item :prop="'users.'+scope.$index+'.roleId'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select v-model="scope.row.roleId" filterable style="width: 100%">
<el-option v-for="i in roleOptions"
:label="i.name"
:key="i.id"
:value="i.id"></el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-link type="primary" @click="formData.users.splice(scope.$index,1)">取消调整
</el-link>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
formData: {},
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: [],
delegationOptions: [],
roleOptions: []
}
},
methods: {
onOpen(sessionId) {
if (!sessionId) {
return
}
this.formData = {
sessionId: sessionId,
users: []
}
this.listRole()
this.listSession()
this.listDelegation(sessionId)
this.dialogFormVisible = true
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
listDelegation(sessionId) {
this.$axios.post("/platform/teacherCongress/common/listDelegation", { sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/teacherCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
sessionChange(sessionId) {
this.listDelegation(sessionId)
},
move() {
if (!this.formData.userId) {
this.$message.warning("请先搜索需要调整的代表")
return
}
const user = this.$refs.userSelectRef.options.find((user) => user.id === this.formData.userId)
const repeat = this.formData.users.some((u) => u.id === user.id)
if (repeat) {
this.$message.warning("调整列表中已存在,请勿重复添加")
return
}
this.formData.users.unshift(user)
this.formData.userId = null
this.$refs.userSelectRef.clearOptions()
},
doSubmit() {
if (this.formData.users.length === 0) {
this.$message.warning("请先搜索并添加需要调整的代表")
return
}
this.$refs.formRef.validate((valid) => {
if (valid) {
const data = this.formData.users.map((param) => {
return {
id: param.id,
userId: param.userId,
delegationId: param.delegationId,
sessionId: this.formData.sessionId,
roleId: param.roleId
}
})
this.$axios
.post("/platform/teacherCongress/delegate/manage/doAdjustUser", {
data: JSON.stringify(data),
sessionId: this.formData.sessionId
})
.then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh")
}
})
}
})
}
},
created() {}
}
@@ -0,0 +1,211 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" @change="sessionChange">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</search-item>
<search-item label="代表团">
<el-select v-model="pageForm.delegationId" filterable @change="delegationChange" clearable style="width: 100%">
<el-option v-for="i in delegationOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="分工会">
<el-select v-model="pageForm.unionId" filterable @change="listUnit" clearable style="width: 100%">
<el-option v-for="i in unionOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="单位">
<el-select v-model="pageForm.unitId" filterable clearable style="width: 100%">
<el-option v-for="i in unitOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="代表类型">
<el-select v-model="pageForm.roleId" filterable clearable style="width: 100%">
<el-option v-for="i in roleOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-plus" @click="$refs.addFormRef.onOpen(pageForm.sessionId)">新增代表</el-button>
<el-button
size="small"
type="danger"
icon="el-icon-delete"
@click="batchDelete()"
:disabled="$refs.tableRef && $refs.tableRef.selection.length===0"
>
批量删除
</el-button>
<el-button size="small" type="primary" icon="el-icon-plus" @click="$refs.adjustFormRef.onOpen(pageForm.sessionId)">代表调整</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" row-key="id" ref="tableRef" style="width: 100%">
<el-table-column type="selection" width="55" reserve-selection fixed="left"></el-table-column>
<el-table-column type="index" width="55" label="序号" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column label="工号" prop="loginName" fixed="left"></el-table-column>
<el-table-column label="姓名" prop="userName" fixed="left" sortable></el-table-column>
<el-table-column label="性别" prop="sex" sortable></el-table-column>
<el-table-column label="年龄" prop="age" sortable></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="代表团" prop="delegationId" width="150" show-overflow-tooltip sortable>
<template scope="{row}">
<dict-tag :options="delegationOptions" :value="row.delegationId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<el-table-column label="所属工会" prop="unionName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="所属单位" prop="unitName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="届次" prop="sessionId">
<template scope="{row}">
<dict-tag :options="sessionOptions" :value="row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column label="代表身份" prop="roleId" sortable>
<template scope="{row}">
<dict-tag :options="roleOptions" :value="row.roleId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<!-- <el-button size="mini">查看</el-button>-->
<el-button size="mini" type="danger" @click="doDelete([scope.row.id])">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<add-form ref="addFormRef" @refresh="doSearch"></add-form>
<adjust-form ref="adjustFormRef" @refresh="doSearch"></adjust-form>
</div>
<script src="/assets/platform/module/democratic/teachercongress/teacherCongressCommonApi.js"></script>
<script>
<!--#include("addForm.js"){}#-->
<!--#include("adjust.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"add-form": AddForm,
"adjust-form": AdjustForm
},
data() {
return {
pageForm: {
sessionId: null,
delegationId: null,
unionId: null,
unitId: null
},
sessionOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
roleOptions: [],
formRules: {}
}
},
methods: {
sessionChange() {
this.pageForm.delegationId = null
this.delegationOptions = []
this.listDelegation()
this.doSearch()
},
delegationChange() {
this.pageForm.unionId = null
this.pageForm.unitId = null
},
listDelegation() {
this.delegationOptions = []
this.pageForm.delegationId = null
this.$axios.post("/platform/teacherCongress/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/teacherCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => {
this.unionOptions = res
})
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => {
this.unitOptions = res
})
},
doDelete(ids) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/delete", { data: JSON.stringify({ ids: ids }) }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
batchDelete() {
if (this.$refs.tableRef && this.$refs.tableRef.rowKey) {
const ids = this.$refs.tableRef.selection.map((row) => row[this.$refs.tableRef.rowKey])
if (ids.length === 0) {
this.$message.warning("请勾选数据后再删除")
return
}
this.doDelete(ids)
this.$refs.tableRef.clearSelection()
}
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.pageForm.sessionId = this.sessionOptions[0].id
this.listDelegation()
this.pageData()
}
}
})
}
},
created() {
this.listRole()
this.listUnion()
this.listUnit()
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,192 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" @change="sessionChange">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</search-item>
<search-item label="代表团">
<el-select v-model="pageForm.delegationId" filterable @change="delegationChange" clearable style="width: 100%">
<el-option v-for="i in delegationOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="分工会">
<el-select v-model="pageForm.unionId" filterable @change="listUnit" clearable style="width: 100%">
<el-option v-for="i in unionOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="单位">
<el-select v-model="pageForm.unitId" clearable filterable style="width: 100%">
<el-option v-for="i in unitOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="代表类型">
<el-select v-model="pageForm.roleId" filterable clearable style="width: 100%">
<el-option v-for="i in roleOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-download" @click="exportXlsx">导出Excel</el-button>
<el-button
size="small"
type="primary"
icon="el-icon-download"
@click="exportDocx"
v-if="$auth.hasPermission('tc.delegate.read.exportDocx')"
>
导出Word
</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" row-key="id" ref="tableRef" style="width: 100%">
<el-table-column type="selection" width="55" reserve-selection fixed="left"></el-table-column>
<el-table-column type="index" width="55" label="序号" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column label="工号" prop="loginName" fixed="left"></el-table-column>
<el-table-column label="姓名" prop="userName" fixed="left" sortable></el-table-column>
<el-table-column label="性别" prop="sex" sortable></el-table-column>
<el-table-column label="年龄" prop="age" sortable></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="代表团" prop="delegationId" width="150" show-overflow-tooltip sortable>
<template scope="{row}">
<dict-tag :options="delegationOptions" :value="row.delegationId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<el-table-column label="所属工会" prop="unionName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="所属单位" prop="unitName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="届次" prop="sessionId">
<template scope="{row}">
<dict-tag :options="sessionOptions" :value="row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column label="代表身份" prop="roleId" sortable>
<template scope="{row}">
<dict-tag :options="roleOptions" :value="row.roleId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<!-- <el-table-column label="操作" width="100">-->
<!-- <template slot-scope="scope">-->
<!-- <el-button size="mini">查看</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageForm: {
sessionId: null,
delegationId: null,
unionId: null,
unitId: null
},
sessionOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
roleOptions: []
}
},
methods: {
sessionChange() {
this.pageForm.delegationId = null
this.delegationOptions = []
this.listDelegation()
this.doSearch()
},
delegationChange() {
this.pageForm.unionId = null
this.pageForm.unitId = null
},
listDelegation() {
this.delegationOptions = []
this.pageForm.delegationId = null
this.$axios.post("/platform/teacherCongress/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/teacherCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => {
this.unionOptions = res
})
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => {
this.unitOptions = res
})
},
exportXlsx() {
this.$downLoad(loc() + "/exportXlsx", this.pageForm)
},
exportDocx() {
this.$downLoad(loc() + "/exportDocx", this.pageForm)
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.pageForm.sessionId = this.sessionOptions[0].id
this.listDelegation()
this.pageData()
}
}
})
},
pageData() {
this.tableLoading = true
this.$axios
.post(loc() + "/pageData", {
pageForm: JSON.stringify(this.pageForm)
})
.then((res) => {
this.tableLoading = false
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.listRole()
this.listUnion()
this.listUnit()
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,82 @@
const AU_FORM_TEMPLATE = {
template: `
<el-dialog :title="formData.id ? '编辑':'新增'" :visible.sync="dialogFormVisible" width="700px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" size="small" label-width="120px" :rules="formRules">
<el-form-item prop="sessionId" label="教代会">
<el-select v-model="formData.sessionId">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="name" label="代表团名称">
<el-input placeholder="请输入代表团名称" v-model="formData.name" maxlength="100"></el-input>
</el-form-item>
<el-form-item prop="code" label="代表团编码">
<el-input placeholder="请输入代表团编码" v-model="formData.code" maxlength="50"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
formData: {},
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: []
}
},
methods: {
onOpen(id) {
this.dialogFormVisible = true
this.listSession()
if (id) {
this.$axios.post("/platform/teacherCongress/delegation/findOne", { id }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
} else {
this.formData = {}
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate()
}
})
}
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios
.post("/platform/teacherCongress/delegation" + (this.formData.id ? "/update" : "/insert"), this.formData)
.then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
}
},
created() {
this.listSession()
}
}
@@ -0,0 +1,89 @@
const HEAD_FORM_TEMPLATE = {
template: `
<el-dialog title="设置团长" :visible.sync="headDialogFormVisible" width="700px" :close-on-click-modal="false">
<el-form :model="formData" ref="headFormRef" size="small" label-width="120px" :rules="formRules">
<el-form-item prop="sessionId" label="教代会">
<el-select v-model="formData.sessionId" disabled>
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userId" label="团长">
<user-select v-model="formData.userId"
v-if="headDialogFormVisible"
api="/platform/teacherCongress/delegation/notHeadUser"
:api_params="{sessionId:formData.sessionId,delegationId:formData.delegationId}"
api_input_key_name="keyWord"
:option_list="headOptions"
option_value="userId"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
placeholder="请输入工号或者姓名"
style="width: 100%"></user-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="headDialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmitHead">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
formData: {},
headDialogFormVisible: false,
headOptions: [],
sessionOptions: [],
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
}
}
},
methods: {
onOpen(delegationId, sessionId) {
if (!delegationId || !sessionId) {
return
}
this.headDialogFormVisible = true
this.listSession()
this.formData = {
sessionId,
delegationId
}
// this.findHeadUser()
},
// findHeadUser() {
// this.$axios.post("/platform/teacherCongress/delegation/headUser", this.formData).then((res) => {
// if (res.code === 0) {
// if (res.data) {
// this.headOptions = [res.data]
// this.$set(this.formData, "userId", res.data.id)
// }
// }
// })
// },
doSubmitHead() {
this.$refs.headFormRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/teacherCongress/delegation/insertHead", this.formData).then((res) => {
if (res.code === 0) {
this.headDialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
}
}
}
@@ -0,0 +1,96 @@
const HEAD_TABLE_TEMPLATE = {
template: `
<div>
<table-tool>
<el-button size="small" type="primary" icon="el-icon-edit" @click="open">添加团长</el-button>
</table-tool>
<el-table :data="tableData" border>
<el-table-column type="index" label="序号" width="100px"></el-table-column>
<el-table-column prop="loginName" label="工号"></el-table-column>
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="mobile" label="电话"></el-table-column>
<el-table-column label="操作" width="100px">
<template scope="scope">
<el-link type="danger" @click="doDelete(scope.row.userId)">删除</el-link>
</template>
</el-table-column>
</el-table>
</div>
`,
props: {
session_id: {
type: String,
required: true
},
delegation_id: {
type: String,
required: true
}
},
data() {
return {
tableData: [],
pageForm: {}
}
},
watch: {
session_id: {
handler: function (val) {
if (val) {
this.pageData()
}
},
immediate: true
},
delegation_id: {
handler: function (val) {
if (val) {
this.pageData()
}
},
immediate: true
}
},
methods: {
pageData() {
this.$axios
.post("/platform/teacherCongress/delegation/headUser", {
...this.pageForm,
sessionId: this.session_id,
delegationId: this.delegation_id
})
.then((res) => {
if (res.code === 0) {
if (res.data) {
this.tableData = [res.data]
} else {
this.tableData = []
}
}
})
},
open() {
this.$emit("open", this.delegation_id, this.session_id)
},
doDelete(userId) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios
.post("/platform/teacherCongress/delegation/deleteHead", {
userId,
sessionId: this.session_id,
delegationId: this.delegation_id
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
}
}
}
@@ -0,0 +1,163 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row :gutter="10" style="height: calc(100vh - 126px)" type="flex">
<el-col :span="5">
<tree @node-click="treeNodeClick" @session-change="sessionChange" ref="treeRef"></tree>
</el-col>
<el-col :span="19">
<el-card shadow="never" style="height: 100%">
<template v-if="!currentTreeNode || (currentTreeNode && currentTreeNode.level===1)">
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter)">
<el-row type="flex">
<el-input clearable placeholder="请输入代表团名称" style="width: 220px" v-model="pageForm.searchKeyword"></el-input>
<el-button @click="doSearch" class="ml5" icon="el-icon-search" size="small" type="primary"></el-button>
</el-row>
</el-card>
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter)">
<table-tool label="代表团">
<el-button @click="$refs.auFormRef.onOpen()" icon="el-icon-plus" size="small" type="primary">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" border header-align="center" style="width: 100%">
<el-table-column :index="indexMethod" label="序号" type="index" width="100px"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="编码" prop="code" width="150px"></el-table-column>
<el-table-column label="教代会" prop="sessionName"></el-table-column>
<el-table-column label="团长" prop="delegationHead"></el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-link @click="$refs.auFormRef.onOpen(scope.row.id)" size="mini" type="primary">编辑</el-link>
<el-link @click="$refs.headFormRef.onOpen(scope.row.id,scope.row.sessionId)" size="mini" type="primary">
设置团长
</el-link>
<el-link @click="$refs.partUnitRef.onOpen(scope.row.id,scope.row.sessionId)" size="mini" type="primary">
设置组成单位
</el-link>
<el-link @click="doDelete(scope.row.id)" size="mini" type="danger">删除</el-link>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template v-else>
<el-tabs v-model="secondLevelTabActive">
<el-tab-pane label="组成单位" name="partUnitTable">
<el-card class="mt10" shadow="never" style="border: 1px solid var(--border-color-lighter)">
<part-unit-table
:delegation_id="currentTreeData.id"
:session_id="pageForm.sessionId"
@open="(delegation_id,session_id)=>{$refs.partUnitRef.onOpen(delegation_id,session_id)}"
ref="partUnitTableRef"
></part-unit-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="设置团长" name="head">
<el-card class="mt10" shadow="never" style="border: 1px solid var(--border-color-lighter)">
<head-table
:delegation_id="currentTreeData.id"
:session_id="pageForm.sessionId"
@open="(delegation_id,session_id)=>{$refs.headFormRef.onOpen(delegation_id,session_id)}"
ref="headTableRef"
></head-table>
</el-card>
</el-tab-pane>
</el-tabs>
</template>
</el-card>
</el-col>
</el-row>
<au-form @refresh="refresh" ref="auFormRef"></au-form>
<part-unit @refresh="refresh" ref="partUnitRef"></part-unit>
<head-form @refresh="refresh" ref="headFormRef"></head-form>
</div>
<script>
<!--#include("tree.js"){}#-->
<!--#include("auForm.js"){}#-->
<!--#include("partUnit.js"){}#-->
<!--#include("partUnitTable.js"){}#-->
<!--#include("headForm.js"){}#-->
<!--#include("headTable.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
sessionOptions: [],
currentTreeNode: null,
currentTreeData: null,
currentTreeSessionId: null,
secondLevelTabActive: "partUnitTable"
}
},
components: {
tree: TREE_TEMPLATE,
"au-form": AU_FORM_TEMPLATE,
"part-unit": PART_UNIT_TEMPLATE,
"part-unit-table": PART_UNIT_TABLE_TEMPLATE,
"head-form": HEAD_FORM_TEMPLATE,
"head-table": HEAD_TABLE_TEMPLATE
},
methods: {
refresh() {
this.$refs.treeRef.listTree()
if (this.$refs.partUnitTableRef) {
this.$refs.partUnitTableRef.doSearch()
}
if (this.$refs.headTableRef) {
this.$refs.headTableRef.pageData()
}
this.doSearch()
},
sessionChange(id) {
this.pageForm.sessionId = id
this.pageData()
},
treeNodeClick(data, node) {
this.currentTreeData = data
this.currentTreeNode = node
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/platform/teacherCongress/delegation/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.refresh()
}
})
})
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
...this.pageForm,
sessionId: this.pageForm.sessionId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,74 @@
const PART_UNIT_TEMPLATE = {
template: `
<el-dialog title="设置组成单位" :visible.sync="partUnitDialogFormVisible" width="1000px" :close-on-click-modal="false">
<el-transfer
ref="transferRef"
:titles="['可选二级单位', '当前成员单位']"
filterable
:props="{
key: 'id',
label: 'name'
}"
:filter-method="(query,item)=>{return item.name.indexOf(query) > -1}"
v-model="selectUnitsIds"
:data="allUnits"
></el-transfer>
<div slot="footer" class="dialog-footer">
<el-button @click="partUnitDialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmitPartUnit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
partUnitDialogFormVisible: false,
selectUnitsIds: [],
allUnits: [],
delegationId: null,
sessionId: null
}
},
methods: {
onOpen(delegationId, sessionId) {
if (!delegationId || !sessionId) {
return
}
this.partUnitDialogFormVisible = true
this.delegationId = delegationId
this.sessionId = sessionId
if (this.$refs.transferRef) {
this.$refs.transferRef.clearQuery("left")
this.$refs.transferRef.clearQuery("right")
}
this.$axios
.post("/platform/teacherCongress/delegation/partUnitTransferData", {
delegationId,
sessionId
})
.then((res) => {
if (res.code === 0) {
this.selectUnitsIds = res.data.selectUnitIds
this.allUnits = res.data.allUnits
}
})
},
doSubmitPartUnit() {
this.$axios
.post(loc() + "/partUnitSet", {
unitIds: JSON.stringify(this.selectUnitsIds),
delegationId: this.delegationId,
sessionId: this.sessionId
})
.then((res) => {
if (res.code === 0) {
this.partUnitDialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
},
created() {}
}
@@ -0,0 +1,70 @@
const PART_UNIT_TABLE_TEMPLATE = {
template: `
<div>
<table-tool>
<el-button size="small" type="primary" icon="el-icon-edit" @click="open">设置组成单位</el-button>
</table-tool>
<el-table :data="tableData" border>
<el-table-column type="index" label="序号" width="100px"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
`,
mixins: [initTableMixins],
props: {
session_id: {
type: String,
required: true
},
delegation_id: {
type: String,
required: true
}
},
data() {
return {
tableData: [],
pageForm: {}
}
},
watch: {
session_id: {
handler: function(val) {
if (val) {
this.doSearch()
}
},
immediate: true
},
delegation_id: {
handler: function(val) {
if (val) {
this.doSearch()
}
},
immediate: true
}
},
methods: {
pageData() {
this.$axios
.post("/platform/teacherCongress/delegation/partUnitPageData", {
...this.pageForm,
sessionId: this.session_id,
delegationId: this.delegation_id
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
open() {
this.$emit("open", this.delegation_id, this.session_id)
}
},
created() {
}
}
@@ -0,0 +1,64 @@
const TREE_TEMPLATE = {
template: `
<el-card shadow="never" style="height: 100%" body-style="{ height: '100%' }">
<el-select placeholder="输入关键字进行查找" v-model="sessionId" clearable class="mb10">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
<el-tree
:data="treeData"
ref="treeRef"
:expand-on-click-node="false"
:props="{
children: 'children',
label: 'name'
}"
default-expand-all
@node-click="treeNodeClick"
:filter-node-method="filterNode"
></el-tree>
</el-card>
`,
data() {
return {
currentTreeNode: null,
currentTreeData: null,
sessionOptions: [],
sessionId: null,
treeData: []
}
},
watch: {
sessionId(val) {
this.$emit("session-change", val)
}
},
methods: {
treeNodeClick(data, node) {
this.$emit("node-click", data, node)
},
filterNode() {
},
listTree() {
this.$axios.post("/platform/teacherCongress/delegation/tree", {sessionId: this.sessionId}).then((res) => {
if (res.code === 0) {
this.treeData = res.data
}
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.sessionId = this.sessionOptions[0].id
this.listTree()
}
}
})
}
},
created() {
this.listSession()
}
}
@@ -0,0 +1,146 @@
const BASIC_TABLE_COMPONENT = {
template: `
<div>
<el-row type="flex">
<el-col></el-col>
</el-row>
<table-tool>
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">新建机构</el-button>
</table-tool>
<el-table key="1" :data="tableData" ref="tableRef">
<el-table-column label="序号" width="100px" type="index" :index="indexMethod"></el-table-column>
<el-table-column prop="name" label="机构名称"></el-table-column>
<el-table-column prop="code" label="机构编码"></el-table-column>
<el-table-column label="操作" width="100px">
<template slot-scope="{row}">
<el-link size="mini" type="danger" @click="del(row.id)">删除</el-link>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogFormVisible" :title="formData.id?'编辑':'新增'" width="40%">
<el-form :model="formData" ref="formRef" :rules="rules" label-width="100px">
<el-form-item label="机构名称" prop="ids">
<el-cascader
v-model="ids"
:options="treeList"
:props="props"
@change="parentChange"
placeholder="请选择机构"
style="width: 100%"
></el-cascader>
</el-form-item>
<el-form-item label="机构代码" prop="code">
<el-input placeholder="请输入机构代码" v-model="formData.code" disabled></el-input>
</el-form-item>
<el-form-item label="备注" prop="notes">
<el-input v-model="formData.notes" placeholder="请输入备注"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
</div>
`,
mixins: [initTableMixins],
props: {
sessionId: {
type: String,
required: true
},
parentId: {
type: String,
required: true
}
},
data() {
return {
rules: {
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
parentId: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
parentData: {},
parentIds: [],
ids: [],
treeList: [],
treeFlat: [],
props: {
checkStrictly: true,
multiple: false,
label: "name",
value: "id"
},
dialogFormVisible: false
}
},
methods: {
pageData() {
this.$axios
.post(loc() + "/pageData", {
...this.pageForm,
sessionId: this.sessionId,
parentId: this.parentId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.total
}
})
},
openAdd() {
this.dialogFormVisible = true
this.formData = {}
this.ids = []
$.post("/platform/teacherCongress/institution/formTree", { sessionId: this.sessionId }).then((res) => {
if (res.code === 0) {
this.treeList = res.data.treeList
this.treeFlat = res.data.treeFlat
}
})
},
// 上级机构选择变化
parentChange(val) {
const id = val[val.length - 1]
const tree = this.treeFlat.find((tree) => tree.id === id)
this.$set(this.formData, "code", tree?.code)
this.$set(this.formData, "name", tree?.name)
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
this.formData.id = this.ids[this.ids.length - 1]
this.formData.parentId = this.ids[this.ids.length - 2] || this.parentId
this.formData.sessionId = this.sessionId
if (valid) {
this.$axios.post(loc() + "/insert", this.formData).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
this.$emit("refresh", null)
}
})
}
})
},
del(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post(loc() + "/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
this.$emit("refresh", null)
}
})
})
}
}
}
@@ -0,0 +1,78 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row type="flex" :gutter="10" style="height: calc(100vh - 126px)">
<el-col :span="5">
<tree @node-click="treeNodeClick" ref="treeRef"></tree>
</el-col>
<el-col :span="19">
<el-card shadow="never" style="height: 100%">
<template>
<basic-table
:session-id="sessionId"
:parent-id="currentTreeData.id"
v-if="showInstitutionTable || (currentTreeData && currentTreeData.id==='0')"
ref="basicTableRef"
@refresh="$refs.treeRef.listTree()"
></basic-table>
</template>
<user-table
:session-id="sessionId"
:institution-id="currentTreeData.id"
ref="userTableRef"
v-if="!showInstitutionTable && sessionId"
></user-table>
</el-card>
</el-col>
</el-row>
</div>
<script>
<!--#include("tree.js"){}#-->
<!--#include("userTable.js"){}#-->
<!--#include("basicTable.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
tree: TREE_COMPONENT,
"user-table": USER_TABLE_COMPONENT,
"basic-table": BASIC_TABLE_COMPONENT
},
computed: {
showInstitutionTable() {
const hasChildren = this.currentTreeData?.children?.length > 0
return hasChildren
}
},
data() {
return {
currentTreeNode: null,
currentTreeData: null,
sessionId: null
}
},
methods: {
treeNodeClick(data, node, sessionId) {
this.currentTreeData = data
this.currentTreeNode = node
this.sessionId = sessionId
this.$nextTick(() => {
if (this.showInstitutionTable) {
this.$refs.basicTableRef && this.$refs.basicTableRef.doSearch()
} else {
this.$refs.userTableRef && this.$refs.userTableRef.doSearch()
}
})
},
openEdit(row) {}
},
created() {}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,61 @@
const TREE_COMPONENT = {
template: `
<el-card shadow="never" style="height: 100%" body-style="{ height: '100%' }">
<el-select v-model="sessionId" :clearable="false" style="width: 100%" @change="listTree">
<el-option v-for="i in sessionOptions" :label="i.fullName" :value="i.id" :key="i.id"></el-option>
</el-select>
<el-tree
:data="treeData"
ref="treeRef"
:expand-on-click-node="false"
:props="{
children: 'children',
label: 'name'
}"
default-expand-all
@node-click="treeNodeClick"
:filter-node-method="filterNode"
></el-tree>
</el-card>
`,
data() {
return {
currentTreeNode: null,
currentTreeData: null,
sessionOptions: [],
sessionId: null,
name: null,
treeData: []
}
},
methods: {
treeNodeClick(data, node) {
this.currentTreeData = data
this.currentTreeNode = node
this.$emit("node-click", data, node, this.sessionId)
},
filterNode() {},
listTree() {
this.$axios.post("/platform/teacherCongress/institution/leftTree", { sessionId: this.sessionId }).then((res) => {
if (res.code === 0) {
this.treeData = res.data
this.$emit("node-click", this.treeData[0], null, this.sessionId)
}
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.sessionId = this.sessionOptions[0].id
this.listTree()
}
}
})
}
},
created() {
this.listSession()
}
}
@@ -0,0 +1,148 @@
const USER_TABLE_COMPONENT = {
template: `
<div>
<el-card shadow="never" style="height: 100%">
<el-row type="flex" :gutter="20">
<el-col :span="4">
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入姓名或者工号">" @keyup.enter.native="doSearch">
</el-input>
</el-col>
<el-col :span="4">
<div class="search-query">
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
</div>
</el-col>
</el-row>
<el-divider class="mb10 mt10"></el-divider>
<table-tool>
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">设置人员</el-button>
</table-tool>
<el-table key="1" :data="tableData" ref="tableRef">
<el-table-column label="序号" width="100px" type="index" :index="indexMethod"></el-table-column>
<el-table-column prop="username" label="姓名"></el-table-column>
<el-table-column prop="loginname" label="工号"></el-table-column>
<el-table-column prop="sex" label="性别"></el-table-column>
<el-table-column prop="mobile" label="手机号码"></el-table-column>
<el-table-column prop="unitName" label="单位" show-overflow-tooltip></el-table-column>
<el-table-column prop="identity" label="身份" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="100px">
<template slot-scope="{row}">
<el-link size="mini" type="danger" @click="del(row.id)">删除</el-link>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog title="设置人员" width="50%" :visible.sync="dialogVisible">
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
<el-form-item label="届次" prop="sessionId">
<el-select v-model="formData.sessionId" disabled>
<el-option v-for="i in sessionOptions" :label="i.fullName" :value="i.id" :key="i.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="工号或姓名" prop="userId">
<user-select
v-model="formData.userId"
style="width: 100%"
api_input_key_name="query"
:option_label_func="(item)=>{return item.username + item.loginname}"
></user-select>
</el-form-item>
<el-form-item label="身份" prop="identity">
<dict-select v-model="formData.identity" code="TEACHER_CONGRESS_INSTITUTION_USER_ROLE"></dict-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
</div>
`,
mixins: [initTableMixins],
props: {
sessionId: {
required: true,
type: String
},
institutionId: {
required: true,
type: String
}
},
data() {
return {
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
userId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
identity: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
dialogVisible: false,
sessionOptions: []
}
},
methods: {
pageData() {
this.$axios
.post(loc() + "/userPageData", {
...this.pageForm,
sessionId: this.sessionId,
institutionId: this.institutionId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/teacherCongress/institution/userInsert", this.formData).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.pageData()
}
})
}
})
},
del(id) {
this.$confirm("确定删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$axios.post("/platform/teacherCongress/institution/userDelete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
.catch(() => {})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
openAdd() {
this.dialogVisible = true
this.formData = {
sessionId: this.sessionId,
institutionId: this.institutionId
}
this.listSession()
}
}
}
@@ -0,0 +1,178 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" clearable>
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</search-item>
<search-item label="关键字">
<el-input placeholder="请输入关键字查询" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%">
<el-table-column type="index" :index="indexMethod" width="50" label="序号"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="sessionId" label="教代会">
<template slot-scope="{row}">
<dict-tag :options="sessionOptions" :value="row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="type" label="类型"></el-table-column>
<el-table-column prop="createdAt" label="上传时间">
<template slot-scope="{row}">{{$moment(row.createdAt).format("YYYY-MM-DD HH:mm:ss")}}</template>
</el-table-column>
<el-table-column prop="pass" label="是否通过">
<template slot-scope="{row}">
<i class="fa fa-circle" :class="row.pass ? 'text-success' : 'text-danger'" style="margin-left: 5px"></i>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button size="mini" type="" @click="openView(scope.row.id)">查看</el-button>
<el-button size="mini" type="primary" @click="openEdit(scope.row.id)">编辑</el-button>
<el-button size="mini" type="danger" @click="doDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<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-item prop="sessionId" label="教代会">
<el-select v-model="formData.sessionId">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="name" label="文件名称">
<el-input placeholder="请输入文件名称" v-model="formData.name" maxlength="1000"></el-input>
</el-form-item>
<el-form-item prop="type" label="文件类型">
<dict-select v-model="formData.type" code="TEACHER_CONGRESS_PREPARE_FILE_TYPE"></dict-select>
</el-form-item>
<el-form-item prop="pass" label="是否通过">
<el-radio-group v-model="formData.pass" size="small">
<el-radio :label="true" border></el-radio>
<el-radio :label="false" border></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="files" label="文件">
<file-upload :value.sync="formData.files" :upload_number="5" upload_result_category="array" complete_result></file-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="查看" :visible.sync="viewDialogVisible" width="60%">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-dialog>
</div>
<script src="/assets/platform/module/democratic/teachercongress/teacherCongressCommonApi.js"></script>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
dialogFormVisible: false,
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
type: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
enable: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
pass: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
files: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: []
}
},
methods: {
openAdd() {
this.dialogFormVisible = true
this.$nextTick(() => {
this.formData = {}
})
},
openEdit(id) {
this.dialogFormVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post(loc() + "/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), { file: JSON.stringify(this.formData) }).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
openView(id) {
this.viewDialogVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
}
},
created() {
this.pageData()
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,230 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" style="width: 100%">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</search-item>
<search-item label="类型">
<el-select v-model="pageForm.type" clearable filterable placeholder="请选择类型">
<el-option
v-for="item in dict.type.TEACHER_CONGRESS_MEETING_TYPE"
:label="item.name"
:value="item.code"
:key="item.id"
></el-option>
</el-select>
</search-item>
<search-item label="名称">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入名称" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%">
<el-table-column type="index" :index="indexMethod" width="50" label="序号"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="sessionName" label="教代会">
<template scope="scope">
<dict-tag :options="sessionOptions" :value="scope.row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="startDateTime" label="开始时间"></el-table-column>
<el-table-column prop="endDateTime" label="结束时间"></el-table-column>
<el-table-column prop="site" label="场地"></el-table-column>
<el-table-column prop="type" label="类型">
<template scope="scope">
<dict-tag :options="dict.type.TEACHER_CONGRESS_MEETING_TYPE" :value="scope.row.type"></dict-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="250">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="openView(scope.row.id)">查看</el-button>
<el-button size="mini" type="primary" @click="openEdit(scope.row.id)">编辑</el-button>
<el-button size="mini" type="danger" @click="doDelete([scope.row.id])">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<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-item label="发布人">
<el-input :value="$store.state.user.username"></el-input>
</el-form-item>
<el-form-item prop="sessionId" label="教代会">
<el-select v-model="formData.sessionId">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" maxlength="100" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="类型" prop="type">
<dict-select v-model="formData.type" code="TEACHER_CONGRESS_MEETING_TYPE" placeholder="请选择类型"></dict-select>
</el-form-item>
<div class="flex">
<el-form-item label="时间" prop="times">
<el-date-picker
style="width: 100%"
v-model="formData.times"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['12:00:00', '08:00:00']"
></el-date-picker>
</el-form-item>
<el-form-item label="经费预算" prop="budget">
<el-input placeholder="请输入内容" v-model="formData.budget" maxlength="2000"></el-input>
</el-form-item>
</div>
<el-form-item label="场地" prop="site">
<el-input placeholder="请输入场地地点" v-model="formData.site" maxlength="50"></el-input>
</el-form-item>
<el-form-item label="内容" prop="content">
<el-input v-model="formData.content" type="textarea" rows="5" maxlength="2000" show-word-limit></el-input>
</el-form-item>
<el-form-item label="纪要" prop="summary">
<el-input v-model="formData.summary" type="textarea" rows="5" maxlength="1000" show-word-limit></el-input>
</el-form-item>
<el-form-item label="附件" prop="files">
<file-upload :value.sync="formData.files" :upload_number="5" upload_result_category="array" complete_result></file-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="查看" :visible.sync="viewDialogVisible" width="60%" :close-on-click-modal="false">
<el-descriptions :column="3" border>
<el-descriptions-item label="名称" :span="3">{{viewData.name}}</el-descriptions-item>
<el-descriptions-item label="发布人">{{viewData.publisher}}</el-descriptions-item>
<el-descriptions-item label="教代会">{{viewData.meetingName}}</el-descriptions-item>
<el-descriptions-item label="类型">{{viewData.type}}</el-descriptions-item>
<el-descriptions-item label="开始时间" :span="3">{{viewData.startDateTime}}</el-descriptions-item>
<el-descriptions-item label="结束时间" :span="3">{{viewData.endDateTime}}</el-descriptions-item>
<el-descriptions-item label="经费预算">{{viewData.budget}}</el-descriptions-item>
<el-descriptions-item label="场地" :span="2">{{viewData.site}}</el-descriptions-item>
<el-descriptions-item label="内容" :span="3">{{viewData.content}}</el-descriptions-item>
<el-descriptions-item label="纪要" :span="3">{{viewData.summary}}</el-descriptions-item>
<el-descriptions-item label="附件" :span="3">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</div>
<script src="/assets/platform/module/democratic/teachercongress/teacherCongressCommonApi.js"></script>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
dicts: ["TEACHER_CONGRESS_MEETING_TYPE"],
data() {
return {
deleteUrl: loc() + "/delete",
dialogFormVisible: false,
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: [],
typeOptions: [],
pageForm: {
sessionId: null,
type: null,
searchKeyword: null
}
}
},
methods: {
openAdd() {
this.formData = {
userId: this.$store.state.user.id,
times: []
}
this.dialogFormVisible = true
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate()
}
})
},
openEdit(id) {
this.dialogFormVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
res.data.times = [res.data.startDateTime, res.data.endDateTime]
if (res.data.files) {
try {
res.data.files = JSON.parse(res.data.files)
} catch (e) {
res.data.files = []
}
}
this.formData = res.data
}
})
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
const formData = this.formData
formData.startDateTime = this.formData.times[0]
formData.endDateTime = this.formData.times[1]
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), { data: JSON.stringify(formData) }).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
openView(id) {
this.viewDialogVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.pageForm.sessionId = this.sessionOptions[0].id
this.pageData()
}
}
})
}
},
created() {
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,193 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="名称">
<el-input clearable placeholder="请输入关键字查询" v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" clearable>
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button @click="openAdd" icon="el-icon-plus" size="small" type="primary">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%">
<el-table-column :index="indexMethod" label="序号" width="50" type="index"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="教代会" prop="j">
<template scope="scope">
<dict-tag :options="sessionOptions" :value="scope.row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column label="类型" prop="type"></el-table-column>
<el-table-column label="上传人" prop="userName"></el-table-column>
<el-table-column label="上传时间" prop="createdAt">
<template scope="{row}">{{$moment(row.createdAt).format('YYYY-MM-DD HH:mm:ss')}}</template>
</el-table-column>
<el-table-column label="是否通过" prop="pass">
<template slot-scope="{row}">
<i class="fa fa-circle" :class="row.pass ? 'text-success' : 'text-danger'" style="margin-left: 5px"></i>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-button @click="openView(scope.row.id)" size="mini" type="">查看</el-button>
<el-button @click="openEdit(scope.row.id)" size="mini" type="primary">编辑</el-button>
<el-button @click="doDelete(scope.row.id)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :close-on-click-modal="false" :title="formData.id ? '编辑':'新增'" :visible.sync="dialogFormVisible" width="60%">
<el-form :model="formData" :rules="formRules" label-width="120px" ref="formRef" size="small">
<el-form-item label="教代会" prop="sessionId">
<el-select v-model="formData.sessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="文件名称" prop="name">
<el-input maxlength="1000" placeholder="请输入文件名称" v-model="formData.name"></el-input>
</el-form-item>
<el-form-item label="文件类型" prop="type">
<dict-select code="TEACHER_CONGRESS_PREPARE_FILE_TYPE" v-model="formData.type"></dict-select>
</el-form-item>
<el-form-item label="是否通过" prop="pass">
<el-radio-group size="small" v-model="formData.pass">
<el-radio :label="true" border></el-radio>
<el-radio :label="false" border></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="文件" prop="files">
<file-upload :upload_number="5" :value.sync="formData.files" complete_result upload_result_category="array"></file-upload>
</el-form-item>
</el-form>
<div class="dialog-footer" slot="footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button @click="doSubmit" type="primary">确 定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="viewDialogVisible" title="查看" width="60%">
<el-descriptions :column="3" border>
<el-descriptions-item label="名称" :span="3">{{viewData.name}}</el-descriptions-item>
<el-descriptions-item label="教代会">
<dict-tag :options="sessionOptions" :value="viewData.sessionId" option_value="id" option_label="fullName"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="类型">{{viewData.type}}</el-descriptions-item>
<el-descriptions-item label="上传人">{{viewData.userName}}</el-descriptions-item>
<el-descriptions-item label="上传时间">{{$moment(viewData.createdAt).format('YYYY-MM-DD HH:mm:ss')}}</el-descriptions-item>
<el-descriptions-item label="是否通过" :span="2">
<el-tag :type="viewData.pass?'success':'danger'" size="small">{{viewData.pass ? '是' :'否'}}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="文件" :span="3">
<file-preview :files="viewData.files" complete_result></file-preview>
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
dialogFormVisible: false,
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
type: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
enable: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
pass: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
files: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: []
}
},
methods: {
openAdd() {
this.dialogFormVisible = true
this.$nextTick(() => {
this.formData = {}
})
},
openEdit(id) {
this.dialogFormVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), { file: JSON.stringify(this.formData) }).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
openView(id) {
this.viewDialogVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
}
},
created() {
this.pageData()
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,176 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年份">
<el-date-picker
:clearable="false"
v-model="pageForm.year"
value-format="yyyy"
formData="yyyy"
type="year"
placeholder="选择年份"
></el-date-picker>
</search-item>
<search-item label="届数">
<dict-select v-model="pageForm.j" code="TEACHER_CONGRESS_J"></dict-select>
</search-item>
<search-item label="次数">
<dict-select v-model="pageForm.c" code="TEACHER_CONGRESS_C"></dict-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50" :index="indexMethod" label="序号"></el-table-column>
<el-table-column prop="year" label="年份"></el-table-column>
<el-table-column prop="j" label="届数"></el-table-column>
<el-table-column prop="c" label="次数"></el-table-column>
<el-table-column prop="description" label="描述"></el-table-column>
<el-table-column prop="startDate" label="开启时间"></el-table-column>
<el-table-column prop="enable" label="开启状态">
<template slot-scope="{row}">
<i class="fa fa-circle" :class="row.enable ? 'text-success' : 'text-danger'" style="margin-left: 5px"></i>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="openEdit(scope.row.id)">编辑</el-button>
<el-button size="mini" type="danger" @click="doDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<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-item prop="year" label="年份">
<el-date-picker
style="width: 100%"
:clearable="false"
v-model="formData.year"
value-format="yyyy"
formData="yyyy"
type="year"
placeholder="选择年"
></el-date-picker>
</el-form-item>
<el-form-item prop="j" label="届数">
<dict-select v-model="formData.j" code="TEACHER_CONGRESS_J"></dict-select>
</el-form-item>
<el-form-item prop="c" label="教代会次数">
<dict-select v-model="formData.c" code="TEACHER_CONGRESS_C"></dict-select>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input type="textarea" :rows="2" style="width: 100%" placeholder="请输入教代会描述" v-model="formData.description"></el-input>
</el-form-item>
<el-form-item prop="enable" label="状态">
<el-radio-group v-model="formData.enable" size="small">
<el-radio :label="true" border>开启</el-radio>
<el-radio :label="false" border>关闭</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="isExtend" label="是否延用" v-if="!formData.id">
<el-radio-group v-model="formData.isExtend" size="small">
<el-radio :label="true" border></el-radio>
<el-radio :label="false" border></el-radio>
</el-radio-group>
<div>
延用上一次教代会的组织机构及代表信息,包含【筹备领导小组;资格审查小组;主席团;执行委员会;专门委员会;代表团;教代会代表】。
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
dialogFormVisible: false,
formRules: {
year: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
j: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
c: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
enable: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
description: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
isExtend: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
}
}
},
methods: {
openAdd() {
this.dialogFormVisible = true
this.$nextTick(() => {
this.formData = {}
})
},
openEdit(id) {
this.dialogFormVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
res.data.year = res.data.year.toString()
this.formData = res.data
}
})
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), this.formData).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post(loc() + "/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,136 @@
const AddForm = {
template: `
<el-dialog title="新增代表" :visible.sync="dialogFormVisible" width="1000px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
<el-form-item prop="sessionId" label="届次">
<el-select v-model="formData.sessionId"
style="width: 100%"
placeholder="代表所属教代会"
@change="sessionChange">
<el-option v-for="item in sessionOptions"
:key="item.id"
:label="item.fullName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="delegationId" label="代表团">
<el-select v-model="formData.delegationId" filterable @change="delegationChange" clearable style="width: 100%">
<el-option v-for="i in delegationOptions"
:label="i.name"
:key="i.id"
:value="i.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="roleId" label="代表类型">
<el-select v-model="formData.roleId" filterable style="width: 100%">
<el-option v-for="i in roleOptions"
:label="i.name"
:key="i.id"
:value="i.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userIds" label="用户">
<user-select v-model="formData.userIds"
v-if="dialogFormVisible"
api="/platform/workerCongress/delegate/manage/publicUser"
:api_params="{sessionId:formData.sessionId,delegationId:formData.delegationId}"
api_input_key_name="keyWord"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
:multiple="true"
style="width: 100%"></user-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
formData: {
userIds: [],
sessionId: null,
delegationId: null,
roleId: null
},
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
delegationId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
roleId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
userIds: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: [],
delegationOptions: [],
roleOptions: []
}
},
methods: {
onOpen(sessionId) {
if (!sessionId) {
return
}
this.formData = {
userIds: [],
sessionId: sessionId,
delegationId: null,
roleId: null
}
this.listSession()
this.listDelegation(sessionId)
this.listRole()
this.dialogFormVisible = true
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
listDelegation(sessionId) {
this.$axios.post("/platform/workerCongress/common/listDelegation", { sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/workerCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
sessionChange(sessionId) {
this.listDelegation(sessionId)
this.formData.userIds = []
},
delegationChange() {
this.formData.userIds = []
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/workerCongress/delegate/manage/insert", { data: JSON.stringify(this.formData) }).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh")
}
})
}
})
}
},
created() {}
}
@@ -0,0 +1,185 @@
var AdjustForm = {
template:
/*language=HTML*/
`
<el-dialog title="代表调整" :visible.sync="dialogFormVisible" width="65%" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
<el-row type="flex" justify="space-between">
<el-form-item prop="sessionId" label="届次">
<el-select v-model="formData.sessionId"
style="width: 100%"
placeholder="代表所属教代会"
@change="sessionChange">
<el-option v-for="item in sessionOptions"
:key="item.id"
:label="item.fullName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userId" label="用户">
<user-select v-model="formData.userId"
ref="userSelectRef"
v-if="dialogFormVisible"
api="/platform/workerCongress/delegate/manage/adjustUserList"
:api_params="{sessionId:formData.sessionId}"
api_input_key_name="keyWord"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
></user-select>
<el-button icon="el-icon-plus" type="primary" @click="move">添加到待调整列表</el-button>
</el-form-item>
</el-row>
<el-form-item prop="users" label="待调整用户">
<el-table :data="formData.users" size="small">
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex" width="50"></el-table-column>
<el-table-column label="所属工会" prop="unionName" show-overflow-tooltip></el-table-column>
<el-table-column label="所属单位" prop="unitName" show-overflow-tooltip></el-table-column>
<el-table-column label="代表团">
<template slot-scope="scope">
<el-form-item :prop="'users.'+scope.$index+'.delegationId'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select v-model="scope.row.delegationId" filterable>
<el-option v-for="d in delegationOptions" :label="d.name" :value="d.id"
:key="d.id"></el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="代表身份">
<template slot-scope="scope">
<el-form-item :prop="'users.'+scope.$index+'.roleId'"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-select v-model="scope.row.roleId" filterable style="width: 100%">
<el-option v-for="i in roleOptions"
:label="i.name"
:key="i.id"
:value="i.id"></el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-link type="primary" @click="formData.users.splice(scope.$index,1)">取消调整
</el-link>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
formData: {},
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: [],
delegationOptions: [],
roleOptions: []
}
},
methods: {
onOpen(sessionId) {
if (!sessionId) {
return
}
this.formData = {
sessionId: sessionId,
users: []
}
this.listRole()
this.listSession()
this.listDelegation(sessionId)
this.dialogFormVisible = true
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
listDelegation(sessionId) {
this.$axios.post("/platform/workerCongress/common/listDelegation", { sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/workerCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
sessionChange(sessionId) {
this.listDelegation(sessionId)
},
move() {
if (!this.formData.userId) {
this.$message.warning("请先搜索需要调整的代表")
return
}
const user = this.$refs.userSelectRef.options.find((user) => user.id === this.formData.userId)
const repeat = this.formData.users.some((u) => u.id === user.id)
if (repeat) {
this.$message.warning("调整列表中已存在,请勿重复添加")
return
}
this.formData.users.unshift(user)
this.formData.userId = null
this.$refs.userSelectRef.clearOptions()
},
doSubmit() {
if (this.formData.users.length === 0) {
this.$message.warning("请先搜索并添加需要调整的代表")
return
}
this.$refs.formRef.validate((valid) => {
if (valid) {
const data = this.formData.users.map((param) => {
return {
id: param.id,
userId: param.userId,
delegationId: param.delegationId,
sessionId: this.formData.sessionId,
roleId: param.roleId
}
})
this.$axios
.post("/platform/workerCongress/delegate/manage/doAdjustUser", {
data: JSON.stringify(data),
sessionId: this.formData.sessionId
})
.then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh")
}
})
}
})
}
},
created() {}
}
@@ -0,0 +1,207 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" @change="sessionChange">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</search-item>
<search-item label="代表团">
<el-select v-model="pageForm.delegationId" filterable @change="delegationChange" clearable style="width: 100%">
<el-option v-for="i in delegationOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="分工会">
<el-select v-model="pageForm.unionId" @change="listUnit" clearable style="width: 100%">
<el-option v-for="i in unionOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="单位">
<el-select v-model="pageForm.unitId" clearable style="width: 100%">
<el-option v-for="i in unitOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="代表类型">
<el-select v-model="pageForm.roleId" filterable clearable style="width: 100%">
<el-option v-for="i in roleOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-plus" @click="$refs.addFormRef.onOpen(pageForm.sessionId)">新增代表</el-button>
<el-button
size="small"
type="danger"
icon="el-icon-delete"
@click="batchDelete()"
:disabled="$refs.tableRef && $refs.tableRef.selection.length===0"
>
批量删除
</el-button>
<el-button size="small" type="primary" icon="el-icon-plus" @click="$refs.adjustFormRef.onOpen(pageForm.sessionId)">代表调整</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" row-key="id" ref="tableRef" style="width: 100%">
<el-table-column type="selection" width="55" reserve-selection></el-table-column>
<el-table-column type="index" width="55" label="序号" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column label="工号" prop="loginName" fixed="left"></el-table-column>
<el-table-column label="姓名" prop="userName" fixed="left" sortable></el-table-column>
<el-table-column label="性别" prop="sex" sortable></el-table-column>
<el-table-column label="年龄" prop="age" sortable></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="代表团" prop="delegationId" width="150" show-overflow-tooltip sortable>
<template scope="{row}">
<dict-tag :options="delegationOptions" :value="row.delegationId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<el-table-column label="所属工会" prop="unionName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="所属单位" prop="unitName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="届次" prop="sessionId">
<template scope="{row}">
<dict-tag :options="sessionOptions" :value="row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column label="代表身份" prop="roleId" sortable>
<template scope="{row}">
<dict-tag :options="roleOptions" :value="row.roleId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button size="mini" type="danger" @click="doDelete([scope.row.id])">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<add-form ref="addFormRef" @refresh="doSearch"></add-form>
<adjust-form ref="adjustFormRef" @refresh="doSearch"></adjust-form>
</div>
<script>
<!--#include("addForm.js"){}#-->
<!--#include("adjust.js"){}#-->
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"add-form": AddForm,
"adjust-form": AdjustForm
},
data() {
return {
pageForm: {
sessionId: null,
delegationId: null,
unionId: null,
unitId: null
},
sessionOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
roleOptions: [],
formRules: {}
}
},
methods: {
sessionChange() {
this.pageForm.delegationId = null
this.delegationOptions = []
this.listDelegation()
},
delegationChange() {
this.pageForm.unionId = null
this.pageForm.unitId = null
},
listDelegation() {
this.delegationOptions = []
this.pageForm.delegationId = null
this.$axios.post("/platform/workerCongress/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/workerCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => {
this.unionOptions = res
})
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => {
this.unitOptions = res
})
},
doDelete(ids) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post(loc() + "/delete", { data: JSON.stringify({ ids: ids }) }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
batchDelete() {
if (this.$refs.tableRef && this.$refs.tableRef.rowKey) {
const ids = this.$refs.tableRef.selection.map((row) => row[this.$refs.tableRef.rowKey])
if (ids.length === 0) {
this.$message.warning("请勾选数据后再删除")
return
}
this.doDelete(ids)
this.$refs.tableRef.clearSelection()
}
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.pageForm.sessionId = this.sessionOptions[0].id
this.listDelegation()
this.pageData()
}
}
})
}
},
created() {
this.listRole()
this.listUnion()
this.listUnit()
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,163 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="教代会">
<el-select v-model="pageForm.sessionId" @change="sessionChange">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</search-item>
<search-item label="代表团">
<el-select v-model="pageForm.delegationId" filterable @change="delegationChange" clearable style="width: 100%">
<el-option v-for="i in delegationOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="分工会">
<el-select v-model="pageForm.unionId" @change="listUnit" clearable style="width: 100%">
<el-option v-for="i in unionOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="单位">
<el-select v-model="pageForm.unitId" clearable style="width: 100%">
<el-option v-for="i in unitOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
<search-item label="代表类型">
<el-select v-model="pageForm.roleId" filterable clearable style="width: 100%">
<el-option v-for="i in roleOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-download" @click="exportXlsx">导出Excel</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" row-key="id" ref="tableRef" style="width: 100%">
<el-table-column type="selection" width="55" reserve-selection></el-table-column>
<el-table-column type="index" width="55" label="序号" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column label="工号" prop="loginName" fixed="left"></el-table-column>
<el-table-column label="姓名" prop="userName" fixed="left" sortable></el-table-column>
<el-table-column label="性别" prop="sex" sortable></el-table-column>
<el-table-column label="年龄" prop="age" sortable></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="代表团" prop="delegationId" width="150" show-overflow-tooltip sortable>
<template scope="{row}">
<dict-tag :options="delegationOptions" :value="row.delegationId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
<el-table-column label="所属工会" prop="unionName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="所属单位" prop="unitName" show-overflow-tooltip sortable></el-table-column>
<el-table-column label="届次" prop="sessionId">
<template scope="{row}">
<dict-tag :options="sessionOptions" :value="row.sessionId" option_value="id" option_label="fullName"></dict-tag>
</template>
</el-table-column>
<el-table-column label="代表身份" prop="roleId" sortable>
<template scope="{row}">
<dict-tag :options="roleOptions" :value="row.roleId" option_value="id" option_label="name"></dict-tag>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
<script>
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
},
data() {
return {
pageForm: {
sessionId: null,
delegationId: null,
unionId: null,
unitId: null
},
sessionOptions: [],
delegationOptions: [],
unionOptions: [],
unitOptions: [],
roleOptions: [],
formRules: {}
}
},
methods: {
sessionChange() {
this.pageForm.delegationId = null
this.delegationOptions = []
this.listDelegation()
},
delegationChange() {
this.pageForm.unionId = null
this.pageForm.unitId = null
},
listDelegation() {
this.delegationOptions = []
this.pageForm.delegationId = null
this.$axios.post("/platform/workerCongress/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
})
},
listRole() {
this.$axios.post("/platform/workerCongress/common/listDelegateRole").then((res) => {
if (res.code === 0) {
this.roleOptions = res.data
}
})
},
listUnion() {
this.$businessTool.listUnion().then((res) => {
this.unionOptions = res
})
},
listUnit() {
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => {
this.unitOptions = res
})
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.pageForm.sessionId = this.sessionOptions[0].id
this.listDelegation()
this.pageData()
}
}
})
},
exportXlsx() {
this.$downLoad(loc() + "/exportXlsx", this.pageForm)
},
},
created() {
this.listRole()
this.listUnion()
this.listUnit()
this.listSession()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,82 @@
const AU_FORM_TEMPLATE = {
template: `
<el-dialog :title="formData.id ? '编辑':'新增'" :visible.sync="dialogFormVisible" width="700px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" size="small" label-width="120px" :rules="formRules">
<el-form-item prop="sessionId" label="工代会">
<el-select v-model="formData.sessionId">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="name" label="代表团名称">
<el-input placeholder="请输入代表团名称" v-model="formData.name" maxlength="100"></el-input>
</el-form-item>
<el-form-item prop="code" label="代表团编码">
<el-input placeholder="请输入代表团编码" v-model="formData.code" maxlength="50"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
formData: {},
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
},
sessionOptions: []
}
},
methods: {
onOpen(id) {
this.dialogFormVisible = true
this.listSession()
if (id) {
this.$axios.post("/platform/workerCongress/delegation/findOne", { id }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
} else {
this.formData = {}
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate()
}
})
}
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios
.post("/platform/workerCongress/delegation" + (this.formData.id ? "/update" : "/insert"), this.formData)
.then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
})
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
}
},
created() {
this.listSession()
}
}
@@ -0,0 +1,89 @@
const HEAD_FORM_TEMPLATE = {
template: `
<el-dialog title="设置团长" :visible.sync="headDialogFormVisible" width="700px" :close-on-click-modal="false">
<el-form :model="formData" ref="headFormRef" size="small" label-width="120px" :rules="formRules">
<el-form-item prop="sessionId" label="教代会">
<el-select v-model="formData.sessionId" disabled>
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userId" label="团长">
<user-select v-model="formData.userId"
v-if="headDialogFormVisible"
api="/platform/workerCongress/delegation/notHeadUser"
:api_params="{sessionId:formData.sessionId,delegationId:formData.delegationId}"
api_input_key_name="keyWord"
:option_list="headOptions"
option_value="userId"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
placeholder="请输入工号或者姓名"
style="width: 100%"></user-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="headDialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmitHead">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
formData: {},
headDialogFormVisible: false,
headOptions: [],
sessionOptions: [],
formRules: {
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
}
}
},
methods: {
onOpen(delegationId, sessionId) {
if (!delegationId || !sessionId) {
return
}
this.headDialogFormVisible = true
this.listSession()
this.formData = {
sessionId,
delegationId
}
// this.findHeadUser()
},
// findHeadUser() {
// this.$axios.post("/platform/teacherCongress/delegation/headUser", this.formData).then((res) => {
// if (res.code === 0) {
// if (res.data) {
// this.headOptions = [res.data]
// this.$set(this.formData, "userId", res.data.id)
// }
// }
// })
// },
doSubmitHead() {
this.$refs.headFormRef.validate((valid) => {
if (valid) {
this.$axios.post("/platform/workerCongress/delegation/insertHead", this.formData).then((res) => {
if (res.code === 0) {
this.headDialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
})
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
}
}
}
@@ -0,0 +1,97 @@
const HEAD_TABLE_TEMPLATE = {
template: `
<div>
<table-tool>
<el-button size="small" type="primary" icon="el-icon-edit" @click="open">添加团长</el-button>
</table-tool>
<el-table :data="tableData" border>
<el-table-column type="index" label="序号" width="100px"></el-table-column>
<el-table-column prop="loginName" label="工号"></el-table-column>
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="mobile" label="电话"></el-table-column>
<el-table-column label="操作" width="100px">
<template scope="scope">
<el-link type="danger" @click="doDelete(scope.row.userId)">删除</el-link>
</template>
</el-table-column>
</el-table>
</div>
`,
props: {
session_id: {
type: String,
required: true
},
delegation_id: {
type: String,
required: true
}
},
data() {
return {
tableData: [],
pageForm: {}
}
},
watch: {
session_id: {
handler: function (val) {
if (val) {
this.pageData()
}
},
immediate: true
},
delegation_id: {
handler: function (val) {
if (val) {
this.pageData()
}
},
immediate: true
}
},
methods: {
pageData() {
this.$axios
.post("/platform/workerCongress/delegation/headUser", {
...this.pageForm,
sessionId: this.session_id,
delegationId: this.delegation_id
})
.then((res) => {
if (res.code === 0) {
if (res.data) {
this.tableData = [res.data]
} else {
this.tableData = []
}
}
})
},
open() {
this.$emit("open", this.delegation_id, this.session_id)
},
doDelete(userId) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios
.post("/platform/workerCongress/delegation/deleteHead", {
userId,
sessionId: this.session_id,
delegationId: this.delegation_id
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.$emit("refresh")
this.pageData()
}
})
})
}
}
}
@@ -0,0 +1,166 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row :gutter="10" style="height: calc(100vh - 126px)" type="flex">
<el-col :span="5">
<tree @node-click="treeNodeClick" @session-change="sessionChange" ref="treeRef"></tree>
</el-col>
<el-col :span="19">
<el-card shadow="never" style="height: 100%">
<template v-if="!currentTreeNode || (currentTreeNode && currentTreeNode.level===1)">
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter)">
<el-row type="flex">
<el-input clearable placeholder="请输入代表团名称" style="width: 220px" v-model="pageForm.searchKeyword"></el-input>
<el-button @click="doSearch" class="ml5" icon="el-icon-search" size="small" type="primary"></el-button>
</el-row>
</el-card>
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter)">
<table-tool>
<el-button @click="$refs.auFormRef.onOpen()" icon="el-icon-plus" size="small" type="primary">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" border header-align="center" style="width: 100%">
<el-table-column :index="indexMethod" label="序号" type="index" width="50"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="编码" prop="code" width="150px"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="团长" prop="delegationHead"></el-table-column>
<el-table-column label="操作" width="300">
<template slot-scope="scope">
<el-link @click="$refs.auFormRef.onOpen(scope.row.id)" size="mini" type="primary">编辑</el-link>
<el-link @click="$refs.headFormRef.onOpen(scope.row.id,scope.row.sessionId)" size="mini" type="primary">
设置团长
</el-link>
<el-link @click="$refs.partUnitRef.onOpen(scope.row.id,scope.row.sessionId)" size="mini" type="primary">
设置组成单位
</el-link>
<el-link @click="doDelete(scope.row.id)" size="mini" type="danger">删除</el-link>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template v-else>
<el-tabs v-model="secondLevelTabActive">
<el-tab-pane label="组成单位" name="partUnitTable">
<el-card class="mt10" shadow="never" style="border: 1px solid var(--border-color-lighter)">
<part-unit-table
:delegation_id="currentTreeData.id"
:session_id="pageForm.sessionId"
@open="(delegation_id,session_id)=>{$refs.partUnitRef.onOpen(delegation_id,session_id)}"
ref="partUnitTableRef"
></part-unit-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="设置团长" name="head">
<el-card class="mt10" shadow="never" style="border: 1px solid var(--border-color-lighter)">
<head-table
:delegation_id="currentTreeData.id"
:session_id="pageForm.sessionId"
@open="(delegation_id,session_id)=>{$refs.headFormRef.onOpen(delegation_id,session_id)}"
ref="headTableRef"
@refresh="refresh"
></head-table>
</el-card>
</el-tab-pane>
</el-tabs>
</template>
</el-card>
</el-col>
</el-row>
<au-form @refresh="refresh" ref="auFormRef"></au-form>
<part-unit @refresh="refresh" ref="partUnitRef"></part-unit>
<head-form @refresh="refresh" ref="headFormRef"></head-form>
</div>
<script>
<!--#include("tree.js"){}#-->
<!--#include("auForm.js"){}#-->
<!--#include("partUnit.js"){}#-->
<!--#include("headForm.js"){}#-->
<!--#include("partUnitTable.js"){}#-->
<!--#include("headTable.js"){}#-->
const vue = new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
sessionOptions: [],
currentTreeNode: null,
currentTreeData: null,
currentTreeSessionId: null,
secondLevelTabActive: "partUnitTable"
}
},
components: {
tree: TREE_TEMPLATE,
"au-form": AU_FORM_TEMPLATE,
"part-unit": PART_UNIT_TEMPLATE,
"head-form": HEAD_FORM_TEMPLATE,
"part-unit-table": PART_UNIT_TABLE_TEMPLATE,
"head-table": HEAD_TABLE_TEMPLATE
},
methods: {
refresh() {
this.$refs.treeRef.listTree()
if (this.$refs.partUnitTableRef) {
this.$refs.partUnitTableRef.doSearch()
}
if (this.$refs.headTableRef) {
this.$refs.headTableRef.pageData()
}
this.doSearch()
},
sessionChange(id) {
this.pageForm.sessionId = id
this.pageData()
},
treeNodeClick(data, node) {
this.currentTreeData = data
this.currentTreeNode = node
console.log(data)
console.log(node)
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
debugger
this.$axios.post(loc() + "/delete", { id: id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.refresh()
}
})
})
},
pageData() {
this.$axios
.post(loc() + "/pageData", {
...this.pageForm,
sessionId: this.pageForm.sessionId
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,74 @@
const PART_UNIT_TEMPLATE = {
template: `
<el-dialog title="设置组成单位" :visible.sync="partUnitDialogFormVisible" width="1000px" :close-on-click-modal="false">
<el-transfer
ref="transferRef"
:titles="['可选二级单位', '当前成员单位']"
filterable
:props="{
key: 'id',
label: 'name'
}"
:filter-method="(query,item)=>{return item.name.indexOf(query) > -1}"
v-model="selectUnitsIds"
:data="allUnits"
></el-transfer>
<div slot="footer" class="dialog-footer">
<el-button @click="partUnitDialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmitPartUnit">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
partUnitDialogFormVisible: false,
selectUnitsIds: [],
allUnits: [],
delegationId: null,
sessionId: null
}
},
methods: {
onOpen(delegationId, sessionId) {
if (!delegationId || !sessionId) {
return
}
this.partUnitDialogFormVisible = true
this.delegationId = delegationId
this.sessionId = sessionId
if (this.$refs.transferRef) {
this.$refs.transferRef.clearQuery("left")
this.$refs.transferRef.clearQuery("right")
}
this.$axios
.post("/platform/workerCongress/delegation/partUnitTransferData", {
delegationId,
sessionId
})
.then((res) => {
if (res.code === 0) {
this.selectUnitsIds = res.data.selectUnitIds
this.allUnits = res.data.allUnits
}
})
},
doSubmitPartUnit() {
this.$axios
.post(loc() + "/partUnitSet", {
unitIds: JSON.stringify(this.selectUnitsIds),
delegationId: this.delegationId,
sessionId: this.sessionId
})
.then((res) => {
if (res.code === 0) {
this.partUnitDialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
},
created() {}
}
@@ -0,0 +1,70 @@
const PART_UNIT_TABLE_TEMPLATE = {
template: `
<div>
<table-tool>
<el-button size="small" type="primary" icon="el-icon-edit" @click="open">设置组成单位</el-button>
</table-tool>
<el-table :data="tableData" border>
<el-table-column type="index" label="序号" width="100px"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
`,
mixins: [initTableMixins],
props: {
session_id: {
type: String,
required: true
},
delegation_id: {
type: String,
required: true
}
},
data() {
return {
tableData: [],
pageForm: {}
}
},
watch: {
session_id: {
handler: function (val) {
if (val) {
this.doSearch()
}
},
immediate: true
},
delegation_id: {
handler: function (val) {
if (val) {
this.doSearch()
}
},
immediate: true
}
},
methods: {
pageData() {
this.$axios
.post("/platform/workerCongress/delegation/partUnitPageData", {
...this.pageForm,
sessionId: this.session_id,
delegationId: this.delegation_id
})
.then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
open() {
this.$emit("open", this.delegation_id, this.session_id)
}
},
created() {
}
}
@@ -0,0 +1,66 @@
const TREE_TEMPLATE = {
template: `
<el-card shadow="never" style="height: 100%" body-style="{ height: '100%' }">
<el-select placeholder="输入关键字进行查找" v-model="sessionId" clearable class="mb10" @change="sessionIdChange">
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
</el-select>
<el-tree
:data="treeData"
ref="treeRef"
:expand-on-click-node="false"
:props="{
children: 'children',
label: 'name'
}"
default-expand-all
@node-click="treeNodeClick"
:filter-node-method="filterNode"
></el-tree>
</el-card>
`,
data() {
return {
currentTreeNode: null,
currentTreeData: null,
sessionOptions: [],
sessionId: null,
treeData: []
}
},
watch: {
sessionId(val) {
this.$emit("session-change", val)
}
},
methods: {
treeNodeClick(data, node) {
this.$emit("node-click", data, node)
},
filterNode() {},
listTree() {
this.$axios.post("/platform/workerCongress/delegation/tree", { sessionId: this.sessionId }).then((res) => {
if (res.code === 0) {
this.treeData = res.data
}
})
},
listSession() {
this.$axios.post("/platform/workerCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.sessionId = this.sessionOptions[0].id
this.listTree()
}
}
})
},
sessionIdChange() {
this.listTree()
}
},
created() {
this.listSession()
}
}
@@ -0,0 +1,174 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年份">
<el-date-picker
:clearable="false"
v-model="pageForm.year"
value-format="yyyy"
formData="yyyy"
type="year"
placeholder="选择年份"
></el-date-picker>
</search-item>
<search-item label="届数">
<dict-select v-model="pageForm.j" code="TEACHER_CONGRESS_J"></dict-select>
</search-item>
<search-item label="次数">
<dict-select v-model="pageForm.c" code="TEACHER_CONGRESS_C"></dict-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="small" type="primary" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%">
<el-table-column type="index" :index="indexMethod" width="50" label="序号"></el-table-column>
<el-table-column prop="year" label="年份"></el-table-column>
<el-table-column prop="j" label="届数"></el-table-column>
<el-table-column prop="c" label="次数"></el-table-column>
<el-table-column prop="description" label="描述"></el-table-column>
<el-table-column prop="startDate" label="开启时间"></el-table-column>
<el-table-column prop="enable" label="开启状态">
<template slot-scope="{row}">
<i class="fa fa-circle" :class="row.enable ? 'text-success' : 'text-danger'" style="margin-left: 5px"></i>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="openEdit(scope.row.id)">编辑</el-button>
<el-button size="mini" type="danger" @click="doDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<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-item prop="year" label="年份">
<el-date-picker
style="width: 100%"
:clearable="false"
v-model="formData.year"
value-format="yyyy"
formData="yyyy"
type="year"
placeholder="选择年"
></el-date-picker>
</el-form-item>
<el-form-item prop="j" label="届数">
<dict-select v-model="formData.j" code="TEACHER_CONGRESS_J"></dict-select>
</el-form-item>
<el-form-item prop="c" label="次数">
<dict-select v-model="formData.c" code="TEACHER_CONGRESS_C"></dict-select>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input type="textarea" :rows="2" style="width: 100%" placeholder="请输入描述" v-model="formData.description"></el-input>
</el-form-item>
<el-form-item prop="enable" label="状态">
<el-radio-group v-model="formData.enable" size="small">
<el-radio :label="true" border>开启</el-radio>
<el-radio :label="false" border>关闭</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="isExtend" label="是否延用" v-if="!formData.id">
<el-radio-group v-model="formData.isExtend" size="small">
<el-radio :label="true" border></el-radio>
<el-radio :label="false" border></el-radio>
</el-radio-group>
<div>
延用上一次工代会的组织机构及代表信息,包含【代表团;工代会代表】。
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="doSubmit">确 定</el-button>
</div>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
dialogFormVisible: false,
formRules: {
year: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
j: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
c: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
enable: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
isExtend: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
}
}
},
methods: {
openAdd() {
this.dialogFormVisible = true
this.$nextTick(() => {
this.formData = {}
})
},
openEdit(id) {
this.dialogFormVisible = true
this.$axios.post(loc() + "/findOne", { id }).then((res) => {
if (res.code === 0) {
res.data.year = res.data.year.toString()
this.formData = res.data
}
})
},
doDelete(id) {
// 确认删除吗
this.$confirm("确认删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/workerCongress/session/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
doSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), this.formData).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
}
})
}
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
+55
View File
@@ -0,0 +1,55 @@
package com.budwk.app;
import cn.hutool.core.lang.Dict;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.boot.test.junit4.NbJUnit4Runner;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.List;
@IocBean
@RunWith(NbJUnit4Runner.class)
public class FlowTest {
@Inject
private FlowEngine flowEngine;
@Test
@Aop(TransAop.READ_COMMITTED)
public void startInstance() {
String operator = "17a7f8ad3ee947b4a26175049a9c253d";
//ProcessInstance instance = flowEngine.startProcessInstanceByKey("JDHTA", "1", "17a7f8ad3ee947b4a26175049a9c253d", Dict.create());
//System.out.println(instance);
Long instanceId = 108L;
// 完成提交任务
//List<ProcessTask> applyTasks = flowEngine.executeProcessTask(199L, operator, Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode()));
//System.out.println("发起任务:" + applyTasks.size());
// 完成邀请复疑人任务 同时邀请复疑人
// Dict dict2 = Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.AGREE.getCode());
// dict2.set(FlowConst.NEXT_NODE_OPERATOR, List.of("00198c31ee094466845979ab8dabf83b", "00266dbf9e014376ab76072851b1a8ac"));
// List<ProcessTask> inviteTasks = flowEngine.executeProcessTask(200L, operator, dict2);
// System.out.println("邀请任务:" + inviteTasks.size());
// 完成第一个复疑人任务
List<ProcessTask> inviteTasks = flowEngine.executeProcessTask(215L, "00266dbf9e014376ab76072851b1a8ac",
Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.COUNTERSIGN_DISAGREE.getCode()));
// 完成第二个复疑人任务 不同意
// List<ProcessTask> inviteTasks = flowEngine.executeProcessTask(202L, "00266dbf9e014376ab76072851b1a8ac",
// Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.COUNTERSIGN_DISAGREE.getCode()));
}
}