package cn.myapps.runtime.rest.workflow.service;

import static cn.myapps.runtime.workflow.storage.runtime.ejb.NodeRT.FLOWSTATE_HANDUP;

import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.myapps.common.util.cache.MemoryCacheUtil;
import cn.myapps.runtime.dynaform.document.model.PureDocument;
import cn.myapps.runtime.workflow.storage.runtime.ejb.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;

import cn.myapps.authtime.user.model.UserVO;
import cn.myapps.authtime.user.service.UserProcess;
import cn.myapps.base.web.WebUser;
import cn.myapps.common.data.ParamsTable;
import cn.myapps.common.exception.OBPMValidateException;
import cn.myapps.common.model.workflow.BillDefiVO;
import cn.myapps.common.util.StringUtil;
import cn.myapps.designtime.common.service.DesignTimeServiceManager;
import cn.myapps.designtime.workflow.definition.service.BillDefiDesignTimeService;
import cn.myapps.runtime.common.service.RunTimeServiceManager;
import cn.myapps.runtime.dynaform.document.ejb.DocumentProcess;
import cn.myapps.runtime.dynaform.document.model.IDocument;
import cn.myapps.runtime.scheduler.ejb.TriggerVO;
import cn.myapps.runtime.scheduler.engine.RegularScheduler;
import cn.myapps.runtime.scheduler.engine.job.Job;
import cn.myapps.runtime.scheduler.engine.job.JobFactory;
import cn.myapps.runtime.scheduler.engine.job.ManualNodeTimingApprovalJob;
import cn.myapps.runtime.workflow.FlowState;
import cn.myapps.runtime.workflow.FlowType;
import cn.myapps.runtime.workflow.element.FlowDiagram;
import cn.myapps.runtime.workflow.element.ManualNode;
import cn.myapps.runtime.workflow.element.Node;
import cn.myapps.runtime.workflow.element.OGraphics;
import cn.myapps.runtime.workflow.engine.StateMachine;
import cn.myapps.runtime.workflow.engine.instruction.InstructionExecutor;
import cn.myapps.runtime.workflow.notification.ejb.NotificationConstant;
import cn.myapps.runtime.workflow.utility.Sequence;
import cn.myapps.util.ProcessFactory;

@Service
public class WorkflowExecuteServiceImpl implements WorkflowExecuteService {

	@Override
	public void start(IDocument doc, WebUser user,ParamsTable params, String flowId)throws Exception {

		BillDefiDesignTimeService flowProcss = DesignTimeServiceManager.billDefiDesignTimeService();
		DocumentProcess proxy = RunTimeServiceManager.documentProcess(doc.getApplicationid());
		BillDefiVO flowVO = (BillDefiVO) flowProcss.doView(flowId);

		Node firstNode = StateMachine.getFirstNode(doc, flowVO, (WebUser) user, params);

		if (firstNode != null) {
			Node startNode = StateMachine.getStartNodeByFirstNode(flowVO, firstNode);
			if (startNode != null) {
				params.setParameter("_flowid", flowId);
				try {
					proxy.doStartFlowOrUpdate(doc, params, (WebUser) user);
				} catch (Exception e) {
					throw e;
				}

			}
		} else {
			throw new OBPMValidateException("workflowCode错误！");
		}
	}

	@Override
	public void submit(IDocument doc, WebUser user, ParamsTable params, String currNodeId, String[] nextNodeIds, String flowType, String comment) throws Exception {

		DocumentProcess proxy = RunTimeServiceManager.documentProcess(doc.getApplicationid());

		proxy.doFlow(doc,params,currNodeId,nextNodeIds,flowType,comment,user);
	}

	@Override
	public void back(IDocument doc, WebUser user, ParamsTable params, String currNodeId, String[] nextNodeIds, String flowType, String comment, String flowId ,String applicationId) throws Exception {
		params.setParameter("_flowid",flowId);
		DocumentProcess proxy = RunTimeServiceManager.documentProcess(
				applicationId);
		proxy.doFlow(doc, params, currNodeId, nextNodeIds, flowType, comment, user);

	}

