..
This commit is contained in:
@@ -5,9 +5,12 @@ import cn.hutool.core.bean.BeanUtil;
|
|||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.base.vo.LabelValueVO;
|
||||||
import com.budwk.app.flow.constant.FlowConst;
|
import com.budwk.app.flow.constant.FlowConst;
|
||||||
import com.budwk.app.flow.engine.FlowEngine;
|
import com.budwk.app.flow.engine.FlowEngine;
|
||||||
import com.budwk.app.flow.engine.model.ProcessModel;
|
import com.budwk.app.flow.engine.model.ProcessModel;
|
||||||
|
import com.budwk.app.flow.engine.model.TaskModel;
|
||||||
|
import com.budwk.app.flow.entity.Candidate;
|
||||||
import com.budwk.app.flow.entity.ProcessDefine;
|
import com.budwk.app.flow.entity.ProcessDefine;
|
||||||
import com.budwk.app.flow.entity.ProcessInstance;
|
import com.budwk.app.flow.entity.ProcessInstance;
|
||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
@@ -27,9 +30,7 @@ import org.nutz.mvc.annotation.At;
|
|||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@IocBean
|
@IocBean
|
||||||
@At("/flow/common")
|
@At("/flow/common")
|
||||||
@@ -163,6 +164,14 @@ public class FlowCommonController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("撤回流程实例")
|
||||||
|
public Result withdrawInstance(@Param("instanceId") Long instanceId) {
|
||||||
|
flowEngine.processInstanceService().withdraw(instanceId, SecurityUtil.getUserId());
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At("/executeTask")
|
@At("/executeTask")
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
@@ -177,6 +186,14 @@ public class FlowCommonController {
|
|||||||
submitType = ProcessSubmitTypeEnum.AGREE.getCode();
|
submitType = ProcessSubmitTypeEnum.AGREE.getCode();
|
||||||
}
|
}
|
||||||
args.put(FlowConst.SUBMIT_TYPE, submitType);
|
args.put(FlowConst.SUBMIT_TYPE, submitType);
|
||||||
|
|
||||||
|
// 设置办理人信息到表单参数
|
||||||
|
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "userName", SecurityUtil.getUserUsername());
|
||||||
|
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "loginName", SecurityUtil.getUserLoginname());
|
||||||
|
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitId", SecurityUtil.getUnitId());
|
||||||
|
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", SecurityUtil.getUnitId());
|
||||||
|
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionId", SecurityUtil.getUnionId());
|
||||||
|
|
||||||
if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.ROLLBACK.getCode())) {
|
if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.ROLLBACK.getCode())) {
|
||||||
// 退回上一个节点
|
// 退回上一个节点
|
||||||
flowEngine.executeAndJumpTask(processTaskId, operator, args, null);
|
flowEngine.executeAndJumpTask(processTaskId, operator, args, null);
|
||||||
@@ -201,4 +218,35 @@ public class FlowCommonController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At("/candidate")
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("获取候选用户")
|
||||||
|
public Result candidate(@Param("taskId") Long taskId) {
|
||||||
|
ProcessTask task = flowEngine.processTaskService().fetch(taskId);
|
||||||
|
ProcessInstance instance = flowEngine.processInstanceService().fetch(task.getProcessInstanceId());
|
||||||
|
ProcessModel processModel = flowEngine.processDefineService().getProcessModel(instance.getProcessDefineId());
|
||||||
|
// 是否存在候选处理
|
||||||
|
List<TaskModel> nextTaskModels = processModel.getNextTaskModels(task.getTaskName());
|
||||||
|
boolean b = nextTaskModels.stream().anyMatch(item -> item.getCandidateHandler() != null);
|
||||||
|
List<Candidate> candidates = processModel.getNextTaskModelCandidates(task.getTaskName());
|
||||||
|
return Result.success(Map.of("candidates", candidates, "support", b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/jumpTaskNames")
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("获取可跳转的任务节点")
|
||||||
|
public Result jumpAbleTaskNames(@Param("instanceId") Long instanceId) {
|
||||||
|
List<LabelValueVO> vos = flowEngine.processTaskService().jumpAbleTaskNameList(instanceId);
|
||||||
|
return Result.success(vos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/surrogate")
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("代理")
|
||||||
|
public Result surrogate(@Param("taskId") Long taskId, @Param("actorIds") String[] actorIds) {
|
||||||
|
flowEngine.processTaskService().addTaskActor(taskId, Arrays.asList(actorIds));
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
|
|||||||
import cn.hutool.core.lang.ClassScanner;
|
import cn.hutool.core.lang.ClassScanner;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.flow.constant.FlowConst;
|
|
||||||
import com.budwk.app.flow.engine.AssignmentHandler;
|
import com.budwk.app.flow.engine.AssignmentHandler;
|
||||||
|
import com.budwk.app.flow.engine.CandidateHandler;
|
||||||
import com.budwk.app.flow.entity.ProcessDesign;
|
import com.budwk.app.flow.entity.ProcessDesign;
|
||||||
import com.budwk.app.flow.service.ProcessDesignService;
|
import com.budwk.app.flow.service.ProcessDesignService;
|
||||||
import com.budwk.app.sys.services.SysUserService;
|
import com.budwk.app.sys.services.SysUserService;
|
||||||
@@ -47,6 +46,8 @@ public class FlowDesignController {
|
|||||||
|
|
||||||
// 获取所有任务参与者处理类
|
// 获取所有任务参与者处理类
|
||||||
public static final List<JSONObject> ASSIGMENT_HANDLER_LIST;
|
public static final List<JSONObject> ASSIGMENT_HANDLER_LIST;
|
||||||
|
// 获取所有候选用户处理类
|
||||||
|
public static final List<JSONObject> CANDIDATE_HANDLER_LIST;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Set<Class<?>> classes = ClassScanner.scanPackageBySuper("com.budwk.app", AssignmentHandler.class);
|
Set<Class<?>> classes = ClassScanner.scanPackageBySuper("com.budwk.app", AssignmentHandler.class);
|
||||||
@@ -68,6 +69,26 @@ public class FlowDesignController {
|
|||||||
ASSIGMENT_HANDLER_LIST = Collections.unmodifiableList(list);
|
ASSIGMENT_HANDLER_LIST = Collections.unmodifiableList(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
Set<Class<?>> classes = ClassScanner.scanPackageBySuper("com.budwk.app", CandidateHandler.class);
|
||||||
|
ArrayList<JSONObject> list = new ArrayList<>(classes.size());
|
||||||
|
for (Class<?> aClass : classes) {
|
||||||
|
try {
|
||||||
|
CandidateHandler handler = (CandidateHandler) ReflectUtil.newInstance(aClass);
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.set("value", handler.getClass().getName());
|
||||||
|
jsonObject.set("order", handler.getOrder());
|
||||||
|
jsonObject.set("name", handler.getMessage());
|
||||||
|
list.add(jsonObject);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("初始化CandidateHandler失败: {}", aClass.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 排序 按order
|
||||||
|
list.sort(Comparator.comparingInt(o -> o.getInt("order")));
|
||||||
|
CANDIDATE_HANDLER_LIST = Collections.unmodifiableList(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At("")
|
@At("")
|
||||||
@Ok("beetl:/platform/flow/design/index.html")
|
@Ok("beetl:/platform/flow/design/index.html")
|
||||||
@@ -101,6 +122,8 @@ public class FlowDesignController {
|
|||||||
jsonObject.set("category", processDesign.getCategory());
|
jsonObject.set("category", processDesign.getCategory());
|
||||||
jsonObject.set("instanceUrl", processDesign.getInstanceUrl());
|
jsonObject.set("instanceUrl", processDesign.getInstanceUrl());
|
||||||
jsonObject.set("h5InstanceUrl", processDesign.getH5InstanceUrl());
|
jsonObject.set("h5InstanceUrl", processDesign.getH5InstanceUrl());
|
||||||
|
jsonObject.set("instanceViewUrl",processDesign.getInstanceViewUrl());
|
||||||
|
jsonObject.set("h5InstanceViewUrl",processDesign.getH5InstanceViewUrl());
|
||||||
processDesign.setContent(jsonObject);
|
processDesign.setContent(jsonObject);
|
||||||
dao.insert(processDesign);
|
dao.insert(processDesign);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@@ -116,6 +139,8 @@ public class FlowDesignController {
|
|||||||
jsonObject.set("category", processDesign.getCategory());
|
jsonObject.set("category", processDesign.getCategory());
|
||||||
jsonObject.set("instanceUrl", processDesign.getInstanceUrl());
|
jsonObject.set("instanceUrl", processDesign.getInstanceUrl());
|
||||||
jsonObject.set("h5InstanceUrl", processDesign.getH5InstanceUrl());
|
jsonObject.set("h5InstanceUrl", processDesign.getH5InstanceUrl());
|
||||||
|
jsonObject.set("instanceViewUrl",processDesign.getInstanceViewUrl());
|
||||||
|
jsonObject.set("h5InstanceViewUrl",processDesign.getH5InstanceViewUrl());
|
||||||
processDesign.setContent(jsonObject);
|
processDesign.setContent(jsonObject);
|
||||||
processDesignService.update(processDesign);
|
processDesignService.update(processDesign);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@@ -125,6 +150,15 @@ public class FlowDesignController {
|
|||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
@ApiOperation("修改流程设计")
|
@ApiOperation("修改流程设计")
|
||||||
public Result updateContent(@Param("design") ProcessDesign processDesign) {
|
public Result updateContent(@Param("design") ProcessDesign processDesign) {
|
||||||
|
JSONObject jsonObject = processDesign.getContent();
|
||||||
|
jsonObject.set("name", processDesign.getName());
|
||||||
|
jsonObject.set("displayName", processDesign.getDisplayName());
|
||||||
|
jsonObject.set("category", processDesign.getCategory());
|
||||||
|
jsonObject.set("instanceUrl", processDesign.getInstanceUrl());
|
||||||
|
jsonObject.set("h5InstanceUrl", processDesign.getH5InstanceUrl());
|
||||||
|
jsonObject.set("instanceViewUrl",processDesign.getInstanceViewUrl());
|
||||||
|
jsonObject.set("h5InstanceViewUrl",processDesign.getH5InstanceViewUrl());
|
||||||
|
processDesign.setContent(jsonObject);
|
||||||
processDesignService.update(processDesign);
|
processDesignService.update(processDesign);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
@@ -160,9 +194,17 @@ public class FlowDesignController {
|
|||||||
@ApiOperation("获取流程设计任务参与者处理类")
|
@ApiOperation("获取流程设计任务参与者处理类")
|
||||||
public Result assigmentHandlerClass() {
|
public Result assigmentHandlerClass() {
|
||||||
return Result.success(ASSIGMENT_HANDLER_LIST);
|
return Result.success(ASSIGMENT_HANDLER_LIST);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("获取流程设计任务参与者处理类")
|
||||||
|
public Result candidateHandlerClass() {
|
||||||
|
return Result.success(CANDIDATE_HANDLER_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
@ApiOperation("获取流程设计任务参与者分页数据")
|
@ApiOperation("获取流程设计任务参与者分页数据")
|
||||||
|
|||||||
@@ -19,4 +19,12 @@ public interface CandidateHandler {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<Candidate> handle(TaskModel model);
|
List<Candidate> handle(TaskModel model);
|
||||||
|
|
||||||
|
default String getMessage() {
|
||||||
|
return this.getClass().getSimpleName();
|
||||||
|
}
|
||||||
|
default int getOrder() {
|
||||||
|
return Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public class ProcessModel extends BaseModel {
|
|||||||
private String category; // 流程定义分类
|
private String category; // 流程定义分类
|
||||||
private String instanceUrl; // 启动实例要填写的表单key
|
private String instanceUrl; // 启动实例要填写的表单key
|
||||||
private String h5InstanceUrl; // 启动实例要填写的手机端表单key
|
private String h5InstanceUrl; // 启动实例要填写的手机端表单key
|
||||||
|
private String instanceViewUrl;
|
||||||
|
private String h5InstanceViewUrl;
|
||||||
private String expireTime; // 期待完成时间变量key
|
private String expireTime; // 期待完成时间变量key
|
||||||
private String instanceNoClass; // 实例编号生成器实现类
|
private String instanceNoClass; // 实例编号生成器实现类
|
||||||
private String preInterceptors; // 节点前置拦截器
|
private String preInterceptors; // 节点前置拦截器
|
||||||
@@ -74,9 +76,7 @@ public class ProcessModel extends BaseModel {
|
|||||||
NodeModel nodeModel = getNode(nodeName);
|
NodeModel nodeModel = getNode(nodeName);
|
||||||
if(nodeModel == null) return res;
|
if(nodeModel == null) return res;
|
||||||
// 获取所有输出边的目标节点
|
// 获取所有输出边的目标节点
|
||||||
List<NodeModel> nextNodeModelList = nodeModel.getOutputs().stream().map(item->{
|
List<NodeModel> nextNodeModelList = nodeModel.getOutputs().stream().map(TransitionModel::getTarget).toList();
|
||||||
return item.getTarget();
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
nextNodeModelList.forEach(item->{
|
nextNodeModelList.forEach(item->{
|
||||||
if(item instanceof TaskModel) {
|
if(item instanceof TaskModel) {
|
||||||
res.add((TaskModel) item);
|
res.add((TaskModel) item);
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ public class LfModel extends BaseModel {
|
|||||||
private String type; // 流程定义分类
|
private String type; // 流程定义分类
|
||||||
private String expireTime;// 过期时间(常量或变量)
|
private String expireTime;// 过期时间(常量或变量)
|
||||||
private String instanceUrl; // 启动实例的url,前后端分离后,定义为路由名或或路由地址
|
private String instanceUrl; // 启动实例的url,前后端分离后,定义为路由名或或路由地址
|
||||||
|
private String h5InstanceUrl;
|
||||||
|
private String instanceViewUrl;
|
||||||
|
private String h5InstanceViewUrl;
|
||||||
private String instanceNoClass; // 启动流程时,流程实例的流水号生成类
|
private String instanceNoClass; // 启动流程时,流程实例的流水号生成类
|
||||||
private String preInterceptors; // 节点前置拦截器
|
private String preInterceptors; // 节点前置拦截器
|
||||||
private String postInterceptors; // 节点后置拦截器
|
private String postInterceptors; // 节点后置拦截器
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ public class ModelParser {
|
|||||||
processModel.setDisplayName(lfModel.getDisplayName());
|
processModel.setDisplayName(lfModel.getDisplayName());
|
||||||
processModel.setType(lfModel.getType());
|
processModel.setType(lfModel.getType());
|
||||||
processModel.setInstanceUrl(lfModel.getInstanceUrl());
|
processModel.setInstanceUrl(lfModel.getInstanceUrl());
|
||||||
|
processModel.setH5InstanceUrl(lfModel.getH5InstanceUrl());
|
||||||
|
processModel.setInstanceViewUrl(lfModel.getInstanceViewUrl());
|
||||||
|
processModel.setH5InstanceViewUrl(lfModel.getH5InstanceViewUrl());
|
||||||
processModel.setInstanceNoClass(lfModel.getInstanceNoClass());
|
processModel.setInstanceNoClass(lfModel.getInstanceNoClass());
|
||||||
processModel.setPostInterceptors(lfModel.getPostInterceptors());
|
processModel.setPostInterceptors(lfModel.getPostInterceptors());
|
||||||
processModel.setPreInterceptors(lfModel.getPreInterceptors());
|
processModel.setPreInterceptors(lfModel.getPreInterceptors());
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ public class ProcessDefine extends BaseModel {
|
|||||||
@Column
|
@Column
|
||||||
private String h5InstanceUrl;
|
private String h5InstanceUrl;
|
||||||
|
|
||||||
|
@Comment("电脑端发起地址")
|
||||||
|
@Column
|
||||||
|
private String instanceViewUrl;
|
||||||
|
|
||||||
|
@Comment("手机端发起地址")
|
||||||
|
@Column
|
||||||
|
private String h5InstanceViewUrl;
|
||||||
|
|
||||||
@Comment("图标")
|
@Comment("图标")
|
||||||
@Column
|
@Column
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|||||||
@@ -50,6 +50,14 @@ public class ProcessDesign extends BaseModel {
|
|||||||
@Column
|
@Column
|
||||||
private String h5InstanceUrl;
|
private String h5InstanceUrl;
|
||||||
|
|
||||||
|
@Comment("电脑端发起地址")
|
||||||
|
@Column
|
||||||
|
private String instanceViewUrl;
|
||||||
|
|
||||||
|
@Comment("手机端发起地址")
|
||||||
|
@Column
|
||||||
|
private String h5InstanceViewUrl;
|
||||||
|
|
||||||
@Comment("图标")
|
@Comment("图标")
|
||||||
@Column
|
@Column
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|||||||
@@ -34,4 +34,16 @@ public class ProcessTaskActor extends BaseModel {
|
|||||||
@Column
|
@Column
|
||||||
private String actorId;
|
private String actorId;
|
||||||
|
|
||||||
|
@Comment("参与者账号")
|
||||||
|
@Column
|
||||||
|
private String actorAccount;
|
||||||
|
|
||||||
|
@Comment("参与者名称")
|
||||||
|
@Column
|
||||||
|
private String actorName;
|
||||||
|
|
||||||
|
@Comment("参与者单位")
|
||||||
|
@Column
|
||||||
|
private String actorUnitName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.budwk.app.flow.handler;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import com.budwk.app.flow.engine.CandidateHandler;
|
||||||
|
import com.budwk.app.flow.engine.model.TaskModel;
|
||||||
|
import com.budwk.app.flow.entity.Candidate;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//@IocBean 此处加了会从容器里面获取 反之反射获取
|
||||||
|
public class FLowDemoCandidateHandler implements CandidateHandler {
|
||||||
|
@Override
|
||||||
|
public List<Candidate> handle(TaskModel model) {
|
||||||
|
Candidate build = Candidate.builder().userId("1").userName("测试1").ext(
|
||||||
|
Dict.of("loginName", "superadmin", "unitName", "工会")
|
||||||
|
).build();
|
||||||
|
return List.of(build);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return "候选人测试DEMO";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -120,6 +120,12 @@ public class ProcessDefineServiceImpl extends BaseServiceImpl<ProcessDefine> imp
|
|||||||
define.setCategory(processModel.getCategory());
|
define.setCategory(processModel.getCategory());
|
||||||
define.setInstanceUrl(processModel.getInstanceUrl());
|
define.setInstanceUrl(processModel.getInstanceUrl());
|
||||||
define.setH5InstanceUrl(processModel.getH5InstanceUrl());
|
define.setH5InstanceUrl(processModel.getH5InstanceUrl());
|
||||||
|
define.setInstanceViewUrl(processModel.getInstanceViewUrl());
|
||||||
|
define.setH5InstanceViewUrl(processModel.getH5InstanceViewUrl());
|
||||||
|
|
||||||
|
// define.setInstanceViewUrl(latestDefine.getInstanceViewUrl());
|
||||||
|
// define.setH5InstanceViewUrl(latestDefine.getH5InstanceViewUrl());
|
||||||
|
|
||||||
define.setState(1);
|
define.setState(1);
|
||||||
define.setContent(JSONUtil.parseObj(defineJsonStr));
|
define.setContent(JSONUtil.parseObj(defineJsonStr));
|
||||||
insert(define);
|
insert(define);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import cn.hutool.core.lang.Dict;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.expression.ExpressionUtil;
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
@@ -35,9 +34,12 @@ import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
|||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -201,16 +203,31 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
|
|||||||
public void addTaskActor(Long processTaskId, List<String> actors) {
|
public void addTaskActor(Long processTaskId, List<String> actors) {
|
||||||
if (CollectionUtil.isEmpty(actors)) return;
|
if (CollectionUtil.isEmpty(actors)) return;
|
||||||
List<String> dbActors = getTaskActors(processTaskId);
|
List<String> dbActors = getTaskActors(processTaskId);
|
||||||
actors.stream().filter(actor -> {
|
List<String> newActors = actors.stream().filter(actor -> !dbActors.contains(actor)).toList();
|
||||||
return !dbActors.contains(actor);
|
Sql sql = Sqls.create("select id,username,loginname,unitname from vw_user where id in (@ids)");
|
||||||
}).forEach(actor -> {
|
sql.setParam("ids", newActors);
|
||||||
|
List<NutMap> list = listMap(sql);
|
||||||
|
|
||||||
|
for (NutMap actor : list) {
|
||||||
ProcessTaskActor processTaskActor = new ProcessTaskActor();
|
ProcessTaskActor processTaskActor = new ProcessTaskActor();
|
||||||
processTaskActor.setProcessTaskId(processTaskId);
|
processTaskActor.setProcessTaskId(processTaskId);
|
||||||
processTaskActor.setActorId(actor);
|
processTaskActor.setActorId(actor.getString("id"));
|
||||||
|
processTaskActor.setActorName(actor.getString("username"));
|
||||||
|
processTaskActor.setActorAccount(actor.getString("loginname"));
|
||||||
|
processTaskActor.setActorUnitName(actor.getString("unitname"));
|
||||||
processTaskActor.setCreatedAt(System.currentTimeMillis());
|
processTaskActor.setCreatedAt(System.currentTimeMillis());
|
||||||
System.out.println(StrUtil.format("给任务:{},添加参与者:{}", processTaskId, actor));
|
System.out.println(StrUtil.format("给任务:{},添加参与者:{}", processTaskId, actor.toString()));
|
||||||
insert(processTaskActor);
|
insert(processTaskActor);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// actors.stream().filter(actor -> !dbActors.contains(actor)).forEach(actor -> {
|
||||||
|
// ProcessTaskActor processTaskActor = new ProcessTaskActor();
|
||||||
|
// processTaskActor.setProcessTaskId(processTaskId);
|
||||||
|
// processTaskActor.setActorId(actor);
|
||||||
|
// processTaskActor.setCreatedAt(System.currentTimeMillis());
|
||||||
|
// System.out.println(StrUtil.format("给任务:{},添加参与者:{}", processTaskId, actor));
|
||||||
|
// insert(processTaskActor);
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package com.budwk.app.flow.vo;
|
|||||||
|
|
||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.budwk.app.flow.constant.FlowConst;
|
||||||
import com.budwk.app.flow.engine.core.Execution;
|
import com.budwk.app.flow.engine.core.Execution;
|
||||||
import com.budwk.app.flow.engine.model.TaskModel;
|
import com.budwk.app.flow.engine.model.TaskModel;
|
||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
@@ -39,6 +41,9 @@ public class ProcessTaskVO extends ProcessTask {
|
|||||||
private Dict taskFormData;
|
private Dict taskFormData;
|
||||||
// @Schema(description = "任务参与者ID")
|
// @Schema(description = "任务参与者ID")
|
||||||
private List<String> taskActorIdList;
|
private List<String> taskActorIdList;
|
||||||
|
|
||||||
|
private List<JSONObject> taskActorList;
|
||||||
|
|
||||||
// @Schema(description = "当前用户是否可执行")
|
// @Schema(description = "当前用户是否可执行")
|
||||||
private boolean executable;
|
private boolean executable;
|
||||||
// @Schema(description = "节点定义信息")
|
// @Schema(description = "节点定义信息")
|
||||||
@@ -47,7 +52,6 @@ public class ProcessTaskVO extends ProcessTask {
|
|||||||
if(this.ext!=null) return this.ext;
|
if(this.ext!=null) return this.ext;
|
||||||
String variable = getVariable();
|
String variable = getVariable();
|
||||||
if(ObjectUtil.isEmpty(ext) && JSONUtil.isTypeJSON(variable)){
|
if(ObjectUtil.isEmpty(ext) && JSONUtil.isTypeJSON(variable)){
|
||||||
// this.ext = JsonTool.fromJson(variable, Dict.class);
|
|
||||||
this.ext = JSONUtil.toBean(variable, Dict.class);
|
this.ext = JSONUtil.toBean(variable, Dict.class);
|
||||||
}
|
}
|
||||||
return ext;
|
return ext;
|
||||||
@@ -57,37 +61,21 @@ public class ProcessTaskVO extends ProcessTask {
|
|||||||
if(this.instanceExt!=null) return this.instanceExt;
|
if(this.instanceExt!=null) return this.instanceExt;
|
||||||
String variable = getVariable();
|
String variable = getVariable();
|
||||||
if(ObjectUtil.isEmpty(instanceExt) && JSONUtil.isTypeJSON(instanceVariable)){
|
if(ObjectUtil.isEmpty(instanceExt) && JSONUtil.isTypeJSON(instanceVariable)){
|
||||||
// this.instanceExt = JsonTool.fromJson(instanceVariable,Dict.class);
|
|
||||||
this.instanceExt = JSONUtil.toBean(instanceVariable, Dict.class);
|
this.instanceExt = JSONUtil.toBean(instanceVariable, Dict.class);
|
||||||
}
|
}
|
||||||
return instanceExt;
|
return instanceExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public Dict getTaskFormData() {
|
public Dict getTaskFormData() {
|
||||||
// // f_前辍才是表单数据
|
// f_前辍才是表单数据
|
||||||
// this.taskFormData = Dict.of();
|
this.taskFormData = Dict.of();
|
||||||
// Dict ext = this.getExt();
|
Dict ext = this.getExt();
|
||||||
// List<String> formDataKeys = ext.keySet().stream().filter(key->key.startsWith(FlowConst.TASK_FORM_DATA_PREFIX)).collect(Collectors.toList());
|
List<String> formDataKeys = ext.keySet().stream().filter(key->key.startsWith(FlowConst.TASK_FORM_DATA_PREFIX)).toList();
|
||||||
// formDataKeys.forEach(key->{
|
formDataKeys.forEach(key->{
|
||||||
// this.taskFormData.put(key,ext.get(key));
|
this.taskFormData.put(key,ext.get(key));
|
||||||
// this.taskFormData.put(key.replaceAll(FlowConst.TASK_FORM_DATA_PREFIX,""),ext.get(key));
|
this.taskFormData.put(key.replaceAll(FlowConst.TASK_FORM_DATA_PREFIX,""),ext.get(key));
|
||||||
// });
|
});
|
||||||
// return taskFormData;
|
return taskFormData;
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 后续个任务
|
|
||||||
*/
|
|
||||||
private List<TaskModel> nextTaskModels;
|
|
||||||
|
|
||||||
// private List<TaskModel> nextTaskModels() {
|
|
||||||
// List<TaskModel> nextModels = new ArrayList<>();
|
|
||||||
//
|
|
||||||
// TaskModel model = getTaskModel();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.huimin.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
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.zhgh.dayofficework.huimin.models.Huimin;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.huimin.service.HuiminService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
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;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/huimin/manage")
|
||||||
|
@Api(("惠民服务管理"))
|
||||||
|
@Slf4j
|
||||||
|
@Ok("json:full")
|
||||||
|
public class HuiminManageController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private HuiminService huiminService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@SaCheckLogin
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/huimin/manage/index.html")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
public Result pageData(PageForm pageForm) {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
Pagination pagination = huiminService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("新增惠民服务")
|
||||||
|
public Result insert(@Param("data") Huimin huimin) {
|
||||||
|
huiminService.insert(huimin);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("修改惠民服务")
|
||||||
|
public Result update(@Param("data") Huimin huimin) {
|
||||||
|
huiminService.updateIgnoreNull(huimin);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("删除惠民服务")
|
||||||
|
public Result delete(String id) {
|
||||||
|
huiminService.delete(id);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.huimin.models;
|
||||||
|
|
||||||
|
import com.budwk.app.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("huimin")
|
||||||
|
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||||
|
@Comment("惠民服务")
|
||||||
|
public class Huimin extends BaseModel {
|
||||||
|
|
||||||
|
@Name
|
||||||
|
@Comment("id")
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Comment("标题")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
@Column
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Comment("封面")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||||
|
@Column
|
||||||
|
private String cover;
|
||||||
|
|
||||||
|
@Comment("内容")
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
@Column
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Comment("是否启用")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
@Column
|
||||||
|
@Default("1")
|
||||||
|
private Boolean enable;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.huimin.service;
|
||||||
|
|
||||||
|
import com.budwk.app.base.service.BaseService;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.huimin.models.Huimin;
|
||||||
|
|
||||||
|
public interface HuiminService extends BaseService<Huimin> {
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.huimin.service.impl;
|
||||||
|
|
||||||
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.huimin.models.Huimin;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.huimin.service.HuiminService;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
|
||||||
|
@IocBean(args = {"refer:dao"})
|
||||||
|
public class HuiminServiceImpl extends BaseServiceImpl<Huimin> implements HuiminService {
|
||||||
|
public HuiminServiceImpl(Dao dao) {
|
||||||
|
super(dao);
|
||||||
|
}
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.suggestionBox.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.democratic.suggestionBox.service.SuggestionBoxService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/suggestionBox2/apply")
|
||||||
|
@Ok("json:full")
|
||||||
|
@Api("意见箱")
|
||||||
|
public class SuggestionApplyController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SuggestionBoxService suggestionBoxService;
|
||||||
|
|
||||||
|
@At("/index")
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/suggestionBox/apply/index.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void index(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/form")
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/suggestionBox/apply/form.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void form() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
public Result pageData(Integer pageNumber, Integer pageSize) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
info.id,
|
||||||
|
info.title,
|
||||||
|
info.userName,
|
||||||
|
info.loginName,
|
||||||
|
info.unitName,
|
||||||
|
info.unionName,
|
||||||
|
info.submitTime,
|
||||||
|
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 taskVariale
|
||||||
|
FROM
|
||||||
|
suggestion_box info
|
||||||
|
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.submitTime");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
Pagination<NutMap> pagination = suggestionBoxService.listPageMap(pageNumber, pageSize, sql);
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+28
-28
@@ -36,34 +36,34 @@ public class SuggestionBoxController {
|
|||||||
@Inject
|
@Inject
|
||||||
private FlowEngine flowEngine;
|
private FlowEngine flowEngine;
|
||||||
|
|
||||||
@At
|
// @At
|
||||||
@SaCheckLogin
|
// @SaCheckLogin
|
||||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/index.html")
|
// @Ok("beetl:/platform/zhghh5/democratic/suggestionBox/index.html")
|
||||||
public void apply() {
|
// public void apply() {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
@At("/h5")
|
// @At("/h5")
|
||||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/index.html")
|
// @Ok("beetl:/platform/zhghh5/democratic/suggestionBox/index.html")
|
||||||
@SaCheckLogin
|
// @SaCheckLogin
|
||||||
public void h5Index() {
|
// public void h5Index() {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@At("/h5/write")
|
// @At("/h5/write")
|
||||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/write.html")
|
// @Ok("beetl:/platform/zhghh5/democratic/suggestionBox/write.html")
|
||||||
@SaCheckLogin
|
// @SaCheckLogin
|
||||||
public void h5Write() {
|
// public void h5Write() {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@At("/h5/mine")
|
// @At("/h5/mine")
|
||||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/mine.html")
|
// @Ok("beetl:/platform/zhghh5/democratic/suggestionBox/mine.html")
|
||||||
@SaCheckLogin
|
// @SaCheckLogin
|
||||||
public void h5Mine() {
|
// public void h5Mine() {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckLogin
|
@SaCheckLogin
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.suggestionBox.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
|
||||||
|
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/suggestionBox/view")
|
||||||
|
@Ok("json:full")
|
||||||
|
@Api("意见箱")
|
||||||
|
public class SuggestionViewController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
|
||||||
|
@At("/index")
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/suggestionBox/view/index.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void index() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/info")
|
||||||
|
@SaCheckLogin
|
||||||
|
public Result info(String id) {
|
||||||
|
SuggestionBox box = dao.fetch(SuggestionBox.class, id);
|
||||||
|
return Result.success(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+105
@@ -0,0 +1,105 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.suggestionBox.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
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.enums.ProcessTaskStateEnum;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.democratic.suggestionBox.service.SuggestionBoxService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
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 java.util.List;
|
||||||
|
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/suggestionBox2/xgh")
|
||||||
|
@Ok("json:full")
|
||||||
|
@Api("意见箱")
|
||||||
|
public class SuggestionXghController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SuggestionBoxService suggestionBoxService;
|
||||||
|
|
||||||
|
@At("/index")
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/suggestionBox/xgh/index.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void index() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/form")
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/suggestionBox/xgh/form.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void form() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
public Result pageData(PageForm pageForm, String title, Integer year, boolean approval) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
info.id,
|
||||||
|
info.title,
|
||||||
|
info.userName,
|
||||||
|
info.loginName,
|
||||||
|
info.unitName,
|
||||||
|
info.unionName,
|
||||||
|
info.submitTime,
|
||||||
|
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 taskVariale
|
||||||
|
FROM
|
||||||
|
wf_process_task t
|
||||||
|
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||||
|
LEFT JOIN suggestion_box info ON info.id = ins.businessNo
|
||||||
|
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("t.taskName", "=", "c6331519-031c-4ec5-92b0-bc7d9647bff4");
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
cnd.desc("t.createdAt");
|
||||||
|
|
||||||
|
cnd.andEX("YEAR(info.submitTime)", "=", year);
|
||||||
|
cnd.and(Cnd.likeEX("info.title", title));
|
||||||
|
|
||||||
|
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
|
||||||
|
cnd.desc("info.submitTime");
|
||||||
|
} else {
|
||||||
|
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||||
|
}
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
Pagination<NutMap> pageVO = suggestionBoxService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||||
|
return Result.success(pageVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+2
-3
@@ -11,18 +11,17 @@ import org.nutz.dao.Cnd;
|
|||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.json.Json;
|
import org.nutz.json.Json;
|
||||||
|
|
||||||
public class SuggestionBoxInterceptor implements FlowInterceptor {
|
public class SuggestionBoxApplyInterceptor implements FlowInterceptor {
|
||||||
@Override
|
@Override
|
||||||
public void intercept(Execution execution) {
|
public void intercept(Execution execution) {
|
||||||
System.out.println("..................");
|
|
||||||
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
|
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
|
||||||
SuggestionBox suggestionBox = Json.fromJson(SuggestionBox.class, formDataStr);
|
SuggestionBox suggestionBox = Json.fromJson(SuggestionBox.class, formDataStr);
|
||||||
|
|
||||||
Dao dao = ServiceContext.find(Dao.class);
|
Dao dao = ServiceContext.find(Dao.class);
|
||||||
dao.insertOrUpdate(suggestionBox);
|
dao.insertOrUpdate(suggestionBox);
|
||||||
|
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(suggestionBox));
|
||||||
|
|
||||||
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
|
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
|
||||||
dao.update(ProcessInstance.class, Chain.make("businessNo", suggestionBox.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
|
dao.update(ProcessInstance.class, Chain.make("businessNo", suggestionBox.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,37 +26,37 @@ public class SuggestionBox extends BaseModel {
|
|||||||
@Column
|
@Column
|
||||||
@Comment("提交人ID")
|
@Comment("提交人ID")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
private String submitterId;
|
private String userId;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交人姓名")
|
@Comment("提交人姓名")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
private String submitterName;
|
private String userName;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交人工号")
|
@Comment("提交人工号")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
private String submitterLoginName;
|
private String loginName;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交人单位ID")
|
@Comment("提交人单位ID")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
private String submitterUnitId;
|
private String unitId;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交人单位名称")
|
@Comment("提交人单位名称")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
private String submitterUnitName;
|
private String unitName;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交人分工会ID")
|
@Comment("提交人分工会ID")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
private String submitterUnionId;
|
private String unionId;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交人分工会名称")
|
@Comment("提交人分工会名称")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
private String submitterUnionName;
|
private String unionName;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("提交时间")
|
@Comment("提交时间")
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.suggestionBox.service;
|
||||||
|
|
||||||
|
import com.budwk.app.base.service.BaseService;
|
||||||
|
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
|
||||||
|
|
||||||
|
public interface SuggestionBoxService extends BaseService<SuggestionBox> {
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package com.budwk.app.zhgh.democratic.suggestionBox.service.impl;
|
||||||
|
|
||||||
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
|
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
|
||||||
|
import com.budwk.app.zhgh.democratic.suggestionBox.service.SuggestionBoxService;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
|
||||||
|
@IocBean(args = {"refer:dao"})
|
||||||
|
public class SuggestionBoxServiceImpl extends BaseServiceImpl<SuggestionBox> implements SuggestionBoxService {
|
||||||
|
public SuggestionBoxServiceImpl(Dao dao) {
|
||||||
|
super(dao);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -665,7 +665,6 @@ td.no-b {
|
|||||||
|
|
||||||
.flow-task-form .el-descriptions-item__label.is-bordered-label {
|
.flow-task-form .el-descriptions-item__label.is-bordered-label {
|
||||||
color: rgb(102, 102, 102) !important;
|
color: rgb(102, 102, 102) !important;
|
||||||
font-weight: bold !important;
|
|
||||||
background: rgb(248, 249, 250) !important;
|
background: rgb(248, 249, 250) !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
border: 1px solid rgb(221, 221, 221) !important;
|
border: 1px solid rgb(221, 221, 221) !important;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const initTableMixins = {
|
const initTableMixins = {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
pageDataUrl: "",
|
||||||
submitLoading: false,
|
submitLoading: false,
|
||||||
searchMore: false,
|
searchMore: false,
|
||||||
tableSize: "",
|
tableSize: "",
|
||||||
@@ -32,7 +33,7 @@ const initTableMixins = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
dropdownCommand({action, value}) {
|
dropdownCommand({ action, value }) {
|
||||||
if (action) action(value)
|
if (action) action(value)
|
||||||
},
|
},
|
||||||
columnChange(val) {
|
columnChange(val) {
|
||||||
@@ -64,8 +65,8 @@ const initTableMixins = {
|
|||||||
this.pageForm.pageSize = val
|
this.pageForm.pageSize = val
|
||||||
this.pageData()
|
this.pageData()
|
||||||
},
|
},
|
||||||
pageData(url = null, data = null) {
|
pageData(data = null) {
|
||||||
const address = url ? url : loc() + "/pageData"
|
const address = this.pageDataUrl ? this.pageDataUrl : loc() + "/pageData"
|
||||||
this.tableLoading = true
|
this.tableLoading = true
|
||||||
this.$axios.post(address, data ? data : this.pageForm).then((res) => {
|
this.$axios.post(address, data ? data : this.pageForm).then((res) => {
|
||||||
this.tableLoading = false
|
this.tableLoading = false
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const initTableMixins = {
|
const initTableMixins = {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
pageDataUrl: "",
|
||||||
submitLoading: false,
|
submitLoading: false,
|
||||||
searchMore: false,
|
searchMore: false,
|
||||||
tableSize: "",
|
tableSize: "",
|
||||||
|
|||||||
+10
-10
File diff suppressed because one or more lines are too long
-13308
File diff suppressed because one or more lines are too long
@@ -6,13 +6,13 @@
|
|||||||
<div class="title-section">
|
<div class="title-section">
|
||||||
<h2 class="page-title">{{ pageTitle }}</h2>
|
<h2 class="page-title">{{ pageTitle }}</h2>
|
||||||
<div class="page-breadcrumb">
|
<div class="page-breadcrumb">
|
||||||
<span>工作流管理</span>
|
<!-- <span>工作流管理</span>-->
|
||||||
<span class="separator">></span>
|
<!-- <span class="separator">></span>-->
|
||||||
<span>{{ isNewApplication ? "发起申请" : "任务处理" }}</span>
|
<span>{{ isNewApplication ? "发起申请" : "任务处理" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-section">
|
<div class="status-section">
|
||||||
<span class="status-label">状态:</span>
|
<span class="status-label">流程状态:</span>
|
||||||
<span class="status-badge" :class="statusClass">{{ processStatusText }}</span>
|
<span class="status-badge" :class="statusClass">{{ processStatusText }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<!-- 历史办理过程面板 -->
|
<!-- 历史办理过程面板 -->
|
||||||
<div v-if="shouldShowHistoryProcess" class="history-panel">
|
<div v-if="shouldShowHistoryProcess" class="history-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h3 class="panel-title">办理过程</h3>
|
<h3 class="panel-title">详细办理过程</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div id="history-process-container" class="form-content">
|
<div id="history-process-container" class="form-content">
|
||||||
@@ -330,7 +330,6 @@ module.exports = {
|
|||||||
|
|
||||||
// 加载申请表单
|
// 加载申请表单
|
||||||
async loadApplicationForm() {
|
async loadApplicationForm() {
|
||||||
debugger
|
|
||||||
if (!this.defineKey || !this.processDefinition.instanceUrl) return
|
if (!this.defineKey || !this.processDefinition.instanceUrl) return
|
||||||
|
|
||||||
this.pjaxLoading.apply = true
|
this.pjaxLoading.apply = true
|
||||||
@@ -401,23 +400,25 @@ module.exports = {
|
|||||||
// 加载历史办理过程
|
// 加载历史办理过程
|
||||||
async loadHistoryProcess() {
|
async loadHistoryProcess() {
|
||||||
if (!this.businessId) return
|
if (!this.businessId) return
|
||||||
|
const { instanceViewUrl } = this.processInstance.jsonObject
|
||||||
|
|
||||||
this.pjaxLoading.historyProcess = true
|
this.pjaxLoading.historyProcess = true
|
||||||
|
if (instanceViewUrl) {
|
||||||
$.pjax({
|
$.pjax({
|
||||||
url: `/platform/article/common/fullForm?businessId=${this.businessId}`,
|
url: `${instanceViewUrl}?businessId=${this.businessId}&instanceId=${this.instanceId}`,
|
||||||
container: "#history-process-container",
|
container: "#history-process-container",
|
||||||
push: false,
|
push: false,
|
||||||
replace: false,
|
replace: false,
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
|
||||||
.done(() => {
|
|
||||||
this.pjaxLoading.historyProcess = false
|
|
||||||
})
|
|
||||||
.fail(() => {
|
|
||||||
this.pjaxLoading.historyProcess = false
|
|
||||||
console.log("历史办理过程加载失败")
|
|
||||||
})
|
})
|
||||||
|
.done(() => {
|
||||||
|
this.pjaxLoading.historyProcess = false
|
||||||
|
})
|
||||||
|
.fail(() => {
|
||||||
|
this.pjaxLoading.historyProcess = false
|
||||||
|
console.log("历史办理过程加载失败")
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 显示流程图
|
// 显示流程图
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="snaker-task-action" v-if="!loading || taskInfo">
|
<div class="snaker-task-action" v-if="!loading || taskInfo">
|
||||||
|
<!-- 指定下一节点处理人 -->
|
||||||
|
<div class="next-handler-section" v-if="!isFirstTaskNodeOrNew && supportCandidate">
|
||||||
|
<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">
|
||||||
|
<el-option v-for="candidate in candidates" :key="candidate.userId" :label="candidate.userName" :value="candidate.userId">
|
||||||
|
<span style="float: left">{{ candidate.userName }}({{ candidate.ext?.loginName }})</span>
|
||||||
|
<span style="float: right; color: #8492a6; font-size: 13px">{{ candidate.ext?.unitName }}</span>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 第一个任务节点或新申请:显示提交、保存草稿、取消 -->
|
<!-- 第一个任务节点或新申请:显示提交、保存草稿、取消 -->
|
||||||
<template v-if="isFirstTaskNodeOrNew">
|
<template v-if="isFirstTaskNodeOrNew">
|
||||||
<el-button type="primary" @click="handleSubmit" :loading="actionLoading" icon="el-icon-upload2">提交</el-button>
|
<el-button type="primary" @click="handleSubmit" :loading="actionLoading" icon="el-icon-upload2">提交</el-button>
|
||||||
@@ -75,6 +88,11 @@ module.exports = {
|
|||||||
NORMAL: 0, // 普通任务
|
NORMAL: 0, // 普通任务
|
||||||
COUNTERSIGN: 1 // 会签任务
|
COUNTERSIGN: 1 // 会签任务
|
||||||
},
|
},
|
||||||
|
// 指定下一节点处理人相关
|
||||||
|
specifyNextHandler: false, // 是否指定下一节点处理人
|
||||||
|
selectedHandler: null, // 选中的处理人ID
|
||||||
|
candidates: [], // 候选人列表
|
||||||
|
supportCandidate: false,
|
||||||
|
|
||||||
taskId: GetQueryString("taskId"),
|
taskId: GetQueryString("taskId"),
|
||||||
instanceId: GetQueryString("instanceId"),
|
instanceId: GetQueryString("instanceId"),
|
||||||
@@ -104,6 +122,7 @@ module.exports = {
|
|||||||
// 只有当有任务ID时才加载任务信息
|
// 只有当有任务ID时才加载任务信息
|
||||||
if (this.taskId) {
|
if (this.taskId) {
|
||||||
this.loadTaskInfo()
|
this.loadTaskInfo()
|
||||||
|
this.loadCandidates()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -149,8 +168,8 @@ module.exports = {
|
|||||||
handleAction(actionKey) {
|
handleAction(actionKey) {
|
||||||
if (this.actionLoading || !this.taskInfo) return
|
if (this.actionLoading || !this.taskInfo) return
|
||||||
|
|
||||||
// 触发父组件事件,传递操作类型和任务信息
|
// 构建操作数据
|
||||||
this.$emit("task-action", {
|
const actionData = {
|
||||||
submitType: this.actionEnum[actionKey],
|
submitType: this.actionEnum[actionKey],
|
||||||
taskId: this.taskId,
|
taskId: this.taskId,
|
||||||
processTaskId: this.taskId,
|
processTaskId: this.taskId,
|
||||||
@@ -158,7 +177,15 @@ module.exports = {
|
|||||||
defineId: this.defineId,
|
defineId: this.defineId,
|
||||||
defineKey: this.defineKey,
|
defineKey: this.defineKey,
|
||||||
businessId: this.businessId
|
businessId: this.businessId
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// 如果指定了下一节点处理人,添加到操作数据中
|
||||||
|
if (this.specifyNextHandler && this.selectedHandler) {
|
||||||
|
actionData.tf_nextNodeOperator = this.selectedHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发父组件事件,传递操作类型和任务信息
|
||||||
|
this.$emit("task-action", actionData)
|
||||||
},
|
},
|
||||||
|
|
||||||
// 保存草稿
|
// 保存草稿
|
||||||
@@ -168,7 +195,7 @@ module.exports = {
|
|||||||
this.$emit("save-draft", {
|
this.$emit("save-draft", {
|
||||||
submitType: this.actionEnum.APPLY,
|
submitType: this.actionEnum.APPLY,
|
||||||
defineKey: this.defineKey,
|
defineKey: this.defineKey,
|
||||||
defineId: this.defineId,
|
defineId: this.defineId
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -182,6 +209,25 @@ module.exports = {
|
|||||||
if (this.taskId) {
|
if (this.taskId) {
|
||||||
this.loadTaskInfo()
|
this.loadTaskInfo()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理指定下一节点处理人勾选框变化
|
||||||
|
onSpecifyNextHandlerChange(checked) {
|
||||||
|
if (!checked) {
|
||||||
|
this.selectedHandler = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 加载候选人列表
|
||||||
|
loadCandidates() {
|
||||||
|
$.get("/flow/common/candidate", {
|
||||||
|
taskId: this.taskId
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.candidates = res.data.candidates
|
||||||
|
this.supportCandidate = res.data.support
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,6 +254,25 @@ module.exports = {
|
|||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 指定下一节点处理人样式 */
|
||||||
|
.next-handler-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 15px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handler-select-wrapper {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handler-select {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 响应式 */
|
/* 响应式 */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.snaker-task-action {
|
.snaker-task-action {
|
||||||
@@ -221,5 +286,14 @@ module.exports = {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.next-handler-section {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handler-select {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,149 +1,173 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
<title>流程设计器</title>
|
<title>流程设计器</title>
|
||||||
<script src="/assets/platform/plugins/vue/vue.js"></script>
|
<script src="/assets/platform/plugins/vue/vue.js"></script>
|
||||||
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
|
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
|
||||||
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
|
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
|
||||||
<link rel="stylesheet" href="https://cdn.staticfile.net/element-ui/2.15.14/theme-chalk/index.css" />
|
<link rel="stylesheet" href="https://cdn.staticfile.net/element-ui/2.15.14/theme-chalk/index.css" />
|
||||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
|
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
|
||||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
|
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
|
||||||
<link rel="stylesheet" href="${base!}/assets/platform/css/root.css" />
|
<link rel="stylesheet" href="${base!}/assets/platform/css/root.css" />
|
||||||
<!-- 引入 core 包和对应 css-->
|
<!-- 引入 core 包和对应 css-->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
||||||
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#app {
|
#app {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<snaker-flow-designer ref="designer"
|
<snaker-flow-designer
|
||||||
v-model="flowData"
|
ref="designer"
|
||||||
@on-save="handleSave"
|
v-model="flowData"
|
||||||
:show-doc="false"
|
@on-save="handleSave"
|
||||||
node-render-type="html"
|
:show-doc="false"
|
||||||
:extend-property-keys="[
|
node-render-type="html"
|
||||||
|
:extend-property-keys="[
|
||||||
'candidateUsers',
|
'candidateUsers',
|
||||||
'candidateGroups',
|
'candidateGroups',
|
||||||
'candidateHandler',
|
'candidateHandler',
|
||||||
'assigneeText',
|
'assigneeText',
|
||||||
'assigneeMode'
|
'assigneeMode'
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<!-- <template v-slot:form-item-task-form="{model,field}">-->
|
<!-- <template v-slot:form-item-task-form="{model,field}">-->
|
||||||
<!-- <el-form-item label="form">-->
|
<!-- <el-form-item label="form">-->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
<!-- </template>-->
|
<!-- </template>-->
|
||||||
|
|
||||||
<template v-slot:form-item-task-assignee="{model,field}">
|
<template v-slot:form-item-task-assignee="{model,field}">
|
||||||
<assignee-form :model="model" :field="field"
|
<assignee-form :model="model" :field="field" :start_node_next_node_ids="startNodeNextNodeIds"></assignee-form>
|
||||||
:start_node_next_node_ids="startNodeNextNodeIds"></assignee-form>
|
</template>
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-slot:form-item-task-assignment-handler="{model,field}">
|
<template v-slot:form-item-task-assignment-handler="{model,field}">
|
||||||
<el-form-item label="参与者处理类">
|
<el-form-item label="参与者处理类">
|
||||||
<el-select v-model="model[field]" style="width: 100%" clearable
|
<el-select v-model="model[field]" style="width: 100%" clearable :disabled="startNodeNextNodeIds.includes(model.name)">
|
||||||
:disabled="startNodeNextNodeIds.includes(model.name)">
|
<el-option
|
||||||
<el-option v-for="item in assignmentHandlerClassOptions" :key="item.value"
|
v-for="item in assignmentHandlerClassOptions"
|
||||||
:value="item.value"
|
:key="item.value"
|
||||||
:label="item.name">
|
:value="item.value"
|
||||||
</el-option>
|
:label="item.name"
|
||||||
</el-select>
|
></el-option>
|
||||||
</el-form-item>
|
</el-select>
|
||||||
</template>
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
</snaker-flow-designer>
|
<template v-slot:form-item-task-candidate-handler="{model,field}">
|
||||||
</div>
|
<el-form-item label="候选者处理类">
|
||||||
</body>
|
<el-select v-model="model[field]" style="width: 100%" clearable :disabled="startNodeNextNodeIds.includes(model.name)">
|
||||||
<script>
|
<el-option
|
||||||
<!--#include('assigneeForm.js'){}#-->
|
v-for="item in candidateHandlerClassOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:value="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
Vue.use(SnakerflowDesigner.default)
|
<!-- <template v-slot="{model,field}">-->
|
||||||
const vue = new Vue({
|
<!-- <el-form-item label="表单查看URL">-->
|
||||||
el: "#app",
|
<!-- <el-input v-model="model[instanceViewUrl]"></el-input>-->
|
||||||
components: {
|
<!-- </el-form-item>-->
|
||||||
"assignee-form": assigneeForm
|
<!-- </template>-->
|
||||||
},
|
</snaker-flow-designer>
|
||||||
data() {
|
</div>
|
||||||
return {
|
</body>
|
||||||
id: "${id!}",
|
<script>
|
||||||
designerData: {},
|
<!--#include('assigneeForm.js'){}#-->
|
||||||
flowData: {},
|
|
||||||
assignmentHandlerClassOptions: []
|
Vue.use(SnakerflowDesigner.default)
|
||||||
}
|
const vue = new Vue({
|
||||||
},
|
el: "#app",
|
||||||
computed: {
|
components: {
|
||||||
startNodeNextNodeIds() {
|
"assignee-form": assigneeForm
|
||||||
if (this.$refs.designer && this.$refs.designer.lf) {
|
},
|
||||||
const graphData = this.$refs.designer.lf.getGraphData()
|
data() {
|
||||||
if (graphData) {
|
return {
|
||||||
const { nodes, edges } = graphData
|
id: "${id!}",
|
||||||
const startNode = nodes.find(v => v.type === "snaker:start")
|
designerData: {},
|
||||||
if (startNode) {
|
flowData: {},
|
||||||
const targetNodeIds = edges.filter(v => v.sourceNodeId === startNode.id).map(v => v.targetNodeId)
|
assignmentHandlerClassOptions: [],
|
||||||
return targetNodeIds
|
candidateHandlerClassOptions: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
startNodeNextNodeIds() {
|
||||||
|
if (this.$refs.designer && this.$refs.designer.lf) {
|
||||||
|
const graphData = this.$refs.designer.lf.getGraphData()
|
||||||
|
if (graphData) {
|
||||||
|
const { nodes, edges } = graphData
|
||||||
|
const startNode = nodes.find((v) => v.type === "snaker:start")
|
||||||
|
if (startNode) {
|
||||||
|
const targetNodeIds = edges.filter((v) => v.sourceNodeId === startNode.id).map((v) => v.targetNodeId)
|
||||||
|
return targetNodeIds
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return []
|
||||||
}
|
}
|
||||||
return []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleSave(val) {
|
|
||||||
const design = {
|
|
||||||
...this.designerData,
|
|
||||||
content: val.json
|
|
||||||
}
|
|
||||||
$.post("/flow/design/updateContent", { design: JSON.stringify(design) }).then(res => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
window.parent.postMessage("success")
|
|
||||||
} else {
|
|
||||||
window.parent.postMessage("error")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getDetail() {
|
methods: {
|
||||||
$.get("/flow/design/detail", { id: this.id }).then((res) => {
|
handleSave(val) {
|
||||||
if (res.code === 0) {
|
const design = {
|
||||||
this.designerData = res.data
|
...this.designerData,
|
||||||
if (res.data.content) {
|
content: val.json
|
||||||
this.flowData = res.data.content
|
}
|
||||||
|
$.post("/flow/design/updateContent", { design: JSON.stringify(design) }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
window.parent.postMessage("success")
|
||||||
} else {
|
} else {
|
||||||
this.flowData = {}
|
window.parent.postMessage("error")
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
},
|
||||||
|
getDetail() {
|
||||||
|
$.get("/flow/design/detail", { id: this.id }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.designerData = res.data
|
||||||
|
if (res.data.content) {
|
||||||
|
this.flowData = res.data.content
|
||||||
|
} else {
|
||||||
|
this.flowData = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
init() {
|
||||||
|
$.get("/flow/design/assigmentHandlerClass").then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.assignmentHandlerClassOptions = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.get("/flow/design/candidateHandlerClass").then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.candidateHandlerClassOptions = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
console.log(this.$refs.designer)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
init() {
|
this.init()
|
||||||
$.get("/flow/design/assigmentHandlerClass").then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.assignmentHandlerClassOptions = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
getData() {
|
if (this.id) {
|
||||||
console.log(this.$refs.designer)
|
this.getDetail()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
</script>
|
||||||
created() {
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (this.id) {
|
|
||||||
this.getDetail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -77,6 +77,12 @@ layout("/layouts/platform.html"){
|
|||||||
<el-form-item label="手机端发起地址" prop="h5InstanceUrl">
|
<el-form-item label="手机端发起地址" prop="h5InstanceUrl">
|
||||||
<el-input v-model="formData.h5InstanceUrl" placeholder="请输入手机端发起地址"></el-input>
|
<el-input v-model="formData.h5InstanceUrl" placeholder="请输入手机端发起地址"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="电脑端查看地址" prop="instanceViewUrl">
|
||||||
|
<el-input v-model="formData.instanceViewUrl" placeholder="请输入电脑端发起地址"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机端查看地址" prop="h5InstanceViewUrl">
|
||||||
|
<el-input v-model="formData.h5InstanceViewUrl" placeholder="请输入手机端发起地址"></el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="图标" prop="icon">
|
<el-form-item label="图标" prop="icon">
|
||||||
<el-input v-model="formData.icon" placeholder="请输入图标"></el-input>
|
<el-input v-model="formData.icon" placeholder="请输入图标"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
<!--#
|
||||||
|
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.displayName" 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="title" label="标题"></el-table-column>
|
||||||
|
<el-table-column prop="isDeployed" label="是否启用">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-tag size="mini" v-if="row.enable" type="success">是</el-tag>
|
||||||
|
<el-tag size="mini" v-else type="info">否</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" fixed="right" width="250px">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-button size="mini" type="primary" @click="onEdit(row)">编辑</el-button>
|
||||||
|
<el-button type="danger" 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="70%">
|
||||||
|
<el-form :model="formData" ref="formRef" label-width="120px">
|
||||||
|
<el-form-item label="标题" prop="title" :rules="{ required: true, message: '请输入标题', trigger: 'blur' }">
|
||||||
|
<el-input v-model="formData.title" placeholder="请输入标题"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="封面图" prop="cover" :rules="{ required: true, message: '请上传封面图', trigger: 'blur' }">
|
||||||
|
<file-upload
|
||||||
|
:value.sync="formData.cover"
|
||||||
|
:upload_number="1"
|
||||||
|
upload_mode="image"
|
||||||
|
upload_result_category="interval"
|
||||||
|
upload_result_type="url"
|
||||||
|
></file-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="内容" prop="content" :rules="{ required: true, message: '请输入内容', trigger: 'blur' }">
|
||||||
|
<text-editor v-model="formData.content"></text-editor>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否启用" prop="enable">
|
||||||
|
<el-switch v-model="formData.enable"></el-switch>
|
||||||
|
</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",
|
||||||
|
store,
|
||||||
|
mixins: [initTableMixins],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
formData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onAdd() {
|
||||||
|
this.formData = {}
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
onEdit(row) {
|
||||||
|
this.dialogVisible = true
|
||||||
|
this.formData = { ...row }
|
||||||
|
},
|
||||||
|
onSubmit() {
|
||||||
|
$.post("/platform/huimin/manage/" + (this.formData.id ? "update" : "insert"), { data: JSON.stringify(this.formData) }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success(res.msg)
|
||||||
|
this.pageData()
|
||||||
|
this.dialogVisible = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.pageData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
<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-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="姓名">{{formData.userName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="工号">{{formData.loginName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="单位">{{formData.unitName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="工会">{{formData.unionName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="标题" :span="2">
|
||||||
|
<el-form-item prop="title" label="标题">
|
||||||
|
<el-input v-model="formData.title" maxlength="100" show-word-limit placeholder="请输入标题"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="填写意见建议内容" :span="2">
|
||||||
|
<el-form-item prop="content" label="填写意见建议内容">
|
||||||
|
<el-input v-model="formData.content" type="textarea" maxlength="500" show-word-limit placeholder="请输入内容"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-form>
|
||||||
|
<snaker-flow-task-form-action @task-action="handleTaskAction" @save-draft="handleSaveDraft" @cancel="handleCancel"></snaker-flow-task-form-action>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: "#suggestion-box-apply-form",
|
||||||
|
store,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
businessId: GetQueryString("businessId"),
|
||||||
|
formData: {},
|
||||||
|
formRules: {
|
||||||
|
title: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
|
content: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleTaskAction(val) {
|
||||||
|
console.log(val)
|
||||||
|
this.$refs.formRef.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$axios
|
||||||
|
.post("/flow/common/startInstanceAndExecute", {
|
||||||
|
...val,
|
||||||
|
bizData: JSON.stringify(this.formData)
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success("操作成功")
|
||||||
|
window.parent.postMessage({ type: "task-complete" }, "*")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSaveDraft(val) {
|
||||||
|
this.$refs.formRef.validateField(["title"], (errMsg) => {
|
||||||
|
if (errMsg) {
|
||||||
|
this.$message.warning("请填写标题")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$axios
|
||||||
|
.post("/flow/common/startInstance", {
|
||||||
|
...val,
|
||||||
|
bizData: JSON.stringify(this.formData)
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success(res.msg)
|
||||||
|
// 发送完成消息
|
||||||
|
window.parent.postMessage(
|
||||||
|
{
|
||||||
|
type: "task-complete"
|
||||||
|
},
|
||||||
|
"*"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
// 关闭浏览器窗口
|
||||||
|
window.close()
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
if (this.businessId) {
|
||||||
|
} else {
|
||||||
|
const { username, loginname, id, unit, union, mobile } = this.$store.state.user
|
||||||
|
this.formData = {
|
||||||
|
userName: username,
|
||||||
|
loginName: loginname,
|
||||||
|
submitterId: id,
|
||||||
|
unitId: unit?.id,
|
||||||
|
unitName: unit?.name,
|
||||||
|
unionId: union?.id,
|
||||||
|
unionName: union?.name,
|
||||||
|
concat: mobile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<!--#
|
||||||
|
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 type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column prop="title" label="投稿标题"></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="unitName" label="投稿人单位"></el-table-column>
|
||||||
|
<el-table-column prop="unionName" label="投稿人工会"></el-table-column>
|
||||||
|
<el-table-column prop="submitTime" label="投稿时间"></el-table-column>
|
||||||
|
<el-table-column prop="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="onOpen(row.id)" size="mini" type="primary">查看</el-button>
|
||||||
|
<el-button v-if="row.taskKey === 'apply' || !row.instanceId" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||||
|
<el-button v-if="['waiting'].includes(row.flow_status)" size="mini" type="danger" @click="onRevoke(row.id)">撤销</el-button>
|
||||||
|
<el-button v-if="row.taskKey === 'apply' || !row.instanceId" @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/suggestionBox2/apply/pageData"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onOpen(id) {},
|
||||||
|
onEdit(row) {
|
||||||
|
window.open(
|
||||||
|
"/flow/common/approval/form?taskId=" +
|
||||||
|
(row.taskId || "") +
|
||||||
|
"&instanceId=" +
|
||||||
|
(row.instanceId || "") +
|
||||||
|
"&businessId=" +
|
||||||
|
row.id +
|
||||||
|
"&defineKey=XWTG"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onRevoke(id) {},
|
||||||
|
onDelete(id) {}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.pageData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<div id="suggestion-box-view">
|
||||||
|
<!-- <el-form ref="formRef" label-width="0" label-suffix=":" class="flow-task-form">-->
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="工会">{{viewData.unionName}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="标题" :span="2">{{viewData.viewData}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="填写意见建议内容" :span="2">{{viewData.content}}</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>
|
||||||
|
<!-- </el-form>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: "#suggestion-box-view",
|
||||||
|
store,
|
||||||
|
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
businessId: GetQueryString("businessId"),
|
||||||
|
instanceId: GetQueryString("instanceId"),
|
||||||
|
viewData: {},
|
||||||
|
doneTasks: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
info() {
|
||||||
|
this.$axios.post("/platform/suggestionBox/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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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,49 @@
|
|||||||
|
<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.parent.postMessage(
|
||||||
|
{
|
||||||
|
type: "task-complete"
|
||||||
|
},
|
||||||
|
"*"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCancel(val) {
|
||||||
|
console.log(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<!--#
|
||||||
|
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 type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column prop="title" label="投稿标题"></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="unitName" label="投稿人单位"></el-table-column>
|
||||||
|
<el-table-column prop="unionName" label="投稿人工会"></el-table-column>
|
||||||
|
<el-table-column prop="submitTime" label="投稿时间"></el-table-column>
|
||||||
|
<el-table-column prop="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="onOpen(row.id)" size="mini" type="primary">查看</el-button>
|
||||||
|
<el-button v-if="row.taskState === 10" @click="openApproval(row)" size="mini" type="primary">审核</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/suggestionBox2/xgh/pageData",
|
||||||
|
pageForm: {
|
||||||
|
approval: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onOpen() {},
|
||||||
|
openApproval(row) {
|
||||||
|
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.pageData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
Reference in New Issue
Block a user