All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.ps1.soar.service.FlowService Maven / Gradle / Ivy

package cn.ps1.soar.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.ps1.aolai.entity.User;
import cn.ps1.aolai.service.AolaiService;
import cn.ps1.aolai.service.UtilsService;
import cn.ps1.aolai.utils.ConfUtil;
import cn.ps1.aolai.utils.Const;
import cn.ps1.soar.entity.Node;
import cn.ps1.soar.entity.Task;
import cn.ps1.soar.entity.Work;
import cn.ps1.soar.utils.FlowUtil;

/**
 * 流程节点配置管理
 * 
 * @author Aolai
 * @version 1.0 $Date: 2023.12.30
 * @since openjdk-1.8
 */
@Service
public class FlowService {

	@Autowired
	private AolaiService aolai;
	@Autowired
	private UtilsService utils;
	@Autowired
	private ZeroService zeroSvc;
//	@Autowired
//	private TaskService taskSvc;

	/**
	 * 根据nodeFlowNo查询获取流程节点一览,仅支持按flowNo查询
	 */
	public Map getNodeList(HttpServletRequest req) {
		Map where = utils.jsonParams(req);
		Map user = utils.userSelf(req);
		where.put(Node.COMP, user.get(User.COMP));
		// 返回审批节点一览
		return utils.success(getNodeList(where));
	}

	/**
	 * 根据nodeFlowNo查询获取流程节点一览,仅支持按flowNo查询
	 */
	private List> getNodeList(Map where) {
		List> items; // nodeComp、nodeFlowNo
		String[] args = { null, Node.TABLE, "", Const.STR_0 };
		items = aolai.findAll(where, null, args);
		// 初始工作流还未定义节点
		if (items.size() == 0) {
			String nodeComp = (String) where.get(Node.COMP);
			String flowNo = (String) where.get(Node.FLOWNO);
			// 根据默认“flowNo00”,返回一个系统默认的全局流程
			where.put(Node.COMP, Const.STR_0);
			where.put(Node.FLOWNO, "flowNo00");
			items = aolai.findAll(where, null, args);
			if (items.size() > 0) {
				for (Map item : items) {
					item.put(Node.COMP, nodeComp);
					item.put(Node.FLOWNO, flowNo);
				}
			}
		}
		// 返回工作流数据
		return items;
	}

	/**
	 * 保存(新增或更新)全部节点的树结构(nodeFlowNo)
	 */
	@Transactional(rollbackFor = { Exception.class })
	public Map saveNodes(HttpServletRequest req) {
		Map data = utils.jsonParams(req);
		Map user = utils.userSelf(req);
		data.put(Node.COMP, user.get(User.COMP));

		// 如果已有的工作流,提示不能再编辑修改
		Map where = FlowUtil.flowNo(data, Node.KEY, Task.KEY);

		// 如果发起工作任务表中存在工作流,提示不能再编辑修改
		if (aolai.exists(null, Task.TABLE, where))
			return utils.failed(ConfUtil.CANT_UPDATE);		

		// 校验字段:nodeNo,nodeName,nodeParent,nodeStyle,nodeStep,nodeRules
		String[] keys = ConfUtil.getValid("saveNodeInfo").split(ConfUtil.COMMA);
		List> nodes = utils.obj2List(data.get("nodeItems"));
		// 遍历节点信息
		for (Map node : nodes) {
			if (!utils.availParams(node, keys) || !setNodeTier(node))
				return utils.invalidParams();
			node.put(Node.COMP, data.get(Node.COMP));
			node.put(Node.FLOWNO, data.get(Node.FLOWNO));
			node.put(Node.OPUID, user.get(User.ID));
			node.put(Node.RULES, utils.obj2Str(node.get(Node.RULES)));
			
			if(utils.isEmpty(node.get(Node.CREATE))) {
				node.put(Node.CREATE, utils.today(Const.DTF));
			}
			node.put(Node.UPDATE, utils.today(Const.DTF));
		}

		// 如果没用过,则直接先删除整个工作流
		Map cond = FlowUtil.flowNo(data, Node.KEY, Node.KEY);
		aolai.delete(null, Node.TABLE, cond);

		// 批量新增数据
		return aolai.batchAdd(null, Node.TABLE, nodes, null, false);
	}

