package com.hotent.portal.controller;


import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.hotent.base.enums.ResponseErrorEnums;
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.Base64;
import com.hotent.portal.model.SysIndexColumn;
import com.hotent.portal.model.SysIndexLayoutManage;
import com.hotent.portal.persistence.manager.SysIndexColumnManager;
import com.hotent.portal.persistence.manager.SysIndexLayoutManageManager;
import com.hotent.sys.persistence.manager.*;
import com.hotent.sys.persistence.model.SysApp;
import com.hotent.sys.persistence.model.SysAuthUser;
import com.hotent.sys.persistence.model.SysModuleDetail;
import com.hotent.uc.api.impl.model.Org;
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.model.IUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.hotent.base.annotation.ApiGroup;
import com.hotent.base.constants.ApiGroupConsts;
import com.hotent.base.controller.BaseController;
import com.hotent.base.model.CommonResult;
import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.HttpUtil;
import com.hotent.base.util.JsonUtil;
import com.hotent.base.util.StringUtil;
import com.hotent.base.util.UniqueIdUtil;
import com.hotent.base.util.time.DateFormatUtil;
import com.hotent.i18n.util.I18nUtil;
import com.hotent.portal.params.TemplateToMenuVo;
import com.hotent.sys.constants.FrontTypeConstant;
import com.hotent.sys.persistence.model.SysMenu;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;


/**
 * 系统菜单 控制器类
 *
 * @company 广州宏天软件股份有限公司
 * @author liyg
 * @email liyg@jee-soft.cn
 * @date 2018-07-02 17:18:55
 */
@RestController
@RequestMapping("/sys/sysMenu/v1")
@Api(tags="系统菜单")
@ApiGroup(group= {ApiGroupConsts.GROUP_PORTAL})
public class SysMenuController extends BaseController<SysMenuManager, SysMenu>{
	@Resource
	SysMenuManager sysMenuManager;
	@Resource
	SysMethodManager sysMethodManager;
	@Value("${qzSetting.isHiddenSysMenu:''}")
	private String isHiddenSysMenu;

	@Resource
	SysAppManager sysAppManager;
	@Resource
	UCFeignService ucFeignService;
	@Resource
	SysAuthUserManager sysAuthUserManager;
//	@Autowired
//	UserManager userService;
	@Resource
	BpmRuntimeFeignService bpmRuntimeFeignService;
	@Resource
	SysIndexLayoutManageManager sysIndexLayoutManageService;
	@Resource
	SysIndexColumnManager sysIndexColumnService;
//	@Autowired
//	FormDataTemplateManager formDataTemplateManager;
	@Autowired
	SysModuleDetailManager sysModuleDetailManager;
//	@Autowired
//	OrgManager orgService;
	@Resource
	UCFeignService uCFeignService;
	@Resource
	FormFeignService formFeignService;

	@RequestMapping(value="listJson", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "菜单资源数据", httpMethod = "POST", notes = "菜单资源数据")
	public PageList<SysMenu> listJson(@ApiParam(name="queryFilter",value="通用查询对象")@RequestBody QueryFilter<SysMenu> queryFilter) throws Exception {
		return sysMenuManager.query(queryFilter);
	}

