package com.engine.organization.service.impl;

import com.engine.core.impl.Service;
import com.engine.hrm.util.HrmWeakPasswordUtil;
import com.engine.organization.entity.extend.po.ExtendInfoPO;
import com.engine.organization.entity.hrmresource.param.HrmResourceImportParam;
import com.engine.organization.mapper.extend.ExtendInfoMapper;
import com.engine.organization.service.HrmResourceImportAdaptService;
import com.engine.organization.util.db.MapperProxyFactory;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import weaver.common.DateUtil;
import weaver.file.FileUploadToPath;
import weaver.file.ImageFileManager;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.settings.ChgPasswdReminder;
import weaver.hrm.settings.RemindSettings;
import weaver.systeminfo.SystemEnv;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author:dxfeng
 * @createTime: 2022/06/27
 * @version: 1.0
 */
public class HrmResourceImportAdaptServiceImpl extends Service implements HrmResourceImportAdaptService {

    private String fileName;

    private String importType;

    private Sheet sheet;

    private int sheetCount = 0;

    private final List<String> errorInfo = new ArrayList<>();

    private String[] temFields;

    //标准模板字段
    private String tempField = "分部,部门," +
            "编号,姓名,登录名,密码,安全级别,性别," +
            "岗位,职务,职务类型,职称,职级," +
            "职责描述,直接上级,助理,状态," +
            "办公室,办公地点,办公电话,移动电话,其他电话," +
            "传真,电子邮件,系统语言,出生日期,民族," +
            "籍贯,户口,身份证号码," +
            "婚姻状况,政治面貌,入团日期,入党日期," +
            "工会会员,学历,学位,健康状况,身高," +
            "体重,用工性质,合同开始日期,合同结束日期,试用期结束日期,现居住地,家庭联系方式,暂住证号码," +
            "入职日期,参加工作日期," +
            "公积金帐户,账号类型,主账号,身高(cm),体重(kg),工资账号户名,工资银行,工资账号," +
            "办公室电话,显示顺序,人员密级";

    //存放必填列下标数组，包含自定义字段中的必填列
    private String[] requiredFields;

    //必填列标准模板或字段下标
    private final String requiredField = "0,1,3,8,9,10,18";

    //标准导入字段数组
    private String[] voFields;

    //标准导入字段
    private String voField = "company_id,department_id," +
            "work_code,last_name,login_id,pass_word,sec_level,sex," +
            "job_title,job_activity,job_group_id,job_call,job_level," +
            "job_activity_desc,manager_id,assistant_id,status," +
            "workroom,location_id,telephone,mobile,mobile_call," +
            "fax,email,system_language,birthday,folk," +
            "native_place,reg_resident_place,certificate_num," +
            "marital_status,policy,be_member_date,be_party_date," +
            "islabouunion,education_level,degree,health_info,height," +
            "weight,use_kind,start_date,end_date,probation_end_date," +
            "resident_place,home_address,temp_resident_number," +
            "company_start_date,work_start_date," +
            "accum_fund_account,account_type,belong_to,height,weight,account_name,bank_id,account_id," +
            "telephone,show_order,classification";

    //基本信息字段数组最后下标
    private int baseFieldsLastIndex = 0;

    //基础自定义信息字段数组最后下标
    private int baseFieldsLastIndex1 = 0;


    // 重复性验证标准数据库字段下标 例如
    private int keyFieldIndex = 2;

    //  重复性验证excel字段下标
    private int keyColumn = -1;

    // 用于做重复性验证，重复性与行键值对，<编号,4>,<编号,5>
    private final Map<String, String> repeatKeyMap = new HashMap<>();

    private int certificateNumIndex = 29;
    private int certificateNumColumn = -1;
    private final Map<Object, String> certificateNums = new HashMap<>();

    Map<String, Map<String, String>> checkInfos = new HashMap<>();

    private final String[] checkKeys = new String[]{"login_id", "work_code"};

    private int accountTypeIndex = 50;
    private int accountTypeColumn = -1;

    // 用于存贮HrmResource所有方法参数内容格式为<methodNmae,Method对象>,通过fieldsMaping中的对应关系可以找到方法和参数
    private final Map<String, Method> parameterTypes = new HashMap<>();

    // HrmResourceVo povo对象属性类型，用于反射赋值
    private final Map<String, String> fieldTypes = new HashMap<>();

    //excel字段数组下标与标准字段数组下标对应关系<excelFieldIndex,voFieldIndex>
    private final Map<Integer, Integer> fieldsMap = new HashMap<>();

    //人员map集合
    private final LinkedHashMap<String, HrmResourceImportParam> hrmResourceMap = new LinkedHashMap<>();

