package com.engine.organization.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.organization.entity.chart.*;
import com.engine.organization.entity.chart.params.StatisticsParam;
import com.engine.organization.enums.ModuleTypeEnum;
import com.engine.organization.mapper.hrmresource.SystemDataMapper;
import com.engine.organization.service.ChartService;
import com.engine.organization.service.OrgChartService;
import com.engine.organization.util.HasRightUtil;
import com.engine.organization.util.OrganizationAssert;
import com.engine.organization.util.OrganizationCommonUtil;
import com.engine.organization.util.OrganizationDateUtil;
import com.engine.organization.util.db.DBType;
import com.engine.organization.util.db.MapperProxyFactory;
import com.engine.organization.util.detach.DetachUtil;
import lombok.SneakyThrows;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetTrans;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.company.SubCompanyComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.systeminfo.SystemEnv;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ExecutorService;

import java.util.stream.Collectors;

/**
 * @author:dxfeng
 * @createTime: 2023/06/29
 * @version: 1.0
 */
public class ChartServiceImpl extends Service implements ChartService {
    private static final String COMPANY_RIGHT = "OrgChart:All";

    public String COMPANY_TABLE = "";
    public String SUB_COMPANY_TABLE = "";
    public String SUB_COMPANY_DEFINED_TABLE = "";
    public String DEPARTMENT_TABLE = "";
    public String DEPARTMENT_DEFINED_TABLE = "";
    public String SUB_COMPANY_ID = "''";
    public String DEPARTMENT_ID = "''";

    /**
     * 显示虚拟组织
     */
    boolean showVirtual = false;

    /**
     * 是否已创建虚拟组织字段
     */
    boolean hasVirtualFields;

    private OrgChartService getOrgChartService(User user) {
        return ServiceUtil.getService(OrgChartServiceImpl.class, user);

    }

    /**
     * 是否实际组织维度
     */
    boolean isRealDimension;

    /**
     * 是否即时数据
     */
    boolean isRealTime;

    @Override
    public Map<String, Object> getCompanyData(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        boolean hasRight = HasRightUtil.hasRight(user, COMPANY_RIGHT, true);
        result.put("hasRight", hasRight);
        if (!hasRight) {
            return result;
        }

        // 根结点
        String root = Util.null2String(params.get("root"));
        root = StringUtils.isBlank(root) ? "0" : root;

        // 维度
        String dimension = Util.null2String(params.get("fclass"));
        dimension = StringUtils.isBlank(dimension) ? "0" : dimension;

        // 是否展示虚拟组织
        String isVirtual = Util.null2String(params.get("fisvitual"));
        showVirtual = "1".equals(isVirtual);

        String depth = Util.null2String(params.get("level"));

        //版本id
        String id = Util.null2String(params.get("id"));

        boolean hideDepartment = "1".equals(Util.null2String(params.get("hidedept")));

        // 初始化表名
        initTableNameByClass(dimension, id);

        RecordSet rs = new RecordSet();
        List<ChartPO> dataList = new ArrayList<>();
        String sql = "";

        ChartPO topChartPO = null;
        //查询当前实际数据
        if (isRealTime) {
            sql = getRealTimeTopSql(root, dimension);
        } else {
            sql = getLastTimeTopSql(root, dimension, id);
        }

        rs.executeQuery(sql);

        // 封装顶部节点
        if (rs.next()) {
            topChartPO = new ChartPO();
            topChartPO.setFtype(rs.getString("type"));
            topChartPO.setFobjid(rs.getString("id"));
            topChartPO.setFname(rs.getString("name"));
            topChartPO.setOnJobNum(isRealTime ? Util.getIntValue(rs.getString("on_job_num"),0) : Util.getIntValue(rs.getString("job_num"),0));
            topChartPO.setStaffNum(Util.getIntValue(rs.getString("staff_num"),0));
            topChartPO.setParentId(null);
            topChartPO.setExpand("1");
            topChartPO.setFisvitual(rs.getString("isvitual"));
            topChartPO.setHasChildren(getHasChildren(topChartPO.getFtype(), topChartPO.getFobjid()).toString());
            filterAndAddData(dataList, topChartPO, hideDepartment);
            //dataList.add(topChartPO);
        }

        // 向下查询数据
        if (null != topChartPO) {
            findChildData(topChartPO, dataList, Integer.parseInt(depth), id, hideDepartment);
        }

        result.put("api_status", true);
        result.put("data", dataList);
        return result;
    }


