package cn.myapps.runtime.dynaform.document.controller;

import cn.hutool.core.util.StrUtil;
import cn.myapps.base.web.WebUser;
import cn.myapps.common.Environment;
import cn.myapps.common.controller.Resource;
import cn.myapps.common.controller.ResourceNotFoundException;
import cn.myapps.common.data.ParamsTable;
import cn.myapps.common.model.activity.ActivityType;
import cn.myapps.common.model.workflow.BillDefiVO;
import cn.myapps.common.util.PropertyUtil;
import cn.myapps.common.util.cache.MemoryCacheUtil;
import cn.myapps.conf.FileModeConfig;
import cn.myapps.runtime.common.controller.AbstractRuntimeController;
import cn.myapps.runtime.common.service.RunTimeServiceManager;
import cn.myapps.runtime.dynaform.PermissionType;
import cn.myapps.runtime.dynaform.document.ejb.Document;
import cn.myapps.runtime.dynaform.document.ejb.DocumentProcess;
import cn.myapps.runtime.dynaform.form.ejb.*;
import cn.myapps.runtime.form.service.FormHelperRunTimeService;
import cn.myapps.runtime.macro.runner.IRunner;
import cn.myapps.runtime.macro.runner.JavaScriptFactory;
import cn.myapps.runtime.workflow.element.FlowDiagram;
import cn.myapps.runtime.workflow.element.Node;
import cn.myapps.runtime.workflow.engine.StateMachine;
import cn.myapps.runtime.workflow.storage.runtime.ejb.FlowStateRT;
import cn.myapps.runtime.workflow.storage.runtime.ejb.NodeRT;
import cn.myapps.util.StringUtil;
import cn.myapps.util.ftp.FtpUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kinggrid.encrypt.KGBase64;
import com.kinggrid.pdf.ElectronicSignatureByKey;
import com.kinggrid.pdf.KGPdfHummer;
import com.kinggrid.pdf.executes.PdfElectronicSeal4KG;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.util.*;

/**
 * FormHelper RESTful API
 * @author spy
 */
