package com.engine.workflow.cmd.requestForm;

import com.api.workflow.service.RequestAuthenticationService;
import com.api.workflow.util.ServiceUtil;
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.entity.BizLogContext;
import com.engine.common.util.AttrSignatureUtil;
import com.engine.common.util.ParamUtil;
import com.engine.core.interceptor.CommandContext;
import com.engine.hrm.biz.HrmClassifiedProtectionBiz;
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.requestForm.RequestRemindBiz;
import com.engine.workflow.biz.requestForm.RequestSecLevelBiz;
import com.engine.workflow.biz.requestForm.SubmitErrorMsgBiz;
import com.engine.workflow.biz.requestForm.TakReplyBiz;
import com.engine.workflow.biz.workflowCore.RequestBaseBiz;
import com.engine.workflow.constant.OperationMenuType;
import com.engine.workflow.constant.RemindTypeEnum;
import com.engine.workflow.constant.SecondAuthType;
import com.engine.workflow.constant.SignSource;
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.requestForm.RequestOperationResultBean;
import com.engine.workflow.service.RequestSecondAuthService;
import com.engine.workflow.service.impl.RequestSecondAuthServiceImpl;
import com.engine.workflow.util.ChuanyueUtil;
import com.engine.workflow.util.SecondAuthUtil;
import com.engine.workflow.util.WfDataCorrectionUtils;
import com.engine.workflow.util.WorkflowOvertimeSettingsUtil;
import com.google.common.base.Strings;
import org.json.JSONObject;
import weaver.conn.RecordSet;
import weaver.file.FileUpload;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.resource.ResourceComInfo;
import weaver.mobile.webservices.workflow.soa.RequestPreProcessing;
import weaver.systeminfo.SystemEnv;
import weaver.workflow.agent.AgentManager;
import weaver.workflow.msg.MsgPushUtil;
import weaver.workflow.msg.entity.MsgEntity;
import weaver.workflow.request.*;
import weaver.workflow.request.entity.RequestOperateEntityTableNameEnum;
import weaver.workflow.request.entity.RequestOperateTypeEnum;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * 批注回复提交
 */
public class RemarkSubmitCmd extends AbstractCommonCommand<Map<String,Object>>{

	private HttpServletRequest request;

	public HttpServletRequest getRequest() {
		return request;
	}

	private static final int SPACE_TIME_MILLIS = 2000;//两秒步长
	private String targetName = "";

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

	public RemarkSubmitCmd(HttpServletRequest request, User user){
		this.request = request;
		this.user = user;
	}
	