    @Override
    public Map<String, Object> asyncCompanyData(Map<String, Object> params) {

        // 维度
        String dimension = Util.null2String(params.get("fclass"));
        dimension = StringUtils.isBlank(dimension) ? "0" : dimension;

        // 是否展示虚拟组织
        String isVirtual = Util.null2String(params.get("fisvitual"));
        showVirtual = "1".equals(isVirtual);
        //版本id
        String versionId = Util.null2String(params.get("id"));
        boolean hideDepartment = "1".equals(Util.null2String(params.get("hidedept")));

        // 初始化表名
        initTableNameByClass(dimension, versionId);

        String ids = (String) params.get("ids");
        List<ChartPO> dataList = new ArrayList<>();
        if (StringUtils.isNotBlank(ids)) {
            RecordSet rs = new RecordSet();
            String[] split = ids.split(",");
            for (String s : split) {
                //TODO 查询当前实际数据
                if (s.contains("_")) {
                    String fObjId = s.split("_")[1];
                    if (s.startsWith("s")) {
                        if (isRealTime) {
                            rs.executeQuery(getRealTimeChildSql("", "1", fObjId));
                        } else {
                            rs.executeQuery(getLastTimeChildSql("", "1", fObjId, versionId));
                        }

                    } else if (s.startsWith("d")) {
                        if (isRealTime) {
                            rs.executeQuery(getRealTimeChildSql("", "2", fObjId));
                        } else {
                            rs.executeQuery(getLastTimeChildSql("", "2", fObjId, versionId));
                        }
                    }
                    while (rs.next()) {
                        ChartPO chartPO = new ChartPO();
                        chartPO.setFtype(rs.getString("type"));
                        chartPO.setFobjid(rs.getString("id"));
                        chartPO.setFname(rs.getString("name"));
                        chartPO.setParentId(s);
                        chartPO.setExpand("0");
                        chartPO.setFisvitual(rs.getString("isvitual"));
                        chartPO.setHasChildren(getHasChildren(chartPO.getFtype(), chartPO.getFobjid()).toString());
                        chartPO.setOnJobNum(isRealTime ? Util.getIntValue(rs.getString("on_job_num"),0) : Util.getIntValue(rs.getString("job_num"),0));
                        chartPO.setStaffNum(Util.getIntValue(rs.getString("staff_num"),0));
                        filterAndAddData(dataList, chartPO, hideDepartment);

                        //dataList.add(chartPO);
                    }
                }
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("api_status", true);
        result.put("data", dataList);
        return result;
    }

    @Override
    public Map<String, Object> getDepartmentDetail(Map<String, Object> params) {
        String rootId = Util.null2String(params.get("rootId"));
        // 维度
        String dimension = Util.null2String(params.get("fclass"));
        dimension = StringUtils.isBlank(dimension) ? "0" : dimension;

        // 是否显示岗位
        String showJobStr = Util.null2String(params.get("showJob"));
        boolean showJob = "1".equals(showJobStr);
        //版本id
        String versionId = Util.null2String(params.get("id"));

        OrganizationAssert.isFalse(StringUtils.isBlank(rootId) || !rootId.startsWith("d_"), SystemEnv.getHtmlLabelName(547440,user.getLanguage()));
        String departmentId = rootId.split("_")[1];
        String detauleType = Util.null2String(params.get("detauleType"));
        if (!"chart".equals(detauleType)) {
            // 展示列表模块
            return ServiceUtil.getService(HrmResourceServiceImpl.class, user).chartResourceList(Integer.parseInt(departmentId), versionId, dimension);
        }


        // 初始化表名
        initTableNameByClass(dimension, versionId);

        List<ChartPO> dataList = new ArrayList<>();
        List<ChartPO> jobTitleList = new ArrayList<>();
        int departmentOnJob = 0;
        int resourceNum;
        RecordSet rs = new RecordSet();
        // TODO 查询当前实际的数据
        String sql;
        if (isRealTime) {
            // 查询部门本身
            if (hasVirtualFields) {
                sql = "select a.id,a.departmentname as name,b.bmfzr,b.bmlx as isvitual from " + DEPARTMENT_TABLE + " a left join hrmdepartmentdefined b on a.id = b.deptid  where a.id  = '" + departmentId + "'";
            } else {
                sql = "select a.id,a.departmentname as name,b.bmfzr from " + DEPARTMENT_TABLE + " a left join hrmdepartmentdefined b on a.id = b.deptid  where a.id  = '" + departmentId + "'";
            }
        } else {
            if (hasVirtualFields) {
                sql = "select " + DEPARTMENT_ID + " as id,a.departmentname as name,fleader as bmfzr,isvirtual as isvitual from " + DEPARTMENT_TABLE + " a where a." + DEPARTMENT_ID + "  = '" + departmentId + "' and versionid = " + versionId;
            } else {
                sql = "select " + DEPARTMENT_ID + " as id,a.departmentname as name from " + DEPARTMENT_TABLE + " a where a." + DEPARTMENT_ID + "  = '" + departmentId + "' and versionid = " + versionId;
            }
        }
        rs.executeQuery(sql);
        ChartPO departmentChartPO = new ChartPO();
        if (rs.next()) {
            String fLeader = Util.null2String(rs.getString("bmfzr"));
            departmentChartPO.setFtype("2");
            departmentChartPO.setFobjid(departmentId);
            departmentChartPO.setId(rootId);
            departmentChartPO.setFname(rs.getString("name"));
            // 岗位处理后的ID
            departmentChartPO.setExpand("1");
            departmentChartPO.setFisvitual(rs.getString("isvitual"));

            // 部门负责人
            departmentChartPO.setFleader(getDepartmentLeader(fLeader));
            dataList.add(departmentChartPO);
        }

        if (showJob) {
            // 查询部门下的岗位
            if (isRealTime) {
                sql = "select a.id,a.jobtitlename as name from hrmjobtitles a inner join jcl_org_job b on a.id = b.ec_jobtitle and (b.delete_type is null or b.delete_type = 0) where b.ec_department = '" + departmentId + "'";
            } else {
                sql = "select jobid as id ,jobname as name from jcl_chart_job where departmentid = '" + departmentId + "' and versionid = " + versionId;
            }
            rs.executeQuery(sql);
            while (rs.next()) {
                ChartPO chartPO = new ChartPO();
                chartPO.setFtype("3");
                chartPO.setFobjid(rs.getString("id"));
                chartPO.setId(departmentId + "_" + chartPO.getFobjid());
                chartPO.setFname(rs.getString("name"));
                // 岗位处理后的ID
                chartPO.setParentId(rootId);
                chartPO.setExpand("1");
                chartPO.setHasChildren("1");
                jobTitleList.add(chartPO);
            }

            // 遍历岗位、查询对应岗位下的人员
            if (isRealTime) {
                if (isRealDimension) {
                    sql = "select a.id,a.lastname as name  ,a.belongto ,a.companyworkyear from hrmresource a where a.status < 4 and a.departmentid = ? and a.jobtitle = ?";
                } else {
                    sql = "select a.id,a.lastname as name ,a.belongto ,a.companyworkyear from hrmresource a inner join hrmresourcevirtual b on a.id = b.resourceid where a.status < 4 and b.departmentid = ? and a.jobtitle = ?";
                }
            } else {
                sql = "select a.resourceid as id,a.lastname as name ,a.belongto ,a.companyworkyear from jcl_chart_resource a where a.status < 4 and a.departmentid = ? and a.jobtitleid = ? and versionid = " + versionId;
            }
            for (ChartPO jobTitlePO : jobTitleList) {
                resourceNum = 0;
                rs.executeQuery(sql, departmentId, jobTitlePO.getFobjid());
                String parentId = departmentId + "_" + jobTitlePO.getFobjid();
                while (rs.next()) {
                    ChartPO chartPO = getResourceChartPO(rs.getString("id"), rs.getString("name"), parentId, rs.getString("belongto"), rs.getString("companyworkyear"));
                    resourceNum++;
                    dataList.add(chartPO);
                }
                jobTitlePO.setFonjob(resourceNum);
                departmentOnJob += resourceNum;
                dataList.add(jobTitlePO);
            }
            departmentChartPO.setHasChildren(CollectionUtils.isNotEmpty(jobTitleList) ? "1" : "0");
        } else {
            // 直接查询岗位下的人员
            if (isRealTime) {
                if (isRealDimension) {
                    sql = "select a.id,a.lastname as name ,a.belongto ,a.companyworkyear from hrmresource a where a.status < 4 and a.departmentid = ? ";
                } else {
                    sql = "select a.id,a.lastname as name ,a.belongto ,a.companyworkyear from hrmresource a inner join hrmresourcevirtual b on a.id = b.resourceid where a.status < 4 and b.departmentid = ? ";
                }
            } else {
                sql = "select a.resourceid as id,a.lastname as name ,a.belongto ,a.companyworkyear from jcl_chart_resource a where a.status < 4 and a.departmentid = ? and versionid = " + versionId;
            }
            rs.executeQuery(sql, departmentId);
            while (rs.next()) {
                ChartPO chartPO = getResourceChartPO(rs.getString("id"), rs.getString("name"), rootId, rs.getString("belongto"), rs.getString("companyworkyear"));
                dataList.add(chartPO);
                departmentOnJob++;
            }
        }
        departmentChartPO.setFonjob(departmentOnJob);


        Map<String, Object> result = new HashMap<>();
        result.put("api_status", true);
        result.put("data", dataList);
        return result;
    }

    @Override
    public String selectVersionDate(String id) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select recorddate from jcl_org_chartversion where id = ?", id);
        rs.next();
        return rs.getString("recorddate");
    }

    /**
     * 构建人员图谱元素
     *
     * @param id              人员ID
     * @param name            人员名称
     * @param parentId        父级ID
     * @param belongTo        是否次账号
     * @param companyWorkYear 司龄
     * @return
     */
    private ChartPO getResourceChartPO(String id, String name, String parentId, String belongTo, String companyWorkYear) {
        ChartPO chartPO = new ChartPO();
        chartPO.setFtype("4");
        chartPO.setFobjid(id);
        chartPO.setId(chartPO.getFobjid());
        chartPO.setFname(name);
        // 岗位处理后的ID
        chartPO.setParentId(parentId);
        chartPO.setExpand("1");
        chartPO.setHasChildren("0");
        chartPO.setBelongto(Util.null2String(belongTo));
        chartPO.setCompanyWorkYear(companyWorkYear);
        try {
            chartPO.setFleaderimg(new ResourceComInfo().getMessagerUrls(chartPO.getId()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return chartPO;
    }

    /**
     * 获取历史顶部元素sql
     *
     * @param root
     * @param dimension 维度ID
     * @param versionId
     * @return
     */
    private String getLastTimeTopSql(String root, String dimension, String versionId) {
        if ("0".equals(root)) {
            //查询集团维度历史版本
            if (isRealDimension) {
                //组织维度
                return "select id,companyname as name,'0' as type  from " + COMPANY_TABLE;
            } else {
                //查询其他维度集团版本信息
                return "select companyvirtualid as id,companyname as name,'0' as type  from  " + COMPANY_TABLE + " where " +
                        " versionid = " + versionId + " and companyvirtualid = " + dimension;
            }
        } else {
            if (hasVirtualFields) {
                if (showVirtual) {
                    return "select " + SUB_COMPANY_ID + " as id,subcompanyname as name,'1' as type,isvirtual as isvitual,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where versionid = " + versionId + " and subcompanyid = " + root;
                } else {
                    return "select " + SUB_COMPANY_ID + " as id,subcompanyname as name,'1' as type,isvirtual as isvitual,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where versionid = " + versionId + " and subcompanyid = " + root + " and (isvirtual is null or isvirtual != '1')";
                }
            } else {
                return "select " + SUB_COMPANY_ID + " as id,subcompanyname as name,'1' as type,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where versionid = " + versionId + " and subcompanyid = " + root;
            }
        }
    }

    @Override
    public Map<String, Object> versionRecord(Map<String, Object> params, User user) {


        RecordSet rs = new RecordSet();

        // 维度
        String dimension = Util.null2String(params.get("fclass"));
        dimension = StringUtils.isBlank(dimension) ? "0" : dimension;
        //描述
        String description = Util.null2String(params.get("description"));

        //当前日期
        String currentDate = OrganizationDateUtil.getFormatLocalDateTime(new Date());
        //当前用户
        String currentUser = String.valueOf(user.getUID());

        //版本记录表数据存储
        synchronized (this) {
            getOrgChartService(user).insertChartVersion(Integer.valueOf(dimension), description);
            String versionId = "";
            String createDate = OrganizationDateUtil.getFormatLocalDate(LocalDate.now());
            rs.executeQuery("select id from JCL_ORG_CHARTVERSION where fclass = ? and createtime = ?", dimension, createDate);
            if (rs.next()) {
                versionId = Util.null2String(rs.getString("id"));
            }

            RecordSetTrans recordSetTrans = new RecordSetTrans();
            try {
                recordSetTrans.setAutoCommit(false);
                if ("0".equals(dimension)) {
                    //实体维度
                    trueDimension(recordSetTrans, versionId, currentUser, currentDate);
                } else {
                    virtualDimension(recordSetTrans, versionId, currentUser, currentDate, dimension);
                }
                recordSetTrans.commit();
            } catch (Exception e) {
                recordSetTrans.rollback();
                e.printStackTrace();
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("api_status", true);
        return result;
    }

    @Override
    public Map<String, Object> getDepartmentTree(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>(2);

        RecordSet rs = new RecordSet();
        List<CompanyTreePO> departmentTree = new ArrayList<>();
        String subCompany = Util.null2String(params.get("subcompany"));
        String dimension = Util.null2String(params.get("fclass"));
        String versionId = Util.null2String(params.get("id"));
        if (StringUtils.isBlank(subCompany)) {
            subCompany = "0";
        }
        String sql = getDepartmentTreeSql(versionId, dimension, subCompany);
        rs.executeQuery(sql);
        while (rs.next()) {
            departmentTree.add(CompanyTreePO.builder().id(rs.getString("id")).pId(rs.getString("pId")).disabled(!rs.getString("id").startsWith("d")).value(rs.getString("value")).title(rs.getString("title")).isLeaf(judgeTreeLeaf(versionId, dimension, rs.getString("id"))).build());
        }
        result.put("departmentTree", departmentTree);
        result.put("api_status", true);
        return result;
    }

    @Override
    public Map<String, Object> getMovingTree(Map<String, Object> params) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id,companyname from hrmcompany");
        TreeSelect companyTree = null;
        List<String> expandedKeys = new ArrayList<>();
        String showCanceled = Util.null2String(params.get("showCanceled"));
        String expandedKeyStr = Util.null2String(params.get("expandedKeys"));
        if (rs.next()) {
            companyTree = TreeSelect.builder().key(rs.getString("id")).title(rs.getString("companyname")).type(TreeSelect.COMPANY).showCanceled(showCanceled).build();
            expandedKeys.add(companyTree.getKey());
        }
        // 所有需展开节点，同时需查询父级部门、分部ID
        addParentTreeId(expandedKeys, expandedKeyStr);
        Map<String, Object> result = new HashMap<>(3);
        result.put("movingTree", Collections.singletonList(companyTree));
        result.put("expandedKeys", expandedKeys);
        result.put("api_status", true);
        return result;
    }

    @Override
    public Map<String, Object> getFullSelectTree(Map<String, Object> params) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id,companyname from hrmcompany");
        TreeSelect companyTree = null;
        List<String> expandedKeys = new ArrayList<>();
        String showCanceled = Util.null2String(params.get("showCanceled"));
        if (rs.next()) {
            companyTree = TreeSelect.builder().key(rs.getString("id")).title(rs.getString("companyname")).type(TreeSelect.COMPANY).showCanceled(showCanceled).build();
            expandedKeys = companyTree.getChildren().stream().filter(item -> CollectionUtils.isNotEmpty(item.getChildren())).map(TreeSelect::getKey).collect(Collectors.toList());
            expandedKeys.add(companyTree.getKey());
        }
        disableTreeItem(Collections.singletonList(companyTree), TreeSelect.DEPARTMENT);
        Map<String, Object> result = new HashMap<>(3);
        result.put("selectTree", companyTree);
        result.put("expandedKeys", expandedKeys);
        result.put("api_status", true);
        return result;
    }

    @SneakyThrows
    @Override
    public Map<String, Object> selectStatistics(Map<String, Object> params) {
        RecordSet rs = new RecordSet();
        Map<String, Object> result = new HashMap<>(4);
        DepartmentComInfo departmentComInfo = new DepartmentComInfo();
        ResourceComInfo resourceComInfo = new ResourceComInfo();
        SubCompanyComInfo subCompanyComInfo = new SubCompanyComInfo();
        List<StatisticsVO> statisticsVOS = new ArrayList<>();
        rs.executeQuery("select id,data_id,super_id,type,on_job_num,staff_num,creator,create_time,update_time from jcl_org_onjob");
        while (rs.next()) {
            Integer type = Util.getIntValue(rs.getString("type"));
            String dataIdName;
            String superIdName;
            if (ModuleTypeEnum.subcompanyfielddefined.getValue().equals(type)) {
                dataIdName = subCompanyComInfo.getSubCompanyname(Util.null2String((rs.getString("data_id"))));
                superIdName = subCompanyComInfo.getSubCompanyname(Util.null2String((rs.getString("super_id"))));
            }else {
                dataIdName = departmentComInfo.getDepartmentname(Util.null2String((rs.getString("data_id"))));
                superIdName = departmentComInfo.getDepartmentname(Util.null2String((rs.getString("super_id"))));
            }

            StatisticsVO statisticsVO = StatisticsVO.builder()
                    .key(Util.getIntValue(rs.getString("id")))
                    .dataIdName(dataIdName)
                    .superIdName(superIdName)
                    .type(type)
                    .onJobNum(Util.getIntValue(rs.getString("on_job_num")))
                    .staffNum(Util.getIntValue(rs.getString("staff_num")))
                    .creator(resourceComInfo.getLastname(Util.null2String(rs.getString("creator"))))
                    .createTime(Util.null2String(rs.getString("create_time")))
                    .updateTime(Util.null2String(rs.getString("update_time")))
                    .build();
            statisticsVOS.add(statisticsVO);
        }
        result.put("result",statisticsVOS);
        return result;
    }

    @Override
    public Map<String, Object> recordStatistics(StatisticsParam statisticsParam) {
        Map<String, Object> result = new HashMap<>(2);
        long startTime = System.currentTimeMillis();
        //需要更新的数据List
        List<StatisticsPO> list = filterIds(statisticsParam.getCompanyId());
        RecordSetTrans rst = new RecordSetTrans();
        // 核心线程数
        int corePoolSize = 5;
        // 最大线程数
        int maxPoolSize = 10;
        // 设置每个子列表的大小
        int batchSize = 100;

        List<List<StatisticsPO>> splittedLists = OrganizationCommonUtil.splitList(list, batchSize);
        // 创建线程池
        ExecutorService executorService = ThreadUtil.newExecutor(corePoolSize, maxPoolSize);

        // 遍历每个子列表，并提交给线程池执行
        for (List<StatisticsPO> subList : splittedLists) {
            executorService.submit(() -> {
                // 在此处编写处理子列表的逻辑
                for (StatisticsPO statisticsPO : subList) {
                    // 处理逻辑
                    StatisticsPO po = buildCount(statisticsPO);
                    statisticsPO.setOnJobNum(po.getOnJobNum());
                    statisticsPO.setStaffNum(po.getStaffNum());
                    statisticsPO.setUpdateTime(OrganizationDateUtil.getFormatLocalDateTime(LocalDateTime.now()));
                }
            });
        }

        // 关闭线程池
        executorService.shutdown();
        // 等待线程池关闭
        while (!executorService.isTerminated()) {
            // 空循环等待线程池终止
        }

        try {
            rst.setAutoCommit(false);
            for (StatisticsPO item : list) {
                rst.executeUpdate("update jcl_org_onjob set on_job_num = ?,staff_num = ? where data_id = ? and type = ?",item.getOnJobNum(),
                        item.getStaffNum(),item.getDataId(),item.getType());
            }

            rst.commit();
        }catch (Exception e) {
            result.put("errorMsg",e.getMessage());
            rst.rollback();
        }


        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        result.put("time",executionTime);
        return result;
    }

    @Override
    public Map<Integer, HrmLabelVO> selectLabel() {
        RecordSet rs = new RecordSet();
        Map<Integer, HrmLabelVO> labelData = new HashMap<>();
        //labelId集合
        List<Integer> labelIds = Arrays.asList(547190,547194,547196,547262,547282,547283,547284,547285,547286,547287,547292,547293,547294,547296,547298,547299,547300,547301,547302,547303,547304,547305,547307,547310,547313,547314,547315,547316,547317,
                547318,547319,547320,547321,547322,547323,547324,547326,547327,547328,547329,547330,547331,547332,547333,547334,547345,547346,547447,547468,547473,547475,547476,547477,547478,547478,547264,547265,547463,547464,547465,
                547480,547481,547482,547483,547484,547485,547486,547487,547488,547489,547490,547491,547492,547493,547494,547495,547505,547506,547507,547508,547509,547510,547512,547513,547514,547515,547516,547517,547518,547519,547520,547521,547522,547523,547524,547525,
                547526);
        labelIds.forEach(item -> {
            rs.executeQuery("select labelName from HtmlLabelInfo where indexid = ? and languageid = ?",item,user.getLanguage());
            if (rs.next()){
                labelData.put(item,HrmLabelVO.builder().labelName(Util.null2String(rs.getString("labelName"))).build());
            }

        });

        return labelData;
    }

    /**
     * 生成人数
     * @param stp
     * @return
     */
    private StatisticsPO buildCount(StatisticsPO stp) {
        RecordSet rs = new RecordSet();
        DepartmentComInfo dept = new DepartmentComInfo();
        SubCompanyComInfo subCompany = new SubCompanyComInfo();
        ArrayList<Integer> list = new ArrayList<>();
        list.add(stp.getDataId());
        StringBuilder jobSql = new StringBuilder();
        StringBuilder staffSql = new StringBuilder();

        if (ModuleTypeEnum.subcompanyfielddefined.getValue().equals(stp.getType())) {
            subCompany.getSubCompanyLists(String.valueOf(stp.getDataId()), list);
            String value = StringUtils.join(list,",");
            jobSql.append("select count(1) as count from hrmresource where status < 4 and subcompanyid1 in (").append(value).append(")");
            staffSql.append("select a.staff_num  from jcl_org_staff a inner join jcl_org_staffplan b\n" +
                    "  on a.plan_id = b.id\n" +
                    " and a.ec_company = ? and a.ec_department is null and a.delete_type = 0\n" +
                    " and b.plan_year = ?");
        }else {
            dept.getAllChildDeptByDepId(list,String.valueOf(stp.getDataId()));
            String value = StringUtils.join(list,",");
            jobSql.append("select count(1) as count from hrmresource where status < 4 and departmentid in (").append(value).append(")");
            staffSql.append("select a.staff_num  from jcl_org_staff a inner join jcl_org_staffplan b\n" +
                    "  on a.plan_id = b.id\n" +
                    " and a.ec_department = ? and a.job_id is null and a.delete_type = 0\n" +
                    " and b.plan_year = ?");
        }

        if ("false".equals(new BaseBean().getPropValue("hrmOrganization","accountType"))) {
            jobSql.append(" and accounttype != 1");
        }

        rs.executeQuery(jobSql.toString());
        rs.next();
        stp.setOnJobNum(Util.getIntValue(rs.getString("count")));

        rs.executeQuery(staffSql.toString(),stp.getDataId(),OrganizationDateUtil.getFormatYear(new Date()));
        if (rs.next()) {
            stp.setStaffNum(Util.getIntValue(rs.getString("staff_num")));
        }else {
            stp.setStaffNum(0);
        }

        return stp;
    }




    /**
     * 基础数据过滤
     * @param companyId
     * @return
     */
    private List<StatisticsPO> filterIds (Integer companyId) {
        RecordSet rs = new RecordSet();
        RecordSet iRs = new RecordSet();
        List<Integer> hisCompanyList = new ArrayList<>();
        List<Integer> hisDepartmentList = new ArrayList<>();

        rs.executeQuery("select data_id from jcl_org_onjob where type = 1");
        while (rs.next()) {
            hisCompanyList.add(Util.getIntValue(rs.getString("data_id")));
        }
        rs.executeQuery("select data_id from jcl_org_onjob where type = 2");
        while (rs.next()) {
            hisDepartmentList.add(Util.getIntValue(rs.getString("data_id")));
        }

        List<StatisticsPO> companyList = new ArrayList<>();
        List<StatisticsPO> departmentList = new ArrayList<>();
        StringBuilder sql = new StringBuilder();
        StringBuilder sql1 = new StringBuilder();
        sql.append("select id,supsubcomid from hrmsubcompany where 1=1");
        sql1.append("select id,supdepid from hrmdepartment where 1=1");
        if (companyId != null) {
            sql.append(" and id = ").append(companyId);
            sql1.append(" and subcompanyid1 = ").append(companyId);
        }

        rs.executeQuery(sql.toString());
        while (rs.next()) {

            StatisticsPO statisticsPO = StatisticsPO.builder()
                    .dataId(Util.getIntValue(rs.getString("id")))
                    .superId(Util.getIntValue(rs.getString("supsubcomid")))
                    .type(1)
                    .onJobNum(0)
                    .staffNum(0)
                    .creator(user.getUID())
                    .createTime(OrganizationDateUtil.getFormatLocalDateTime(LocalDateTime.now()))
                    .updateTime(OrganizationDateUtil.getFormatLocalDateTime(LocalDateTime.now()))
                    .build();
            companyList.add(statisticsPO);
        }

        rs.executeQuery(sql1.toString());
        while (rs.next()) {
            StatisticsPO statisticsPO = StatisticsPO.builder()
                    .dataId(Util.getIntValue(rs.getString("id")))
                    .superId(Util.getIntValue(rs.getString("supdepid")))
                    .type(2)
                    .onJobNum(0)
                    .staffNum(0)
                    .creator(user.getUID())
                    .createTime(OrganizationDateUtil.getFormatLocalDateTime(LocalDateTime.now()))
                    .updateTime(OrganizationDateUtil.getFormatLocalDateTime(LocalDateTime.now()))
                    .build();
            departmentList.add(statisticsPO);

        }

        List<StatisticsPO> addCompanyList = companyList.stream()
                .filter(entity -> !hisCompanyList.contains(entity.getDataId()))
                .collect(Collectors.toList());


        List<StatisticsPO> addDeptList = departmentList.stream()
                .filter(entity -> !hisDepartmentList.contains(entity.getDataId()))
                .collect(Collectors.toList());

        addCompanyList.addAll(addDeptList);


        if (CollectionUtils.isNotEmpty(addCompanyList)) {
            addCompanyList.forEach(item -> iRs.executeUpdate("insert into jcl_org_onjob(data_id,super_id,type,on_job_num,staff_num,creator,create_time,update_time)" +
                            " values(?,?,?,?,?,?,?,?)",item.getDataId(),item.getSuperId(),item.getType(),
                    item.getOnJobNum(),item.getStaffNum(),item.getCreator(),item.getCreateTime(),item.getUpdateTime()));
        }

        companyList.addAll(departmentList);
        return companyList;
    }

    /**
     * 添加树结构所有上级节点
     *
     * @param expandedKeys   完整的上级ID集合
     * @param expandedKeyStr 需要展开的树ID
     */
    private void addParentTreeId(List<String> expandedKeys, String expandedKeyStr) {
        if (StringUtils.isNotBlank(expandedKeyStr)) {
            try {
                if (expandedKeyStr.startsWith("d")) {
                    expandedKeyStr = expandedKeyStr.replace("d", "");
                    String[] array;
                    // 上级分部ID
                    String subcompanyid1 = new DepartmentComInfo().getSubcompanyid1(expandedKeyStr);
                    if (StringUtils.isNotBlank(subcompanyid1)) {
                        String allSupCompany = new SubCompanyComInfo().getAllSupCompany(subcompanyid1);
                        array = allSupCompany.split(",");
                        for (String supCompany : array) {
                            if (StringUtils.isBlank(supCompany)) {
                                continue;
                            }
                            expandedKeys.add("s" + supCompany);
                        }
                        expandedKeys.add("s" + subcompanyid1);
                    }

                    // 上级部门ID
                    String allSupDepartment = new DepartmentComInfo().getAllSupDepartment(expandedKeyStr);
                    array = allSupDepartment.split(",");
                    for (String supDepartment : array) {
                        if (StringUtils.isBlank(supDepartment)) {
                            continue;
                        }
                        expandedKeys.add("d" + supDepartment);
                    }
                    expandedKeys.add("d" + expandedKeyStr);
                } else {
                    // 上级分部ID
                    String allSupCompany = new SubCompanyComInfo().getAllSupCompany(expandedKeyStr);
                    String[] array = allSupCompany.split(",");
                    for (String supCompany : array) {
                        if (StringUtils.isBlank(supCompany)) {
                            continue;
                        }
                        expandedKeys.add("s" + supCompany);
                    }
                    expandedKeys.add("s" + expandedKeyStr);

                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
    }

    /**
     * 树节点是否禁用
     *
     * @param companyTreeList TreeSelect组件数据集合
     */
    private void disableTreeItem(List<TreeSelect> companyTreeList, String enableTreeType) {
        if (CollectionUtils.isNotEmpty(companyTreeList)) {
            for (TreeSelect treeSelect : companyTreeList) {
                treeSelect.setDisabled(!enableTreeType.equals(treeSelect.getType()));
                List<TreeSelect> children = treeSelect.getChildren();
                if (CollectionUtils.isNotEmpty(children)) {
                    disableTreeItem(children, enableTreeType);
                }
            }
        }
    }

    private void trueDimension(RecordSetTrans recordSetTrans, String versionId, String currentUser, String currentDate) {
        RecordSet rs = new RecordSet();
        rs.execute("delete from jcl_chart_subcompany where versionid = " + versionId);
        rs.execute("delete from jcl_chart_department where versionid = " + versionId);
        rs.execute("delete from jcl_chart_job where versionid = " + versionId);
        rs.execute("delete from jcl_chart_resource where versionid = " + versionId);

        String subCompanyQuerySql;//分部查询数据sql
        String deptQuerySql;//部门查询数据sql
        //判断是否有虚拟组织字段
        boolean virtualFlag = isHasVirtualFields();
        if (virtualFlag) {
            subCompanyQuerySql = "select a.id as subcompanyid,\n" +
                    "               a.subcompanyname,\n" +
                    "               a.subcompanydesc,\n" +
                    "               a.companyid      as company,\n" +
                    "               a.SUPSUBCOMID    as supsubcompanyid,\n" +
                    "               b.subcompanyname as supsubcompany,\n" +
                    "               a.canceled,\n" +
                    "               a.subcompanycode,\n" +
                    "               a.limitusers,\n" +
                    "               a.tlevel,\n" +
                    "               c.fblx           as isvirtual,d.on_job_num,d.staff_num \n" +
                    "        from hrmsubcompany a\n" +
                    "                 left join hrmsubcompany b on a.supsubcomid = b.id\n" +
                    "                 left join hrmsubcompanydefined c on a.id = c.subcomid " +
                    "                 left join JCL_ORG_ONJOB d on a.id=d.data_id and d.type=1 ";
            deptQuerySql = "select a.id as departmentid, a.departmentmark, a.departmentname, a.subcompanyid1  as subcompanyid, " +
                    "b.SUBCOMPANYNAME as subcompany,a.supdepid as supdepartmentid,c.departmentname as supdepartment," +
                    "a.canceled,a.departmentcode,a.coadjutant,a.tlevel,d.bmlx as isvirtual,a.bmfzr as fleader,e.on_job_num,e.staff_num " +
                    "from hrmdepartment a left join hrmsubcompany b on a.subcompanyid1 = b.id " +
                    "left join hrmdepartment c on a.supdepid = c.id " +
                    "left join hrmdepartmentdefined d on a.id=d.deptid " +
                    "left join JCL_ORG_ONJOB e on a.id=e.data_id and e.type=2 ";

        } else {
            subCompanyQuerySql = "select a.id as subcompanyid,\n" +
                    "               a.subcompanyname,\n" +
                    "               a.subcompanydesc,\n" +
                    "               a.companyid      as company,\n" +
                    "               a.supsubcomid    as supsubcompanyid,\n" +
                    "               b.subcompanyname as supsubcompany,\n" +
                    "               a.canceled,\n" +
                    "               a.subcompanycode,\n" +
                    "               a.limitusers,\n" +
                    "               a.tlevel,\n" +
                    "               c.on_job_num,\n" +
                    "               c.staff_num\n" +
                    "        from hrmsubcompany a\n" +
                    "        left join hrmsubcompany b on a.supsubcomid = b.id\n" +
                    "        left join JCL_ORG_ONJOB c on a.id=c.data_id and c.type=1 ";
            deptQuerySql = "select a.id as departmentid,\n" +
                    "               a.departmentmark,\n" +
                    "               a.departmentname,\n" +
                    "               a.subcompanyid1  as subcompanyid,\n" +
                    "               b.SUBCOMPANYNAME as subcompany,\n" +
                    "               a.supdepid       as supdepartmentid,\n" +
                    "               c.departmentname as supdepartment,\n" +
                    "               a.canceled,\n" +
                    "               a.departmentcode,\n" +
                    "               a.coadjutant,\n" +
                    "               a.tlevel,\n" +
                    "               a.bmfzr          as fleader,\n" +
                    "               d.on_job_num,\n" +
                    "               d.staff_num" +
                    "        from hrmdepartment a\n" +
                    "                 left join hrmsubcompany b on a.subcompanyid1 = b.id\n" +
                    "                 left join hrmdepartment c on a.supdepid = c.id\n" +
                    "                 left join JCL_ORG_ONJOB d on a.id=d.data_id and d.type=2 ";
        }


        List<Object> insertList = new ArrayList<>();
        List<List<Object>> insertParamList = new ArrayList<>();
        //当前分部版本存储
        rs.executeQuery(subCompanyQuerySql);
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(currentUser);
            insertList.add(StringUtils.isBlank(rs.getString("subcompanyid")) ? null : rs.getInt("subcompanyid"));
            insertList.add(rs.getString("subcompanyname"));
            insertList.add(rs.getString("subcompanydesc"));
            insertList.add(rs.getString("company"));
            insertList.add(StringUtils.isBlank(rs.getString("supsubcompanyid")) ? null : rs.getInt("supsubcompanyid"));
            insertList.add(rs.getString("supsubcompany"));
            insertList.add(StringUtils.isBlank(rs.getString("canceled")) ? null : rs.getInt("canceled"));
            insertList.add(rs.getString("subcompanycode"));
            insertList.add(StringUtils.isBlank(rs.getString("limitusers")) ? null : rs.getInt("limitusers"));
            insertList.add(StringUtils.isBlank(rs.getString("tlevel")) ? null : rs.getInt("tlevel"));
            insertList.add(currentDate);
            insertList.add(virtualFlag ? Util.getIntValue(rs.getString("isvirtual"), 0) : 0);
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertList.add(Util.getIntValue(rs.getString("on_job_num"),0));
            insertList.add(Util.getIntValue(rs.getString("staff_num"),0));
            insertParamList.add(insertList);
        }

        String insertSubSql = "insert into jcl_chart_subcompany(creater, subcompanyid, subcompanyname, subcompanydesc, company,\n" +
                "                                             supsubcompanyid, supsubcompany, canceled, subcompanycode, limitusers,\n" +
                "                                             tlevel, versiondate, isvirtual,versionId,job_num,staff_num) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertSubSql, insertParamList);

        //当前部门版本存储
        rs.executeQuery(deptQuerySql);
        insertParamList = new ArrayList<>();
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(currentUser);
            insertList.add(StringUtils.isBlank(rs.getString("departmentid")) ? null : rs.getInt("departmentid"));
            insertList.add(rs.getString("departmentmark"));
            insertList.add(rs.getString("departmentname"));
            insertList.add(StringUtils.isBlank(rs.getString("subcompanyid")) ? null : rs.getInt("subcompanyid"));
            insertList.add(rs.getString("subcompany"));
            insertList.add(StringUtils.isBlank(rs.getString("supdepartmentid")) ? null : rs.getInt("supdepartmentid"));
            insertList.add(rs.getString("supdepartment"));
            insertList.add(rs.getInt("canceled"));
            insertList.add(rs.getString("departmentcode"));
            insertList.add(rs.getString("coadjutant"));
//            insertList.add(rs.getInt("tlevel"));
            insertList.add(rs.getString("fleader"));
            insertList.add(currentDate);
            insertList.add(virtualFlag ? Util.getIntValue(rs.getString("isvirtual"), 0) : 0);
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertList.add(Util.getIntValue(rs.getString("on_job_num"),0));
            insertList.add(Util.getIntValue(rs.getString("staff_num"),0));
            insertParamList.add(insertList);
        }
        String insertDeptSql = "insert into jcl_chart_department(creater, departmentid, departmentmark, departmentname, subcompanyid,\n" +
                "                                         subcompany, supdepartmentid, supdepartment, canceled, departmentcode,\n" +
                "                                         coadjutant, fleader,versiondate, isvirtual,versionid,job_num,staff_num) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertDeptSql, insertParamList);

        //当前岗位版本存储
        rs.executeQuery("select b.id as jobid,b.JOBTITLENAME as jobname,a.ec_department as departmentid," +
                "c.departmentname as department,a.ec_company as subcompanyid,d.subcompanyname as subcompany," +
                "b.jobresponsibility,a.forbidden_tag as canceled,a.job_no as jobcode,a.description " +
                "from jcl_org_job a inner join hrmjobtitles b on a.ec_jobtitle = b.id " +
                "left join hrmdepartment c on a.ec_department=c.id " +
                "left join hrmsubcompany d on a.ec_company=d.id");
        insertParamList = new ArrayList<>();
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(StringUtils.isBlank(rs.getString("jobid")) ? null : rs.getString("jobid"));
            insertList.add(currentUser);
            insertList.add(rs.getString("jobname"));
            insertList.add(rs.getString("departmentid"));
            insertList.add(rs.getString("department"));
            insertList.add(rs.getString("subcompanyid"));
            insertList.add(rs.getString("subcompany"));
            insertList.add(rs.getString("jobresponsibility"));
            insertList.add(StringUtils.isBlank(rs.getString("canceled")) ? null : rs.getInt("canceled"));
            insertList.add(rs.getString("jobcode"));
            insertList.add(rs.getString("description"));
            insertList.add(currentDate);
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertParamList.add(insertList);
        }
        String insertJobSql = "insert into jcl_chart_job(jobid,creater,jobname,departmentid,department,subcompanyid," +
                "subcompany,jobresponsibility,canceled,jobcode,description,versiondate,versionid)values(?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertJobSql, insertParamList);

        //当前人员版本存储
        rs.executeQuery("select a.id as resourceid,workyear,usekind,managerstr,status,sex,accounttype,belongto," +
                "loginid,maritalstatus,a.telephone,mobile,mobilecall,email,b.locationname,resourcetype,startdate," +
                "enddate,d.id as jobtitleid,d.JOBTITLENAME as jobtitle,joblevel,seclevel,departmentid,e.departmentname as department," +
                "a.subcompanyid1 as subcompanyid,f.subcompanyname as subcompany,a.costcenterid as costcenter," +
                "a.managerid as manager,a.assistantid as assistant,workcode,classification,policy," +
                "degree,a.lastname,a.companyworkyear from hrmresource a " +
                "left join hrmlocations b on a.locationid = b.id " +
                "left join hrmjobtitles d on a.jobtitle = d.id " +
                "left join hrmdepartment e on a.departmentid = e.id " +
                "left join hrmsubcompany f on a.subcompanyid1=f.id");
        insertParamList = new ArrayList<>();
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(StringUtils.isBlank(rs.getString("resourceid")) ? null : rs.getInt("resourceid"));
            insertList.add(currentUser);
            insertList.add(StringUtils.isBlank(rs.getString("workyear")) ? null : rs.getString("workyear"));
            insertList.add(rs.getString("usekind"));
            insertList.add(rs.getString("managerstr"));
            insertList.add(StringUtils.isBlank(rs.getString("status")) ? null : rs.getInt("status"));
            insertList.add(rs.getString("sex"));
            insertList.add(StringUtils.isBlank(rs.getString("accounttype")) ? null : rs.getInt("accounttype"));
            insertList.add(StringUtils.isBlank(rs.getString("belongto")) ? null : rs.getInt("belongto"));
            insertList.add(rs.getString("loginid"));
            insertList.add(rs.getString("maritalstatus"));
            insertList.add(rs.getString("telephone"));
            insertList.add(rs.getString("mobile"));
            insertList.add(rs.getString("mobilecall"));
            insertList.add(rs.getString("email"));
            insertList.add(rs.getString("locationname"));
            insertList.add(rs.getString("resourcetype"));
            insertList.add(rs.getString("startdate"));
            insertList.add(rs.getString("enddate"));
            insertList.add(StringUtils.isBlank(rs.getString("jobtitleid")) ? null : rs.getInt("jobtitleid"));
            insertList.add(rs.getString("jobtitle"));
            insertList.add(StringUtils.isBlank(rs.getString("joblevel")) ? null : rs.getInt("joblevel"));
            insertList.add(StringUtils.isBlank(rs.getString("seclevel")) ? null : rs.getInt("seclevel"));
            insertList.add(StringUtils.isBlank(rs.getString("departmentid")) ? null : rs.getInt("departmentid"));
            insertList.add(rs.getString("department"));
            insertList.add(StringUtils.isBlank(rs.getString("subcompanyid")) ? null : rs.getInt("subcompanyid"));
            insertList.add(rs.getString("subcompany"));
            insertList.add(rs.getString("costcenter"));
            insertList.add(StringUtils.isBlank(rs.getString("manager")) ? null : rs.getInt("manager"));
            insertList.add(StringUtils.isBlank(rs.getString("assistant")) ? null : rs.getInt("assistant"));
            insertList.add(rs.getString("workcode"));
            insertList.add(rs.getString("classification"));
            insertList.add(currentDate);
            insertList.add(rs.getString("policy"));
            insertList.add(rs.getString("degree"));
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertList.add(rs.getString("lastname"));
            insertList.add(StringUtils.isBlank(rs.getString("companyworkyear")) ? null : rs.getString("companyworkyear"));
            insertParamList.add(insertList);
        }
        String insertResourceSql = "insert into jcl_chart_resource(resourceid, creater, workyear, usekind, managerstr," +
                "status, sex, accounttype,belongto, loginid, maritalstatus, telephone, mobile, mobilecall, email," +
                "locationname, resourcetype, startdate, enddate, jobtitleid, jobtitle, joblevel,seclevel, departmentid," +
                "department, subcompanyid, subcompany, costcenter,manager, assistant, workcode, classification, " +
                "versiondate, policy, degree,versionid,lastname,companyworkyear) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +
                "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertResourceSql, insertParamList);
    }

    private void virtualDimension(RecordSetTrans recordSetTrans, String versionId, String currentUser, String currentDate, String fclass) {
        RecordSet rs = new RecordSet();
        List<Object> insertList;
        List<List<Object>> insertParamList = new ArrayList<>();
        rs.execute("delete from jcl_chart_companyvirtual where versionid = " + versionId);
        rs.execute("delete from jcl_chart_subcompanyvirtual where versionid = " + versionId);
        rs.execute("delete from jcl_chart_departmentvirtual where versionid = " + versionId);
        rs.execute("delete from jcl_chart_resource where versionid = " + versionId);

        //虚拟总部存储
        rs.executeQuery("select id as companyvirtualid,companyname,companycode,companydesc,showorder,canceled," +
                "virtualtype,virtualtypedesc from hrmcompanyvirtual where id=?", fclass);
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(StringUtils.isBlank(rs.getString("companyvirtualid")) ? null : rs.getInt("companyvirtualid"));
            insertList.add(currentUser);
            insertList.add(rs.getString("companyname"));
            insertList.add(rs.getString("companycode"));
            insertList.add(rs.getString("companydesc"));
            insertList.add(StringUtils.isBlank(rs.getString("showorder")) ? null : rs.getInt("showorder"));
            insertList.add(StringUtils.isBlank(rs.getString("canceled")) ? null : rs.getInt("canceled"));
            insertList.add(rs.getString("virtualtype"));
            insertList.add(rs.getString("virtualtypedesc"));
            insertList.add(currentDate);
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertParamList.add(insertList);
        }
        String insertVirtualComSql = "insert into jcl_chart_companyvirtual(companyvirtualid,creater,companyname,companycode,companydesc,showorder,\n" +
                "canceled,virtualtype,virtualtypedesc,versiondate,versionid) values(?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertVirtualComSql, insertParamList);

        //虚拟分部版本存储
        rs.executeQuery("select a.id as subcompanyvirtualid,a.subcompanyname,a.subcompanycode,a.subcompanydesc," +
                "b.subcompanyname as supsubcompany,a.supsubcomid,c.companyname as company,a.companyid,a.canceled," +
                "a.virtualtypeid  as virtualtype,a.tlevel,a.showorder from hrmsubcompanyvirtual a " +
                "left join hrmsubcompanyvirtual b on a.supsubcomid = b.id\n" +
                "left join hrmcompanyvirtual c on a.companyid = c.id where a.companyid=?", fclass);
        insertParamList = new ArrayList<>();
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(StringUtils.isBlank(rs.getString("subcompanyvirtualid")) ? null : rs.getInt("subcompanyvirtualid"));
            insertList.add(currentUser);
            insertList.add(rs.getString("subcompanyname"));
            insertList.add(rs.getString("subcompanycode"));
            insertList.add(rs.getString("subcompanydesc"));
            insertList.add(rs.getString("supsubcompany"));
            insertList.add(StringUtils.isBlank(rs.getString("supsubcomid")) ? null : rs.getInt("supsubcomid"));
            insertList.add(rs.getString("company"));
            insertList.add(StringUtils.isBlank(rs.getString("companyid")) ? null : rs.getInt("companyid"));
            insertList.add(StringUtils.isBlank(rs.getString("canceled")) ? null : rs.getInt("canceled"));
            insertList.add(rs.getString("virtualtype"));
            insertList.add(rs.getString("tlevel"));
            insertList.add(StringUtils.isBlank(rs.getString("showorder")) ? null : rs.getInt("showorder"));
            insertList.add(currentDate);
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertParamList.add(insertList);
        }
        String insertVirtualSubComSql = "insert into jcl_chart_subcompanyvirtual(subcompanyvirtualid, creater, " +
                "subcompanyname, subcompanycode,subcompanydesc, supsubcompany, supsubcompanyid, company, companyid," +
                "canceled, virtualtype, tlevel, showorder, versiondate,versionid) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertVirtualSubComSql, insertParamList);

        //虚拟部门版本存储
        rs.executeQuery("select a.id as departmentvirtualid,a.departmentname,a.departmentcode,a.departmentmark," +
                "b.DEPARTMENTNAME as supdeptment,b.SUPDEPID as supdepid,a.allsupdepid,c.SUBCOMPANYNAME as subcompany," +
                "a.SUBCOMPANYID1  as subcompanyid,a.canceled,a.virtualtype,a.tlevel,a.showorder from hrmdepartmentvirtual a " +
                "left join hrmdepartmentvirtual b on a.SUPDEPID = b.id " +
                "left join hrmsubcompanyvirtual c on a.SUBCOMPANYID1 = c.id where a.virtualtype = ?", fclass);
        insertParamList = new ArrayList<>();
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(StringUtils.isBlank(rs.getString("departmentvirtualid")) ? null : rs.getInt("departmentvirtualid"));
            insertList.add(currentUser);
            insertList.add(rs.getString("departmentname"));
            insertList.add(rs.getString("departmentcode"));
            insertList.add(rs.getString("departmentmark"));
            insertList.add(rs.getString("supdeptment"));
            insertList.add(StringUtils.isBlank(rs.getString("supdepid")) ? null : rs.getInt("supdepid"));
            insertList.add(StringUtils.isBlank(rs.getString("allsupdepid")) ? null : rs.getInt("allsupdepid"));
            insertList.add(rs.getString("subcompany"));
            insertList.add(StringUtils.isBlank(rs.getString("subcompanyid")) ? null : rs.getInt("subcompanyid"));
            insertList.add(StringUtils.isBlank(rs.getString("canceled")) ? null : rs.getInt("canceled"));
            insertList.add(rs.getString("virtualtype"));
            insertList.add(rs.getString("tlevel"));
            insertList.add(StringUtils.isBlank(rs.getString("showorder")) ? null : rs.getInt("showorder"));
            insertList.add(currentDate);
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertParamList.add(insertList);
        }
        String insertVirtualDeptSql = "insert into jcl_chart_departmentvirtual(departmentvirtualid, creater, " +
                "departmentname, departmentcode,departmentmark, supdeptment, supdepid, allsupdepid, subcompany, " +
                "subcompanyid, canceled, virtualtype, tlevel, showorder, versiondate,versionid) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertVirtualDeptSql, insertParamList);

        //虚拟人员版本存储
        rs.executeQuery("select resourceid,workyear,usekind,a.managerstr,status,sex,accounttype,belongto,loginid," +
                "maritalstatus,b.telephone,mobile,mobilecall,email,c.locationname,resourcetype,startdate,enddate," +
                "d.id as jobtitleid,d.JOBTITLENAME as jobtitle,joblevel,seclevel,e.id as departmentid,e.departmentname as department," +
                "f.id as subcompanyid,f.subcompanyname as subcompany,b.costcenterid as costcenter," +
                "b.managerid as manager,b.assistantid as assistant,workcode,classification,policy,degree,b.lastname,b.companyworkyear," +
                "a.virtualtype from hrmresourcevirtual a \n" +
                "left join hrmresource b on a.RESOURCEID=b.ID\n" +
                "left join  hrmlocations c on b.locationid=c.id\n" +
                "left join hrmjobtitles d on b.jobtitle=d.id\n" +
                "left join hrmdepartmentvirtual e on a.DEPARTMENTID=e.id\n" +
                "left join hrmsubcompanyvirtual f on a.SUBCOMPANYID=f.id where a.virtualtype=?", fclass);
        insertParamList = new ArrayList<>();
        while (rs.next()) {
            insertList = new ArrayList<>();
            insertList.add(StringUtils.isBlank(rs.getString("resourceid")) ? null : rs.getInt("resourceid"));
            insertList.add(currentUser);
            insertList.add(StringUtils.isBlank(rs.getString("workyear")) ? null : rs.getString("workyear"));
            insertList.add(rs.getString("usekind"));
            insertList.add(rs.getString("managerstr"));
            insertList.add(StringUtils.isBlank(rs.getString("status")) ? null : rs.getInt("status"));
            insertList.add(rs.getString("sex"));
            insertList.add(StringUtils.isBlank(rs.getString("accounttype")) ? null : rs.getInt("accounttype"));
            insertList.add(StringUtils.isBlank(rs.getString("belongto")) ? null : rs.getInt("belongto"));
            insertList.add(rs.getString("loginid"));
            insertList.add(rs.getString("maritalstatus"));
            insertList.add(rs.getString("telephone"));
            insertList.add(rs.getString("mobile"));
            insertList.add(rs.getString("mobilecall"));
            insertList.add(rs.getString("email"));
            insertList.add(rs.getString("locationname"));
            insertList.add(rs.getString("resourcetype"));
            insertList.add(rs.getString("startdate"));
            insertList.add(rs.getString("enddate"));
            insertList.add(StringUtils.isBlank(rs.getString("jobtitleid")) ? null : rs.getInt("jobtitleid"));
            insertList.add(rs.getString("jobtitle"));
            insertList.add(StringUtils.isBlank(rs.getString("joblevel")) ? null : rs.getInt("joblevel"));
            insertList.add(StringUtils.isBlank(rs.getString("seclevel")) ? null : rs.getInt("seclevel"));
            insertList.add(StringUtils.isBlank(rs.getString("departmentid")) ? null : rs.getInt("departmentid"));
            insertList.add(rs.getString("department"));
            insertList.add(StringUtils.isBlank(rs.getString("subcompanyid")) ? null : rs.getInt("subcompanyid"));
            insertList.add(rs.getString("subcompany"));
            insertList.add(rs.getString("costcenter"));
            insertList.add(StringUtils.isBlank(rs.getString("manager")) ? null : rs.getInt("manager"));
            insertList.add(StringUtils.isBlank(rs.getString("assistant")) ? null : rs.getInt("assistant"));
            insertList.add(rs.getString("workcode"));
            insertList.add(rs.getString("classification"));
            insertList.add(currentDate);
            insertList.add(rs.getString("policy"));
            insertList.add(rs.getString("degree"));
            insertList.add(StringUtils.isBlank(versionId) ? null : Util.getIntValue(versionId));
            insertList.add(rs.getString("lastname"));
            insertList.add(StringUtils.isBlank(rs.getString("companyworkyear")) ? null : rs.getString("companyworkyear"));
            insertParamList.add(insertList);
        }
        String insertVirtualHrmSql = "insert into jcl_chart_resource(resourceid, creater, workyear, usekind, managerstr," +
                "status, sex, accounttype,belongto, loginid, maritalstatus, telephone, mobile, mobilecall, email," +
                "locationname, resourcetype, startdate, enddate, jobtitleid, jobtitle, joblevel,seclevel, departmentid," +
                "department, subcompanyid, subcompany, costcenter,manager, assistant, workcode, classification, " +
                "versiondate, policy, degree,versionid,lastname,companyworkyear) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +
                "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        insertData(recordSetTrans, insertVirtualHrmSql, insertParamList);
    }

