package com.blueland.bpm.manage.web;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.blueland.bpm.application.model.ApplicationEntity;
import com.blueland.bpm.application.service.ApplicationManager;
import com.blueland.bpm.common.page.Page;
import com.blueland.bpm.common.util.DateUtil;
import com.blueland.bpm.common.util.ServiceResponse;
import com.blueland.bpm.engine.config.model.ProcessInfoConfig;
import com.blueland.bpm.engine.config.model.SysGlType;
import com.blueland.bpm.engine.config.service.ProcessInfoConfigManager;
import com.blueland.bpm.engine.config.service.SysGlTypeManager;
import com.blueland.bpm.engine.core.model.*;
import com.blueland.bpm.engine.core.service.ProcessConfigService;
import com.blueland.bpm.engine.core.service.ProcessDefinitionService;
import com.blueland.bpm.engine.core.service.ProcessModelService;
import com.blueland.bpm.engine.core.service.ProcessTraceService;
import com.blueland.bpm.engine.core.service.impl.ProcessModelNewService;
import com.blueland.bpm.engine.util.*;
import com.blueland.bpm.identity.OrgService;
import com.blueland.bpm.identity.RoleService;
import com.blueland.bpm.identity.UserService;
import com.blueland.bpm.identity.model.Org;
import com.blueland.bpm.identity.model.Role;
import com.blueland.bpm.identity.model.User;
import com.blueland.bpm.manage.config.web.ProcDefTreeManager;
import com.blueland.bpm.manage.service.AgainSaveSessionService;
import com.blueland.bpm.manage.util.TreeNode;
import com.blueland.bpm.manage.util.*;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.ReadOnlyProcessDefinition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.validation.ProcessValidator;
import org.activiti.validation.ProcessValidatorFactory;
import org.activiti.validation.ValidationError;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

@Controller
@RequestMapping(value = "/procDefModelMgr")
public class ProcessDefModelController extends BaseProcessController {
	@Autowired
	private ProcessInfoConfigManager processInfoConfigManager;
	@Autowired
	private ProcessDefinitionService processDefinitionService;
	@Autowired
	private ProcessConfigService processConfigService;
	@Autowired
	private ProcessModelNewService processModelNewService;
	@Autowired
	private ProcessModelService processModelService;
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	CustomProcessValidator customProcessValidator;
	@Autowired
	ProcDefTreeManager procDefTreeManager;
	@Autowired
	private SysGlTypeManager sysGlTypeManager;
	@Autowired
	private UserService userService;
	@Autowired
	private OrgService orgService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private AgainSaveSessionService againSaveSessionService;
	@Autowired
	private ProcessTraceService processTraceService;
	@Autowired
	private ApplicationManager applicationManager;
	protected Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 流程配置以及建模
	 * 
	 * @param userId
	 * @param query
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/list_dev")
	public ModelAndView list_dev(String appId, ProcessInfoConfig query, HttpServletRequest request,
			HttpServletResponse response) {
		// 把session重新保存
		if (StringUtils.isNotEmpty(appId)) {
			againSaveSessionService.saveSession(appId, request, response);
		}
		SysGlType sysGlType = new SysGlType();
		sysGlType.setTypeParentId("TOP_FLOW_TYPE");
		sysGlType.setAppKey((String) request.getSession().getAttribute(MyContants.APP_ID_KEY));
		List<SysGlType> sysGlTypes = sysGlTypeManager.findByExample(sysGlType);
		query.setSortColumns("CREATE_TIME desc");
		if ("true".equalsIgnoreCase(MyContants.IS_OPEN_TENANT)) {
			query.setTenantId(BaseUser.getInstance().getLoginUserAppId(request));
		}
		query.setProcessMgrIsshow(null);
		Page<List<ProcessInfoConfig>> page = processConfigService.findProcessConfigAndModel(query);
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/list_dev");
		modelAndView.addAllObjects(toModelMap(page, query));
		modelAndView.addObject("sysGlTypes", sysGlTypes);
		modelAndView.addObject("modelKey", request.getParameter("modelKey"));
		modelAndView.addObject("modelName", request.getParameter("modelName"));
		modelAndView.addObject("appId", appId);
		return modelAndView;
	}