    Map<Integer, String> cusFieldValMap = new HashMap<>();     //个人信心自定义字段与工作信息自定字段数据验证条件

    private int userlanguage = 7;   //登录语言

    //弱密码禁止保存：false-允许保存弱密码、true-不允许保存弱密码
    private boolean weakPasswordDisable = false;
    //判断弱密码
    private HrmWeakPasswordUtil hrmWeakPasswordUtil;

    /**
     * map集合创建类
     *
     * @param fu 上传参数
     * @return List
     */
    @Override
    public List<String> creatImportMap(FileUploadToPath fu) {
        try {
            new BaseBean().writeLog("lxr2018>>>language2=" + userlanguage);
            // 初始化数据
            initDataSource(fu);

            if (!errorInfo.isEmpty()) {
                deleteFile();
                return errorInfo;
            }
            //初始化模板字段
            initTempFields();

            // 模板验证
            valExcelTemp();

            if (!errorInfo.isEmpty()) {
                deleteFile();
                return errorInfo;
            }

            // 读取数据并验证
            readExcel();

            deleteFile();
            return errorInfo;
        } catch (NegativeArraySizeException e) {
            //目前尚不清楚，这种异常的产生原因
            errorInfo.add(SystemEnv.getHtmlLabelName(83615, userlanguage));
            new BaseBean().writeLog(e);
            return errorInfo;
        } catch (Exception e) {
            //Excel导入错误，请阅读注意事项并检查模板文件
            errorInfo.add(SystemEnv.getHtmlLabelName(83617, userlanguage));
            new BaseBean().writeLog(e);
            return errorInfo;
        }

    }

    private void deleteFile() {
        new Thread(() -> {
            try {
                Thread.sleep(30 * 1000);
                ImageFileManager.deletePdfImageFile(Util.getIntValue(fileName));
            } catch (InterruptedException e) {
                new BaseBean().writeLog(e);
            }
        }).start();
    }

    /**
     * 获取人员map
     */
    @Override
    public Map<String, HrmResourceImportParam> getHrmImportMap() {

        return hrmResourceMap;
    }

    /**
     * 获取上传文件，初始化参数
     *
     * @param fu
     */
    public void initDataSource(FileUploadToPath fu) {
        this.importType = fu.getParameter("importType");

        // 重复性验证字段
        String keyField = fu.getParameter("keyField");

        voFields = voField.split(",");

        for (int i = 0; i < voFields.length; i++) {
            if (keyField.equals(voFields[i])) {
                keyFieldIndex = i;
            }
            // 身份证号
            if ("certificate_num".equalsIgnoreCase(voFields[i])) {
                certificateNumIndex = i;
            }
            // 账号类型
            if ("account_type".equalsIgnoreCase(voFields[i])) {
                accountTypeIndex = i;
            }
            if (keyFieldIndex != 2 && certificateNumIndex != 29) break;
        }
        try {
            this.fileName = fu.getParameter("excelfile");
            ImageFileManager manager = new ImageFileManager();
            manager.getImageFileInfoById(Util.getIntValue(this.fileName));
            Workbook workbook = WorkbookFactory.create(manager.getInputStream());
            this.sheetCount = workbook.getNumberOfSheets();
            this.sheet = workbook.getSheetAt(this.sheetCount > 1 ? 1 : 0);
        } catch (FileNotFoundException ignored) {
        } catch (IOException e) {
            errorInfo.add(SystemEnv.getHtmlLabelName(83618, userlanguage));                    //上传文件不是excel文件
            new BaseBean().writeLog(e);
        } catch (IndexOutOfBoundsException e) {
            errorInfo.add(SystemEnv.getHtmlLabelName(83619, userlanguage));
            new BaseBean().writeLog(e);
        }

        ChgPasswdReminder reminder = new ChgPasswdReminder();
        RemindSettings settings = reminder.getRemindSettings();
        //判断是否启用【弱密码禁止保存】
        this.weakPasswordDisable = Util.null2String(settings.getWeakPasswordDisable()).equals("1");
        try {
            //判断是否为弱密码
            hrmWeakPasswordUtil = new HrmWeakPasswordUtil();
        } catch (Exception e) {
            errorInfo.add("加载弱密码集合出错");
            new BaseBean().writeLog(e);
        }
    }