	public Map<String,Object> execute(CommandContext commandContext){
		Map<String,Object> result = new HashMap<String,Object>();
		try {
			RequestOperationResultBean resultBean = this.getResult();
			result.put("data", resultBean);
			Util_TableMap.setObjVal(Util.null2String(resultBean.getResultInfo().get("sessionkey")), resultBean);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public RequestOperationResultBean getResult() throws Exception {

		RequestOperationResultBean resultBean = new  RequestOperationResultBean();
		RecordSet rs = new RecordSet();

		FileUpload fu = new FileUpload(request);
		String comemessage  = Util.null2String(request.getParameter("comemessage"));
		String userid = "" + user.getUID();
		int usertype = (user.getLogintype()).equals("1") ? 0 : 1;
		int requestid = Util.getIntValue(fu.getParameter("requestid"), -1);
		//代替session
		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));
		if(!attrSignatureUtil.verifySignature(_attributesString, _attributesSignature)) {
			resultBean.setType(RequestExecuteType.FAILD);
			resultBean.getResultInfo().put("requestid",requestid);
			return resultBean;
		}

		String src = Util.null2String(fu.getParameter("src"));
		String iscreate = Util.null2String(fu.getParameter("iscreate"));

		//*********防重复提交验证*************
		//小于时间间隔内，判定为重复提交
		String requestKey = new StringBuilder(String.valueOf(requestid)).append("_").append(user.getUID()).toString();
		String tokenValueCache = Util_TableMap.getVal(requestKey);
		if(tokenValueCache != null && System.currentTimeMillis() - Long.parseLong(tokenValueCache) < SPACE_TIME_MILLIS) {
			writeLog("RemarkSubmitCmd-----过滤重复提交 requestid = " + requestKey);
			Util_TableMap.setVal(requestKey, System.currentTimeMillis()+"", 120);
			resultBean.setType(RequestExecuteType.SUCCESS);
			return resultBean;
		} else {
			Util_TableMap.setVal(requestKey, System.currentTimeMillis()+"", 120);
		}
		//*********防重复提交验证*************
		int workflowid = Util.getIntValue(fu.getParameter("workflowid"), -1);
		String workflowtype = Util.null2String(fu.getParameter("workflowtype"));
		int nodeid = Util.getIntValue(fu.getParameter("nodeid"), -1);
		String nodetype = Util.null2String(fu.getParameter("nodetype"));
		String needwfback = Util.null2String(fu.getParameter("needwfback"));
		String remark = Util.null2String(fu.getParameter("remark"));
		int formid = Util.getIntValue(fu.getParameter("formid"), -1);
		int isbill = Util.getIntValue(fu.getParameter("isbill"), -1);
		int billid = Util.getIntValue(fu.getParameter("billid"), -1);
		String requestname = Util.fromScreen3(fu.getParameter("requestname"), user.getLanguage());
		String requestlevel = Util.fromScreen(fu.getParameter("requestlevel"), user.getLanguage());
		String messageType = Util.fromScreen(fu.getParameter("messageType"), user.getLanguage());
		String isFromEditDocument = Util.null2String(fu.getParameter("isFromEditDocument"));
		String submitNodeId = Util.null2String(fu.getParameter("submitNodeId"));
		String Intervenorid = Util.null2String(fu.getParameter("Intervenorid"));
		int isremark = Util.getIntValue(fu.getParameter("isremark"), -1);
		int realIsReamrk = isremark;
		String remarkLocation = Util.null2String(fu.getParameter("remarkLocation"));
		boolean IsCanModify = "true".equals(attrSignatureUtil.getAttribute("IsCanModify")) ? true : false;
		String ifchangstatus = WorkflowOvertimeSettingsUtil.getOverTimeSettingsEntity().getChangestatus() ;
		int agentType = Util.getIntValue(Util.null2String(fu.getParameter("agentType")));
		int agentorByAgentId = Util.getIntValue(Util.null2String(fu.getParameter("agentorByAgentId")));


		String f_weaver_belongto_userid = request.getParameter("f_weaver_belongto_userid");// 需要增加的代码
		String f_weaver_belongto_usertype = request.getParameter("f_weaver_belongto_usertype");// 需要增加的代码

		String sessionkey = workflowid + "_" + nodeid + "_" + user.getUID() + "_" + System.currentTimeMillis();
		Map<String,Object> resultInfo = resultBean.getResultInfo();
		resultInfo.put("f_weaver_belongto_userid", f_weaver_belongto_userid);
		resultInfo.put("f_weaver_belongto_usertype", f_weaver_belongto_usertype);
		resultInfo.put("requestid", requestid);
		resultInfo.put("sessionkey", sessionkey);

		if (Util.getIntValue(fu.getParameter("takisremark"), -1) == 2 && agentType == 1) {//被代理人意见征询回复提交， 收回代理
			AgentManager agentManager = new AgentManager(user);
			agentManager.agentBackRequest(agentorByAgentId, user.getUID(), workflowid + "", requestid);
		}

		if (src.equals("") || workflowid == -1 || nodeid == -1 || nodetype.equals("")) {
			resultBean.setType(RequestExecuteType.SEND_PAGE);
			resultBean.setSendPage(weaver.general.GCONST.getContextPath()+"/notice/RequestError.jsp");
			return resultBean;
		}


		RequestAuthenticationService authenticationService = new RequestAuthenticationService();
		authenticationService.setUser(user);
		boolean hasRight = authenticationService.getRequestUserRight(null, requestid);
		if (!hasRight) {
			resultBean.setType(RequestExecuteType.FAILD);
			resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request, user, "1", ""));
			resultBean.getResultInfo().put("requestid",requestid);
			return resultBean;
		}

		Map<String, Object> authInfo = authenticationService.getAuthInfo();
		int isreamrk = Util.getIntValue(Util.null2String(authInfo.get("isremarkForRM")));
		//**********加个注释，强制编译下
		if(!(isreamrk == 1 || isreamrk == 0 || isreamrk == 9 || isreamrk==11)) {
			resultBean.setType(RequestExecuteType.FAILD);
			Map message = new HashMap();
			message.put("prompttype", PromptType.ERRORMSG.getType());
			message.put("title", SystemEnv.getHtmlLabelName(18015,user.getLanguage()) + SystemEnv.getHtmlLabelName(1454,user.getLanguage()));
			resultBean.setMessageInfo(message);
			return resultBean;
		}

		int extendnodeid = FreeNodeBiz.getExtendNodeId(requestid,nodeid);

		RequestManager requestManager = new RequestManager();
		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);
		requestManager.setRequestname(requestname);
		requestManager.setRequestlevel(requestlevel);
		requestManager.setRemark(remark);
		requestManager.setRequest(fu);
		requestManager.setSubmitNodeId(submitNodeId);
		requestManager.setIntervenorid(Intervenorid);
		requestManager.setRemarkLocation(remarkLocation);
		requestManager.setMessageType(messageType);
		requestManager.setIsFromEditDocument(isFromEditDocument);
		requestManager.setUser(user);
		requestManager.setTakisremark(Util.getIntValue(fu.getParameter("takisremark"), -1));
		requestManager.setCanModify(IsCanModify);
		boolean savestatus = requestManager.saveRequestInfo();
		requestid = requestManager.getRequestid();
		if (!savestatus) {
			if (requestid != 0) {
				String message = requestManager.getMessage();
				message = "".equals(message) ? "1" : message;
				resultBean.setType(RequestExecuteType.FAILD);
				resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request, user, message, requestManager.getMessagecontent()));
				resultBean.getResultInfo().put("requestid",requestid);
				return resultBean;
			}
		}


		/**======================流程数据加密处理========================*/
		String isCAAuth = Util.null2String(request.getParameter("isCAAuth"));        //是否是CA认证，主要是需要CA认证时的参数
		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 = com.engine.common.util.ServiceUtil.getService(RequestSecondAuthServiceImpl.class, user);
		if (savestatus) {
			if ("1".equals(isCAAuth)) {        //需要CA认证，保存后不提交流程，直接返回
				//先保存签字意见
				requestManager.setIsremark(0);
				requestManager.setSrc("save");
				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"));
				}
			}
		}

		int currid = -1;
		int takisremark = -1;
		int handleforwardid = -1;
		String zsql = ServiceUtil.calculateCurrentNodeSql(String.valueOf(requestid),Util.getIntValue(userid),usertype);
		rs.executeQuery(zsql);
		if (rs.next()) {
			takisremark = Util.getIntValue(rs.getString("takisremark"));
			handleforwardid = Util.getIntValue(rs.getString("handleforwardid"));
			currid = Util.getIntValue(rs.getString("id"));
		}

		RequestOperationMsgManager romm = new RequestOperationMsgManager();
		List<MsgEntity> requestMsgEntity = null;
		if(handleforwardid <= 0 && isremark != 11 && isremark != 1){
			requestMsgEntity = romm.getForwardReplyMsg(String.valueOf(requestid),userid);  //抄送回复消息
		}else if(handleforwardid <= 0 && realIsReamrk == 1) {
			requestMsgEntity = romm.forwardReplyNotice(requestid,user);  //转发批注
		}else if(isremark == 11){
			requestMsgEntity = romm.getChuanyueMsg(requestid,userid,nodeid,0);//传阅批示
		}

		if (takisremark == 2 && HrmClassifiedProtectionBiz.isOpenClassification()) {//意见征询回复时，对征询人做密级校验
			List<String> userIds = this.getForwardUserId(rs,requestid,nodeid,userid,false);
			String userId = userIds.isEmpty() ? "" : userIds.get(0);
			int userSecLevel = Util.getIntValue(new HrmClassifiedProtectionBiz().getMaxResourceSecLevelById2(userId));
			int requestSecLevel = new RequestSecLevelBiz().getSecLevelByRequestId(requestid+"");
			if (requestSecLevel < userSecLevel) {

				StringBuffer errorInfoMsgBuffer = new StringBuffer();

				String nextnodename = WorkflowRequestMessage.getWorkflowNodename(nodeid);
				WorkflowRequestMessage.getNodeErrorMsgTitle(errorInfoMsgBuffer, nextnodename, user.getLanguage());

				String messageContent = "";

				try {
					ResourceComInfo rci = new ResourceComInfo();
					messageContent = rci.getLastname(userId);
				} catch (Exception e) {
					e.printStackTrace();
				}

				messageContent = errorInfoMsgBuffer.toString() + WorkflowRequestMessage.getBoldInfo(messageContent) + " " + SystemEnv.getHtmlLabelName(501273, user.getLanguage());

				JSONObject msgInfo = WorkflowRequestMessage.getBottomInfo(SystemEnv.getHtmlLabelName(126540,user.getLanguage()),workflowid,WorkflowRequestMessage.WF_NODE_SET);
				msgInfo.put("details", messageContent);

				resultBean.setType(RequestExecuteType.FAILD);
				resultBean.setMessageInfo(SubmitErrorMsgBiz.getMsgInfo(request, user, "126221", msgInfo.toString()));
				resultBean.getResultInfo().put("requestid",requestid);

				//String sessionkey = workflowid + "_" + nodeid + "_" + user.getUID() + "_" + System.currentTimeMillis();
				//resultBean.getResultInfo().put("sessionkey", sessionkey);
				//Util_TableMap.setObjVal(sessionkey, resultBean);
				return resultBean;
			}
		}

		RequestOperationLogManager rolm = new RequestOperationLogManager(requestManager);
		rolm.setLastNodetype(nodeid);
		rolm.flowTransStartBefore();
		int optLogid = -1;
		// 强制收回
		int wfcuroptid = -1;
		if (isremark == 9) {
			rs.executeQuery("select id from workflow_currentoperator where requestid = ? and userid = ? and usertype = ? and isremark = ?",requestid,userid,usertype,isremark);
			if (rs.next()) {
				wfcuroptid = Util.getIntValue(rs.getString(1));
				optLogid = rolm.getOptLogID(wfcuroptid);
			}
		}

		//统一获取提交日期，获取不到再从数据库获取
		String reqCurrentdate = Util.null2String(requestManager.getCurrentDate());
		String reqCurrenttime = Util.null2String(requestManager.getCurrentTime());
		if("".equals(reqCurrentdate)){
			RecordSet rsreq = new RecordSet();
			rsreq.executeProc("GetDBDateAndTime", "");
			if (rsreq.next()) {
				reqCurrentdate = rsreq.getString("dbdate");
				reqCurrenttime = rsreq.getString("dbtime");
			}
		}

		char flag = Util.getSeparator();
		// 提交
		if (isremark == 9) {
			if (!"0".equals(needwfback)) {
				this.workflow_CurOpe_UbyForward(rs, requestid, Util.getIntValue(userid), usertype,reqCurrentdate,reqCurrenttime);
			} else {
				this.workflow_CurOpe_UbyForwardNB(rs,requestid, Util.getIntValue(userid), usertype,reqCurrentdate,reqCurrenttime);
			}
		} else if (isremark != 11){
			if(isremark == 1 && takisremark != 2){
				//当操作者在同一节点同时是转发接收人以及抄送不需提交的抄送人，打开表单时，不会将抄送记录修改为已操作，在这里修改一下，进行批注时，将抄送记录修改为已操作
				rs.executeUpdate("update workflow_currentoperator set isremark= 2 where requestid = ? and userid = ? and usertype = ? and preisremark = '8' and isremark = 8 ",requestid,userid,usertype);
			}
			if (!"0".equals(needwfback)) {
				//rs.executeProc("workflow_CurOpe_UbySend", "" + requestid + flag + userid + flag + usertype + flag + isremark);
				rs.executeUpdate("update workflow_currentoperator set isremark = 2,operatedate = ?,operatetime = ?,needwfback= '1' where requestid = ? and userid = ? and usertype = ? and isremark = ?",reqCurrentdate, reqCurrenttime, requestid, userid, usertype, isremark);

			} else {
				//rs.executeProc("workflow_CurOpe_UbySendNB", "" + requestid + flag + userid + flag + usertype + flag + isremark);
				rs.executeUpdate("update workflow_currentoperator set isremark=2,operatedate=?,operatetime=?,needwfback='0' where requestid =? and userid =? and usertype=? and isremark=?",reqCurrentdate,reqCurrenttime,requestid,userid,usertype,isremark);
			}
		}

		// 推送处理start
		//new Thread(new RequestPreProcessing(workflowid, isbill, formid, requestid, requestname, "", nodeid, 0, false, "", user, true)).start();
	    WFPathUtil wfutil = new WFPathUtil();
	    wfutil.getFixedThreadPool().execute(new RequestPreProcessing(workflowid, isbill, formid, requestid, requestname, "", nodeid, 0, false, "", user, true));
	    //提交反馈
		RequestBaseBiz.operateFeedBack(requestid,workflowid,extendnodeid,user.getUID(),remark,reqCurrentdate,reqCurrenttime);
		String curnodetype = "";
		int currentnodeid = 0;
		rs.executeSql("select currentnodetype,currentnodeid from workflow_Requestbase where requestid=" + requestid);
		if (rs.next()) {
			curnodetype = Util.null2String(rs.getString(1));
			currentnodeid = rs.getInt(2);
		}
		if (curnodetype.equals("3"))// 归档流程转发后，转发人或抄送人提交后到办结事宜。

			rs.executeSql("update workflow_currentoperator set iscomplete=1 where userid=" + userid + " and usertype=" + usertype + " and requestid=" + requestid);
		RequestLog requestlog = new RequestLog();
		requestlog.setRequest(fu);

		////取数据库服务器的当前时间  || 和RequestManager统一，避免批注的时间和提交的时间不一致，导致先批注的签字意见显示在后提交的签字意见前面
		requestlog.setCurrentdate(reqCurrentdate);
		requestlog.setCurrenttime(reqCurrenttime);
		requestlog.setIsremark(isremark);
		requestlog.setCurrId(currid);

		if("".equals(remark.trim())) {
			OperationMenuType type  = null;
			if (isremark == 1) {
				if(takisremark == 2) {
					type = OperationMenuType.TAKING_OPINIONS;
				} else {
					type = OperationMenuType.FORSUB;
				}
			} else if (isremark == 9) {
				type = OperationMenuType.CCSUB;
			}
			if(type != null) {
				remark =  Util.null2String(MenuDefaultSignBiz.getMenuDefaultSignMap(workflowid,nodeid,type));
			}
		}
		//语音附件
		int speechAttachment = Util.getIntValue(fu.getParameter("speechAttachment"),0);
		String handWrittenSign = Util.null2String(request.getParameter("handWrittenSign"),"");
		String fulltextannotation = Util.null2String(fu.getParameter("fulltextannotation"));
		String speechAttachmente9 = Util.null2String(fu.getParameter("speechAttachmente9"));
		String clientType = Util.null2String(fu.getParameter("clientType"), SignSource.PC_BROWSER.getType());

		//传阅回复默认签字意见
		if(isremark==11)remark = getRemark(workflowid,currentnodeid,remark);



		String currentString = "";
		if (takisremark == 2) {
			currentString = requestlog.saveLog2(workflowid, requestid, nodeid, "b", remark, user, clientType, speechAttachment, handWrittenSign, "", remarkLocation,fulltextannotation,speechAttachmente9); // 意见征询
		} else if (handleforwardid > 0) {
			currentString = requestlog.saveLog2(workflowid, requestid, nodeid, "j", remark, user, clientType, speechAttachment, handWrittenSign, "", remarkLocation,fulltextannotation,speechAttachmente9); // 转办
		} else {
			currentString = requestlog.saveLog2(workflowid, requestid, nodeid, isremark==11?"y":"9", remark, user, clientType, speechAttachment, handWrittenSign, "", remarkLocation,fulltextannotation,speechAttachmente9);
			// 抄送需要提交 时， 添加 强制收回支持
			if (isremark == 9) {
				rs.executeSql("select logid from workflow_requestlog where requestid = " + requestid + " and nodeid = " + nodeid + " and operator=" + user.getUID() + " and operatortype=" + usertype
						+ " and logtype = '9' order by operatedate, operatetime");
				if (rs.next()) {
					int newlogid = rs.getInt(1);
					if (newlogid > 0) {
						// 向之前的日志中添加本条提交的记录， 方便在强制收回的时候能够收回
						rolm.addDetailLog(optLogid, RequestOperateEntityTableNameEnum.REQUESTLOG.getTableName(), newlogid, 0, "", "", "");
					}
				}
			}
		}


		/***================数据保护==============*/
		if (!"".equals(currentString) && currentString.indexOf("~~current~~") > -1) {
			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, currentnodeid, uuidStr);
				}
			} else if (protectType == SecondAuthType.CAAuth.getId()||
					(protectType == SecondAuthType.QYS.getId()&&qysSignWay == 1)) {   //CA数据保护
				if ("1".equals(isProtectSuccess) && !"".equals(authKey)) {
					requestSecondAuthService.updateProtectDatas(requestid, workflowid, currentnodeid, 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);
			}
		}

		WFLinkInfo wflinkinfo = new WFLinkInfo();
		int nodeattr = wflinkinfo.getNodeAttribute(nodeid);
		Set<String> branchNodeSet = new HashSet<String>();
		if (nodeattr == 2) { // 分支中间节点
			String branchnodes = "";
			branchnodes = wflinkinfo.getNowNodeids(requestid);
			if (!"".equals(branchnodes)) {
				String[] strs = branchnodes.split(",");
				for (int k = 0; k < strs.length; k++) {
					String nodestr = strs[k];
					if (!"-1".equals(nodestr)) {
						branchNodeSet.add(nodestr);
					}
				}
			}
		}

		/** 日志权限的处理，非归档节点，且提交时的节点，跟流程当前节点相同才需要权限控制 */
		if (!"".equals(currentString) && currentString.indexOf("~~current~~") > -1 && !"3".equals(curnodetype) && (nodeid == currentnodeid || branchNodeSet.contains(nodeid + ""))) {
			int wfcurrrid = Util.getIntValue((String) attrSignatureUtil.getAttribute("wfcurrrid"), 0);
			if (wfcurrrid == 0) {
				rs.executeSql("select isremark,isreminded,preisremark,id,groupdetailid,nodeid from workflow_currentoperator where requestid=" + requestid + " and userid=" + userid + " and usertype="
						+ usertype + " order by isremark,id");
				while (rs.next()) {
					String isremark_tmp = Util.null2String(rs.getString("isremark"));
					wfcurrrid = Util.getIntValue(rs.getString("id"));
					// 转发特殊处理，转发信息本人未处理一直需要处理即使流程已归档
					if (isremark_tmp.equals("1") || isremark_tmp.equals("5") || isremark_tmp.equals("7") || isremark_tmp.equals("9") || (isremark_tmp.equals("0") && !nodetype.equals("3"))) {
						break;
					}
					if (isremark_tmp.equals("8")) {
						break;
					}
				}
			}

			String[] arraycurrent = Util.TokenizerString2(currentString, "~~current~~");
			String currentdate = arraycurrent[0];
			String currenttime = arraycurrent[1];
			RequestRemarkRight remarkRight = new RequestRemarkRight();
			remarkRight.setRequestid(requestid);
			remarkRight.setNodeid(nodeid);
			remarkRight.setWorkflow_currentid(wfcurrrid);
			String logtype = "7";
			if (takisremark == 2) { // 征询
				logtype = "b";
			} else if (handleforwardid > 0) { // 转办
				logtype = "j";
			} else if (isremark == 11) { // 传阅批示
				logtype = "y";
			} else { // 转发
				logtype = "9";
			}
			String rightSql = " select logid from workflow_requestlog where workflowid = " + workflowid + " and nodeid = " + nodeid + " and logtype = '" + logtype + "' and requestid = " + requestid
					+ " and operatedate = '" + currentdate + "' and operatetime = '" + currenttime + "' and operator = " + userid;
			rs.executeSql(rightSql);
			int logid = -1;
			if (rs.next()) {
				logid = rs.getInt("logid");
			}
			String userids = "";
			remarkRight.saveRemarkRight(logid, userids);
		}

		String logtype = "7";
		if (!"".equals(currentString) && currentString.indexOf("~~current~~") > -1) {
			String[] arraycurrent = Util.TokenizerString2(currentString, "~~current~~");
			String currentdate = arraycurrent[0];
			String currenttime = arraycurrent[1];

			if (takisremark == 2) { // 征询
				logtype = "b";
			} else if (handleforwardid > 0) { // 转办
				logtype = "j";
			} else { // 转发
				logtype = "9";
			}
			RequestSignRelevanceWithMe reqsignwm = new RequestSignRelevanceWithMe();
			reqsignwm.inertRelevanceInfo(workflowid + "", requestid + "", currentnodeid + "", logtype, currentdate, currenttime, userid, remark);
		}

		if(isremark==11 || takisremark == 2){
			String[] arraycurrent = Util.TokenizerString2(currentString, "~~current~~");
			String currentdate = Util.null2String(arraycurrent[0]);
			String currenttime = Util.null2String(arraycurrent[1]);
			ChuanyueUtil.executeProc4Chuanyue(workflowid,requestid,nodeid,user.getUID(),usertype,currentdate,currenttime,needwfback);
		}

		if (takisremark == 2) {//暂不清楚为什么屏蔽这么久
			ArrayList resourceids = new ArrayList();
			resourceids.add(userid);
			RequestAddShareInfo requestAddShareInfo = new RequestAddShareInfo();
			requestAddShareInfo.addShareInfo("" + requestid, resourceids, "false", true, false, true); // 收回被征询人的文档编辑权限

			String forwardids = "";//记录需要做数据修正的forwardid
			// 多个分叉中间点意见征询给同一人时， 需要找到当前所有的节点，判断是否存在意见征询动作
			WFLinkInfo wfLinkinfo = new WFLinkInfo();
			TakReplyBiz takOptionBiz = new TakReplyBiz(requestid, workflowid, user);
			String takNodeIds = wfLinkinfo.getNowNodeids(requestid);
			String taksql = "select id,takid,multiTakLevel, nodeid from workflow_currentoperator where requestid= " + requestid + " and nodeid in ( " + takNodeIds + ") and userid = " + userid
					+ " and preisremark='1' and takisremark = 2 order by userid,id";
			rs.executeSql(taksql);
			RecordSet rs1 = new RecordSet();
			while (rs.next()) {
				int beforwardid = Util.getIntValue(rs.getString("id"));
				int beforwardNodeId = Util.getIntValue(rs.getString("nodeid"));
				int forwardid = Util.getIntValue(rs.getString("takid"));
				int multiTakLevel = Util.getIntValue(rs.getString("multiTakLevel"), 0);
				//兼容老数据，workflow_currentoperator表中没存takid时，从workflow_forward中取
				if (forwardid <= 0) {
					rs1.executeSql("select forwardid from workflow_forward where requestid = " + requestid + " and beforwardid = " + beforwardid);
					rs1.next();
					forwardid = Util.getIntValue(rs1.getString("forwardid"));
				}

				if (forwardid > 0) { // 找到征询人

					if (multiTakLevel <= 0) {//添加回复人
						rs1.executeQuery("select 1 from workflow_currentoperator where isremark = 0 and takisremark = '-2' and id = ?", forwardid);
						if(rs1.next()) {
							takOptionBiz.getReplyToIds().add(forwardid);
						}
					}

					String sumBeforWardSql = "select * from workflow_currentoperator where requestid= " + requestid + " and nodeid = " + beforwardNodeId
							+ " and ((isremark=1 and preisremark='1') or istakout = 1) and takisremark = 2 and (id in (select beforwardid from workflow_forward where requestid=" + requestid + " and forwardid="
							+ forwardid + " and beforwardid<>" + beforwardid + ") or takid = " + forwardid + ")";
					rs1.executeSql(sumBeforWardSql);
					if (!rs1.next()) { // 判断是否所有被征询人都已回复
						forwardids += forwardid + ",";
						String uptaksql2 = "update workflow_currentoperator set takisremark=0 where requestid= " + requestid + " and nodeid = " + beforwardNodeId
								+ " and isremark = 0 and takisremark = -2 and id=" + forwardid;
						rs1.executeSql(uptaksql2);
						//多重意见征询回复
						if (multiTakLevel > 0) {
							takOptionBiz.doTakingReply(forwardid, multiTakLevel, beforwardid);
						} else {
							int forwardUserid = 0;
							rs1.executeQuery("select userid from workflow_currentoperator where id = ?", forwardid);
							if (rs1.next()) {
								forwardUserid = Util.getIntValue(rs1.getString("userid"), 0);
							}

							//调整islasttimes，让流程回到待办
							rs1.executeQuery("select id from workflow_currentoperator where islasttimes = 1 and requestid = ? and userid = ?", requestid, forwardUserid);
							int count = rs1.getCounts();//一个requestid，userid存在islasttimes = 1的记录数量，只要不等于1说明需要修复
							int forwardid_temp = -1;//islasttimes = 1的记录与征询人的这条记录不相同，则需要修复
							if(rs1.next()){
								forwardid_temp = rs1.getInt("id");
							}
							//增加需要进入修复逻辑的条件（增加条件的原因是因为很多客户再执行这段逻辑时，执行完第一句时，执行第二句就死锁了，导致出问题了）
							if(count != 1 || forwardid_temp != forwardid){
								rs1.executeUpdate("update workflow_currentoperator set islasttimes = 0 where requestid = ? and userid = ? and id != ?", requestid, forwardUserid, forwardid);
								rs1.executeUpdate("update workflow_currentoperator set islasttimes = 1 where id = ?", forwardid);
							}

							// 如果意见征询接收人可以上传附件，需要对意见征询人赋权
							try {
								RequestAddShareInfo shareinfo = new RequestAddShareInfo();
								shareinfo.setRequestid(requestid);
								shareinfo.SetWorkFlowID(workflowid);
								shareinfo.SetNowNodeID(nodeid);
								shareinfo.SetNextNodeID(nodeid);
								shareinfo.setIsbill(isbill);
								shareinfo.setUser(user);
								shareinfo.SetIsWorkFlow(1);
								String billtablename = "";
								if (isbill == 1) {
									rs1.executeSql("select tablename from workflow_bill where id = " + formid);
									if (rs1.next())
										billtablename = rs1.getString("tablename");
								}
								shareinfo.setBillTableName(billtablename);
								shareinfo.setHaspassnode(false);
								shareinfo.setNeedModifyNownodeToView(false);
								shareinfo.addShareInfo();
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
				rs1.executeQuery("select userid from workflow_currentoperator where id = ?",forwardid);
				rs1.next();
				//修正A提交B，A再转发给B，B意见征询给C，C回复后，流程在B的已办问题
				String uptaksql2 = "update workflow_currentoperator set takisremark=0 , isremark = 1 where requestid= ? and userid = ? and nodeid not in ("+takNodeIds+") and isremark = 0 and takisremark = -2 and islasttimes = 0" ;
				rs1.executeUpdate(uptaksql2,requestid,Util.null2String(rs1.getString("userid")));
			}
			//意见征询回复后，更新签字意见的接收人
			takOptionBiz.updateRequestLog();
			//修正：意见征询人在currentoperator表有两条数据，意见征询时workflow_forward表存的forwardid不对，导致回复时更新takisremark更新错的情况,导致流程回不到待办
			WfDataCorrectionUtils.correctTakData(requestid,forwardids);
		}
		if("b".equals(logtype) || "9".equals(logtype) ){
			if("b".equals(logtype)){
				rolm.setSrc(RequestOperateTypeEnum.TAKEREPLY.getId());
			}else if("9".equals(logtype)){
				rolm.setSrc(RequestOperateTypeEnum.FORWARDREPLY.getId());
			}
			rolm.flowTransSubmitAfter();
		}

		//意见征询的加强处理，防止被征询回复后，流程不在待办
		rs.executeQuery("select id from workflow_currentoperator where requestid = ? and isremark = '0' and takisremark = '-2'", requestid);
		while (rs.next()) {
			int tempId = rs.getInt(1);
			if(!checkIsTakOut(requestid, tempId)) {//征询出去的记录都已回复，将此记录设置为已回复状态
				rs.executeUpdate("update workflow_currentoperator set takisremark = '0' where requestid = ? and id = ?", requestid, tempId);
			}
		}
		if (takisremark == 2){
			this.remarkRemind(requestid,workflowid,src,fu,resultInfo,nodeid);
		}
		if("7".equals(logtype)){
			targetName = "转发";
		} else if ("b".equals(logtype)){
			targetName = "意见征询回复";
		} else if ("j".equals(logtype)){
			targetName = "转办反馈";
		} else if ("y".equals(logtype)){
			targetName = "传阅批注";
		} else if ("9".equals(logtype)){
			targetName = "批注";
		}

		if("1".equals(comemessage)){
			resultBean.setType(RequestExecuteType.SEND_PAGE);
			resultBean.setSendPage(weaver.general.GCONST.getContextPath()+"/spa/workflow/index_mobx.jsp#/main/workflow/listDoing");
		}else{
			resultBean.setType(RequestExecuteType.SUCCESS);
		}
		new MsgPushUtil().pushMsg(requestMsgEntity);
		return resultBean;
	}

	/**
	 * 检查当前记录是否处于意见征询出去的状态
	 * @param id
	 * @return
	 */
	public boolean checkIsTakOut(int requestid, int id) {
		RecordSet rs = new RecordSet();
		rs.executeQuery("select id,isremark from workflow_currentoperator where requestid = ? and takid = ? and takisremark = '2'", requestid, id);
		while (rs.next()) {
			int tempId = rs.getInt(1);
			String tempIsremark = rs.getString(2);
			if ("1".equals(tempIsremark)) {//存在未回复的记录
				return true;
			} else if(checkIsTakOut(requestid, tempId)){
				//isremark为2的情况，验证多级征询
				return true;
			}
		}
		return false;
	}

	/**
	 * 根据被转发\被意见征询人 找出转发\意见征询人
	 * @param rs
	 * @param requestid
	 * @param nodeid
	 * @param userid  转发\被意见征询人
	 * @return     转发\意见征询人
	 */
	private List<String> getForwardUserId(RecordSet rs,int requestid,int nodeid,String userid,boolean isShowReplyNotice){
		List<String> forwardUserId = new ArrayList<>();
		//根据当前被征询人找出征询人
		rs.executeQuery("select id,takisremark from workflow_currentoperator where requestid = ? and nodeid = ? and userid = ? and isremark = 1", requestid, nodeid, userid);
		List<String> beforwardIds = new ArrayList<>();
		while(rs.next()){
			beforwardIds.add(Util.null2String(rs.getString("id")));
		}
		if(beforwardIds.isEmpty()) return forwardUserId;;
		List<String> forwardIds = this.getForwardIds(rs,beforwardIds,requestid,isShowReplyNotice);
		if(forwardIds.isEmpty()) return forwardUserId;
		rs.executeQuery("select userid from workflow_currentoperator where " + Util.getSubINClause(String.join(",",forwardIds),"id","in"));
		while (rs.next()){
			forwardUserId.add(Util.null2String(rs.getString("userid")));
		}
		return forwardUserId;
	}

	/**
	 *
	 * @param rs
	 * @param beforwardIds
	 * @param requestid
	 * @return
	 */
	private List<String> getForwardIds(RecordSet rs,List<String> beforwardIds,int requestid,boolean isShowReplyNotice){
		List<String> forwardIds = new ArrayList<>();
		String sql = "select forwardid from workflow_forward where requestid = ?  ";
		if(isShowReplyNotice){
			sql += " and isShowReplyNotice = '1'";
		}
		sql += " and "+  Util.getSubINClause(String.join(",",beforwardIds),"beforwardid","in");
		rs.executeQuery(sql, requestid);

		while(rs.next()){
			forwardIds.add(Util.null2String(rs.getString("forwardid")));
		}
		return forwardIds;
	}

	private String getRemark(int workflowid,int nodeid,String remark){
		if("".equals(remark) || "\n".equals(remark) ){
			RecordSet rs = new RecordSet();
			rs.executeQuery("select newname7 from workflow_nodeCustomNewMenu where menutype = -25 and wfid = ? and nodeid = ?",workflowid,nodeid);
			if(rs.next()){
				String newname7 = rs.getString(1);
				remark = Util.processBody(Util.null2String(rs.getString(1)).trim(),
						"" + user.getLanguage());
			}
		}
		return remark;
	}
	
	@Override
	public BizLogContext getLogContext() {
		BizLogContext bizLogContext = new BizLogContext();
		BizLogOperateType bizLogOperateType = BizLogOperateType.APPROVE;
		bizLogContext.setDateObject(new Date());
		bizLogContext.setUserid(user.getUID());
		bizLogContext.setUsertype(Util.getIntValue(user.getLogintype()));
		bizLogContext.setTargetId("remark_submit");
		bizLogContext.setTargetName(targetName);
		bizLogContext.setLogType(BizLogType.WORKFLOW);
		bizLogContext.setLogSmallType(BizLogSmallType4Workflow.WORKFLOW_APPROVE);
		bizLogContext.setOperateType(bizLogOperateType);
		bizLogContext.setClientIp(Util.null2String(Util.getIpAddr(request)));
		bizLogContext.setParams(ParamUtil.request2Map(request));
		bizLogContext.setDesc(String.format(user.getLastname() + "进行了"+targetName+"操作"));

		return bizLogContext;
	}



	/**
	 * PROCEDURE workflow_CurOpe_UbyForward 改造而来
	 * @param rs
	 * @throws Exception
	 */
	private static void workflow_CurOpe_UbyForward(RecordSet rs, int requestid, int userid, int usertype, String currentdate, String currenttime) throws Exception {
		String upSql = "update workflow_currentoperator set isremark = 2, operatedate = '" + currentdate + "', operatetime = '" + currenttime + "',processUser = "+userid
				+ " where requestid = " + requestid + " and userid =" + userid
				+ " and usertype = " + usertype + " and (isremark = 1 or isremark = 8 or isremark = 9)";
		rs.executeSql(upSql);
	}

	/**
	 * PROCEDURE workflow_CurOpe_UbyForwardNB 改造而来
	 * @param rs
	 * @throws Exception
	 */
	private static void workflow_CurOpe_UbyForwardNB(RecordSet rs, int requestid, int userid, int usertype, String currentdate, String currenttime) throws Exception {
		String upSql = " update workflow_currentoperator set isremark='2', operatedate = '" + currentdate + "', operatetime = '" + currenttime + "', needwfback  = '0',processUser = "+userid
				+ " where requestid = " + requestid
				+ " and userid = " + userid
				+ " and usertype = " + usertype
				+ " and (isremark = '1' or isremark = '8' or isremark = '9')";

		rs.executeSql(upSql);
	}

	/**
	 * 意见征询回复提醒
	 * @param requestid
	 * @param workflowid
	 * @param src
	 * @param fu
	 * @param resultInfo
	 */
	private void remarkRemind(int requestid,int workflowid,String src,FileUpload fu,Map<String,Object> resultInfo,int nodeid ){

		RecordSet rs = new RecordSet();
		//根据当前被征询人找出征询人
		rs.executeQuery("select id from workflow_currentoperator where requestid = ? and nodeid = ? and userid = ? and isremark = 2 and takisremark = 2", requestid, nodeid, user.getUID());
		rs.next();
		int beforwardId = Util.getIntValue(Util.null2String(rs.getString("id")));
		rs.executeQuery("select forwardid from workflow_forward where requestid = ? and beforwardid = ?", requestid, beforwardId);
		rs.next();
		int forwardId = Util.getIntValue(Util.null2String(rs.getString("forwardid")));
		Set<String> allBeforwardId = new HashSet<>();
		rs.executeQuery("select beforwardid from workflow_forward where requestid = ? and forwardid = ?",requestid,forwardId); //所有被征询人
		while(rs.next()){
			allBeforwardId.add(Util.null2String(rs.getString("beforwardid")));
		}
		if (allBeforwardId.isEmpty()) return;
		String ss = String.join(",",allBeforwardId);
		rs.executeQuery("select 1 from workflow_currentoperator where ("+Util.getSubINClause(ss,"id","in")+") and isremark = 1 and takisremark = 2");
		//
		if(!rs.next()){
			rs.executeQuery("select userid from workflow_currentoperator where  id = ? ", forwardId );
			String remindTypes = Util.null2String(fu.getParameter("remindTypes"));
			if(!Strings.isNullOrEmpty(remindTypes) && rs.next()){

//				boolean isChooseReminder = RequestRemindBiz.isNeedRemind(workflowid,requestid,src,user.getUID());
//				if (isChooseReminder) {
//					resultInfo.put("needRemind", true);
//				} else {

					String isSmsRemind = remindTypes.indexOf(RemindTypeEnum.SMS.getCode()) > -1 ? "1" : "0";
					String isEmailRemind = remindTypes.indexOf(RemindTypeEnum.EMAIL.getCode()) > -1 ? "1" : "0";

					String taker = rs.getString(1);
					Map<String,Object> params = new HashMap<>();
					params.put("reminder",taker);
					params.put("requestId",requestid);
					params.put("workflowId",workflowid);
					params.put("submitType", "");
					RequestRemindBiz requestRemindBiz = new RequestRemindBiz(user);

					if("1".equals(isSmsRemind)) requestRemindBiz.requestRemind(params,RemindTypeEnum.SMS);
					if("1".equals(isEmailRemind)) requestRemindBiz.requestRemind(params,RemindTypeEnum.EMAIL);

//				}
			}
		}
	}

	/**
	 * 简单校验 是否已回复过
	 * @param requestid
	 * @param nodeid
	 * @return
	 */
	private boolean isDidremarkSubmit(int requestid , int nodeid){
		RecordSet recordSet = new RecordSet();
		String sql = "select takid from workflow_currentoperator  t where t.requestid=? and nodeid=? and userid=? and islasttimes=1 and isremark=1 and takisremark=2";
		recordSet.executeQuery(sql,requestid,nodeid,user.getUID());
		if(recordSet.next()){
			return false;
		}
		return true;
	}
}