    private void insertData(RecordSetTrans recordSetTrans, String insertSql, List<List<Object>> insertParamList) {
        try {
            recordSetTrans.executeBatchSql(insertSql, insertParamList);
        } catch (Exception e) {
            recordSetTrans.rollback();
            e.printStackTrace();
        }
    }

    private boolean isHasVirtualFields() {
        RecordSet rs = new RecordSet();
        boolean flag = false;
        rs.executeQuery("select count(1) as num from hrm_formfield where (GROUPID =6 and FIELDNAME = 'fblx') or (GROUPID =7 and FIELDNAME = 'bmlx')");
        if (rs.next()) {
            String num = rs.getString("num");
            flag = "2".equals(num);
        }
        return flag;
    }

    /**
     * 查询实时数据,顶级元素SQL
     *
     * @param root      顶级元素ID
     * @param dimension 维度ID
     * @return 查询SQL
     */
    private String getRealTimeTopSql(String root, String dimension) {
        if ("0".equals(root)) {
            // 查询集团数据
            if (isRealDimension) {
                // 查询实际集团表
                return "select id,companyname as name,'0' as type  from " + COMPANY_TABLE;
            } else {
                // 查询其他维度集团信息
                return "select id,companyname as name,'0' as type  from " + COMPANY_TABLE + " where id = '" + dimension + "'";
            }
        } else {
            if (hasVirtualFields) {
                if (showVirtual) {
                    return "select a.id,a.subcompanyname as name,'1' as type ,b.fblx as isvitual,c.on_job_num,c.staff_num from " + SUB_COMPANY_TABLE + " a left join " + SUB_COMPANY_DEFINED_TABLE + " b on a.id = b.subcomid left join jcl_org_onjob c on a.id=c.data_id and c.type=1  where a.id = '" + root + "' order by showorder,id";
                } else {
                    return "select a.id,a.subcompanyname as name,'1' as type ,b.fblx as isvitual,c.on_job_num,c.staff_num from " + SUB_COMPANY_TABLE + " a left join " + SUB_COMPANY_DEFINED_TABLE + " b on a.id = b.subcomid left join jcl_org_onjob c on a.id=c.data_id and c.type=1 where a.id = '" + root + "' and (b.fblx is null or b.fblx!='1') order by showorder,id";

                }
            } else {
                return "select a.id,a.subcompanyname as name,'1' as type,b.on_job_num,b.staff_num from " + SUB_COMPANY_TABLE + " a left join jcl_org_onjob b on a.id=b.data_id and b.type=1 where a.id = '" + root + "' order by a.showorder,a.id";
            }
        }
    }

