package com.hotent.portal.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.hotent.base.enums.ResponseErrorEnums;
import com.hotent.base.exception.BaseException;
import com.hotent.base.feign.BpmModelFeignService;
import com.hotent.base.feign.BpmRuntimeFeignService;
import com.hotent.base.feign.FormFeignService;
import com.hotent.base.feign.UCFeignService;
import com.hotent.base.query.*;
import com.hotent.base.util.*;
import com.hotent.base.util.Base64;
import com.hotent.base.util.time.DateFormatUtil;
import com.hotent.portal.model.AppModel;
import com.hotent.portal.persistence.manager.AppModelManager;
import com.hotent.sys.persistence.manager.*;
import com.hotent.sys.persistence.model.*;
import com.hotent.sys.util.SysPropertyUtil;
import com.hotent.uc.api.impl.util.ContextUtil;
import com.hotent.uc.api.impl.vo.BoDefVo;
import com.hotent.uc.api.impl.vo.FormDataTemplateVo;
import com.hotent.uc.api.impl.vo.FormVo;
import com.hotent.uc.api.impl.vo.SysAppVo;
import com.hotent.uc.api.model.IUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import com.hotent.base.controller.BaseController;
import com.hotent.base.model.CommonResult;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 
 * <pre> 
 * 描述：应用信息 控制器类
 * 构建组：x7
 * 作者:qiuxd
 * 邮箱:qiuxd@jee-soft.cn
 * 日期:2020-08-20 15:23:19
 * 版权：广州宏天软件股份有限公司
 * </pre>
 */
@RestController
@RequestMapping(value="/portal/sysApp/v1")
@Api(tags="sysAppController")
public class SysAppController extends BaseController<SysAppManager, SysApp> {
	@Resource
	SysAppManager sysAppManager;
	@Resource
	AppTagsRelationManager appTagsRelationManager;
	@Resource
	SysMenuManager sysMenuManager;
	@Resource
	SysAppOftenManager sysAppOftenManager;
	@Resource
	SysAuthUserManager sysAuthUserManager;
	@Resource
	UCFeignService ucFeignService;
	@Resource
	AppModelManager appModelManager;
	//@Resource
	//FormManager formManager;
	//@Resource
	//FormDataTemplateManager formDataTemplateManager;
	@Resource
	FormFeignService formFeignService;
	@Resource
	BpmModelFeignService bpmModelFeignService;
	@Resource
	CurrentUserService currentUserService;
	//@Resource
	//FormController formController;
	//@Autowired
	//BoDefManager boDefManager;
	//@Resource
	//FormMetaManager formMetaManager;
	@Resource
	BpmRuntimeFeignService bpmRuntimeFeignService;

	@Override
	@PostMapping(value = "/query", produces = {"application/json; charset=utf-8"})
	@ApiOperation("分页查询结果")
	public PageList<SysApp> query(@ApiParam(name = "queryFilter", value = "分页查询信息") @RequestBody QueryFilter<SysApp> queryFilter) {
		List<FieldSort> sorter = queryFilter.getSorter();
		sorter.add(new FieldSort("ID_", Direction.DESC));
		queryFilter.setSorter(sorter);
		return baseService.query(queryFilter);
	}

	@PostMapping("/authList")
	@ApiOperation(value = "获取已授权的应用", httpMethod = "POST", notes = "获取已授权的应用")
	public List<SysApp> authList(@ApiParam(name = "queryFilter", value = "查询对象") @RequestBody SysApp sysApp) throws Exception {
		return sysAppManager.queryByAuth(sysApp);
	}

	@PostMapping("/queryByFilter")
	@ApiOperation(value = "查询已授权的应用", httpMethod = "POST", notes = "查询已授权的应用")
	public PageList<SysApp> queryByFilter(@ApiParam(name = "queryFilter", value = "通用查询对象") @RequestBody QueryFilter<SysApp> queryFilter) throws Exception {
		return sysAppManager.queryCurUserByFilter(queryFilter); //只获取当前登录用户组织和岗位的数据
	}

	@PostMapping("/queryByTagIds/{menuId}")
	@ApiOperation(value = "通过标签ID查询获取已授权的应用", httpMethod = "POST", notes = "通过标签ID查询获取已授权应用")
	public List<SysApp> queryByTagIds(@ApiParam(name = "menuId", value = "菜单ID") @PathVariable String menuId,
									  @ApiParam(name = "tagMaps", value = "查询对象") @RequestBody List<Map<String, String>> tagMaps) throws Exception {
		return sysAppManager.queryByTagIds(menuId, tagMaps);
	}

	@GetMapping("/getDetail")
	@ApiOperation(value = "通过id查询应用详情", httpMethod = "GET", notes = "通过id查询应用详情")
	public SysApp getDetail(@ApiParam(name="id",value="业务对象主键", required = true)@RequestParam String id) throws Exception {
		return sysAppManager.get(id);
	}

	/**
	 * 新增应用信息
	 *
	 * @param sysApp
	 * @return
	 * @throws Exception
	 * @throws
	 */
	@PostMapping(value = "save")
	@ApiOperation(value = "新增,更新应用信息数据", httpMethod = "POST", notes = "新增,更新portal_sys_app数据")
	public CommonResult<String> save(@ApiParam(name = "sysApp", value = "应用信息业务对象", required = true) @RequestBody SysApp sysApp) throws Exception {
		String msg = "添加应用信息成功";
		if (StringUtil.isEmpty(sysApp.getId())) {

			sysAppManager.create(sysApp);
		} else {
			sysAppManager.update(sysApp);
			msg = "更新应用信息成功";
		}
		return new CommonResult<String>(msg);
	}