	@Override
	public void retract(IDocument doc, WebUser user, ParamsTable params, String applicationId) throws Exception {
		DocumentProcess proxy = RunTimeServiceManager.documentProcess(
				applicationId);
		BillDefiVO flowVO = doc.getState().getFlowVO();
		FlowDiagram fd = flowVO.toFlowDiagram();

		Node currNode = null;
		if (doc.getState().isComplete()) {
			FlowHistoryService procss = new FlowHistoryServiceImpl(applicationId);
			RelationHIS his = procss.getCompleteRelationHIS(doc.getId(), doc.getState().getId());
			currNode = (Node) fd.getElementByID(his.getEndnodeid());

		} else if (doc.getState().getNoderts() != null && doc.getState().getNoderts().size() > 0) {
			NodeRT nodert = (NodeRT) doc.getState().getNoderts().iterator().next();
			currNode = (Node) fd.getElementByID(nodert.getNodeid());
		}

		Node nextNode = StateMachine.getBackNodeByHis(doc, flowVO, currNode.id, user, FlowState.RUNNING);
		if (nextNode != null) {

			Collection<Node> fromNode = new ArrayList<Node>();
			if (((ManualNode) nextNode).issplit) {
				Collection<NodeRT> noderts = doc.getState().getNoderts();
				Collection<Node> nextNodeList = fd.getNextNodeList(nextNode.id, doc, params, user);
				if (!nextNodeList.isEmpty() && !noderts.isEmpty()) {
					for (Iterator<Node> iterator = nextNodeList.iterator(); iterator.hasNext();) {
						Node node = (Node) iterator.next();
						for (Iterator<NodeRT> iter = noderts.iterator(); iter.hasNext();) {
							NodeRT rt = iter.next();
							if (node.id.equals(rt.getNodeid())) {
								fromNode.add(node);
								break;
							}
						}
					}
				}
			} else {
				fromNode.add(currNode);
			}

			for (Iterator<Node> iterator = fromNode.iterator(); iterator.hasNext();) {
				Node node = (Node) iterator.next();

				// 指的审批人
				String submitTo = "[{\"nodeid\":'" + nextNode.id + "',\"isToPerson\":'true',\"userids\":\"['"
						+ user.getId() + "']\"},]";
				params.setParameter("submitTo", submitTo);

				String[] nextids = { nextNode.id };
				proxy.doFlow(doc, params, node.id, nextids,
						FlowType.RUNNING2RUNNING_RETRACEMENT, "", user);

			}
		}
	}