    /**
     * 查询实时数据,子元素SQL
     *
     * @param sql    查询SQL
     * @param fType  上级元素类型
     * @param fObjId 上级元素ID
     * @return 查询SQL
     */
    private String getRealTimeChildSql(String sql, String fType, String fObjId) {
        if (StringUtils.isNotBlank(fType)) {
            switch (fType) {
                case "0":
                    if (hasVirtualFields) {
                        if (showVirtual) {
                            sql = "select a.id,a.subcompanyname as name,'1' as type ,b.fblx as isvitual,c.on_job_num,c.staff_num from " + SUB_COMPANY_TABLE + " a left join " + SUB_COMPANY_DEFINED_TABLE + " b on a.id = b.subcomid left join jcl_org_onjob c on a.id=c.data_id and c.type=1 where (a.canceled is null or a.canceled != '1') and (a.supsubcomid is null or a.supsubcomid = '0') and a.companyid = '" + fObjId + "'";
                        } else {
                            sql = "select a.id,a.subcompanyname as name,'1' as type ,b.fblx as isvitual,c.on_job_num,c.staff_num from " + SUB_COMPANY_TABLE + " a left join " + SUB_COMPANY_DEFINED_TABLE + " b on a.id = b.subcomid left join jcl_org_onjob c on a.id=c.data_id and c.type=1 where (a.canceled is null or a.canceled != '1') and (a.supsubcomid is null or a.supsubcomid = '0') and (b.fblx is null or b.fblx != '1') and a.companyid = '" + fObjId + "'";
                        }
                    } else {
                        sql = "select a.id,a.subcompanyname as name,'1' as type,b.on_job_num,b.staff_num from " + SUB_COMPANY_TABLE + " a left join jcl_org_onjob b on a.id=b.data_id and b.type=1 where (a.canceled is null or a.canceled != '1') and (a.supsubcomid is null or a.supsubcomid = '0') and a.companyid = '" + fObjId + "'";
                    }

                    // 一级分部数据分权处理
                    if (isRealTime && user.getUID() != 1 && isRealDimension) {
                        DetachUtil detachUtil = new DetachUtil(user);
                        if(detachUtil.isDETACH()) {
                            String ids = detachUtil.getJclRoleLevels();
                            sql = sql + " and a.id in (" + ids + ")";
                        }
                    }
                    break;
                case "1":
                    if (hasVirtualFields) {
                        if (showVirtual) {
                            sql = "select a.id,a.subcompanyname as name,'1' as type ,b.fblx as isvitual,showorder,c.on_job_num,c.staff_num from " + SUB_COMPANY_TABLE + " a left join " + SUB_COMPANY_DEFINED_TABLE + " b on a.id = b.subcomid left join jcl_org_onjob c on a.id=c.data_id and c.type=1 where (a.canceled is null or a.canceled != '1') and a.supsubcomid = '" + fObjId + "'" +
                                    " union select a.id,a.departmentname as name,'2' as type ,b.bmlx as isvitual,showorder,c.on_job_num,c.staff_num from " + DEPARTMENT_TABLE + " a left join " + DEPARTMENT_DEFINED_TABLE + " b on a.id = b.deptid left join jcl_org_onjob c on a.id=c.data_id and c.type=2 where (a.canceled is null or a.canceled != '1') and (a.supdepid is null or a.supdepid = '0') and subcompanyid1 = '" + fObjId + "'";
                        } else {
                            sql = "select a.id,a.subcompanyname as name,'1' as type ,b.fblx as isvitual,showorder,c.on_job_num,c.staff_num from " + SUB_COMPANY_TABLE + " a left join " + SUB_COMPANY_DEFINED_TABLE + " b on a.id = b.subcomid left join jcl_org_onjob c on a.id=c.data_id and c.type=1 where (a.canceled is null or a.canceled != '1') and (b.fblx is null or b.fblx != '1') and a.supsubcomid = '" + fObjId + "'" +
                                    " union select a.id,a.departmentname as name,'2' as type ,b.bmlx as isvitual,showorder,c.on_job_num,c.staff_num from " + DEPARTMENT_TABLE + " a left join " + DEPARTMENT_DEFINED_TABLE + " b on a.id = b.deptid left join jcl_org_onjob c on a.id=c.data_id and c.type=2 where (a.canceled is null or a.canceled != '1') and (a.supdepid is null or a.supdepid = '0') and (b.bmlx is null or b.bmlx != '1') and subcompanyid1 = '" + fObjId + "'";
                        }
                    } else {
                        sql = "select a.id,a.subcompanyname as name,'1' as type,showorder,b.on_job_num,b.staff_num from " + SUB_COMPANY_TABLE + " a left join jcl_org_onjob b on a.id=b.data_id and b.type=1 where (canceled is null or canceled != '1') and supsubcomid = '" + fObjId + "'" +
                                " union select a.id,a.departmentname as name,'2' as type,showorder,b.on_job_num,b.staff_num from " + DEPARTMENT_TABLE + " a left join jcl_org_onjob b on a.id=b.data_id and b.type=2 where (canceled is null or canceled != '1') and (supdepid is null or supdepid = '0') and subcompanyid1 = '" + fObjId + "'";
                    }
                    break;
                case "2":
                    if (hasVirtualFields) {
                        if (showVirtual) {
                            sql = "select a.id,a.departmentname as name,'2' as type ,b.bmlx as isvitual,c.on_job_num,c.staff_num from " + DEPARTMENT_TABLE + " a left join " + DEPARTMENT_DEFINED_TABLE + " b on a.id = b.deptid left join jcl_org_onjob c on a.id=c.data_id and c.type=2 where (a.canceled is null or a.canceled != '1') and supdepid = '" + fObjId + "'";
                        } else {
                            sql = "select a.id,a.departmentname as name,'2' as type ,b.bmlx as isvitual,c.on_job_num,c.staff_num from " + DEPARTMENT_TABLE + " a left join hrmdepartmentdefined b on a.id = b.deptid left join jcl_org_onjob c on a.id=c.data_id and c.type=2 where (canceled is null or canceled != '1') and (b.bmlx is null or b.bmlx != '1') and a.supdepid  = '" + fObjId + "'";
                        }
                    } else {
                        sql = "select a.id,a.departmentname as name,'2' as type,b.on_job_num,b.staff_num from " + DEPARTMENT_TABLE + " a left join jcl_org_onjob b on a.id=b.data_id and b.type=2 where (canceled is null or canceled != '1') and supdepid  = '" + fObjId + "'";
                    }
                    break;
                default:
                    break;
            }
            sql += " order by showorder,id";
        }
        return sql;
    }

