package com.kingdee.eas.custom.synctask;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.dao.IObjectValue;
import com.kingdee.bos.metadata.entity.*;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.eas.basedata.org.*;
import com.kingdee.eas.basedata.org.AdminOrgUnitCollection;
import com.kingdee.eas.basedata.org.AdminOrgUnitFactory;
import com.kingdee.eas.basedata.org.AdminOrgUnitInfo;
import com.kingdee.eas.basedata.org.IAdminOrgUnit;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.log.ISyncLog;
import com.kingdee.eas.custom.log.SyncLogFactory;
import com.kingdee.eas.custom.log.SyncLogInfo;
import com.kingdee.eas.custom.log.app.DataDirectionEnum;
import com.kingdee.eas.custom.log.app.DockingSystemEnum;
import com.kingdee.eas.custom.log.app.SyncEntityNameEnum;
import com.kingdee.eas.custom.log.app.SyncStatusEnum;
import com.kingdee.eas.custom.synctask.entity.AdminOrg;
import com.kingdee.eas.custom.synctask.entity.PersonEntity;
import com.kingdee.eas.custom.synctask.entity.PositionEntity;
import com.kingdee.eas.hr.ats.AtsUtil;
import com.kingdee.eas.hr.base.EmployeeTypeInfo;
import com.kingdee.eas.hr.emp.*;
import com.kingdee.eas.hr.org.JobLevelInfo;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import com.kingdee.util.StringUtils;
import okhttp3.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


public class SyncTranForOAFacadeControllerBean extends AbstractSyncTranForOAFacadeControllerBean {
    private static Logger logger =
            Logger.getLogger(SyncTranForOAFacadeControllerBean.class);
    private Properties propt = new Properties();
    private static Map<String, String> personStatusMap = new HashMap<String, String>();

    static {
        personStatusMap.put("001", "正式");//正式员工
        personStatusMap.put("013", "正式");//返聘
        personStatusMap.put("007", "正式");//长期病假
        personStatusMap.put("003", "正式");//停薪留职
        personStatusMap.put("004", "正式");//出国
        personStatusMap.put("S01", "正式");//长学
        personStatusMap.put("S20", "正式");//顾问
        personStatusMap.put("021", "解聘");//解聘
        personStatusMap.put("S09", "离职");//离职
        personStatusMap.put("010", "离职");//被动离职
        personStatusMap.put("009", "离职");//辞职
        personStatusMap.put("005", "离职");//下岗
        personStatusMap.put("020", "离职");//开除
        personStatusMap.put("S08", "离职");//返聘终止
        personStatusMap.put("S05", "离职");//派遣终止
        personStatusMap.put("S07", "离职");//临时工终止
        personStatusMap.put("S03", "离职");//实习终止
        personStatusMap.put("S06", "临时工");//临时工
        personStatusMap.put("035", "临时工");//待分配
        personStatusMap.put("S04", "临时工");//劳务派遣
        personStatusMap.put("006", "临时工");//待岗
        personStatusMap.put("002", "试用");//试用员工
        personStatusMap.put("S02", "试用");//实习生
        personStatusMap.put("011", "退休");//退休
        personStatusMap.put("012", "退休");//离休
    }

    public SyncTranForOAFacadeControllerBean() throws BOSException {
        String syncOAConfigPath = System.getProperty("EAS_HOME") + "/server/properties/scy/syncOAConfig.properties";
        try {
            propt.load(new FileInputStream(syncOAConfigPath));
        } catch (IOException e) {
            e.printStackTrace();
            String errorMsg = "获取配置文件报错，请检查配置：" + syncOAConfigPath + "   " + e.getMessage();
            throw new BOSException(errorMsg);
        }
    }