	/**
	 * 查看流程图
	 * 
	 * @param procDefId
	 * @param resourceType
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/resource")
	public void resource(String procDefKey, String procDefId, String resourceType, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		if (StringUtils.isEmpty(procDefId)) {
			ProcessDefinitionModel model = processDefinitionService.getProcessDefBykey(procDefKey);
			if (model != null)
				procDefId = model.getProcDefId();
		}

		InputStream in = processDefinitionService.loadProcessResource(procDefId, resourceType);
		OutputStream out = response.getOutputStream();
		try {

			org.apache.commons.io.IOUtils.copy(in, out);
			response.flushBuffer();
		} catch (Exception e) {
			logger.error("", e);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				logger.error("", e);
			}
		}

	}

	/**
	 * 导出 流程清单 excel
	 * 
	 * 
	 */
	@RequestMapping(value = "/export")
	public void export(HttpServletRequest request, HttpServletResponse response) {
		SearchProcessListDTO params = new SearchProcessListDTO();
		params.setTenantId(BaseUser.getInstance().getLoginUserAppId(request));
		System.out.println("租户ID:" + BaseUser.getInstance().getLoginUserAppId(request));
		List<ProcessDefinitionModel> defs = processDefinitionService.findProcessDefs(params);
		List<ReadOnlyProcessDefinition> rpdf = new ArrayList<ReadOnlyProcessDefinition>();

		for (int i = 0; i < defs.size(); i++) {
			RepositoryServiceImpl repositoryServiceImpl = (org.activiti.engine.impl.RepositoryServiceImpl) repositoryService;
			ReadOnlyProcessDefinition rpd = repositoryServiceImpl
					.getDeployedProcessDefinition(defs.get(i).getProcDefId());
			if (rpd == null) {
				System.out.println("流程模型出现异常，pdf:" + defs.get(i));
				continue;
			}
			rpdf.add(rpd);
		}

		String url = request.getServletContext().getRealPath("/");
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String exls = url + "/file/";
		String name = "流程清单" + "_" + df.format(new Date()) + ".xls";
		String path = exls.replace("/", File.separator);
		File file = new File(exls);
		if (!file.exists()) {
			file.mkdirs();
		}
		XLSExportUtil exportUtil = new XLSExportUtil(name, path);
		exportUtil.removeSheetAt(0);
		String[] sheet1 = { "流程定义ID", "流程KEY", "流程名称", "应用" };
		// 第一个sheet
		ProcessDefSheet(exportUtil, "流程定义", sheet1, defs);

		String[] sheet2 = { "流程定义ID", "流程KEY", "流程名称", "环节ID", "环节名称", "应用" };
		// 第二个sheet
		ReadOnlyProcessSheet(exportUtil, "流程环节", sheet2, defs, rpdf);

		// 第三个sheet
		String[] sheet3 = { "流程定义ID", "流程KEY", "流程名称", "环节ID", "环节名称", "资源类型", "资源ID", "应用" };
		ActivityResourceSheet(exportUtil, "流程资源", sheet3, defs, rpdf);

		response.setContentType("application/vnd.ms-excel");

		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			exportUtil.exportXLS();
			response.setHeader("Content-disposition",
					"attachment;filename=" + new String(name.getBytes(), "iso-8859-1"));

			FileInputStream is = new FileInputStream(exls + name);
			ServletOutputStream out = response.getOutputStream();
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(out);
			byte[] buff = new byte[2048];
			int bytesRead;
			// Simple read/write loop.
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
			bis.close();
			bos.close();
		} catch (Exception e) {

			e.printStackTrace();
		}

	}

	/**
	 * 导出 流程清单 excel
	 * 
	 * 
	 */
	@RequestMapping(value = "/allExport")
	public void allExport(HttpServletRequest request, HttpServletResponse response) {
		SearchProcessListDTO params = new SearchProcessListDTO();
		List<ProcessDefinitionModel> defs = processDefinitionService.findProcessDefs(params);
		List<ReadOnlyProcessDefinition> rpdf = new ArrayList<ReadOnlyProcessDefinition>();

		for (int i = 0; i < defs.size(); i++) {
			RepositoryServiceImpl repositoryServiceImpl = (org.activiti.engine.impl.RepositoryServiceImpl) repositoryService;
			ReadOnlyProcessDefinition rpd = repositoryServiceImpl
					.getDeployedProcessDefinition(defs.get(i).getProcDefId());
			if (rpd == null) {
				System.out.println("流程模型出现异常，pdf:" + defs.get(i));
				continue;
			}
			rpdf.add(rpd);
		}

		String url = request.getServletContext().getRealPath("/");
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String exls = url + "/file/";
		String name = "流程清单" + "_" + df.format(new Date()) + ".xls";
		String path = exls.replace("/", File.separator);
		File file = new File(exls);
		if (!file.exists()) {
			file.mkdirs();
		}
		XLSExportUtil exportUtil = new XLSExportUtil(name, path);
		exportUtil.removeSheetAt(0);
		String[] sheet1 = { "流程定义ID", "流程KEY", "流程名称", "应用" };
		// 第一个sheet
		ProcessDefSheet(exportUtil, "流程定义", sheet1, defs);

		String[] sheet2 = { "流程定义ID", "流程KEY", "流程名称", "环节ID", "环节名称", "应用" };
		// 第二个sheet
		ReadOnlyProcessSheet(exportUtil, "流程环节", sheet2, defs, rpdf);

		// 第三个sheet
		String[] sheet3 = { "流程定义ID", "流程KEY", "流程名称", "环节ID", "环节名称", "资源类型", "资源ID", "应用" };
		ActivityResourceSheet(exportUtil, "流程资源", sheet3, defs, rpdf);

		response.setContentType("application/vnd.ms-excel");

		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			exportUtil.exportXLS();
			response.setHeader("Content-disposition",
					"attachment;filename=" + new String(name.getBytes(), "iso-8859-1"));

			FileInputStream is = new FileInputStream(exls + name);
			ServletOutputStream out = response.getOutputStream();
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(out);
			byte[] buff = new byte[2048];
			int bytesRead;
			// Simple read/write loop.
			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
				bos.write(buff, 0, bytesRead);
			}
			bis.close();
			bos.close();
		} catch (Exception e) {

			e.printStackTrace();
		}

	}

	public void ProcessDefSheet(XLSExportUtil exportUtil, String sheetName, String[] titles,
			List<ProcessDefinitionModel> defs) {
		int rowNum = 0; // 行数
		int cellNum = 0; // 列数
		exportUtil.createSheet(sheetName); // 新增sheet设置名称
		exportUtil.createRow(rowNum++); // 在sheet中新增一行、展示查询数据——标题
		for (String title : titles) {
			exportUtil.setCell(cellNum++, title);
		}
		for (ProcessDefinitionModel pdf : defs) {
			exportUtil.createRow(rowNum++);
			exportUtil.setCell(0, pdf.getProcDefId());
			exportUtil.setCell(1, pdf.getProcDefKey());
			exportUtil.setCell(2, pdf.getProcDefName());
			exportUtil.setCell(3, pdf.getTenantId());
		}
	}

	public void ReadOnlyProcessSheet(XLSExportUtil exportUtil, String sheetName, String[] titles,
			List<ProcessDefinitionModel> defs, List<ReadOnlyProcessDefinition> rpdf) {
		int rowNum = 0; // 行数
		int cellNum = 0; // 列数
		exportUtil.createSheet(sheetName); // 新增sheet设置名称
		exportUtil.createRow(rowNum++); // 在sheet中新增一行、展示查询数据——标题
		for (String title : titles) {
			exportUtil.setCell(cellNum++, title);
		}
		for (int i = 0; i < defs.size(); i++) {

			List<PvmActivity> actis = (List<PvmActivity>) rpdf.get(i).getActivities();
			for (PvmActivity activity : actis) {
				if (!ProcessDefinitionUtils.isUserTask((ActivityImpl) activity)) {
					continue;
				}
				exportUtil.createRow(rowNum++);
				exportUtil.setCell(0, defs.get(i).getProcDefId());
				exportUtil.setCell(1, defs.get(i).getProcDefKey());
				exportUtil.setCell(2, defs.get(i).getProcDefName());
				exportUtil.setCell(3, activity.getId());
				exportUtil.setCell(4, activity.getProperty("name").toString());
				exportUtil.setCell(5, defs.get(i).getTenantId());
			}

		}
	}

	public void ActivityResourceSheet(XLSExportUtil exportUtil, String sheetName, String[] titles,
			List<ProcessDefinitionModel> defs, List<ReadOnlyProcessDefinition> rpdf) {
		int rowNum = 0; // 行数
		int cellNum = 0; // 列数
		exportUtil.createSheet(sheetName); // 新增sheet设置名称
		exportUtil.createRow(rowNum++); // 在sheet中新增一行、展示查询数据——标题
		for (String title : titles) {
			exportUtil.setCell(cellNum++, title);
		}
		for (int i = 0; i < defs.size(); i++) {
			List<PvmActivity> actis = (List<PvmActivity>) rpdf.get(i).getActivities();
			for (PvmActivity activity : actis) {
				if (!ProcessDefinitionUtils.isUserTask((ActivityImpl) activity)) {
					continue;
				}
				TaskDefinition taskDefinition = (TaskDefinition) activity.getProperty("taskDefinition");
				Set<Expression> roles = taskDefinition.getCandidateGroupIdExpressions();
				for (Expression roleId : roles) {
					exportUtil.createRow(rowNum++);
					exportUtil.setCell(0, defs.get(i).getProcDefId());
					exportUtil.setCell(1, defs.get(i).getProcDefKey());
					exportUtil.setCell(2, defs.get(i).getProcDefName());
					exportUtil.setCell(3, activity.getId());
					exportUtil.setCell(4, activity.getProperty("name").toString());
					exportUtil.setCell(5, "角色");
					exportUtil.setCell(6, roleId.getExpressionText());
					exportUtil.setCell(7, defs.get(i).getTenantId());
				}
				Set<Expression> orgs = taskDefinition.getCandidateOrgIdExpressions();
				for (Expression orgId : orgs) {
					exportUtil.createRow(rowNum++);
					exportUtil.setCell(0, defs.get(i).getProcDefId());
					exportUtil.setCell(1, defs.get(i).getProcDefKey());
					exportUtil.setCell(2, defs.get(i).getProcDefName());
					exportUtil.setCell(3, activity.getId());
					exportUtil.setCell(4, activity.getProperty("name").toString());
					exportUtil.setCell(5, "组织");
					exportUtil.setCell(6, orgId.getExpressionText());
					exportUtil.setCell(7, defs.get(i).getTenantId());
				}
				Set<Expression> users = taskDefinition.getCandidateUserIdExpressions();
				for (Expression userId : users) {
					exportUtil.createRow(rowNum++);
					exportUtil.setCell(0, defs.get(i).getProcDefId());
					exportUtil.setCell(1, defs.get(i).getProcDefKey());
					exportUtil.setCell(2, defs.get(i).getProcDefName());
					exportUtil.setCell(3, activity.getId());
					exportUtil.setCell(4, activity.getProperty("name").toString());
					exportUtil.setCell(5, "人员");
					exportUtil.setCell(6, userId.getExpressionText());
					exportUtil.setCell(7, defs.get(i).getTenantId());
				}
			}
		}
	}

	/**
	 * 导出流程模型XML
	 * 
	 * @param procDefId
	 * @param resourceType
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/exportProcessResource")
	public void exportProcessResource(String procDefId, String resourceType, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
		InputStream in = processDefinitionService.loadProcessResource(procDefId, resourceType);
		OutputStream out = response.getOutputStream();
		try {
			String filename = processDefinition.getProcDefName() + ".bpmn20.xml";
			response.reset();
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
			response.setContentType("application/octet-stream; charset=utf-8");
			org.apache.commons.io.IOUtils.copy(in, out);
			response.flushBuffer();
		} catch (Exception e) {
			logger.error("", e);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				logger.error("", e);
			}
		}

	}

	/**
	 * 导出所有流程数据包含模型和配置数据
	 * 
	 * @param procDefId
	 * @param resourceType
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/exportProcessAllFile")
	public void exportProcessAllFile(String[] procDefIds, String exportall, String resourceType,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		OutputStream out = response.getOutputStream();
		InputStream in = null;
		ByteArrayOutputStream processModelDataOut = null;
		ByteArrayOutputStream processDataDataOut = null;
		String exportFileName = "";

		ApplicationEntity app = BaseUser.getInstance().getLoginUserApplication(request);
		exportFileName = app.getAppName();

		if ("0".equals(exportall) || ("1".equals(exportall) && procDefIds.length > 1)) {// 导出多个流程文件或者导出全部流程文件生成文件名
			// 导出全部时文件名
			exportFileName = exportFileName + "-" + DateUtil.convertDateToString("yyyyMMddHHmm", new Date()) + "--流程文件";
		}

		try {
			Map<String, byte[]> fileData = new HashMap<String, byte[]>();
			if ("0".equals(exportall)) {// 导出所有
				ProcessInfoConfig params = new ProcessInfoConfig();
				params.setTenantId(BaseUser.getInstance().getLoginUserAppId(request));
				List<String> procDefIdsList = processConfigService.getAllProcessIdForExport(params);
				if (!procDefIdsList.isEmpty()) {
					procDefIds = procDefIdsList.toArray(new String[procDefIdsList.size()]);
				}

			}
			if (null != procDefIds && !"".equals(procDefIds)) {
				for (String procDefId : procDefIds) {
					ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
					if (processDefinition == null) {
						return;
					}
					// 生成导出文件文件名
					if ("1".equals(exportall)) {// 导出单个流程文件
						if (procDefIds.length <= 1) {
							exportFileName = exportFileName + processDefinition.getProcDefName() + "-"
									+ DateUtil.convertDateToString("yyyyMMddHHmm", new Date()) + "-流程文件"+processDefinition.getVersion();
						}
					}

					// 导出流程图
					in = processDefinitionService.loadProcessResource(procDefId, resourceType);
					processModelDataOut = new ByteArrayOutputStream();
					org.apache.commons.io.IOUtils.copy(in, processModelDataOut);
					String processModelfilename = processDefinition.getProcDefKey() + ".bpmn20.xml";

					// 导出流程配置
					processDataDataOut = processConfigService.exportOneProcessData(procDefId);
					String processDataFilename = processDefinition.getProcDefKey() + ".data" + ".xml";

					fileData.put(processModelfilename, processModelDataOut.toByteArray());
					fileData.put(processDataFilename, processDataDataOut.toByteArray());
				}

			}

			response.reset();
			response.setCharacterEncoding("UTF-8");
			// response.setHeader("Content-Disposition", "attachment;
			// filename="+URLEncoder.encode(processDefinition.getProcDefName(),"UTF-8")+".zip");
			response.setHeader("Content-Disposition",
					"attachment; filename=" + URLEncoder.encode(exportFileName, "UTF-8") + ".zip");
			response.setContentType("application/octet-stream; charset=utf-8");

			ProcessZipUtil.zipFiles(fileData, out);
			response.flushBuffer();
		} catch (Exception e) {
			logger.error("导出流程所有资源出现异常,procDefIds:" + procDefIds, e);
		} finally {
			IOUtils.closeQuietly(in);
			IOUtils.closeQuietly(processDataDataOut);
			IOUtils.closeQuietly(processModelDataOut);

		}

	}

	/**
	 * 导入所有流程数据包含模型和配置数据
	 * 
	 * @param procDefId
	 * @param resourceType
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/importProcessAllFile")
	public ModelAndView importProcessAllFile(@RequestParam(value = "file", required = false) MultipartFile file,
			HttpServletRequest request) throws IOException {
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/importProcessConfigData");
		String savetype = request.getParameter("savetype");
		String result = "导入成功";
		try {
			// 每一个流程包含流程图和流程配置文件数据
			Map<String, byte[][]> processAllFile = ProcessZipUtil.unZipFiles(file.getBytes());
			for (Entry<String, byte[][]> processAllFileEntry : processAllFile.entrySet()) {
				byte[][] processByteList = processAllFileEntry.getValue();
				ProcessDefinitionModel processDefinition = deployProcess(processByteList[0],
						processAllFileEntry.getKey(), BaseUser.getInstance().getLoginUserAppId(request), savetype);
				if (processDefinition != null) {
					processConfigService.importOneProcessData(processDefinition.getProcDefId(),
							BaseUser.getInstance().getLoginUserAppId(request), processDefinition.getDeploymentId(),
							new String(processByteList[1], "UTF-8"), "0");
				}
			}
			modelAndView.addObject("flashSuccess", result);
		} catch (Exception e) {
			e.printStackTrace();
			modelAndView.addObject("flashSuccess", "导入流程图及配置文件失败!");
		}

		// 操作日志
		MyContants.saveUserOperate(request, "", true, result, MyContants.LOGIN_SESSION_USER, MyContants.APPLICATION);
		return modelAndView;

	}

	/**
	 * 彻底删除流程定义（可能包含该定义下所有运行流程实例数据）
	 * 
	 * @param procDefId
	 * @param deploymentId
	 * @param cascode
	 * @param request
	 * @param redirectAttributes
	 * @return
	 */
	@RequestMapping(value = "/delete")
	public ModelAndView delete(String procDefId, String deploymentId, boolean cascode, HttpServletRequest request,
			RedirectAttributes redirectAttributes) {
		boolean result = false;
		try {
			ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
			if (processDefinition != null) {
				result = processDefinitionService.delete(procDefId, deploymentId, cascode);
			}
		} catch (Exception e) {
			logger.error("", e);
		}
		redirectAttributes.addFlashAttribute(ACTION_MESSAGE, result ? DELETE_SUCCESS : this.ACTION_ERROR);
		ModelAndView modelAndView = new ModelAndView("redirect:/procDefModelMgr/list_dev.do");
		return modelAndView;
	}

	/**
	 * 删除历史版本界面
	 * 
	 * @param procDefId
	 * @param deploymentId
	 * @param cascode
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/history/delete")
	@ResponseBody
	public Map deleteforhistorypage(String procDefId, String deploymentId, boolean cascode,
			HttpServletRequest request) {
		Map result = new HashMap();
		result.put("success", true);
		try {
			ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
			if (processDefinition != null) {
				ProcessMgrDataShare.setProcessMgrData(WorkFlowContants.PROCESS_DEF_DEL_MANAGE_OPT);
				boolean temp = processDefinitionService.delete(procDefId, deploymentId, cascode);
				ProcessMgrDataShare.clear();
				result.put("success", temp);
			}

			// 根据key获取到所有版本
			List<ProcessDefinitionModel> allVersionList = processDefinitionService
					.findAllVersionProcessDefs(processDefinition.getProcDefKey());
			String returnProcDefId = "";
			if (null != allVersionList && 0 != allVersionList.size()) {
				returnProcDefId = allVersionList.get(0).getProcDefId();
			}
			result.put("returnProcDefId", returnProcDefId);
		} catch (Exception e) {
			logger.error("", e);
			result.put("success", false);
			result.put("reason", e.getMessage());
		}
		MyContants.saveUserOperate(request, "deploymentId;procDefId", (Boolean) result.get("success"),
				result.containsKey("reason") ? result.get("reason").toString() : "", MyContants.LOGIN_SESSION_USER,
				MyContants.APPLICATION);
		return result;
	}

	/**
	 * 导入、部署流程
	 * 
	 * @param file
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/deployFile")
	public ModelAndView deploy(@RequestParam(value = "file", required = false) MultipartFile file,
			HttpServletRequest request) throws IOException {
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/deployProcessFile");
		String fileName = file.getOriginalFilename();
		BpmnModel bpmnModel = null;
		try {
			bpmnModel = this.processModelNewService.convertFileToBpmnModel(new ByteArrayInputStream(file.getBytes()));
		} catch (Exception e) {
			logger.error("", e);
		}
		if (bpmnModel == null) {
			modelAndView.addObject("flashSuccess", "验证bpmn.xml出现异常，非法的bpmn.xml");
			return modelAndView;
		}
		InputStream in = new ByteArrayInputStream(file.getBytes());
		try {
			ProcessDefinitionModel processDefinition = processDefinitionService
					.deploySingleProcess(BaseUser.getInstance().getLoginUserAppId(request), in, fileName);
			if (processDefinition != null) {
				processModelNewService.syncBpmnModelToDb(processDefinition);
				modelAndView.addObject("flashSuccess", "导入成功!");
			}
		} catch (Exception e) {
			logger.error("", e);
			modelAndView.addObject("flashSuccess", "导入失败!");
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				logger.error("", e);
			}
		}
		return modelAndView;
	}

	

	/**
	 * /** 流程配置界面
	 * 
	 * @param userId
	 * @param procDefId
	 * @param request
	 * @param query
	 * @return
	 */
	@RequestMapping(value = "/config")
	public ModelAndView config(String userId, String procDefId, HttpServletRequest request, ProcessInfoConfig query) {
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/config");
		modelAndView.addObject("processDefinition", processDefinition);
		this.saveQueryParams(request, query);
		return modelAndView;
	}
	
	/**
	 * /** 新的流程配置界面
	 * 
	 * @param userId
	 * @param procDefId
	 * @param request
	 * @param query
	 * @return
	 */
	@RequestMapping(value = "/proConfig")
	public ModelAndView proConfig(String userId, String procDefId, HttpServletRequest request, ProcessInfoConfig query) {
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/proConfig");
		modelAndView.addObject("processDefinition", processDefinition);
		this.saveQueryParams(request, query);
		return modelAndView;
	}

	/*
	 * 贯穿流程设置
	 */
	@RequestMapping(value = "/callactivityconfig")
	public ModelAndView callactivityconfig(String userId, String callActivityProcKey, String isSubProcess,
			HttpServletRequest request, ProcessInfoConfig query) {
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDefBykey(callActivityProcKey);
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/config");
		modelAndView.addObject("processDefinition", processDefinition);
		modelAndView.addObject("isSubProcess", isSubProcess);
		this.saveQueryParams(request, query);
		return modelAndView;
	}

	/**
	 * 直接修改、更新流程模型XML
	 * 
	 * @param procDefId
	 * @param bpmnXml
	 * @param request
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping(value = "/updateBpmnFile")
	@ResponseBody
	public String updateBpmnFile(String procDefId, String bpmnXml, HttpServletRequest request)
			throws UnsupportedEncodingException {
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
		byte[] updateBpmnByte = bpmnXml.getBytes("UTF-8");
		List<ValidationError> validationErrors = null;
		try {
			validationErrors = processModelNewService.validateBpmnXml(new ByteArrayInputStream(updateBpmnByte));
		} catch (Exception e) {
			logger.error("", e);
			return "验证bpmn.xml出现异常，非法的bpmn.xml";
		}
		if (!validationErrors.isEmpty()) {
			return validationErrors.toString();
		}
		// 更新bpmn.xml
		processDefinitionService.updateDeploymentResource(processDefinition.getDeploymentId(),
				processDefinition.getProcDefId(), updateBpmnByte, false);
		// 更新流程定义缓存
		processDefinitionService.refreshProcessDefineCache(processDefinition.getProcDefId());
		processModelNewService.syncBpmnModelToDb(processDefinition);
		return this.ACTION_SUCCESS;
	}

	/**
	 * 编辑流程模型XML
	 * 
	 * @param procDefId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/editProcessFile")
	public ModelAndView editProcessFile(String procDefId, HttpServletRequest request) {
		InputStream in = processDefinitionService.loadProcessResource(procDefId, "xml");
		String bpmnXml = "";
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			org.apache.commons.io.IOUtils.copy(in, out);
			bpmnXml = out.toString("UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				logger.error("", e);
			}
		}
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/editProcessFile");
		modelAndView.addObject("bpmnXml", bpmnXml);
		modelAndView.addObject("procDefId", procDefId);
		return modelAndView;
	}

	/**
	 * 将流程定义XML转换成流程模型JSON
	 * 
	 * @param procDefId
	 * @return
	 */
	@RequestMapping(value = "/convert-to-model")
	@ResponseBody
	public String convertToModel(String procDefId) {
		boolean result = processModelNewService.syncProcessModelToJsonModel(procDefId);
		return result ? this.ACTION_SUCCESS : this.ACTION_ERROR;
	}

	/**
	 * 发布流程
	 **/
	@RequestMapping(value = "releaseProcess")
	@ResponseBody
	public String releaseProcess(HttpServletRequest request, String procDefId) {
		ProcessInfoConfig processInfoConfig = processInfoConfigManager.getById(procDefId);
		if (processInfoConfig == null) {
			return "procDefId[" + procDefId + "]无效!";
		}
		/*if (StringUtils.isEmpty(processInfoConfig.getProcessTypeName())) {
			return "流程分类不能为空,请选择流程分类后再发布流程!";
		}*/
		String result = this.ACTION_SUCCESS;
		try {
			String validateMsg = customProcessValidator.validate(procDefId);
			if (!StringUtils.isEmpty(validateMsg)) {
				return ACTION_ERROR + "!" + validateMsg;
			}
			processInfoConfigManager.releaseProcessInfo(processInfoConfig);
			processModelNewService.syncProcessModelToJsonModel(procDefId);
		} catch (Exception e) {
			logger.error("", e);
			result = ACTION_ERROR + e.getMessage();
		}
		return result;
	}

	/**
	 * 保存更新对象
	 **/
	@RequestMapping(value = "unReleaseProcess")
	@ResponseBody
	public String unReleaseProcess(HttpServletRequest request, String procDefId) {
		ProcessInfoConfig processInfoConfig = processInfoConfigManager.getById(procDefId);
		if (processInfoConfig == null) {
			return "procDefId[" + procDefId + "]无效!";
		}
		processInfoConfigManager.unReleaseProcessInfo(processInfoConfig);
		return UPDATE_SUCCESS;
	}

	/**
	 * 导出单独的流程配置数据
	 * 
	 * @param procDefId
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/exportProcessConfigData")
	public void exportProcessConfigData(String procDefId, HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDef(procDefId);
		if (processDefinition == null) {
			return;
		}
		ByteArrayOutputStream dataOut = processConfigService.exportOneProcessData(procDefId);
		OutputStream out = response.getOutputStream();
		String filename = processDefinition.getProcDefName() + "-data" + ".xml";
		try {
			response.reset();
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
			response.setContentType("application/octet-stream; charset=utf-8");
			ByteArrayInputStream in = new ByteArrayInputStream(dataOut.toByteArray());
			IOUtils.copy(in, out);
			response.flushBuffer();
		} catch (Exception e) {
			logger.error("", e);
		} finally {
			try {
				dataOut.close();
			} catch (IOException e) {
				logger.error("", e);
			}
		}

	}

	/**
	 * 导入流程配置数据
	 * 
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/importProcessConfigData")
	public ModelAndView importProcessConfigData(@RequestParam(value = "file", required = false) MultipartFile file,
			HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/importProcessConfigData");
		try {
			ServiceResponse serviceResponse = processConfigService.importOneProcessData("",
					BaseUser.getInstance().getLoginUserAppId(request), "", new String(file.getBytes(), "UTF-8"), "0");
			if (serviceResponse.getStatus().equals(serviceResponse.STATUS_OP_SUCCESS)) {
				modelAndView.addObject("flashSuccess", "导入成功!");
			} else {
				modelAndView.addObject("flashSuccess", "导入失败!");
			}
		} catch (Exception e) {
			logger.error("", e);
			modelAndView.addObject("flashSuccess", "导入失败!");
		}
		return modelAndView;
	}

	/**
	 * 进入更新页面
	 **/
	@RequestMapping(value = "getActivityDefModel")
	@ResponseBody
	public ActivityDefinitionModel getActivityDefModel(HttpServletRequest request, String procDefId, String actDefId) {
		ActivityDefinitionModel activityDefinitionModel = processDefinitionService.getActivity(procDefId, actDefId);

		BpmnModel bpmnModel = processModelNewService.getBpmnModelByProcDefId(procDefId);
		UserTask userTask = ProcessModelUtils.findUserTask(bpmnModel, actDefId);
		List<ActivityResourceModel> activityResources = new ArrayList<ActivityResourceModel>();
		for (String groupId : userTask.getCandidateGroups()) {
			Role role = roleService.getRoleById(groupId);
			ActivityResourceModel actitityResource = new ActivityResourceModel(groupId, "角色",
					role != null ? role.getRoleName() : "<font color='red'>该角色已失效</font>", 0, "ROLE",
					role.getRoleSort());
			actitityResource.setRemark(groupId);
			activityResources.add(actitityResource);
		}
		for (String orgId : userTask.getCandidateOrgs()) {
			Org org = orgService.getOrgById(orgId);
			ActivityResourceModel actitityResource = new ActivityResourceModel(orgId, "组织",
					org != null ? org.getOrgName() : "<font color='red'>该组组已失效</font>", 0, "ORG", org.getOrgSort());
			actitityResource.setRemark(orgId);
			activityResources.add(actitityResource);
		}
		for (String userId : userTask.getCandidateUsers()) {
			User user = userService.getUserById(userId);
			Org org = orgService.getOrgById(user.getOrgId());
			ActivityResourceModel actitityResource = new ActivityResourceModel(userId, "人员",
					(user != null && StrUtil.isNotEmpty(user.getUserId())) ? user.getUserName() + "（" + org.getOrgName() + "）"
							: "<font color='red'>该人员已失效</font>",
					0, "USER", user.getUserSort());
			actitityResource.setRemark(user.getUserId());
			activityResources.add(actitityResource);
		}
		activityDefinitionModel.setActivityResources(activityResources);
		return activityDefinitionModel;
	}

	/**
	 * 获取流程类型树
	 * 
	 * @throws Exception
	 **/
	@RequestMapping(value = "getProcDefTree")
	@ResponseBody
	public List<TreeNode> getProcDefTree(HttpServletRequest request, String filterNodeIdsStr, String selectType)
			throws Exception {
		String typeId = request.getParameter("id");

		String userId = BaseUser.getInstance().getSessionUser(request).getUserId();
		List<TreeNode> treeNodes = procDefTreeManager.getProcDefTree(typeId, userId, selectType);
		String[] filterNodeIds = null;
		if (StringUtils.isNotEmpty(filterNodeIdsStr)) {
			if (filterNodeIdsStr.indexOf(",") != -1) {
				filterNodeIds = filterNodeIdsStr.split(",");
			} else {
				filterNodeIds = new String[] { filterNodeIdsStr };
			}
			for (String filterNodeId : filterNodeIds) {
				TreeNode treeNode = new TreeNode();
				treeNode.setId(filterNodeId);
				treeNodes.remove(treeNode);
			}
		}
		return treeNodes;
	}

	@RequestMapping(value = "getProcDefTree_bak")
	@ResponseBody
	public List<TreeNode> getProcDefTree_bak(HttpServletRequest request, String filterNodeIdsStr) throws Exception {
		String typeId = request.getParameter("id");
		SearchProcessListDTO searchProcessList = new SearchProcessListDTO();
		searchProcessList.setTenantId(BaseUser.getInstance().getLoginUserAppId(request));
		List<TreeNode> treeNodes = procDefTreeManager.getProcDefTree_bak(searchProcessList);
		;
		String[] filterNodeIds = null;
		if (StringUtils.isNotEmpty(filterNodeIdsStr)) {
			if (filterNodeIdsStr.indexOf(",") != -1) {
				filterNodeIds = filterNodeIdsStr.split(",");
			} else {
				filterNodeIds = new String[] { filterNodeIdsStr };
			}
			for (String filterNodeId : filterNodeIds) {
				TreeNode treeNode = new TreeNode();
				treeNode.setId(filterNodeId);
				treeNodes.remove(treeNode);
			}
		}
		return treeNodes;
	}

	/**
	 * 获取历史定义
	 * 
	 * @param procDefId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "getHistoryProcessDefModel")
	public ModelAndView getHistoryProcessDefModel(String procDefId, HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/historyVersionProcess");

		try {
			String[] size = processTraceService.getProcessDiagramSize(procDefId);
			modelAndView.addObject("imageWidth", size[0]);
			modelAndView.addObject("imageHeight", size[1]);
		} catch (Exception e) {
			e.printStackTrace();
		}

		ProcessDefinitionModel proc = processDefinitionService.getProcessDef(procDefId);
		// 根据key获取到所有版本
		List<ProcessDefinitionModel> result = processDefinitionService.findAllVersionProcessDefs(proc.getProcDefKey());
		modelAndView.addObject("result", result);
		return modelAndView;
	}

	/**
	 * 获取流程图的宽高
	 **/
	@RequestMapping(value = "getProcessImageWidthAndHeight")
	@ResponseBody
	public String getProcessImageWidthAndHeight(HttpServletRequest request, String procDefId) {
		Map result = new HashMap();
		result.put("success", true);

		// 为了获取版本号
		ProcessDefinitionModel proc = processDefinitionService.getProcessDef(procDefId);

		try {
			String[] size = processTraceService.getProcessDiagramSize(procDefId);
			result.put("imageWidth", size[0]);
			result.put("imageHeight", size[1]);
		} catch (Exception e) {
			e.printStackTrace();
			result.put("success", false);
			result.put("reason", e.getMessage());
		}
		result.put("version", proc.getVersion());
		String returnValue = JsonUtil.convertToJson(result);
		return returnValue;
	}

	/**
	 * @param bpmnBytes
	 * @param procDefKey
	 * @param appId
	 * @param savetype
	 *            标示是新建还是覆盖 savetype为'create'为新建 值为'update'为覆盖
	 * @return
	 */
	private ProcessDefinitionModel deployProcess(byte[] bpmnBytes, String procDefKey, String appId, String savetype) {
		ProcessDefinitionModel proceDefModel = null;
		if ("create".equals(savetype)) {// 如果选择新建
			// 直接新增版本
			proceDefModel = processDefinitionService.deploySingleProcess(appId, new ByteArrayInputStream(bpmnBytes),
					procDefKey + ".bpmn20.xml");
		} else {// 如果选择覆盖
				// 获取最新版本的流程定义
			proceDefModel = processDefinitionService.getProcessDefBykey(procDefKey);
			if (proceDefModel == null) {// 查询不到已有版本，新增版本
				proceDefModel = processDefinitionService.deploySingleProcess(appId, new ByteArrayInputStream(bpmnBytes),
						procDefKey + ".bpmn20.xml");
			} else {// 覆盖已有版本
				// 更新bpmn.xml
				processDefinitionService.updateDeploymentResource(proceDefModel.getDeploymentId(),
						proceDefModel.getProcDefId(), bpmnBytes, true);
				// 更新流程定义缓存
				processDefinitionService.refreshProcessDefineCache(proceDefModel.getProcDefId());
			}
		}
		return proceDefModel;
	}

	/**
	 * 创建模型
	 */
	@RequestMapping(value = "create")
	@ResponseBody
	public Map<String, String> create(String name, String key, String description, HttpServletRequest request,
			HttpServletResponse response) {
		String path = "";
		String errorMsg = "";
		try {
			String modelId = processModelService.create(name, key, description,
					BaseUser.getInstance().getLoginUserAppId(request));
			path = MyContants.BPM_PROCESS_MODELER_PATH + "_dev" + "?id=" + modelId;
		} catch (Exception e) {
			if (e instanceof WorkFlowException) {
				errorMsg = ((WorkFlowException) e).getWebShowErrorMessage();
			}
		}
		Map result = new HashMap();
		result.put("path", path);
		result.put("errorMsg", errorMsg);
		return result;

	}

	/**
	 * 开发平台流程建模入口
	 */
	@RequestMapping(value = "index")
	public ModelAndView index(String key,String name, String formId,String formName,String modelId,String tenant,String procDefKey,String appId, HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/config");
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(formName)) {
			modelAndView.addObject("errorMsg", "参数异常！");
			return modelAndView;
		}
		String getKey = key;
		if(StringUtils.isNotBlank(procDefKey)){
			getKey=procDefKey;
			modelAndView.addObject("modelPath", MyContants.BPM_PROCESS_MODELER_PATH +"?appId="+tenant+"&key="+key+"&formId="+formId+"&modelId="+modelId+"&formName="+formName+"&procDefKey="+procDefKey);
		}else{
			modelAndView.addObject("modelPath", MyContants.BPM_PROCESS_MODELER_PATH +"?appId="+tenant+"&key="+key+"&formId="+formId+"&modelId="+modelId+"&formName="+formName);
		}
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDefBykey(getKey);
		modelAndView.addObject("processDefinition", processDefinition);
		modelAndView.addObject("formId", formId);
		modelAndView.addObject("modelId", modelId);
		modelAndView.addObject("key", key);
		modelAndView.addObject("formName", formName);
		modelAndView.addObject("appId", tenant);
		modelAndView.addObject("mAppId", appId);
		return modelAndView;
	}
