/*
 *
 * Copyright (c) 2001-2018 泛微软件.
 * 泛微协同商务系统,版权所有.
 *
 */
package com.cloudstore.dev.api.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.api.cube.service.CubeSearchService;
import com.api.cube.util.CubeSearchTransMethod;
import com.api.formmode.cache.CustomSearchComInfo;
import com.cloudstore.api.util.Util_DateTime;
import com.cloudstore.api.util.Util_Ehcache;
import com.cloudstore.dev.api.bean.*;
import com.cloudstore.dev.api.dao.Dao_Table;
import com.cloudstore.dev.api.dao.Dao_TableFactory;
import com.cloudstore.dev.api.util.TextUtil;
import com.cloudstore.dev.api.util.Util_TableMap;
import com.cloudstore.dev.api.util.Util_public;
import com.cloudstore.eccom.core.WeaCommon;
import com.cloudstore.eccom.result.WeaResultMsg;
import com.engine.common.constant.BizLogOperateType;
import com.engine.common.constant.BizLogSmallType4SysEngine;
import com.engine.common.constant.BizLogType;
import com.engine.common.entity.BizLogContext;
import com.engine.common.util.LogUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import weaver.common.StringUtil;
import weaver.conn.RecordSet;
import weaver.conn.constant.DBConstant;
import weaver.formmode.data.ModeDataIDUpdateSingle;
import weaver.formmode.service.CommonConstant;
import weaver.general.BaseBean;
import weaver.general.StaticObj;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.interfaces.datasource.DataSource;
import weaver.rsa.security.RSA;
import weaver.security.util.SecurityMethodUtil;
import weaver.servicefiles.DataSourceXML;
import weaver.systeminfo.SystemEnv;
import weaver.systeminfo.setting.HrmUserSetting;
import weaver.systeminfo.setting.HrmUserSettingComInfo;
import weaver.systeminfo.setting.HrmUserSettingHandler;
import weaver.wechat.util.Utils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Service_DevTable 表格接口
 *
 */
@Path("/ec/dev/table")
public class Service_DevTable {

    private static final Log logger = LogFactory.getLog(Service_DevTable.class);

    public  String checkData = null;
    private Dao_Table d = null;
    public Service_DevTable() {
        try {
            d = getDaoTableByPool(null);
        } catch (Exception e) {
            logger.error(e);
        }
    }