    /**
     * 查询历史数据,子元素SQL
     *
     * @param sql    查询SQL
     * @param fType  上级元素类型
     * @param fObjId 上级元素ID
     * @return 查询SQL
     */
    private String getLastTimeChildSql(String sql, String fType, String fObjId, String versionId) {
        if (StringUtils.isNotBlank(fType)) {
            switch (fType) {
                case "0":
                    if (hasVirtualFields) {
                        if (showVirtual) {
                            sql = "select " + SUB_COMPANY_ID + " as id,a.subcompanyname as name,'1' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a   where (a.canceled is null or a.canceled != '1') and (a.supsubcompanyid is null or a.supsubcompanyid = '0') and versionid = " + versionId;
                        } else {
                            sql = "select " + SUB_COMPANY_ID + " as id,a.subcompanyname as name,'1' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where (a.canceled is null or a.canceled != '1') and (a.supsubcompanyid is null or a.supsubcompanyid = '0') and (isvirtual is null or isvirtual != '1') and versionid = " + versionId;
                        }
                    } else {
                        sql = "select " + SUB_COMPANY_ID + " as id,a.subcompanyname as name,'1' as type,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where (a.canceled is null or a.canceled != '1') and (a.supsubcompanyid is null or a.supsubcompanyid = '0') and versionid = " + versionId;
                    }
                    if (!isRealDimension) {
                        sql += " and companyid = " + fObjId;
                    }
                    break;
                case "1":
                    if (hasVirtualFields) {
                        if (showVirtual) {
                            sql = "select " + SUB_COMPANY_ID + " as id,a.subcompanyname as name,'1' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where (a.canceled is null or a.canceled != '1') and a.supsubcompanyid = '" + fObjId + "' and versionid = " + versionId +
                                    " union select " + DEPARTMENT_ID + " as id,a.departmentname as name,'2' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + DEPARTMENT_TABLE + " a  where (a.canceled is null or a.canceled != '1') and (a.supdepartmentid is null or a.supdepartmentid = '0') and subcompanyid = '" + fObjId + "' and versionid = " + versionId;
                        } else {
                            sql = "select " + SUB_COMPANY_ID + " as id,a.subcompanyname as name,'1' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where (a.canceled is null or a.canceled != '1') and (isvirtual is null or isvirtual != '1') and a.supsubcompanyid = '" + fObjId + "' and versionid = " + versionId +
                                    " union select " + DEPARTMENT_ID + " as id,a.departmentname as name,'2' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + DEPARTMENT_TABLE + " a  where (a.canceled is null or a.canceled != '1') and (a.supdepartmentid is null or a.supdepartmentid = '0') and (isvirtual is null or isvirtual != '1') and subcompanyid = '" + fObjId + "' and versionid = " + versionId;
                        }
                    } else {
                        sql = "select " + SUB_COMPANY_ID + " as id,a.subcompanyname as name,'1' as type,a.job_num,a.staff_num from " + SUB_COMPANY_TABLE + " a  where (canceled is null or canceled != '1') and supsubcompanyid = '" + fObjId + "' and versionid = " + versionId +
                                " union select " + DEPARTMENT_ID + " as id,a.departmentname as name,'2' as type,a.job_num,a.staff_num from " + DEPARTMENT_TABLE + " a  where (canceled is null or canceled != '1') and (supdepid is null or supdepid = '0') and subcompanyid = '" + fObjId + "' and versionid = " + versionId;
                    }
                    break;
                case "2":
                    if (hasVirtualFields) {
                        if (showVirtual) {
                            sql = "select " + DEPARTMENT_ID + " as id,a.departmentname as name,'2' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + DEPARTMENT_TABLE + " a  where (a.canceled is null or a.canceled != '1') and supdepartmentid = '" + fObjId + "' and versionid = " + versionId;
                        } else {
                            sql = "select " + DEPARTMENT_ID + " as id,a.departmentname as name,'2' as type ,isvirtual as isvitual,a.job_num,a.staff_num from " + DEPARTMENT_TABLE + " a  where (canceled is null or canceled != '1') and (isvirtual is null or isvirtual != '1') and a.supdepartmentid  = '" + fObjId + "' and versionid = " + versionId;
                        }
                    } else {
                        sql = "select " + DEPARTMENT_ID + " as id,a.departmentname as name,'2' as type,a.job_num,a.staff_num from " + DEPARTMENT_TABLE + " a  where (canceled is null or canceled != '1') and supdepid  = '" + fObjId + "' and versionid = " + versionId;
                    }
                    break;
                default:
                    break;
            }
        }
        return sql;
    }