	@RequestMapping(value="getTreeByExtOrgId", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得树形菜单(扩展组织id)", httpMethod = "GET", notes = "获得树形菜单(扩展组织id)")
	public List<SysMenu> getTreeByExtOrgId(@ApiParam(name="orgId",value="组织id", required = true)@RequestParam(required=true) String orgId) throws Exception {
		IUser user = ContextUtil.getCurrentUser(); //获取当前用户
		ObjectNode orgNode = uCFeignService.getOrgById(orgId);
		Org org = JsonUtil.toBean(orgNode.toString(), Org.class);
		String parentId = org.getParentId();
		List<SysMenu> list = new ArrayList<>();
		if("0".equals(parentId)) {
			//第一层组织
			if(user.isAdmin()) {
				list = sysMenuManager.getAllByTenant("");
			} else {
				list = sysMenuManager.getTreeByTenantByExtOrgId(orgId);
			}
		} else {
			list = sysMenuManager.getTreeByTenantByExtOrgId(parentId);
		}
		list=BeanUtils.listToTree(list);
		return list;
	}

	@RequestMapping(value="getTree", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得树形菜单", httpMethod = "GET", notes = "获得树形菜单")
	public List<SysMenu> getTree(@ApiParam(name="ignoreAlias",value="忽略菜单（多个用逗号隔开）", required = true)@RequestParam Optional<String> ignoreAlias) throws Exception {
		List<SysMenu> list =sysMenuManager.getAllByTenant(ignoreAlias.orElse(""));
		list=BeanUtils.listToTree(list);
		return list;
	}

	@RequestMapping(value="getTreeByFree", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得树形菜单(免授权的树形菜单列表)", httpMethod = "GET", notes = "获得树形菜单(免授权的树形菜单列表)")
	public List<SysMenu> getTreeByFree(@ApiParam(name="menuId",value="菜单id", required = true)@RequestParam String menuId) throws Exception {
		SysMenu sysMenu = sysMenuManager.getById(menuId);
		String path = sysMenu.getPath();
		List<SysMenu> list = sysMenuManager.getByChidrensParentPath(path);
		list=BeanUtils.listToTree(list);
		return list;
	}

	@RequestMapping(value="saveMenus", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "保存资源菜单", httpMethod = "POST", notes = "保存资源菜单")
	public CommonResult<String> saveMenus(@ApiParam(name="list",value="菜单列表")@RequestBody List<SysMenu> list) throws Exception {
		CommonResult<String> res=sysMenuManager.saveMenus(list);
		return res;
	}

	/**
	 *
	 * @param roleAlias
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getMenuByRoleAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得角色树形菜单", httpMethod = "GET", notes = "获得角色树形菜单")
	public List<SysMenu> getMenuByRoleAlias(@ApiParam(name="roleAlias",value="角色别名", required = true)@RequestParam String roleAlias) throws Exception {
		return sysMenuManager.getMenuByRoleAlias(roleAlias);
	}

	/**
	 *
	 * @param roleAlias
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getAllMenuRoleAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得角色树形菜单", httpMethod = "GET", notes = "获得角色树形菜单")
	public ArrayList<Map<String,Object>> getAllMenuRoleAlias(@ApiParam(name="roleAlias",value="角色别名", required = true)@RequestParam String roleAlias) throws Exception {
		return (ArrayList<Map<String, Object>>) sysMenuManager.getAllMenuRoleAlias(roleAlias);
	}

	@RequestMapping(value="getMenuRoleAliasByExtOrgId", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得角色树形菜单(扩展组织id)", httpMethod = "GET", notes = "获得角色树形菜单(扩展组织id)")
	public ArrayList<Map<String,Object>> getMenuRoleAliasByExtOrgId(
			@ApiParam(name="roleAlias",value="角色别名", required = true)@RequestParam String roleAlias,
			@ApiParam(name="orgId",value="组织id", required = true)@RequestParam(required=true) String orgId) throws Exception {
		IUser user = ContextUtil.getCurrentUser(); //获取当前用户
		ObjectNode orgNode = uCFeignService.getOrgById(orgId);
		Org org = JsonUtil.toBean(orgNode.toString(), Org.class);
		//Org org = orgService.getById(orgId);
		String parentId = org.getParentId();
		if("0".equals(parentId)) {
			//第一层组织
			if(user.isAdmin()) {
				return (ArrayList<Map<String, Object>>) sysMenuManager.getAllMenuRoleAliasByExtOrgId(roleAlias, orgId);
			} else {
				return (ArrayList<Map<String, Object>>) sysMenuManager.getMenuRoleAliasByExtOrgId(roleAlias, orgId, orgId);
			}
		} else {
			return (ArrayList<Map<String, Object>>) sysMenuManager.getMenuRoleAliasByExtOrgId(roleAlias, parentId, orgId);
		}
	}

	@RequestMapping(value="getMenuByExtOrgId", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获得树形菜单(扩展组织id)", httpMethod = "GET", notes = "获得树形菜单(扩展组织id)")
	public ArrayList<Map<String,Object>> getMenuByExtOrgId(
			@ApiParam(name="orgId",value="组织id", required = true)@RequestParam(required=true) String orgId) throws Exception {
		IUser user = ContextUtil.getCurrentUser(); //获取当前用户
		ObjectNode orgNode = uCFeignService.getOrgById(orgId);
		Org org = JsonUtil.toBean(orgNode.toString(), Org.class);
		String parentId = org.getParentId();
		if("0".equals(parentId)) {
			//第一层组织
			if(user.isAdmin()) {
				return (ArrayList<Map<String, Object>>) sysMenuManager.getAllMenuByExtOrgId(orgId);
			} else {
				return (ArrayList<Map<String, Object>>) sysMenuManager.getMenuByExtOrgId(orgId, orgId);
			}
		} else {
			return (ArrayList<Map<String, Object>>) sysMenuManager.getMenuByExtOrgId(parentId, orgId);
		}
	}

	/**
	 * 通过角色别名 获取 授权的菜单
	 * @author: 梁宏锦
	 * @date: 2024/04/10
	 * @param roleAlias: 角色别名 xgly,xtgly
	 * @param parentId: 菜单跟目录id
	 * @param userId: 用户id(应用端 加载门户栏目/流程/应用 时需要)
	 * @param checked: 筛选是否选中
	 * @return: java.util.ArrayList<java.util.Map<java.lang.String,java.lang.Object>>
	 **/
	@RequestMapping(value = "getCheckMenuByRoleAlias", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "通过角色别名 获取 授权的菜单", httpMethod = "GET", notes = "通过角色别名 获取 授权的菜单")
	public CommonResult<List<SysMenu>> getCheckMenuByRoleAlias(
			@ApiParam(name = "roleAlias", value = "角色别名", required = true) @RequestParam(required = false) String roleAlias,
			@ApiParam(name = "parentId", value = "截取父级", required = false) @RequestParam(required = false) String parentId,
			@ApiParam(name = "userId", value = "用户id", required = false) @RequestParam(required = false) String userId,
			@ApiParam(name = "checked", value = "获取已授权菜单", required = false) @RequestParam(required = false) String checked
	) throws Exception {
		if (StringUtil.isEmpty(parentId)) {
			parentId = "-1";
		}
		SysMenu menu = sysMenuManager.getById(parentId);
		String path = menu.getPath() + '%';
		parentId = menu.getParentId();

		List<String> alias = null;
		if(StringUtil.isNotEmpty(roleAlias)) {
			alias = new ArrayList<>();
			alias = Arrays.asList(roleAlias.split(","));
		}
		List<Map<String, Object>> list = sysMenuManager.getCheckMenuByRoleAlias(alias, path, checked);
		List<SysMenu> menuList = list.stream()
				.map(map -> {
					String type = (String)map.get("type_");
					String routeExtend = (String)map.get("route_extend_");

					SysMenu sysMenu = new SysMenu();
					sysMenu.setId((String) map.get("id"));
					sysMenu.setParentId((String) map.get("parentId"));
					sysMenu.setName((String) map.get("name"));
					sysMenu.setAlias((String) map.get("alias"));
					sysMenu.setRouterExtend("menu");
					sysMenu.setSn((Integer) map.get("sn"));
					sysMenu.setTenantId((String) map.get("tenant_id_"));
					sysMenu.setIsParent(String.valueOf(map.get("isParent")));
					sysMenu.setCheck(String.valueOf(map.get("checked")));
					this.getRouteExtend(sysMenu, type, routeExtend);
					return sysMenu;
				})
				.collect(Collectors.toList());
		//应用端 添加 首页门户及栏目信息
		this.addMenuByHomeIndex(userId, menuList);
		//应用端 添加门户及栏目信息
		this.addMenuByPotal(userId, menuList);
		//应用端 新建流程 添加应用
		this.addMenuByBpmCenterApply(userId, menuList);
		//应用端 应用中心 添加应用
		this.addMenuByAppCenterApply(userId, menuList);
		//管理端 菜单 添加应用
		this.addMenuByMenuAlias(userId, menuList);
		//管理端 菜单 添加大屏菜单
		this.addDatavMenuByAlias(userId, menuList);
		List<SysMenu> result = this.filterByMenuAlias(parentId, menuList);

		CommonResult<List<SysMenu>> res = new CommonResult(ResponseErrorEnums.SUCCESS_OPTION);
		res.setValue(result);
		return res;
	}

	/**
	 * 解析系统菜单 路由配置
	 * @author: 梁宏锦
	 * @date: 2024/04/24
	 * @param sysMenu: 系统菜单
	 * @param type: 菜单类型
	 * @param routeExtend: 路由信息
	 * @return: void
	 **/
	private void getRouteExtend(SysMenu sysMenu, String type, String routeExtend) {
		if(!"page".equals(type)) {
			return;
		}
		try {
			JsonNode jsonNode = JsonUtil.toJsonNode(routeExtend);
			String route_component = jsonNode.get("component").asText();
			String route_path = jsonNode.get("path").asText();
			//解析门户信息
			if("indexLayout".equals(route_component)) {
				int route_index = route_path.indexOf('=');
				if (route_index != -1) {
					String route_alias = route_path.substring(route_index + 1);
					sysMenu.setActiveTab("indexLayout");
					sysMenu.setAlias(route_alias);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 遍历门户 下级栏目信息
	 * @author: 梁宏锦
	 * @date: 2024/04/24
	 * @param columnList: 栏目结果集
	 * @param jsonNode: 节点信息
	 * @return: void
	 **/
	private void traverse(List<String> columnList, JsonNode jsonNode) {
		if (jsonNode.isObject()) {
			Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
			while (fields.hasNext()) {
				Map.Entry<String, JsonNode> entry = fields.next();
				String key = entry.getKey();
				JsonNode value = entry.getValue();
				if("alias".equals(key)) {
					String val = value.asText();
					if(!columnList.contains(val)) {
						columnList.add(val);
					}
				}
				traverse(columnList, value);
			}
		} else if (jsonNode.isArray()) {
			for (int i = 0; i < jsonNode.size(); i++) {
				traverse(columnList, jsonNode.get(i));
			}
		}
	}

	/**
	 * 管理端 菜单 添加大屏信息
	 * @author: 梁宏锦
	 * @date: 2024/04/25
	 * @param userId: 用户id
	 * @param menuList: 菜单信息
	 * @return: java.util.List<com.hotent.sys.persistence.model.SysMenu>
	 **/
	private void addDatavMenuByAlias(String userId, List<SysMenu> menuList) throws Exception {
		List<SysMenu> mSysMenuList  = menuList.stream()
				.filter(sysMenu -> "menu".equals(sysMenu.getRouteExtend()) && sysMenu.getAlias().startsWith("datavShow/"))
				.collect(Collectors.toList());

		for (int num = 0; num < mSysMenuList.size() ; num++) {
			SysMenu sysMenu = mSysMenuList.get(num);
			String menuAlias = sysMenu.getAlias();
			String[] parts = menuAlias.split("/");
			String alias = parts[1];

			QueryFilter<SysIndexLayoutManage> queryFilter = QueryFilter.build();
			queryFilter.withPage(new PageBean(1, PageBean.WITHOUT_PAGE));
			queryFilter.addFilter("TYPE_", "datav", QueryOP.EQUAL);
			queryFilter.addFilter("ALIAS", alias, QueryOP.EQUAL);
			queryFilter.addFilter("IS_DEF", "0", QueryOP.EQUAL);
			PageList<SysIndexLayoutManage> page = sysIndexLayoutManageService.query(queryFilter);
			if(page.getRows()==null || page.getRows().size()<=0) {
				return;
			}
			SysIndexLayoutManage sysIndexLayoutManage = page.getRows().get(0);
			String formDataTemplateId = sysMenu.getId() + "_" + sysIndexLayoutManage.getId();

			SysMenu menu = new SysMenu();
			menu.setId(formDataTemplateId);
			menu.setParentId(sysMenu.getId());
			menu.setName(sysIndexLayoutManage.getName());
			menu.setRouterExtend("datav");
			menu.setType("");
			menu.setAlias(sysIndexLayoutManage.getAlias());
			menu.setActiveTab(sysIndexLayoutManage.getId());
			menu.setHref("");
			menu.setSn(0);
			menu.setTenantId("");
			menu.setIsParent("0");
			menu.setCheck("0");
			menuList.add(menu);
		}
	}

	/**
	 * 管理端 菜单 添加应用信息
	 * @author: 梁宏锦
	 * @date: 2024/04/25
	 * @param userId: 用户id
	 * @param menuList: 菜单信息
	 * @return: java.util.List<com.hotent.sys.persistence.model.SysMenu>
	 **/
	private void addMenuByMenuAlias(String userId, List<SysMenu> menuList) throws Exception {
		List<SysMenu> mSysMenuList  = menuList.stream()
				.filter(sysMenu -> "menu".equals(sysMenu.getRouteExtend()) && sysMenu.getAlias().startsWith("templateShow/"))
				.collect(Collectors.toList());

		for (int num = 0; num < mSysMenuList.size() ; num++) {
			SysMenu sysMenu = mSysMenuList.get(num);
			String menuAlias = sysMenu.getAlias();
			String[] parts = menuAlias.split("/");
			String alias = parts[1];

			ObjectNode formDataTemplateNode = formFeignService.getFormDataTemplateByAlias(alias);
			FormDataTemplateVo formDataTemplate = JsonUtil.toBean(formDataTemplateNode.toString(), FormDataTemplateVo.class);
			//FormDataTemplate formDataTemplate = formDataTemplateManager.getByAlias(alias);
			String formDataTemplateId = sysMenu.getId() + "_" + formDataTemplate.getId();

			SysMenu menu = new SysMenu();
			menu.setId(formDataTemplateId);
			menu.setParentId(sysMenu.getId());
			menu.setName(formDataTemplate.getName());
			menu.setRouterExtend("template");
			menu.setType("");
			menu.setAlias(formDataTemplate.getAlias());
			menu.setActiveTab(formDataTemplate.getId());
			menu.setHref("");
			menu.setSn(0);
			menu.setTenantId("");
			menu.setIsParent("0");
			menu.setCheck("0");
			menuList.add(menu);
		}
	}

	/**
	 * 应用端 首页 添加门户及栏目信息
	 * @author: 梁宏锦
	 * @date: 2024/04/11
	 * @param userId: 用户id
	 * @param menuList: 菜单信息
	 * @return: java.util.List<com.hotent.sys.persistence.model.SysMenu>
	 **/
	private void addMenuByHomeIndex(String userId, List<SysMenu> menuList) throws Exception {
		//if(StringUtil.isEmpty(userId)){
		//	return;
		//}

		Optional<SysMenu> mSysMenu  = menuList.stream()
				.filter(sysMenu -> "menu".equals(sysMenu.getRouteExtend()) && "Index".equals(sysMenu.getAlias()))
				.findFirst();

		if (mSysMenu.isPresent()) {
			SysMenu sysMenu = mSysMenu.get();

			List<SysIndexLayoutManage> list = sysIndexLayoutManageService.getByAlias("default_front");
			if(list==null || list.size()<=0) {
				return;
			}
			Optional<SysIndexLayoutManage> optional = list.stream()
					.filter(item -> "column".equals(item.getType()))
					.findFirst();
			if (!optional.isPresent()) {
				return;
			}
			SysIndexLayoutManage sysIndexLayoutManage = optional.get();
			String designHtmlEnc = sysIndexLayoutManage.getDesignHtml();
			String indexLayoutManageId = sysMenu.getId() + "_" + sysIndexLayoutManage.getId();

			SysMenu menu = new SysMenu();
			menu.setId(indexLayoutManageId);
			menu.setParentId(sysMenu.getId());
			menu.setName(sysIndexLayoutManage.getName());
			menu.setRouterExtend("layoutManage");
			menu.setType(String.valueOf(sysIndexLayoutManage.getLayoutType())); //0:PC端  1:手机端 2:应用端
			menu.setAlias(sysIndexLayoutManage.getAlias());
			menu.setActiveTab("");
			menu.setHref("");
			menu.setSn(0);
			menu.setTenantId("");
			menu.setIsParent("0");
			menu.setCheck("0");
			menuList.add(menu);

			JsonNode designNode;
			if(StringUtil.isNotEmpty(designHtmlEnc)) {
				String designHtml = new String(Base64.decodeBase64(designHtmlEnc), StandardCharsets.UTF_8);
				designNode = JsonUtil.toJsonNode(designHtml);

				List<String> columnList = new ArrayList<>();
				this.traverse(columnList, designNode); //遍历栏目所有属性

				if(columnList!=null && columnList.size()>0) {
					QueryFilter<SysIndexColumn> queryFilter = QueryFilter.build();
					queryFilter.withPage(new PageBean(0, PageBean.WITHOUT_PAGE));
					queryFilter.addFilter("alias", columnList, QueryOP.IN, FieldRelation.AND);
					PageList<SysIndexColumn> pageColumnList = sysIndexColumnService.query(queryFilter);
					List<SysIndexColumn> indexColumnList = pageColumnList.getRows();
					for (int i = 0; i < indexColumnList.size(); i++) {
						SysIndexColumn sysIndexColumn = indexColumnList.get(i);

						SysMenu menu_c = new SysMenu();
						menu_c.setId(sysMenu.getId() + "_" + sysIndexColumn.getId());
						menu_c.setParentId(indexLayoutManageId);
						menu_c.setName(sysIndexColumn.getName());
						menu_c.setRouterExtend("indexColumn");
						menu_c.setType(String.valueOf(sysIndexColumn.getIsPublic())); //0:PC端  1:手机端 2:应用端
						menu_c.setAlias(sysIndexColumn.getAlias());
						menu_c.setActiveTab(sysIndexColumn.getId());
						menu_c.setHref("");
						menu_c.setSn(0);
						menu_c.setTenantId("");
						menu_c.setIsParent("0");
						menu_c.setCheck("0");
						menuList.add(menu_c);
					}
				}
			}
		}
	}

	/**
	 * 应用端 添加门户及栏目信息
	 * @author: 梁宏锦
	 * @date: 2024/04/11
	 * @param userId: 用户id
	 * @param menuList: 菜单信息
	 * @return: java.util.List<com.hotent.sys.persistence.model.SysMenu>
	 **/
	private void addMenuByPotal(String userId, List<SysMenu> menuList) throws Exception {
		//if(StringUtil.isEmpty(userId)){
		//	return;
		//}

		List<SysMenu> mSysMenuList  = menuList.stream()
				.filter(sysMenu -> "menu".equals(sysMenu.getRouteExtend()) && "indexLayout".equals(sysMenu.getActiveTab()))
				.collect(Collectors.toList());

		for (int num = 0; num < mSysMenuList.size() ; num++) {
			SysMenu sysMenu = mSysMenuList.get(num);
			String alias = sysMenu.getAlias();

			List<SysIndexLayoutManage> list = sysIndexLayoutManageService.getByAlias(alias);
			if(list==null || list.size()<=0) {
				return;
			}
			Optional<SysIndexLayoutManage> optional = list.stream()
					.filter(item -> "column".equals(item.getType()))
					.findFirst();
			if (!optional.isPresent()) {
				return;
			}
			SysIndexLayoutManage sysIndexLayoutManage = optional.get();
			String designHtmlEnc = sysIndexLayoutManage.getDesignHtml();
			String indexLayoutManageId = sysMenu.getId() + "_" + sysIndexLayoutManage.getId();

			SysMenu menu = new SysMenu();
			menu.setId(indexLayoutManageId);
			menu.setParentId(sysMenu.getId());
			menu.setName(sysIndexLayoutManage.getName());
			menu.setRouterExtend("layoutManage");
			menu.setType(String.valueOf(sysIndexLayoutManage.getLayoutType())); //0:PC端  1:手机端 2:应用端
			menu.setAlias(sysIndexLayoutManage.getAlias());
			menu.setActiveTab("");
			menu.setHref("");
			menu.setSn(0);
			menu.setTenantId("");
			menu.setIsParent("0");
			menu.setCheck("0");
			menuList.add(menu);

			JsonNode designNode;
			if(StringUtil.isNotEmpty(designHtmlEnc)) {
				String designHtml = new String(Base64.decodeBase64(designHtmlEnc), StandardCharsets.UTF_8);
				designNode = JsonUtil.toJsonNode(designHtml);

				List<String> columnList = new ArrayList<>();
				this.traverse(columnList, designNode); //遍历栏目所有属性

				if(columnList!=null && columnList.size()>0) {
					QueryFilter<SysIndexColumn> queryFilter = QueryFilter.build();
					queryFilter.withPage(new PageBean(0, PageBean.WITHOUT_PAGE));
					queryFilter.addFilter("alias", columnList, QueryOP.IN, FieldRelation.AND);
					PageList<SysIndexColumn> pageColumnList = sysIndexColumnService.query(queryFilter);
					List<SysIndexColumn> indexColumnList = pageColumnList.getRows();
					for (int i = 0; i < indexColumnList.size(); i++) {
						SysIndexColumn sysIndexColumn = indexColumnList.get(i);

						SysMenu menu_c = new SysMenu();
						menu_c.setId(sysMenu.getId() + "_" + sysIndexColumn.getId());
						menu_c.setParentId(indexLayoutManageId);
						menu_c.setName(sysIndexColumn.getName());
						menu_c.setRouterExtend("indexColumn");
						menu_c.setType(String.valueOf(sysIndexColumn.getIsPublic())); //0:PC端  1:手机端 2:应用端
						menu_c.setAlias(sysIndexColumn.getAlias());
						menu_c.setActiveTab(sysIndexColumn.getId());
						menu_c.setHref("");
						menu_c.setSn(0);
						menu_c.setTenantId("");
						menu_c.setIsParent("0");
						menu_c.setCheck("0");
						menuList.add(menu_c);
					}
				}
			}
		}
	}

	/**
	 * 应用端 新建流程 添加应用
	 * @author: 梁宏锦
	 * @date: 2024/04/11
	 * @param userId: 用户id
	 * @param menuList: 菜单信息
	 * @return: java.util.List<com.hotent.sys.persistence.model.SysMenu>
	 **/
	private void addMenuByBpmCenterApply(String userId, List<SysMenu> menuList) throws Exception {
		Optional<SysMenu> mSysMenu  = menuList.stream()
				.filter(sysMenu -> "menu".equals(sysMenu.getRouteExtend()) && sysMenu.getAlias().equals("new"))
				.findFirst();

		if (mSysMenu.isPresent()) {
			SysMenu sysMenu = mSysMenu.get();

			ArrayNode childrenNode = null;
			if(StringUtil.isNotEmpty(userId)){
				CommonResult<JsonNode> userNode = ucFeignService.getUserById(userId);
				String account = userNode.getValue().get("account").asText();
				QueryFilter<SysApp> queryFilter = QueryFilter.build();
				queryFilter.withPage(new PageBean(0, PageBean.WITHOUT_PAGE));
				ObjectNode objectNode = bpmRuntimeFeignService.queryNewProcessListByUserAccount(account, queryFilter);
				childrenNode = (ArrayNode)objectNode.get("rows");
			} else {
				QueryFilter<SysApp> queryFilter = QueryFilter.build();
				queryFilter.withPage(new PageBean(0, PageBean.WITHOUT_PAGE));
				ObjectNode objectNode = bpmRuntimeFeignService.queryNewProcessListAll(queryFilter);
				childrenNode = (ArrayNode)objectNode.get("rows");
			}

			for (int i = 0; i < childrenNode.size(); i++) {
				JsonNode node = childrenNode.get(i);

				String id = node.get("id").asText();
				String defId = node.get("defId").asText();
				String name = node.get("name").asText();
				String defKey = node.get("defKey").asText();
				ObjectNode authorizeRightNode = (ObjectNode)node.get("authorizeRight");
				String authorizeRight = JsonUtil.toJson(authorizeRightNode);

				SysMenu menu = new SysMenu();
				menu.setId(sysMenu.getId() + "_" + id);
				menu.setParentId(sysMenu.getId());
				menu.setName(name);
				menu.setRouterExtend("flow");
				menu.setType("7"); //流程模块
				menu.setAlias(defKey);
				menu.setActiveTab(defId);
				menu.setHref(authorizeRight);
				menu.setSn(0);
				menu.setTenantId("");
				menu.setIsParent("0");
				menu.setCheck("0");
				menuList.add(menu);
			}
		}
	}

	/**
	 * 应用端 应用中心 添加应用
	 * @author: 梁宏锦
	 * @date: 2024/04/11
	 * @param userId: 用户id
	 * @param menuList: 菜单信息
	 * @return: java.util.List<com.hotent.sys.persistence.model.SysMenu>
	 **/
	private void addMenuByAppCenterApply(String userId, List<SysMenu> menuList) throws IOException {
		//if(StringUtil.isEmpty(userId)){
		//	return;
		//}

		Optional<SysMenu> mSysMenu  = menuList.stream()
				.filter(sysMenu -> "menu".equals(sysMenu.getRouteExtend()) && sysMenu.getAlias().equals("appCenter2"))
				.findFirst();

		if (mSysMenu.isPresent()) {
			SysMenu sysMenu = mSysMenu.get();

			QueryFilter<SysApp> queryFilter = QueryFilter.build();
			queryFilter.withPage(new PageBean(0, PageBean.WITHOUT_PAGE));
			List<FieldSort> sorter = queryFilter.getSorter();
			sorter.add(new FieldSort("SN_", Direction.ASC));
			queryFilter.setSorter(sorter);


			if(StringUtil.isNotEmpty(userId)){
				Map<String, Map<String, String>> map = ucFeignService.getUserRightMapByIds(userId);
				Map<String, String> userRightMap = map.get(userId);
				if(userRightMap.get("position")!=null) {
					userRightMap.put("pos", userRightMap.get("position"));
				}
				List<String> authIds = sysAuthUserManager.getAuthorizeIdsByUserMap(userRightMap, SysAuthUser.BPMDEFUSER_OBJ_TYPE.SYS_APP);
				queryFilter.addFilter("ID_", authIds, QueryOP.IN);
			}

			PageList<SysApp> sysAppPage = sysAppManager.query(queryFilter);
			List<SysApp> list = sysAppPage.getRows();
			for (int i = 0; i < list.size() ; i++) {
				SysApp app = list.get(i);
				String appId = app.getId();
				Short type = app.getType();
				String content = app.getContent();
				Short isPublish = app.getIsPublish();
				if (isPublish.intValue()!=1) {
					continue; //未发布不展示
				}
				String app_content = "";
				String app_id = "";
				String app_alias = "";
				String type_name = "";
				if(StringUtil.isNotEmpty(content) && content.startsWith("{")) {
					JSONObject json = JSONUtil.parseObj(content);
					app_content = json.toString();
					//type 9:datav大屏 8:流程 7:流程模块 6:表单 2:表单列表 (5:网页跳转 4:图表 3:数据列表 1:常规应用)
					if (type.intValue()==9) {
						app_alias = json.getStr("alias"); //datav大屏
						app_id = json.getStr("id");
						type_name = "datav大屏";
					} else if (type.intValue()==8) {
						app_alias = json.getStr("key"); //流程
						app_id = json.getStr("id");
						type_name = "流程";
					} else if (type.intValue()==7) {
						app_alias = json.getStr("id"); //没有别名
						app_id = json.getStr("id"); //流程模块
						type_name = "流程模块";
					} else if (type.intValue()==6) {
						app_alias = json.getStr("key"); //表单
						app_id = json.getStr("id");
						type_name = "表单";
					} else if (type.intValue()==2) {
						app_alias = json.getStr("alias"); //表单列表
						app_id = json.getStr("id");
						type_name = "表单列表";
					} else if (type.intValue()==5) {
						app_alias = appId; //没有别名
						type_name = "网页跳转";
					} else if (type.intValue()==4) {
						app_alias = json.getStr("id"); //没有别名
						type_name = "图表";
					} else if (type.intValue()==3) {
						app_alias = appId; //没有别名
						type_name = "数据列表";
					} else if (type.intValue()==1) {
						app_alias = appId; //没有别名
						type_name = "常规应用";
					}
				} else {
					if (type.intValue()==5) {
						app_alias = appId; //没有别名
						type_name = "网页跳转";
					} else if (type.intValue()==3) {
						app_alias = appId; //没有别名
						type_name = "数据列表";
					} else if (type.intValue()==1) {
						app_alias = appId; //没有别名
						type_name = "常规应用";
					}
				}
				String menuId = sysMenu.getId() + "_" + app.getId();
				SysMenu menu = new SysMenu();
				menu.setId(menuId);
				menu.setParentId(sysMenu.getId());
				menu.setName(app.getName());
				menu.setRouterExtend("app");
				menu.setType(String.valueOf(type));
				menu.setTabsStyle(type_name);
				menu.setAlias(app_alias);
				menu.setActiveTab(app_id);
				menu.setHref(app_content);
				menu.setSn(app.getSn());
				menu.setTenantId(app.getTenantId());
				menu.setIsParent("0");
				menu.setCheck("0");
				menuList.add(menu);

				//加载 流程模块 下级应用列表
				if (type.intValue()==7) {
					this.addMenuBySysModule(menuList, menuId,  app_id);
				}
			}
		}
	}


	/**
	 * 加载app应用中 流程模块列表
	 * @author: 梁宏锦
	 * @date: 2024/05/27
	 * @param menuList: 菜单列表
	 * @param parentMenuId: 父菜单id
	 * @param moduleId: 流程模块Id
	 **/
	private void addMenuBySysModule(List<SysMenu> menuList, String parentMenuId,  String moduleId) throws IOException {
		List<SysModuleDetail> moduleDetailList = sysModuleDetailManager.getModuleDetail(moduleId, "datalist");
		for (int j = 0; j < moduleDetailList.size() ; j++) {
			SysModuleDetail detail = moduleDetailList.get(j);
			String detailAlias = detail.getCode();

			ObjectNode formDataTemplateNode = formFeignService.getFormDataTemplateByAlias(detailAlias);
			FormDataTemplateVo formDataTemplate = JsonUtil.toBean(formDataTemplateNode.toString(), FormDataTemplateVo.class);
			//FormDataTemplate formDataTemplate = formDataTemplateManager.getByAlias(detailAlias);
			String formDataTemplateId = parentMenuId + "_" + formDataTemplate.getId() + "_" + j;

			SysMenu menu = new SysMenu();
			menu.setId(formDataTemplateId);
			menu.setParentId(parentMenuId);
			menu.setName(formDataTemplate.getName());
			menu.setRouterExtend("datalist");
			menu.setType("");
			menu.setAlias(formDataTemplate.getAlias());
			menu.setActiveTab(formDataTemplate.getId());
			menu.setHref("");
			menu.setSn(j);
			menu.setTenantId("");
			menu.setIsParent("0");
			menu.setCheck("0");
			menuList.add(menu);
		}
	}

	public List<SysMenu> filterByMenuAlias(String parentId, List<SysMenu> lists) {
		List<SysMenu> result = new ArrayList<SysMenu>();
		if(BeanUtils.isEmpty(lists)) {
			return result;
		}
		if(StringUtil.isEmpty(parentId)) {
			parentId = "-1";
		}
		// 通过parentId来过滤菜单数组
		BeanUtils.listByPid(lists, parentId, result);
		// 将返回的数组由平铺结果转换为nest结构
		return BeanUtils.listToTree(result);
	}

	/**
	 * 通过角色别名/菜单别名 获取 授权角色信息
	 * @author: 梁宏锦
	 * @date: 2024/04/10
	 * @param roleAlias: 角色别名
	 * @param menuAlias: 菜单别名
	 * @param userId: 用户Id
	 * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
	 **/
	@RequestMapping(value = "getRoleInfoByRoleAliasOrMenuAlias", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "通过角色别名/菜单别名 获取 授权角色信息", httpMethod = "GET", notes = "通过角色别名/菜单别名 获取 授权角色信息")
	public CommonResult<List<Map<String, Object>>> getRoleInfoByRoleAliasOrMenuAlias(
			@ApiParam(name = "roleAlias", value = "角色别名", required = true) @RequestParam(required = false) String roleAlias,
			@ApiParam(name = "menuAlias", value = "菜单别名", required = false) @RequestParam("menuAlias") String menuAlias,
			@ApiParam(name = "userId", value = "用户id", required = false) @RequestParam(required = false) String userId
	) throws Exception {
		List<String> alias = null;
		if(StringUtil.isNotEmpty(roleAlias)) {
			alias = new ArrayList<>();
			alias = Arrays.asList(roleAlias.split(","));
		}

		List<Map<String, Object>> list = sysMenuManager.getRoleInfoByRoleAliasOrMenuAlias(alias, menuAlias, userId);
		CommonResult<List<Map<String, Object>>> result = new CommonResult(ResponseErrorEnums.SUCCESS_OPTION);
		result.setValue(list);
		return result;
	}

	/**
	 * 通过角色别名/菜单别名 获取 授权用户信息
	 * @author: 梁宏锦
	 * @date: 2024/04/10
	 * @param roleAlias: 角色别名
	 * @param menuAlias: 菜单别名
	 * @param userId: 用户Id
     * @param fullName: 用户姓名或账号
     * @param roleCode: 角色code(忘了对应啥需求了_作废)
     * @param page: 页号
	 * @param pageSize: 分页大小
	 * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
	 **/
	@RequestMapping(value = "getUserInfoByRoleAliasOrMenuAlias", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "通过角色别名/菜单别名 获取 授权用户信息", httpMethod = "GET", notes = "通过角色别名/菜单别名 获取 授权用户信息")
	public CommonResult<Page<Map<String, Object>>> getUserInfoByRoleAliasOrMenuAlias(
			@ApiParam(name = "roleAlias", value = "角色别名", required = true) @RequestParam(required = false) String roleAlias,
			@ApiParam(name = "menuAlias", value = "菜单别名", required = false) @RequestParam("menuAlias") String menuAlias,
			@ApiParam(name = "userId", value = "用户id", required = false) @RequestParam(required = false) String userId,
			@ApiParam(name = "fullName", value = "用户姓名或账号", required = false) @RequestParam(required = false) String fullName,
			@ApiParam(name = "roleCode", value = "角色code", required = false) @RequestParam(required = false) String roleCode,
			@ApiParam(name = "page", value = "页号",required = false) @RequestParam(required = false) Integer page,
			@ApiParam(name = "pageSize", value = "分页大小",required = false) @RequestParam(required = false) Integer pageSize
	) throws Exception {
		List<String> alias = null;
		if(StringUtil.isNotEmpty(roleAlias)) {
			alias = new ArrayList<>();
			alias = Arrays.asList(roleAlias.split(","));
		}
		List<String> roleList = new ArrayList<>();
		if(StringUtil.isEmpty(roleCode)) {
			List<Map<String, Object>> resultList = sysMenuManager.getRoleInfoByRoleAliasOrMenuAlias(alias, menuAlias, userId);
			roleList = resultList.stream()
					.map(p -> (String)p.get("CODE_"))
					.collect(Collectors.toList());
		} else {
			roleList.add(roleCode);
		}

		QueryFilter filter = QueryFilter.build().withPage(new PageBean(page, pageSize));
		filter.addFilter("r.CODE_", roleList, QueryOP.IN, FieldRelation.AND, "group_code");
		if (StringUtil.isNotEmpty(fullName)) {
            filter.addFilter("u.fullname_", fullName, QueryOP.LIKE, FieldRelation.OR, "quick");
            filter.addFilter("u.account_", fullName, QueryOP.LIKE, FieldRelation.OR, "quick");
        }
		filter.withSorter(new FieldSort("u.fullname_", Direction.ASC));
        Page<Map<String, Object>> list = (Page<Map<String, Object>>)sysMethodManager.getUserListMapByRoleCode(filter);

		CommonResult<Page<Map<String, Object>>> result = new CommonResult(ResponseErrorEnums.SUCCESS_OPTION);
		result.setValue(list);
		return result;
	}

	/**
	 * 通过角色别名/菜单别名 获取 授权组织信息
	 * @author: 梁宏锦
	 * @date: 2024/04/10
	 * @param roleAlias: 角色别名
	 * @param menuAlias: 菜单别名
	 * @param page: 页号
	 * @param pageSize: 分页大小
	 * @return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
	 **/
	@RequestMapping(value = "getOrgRoleByRoleAliasOrMenuAlias", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "通过角色别名/菜单别名 获取 授权组织信息", httpMethod = "GET", notes = "通过角色别名/菜单别名 获取 授权组织信息")
	public CommonResult<PageList<Map<String, Object>>> getOrgRoleByRoleAliasOrMenuAlias(
			@ApiParam(name = "roleAlias", value = "角色别名", required = true) @RequestParam(required = false) String roleAlias,
			@ApiParam(name = "menuAlias", value = "菜单别名", required = false) @RequestParam("menuAlias") String menuAlias,
			@ApiParam(name = "page", value = "页号",required = false) @RequestParam(required = false) Integer page,
			@ApiParam(name = "pageSize", value = "分页大小",required = false) @RequestParam(required = false) Integer pageSize
	) throws Exception {
		List<String> alias = null;
		if(StringUtil.isNotEmpty(roleAlias)) {
			alias = new ArrayList<>();
			alias = Arrays.asList(roleAlias.split(","));
		}
		IPage<Map<String, Object>> npage = new Page<Map<String, Object>>(page, pageSize);
		PageList<Map<String, Object>> list = sysMenuManager.getOrgRoleByRoleAliasOrMenuAlias(npage, alias, menuAlias);

		CommonResult<PageList<Map<String, Object>>> result = new CommonResult(ResponseErrorEnums.SUCCESS_OPTION);
		result.setValue(list);
		return result;
	}

	/**
	 * 获取授权的后台方法
	 * @param roleAlias
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getAllMethodByRoleAlias", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获取授权的后台方法", httpMethod = "POST", notes = "获取授权的后台方法")
	public ArrayList<Map<String,Object>> getAllMethodByRoleAlias(@ApiParam(name="roleAlias",value="角色别名", required = true)@RequestParam String roleAlias) throws Exception {
		return (ArrayList<Map<String, Object>>) sysMethodManager.getAllMethodByRoleAlias(roleAlias);
	}



	@RequestMapping(value="getJson", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "菜单资源数据明细页面", httpMethod = "GET", notes = "菜单资源数据明细页面")
	public @ResponseBody SysMenu getJson(@ApiParam(name="id", value="主键", required = true)@RequestParam String id) throws Exception {
		return sysMenuManager.getJson(id);
	}

	@RequestMapping(value="save", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "保存菜单资源数据信息", httpMethod = "POST", notes = "保存菜单资源数据信息")
	public CommonResult<String> save(@ApiParam(name="sysMenu", value="菜单资源", required = true)@RequestBody SysMenu sysMenu,
			@ApiParam(name="parentId", value="父节点id", required = true)@RequestParam Optional<String> parentId) throws Exception {
		CommonResult<String> res=sysMenuManager.saveMenus(sysMenu,parentId);
		return res;
	}

    @RequestMapping(value="saveBatch", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "批量保存菜单资源数据信息", httpMethod = "POST", notes = "保存菜单资源数据信息")
    public CommonResult<String> saveBatch(@ApiParam(name="list", value="菜单资源", required = true)@RequestBody List<SysMenu> list) throws Exception {
		CommonResult<String> res=sysMenuManager.saveDataByBatch(list);
		return res;
    }

	@RequestMapping(value="remove", method=RequestMethod.DELETE, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "批量删除菜单信息记录", httpMethod = "DELETE", notes = "批量删除菜单信息记录")
	public CommonResult<String> remove(@ApiParam(name="id", value="主键", required = true)@RequestParam String id) throws Exception {
		sysMenuManager.removeByResId(id);
		return new CommonResult<String>(true, "删除菜单信息成功");
	}

	@RequestMapping(value="isMenuExistByAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "检测菜单资源别名是否已经存在", httpMethod = "GET", notes = "检测菜单资源别名是否已经存在")
	public @ResponseBody CommonResult<Boolean> isMenuExistByAlias(@ApiParam(name="alias", value="菜单别名", required = true)@RequestParam String alias) throws Exception {
        boolean existByAlias = sysMenuManager.isExistByAlias(alias);
        CommonResult<Boolean> commonResult = new CommonResult<Boolean>();
        commonResult.setValue(existByAlias);
        return commonResult;
	}

	@RequestMapping(value="isMethodExistByAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "检测请求方法别名是否已经存在", httpMethod = "GET", notes = "检测请求方法别名是否已经存在")
	public @ResponseBody CommonResult<Boolean> isMethodExistByAlias(@ApiParam(name="alias", value="菜单别名", required = true)@RequestParam String alias) throws Exception {
		boolean existByAlias = sysMethodManager.isExistByAlias(alias);
		CommonResult<Boolean> commonResult = new CommonResult<Boolean>();
		commonResult.setValue(existByAlias);
		return commonResult;
	}

	/**
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getCurrentUserMenu", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获取当前用户的菜单", httpMethod = "GET", notes = "获取当前用户的菜单")
	public @ResponseBody CommonResult<List<SysMenu> > getCurrentUserMenu(@ApiParam(name="menuAlias", value="菜单类型", required = true)@RequestParam String menuAlias) throws Exception {
		CommonResult<List<SysMenu>> commonResult = new CommonResult<List<SysMenu>>(true,"获取当前用户菜单信息");
		List<SysMenu> lists = sysMenuManager.getCurrentUserMenu();
		lists = i18nSysMenu(lists);
		List<SysMenu> result = sysMenuManager.filterByMenuAlias(menuAlias, lists);
		if("true".equals(isHiddenSysMenu)) {
			//用户中心 3441009 系统管理 3421053
			result = result.stream().filter(m -> !"3441009".equals(m.getId()) && !"3421053".equals(m.getId())).collect(Collectors.toList());
		}
		commonResult.setValue(result);
		return commonResult;
	}

    @RequestMapping(value="getAppCenterMenu", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "获取当前用户应用分类菜单", httpMethod = "GET", notes = "获取当前用户应用分类菜单")
    public @ResponseBody CommonResult<List<SysMenu> > getAppCenterMenu(@ApiParam(name="menuAlias", value="菜单类型", required = true)@RequestParam String menuAlias) throws Exception {
        CommonResult<List<SysMenu>> commonResult = new CommonResult<List<SysMenu>>(true,"获取当前用户菜单信息");
        List<SysMenu> lists = null;
        if("appCenter".equals(menuAlias)){
            lists = sysMenuManager.getAll();
        }else {
            lists =sysMenuManager.getCurrentUserMenu();
        }
        lists = i18nSysMenu(lists);
        List<SysMenu> result = sysMenuManager.filterByAppCenter(menuAlias , lists);
        commonResult.setValue(result);
        return commonResult;
    }

    /**
     * 根据菜单别名获取当前用户的菜单
     * @return
     * @throws Exception
     */
    @RequestMapping(value="getCurrentUserMenuByAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "根据菜单别名获取当前用户的菜单", httpMethod = "GET", notes = "根据菜单别名获取当前用户的菜单")
    public @ResponseBody CommonResult<List<SysMenu> > getCurrentUserMenuByAlias(@ApiParam(name="alias", value="菜单别名", required = true)@RequestParam String alias) throws Exception {
        CommonResult<List<SysMenu>> commonResult = new CommonResult<List<SysMenu>>(true,"根据菜单别名获取当前用户的菜单");
        List<SysMenu> lists = sysMenuManager.getCurrentUserMenu();
        List<SysMenu> collect = lists.stream().filter(r -> alias.equals(r.getAlias())).distinct().collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(collect)){
            commonResult.setValue(collect);
        }
        return commonResult;
    }

	/**
	 * 根据当前用户授权应用获取应用分类菜单
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getAppMenuByAuthApp", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "根据当前用户授权应用获取应用分类菜单", httpMethod = "GET", notes = "根据当前用户授权应用获取应用分类菜单")
	public @ResponseBody CommonResult<List<SysMenu> > getAppMenuByAuthApp(@ApiParam(name="menuAlias", value="菜单类型", required = true)@RequestParam String menuAlias) throws Exception {
		List<SysMenu> result = sysMenuManager.getAppMenuByAuthApp(menuAlias);
		return new CommonResult<>(true, "获取当前用户菜单信息", result);
	}

	//  菜单资源国际化
	private List<SysMenu> i18nSysMenu(List<SysMenu> lists) {
		List<String> i18nKey = new ArrayList<String>();
		for (SysMenu sysMenu : lists) {
			i18nKey.add(sysMenu.getAlias());
		}
		Map<String, String> messages = I18nUtil.getMessages(i18nKey, LocaleContextHolder.getLocale());
		for (SysMenu sysMenu : lists) {
			String key = sysMenu.getAlias();
			if(messages.containsKey(key) && StringUtil.isNotEmpty(messages.get(key)) && !key.equals(messages.get(key)) ){
				sysMenu.setName(messages.get(key));
			}
		}
		return lists;
	}

	/**
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getCurrentUserMethodAuth", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "获取当前用户的请求权限", httpMethod = "GET", notes = "获取当前用户的请求权限")
	public @ResponseBody Map<String,List<String>> getCurrentUserMethodAuth() throws Exception {
		return sysMenuManager.getCurrentUserMethodAuth();
	}

	@RequestMapping(value="addDataTemplateToMenu", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "添加业务数据模板到菜单", httpMethod = "POST", notes = "添加业务数据模板到菜单")
	public CommonResult<String> addDataTemplateToMenu(@ApiParam(name="templateToMenuVo", value="业务数据模板添加到菜单参数", required = true)@RequestBody TemplateToMenuVo templateToMenuVo) throws Exception {
		if(StringUtil.isEmpty(templateToMenuVo.getParentAlias())){
			return new CommonResult<String>(false, "父菜单别名不能为空");
		}
		if(StringUtil.isEmpty(templateToMenuVo.getAlias())){
			return new CommonResult<String>(false, "别名不能为空");
		}
//		if(StringUtil.isEmpty(templateToMenuVo.getPath())){
//			return new CommonResult<String>(false, "路径不能为空");
//		}
		SysMenu pMenu = sysMenuManager.getByAlias(templateToMenuVo.getParentAlias());
		if(BeanUtils.isEmpty(pMenu)){
			return new CommonResult<String>(false, "根据父菜单别名"+templateToMenuVo.getParentAlias()+"未找到对应菜单！");
		}
		boolean isExist = sysMenuManager.isExistByAlias(templateToMenuVo.getAlias());
		if(isExist){
			return new CommonResult<String>(false, "别名【"+templateToMenuVo.getAlias()+"】已存在！");
		}
//		SysMenu templateListMenu = sysMenuManager.getByAlias("form.bpmDataTemplatePreview");
//		if(BeanUtils.isEmpty(templateListMenu)){
//			return new CommonResult<String>(false, "业务数据模板中预览列表路由【form.bpmDataTemplatePreview】不存在或已改别名，无法添加到菜单！");
//		}
		SysMenu templateListMenu = new SysMenu();
		//将业务数据模板预览的列表页面和添加页面菜单复制一份到添加的菜单
		try {
			String id = UniqueIdUtil.getSuid();
			if(pMenu.getPath().endsWith(".")) {
				templateListMenu.setPath(String.format("%s%s.", pMenu.getPath(),id));
			}else {
				templateListMenu.setPath(String.format("%s.%s.", pMenu.getPath(),id));
			}
			templateListMenu.setSn(99);
			templateListMenu.setOpen(false);
            templateListMenu.setHref(templateToMenuVo.getHref());
			templateListMenu.setAlias(templateToMenuVo.getAlias());
			templateListMenu.setName(templateToMenuVo.getName());
			templateListMenu.setActiveTab(templateToMenuVo.getPath());
			templateListMenu.setId(id);
			templateListMenu.setParentId(pMenu.getId());
			templateListMenu.setRouterExtend(templateToMenuVo.getRouteExtend());
            templateListMenu.setType(templateToMenuVo.getType());
			sysMenuManager.create(templateListMenu);
		} catch (Exception e) {
			return new CommonResult<String>(false, "添加失败："+e.getMessage());
		}
		return new CommonResult<String>(true, "添加成功，重新登录后生效！");
	}

	@RequestMapping(value="addDatavToMenu", method=RequestMethod.POST, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "添加业务数据模板到菜单", httpMethod = "POST", notes = "添加业务数据模板到菜单")
	public CommonResult<String> addDatavToMenu(@ApiParam(name="templateToMenuVo", value="业务数据模板添加到菜单参数", required = true)@RequestBody TemplateToMenuVo templateToMenuVo) throws Exception {
		if(StringUtil.isEmpty(templateToMenuVo.getParentAlias())){
			return new CommonResult<String>(false, "父菜单别名不能为空");
		}
		if(StringUtil.isEmpty(templateToMenuVo.getAlias())){
			return new CommonResult<String>(false, "别名不能为空");
		}
//		if(StringUtil.isEmpty(templateToMenuVo.getPath())){
//			return new CommonResult<String>(false, "路径不能为空");
//		}
		SysMenu pMenu = sysMenuManager.getByAlias(templateToMenuVo.getParentAlias());
		if(BeanUtils.isEmpty(pMenu)){
			return new CommonResult<String>(false, "根据父菜单别名"+templateToMenuVo.getParentAlias()+"未找到对应菜单！");
		}
		boolean isExist = sysMenuManager.isExistByAlias(templateToMenuVo.getAlias());
		if(isExist){
			return new CommonResult<String>(false, "别名【"+templateToMenuVo.getAlias()+"】已存在！");
		}
//		SysMenu templateListMenu = sysMenuManager.getByAlias("form.bpmDataTemplatePreview");
//		if(BeanUtils.isEmpty(templateListMenu)){
//			return new CommonResult<String>(false, "业务数据模板中预览列表路由【form.bpmDataTemplatePreview】不存在或已改别名，无法添加到菜单！");
//		}
		SysMenu templateListMenu = new SysMenu();
		//将业务数据模板预览的列表页面和添加页面菜单复制一份到添加的菜单
		try {
			String id = UniqueIdUtil.getSuid();
			templateListMenu.setPath(pMenu.getPath()+id+".");
			templateListMenu.setSn(99);
			templateListMenu.setOpen(false);
			templateListMenu.setAlias(templateToMenuVo.getAlias());
			templateListMenu.setName(templateToMenuVo.getName());
			templateListMenu.setActiveTab(templateToMenuVo.getPath());
			templateListMenu.setId(id);
			templateListMenu.setParentId(pMenu.getId());
			//组装动态路由信息
			ObjectNode routeExtendNode = JsonUtil.getMapper().createObjectNode();
			String[] paths = templateToMenuVo.getAlias().split("/");
			routeExtendNode.put("path", String.format("datav/%s?alias=%s", paths[1],paths[1]));
			routeExtendNode.put("component", "DatavLayout");
			routeExtendNode.put("redirect", "");
			routeExtendNode.put("alwaysShow", false);
			routeExtendNode.put("caseSensitive", false);
			ObjectNode metaNode = JsonUtil.getMapper().createObjectNode();
			metaNode.put("title", templateToMenuVo.getName());
			metaNode.put("isChildren", true);
			routeExtendNode.set("meta", metaNode);
			templateListMenu.setRouterExtend(JsonUtil.toJson(routeExtendNode));
            templateListMenu.setType(templateToMenuVo.getType());
			sysMenuManager.create(templateListMenu);
		} catch (Exception e) {
			return new CommonResult<String>(false, "添加失败："+e.getMessage());
		}
		return new CommonResult<String>(true, "添加成功，重新登录后生效！");
	}

	@RequestMapping(value="import", method=RequestMethod.POST, produces={"application/json; charset=utf-8" })
	@ApiOperation(value = "菜单导入", httpMethod = "POST", notes = "菜单导入")
	public CommonResult<String> importData(MultipartHttpServletRequest request, @ApiParam(name="parentMenuId", value="父菜单ID", required = true)@RequestParam String parentMenuId) throws Exception{
		CommonResult<String> res=sysMenuManager.importData(request,parentMenuId);
		return res;
	}

	@RequestMapping(value="export" ,method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
	@ApiOperation(value = "菜单导出", httpMethod = "GET", notes = "菜单导出")
	public void export(@ApiParam(name = "parentMenuId", value = "父菜单ID") @RequestParam String parentMenuId,HttpServletRequest request, HttpServletResponse response) throws 	Exception{
		SysMenu menu = sysMenuManager.get(parentMenuId);
		if(BeanUtils.isNotEmpty(menu)){
			List<SysMenu> childrenMenus = sysMenuManager.getByChidrensParentPath(menu.getPath());
			String json = JsonUtil.toJson(childrenMenus);
			Map<String, String> fileContentMap = new HashMap<String, String>();
			fileContentMap.put("sysMenus.json", json);
			String fileName = "sysMenus_"+ DateFormatUtil.format(LocalDateTime.now(), "yyyy_MMdd_HHmm");
			HttpUtil.downLoadFile(request, response, fileContentMap, fileName);
		}else{
			throw new RuntimeException("导出的菜单不存在！");
		}
	}

	@RequestMapping(value="getByAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "根据菜单别名获取菜单信息", httpMethod = "GET", notes = "根据菜单别名获取菜单信息")
	public @ResponseBody SysMenu getByAlias(@ApiParam(name="alias", value="别名", required = true)@RequestParam String alias) throws Exception {
		return sysMenuManager.getByAlias(alias);
	}
	
	@RequestMapping(value="getFirstMenuRouterPathByTemplateAlias", method=RequestMethod.GET, produces = { "application/json; charset=utf-8" })
	@ApiOperation(value = "根据数据应用模板别名查询匹配的第一条记录的菜单前台访问路径", httpMethod = "GET", notes = "根据数据应用模板别名查询匹配的第一条记录的菜单前台访问路径")
	public @ResponseBody CommonResult<String> getFirstMenuRouterPathByTemplateAlias(@ApiParam(name="templateAlias", value="模板别名", required = true)@RequestParam String templateAlias, 
			@ApiParam(name = "frontType", value = "前端类型(manage、front、mobile)", required = false) @RequestParam Optional<String> frontType)
			throws Exception {
		return sysMenuManager.getFirstMenuRouterPathByTemplateAlias(templateAlias,
				frontType.isPresent() ? FrontTypeConstant.valueOf(frontType.get()) : FrontTypeConstant.front);
	}
}