    private Dao_Table getDaoTableByPool(String poolname) throws Exception {
        try {
            logger.info("====>wyw getDaoTableByPool() param poolname:"+poolname);
            if (StringUtils.isBlank(poolname) && d != null) {
                return d;
            }
            String dbType;
            if (StringUtils.isBlank(poolname)||DataSourceXML.SYS_LOCAL_POOLNAME.equals(poolname)) {
                RecordSet rs = new RecordSet();
                dbType = rs.getDBType();
            } else {
                DataSource datasource = (DataSource) StaticObj.getServiceByFullname("datasource."+poolname, DataSource.class);
                dbType = datasource.getType();
            }
            new BaseBean().writeLog("====>wyw getDaoTableByPool() dbType:"+dbType);
            logger.info("====>wyw getDaoTableByPool() dbType:"+dbType);
            logger.info("====>wyw getDaoTableByPool() isDBType:"+(isDBType("cirrodata",dbType)?"true1":"false2"));

//            if (isDBType(DBConstant.DB_TYPE_ORACLE,dbType)||isDBType("informix",dbType))
            if (isDBType(DBConstant.DB_TYPE_ORACLE,dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TableOracle");
            else if (isDBType(DBConstant.DB_TYPE_MYSQL,dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TableMysql");
            else if (isDBType(DBConstant.DB_TYPE_SQLSERVER,dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TableSqlServer");
            else if (isDBType(DBConstant.DB_TYPE_DB2,dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TableDB2");
            else if (isDBType(DBConstant.DB_TYPE_HANA,dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TableHana");
            else if(isDBType(DBConstant.DB_TYPE_POSTGRESQL,dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TablePostgresql");
            else if(isDBType("informix",dbType))
                return Dao_TableFactory.getInstance().getDao("Dao_TableInformix");//wyw informix数据库
            else
                throw new Exception("不支持的数据库类型:"+dbType );
        } catch (Exception e) {
            throw new Exception("无法读取数据源,poolName:" + poolname, e);
        }
    }

    /**
     * 判断数据库类型支持版本问题
     * @param dbTypeDef 标准数据库类型字符
     * @param dbType 数据库类型可以包含版本号
     * @return
     */
    public boolean isDBType(String dbTypeDef,String dbType) {
        if(dbType.equals("dm")||dbType.equals("st")||dbType.equals("jc")||dbType.equals("gs")) dbType="oracle";
        if(dbType.equals("nt")||dbType.equals("ob")) dbType="oracle";
        if(dbType.equals("pg")) dbType="postgresql";
        if(dbType.equals("hg")) dbType="postgresql";
        if(dbType.equals("og")) dbType="postgresql";
        if(dbType.equals("ux")) dbType="postgresql";
        if(dbType.equals("obmysql")) dbType="mysql";
        return StringUtil.isNull(dbType)?false: dbType.toLowerCase().startsWith(dbTypeDef);
    }

    /**
     * 1、列定义 2、数据总数
     *
     * @param request
     * @param response
     * @param dataKey
     * @return
     */
    @POST
    @Path("/counts")
    @Produces(MediaType.TEXT_PLAIN)
    public String getcounts(@Context HttpServletRequest request,
                            @Context HttpServletResponse response,
                            @FormParam("dataKey") String dataKey) {
        JSONObject rspJson = new JSONObject();
        rspJson.put("status", false);
        try {

            if (StringUtils.isBlank(dataKey)) {
                rspJson.put("msg", "dataKey is null");
                return rspJson.toJSONString();
            }
            User user = HrmUserVarify.getUser(request, response);
            int languageid=user!=null?user.getLanguage():7;

            //解决counts接口非组件发起调用接口时找不到缓存数据问题
            Thread.sleep(100);

            String xmlString = Util_TableMap.getVal(dataKey);
            if (StringUtils.isBlank(xmlString)) {
                logger.info("读取dataKey为空:"+dataKey);
                rspJson.put("msg",SystemEnv.getHtmlLabelName(508217 ,languageid) );
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            SplitPageBean bean = new SplitPageBean(xmlString,0, "RootMap", "sql", "head");

            // 兼容免登录业务
            String loginFree = Util.null2String(bean.getRootMap().getString("loginFree"));
            if (!loginFree.equals("true") && user == null) {
                rspJson.put("msg", SystemEnv.getHtmlLabelName(10004767, languageid));
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            if (bean.getRootMap().containsKey("datasource")) {
                rspJson = getMethodDatas(bean, user, rspJson, request, response);
                if (rspJson.containsKey("datas")) {
                    rspJson.remove("datas");
                }
            } else {
                JSONObject sqlMap = bean.getSql();
                String poolname = bean.getSql().getString("poolname");
                new BaseBean().writeLog("====poolname:"+poolname);
                rspJson.put("count", getDaoTableByPool(poolname).getDevTableCount(sqlMap));
            }
            rspJson.put("status", true);
            // "TimesE is :" + (System.currentTimeMillis() - times1));
        } catch (Exception e) {
            logger.error(e.getMessage());
            //e.printStackTrace();
            //rspJson.put("msg", Util_public.getErrorInfoFromException(e));
        }
        String result = JSON.toJSONString(rspJson);
        return result;
    }

    private JSONObject getMethodDatas(SplitPageBean bean, User user, JSONObject rspJson, HttpServletRequest request, HttpServletResponse response) throws Exception {
        JSONObject Rootheads = bean.getRootMap();
        JSONObject sp = bean.getSql();
        JSONArray heads = bean.getHeads();

        Map<String, String> getCanMap = new HashMap<String, String>();
        String tPrimaryKey = Util.null2String(sp.getString("sqlprimarykey"));
        String [] primarys = primarys = tPrimaryKey.split(",");
        if ("".equals(tPrimaryKey)) {
            rspJson.put("errMsg", "tPrimaryKey is null!");
        }
        boolean needCanMap = false;
        if (Rootheads.containsKey("sourceparams")) {
            getCanMap.put("fromExport",Util.null2String(bean.getSql().get("fromExport")));
            String sourceparamString = Util.null2String(Rootheads.getString("sourceparams"));
            if (!"".equals(sourceparamString)) {
                String[] sclist = sourceparamString.split("\\+");
                for (int i = 0; i < sclist.length; i++) {
                    String[] keyandvalue = sclist[i].split(":");
                    if (2 == keyandvalue.length) {
                        getCanMap.put(keyandvalue[0], keyandvalue[1]);
                    }
                }
            }
            needCanMap = true;
        }
        String dataSourceKey = Rootheads.getString("datasource");

        String[] funcName = dataSourceKey.split("\\.");
        String useFunName = funcName[funcName.length - 1];
        String useFun = dataSourceKey.substring(0, dataSourceKey.length() - useFunName.length() - 1);

        Class usedClass = Class.forName(useFun);

        Method useMethod1;
        if (needCanMap) {
            useMethod1 = usedClass.newInstance().getClass().getMethod(useFunName, User.class, Map.class,HttpServletRequest.class,HttpServletResponse.class);
        } else {
            useMethod1 = usedClass.newInstance().getClass().getMethod(useFunName, User.class,HttpServletRequest.class,HttpServletResponse.class);
        }
        List<Map<String, String>> getDatas = new ArrayList<Map<String, String>>();
        if (Rootheads.containsKey("pageBySelf")) {
            // 这个逻辑是说明有分页参数，获取返回结构不一样
            Map<String, Object> getDatasforMap = new HashMap<String, Object>();
            if (needCanMap) {
                getDatasforMap = (Map<String, Object>) useMethod1.invoke(
                        usedClass.newInstance(), user, getCanMap, request,
                        response);
            } else {
                getDatasforMap = (Map<String, Object>) useMethod1.invoke(
                        usedClass.newInstance(), user, request, response);
            }
            if (null != getDatasforMap) {
                if (getDatasforMap.containsKey("dataAll")) {
                    rspJson.put("datas", getDatasforMap.get("dataAll"));
                }
                if (getDatasforMap.containsKey("recordCount")) {
                    rspJson.put("count", getDatasforMap.get("recordCount"));
                }else{
                    rspJson.put("count", 0);
                }
            } else {
                rspJson.put("count", 0);
                rspJson.put("datas", new ArrayList<Map<String, String>>());
            }

        } else {

            if (needCanMap) {
                getDatas = (List<Map<String, String>>) useMethod1.invoke(
                        usedClass.newInstance(), user, getCanMap, request,
                        response);
            } else {
                getDatas = (List<Map<String, String>>) useMethod1.invoke(
                        usedClass.newInstance(), user, request, response);
            }
            if (null != getDatas) {
                rspJson.put("datas", getDatas);
                rspJson.put("count", getDatas.size());
            }
        }
        for (int i = 0; i < getDatas.size(); i++) {
            Map<String, String> getData = getDatas.get(i);
            for (int j = 0; j < heads.size(); j++) {

                JSONObject onceHead = heads.getJSONObject(j);
                if (!getData.containsKey(
                        onceHead.getString("dataIndex"))) {
                    if ("randomFieldId".equals(onceHead.getString("dbField"))) {
                        getData.put(onceHead.getString("dataIndex"),getData.get(tPrimaryKey));
                    } else {
                        getData.put(onceHead.getString("dataIndex"),getData.get(onceHead.getString("dbField")));
                    }
                }
            }}
        ////============添加外部数据源 对randomField数据的处理 Andyzhang
        if ("1".equals(Rootheads.getString("randomfieldopen")))
            for (int i = 0; i < rspJson.getJSONArray("datas").size(); i++) {
                JSONObject obj = rspJson.getJSONArray("datas").getJSONObject(i);
                for (int j = 0; j < heads.size(); j++) {
                    JSONObject onceHead = heads.getJSONObject(j);
                    if ("set".equals(onceHead.getString("from"))) {
                        obj.put(onceHead.getString("dataIndex"), obj.getString(onceHead.getString("dbField")));
                    }
                }
            }
        return rspJson;
    }

    // 统一处理显示列定制
    private JSONArray getShowColHeads(SplitPageBean bean, String pageUid,
                                      User user) {
        if ("".equals(pageUid)) {
            return bean.getHeads();
        }
        List<UserDefCol> cols = d.getUserDefColumns(pageUid, user.getUID());
        if (cols == null || cols.isEmpty()) {
            return bean.getHeads();
        }
        Map<String, JSONObject> headMap = Maps.newHashMap();
        Map<String, JSONObject> noDataIndexMap = Maps.newHashMap();
        for (int i=0;i<bean.getHeads().size();i++) {
            JSONObject col = (JSONObject)bean.getHeads().get(i);
            col.put("orders", i);
            if (StringUtils.isBlank(col.getString("dataIndex")) || headMap.containsKey(col.getString("dataIndex"))) {
                noDataIndexMap.put(String.valueOf(i), col);//只是为了匹配下面方法的格式，没有实际意义。
            } else {
                headMap.put(col.getString("dataIndex"), col);
            }
        }

        JSONArray heads = new JSONArray();
        for (UserDefCol col: cols) {
            if (!headMap.containsKey(col.getDataIndex()))
                continue;
            JSONObject head = headMap.get(col.getDataIndex());
            //配置可以默认显示的列 Andyzhang
            head.put("display",String.valueOf("0".equals(col.getDisplay())));
            if ("1".equalsIgnoreCase(head.getString("ignoreConfig")))
                head.put("display","true");

            if (StringUtils.isNotBlank(col.getWidth()))
                head.put("oldWidth",col.getWidth());
            heads.add(head);
            headMap.remove(col.getDataIndex());
        }
        this.addToListByOrders(heads, headMap);
        this.addToListByOrders(heads, noDataIndexMap);
        return heads;
    }

    /**
     * 格式化輸出
     * @param bean
     * @param data
     * @param sumlist
     * @param decimalFormat
     * @return
     */
    public Map<String, String> sumTransMethod(SplitPageBean bean,Map<String, String> data,String[] sumlist,String decimalFormat,String tCountcolumns)
    {
        if (StringUtils.isNotBlank(decimalFormat)) {
            String[] str=decimalFormat.split("\\|");
            int i=0;
            for(String item:sumlist) {
                String format=str[i];
                String value=data.get(item);
                String valueSpan=String.format(format, Util.getDoubleValue(value, 0));
                data.put(item+"span", valueSpan);
                data.put(item, valueSpan);
                i++;
            }
        }

        if ("true".equals(bean.getRootMap().getString("counttransmethod")))
            for(Object column : (List)bean.getHeads()) {
                JSONObject obj = (JSONObject) column;
                String name = obj.getString("dbField");
                String jsonName = obj.getString("dataIndex");
                for(String item:sumlist) {
                    if (item.equalsIgnoreCase(name)) {
                        if (obj.containsKey("transMethod") && StringUtils.isNotBlank(obj.getString("transMethod"))) {
                            if ("true".equals(obj.getString("display"))|| "true".equals(obj.getString("transMethodForce"))) {
                                try {
                                    String transMethod = obj.getString("transMethod");
                                    Object[] params = getParams(obj, data);
                                    String valueSpan = doMethod(transMethod, params, obj.getString("dbField"));
                                    data.put(jsonName+"span", valueSpan);
                                }catch(Exception e) {
                                    e.printStackTrace();
                                    logger.error(e.getMessage());
                                }
                            }
                        }
                    }
                }
            }
        return data;
    }
    /**
     * TODO
     * @param transMethod
     * @param params
     * @param defaultValue
     * @return
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    private static String doMethod(String transMethod, Object[] params, String defaultValue) throws Exception {
        if("".equals(transMethod)) return defaultValue;
        if ("com.api.cube.util.CubeSearchTransMethod.getOthers".equals(transMethod)) {
            String otherpara = (String)params[1]+"+$issumcolumn$";
            return CubeSearchTransMethod.INSTANCE.getOthers((String)params[0], otherpara);
        }
        Object o = doMethod(transMethod, params);
        return o.toString();
    }
    /**
     * 获得一行数据中某个key的具体数据。处理了RecordSet与Map类型
     * @param data
     * @param key
     * @return
     */
    private static String getValue(Object data, String key) {
        if (data instanceof Map) {
            return (String)((Map) data).get(key);
        } else if (data instanceof RecordSet) {
            return ((RecordSet) data).getString(key);
        } else {
            return "";
        }
    }

    /**
     * 将transMethod方法的参数转化成某个固定格式，为了后面的处理
     * @param obj
     * @param name
     * @param rs
     * @return
     */
    private static JSONArray transMethodToNew(JSONObject obj,String name,Object rs) {
        //String column = Util.null2String(obj.getString("dbField"));
        String others = Util.null2String(obj.getString(name));
        JSONArray tmParams = new JSONArray();
        String otherArr[] = others.split("[+]");
        JSONObject tmObj1 = new JSONObject();
        tmObj1.put("type","fixedValue");
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<otherArr.length;i++) {

            int pos = otherArr[i].toLowerCase().indexOf("column:");
            if (pos != -1) {
                String tempOtherPara = otherArr[i].substring(pos + 7);
                String paramString = Util.null2String(getValue(rs, tempOtherPara));
                if ("".equals(paramString)) {
                    sb.append(" ");
                } else {
                    sb.append(paramString);
                }
            } else {
                sb.append(otherArr[i]);
            }
            if(i!=otherArr.length-1) {
                sb.append("+");
            }
        }
        tmObj1.put("obj",sb.toString());
        tmParams.add(tmObj1);
        return tmParams;
    }

    /**
     * 获得transMethod方法的参数
     * @param obj
     * @param data
     * @return
     */
    private static Object[] getParams(JSONObject obj, Object data) {
        JSONArray tmParams = new JSONArray();
        JSONObject tmObj = new JSONObject();
        tmObj.put("type","columns");
        tmObj.put("obj",obj.getString("dbField"));
        tmParams.add(tmObj);
        if(obj.containsKey("transMethodOther")) {
            if(obj.get("transMethodOther")!=null)
                tmParams.addAll(transMethodToNew(obj,"transMethodOther",data));
        }
        if(obj.containsKey("transMethodOther2")) {
            if(obj.get("transMethodOther2")!=null)
                tmParams.addAll(transMethodToNew(obj,"transMethodOther2",data));
        }
        Object[] sl = new Object[tmParams.size()];
        int i = 0;
        for(Object t : (List)tmParams) {
            JSONObject tObj = (JSONObject)t;
            String typeStr = tObj.getString("type");
            String objStr = tObj.getString("obj");
            if(typeStr.equals("columns")) {
                sl[i] = getValue(data, objStr);
            }
            else {
                sl[i] = objStr;
            }
            i++;
        }
        return sl;
    }

    /**
     * 执行方法
     * @param transMethod
     * @param params
     * @return
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static Object doMethod(String transMethod, Object[] params) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        String tmArr[] = transMethod.split("\\.");
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<tmArr.length-1;i++) {
            sb.append(tmArr[i]);
            if(i!=tmArr.length-2) {
                sb.append(".");
            }
        }
        Class<?> clazz = Class.forName(sb.toString());
        Object obj = clazz.newInstance();
        Class[] cl = new Class[params.length];
        for (int i=0;i < params.length;i++) {
            cl[i] = String.class;
        }

        Method m1 = clazz.getDeclaredMethod(tmArr[tmArr.length-1],cl);
        return m1.invoke(obj,params);
    }


    @GET
    @Path("/refresh")
    @Produces(MediaType.TEXT_PLAIN)
    public String refreshDatakey(@Context HttpServletRequest request, @Context HttpServletResponse response)
    {
        JSONObject rspJson = new JSONObject();
        rspJson.put("status", true);
        String dataKey=request.getParameter("dataKey");
        if (StringUtils.isBlank(dataKey)) {
            rspJson.put("msg", "dataKey"+ SystemEnv.getHtmlLabelName(385284,weaver.general.ThreadVarLanguage.getLang())+"");
            return rspJson.toJSONString();
        }

        String xmlString = Util_TableMap.getVal(dataKey);
        if (StringUtils.isBlank(xmlString)){
            User user = HrmUserVarify.getUser(request, response);
            int languageid=user!=null?user.getLanguage():7;
            rspJson.put("msg",SystemEnv.getHtmlLabelName(508217 ,languageid) );
            rspJson.put("errorCode", "005");
            return rspJson.toJSONString();
        }
        else {
            Util_TableMap.refreshKey(dataKey);
        }
        return rspJson.toJSONString();
    }


    @POST
    @Path("/datas")
    @Produces(MediaType.TEXT_PLAIN)
    public String datas(@Context HttpServletRequest request,
                        @Context HttpServletResponse response,
                        @FormParam("dataKey") String dataKey,
                        @FormParam("pageSize") String pageSize,
                        @FormParam("sortParams") String sortParams,
                        @FormParam("min") String min, @FormParam("max") String max,
                        @FormParam("current") String current,@FormParam("ismobile") String ismobile) {

        JSONObject rspJson = new JSONObject();
        rspJson.put("status", false);

        if (!Util_public.checkSortParams(sortParams)){
            rspJson.put("msg","SQL Injection error");
            return rspJson.toJSONString();
        }

        try {
            TimeMarker timeMarker = new TimeMarker();
            timeMarker.setMark(true);
            timeMarker.markStart();

            if (StringUtils.isBlank(dataKey)) {
                rspJson.put("msg", "dataKey is null");
                return rspJson.toJSONString();
            }
            User user = HrmUserVarify.getUser(request, response);
            int languageid=user!=null?user.getLanguage():7;

            String xmlString = Util_TableMap.getVal(dataKey);
            if (StringUtils.isBlank(xmlString)) {
                rspJson.put("msg",SystemEnv.getHtmlLabelName(508217 ,languageid) );
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            String sessionId = Util_TableMap.getSessionVal(dataKey);
            if (!StringUtils.equals( SessionFilter.getSessionId(),sessionId)) {
                rspJson.put("msg",SystemEnv.getHtmlLabelName(388918 ,languageid) );
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap", "operates", "head", "sql", "checkboxpopedom", "browser", "otherHeads");

            // 校验免登录标识
            String loginFree = Util.null2String(bean.getRootMap().getString("loginFree"));
            if (!loginFree.equals("true") && user == null) {
                rspJson.put("msg",SystemEnv.getHtmlLabelName(10004767 ,languageid) );
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            Util_TableMap.refreshKey(dataKey);

            if ("1".equalsIgnoreCase(ismobile)) bean.getSql().put("ismobile", "ismobile");

            //获取测试预览的当前操作用户
//            if (bean.getRootMap() != null && bean.getRootMap().containsKey("sourceparams")) {
//                String sourceparams = (String)bean.getRootMap().get("sourceparams");
//                String datashowid = sourceparams.substring(sourceparams.indexOf(":")+1);
//
//                RecordSet rs = new RecordSet();
//                rs.executeQuery("select showname from datashowset where id = ?", datashowid);
//                if (rs.next()) {
//                    String showname = rs.getString(Util.null2String("showname"));
//                    String operatorId = (String)StaticObj.getInstance().getObject("browser.operatoruser." + showname);
//                    if (operatorId != null && operatorId.length() > 0) {
//                        user = User.getUser(Integer.parseInt(operatorId), 0);
//                    }
//                }
//            }

            timeMarker.mark("init Bean");
            String isPageAutoWrap="1";
            // 加入读取折行逻辑
            if (user!=null) {
                HrmUserSettingComInfo userSetting = new HrmUserSettingComInfo();
                String id = userSetting.getId(user.getUID() + "");
                if ("".equals(id)) {
                    HrmUserSettingHandler handler = new HrmUserSettingHandler();
                    HrmUserSetting setting = handler.getSetting(user.getUID());
                    boolean rtxload = setting.isRtxOnload();
                    String isload = "0";
                    if (rtxload) {
                        isload = "1";
                    }
                    d.insertUserSetting(user.getUID(), isload);
                    userSetting.removeHrmUserSettingComInfoCache();
                    userSetting = new HrmUserSettingComInfo();
                    id = userSetting.getId(user.getUID() + "");
                }
                //默认折行
                isPageAutoWrap = userSetting.getIsPageAutoWrap(id);
            }

            boolean flag = !"0".equals(isPageAutoWrap);
            String pageAutoWrap=bean.getRootMap().getString("pageAutoWrap");
            if (StringUtils.isNotBlank(pageAutoWrap)){
                flag="1".equals(pageAutoWrap) ;
            }
            rspJson.put("pageAutoWrap", flag);
            //rspJson.put("pageAutoWrap", "1".equals(isPageAutoWrap));

            // pageSize逻辑上移
            String paSize = "";
            String pageUId = "";
            if (null != bean.getRootMap()) {
                pageUId = Util.null2String(bean.getRootMap().getString("pageUid"));
            }
            String tablePageSize = bean.getRootMap().getString("pagesize");

            if (null != bean.getHeads()) {
                if (user!=null) bean.setHeads(getShowColHeads(bean, pageUId, user));
                bean.mergeHeads();
            }

            //调整分页规则
            if (StringUtils.isNotBlank(pageSize)) {
                rspJson.put("pageSize", pageSize);
            }
            else
            if (!"".equals(pageUId)) {
                if (user!=null)
                    paSize = d.getPageSize(user.getUID(), pageUId);
                if (StringUtils.isBlank(paSize)) {
                    // 需要新增
                    rspJson.put("pageSize", StringUtils.isBlank(tablePageSize) ? 10 : tablePageSize);
                } else {
                    rspJson.put("pageSize", paSize);
                }
            } else {
                rspJson.put("pageSize", 10);
            }

            // 分页逻辑上移
            min = Util.null2String(min);
            max = Util.null2String(max);
            current = Util.null2String(current);
            if ("".equals(max) || "".equals(min)) {
                // 只要空就走以下逻辑
                if ("".equals(current)) {
                    min = "1";
                    max = rspJson.getString("pageSize");
                } else {
                    int minInt = (Integer.valueOf(current) - 1) * Integer.valueOf(rspJson.getString("pageSize")) + 1;
                    int maxInt = minInt + Integer.valueOf(rspJson.getString("pageSize")) - 1;
                    min = minInt + "";
                    max = maxInt + "";
                }
            }

            timeMarker.mark("get current user and count page ");
            List<Map<String, String>> mssl = new ArrayList<Map<String, String>>();

            if (bean.getRootMap().containsKey("datasource")) {
                // 说明不需要拼接sql，直接从接口获取数据
                // 支持方法中直接分页
                mssl = getDataFromDatasource(request, response, sortParams, min, max, timeMarker, rspJson, bean, user,ismobile);


                rspJson.put("datas", mssl);
                rspJson.put("columns", bean.getHeads());
                rspJson.put("ops", bean.getOperates());

            } else {
                String poolname = bean.getSql().getString(  "poolname");
                // 加入分页逻辑
                //根据pageUId 查询 mode_customsearch 里的相关信息，是否需要置顶，以及置顶条件，然后给需要置顶的表，修改表结构添加isTop 字段，用于排序。
                if(pageUId.startsWith("mode_customsearch:")) {
                    CustomSearchComInfo customSearchComInfo = new CustomSearchComInfo();
                    int custom_id = Util.getIntValue(Util.null2String(pageUId.substring(pageUId.indexOf(":") + 1, pageUId.length())), 0);
                    if(custom_id!=0){
                        String dataShowType =  customSearchComInfo.getDatashowtype(custom_id+"");
                        Map<String,Object> otherparam = new HashMap<>();
                        otherparam.put("user",user);
                        if(!dataShowType.equals("2")){
                            getCompleteSql(pageUId,bean,otherparam);//添加密级判断，以及数据置顶逻辑
                        }
                    }
                }

                JSONObject jsonObject = bean.getSql();
                if ("excel".equals(request.getParameter("displayType")) && !jsonObject.containsKey("wrapclose")){ //查询 excel 换行
                    jsonObject.put("wrapclose", "1");
                }

                mssl = getDaoTableByPool(poolname).getDevTableDatas(jsonObject, bean.getHeads(), min, max, sortParams, bean.getBroList(), timeMarker);
                // 需要判断是否包含字段密级字段（seclevel） 目前参数不支持 快速判断（分页最大值为100，最差情况也就是遍历一百次）
//                AddSeclevelUtil addSeclevelUtil = new AddSeclevelUtil();
//                HashMap<String,Object> otherparam = new HashMap<>();
//                addSeclevelUtil.getSecLevelItems(mssl,user,otherparam);

                timeMarker.mark("read data from datasource");
                if(pageUId.startsWith("mode_customsearch:")) {
                    CubeSearchTransMethod.clearCache(pageUId);
                }
                // 加入查询分页数量
                //logger.info("heads:"+ JSON.toJSONString( bean.getHeads()));

                rspJson.put("columns", bean.getHeads());
                rspJson.put("ops", bean.getOperates());
                rspJson.put("datas", mssl);
                rspJson.put("isSts", false);
                // 加入以前的合并同类给出合计值功能
                if (bean.getSql().containsKey("sumColumns")) {
                    // 说明存在合计参数
                    String[] sumlist = Util.null2String(bean.getSql().getString("sumColumns")).split(",");
                    List<String> sumDecryptList = Util.TokenizerString(bean.getSql().getString("sumDecryptColumns"), ",");
                    String tCountcolumns = Util.null2String(bean.getSql().getString("countcolumnsdbtype"));
                    String decimalFormat = Util.null2String(bean.getSql().getString("decimalFormat"));
                    Map<String, String> sumMap = new HashMap<String, String>();
                    for (int i = 0; i < sumlist.length; i++) {
                        if(sumDecryptList.indexOf(sumlist[i]) > -1){
                            sumMap.put(sumlist[i].trim(), "****");
                            sumMap.put(sumlist[i].trim() + "span", "****");
                            continue;
                        }
                        Double thissum = 0.00;
                        Double sumspan = null;
                        for (int j = 0; j < mssl.size(); j++) {
                            if (Util_public.isThousandsField(sumlist[i], tCountcolumns))
                            {
                                String str=mssl.get(j).get(sumlist[i].trim());
                                if (StringUtils.isNotEmpty(str)) str=str.replace(",", "");
                                thissum += Util.getDoubleValue(str, 0);
                            }
                            else
                                thissum += Util.getDoubleValue(mssl.get(j).get(sumlist[i].trim()), 0);
                            //span不进行转换后统计列计算 andyzhang
                            //当页合计

                        }
                        sumMap.put(sumlist[i].trim(),Util_public.parseString(thissum) );
                        sumMap.put(sumlist[i].trim() + "span", Util_public.parseString(thissum));
                    }

                    sumMap=sumTransMethod(bean,sumMap,sumlist,decimalFormat,tCountcolumns);

                    Map<String, String> allSumMap = new HashMap<String, String>();
                    allSumMap = getDaoTableByPool(poolname).getSqlSum(bean.getSql(), sumlist, allSumMap);
                    // 如果存在sumValues，说明这个值在取tableString时已经计算好了。针对需要transMethod配置显示数据的场景。
                    // 格式： key:value+key2:value2
                    if (bean.getSql().containsKey("sumValues")) {
                        String[] sumValues = Util.null2String(bean.getSql().getString("sumValues")).split("\\+");
                        for (int i = 0; i < sumValues.length; i++) {
                            String[] sumValue = sumValues[i].split(":");
                            //allSumMap.put(sumValue[0].trim(), Util.getDoubleValue(sumValue[1].trim(), 0));
                            allSumMap.put(sumValue[0].trim(), sumValue[1].trim());
                        }
                    }

                    allSumMap=sumTransMethod(bean,allSumMap,sumlist,decimalFormat,tCountcolumns);
                    //decimalFormat="%.0f|%.2f|%.2f|%.0f|";

                    rspJson.put("isSts", true);
                    rspJson.put("stsData", sumMap);
                    rspJson.put("stsAllData", allSumMap);
                    timeMarker.mark("sum data");
                }
            }
            boolean haveCheck = false;
            if (bean.getCheckboxList().size() > 0) {
                JSONObject checkboxFirst = (JSONObject)bean.getCheckboxList().get(0);
                haveCheck = checkboxFirst.getString("id") != null;
            }
            rspJson.put("haveCheck", haveCheck);
            rspJson.put("status", true);

            // 暂时来说，这里向rspJson里放入了browser,columns,datas，还没有抽出来。
            bean.outputByBrowser(rspJson, mssl);
            timeMarker.mark("do browser");
            rspJson.put("rootMap", bean.getRootMap());
            // result = JSON.toJSONString(rspJson);

            // "AAATimesF is :" + (System.currentTimeMillis() - startTime));
            timeMarker.markEnd();
            if (timeMarker.isMark()) {
                rspJson.put("timeJson", timeMarker.toTimeCostJSON());
            }

            rspJson.put("expandOperate", 0);

            //移动端信息
            if (bean.getRootMap().containsKey("mobileshowtype"))
                rspJson.put("mobileshowtype",bean.getRootMap().getString("mobileshowtype"));

            if (bean.getRootMap().containsKey("rowstylefield"))
                rspJson.put("rowstylefield",bean.getRootMap().getString("rowstylefield"));

            if (bean.getRootMap().containsKey("mobileshowtemplate")) {
                String str=bean.getRootMap().getString("mobileshowtemplate");
                if (StringUtil.isNotNull(str)) {
                    SplitMobileTemplateBean tempBean=Util_public.getMobileTemplateExt(str);
                    rspJson.put("mobileshowtemplate",tempBean);
                }
            }

        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            //rspJson.put("msg", Util_public.getErrorInfoFromException(e));
            rspJson.put("msg", "error");
        }

        return rspJson.toJSONString();
    }


    private List<Map<String, String>> getDataFromDatasource(HttpServletRequest request, HttpServletResponse response,
                                                            String sortParams,String min,
                                                            String max, TimeMarker timeMarker, JSONObject rspJson,
                                                            SplitPageBean bean, User user, String ismobile) throws Exception {
        List<Map<String, String>> mssl = Lists.newArrayList();
        request.setAttribute("min", min);
        request.setAttribute("max", max);
        request.setAttribute("pageSize", rspJson.getString("pageSize"));
        request.setAttribute("sortParams", sortParams);
        String tPrimaryKey = Util.null2String(bean.getSql().getString("sqlprimarykey"));
        rspJson = getMethodDatas(bean, user, rspJson, request, response);
        if (timeMarker != null) {
            timeMarker.mark("read data from dataSource");
        }

        List<Map<String, String>> getDatas = Lists.newArrayList();
        if (rspJson.containsKey("datas")) {
            getDatas = (List<Map<String, String>>) rspJson.get("datas");
        }
        int minInt = 0;
        int maxInt = getDatas.size();
        if (!bean.getRootMap().containsKey("pageBySelf")) {
            minInt = Integer.valueOf(min) - 1;
            maxInt = Integer.valueOf(max);
            if (minInt < 0) {
                minInt = 0;
            }
            if (maxInt > getDatas.size())
                maxInt = getDatas.size();
        }
        for (int i = minInt; i < maxInt; i++) {
            Map<String, String> getData = getDatas.get(i);
            for (Object obj : (List)bean.getHeads()) {
                JSONObject column = (JSONObject)obj;
                //加入对base64的支持功能 andyzhang
                if (column.containsKey("isBase64")&& column.getString("isBase64").equals("1")){
                    String jsonName = column.getString("dataIndex");
                    String value=getData.get(jsonName);
                    value=TextUtil.toBase64ForMultilang(value);
                    /*if (Util.isEnableMultiLang()) {//weainput多语言需要在前面加上base_标识
                    	value=TextUtil.toBase64ForMultilang(value);
					}else {
						value=Util_public.base64Encode(value);
					}*/
                    getData.put(jsonName, value);
                }
                if (column.containsKey("transMethod") && column.containsKey("display"))
                    if ("true".equals(column.getString("display"))|| "true".equals(column.getString("transMethodForce"))) {
                        String jsonName = column.getString("dataIndex");
                        String transvalue = Util_public.doTransMethod(column, getData);

                        if ("1".equalsIgnoreCase(ismobile)) {
                            if (StringUtils.isNotBlank(transvalue))
                                transvalue=Util_public.deletcLink(transvalue);
                        }
                        getData.put(jsonName+"span", transvalue);
                    }
                if (StringUtils.isNotBlank(tPrimaryKey)) {
                    getData.put("randomFieldId",getData.get(tPrimaryKey));
                }
            }
            mssl.add(getData);
        }

        if (timeMarker != null) {
            timeMarker.mark("do transmethod in dataSource");
        }
        return mssl;
    }

    // 测试用获取 xmlString以及oracle和sql拼好的语句
    @GET
    @Path("/getxml")
    @Produces(MediaType.TEXT_PLAIN)
    public String datas(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        // long startTime = System.currentTimeMillis();
        String dataKey = Util.null2String(request.getParameter("dataKey"));
        JSONObject jo = new JSONObject();
        jo.put("status", false);
        try {
            if (!"".equals(dataKey)) {
                //AndyZhang 解决IP地址切换的导致的数据获取不到问题
                String xmlString = Util.null2String(Util_TableMap.getVal(dataKey));
                if (!"".equals(xmlString)) {
                    jo.put("xmlString", xmlString);
                    SplitPageBean bean = new SplitPageBean(request, dataKey, "head", "sql");
                    String sortParams = Util.null2String(request.getParameter("sortParams"));
                    RecordSet rs = new RecordSet();
                    String sql = getDevTableSql(bean.getSql(), bean.getHeads(), sortParams, rs.getDBType());
                    jo.put("sql", sql);
                    jo.put("status", true);
                } else {
                    jo.put("msg", "xmlString "+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                }
            } else {
                jo.put("msg", "dataKey "+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
            }
        } catch (Exception e) {
            logger.error(e);
            //e.printStackTrace();
            jo.put("msg", Util_public.getErrorInfoFromException(e));
        }
        return jo.toString();
    }

    public String getTableSqlByKey(HttpServletRequest request, String dataKey) throws Exception {
        // String dataKey = Util.null2String(request.getParameter("dataKey"));
        if (null == dataKey || "".equals(dataKey)
                || !Util_TableMap.containsKey(dataKey))
            return "";
        SplitPageBean bean = new SplitPageBean(request, dataKey, "head", "sql");
        RecordSet rs = new RecordSet();
        String dbtype = "oracle".equalsIgnoreCase(rs.getDBType()) ? "oracle" : "sqlserver";
        return getDevTableSql(bean.getSql(), bean.getHeads(), "", dbtype);
    }

    public String getTableSqlByKeyNoOrder(HttpServletRequest request, String dataKey) throws Exception {
        // String dataKey = Util.null2String(request.getParameter("dataKey"));
        if (null == dataKey || "".equals(dataKey)
                || !Util_TableMap.containsKey(dataKey))
            return "";
        SplitPageBean bean = new SplitPageBean(request, dataKey, "head", "sql");
        RecordSet rs = new RecordSet();
        String dbtype = "oracle".equalsIgnoreCase(rs.getDBType()) ? "oracle" : "sqlserver";
        return getDevTableSqlNoOrder(bean.getSql(), bean.getHeads(), "", dbtype);
    }

    private String getDevTableSqlNoOrder(JSONObject sqlObj, JSONArray heads,
                                         String sortParams, String type) {

        String tFields = Util.null2String(sqlObj.getString("backfields"));
        String tFrom = Util.toSqlForSplitPage(Util.null2String(sqlObj
                .getString("sqlform")));
        String tWhere = Util.toSqlForSplitPage(Util.null2String(sqlObj
                .getString("sqlwhere")));
        String tOrder = Util.null2String(sqlObj.getString("sqlorderby"));
        String tOrderWay = Util.null2String(sqlObj.getString("sqlsortway"));
        String tDistinct = Util.null2String(sqlObj.getString("sqlisdistinct"));

        StringBuilder sb = new StringBuilder();

        sb.append(" select " + ("true".equals(tDistinct) ? "distinct " : "")
                + tFields);
        sb.append(" ");
        if (!tFrom.startsWith("from"))
            sb.append("from");
        sb.append(" ").append(tFrom);
        sb.append(" ");
        if (!tWhere.startsWith("where") && !"".equals(tWhere))
            sb.append(" where");
        sb.append(" ").append(tWhere);
        if (!"".equals(tOrder))
            sb.append(" order by ").append(tOrder);

        return sb.toString();
    }

    private String getDevTableSql(JSONObject sqlObj, JSONArray heads,
                                  String sortParams, String type) {
        String tFields = Util.null2String(sqlObj.getString("backfields"));
        String tFrom = Util.toSqlForSplitPage(Util.null2String(sqlObj
                .getString("sqlform")));
        String tWhere = Util.toSqlForSplitPage(Util.null2String(sqlObj
                .getString("sqlwhere")));
        String tOrder = Util.null2String(sqlObj.getString("sqlorderby"));
        String tOrderWay = Util.null2String(sqlObj.getString("sqlsortway"));
        String tDistinct = Util.null2String(sqlObj.getString("sqlisdistinct"));

        StringBuilder sb = new StringBuilder();

        sb.append(" select " + ("true".equals(tDistinct) ? "distinct " : "")
                + tFields);
        sb.append(" ");
        if (!tFrom.startsWith("from"))
            sb.append("from");
        sb.append(" ").append(tFrom);
        sb.append(" ");
        if (!tWhere.startsWith("where") && !"".equals(tWhere))
            sb.append(" where");
        sb.append(" ").append(tWhere);
        if (!"".equals(tOrder))
            sb.append(" order by ").append(tOrder);
        if (!"".equals(tOrderWay))
            sb.append("  ").append(tOrderWay);

        return sb.toString();
    }

    /**
     * 分页函数接口
     * @param request 请求对象
     * @param response 回复对象
     * @param dataKey  tableString 键
     * @param min      开始行号
     * @param pageSize 分页大小
     * @param max      末尾行号
     * @return
     */
    @POST
    @Path("/pageSize")
    @Produces(MediaType.TEXT_PLAIN)
    public String datas(@Context HttpServletRequest request,
                        @Context HttpServletResponse response,
                        @FormParam("dataKey") String dataKey, @FormParam("min") String min,
                        @FormParam("pageSize") String pageSize,
                        @FormParam("max") String max) {
        long startTime = System.currentTimeMillis();
        String result = "";
        JSONObject rspJson = new JSONObject();
        rspJson.put("status", false);
        String pageUid = "";
        User user = HrmUserVarify.getUser(request, response);
        String xmlString = Util_TableMap.getVal(dataKey);

        if (StringUtils.isBlank(xmlString)) {
            int languageid=user!=null?user.getLanguage():7;
            rspJson.put("msg",SystemEnv.getHtmlLabelName(508217 ,languageid) );
            rspJson.put("errorCode", "005");
            return rspJson.toJSONString();
        }

        try {
            SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap");
            pageUid = Util.null2String(bean.getRootMap().getString("pageUid"));
        } catch(Exception e) {
            logger.error(e);
            e.printStackTrace();
            //rspJson.put("msg", Util_public.getErrorInfoFromException(e));
        }
        if (StringUtils.isBlank(pageUid)) {
            if (rspJson.get("msg") == null) {
                rspJson.put("msg", "pageUid"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
            }
            return rspJson.toJSONString();
        }

        if (user==null) {
            rspJson.put("msg", "user"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");

            return rspJson.toJSONString();
        }
        //加入查询分页数量
        min = Util.null2String(min);
        max = Util.null2String(max);
        pageSize = Util.null2String(pageSize);
        if (!"".equals(pageUid)) {
            int usedPageSize = 10;
            if (!"".equals(pageSize)) {
                usedPageSize = Integer.valueOf(pageSize);
            } else if (!"".equals(min) && !"".equals(max)) {
                usedPageSize = (Integer.valueOf(max) - Integer.valueOf(min)) + 1;
            }

            String paSize = d.getPageSize(user.getUID(), pageUid);
            if ("".equals(paSize)) {
                // 需要新增
                d.insertPageSize(user.getUID(), pageUid, usedPageSize);
            } else if (usedPageSize != Integer.valueOf(paSize)) {
                // 需要修改
                d.updatePageSize(user.getUID(), pageUid, usedPageSize);
            }
            rspJson.put("pageSize", usedPageSize);
            rspJson.put("status", true);
        } else {
            rspJson.put("errMsg", "pageUid"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
        }
        result = JSON.toJSONString(rspJson);
        return result;
    }

    /**
     * 安全性检查
     * @param data
     * @return
     */
    public JSONObject checkJson(JSONObject data){
        if (Objects.isNull(checkData)) {
            BaseBean bb = new BaseBean();
            checkData =Util.null2String(bb.getPropValue("weaver_new_session","checkdata")) ;
        }

        if ("0".equals(checkData))
            return data;

        Set<Map.Entry<String, Object>> jsonData =  data.entrySet();
        for (Map.Entry<String, Object> entry : jsonData) {
            String value=Util.null2String(entry.getValue());
            value = SecurityMethodUtil.checkSql(value);
            value = SecurityMethodUtil.clearKeywordFromConditon(value);
            entry.setValue(value);
        }

        return data;
    }


    /**
     * 获取选择框的状态列表
     * @param request   请求
     * @param response  响应
     * @param dataKey   键值
     * @param checkId   编号
     * @param randomDatas
     * @return
     */
    @POST
    @Path("/checks")
    @Produces(MediaType.TEXT_PLAIN)
    public String checks(@Context HttpServletRequest request,
                         @Context HttpServletResponse response,
                         @FormParam("dataKey") String dataKey, @FormParam("checkId") String checkId,
                         @FormParam("randomDatas") String randomDatas) {
        JSONObject rspJson = new JSONObject();
        /*防止html注入
        if(StringUtils.isNotBlank(randomDatas))
            randomDatas=randomDatas.replaceAll("[\\>\\<]", "");
        */
        JSONArray rdJson = JSON.parseArray(randomDatas);
        try {
            if (StringUtils.isBlank(dataKey)) {
                rspJson.put("msg", "dataKey is null");
                //rspJson.put("errorCode", "005");
                rspJson.put("status", false);
                return rspJson.toJSONString();
            }

            User user = HrmUserVarify.getUser(request, response);

            String xmlString = Util_TableMap.getVal(dataKey);
            if (StringUtils.isBlank(xmlString)) {
                int languageid=user!=null?user.getLanguage():7;
                rspJson.put("msg",SystemEnv.getHtmlLabelName(508217 ,languageid) );
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            List<String> getList = new ArrayList<String>();
            SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap", "operates", "head", "checkboxpopedom", "otherHeads");

            // 校验免登录标识
            String loginFree = Util.null2String(bean.getRootMap().getString("loginFree"));
            if (!loginFree.equals("true") && user == null) {
                int languageid=user!=null?user.getLanguage():7;
                rspJson.put("msg",SystemEnv.getHtmlLabelName(10004767 ,languageid) );
                rspJson.put("errorCode", "005");
                return rspJson.toJSONString();
            }

            bean.mergeHeads();

            JSONObject popdom = bean.getOperates().size() > 0 ? bean.getOperates().getJSONObject(0) : null;
            String opTransmethod = popdom != null ? Utils.null2String(popdom.getString("transmethod")) : "";
            JSONObject checkbox = bean.getCheckBox(checkId);
            String showmethod = Util.null2String(checkbox.getString("showmethod"));
            for (int i = 0; i < rdJson.size(); i++) {
                JSONObject newRd = new JSONObject();
                JSONObject rd = rdJson.getJSONObject(i);
                rd=checkJson(rd);
                JSONArray tmParams = transMethodToNew(checkbox, "popedompara", rd, bean.getHeads());
                String opValue = "";
                String value = "";
                try {
                    // "tmParams:"+tmParams.toJSONString());
                    if ("".equals(showmethod) || "true".equals(showmethod))
                        value = "true";
                    else if ("false".equals(showmethod))
                        value = "false";
                    else //检查参数安全 andyzhang 2019-12-23
                        //value = SecurityMethodUtil.textXssClean(doMethod(rd, showmethod, tmParams, "", bean.getHeads()));
                        value = doMethod(rd, showmethod, tmParams, "", bean.getHeads());

                    if ("".equals(opTransmethod) || "true".equals(opTransmethod))
                        newRd.put("randomFieldOp", "true");
                    else if ("false".equals(opTransmethod))
                        newRd.put("randomFieldOp", "false");
                    else {
                        JSONArray opParams = new JSONArray();
                        JSONObject tmObj = new JSONObject();
                        tmObj.put("type", "fixedValue");
                        tmObj.put("obj", rd.getString("randomFieldId") == null ? 0
                                : rd.getString("randomFieldId"));
                        opParams.add(tmObj);

                        opParams.addAll(transMethodToNew(popdom, "otherpara", rd, bean.getHeads()));
                        opParams.addAll(transMethodToNew(popdom, "otherpara2", rd, bean.getHeads()));
                        opValue = doMethod(rd, opTransmethod, opParams, "",bean.getHeads());
                        for (int j = 1; j < bean.getOperates().size(); j++) {
                            JSONObject op = bean.getOperates().getJSONObject(j);
                            JSONArray rfop = transMethodToNew(op, "otherpara", rd, bean.getHeads());
                            // l.write("checks rfop :" + rfop.toString());
                            newRd.put("randomFieldOpPara" + op.getString("index"), rfop);
                        }
                        newRd.put("randomFieldOp", opValue);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                newRd.put("randomFieldCk", value);
                newRd.put("randomFieldId", rd.getString("randomFieldId"));
                // "opValue:"+opValue);
                // l.write("checks out try newRd :" + newRd.toString());
                rdJson.set(i, newRd);
            }
        } catch (Exception e) {
            logger.error("checks 错误："+e.getMessage());
            rspJson.put("msg", e.getMessage());
            e.printStackTrace();
            //rspJson.put("msg", Util_public.getErrorInfoFromException(e));
        }
        // return JSON.toJSONString(rspJson);
        //l.writeLog(JSON.toJSONString(rspJson));
        rspJson.put("status", true);
        rspJson.put("datas", rdJson);
        return JSON.toJSONString(rspJson);
    }

    private boolean checkDataKey(String dataKey) {
        return !dataKey.matches("^[A-Za-z0-9-]+$");
    }


    /**
     * 读取待选列
     * @param request
     * @param response
     * @return
     */
    @GET
    @Path("/showCol")
    @Produces(MediaType.TEXT_PLAIN)
    public String getshowCol(@Context HttpServletRequest request,
                             @Context HttpServletResponse response) {
        JSONObject rspJson = new JSONObject();
        String dataKey = Util.null2String(request.getParameter("dataKey"));
        rspJson.put("status", false);
        if (StringUtils.isBlank(dataKey)) {
            rspJson.put("errMsg", "dataKey "+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
            return rspJson.toJSONString();
        }
        try {
            SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap","head");
            String pageUid = "";
            if (null != bean.getRootMap()) {
                pageUid = Util.null2String(bean.getRootMap().getString("pageUid"));
            }
            if (StringUtils.isBlank(pageUid)) {
                rspJson.put("errMsg", "pageUid"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                return rspJson.toJSONString();
            }
            // 获得当前用户的定制列
            User user = HrmUserVarify.getUser(request, response);

            if (user==null) {
                rspJson.put("errMsg", "user"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                return rspJson.toJSONString();
            }

            List<UserDefCol> userDefCols = d.getUserDefColumns(pageUid, user.getUID());
            JSONArray unchoosedColumns = bean.getUnchoosedColumns();
            JSONArray choosedColumns = bean.getChoosedColumns();

            // 用户如果有定制列，则按用户的定义处理
            // 但如果用户配置的定制列已不存在，或者有不在配置列中的，则按当前配置的处理
            if (userDefCols != null && !userDefCols.isEmpty()) {
                JSONArray defUnchoose = new JSONArray();//用户自定义的未选列
                JSONArray defChoosed = new JSONArray();//用户自定义的已选列
                // 将默认的待选已选转为Map，增加orders属性
                Map<String, JSONObject> unchooseMap = Maps.newHashMap();
                Map<String, JSONObject> choosedMap = Maps.newHashMap();
                for (int i=0; i< unchoosedColumns.size();i++) {
                    JSONObject col = (JSONObject) unchoosedColumns.get(i);
                    col.put("orders", i);
                    unchooseMap.put(col.getString("dataIndex"), col);
                }
                for (int i=0; i< choosedColumns.size();i++) {
                    JSONObject col = (JSONObject) choosedColumns.get(i);
                    col.put("orders", i);
                    choosedMap.put(col.getString("dataIndex"), col);
                }
                // 按用户配置的定制列来组装数据
                for (UserDefCol defCol: userDefCols) {
                    String dataIndex = defCol.getDataIndex();
                    JSONObject col = unchooseMap.get(dataIndex);
                    unchooseMap.remove(dataIndex);
                    if (col == null) {
                        col = choosedMap.get(dataIndex);
                        choosedMap.remove(dataIndex);
                    }
                    if (col == null) {
                        continue;
                    }
                    col.put("display", defCol.getDisplay());
                    col.put("orders", defCol.getOrders());
                    if ("0".equals(defCol.getDisplay())) {
                        defChoosed.add(col);
                    } else {
                        defUnchoose.add(col);
                    }
                }
                // 对于不在用户配置内的，按它们的配置位置加入到列表中
                if (!unchooseMap.isEmpty()) {
                    addToListByOrders(defUnchoose, unchooseMap);
                }
                if (!choosedMap.isEmpty()) {
                    addToListByOrders(defChoosed, choosedMap);
                }
                unchoosedColumns = defUnchoose;
                choosedColumns = defChoosed;
            }

            rspJson.put("destdatas", choosedColumns);
            rspJson.put("srcdatas", unchoosedColumns);
            rspJson.put("currentPage", "1");
            rspJson.put("totalPage", "1");
            rspJson.put("status", true);

        } catch(Exception e) {
            logger.error(e);
            //e.printStackTrace();
            //rspJson.put("msg", Util_public.getErrorInfoFromException(e));
            return rspJson.toJSONString();
        }
        return JSON.toJSONString(rspJson);
    }

    private class OrderCompare implements Comparable<OrderCompare> {
        JSONObject jsonObject;
        public OrderCompare(JSONObject jsonObject){
            this.jsonObject = jsonObject;
        }
        private int getOrders() {
            return jsonObject.getIntValue("orders");
        }

        @Override
        public int compareTo(OrderCompare o) {
            return Integer.valueOf(this.getOrders()).compareTo(Integer.valueOf(o.getOrders()));
        }
    }

    /**
     * 将map中的value按顺序(orders属性)加入到前面的list中。
     * @param array
     * @param map
     */
    private void addToListByOrders(JSONArray array, Map<String, JSONObject> map) {
        List<OrderCompare> list = Lists.newArrayList();
        for (JSONObject jo: map.values()) {
            list.add(new OrderCompare(jo));
        }
        Collections.sort(list);
        for (OrderCompare o : list){
            int index = o.getOrders();
            if (index < array.size()) {
                array.add(index, o.jsonObject);
            } else {
                array.add(o.jsonObject);
            }
        }
    }

    /**
     * 保存已选列
     * @param request
     * @param response
     * @param dataKey
     * @param systemIds
     * @return
     */
    @POST
    @Path("/showCol")
    @Produces(MediaType.TEXT_PLAIN)
    public String postshowCol(@Context HttpServletRequest request,
                              @Context HttpServletResponse response,
                              @FormParam("dataKey") String dataKey,
                              @FormParam("systemIds") String systemIds,
                              @FormParam("widths") String widths) {
        JSONObject rspJson = new JSONObject();
        rspJson.put("status", false);
        if (StringUtils.isBlank(dataKey)) {
            rspJson.put("errMsg", "dataKey "+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
            return rspJson.toJSONString();
        }
        try {
            SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap","head");
            String pageUid = "";
            if (null != bean.getRootMap()) {
                pageUid = Util.null2String(bean.getRootMap().getString("pageUid"));
            }
            if (StringUtils.isBlank(pageUid)) {
                rspJson.put("errMsg", "pageUid"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                return rspJson.toJSONString();
            }

            User user = HrmUserVarify.getUser(request, response);

            if (user==null) {
                rspJson.put("errMsg", "user"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                return rspJson.toJSONString();
            }

            if (StringUtils.isBlank(systemIds)) {
                boolean result = d.clearShowCol(pageUid, user.getUID());
                rspJson.put("status", result);
            } else {
                String[] dataIndexArr = Util.null2String(systemIds).split(",");
                String[] widthIndexArr = Util.null2String(widths).split(",");

                if (StringUtils.isNotBlank(widths))
                    widthIndexArr = Util.null2String(widths).split(",");

                List<UserDefCol> choosedDefCols = Lists.newArrayList();//已选列
                List<UserDefCol> unchoosedDefCols = Lists.newArrayList();//待选列
                // 处理传入的已选列
                Set<String> dataIndexSet = Sets.newHashSet();
                for (int i=0;i<dataIndexArr.length;i++) {
                    String dataIndex = dataIndexArr[i];
                    dataIndexSet.add(dataIndex);

                    String widthNew="";
                    if (StringUtils.isNotBlank(widths)) widthNew=widthIndexArr[i];
                    //int orders = i;//排序改为在下面处理，因为还有不参与列定制配置的需求。
                    UserDefCol col = new UserDefCol(dataIndex, user.getUID(), pageUid, "0"/*0为显示，1为不显示*/, 0,widthNew);
                    choosedDefCols.add(col);
                }
                // 将tableString中不在传入列内的处理为待选列
                int orders = 0;
                for (int i=0;i<bean.getChoosedColumns().size();i++) {
                    JSONObject col = (JSONObject)bean.getChoosedColumns().get(i);
                    if (dataIndexSet.contains(col.getString("dataIndex"))) {
                        continue;
                    }
                    if ("false".equals(col.getString("customCol"))) {
                        // 处理不参与列定制配置的列
                        int order = Util.getIntValue(col.getString("_index"), 0);
                        UserDefCol defCol = new UserDefCol(col.getString("dataIndex"), user.getUID(), pageUid, "0", order,"");
                        if (order >= choosedDefCols.size()) {
                            choosedDefCols.add(defCol);
                        } else {
                            choosedDefCols.add(order, defCol);
                        }
                    } else {
                        orders++;
                        UserDefCol defCol = new UserDefCol(col.getString("dataIndex"), user.getUID(), pageUid, "1", orders,"");
                        unchoosedDefCols.add(defCol);
                    }
                }
                for (int i = 0; i<bean.getUnchoosedColumns().size(); i++) {
                    JSONObject col = (JSONObject)bean.getUnchoosedColumns().get(i);
                    if (dataIndexSet.contains(col.getString("dataIndex"))) {
                        continue;
                    }
                    orders++;
                    UserDefCol defCol = new UserDefCol(col.getString("dataIndex"), user.getUID(), pageUid, "1", orders,"");
                    unchoosedDefCols.add(defCol);
                }
                // 处理已选列的顺序
                for (int i=0;i<choosedDefCols.size();i++) {
                    UserDefCol col = choosedDefCols.get(i);
                    col.setOrders(i);
                }
                d.clearShowCol(pageUid, user.getUID());
                d.insertShowCol(choosedDefCols, unchoosedDefCols);
                rspJson.put("status", true);
            }

        } catch(Exception e) {
            logger.error(e);
            //e.printStackTrace();
            //rspJson.put("msg", Util_public.getErrorInfoFromException(e));
            return rspJson.toJSONString();
        }
        return JSON.toJSONString(rspJson);
    }

    public static String delHTMLTag(String htmlStr) {
        String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
        String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式
        String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
        if (StringUtils.isEmpty(htmlStr)) return htmlStr;
        Pattern p_script = Pattern.compile(regEx_script,
                Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); // 过滤script标签

        Pattern p_style = Pattern
                .compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); // 过滤style标签

        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); // 过滤html标签

        return htmlStr.trim(); // 返回文本字符串
    }


    private JSONObject getJSONObject(String field,JSONArray heads)
    {
        for(Object head : (List)heads) {
            JSONObject obj = (JSONObject)head;
            String fieldName=obj.getString("dbField");
            if (field.equalsIgnoreCase(fieldName)) {
                return obj;
            };
        }
        return null;
    }

    public JSONArray getExportFields(String fields,JSONArray heads)
    {
        if (StringUtils.isNotBlank(fields)) {
            String[] field_list=fields.split(",");
            JSONArray newHeads=new JSONArray();

            List<String> list= Arrays.asList(field_list);
            for(Object head : (List)heads) {
                JSONObject obj = (JSONObject) head;
                obj.put("display", "false");
                String fieldName=obj.getString("dbField");
                if (list.contains(fieldName)) {obj.put("display", "true");};
            }

            for(String item:field_list) {
                JSONObject obj = getJSONObject(item,heads);
                if (obj!=null) {
                    obj.put("display", "true");
                    newHeads.add(obj);
                }
            }
            return newHeads;
        }
        else
            return heads;

    }

    public boolean getUserExportConfig(int userId)
    {
        BaseBean bean=new BaseBean();
        String status=bean.getPropValue("weaver_export_config", "status");
        status=StringUtils.isBlank(status)?"0":status;
        if ("0".equals(status)) return true;
        String userList=bean.getPropValue("weaver_export_config", "user");
        String deptList=bean.getPropValue("weaver_export_config", "dept");
        if (StringUtils.isNotEmpty(userList)) {
            String[] list=userList.split(",");
            for(String item:list) {
                if (String.valueOf(userId).equalsIgnoreCase(item))
                    return true;
            }
        }

        if (StringUtils.isNotEmpty(deptList)) {
            String[] list=deptList.split(",");
            String where="";
            for(String item:list) {
                where=StringUtils.isEmpty(where)?item:where+","+item;
            }
            RecordSet rs=new RecordSet();
            rs.executeQuery("select id from HrmResource where departmentid in ("+where+") and id =?",userId);
            return rs.getCounts()>0;
        }
        return false;

    }

    /**
     * 清除Excel临时文件
     * @param request
     * @param response
     * @return
     */
    @GET
    @Path("/cleartemp")
    @Produces(MediaType.TEXT_PLAIN)
    public String cleartemp(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        String fileName=request.getParameter("filename");
        WeaResultMsg result=new WeaResultMsg(true);

        if (StringUtils.isBlank(fileName) || fileName.contains("..")){
            return result.fail("file name error").toString();
        }

        String path = request.getSession().getServletContext().getRealPath("cloudstore/system/tmpFile/" + fileName);

        File file=new File(path);

        if (file.exists()) {
            try {
                file.delete();
                return result.success("ok").toString();
            }
            catch (Exception ex) {
                return result.success(ex.getMessage()).toString();
            }
        }
        return result.success(""+ SystemEnv.getHtmlLabelName(391241,weaver.general.ThreadVarLanguage.getLang())+"").toString();
    }

    /**
     * 下载文件并且自动删除文件
     * @param request
     * @param response
     * @throws IOException
     */
    @GET
    @Path("/downfiledata")
    @Produces(MediaType.TEXT_PLAIN)
    public String downloadExcel (@Context HttpServletRequest request, @Context HttpServletResponse response)
            throws  IOException {
        WeaResultMsg result=new WeaResultMsg(false);

        String fileName=request.getParameter("filename");

        if (!SecurityMethodUtil.isValidPath(fileName)){
            return result.fail("file name error").toString();
        }

        String reName=request.getParameter("rename");
        if (StringUtils.isNotBlank(reName))
            reName=URLDecoder.decode(reName,"utf-8");
        String path = request.getSession().getServletContext().getRealPath("filesystem/cloudstore/system/tmpFile/" + fileName);

        response.reset();
        response.setCharacterEncoding("UTF-8");
        logger.info("开始导出文件:"+fileName);
        logger.info("文件名:"+reName);
        File file = new File(path);
        if (!file.exists()) return result.fail(""+ SystemEnv.getHtmlLabelName(10004787,weaver.general.ThreadVarLanguage.getLang())+""+fileName).toString();

        response.setContentType("application/vnd.ms-excel;charset=ISO-8859-1");
        //response.setContentType("application/octet-stream");

        String agent = request.getHeader("User-Agent");

        if (StringUtils.isNotBlank(reName)){
            //response.addHeader("Content-Disposition","attachment;filename=" +reName);
            if((agent.contains("Firefox")||agent.contains(" Chrome")||agent.contains("Safari") )&& !agent.contains("Edge")){
                response.setHeader("content-disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(reName.replaceAll("<", "").replaceAll(">", "").replaceAll("&lt;", "").replaceAll("&gt;", ""),"UTF-8").replaceAll("\\+", "%20").replaceAll("%28", "(").replaceAll("%29", ")"));
            }else{
                response.setHeader("content-disposition", "attachment; filename=\"" +
                        URLEncoder.encode(reName.replaceAll("<", "").replaceAll(">", "").replaceAll("&lt;", "").replaceAll("&gt;", ""),"UTF-8").replaceAll("\\+", "%20").replaceAll("%28", "(").replaceAll("%29", ")")+"\"");
            }
        }
        else
            response.addHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes(),"utf-8"));

        InputStream in = new FileInputStream(file);
        response.setHeader("Content-Length", String.valueOf(in.available()));
        logger.info("文件长度:"+in.available());
        OutputStream out = response.getOutputStream();
        int size=0;
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer,0,len);
            size=size+len;
        }
        logger.info("文件长度写出:"+size);
        in.close();
        out.flush();
        out.close();
        file.deleteOnExit();
        file.delete();
        return "";
    }


    @POST
    @Path("/export")
    @Produces(MediaType.TEXT_PLAIN)
    public String export(@Context HttpServletRequest request,
                         @Context HttpServletResponse response,
                         @FormParam("dataKey") String dataKey,
                         @FormParam("filetype") String filetype, @FormParam("filename") String filename,
                         @FormParam("fields")String fields,@FormParam("min") String min, @FormParam("max") String max,
                         @FormParam("htmlfields")String htmlfields,@FormParam("sharepassword") String sharepassword) {
        /*if (StringUtils.isNotBlank(filename)) {
            try {
                filename = URLDecoder.decode(filename, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }*/
        JSONObject rspJson = new JSONObject();

        if (StringUtils.isBlank(filetype)) {
            filetype="xlsx";
        } else if (!StringUtils.equalsAny(filetype, "xlsx", "xls") ) {
            rspJson.put("msg", "file type error");
            rspJson.put("errorCode", "005");
            return rspJson.toJSONString();
        }

        if (!SecurityMethodUtil.isValidPath(filename)){
            rspJson.put("msg", "file name error");
            rspJson.put("errorCode", "005");
            return rspJson.toJSONString();
        }

        String xmlString = Util_TableMap.getVal(dataKey);
        if (StringUtils.isBlank(xmlString)) {
            rspJson.put("msg", ""+ SystemEnv.getHtmlLabelName(10004788,weaver.general.ThreadVarLanguage.getLang())+"");
            rspJson.put("errorCode", "005");
            rspJson.put("dataKey", dataKey);
            return rspJson.toJSONString();
        }
        String pageUId="";
        String maxOccurs ="0";
        boolean status = true;
        try {
            SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap", "head", "sql");
            User user = HrmUserVarify.getUser(request, response);

            pageUId = bean.getRootMap().getString("pageUid");

            logger.info("pageUid=======>>   " + pageUId);
            String exportRight= bean.getRootMap().getString("exportRight");
            String rootFileName = bean.getRootMap().getString("fileName");

            //Map<String,Date> maxMap=new HashMap<>();
            if(Objects.nonNull(pageUId)) maxOccurs = Util_Ehcache.getInstance().getLockStr(pageUId);

            if (Util.getIntValue(maxOccurs,0)>3){
                logger.info("限制下载并发:"+maxOccurs);
                rspJson.put("msg", SystemEnv.getHtmlLabelName(522074 ,user.getLanguage()));
                rspJson.put("errorCode", "005");
                rspJson.put("dataKey", dataKey);
                return rspJson.toJSONString();
            }
            else{
                if(Objects.nonNull(pageUId)) {
                    maxOccurs = String.valueOf(Util.getIntValue(Util_Ehcache.getInstance().getLockStr(pageUId), 0) + 1);
                    Util_Ehcache.getInstance().putLock(pageUId, maxOccurs);
                    logger.info("限制下载并发:" + maxOccurs);
                }
            }

            String isEncryptShare = Util.null2String(bean.getRootMap().getString("isEncryptShare"));
            if(isEncryptShare.equals("1")&&StringUtils.isBlank(sharepassword)){
                if(Objects.nonNull(pageUId))logger.info("加密绕过:"+pageUId);
                rspJson.put("msg", SystemEnv.getHtmlLabelName(382663 ,user.getLanguage()));
                rspJson.put("errorCode", "005");
                rspJson.put("dataKey", dataKey);
                return rspJson.toJSONString();
            }

            //andyzhang 判断权限在导出
            if (StringUtils.isNotBlank(exportRight))
                if (!HrmUserVarify.checkUserRight(Util.null2String(exportRight), user)){
                    rspJson.put("noright", true);
                    rspJson.put("status",status);
                    if(Objects.nonNull(pageUId)) {
                        maxOccurs = String.valueOf(Util.getIntValue(Util_TableMap.getValWithEh(pageUId), 0) - 1);
                        Util_TableMap.setObjValWithEh(pageUId, maxOccurs);
                    }
                    return rspJson.toJSONString();
                }
            //andyzhang 根据配置导出
            if (null != bean.getHeads() && Objects.nonNull(pageUId)) {
                if (user!=null) bean.setHeads(getShowColHeads(bean, pageUId, user));
                bean.mergeHeads();
            }

            JSONArray heads=bean.getHeads();
            if (StringUtils.isNotBlank(fields))
                heads=getExportFields(fields,bean.getHeads());

            List<Map<String, String>> mssl = null;
            bean.getSql().put("fromExport","1");

            String filetypestr="."+filetype;

            String fileNameRadom = (rootFileName != null ? rootFileName : "table") + Util_DateTime.getNowDateTimeStr() +
                    Util_public.createGuid() +filetypestr ;
            HttpSession session = request.getSession(true);
            File f = new File(session.getServletContext().getRealPath("filesystem/cloudstore/system/tmpFile/"));
            if(!f.exists()) {
                f.mkdirs();
            }

            String url = session.getServletContext().getRealPath("filesystem/cloudstore/system/tmpFile/" + fileNameRadom);
            String realUrl = "filesystem/cloudstore/system/tmpFile/" + fileNameRadom;

            if (StringUtils.isBlank(fields)&& user!=null && Objects.nonNull(pageUId))
                heads = getShowColHeads(bean, pageUId, user);

            String languageId="7";
            if (user!=null)
                languageId = String.valueOf(user.getLanguage());

            Workbook workbook = null;
            FileOutputStream fOut = new FileOutputStream(url);

            // 先限制结束位置为第 100万 条
            // int end = Integer.MAX_VALUE;
            int end = 1000000;
            int start = 0;
            // 步长
            final int STEP_SIZE = 5000;
            // 当前max值
            int temMax = STEP_SIZE;
            int temMin = 1;
            // 如果用户设置了min、max
            if (StringUtils.isNotBlank(min)) {
                start = Integer.parseInt(min);
                temMin = start;
                temMax = temMin + STEP_SIZE;
            }
            if (StringUtils.isNotBlank(max)) {
                end = Integer.parseInt(max);
                temMax = Math.min(end, temMax);
            }
            boolean isEXCEL2003 = "xls".equalsIgnoreCase(filetype);
            if (isEXCEL2003) {
                // excel 单sheet页最多65535行，限定最大行数。
                end = Math.min(start + 65530, end);
            }
            // 标记当前操作是不是 向excel中追加
            boolean isAddRow = false;
            TimeMarker timeMarker = new TimeMarker();
            timeMarker.setMark(true);
            timeMarker.markStart();
            while (true) {
                // 从数据库查询数据
                if (bean.getRootMap().containsKey("datasource")) {
                    mssl = getDataFromDatasource(request, response, null, String.valueOf(temMin), String.valueOf(temMax), null, rspJson, bean, user,"");
                } else {
                    String poolname = bean.getSql().getString("poolname");
                    mssl = getDaoTableByPool(poolname).getDevTableDatas(bean.getSql(),  heads, String.valueOf(temMin),
                            String.valueOf(temMax), "", new ArrayList(), new TimeMarker());
                }
                timeMarker.mark("get data from database " + temMax);
                if (StringUtils.isNotBlank(htmlfields))
                    Util_public.replaceHtml(heads,mssl,htmlfields);

                // 处理追加
                if (isEXCEL2003) {
                    if (isAddRow) {
                        workbook = addRowExcel2003(workbook, heads, mssl, languageId);
                    } else {
                        workbook = exportExcel2003(heads,mssl,languageId,filename);
                        isAddRow = true;
                    }
                } else {
                    if (isAddRow) {
                        workbook = addRowExcel2007(workbook, heads, mssl, languageId);
                    } else {
                        workbook=exportExcel2007(heads,mssl,languageId,filename);
                        isAddRow = true;
                    }
                }
                timeMarker.mark("add data to file " + temMax);
                // 移动窗口
                temMin += STEP_SIZE;
                temMax = Math.min(end, temMax + STEP_SIZE);
                // 如果查询结果 mssl 的长度小于步长，说明已经到数据末尾。
                if (mssl.size() < STEP_SIZE || temMin > temMax) {
                    break;
                }

            }

            workbook.write(fOut);
            fOut.flush();

            fOut.getFD().sync();
            fOut.close();

            if (StringUtils.isNotBlank(sharepassword)) {

                RSA rsa=new RSA();
                sharepassword=rsa.decrypt(request, sharepassword);

                if ("xls".equalsIgnoreCase(filetype)) {
                    Biff8EncryptionKey.setCurrentUserPassword(sharepassword);
                    POIFSFileSystem fs = new POIFSFileSystem(new File(url), true);
                    HSSFWorkbook hwb = new HSSFWorkbook(fs.getRoot(), true);
                    FileOutputStream out = new FileOutputStream(url);
                    hwb.write(out);
                    hwb.close();
                    out.close();
                    Biff8EncryptionKey.setCurrentUserPassword(null);

                } else {

                    POIFSFileSystem fs = new POIFSFileSystem();
                    EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
                    Encryptor enc = info.getEncryptor();
                    //设置密码
                    enc.confirmPassword(sharepassword);
                    OPCPackage opc = OPCPackage.open(new File(url), PackageAccess.READ_WRITE);
                    OutputStream os = enc.getDataStream(fs);
                    opc.save(os);
                    opc.close();
                    os.close();
                    //把加密后的文件写回到流
                    FileOutputStream fos = new FileOutputStream(url);
                    fs.writeFilesystem(fos);
                    fs.close();
                    fos.close();

                }
            }

            String rename="";
            if (StringUtils.isNotBlank(filename))
                rename=URLEncoder.encode(URLEncoder.encode(filename+"."+filetype,"utf-8"),"utf-8");
            rspJson.put("size",mssl.size());
            rspJson.put("url","/api/ec/dev/table/downfiledata?filename="+fileNameRadom+"&rename="+rename);
            // }

            timeMarker.mark("deal with file");
            //加入导出日志
            BizLogContext bizLogContext=new BizLogContext();
            bizLogContext.setLogType(BizLogType.SYSTEM);
            bizLogContext.setDateObject(new Date());
            if (user!=null)
                bizLogContext.setUserid(user.getUID());
            String pageId = Util.null2String(bean.getRootMap().getString("pageId"));
            bizLogContext.setTargetId(pageId);
            bizLogContext.setLogSmallType(BizLogSmallType4SysEngine.SYSTEM_ENGINE_EXPORT);
            if ("Hrm:resourceSearchResultByManager".equals(pageId)||"Hrm:resourceSearchResult".equals(pageId)) {
                bizLogContext.setTargetName("~`~`7 导出人员Excel日志`~`8 Export personnel excel log`~`9 導出人員Excel日誌`~`~");
                bizLogContext.setLogType(BizLogType.HRM);
            }
            else
                bizLogContext.setTargetName(""+ SystemEnv.getHtmlLabelName(382051,weaver.general.ThreadVarLanguage.getLang())+"");
            if (user!=null)
                bizLogContext.setUsertype(Util.getIntValue(user.getLogintype()));
            bizLogContext.setOperateType(BizLogOperateType.SELECT);
            //bizLogContext.setParams(request.getParameterMap());
            bizLogContext.setClientIp(Util.null2String(Util.getIpAddr(request)));
            bizLogContext.setDesc(xmlString);
            //l.writeLog(bizLogContext.toString());
            saveLog(bizLogContext);
            //标记导出日志时间
            timeMarker.mark("deal with log");
            timeMarker.markEnd();
            rspJson.put("timeMark", timeMarker.toTimeCostJSON());
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            status = false;
            rspJson.put("url","");
            rspJson.put("err",e.getMessage());
            if(Objects.nonNull(pageUId))Util_Ehcache.getInstance().putLock(pageUId,"0");
        }
        rspJson.put("status",status);
        if(Objects.nonNull(pageUId)) {
            maxOccurs = String.valueOf(Util.getIntValue(Util_Ehcache.getInstance().getLockStr(pageUId), 0) - 1);
            Util_Ehcache.getInstance().putLock(pageUId, maxOccurs);
        }
        logger.info("限制下载并发归位:"+maxOccurs);


        return rspJson.toJSONString();
    }


    public void downExcel(String fileName, String filetype, Workbook workbook,HttpServletRequest request, HttpServletResponse response) {
        try {
            fileName=fileName+ "."+filetype;
            String agent = request.getHeader("User-Agent");

            if((agent.contains("Firefox")||agent.contains(" Chrome")||agent.contains("Safari") )&& !agent.contains("Edge")){
                response.setHeader("content-disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName.replaceAll("<", "").replaceAll(">", "").replaceAll("&lt;", "").replaceAll("&gt;", ""),"UTF-8").replaceAll("\\+", "%20").replaceAll("%28", "(").replaceAll("%29", ")"));
            }else{
                response.setHeader("content-disposition", "attachment; filename=\"" +
                        URLEncoder.encode(fileName.replaceAll("<", "").replaceAll(">", "").replaceAll("&lt;", "").replaceAll("&gt;", ""),"UTF-8").replaceAll("\\+", "%20").replaceAll("%28", "(").replaceAll("%29", ")")+"\"");
            }


            ByteArrayOutputStream bout=new ByteArrayOutputStream();
            workbook.write(bout);
            logger.info(fileName+":"+bout.toByteArray().length);
            ServletOutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel;charset=ISO-8859-1");
            response.setHeader("Content-Length",String.valueOf(bout.toByteArray().length));
            //解决某些操作系统环境下载打不开的问题
            bout.writeTo(out);
            out.flush();
            out.close();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }

    }

    public String doMethod(Map<String,String> mss,String tm,JSONArray tmp,String value) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        if("".equals(tm)) return value;
        String tmArr[] = tm.split("\\.");
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<tmArr.length-1;i++) {
            sb.append(tmArr[i]);
            if(i!=tmArr.length-2) {
                sb.append(".");
            }
        }
        Class<?> clazz = Class.forName(sb.toString());
        Object obj = clazz.newInstance();
        //List<Class> cl = new ArrayList<Class>();
        Class[] cl = new Class[tmp.size()];
        Object[] sl = new Object[tmp.size()];
        int i = 0;
        for(Object t : (List)tmp) {
            JSONObject tObj = (JSONObject)t;
            String typeStr = tObj.getString("type");
            String objStr = tObj.getString("obj");
            if(typeStr.equals("columns")) {
                sl[i] = mss.get(objStr);
            }
            else {
                sl[i] = objStr;
            }
            cl[i] = String.class;
            i++;
        }
        Method m1 = clazz.getDeclaredMethod(tmArr[tmArr.length-1],cl);
        Object o = m1.invoke(obj,sl);
        return o.toString();
    }

    public void setCell(HSSFRow r, int n, String value, String type, HSSFWorkbook workbook, CellStyle DatecellStyle,
                        CellStyle NumbercellStyle,CellStyle StrcellStyle,String languageId) {
        HSSFCell cell = r.createCell((short) n);
        if (null != type && !"".equals(type)) {
            // / "type is not null :" + type);
            if (type.indexOf("number") > -1) {
                cell.setCellStyle(NumbercellStyle);
                cell.setCellValue(value);
            } else if ("date".equals(type)) {
                cell.setCellStyle(DatecellStyle);
                cell.setCellValue(value);
            } else {
                cell.setCellType(CellType.STRING);
                cell.setCellStyle(StrcellStyle);
                value=Util.formatMultiLang(value,languageId);
                cell.setCellValue(value);
            }
        } else {
            cell.setCellType(CellType.STRING);
            cell.setCellStyle(StrcellStyle);
            value=Util.formatMultiLang(value,languageId);
            //AndyZhang 加入时区转换功能
            value=Util_public.transformTimeZone(value);
            cell.setCellValue(value);
        }

    }

    public JSONArray transMethodToNew(JSONObject obj,String name,JSONObject mss,JSONArray heads) {

        String others = Util.null2String(obj.getString(name));
        JSONArray tmParams = new JSONArray();
        String otherArr[] = others.split("[+]");
        JSONObject tmObj1 = new JSONObject();
        tmObj1.put("type","fixedValue");
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<otherArr.length;i++) {

            int pos = otherArr[i].toLowerCase().indexOf("column:");
            if (pos != -1) {
                String tempOtherPara = otherArr[i].substring(pos + 7);
                String paramString = Util.null2String(mss.get(getRealKey(heads,tempOtherPara)));
                if ("".equals(paramString)) {
                    sb.append(" ");
                } else {
                    sb.append(paramString);
                }
            } else {
                sb.append(otherArr[i]);
            }
            if(i!=otherArr.length-1) {
                sb.append("+");
            }
        }
        tmObj1.put("obj",sb.toString());
        if (!"".equals(tmObj1.getString("obj"))) {
            tmParams.add(tmObj1);
        }
        return tmParams;
    }

    public String doMethod(JSONObject mss,String tm,JSONArray tmp,String value,JSONArray heads) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        Object o = null;

        if(tm == null || "".equals(tm)) return value;
        String tmArr[] = tm.split("\\.");
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<tmArr.length-1;i++) {
            sb.append(tmArr[i]);
            if(i!=tmArr.length-2) {
                sb.append(".");
            }
        }
        Class<?> clazz = Class.forName(sb.toString());
        Object obj = clazz.newInstance();
        Class[] cl = new Class[tmp.size()];
        Object[] sl = new Object[tmp.size()];
        int i = 0;
        for(Object t : (List)tmp) {
            JSONObject tObj = (JSONObject)t;
            String typeStr = tObj.getString("type");
            String objStr = tObj.getString("obj");
            if(typeStr.equals("columns")) {
                sl[i] = mss.get(getRealKey(heads,objStr));
            }
            else {
                sl[i] = objStr;
            }
            cl[i] = String.class;
            i++;
        }
        Method m1 = clazz.getDeclaredMethod(tmArr[tmArr.length-1],cl);
        o = m1.invoke(obj, sl);

        return o.toString();
    }

    /**
     * from='set'
     * @param heads
     * @param rdField
     * @return
     */
    public String getRealKey(JSONArray heads,String rdField) {
        String value = "";
        for(int i=0;i<heads.size()&&"".equals(value);i++) {
            JSONObject obj = heads.getJSONObject(i);
            if(rdField.equals(obj.getString("dbField"))&&"set".equals(obj.getString("from"))) {
                value = obj.getString("dataIndex");
            }
        }
        return value;
    }


    /**
     * 清除待办列
     * @param request
     * @param response
     * @param pageUid
     * @return
     */
    @GET
    @Path("/clearShowCol")
    @Produces(MediaType.TEXT_PLAIN)
    public String clearShowCol(@Context HttpServletRequest request,
                               @Context HttpServletResponse response,
                               @QueryParam("pageUid") String pageUid) {
        User user = HrmUserVarify.getUser(request, response);
        JSONObject rspJson = new JSONObject();
        if (user==null) {
            rspJson.put("errMsg", "user "+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
            return rspJson.toJSONString();
        }
        if (1 == user.getUID()) {
            if (StringUtils.isBlank(pageUid)) {
                rspJson.put("error", 1);
                rspJson.put("msg", ""+ SystemEnv.getHtmlLabelName(83869,weaver.general.ThreadVarLanguage.getLang())+"pageUid");
            } else {
                try {
                    if ("all".equals(pageUid)) {
                        d.clearShowCol(null);
                    } else {
                        d.clearShowCol(pageUid);
                    }
                    rspJson.put("error", 0);
                    rspJson.put("msg", ""+ SystemEnv.getHtmlLabelName(311,weaver.general.ThreadVarLanguage.getLang())+"pageUid"+ SystemEnv.getHtmlLabelName(24358,weaver.general.ThreadVarLanguage.getLang())+" "+ pageUid + " "+ SystemEnv.getHtmlLabelName(10004789,weaver.general.ThreadVarLanguage.getLang())+"");
                } catch(Exception e) {
                    rspJson.put("error", 1);
                    logger.error(e);
                    //e.printStackTrace();
                    //rspJson.put("msg", "处理出错,报错信息为:"+Util_public.getErrorInfoFromException(e));
                }
            }
        } else {
            rspJson.put("error", 1);
            rspJson.put("msg", ""+ SystemEnv.getHtmlLabelName(10004790,weaver.general.ThreadVarLanguage.getLang())+"sysadmin"+ SystemEnv.getHtmlLabelName(24533,weaver.general.ThreadVarLanguage.getLang())+"");
        }
        return rspJson.toJSONString();
    }

    public Workbook exportExcel2003(JSONArray heads,List<Map<String, String>> mssl,String languageId,String filename)
    {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();
        workbook.setSheetName(0, StringUtils.isNotBlank(filename)?filename:"datas");
        HSSFRow row = sheet.createRow((short) 0);

        CellStyle DatecellStyle = workbook.createCellStyle();
        DataFormat DateCSformat = workbook.createDataFormat();
        DatecellStyle.setDataFormat(DateCSformat.getFormat("yyyy-mm-dd"));

        CellStyle NumbercellStyle = workbook.createCellStyle();
        DataFormat NumberCSformat = workbook.createDataFormat();
        NumbercellStyle.setDataFormat(NumberCSformat.getFormat("#,##0.00"));

        CellStyle StrcellStyle = workbook.createCellStyle();
        DataFormat format = workbook.createDataFormat();
        StrcellStyle.setDataFormat(format.getFormat("@"));

        int col = 0;
        for(Object head : (List)heads) {
            JSONObject obj = (JSONObject) head;
            if (!"false".equals(obj.getString("display"))) {
                this.setCell(row, col++, obj.getString("title"), "", workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
            }
        }
        int rowNum = 1;

        for(int i=0;i<mssl.size();i++) {
            row = sheet.createRow((short) rowNum++);
            col = 0;
            Map<String,String> mss = mssl.get(i);
            //logger.info("mss is :" + JSON.toJSONString(mss));
            for(Object head : (List)heads) {
                JSONObject obj = (JSONObject) head;

                if (!"false".equals(obj.getString("display"))) {
                    if (obj.containsKey("transMethod")) {
                        String name = obj.getString("dataIndex");
                        String value = mss.get(name);
                        //String valueSpan = delHTMLTag("".equals(mss.get(name + "span")) ? value : mss.get(name + "span"));
                        //直接送转换数据
                        String valueSpan = delHTMLTag(mss.get(name + "span"));
                        this.setCell(row, col++, valueSpan, obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    } else {
                        this.setCell(row, col++, delHTMLTag(mss.get(obj.getString("dataIndex"))), obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    }
                }

            }
        }
        return workbook;
    }

    /**
     * excel2003 追加行
     * @param wb
     * @param heads
     * @param mssl
     * @param languageId
     * @return
     */
    public Workbook addRowExcel2003(Workbook wb, JSONArray heads,List<Map<String, String>> mssl,String languageId)
    {
        HSSFWorkbook workbook;
        if(wb instanceof HSSFWorkbook){
            workbook = (HSSFWorkbook) wb;
        } else {
            return wb;
        }

        HSSFSheet sheet = workbook.getSheetAt(0);

        CellStyle DatecellStyle = workbook.createCellStyle();
        DataFormat DateCSformat = workbook.createDataFormat();
        DatecellStyle.setDataFormat(DateCSformat.getFormat("yyyy-mm-dd"));

        CellStyle NumbercellStyle = workbook.createCellStyle();
        DataFormat NumberCSformat = workbook.createDataFormat();
        NumbercellStyle.setDataFormat(NumberCSformat.getFormat("#,##0.00"));

        CellStyle StrcellStyle = workbook.createCellStyle();
        DataFormat format = workbook.createDataFormat();
        StrcellStyle.setDataFormat(format.getFormat("@"));

        int col = 0;
        int rowNum = sheet.getLastRowNum() + 1;
        HSSFRow row = null;

        for(int i=0;i<mssl.size();i++) {
            row = sheet.createRow( rowNum++);
            col = 0;
            Map<String,String> mss = mssl.get(i);
            //logger.info("mss is :" + JSON.toJSONString(mss));
            for(Object head : (List)heads) {
                JSONObject obj = (JSONObject) head;

                if (!"false".equals(obj.getString("display"))) {
                    if (obj.containsKey("transMethod")) {
                        String name = obj.getString("dataIndex");
                        String value = mss.get(name);
                        //直接送转换数据
                        String valueSpan = delHTMLTag(mss.get(name + "span"));
                        this.setCell(row, col++, valueSpan, obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    } else {
                        this.setCell(row, col++, delHTMLTag(mss.get(obj.getString("dataIndex"))), obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    }
                }

            }
        }
        return workbook;
    }

    public Workbook exportExcel2007(JSONArray heads, List<Map<String, String>> mssl,String languageId,String filename)
    {
        SXSSFWorkbook workbook = new SXSSFWorkbook();

        SXSSFSheet sheet = workbook.createSheet();
        workbook.setSheetName(0, StringUtils.isNotBlank(filename)?filename:"datas");
        SXSSFRow row = sheet.createRow(0);

        CellStyle DatecellStyle = workbook.createCellStyle();
        DataFormat DateCSformat = workbook.createDataFormat();
        DatecellStyle.setDataFormat(DateCSformat.getFormat("yyyy-mm-dd"));

        CellStyle NumbercellStyle = workbook.createCellStyle();
        DataFormat NumberCSformat = workbook.createDataFormat();
        NumbercellStyle.setDataFormat(NumberCSformat.getFormat("#,##0.00"));

        CellStyle StrcellStyle = workbook.createCellStyle();
        DataFormat format = workbook.createDataFormat();
        StrcellStyle.setDataFormat(format.getFormat("@"));

        int col = 0;
        for(Object head : (List)heads) {
            JSONObject obj = (JSONObject) head;
            if (!"false".equals(obj.getString("display"))) {
                this.setCell(row, col++, obj.getString("title"), "", workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
            }
        }
        int rowNum = 1;
        // " start transmethod ");
        for(int i=0;i<mssl.size();i++) {
            row = sheet.createRow( rowNum++);
            col = 0;
            Map<String,String> mss = mssl.get(i);
            //logger.info("mss is :" + JSON.toJSONString(mss));
            for(Object head : (List)heads) {
                JSONObject obj = (JSONObject) head;

                if (!"false".equals(obj.getString("display"))) {
                    if (obj.containsKey("transMethod")) {
                        String name = obj.getString("dataIndex");
                        String value = mss.get(name);

                        //String valueSpan = delHTMLTag("".equals(mss.get(name + "span")) ? value : mss.get(name + "span"));
                        //直接送转换数据
                        String valueSpan = delHTMLTag(mss.get(name + "span"));
                        this.setCell(row, col++, valueSpan, obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    } else {
                        String name =obj.getString("dataIndex");
                        String value=String.valueOf(mss.get(name));
                        this.setCell(row, col++, delHTMLTag(value), obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    }
                }
            }
        }
        return workbook;
    }

    /**
     * exce2007 追加行
     * @param wb
     * @param heads
     * @param mssl
     * @param languageId
     * @return
     */
    public Workbook addRowExcel2007(Workbook wb, JSONArray heads, List<Map<String, String>> mssl,String languageId)
    {
        SXSSFWorkbook workbook;
        if(wb instanceof SXSSFWorkbook){
            workbook = (SXSSFWorkbook) wb;
        } else {
            return wb;
        }

        SXSSFSheet sheet = workbook.getSheetAt(0);

        CellStyle DatecellStyle = workbook.createCellStyle();
        DataFormat DateCSformat = workbook.createDataFormat();
        DatecellStyle.setDataFormat(DateCSformat.getFormat("yyyy-mm-dd"));

        CellStyle NumbercellStyle = workbook.createCellStyle();
        DataFormat NumberCSformat = workbook.createDataFormat();
        NumbercellStyle.setDataFormat(NumberCSformat.getFormat("#,##0.00"));

        CellStyle StrcellStyle = workbook.createCellStyle();
        DataFormat format = workbook.createDataFormat();
        StrcellStyle.setDataFormat(format.getFormat("@"));

        int col = 0;
        int rowNum = sheet.getLastRowNum() + 1;
        SXSSFRow row = null;

        for(int i=0;i<mssl.size();i++) {
            row = sheet.createRow( rowNum++);
            col = 0;
            Map<String,String> mss = mssl.get(i);
            for(Object head : (List)heads) {
                JSONObject obj = (JSONObject) head;

                if (!"false".equals(obj.getString("display"))) {
                    if (obj.containsKey("transMethod")) {
                        String name = obj.getString("dataIndex");
                        String value = mss.get(name);

                        //直接送转换数据
                        String valueSpan = delHTMLTag(mss.get(name + "span"));
                        this.setCell(row, col++, valueSpan, obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    } else {
                        String name =obj.getString("dataIndex");
                        String value=String.valueOf(mss.get(name));
                        this.setCell(row, col++, delHTMLTag(value), obj.getString("exportType"), workbook,DatecellStyle,NumbercellStyle,StrcellStyle,languageId);
                    }
                }
            }
        }
        return workbook;
    }

    public void setCell(Row r, int n, String value, String type, Workbook workbook, CellStyle DatecellStyle,
                        CellStyle NumbercellStyle,CellStyle StrcellStyle,String languageId) {
        Cell cell = r.createCell(n);
        if (null != type && !"".equals(type)) {
            if (type.indexOf("number") > -1) {
                cell.setCellStyle(NumbercellStyle);
                cell.setCellValue(value);
            } else if ("date".equals(type)) {

                cell.setCellStyle(DatecellStyle);
                cell.setCellValue(value);
            } else {
                cell.setCellStyle(StrcellStyle);
                value=Util.formatMultiLang(value,languageId);
                cell.setCellValue(value);
            }
        } else {
            // "type is  null ");
            cell.setCellStyle(StrcellStyle);
            value=Util.formatMultiLang(value,languageId);
            //AndyZhang 加入时区转换功能
            value=Util_public.transformTimeZone(value);
            cell.setCellValue(value);
        }
    }
    public void saveLog(BizLogContext bizLogContext) {
        LogUtil.writeBizLog(bizLogContext);
    }

    /**
     * 设置默认用户的自定义字段数据
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @GET
    @Path("/syndefcols")
    @Produces(MediaType.TEXT_PLAIN)
    public String synchronizationColsDef(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {

        String pageuid=request.getParameter("pageuid");
        String systemIds=request.getParameter("systemIds");
        String systemIdsHide=request.getParameter("systemIdsHide");
        return synchronizationCols(request,response,"","0",pageuid,systemIds,systemIdsHide);
    }

    /**
     * #1063683
     * 概述：显示列定制增加更改默认显示列及同步显示列定制功能
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @GET
    @Path("/syncols")
    @Produces(MediaType.TEXT_PLAIN)
    public String syncCols(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {
        WeaResultMsg result=new WeaResultMsg(false);
        User user = HrmUserVarify.getUser(request, response);
        String dataKey=request.getParameter("dataKey");
        String sOrgType=request.getParameter("orgType");
        OrgType orgType=OrgType.valueOf(sOrgType);
        String orgId=request.getParameter("orgId");
        int def=Util.getIntValue(request.getParameter("def"),0) ;
        String pageuid="";
        String systemIds=request.getParameter("systemIds");
        String systemIdsHide=request.getParameter("systemIdsHide");


        if (!StringUtils.isEmpty(dataKey)) {
            try {
                SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap","head");
                if (null != bean.getRootMap())
                    pageuid = Util.null2String(bean.getRootMap().getString("pageUid"));

                if (StringUtils.isEmpty(pageuid))
                    return result.fail(""+ SystemEnv.getHtmlLabelName(10004769,weaver.general.ThreadVarLanguage.getLang())+"pageuid").toString();

                if (user==null) {
                    result.fail("user"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                    return result.toString();
                }

                List<UserDefCol> userDefCols = d.getUserDefColumns(pageuid, user.getUID());
                JSONArray unchoosedColumns = bean.getUnchoosedColumns();
                JSONArray choosedColumns = bean.getChoosedColumns();

                if (userDefCols != null && !userDefCols.isEmpty()) {
                    JSONArray defUnchoose = new JSONArray();//用户自定义的未选列
                    JSONArray defChoosed = new JSONArray();//用户自定义的已选列
                    // 将默认的待选已选转为Map，增加orders属性
                    Map<String, JSONObject> unchooseMap = Maps.newHashMap();
                    Map<String, JSONObject> choosedMap = Maps.newHashMap();
                    for (int i=0; i< unchoosedColumns.size();i++) {
                        JSONObject col = (JSONObject) unchoosedColumns.get(i);
                        col.put("orders", i);
                        unchooseMap.put(col.getString("dataIndex"), col);
                    }
                    for (int i=0; i< choosedColumns.size();i++) {
                        JSONObject col = (JSONObject) choosedColumns.get(i);
                        col.put("orders", i);
                        choosedMap.put(col.getString("dataIndex"), col);
                    }
                    // 按用户配置的定制列来组装数据
                    for (UserDefCol defCol: userDefCols) {
                        String dataIndex = defCol.getDataIndex();
                        JSONObject col = unchooseMap.get(dataIndex);
                        unchooseMap.remove(dataIndex);
                        if (col == null) {
                            col = choosedMap.get(dataIndex);
                            choosedMap.remove(dataIndex);
                        }
                        if (col == null) {
                            continue;
                        }
                        col.put("display", defCol.getDisplay());
                        col.put("orders", defCol.getOrders());
                        if ("0".equals(defCol.getDisplay())) {
                            defChoosed.add(col);
                        } else {
                            defUnchoose.add(col);
                        }
                    }
                    // 对于不在用户配置内的，按它们的配置位置加入到列表中
                    if (!unchooseMap.isEmpty()) {
                        addToListByOrders(defUnchoose, unchooseMap);
                    }
                    if (!choosedMap.isEmpty()) {
                        addToListByOrders(defChoosed, choosedMap);
                    }
                    unchoosedColumns = defUnchoose;
                    choosedColumns = defChoosed;
                }

                BizLogContext bizLogContext=new BizLogContext();
                //加入导出日志
                bizLogContext.setLogType(BizLogType.SYSTEM);
                bizLogContext.setDateObject(new Date());
                if (user!=null){
                    bizLogContext.setUserid(user.getUID());
                    bizLogContext.setUsertype(Util.getIntValue(user.getLogintype()));
                }
                bizLogContext.setLogSmallType(BizLogSmallType4SysEngine.SYSTEM_ENGINE_EXPORT);
                bizLogContext.setOperateType(BizLogOperateType.ADD);
                bizLogContext.setClientIp(Util.null2String(Util.getIpAddr(request)));

                List<UserDefCol> choosedDefCols=new ArrayList<>();
                List<UserDefCol> unchoosedDefCols=new ArrayList<>();

                for (int i=0; i< choosedColumns.size();i++) {
                    JSONObject col = (JSONObject) choosedColumns.get(i);
                    UserDefCol udc=new UserDefCol();

                    udc.setDataIndex(col.getString("dataIndex"));
                    udc.setDisplay(col.getString("dataIndex"));
                    udc.setOrders(col.getInteger("orders"));
                    udc.setPageUid(col.getString("pageUid"));
                    udc.setWidth(col.getString("width"));
                    udc.setUserId(user.getUID());
                    choosedDefCols.add(udc);
                }

                for (int i=0; i< unchoosedColumns.size();i++) {
                    JSONObject col = (JSONObject) unchoosedColumns.get(i);
                    UserDefCol udc=new UserDefCol();

                    udc.setDataIndex(col.getString("dataIndex"));
                    udc.setDisplay(col.getString("dataIndex"));
                    udc.setOrders(col.getInteger("orders"));
                    udc.setPageUid(col.getString("pageUid"));
                    udc.setWidth(col.getString("width"));
                    udc.setUserId(user.getUID());
                    unchoosedDefCols.add(udc);
                }

                logger.info("choosedDefCols:"+ JSON.toJSONString(choosedDefCols));
                logger.info("unchoosedDefCols:"+JSON.toJSONString(unchoosedDefCols));
                logger.info("orgType:"+orgType);
                logger.info("orgId:"+orgId);
                d.synCols(bizLogContext,choosedDefCols, unchoosedDefCols, orgType, orgId,def);

            }
            catch (Exception ex	) {
                logger.error(ex.getMessage());
                return  result.fail(ex.toString()).toString();
            }


        }


        return result.success().toString();
    }

    /**
     * 同步自定义字段到任意用户
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @GET
    @Path("/syncols")
    @Produces(MediaType.TEXT_PLAIN)
    public String synchronizationCols(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {
        String dataKey=request.getParameter("dataKey");
        String userlist=request.getParameter("userlist");
        String pageuid=request.getParameter("pageuid");
        String systemIds=request.getParameter("systemIds");
        String systemIdsHide=request.getParameter("systemIdsHide");
        return synchronizationCols(request,response,dataKey,userlist,pageuid,systemIds,systemIdsHide);
    }
    /**
     * 同步自定义字段到任意用户
     * @param request
     * @param response
     * @param dataKey
     * @param userlist
     * @param pageuid
     * @param systemIds
     * @param systemIdsHide
     * @return
     * @throws IOException
     */
    public String synchronizationCols(HttpServletRequest request,HttpServletResponse response,String dataKey,String userlist,
                                      String pageuid,String systemIds,String systemIdsHide) throws IOException {
        WeaResultMsg result=new WeaResultMsg(false);

        if (!StringUtils.isEmpty(dataKey)) {
            try {
                SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap","head");
                if (null != bean.getRootMap()) {
                    pageuid = Util.null2String(bean.getRootMap().getString("pageUid"));
                }

                if (StringUtils.isEmpty(pageuid))
                    return result.fail(""+ SystemEnv.getHtmlLabelName(10004769,weaver.general.ThreadVarLanguage.getLang())+"pageuid").toString();

                User user = HrmUserVarify.getUser(request, response);
                if (user==null) {
                    result.fail("user"+ SystemEnv.getHtmlLabelName(18622,weaver.general.ThreadVarLanguage.getLang())+"");
                    return result.toString();
                }

                List<UserDefCol> userDefCols = d.getUserDefColumns(pageuid, user.getUID());
                JSONArray unchoosedColumns = bean.getUnchoosedColumns();
                JSONArray choosedColumns = bean.getChoosedColumns();

                if (userDefCols != null && !userDefCols.isEmpty()) {
                    JSONArray defUnchoose = new JSONArray();//用户自定义的未选列
                    JSONArray defChoosed = new JSONArray();//用户自定义的已选列
                    // 将默认的待选已选转为Map，增加orders属性
                    Map<String, JSONObject> unchooseMap = Maps.newHashMap();
                    Map<String, JSONObject> choosedMap = Maps.newHashMap();
                    for (int i=0; i< unchoosedColumns.size();i++) {
                        JSONObject col = (JSONObject) unchoosedColumns.get(i);
                        col.put("orders", i);
                        unchooseMap.put(col.getString("dataIndex"), col);
                    }
                    for (int i=0; i< choosedColumns.size();i++) {
                        JSONObject col = (JSONObject) choosedColumns.get(i);
                        col.put("orders", i);
                        choosedMap.put(col.getString("dataIndex"), col);
                    }
                    // 按用户配置的定制列来组装数据
                    for (UserDefCol defCol: userDefCols) {
                        String dataIndex = defCol.getDataIndex();
                        JSONObject col = unchooseMap.get(dataIndex);
                        unchooseMap.remove(dataIndex);
                        if (col == null) {
                            col = choosedMap.get(dataIndex);
                            choosedMap.remove(dataIndex);
                        }
                        if (col == null) {
                            continue;
                        }
                        col.put("display", defCol.getDisplay());
                        col.put("orders", defCol.getOrders());
                        if ("0".equals(defCol.getDisplay())) {
                            defChoosed.add(col);
                        } else {
                            defUnchoose.add(col);
                        }
                    }
                    // 对于不在用户配置内的，按它们的配置位置加入到列表中
                    if (!unchooseMap.isEmpty()) {
                        addToListByOrders(defUnchoose, unchooseMap);
                    }
                    if (!choosedMap.isEmpty()) {
                        addToListByOrders(defChoosed, choosedMap);
                    }
                    unchoosedColumns = defUnchoose;
                    choosedColumns = defChoosed;
                }

                String sqlWhere="";
                String sqlWhereDelete="";
                ArrayList<Object> params=new ArrayList<>();

                if (!StringUtils.isEmpty(userlist)) {
                    sqlWhereDelete=WeaCommon.createWhereInSQL(userlist, params);
                    sqlWhere = " where id in " + WeaCommon.createWhereInSQL(userlist, params);
                }

                ArrayList<Object> paramsWhere=new ArrayList<>();
                paramsWhere.add(pageuid);
                RecordSet rs=new RecordSet();
                rs.executeUpdate("delete from cloudstore_defcol where pageuid=? "+ (StringUtils.isEmpty(userlist)?"":" and userid in") ,paramsWhere);

                for(int i=0; i<choosedColumns.size();i++) {
                    JSONObject obj=choosedColumns.getJSONObject(i);
                    String dataIndex=obj.get("dbField").toString();
                    ArrayList<Object> paramsReal=new ArrayList<>();
                    paramsReal.add(pageuid);
                    paramsReal.add(i);
                    paramsReal.add(dataIndex);
                    paramsReal.addAll(params);
                    String sql=" Insert into cloudstore_defcol(userid,sysid,pageuid,orders,display,dataindex,width) "+
                            " select id,'',?,?,0,?,'' from HrmResource "+sqlWhere;
                    rs.executeUpdate(sql,paramsReal);
                }

                for(int i=0; i<unchoosedColumns.size();i++) {
                    JSONObject obj=unchoosedColumns.getJSONObject(i);
                    String dataIndex=obj.get("dbField").toString();

                    ArrayList<Object> paramsReal=new ArrayList<>();
                    paramsReal.add(pageuid);
                    paramsReal.add(i);
                    paramsReal.add(dataIndex);
                    paramsReal.addAll(params);

                    String sql=" Insert into cloudstore_defcol(userid,sysid,pageuid,orders,display,dataindex,width) "+
                            " select id,'',?,?,1,?,'' from HrmResource "+sqlWhere;
                    rs.executeUpdate(sql,paramsReal);
                }
            }
            catch (Exception ex	) {
                logger.error(ex.getMessage());
                return  result.fail(ex.toString()).toString();
            }
        }
        else{
            if (StringUtils.isEmpty(pageuid))
                return result.fail(""+ SystemEnv.getHtmlLabelName(10004769,weaver.general.ThreadVarLanguage.getLang())+"pageuid").toString();
            if (StringUtils.isEmpty(systemIds))
                return result.fail(""+ SystemEnv.getHtmlLabelName(10004769,weaver.general.ThreadVarLanguage.getLang())+"systemIds").toString();
            if (StringUtils.isEmpty(systemIdsHide))
                return result.fail(""+ SystemEnv.getHtmlLabelName(10004769,weaver.general.ThreadVarLanguage.getLang())+"systemIdsHide").toString();

            RecordSet rs=new RecordSet();
            rs.executeUpdate("delete from cloudstore_defcol where pageuid=?",pageuid);

            String[] dataIndexArr = Util.null2String(systemIds).split(",");
            String[] dataIndexArrHide = Util.null2String(systemIdsHide).split(",");

            String sqlWhere="";
            ArrayList<Object> params=new ArrayList<>();

            if (!StringUtils.isEmpty(userlist))
                sqlWhere=" where id in "+WeaCommon.createWhereInSQL(userlist,params);

            int i=0;
            for(String dataIndex :dataIndexArr) {
                ArrayList<Object> paramsReal=new ArrayList<>();
                paramsReal.add(pageuid);
                paramsReal.add(++i);
                paramsReal.add(dataIndex);
                paramsReal.addAll(params);

                String sql=" Insert into cloudstore_defcol(userid,sysid,pageuid,orders,display,dataindex,width) "+
                        " select id,'',?,?,0,?,'' from HrmResource "+sqlWhere;
                rs.executeUpdate(sql,paramsReal);
            }
            for(String dataIndex :dataIndexArrHide) {
                ArrayList<Object> paramsReal=new ArrayList<>();
                paramsReal.add(pageuid);
                paramsReal.add(++i);
                paramsReal.add(dataIndex);
                paramsReal.addAll(params);

                String sql=" Insert into cloudstore_defcol(userid,sysid,pageuid,orders,display,dataindex,width) "+
                        " select id,'',?,?,1,?,'' from HrmResource "+sqlWhere;
                rs.executeUpdate(sql,paramsReal);
            }
        }
        result.success();
        return result.toString();
    }


    public SplitPageBean getCompleteSql(String pageUId, SplitPageBean bean,Map<String,Object> params) {

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
        String curDate = sdf.format(date);
        JSONObject sqlObj = bean.getSql();

        String defaultsqltop = "";
        String detailTable = "";
        String relationCondition = " ";
        String formid = "";
        CubeSearchService cubeSearchService = new CubeSearchService();//原先用来处理sql动态参数的，暂时不考虑先保留代码
        //获取mode_customsearch id
        int id = Util.getIntValue(Util.null2String(pageUId.substring(pageUId.indexOf(":") + 1, pageUId.length())), 0);
        //置顶标识
        int enabledtop = 0;
        int modeid = 0;
        //设定排序的表的过滤条件
        String sqlwhere = "";
        String tOrder = Util.null2String(sqlObj.getString("sqlorderby"));//bean 里面的排序语句，如果当前表在mode_customsearch设置了置顶条件，那么需要将置顶条件字段拼接在前面
        String sqlFrom = Util.null2String(sqlObj.getString("sqlform"));
        String beanSqlWhere = Util.null2String(sqlObj.getString("sqlwhere"));
        if (!("".equals(sqlFrom))) {
            //获取表名
            String tableName = sqlFrom.substring(4, sqlFrom.indexOf("t1")).trim();
            if (id != 0) {
                String topColumn = "mode_top_" + id;
                //查询 mode_customsearch 表里面的信息，enabledtop  defaultsqltop
                String sqlForModeCustomsearch = "select enabledtop,defaultsqltop,detailtable,modeid,formid from mode_customsearch where id = " + id;

                RecordSet rs = new RecordSet();
                rs.execute(sqlForModeCustomsearch);
                while (rs.next()) {
                    enabledtop = Util.getIntValue(Util.null2String(rs.getString("enabledtop"), "0"));
                    // sqlwhere = Util.null2String(rs.getString("defaultsqltop"),"");
                    defaultsqltop = Util.null2String(rs.getString("defaultsqltop"), "");
                    String temp =  Util.null2String(rs.getString("detailtable"));
                    detailTable= !"".equals(temp)?","+temp+" d1 ":"";
                    relationCondition = !"".equals(temp)?" and t1.id = d1.mainid  ":" ";
                    modeid = Util.getIntValue(Util.null2String(rs.getString("modeid"), "0"));
                    bean.getSql().put("modeid", modeid);
                    params.put("modeId",modeid);
                    formid = Util.null2String(rs.getString("formid"));
                }

                if (!weaver.formmode.virtualform.VirtualFormHandler.isVirtualForm(formid)){
                    ModeDataIDUpdateSingle.INSTANCE.updateModifyInfo(tableName);
                }
                //添加密级处理
//                AddSeclevelUtil addSeclevelUtil = new AddSeclevelUtil();
//                String secLevelSqlWhere =  addSeclevelUtil.getBrowserOrSearchSecLevelSqlWhere(params);
//                if(!"".equals(secLevelSqlWhere)){
//                    beanSqlWhere+= secLevelSqlWhere;
//                    sqlObj.put("sqlwhere",beanSqlWhere);
//                }



                if (enabledtop == 1) {
                    //查询设置表单的表 存不存在标记置顶的字段
                    try {
                        String sqlGetTopCol = "select id, " + topColumn + " from " + tableName+" where 1=2 ";
                        rs.execute(sqlGetTopCol);
                        if ("".equals(rs.getExceptionMsg())) {//rs对象内部处理了异常，只能根据msg 来判断是否有异常，先保留try catch
                            String nullFun = CommonConstant.DB_ISNULL_FUN;
                            tOrder = !"".equals(tOrder) ? nullFun+"(t1." + topColumn + ",0) desc," + tOrder : nullFun+"(t1." + topColumn + ",0) desc";
                            bean.getSql().put("topColumn", "mode_top_" + id);
                            bean.getSql().put("sqlorderby", tOrder);

                            if (!"".equals(defaultsqltop)) {
                                //查询出当天满足条件的(当天数据量较小)
                                if(defaultsqltop.indexOf("d1.") ==-1){
                                    detailTable="";
                                    relationCondition= "";
                                }

                                String sqlGetCurData = " select t1.id from " + tableName + " t1  "+ detailTable +"  where t1.modedatacreatedate='" + curDate + "' and " + defaultsqltop +relationCondition+ " and t1.formmodeid =" + modeid +" and t1."+topColumn+" is null ";
                                rs.executeQuery(sqlGetCurData);
                                int dataId = 0;
                                if("".equals(rs.getExceptionMsg())){
                                    while (rs.next()) {
                                        dataId = Util.getIntValue(rs.getString("id"), 0);
                                        String sqlUpdateDayData = " update " + tableName + " set " + topColumn + "=1 where id=" + dataId;
                                        rs.execute(sqlUpdateDayData);
                                    }
                                }

                            }
                        }
                    } catch (Exception e) {
                        //打印日志，列不存在
                    }
                }
            }
        }
        return bean;
    }

}