    /**
     * 查询实时数据,子节点元素
     *
     * @param topChartPO     父级元素
     * @param dataList       所有元素集合
     * @param selectDepth    所选部门层级
     * @param hideDepartment
     */
    private void findChildData(ChartPO topChartPO, List<ChartPO> dataList, Integer selectDepth, String versionId, boolean hideDepartment) {
        String fType = topChartPO.getFtype();
        String fObjId = topChartPO.getFobjid();
        String sql = "";
        if (isRealTime) {
            sql = getRealTimeChildSql(sql, fType, fObjId);
        } else {
            sql = getLastTimeChildSql(sql, fType, fObjId, versionId);
        }

        if (StringUtils.isNotBlank(sql)) {
            List<ChartPO> currentList = new ArrayList<>();
            RecordSet recordSet = new RecordSet();
            recordSet.executeQuery(sql);
            while (recordSet.next()) {
                ChartPO chartPO = new ChartPO();
                chartPO.setFtype(recordSet.getString("type"));
                chartPO.setFobjid(recordSet.getString("id"));
                chartPO.setFname(recordSet.getString("name"));
                chartPO.setOnJobNum(isRealTime ? Util.getIntValue(recordSet.getString("on_job_num"),0) : Util.getIntValue(recordSet.getString("job_num"),0));
                chartPO.setStaffNum(Util.getIntValue(recordSet.getString("staff_num"),0));
                chartPO.setParentId(topChartPO.getId());
                chartPO.setFisvitual(recordSet.getString("isvitual"));
                chartPO.setHasChildren(getHasChildren(chartPO.getFtype(), chartPO.getFobjid()).toString());
                chartPO.setDepartmentDepth(getDepartmentDepth(chartPO, topChartPO));
                // 小于、等于所选层级元素展开
                chartPO.setExpand(inDepth(selectDepth, chartPO.getDepartmentDepth()) ? "1" : "0");
                filterAndAddData(currentList, chartPO, hideDepartment);
            }


            for (ChartPO chartPO : currentList) {
                if (inDepth(selectDepth, chartPO.getDepartmentDepth())) {
                    findChildData(chartPO, dataList, selectDepth, versionId, hideDepartment);
                }
            }

            dataList.addAll(currentList);
        }


    }