    /**
     * 同步组织
     *
     * @param ctx
     * @param billds
     * @param action
     * @throws BOSException
     */
    @Override
    protected Map _syncOrgUnitToOA(Context ctx, String billds, ActionTypeEnum action)
            throws BOSException, EASBizException {
        ISyncLog iSyncLog = SyncLogFactory.getLocalInstance(ctx);
        SyncLogInfo syncLogInfo = new SyncLogInfo();
        syncLogInfo.setEntityName(SyncEntityNameEnum.adminOrg);
        syncLogInfo.setDataDirection(DataDirectionEnum.outflow);
        syncLogInfo.setDockingSystem(DockingSystemEnum.OA);
        try {
            super._syncOrgUnitToOA(ctx, billds, action);
            logger.error("_syncOrgUnitToOA---start");
            logger.error("_syncOrgUnitToOA---billds: " + billds);
            IAdminOrgUnit iAdminOrgUnit = AdminOrgUnitFactory.getLocalInstance(ctx);
            List dataList = new ArrayList();
            //String actionType = action == null ? "" : action.getValue().toLowerCase();
            //当参数billIds不为空值时，增量同步参数中的部门数据到OA
            FilterInfo filterInfo = new FilterInfo();
            FilterItemCollection filterItems = filterInfo.getFilterItems();
            filterItems.add(new FilterItemInfo("id", "00000000-0000-0000-0000-000000000000CCE7AED4", CompareType.NOTEQUALS));
            if (!StringUtils.isEmpty(billds)) {
                Set<String> adminOrgIds = AtsUtil.toSet(billds);
                logger.error("_syncOrgUnitToOA---adminOrgIds---" + adminOrgIds);
                filterItems.add(new FilterItemInfo("id", adminOrgIds, CompareType.INCLUDE));
            }
            SelectorItemCollection sic = new SelectorItemCollection();
            sic.add("*");
            sic.add("parent.number");
            sic.add("responPosition.name");
            sic.add("responPosition.number");
            sic.add("bmfzr.number");
            sic.add("bmfzr.name");
            sic.add("bmjl.name");
            sic.add("bmjl.number");
            sic.add("zj.name");
            sic.add("zj.number");
            sic.add("fz.name");
            sic.add("fz.number");
            EntityViewInfo entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, null);
            AdminOrgUnitCollection adminOrgUnitCollection = iAdminOrgUnit.getAdminOrgUnitCollection(entityViewInfo);
            for (int i = 0; i < adminOrgUnitCollection.size(); i++) {
                AdminOrgUnitInfo adminOrgUnitInfo = adminOrgUnitCollection.get(i);
                String orgName = adminOrgUnitInfo.getName();
                AdminOrg adminOrg = new AdminOrg();
                boolean isSealUp = adminOrgUnitInfo.isIsSealUp();
                if (action == ActionTypeEnum.DELETE) {
                    logger.error("_syncOrgUnitToOA---action--" + action.getValue());
                    adminOrg.setAction("delete");
                } else {
                    adminOrg.setAction("add");
                }
                if (isSealUp) {
                    adminOrg.setCanceled("0");
                } else {
                    adminOrg.setCanceled("1");
                }
                adminOrg.setOrder(String.valueOf(adminOrgUnitInfo.getIndex()));
                adminOrg.setCode(adminOrgUnitInfo.getNumber());
                adminOrg.setShortname(orgName);
                adminOrg.setFullname(orgName);
                //adminOrg.setParent_code("ITCS");
                adminOrg.setOrg_code("0");
                AdminOrgUnitInfo parent = adminOrgUnitInfo.getParent();
                if (parent != null) {
                    adminOrg.setParent_code(parent.getNumber());
                }
                Map map = new HashMap();
                //部门负责人
                IObjectValue bmfzr = (IObjectValue) adminOrgUnitInfo.get("bmfzr");
                if (bmfzr != null) {
                    //map.put("bmfzr", bmfzr.get("name"));
                }
                //经理
                IObjectValue bmjl = (IObjectValue) adminOrgUnitInfo.get("bmjl");
                if (bmjl != null) {
                    //map.put("bmjl", bmjl.get("name"));
                }
                //总监
                IObjectValue zj = (IObjectValue) adminOrgUnitInfo.get("zj");
                if (zj != null) {
                    //map.put("zj", zj.get("name"));
                }
                //副总
                IObjectValue fz = (IObjectValue) adminOrgUnitInfo.get("fz");
                if (fz != null) {
                    //map.put("fz", fz.get("name"));
                }
                //map.put("fz", fz == null ? "" : fz.get("name"));
                adminOrg.setCustomData(map);
                dataList.add(adminOrg);
            }
            if (dataList.size() <= 0 && "00000000-0000-0000-0000-000000000000CCE7AED4".equals(billds)) {
                throw new BOSException("集团不可同步OA");
            }
            //执行同步组织到OA
            return executeSyncOrgUnitToOA(ctx, dataList, syncLogInfo);
        } catch (Exception e) {
            e.printStackTrace();
            syncLogInfo.setSyncStatus(SyncStatusEnum.ERROR);
            syncLogInfo.setSyncResult(e.getMessage());
            iSyncLog.save(syncLogInfo);
            throw new BOSException(e.getMessage());
        }
    }

    /**
     * 通过职位获取人员OAID
     *
     * @param ctx
     * @param postitonId
     * @return
     * @throws BOSException
     */
    public PersonPositionInfo getOAIDbyPostitonId(Context ctx, String postitonId) throws BOSException {
        IPersonPosition iPersonPosition = PersonPositionFactory.getLocalInstance(ctx);
        PersonPositionCollection personPositionCollection = iPersonPosition
                .getPersonPositionCollection("select * ,person.name where primaryPosition = '" + postitonId + "'");
        PersonPositionInfo personPositionInfo = personPositionCollection.get(0);
        return personPositionInfo;
    }


    /**
     * 执行同步组织到OA
     *
     * @param dataList
     * @return
     */
    public Map executeSyncOrgUnitToOA(Context ctx, List dataList, SyncLogInfo syncLogInfo) throws
            IOException, BOSException, EASBizException {
        if (dataList != null && dataList.size() > 0) {
            ObjectMapper mapper = new ObjectMapper();
            //封装请求参数
            String data = mapper.writeValueAsString(dataList);
            String params = String.format("token = %s &data = %s", getToken(), data);
            logger.error("executeSyncOrgUnitToOA----------------------params" + params);
            syncLogInfo.setRequestParams(params);
            //封装请求参数
            String syncOrgUnitApiUrl = this.propt.getProperty("syncOrgUnitApiUrl");
            logger.error("executeSyncOrgUnitToOA----------------------syncOrgUnitApiUrl" + syncOrgUnitApiUrl);
            if (StringUtils.isEmpty(syncOrgUnitApiUrl)) {
                throw new BOSException("同步组织到OA接口地址不能为空!");
            }
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(120, TimeUnit.SECONDS)
                    .writeTimeout(120, TimeUnit.SECONDS)
                    .readTimeout(120, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
            RequestBody body = RequestBody.create(mediaType, params);
            Request request = new Request.Builder()
                    .url(syncOrgUnitApiUrl)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "*/*")
                    //.addHeader("Accept-Encoding", "gzip, deflate, br")
                    .addHeader("User-Agent", "PostmanRuntime-ApipostRuntime/1.1.0")
                    .addHeader("Connection", "keep-alive")
                    .build();
            Response response = client.newCall(request).execute();
            //处理响应结果,写入日志
            return handlerResponse(ctx, response, syncLogInfo);
        } else {
            throw new BOSException("同步数据不能为空！");
        }
    }

    /**
     * 处理响应结果,写入日志
     *
     * @param ctx
     * @param response
     * @param syncLogInfo
     * @throws IOException
     * @throws BOSException
     * @throws EASBizException
     */
    private Map<String, Map<String, String>> handlerResponse(Context ctx, Response response, SyncLogInfo syncLogInfo)
            throws IOException, BOSException, EASBizException {
        if (syncLogInfo == null) {
            return null;
        }
        ISyncLog iSyncLog = SyncLogFactory.getLocalInstance(ctx);
        Map<String, Map<String, String>> resultMap = new HashMap<String, Map<String, String>>();
        String errorMsg = null;//错误信息
        if (response != null) {
            int success = 0;
            int fail = 0;
            String respBody = response.body().string();
            JSONObject respMap = JSONObject.parseObject(respBody);
            logger.error("handlerResponse--------------respMap------" + respBody);
            if (response.isSuccessful()) {
                String code = respMap.getString("code");
                if ("1".equals(code)) {
                    StringBuilder msg = new StringBuilder();
                    JSONObject result = respMap.getJSONObject("result");
                    for (String orgNumber : result.keySet()) {
                        Map<String, String> map = new HashMap<String, String>();
                        JSONObject jsonObject = result.getJSONObject(orgNumber);
                        msg.append("[").append(orgNumber).append("]");
                        if ("1".equals(jsonObject.getString("code"))) {
                            success++;
                            map.put("state", "success");
                            map.put("msg", "同步成功");
                            msg.append("同步成功\n");
                        } else {
                            fail++;
                            map.put("state", "fail");
                            map.put("msg", jsonObject.getString("msg"));
                            msg.append("同步失败，").append(jsonObject.getString("msg")).append("\n");
                        }
                        resultMap.put(orgNumber, map);
                    }
                    int total = fail + success;
                    syncLogInfo.setSyncStatus(SyncStatusEnum.SUCCESS);
                    syncLogInfo.setSyncCount(total);
                    syncLogInfo.setSuccessNum(success);
                    syncLogInfo.setFailNum(fail);
                    syncLogInfo.setSyncResult(msg.toString());
                } else {
                    syncLogInfo.setSyncStatus(SyncStatusEnum.FAIL);
                    errorMsg = respMap.getString("msg");
                    syncLogInfo.setSyncResult(errorMsg);
                }
            } else {
                syncLogInfo.setSyncStatus(SyncStatusEnum.FAIL);
                syncLogInfo.setSyncResult("请求超时");
                errorMsg = "请求超时";
            }
        } else {
            syncLogInfo.setSyncStatus(SyncStatusEnum.FAIL);
            syncLogInfo.setSyncResult("同步数据为空");
            errorMsg = "同步数据为空";
        }
        iSyncLog.save(syncLogInfo);
        if (!StringUtils.isEmpty(errorMsg)) {
            throw new BOSException(errorMsg);
        }
        return resultMap;
    }

    /**
     * 获取token
     *
     * @return
     */
    private String getToken() throws BOSException {
        String key = this.propt.getProperty("key");
        if (StringUtils.isEmpty(key)) {
            throw new BOSException("获取token key不能为空！");
        }
        long l = System.currentTimeMillis();//时间戳毫秒数
        String code = key.concat(Long.toString(l));
        String s = DigestUtils.md5Hex(code).toUpperCase();
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", s);
        map.put("ts", Long.toString(l));
        logger.error("getToken" + JSONObject.toJSONString(map));
        return JSONObject.toJSONString(map);
    }

    /**
     * 同步职位信息
     *
     * @param ctx
     * @param billds
     * @param action
     * @throws BOSException
     */
    @Override
    protected Map _syncPositionToOA(Context ctx, String billds, ActionTypeEnum action) throws
            BOSException, EASBizException {
        ISyncLog iSyncLog = SyncLogFactory.getLocalInstance(ctx);
        SyncLogInfo syncLogInfo = new SyncLogInfo();
        syncLogInfo.setEntityName(SyncEntityNameEnum.postiton);
        syncLogInfo.setDataDirection(DataDirectionEnum.outflow);
        syncLogInfo.setDockingSystem(DockingSystemEnum.OA);
        try {
            super._syncPositionToOA(ctx, billds, action);
            logger.error("_syncPositionToOA---billds: " + billds);
            String data = getPositionColData(ctx, billds);
            String syncPositionApiUrl = this.propt.getProperty("syncPositionApiUrl");
            return synScyRequest(ctx, data, syncPositionApiUrl, syncLogInfo);
        } catch (Exception e) {
            e.printStackTrace();
            syncLogInfo.setSyncStatus(SyncStatusEnum.ERROR);
            syncLogInfo.setSyncResult(e.getMessage());
            iSyncLog.save(syncLogInfo);
            throw new BOSException(e.getMessage());
        }
    }

    /**
     * 获取岗位信息
     *
     * @param ctx
     * @param billIds
     * @return
     * @throws IOException
     * @throws BOSException
     */
    protected String getPositionColData(Context ctx, String billIds) throws IOException, BOSException {
        List list = new ArrayList();
        ObjectMapper mapper = new ObjectMapper();
        Set positionIds = new HashSet();
        PositionCollection positionCollection = new PositionCollection();
        IPosition localInstance = PositionFactory.getLocalInstance(ctx);
        if (org.apache.commons.lang.StringUtils.isNotBlank(billIds)) {
            String[] split = billIds.split(",");
            for (int i = 0; i < split.length; i++) {
                positionIds.add(split[i]);
            }
            positionCollection = localInstance.getPositionCollection("where id in( " + AtsUtil.convertSetToString(positionIds) + ")");
        } else {
            positionCollection = localInstance.getPositionCollection();
        }
        for (int i = 0; i < positionCollection.size(); i++) {
            PositionEntity positionEntity = new PositionEntity();
            PositionInfo positionInfo = positionCollection.get(i);
            DeletedStatusEnum deletedStatus = positionInfo.getDeletedStatus();
            if (deletedStatus.getValue() == 2) { // 失效
                positionEntity.setAction("delete");
            } else {
                positionEntity.setAction("add");
            }
            positionEntity.setJobtitlecode(positionInfo.getNumber());
            positionEntity.setJobtitlename(positionInfo.getName());
            positionEntity.setJobtitleremark(positionInfo.getName());
            list.add(positionEntity);
        }
        //封装请求参数
        String data = mapper.writeValueAsString(list);
        logger.error("_syncPositionToOA----------------------data" + data);
        return data;
    }

    /**
     * 同步请求方法
     *
     * @param param
     * @param aipUrl
     * @return
     * @throws IOException
     */
    public Map synScyRequest(Context ctx, String param, String aipUrl, SyncLogInfo syncLogInfo) throws
            IOException, BOSException, EASBizException {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(120, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .readTimeout(120, TimeUnit.SECONDS)
                .build();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        String data = String.format("token = %s &data = %s", getToken(), param);
        syncLogInfo.setRequestParams(data);
        //logger.error("synAdminOrgRequest----------------------date" + data);
        RequestBody body = RequestBody.create(mediaType, data);
        Request request = new Request.Builder()
                .url(aipUrl)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "*/*")
                //.addHeader("Accept-Encoding", "gzip, deflate, br")
                .addHeader("User-Agent", "PostmanRuntime-ApipostRuntime/1.1.0")
                .addHeader("Connection", "keep-alive")
                .build();
        //处理响应结果,写入日志
        Response response = client.newCall(request).execute();
        return handlerResponse(ctx, response, syncLogInfo);
    }


    /**
     * 同步员工信息
     *
     * @param ctx
     * @param billds
     * @param action
     * @throws BOSException
     */
    @Override
    protected Map _syncPersonToOA(Context ctx, String billds, ActionTypeEnum action)
            throws BOSException, EASBizException {
        super._syncPersonToOA(ctx, billds, action);
        logger.error("_syncpersonToOA----------------------start");
        logger.error("_syncpersonToOA----------------------billds: " + billds);
        ISyncLog iSyncLog = SyncLogFactory.getLocalInstance(ctx);
        SyncLogInfo syncLogInfo = new SyncLogInfo();
        syncLogInfo.setEntityName(SyncEntityNameEnum.person);
        syncLogInfo.setDataDirection(DataDirectionEnum.outflow);
        syncLogInfo.setDockingSystem(DockingSystemEnum.OA);
        try {
            IPersonPosition iPersonPosition = PersonPositionFactory.getLocalInstance(ctx);
            List<PersonEntity> dataList = new ArrayList();
            //当参数billIds不为空值时，增量同步参数中的部门数据到OA
            FilterInfo filterInfo = null;
            if (!StringUtils.isEmpty(billds)) {
                Set<String> personIds = AtsUtil.toSet(billds);
                filterInfo = new FilterInfo();
                filterInfo.getFilterItems().add(new FilterItemInfo("person", personIds, CompareType.INCLUDE));
            }
            SelectorItemCollection sic = new SelectorItemCollection();
            sic.add("*");
            sic.add("person.number");
            sic.add("person.name");
            sic.add("person.id");
            sic.add("person.hireDate");
            sic.add("person.nCell");
            sic.add("person.isSyncOA");
            sic.add("person.securityLe.id");
            sic.add("person.securityLe.name");
            sic.add("person.securityLe.number");
            sic.add("person.workPlace.name");
            sic.add("person.personnelCa.name");
            sic.add("person.immediateSu.oAid");
            sic.add("person.immediateSu.name");
            sic.add("person.immediateSu.number");
            sic.add("person.employeeType.number");
            sic.add("personDep.name");
            sic.add("personDep.number");
            sic.add("personDep.id");
            sic.add("jobLevel.name");
            sic.add("jobLevel.number");
            sic.add("primaryPosition.id");
            sic.add("primaryPosition.name");
            sic.add("primaryPosition.number");
            //获取职位上面的上级职位的人员
            sic.add("primaryPosition.parent.number");
            sic.add("primaryPosition.parent.name");
            EntityViewInfo entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, null);
            PersonPositionCollection personPositionCollection = iPersonPosition.getPersonPositionCollection(entityViewInfo);
            //参加工作日期
            Map<String, Date> personOtherInfoMap = new HashMap();
            IPersonOtherInfo iPersonOtherInfo = PersonOtherInfoFactory.getLocalInstance(ctx);
            //PersonOtherInfoCollection personOtherInfoCollection = iPersonOtherInfo.getPersonOtherInfoCollection("where person = '" + personInfo.getId() + "'");
            PersonOtherInfoCollection personOtherInfoCollection = iPersonOtherInfo
                    .getPersonOtherInfoCollection("select * , person.id");
            for (int i = 0; i < personOtherInfoCollection.size(); i++) {
                PersonOtherInfoInfo personOtherInfoInfo = personOtherInfoCollection.get(i);
                //logger.error("personOtherInfoInfo.getPerson().getId------------" + personOtherInfoInfo.getPerson().getId());
                personOtherInfoMap.put(personOtherInfoInfo.getPerson().getId().toString()
                        , personOtherInfoInfo.getJobStartDate());
            }

            //调用同步oa操作
            Set setPersonIds = new HashSet();
            for (int i = 0; i < personPositionCollection.size(); i++) {
                //职业信息
                PersonPositionInfo personPositionInfo = personPositionCollection.get(i);
                PersonInfo personInfo = personPositionInfo.getPerson();
                if (personInfo.get("isSyncOA") != null) {
                    Integer isSyncOA = Integer.parseInt((String) personInfo.get("isSyncOA"));
                    if (isSyncOA == 0) {
                        PersonEntity person = packagingPerson(ctx, personPositionInfo, personOtherInfoMap, action);
                        dataList.add(person);
                        setPersonIds.add(personPositionInfo.getPerson().getId());
                    }
                }
            }
            ObjectMapper mapper = new ObjectMapper();
            logger.error("_syncpersonToOA------------------dataList----- " + mapper.writeValueAsString(dataList));
            if (dataList.size() > 0) {
                //调用执行人员到OA
                return executeSyncPersonToOA(ctx, dataList, syncLogInfo);
            } else {
                Map errorMap = new HashMap();
                errorMap.put("state", "error");
                errorMap.put("msg", "同步数据不能为空或检查是否同步OA字段是否等于否！");
                return errorMap;
            }
        } catch (Exception e) {
            e.printStackTrace();
            syncLogInfo.setSyncStatus(SyncStatusEnum.ERROR);
            syncLogInfo.setSyncResult(e.getMessage());
            iSyncLog.save(syncLogInfo);
            throw new BOSException(e.getMessage());
        }
    }

    /**
     * 执行同步人员到OA
     *
     * @param dataList
     */
    public Map executeSyncPersonToOA(Context ctx, List dataList, SyncLogInfo syncLogInfo) throws
            IOException, BOSException, EASBizException {
        if (dataList != null && dataList.size() > 0) {
            ObjectMapper mapper = new ObjectMapper();
            //封装请求参数
            String data = mapper.writeValueAsString(dataList);
            String params = String.format("token = %s &data = %s", getToken(), data);
            syncLogInfo.setRequestParams(params);
            logger.error("executeSyncPersonToOA----------------------params----" + params);
            //封装请求参数
            String syncPersonApiUrl = this.propt.getProperty("syncPersonApiUrl");
            logger.error("executeSyncPersonToOA----------------------syncPersonApiUrl----" + syncPersonApiUrl);
            if (StringUtils.isEmpty(syncPersonApiUrl)) {
                throw new BOSException("同步人员到OA接口地址不能为空!");
            }
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(120, TimeUnit.SECONDS)
                    .writeTimeout(120, TimeUnit.SECONDS)
                    .readTimeout(120, TimeUnit.SECONDS)
                    .build();
            MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
            RequestBody body = RequestBody.create(mediaType, params);
            Request request = new Request.Builder()
                    .url(syncPersonApiUrl)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "*/*")
                    //.addHeader("Accept-Encoding", "gzip, deflate, br")
                    .addHeader("User-Agent", "PostmanRuntime-ApipostRuntime/1.1.0")
                    .addHeader("Connection", "keep-alive")
                    .build();
            Response response = client.newCall(request).execute();
            //处理响应结果,写入日志
            return handlerResponse(ctx, response, syncLogInfo);
        } else {

            throw new BOSException("同步数据不能为空或检查是否同步OA字段是否等于否！");
        }
    }

    /**
     * 封装人员对象
     *
     * @param personPositionInfo
     * @return
     */
    public PersonEntity packagingPerson(Context ctx, PersonPositionInfo personPositionInfo, Map<String, Date> personOtherInfoMap, ActionTypeEnum action) throws
            BOSException, EASBizException, SQLException, IOException {
        SimpleDateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd");
        //人员
        PersonInfo personInfo = personPositionInfo.getPerson();
        //自定义人员实体
        PersonEntity person = new PersonEntity();
        //编码
        person.setWorkcode(personInfo.getNumber());
        //人员名称
        //logger.error("personInfo.getName------------" + personInfo.getName());
        person.setLastname(personInfo.getName());
        //分部
        person.setSubcompany("0");
        //部门
        AdminOrgUnitInfo personDep = personPositionInfo.getPersonDep();
        person.setDepartment(personDep.getNumber());
        //岗位
        PositionInfo primaryPosition = personPositionInfo.getPrimaryPosition();
        person.setJobtitle(primaryPosition.getNumber());
        //直接上级
        //获取所以职位对应的人员
        String getParentPersonSql = getParentPersonSql(personInfo.getNumber());
        IRowSet iRowSet = DbUtil.executeQuery(ctx, getParentPersonSql);
        String personNumber = "";
        while (iRowSet.next()) {
            String positionNumber = iRowSet.getString("positionNumber");
            personNumber = iRowSet.getString("personNumber");
        }
        if (!StringUtils.isEmpty(personNumber)) {
            person.setManagerid(personNumber);
        }
        //IObjectValue immediateSu = (IObjectValue) personInfo.get("immediateSu");
        //if (immediateSu != null) {
        //    person.setManagerid((String) immediateSu.get("number"));
        //}
        //助理 @todo
        //person.setAssistantid("");
        //状态
        EmployeeTypeInfo employeeType = personInfo.getEmployeeType();
        String number = employeeType.getNumber();
        String personStatus = personStatusMap.getOrDefault(number, "无效");
        person.setStatus(personStatus);
        //办公地点 @todo
        IObjectValue workPlace = (IObjectValue) personInfo.get("workPlace");
        if (workPlace != null) {
            person.setLocationid((String) workPlace.get("name"));
        }
        //移动电话
        person.setMobile(personInfo.getNCell());
        //办公室电话
        person.setTelephone(personInfo.getOfficePhone());
        //电子邮件
        person.setEmail(personInfo.getEmail());
        //入职日期
        //Date enterDate = personPositionInfo.getEnterDate();
        Date hireDate = personInfo.getHireDate();
        logger.error("personInfo.getHireDate------------" + personInfo.getHireDate());
        if (hireDate != null) {
            person.setCompanystartdate(originalFormat.format(hireDate));
        } else {
            //throw new BOSException("同步人员【" + personInfo.getName() + "】 入职日期不可为空！");
            person.setCompanystartdate("");
        }
        //参加工作日期
        Date jobStartDate = personOtherInfoMap.get(personInfo.getId().toString());
        if (jobStartDate != null) {
            person.setWorkstartdate(originalFormat.format(jobStartDate));
        }
        //登录名称
        person.setLoginid(personInfo.getNumber());
        //明文密码，会转密文  默认：Scy$1234
        if (action == ActionTypeEnum.ADD || !isPersonExistOA(personInfo.getNumber())) {
            person.setPassword("Scy$1234");
        }
        //安全级别
        IObjectValue securityLe = (IObjectValue) personInfo.get("securityLe");
        if (securityLe != null) {
            person.setSeclevel(securityLe.get("name").toString());
        }
        //人员类别
        IObjectValue personnelCa = (IObjectValue) personInfo.get("personnelCa");
        if (personnelCa != null) {
            Map customMap = new HashMap();
            customMap.put("field6", personnelCa.get("name"));
            person.setBaseCustomData(customMap);
        }
        //职级
        JobLevelInfo jobLevel = personPositionInfo.getJobLevel();
        if (jobLevel != null) {
            person.setJoblevel(jobLevel.getName());
        }
        //职务
        person.setJobactivityid("费用会计");
        //职务类型
        person.setJobactivityid("专业类");
        return person;
    }


    /**
     * 根据id从OA系统同步人员信息
     *
     * @param ctx
     * @param personIds
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _syncPersonFromOAById(Context ctx, String personIds) throws BOSException, EASBizException {
        super._syncPersonFromOAById(ctx, personIds);
        if (StringUtils.isEmpty(personIds)) {
            this._syncPersonFromOAByNumber(ctx, null);
        } else {
            try {
                String query = "select fnumber from t_bd_person where fid in (" + AtsUtil.getStrFromString(personIds) + ")";
                IRowSet iRowSet = DbUtil.executeQuery(ctx, query);
                StringBuilder personNumbers = new StringBuilder();
                while (iRowSet.next()) {
                    String fnumber = iRowSet.getString("fnumber");
                    personNumbers.append(fnumber).append(",");
                }
                personNumbers.deleteCharAt(personNumbers.lastIndexOf(","));
                this._syncPersonFromOAByNumber(ctx, personNumbers.toString());
            } catch (SQLException e) {
                e.printStackTrace();
                throw new BOSException("根据id从OA系统同步人员信息方法报错: " + e.getMessage());
            }
        }
    }

    /**
     * 根据工号从OA系统同步人员信息
     *
     * @param ctx
     * @param personNumbers
     * @throws BOSException
     * @throws EASBizException
     */
    @Override
    protected void _syncPersonFromOAByNumber(Context ctx, String personNumbers) throws
            BOSException, EASBizException {
        super._syncPersonFromOAByNumber(ctx, personNumbers);
        ISyncLog iSyncLog = SyncLogFactory.getLocalInstance(ctx);
        logger.error("_syncPersonFromOAByNumber -> personNumbers" + personNumbers);
        int pagesize = 2000;//每页数量
        int curpage = 1;//当前页
        int totalSize = 0;//总条数
        int totalPage = 0;//总页数
        boolean flag = true;
        do {
            SyncLogInfo syncLogInfo = new SyncLogInfo();
            syncLogInfo.setEntityName(SyncEntityNameEnum.person);
            syncLogInfo.setDataDirection(DataDirectionEnum.flowInto);
            syncLogInfo.setDockingSystem(DockingSystemEnum.OA);
            try {
                totalSize = executeSyncPersonFromOA(ctx, curpage, pagesize, personNumbers, syncLogInfo);
                if (flag) {
                    totalPage = totalSize % pagesize == 0 ? totalSize / pagesize : totalSize / pagesize + 1;
                    flag = false;
                }
                curpage++;
                iSyncLog.save(syncLogInfo);
            } catch (Exception e) {
                e.printStackTrace();
                syncLogInfo.setSyncStatus(SyncStatusEnum.ERROR);
                syncLogInfo.setSyncResult(e.getMessage());
                iSyncLog.save(syncLogInfo);
                throw new BOSException(e.getMessage());
            }
        } while (curpage <= totalPage);
    }


    /**
     * 执行从OA系统同步人员信息
     *
     * @param ctx
     * @param curpage
     * @param pagesize
     * @param personNumbers
     * @param syncLogInfo
     * @return
     * @throws IOException
     * @throws BOSException
     * @throws EASBizException
     */
    public Integer executeSyncPersonFromOA(Context ctx,
                                           int curpage,
                                           int pagesize,
                                           String personNumbers,
                                           SyncLogInfo syncLogInfo)
            throws IOException, BOSException, EASBizException {
        String updatePersonSql = "update t_bd_person set cfOAId = ? where fnumber = ?";
        List<Object[]> updateParams = new ArrayList<Object[]>();
        //封装请求参数
        String params = null;
        if (StringUtils.isEmpty(personNumbers)) {
            params = String.format("token = %s &params = {\"pagesize\":%d,\"curpage\":%d}", getToken(), pagesize, curpage);
        } else {
            params = String.format("token = %s &params = {\"workcode\":\"%s\",\"pagesize\":%d,\"curpage\":%d}", getToken(), personNumbers, pagesize, curpage);
        }
        syncLogInfo.setRequestParams(params);
        logger.error("executeSyncPersonFromOA----------------------params" + params);
        //封装请求参数
        String getHrmUserApiUrl = this.propt.getProperty("getHrmUserApiUrl");
        logger.error("executeSyncPersonFromOA----------------------getHrmUserApiUrl" + getHrmUserApiUrl);
        if (StringUtils.isEmpty(getHrmUserApiUrl)) {
            throw new BOSException("获取人员接口地址不能为空!");
        }
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, params);
        Request request = new Request.Builder()
                .url(getHrmUserApiUrl)
                .post(body)
                .addHeader("content-type", "application/x-www-form-urlencoded")
                .build();
        Response response = client.newCall(request).execute();
        String respBody = response.body().string();
        JSONObject respMap = JSONObject.parseObject(respBody);
        logger.error("handlerResponse--------------respMap" + respBody);
        if (response.isSuccessful()) {
            String code = respMap.getString("code");
            String msg = respMap.getString("msg");
            if ("1".equals(code)) {
                JSONObject respData = respMap.getJSONObject("data");
                Integer totalSize = respData.getInteger("totalSize");
                JSONArray respDataList = respData.getJSONArray("dataList");
                for (int i = 0; i < respDataList.size(); i++) {
                    JSONObject jsonObject = respDataList.getJSONObject(i);
                    String workcode = jsonObject.getString("workcode");
                    if (!StringUtils.isEmpty(workcode)) {
                        Object[] objects = new Object[2];
                        objects[0] = jsonObject.getString("id");
                        objects[1] = workcode;
                        updateParams.add(objects);
                    }
                }
                if (!updateParams.isEmpty()) {
                    DbUtil.executeBatch(ctx, updatePersonSql, updateParams);
                }
                syncLogInfo.setSyncStatus(SyncStatusEnum.SUCCESS);
                syncLogInfo.setSyncCount(updateParams.size());
                syncLogInfo.setSuccessNum(updateParams.size());
                return totalSize;
            } else {
                syncLogInfo.setSyncStatus(SyncStatusEnum.FAIL);
                syncLogInfo.setSyncResult(msg);
            }
        } else {
            syncLogInfo.setSyncStatus(SyncStatusEnum.FAIL);
            syncLogInfo.setSyncResult("请求超时");
        }
        return 0;
    }

    /**
     * 获取所有人员直接上级
     * <p>
     * select position.fnumber as positionNumber , personParent.fnumber from T_ORG_PositionMember positioonMenber
     * left join T_ORG_Position position on position.fid = positioonMenber.FPositionID
     * left join T_ORG_Position positionParent on position.fid = positionParent.FPARENTID
     * left join T_HR_EmpOrgRelation empOrgRelation on empOrgRelation.FPOSITIONID  = positionParent.fid
     * left join t_Bd_person person on person.fid = empOrgRelation.FPERSONID and empOrgRelation.FIsSystem='1'
     * left join  t_Bd_person personParent on  personParent.fid = positioonMenber.FPERSONID
     * where  person.fname_l2 = '王玲娇'
     */
    public String getParentPersonSql(String personNumber) {
        StringBuilder sb = new StringBuilder();
        sb.append("select").append("\n");
        sb.append(" position.fnumber as positionNumber , personParent.fnumber as personNumber,position.fname_l2,personParent.fname_l2").append("\n");
        sb.append("from T_ORG_PositionMember positioonMenber").append("\n");
        sb.append("left join T_ORG_Position position on position.fid = positioonMenber.FPositionID").append("\n");
        sb.append("left join T_ORG_Position positionParent on position.fid = positionParent.FPARENTID ").append("\n");
        sb.append("left join T_HR_EmpOrgRelation empOrgRelation on empOrgRelation.FPOSITIONID  = positionParent.fid and FAssignType = 1").append("\n");
        sb.append("left join t_Bd_person person on person.fid = empOrgRelation.FPERSONID and empOrgRelation.FIsSystem='1'").append("\n");
        sb.append("left join  t_Bd_person personParent on  personParent.fid = positioonMenber.FPERSONID ").append("\n");
        sb.append("where  person.fnumber = '" + personNumber + "'").append("\n");
        return sb.toString();
    }

    /**
     * 判断oa是否存在该人员
     */
    public boolean isPersonExistOA(String personNumber) throws BOSException, IOException {
        OkHttpClient client = new OkHttpClient();
        String params = String.format("token = %s &params = {\"workcode\":\"%s\"}", getToken(), personNumber);
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, params);
        Request request = new Request.Builder()
                .url("http://oa.shichuangyi.cn:8080/api/hrm/resful/getHrmUserInfoWithPage")
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "*/*")
                .addHeader("User-Agent", "PostmanRuntime-ApipostRuntime/1.1.0")
                .addHeader("Connection", "keep-alive")
                .build();
        Response response = client.newCall(request).execute();
        String respBody = response.body().string();
        JSONObject respMap = JSONObject.parseObject(respBody);
        JSONObject data = respMap.getJSONObject("data");
        Integer totalSize = data.getInteger("totalSize");
        if (totalSize > 0) {
            return true;
        } else {
            return false;
        }
    }
}