	@PostMapping(value = "saveAndPublish")
	@ApiOperation(value = "新增应用并发布", httpMethod = "POST", notes = "新增应用并发布")
	public CommonResult<String> saveAndPublish(@ApiParam(name = "sysApp", value = "应用信息业务对象", required = true) @RequestBody SysApp sysApp) throws Exception {
		if (StringUtil.isEmpty(sysApp.getMenuId())) {
			throw new BaseException("请选择发布的菜单");
		}
		sysApp.setIsPublish(SysApp.IS_PUBLISH);
		sysAppManager.getBaseMapper().insert(sysApp);
		return new CommonResult<>(true, "保存成功");
	}

	/**
	 * 批量删除portal_sys_app记录
	 *
	 * @param ids
	 * @return
	 * @throws Exception
	 * @throws
	 */
	@DeleteMapping(value = "/remove")
	@ApiOperation(value = "批量删除应用信息记录", httpMethod = "DELETE", notes = "批量删除应用信息记录")
	public CommonResult<String> removes(@ApiParam(name = "ids", value = "业务主键数组,多个业务主键之间用逗号分隔", required = true) @RequestParam String... ids) throws Exception {
		sysAppManager.removeByIds(ids);
		return new CommonResult<String>(true, "删除成功");
	}

	@PostMapping(value = "/publish")
	@ApiOperation(value = "发布应用", httpMethod = "POST", notes = "发布应用")
	public CommonResult<String> publish(@ApiParam(name = "id", value = "应用ID", required = true) @RequestBody SysApp sysApp) throws Exception {
		String message = SysApp.IS_PUBLISH.equals(sysApp.getIsPublish()) ? "发布成功" : "取消发布成功";
		//判断是否需要 应用上下架审核
		String appPublishFlag = SysPropertyUtil.getByAlias("appPublishFlag");
		if("true".equals(appPublishFlag)) {
			message = SysApp.IS_PUBLISH.equals(sysApp.getIsPublish()) ? "应用上架审核过程中。。。" : "应用下架审核过程中。。。";
			String appAction = SysApp.IS_PUBLISH.equals(sysApp.getIsPublish())? "0": "1";
			if(SysApp.IS_PUBLISH.equals(sysApp.getIsPublish())) {
				sysApp.setIsPublish(SysApp.NOT_PUBLISH);
			} else {
				sysApp.setIsPublish(SysApp.IS_PUBLISH);
			}

			//发起上下架审核流程
			IUser user = ContextUtil.getCurrentUser(); //获取当前用户
			ObjectNode startFlowParam = JsonUtil.getMapper().createObjectNode();
			startFlowParam.put("account", user.getAccount());
			startFlowParam.put("approval", true);
			startFlowParam.put("businessKey", "");
			startFlowParam.put("data", "");
			startFlowParam.put("defId", "");
			startFlowParam.put("flowKey", "yysjshlc");
			startFlowParam.put("formType", "");
			startFlowParam.put("proInstId", "");
			startFlowParam.put("startOrgId", "");
			startFlowParam.put("supportMobile", 0);

			ObjectNode datas = JsonUtil.getMapper().createObjectNode();
			ObjectNode vars = JsonUtil.getMapper().createObjectNode();
			vars.put("code", this.generateSerialNumber());
			vars.put("userId", user.getUserId());
			vars.put("userName", user.getUsername());
			vars.put("appId", sysApp.getId());
			vars.put("appName", sysApp.getName());
			vars.put("appDesc", sysApp.getDesc());
			vars.put("menuName", sysApp.getMenuName());
			vars.put("type", sysApp.getType());
			vars.put("appType", "0");
			vars.put("appAction", appAction);
			String content = sysApp.getContent();
			//1:常规应用 2:表单列表 3:数据列表 4:图表 5:网页跳转 6:表单 7:流程模块 8:流程 9:datav大屏
			if("1".equals(sysApp.getType())) {
			} else if("2".equals(sysApp.getType()) || "3".equals(sysApp.getType()) || "9".equals(sysApp.getType())) {
				JsonNode node = JsonUtil.toJsonNode(content);
				vars.put("relId", node.get("id").textValue());
				vars.put("relName", node.get("name").textValue());
				vars.put("relKey", node.get("alias").textValue());
			} else if("4".equals(sysApp.getType()) || "7".equals(sysApp.getType())) {
				JsonNode node = JsonUtil.toJsonNode(content);
				vars.put("relId", node.get("id").textValue());
				vars.put("relName", node.get("name").textValue());
			} else if("5".equals(sysApp.getType())) {
				vars.put("relName", content);
			} else if("6".equals(sysApp.getType()) || "8".equals(sysApp.getType()) ) {
				JsonNode node = JsonUtil.toJsonNode(content);
				vars.put("relId", node.get("id").textValue());
				vars.put("relName", node.get("name").textValue());
				vars.put("relKey", node.get("key").textValue());
			}
			datas.set("qzdef_yysj", vars);
			startFlowParam.put("data", Base64.getBase64(datas.toString()));
			bpmRuntimeFeignService.start(startFlowParam);
		}
		sysAppManager.publish(sysApp);
		return new CommonResult<String>(true, message);
	}