    /**
     * 验证模板格式
     */
    public void valExcelTemp() {
        int rowIndex = (this.sheetCount > 1 ? 1 : 0);
        Row row;
        Cell cell;
        String cellValue;
        List<String> fieldList = new ArrayList<>();
        try {
            row = sheet.getRow(rowIndex);
            for (int i = 0; i < row.getLastCellNum(); i++) {
                boolean flag = false;
                cell = row.getCell((short) i);
                if (cell != null) {
                    cellValue = getCellValue(cell).trim();
                    for (int k = 0; k < temFields.length; k++) {
                        if (cellValue.equals(temFields[k])) {
                            fieldsMap.put(i, k);
                            fieldList.add(cellValue);
                            if (keyFieldIndex == k)  //如果重复性验证标准数据库字段下标与标准excel模板下标相等，则找到对应的excel验证列
                                keyColumn = i;
                            if (certificateNumIndex == k) {
                                certificateNumColumn = i;
                            }
                            if (accountTypeIndex == k) {
                                accountTypeColumn = i;
                            }
                            flag = true;
                            break;
                        }
                    }
                    if (!flag)
                        errorInfo.add(getCellPosition(i, (rowIndex + 1)) + "[" + cellValue + "]" + " 不是模板中字段，请检查是否有误");      //不是模板中字段，请检查是否有误
                    if (importType.equals("add")) {  //如果是插入操作才验证固定列
                        if (i == 0 && !cellValue.equals(temFields[0]))
                            errorInfo.add("分部必须在第" + (rowIndex + 1) + "行第1列");   //【分部】固定列
                        if (i == 1 && !cellValue.equals(temFields[1]))
                            errorInfo.add("部门必须在第" + (rowIndex + 1) + "行第2列");    // 【部门】固定列
                    } else {
                        //如果是更新，并且存在分部部门列，就规定分部、部门在第1、2列
                        if (cellValue.equals(temFields[0]) && !temFields[1].equals(getCellValue(rowIndex, 1).trim()))
                            errorInfo.add("更新时有分部则后一列必须为部门，且第" + (rowIndex + 1) + "行第1列为分部，第2列为部门");   //【分部】固定列
                        else if (cellValue.equals(temFields[0]) && i != 0)
                            errorInfo.add("分部必须在第" + (rowIndex + 1) + "行第1列");   //【分部】固定列


                        if (cellValue.equals(temFields[1]) && !temFields[0].equals(getCellValue(rowIndex, 0).trim()))
                            errorInfo.add("更新时有部门则前一列必须为分部，且第" + (rowIndex + 1) + "行第1列为分部，第2列为部门");   //【分部】固定列
                        else if (cellValue.equals(temFields[1]) && i != 1)
                            errorInfo.add("部门必须在第" + (rowIndex + 1) + "行第2列");   //【部门】固定列

                    }
                }
            }
            if (keyColumn == -1)
                errorInfo.add("[" + temFields[keyFieldIndex] + "]" + " 您所选的重复性验证字段不在模板中");  //您所选的重复性验证字段不在模板中

            if (importType.equals("add")) {  //如果是插入操作才验证必填列
                for (String field : requiredFields) {
                    boolean flag = false;
                    for (String s : fieldList) {
                        if (temFields[Integer.parseInt(field)].equals(s)) {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag)
                        errorInfo.add("[" + temFields[Integer.parseInt(field)] + "]" + " 为必填字段");  //必填字段
                }
            }
        } catch (IllegalArgumentException e) {
            errorInfo.add(SystemEnv.getHtmlLabelName(83617, userlanguage));             //   excel模板有误时
            new BaseBean().writeLog(e);
        }
    }

    /**
     * 初始化反射所需要的方法和字段Map，parameterTypes，fieldTypes
     */
    public void initReflectParam() {
        Class<HrmResourceImportParam> hrmResourceImportParamClass = HrmResourceImportParam.class;
        Method[] hrmResourceMethods = hrmResourceImportParamClass.getDeclaredMethods();

        for (Method hrmResourceMethod : hrmResourceMethods) {
            parameterTypes.put(hrmResourceMethod.getName(),
                    hrmResourceMethod);
        }

        Field[] hrmResourceFields = hrmResourceImportParamClass.getDeclaredFields();

        for (Field hrmResourceField : hrmResourceFields) {
            Class<?> fieldTypeClass = hrmResourceField.getType();
            fieldTypes.put(hrmResourceField.getName(), fieldTypeClass
                    .getName());
        }
    }

    /**
     * 读取excel数据
     */
    public void readExcel() {

        initReflectParam(); // 初始化反射参数

        boolean flag; // 标记验证是否通过
        Row row;
        Cell cell;
        int rowNum; // 行号
        int cellNum; // 列号
        int firstRow = (this.sheetCount > 1 ? 2 : 1);
        String keyValue = "";
        int lastRow = sheet.getLastRowNum();
        String subCompany = "";
        String department = "";
        String cellValue;
        int fieldIndex;
        HrmResourceImportParam importParam;

        for (int i = firstRow; i <= lastRow; i++) {
            flag = true;
            row = sheet.getRow(i);
            if (row == null) {
                errorInfo.add(SystemEnv.getHtmlLabelName(15323, userlanguage) + " " + (i + 1) + " " + SystemEnv.getHtmlLabelName(83622, userlanguage));
                continue;
            }
            rowNum = row.getRowNum();
            StringBuilder baseFieldsValue = new StringBuilder();
            StringBuilder baseFields = new StringBuilder();
            if (repeatValidate(row, rowNum)) { // 重复性验证
                continue;
            }

            importParam = new HrmResourceImportParam();

            for (int cellIndex = 0; cellIndex < fieldsMap.size(); cellIndex++) {

                cell = row.getCell((short) cellIndex);

                cellNum = cellIndex;


                fieldIndex = fieldsMap.get(cellNum);

                cellValue = getCellValue(cell).trim();

                if (valExcelDataFormate(rowNum, cellNum, cellValue)) {
                    if (fieldIndex == keyFieldIndex) { // 验证通过，如果当前单元格为重复性验证单元格，则把值赋给keyValue
                        keyValue = cellValue;
                    }
                } else {
                    flag = false;
                }

                if (flag) { // 为true则，设置值，否则不需要

                    if (fieldIndex == 0 && getCellValue(1, cellNum).equals("分部")) { // 对于excel分部为空则取上面分部读取的值
                        if (cellValue.equals(""))
                            cellValue = subCompany;
                        else
                            subCompany = cellValue;
                    }

                    if (fieldIndex == 1 && getCellValue(1, cellNum).equals("部门")) { // 对于excel部门为空则取上面部门读取的值
                        if (cellValue.equals(""))
                            cellValue = department;
                        else
                            department = cellValue;
                    }

                    if (fieldIndex <= baseFieldsLastIndex) {
                        setHrmResourceValue(fieldIndex, cellValue, importParam, null);
                    }

                    if (fieldIndex > baseFieldsLastIndex && fieldIndex <= baseFieldsLastIndex1) {
                        baseFields.append(",").append(voFields[fieldIndex]);
                        if (cellValue.equals(""))
                            cellValue = "?";
                        baseFieldsValue.append(";").append(cellValue);
                        setHrmResourceValue(0, baseFields.substring(1), importParam, "baseFields");
                        setHrmResourceValue(0, baseFieldsValue.substring(1), importParam, "baseFieldsValue");
                    }

                }
            }
            String currentDate = weaver.common.DateUtil.getCurrentDate();
            if (Util.null2String(importParam.getWork_start_date()).length() > 0 && Util.null2String(importParam.getWork_year()).length() == 0) {//计算工龄
                int day = weaver.common.DateUtil.dayDiff(importParam.getWork_start_date(), currentDate);
                DecimalFormat df = new DecimalFormat("0.0");
                importParam.setWork_year(df.format(day / 365.0));
            }

            if (Util.null2String(importParam.getCompany_start_date()).length() > 0 && Util.null2String(importParam.getCompany_work_year()).length() == 0) {//计算司令
                int day = DateUtil.dayDiff(importParam.getWork_start_date(), currentDate);
                DecimalFormat df = new DecimalFormat("0.0");
                importParam.setCompany_work_year(df.format(day / 365.0));
            }

            repeatKeyMap.put(keyValue, "" + (i + 1)); // 用于重复性验证
            if (importParam.getAccount_type() != null && !"".equals(importParam.getAccount_type())) {
                if ("主账号".equals(importParam.getAccount_type())) {
                    certificateNums.put(importParam.getCertificate_num(), String.valueOf(i + 1));
                }
            } else {
                certificateNums.put(importParam.getCertificate_num(), String.valueOf(i + 1));
            }

            if (checkInfo(importParam, rowNum)) { // 重复性验证
                continue;
            }

            //新增账号、工号唯一性校验
            for (String key : checkKeys) {
                Map<String, String> checkInfo = checkInfos.get(key);
                if (checkInfo == null) {
                    checkInfo = new HashMap<>();
                    checkInfos.put(key, checkInfo);
                } else {
                    checkInfo = checkInfos.get(key);
                }
                String val = "";
                switch (key) {
                    case "login_id":
                        val = importParam.getLogin_id();
                        break;
                    case "work_code":
                        val = importParam.getWork_code();
                        break;
                    case "certificate_num":
                        val = importParam.getCertificate_num();
                        break;
                }
                checkInfo.put(val, String.valueOf(i + 1));
                checkInfos.put(key, checkInfo);
            }

            if (flag) {
                hrmResourceMap.put(keyValue, importParam);
            }
        }
    }

    /**
     * 重复性验证，读取唯一性cell值，然后从HrmResourceMap中查找是否存在
     *
     * @param row    行
     * @param rowNum 行下标
     */
    public boolean repeatValidate(Row row, int rowNum) {
        if (certificateNumColumn == -1)
            return false;
        String certificateNum = getCellValue(row.getCell((short) certificateNumColumn)).trim();
        String accounttype = getCellValue(row.getCell((short) accountTypeColumn)).trim();
        String key = getCellValue(row.getCell((short) keyColumn)).trim();
        if (voFields[fieldsMap.get(keyColumn)].equals(""))
            key = getCellValue(row.getCell((short) 0)).trim() + ">" + getCellValue(row.getCell((short) 1)).trim() + "_" + key;
        String repeatRow = repeatKeyMap.get(key);
        String cnRow = certificateNums.get(certificateNum);
        if (repeatRow != null) {
            errorInfo.add((rowNum + 1) + "," + repeatRow + " 行重复");  //重复 num_5,6 行重复
            return true;
        } else if (cnRow != null && certificateNum.length() > 0) {
            if ("次账号".equalsIgnoreCase(accounttype)) {
                return false;
            } else {
                errorInfo.add((rowNum + 1) + "," + cnRow + " " + SystemEnv.getHtmlLabelName(83623, userlanguage));
                return true;
            }
        } else {
            return false;
        }
    }

    private boolean checkInfo(HrmResourceImportParam importParam, int rowNum) {
        //新增账号、工号唯一性校验
        for (String key : checkKeys) {
            Map<String, String> checkInfo = checkInfos.get(key);
            if (checkInfo != null && !checkInfo.isEmpty()) {
                String val = "";
                String errorMsg = "";
                switch (key) {
                    case "login_id":
                        val = Util.null2String(importParam.getLogin_id()).trim();
                        errorMsg = SystemEnv.getHtmlLabelName(520127, userlanguage);
                        break;
                    case "work_code":
                        val = Util.null2String(importParam.getWork_code()).trim();
                        errorMsg = SystemEnv.getHtmlLabelName(520128, userlanguage);
                        break;
                    case "certificate_num":
                        val = Util.null2String(importParam.getCertificate_num()).trim();
                        errorMsg = SystemEnv.getHtmlLabelName(83623, userlanguage);
                        break;
                }
                String cnRow = Util.null2String(checkInfo.get(val));
                if (cnRow.length() > 0 && val.length() > 0) {
                    errorInfo.add((rowNum + 1) + "," + cnRow + errorMsg);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 验证数据格式，必填列是否为空
     *
     * @param rowNum    行号
     * @param cellNum   列号
     * @param cellValue 单元格值
     * @return
     */
    public boolean valExcelDataFormate(int rowNum, int cellNum, String cellValue) {

        boolean flag = true;
        String msg;
        int fieldIndex = fieldsMap.get(cellNum);
        String fieldName = voFields[fieldIndex];

        // 人员信息第1行(模板第2行)的分部和部门为必填

        if ((rowNum == 1 || rowNum == 2) && fieldName.equals("company_id") && getCellValue(1, cellNum).equals("分部") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";           //【分部】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        if ((rowNum == 1 || rowNum == 2) && fieldName.equals("department_id") && getCellValue(1, cellNum).equals("部门") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";           //【部门】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;

        }
        //【分部】不为空则【部门】为必填
        if (fieldName.equals("department_id") && cellValue.equals("")) {
            if (!getCellValue(rowNum, cellNum - 1).equals("")) { //分部不为空
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
                return false;
            }
        }

        // 姓名
        if (fieldName.equals("last_name") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";          //【姓名】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        // 岗位
        if (fieldName.equals("job_title") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";          //【岗位】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        if (fieldName.equals("job_activity") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";          //【职务】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        if (fieldName.equals("job_group_id") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";         //【职务类型】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        // 办公地点
        if (fieldName.equals("location_id") && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";         //【办公地点】为必填
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        //自定义字段为必填设置时
        if (fieldIndex > baseFieldsLastIndex && requiredField.contains(String.valueOf(fieldIndex))) {
            if (cellValue.equals("")) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
                return false;
            }
        }

        //基本信息、个人信息、工作信息自定义验证
        if (fieldIndex > baseFieldsLastIndex && !cellValue.equals("")) {
            //自定义信息字段不能包含‘?’问号
            if (cellValue.contains("?") && getStrLength(cellValue) == 1) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83627, userlanguage));
                return false;
            }
            String valType = cusFieldValMap.get(fieldIndex);
            if (valType != null)
                if (valType.equals("isInt")) {
                    if (!isInteger(cellValue)) {
                        msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                        errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83628, userlanguage));
                        return false;
                    }
                    if (getStrLength(cellValue) > 18 && (Integer.MAX_VALUE < Double.parseDouble(cellValue) || Double.parseDouble(cellValue) < Integer.MIN_VALUE)) {
                        msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                        errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83629, userlanguage) + Integer.MAX_VALUE + SystemEnv.getHtmlLabelName(15508, userlanguage) + Integer.MIN_VALUE);
                        return false;
                    }

                } else if (valType.equals("isDouble")) {
                    if (isDecimal(cellValue)) {
                        msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                        errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83637, userlanguage));
                        return false;
                    }
                    if (getStrLength(cellValue) > 18) {
                        flag = false;
                        msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                        errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83639, userlanguage));
                    }
                } else if (valType.equals("isDate")) {
                    if (getStrLength(cellValue) != 10) {
                        flag = false;
                        msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                        errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83640, userlanguage));
                    }

                } else if (isInteger(valType) && getStrLength(cellValue) > Integer.parseInt(valType)) {
                    msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                    errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83641, userlanguage) + valType + SystemEnv.getHtmlLabelName(20075, userlanguage));
                    return false;
                } else if (valType.equals("isCheck") && !cellValue.equals("0") && !cellValue.equals("1")) {
                    msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                    errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83644, userlanguage));
                    return false;
                }
        }

        //安全级别、职级整数格式验证、大于0验证
        if ((fieldName.equals("sec_level") || fieldName.equals("job_level")) && !cellValue.equals("")) {
            if (fieldName.equals("sec_level")) {
                //安全级别不能大于999
                if (Util.getIntValue(cellValue) > 999) {
                    msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                    errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(515522, userlanguage));
                    return false;
                }
                //安全级别不能小于-999
                if (Util.getIntValue(cellValue) < -999) {
                    msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                    errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(515523, userlanguage));
                    return false;
                }
            } else {
                if (!isInteger(cellValue)) {
                    msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                    errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83645, userlanguage));
                    return false;
                }
                if (Integer.parseInt(cellValue) < 0 || Integer.parseInt(cellValue) > 1000) {
                    msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                    errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83648, userlanguage));
                    return false;
                }
            }
        }
        //身高、体重数据格式验证、大于0验证
        if ((fieldName.equals("height") || fieldName.equals("weight")) && !cellValue.equals("")) {
            if (isDecimal(cellValue)) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83650, userlanguage));
                return false;
            }
            if (Double.parseDouble(cellValue) < 0 || Double.parseDouble(cellValue) > 1000) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83648, userlanguage));
                return false;
            }
        }


        //长度为200个字符的标准字段
        if ((fieldName.equals("job_title") || fieldName.equals("job_activity") || fieldName.equals("job_group_id") ||
                fieldName.equals("location_id") || fieldName.equals("job_activity_desc") || fieldName.equals("reg_resident_place")) && !cellValue.equals("") && getStrLength(cellValue) > 200) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83666, userlanguage) + "200" + SystemEnv.getHtmlLabelName(20075, userlanguage));
            return false;
        }

        //长度为100的标准字段
        if ((fieldName.equals("login_id") || fieldName.equals("pass_word") || fieldName.equals("home_address") || fieldName.equals("native_place")) && !cellValue.equals("") && getStrLength(cellValue) > 100) {

            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";         //自定义日期字段长度验证
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83666, userlanguage) + "100" + SystemEnv.getHtmlLabelName(20075, userlanguage));
            return false;

        }
        //长度为60的标准字段
        if ((fieldName.equals("last_name") || fieldName.equals("pass_word") || fieldName.equals("telephone") || fieldName.equals("mobile") || fieldName.equals("mobile_call")
                || fieldName.equals("email") || fieldName.equals("workroom") || fieldName.equals("work_code") || fieldName.equals("fax")
                || fieldName.equals("certificate_num") || fieldName.equals("job_call") || fieldName.equals("temp_resident_number"))
                && !cellValue.equals("") && getStrLength(cellValue) > 60) {

            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83666, userlanguage) + "60" + SystemEnv.getHtmlLabelName(20075, userlanguage));
            return false;

        }

        //长度为30个字符的标准字段
        if ((fieldName.equals("degree") || fieldName.equals("policy")) && !cellValue.equals("") && getStrLength(cellValue) > 30) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83666, userlanguage) + "30" + SystemEnv.getHtmlLabelName(20075, userlanguage));
            return false;
        }

        //长度为10个字符的标准字段
        if ((fieldName.equals("birthday") || fieldName.equals("be_member_date") || fieldName.equals("be_party_date") ||
                fieldName.equals("start_date") || fieldName.equals("end_date") || fieldName.equals("probation_end_date")) && !cellValue.equals("") && getStrLength(cellValue) > 10) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83666, userlanguage) + "10" + SystemEnv.getHtmlLabelName(20075, userlanguage));
            return false;
        }

        //分部各级长度验证
        if (fieldName.equals("company_id") && !cellValue.equals("")) {
            String[] subcompanyname = cellValue.split(">");
            for (String s : subcompanyname) {
                if (getStrLength(s) > 200)
                    flag = false;
            }
            if (!flag) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83667, userlanguage));
                return false;
            }
        }

        //部门各级长度验证
        if (fieldName.equals("department_id") && !cellValue.equals("")) {
            String[] departmentname = cellValue.split(">");
            for (String s : departmentname) {
                if (getStrLength(s) > 200)
                    flag = false;
            }
            if (!flag) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83668, userlanguage));
                return false;
            }
        }

        //当启用【弱密码禁止保存】时，弱密码导入失败，失败信息为“密码安全性过弱”
        if ("pass_word".equalsIgnoreCase(fieldName)) {
            if (weakPasswordDisable && hrmWeakPasswordUtil.isWeakPsd(cellValue)) {
                msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";
                errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(515436, userlanguage));
                return flag;
            }
        }

        if (fieldIndex == keyFieldIndex && cellValue.equals("")) {
            msg = getCellPosition(cellNum, rowNum + 1) + "[" + temFields[fieldIndex] + "]";      // 重复性验证字段不在模板中
            errorInfo.add(msg + " " + SystemEnv.getHtmlLabelName(83626, userlanguage));
            return false;
        }

        return flag;
    }

    /**
     * 通过反射为对象赋值
     *
     * @param cellNum     列号
     * @param cellValue   单元格值
     * @param importParam 需要赋值的HrmResource
     */
    public void setHrmResourceValue(int cellNum, String cellValue,
                                    HrmResourceImportParam importParam, String field) {
        if (field == null) {
            String excelField = voFields[cellNum];
            String methodName = "set" + excelField.substring(0, 1).toUpperCase()
                    + excelField.substring(1);
            Method method = parameterTypes.get(methodName);
            try {
                String fieldType = fieldTypes.get(excelField);
                if (fieldType.equals("java.lang.String"))
                    method.invoke(importParam, cellValue);
                else if (fieldType.equals("java.lang.Integer")) {
                    if (!cellValue.equals("")) {
                        method.invoke(importParam, Integer.parseInt(cellValue));
                    }
                } else if (fieldType.equals("java.lang.Float") && !cellValue.equals(""))
                    method.invoke(importParam, Float.parseFloat(cellValue));
                else if (fieldType.equals("java.lang.Short") && !cellValue.equals("")) {
                    method.invoke(importParam, Short.parseShort(cellValue));
                }
            } catch (Exception e) {
                new BaseBean().writeLog(e);
            }
        } else {
            String methodName = "set" + field.substring(0, 1).toUpperCase()
                    + field.substring(1);
            Method method = parameterTypes.get(methodName);
            try {
                method.invoke(importParam, cellValue);
            } catch (Exception e) {
                new BaseBean().writeLog(e);
            }
        }
    }

    /**
     * excel单元格位置转换
     *
     * @param cellIndex 列号
     * @param rowNum    行号
     * @return
     */
    public String getCellPosition(int cellIndex, int rowNum) {

        int count = cellIndex / 26;
        String cellChar = String.valueOf((char) (cellIndex % 26 + 65));
        String cellPosition;

        if (count != 0)
            cellPosition = (char) ((count - 1) + 65) + cellChar;
        else
            cellPosition = cellChar;
        cellPosition += rowNum;
        return cellPosition;
    }

    /**
     * 初始化模板字段
     */
    public void initTempFields() {
        new BaseBean().writeLog("initTempFields");

        temFields = tempField.split(",");

        baseFieldsLastIndex = temFields.length - 1;

        int requiredFieldIndex = baseFieldsLastIndex;

        /*基本信息信息字段*/
        StringBuilder baseField = new StringBuilder();
        StringBuilder baseFieldLabel = new StringBuilder();
        String fieldHtmlType;
        List<ExtendInfoPO> infoPOList = MapperProxyFactory.getProxy(ExtendInfoMapper.class).listFields("4", "", "JCL_ORG_HRMRESOURCE", "");
        for (ExtendInfoPO extendInfoPO : infoPOList) {
            fieldHtmlType = extendInfoPO.getControlType().toString();
            if (fieldHtmlType.equals("1") || fieldHtmlType.equals("2") || fieldHtmlType.equals("3")
                    || fieldHtmlType.equals("4") || fieldHtmlType.equals("5")) {
                baseField.append(",field").append(extendInfoPO.getId());
                baseFieldLabel.append(",").append(extendInfoPO.getFieldNameDesc());
                requiredFieldIndex++;
                //验证条件
                //1为html文本类型
                switch (fieldHtmlType) {
                    case "1":
                        switch (extendInfoPO.getBrowserType()) {
                            case "1"://1为文本数据类型
                                String fielddbtype = extendInfoPO.getFieldType();
                                fielddbtype = fielddbtype.substring(fielddbtype.indexOf("(") + 1, fielddbtype.lastIndexOf(")")); //截取字符设置的长度
                                cusFieldValMap.put(requiredFieldIndex, fielddbtype);
                                break;
                            case "2":// 2为整数数据类型
                                cusFieldValMap.put(requiredFieldIndex, "isInt");
                                break;
                            case "3":// 3为浮点数数据类型
                                cusFieldValMap.put(requiredFieldIndex, "isDouble");
                                break;
                            default:
                                cusFieldValMap.put(requiredFieldIndex, "");
                                break;
                        }
                        break;
                    case "4"://4 为check框
                        cusFieldValMap.put(requiredFieldIndex, "isCheck");
                        break;
                    case "3":
                        if (extendInfoPO.getBrowserType().equals("2")) {
                            cusFieldValMap.put(requiredFieldIndex, "isDate");
                        } else if (extendInfoPO.getBrowserType().equals("19")) {
                            cusFieldValMap.put(requiredFieldIndex, "isTime");
                        } else {
                            cusFieldValMap.put(requiredFieldIndex, "isBrowser");
                        }
                        break;
                    case "5":
                        cusFieldValMap.put(requiredFieldIndex, "isSelect");
                        break;
                }
            }
        }
        voField = voField + baseField;
        tempField = tempField + baseFieldLabel;
        temFields = tempField.split(",");
        baseFieldsLastIndex1 = temFields.length - 1;
        requiredFields = requiredField.split(",");
    }

    /**
     * 获取excel单元格值
     *
     * @param cell 要读取的单元格对象
     * @return
     */
    public String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null)
            return "";
        switch (cell.getCellType()) {
            case BOOLEAN:                                  //得到Boolean对象的方法
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {//先看是否是日期格式
                    SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM-dd");
                    cellValue = sft.format(cell.getDateCellValue());   //读取日期格式
                } else {
                    cellValue = String.valueOf(new Double(cell.getNumericCellValue())); //读取数字
                    if (cellValue.endsWith(".0"))
                        cellValue = cellValue.substring(0, cellValue.indexOf("."));
                }
                break;
            case FORMULA:                               //读取公式
                cellValue = cell.getCellFormula();
                break;
            case STRING:                              //读取String
                cellValue = cell.getStringCellValue();
                if (cellValue == null)
                    cellValue = "";
                Date d = validDate(cellValue);
                if (d != null)
                    cellValue = new SimpleDateFormat("yyyy-MM-dd").format(d);
                break;
        }
        cellValue = Util.toHtmlForHrm(cellValue);
        return cellValue;
    }

    private Date validDate(String str) {
        Date d = null;
        SimpleDateFormat fmt1 = new SimpleDateFormat("yyyy-MM-dd");
        fmt1.setLenient(false);
        SimpleDateFormat fmt2 = new SimpleDateFormat("yyyy/MM/dd");
        fmt2.setLenient(false);
        try {
            d = fmt1.parse(str);
        } catch (Exception ignored) {
        }
        try {
            d = fmt2.parse(str);
        } catch (Exception ignored) {

        }
        return d;
    }

    /**
     * 获取指定行、列的单元格值
     *
     * @param rowNum
     * @param cellNum
     * @return
     */
    public String getCellValue(int rowNum, int cellNum) {
        Row row = sheet.getRow(rowNum);
        Cell cell = row.getCell((short) cellNum);
        String cellValue = getCellValue(cell);
        cellValue = Util.toHtmlForHrm(cellValue);
        return cellValue;
    }

    //浮点数判断
    public boolean isDecimal(String str) {
        if (str == null || "".equals(str))
            return true;
        Pattern pattern = Pattern.compile("\\d*(\\.?)\\d*");
        return !pattern.matcher(str).matches();
    }

    //整数判断
    public boolean isInteger(String str) {
        if (str == null)
            return false;
        Pattern pattern = Pattern.compile("\\d+");
        return pattern.matcher(str).matches();
    }

    /**
     * 获取字符串字节长度 由于java中中英字符都按1个字符，而数据库中汉字按两个字符计算
     *
     * @param str
     * @return
     */
    public int getStrLength(String str) {
        try {
            if (str == null)
                return 0;
            else
                return new String(str.getBytes("gb2312"), StandardCharsets.ISO_8859_1).length();
        } catch (Exception e) {
            new BaseBean().writeLog(e);
            return 0;
        }
    }

    @Override
    public void setUserlanguage(int userlanguage) {
        this.userlanguage = userlanguage;
    }
}