	@Override
	public void recovery(IDocument doc, WebUser user, ParamsTable params, String applicationId) throws Exception {
		Date actionTime = new Date();

		FlowRuntimeService nodeRTProcess = new FlowRuntimeServiceImpl( applicationId);
		FlowHistoryService relationHISProcess = new FlowHistoryServiceImpl( applicationId);

		//获取当前节点id和nodertId
		FlowStateRT instance1 = doc.getState();
		BillDefiVO flowVO1 = instance1.getFlowVO();
		NodeRT nodeRT1 = null;
		String currNodeId = null;
		FlowDiagram fd1 = null;
		if (flowVO1 != null) {
			fd1 = flowVO1.toFlowDiagram();
			if (instance1.isTemp()) {
				nodeRT1 = ((List<NodeRT>) instance1.getNoderts()).get(0);
				currNodeId = nodeRT1.getNodeid();
			}

			if (currNodeId == null && nodeRT1 == null) {
				nodeRT1 = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
				if (nodeRT1 != null)
					currNodeId = nodeRT1.getNodeid();
			}
		}

		String nodertId = nodeRT1.getId();
		NodeRT nodeRT = (NodeRT) nodeRTProcess.doViewNodeRT(nodertId);
		if(nodeRT != null){
			BillDefiVO flowVO = doc.getState().getFlowVO();
			// 获取当前结点
			Node currnode = null;
			FlowDiagram fd = null;
			if (flowVO != null) {
				fd = flowVO.toFlowDiagram();
			}
			String currnodeid = nodeRT.getNodeid();
			if (currnodeid != null) {
				currnode = (Node) fd.getElementByID(currnodeid);
			}

			nodeRT.setState(0);
			Date lastProcessTime = new Date();
			long time = lastProcessTime.getTime() - nodeRT.getLastProcessTime().getTime();
			//更改审批时限
			if(((ManualNode)currnode).isLimited && nodeRT.getDeadline() !=null){
				if(nodeRT.getDeadline() != null){
					Date deadline = new Date(nodeRT.getDeadline().getTime() + time);
					nodeRT.setDeadline(deadline);
				}
			}
			//更改过期通知时间
			Collection<ActorRT> actorRTs = nodeRT.getActorrts();
			Map<String, Object> strategyMap = ((ManualNode)currnode).getNotificationStrategyMap();
			if(strategyMap.containsKey(NotificationConstant.STRTAGERY_OVERDUE)){
				for(Iterator<ActorRT> it = actorRTs.iterator(); it.hasNext();){
					ActorRT actorRT = it.next();
					if(actorRT.getDeadline() != null){
						Date deadline = new Date(actorRT.getDeadline().getTime() + time);
						actorRT.setDeadline(deadline);
					}
				}
			}
			nodeRT.setActorrts(actorRTs);
			nodeRT.setLastProcessTime(lastProcessTime);
			nodeRTProcess.doUpdateNodeRT(nodeRT);

			//加入流程历史
			FlowStateRT instance = doc.getState(currNodeId);
			RelationHIS rhis = new RelationHIS();
			rhis.setId(Sequence.getSequence());
			rhis.setFlowStateId(instance.getId());
			rhis.setFlowid(instance.getFlowid());
			rhis.setFlowname(instance.getFlowVO().getSubject());
			rhis.setDocid(instance.getDocid());
			rhis.setStartnodeid(currnode.id);
			rhis.setStartnodename(currnode.name);
			rhis.setEndnodeid(currnode.id);
			rhis.setEndnodename(currnode.name);
			rhis.setIspassed(false);
			rhis.setActiontime(actionTime);
			rhis.setAttitude("");
			rhis.setAuditor(user.getId());
			ActorHIS actorHIS =null;
			if(!StringUtil.isBlank(user.getProxyUserId())){
				UserVO uservo = (UserVO) ProcessFactory.createProcess(UserProcess.class).doView(user.getProxyUserId());
				actorHIS = new ActorHIS(uservo);
				actorHIS.setAgentid(user.getId());
				actorHIS.setAgentname(user.getName());
			}else{
				actorHIS = new ActorHIS(user);
			}
			actorHIS.setAttitude("");
			actorHIS.setSignature("");
			actorHIS.setProcesstime(actionTime);
			rhis.getActorhiss().add(actorHIS);
			rhis.setFlowOperation(FlowType.RUNNING2RUNNING_RECOVER);
			rhis.setReminderCount(0);
			relationHISProcess.doCreateRelationHIS(rhis);

			//调整deadline后重新加入任务
			if(((ManualNode)currnode).isLimited && nodeRT.getDeadline() !=null){
				Job job = JobFactory.createJob(ManualNodeTimingApprovalJob.class,instance.getDocid(),instance.getId(),nodeRT.getId(),instance.getApplicationid(),null);
				TriggerVO trigger = new TriggerVO(job, nodeRT.getDeadline().getTime());
				RegularScheduler.addTrigger(trigger,applicationId);
			}
		}
	}

	@Override
	public void terminate(IDocument doc, WebUser user, ParamsTable params, String applicationId) throws Exception {
		//获取当前节点id和nodertId
		FlowStateRT instance = doc.getState();
		FlowDiagram fd = instance.getFlowVO().toFlowDiagram();
		BillDefiVO flowVO = instance.getFlowVO();
		NodeRT nodeRT = null;
		String currNodeId = null;
		if (flowVO != null) {
			fd = flowVO.toFlowDiagram();
			if (instance.isTemp()) {
				nodeRT = ((List<NodeRT>) instance.getNoderts()).get(0);
				currNodeId = nodeRT.getNodeid();
			}

			if (currNodeId == null && nodeRT == null) {
				nodeRT = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
				if (nodeRT != null)
					currNodeId = nodeRT.getNodeid();
			}
		}

		boolean update = false;
		Node currNode = (Node) fd.getElementByID(currNodeId);
		Node endNode = new Node(fd) {

			public void showTips(Graphics g) {
			}

			public void paint(OGraphics g) {
			}
		};
		String label = "终止";
		endNode.name = label;
		endNode.statelabel = label;
		endNode.id = "terminate_id";
		FlowRuntimeService nodeRTProcess = new FlowRuntimeServiceImpl(
				doc.getApplicationid());

		if (!instance.isComplete() && !instance.isTerminated()) {
			if (instance.getNoderts() != null && instance.getNoderts().size() > 0) {
				for (Iterator<?> iterator = instance.getNoderts().iterator(); iterator.hasNext();) {
					NodeRT nodert = (NodeRT) iterator.next();
					nodeRTProcess.doRemoveNodeRT(nodert.getId());
				}
				instance.getNoderts().clear();
				update = true;
			}
		}

		if (update) {
			Date actionTime = new Date();

			NodeRT nodert = new NodeRT(instance, endNode, FlowType.RUNNING2TERMIATE);
			instance.getNoderts().add(nodert);
			// 更新流程实例
			StateMachine.updateFlowState(instance,user);
			// 更新流程历史
			StateMachine.updatePreviousRelationHIS(instance, currNode, user, actionTime);
			StateMachine.createOrUpdateRelationHIS(instance, currNode, endNode, user, actionTime, "",
					"", FlowType.RUNNING2TERMIATE,params,"",nodeRT);
			// 执行指令
			InstructionExecutor.getInstance().execute();
			// 更新文档
			DocumentProcess proxy = RunTimeServiceManager.documentProcess(
					applicationId);
			doc.setAuditdate(actionTime);
			doc.setAuditorList("");
			doc.setAuditorNames("");
			doc.setStateLabelInfo(null);
			doc.setAuditorList(null);
			doc.setAudituser(user.getId());
			doc.setLastFlowOperation(FlowType.RUNNING2TERMIATE);
			doc.setLastmodified(actionTime);
			doc.setLastmodifier(user.getId());
			doc.setStateLabel(label);
			proxy.doCreateOrUpdate(doc, user);
		}
	}

	@Override
	public void suspend(IDocument doc, WebUser user, ParamsTable params, String applicationId) throws Exception {
		Date actionTime = new Date();
		FlowRuntimeService nodeRTProcess = new FlowRuntimeServiceImpl(
				applicationId);
		FlowHistoryService relationHISProcess = new FlowHistoryServiceImpl(applicationId);

		//获取当前节点id和nodertId
		FlowStateRT instance = doc.getState();
		BillDefiVO flowVO = instance.getFlowVO();
		NodeRT nodeRT = null;
		String currNodeId = null;
		FlowDiagram fd = null;
		if (flowVO != null) {
			fd = flowVO.toFlowDiagram();
			if (instance.isTemp()) {
				nodeRT = ((List<NodeRT>) instance.getNoderts()).get(0);
				currNodeId = nodeRT.getNodeid();
			}

			if (currNodeId == null && nodeRT == null) {
				nodeRT = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
				if (nodeRT != null)
					currNodeId = nodeRT.getNodeid();
			}
		}
		if (nodeRT != null) {
			nodeRT.setState(FLOWSTATE_HANDUP);
			nodeRT.setLastProcessTime(new Date());
			nodeRT.setActorrts(nodeRT.getActorrts());
			nodeRTProcess.doUpdateNodeRT(nodeRT);

			// 加入流程历史
			flowVO = doc.getState().getFlowVO();
			// 获取当前结点
			Node currnode = null;
			fd = null;
			if (flowVO != null) {
				fd = flowVO.toFlowDiagram();
			}
			String currnodeid = nodeRT.getNodeid();
			if (currnodeid != null) {
				currnode = (Node) fd.getElementByID(currnodeid);
			}
			RelationHIS rhis = new RelationHIS();
			rhis.setId(Sequence.getSequence());
			rhis.setFlowStateId(instance.getId());
			rhis.setFlowid(instance.getFlowid());
			rhis.setFlowname(instance.getFlowVO().getSubject());
			rhis.setDocid(instance.getDocid());
			rhis.setStartnodeid(currnode.id);
			rhis.setStartnodename(currnode.name);
			rhis.setEndnodeid(currnode.id);
			rhis.setEndnodename(currnode.name);
			rhis.setIspassed(false);
			rhis.setActiontime(actionTime);
			rhis.setAuditor(user.getId());
			ActorHIS actorHIS = null;
			if (!StringUtil.isBlank(user.getProxyUserId())) {
				UserVO uservo = (UserVO) ProcessFactory.createProcess(UserProcess.class).doView(user.getProxyUserId());
				actorHIS = new ActorHIS(uservo);
				actorHIS.setAgentid(user.getId());
				actorHIS.setAgentname(user.getName());
			} else {
				actorHIS = new ActorHIS(user);
			}
			actorHIS.setProcesstime(actionTime);
			rhis.getActorhiss().add(actorHIS);
			rhis.setFlowOperation(FlowType.RUNNING2RUNNING_HANDUP);
			rhis.setReminderCount(0);
			relationHISProcess.doCreateRelationHIS(rhis);

			// 如果是有审批时限设置,取消之前任务
			if (((ManualNode) currnode).isLimited && nodeRT.getDeadline() != null) {
				String token = TriggerVO.generateManualNodeTimingApprovalJobToken(doc.getId(), doc.getStateid(),
						nodeRT.getId());
				RegularScheduler.cancelTrigger(token,applicationId);
			}
		}
	}

	@Override
	public void startFree(IDocument doc, WebUser user, ParamsTable params, String applicationId, String comment, String nextUserId) throws Exception {
		FlowRuntimeService fsProcess = new FlowRuntimeServiceImpl( applicationId);
		fsProcess.doStartFreeWorkflow(doc, nextUserId, comment, params, user);
	}

	@Override
	public void submitFree(IDocument doc, WebUser user, ParamsTable params, String applicationId, String comment, String nextUserId) throws Exception {
		DocumentProcess dProcess = RunTimeServiceManager.documentProcess(
				applicationId);
		FlowRuntimeService fsProcess = new FlowRuntimeServiceImpl( applicationId);

		dProcess.doStartFlowOrUpdate(doc, params, user);
		fsProcess.doProcessFreeWorkflow(doc.getState(), nextUserId, comment, params, user);
	}

	@Override
	public void backFree(IDocument doc, WebUser user, ParamsTable params, String applicationId, String comment, String nextUserId) throws Exception {
		FlowRuntimeService fsProcess = new FlowRuntimeServiceImpl( applicationId);
		fsProcess.doBackOffFreeWorkflow(doc.getState(), nextUserId, comment, params, user);
	}

	@Override
	public void completeFree(IDocument doc, WebUser user, ParamsTable params, String applicationId, String comment) throws Exception {
		FlowRuntimeService fsProcess = new FlowRuntimeServiceImpl( applicationId);
		fsProcess.doCompleteFreeWorkflow(doc.getState(), comment, params, user);
	}

	@Override
	public IDocument updateAuditor(ParamsTable params, WebUser user, String applicationId,String instanceId, List<String> userIds) throws Exception {
		FlowRuntimeService stateProcess = new FlowRuntimeServiceImpl( applicationId);
		FlowStateRT instance = (FlowStateRT) stateProcess.findFlowStateRT(instanceId);
//		FlowStateRT instance = doc.getState();
		IDocument doc = instance.getDocument();
		BillDefiVO flowVO = instance.getFlowVO();
		NodeRT nodeRT = null;
		String currNodeId = null;
		FlowDiagram flowDiagram = null;
		if (flowVO != null) {
			flowDiagram = flowVO.toFlowDiagram();
			if (instance.isTemp()) {
				nodeRT = ((List<NodeRT>) instance.getNoderts()).get(0);
				currNodeId = nodeRT.getNodeid();
			}

			if (currNodeId == null && nodeRT == null) {
				nodeRT = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
				if (nodeRT != null)
					currNodeId = nodeRT.getNodeid();
			}
		}
		//审批人集合
//		auditorList = "{"+currNodeId+":"+auditorList+"}";
//		params.setParameter("content.auditorList", auditorList);
		JSONObject json = (JSONObject) JSONObject.parse(doc.getAuditorList());
		for (Map.Entry<String, Object> entry : json.entrySet()) {
			JSONArray value = (JSONArray) entry.getValue();
			if(value != null){
				for (String id : userIds) {
					if(!value.contains(id)){
						value.add(id);
					}
				}
			}
		}
		params.setParameter("_currid", currNodeId);
		doc.setAuditorList(json.toString());

		DocumentProcess docProcess = (DocumentProcess) ProcessFactory.createRuntimeProcess(DocumentProcess.class, applicationId);

		if(instance.getDocument() != null){
			docProcess.doChangeAuditor(instance.getDocument(), params, user);
		}
		return doc;
	}

	@Override
	public String doFlowAssist(String applicationId, String instanceId, String attitude, WebUser user) throws Exception {
		FlowRuntimeService stateProcess = new FlowRuntimeServiceImpl( applicationId);
		FlowStateRT instance = (FlowStateRT) stateProcess.findFlowStateRT(instanceId);

		String nodeRTId = "";
		Collection<NodeRT> cNodeRTs = instance.getNoderts();
		for (NodeRT nodeRT2 : cNodeRTs) {
			Collection<CoActorRT> coActors = nodeRT2.getCoActors();
			for (CoActorRT coActorRT : coActors) {
				if(user.getId().equals(coActorRT.getUserId())){

					nodeRTId = nodeRT2.getId();
					stateProcess.doEvaluate(instanceId, nodeRTId, attitude, user);
					return "协办成功";
				}
			}
		}
//		stateProcess.doEvaluate(instanceId, nodeRTId, attitude, user);
		return "协办失败";
	}

	@Override
	public String addCoAuditor(String applicationId, String docId, List<String> userIds, WebUser user) throws Exception {
		DocumentProcess dProcess = (DocumentProcess) ProcessFactory.createRuntimeProcess(DocumentProcess.class, applicationId);
		IDocument doc = (IDocument) dProcess.doView(docId);
		FlowStateRT instance = doc.getState();
		BillDefiVO flowVO = instance.getFlowVO();
		NodeRT nodeRT = null;
		String currNodeId = null;
		if (flowVO != null) {
			if (instance.isTemp()) {
				nodeRT = ((List<NodeRT>) instance.getNoderts()).get(0);
				currNodeId = nodeRT.getNodeid();
			}

			if (currNodeId == null && nodeRT == null) {
				nodeRT = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
				if (nodeRT != null)
					currNodeId = nodeRT.getNodeid();
			}
		}

		JSONObject json = (JSONObject) JSONObject.parse(doc.getCoAuditorList());
		@SuppressWarnings("unchecked")
		List<String> userIdList =  (List<String>) json.get(currNodeId);
		if(userIdList != null){
			for (String id : userIds) {
				if(!userIdList.contains(id)){
					userIdList.add(id);
				}
			}
		} else {
			userIdList = new ArrayList<String>();
			for (String id : userIds) {
				if(!userIdList.contains(id)){
					userIdList.add(id);
				}
			}
		}
		json.put(currNodeId, userIdList);
		doc.setCoAuditorList(json.toString());
		ParamsTable params = new ParamsTable();
		params.setParameter("_currid", currNodeId);
		dProcess.doChangeCoAuditor(doc, params, user);

		return "协办加签成功";
	}

	@Override
	public PureDocument reminderWorkflow(WebUser user, String applicationid, String instanceId, String[] nodertIds, String reminderContent) throws Exception {
		FlowRuntimeService stateProcess = new FlowRuntimeServiceImpl(applicationid);
		DocumentProcess dProcess = (DocumentProcess) ProcessFactory.createRuntimeProcess(DocumentProcess.class, applicationid);
		FlowStateRT instance = (FlowStateRT) stateProcess.findFlowStateRT(instanceId);
		ParamsTable params = new ParamsTable();
		PureDocument doc = (PureDocument) dProcess.doView(instance.getDocid());
		dProcess.doPlatformFlowReminder(doc, nodertIds, reminderContent, params, user);
		MemoryCacheUtil.putToPrivateSpace(doc.getId(), doc, user);
		return doc;
	}

	@Override
	public IDocument updateApprovers(ParamsTable params, WebUser user, String applicationId,String instanceId, List<String> userIds) throws Exception {
		FlowRuntimeService stateProcess = new FlowRuntimeServiceImpl( applicationId);
		FlowStateRT instance = (FlowStateRT) stateProcess.findFlowStateRT(instanceId);
//		FlowStateRT instance = doc.getState();
		IDocument doc = instance.getDocument();
		BillDefiVO flowVO = instance.getFlowVO();
		NodeRT nodeRT = null;
		String currNodeId = null;
		FlowDiagram flowDiagram = null;
		if (flowVO != null) {
			flowDiagram = flowVO.toFlowDiagram();
			if (instance.isTemp()) {
				nodeRT = ((List<NodeRT>) instance.getNoderts()).get(0);
				currNodeId = nodeRT.getNodeid();
			}

			if (currNodeId == null && nodeRT == null) {
				nodeRT = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
				if (nodeRT != null)
					currNodeId = nodeRT.getNodeid();
			}
		}
		//审批人集合
//		auditorList = "{"+currNodeId+":"+auditorList+"}";
//		params.setParameter("content.auditorList", auditorList);
		JSONObject json = (JSONObject) JSONObject.parse(doc.getAuditorList());
		for (Map.Entry<String, Object> entry : json.entrySet()) {
			JSONArray value = (JSONArray) entry.getValue();
			value.clear();
			if(value != null){
				for (String id : userIds) {
					value.add(id);
				}
			}
		}
		params.setParameter("_currid", currNodeId);
		doc.setAuditorList(json.toString());

		DocumentProcess docProcess = (DocumentProcess) ProcessFactory.createRuntimeProcess(DocumentProcess.class, applicationId);

		if(instance.getDocument() != null){
			docProcess.doChangeAuditor(instance.getDocument(), params, user);
		}
		return doc;
	}


	@Override
	public String doFlowSupplement(String applicationId, String instanceId, String comments, WebUser user) throws Exception {
		FlowRuntimeService flowStateRTProcess = new FlowRuntimeServiceImpl( applicationId);
		FlowStateRT instance = (FlowStateRT) flowStateRTProcess.findFlowStateRT(instanceId);
		FlowHistoryService relationHISProcess= new FlowHistoryServiceImpl( applicationId);
		// 新建历史记录
		RelationHIS rhis = new RelationHIS();
		rhis.setId(Sequence.getSequence());
		rhis.setFlowStateId(instanceId);
		rhis.setFlowid(instance.getFlowid());
		rhis.setFlowname(instance.getFlowVO().getSubject());
		rhis.setDocid(instance.getDocid());
		rhis.setStartnodeid("");
		rhis.setStartnodename("添加/补签意见");
		rhis.setEndnodeid("");
		rhis.setEndnodename("添加/补签意见");
		rhis.setIspassed(false);
		rhis.setActiontime(new Date());
		rhis.setAttitude(comments); // 添加/补签意见
		rhis.setAuditor(user.getId());
		ActorHIS actorHIS = null;
		if (!StringUtil.isBlank(user.getProxyUserId())) {
//			actorHIS = new ActorHIS((new WebUser(user.getEmployer())));
			UserVO uservo = (UserVO) ProcessFactory.createProcess(UserProcess.class).doView(user.getProxyUserId());
			actorHIS = new ActorHIS(new WebUser(uservo));
			actorHIS.setAgentid(user.getId());
			actorHIS.setAgentname(user.getName());
		} else {
			actorHIS = new ActorHIS(user);
		}
		actorHIS.setProcesstime(new Date());
		actorHIS.setAttitude(comments);
		actorHIS.setSignature("");
		rhis.getActorhiss().add(actorHIS);
		rhis.setFlowOperation("添加/补签意见");
		rhis.setReminderCount(0);
		//添加到指令队列
		relationHISProcess.doCreateRelationHIS(rhis);

		return "补签成功";
	}


	@Override
	public void deleteFlow(String docId,String applicationId) throws Exception {
		FlowRuntimeService flowProcess = new FlowRuntimeServiceImpl( applicationId);
		flowProcess.doDeleteFlow(docId);
	}
}