	public String generateSerialNumber() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String timestamp = sdf.format(new Date());
		Random random = new Random();
		int randomNum = random.nextInt(900) + 100; // 生成100到999之间的随机数
		return timestamp + randomNum;
	}

	@PostMapping(value = "/saveAppTags/{appId}")
	@ApiOperation(value = "保存应用标签", httpMethod = "POST", notes = "保存应用标签")
	public CommonResult<String> saveAppTags(@ApiParam(name = "appId", value = "应用ID", required = true) @PathVariable String appId,
											@ApiParam(name = "tagIds", value = "标签ID集", required = true) @RequestBody String tagIds) {
		try {
			appTagsRelationManager.saveAppTags(appId, tagIds);
			return new CommonResult<>(true, "保存成功");
		} catch (Exception e) {
			return new CommonResult<>(false, "保存失败");
		}
	}

	@GetMapping(value = "/getAppTagsById/{appId}")
	@ApiOperation(value = "根据应用ID获取应用标签", httpMethod = "GET", notes = "根据应用ID获取应用标签")
	public CommonResult<List<AppTagsRelation>> getAppTagsById(@ApiParam(name = "appId", value = "应用Id", required = true) @PathVariable String appId) throws Exception {
		List<AppTagsRelation> byAppId = appTagsRelationManager.getByAppId(appId);
		return new CommonResult<>(true, "获取成功", byAppId);
	}

	@GetMapping(value = "/validMenu")
	@ApiOperation(value = "获取APP首个有内容的菜单", httpMethod = "GET", notes = "获取APP首个有内容的菜单")
	public List<String> validMenu() throws Exception {
		List<String> validMenu = sysAppManager.getValidMenu(ContextUtil.getCurrentUserId());
		return validMenu;
	}

	@RequestMapping(value = "exportXml", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "导出应用xml", httpMethod = "GET", notes = "导出应用xml")
	public void exportXml(HttpServletRequest request, HttpServletResponse response,
						  @ApiParam(name = "ids", value = "应用id", required = true) @RequestParam String ids) throws Exception {
		response.setContentType("APPLICATION/OCTET-STREAM");
		if (BeanUtils.isNotEmpty(ids)) {
			String[] stringsIds = ids.split(",");
			List<String> list = Arrays.asList(stringsIds);
			String zipName = "ht_sysApp_" + DateFormatUtil.format(LocalDateTime.now(), "yyyy_MMdd_HHmmss");
			// 写XML
			Map<String, String> strXml = baseService.exportData(list);
			HttpUtil.downLoadFile(request, response, strXml, zipName);
		}
	}


	@RequestMapping(value = "removeFullXml", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "导出完整应用xml", httpMethod = "GET", notes = "导出完整应用xml")
	public CommonResult<String> removeFullXml(HttpServletRequest request, HttpServletResponse response,
							  @ApiParam(name = "ids", value = "应用id", required = true) @RequestParam String ids) throws Exception {
		if (BeanUtils.isEmpty(ids)) {
			throw new BaseException(ResponseErrorEnums.NO_PERMISSION, "缺少应用id，导出失败！");
		}
		String[] stringsIds = ids.split(",");
		if (stringsIds.length > 1) {
			throw new BaseException(ResponseErrorEnums.NO_PERMISSION, "仅支持单笔应用id导出，导出失败！");
		}

		try {
			String appId = stringsIds[0];
			SysApp sysApp = sysAppManager.get(appId);
			Short sysAppType = sysApp.getType();
			String content = sysApp.getContent();
			if(sysAppType!=2 && sysAppType!=5 && sysAppType!=6 && sysAppType!=8) {
				throw new BaseException(ResponseErrorEnums.NO_PERMISSION,  "仅支持对网页跳转/表单/表单列表/流程类型的应用进行删除，删除失败！");
			}

			if(sysAppType==2) { //表单列表
				JsonNode contentNode = JsonUtil.toJsonNode(content);
				String contentId = contentNode.get("id").asText();
				ObjectNode formDataTemplateNode = formFeignService.getFormDataTemplateById(contentId);
				FormDataTemplateVo formDataTemplate = JsonUtil.toBean(formDataTemplateNode.toString(), FormDataTemplateVo.class);
				//FormDataTemplate formDataTemplate = formDataTemplateManager.getById(contentId);

				String formKey = formDataTemplate.getFormKey();
				String mobileFormAlias = formDataTemplate.getMobileFormAlias();
				FormVo bpmForm = null;
				if(StringUtil.isNotEmpty(formKey)) {
					ObjectNode bpmFormNode = formFeignService.getMainByFormKey(formKey);
					bpmForm = JsonUtil.toBean(bpmFormNode.toString(), FormVo.class);
				}
				//Form bpmForm = formManager.getMainByFormKey(formKey);
				FormVo mobileBpmForm = null;
				if(StringUtil.isNotEmpty(mobileFormAlias)) {
					ObjectNode mobileBpmFormNode = formFeignService.getMainByFormKey(mobileFormAlias);
					mobileBpmForm = JsonUtil.toBean(mobileBpmFormNode.toString(), FormVo.class);
				}
				//Form mobileBpmForm = formManager.getMainByFormKey(mobileFormAlias);
				List<String> listIds = new ArrayList<>();
				if(bpmForm!=null) {
					listIds.add(bpmForm.getId());
				}
				if(mobileBpmForm!=null) {
					listIds.add(mobileBpmForm.getId());
				}
				String[] aryIds = listIds.toArray(new String[0]);
				String aryIdsStr = String.join(",", aryIds);
				String bpmNames  = formFeignService.checkBpmForm(aryIdsStr); //检查是否绑定了流程
				//String bpmNames  = formController.checkBpmForm(aryIds); //检查是否绑定了流程
				if(StringUtil.isEmpty(bpmNames)){
					sysAppManager.removeByIds(appId);
					formFeignService.removeFormDataTemplateByIds(contentId);
					//formDataTemplateManager.removeByIds(contentId);
					//删除mobile表单
					if(mobileBpmForm!=null) {
						String[] bpmFormIds = new String[]{mobileBpmForm.getId()};
						formFeignService.removeForm(String.join(",", bpmFormIds));
						//formManager.remove(bpmFormIds);
					}
					ArrayNode boIdArrayNode = formFeignService.getBODefIdByFormId(bpmForm.getDefId());
					List<JsonNode> boIds = JsonUtil.arrayToListByJsonNode(boIdArrayNode);
					//List<String> boIds = formMetaManager.getBODefIdByFormId(bpmForm.getDefId());
					String[] formIds = new String[]{bpmForm.getId()};
					formFeignService.removeForm(String.join(",", formIds));
					//formManager.remove(formIds);
					for (int i = 0; i < boIds.size(); i++) {
						JsonNode node = boIds.get(i);
						String boId = node.asText();
						formFeignService.removeBODefByIds(boId);
						//boDefManager.removeByIds(boId);
					}
				}else{
					return new CommonResult(false, "删除失败："+bpmNames, null);
				}
			} else if(sysAppType==5) { // 网页跳转
				sysAppManager.removeByIds(appId);
			} else if(sysAppType==6) { // 表单
				JsonNode contentNode = JsonUtil.toJsonNode(content);
				String contentAlias = contentNode.get("key").asText();
				ObjectNode mobileBpmFormNode = formFeignService.getMainByFormKey(contentAlias);
				FormVo bpmForm = JsonUtil.toBean(mobileBpmFormNode.toString(), FormVo.class);
				//Form bpmForm = formManager.getMainByFormKey(contentAlias);
				String[] aryIds = {bpmForm.getId()};
				String bpmNames  = formFeignService.checkBpmForm(String.join(",", aryIds)); //检查是否绑定了流程
				//String bpmNames  = formController.checkBpmForm(aryIds); //检查是否绑定了流程
				if(StringUtil.isEmpty(bpmNames)){
					sysAppManager.removeByIds(appId);
					ArrayNode boIdArrayNode = formFeignService.getBODefIdByFormId(bpmForm.getDefId());
					List<JsonNode> boIds = JsonUtil.arrayToListByJsonNode(boIdArrayNode);
					//List<String> boIds = formMetaManager.getBODefIdByFormId(bpmForm.getDefId());
					formFeignService.removeForm(String.join(",", aryIds));
					//formManager.remove(aryIds);
					for (int i = 0; i < boIds.size(); i++) {
						JsonNode node = boIds.get(i);
						String boId = node.asText();
						formFeignService.removeBODefByIds(boId);
						//boDefManager.removeByIds(boId);
					}
				}else{
					return new CommonResult(false, "删除失败："+bpmNames, null);
				}
			} else if(sysAppType==8) { // 流程
				JsonNode contentNode = JsonUtil.toJsonNode(content);
				String contentAlias = contentNode.get("key").asText();
				ObjectNode objectNode = bpmModelFeignService.getProcDefByDefKey(contentAlias);
				String defId = objectNode.get("defId").asText();
				Map<String, Object> map = bpmModelFeignService.definitionData(defId);
				Map<String, String> pcFormMap = (LinkedHashMap)map.get("pcForm");
				Map<String, String> mobileFormMap = (LinkedHashMap)map.get("mobileForm");
				//删除流程
				String bpmIds = objectNode.get("id").asText();
				bpmModelFeignService.physicsRemoveAllVersionByIds(bpmIds);
				//删除应用
				sysAppManager.removeByIds(appId);
				//删除mobile表单
				if(mobileFormMap!=null) {
					String mobileAlias = mobileFormMap.get("mobileAlias");
					ObjectNode mobileBpmFormNode = formFeignService.getMainByFormKey(mobileAlias);
					FormVo mobileBpmForm = JsonUtil.toBean(mobileBpmFormNode.toString(), FormVo.class);
					//Form mobileBpmForm = formManager.getMainByFormKey(mobileAlias);
					String[] bpmFormIds = new String[]{mobileBpmForm.getId()};
					formFeignService.removeForm(String.join(",", bpmFormIds));
					//formManager.remove(bpmFormIds);
				}
				//删除pc表单
				if(pcFormMap!=null) {
					String pcAlias = pcFormMap.get("pcAlias");
					ObjectNode bpmFormNode = formFeignService.getMainByFormKey(pcAlias);
					FormVo bpmForm = JsonUtil.toBean(bpmFormNode.toString(), FormVo.class);
					//Form bpmForm = formManager.getMainByFormKey(pcAlias);
					ArrayNode boIdArrayNode = formFeignService.getBODefIdByFormId(bpmForm.getDefId());
					List<JsonNode> boIds = JsonUtil.arrayToListByJsonNode(boIdArrayNode);
					//List<String> boIds = formMetaManager.getBODefIdByFormId(bpmForm.getDefId());
					String[] aryIds = {bpmForm.getId()};
					formFeignService.removeForm(String.join(",", aryIds));
					//formManager.remove(aryIds);
					for (int i = 0; i < boIds.size(); i++) {
						JsonNode node = boIds.get(i);
						String boId = node.asText();
						formFeignService.removeBODefByIds(boId);
						//boDefManager.removeByIds(boId);
					}
				}
			}
			return new CommonResult<>(true, "删除应用成功");
		} catch (Exception e) {
			e.printStackTrace();
			return new CommonResult<>(false, "删除应用失败：" + e.getMessage());
		}
	}

	@RequestMapping(value = "exportFullXml", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "导出完整应用xml", httpMethod = "GET", notes = "导出完整应用xml")
	public void exportFullXml(HttpServletRequest request, HttpServletResponse response,
						  @ApiParam(name = "ids", value = "应用id", required = true) @RequestParam String ids,
						  @ApiParam(name = "backupFlag", value = "备份标志", required = false) @RequestParam(required = false) boolean backupFlag) throws Exception {
		if (BeanUtils.isEmpty(ids)) {
			throw new BaseException(ResponseErrorEnums.NO_PERMISSION,  "缺少应用id，导出失败！");
		}
		String[] stringsIds = ids.split(",");
		if(stringsIds.length>1) {
			throw new BaseException(ResponseErrorEnums.NO_PERMISSION,  "仅支持单笔应用id导出，导出失败！");
		}

		String appId = stringsIds[0];
		SysApp sysApp = sysAppManager.get(appId);
		Short sysAppType = sysApp.getType();
		String content = sysApp.getContent();
		if(sysAppType!=2 && sysAppType!=5 && sysAppType!=6 && sysAppType!=8) {
			throw new BaseException(ResponseErrorEnums.NO_PERMISSION,  "仅支持对网页跳转/表单/表单列表/流程类型的应用进行导出，导出失败！");
		}

		Map<String,String> resultMap = new LinkedHashMap<>();
		List<String> appIdList = new ArrayList<>(Arrays.asList(appId));
		Map<String, String> mapApp = baseService.exportData(appIdList);
		resultMap.putAll(mapApp);

		if (BeanUtils.isNotEmpty(content) && content.startsWith("{") && content.endsWith("}")) {
			JsonNode contentNode = JsonUtil.toJsonNode(content);
			if(sysAppType==2) { //表单列表
				String contentId = contentNode.get("id").asText();
				List<String> formTemplateIdList = new ArrayList<>(Arrays.asList(contentId));

				String formTemplateIdListJson = JSONUtil.toJsonStr(formTemplateIdList);
				ObjectNode mapTemplateNode = formFeignService.exportDef(formTemplateIdListJson);
				Map mapTemplate = JsonUtil.toMap(mapTemplateNode.toString());
				//Map mapTemplate = formDataTemplateManager.exportDef(formTemplateIdList);
				resultMap.putAll(mapTemplate);

				ObjectNode formDataTemplateNode = formFeignService.getFormDataTemplateById(contentId);
				FormDataTemplateVo formDataTemplate = JsonUtil.toBean(formDataTemplateNode.toString(), FormDataTemplateVo.class);
				//FormDataTemplate formDataTemplate = formDataTemplateManager.getById(contentId);
				String formKey = formDataTemplate.getFormKey();
				String mobileFormAlias = formDataTemplate.getMobileFormAlias();

				FormVo bpmForm = null;
				if(StringUtil.isNotEmpty(formKey)) {
					ObjectNode bpmFormNode = formFeignService.getMainByFormKey(formKey);
					bpmForm = JsonUtil.toBean(bpmFormNode.toString(), FormVo.class);
				}
				//Form bpmForm = formManager.getMainByFormKey(formKey);
				FormVo mobileBpmForm = null;
				if(StringUtil.isNotEmpty(mobileFormAlias)) {
					ObjectNode mobileBpmFormNode = formFeignService.getMainByFormKey(mobileFormAlias);
					mobileBpmForm = JsonUtil.toBean(mobileBpmFormNode.toString(), FormVo.class);
				}
				//Form mobileBpmForm = formManager.getMainByFormKey(mobileFormAlias);
				List<String> formIdList = new ArrayList<>();
				if(bpmForm!=null) {
					formIdList.add(bpmForm.getId());
				}
				if(mobileBpmForm!=null) {
					formIdList.add(mobileBpmForm.getId());
				}

				String formIdListJson = JSONUtil.toJsonStr(formIdList);
				ObjectNode mapFormNode = formFeignService.exportForms(formIdListJson);
				Map mapForm = JsonUtil.toMap(mapFormNode.toString());
				//Map mapForm = formManager.exportForms(formIdList,true, true);
				resultMap.putAll(mapForm);
			} else if(sysAppType==5) { // 网页跳转

			} else if(sysAppType==6) { // 表单
				String contentAlias = contentNode.get("key").asText();
				ObjectNode bpmFormNode = formFeignService.getMainByFormKey(contentAlias);
				FormVo bpmForm = JsonUtil.toBean(bpmFormNode.toString(), FormVo.class);
				//Form bpmForm = formManager.getMainByFormKey(contentAlias);
				List<String> formIdList = new ArrayList<>(Arrays.asList(bpmForm.getId()));

				String formIdListJson = JSONUtil.toJsonStr(formIdList);
				ObjectNode mapFormNode = formFeignService.exportForms(formIdListJson);
				Map mapForm = JsonUtil.toMap(mapFormNode.toString());
				//Map mapForm = formManager.exportForms(formIdList,true, true);
				resultMap.putAll(mapForm);
			} else if(sysAppType==8) { // 流程
				String contentAlias = contentNode.get("key").asText();
				Map mapFlow = bpmModelFeignService.getExportXmlByDefKey(contentAlias);
				resultMap.putAll(mapFlow);
			}
		}

		if(!backupFlag) { //只是备份的话，不需要修改别名
			String jsonStr = JSONUtil.toJsonStr(resultMap);
			resultMap = bpmModelFeignService.getExportXmlReplaceAlias(jsonStr);
		}
		response.setContentType("APPLICATION/OCTET-STREAM");
		String zipName = "ht_sysAppFull_" + DateFormatUtil.format(LocalDateTime.now(), "yyyy_MMdd_HHmmss");
		HttpUtil.downLoadFile(request, response, resultMap, zipName);
	}

	@RequestMapping(value = "importFullXml", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "应用复制完整导入", httpMethod = "POST", notes = "应用复制完整导入")
	public CommonResult<String> importFullXml(MultipartHttpServletRequest request, HttpServletResponse response) throws Exception {
		String unZipFilePath = null;
		try {
			MultipartFile file = request.getFile("file");
			String rootRealPath = Paths.get(FileUtil.getIoTmpdir(), "/attachFiles/unZip").toString();
			FileUtil.createFolder(rootRealPath, true);
			ZipUtil.unZipFile(file, rootRealPath);
			String name = file.getOriginalFilename();
			String fileDir = StringUtil.substringBeforeLast(name, ".");
			unZipFilePath = Paths.get(rootRealPath, fileDir).toString();

			if(!name.startsWith("ht_sysAppFull")) {
				throw new BaseException(ResponseErrorEnums.NO_PERMISSION, "导入文件类型名称错误，导入失败！");
			}

			String boXmlStr = "";
			try {
				boXmlStr = FileUtil.readFile(Paths.get(unZipFilePath, "bo.xml").toString());
			} catch (Exception e) {}
			String formXmlStr = "";
			try {
				formXmlStr = FileUtil.readFile(Paths.get(unZipFilePath, "form.xml").toString());
			} catch (Exception e) {}
			String formRightsXml = "";
			try {
				formRightsXml = FileUtil.readFile(Paths.get(unZipFilePath, "formrights.xml").toString());
			} catch (Exception e) {}
			String sysAppsPortalXml = "";
			try {
				sysAppsPortalXml = FileUtil.readFile(Paths.get(unZipFilePath, "sysApps.portal.xml").toString());
			} catch (Exception e) {}
			String bpmdefsXml = "";
			try {
				bpmdefsXml = FileUtil.readFile(Paths.get(unZipFilePath, "bpmdefs.flow.xml").toString());
			} catch (Exception e) {}

			String formDataTemplatesXml = "";
			try {
				formDataTemplatesXml = FileUtil.readFile(Paths.get(unZipFilePath, "formDataTemplates.form.xml").toString());
			} catch (Exception e) {}

			ArrayNode boDefsNode = formFeignService.parseBoDefXml(boXmlStr);
			List<ObjectNode> boDefs = JsonUtil.arrayToList(boDefsNode);
			//List<BoDef> boDefs = boDefManager.parseXml(boXmlStr);
			for (int i = 0; i < boDefs.size(); i++) {
				ObjectNode boDefNode = boDefs.get(i);
				BoDefVo boDef = JsonUtil.toBean(boDefNode.toString(), BoDefVo.class);
				//BoDef boDef = boDefs.get(i);
				String alias = boDef.getAlias();

				ObjectNode boDefOldNode = formFeignService.getBODefByAlias(alias);
				//BoDefVo boDefOld = JsonUtil.toBean(boDefOldNode.toString(), BoDefVo.class);
				//BoDef boDefOld = boDefManager.getByAlias(alias);
				if(boDefOldNode!=null) {
					throw new BaseException(ResponseErrorEnums.NO_PERMISSION, "导入文件建模已经存在，请删除后再导入，导入失败！");
				}
			}

			JSONObject json = JSONUtil.createObj();
			if (StringUtil.isNotEmpty(boXmlStr)) {
				json.set("boXmlStr", boXmlStr);
			}
			if (StringUtil.isNotEmpty(formXmlStr)) {
				json.set("formXmlStr", formXmlStr);
			}
			if (StringUtil.isNotEmpty(formRightsXml)) {
				json.set("formRightsXml", formRightsXml);
			}
			if (StringUtil.isNotEmpty(sysAppsPortalXml)) {
				json.set("sysAppsPortalXml", sysAppsPortalXml);
			}
			if (StringUtil.isNotEmpty(bpmdefsXml)) {
				json.set("bpmdefsXml", bpmdefsXml);
			}
			if (StringUtil.isNotEmpty(formDataTemplatesXml)) {
				json.set("formDataTemplatesXml", formDataTemplatesXml);
			}
			return bpmModelFeignService.importFullXml(json.toString());
		} catch (Exception e) {
			e.printStackTrace();
			return new CommonResult<>(false, "导入失败：" + e.getMessage());
		} finally {
			if (StringUtil.isNotEmpty(unZipFilePath)) {
				File formDir = new File(unZipFilePath);
				if (formDir.exists()) {
					FileUtil.deleteDir(formDir);
				}
			}
		}
	}

	@RequestMapping(value = "import", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "应用导入", httpMethod = "POST", notes = "应用导入")
	public CommonResult<String> importData(MultipartHttpServletRequest request, HttpServletResponse response) throws Exception {
		CommonResult<String> res = sysAppManager.importData(request, response);
		return res;
	}

	/**
	 * 首页门户 获取应用数量统计
	 */
	@GetMapping(value = "/portal/appnum")
	@ApiOperation(value = "首页门户 获取应用数量统计", httpMethod = "GET", notes = "首页门户 获取应用数量统计")
	public JSONObject getPortalUserNum() throws Exception {
		LambdaQueryWrapper<SysApp> wrapper = new LambdaQueryWrapper<SysApp>();
		wrapper.eq(SysApp::getIsPublish, SysApp.IS_PUBLISH);
		Integer num = baseService.count(wrapper);
		JSONObject obj = new JSONObject();
		obj.set("appnum", num);
		return obj;
	}

	/**
	 * 首页门户 通用应用更多
	 */
	@GetMapping(value = "/portal/sysAppOften")
	@ApiOperation(value = "首页门户 通用应用更多", httpMethod = "GET", notes = "首页门户 通用应用更多")
	public List<SysMenu> getPortalSysAppOften(
			@ApiParam(name = "searchWord", value = "应用名称", required = true) @RequestParam(required = false) String searchWord) throws Exception {
		String menuAlias = "app_menu";
		List<SysMenu> list = sysMenuManager.getAppMenuByAuthApp(menuAlias);
		//判断是否根据组织进行过滤
		List<String> extAppIdList = new ArrayList<>();
		String appExtOrgfilter = SysPropertyUtil.getByAlias("appOrgfilter");
		if("true".equals(appExtOrgfilter)) {
			Map<String,Set<String>> userRightMap = currentUserService.getCurUserOrgAndPosRightMap();
			Set<String> set = userRightMap.get("org");
			String orgIds = String.join(",", set);
			String extAppIds = ucFeignService.queryExtAuthAppIdByOrgIds("2", orgIds);
			if(StringUtil.isNotEmpty(extAppIds)) {
				extAppIdList.addAll(Arrays.asList(extAppIds.split(",")));
			}
		}

		//获取用户设置的 通用应用
		IUser user = ContextUtil.getCurrentUser();
		List<SysAppOften> oftenList = sysAppOftenManager.querySysAppOften(user.getUserId(),"0");
		Map<String, String> map = new HashMap<>();
		for (int i = 0; i < oftenList.size(); i++) {
			SysAppOften often = oftenList.get(i);
			if("true".equals(appExtOrgfilter) && !extAppIdList.contains(often.getAppId())) {
				continue;
			}
			map.put(often.getAppId(), "1");
		}

		for (int i = 0; i < list.size(); i++) {
			SysMenu sysMenu = list.get(i);

			Map<String, Object> params = new HashMap<>();
			params.put("menuId", sysMenu.getId());
			if(StringUtil.isNotEmpty(searchWord)) {
				params.put("searchWord", searchWord);
			}
			QueryFilter<SysApp> queryFilter = QueryFilter.build();
			queryFilter.setPageBean(new PageBean(1, PageBean.WITHOUT_PAGE));
			queryFilter.setParams(params);
			PageList<SysApp> pageList = sysAppManager.queryByFilter(queryFilter);
			if (pageList != null && pageList.getRows().size() > 0) {
				List<SysApp> appList = pageList.getRows();
				List<SysApp> sysAppList = new ArrayList<>();
				for (int j = 0; j < appList.size(); j++) {
					SysApp sysApp = appList.get(j);
					if("true".equals(appExtOrgfilter) && !extAppIdList.contains(sysApp.getId())) {
						continue;
					}
					String flag = map.get(sysApp.getId());
					sysApp.setIsAppOften(StringUtil.isEmpty(flag)? (short)0: (short)1);
					sysAppList.add(sysApp);
				}
				sysMenu.getSysAppList().addAll(sysAppList);
			}
		}
		return list;
	}

	/**
	 * 首页门户 加载通用应用
	 */
	@GetMapping(value = "/portal/loadMySysAppOften")
	@ApiOperation(value = "首页门户 加载通用应用", httpMethod = "POST", notes = "首页门户 加载通用应用")
	public List<SysApp> loadMySysAppOften(@ApiParam(name="type",value="0=pc,1=mobile", required = true)@RequestParam String type) throws Exception {
		//获取用户设置的 通用应用
		IUser user = ContextUtil.getCurrentUser();
		List<String> ids = new ArrayList<String>();
		List<SysAppOften> oftenList = sysAppOftenManager.querySysAppOften(user.getUserId(),type);
		for (int i = 0; i <oftenList.size() ; i++) {
			SysAppOften often = oftenList.get(i);
			if(!ids.contains(often.getAppId())) {
				ids.add(often.getAppId());
			}
		}
		//如果不是超级管理员，获取权限应用列表
		if(!user.isAdmin()){
			List<String> authIds = sysAuthUserManager.getAuthorizeIdsByCurUserOrgMap(SysAuthUser.BPMDEFUSER_OBJ_TYPE.SYS_APP);
			ids.retainAll(authIds);
		}
		String appExtOrgfilter = SysPropertyUtil.getByAlias("appOrgfilter");
		if("true".equals(appExtOrgfilter)) {
			Map<String,Set<String>> userRightMap = currentUserService.getCurUserOrgAndPosRightMap();
			Set<String> set = userRightMap.get("org");
			String orgIds = String.join(",", set);
			String authType = "2";
			if(type.equals("0")){
				authType = "2";
			} else {
				authType = "3";
			}
			String extAppIds = ucFeignService.queryExtAuthAppIdByOrgIds(authType, orgIds);
			if(StringUtil.isNotEmpty(extAppIds)) {
				List<String> extAppIdList = new ArrayList<>(Arrays.asList(extAppIds.split(",")));
				ids.retainAll(extAppIdList);
				if(ids.size()<=0) {
					ids.add("0");
				}
			} else {
				ids.clear();
				ids.add("0");
			}
		}
		List<SysApp> list = new ArrayList<>();
		if(ids!=null && ids.size()>0) {
			if(type.equals("0")){
				LambdaQueryWrapper<SysApp> wrapper = new LambdaQueryWrapper<>();
				wrapper.in(SysApp::getId, ids);
				wrapper.eq(SysApp::getIsPublish, SysApp.IS_PUBLISH);
				list = sysAppManager.getBaseMapper().selectList(wrapper);
			}else{
				LambdaQueryWrapper<AppModel> wrapper = new LambdaQueryWrapper<>();
				wrapper.in(AppModel::getId, ids);
				wrapper.eq(AppModel::getEnable, SysApp.IS_PUBLISH);
				List<AppModel> mobileAppList=  appModelManager.getBaseMapper().selectList(wrapper);
				for(int i=0;i<mobileAppList.size();i++){
					AppModel appModel=mobileAppList.get(i);
					SysApp sysApp=new SysApp();
					sysApp.setId(appModel.getId());
					sysApp.setName(appModel.getName());
					sysApp.setIsPublish(SysApp.IS_PUBLISH);
					sysApp.setContent(appModel.getContent());
					sysApp.setIcon(appModel.getIcon());
					sysApp.setIconColor(appModel.getIconColor());
					sysApp.setSn(appModel.getSn());
					sysApp.setMode(appModel.getMode());
					if(appModel.getLocalAuthCode()!=null){
						int value=appModel.getLocalAuthCode();
						sysApp.setLocalAuthCode(Short.parseShort(value+""));
					}else{
						sysApp.setLocalAuthCode((short)0);
					}
					list.add(sysApp);
				}
			}
			list.stream().forEach(i -> i.setIsAppOften((short)1));
		}
		return list;
	}

	/**
	 * 首页门户 加载通用应用
	 */
	@GetMapping(value = "/portal/loadMySysAppOftenByNoAuth")
	@ApiOperation(value = "首页门户 加载通用应用", httpMethod = "POST", notes = "首页门户 加载通用应用")
	public List<SysApp> loadMySysAppOftenByNoAuth(@ApiParam(name="type",value="0=pc,1=mobile", required = true)@RequestParam String type) throws Exception {
		//获取用户设置的 通用应用
		JsonNode userJson=ucFeignService.getUser("admin","");
		String userId=userJson.get("id").asText();
		List<String> ids = new ArrayList<String>();
		List<SysAppOften> oftenList = sysAppOftenManager.querySysAppOften(userId,type);
		for (int i = 0; i <oftenList.size() ; i++) {
			SysAppOften often = oftenList.get(i);
			if(!ids.contains(often.getAppId())) {
				ids.add(often.getAppId());
			}
		}
		List<SysApp> list = new ArrayList<>();
		if(ids!=null && ids.size()>0) {
			if(type.equals("0")){
				LambdaQueryWrapper<SysApp> wrapper = new LambdaQueryWrapper<>();
				wrapper.in(SysApp::getId, ids);
				wrapper.eq(SysApp::getIsPublish, SysApp.IS_PUBLISH);
				list = sysAppManager.getBaseMapper().selectList(wrapper);
			}else{
				LambdaQueryWrapper<AppModel> wrapper = new LambdaQueryWrapper<>();
				wrapper.in(AppModel::getId, ids);
				wrapper.eq(AppModel::getEnable, SysApp.IS_PUBLISH);
				List<AppModel> mobileAppList=  appModelManager.getBaseMapper().selectList(wrapper);
				for(int i=0;i<mobileAppList.size();i++){
					AppModel appModel=mobileAppList.get(i);
					SysApp sysApp=new SysApp();
					sysApp.setId(appModel.getId());
					sysApp.setName(appModel.getName());
					sysApp.setIsPublish(SysApp.IS_PUBLISH);
					sysApp.setContent(appModel.getContent());
					sysApp.setIcon(appModel.getIcon());
					sysApp.setIconColor(appModel.getIconColor());
					sysApp.setSn(appModel.getSn());
					sysApp.setMode(appModel.getMode());
					if(appModel.getLocalAuthCode()!=null){
						int value=appModel.getLocalAuthCode();
						sysApp.setLocalAuthCode(Short.parseShort(value+""));
					}else{
						sysApp.setLocalAuthCode((short)0);
					}

					list.add(sysApp);
				}
			}
			list.stream().forEach(i -> i.setIsAppOften((short)1));
		}
		return list;
	}

	/**
	 * 首页门户 保存通用应用
	 */
	@PostMapping(value = "/portal/saveMySysAppOften")
	@ApiOperation(value = "首页门户 保存通用应用", httpMethod = "POST", notes = "首页门户 保存通用应用")
	public CommonResult<String> saveMySysAppOften(@ApiParam(name="ids",value="应用主键数组,多个应用主键之间用逗号分隔", required = true)@RequestBody String reqStr) throws Exception {
		IUser user = ContextUtil.getCurrentUser();
		JSONObject reqInfo = new JSONObject(reqStr);
		String str = reqInfo.getStr("ids");
		String type = reqInfo.getStr("type");
		String[] ids = str.split(",");
		sysAppOftenManager.removeByUserIdAndAppId(user.getUserId(), null,type);
		List<SysAppOften> oftenList = new ArrayList<>();
		for (int i = 0; i < ids.length; i++) {
			String appId = ids[i];
			SysAppOften often = new SysAppOften();
			often.setId(UniqueIdUtil.getSuid());
			often.setAppId(appId);
			often.setUserId(user.getUserId());
			often.setUserName(user.getFullname());
			often.setOrder(i);
			often.setType(type);
			oftenList.add(often);
		}
		if(oftenList.size()>0) {
			sysAppOftenManager.saveBatch(oftenList);
		}
		return new CommonResult<String>("添加常用应用成功");
	}


}