    /**
     * 根据维度初始化表名
     *
     * @param dimension 所选维度
     */
    public void initTableNameByClass(String dimension, String id) {
        isRealDimension = StringUtils.isBlank(dimension) || "0".equals(dimension);
        isRealTime = StringUtils.isBlank(id) || "0".equals(id);
        if (isRealTime) {
            if (isRealDimension) {
                COMPANY_TABLE = "hrmcompany";
                SUB_COMPANY_TABLE = "hrmsubcompany";
                SUB_COMPANY_DEFINED_TABLE = "hrmsubcompanydefined";
                DEPARTMENT_TABLE = "hrmdepartment";
                DEPARTMENT_DEFINED_TABLE = "hrmdepartmentdefined";
                RecordSet rs = new RecordSet();
                rs.executeQuery("select count(1) as num from hrm_formfield where (GROUPID =6 and FIELDNAME = 'fblx') or (GROUPID =7 and FIELDNAME = 'bmlx')");
                if (rs.next()) {
                    String num = rs.getString("num");
                    hasVirtualFields = "2".equals(num);

                } else {
                    hasVirtualFields = false;
                }
            } else {
                COMPANY_TABLE = "hrmcompanyvirtual";
                SUB_COMPANY_TABLE = "hrmsubcompanyvirtual";
                DEPARTMENT_TABLE = "hrmdepartmentvirtual";
                // 其他维度，无虚拟组织
                hasVirtualFields = false;
            }
        } else {
            if (isRealDimension) {
                COMPANY_TABLE = "hrmcompany";
                SUB_COMPANY_TABLE = "jcl_chart_subcompany";
                DEPARTMENT_TABLE = "jcl_chart_department";
                SUB_COMPANY_ID = "subcompanyid";
                DEPARTMENT_ID = "departmentid";
                hasVirtualFields = true;
            } else {
                COMPANY_TABLE = "jcl_chart_companyvirtual";
                SUB_COMPANY_TABLE = "jcl_chart_subcompanyvirtual";
                DEPARTMENT_TABLE = "jcl_chart_departmentvirtual";
                SUB_COMPANY_ID = "subcompanyvirtualid";
                DEPARTMENT_ID = "departmentvirtualid";
                // 其他维度，无虚拟组织
                hasVirtualFields = false;
            }
        }
    }