@Api(tags = "表单工具模块")
@Component
@RequestMapping(path = "/api/runtime", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class FormHelperController extends AbstractRuntimeController {

	private static final Logger logger = LoggerFactory.getLogger(FormHelperController.class);

	@Autowired
	private FormHelperRunTimeService service;

	/**
	 * 判断是否存在预览环境(用于在线预览)
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/files/preview/environment")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "判断是否存在预览环境(用于在线预览)", notes = "判断是否存在预览环境(用于在线预览)")
	public Resource previewEnabled() throws Exception {
		return success("ok", true);
	}

	/**
	 * 判断该文件是否存在pdf文件
	 * @param path
	 * 		文件路径
	 * @param fileRealName
	 * 		文件真实名称
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/files/hasPdf")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "判断该文件是否存在pdf文件", notes = "判断该文件是否存在pdf文件")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "path",value = "路径",required = true,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "fileRealName",value = "真实名称",required = true,paramType = "query",dataType = "string")
	})
	public Resource hasPdfFile(@RequestParam String path, @RequestParam String fileRealName) throws Exception {
		return success("ok", true);
	}

	private void getFtpFile(String path){
		try {

			String fullPath = Environment.getInstance().getRealPath(path);
			File file = new File(fullPath);
			if (file.exists()){
				if(file.length()>0){
					return ;
				}
			}

			//文件路径
			String filePath = path.substring(0, path.lastIndexOf("/") + 1);
			//文件名称
			String fileName = path.substring(path.lastIndexOf("/") + 1);
			FtpUtils.downloadFile(FileModeConfig.getHost(),
					FileModeConfig.getUserName(),
					FileModeConfig.getPassword(),
					FileModeConfig.getPort(),
					(StrUtil.isEmpty(FileModeConfig.getFilePath()) ? "": FileModeConfig.getFilePath()) + filePath,
					fullPath.substring(0, fullPath.lastIndexOf("/") + 1),
					fileName);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	/**
	 * 水印文件打印
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @param content
	 * 		请求包体
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/{applicationId}/documents/{docId}/files/watermark/print")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "水印文件打印", notes = "水印文件打印")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource doFilePrintWithWaterMark(@PathVariable String applicationId, @PathVariable String docId, @RequestBody String content) throws Exception {
		JSONObject json = JSON.parseObject(content);
		String path = (String) json.get("path");
		if(!path.startsWith("/uploads/")){
			throw new ResourceNotFoundException("Error: file illegal!");
		}
		String fileName = (String) json.get("fileName");
		String itemId = (String) json.get("itemId");
		String realPath = request.getSession().getServletContext().getRealPath("/");
		String result = service.doFilePrintWithWaterMark(applicationId, docId, itemId, realPath, path, fileName, getUser());
		return success("ok", result);
	}

	@GetMapping("/{applicationId}/documents/{docId}/formhelper/inputlog")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取控件修改历史", notes = "获取控件修改历史")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "fieldName",value = "文件名",required = true,paramType = "query",dataType = "string")
	})
	public Resource getFieldModifiedLog(@PathVariable String applicationId, @PathVariable String docId,
										@RequestParam String fieldName) throws Exception{
		JSONArray result =service.getFieldModifiedLog(docId, applicationId, fieldName, getParams(), getUser());
		return success("ok", result);
	}

	/**
	 * 保存金格HTML电子签章
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @param content
	 * 		请求包体
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/{applicationId}/documents/{docId}/htmlsignature")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "保存金格HTML电子签章", notes = "保存金格HTML电子签章")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource saveHTMLSignature(@PathVariable String applicationId, @PathVariable String docId, @RequestBody String content) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null){
			net.sf.json.JSONObject signature = net.sf.json.JSONObject.fromObject(content);
			FlowStateRT instance = doc.getState();
			if(instance != null){
				BillDefiVO flowVO = instance.getFlowVO();
				String currNodeId = null;
				FlowDiagram fd = null;
				if (flowVO != null) {
					NodeRT nodert = null;
					fd = flowVO.toFlowDiagram();
					if (instance.isTemp()) {
						nodert = ((List<NodeRT>) instance.getNoderts()).get(0);
						currNodeId = nodert.getNodeid();
					}

					if (currNodeId == null && nodert == null) {
						nodert = StateMachine.getCurrUserNodeRT(doc, getUser(), currNodeId);
						if (nodert != null)
							currNodeId = nodert.getNodeid();
					}
				}
				// 获取当前结点
				Node currnode = null;
				if (currNodeId != null) {
					currnode = (Node) fd.getElementByID(currNodeId);
				}

				if(currnode != null){
					signature.put("nodeId", currnode.getId());
					signature.put("stateLabel", currnode.getStatelabel());
					;				}
			}

			if(!cn.myapps.util.StringUtil.isBlank(doc.getKinggridSignature())){
				net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
				Object htmlSignature = kinggridSignature.get("htmlSignature");
				if(htmlSignature != null){
					JSONArray jsonArr = (JSONArray) htmlSignature;
					jsonArr.add(signature);
				} else {
					JSONArray jsonArr = new JSONArray();
					jsonArr.add(signature);
					kinggridSignature.put("htmlSignature", jsonArr);
				}
				doc.setKinggridSignature(kinggridSignature.toString());
			} else {
				net.sf.json.JSONObject kinggridSignature = new net.sf.json.JSONObject();
				JSONArray jsonArr = new JSONArray();
				jsonArr.add(signature);
				kinggridSignature.put("htmlSignature", jsonArr);
				doc.setKinggridSignature(kinggridSignature.toString());
			}
			process.doUpdate(doc);
			//更新缓存
			Document document = (Document)MemoryCacheUtil.getFromPrivateSpace(docId, getUser());
			document.setKinggridSignature(doc.getKinggridSignature());
			MemoryCacheUtil.putToPrivateSpace(docId, document, getUser());

			return success("ok", null);
		} else {
			return error(4001, "请先保存表单!", null);
		}
	}

	/**
	 * 获取金格HTML电子签章
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/documents/{docId}/htmlsignature")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取金格HTML电子签章", notes = "获取金格HTML电子签章")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string")
	})
	public Resource getHTMLSignature(@PathVariable String applicationId, @PathVariable String docId) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null && !cn.myapps.util.StringUtil.isBlank(doc.getKinggridSignature())){
			net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
			Object htmlSignature = kinggridSignature.get("htmlSignature");
			if(htmlSignature != null){
				JSONArray result = (JSONArray)htmlSignature;
				return success("ok", result);
			}
		}
		return success("ok", null);
	}

	/**
	 * 更新金格HTML电子签章
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@PutMapping("/{applicationId}/documents/{docId}/htmlsignature")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "更新金格HTML电子签章", notes = "更新金格HTML电子签章")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "签章id包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource updateHTMLSignature(@PathVariable String applicationId, @PathVariable String docId, @RequestBody  String content) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null && !cn.myapps.util.StringUtil.isBlank(doc.getKinggridSignature())){
			JSONArray ids = cn.myapps.util.json.JsonTmpUtil.fromObject(content);

			if(!StringUtil.isBlank(doc.getKinggridSignature())){
				net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
				Object htmlSignature = kinggridSignature.get("htmlSignature");
				if(htmlSignature != null){
					JSONArray htmlSignatureArr = (JSONArray) htmlSignature;
					if(ids.isEmpty()){
						JSONArray jsonArr = new JSONArray();
						kinggridSignature.put("htmlSignature", jsonArr);
					} else {
						for(Iterator iterator = htmlSignatureArr.iterator();iterator.hasNext();){
							net.sf.json.JSONObject json = (net.sf.json.JSONObject) iterator.next();
							String signatureId = json.getString("signatureId");
							//获取在signatureData->position->defaultSignature
							net.sf.json.JSONObject oldeSignatureData = (net.sf.json.JSONObject) json.get("signatureData");

							boolean flag = true;
							Iterator iterator2 = ids.iterator();
							//不管有没有position，加就vans了
							while(iterator2.hasNext()){
//                                String id = (String) iterator2.next();
								net.sf.json.JSONObject next = (net.sf.json.JSONObject) iterator2.next();
								String id = next.getString("signatureId");

								if(signatureId.equals(id)){
									flag = false;
									net.sf.json.JSONObject newPosition = (net.sf.json.JSONObject) next.get("position");
//									JSONObject newDefaultSignature = (JSONObject) newPosition.get("defaultSignature");
									oldeSignatureData.put("position",newPosition);
								}
							}
							if(flag){
								iterator.remove();
							}
						}
						kinggridSignature.put("htmlSignature", htmlSignatureArr);
					}
					doc.setKinggridSignature(kinggridSignature.toString());
				}
			}
			process.doUpdate(doc);
			//更新缓存
			Document document = (Document)MemoryCacheUtil.getFromPrivateSpace(docId, getUser());
			document.setKinggridSignature(doc.getKinggridSignature());
			MemoryCacheUtil.putToPrivateSpace(docId, document, getUser());
		}
		return success("ok", null);
	}

	/**
	 * 获取表单配置的签章按钮
	 * @param applicationId 软件id
	 * @param docid 文档id
	 * @return
	 * @throws Exception
	 */
	@GetMapping(path = "/{applicationId}/documents/{docId}/signatureButtonFields")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取表单配置的签章按钮", notes = "获取表单配置的签章按钮")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档Id",required = true,paramType = "path",dataType = "string")
	})
	public Resource getFormSignatureButtonFields(@PathVariable String applicationId, @PathVariable String docId) throws Exception {
		WebUser user = getUser();
		ParamsTable params = getParams();

		DocumentProcess dProcess = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) dProcess.doView(docId);
		if(doc != null){
			Form form = doc.getForm();
			doc = form.recalculateDocument(doc, params, user);
			IRunner runner = JavaScriptFactory.getInstance(user.getSessionid(), applicationId);
			runner.initBSFManager(doc, params, user, new ArrayList<ValidateMessage>());

			List<Map<String, Object>> data = new ArrayList<Map<String,Object>>();
			Collection<FormField> fields = form.getFields();
			for (FormField formField : fields) {
				if(formField instanceof TabField){
					Map<String, Object> value = formField.toAttributes(doc, runner, user, PermissionType.MODIFY);
					List<com.alibaba.fastjson.JSONObject> tabs = (ArrayList<com.alibaba.fastjson.JSONObject>)value.get("tabs");
					for (Iterator<com.alibaba.fastjson.JSONObject> tabIterator = tabs.iterator(); tabIterator.hasNext();){
						com.alibaba.fastjson.JSONObject tab = tabIterator.next();
						Object tabFieldsObj = tab.get("fields");
						if(tabFieldsObj != null){
							Collection tabFields = (ArrayList)tab.get("fields");
							for (Iterator tabFieldIterator = tabFields.iterator();tabFieldIterator.hasNext();){
								Map fieldJson = (HashMap)tabFieldIterator.next();
								if("ButtonField".equals(String.valueOf(fieldJson.get("formField"))) && ((Integer) fieldJson.get("activityType")) == ActivityType.SIGNATURE){
									if((Integer)fieldJson.get("displayType") != PermissionType.HIDDEN){
										data.add(fieldJson);
									}
								}
							}
						}
					}
				}
				if(formField instanceof ButtonField && ((ButtonField) formField).getActType() == ActivityType.SIGNATURE){
					Map<String, Object> value = formField.toAttributes(doc, runner, user, PermissionType.MODIFY);
					//由于md皮肤和新的h5皮肤需要带上表单编辑器自定义的属性
					if(formField.getOtherPropsAsMap() != null && value != null && !value.isEmpty()) {
						for(String propertyKey:formField.getOtherPropsAsMap().keySet()) {
							if(value.get(propertyKey) == null) {
								value.put(propertyKey,formField.getOtherPropsAsMap().get(propertyKey));
							}
						}
					}
					if((Integer)value.get("displayType") != PermissionType.HIDDEN){
						data.add(value);
					}
				}
			}
			return success("ok", data);
		}
		return success("ok", null);
	}

	/**
	 * 更新金格pdf电子签章
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@PutMapping("/{applicationId}/documents/{docId}/pdfsignature")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "更新金格pdf电子签章", notes = "更新金格pdf电子签章")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "flowDocId",value = "流程文档id",required = false,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "签章信息包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource updatePdfSignature(@PathVariable String applicationId, @PathVariable String docId, @RequestParam(required = false) String flowDocId, @RequestBody  String content) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null){
			net.sf.json.JSONObject signatureData = net.sf.json.JSONObject.fromObject(content);
			signatureData.put("userId", getUser().getId());
			signatureData.put("signatureNum", 1);

			if(!StringUtil.isBlank(flowDocId)){
				Document flowDoc = (Document) process.doView(flowDocId);
				if(flowDoc != null){
					FlowStateRT instance = flowDoc.getState();
					if(instance != null){
						BillDefiVO flowVO = instance.getFlowVO();
						String currNodeId = null;
						FlowDiagram fd = null;
						if (flowVO != null) {
							NodeRT nodert = null;
							fd = flowVO.toFlowDiagram();
							if (instance.isTemp()) {
								nodert = ((List<NodeRT>) instance.getNoderts()).get(0);
								currNodeId = nodert.getNodeid();
							}

							if (currNodeId == null && nodert == null) {
								nodert = StateMachine.getCurrUserNodeRT(flowDoc, getUser(), currNodeId);
								if (nodert != null)
									currNodeId = nodert.getNodeid();
							}
						}
						// 获取当前结点
						Node currnode = null;
						if (currNodeId != null) {
							currnode = (Node) fd.getElementByID(currNodeId);
							signatureData.put("nodeId", currnode.id);
							signatureData.put("statelabel", currnode.statelabel);
						}
					}
				}
			} else {
				FlowStateRT instance = doc.getState();
				if(instance != null){
					BillDefiVO flowVO = instance.getFlowVO();
					String currNodeId = null;
					FlowDiagram fd = null;
					if (flowVO != null) {
						NodeRT nodert = null;
						fd = flowVO.toFlowDiagram();
						if (instance.isTemp()) {
							nodert = ((List<NodeRT>) instance.getNoderts()).get(0);
							currNodeId = nodert.getNodeid();
						}

						if (currNodeId == null && nodert == null) {
							nodert = StateMachine.getCurrUserNodeRT(doc, getUser(), currNodeId);
							if (nodert != null)
								currNodeId = nodert.getNodeid();
						}
					}
					// 获取当前结点
					Node currnode = null;
					if (currNodeId != null) {
						currnode = (Node) fd.getElementByID(currNodeId);
						signatureData.put("nodeId", currnode.id);
						signatureData.put("statelabel", currnode.statelabel);
					}
				}
			}

			if(!StringUtil.isBlank(doc.getKinggridSignature())){
				net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());

				Object versionObj = kinggridSignature.get("version");
				if(versionObj != null){
					int version = (int) versionObj;
					kinggridSignature.put("version", ++version);
				} else {
					kinggridSignature.put("version", 1);
				}

				Object pdfSignature = kinggridSignature.get("pdfSignature");
				if(pdfSignature != null){
					net.sf.json.JSONObject pdfSignatureJson = (net.sf.json.JSONObject) pdfSignature;
					Object signatures = pdfSignatureJson.get("signatures");
					if(signatures != null){
						net.sf.json.JSONObject signaturesJson = (net.sf.json.JSONObject) signatures;
						Object data = signaturesJson.get("data");
						if(data != null){
							JSONArray dataArr = (JSONArray) data;
							signatureData.put("signatureNum", dataArr.size() + 1);
							dataArr.add(signatureData);
							signaturesJson.put("data", dataArr);
						} else {
							JSONArray dataArr = new JSONArray();
							dataArr.add(signatureData);
							signaturesJson.put("data", dataArr);
						}
						pdfSignatureJson.put("signatures", signaturesJson);
					} else {
						net.sf.json.JSONObject signaturesJson = new net.sf.json.JSONObject();
						JSONArray dataArr = new JSONArray();
						dataArr.add(signatureData);
						signaturesJson.put("data", dataArr);
						pdfSignatureJson.put("signatures", signaturesJson);
					}
					kinggridSignature.put("pdfSignature", pdfSignatureJson);
				} else {
					net.sf.json.JSONObject pdfSignatureJson = new net.sf.json.JSONObject();
					net.sf.json.JSONObject signaturesJson = new net.sf.json.JSONObject();
					JSONArray dataArr = new JSONArray();
					dataArr.add(signatureData);
					signaturesJson.put("data", dataArr);
					pdfSignatureJson.put("signatures", signaturesJson);
					kinggridSignature.put("pdfSignature", pdfSignatureJson);
				}
				doc.setKinggridSignature(kinggridSignature.toString());
			}
			process.doUpdate(doc);
			//更新缓存
			Document document = (Document)MemoryCacheUtil.getFromPrivateSpace(docId, getUser());
			document.setKinggridSignature(doc.getKinggridSignature());
			MemoryCacheUtil.putToPrivateSpace(docId, document, getUser());
			return success("ok", null);
		}
		return success("ok", null);
	}

	/**
	 * 获取需要删除的金格pdf电子签章数量统计
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/documents/{docId}/deletedpdfsignature")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取需要删除的金格pdf电子签章数量统计", notes = "获取需要删除的金格pdf电子签章数量统计")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string")
	})
	public Resource getDeleteSignatures(@PathVariable String applicationId, @PathVariable String docId) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null){
			if(!StringUtil.isBlank(doc.getKinggridSignature())){
				net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
				Object pdfSignature = kinggridSignature.get("pdfSignature");
				if(pdfSignature != null){
					net.sf.json.JSONObject pdfSignatureJson = (net.sf.json.JSONObject) pdfSignature;
					Object signatures = pdfSignatureJson.get("signatures");
					if(signatures != null){
						net.sf.json.JSONObject signaturesJson = (net.sf.json.JSONObject) signatures;
						Object data = signaturesJson.get("data");
						if(data != null){
							JSONArray dataArr = (JSONArray) data;

							int count = 0;
							Iterator iterator = dataArr.iterator();
							//计算需要删除的签章个数，因为金格那边只能删除最后一个签章
							while(iterator.hasNext()){
								net.sf.json.JSONObject signature = (net.sf.json.JSONObject)iterator.next();
								Object isSignatureObj = signature.get("isSignature");
								if(isSignatureObj != null){
									boolean isSignature = signature.getBoolean("isSignature");
									if(isSignature){
										count++;
									}
								} else {
									count++;
								}
							}
							return success("ok", count);
						}
					}
				}
			}
			return success("ok", null);
		}
		return success("ok", null);
	}

	/**
	 * 删除金格pdf电子签章信息
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@DeleteMapping("/{applicationId}/documents/{docId}/pdfsignature")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "删除金格pdf电子签章信息", notes = "删除金格pdf电子签章信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string")
	})
	public Resource deleteSignatures(@PathVariable String applicationId, @PathVariable String docId) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null){
			if(!StringUtil.isBlank(doc.getKinggridSignature())){
				net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
				Object pdfSignature = kinggridSignature.get("pdfSignature");
				if(pdfSignature != null){
					net.sf.json.JSONObject pdfSignatureJson = (net.sf.json.JSONObject) pdfSignature;
					Object signatures = pdfSignatureJson.get("signatures");
					if(signatures != null){
						net.sf.json.JSONObject signaturesJson = (net.sf.json.JSONObject) signatures;
						Object data = signaturesJson.get("data");
						if(data != null){
							JSONArray dataArr = (JSONArray) data;
							//记录需要删除的签章信息个数，除了标记为不是签章的
							int count = 0;
							Iterator iterator = dataArr.iterator();
							while(iterator.hasNext()){
								net.sf.json.JSONObject signature = (net.sf.json.JSONObject)iterator.next();
								Object isSignatureObj = signature.get("isSignature");
								int signatureNum = signature.getInt("signatureNum");
								if(isSignatureObj != null){
									boolean isSignature = signature.getBoolean("isSignature");
									if(isSignature){
										if(signatureNum > count){
											count = signatureNum;
										}
									}
								} else {
									if(signatureNum > count){
										count = signatureNum;
									}
								}
							}
							iterator = dataArr.iterator();
							while(iterator.hasNext()){
								net.sf.json.JSONObject signature = (net.sf.json.JSONObject)iterator.next();
								int signatureNum = signature.getInt("signatureNum");
								if(signatureNum >= count){
									iterator.remove();
								}
							}
							signaturesJson.put("data", dataArr);
							pdfSignatureJson.put("signatures", signaturesJson);
							kinggridSignature.put("pdfSignature", pdfSignatureJson);
							doc.setKinggridSignature(kinggridSignature.toString());
							process.doUpdate(doc);

							Document document = (Document)MemoryCacheUtil.getFromPrivateSpace(docId, getUser());
							document.setKinggridSignature(doc.getKinggridSignature());
							MemoryCacheUtil.putToPrivateSpace(docId, document, getUser());
							return success("ok", "删除成功！");
						}
					}
				}
			}
			return success("ok", null);
		}
		return success("ok", null);
	}

	/**
	 * 获取PDF签章的相关信息，pdfUrl和按钮
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/{applicationId}/documents/pdfsignatures")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取PDF签章的相关信息，pdfUrl和按钮", notes = "获取PDF签章的相关信息，pdfUrl和按钮")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "请求包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource getSignatureDatas(@PathVariable String applicationId, @RequestBody String content) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		ParamsTable params = getParams();
		WebUser user = getUser();

		Map<String, Object> result = new HashMap<String, Object>();
		//签章pdf路径集合
		List<String> pdfUrls = new ArrayList<String>();
		//签章按钮对象数据
		List<Map<String, Object>> acts = new ArrayList<Map<String, Object>>();
		//签章按钮名字和对应类型
		net.sf.json.JSONObject actJson = new net.sf.json.JSONObject();
		//需要签章文档id集合
		List<String> ids = cn.myapps.util.json.JsonTmpUtil.fromObject(content);
		for (String id : ids) {
			Document doc = (Document) process.doView(id);
			if(doc != null){
				Form form = doc.getForm();
				doc = form.recalculateDocument(doc, params, user);
				IRunner runner = JavaScriptFactory.getInstance(user.getSessionid(), applicationId);
				runner.initBSFManager(doc, params, user, new ArrayList<ValidateMessage>());

				Collection<FormField> fields = form.getFields();
				for (FormField formField : fields) {
					if(formField instanceof TabField){
						Map<String, Object> value = formField.toAttributes(doc, runner, user, PermissionType.MODIFY);
						com.alibaba.fastjson.JSONObject allTabFieldJson = new  com.alibaba.fastjson.JSONObject();
						List<com.alibaba.fastjson.JSONObject> tabs = (ArrayList<com.alibaba.fastjson.JSONObject>)value.get("tabs");
						for (Iterator<com.alibaba.fastjson.JSONObject> tabIterator = tabs.iterator(); tabIterator.hasNext();){
							com.alibaba.fastjson.JSONObject tab = tabIterator.next();
							Object tabFieldsObj = tab.get("fields");
							if(tabFieldsObj != null){
								Collection tabFields = (ArrayList)tab.get("fields");
								for (Iterator tabFieldIterator = tabFields.iterator();tabFieldIterator.hasNext();){
									Map fieldJson = (HashMap)tabFieldIterator.next();
									if("ButtonField".equals(String.valueOf(fieldJson.get("formField"))) && ((Integer) fieldJson.get("activityType")) == ActivityType.SIGNATURE){
										if((Integer)fieldJson.get("displayType") != PermissionType.HIDDEN){
											String actNmae = (String) fieldJson.get("title");
											String signatureAction = (String)fieldJson.get("signatureAction");
											Object signatureActionObj = actJson.get(actNmae);
											if(signatureActionObj != null){
												if(!signatureAction.equals((String)signatureActionObj)){
													actJson.put(actNmae, signatureAction);
													acts.add(fieldJson);
												}
											} else {
												actJson.put(actNmae, signatureAction);
												acts.add(fieldJson);
											}
										}
									}
								}
							}
						}
					}
					if(formField instanceof ButtonField && ((ButtonField) formField).getActType() == ActivityType.SIGNATURE){
						Map<String, Object> value = formField.toAttributes(doc, runner, user, PermissionType.MODIFY);
						//由于md皮肤和新的h5皮肤需要带上表单编辑器自定义的属性
						if(formField.getOtherPropsAsMap() != null && value != null && !value.isEmpty()) {
							for(String propertyKey:formField.getOtherPropsAsMap().keySet()) {
								if(value.get(propertyKey) == null) {
									value.put(propertyKey,formField.getOtherPropsAsMap().get(propertyKey));
								}
							}
						}
						if((Integer)value.get("displayType") != PermissionType.HIDDEN){
							String actNmae = (String) value.get("title");
							String signatureAction = (String)value.get("signatureAction");
							Object signatureActionObj = actJson.get(actNmae);
							if(signatureActionObj != null){
								if(!signatureAction.equals((String)signatureActionObj)){
									acts.add(value);
									actJson.put(actNmae, signatureAction);
								}
							} else {
								acts.add(value);
								actJson.put(actNmae, signatureAction);
							}
						}
					}
				}

				String kinggridSignature = doc.getKinggridSignature();
				if (!StringUtil.isBlank(kinggridSignature)) {
					net.sf.json.JSONObject kinggridSignatureJson = net.sf.json.JSONObject.fromObject(kinggridSignature);
					Object pdfSignature = kinggridSignatureJson.get("pdfSignature");
					if (pdfSignature != null) {
						net.sf.json.JSONObject pdfSignatureJson = (net.sf.json.JSONObject) pdfSignature;
						String pdfUrl = pdfSignatureJson.getString("pdfUrl");
						pdfUrls.add(pdfUrl);
					}
				}
			}
		}
		result.put("pdfUrls", pdfUrls);
		result.put("acts", acts);
		return success("ok", result);
	}

	/**
	 * 批量金格PDF电子签章
	 * @param content
	 * 		请求包体
	 * @return
	 * @throws Exception
	 */
	@PutMapping("/{applicationId}/documents/pdfsignatures/batch")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "批量金格PDF电子签章", notes = "批量金格PDF电子签章")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "请求包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource batchSignature(@PathVariable String applicationId,  @RequestBody String content) throws Exception {
		ParamsTable params = getParams();
		WebUser user = getUser();
		net.sf.json.JSONObject json =  net.sf.json.JSONObject.fromObject(content);
		String option = json.getString("option");
		String path = PropertyUtil.getPath();

		String resouces = path + File.separator + "resouces";
		String result = path + File.separator + "result";
		//String key = path + File.separator + "iSignature.key";

		if("calculateHash".equals(option)){
			String keysn = json.getString("keysn");
			String orgname = json.getString("orgname");
			List<String> ids = json.getJSONArray("ids");
			String position = json.getString("position");

			net.sf.json.JSONObject sealObj = json.getJSONObject("seal");
			String imgdata = sealObj.getString("imgdata");
			double width = sealObj.getDouble("width");
			double height = sealObj.getDouble("height");
			String imgext = sealObj.getString("imgext");
			String signsn = sealObj.getString("signsn");
			String signname = sealObj.getString("signname");
			String username = sealObj.getString("username");

			KGBase64 bas64 = new KGBase64();
			bas64.setBase64Table(signsn);
			byte[] imgb = bas64.decode(imgdata.substring(65));


			File resoucesFile = new File(resouces);
			String[] fileNames = resoucesFile.list();
			JSONArray array = new JSONArray();
			DocumentProcess dProcess = RunTimeServiceManager.documentProcess(applicationId);
			for(String id : ids){
				Document doc = (Document) dProcess.doView(id);
				Form form = doc.getForm();
				doc = form.recalculateDocument(doc, params, user);

				if(!StringUtil.isBlank(doc.getKinggridSignature())) {
					net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
					Object pdfSignature = kinggridSignature.get("pdfSignature");
					if (pdfSignature != null) {
						net.sf.json.JSONObject pdfSignatureJson = (net.sf.json.JSONObject) pdfSignature;
						Object pdfUrlObj = pdfSignatureJson.get("pdfUrl");
						if(pdfUrlObj != null){
							//是否需要签章
							boolean isSignature = false;
							IRunner runner = JavaScriptFactory.getInstance(user.getSessionid(), applicationId);
							runner.initBSFManager(doc, params, user, new ArrayList<ValidateMessage>());
							//当前节点需要签章的按钮位置
							Collection<FormField> fields = form.getFields();
							for (FormField formField : fields) {
								if(formField instanceof TabField){
									Map<String, Object> value = formField.toAttributes(doc, runner, user, PermissionType.MODIFY);
									com.alibaba.fastjson.JSONObject allTabFieldJson = new  com.alibaba.fastjson.JSONObject();
									List<com.alibaba.fastjson.JSONObject> tabs = (ArrayList<com.alibaba.fastjson.JSONObject>)value.get("tabs");
									for (Iterator<com.alibaba.fastjson.JSONObject> tabIterator = tabs.iterator(); tabIterator.hasNext();){
										com.alibaba.fastjson.JSONObject tab = tabIterator.next();
										Object tabFieldsObj = tab.get("fields");
										if(tabFieldsObj != null){
											Collection tabFields = (ArrayList)tab.get("fields");
											for (Iterator tabFieldIterator = tabFields.iterator();tabFieldIterator.hasNext();){
												Map fieldJson = (HashMap)tabFieldIterator.next();
												if("ButtonField".equals(String.valueOf(fieldJson.get("formField"))) && ((Integer) fieldJson.get("activityType")) == ActivityType.SIGNATURE){
													if((Integer)fieldJson.get("displayType") != PermissionType.HIDDEN){
														String actNmae = (String) fieldJson.get("title");
														String signatureAction = (String)fieldJson.get("signatureAction");
														if(position.equals(actNmae)){
															isSignature = true;
															break;
														}
													}
												}
											}
										}
									}
								}
								if(formField instanceof ButtonField && ((ButtonField) formField).getActType() == ActivityType.SIGNATURE){
									Map<String, Object> value = formField.toAttributes(doc, runner, user, PermissionType.MODIFY);
									//由于md皮肤和新的h5皮肤需要带上表单编辑器自定义的属性
									if(formField.getOtherPropsAsMap() != null && value != null && !value.isEmpty()) {
										for(String propertyKey:formField.getOtherPropsAsMap().keySet()) {
											if(value.get(propertyKey) == null) {
												value.put(propertyKey,formField.getOtherPropsAsMap().get(propertyKey));
											}
										}
									}
									if((Integer)value.get("displayType") != PermissionType.HIDDEN){
										String actNmae = (String) value.get("title");
										String signatureAction = (String)value.get("signatureAction");
										if(position.equals(actNmae)){
											isSignature = true;
											break;
										}
									}
								}
							}
							if(isSignature){
								String pdfUrl = (String) pdfUrlObj;
								KGPdfHummer hummer = null;
								FileOutputStream fileOutputStream = null;
								String fileName = pdfUrl.substring(pdfUrl.lastIndexOf("/") + 1);
								String newFileName = "temp_" + fileName;
								String newPdfUrl = pdfUrl.replace(fileName, newFileName);
								try{
									fileOutputStream = new FileOutputStream(path + newPdfUrl);
									hummer = KGPdfHummer.createInstance(path + pdfUrl, null, true, fileOutputStream,true);

									PdfElectronicSeal4KG pdfElectronicSeal4KG = new PdfElectronicSeal4KG(null,0,null);
									pdfElectronicSeal4KG.setImage(imgb, imgext.substring(1), (int)(width * 7200F/254F), (int)(height * 7200F/254F));
									pdfElectronicSeal4KG.setSealMsg(keysn, orgname, username, signsn, signname);
									pdfElectronicSeal4KG.setPagen(0);
									pdfElectronicSeal4KG.setText(position, false);

									ElectronicSignatureByKey electronicSignatureByKey = new ElectronicSignatureByKey();
									pdfElectronicSeal4KG.addExtraExecute(electronicSignatureByKey);

									hummer.addExecute(pdfElectronicSeal4KG);
									hummer.doExecute();

									String needSigMessage = electronicSignatureByKey.getHash();
									String sigKeepData = electronicSignatureByKey.getKeepData();


									net.sf.json.JSONObject obj = new net.sf.json.JSONObject();
									obj.put("needSigMessage", needSigMessage);
									obj.put("sigKeepData", sigKeepData);
									obj.put("fileName",pdfUrl);
									array.add(obj);
									try {
										if(fileOutputStream != null) fileOutputStream.close();
									} catch (IOException e) {
									}
									if(hummer != null) hummer.close();
								} catch (Exception e) {
									e.printStackTrace();
								} finally {
									try {
										if(fileOutputStream != null) fileOutputStream.close();
									} catch (IOException e) {
									}
									if(hummer != null) hummer.close();
								}
								File oldFile = new File(path + pdfUrl);
								oldFile.delete();
								File newFile = new File(path + newPdfUrl);
								newFile.renameTo(oldFile);

								updateSignatureData(position, doc, user, dProcess);
							}
						}
					}
				}
			}
			return success("ok", array);
		} else if("rewriteSigned".equals(option)){
			String certContext = json.getString("certContext");

			JSONArray array = json.getJSONArray("data");
			for(int i=0;i<array.size();i++){
				net.sf.json.JSONObject obj = array.getJSONObject(i);
				String fileName = obj.getString("fileName");
				String sigKeepData = obj.getString("sigKeepData");
				String certSignMsg = obj.getString("certSignMsg");

				KGPdfHummer hummer = null;
				FileOutputStream  fileOutputStream = null;
				try{
					fileOutputStream = new FileOutputStream(result + File.separator + fileName);
					hummer = KGPdfHummer.createInstance(result + File.separator + "tmp_" + fileName, null, true, fileOutputStream,true);

					ElectronicSignatureByKey electronicSignatureByKey = new ElectronicSignatureByKey();
					electronicSignatureByKey.setKeepData(sigKeepData);
					//electronicSignatureByKey.setSig(certSignMsg, certContext);

					hummer.addExecute(electronicSignatureByKey.getRewriteSig());
					hummer.doExecute();
				} catch (Exception e) {


					e.printStackTrace();
					return error(40001, e.getMessage(), null);
				} finally {
					try {
						if(fileOutputStream != null) fileOutputStream.close();
					} catch (IOException e) {
					}
					if(hummer != null) hummer.close();
					new File(result + File.separator + "tmp_" + fileName).delete();
				}
			}
			return success("ok", array);
		}
		return success("ok", "签名成功！");
	}

	/**
	 * 获取金格pdf电子签章的版本号
	 * @param applicationId
	 * 		软件id
	 * @param docId
	 * 		文档id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/{applicationId}/documents/{docId}/pdfsignature/version")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取金格pdf电子签章的版本号", notes = "获取金格pdf电子签章的版本号")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "docId",value = "文档id",required = true,paramType = "path",dataType = "string")
	})
	public Resource getSignatureVersion(@PathVariable String applicationId, @PathVariable String docId) throws Exception {
		DocumentProcess process = RunTimeServiceManager.documentProcess(applicationId);
		Document doc = (Document) process.doView(docId);
		if(doc != null){
			if(!StringUtil.isBlank(doc.getKinggridSignature())){
				net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
				Object version = kinggridSignature.get("version");
				return success("ok", version);
			}
			return success("ok", null);
		}
		return success("ok", null);
	}

	/**
	 * 更新金格PDF签章kinggridsignature字段信息
	 * @param position
	 * 		签章位置
	 * @param doc
	 * 		当前文档
	 * @param user
	 * 		当前登录用户
	 * @param process
	 * 		文档服务类
	 * @return
	 * @throws Exception
	 */
	private void updateSignatureData(String position, Document doc, WebUser user, DocumentProcess process) throws Exception{
		net.sf.json.JSONObject signatureData = new net.sf.json.JSONObject();
		signatureData.put("position", position);
		signatureData.put("userId", user.getId());
		signatureData.put("signatureNum", 1);

		FlowStateRT instance = doc.getState();
		if(instance != null){
			BillDefiVO flowVO = instance.getFlowVO();
			String currNodeId = null;
			FlowDiagram fd = null;
			if (flowVO != null) {
				NodeRT nodert = null;
				fd = flowVO.toFlowDiagram();
				if (instance.isTemp()) {
					nodert = ((List<NodeRT>) instance.getNoderts()).get(0);
					currNodeId = nodert.getNodeid();
				}

				if (currNodeId == null && nodert == null) {
					nodert = StateMachine.getCurrUserNodeRT(doc, user, currNodeId);
					if (nodert != null)
						currNodeId = nodert.getNodeid();
				}
			}
			// 获取当前结点
			Node currnode = null;
			if (currNodeId != null) {
				currnode = (Node) fd.getElementByID(currNodeId);
				signatureData.put("nodeId", currnode.id);
				signatureData.put("statelabel", currnode.statelabel);
			}
		}

		if(!StringUtil.isBlank(doc.getKinggridSignature())){
			net.sf.json.JSONObject kinggridSignature = net.sf.json.JSONObject.fromObject(doc.getKinggridSignature());
			Object pdfSignature = kinggridSignature.get("pdfSignature");
			if(pdfSignature != null){
				net.sf.json.JSONObject pdfSignatureJson = (net.sf.json.JSONObject) pdfSignature;
				Object signatures = pdfSignatureJson.get("signatures");
				if(signatures != null){
					net.sf.json.JSONObject signaturesJson = (net.sf.json.JSONObject) signatures;
					Object data = signaturesJson.get("data");
					if(data != null){
						JSONArray dataArr = (JSONArray) data;
						signatureData.put("signatureNum", dataArr.size() + 1);
						dataArr.add(signatureData);
						signaturesJson.put("data", dataArr);
					} else {
						JSONArray dataArr = new JSONArray();
						dataArr.add(signatureData);
						signaturesJson.put("data", dataArr);
					}
					pdfSignatureJson.put("signatures", signaturesJson);
				} else {
					net.sf.json.JSONObject signaturesJson = new net.sf.json.JSONObject();
					JSONArray dataArr = new JSONArray();
					dataArr.add(signatureData);
					signaturesJson.put("data", dataArr);
					pdfSignatureJson.put("signatures", signaturesJson);
				}
				kinggridSignature.put("pdfSignature", pdfSignatureJson);
			} else {
				net.sf.json.JSONObject pdfSignatureJson = new net.sf.json.JSONObject();
				net.sf.json.JSONObject signaturesJson = new net.sf.json.JSONObject();
				JSONArray dataArr = new JSONArray();
				dataArr.add(signatureData);
				signaturesJson.put("data", dataArr);
				pdfSignatureJson.put("signatures", signaturesJson);
				kinggridSignature.put("pdfSignature", pdfSignatureJson);
			}
			doc.setKinggridSignature(kinggridSignature.toString());
		} else {
			net.sf.json.JSONObject kinggridSignature = new net.sf.json.JSONObject();
			net.sf.json.JSONObject pdfSignatureJson = new net.sf.json.JSONObject();
			net.sf.json.JSONObject signaturesJson = new net.sf.json.JSONObject();
			JSONArray dataArr = new JSONArray();
			dataArr.add(signatureData);
			signaturesJson.put("data", dataArr);
			pdfSignatureJson.put("signatures", signaturesJson);
			kinggridSignature.put("pdfSignature", pdfSignatureJson);
			doc.setKinggridSignature(kinggridSignature.toString());
		}
		process.doUpdate(doc);
		//更新缓存
		Document document = (Document)MemoryCacheUtil.getFromPrivateSpace(doc.getId(), user);
		document.setKinggridSignature(doc.getKinggridSignature());
		MemoryCacheUtil.putToPrivateSpace(doc.getId(), document, user);
	}
}
