package com.api.htsc.browser;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.api.cube.util.CubeSearchTransMethod;
import com.cloudstore.api.util.Util_Log;
import com.cloudstore.dev.api.bean.SplitMobileTemplateBean;
import com.cloudstore.dev.api.bean.SplitPageBean;
import com.cloudstore.dev.api.bean.TimeMarker;
import com.cloudstore.dev.api.bean.UserDefCol;
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.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.apache.commons.lang3.StringUtils;
import weaver.common.StringUtil;
import weaver.conn.RecordSet;
import weaver.conn.constant.DBConstant;
import weaver.general.StaticObj;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.interfaces.datasource.DataSource;
import weaver.servicefiles.DataSourceXML;
import weaver.systeminfo.SystemEnv;
import weaver.systeminfo.setting.HrmUserSetting;
import weaver.systeminfo.setting.HrmUserSettingComInfo;
import weaver.systeminfo.setting.HrmUserSettingHandler;


@Path("/filter/table")
public class FilterTableBrowser {
  
  Dao_Table dao = null;
  Util_Log log = null;
  
  public FilterTableBrowser() {
    log = new Util_Log();
    try {
      dao = getDaoTableByPool(null);
    } catch (Exception e) {
      log.writeLog(e);
    }
  }
  
  private Dao_Table getDaoTableByPool(String poolname) throws Exception {
    try {
      if (StringUtils.isBlank(poolname) && dao != null) {
        return dao;
      }
      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();
      }
      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 {
        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) {
    return !StringUtil.isNull(dbType) && dbType.toLowerCase().startsWith(dbTypeDef);
  }
  
  
  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 tPrimaryKey = Util.null2String(sp.getString("sqlprimarykey"));
    if ("".equals(tPrimaryKey)) {
      rspJson.put("errMsg", "tPrimaryKey is null!");
    }
    boolean needCanMap = false;
    if (Rootheads.containsKey("sourceparams")) {
      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<>();
    if (Rootheads.containsKey("pageBySelf")) {
      // 这个逻辑是说明有分页参数，获取返回结构不一样
      Map<String, Object> getDatasforMap;
      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 = dao.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();
                  log.write(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 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为空");
      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, @FormParam("filterList") String filterList,
      @FormParam("deptTypeExcludeList") String deptTypeExcludeList) {
    
    JSONObject rspJson = new JSONObject();
    rspJson.put("status", false);
    try {
      TimeMarker timeMarker = new TimeMarker();
      timeMarker.setMark(true);
      timeMarker.markStart();
      
      if (StringUtils.isBlank(dataKey)) {
        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();
      }
      
      Util_TableMap.refreshKey(dataKey);
      SplitPageBean bean = new SplitPageBean(request, dataKey, "RootMap", "operates", "head", "sql",
          "checkboxpopedom", "browser", "otherHeads");
      
      if ("1".equalsIgnoreCase(ismobile)) {
        bean.getSql().put("ismobile", "ismobile");
      }
      
      //按照部门类别过滤数据
      if (StringUtils.isNotBlank(deptTypeExcludeList)) {
        String tFrom = Util.toSqlForSplitPage(Util.null2String(bean.getSql().getString("sqlform")));
        String tWhere = Util
            .toSqlForSplitPage(Util.null2String(bean.getSql().getString("sqlwhere")));
        StringBuilder fromBuilder = new StringBuilder();
        fromBuilder.append(tFrom);
        fromBuilder.append(
            " join (select DEPTID as did,DEPTTYPECODE as dtypecode from hrmdepartmentdefined) tt\n" +
            " on HRMDEPARTMENT.ID=tt.did ");
        bean.getSql().put("sqlform", fromBuilder.toString());
        
        StringBuilder whereBuilder = new StringBuilder();
        if (!"".equals(tWhere) && !tWhere.trim().startsWith("where")) {
          whereBuilder.append(" where");
        }
        whereBuilder.append(" ").append(tWhere);
        String[] deptTypeExcludeArr = deptTypeExcludeList.split(",");
        String deptTypeCodeExcludeWhere = "";
        for (String excludeDeptTypeCode : deptTypeExcludeArr) {
          if (StringUtils.isNotEmpty(excludeDeptTypeCode)) {
            deptTypeCodeExcludeWhere = String
                .format("%s,'%s'", deptTypeCodeExcludeWhere, excludeDeptTypeCode);
          }
        }
        if (StringUtils.isNotBlank(deptTypeCodeExcludeWhere)) {
          deptTypeCodeExcludeWhere = deptTypeCodeExcludeWhere.substring(1);
          whereBuilder.append(" and tt.dtypecode not in (").append(deptTypeCodeExcludeWhere)
              .append(") ");
        }
        bean.getSql().put("sqlwhere", whereBuilder.toString());
      }
      if (StringUtils.isNotBlank(filterList)) {
        String tWhere = Util
            .toSqlForSplitPage(Util.null2String(bean.getSql().getString("sqlwhere")));
        StringBuilder builder = new StringBuilder();
        if (!"".equals(tWhere) && !tWhere.trim().startsWith("where")) {
          builder.append(" where");
        }
        builder.append(" ").append(tWhere);
        String[] filterArr = filterList.split(",");
        for (String filter : filterArr) {
          if (StringUtils.isNotEmpty(filter)) {
            String[] split = filter.split(":");
            if (split.length == 2) {
              String filterField = split[0];
              String filterValue = split[1];
              String filterWhere = String
                  .format(" and %s not like '%%%s%%'", filterField, filterValue);
              builder.append(filterWhere);
            }
          }
        }
        bean.getSql().put("sqlwhere", builder.toString());
      }
      log.writeLog("filter sql :" + getDevTableSql(bean.getSql()));
      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";
          }
          dao.insertUserSetting(user.getUID(), isload);
          userSetting.removeHrmUserSettingComInfoCache();
          userSetting = new HrmUserSettingComInfo();
          id = userSetting.getId(user.getUID() + "");
        }
        
        //默认折行
        isPageAutoWrap = userSetting.getIsPageAutoWrap(id);
      }
      
      boolean flag = true;
      if ("0".equals(isPageAutoWrap)) {
        flag = false;
      }
      rspJson.put("pageAutoWrap", flag);
      // 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 = dao.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");
        // 加入分页逻辑
        mssl = getDaoTableByPool(poolname)
            .getDevTableDatas(bean.getSql(), bean.getHeads(), min, max, sortParams,
                bean.getBroList(), timeMarker);
        timeMarker.mark("read data from datasource");
        if (pageUId.startsWith("mode_customsearch:")) {
          CubeSearchTransMethod.clearCache(pageUId);
        }
        // 加入查询分页数量
        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(",");
          String tCountcolumns = Util.null2String(bean.getSql().getString("countcolumnsdbtype"));
          String decimalFormat = Util.null2String(bean.getSql().getString("decimalFormat"));
          Map<String, String> sumMap = new HashMap<>();
          for (int i = 0; i < sumlist.length; i++) {
            double thissum = 0.00;
            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);
              }
            }
            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<>();
          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(), sumValue[1].trim());
            }
          }
          
          allSumMap = sumTransMethod(bean, allSumMap, sumlist, decimalFormat, tCountcolumns);
          
          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());
      
      timeMarker.markEnd();
      if (timeMarker.isMark()) {
        rspJson.put("timeJson", timeMarker.toTimeCostJSON());
      }
      
      //移动端信息
      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) {
      log.writeLog(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.parseInt(min) - 1;
      maxInt = Integer.parseInt(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);
          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;
  }
  
  private String getDevTableSql(JSONObject sqlObj) {
    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 (!"".equals(tWhere) && !tWhere.trim().startsWith("where")) {
      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();
  }
  
  
  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.compare(this.getOrders(), 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);
      }
    }
  }
  
}