/*
	*//**
	 * 创建流程模型并打开流程建模
	 *//*
	@RequestMapping(value = "createOpenFlow")
	public ModelAndView createOpenFlow(HttpServletRequest request, String key,String name, String formId,String modelId,String appId) {
		*//**if (key.indexOf("_devpf") == -1) {
			key = key + "_devpf";
		}**//*
		Model model = null;
		ProcessDefinitionModel processDefinition = null;
		try {
			model = processModelService.getModel(key, appId);
		} catch (Exception e) {
			// 不用捕获异常
		}
		String modelId = "";
		if (model == null) {
			modelId = processModelService.create(name, key, "", appId);
		} else {
			modelId = model.getId();
			processDefinition = processDefinitionService.getProcessDefBykey(key);
		}
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/config");
		modelAndView.addObject("processDefinition", processDefinition);
		modelAndView.addObject("modelId", modelId);
		modelAndView.addObject("key", key);
		modelAndView.addObject("name", name);
		modelAndView.addObject("modelPath", PROCESS_MODEL_PATH +"?key=" + key);
		return modelAndView;
	}

	*//**
	 * 创建流程模型并打开流程建模
	 *//*
	@RequestMapping(value = "openFlow")
	public ModelAndView openFlow(HttpServletRequest request, String key, String name, String appId) {
		if (StringUtils.isEmpty(appId)) {
			appId = BaseUser.getInstance().getLoginUserAppId(request);
		}
		Model model = null;
		try {
			model = processModelService.getModel(key, appId);
		} catch (Exception e) {
			// 不用捕获异常
		}
		ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDefBykey(key);
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/config");
		modelAndView.addObject("processDefinition", processDefinition);
		modelAndView.addObject("modelId", model.getId());
		modelAndView.addObject("key", key);
		modelAndView.addObject("name", name);

		modelAndView.addObject("modelPath", PROCESS_MODEL_PATH + "_dev" + "?id=" + model.getId());
		return modelAndView;
	}*/

	public String validate(byte[] bpmnBytes) {
		String errorMsg = "";
		List<ValidationError> validationErrors = null;
		try {
			BpmnModel bpmnModel = this.processModelNewService.convertByteToBpmnModel(bpmnBytes, "");
			ProcessValidator processValidator = new ProcessValidatorFactory().createDefaultProcessValidator();
			validationErrors = processValidator.validate(bpmnModel);
		} catch (Exception e) {
			errorMsg = "非法的流程模型!";
			e.printStackTrace();
		}
		if (!validationErrors.isEmpty()) {
			errorMsg = validationErrors.toString();
		}
		return errorMsg;

	}
	
	
	/**
	 * 根据新流程建模部署流程
	 */
	@RequestMapping(value="/deploy", method = RequestMethod.POST, produces="application/json; charset=UTF-8")
	@ResponseBody
	public Map<String,String> deployNew(@RequestBody Map<String, String> values, HttpServletRequest request,
			RedirectAttributes redirectAttributes) {
		Map<String,String> result = new HashMap<String,String> ();
		String name = values.get("name");
		String key = values.get("key");
		String flowXml=values.get("flow_xml");
		String appId=values.get("appId");
		String code="200";
		String errorcode="404";
		try {
			if (StringUtils.isEmpty(name)||StringUtils.isEmpty(key)||StringUtils.isEmpty(flowXml)||StringUtils.isEmpty(appId)) {
				result.put("msg", "保存流程失败，参数为空");
				result.put("code", errorcode);
				return result;
			}
			byte[] bpmnBytes = flowXml.getBytes("utf-8");
			// by lw
			String errorMsg = validate(bpmnBytes);
			if (StringUtils.isNotEmpty(errorMsg)) {
				result.put("msg", "验证流程建模异常,异常信息："+errorMsg);
				result.put("code", errorcode);
				return result;
			}
			result = this.processModelNewService.deploy(bpmnBytes,key,name, appId);
			try {
				String procDefId = result.get("procDefId");
				ProcessInfoConfig processInfoConfig = processInfoConfigManager.getById(procDefId);
				if(null != processInfoConfig){
					String createTime = DateUtil.convertDateToString("yyyy-MM-dd HH:mm:ss", processInfoConfig.getCreateTime());
					result.put("version", String.valueOf(processInfoConfig.getProcessVersion()));
					result.put("create_time", createTime);
				}
			} catch (Exception e) {
				logger.error("流程部署-查询流程配置信息失败：result={}", result);
			}
		} catch (Exception e) {
			String errorMsg = String.format("[%s]流程部署失败,错误信息:[%s]", key, e.getLocalizedMessage());
			logger.error(errorMsg, e);
			result.put("msg", errorMsg);
			result.put("code", errorcode);
			return result;
		}
		result.put("code", code);
		return result;
	}

	
	
	/**
	 * 根据新流程建模部署流程,直接覆盖已有流程定义版本，并更新流程定义的缓存
	 */
	@RequestMapping(value="/deployCascodeUpdate", method = RequestMethod.POST, produces="application/json; charset=UTF-8")
	@ResponseBody
	public Map<String,String> deployCascodeUpdateNew(@RequestBody Map<String, String> values, HttpServletRequest request,
			RedirectAttributes redirectAttributes) {
		Map<String,String> result = new HashMap<String,String> ();
		boolean isSuccess = false;
		String name = values.get("name");
		String key = values.get("key");
		String flowXml=values.get("flow_xml");
		String appId=values.get("appId");
		String code="200";
		String errorcode="404";
		try {
			if (StringUtils.isEmpty(name)||StringUtils.isEmpty(key)||StringUtils.isEmpty(flowXml)||StringUtils.isEmpty(appId)) {
				result.put("msg", "保存流程失败，参数为空");
				result.put("code", errorcode);
				return result;
			}
			byte[] bpmnBytes = flowXml.getBytes("utf-8");
			// by lw
			String errorMsg = validate(bpmnBytes);
			if (StringUtils.isNotEmpty(errorMsg)) {
				result.put("msg", "验证流程建模异常,异常信息："+errorMsg);
				result.put("code", errorcode);
				return result;
			}
			if (processModelNewService.isPprocessDeployment(key, appId)) {
				result = processModelNewService.deployCascodeUpdate(bpmnBytes,key);
			} else {
				result = processModelNewService.deploy(bpmnBytes,key, name,appId);
			}
			isSuccess = true;
		} catch (Exception e) {
			logger.error("流程部署失败：key={}", key, e);
			result.put("msg", "流程部署失败");
			result.put("code", errorcode);
			return result;
		}
		try {
			String procDefId = result.get("procDefId");
			ProcessInfoConfig processInfoConfig = processInfoConfigManager.getById(procDefId);
			if(null != processInfoConfig){
				String createTime = DateUtil.convertDateToString("yyyy-MM-dd HH:mm:ss", processInfoConfig.getCreateTime());
				result.put("version", String.valueOf(processInfoConfig.getProcessVersion()));
				result.put("create_time", createTime);
			}
		} catch (Exception e) {
			logger.error("流程部署-查询流程配置信息失败：result={}", result);
		}
		result.put("code", code);
		MyContants.saveUserOperate(request, "modelId", isSuccess, result.get("msg"), MyContants.LOGIN_SESSION_USER,
				MyContants.APPLICATION);
		return result;
	}
	
	
	/**
	 * 在新流程建模打开流程
	 */
	@RequestMapping(value = "openProcess")
	@ResponseBody
	public Map<String, String> openProcess(HttpServletRequest request, String key, String appId) {
		Map<String, String> result = new HashMap<String, String>();
		String msg="";
		if (StringUtils.isEmpty(appId)) {
			appId = BaseUser.getInstance().getLoginUserAppId(request);
		}
		result.put("procDefId", "");
		result.put("name", "");
		result.put("key", "");	
		result.put("flow_xml", "");
		try {
			ProcessDefinitionModel processDefinition = processDefinitionService.getProcessDefBykey(key);
			if(null != processDefinition) {
				BpmnModel bpmnModel = processModelNewService.getBpmnModelByProcDefId(processDefinition.getProcDefId());
				processModelNewService.convertBpmnModelToByte(bpmnModel);
				result.put("procDefId", processDefinition.getProcDefId());
				result.put("name", processDefinition.getProcDefName());
				result.put("key", processDefinition.getProcDefKey());	
				result.put("flow_xml", new String(processModelNewService.convertBpmnModelToByte(bpmnModel), "UTF-8"));
				result.put("version", String.valueOf(processDefinition.getVersion()));
				String createTime = "";
				ProcessInfoConfig processInfoConfig = processInfoConfigManager.getById(processDefinition.getProcDefId());
				try {
					if(null != processInfoConfig && null != processInfoConfig.getCreateTime()){
						createTime = DateUtil.convertDateToString("yyyy-MM-dd HH:mm:ss", processInfoConfig.getCreateTime());
					}
				} catch (Exception e) {
					logger.error("创建时间转换失败：processInfoConfig={}", JSONUtil.toJsonStr(processInfoConfig));
				}
				result.put("create_time", createTime);
				msg="success";
			}
		} catch (Exception e) {
			logger.error("流程部署失败：key={}", key, e);
			msg="error";
		}
		result.put("msg", msg);
		return result;
	}
	/**
	 * 选择流程模型列表
	 */
	@RequestMapping(value = "/model/list")
	public ModelAndView modelList(HttpServletRequest request,String appId, ProcessInfoConfig query) {
		SysGlType sysGlType = new SysGlType();
		sysGlType.setTypeParentId("TOP_FLOW_TYPE");
		sysGlType.setAppKey((String) request.getSession().getAttribute(MyContants.APP_ID_KEY));
		List<SysGlType> sysGlTypes = sysGlTypeManager.findByExample(sysGlType);
		query.setSortColumns("CREATE_TIME desc");
		if ("true".equalsIgnoreCase(MyContants.IS_OPEN_TENANT)) {
			query.setTenantId(appId);
		}
		query.setProcessMgrIsshow(null);
		Page<List<ProcessInfoConfig>> page = processConfigService.findProcessConfigAndModel(query);
		ModelAndView modelAndView = new ModelAndView("/procDefModelMgr/chooseModel");
		modelAndView.addAllObjects(toModelMap(page, query));
		modelAndView.addObject("sysGlTypes", sysGlTypes);
		modelAndView.addObject("modelKey", request.getParameter("modelKey"));
		modelAndView.addObject("modelName", request.getParameter("modelName"));
		modelAndView.addObject("appId", request.getParameter("appId"));
		return modelAndView;
	}
	@RequestMapping(value = "findAllTenant")
	@ResponseBody
	public Map<String,Object> list(HttpServletRequest request,@RequestBody Map<String,Object> params) {
		Map<String,Object> result = new HashMap<String, Object>();
		ApplicationEntity query = new ApplicationEntity();
		query.setAppTypes("('inner','outside')");
		result.put("list", applicationManager.findByExample(query));
		return result;
	}
	/**
	 * 获取流程的xml内容，在前端解析xml生成流程图
	 * @param procDefId
	 * @param request
	 * @return
	 */
	@RequestMapping(value="/showProcessXml")
	@ResponseBody
	public Map<String,Object> showProcessXml(String procDefId,HttpServletRequest request) {
		Map<String,Object> result =  new HashMap<String, Object>();
		InputStream in=processDefinitionService.loadProcessResource(procDefId, "xml");
		String bpmnXml="";
		ByteArrayOutputStream out=new ByteArrayOutputStream();
		try{
			org.apache.commons.io.IOUtils.copy(in, out); 
			bpmnXml=out.toString("UTF-8");
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				logger.error("",e);
			}
		}
		result.put("bpmnXml", bpmnXml);
		return result;
	}

}