	/**
	 * 检查参数的有效性
	 */
	private boolean setNodeTier(Map node) {
		int pTier = 0;
		String pNo = (String) node.get(Node.PARENT);
		if (pNo.length() > 1) {
			pTier = pNo.length() / FlowUtil.NODE_TIER_W;
		}
		String nodeNo = (String) node.get(Node.NO);
		int nodeTier = nodeNo.length() / FlowUtil.NODE_TIER_W;
		if (nodeTier != pTier + 1)
			return false;
		node.put(Node.TIER, nodeTier);
		return true;
	}

	/**
	 * 发送通知消息
	 */
	boolean notifyAll(List> nodes) {
		// 遍历需要通知的相关节点的待审批人员
		List> empList = new ArrayList<>();
		for (Map node : nodes) {
			if (FlowUtil.STYLE_NORMAL.equals(node.get(Node.STYLE))
					&& FlowUtil.STATE_READY.equals(node.get(Work.STATE))) {
				// 需要发送邮件或短信形式通知的员工
				empList.add(node);
			}
		}
		return zeroSvc.notifyAll(nodes.get(0).get(Node.COMP), empList);
	}

	/**
	 * 审批完成或驳回后的业务回调(补充了taskInfo参数以避免重复检索)
	 */
	boolean followProcess(Map taskInfo) {

		// 这里传入的参数task非空,不必再查询
		// 如果传入task为空,重新获取task。  ...params:{taskComp,taskId}
//		if(utils.isEmpty(task)){
//			Map cond = utils.sameId(params, Task.KEY);
//			task = aolai.findOne(null, Task.TABLE, cond);
//			if (task.containsKey(Const.STS)) {
//				return true;
//			}
//		}
		return zeroSvc.followProcess(taskInfo);
	}

	/**
	 * 审批节点与工作流节点:for EventEmitter
	 */
	String workNodeTables() {
		return Work.TABLE + " JOIN " + Node.TABLE;
	}

	/**
	 * 审批节点数据表
	 */
	String workTable() {
		return Work.TABLE;
	}

	/**
	 * 通过taskId获取业务流程的节点信息( for EventEmitter )
	 */
	List> getFlowNodes(Map params) {
		// 通过任务流水号、流程编号获取审批节点
		Map where = nodesCond(params);
		// 根据请求参数查询数据并返回查询结果
		Map> tables;
		tables = nodesCond((String) params.get(Task.ID));

		Map order = new HashMap<>();
		order.put(Node.NO, "ASC"); // 树结构

		// 排除“驳回”数据
		// where.put("{workState} !=", FlowUtil.STATE_REJECT);

		// 这里用左连接:left join
		return aolai.findAll(null, tables, "getFlowNodes", where, order);
	}

	/**
	 * 获取审批节点的查询条件
	 */
	private Map nodesCond(Map params) {
		// 首先、根据流程编号、任务编号,获取“待审批”“审批中”的节点
		Map where = FlowUtil.flowNo(params, Task.KEY, Node.KEY);
		where.put(Task.ID, params.get(Task.ID));
		return where;
	}

	/**
	 * 获取审批节点的关联表
	 */
	private Map> nodesCond(String taskId) {
		Map> tables = new HashMap<>();
		// 流程节点表
		tables.put(Node.TABLE, null);
		// 关联流程节点表
		taskId = taskId == null ? "" : taskId; // 新建任务时taskId==null
		Map cond1 = new HashMap<>();
		cond1.put(Task.COMP, Node.COMP);
		cond1.put(Task.FLOWNO, Node.FLOWNO);
		cond1.put(Task.ID, taskId);
		// 发起的工作任务表
		tables.put(Task.TABLE, cond1);

		// 关联审批节点表
		Map cond2 = new HashMap<>();
		cond2.put(Work.COMP, Node.COMP);
		cond2.put(Work.NODENO, Node.NO);
		cond2.put(Work.TASKID, taskId); // 锁定任务
		// 默认选取索引为“0”的待处理节点(workIdx=‘0’)
		cond2.put(Work.IDX, Const.STR_0);
		// “审批节点”表
		tables.put(Work.TABLE, cond2);
		return tables;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy