package com.engine.workflow.cmd.requestForm;


import com.api.workflow.service.RequestAuthenticationService;
import com.cloudstore.dev.api.util.Util_TableMap;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.constant.BizLogOperateType;
import com.engine.common.constant.BizLogSmallType4Workflow;
import com.engine.common.constant.BizLogType;
import com.engine.common.constant.ParamConstant;
import com.engine.common.entity.BizLogContext;
import com.engine.common.util.AttrSignatureUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.core.interceptor.CommandContext;
import com.engine.workflow.biz.GetNextNodeContentBiz;
import com.engine.workflow.biz.RobotNode.RobotNodeBiz;
import com.engine.workflow.biz.RobotNode.RobotNodeFlowBiz;
import com.engine.workflow.biz.RobotNode.RobotNodeServiceBiz;
import com.engine.workflow.biz.SecondAuthBiz;
import com.engine.workflow.biz.freeNode.FreeNodeBiz;
import com.engine.workflow.biz.operationMenu.MenuDefaultSignBiz;
import com.engine.workflow.biz.requestFlow.SaveFormDatasBiz;
import com.engine.workflow.biz.requestFlowLog.RequestFlowLogBiz;
import com.engine.workflow.biz.requestForm.*;
import com.engine.workflow.biz.requestSubmit.RequestFlowErrorLogBiz;
import com.engine.workflow.biz.requestSubmit.RequestOperationBiz;
import com.engine.workflow.constant.*;
import com.engine.workflow.constant.requestForm.PromptType;
import com.engine.workflow.constant.requestForm.RequestConstant;
import com.engine.workflow.constant.requestForm.RequestExecuteType;
import com.engine.workflow.entity.RequestFlowLogEntity;
import com.engine.workflow.entity.requestForm.RequestOperationResultBean;
import com.engine.workflow.service.RequestManagerService;
import com.engine.workflow.service.RequestSecondAuthService;
import com.engine.workflow.service.impl.RequestManagerServiceImpl;
import com.engine.workflow.service.impl.RequestSecondAuthServiceImpl;
import com.engine.workflow.util.SecondAuthUtil;
import com.google.common.base.Strings;
import org.apache.xpath.operations.Bool;
import org.json.JSONObject;
import weaver.conn.RecordSet;
import weaver.cpt.util.CptWfUtil;
import weaver.docs.docs.DocCheckInOutUtil;
import weaver.file.FileUpload;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;
import weaver.workflow.agent.AgentManager;
import weaver.workflow.exceldesign.DetailOrderManager;
import weaver.workflow.logging.Logger;
import weaver.workflow.logging.LoggerFactory;
import weaver.workflow.msg.MsgPushUtil;
import weaver.workflow.msg.entity.MsgEntity;
import weaver.workflow.request.*;
import weaver.workflow.workflow.WFManager;
import weaver.workflow.workflow.WorkflowConfigComInfo;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

/**
 * 流程提交
 */
public class RequestSubmitCmd extends AbstractCommonCommand<Map<String,Object>>{

	private final static Logger log = LoggerFactory.getLogger(RequestManager.class);

	private HttpServletRequest request;

	private RequestFlowLogEntity requestFlowLogEntity;
	private boolean markLog = false;

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public RequestSubmitCmd(HttpServletRequest request, User user){
		this.request = request;
		this.user = user;
		initParams();
	}

	public Map<String,Object> execute(CommandContext commandContext){
		Map<String,Object> result = new HashMap<String,Object>();

		//初始化流程流转日志对象
		requestFlowLogEntity  = RequestFlowLogBiz.initRequestFlowLogEntity(user,RequestFlowLogSrcType.OTHER,request);


		try {
			//校验token避免重复提交
			String tokenKey = "";
			boolean isCreate = "1".equals(request.getParameter("iscreate"));
			int lastloginuserid = Util.getIntValue(request.getParameter("lastloginuserid"));
			if(isCreate && lastloginuserid > 0 && lastloginuserid != user.getUID()) {
				result.put("errorInfo",SystemEnv.getHtmlLabelName(515427,user.getLanguage()));
				return result;
			}
			if(isCreate)
				tokenKey = user.getUID()+"_"+Util.null2String(request.getParameter("workflowid"))+"_addrequest_submit_token";
			else
				tokenKey = user.getUID()+"_"+Util.null2String(request.getParameter("requestid"))+"_request_submit_token";
            String tokenValue = Util.null2String(request.getParameter(tokenKey));
			String tokenValueCache = Util_TableMap.getVal(tokenKey);
			if(!"".equals(tokenValueCache) && tokenValue.equals(tokenValueCache)){
				result.put("msg", ""+ SystemEnv.getHtmlLabelName(10005579,weaver.general.ThreadVarLanguage.getLang())+"");
				result.put("errorType","repeatSubmit");
                return result;
			}else{
				Util_TableMap.setVal(tokenKey, tokenValue, 120);
            }
			//前台联动超过时间未返回，未卡住提交情况记录日志
			String linkageUnFinishedKey = Util.null2String(request.getParameter("linkageUnFinishedKey"));
			if(!"".equalsIgnoreCase(linkageUnFinishedKey))
				new weaver.general.BaseBean().writeLog(tokenKey+"--linkageUnFinishedKey--"+linkageUnFinishedKey);
			//消息
			String src = Util.null2String(request.getParameter("src"));
			int requestid = Util.getIntValue(request.getParameter("requestid"), -1);
			RequestOperationMsgManager romm = new RequestOperationMsgManager();
			List<MsgEntity> requestMsgEntity = null;
			RequestOperationResultBean resultBean = this.getResult();	//插入操作日志
			result.put("data", resultBean);
			//是否为提交需确认
			boolean isNeedConfirm = ("save".equals(src) && "1".equals(resultBean.getResultInfo().get("isaffirmance")) );
			//流程异常处理、出口提示不刷新表单，需要更新操作时间避免出现数据已更改异常
			if(resultBean.getType() == RequestExecuteType.WF_LINK_TIP || resultBean.getType() == RequestExecuteType.R_CHROSE_OPERATOR || isNeedConfirm) {
				Util_TableMap.clearVal(tokenKey);	//两次情况需要清空token
				RecordSet recordSet = new RecordSet();
				if (requestid > 0) {
					recordSet.execute("select lastOperator,lastOperateDate,lastOperateTime from workflow_Requestbase where requestid = " + requestid);
					if(recordSet.next()){
						resultBean.getSubmitParams().put("lastOperator", Util.null2String(recordSet.getString("lastOperator")));
						resultBean.getSubmitParams().put("lastOperateDate", Util.null2String(recordSet.getString("lastOperateDate")));
						resultBean.getSubmitParams().put("lastOperateTime", Util.null2String(recordSet.getString("lastOperateTime")));
					}
				}
			}
			//消息中心流程异步提交消息提醒
			if(resultBean.getType() == RequestExecuteType.ASYNC_SUBMIT && "0".equals(user.getLogintype())){

				requestMsgEntity = romm.requestSubmitErrorMsg(String.valueOf(requestid),resultBean,user.getUID());
			}
			if("reject".equals(src) && resultBean.getType()==RequestExecuteType.SUCCESS){
				String rejectNodeids = request.getParameter("RejectNodes");
				requestMsgEntity = romm.rejectNoticeMsg(String.valueOf(requestid),rejectNodeids);
			}
//			boolean isaffirmance = "1".equals(request.getParameter("isaffirmance"));
			if (isCreate && (
					resultBean.getType() == RequestExecuteType.SUCCESS && "save".equals(src)
					|| resultBean.getType() == RequestExecuteType.FAILD && "submit".equals(src))) {
				requestid = Util.getIntValue(Util.null2String(resultBean.getSubmitParams().get("requestid")), -1);
				requestMsgEntity = romm.createRequestMsg(requestid,user.getUID());
			}

			if (isCreate && (resultBean.getType() == RequestExecuteType.SUCCESS && "submit".equals(src) )) {
				int nodeid = Util.getIntValue(request.getParameter("nodeid"), -1);
				requestid = Util.getIntValue(Util.null2String(resultBean.getSubmitParams().get("requestid")), -1);
				RequestFormBiz.updateLastViewDate(requestid,user.getUID(),nodeid);
			}
			if(requestMsgEntity != null){
				new MsgPushUtil().pushMsg(requestMsgEntity);
			}
			resultBean.getSubmitParams().put(tokenKey,System.currentTimeMillis());
            Util_TableMap.setObjVal(Util.null2String(resultBean.getResultInfo().get("sessionkey")), resultBean);

			//流程流转日志信息入库
			requestFlowLogEntity.getResultdata().putAll(result);
			requestFlowLogEntity.setResult(resultBean.getType().toString());
			if(resultBean.getType() == RequestExecuteType.FAILD && resultBean.getMessageInfo()!=null &&resultBean.getMessageInfo().containsKey("detail")){
				requestFlowLogEntity.setMessageInfo(Util.null2String(resultBean.getMessageInfo().get("detail")));
			}
			RequestFlowLogBiz.SaveRequestFlowLog(requestFlowLogEntity);
			markLog = true;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	private RequestOperationResultBean getResult() throws Exception{
		boolean isPrintLogUser = RequestOperationBiz.isPrintLogUser(user);
		long t1 = System.currentTimeMillis();
        t1 = writeTimeLog(isPrintLogUser,64,t1,"开始执行提交");
		RequestOperationResultBean resultBean = new  RequestOperationResultBean();
		Map<String,Object> resultInfo = resultBean.getResultInfo();

		//流程测试情况返回值
		TestWorkflowCheckBiz testBiz = new TestWorkflowCheckBiz();
		Map<String,Object> testParams = resultBean.getTestParams();
		boolean belongTest = testBiz.judgeBelongTest(request, false);
		testParams.put("belongTest", belongTest);
		if(belongTest){
			testParams.put("wfTestStr", Util.null2String(request.getParameter("wfTestStr")));
		}
		HttpSession session = request.getSession();

		RecordSet recordSet = new RecordSet();
		RequestManager requestManager = new RequestManager();
		requestManager.setRequestFlowLogEntity(requestFlowLogEntity);
		String f_weaver_belongto_userid = request.getParameter("f_weaver_belongto_userid");// 需要增加的代码
		String f_weaver_belongto_usertype = request.getParameter("f_weaver_belongto_usertype");// 需要增加的代码
		resultInfo.put("f_weaver_belongto_userid", f_weaver_belongto_userid);
		resultInfo.put("f_weaver_belongto_usertype", f_weaver_belongto_usertype);
		String userid = "" + user.getUID();

		String iscreate = Util.null2String(request.getParameter("iscreate"));
		int requestid = Util.getIntValue(request.getParameter("requestid"), -1);
		//验证是否有流程权限
		RequestAuthenticationService authService = new RequestAuthenticationService();
		authService.setUser(user);
		if (!"1".equals(iscreate) && !authService.verify(request, requestid)) {
			resultBean.getResultInfo().put("requestid",requestid);
			resultBean.setType(RequestExecuteType.FAILD);
			return resultBean;
		}

		AttrSignatureUtil attrSignatureUtil = new AttrSignatureUtil(user.getUID(), request.getHeader("user-agent"));
		String _attributesString = Util.null2String(request.getParameter(RequestConstant.SIGNATURE_ATTRIBUTES_STR));
		String _attributesSignature = Util.null2o(request.getParameter(RequestConstant.SIGNATURE_SECRET_KEY));
		attrSignatureUtil.verifySignature(_attributesString, _attributesSignature);
		String comemessage  = Util.null2String(request.getParameter("comemessage"));
		String rands[] = Util.TokenizerString2(Util.null2String(request.getParameter("rand")), "+");
		String rand = "";
		boolean needout = false;
		if (rands.length > 0)
			rand = rands[0];
		if (rands.length > 1)
			needout = true;
		String needoutprint = Util.null2String(request.getParameter("needoutprint"));// 等于1，代表点的正文

		String src = Util.null2String(request.getParameter("src"));
		int workflowid = Util.getIntValue(request.getParameter("workflowid"), -1);
		String workflowtype = Util.null2String(request.getParameter("workflowtype"));
		int isremark = Util.getIntValue(request.getParameter("isremark"), -1);
		int formid = Util.getIntValue(request.getParameter("formid"), -1);
		int isbill = Util.getIntValue(request.getParameter("isbill"), -1);
		int billid = Util.getIntValue(request.getParameter("billid"), -1);
		int nodeid = Util.getIntValue(request.getParameter("nodeid"), -1);
		String nodetype = Util.null2String(request.getParameter("nodetype"));
		String requestname = Util.fromScreen3(request.getParameter("requestname"), user.getLanguage());
		String requestlevel = Util.fromScreen(request.getParameter("requestlevel"), user.getLanguage());
		String isFromEditDocument = Util.null2String(request.getParameter("isFromEditDocument"));
		int SubmitToNodeid  = Util.getIntValue(request.getParameter("SubmitToNodeid"),0);
		String remark = Util.null2String(request.getParameter("remark"));
		String needwfback = Util.null2String(request.getParameter("needwfback"));
		int RejectToNodeid = Util.getIntValue(Util.null2String(request.getParameter("RejectToNodeid")),0);
		int RejectToType = Util.getIntValue(Util.null2String(request.getParameter("RejectToType")),0);
		boolean asyncSubmit  = "1".equals(Util.null2String(request.getParameter("asyncSubmit")));//异步提交
		String eh_setoperator = Util.null2String(request.getParameter("eh_setoperator"));
		String clientType = Util.null2String(request.getParameter("clientType"), SignSource.PC_BROWSER.getType());

		String sessionkey = workflowid + "_" + nodeid + "_" + user.getUID() + "_" + System.currentTimeMillis();
		resultInfo.put("sessionkey", sessionkey);

		//判断是否有流程删除权限
		if("delete".equals(src)  && !RequestDeleteUtils.verifyDelRight(requestid,user,false)) {
			resultBean.getResultInfo().put("requestid",requestid);
			resultBean.setType(RequestExecuteType.FAILD);
			return resultBean;
		}

		int agentType = Util.getIntValue(Util.null2String(request.getParameter("agentType")));
		int agentorByAgentId = Util.getIntValue(Util.null2String(request.getParameter("agentorByAgentId")));
		if (agentType == 1 && !src.equals("save")) {//流程代理出去，本人提交，需先收回代理
			AgentManager agentManager = new AgentManager(user);
			agentManager.agentBackRequest(agentorByAgentId, user.getUID(), workflowid + "", requestid);
		}

		//正在进行自动批准
		if(isAutoApproving(requestid,nodeid,resultBean)) {
			return resultBean;
		}
		int index = remark.indexOf("<br/><br/><span style='font-size:11px;color:#666;'>来自");
		String myremark = remark;
		String remarkSuffix = "";
		if(index > -1){
			myremark = remark.substring(0, index);
			remarkSuffix = remark.substring(index);
		}
		//设置默认意见
		myremark = Util.null2String(myremark).replace("<p>", "")
				.replace("</p>", "")
				.replace("\n", "")
				.replace("&nbsp;", "");
		if("".equals(myremark.trim())) {
			OperationMenuType type  = null;
			if("submit".equals(src)) {
				type = SubmitToNodeid > 0 ? OperationMenuType.SUBMIT_DIRECT : OperationMenuType.SUBMIT;
			} else if ("reject".equals(src)) {
				type = OperationMenuType.REJECT;
			}
			if(type != null) {
                remark =  Util.null2String(MenuDefaultSignBiz.getMenuDefaultSignMap(workflowid,nodeid,type)) + remarkSuffix;
            }
		}
		String method = Util.fromScreen(request.getParameter("method"), user.getLanguage()); // 作为新建文档时候的参数传递
		String remarkLocation = Util.null2String(request.getParameter("remarkLocation")); // 签字意见添加位置
		String topage = URLDecoder.decode(Util.null2String(request.getParameter("topage"))); // 返回的页面

		String submitNodeId = Util.null2String(request.getParameter("submitNodeId"));

		//
		String isFirstSubmit = Util.null2String(request.getParameter("isFirstSubmit"));

		//支持干预给客户
		String Intervenorid = Util.null2String(request.getParameter("Intervenorid"));
		String Intervenorid_crm = Util.null2String(request.getParameter("Intervenorid_crm"));
		String IntervenorType = "";
		String Intervenorid_temp = "";
		if(!"".equals(Intervenorid)){
			ArrayList<String> intervenoridArr = Util.TokenizerString(Intervenorid,",");
			for(String id : intervenoridArr) {
				Intervenorid_temp += "," + id;
				IntervenorType += ","+0;
			}
		}
		if(!"".equals(Intervenorid_crm)){
			ArrayList<String> intervenoridArr = Util.TokenizerString(Intervenorid_crm,",");
			for(String id : intervenoridArr) {
				Intervenorid_temp += "," + id;
				IntervenorType += ","+1;
			}
		}
		Intervenorid_temp = Intervenorid_temp.length() > 0 ? Intervenorid_temp.substring(1) : "";
		Intervenorid = Intervenorid_temp;
		IntervenorType = IntervenorType.length() > 0 ? IntervenorType.substring(1) : "";

		int SignType = Util.getIntValue(request.getParameter("SignType"), 0);
		int enableIntervenor = Util.getIntValue(request.getParameter("enableIntervenor"), 1);// 是否启用节点及出口附加操作

		int isovertime = Util.getIntValue(request.getParameter("isovertime"), 0);
		int isagentCreater = Util.getIntValue((String) attrSignatureUtil.getAttribute("isagent"));
		int beagenter = Util.getIntValue((String) attrSignatureUtil.getAttribute("beagenter"), 0);
		RequestDoc requestDoc = new RequestDoc();
		boolean docFlag = requestDoc.haveDocFiled("" + workflowid, "" + nodeid);
		int urger = Util.getIntValue((String) attrSignatureUtil.getAttribute("urger"), 0);
		String isintervenor = Util.null2String((String) attrSignatureUtil.getAttribute("isintervenor"));
		if (src.equals("") || workflowid == -1 || formid == -1 || isbill == -1 || nodeid == -1 || nodetype.equals("")) {
			StringBuilder msg = new StringBuilder(""+ SystemEnv.getHtmlLabelName(10005635,weaver.general.ThreadVarLanguage.getLang())+"src:").append(src).append(",workflowid:").append(workflowid).append(",formid:").append(formid);
			msg.append(",isbill:").append(isbill).append(",nodeid:").append(nodeid).append(",nodetype:").append(nodetype).append(",user:").append(user.getLastname());
			writeLog(msg.toString());
			resultBean.setType(RequestExecuteType.SEND_PAGE);
			resultBean.setSendPage(weaver.general.GCONST.getContextPath()+"/notice/RequestError.jsp");
			return resultBean;
		}

		String tempIsCanSubmit = Util.null2String(attrSignatureUtil.getAttribute("IsCanSubmit"));
		String tempCoadCanSubmit =  Util.null2String(attrSignatureUtil.getAttribute("coadCanSubmit"));
		boolean IsCanSubmit = "true".equals(tempIsCanSubmit);
		boolean coadCanSubmit = "true".equals(tempCoadCanSubmit);
		boolean IsCanModify = "true".equals(attrSignatureUtil.getAttribute("IsCanModify"));
		if("".equals(tempIsCanSubmit)){
			int usertype = "2".equals(user.getLogintype()) ? 1 : 0;
			recordSet.executeSql("select isremark,isreminded,preisremark,id,groupdetailid,nodeid,takisremark,(CASE WHEN isremark=9 THEN 7.5  WHEN (isremark = 4 ) THEN 1.5 "
					+ "WHEN (isremark=1 and takisremark=2) THEN 0.9 WHEN (preisremark=1 and takisremark=2) "
					+ "THEN 0.9 ELSE isremark END) orderisremark from workflow_currentoperator where requestid=" + requestid + " and userid=" + userid + " and usertype=" + usertype
					+ " order by orderisremark, id  ");
			if(recordSet.next()){
				String isremarkForRM = Util.null2String(recordSet.getString("isremark"));
				int wfcurrrid = Util.getIntValue(recordSet.getString("id"));
				int groupdetailid = Util.getIntValue(recordSet.getString("groupdetailid"), 0);


				WFForwardManager wfForwardManager = new WFForwardManager();
				wfForwardManager.init();
				wfForwardManager.setWorkflowid(workflowid);
				wfForwardManager.setNodeid(nodeid);
				wfForwardManager.setIsremark(isremarkForRM);
				wfForwardManager.setRequestid(requestid);
				wfForwardManager.setBeForwardid(wfcurrrid);
				wfForwardManager.getWFNodeInfo();
				IsCanSubmit = wfForwardManager.getCanSubmit();
				WFCoadjutantManager wfCoadjutantManager = new WFCoadjutantManager();
				wfCoadjutantManager.getCoadjutantRights(groupdetailid);
				String coadsigntype = wfCoadjutantManager.getSigntype();
				String coadismodify = wfCoadjutantManager.getIsmodify();
				coadCanSubmit = wfCoadjutantManager.getCoadjutantCanSubmit(requestid, wfcurrrid, isremarkForRM, coadsigntype);
				IsCanModify = wfForwardManager.getCanModify();
				if (!IsCanModify && coadismodify.equals("1")) IsCanModify = true;
			}
		}
		String IsBeForwardPending = Util.null2String((String) attrSignatureUtil.getAttribute("IsBeForwardPending"));
		String coadispending = Util.null2String((String) attrSignatureUtil.getAttribute("coadispending"));
		String coadsigntype = Util.null2String((String) attrSignatureUtil.getAttribute("coadsigntype"));
		int ispending = -1;
		if (isremark == 7 && coadispending.equals("1")) {
			if (IsBeForwardPending.equals("1")) {
				ispending = 2;
			} else {
				ispending = 1;
			}
		} else if (IsBeForwardPending.equals("1")) {
			ispending = 0;
		}
		int wfcurrrid = Util.getIntValue((String) attrSignatureUtil.getAttribute("wfcurrrid"), 0);
		int intervenorright = Util.getIntValue((String) attrSignatureUtil.getAttribute("intervenorright"), 0);
		if (src.equals("supervise") || (src.equals("submit") && isremark == 5) || (src.equals("intervenor") && intervenorright > 0) || (belongTest && src.equals("intervenor"))) {
			IsCanSubmit = true;
		}
		session.removeAttribute("errormsgid_" + user.getUID() + "_" + requestid);
		session.removeAttribute("errormsg_" + user.getUID() + "_" + requestid);
		if ((requestid > 0 && (!IsCanSubmit && !coadCanSubmit)) || requestManager.checkNodeOperatorComment(requestid, user.getUID(), nodeid)) {
			if (needoutprint.equals("")) {
				resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request,user,WorkflowRequestMessage.WF_REQUEST_ERROR_CODE_02,""));
				resultBean.setType(RequestExecuteType.FAILD);
			}
			resultBean.getResultInfo().put("requestid",requestid);
			return resultBean;
		}
		String isMultiDoc = Util.null2String(request.getParameter("isMultiDoc")); // 多文档新建

		/** 指定下一节点流转 **/
		boolean isSelectNextFlow = Util.null2String(request.getParameter("selectNextFlow")).equals("1") && src.equals("submit");//是否指定下一节点流转
		String selectNodeFlow_nodeIds = Util.null2String(request.getParameter("selectNodeFlow_nodeIds"));
		SelectNextFlowMode selectNextFlowMode = SelectNextFlowMode.getModeType(Util.getIntValue(request.getParameter("selectNextFlowMode")));
		String selectNodeFlowNodeCanFlowNextNode = Util.null2String(request.getParameter("selectNodeFlowNodeCanFlowNextNode"));
//		String selectNodeFlow_operator = Util.null2String(request.getParameter("selectNodeFlow_operator"));
//		String ccOperator = Util.null2String(request.getParameter("ccOperator"));
//		String canSubmit = Util.null2String(request.getParameter("canSubmit"));
		/** 指定下一节点流转 **/

		String isCAAuth = Util.null2String(request.getParameter("isCAAuth"));        //是否是CA认证，主要是需要CA数据保护时会传此参数的值

		requestManager.setIsMultiDoc(isMultiDoc);
		requestManager.setSrc(src);
		requestManager.setIscreate(iscreate);
		requestManager.setRequestid(requestid);
		requestManager.setWorkflowid(workflowid);
		requestManager.setWorkflowtype(workflowtype);
		requestManager.setIsremark(isremark);
		requestManager.setFormid(formid);
		requestManager.setIsbill(isbill);
		requestManager.setBillid(billid);
		requestManager.setNodeid(nodeid);
		requestManager.setNodetype(nodetype);

		requestname =  SaveFormDatasBiz.convertSlash(requestname); //mysql数据库单文本处理反斜杠
		requestManager.setRequestname(requestname);
		requestManager.setRequestlevel(requestlevel);
		requestManager.setRemark(remark);
		requestManager.setOneVoteApprove("1".equals(request.getParameter("oneVoteApprove")));
		if(request instanceof weaver.filter.WeaverRequest) {
			requestManager.setRequest(request);
		} else {
			FileUpload fu = new FileUpload(request);
			requestManager.setRequest(fu);
		}
		requestManager.setSubmitNodeId(submitNodeId);
		requestManager.setIntervenorid(Intervenorid);
		requestManager.setIntervenoridType(IntervenorType);
		requestManager.setSignType(SignType);

		String needConformCheck = Util.null2String(request.getParameter("needConformCheck"),"1");
		requestManager.setNeedConformCheck("1".equals(needConformCheck));

		if("intervenor".equals(src) && !"".equals(Intervenorid)){//配合邮件，干预时set currentoperator属性
			ArrayList<String> intervenoridArr = Util.TokenizerString(Intervenorid,",");
			ArrayList<String> intervenortypeArr = Util.TokenizerString(IntervenorType,",");
			Hashtable operatorsht = new Hashtable();
			int tempgroupid = 1;
			if(SignType == 1 || SignType == 2){//会签
				ArrayList tempoperators = new ArrayList();
				for(int i = 0;i < intervenoridArr.size();i++){
					String operator = intervenoridArr.get(i) + "_" + (intervenortypeArr.size() > i ? intervenortypeArr.get(i) : "0") + "_0_0";//userid_usertype_groupdetailid_signorder--参照requestnodeflow，signorder会签和非会签依次处理均给0
					tempoperators.add(operator);
					if(SignType == 2){
						break;
					}
				}
				operatorsht.put(tempgroupid+"",tempoperators);
			}else{//非会签
				for(int i = 0;i < intervenoridArr.size();i++){
					String operator = intervenoridArr.get(i) + "_" + (intervenortypeArr.size() > i ? intervenortypeArr.get(i) : "0") + "_0_0";//userid_usertype_groupdetailid_signorder--参照requestnodeflow，signorder会签和非会签依次处理均给0
					ArrayList tempoperators = new ArrayList();
					tempoperators.add(operator);
					operatorsht.put(tempgroupid+"",tempoperators);
					tempgroupid++;
				}
			}

			requestManager.setCurrentOperator(operatorsht);
		}

		requestManager.setIsFromEditDocument(isFromEditDocument);
		requestManager.setUser(user);
		requestManager.setIsagentCreater(isagentCreater);
		requestManager.setBeAgenter(beagenter);
		requestManager.setIsPending(ispending);
		requestManager.setRequestKey(wfcurrrid);
		requestManager.setCanModify(IsCanModify);
		requestManager.setCoadsigntype(coadsigntype);
		requestManager.setEnableIntervenor(enableIntervenor);// 是否启用节点及出口附加操作
		requestManager.setRemarkLocation(remarkLocation);
		requestManager.setIsFirstSubmit(isFirstSubmit);
		requestManager.setComeE9(true);
		requestManager.setSelectNextFlow(isSelectNextFlow);
		requestManager.setSelectNodeFlowNodeIds(selectNodeFlow_nodeIds);
		requestManager.setSelectNextFlowMode(selectNextFlowMode);
		//如果是指定流转，并且这个参数不是空，则赋值false，如果没有就是默认true
		if(isSelectNextFlow==true&&!"".equals(selectNodeFlowNodeCanFlowNextNode)){
			requestManager.setSelectNodeFlowNodeCanFlowNextNode(Boolean.parseBoolean(selectNodeFlowNodeCanFlowNextNode));
		}
//		requestManager.setSelectNodeFlowOperator(selectNodeFlow_operator);
//		requestManager.setSelectNodeFlowCCOperator(ccOperator);
//		requestManager.setSelectNodeCanSubmit(canSubmit);
		requestManager.setClientType(clientType);
		setEmSignInfo(requestManager);
		//

		LocationFieldSaveBiz locationFieldSaveBiz = new LocationFieldSaveBiz();
		if(request instanceof weaver.filter.WeaverRequest) {
			locationFieldSaveBiz.setRequest(request);
		} else {
			FileUpload fu = new FileUpload(request);
			locationFieldSaveBiz.setRequest(fu);
		}
		locationFieldSaveBiz.setIsBill(isbill);
		locationFieldSaveBiz.setFormId(formid);
		locationFieldSaveBiz.setPosition(Util.null2String(request.getParameter("position")));
		locationFieldSaveBiz.setPositionName(Util.null2String(request.getParameter("address")));
		locationFieldSaveBiz.setEditFields(Util.null2String(request.getParameter("locationEditFields")));
		locationFieldSaveBiz.setSubmitSrc(src);
		locationFieldSaveBiz.setRequestId(requestid);
		locationFieldSaveBiz.setNodeid(nodeid);
		locationFieldSaveBiz.setUserid(user.getUID());

		//CA数据保护时，先做保存操作
		if ("1".equals(isCAAuth)) {
			requestManager.setSrc("save");
		}

		boolean havaChage = false;
		if (docFlag) {
			requestDoc.setUser(user);
			havaChage = requestDoc.haveChage("" + workflowid, "" + requestid, request); // 如果改变了发文目录
		}
		WFManager wfManager = new WFManager();
		wfManager.setWfid(workflowid);
		wfManager.getWfInfo();
		String isShowChart = Util.null2s(wfManager.getIsShowChart().trim(),"0");
		String stopInChart =Util.null2s( wfManager.getStopInChart().trim(),"0");
		String stopInForm = Util.null2s(wfManager.getStopInForm().trim(),"0");

		boolean isShowFlowMessage = isShowChart.equals("3")&&(src.equals("submit")||src.equals("reject")||src.equals("intervenor"));
		RequestManagerService requestManagerService = ServiceUtil.getService(RequestManagerServiceImpl.class, user);
		boolean savestatus = true;
		if (!"1".equals(isFirstSubmit)) {
//			savestatus = requestManager.saveRequestInfo();
			//是否为提交需确认
			boolean isNeedConfirm = ("save".equals(src) && "1".equals(request.getParameter("isaffirmance")) );
			if(isNeedConfirm){
				//拿保存前明细表数据,如果requestid=-1,说明是第一次保存,之前没有数据,直接放空的list
				Map<String,List<String>> detailTableDatasId = new HashMap<>();
				List<String> tablestmp = new ArrayList<>();
				RecordSet rs = new RecordSet();
				RecordSet rs1 = new RecordSet();
				String billDetailKey = RequestFormBiz.getBillDetailKeyField(formid);
				String primaryKey = RequestFormBiz.getDetailTablePrimaryKey(formid);
				DetailOrderManager detailOrderManager = new DetailOrderManager();
				String mainTablename = "";
				if(isbill == 0)
					rs.executeQuery("select distinct groupid as tablename from workflow_formfield where formid=? and isdetail='1' order by groupid",formid);
				else
					rs.executeQuery("select a.tablename,b.tablename as maintable,a.orderid from workflow_billdetailtable a,workflow_bill b where a.billid = b.id and a.billid = ? order by a.orderid",formid);
				int groupid = 1;
				if(rs.getCounts() != 0){
					while(rs.next()){
						List<String> datasIdtmp = new ArrayList<>();
						if(isbill == 0){
							if(requestid != -1){
								rs1.executeQuery("select "+primaryKey+" from workflow_formdetail t where requestid="+requestid+" and groupid="+(groupid-1));
								while(rs1.next()){
									datasIdtmp.add(rs1.getString("id"));
								}
							}
							detailTableDatasId.put("workflow_formdetail_"+groupid,datasIdtmp);
							tablestmp.add("workflow_formdetail_"+groupid);
						}else{
							String detailTablename = rs.getString("tablename");
							mainTablename = rs.getString("maintable");
							if(requestid != -1){
								rs1.executeQuery("select id from "+detailTablename+" where mainid = (select id from "+mainTablename+" where requestid = ?)",requestid);
								while(rs1.next()){
									datasIdtmp.add(rs1.getString("id"));
								}
							}
							detailTableDatasId.put(detailTablename,datasIdtmp);
							tablestmp.add(detailTablename);
						}
						groupid++;
					}
				}

				//保存
				savestatus = requestManagerService.saveRequestInfo(requestManager);

				//取保存后明细表数据
				Map<String,List<String>> newDetailTableDatasId = new HashMap<>();
				requestid = requestManager.getRequestid();
				groupid = 1;
				for(String tabletmp : tablestmp){
					List<String> datasId = detailTableDatasId.get(tabletmp);
					List<String> datasIdtmp = new ArrayList<>();
					String orderSql = " t.id ";
					if(isbill == 0){
						if(datasId.size() == 0){
							rs.executeQuery("select "+primaryKey+" from workflow_formdetail t where requestid="+requestid+" and groupid="+(groupid-1) +" order by " + orderSql);
						}else{
							rs.executeQuery("select "+primaryKey+" from workflow_formdetail t where requestid="+requestid+" and groupid="+(groupid-1)+" and "+Util.getSubINClause(String.join(",",datasId), "id", "not in")+" order by " + orderSql);
						}

					}else{
						if(datasId.size() == 0){
							rs.executeQuery("select "+primaryKey+" from "+tabletmp+" t where "+billDetailKey+" = (select id from "+mainTablename+" where requestid = ?) order by "+orderSql,requestid);
						}else{
							rs.executeQuery("select "+primaryKey+" from "+tabletmp+" t where "+billDetailKey+" = (select id from "+mainTablename+" where requestid = ?) and "+Util.getSubINClause(String.join(",",datasId), "id", "not in")+" order by "+orderSql,requestid);
						}
					}
					while(rs.next()){
						datasIdtmp.add(rs.getString(primaryKey));
					}
					newDetailTableDatasId.put("detail_" + groupid,datasIdtmp);
					groupid++;
				}
				resultBean.setInsertDetailDatasInfo(newDetailTableDatasId);
			} else{
			//使用service来执行表单保存方法，使其支持代理开发
			savestatus = requestManagerService.saveRequestInfo(requestManager);
			}

		} else if(!"n".equals(eh_setoperator)){//提交需确认、出口提示、异常处理等，用户点击确认提交后再存入位置信息
			locationFieldSaveBiz.save();
		}
        t1 = writeTimeLog(isPrintLogUser,305,t1,"保存完成savestatus："+savestatus);
		requestid = requestManager.getRequestid();
		requestFlowLogEntity.setRequestid(requestid);  //将requestid 计入流转日志对象
		requestFlowLogEntity.setNodeid(nodeid);
		Map<String,Object> submitParams = resultBean.getSubmitParams();
		resultInfo.put("requestid", requestid);
		if(belongTest){		//走过保存逻辑则更新workflow_requestbase为测试状态
			testBiz.updateRequestBaseDeleted(requestid);
		}
		String timestamp = Util.null2String(request.getParameter("timestamp"));
		if(!"".equals(timestamp))
			submitParams.put("timestamp", timestamp);
		if("1".equals(iscreate)){
			submitParams.put("isremark", requestManager.getIsremark());
		}
		submitParams.put("requestid",requestid);
		if(requestid > 0){
			submitParams.put("iscreate", "0");
		}

		//保存页面上选择的提醒方式
		String remindTypes = Util.null2String(request.getParameter("remindTypes"));
		RequestRemindBiz.updateRemindTypes(remindTypes,requestid);

		if ("save".equals(src)) {
			session.setAttribute("needwfback_" + user.getUID() + "_" + requestid, needwfback);
			resultInfo.put("isaffirmance", Util.null2String(request.getParameter("isaffirmance")));
			resultInfo.put("selectNextFlow", Util.null2String(request.getParameter("selectNextFlow")));
			if("1".equals(Util.null2String(request.getParameter("isaffirmance")))){
				SubmitConfirmInfoBiz confirmService = new SubmitConfirmInfoBiz();
				if(agentType == 1) {
					//代理出去已办提交，取代理人身份计算下一节点
					confirmService.setUser(new User(agentorByAgentId));
				} else {
					confirmService.setUser(user);
				}
				confirmService.setRequestid(requestid);
				confirmService.setWorkflowid(workflowid);
				confirmService.setNodeid(nodeid);
				confirmService.setFormid(formid);
				confirmService.setIsbill(isbill);
				confirmService.setWfcurrrid(wfcurrrid);
				confirmService.setIsremark(isremark);
				confirmService.setSrc("".equals(Util.null2String(request.getParameter("isaffirmanceSrc")))? "submit":request.getParameter("isaffirmanceSrc"));
				confirmService.setSubmitNodeId(submitNodeId);
				confirmService.setRejectToNodeid(RejectToNodeid);
				confirmService.setRejectToType(RejectToType);
				confirmService.setFlowToNextFreeNode("1".equals(request.getParameter("flowToNextFreeNode")));
				confirmService.setNewRejectNodeIds(request.getParameter("newRejectNodeIds"));
				confirmService.setFreeNodeOperators(Util.null2String(request.getParameter("operatorids")));
				confirmService.setIsToNewAddSign(Util.getIntValue(request.getParameter("isToNewAddSign")));
				confirmService.setCountersignAttribute(Util.getIntValue(request.getParameter("countersignAttribute")));

				String isaffirmanceSrc =Util.null2String(request.getParameter("isaffirmanceSrc"));
				submitParams.put("needwfback", needwfback);
				submitParams.put("flowToNextFreeNode", request.getParameter("flowToNextFreeNode"));
				//退回确认
				if("reject".equals(isaffirmanceSrc)){
					submitParams.put("RejectNodes",request.getParameter("RejectNodes"));
					submitParams.put("RejectToNodeid",request.getParameter("RejectToNodeid"));
					submitParams.put("RejectToType",request.getParameter("RejectToType"));
					submitParams.put("isSubmitDirect",  request.getParameter("isSubmitDirect"));
					submitParams.put("newRejectNodeIds",request.getParameter("newRejectNodeIds"));
					resultInfo.put("isaffirmanceSrc", "reject");
				}
				if(SubmitToNodeid > 0 || FreeNodeBiz.isFreeNode(SubmitToNodeid)){
					submitParams.put("SubmitToNodeid", SubmitToNodeid);
					confirmService.setSubmitToNodeid(SubmitToNodeid);
				}

				//提交需确认，返回位置信息到前台
				resultInfo.put("position", Util.null2String(request.getParameter("position")));
				String addressKey = "address_" + UUID.randomUUID().toString();
				Util_TableMap.setObjVal(addressKey, Util.null2String(request.getParameter("address")));
				resultInfo.put("address", addressKey);

				resultBean.setMessageInfo(this.generateConfirmInfo(confirmService, "reject".equals(isaffirmanceSrc)));
			}
		} else if ("submit".equals(src)) {
			needwfback = Util.null2String((String) request.getParameter("needwfback"));
			String needwfback_s = Util.null2String((String) session.getAttribute("needwfback_" + user.getUID() + "_" + requestid));
			if ("1".equals(needwfback) && "0".equals(needwfback_s)) {
				requestManager.setNeedwfback("0");
			}
			session.removeAttribute("needwfback_" + user.getUID() + "_" + requestid);
		}
		// 保存失败(错误提示)
		if (!savestatus) {
			String message = requestManager.getMessage();
			String messagecontent = requestManager.getMessagecontent();
			if("".equals(message) || requestid <= 0)
				message = "1";
			resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request,user,message,messagecontent));
			resultBean.setType(RequestExecuteType.FAILD);
			resultBean.setConflictFieldInfo(requestManager.getConflictFieldInfo());
			RequestFlowErrorLogBiz.addDataInQueue(requestManager);
			// saveRequestInfo失败后未处理requestnamenew标题需要处理下
			new SetNewRequestTitle().getAllRequestName(new RecordSet(),requestid+"",requestname,workflowid+"",nodeid+"",formid,isbill,user.getLanguage());
			return resultBean;
		}

		/**======================流程数据加密处理========================*/
		String CAKey = Util.null2String(request.getParameter("CAKey"));                //缓存提交时的数据的key，主要是需要CA认证时的参数
		int protectType = Util.getIntValue(Util.null2String(request.getParameter("protectType")), 0);    //二次认证认证成功后的参数，数据保护的方式
		int secondAuthType = Util.getIntValue(Util.null2String(request.getParameter("secondAuthType")), 0);    //二次认证认证成功后的参数，二次认证的方式
		int qysSignWay = Util.getIntValue(Util.null2String(request.getParameter("qysSignWay")), 0);    //契约锁认证的方式，1：ukey，2：契约锁服务
		String uuidStr = "";
		boolean isNeedUpdate = false;
		RequestSecondAuthService requestSecondAuthService = ServiceUtil.getService(RequestSecondAuthServiceImpl.class, user);
		if (savestatus) {
			if ("1".equals(isCAAuth)) {        //需要CA认证，保存后不提交流程，直接返回
				//先保存签字意见
				requestManager.saveRequestLog2();

				resultBean.setType(RequestExecuteType.SUCCESS);
				resultInfo.put("isCAAuth", isCAAuth);
				resultInfo.put("CAKey", CAKey);
				return resultBean;
			} else {
				if (protectType == SecondAuthType.QYS.getId() && qysSignWay == 2) {        //契约锁数据保护
					String tempRemark = requestManager.getRemark();
					Map<String, Object> protectResult = requestSecondAuthService.protectDatas(requestid, workflowid, formid, isbill, nodeid, tempRemark);
					String protectSuccess = Util.null2String(protectResult.get("success"));
					if ("0".equals(protectSuccess)) {        //说明数据保护失败
						resultBean.setType(RequestExecuteType.FAILD);

						String protectMsg = Util.null2String(protectResult.get("message"));
						resultBean.setMessageInfo(SecondAuthUtil.getErrorMsg(user, protectMsg));
						return resultBean;
					} else if ("1".equals(protectSuccess)) {
						isNeedUpdate = true;
						uuidStr = Util.null2String(protectResult.get("uuid"));
					}
				}
			}
		}

		/** Save Detail end* */
		boolean flowstatus = true;
		if (!"save".equals(src) || isremark != 1) {
			if ("n".equals(eh_setoperator)) { // 异常处理窗口未选择操作者，以提交失败处理
				flowstatus = false;
				JSONObject msgjson = new JSONObject();
				String ehnextnodeid = Util.null2String(request.getParameter("ehnextnodeid"));
				String bottom = "<span>" + SystemEnv.getHtmlLabelName(126560, user.getLanguage()) + "，" + SystemEnv.getHtmlLabelName(126554, user.getLanguage())
						+ "<a href=\"javascript:chooseExceptionOperator("+ehnextnodeid+")\"> " + SystemEnv.getHtmlLabelName(126555, user.getLanguage()) + " </a>" + SystemEnv.getHtmlLabelName(126561, user.getLanguage())
						+ "</span>";
				msgjson.put("details", bottom);
				requestManager.setMessagecontent(msgjson.toString());
				resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request,user,WorkflowRequestMessage.WF_REQUEST_ERROR_CODE_07,requestManager.getMessagecontent()));
				resultBean.setType(RequestExecuteType.FAILD);
				return resultBean;
			} else {
				if ("y".equals(eh_setoperator)) {
					// 异常处理选择了操作者，拼装操作者信息
					requestManager.createEh_operatorMap_pc();
				}

				if(belongTest && RobotNodeBiz.isRobotNode(nodetype)){
					RobotNodeFlowBiz robotNodeFlowBiz = new RobotNodeFlowBiz();
					Map<String, Object> robotFlowResult = robotNodeFlowBiz.robotNodeFlow(new RobotNodeServiceBiz().getRobotNodeSet(nodeid),requestid, workflowid, nodeid, true);
					flowstatus = (Boolean) robotFlowResult.get("flowResult");
					if(robotFlowResult.get("requestmanager") != null) requestManager = (RequestManager) robotFlowResult.get("requestmanager");
				}else {
					//使用service来执行向下流转方法，使其支持代理开发
					flowstatus = requestManagerService.flowNextNode(requestManager);
				}

				if(!flowstatus) {//流程提交失败，回滚位置信息
					requestManager.rollbackLocationFieldValue();
					if (locationFieldSaveBiz.isSaved()) {
						locationFieldSaveBiz.rollback();
					}
					RequestFlowErrorLogBiz.addDataInQueue(requestManager);
					// 流程提交失败 更新requestnamenew标题
					new SetNewRequestTitle().getAllRequestName(new RecordSet(),requestid+"",requestname,workflowid+"",nodeid+"",formid,isbill,user.getLanguage());
				}

                t1 = writeTimeLog(isPrintLogUser,445,t1,"流转下一节点flowstatus："+flowstatus);
				// 出口提示
				if (!flowstatus && (WorkflowRequestMessage.WF_CUSTOM_LINK_TIP).equals(requestManager.getMessage())) {
					String ismode = Util.null2String(request.getParameter("ismode"));
					String divcontent = Util.null2String(request.getParameter("divcontent"));
					String content = Util.null2String(request.getParameter("content"));
					resultInfo.put("divcontent", divcontent);
					resultInfo.put("content", content);

					Map<String, Integer> detailRowPerInfo = new HashMap<String, Integer>();
					Set<String> keyset = requestManager.getNewAddDetailRowPerInfo().keySet();
					Iterator<String> it1 = keyset.iterator();
					while (it1.hasNext()) {
						String rowid = it1.next();
						int rowno = requestManager.getNewAddDetailRowPerInfo().get(rowid);
						detailRowPerInfo.put(rowid, rowno);
						it1.remove();
					}
					resultInfo.put("detailRowPerInfo", detailRowPerInfo);
					resultInfo.put("msgcontent", requestManager.getMessagecontent());
					resultBean.setType(RequestExecuteType.WF_LINK_TIP);
					return resultBean;
				}

				if (!flowstatus && requestManager.isNeedChooseOperator()) { // 流转异常处理，找不到操作者且后台设置了提交至指定人员
					resultInfo.put("needChooseOperator", "y");
					resultInfo.put("ehnextnodeid", requestManager.getNextNodeid());
					submitParams.put("needwfback", needwfback);
					resultBean.setType(RequestExecuteType.R_CHROSE_OPERATOR);
					return resultBean;
				}


				if(flowstatus&&isShowFlowMessage){
					GetNextNodeContentBiz getNextNodeContentBiz = new GetNextNodeContentBiz(user);
					getNextNodeContentBiz.getNextNodeContent(resultBean,nodeid,requestManager.getRequestid(),submitNodeId,src);
					resultInfo.put("isShowChart", isShowChart);
				}
			}
		} else {
			// 被转发人保存
			RequestLog requestLog = new RequestLog();
			if(request instanceof weaver.filter.WeaverRequest) {
				requestManager.setRequest(request);
			} else {
				FileUpload fu = new FileUpload(request);
				requestManager.setRequest(fu);
				requestLog.setRequest(fu);
			}
			requestLog.saveLog(workflowid, requestid, nodeid, "1", remark, user);
		}

		if (flowstatus) {        //流转成功，更新保护数据跟签字意见的关系
			String authKey = Util.null2String(request.getParameter("authKey"));
			String isProtectSuccess = Util.null2String(request.getParameter("isProtectSuccess"));
			String isAuthSuccess = Util.null2String(request.getParameter("isAuthSuccess"));

			if (protectType == SecondAuthType.QYS.getId()&&qysSignWay == 2) {   //契约锁数据保护
				if (isNeedUpdate && !"".equals(uuidStr)) {        //契约锁服务签署
					requestSecondAuthService.updateProtectDatas(requestid, workflowid, nodeid, uuidStr);
				}
			} else if (protectType == SecondAuthType.CAAuth.getId()||
			(protectType == SecondAuthType.QYS.getId()&&qysSignWay == 1)) {   //CA数据保护
				if ("1".equals(isProtectSuccess) && !"".equals(authKey)) {
					requestSecondAuthService.updateProtectDatas(requestid, workflowid, nodeid, authKey);
				}
			}

			//契约锁二次认证或者契约锁数据保护
			if ((secondAuthType == SecondAuthType.QYS.getId() && "1".equals(isAuthSuccess)) ||
					(protectType == SecondAuthType.QYS.getId() && (isNeedUpdate || (qysSignWay == 1 && "1".equals(isProtectSuccess))))) {
				String sealId = Util.null2String(request.getParameter("qysSealId"));
				String sealImg = Util.null2String(request.getParameter("qysSealImg"));
				String certDetails = Util.null2String(request.getParameter("qysCertDetails"));

				//查询本次操作插入的日志的id
				int logId = SecondAuthBiz.getLogId(requestid, workflowid, nodeid, user);

				//保存契约锁验证的盖章信息
				Map<String, Object> authParam = new HashMap<String, Object>();
				authParam.put("sealId", sealId);
				authParam.put("sealImg", sealImg);
				authParam.put("certDetails", certDetails);
				authParam.put("logid", logId);
				authParam.put("requestId", requestid);
				SecondAuthBiz.saveQYSSignature(authParam, user);
			}
		}

		if (!flowstatus) {
			String message = requestManager.getMessage();
			if (!message.equals("")) {
				resultInfo.put("isintervenor", isintervenor);
			} else {
				message = "2";
			}
			resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request,user,message,requestManager.getMessagecontent()));
			resultBean.setType(RequestExecuteType.FAILD);
			return resultBean;
		}

		//判断下一节点操作者是否为当前处理人    正在自动流转也关闭窗口
		boolean isNextNodeOperator =  false;
		if(("reject".equals(src) || "submit".equals(src)) && "0".equals(isShowChart) && requestManager.getNodeInfoCache().size()==0){
			String logintype = user.getLogintype();     //当前用户类型  1: 类别用户  2:外部用户
			int usertype = 0;
			if(logintype.equals("1")) usertype = 0;
			if(logintype.equals("2")) usertype = 1;
			recordSet.executeSql("select requestid,isremark from workflow_currentoperator where userid="+userid+" and usertype="+usertype+" and requestid="+requestid + " and isremark in ('0','8','9','6')");
			while(recordSet.next()) {
				isNextNodeOperator = true;
				if("6".equals(Util.null2String(recordSet.getString("isremark")))){
					isNextNodeOperator = false;
					break;
				}
			}
			resultInfo.put("isNextNodeOperator", isNextNodeOperator);
		}

		if("1".equals(comemessage) && !"save".equals(src) && !isNextNodeOperator){
			resultBean.setType(RequestExecuteType.SEND_PAGE);
			resultBean.setSendPage(weaver.general.GCONST.getContextPath()+"/spa/workflow/index_mobx.jsp#/main/workflow/listDoing");
			return resultBean;
		}
		/**** 至此处代表流程提交成功，流程测试串需换成下一节点操作者信息，覆盖原串信息 ****/
		if(belongTest){
			String wfTestStrNew = testBiz.calculateNextOperator(request.getSession(), workflowid, requestid, requestManager.getNextNodeid());
			testParams.put("requestid", requestid);
			testParams.put("wfTestStr", wfTestStrNew);
		}

		if(!belongTest) this.isNeedRemind(resultInfo,recordSet,requestManager);		//流程提醒

		new Thread(new CptWfUtil(requestManager, "freezeCptnum")).start();
		String fromPDA = Util.null2String((String) attrSignatureUtil.getAttribute("loginPAD"));
		if (method.equals("")) {
			if (docFlag) {
				DocCheckInOutUtil dcou = new DocCheckInOutUtil();
				dcou.docCheckInWhenRequestOperation(user, requestid, request);
				RequestDoc requestDocNew = new RequestDoc();
				requestDocNew.setUser(user);
				boolean blockChangeDocFiled = "1".equals(new RecordSet().getPropValue("weaver_changeDocFiled", "blockChangeDocFiled"));
				String blockWorkflowId = new RecordSet().getPropValue("weaver_changeDocFiled", "blockWorkflowId");
				boolean isBlockForWf = ("," + blockWorkflowId + ",").indexOf("," + workflowid + ",") >= 0;
				if (!blockChangeDocFiled){
					if(!isBlockForWf){
						requestDocNew.changeDocFiled("" + workflowid, "" + requestid, request, user.getLanguage(), havaChage); // 如果改变了发文目录
					}

				}
				//requestDocNew.changeDocFiled("" + workflowid, "" + requestid, request, user.getLanguage(), havaChage); // 如果改变了发文目录
			}
			if (!topage.equals("")) {

			} else {
				String pcUrl = wfManager.getShowChartUrl();
				String mobileUrl = wfManager.getMobileUrl();

				if (iscreate.equals("1")) {
					resultBean.setType(RequestExecuteType.SUCCESS);
					if(!"save".equals(src)){
						if(isShowChart.equals("1")) {
							WorkflowConfigComInfo workflowConfigComInfo = new WorkflowConfigComInfo();
							String mobile_showchart = Util.null2String(workflowConfigComInfo.getValue("mobile_showchart"));
							resultInfo.put("pcUrl", pcUrl);
							resultInfo.put("mobileUrl", mobileUrl);
							resultInfo.put("stopInChart", stopInChart);
							resultInfo.put("mobile_showchart", mobile_showchart);
						}
						resultInfo.put("isShowChart", isShowChart);
					}
				} else {
					if ("delete".equals(src) && savestatus && flowstatus) {
						resultBean.setType(RequestExecuteType.DELETE);
						resultInfo.put("label", SystemEnv.getHtmlLabelName(20461, user.getLanguage()));
					} else {
						String docFlags = Util.null2String((String) attrSignatureUtil.getAttribute("requestAdd" + requestid)); // 流程建文档相关

						// String isShowPrompt = "true";
						if (docFlags.equals("1")) {
							resultBean.setType(RequestExecuteType.SUCCESS);
						} else {
							if (fromPDA.equals("1")) {
								resultBean.setType(RequestExecuteType.SUCCESS);
							} else {
								if(isShowChart.equals("1")) {
									WorkflowConfigComInfo workflowConfigComInfo = new WorkflowConfigComInfo();
									String mobile_showchart = Util.null2String(workflowConfigComInfo.getValue("mobile_showchart"));
									resultInfo.put("pcUrl", pcUrl);
									resultInfo.put("mobileUrl", mobileUrl);
									resultInfo.put("stopInChart", stopInChart);
									resultInfo.put("mobile_showchart", mobile_showchart);
								}
								resultInfo.put("isShowChart", isShowChart);
								resultBean.setType(RequestExecuteType.SUCCESS);
							}
						}
					}
				}
			}
		}else{
			  String adddocfieldid = method.substring(7) ;
			    String addMethod=method.substring(0,7) ;
			    if(adddocfieldid.indexOf("_")>0)
			    {
			    	String docrowindex = Util.null2String(requestManager.getDocrowindex());
			    	if(!docrowindex.equals(""))
			    		adddocfieldid = adddocfieldid.substring(0,adddocfieldid.indexOf("_"))+"_"+docrowindex;
			    }

			//新建文档
			if(("docnew_"+isMultiDoc).equals(method)){
				resultInfo.put("isToCreateDocPage", "1");
			    String notencoderToPage = weaver.general.GCONST.getContextPath()+"/workflow/request/ViewRequestForwardSPA.jsp?f_weaver_belongto_userid="+userid+"&f_weaver_belongto_usertype="+f_weaver_belongto_usertype+"&requestid="+requestid+"&docfileid="+adddocfieldid+"&topage="+topage+"&urger="+urger+"&isintervenor="+isintervenor;
			    topage = URLEncoder.encode(notencoderToPage);
				resultBean.setSendPage(weaver.general.GCONST.getContextPath()+"/docs/docs/DocList.jsp?hasTab=1&workflowid="+workflowid+"&isOpenNewWind=0&topage="+topage);
				resultBean.setType(RequestExecuteType.SUCCESS);
			}else{
				resultBean.setType(RequestExecuteType.SUCCESS);
			}
		}
        t1 = writeTimeLog(isPrintLogUser,582,t1,"提交结束");
		return resultBean;
	}


	@Override
	public BizLogContext getLogContext() {
		if(!this.markLog){
		return null;
	}
		String src = Util.null2String(request.getParameter("src"));
		BizLogContext bizLogContext = new BizLogContext();
		BizLogOperateType bizLogOperateType = BizLogOperateType.APPROVE;
		bizLogContext.setDateObject(new Date());
		bizLogContext.setUserid(user.getUID());
		bizLogContext.setUsertype(Util.getIntValue(user.getLogintype()));
		bizLogContext.setTargetId("request_"+src);
		String targetName = "";
		if("save".equals(src)){
			targetName = "保存";
		} else if ("submit".equals(src)) {
			targetName = "提交";
		} else if ("reject".equals(src)) {
			targetName = "退回";
		} else if ("intervenor".equals(src)) {
			targetName = "干预";
		} else if ("delete".equals(src)) {
			targetName = "删除";
		} else if ("supervise".equals(src)) {
			targetName = "督办";
		}
		bizLogContext.setTargetName(targetName);
		bizLogContext.setLogType(BizLogType.WORKFLOW);
		bizLogContext.setLogSmallType(BizLogSmallType4Workflow.WORKFLOW_APPROVE);
		bizLogContext.setOperateType(bizLogOperateType);
		bizLogContext.setClientIp(Util.null2String(params.get(ParamConstant.PARAM_IP)));
		bizLogContext.setParams(params);
		bizLogContext.setDesc(String.format(user.getLastname() + "进行了"+targetName+"操作"));
		return bizLogContext;
	}

	private Map<String,Object> generateConfirmInfo(SubmitConfirmInfoBiz confirmService,boolean isReject){
		Map<String,Object> msgInfo = new HashMap<String,Object>();
		String title  =  isReject ? SystemEnv.getHtmlLabelName(386334, user.getLanguage()) + "：" : SystemEnv.getHtmlLabelName(386336, user.getLanguage()) + "：";
		msgInfo.put("prompttype", PromptType.CONFIRMINFO.getType());
		msgInfo.put("title", title);
		boolean isSuccess = false;	//是否获取成功
		String titlesuffix = "";
		String nodeNameValue = "";
		String nodeIds = "";
		try {
			if(confirmService.getIsToNewAddSign() == 0) {
				confirmService.setFlowToNextFreeNode(true);
			}
			Map<String, Object> result = confirmService.getRequestoperator();
			if (result == null || result.isEmpty())
				throw new Exception("Empty Result");
			msgInfo.put("hasPassThisNode", result.get("hasPassThisNode"));
			if (result.containsKey("isWaitMerge")) {
				isSuccess = true;
				titlesuffix = SystemEnv.getHtmlLabelName(21399, user.getLanguage());
				nodeNameValue = SystemEnv.getHtmlLabelName(21399, user.getLanguage());
			} else if(result.containsKey("simpleModeAddFreeNode")) {
				titlesuffix = SystemEnv.getHtmlLabelName(83284, user.getLanguage());
				nodeNameValue = SystemEnv.getHtmlLabelName(83284, user.getLanguage());
				isSuccess = true;
				msgInfo.put("operators", result.get("operatorlist"));
			} else {
				isSuccess = true;
				this.removeRepeat(result);//去除重复
				msgInfo.put("operators", result.get("operatorlist"));
				titlesuffix = Util.null2String(result.get("nodename"));
				nodeNameValue = Util.null2String(result.get("nodenameValue"));
				nodeIds = Util.null2String(result.get("nodeid"));
			}

		} catch (Exception e) {
			e.printStackTrace();
			//抛异常全部当获取失败处理
			isSuccess = false;
		}
		if(!isSuccess && "".equals(titlesuffix))
			titlesuffix = SystemEnv.getHtmlLabelName(127889, user.getLanguage());
		msgInfo.put("isSuccess", isSuccess);
		msgInfo.put("titlesuffix", titlesuffix);
		msgInfo.put("nodeNameValue", nodeNameValue);
		msgInfo.put("nodeIds", nodeIds);
		return msgInfo;
	}

	private long writeTimeLog(boolean isPrintLogUser,int linenum,long t1,String msg){
		if(isPrintLogUser) {
			writeLog(linenum + "----------userid:" + user.getUID() + ",requestid:"+Util.null2String(request.getParameter("requestid")) + ",time:" +(System.currentTimeMillis() - t1)/1000 +"--" + msg);
		}
		return System.currentTimeMillis();
	}


	/**
	 * 去除重复
	 * @param result
	 */
	private void removeRepeat(Map<String,Object> result){
		List<Map<String,Object>> operatorlist = (List<Map<String,Object>>)result.get("operatorlist");
		if(operatorlist != null && operatorlist.size() > 0){
			Iterator<Map<String,Object>> iterator = operatorlist.iterator();
			Set<String> sets = new HashSet<>();
			while(iterator.hasNext()){
				Map<String,Object> operator = iterator.next();
				String jsonStr = com.alibaba.fastjson.JSONObject.toJSONString(operator);
				if(sets.contains(jsonStr)){
					iterator.remove();
				} else {
					sets.add(jsonStr);
				}
			}
		}
	}

	//判断是否正在进行自动批准
	private boolean isAutoApproving(int requestid,int nodeid,RequestOperationResultBean resultBean){
		RecordSet rs = new RecordSet();
		rs.executeQuery("select isremark from workflow_currentoperator where requestid  = ? and nodeid = ? and userid  = ? and isremark = '6' ",requestid,nodeid,user.getUID());
		if(rs.next()) {
			resultBean.setType(RequestExecuteType.FAILD);
			Map<String,Object> resultInfo = resultBean.getResultInfo();
			resultInfo.put("requestid", requestid);
			Map<String,Object> errorMsg = new HashMap <>();
			errorMsg.put("prompttype", PromptType.ERRORMSG.getType());
			errorMsg.put("title", ""+ SystemEnv.getHtmlLabelName(10005636,weaver.general.ThreadVarLanguage.getLang())+"");
			resultBean.setMessageInfo(errorMsg);
			return true;
		}
		return false;
	}

	//设置移动端保存参数
	public void setEmSignInfo(RequestManager requestManager){
		int speechAttachment = Util.getIntValue(request.getParameter("speechAttachment"));
		String handWrittenSign = Util.null2String(request.getParameter("handWrittenSign"));
		requestManager.setSpeechAttachment(speechAttachment);
		requestManager.setHandWrittenSign(handWrittenSign);
	}

	/**
	 * 流程提交-提醒
	 * 根据提醒字段判断是否是老提醒，老提醒根据提醒字段做提醒
	 * 不是老提醒，判断提交后是否需要自主选择提醒接收人，需要则返回标识，
	 * 不需要则读取默认提醒设置做提醒
	 * @param resultInfo
	 * @param recordSet
	 * @param requestManager
	 */
	private void isNeedRemind(Map<String,Object> resultInfo,RecordSet recordSet,RequestManager requestManager){
		String isaffirmance = Util.null2String(resultInfo.get("isaffirmance"));
		if(RobotNodeBiz.isRobotNode(requestManager.getNextNodetype()) || "1".equals(isaffirmance)){
			return ;
		}

		resultInfo.put("needRemind", false);
		//前端表单用户选择的提醒方式，E8历史数据该参数值默认为 -1
		String remindTypes = Util.null2String(request.getParameter("remindTypes"));

		String src = Util.null2String(request.getParameter("src"));
		if (!("submit".equals(src) || "reject".equals(src) || "intervenor".equals(src))) return;

		//自动审批的节点不需要提醒,如果都自动审批掉了,这次提交就不需提醒了,直接去提醒自动审批提交后的节点
		Set<Integer> remindNodes = this.remindNodes(requestManager);
		if (remindNodes.isEmpty()) return ;

		int requestid = requestManager.getRequestid();
		int workflowid = Util.getIntValue(request.getParameter("workflowid"), -1);
		WFManager wfManager = new WFManager();
		try {
			wfManager.setWfid(workflowid);
			wfManager.getWfInfo();
		} catch (Exception e){ e.printStackTrace(); }

		//E8提醒设置兼容
		if ("-1".equals(remindTypes)) {
			this.doRemindWithE8(wfManager,requestid,workflowid,src);
			return;
		}

		//E9
		if (!RequestRemindBiz.isOpenRemind(wfManager)) return;
		recordSet.executeQuery("select remindscope from workflow_base where id = ? ", workflowid);
		recordSet.next();
		int remindscope = Util.getIntValue(recordSet.getString("remindscope"),0);

		boolean isflowNext = RequestRemindBiz.isflowNext(requestid,src,user.getUID());

		if("1".equals(wfManager.getIsChoseReminder())) {
			String nodetype = Util.null2String(request.getParameter("nodetype"));
			if (!"intervenor".equals(src) && isflowNext && remindscope !=1 && !Strings.isNullOrEmpty(remindTypes) && !"4".equals(nodetype)) {
				resultInfo.put("needRemind", true);
				return ;
			}
		}

		this.doRemindWithE9(requestid,workflowid,src,remindTypes,isflowNext);
		return ;
	}

	private void doRemindWithE9(int requestid, int workflowid,String src,String remindTypes, boolean isflowNext){
		RequestRemindBiz requestRemindBiz = new RequestRemindBiz(user,requestid,workflowid,src);
		String isSmsRemind = remindTypes.indexOf(RemindTypeEnum.SMS.getCode()) > -1 ? "1" : "0";
		String isEmailRemind = remindTypes.indexOf(RemindTypeEnum.EMAIL.getCode()) > -1 ? "1" : "0";
		if (isflowNext) {
			if("1".equals(isSmsRemind)) requestRemindBiz.requestRemind(requestid,workflowid,src,RemindTypeEnum.SMS,0);
			if("1".equals(isEmailRemind)) requestRemindBiz.requestRemind(requestid,workflowid,src,RemindTypeEnum.EMAIL,0);
			RequestRemindBiz.updateRemindTypes("",requestid);
		} else {
			requestRemindBiz.doRemind(requestid,user.getUID(),workflowid,src,isSmsRemind,isEmailRemind);
		}
		requestRemindBiz.requestEmailApproveRemind(String.valueOf(workflowid),String.valueOf(requestid),src);
	}

	/**
	 * E8数据流程提醒
	 * @param wfManager
	 * @param requestid
	 * @param workflowid
	 * @param src
	 */
	private void doRemindWithE8(WFManager wfManager,int requestid, int workflowid,String src){

		RequestRemindBiz requestRemindBiz = new RequestRemindBiz(user,requestid,workflowid,src);
		int messageType = Util.getIntValue(Util.null2String(request.getParameter("messageType")),-1); // 老短信提醒
		int mailMessageType = Util.getIntValue(Util.null2String(request.getParameter("chatsType")),-1); // 老邮件提醒
		//历史数据可能只有短信提醒，但是其实也开启了邮件提醒
		int _mailMessageType = Util.getIntValue(wfManager.getMailMessageType(),-1);
		boolean isflowNext = RequestRemindBiz.isflowNext(requestid,src,user.getUID());
		if (isflowNext) {
			if(messageType >=1) {
				requestRemindBiz.requestRemind(requestid,workflowid,src,RemindTypeEnum.SMS,messageType);
			}
			if(mailMessageType == 1 || _mailMessageType == 1) {
				requestRemindBiz.requestRemind(requestid,workflowid,src,RemindTypeEnum.EMAIL,0);
			}
		} else {
			String isSmsRemind = messageType >=1 ? "1" : "0";
			String isEmailRemind = (mailMessageType == 1 || _mailMessageType == 1) ? "1" : "0";
			requestRemindBiz.doRemind(requestid,user.getUID(),workflowid,src,isSmsRemind,isEmailRemind);
		}
		requestRemindBiz.requestEmailApproveRemind(String.valueOf(workflowid),String.valueOf(requestid),src);
		return;
	}
	/**
	 * 下一节点中，除去自动审批的节点（自动审批节点不需要提醒）
	 * @param requestManager
	 * @return
	 */
	private Set<Integer> remindNodes(RequestManager requestManager){

		List nextNodeids = requestManager.getNextnodeids();
		Map <Integer, WFAutoApproveUtils.AutoApproveParams> nodeInfoCache = requestManager.getNodeInfoCache();
		Set<Integer> nodeInfoCacheKey = nodeInfoCache.keySet();

		Set<Integer> nodeIds = new HashSet<>();
		for(Object id : nextNodeids){
			int intId = Util.getIntValue((String)id);
			boolean exists = false;
			for(Integer cacheId : nodeInfoCacheKey){
				if(cacheId == intId){ exists = true; }
			}
			if(!exists){
				nodeIds.add(intId);
			}
		}

		return nodeIds;
	}


	private void initParams() {
		String[] initParamsKeys = {"requestid","workflowid","formid","isbill","remark","iscreate","isremark","f_weaver_belongto_userid",
		"f_weaver_belongto_usertype","src","workflowtype","nodeid","nodetype","creater","creatertype","SubmitToNodeid","RejectToNodeid"};
		this.params = new HashMap<>();
		for(String paramKey : initParamsKeys) {
			params.put(paramKey,request.getParameter(paramKey));
		}
	}
}