    /**
     * 判断是否有子元素
     *
     * @param fType  元素类型
     * @param fObjId 元素ID
     * @return boolean 包含子元素：true,不包含子元素：false
     */
    private Boolean getHasChildren(String fType, String fObjId) {
        return false;
    }

    /**
     * 获取部门负责人
     *
     * @param ids 部门负责人ID
     * @return 人员名称
     */
    private String getDepartmentLeader(String ids) {
        if (!isRealTime) {
            return ids;
        }
        if (StringUtils.isBlank(ids)) {
            return "";
        }
        List<String> leaderList = new ArrayList<>();
        String[] split = ids.split(",");
        for (String s : split) {
            String lastName = MapperProxyFactory.getProxy(SystemDataMapper.class).getScHrmResourceNameById(s);
            if (StringUtils.isNotBlank(lastName)) {
                leaderList.add(lastName);
            }
        }
        return StringUtils.join(leaderList, ",");
    }

    /**
     * 当前元素是否在展开层级内
     *
     * @param selectDepth  所选部门层级
     * @param currentDepth 当前部门层级
     */
    private boolean inDepth(Integer selectDepth, Integer currentDepth) {
        if (selectDepth == 1) {
            return true;
        }
        return currentDepth < selectDepth + 1;
    }

    /**
     * 获取当前部门层级
     *
     * @param chartPO     当前元素
     * @param parentChart 上级元素
     */
    private Integer getDepartmentDepth(ChartPO chartPO, ChartPO parentChart) {
        if ("2".equals(chartPO.getFtype())) {
            if ("1".equals(parentChart.getFtype())) {
                return 2;
            }
            return parentChart.getDepartmentDepth() + 1;
        }
        return 0;
    }


    /**
     * 获取部门树下拉框SQL
     *
     * @param versionId  版本ID
     * @param dimension  维度
     * @param subCompany 上级Id
     * @return SQL
     */
    private String getDepartmentTreeSql(String versionId, String dimension, String subCompany) {
        // 是否展示当前数据
        boolean isSearchCurrent = StringUtils.isBlank(versionId) || "0".equals(versionId);
        boolean isCurrentDimension = StringUtils.isNotBlank(dimension) && !"0".equals(dimension);
        boolean isDepartment = subCompany.startsWith("d");
        String sql;
        DBType dbType = DBType.get(new RecordSet().getDBType());
        if (isDepartment) {
            subCompany = subCompany.replace("d", "");
            if (isSearchCurrent) {
                sql = "select " + dbType.concat("d", "id") + "as id, id as value, departmentname as title, " + dbType.concat("d", "supdepid") + " as pId from hrmdepartment where (canceled is null or canceled != '1') and " + dbType.ifNull("supdepid", "0") + " = " + subCompany;
                if (isCurrentDimension) {
                    sql = "select " + dbType.concat("d", "id") + "as id, id as value, departmentname as title, " + dbType.concat("d", "supdepid") + " as pId from hrmdepartmentvirtual where (canceled is null or canceled != '1') and " + dbType.ifNull("supdepid", "0") + " = " + subCompany;
                }
                sql += " order by showorder,id ";
            } else {
                sql = "select " + dbType.concat("d", "departmentid") + "as id, departmentid as value, departmentname as title, " + dbType.concat("d", "supdepartmentid") + " as pId from jcl_chart_department where (canceled is null or canceled != '1') and " + dbType.ifNull("supdepartmentid", "0") + " = " + subCompany;
                if (isCurrentDimension) {
                    sql = "select " + dbType.concat("d", "departmentvirtualid") + "as id, departmentvirtualid as value, departmentname as title, " + dbType.concat("d", "supdepid") + " as pId from jcl_chart_departmentvirtual where (canceled is null or canceled != '1') and " + dbType.ifNull("supdepid", "0") + " = " + subCompany;
                }
                // 添加时间轴条件
                sql += " and versionid = " + versionId;
            }
        } else {
            if (isSearchCurrent) {
                sql = "select " + dbType.concat("", "id") + " as id, id as value, subcompanyname as title, supsubcomid as pId, showorder from hrmsubcompany where (canceled is null or canceled != '1') and " + dbType.ifNull("supsubcomid", "0") + " = " + subCompany +
                        " union select " + dbType.concat("d", "id") + "as id, id as value, departmentname as title, subcompanyid1 as pId, showorder from hrmdepartment where (canceled is null or canceled != '1') and  (supdepid is null or supdepid =0) and " + dbType.ifNull("subcompanyid1", "0") + " = " + subCompany;
                if (isCurrentDimension) {
                    sql = "select id as id, id as value, subcompanyname as title, supsubcomid as pId from hrmsubcompanyvirtual where (canceled is null or canceled != '1') and " + dbType.ifNull("supsubcomid", "0") + " = " + subCompany + " and companyid = '" + dimension + "' " +
                            " union select " + dbType.concat("d", "id") + "as id, id as value, departmentname as title, subcompanyid1 as pId from hrmdepartmentvirtual where (canceled is null or canceled != '1') and (supdepid is null or supdepid =0) and" + dbType.ifNull("subcompanyid1", "0") + " = " + subCompany;
                }
                sql += " order by showorder,id ";
            } else {
                sql = "select " + dbType.concat("", "subcompanyid") + " as id, subcompanyid as value, subcompanyname as title, supsubcompanyid as pId from jcl_chart_subcompany where (canceled is null or canceled != '1') and " + dbType.ifNull("supsubcompanyid", "0") + " = " + subCompany +
                        " union select " + dbType.concat("d", "subcompanyid") + "as id, subcompanyid as value, departmentname as title, subcompanyid as pId from jcl_chart_department where (canceled is null or canceled != '1') and (supdepartmentid is null or supdepartmentid =0) and " + dbType.ifNull("subcompanyid", "0") + " = " + subCompany;
                if (isCurrentDimension) {
                    sql = "select " + dbType.concat("", "subcompanyvirtualid") + " as id, subcompanyvirtualid as value, subcompanyname as title, supsubcompanyid as pId from jcl_chart_subcompanyvirtual where (canceled is null or canceled != '1') and " + dbType.ifNull("supsubcompanyid", "0") + " = " + subCompany + " and companyid = '" + dimension + "' " +
                            " union select " + dbType.concat("d", "departmentvirtualid") + "as id, departmentvirtualid as value, departmentname as title, subcompanyid as pId from jcl_chart_departmentvirtual where (canceled is null or canceled != '1') and (supdepid is null or supdepid =0) and" + dbType.ifNull("subcompanyid", "0") + " = " + subCompany;
                }
                // 添加时间轴条件
                sql += " and versionid = " + versionId;
            }
        }
        return sql;
    }

    /**
     * 判断树是否为叶子节点
     *
     * @param sql    查询下级元素SQL
     * @param treeId 当前元素ID
     * @return
     */

    /**
     * 判断树是否为叶子节点
     *
     * @param versionId  版本ID
     * @param dimension  维度
     * @param subCompany 上级元素ID
     * @return
     */
    private boolean judgeTreeLeaf(String versionId, String dimension, String subCompany) {
        RecordSet recordSet = new RecordSet();
        String sql = getDepartmentTreeSql(versionId, dimension, subCompany);
        recordSet.executeQuery(sql);
        return !recordSet.next();
    }


    /**
     * 过滤部门元素
     *
     * @param currentList
     * @param chartPO
     * @param hideDepartment
     */
    private void filterAndAddData(List<ChartPO> currentList, ChartPO chartPO, boolean hideDepartment) {

        if (hideDepartment) {
            if ("2".equals(chartPO.getFtype())) {
                return;
            }
        }

        currentList.add(chartPO);
    }
}
