package com.dk.mdm.service.mst;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.model.pojo.PageList;
import com.dk.common.model.pojo.mst.StaffPurview;
import com.dk.common.model.pojo.mst.StaffRight;
import com.dk.common.model.vo.core.StaffEntity;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.common.util.AESUtil;
import com.dk.mdm.feign.CompanyFeign;
import com.dk.mdm.feign.UserFeign;
import com.dk.mdm.infrastructure.convert.mst.StaffConvert;
import com.dk.mdm.infrastructure.util.AuthUtils;
import com.dk.mdm.mapper.common.CommonMapper;
import com.dk.mdm.mapper.mst.*;
import com.dk.mdm.model.pojo.mst.*;
import com.dk.common.service.BaseService;
import com.dk.common.mapper.BaseMapper;
import com.dk.mdm.model.query.ivt.InboundItemQuery;
import com.dk.mdm.model.query.mst.ComMenuQuery;
import com.dk.mdm.model.query.mst.DictionaryDataQuery;
import com.dk.mdm.model.query.mst.GoodsCategoryQuery;
import com.dk.mdm.model.query.mst.StaffQuery;
import com.dk.common.model.response.mst.StaffResponse;
import com.dk.common.model.vo.mst.StaffVO;
import com.dk.mdm.model.response.mst.ComMenuResponse;
import com.dk.mdm.model.response.mst.DictionaryDataResponse;
import com.dk.mdm.model.vo.mst.ComMenuVO;
import com.dk.mdm.service.common.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author : 姜永辉
 * @desc : 员工API接口
 * @date : 2023/1/4 9:25
 */
@Service
@Slf4j
public class StaffService extends BaseService<Staff> {
    @Resource
    private CompanyFeign companyFeign;
    @Resource
    private UserFeign userFeign;

    @Override
    public BaseMapper<Staff> getRepository() {
        return staffMapper;
    }

    /**
     * @desc : 重写主键
     * @author : 姜永辉
     * @date : 2023/1/9 10:39
     */
    @Override
    public String getPrimaryKey() {
        return "staff_id";
    }

    @Autowired
    private StaffMapper staffMapper;

    @Autowired
    private StaffConvert staffConvert;

    @Autowired
    private StaffRightService staffRightService;

    @Autowired
    private StaffPurviewService staffPurviewService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private ComMenuService comMenuService;

    @Autowired
    private ComMenuMapper comMenuMapper;

    @Autowired
    private SettingValueMapper settingValueMapper;

    @Autowired
    private AuthUtils authUtils;
    @Autowired
    DictionaryDataMapper dictionaryDataMapper;
    @Autowired
    GoodsCategoryMapper goodsCategoryMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    RoleFunMapper roleFunMapper;
    @Autowired
    UnitMapper unitMapper;
    @Autowired
    SaleChannelMapper saleChannelMapper;
    @Autowired
    WarehouseMapper warehouseMapper;
    @Autowired
    MoneyAccountMapper moneyAccountMapper;
    @Autowired
    PrintLayoutMapper printLayoutMapper;

    /**
     * @desc : 条件查询
     * @author : 姜永辉
     * @date : 2023/1/9 10:40
     */
    @Pagination
    public ResponseResultVO<PageList<StaffResponse>> selectByCond(StaffQuery staffQuery) {
        // 获取当前公司的cpId
        if (staffQuery.getCpId() == null) {
            Integer cpId = authUtils.getStaff().getCpId();
            staffQuery.setCpId(cpId);
        }
//        Map<String, Object> map = new HashMap<>();
//        map.put("grade_code", "STD");
//        map.put("end_date", "2099-12-31");
////        map.put("user_end_date", "2025-04-01");
//        map.put("wx_max_num", 20);
////        map.put("web_max_num", 20);
//        List<Map<String,Object>> mapList = new ArrayList<>();
//        Map<String,Object> map1 = new HashMap<>();
//        List<String> funList = new ArrayList<>();
//        funList.add("45adf0c1-cb1d-4baa-8cd0-9cefe5649687");
//        funList.add("af9fe752-9431-4301-907a-ebee6f1d01bd");
//        funList.add("a577397a-78b9-475d-b44a-92294a4ac5a7");
//        funList.add("0b95fe60-add2-4177-9cab-6bd936aac090");
//        funList.add("5f415229-e64c-4e88-b9c4-72a661b56d64");
//        funList.add("3644ebc5-fde2-44fc-bba8-9adc91ccb483");
//        funList.add("f2f912f4-dad3-42ca-9835-184de6ecf27b");
//        map1.put("activityId","10002024-0701-0000-0000-0000052aaec4");
//        map1.put("funUuids",funList);
//        mapList.add(map1);
//        Map<String,Object> map2 = new HashMap<>();
//        List<String> funList2 = new ArrayList<>();
//        funList2.add("851e952a-27c6-42d2-91ad-097e266f63ea");
//        map2.put("activityId","10002024-0701-0000-0000-0000052aaec3");
//        map2.put("funUuids",funList2);
//        mapList.add(map2);
//        Map<String,Object> map3 = new HashMap<>();
//        List<String> funList3 = new ArrayList<>();
//        funList3.add("3e43dc4c-0e98-49ca-8ca4-2fe47f286e1d");
//        funList3.add("1b3ce29f-f7d6-40c0-9ca5-754ff8e85db6");
//        funList3.add("67df7456-3deb-41de-a6db-f916eae66089");
//        map3.put("activityId","10002024-0701-0000-0000-0000052aaec3");
//        map3.put("funUuids",funList3);
//        mapList.add(map3);
//        map.put("fun_package",mapList);
//        String s1 = JSON.toJSONString(map);
//        // 加密
//        String s = AESUtil.aesEncrypt(s1);
//        // 解密
//        Map<String,Object> ss = JSON.parseObject(AESUtil.desEncrypt(s),Map.class) ;
        return super.mergeListWithCount(staffQuery, staffMapper.selectByCond(staffQuery),
                staffMapper.countByCond(staffQuery));
    }

    /**
     * @desc : 保存方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insert(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 获取当前公司的cpId
        StaffEntity staffEntity = authUtils.getStaff();
        Integer cpId = staffEntity.getCpId();
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStaffPhone(staff.getStaffPhone());
        staffQuery.setCpId(cpId);
        staffQuery.setFlgValid(true);
        staff.setCpId(cpId);
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }

        staffQuery.setStaffPhone(null);
        staffQuery.setStaffCode(staff.getStaffCode());
        staffResponses = staffMapper.selectByCondByCode(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_CODE_EXIST);
        }
        //可以绑定微信的员工人数  人数上限
        if (staffVO.getFlgCanLogin() != null && staffVO.getFlgCanLogin()) {
            ResponseResultVO<?> resultMaxnum = companyFeign.getCompanyMaxStaffNum(cpId);
            if (resultMaxnum.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
                // 无用户
                throw new BaseBusinessException(ErrorCodeEnum.USER_REGISTER_ERROR.getCode(),
                        ErrorCodeEnum.USER_REGISTER_ERROR.getMessage());
            } else {
                Map<String, Object> mp = (Map<String, Object>) resultMaxnum.getData();
                int intWebMaxnum = 0;
                if (mp.get("web_max_num") != null) {
                    intWebMaxnum = Integer.parseInt(mp.get("web_max_num") + "");
                }

                int intWxMaxnum = 0;
                if (mp.get("wx_max_num") != null) {
                    intWxMaxnum = Integer.parseInt(mp.get("wx_max_num") + "");
                }
                staffQuery = new StaffQuery();
                staffQuery.setFlgCanLogin(true);
                staffQuery.setFlgValid(true);
                staffQuery.setCpId(cpId);
                List<StaffResponse> staffResponsesFlgCanLogin = staffMapper.selectByCond(staffQuery);
                if (staffResponsesFlgCanLogin != null && staffResponsesFlgCanLogin.size() > 0) {
                    List<StaffResponse> collectPc = staffResponsesFlgCanLogin.stream().filter(it -> (it.getLoginType() != null && it.getLoginType() == 1) || (it.getLoginType() != null && it.getLoginType() == 3)).collect(Collectors.toList());
                    List<StaffResponse> collectWx = staffResponsesFlgCanLogin.stream().filter(it -> (it.getLoginType() != null && it.getLoginType() == 2) || (it.getLoginType() != null && it.getLoginType() == 3)).collect(Collectors.toList());
                    if ((staffVO.getLoginType() == 1 || staffVO.getLoginType() == 3) &&
                            collectPc != null && collectPc.size() > 0 && intWebMaxnum < collectPc.size() + 1) {
                        // 无用户
                        throw new BaseBusinessException(ErrorCodeEnum.USER_MAX_PC_STAFF_ERROR.getCode(),
                                ErrorCodeEnum.USER_MAX_PC_STAFF_ERROR.getMessage());
                    }
                    if ((staffVO.getLoginType() == 2 || staffVO.getLoginType() == 3) &&
                            collectWx != null && collectWx.size() > 0 && intWxMaxnum < collectWx.size() + 1) {
                        // 无用户
                        throw new BaseBusinessException(ErrorCodeEnum.USER_MAX_WX_STAFF_ERROR.getCode(),
                                ErrorCodeEnum.USER_MAX_WX_STAFF_ERROR.getMessage());
                    }
                }
            }
        }

        // 获取编码和主键UuId
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.STAFF.getName(), false);
        staff.setStaffId(codeMap.get("outId").toString());
//        staff.setStaffCode(codeMap.get("outNote").toString());
        super.insert(staff);

        // 常用菜单的插入
        if (staffVO.getFlgCanLogin() != null && staffVO.getFlgCanLogin()) {
            ResponseResultVO<?> comMenuRes = companyFeign.getComMenu(staffEntity.getGradeCode());
            if (comMenuRes.getCode() == ResponseCodeEnum.SUCCESS.getCode()) {
                List<Map<String, Object>> comMenuMapList = (List<Map<String, Object>>) comMenuRes.getData();

                List<ComMenu> listCom = new ArrayList<>();
                if (comMenuMapList != null && comMenuMapList.size() > 0) {
                    for (int i = 0; i < comMenuMapList.size(); i++) {
                        Map<String, Object> m = comMenuMapList.get(i);
                        ComMenu comMenu = new ComMenu();
                        comMenu.setMenuUuid(m.get("menuUuid").toString());
                        comMenu.setStaffId(staff.getStaffId());
                        comMenu.setAppCode(m.get("appCode").toString());
                        comMenu.setDisplayNo((Integer) m.get("displayNo"));
                        comMenu.setCpId(cpId);
                        listCom.add(comMenu);
                    }
                    comMenuMapper.insertBatch(listCom);
                }
            }
        }
        // 讲电话和名称插入微信用户表里
        Map<String, Object> collectQuery = new HashMap<>();
        collectQuery.put("currentCp", staff.getCpId());
        collectQuery.put("userName", staff.getStaffName());
        collectQuery.put("userPhone", staff.getStaffPhone());
        ResponseResultVO<?> resultVO = userFeign.registerFeign(collectQuery);
        Map<String, Object> m = new HashMap<>();

        // 如果没有成功返回，状态设置为待审
        if (resultVO.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
            // 无用户
            throw new BaseBusinessException(ErrorCodeEnum.USER_REGISTER_ERROR.getCode(),
                    ErrorCodeEnum.USER_REGISTER_ERROR.getMessage());
        } else {
            m = (Map<String, Object>) resultVO.getData();
        }
        staff.setWxUserId(m.get("userId").toString());
        super.updateByUuid(staff);
        return ResponseResultUtil.success(staff);
    }

    /**
     * @desc : 保存方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insertFeignStaff(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setCpId(staff.getCpId());
        staffQuery.setStaffPhone(staff.getStaffPhone());
        staffQuery.setFlgValid(true);
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }
        // 获取编码和主键UuId
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(
                Constant.docNameConstant.STAFF.getName(), staff.getCpId(), true);
        staff.setStaffId(codeMap.get("outId").toString());
        staff.setStaffCode(codeMap.get("outNote").toString());
        staff.setFlgCanLogin(true);
        // 标准版
        if (Constant.GradeCode.STD.getName().equals(staffVO.getGradeCode())) {
            staff.setLoginType(2);
        } else {
            staff.setLoginType(3);
        }
//        初始标识
        staff.setFlgInit(true);
        super.insert(staff);
        return ResponseResultUtil.success(staff);
    }

    /**
     * @desc : 注册商户时候插入  角色 基础资料（仓库 渠道 收入 支出 入库 出库 账户 来源 盈亏原因） 计量单位 种类  打印票据  等等。
     * 返回角色的数据
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<?> insertFeignCompanyData(Map<String, List<Map<String, Object>>> map) {
        // 公司
        List<Map<String, Object>> listCom = map.get("company");
        // 版本
        String gradeCode = listCom.get(0).get("gradeCode").toString();
        // 角色
        List<Map<String, Object>> listRoles = map.get("roles");
        List<Role> listR = new ArrayList<>();
        String roleid = "";
        Integer cpId = Integer.parseInt(listCom.get(0).get("cpId").toString());
        String staffId = listCom.get(0).get("staffId").toString();

        List<Map<String, Object>> listComMenu = map.get("listComMenu");
        List<ComMenu> listC = new ArrayList<>();
        if (listComMenu != null && listComMenu.size() > 0) {
            for (int i = 0; i < listComMenu.size(); i++) {
                Map<String, Object> m = listComMenu.get(i);
                ComMenu comMenu = new ComMenu();
                comMenu.setMenuUuid(m.get("menuUuid").toString());
                comMenu.setAppCode(m.get("appCode").toString());
                comMenu.setDisplayNo((Integer) m.get("displayNo"));
                comMenu.setCpId(cpId);
                comMenu.setStaffId(staffId);
                listC.add(comMenu);
            }
            comMenuMapper.insertBatch(listC);
        }
        // 插入常用功能 标准版 插入 销售出库 库存查询 商品档案
        if (Constant.STD.equals(gradeCode)) {
//            List<String> objectCodeList = new ArrayList<>();
//            // 商品属性
//            objectCodeList.add("goods-attr");
//            // 商品档案
//            objectCodeList.add("goods");
//            // 销售订单
//            objectCodeList.add("order");
//            // 销售出库
//            objectCodeList.add("order-out");
//            // 库存查询
//            objectCodeList.add("ivt-detail-report");
//
//            ComMenuVO comMenuVO = new ComMenuVO();
//            comMenuVO.setCpId(cpId).setStaffId(staffId).setAppCode(Constant.AppCode.WEIXIN.getCode())
//                    .setObjectCodeList(objectCodeList);
//            comMenuMapper.saveByCompany(comMenuVO);

            // 系统参数
            List<SettingValue> settingValueList = new ArrayList<>();
            // 自动办理
            settingValueList.add(new SettingValue().setCpId(cpId).setSettingCode(Constant.SystemConstant.IVT_001.getValue())
                    .setSettingValue("true"));
            // 欠货销售
            settingValueList.add(new SettingValue().setCpId(cpId).setSettingCode(Constant.SystemConstant.IVT_002.getValue())
                    .setSettingValue("false"));
            settingValueMapper.insertBatch(settingValueList);
        }
        for (int i = 0; i < listRoles.size(); i++) {
            Map<String, Object> m = listRoles.get(i);
            Role role = new Role();
            //设置编码
            Map<String, Object> uniqueNoteCode = commonService.getUniqueNoteCode(Constant.docNameConstant.ROLE.getName(), cpId, false);
            if (Constant.ROLE_DATA.equals(m.get("roleCode").toString())) {
                roleid = uniqueNoteCode.get("outId").toString();
            }
            role.setRoleId(uniqueNoteCode.get("outId").toString());
            role.setRoleCode(m.get("roleCode").toString());
            role.setRoleName(m.get("roleName").toString());
            role.setDisplayNo((Integer) m.get("displayNo"));
            role.setCpId(cpId);
            role.setOpCreateUserId(staffId);
            // 标准版 不限制权限
            if (Constant.STD.equals(gradeCode)) {
                role.setFlgNolimitFun(true);
                role.setFlgNolimitPvw(true);
                role.setFlgNolimitSen(true);
            } else {
                role.setFlgNolimitFun(false);
                role.setFlgNolimitPvw(false);
                role.setFlgNolimitSen(false);
            }
            listR.add(role);
        }
        roleMapper.insertBatch(listR);

        // 更新用户的角色ids-
        List<String> roleids = new ArrayList<>();
        roleids.add(roleid);
        this.updateByUuid(new Staff().setStaffId(staffId).setRoleIds(roleids));
        // 角色权限
        RoleFun roleFun = new RoleFun();
        roleFun.setRoleId(roleid);
        roleFun.setCpId(cpId);
        roleFun.setOpCreateUserId(staffId);
        roleFunMapper.insertRoleFunFeign(roleFun);
        // 仓库
        List<Map<String, Object>> listWarehouses = map.get("warehouses");
        List<Warehouse> listW = new ArrayList<>();
        if (listWarehouses != null && listWarehouses.size() > 0) {
            for (int i = 0; i < listWarehouses.size(); i++) {
                Map<String, Object> m = listWarehouses.get(i);
                Warehouse warehouse = new Warehouse();
                warehouse.setWhCode(m.get("whCode").toString());
                warehouse.setWhName(m.get("whName").toString());
                warehouse.setDisplayNo((Integer) m.get("displayNo"));
                warehouse.setFlgDefault((Boolean) m.get("flgDefault"));
                warehouse.setCpId(cpId);
                warehouse.setOpCreateUserId(staffId);
                listW.add(warehouse);
            }
            warehouseMapper.insertBatch(listW);
        }

        // 渠道
        List<Map<String, Object>> listSaleChannels = map.get("saleChannels");
        List<SaleChannel> listSc = new ArrayList<>();
        if (listSaleChannels != null && listSaleChannels.size() > 0) {
            for (int i = 0; i < listSaleChannels.size(); i++) {
                Map<String, Object> m = listSaleChannels.get(i);
                SaleChannel saleChannel = new SaleChannel();
                saleChannel.setChannelCode(m.get("channelCode").toString());
                saleChannel.setChannelName(m.get("channelName").toString());
                saleChannel.setDisplayNo((Integer) m.get("displayNo"));
                saleChannel.setFlgDefault((Boolean) m.get("flgDefault"));
                saleChannel.setCpId(cpId);
                saleChannel.setOpCreateUserId(staffId);
                listSc.add(saleChannel);
            }
            saleChannelMapper.insertBatch(listSc);
        }

        // 基础资料
        List<Map<String, Object>> listDictionaryDatas = map.get("dictionaryDatas");
        List<DictionaryData> listDD = new ArrayList<>();
        if (listDictionaryDatas != null && listDictionaryDatas.size() > 0) {
            for (int i = 0; i < listDictionaryDatas.size(); i++) {
                Map<String, Object> m = listDictionaryDatas.get(i);
                DictionaryData dictionaryData = new DictionaryData();
//                Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.DICTIONARYDATA.getName(),cpId, true);
//                // 获取编码和主键UuId  codeMap.get("outId").toString()
                dictionaryData.setDataId(UUID.randomUUID().toString());
                dictionaryData.setDictCode(m.get("dictCode").toString());
                dictionaryData.setDataCode(m.get("dataCode").toString());
                dictionaryData.setDataValue(m.get("dataValue").toString());
                dictionaryData.setDisplayNo((Integer) m.get("displayNo"));
                dictionaryData.setFlgDefault((Boolean) m.get("flgDefault"));
                dictionaryData.setCpId(cpId);
                dictionaryData.setOpCreateUserId(staffId);
                listDD.add(dictionaryData);
            }
            dictionaryDataMapper.insertBatch(listDD);
        }

        // 资金账户
        List<Map<String, Object>> listMoneyAccounts = map.get("moneyAccounts");
        List<MoneyAccount> listMa = new ArrayList<>();
        if (listMoneyAccounts != null && listMoneyAccounts.size() > 0) {
            for (int i = 0; i < listMoneyAccounts.size(); i++) {
                Map<String, Object> m = listMoneyAccounts.get(i);
                MoneyAccount moneyAccount = new MoneyAccount();
                moneyAccount.setMacCode(m.get("macCode").toString());
                moneyAccount.setMacName(m.get("macName").toString());
//               从上面数据字典中查询 新的id 240814
                List<DictionaryData> dictionaryDatas = listDD.stream().filter(it ->
                        "基础资料-账户".equals(it.getDictCode()) && (m.get("macName") + "").equals(it.getDataValue())
                ).collect(Collectors.toList());

                if (dictionaryDatas != null && dictionaryDatas.size() > 0) {
                    moneyAccount.setMacType(dictionaryDatas.get(0).getDataId());
                } else {
                    // 该值不正确  要清洗数据
                    moneyAccount.setMacType(m.get("macType").toString());
                }
                moneyAccount.setAccDate(LocalDate.now());
//                moneyAccount.setBalance((BigDecimal) m.get("balance"));
                moneyAccount.setBalance(new BigDecimal(m.get("balance").toString()));
                moneyAccount.setFlgDefault((Boolean) m.get("flgDefault"));
                moneyAccount.setFlgNegative((Boolean) m.get("flgNegative"));
                moneyAccount.setDisplayNo((Integer) m.get("displayNo"));
                moneyAccount.setCpId(cpId);
                listMa.add(moneyAccount);
            }
            moneyAccountMapper.insertBatch(listMa);
        }
        // 计量单位
        List<Map<String, Object>> listUnits = map.get("units");
        List<Unit> listU = new ArrayList<>();
        if (listUnits != null && listUnits.size() > 0) {
            for (int i = 0; i < listUnits.size(); i++) {
                Map<String, Object> m = listUnits.get(i);
                Unit unit = new Unit();
                unit.setUnitCode(m.get("unitCode").toString());
                unit.setUnitName(m.get("unitName").toString());
                unit.setDecimalPlaces((Integer) m.get("decimalPlaces"));
                unit.setDisplayNo((Integer) m.get("displayNo"));
                unit.setCpId(cpId);
                unit.setOpCreateUserId(staffId);
                listU.add(unit);
            }
            unitMapper.insertBatch(listU);
        }

        // 种类
        List<Map<String, Object>> listGoodsCategorys = map.get("goodsCategorys");
        List<GoodsCategory> listG = new ArrayList<>();
        List<Map<String, Object>> parentList = listGoodsCategorys.stream().filter(it -> it.get("parentId") == null).collect(Collectors.toList());
        if (parentList != null && parentList.size() > 0) {
            for (int i = 0; i < parentList.size(); i++) {
                Map<String, Object> m = parentList.get(i);
                // 获取子级
                List<Map<String, Object>> childList = listGoodsCategorys.stream().filter(it -> m.get("catId").equals(it.get("parentId"))).collect(Collectors.toList());
                GoodsCategory goodsCategory = new GoodsCategory();
                goodsCategory.setCatCode(m.get("catCode") + "");
                goodsCategory.setCatName(m.get("catName") + "");
                if (m.get("parentId") != null) {
                    goodsCategory.setParentId(m.get("parentId") + "");
                }
                if (m.get("topId") != null) {
                    goodsCategory.setTopId(m.get("topId") + "");
                }
                goodsCategory.setCatId(UUID.randomUUID().toString());
                goodsCategory.setDisplayNo((Integer) m.get("displayNo"));
                goodsCategory.setCpId(cpId);
                goodsCategory.setOpCreateUserId(staffId);
                goodsCategoryMapper.insert(goodsCategory);
                listG = new ArrayList<>();
                // 插入子级
                for (Map<String, Object> c : childList) {
                    GoodsCategory gc = new GoodsCategory();
                    gc.setCatCode(c.get("catCode") + "");
                    gc.setCatName(c.get("catName") + "");
                    gc.setParentId(goodsCategory.getCatId());
                    gc.setTopId(goodsCategory.getTopId());
                    gc.setDisplayNo((Integer) c.get("displayNo"));
                    gc.setCpId(cpId);
                    gc.setOpCreateUserId(staffId);
                    listG.add(gc);
                }
                ;
                if (listG != null && listG.size() > 0) {
                    goodsCategoryMapper.insertBatch(listG);
                }
            }
            //执行函数
            goodsCategoryMapper.resetLevelGoodsCategory(new GoodsCategoryQuery());
        }

        // 打印票据
        List<Map<String, Object>> listPrintLayout = map.get("printLayout");
        List<PrintLayout> listP = new ArrayList<>();
        if (listPrintLayout != null && listPrintLayout.size() > 0) {
            for (int i = 0; i < listPrintLayout.size(); i++) {
                Map<String, Object> m = listPrintLayout.get(i);
                PrintLayout printLayout = new PrintLayout();
                printLayout.setLayoutName(m.get("layoutName") + "");
                printLayout.setLayoutData(JSONObject.parseObject(JSONObject.toJSONString(m.get("layoutData"))));
                printLayout.setDisplayNo((Integer) m.get("displayNo"));
                printLayout.setDocName(m.get("docName") + "");
                printLayout.setCpId(cpId);
                printLayout.setOpCreateUserId(staffId);
                listP.add(printLayout);
            }
            printLayoutMapper.insertBatch(listP);
        }
        return ResponseResultUtil.success();
    }


    /**
     * @desc : 保存方法-邀请员工的确定
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<?> insertRequestStaff(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setCpId(staff.getCpId());
        staffQuery.setStaffPhone(staff.getStaffPhone());
        staffQuery.setFlgValid(true);
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }
        // 获取编码和主键UuId
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.STAFF.getName(), true);
        staff.setStaffId(codeMap.get("outId").toString());
        staff.setStaffCode(codeMap.get("outNote").toString());
        // 更新 被邀人员的cpid
        if (staff.getWxUserId() != null) {
            // 更新 被邀请人员的微信用户的cpid 加入公司
            Map<String, Object> collectQuery = new HashMap<>();
            collectQuery.put("cpId", staff.getCpId());
            collectQuery.put("userId", staff.getWxUserId());
            companyFeign.updateWxUserCompany(collectQuery);
        }
        // 插入员工
        super.insert(staff);
        return ResponseResultUtil.success(staff);
    }

    /**
     * @desc : 编辑方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> update(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 查询原来的getFlgCanLogin
        StaffResponse staffResponseOld = staffMapper.selectById(staffVO.getStaffId());

        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStaffPhone(staff.getStaffPhone());
        staffQuery.setCpId(cpId);
        staffQuery.setFlgValid(true);
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0 && !staffVO.getStaffId().equals(staffResponses.get(0).getStaffId())) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }

        staffQuery.setStaffPhone(null);
        staffQuery.setStaffCode(staff.getStaffCode());
        staffResponses = staffMapper.selectByCondByCode(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0 && !staffVO.getStaffId().equals(staffResponses.get(0).getStaffId())) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_CODE_EXIST);
        }

        super.updateByUuid(staff);

        //可以绑定微信的员工人数  人数上限
        if (staffVO.getFlgCanLogin() != null && staffVO.getFlgCanLogin()) {
            ResponseResultVO<?> resultMaxnum = companyFeign.getCompanyMaxStaffNum(cpId);
            if (resultMaxnum.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
                // 无用户
                throw new BaseBusinessException(ErrorCodeEnum.USER_REGISTER_ERROR.getCode(),
                        ErrorCodeEnum.USER_REGISTER_ERROR.getMessage());
            } else {
                if (staffResponseOld.getFlgCanLogin() != staffVO.getFlgCanLogin()) {
                    Map<String, Object> mp = (Map<String, Object>) resultMaxnum.getData();
                    int intWebMaxnum = 0;
                    if (mp.get("web_max_num") != null) {
                        intWebMaxnum = Integer.parseInt(mp.get("web_max_num") + "");
                    }

                    int intWxMaxnum = 0;
                    if (mp.get("wx_max_num") != null) {
                        intWxMaxnum = Integer.parseInt(mp.get("wx_max_num") + "");
                    }
                    StaffQuery staffQueryf = new StaffQuery();
                    staffQueryf.setFlgCanLogin(true);
                    staffQueryf.setCpId(cpId);
                    List<StaffResponse> staffResponsesFlgCanLogin = staffMapper.selectByCond(staffQueryf);
                    if (staffResponsesFlgCanLogin != null && staffResponsesFlgCanLogin.size() > 0) {
                        List<StaffResponse> collectPc = staffResponsesFlgCanLogin.stream().filter(it -> it.getLoginType() == 1 || it.getLoginType() == 3).collect(Collectors.toList());
                        List<StaffResponse> collectWx = staffResponsesFlgCanLogin.stream().filter(it -> it.getLoginType() == 2 || it.getLoginType() == 3).collect(Collectors.toList());
                        if (collectPc != null && collectPc.size() > 0 && intWebMaxnum < collectPc.size()) {
                            // 无用户
                            throw new BaseBusinessException(ErrorCodeEnum.USER_MAX_PC_STAFF_ERROR.getCode(),
                                    ErrorCodeEnum.USER_MAX_PC_STAFF_ERROR.getMessage());
                        }
                        if (collectWx != null && collectWx.size() > 0 && intWxMaxnum < collectWx.size()) {
                            // 无用户
                            throw new BaseBusinessException(ErrorCodeEnum.USER_MAX_WX_STAFF_ERROR.getCode(),
                                    ErrorCodeEnum.USER_MAX_WX_STAFF_ERROR.getMessage());
                        }
                    }

                }

//                if (staffResponsesFlgCanLogin != null && staffResponsesFlgCanLogin.size() > 0 && intMaxnum < staffResponsesFlgCanLogin.size()) {
//                    // 无用户
//                    throw new BaseBusinessException(ErrorCodeEnum.USER_MAX_STAFF_ERROR.getCode(),
//                            ErrorCodeEnum.USER_MAX_STAFF_ERROR.getMessage());
//                }

            }
//            if (staffResponseOld.getFlgCanLogin() != staffVO.getFlgCanLogin()) {
//                // 增加一个可以cur_staff_num
//                Map<String, Object> m = new HashMap<>();
//                m.put("curStaffNum", 1);
//                m.put("cpId", cpId);
//                ResponseResultVO<Boolean> booleanResponseResultVO = companyFeign.updateCompanyCurStaffNum(m);
//                if (booleanResponseResultVO.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
//                    // 无用户
//                    throw new BaseBusinessException(ErrorCodeEnum.USER_REGISTER_ERROR.getCode(),
//                            ErrorCodeEnum.USER_REGISTER_ERROR.getMessage());
//                }
//            }
        } else {
//            2024-05-20 edit
//            if (staffResponseOld.getFlgCanLogin() != staffVO.getFlgCanLogin()) {
//                // 减少一个可以cur_staff_num
//                Map<String, Object> m = new HashMap<>();
//                m.put("curStaffNum", -1);
//                m.put("cpId", cpId);
//                ResponseResultVO<Boolean> booleanResponseResultVO = companyFeign.updateCompanyCurStaffNum(m);
//                if (booleanResponseResultVO.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
//                    // 无用户
//                    throw new BaseBusinessException(ErrorCodeEnum.USER_REGISTER_ERROR.getCode(),
//                            ErrorCodeEnum.USER_REGISTER_ERROR.getMessage());
//                }
//            }
        }
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 更新员工的登录标识
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<Boolean> updateFeignStaffFlgCanLogin(List<String> list) {
        //  FlgCanLogin  登录系统（1：PC端，2：移动端，3：PC+移动端, 4：无）
        staffMapper.updateFeignStaffFlgCanLogin(list);
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 保存权限方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> saveStaffRight(StaffVO staffVO) {
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        staffRightService.delete(staffVO.getStaffId());
        for (StaffRight staffRight : staffVO.getStaffRightList()) {
            staffRight.setStaffId(staff.getStaffId());
            staffRight.setRightType(1);
            staffRight.setCpId(cpId);
        }
        if (staffVO.getStaffRightList() != null && staffVO.getStaffRightList().size() > 0) {
            staffRightService.saveStaffRight(staffVO.getStaffRightList());
        }
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 保存权限方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> saveStaffPurview(StaffVO staffVO) {
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        for (StaffPurview staffRight : staffVO.getStaffPurviewList()) {
            staffRight.setStaffId(staff.getStaffId());
            staffRight.setCpId(cpId);
        }
        staffPurviewService.saveStaffPurview(staffVO.getStaffPurviewList());
        return ResponseResultUtil.success();
    }


    /**
     * @desc : 员工离职
     * @author : 姜永辉
     * @date : 2023/2/13 13:45
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> dimission(StaffVO staffVO) {
        // 将微信的用户的信息 openid  current_cp  , "joined_cps"   缩减相应的cpid
        // 更新 被邀请人员的微信用户的cpid 加入公司
        Map<String, Object> collectQuery = new HashMap<>();
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        collectQuery.put("cpId", cpId);
        collectQuery.put("userId", staffVO.getWxUserId());
        ResponseResultVO<?> resultVO = userFeign.updateClearOpenidFeign(collectQuery);
        // 如果没有成功返回，状态设置为待审
        if (resultVO.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
            // 无用户
            throw new BaseBusinessException(ErrorCodeEnum.STAFF_UPDATE_ERROR.getCode(),
                    ErrorCodeEnum.STAFF_UPDATE_ERROR.getMessage());
        }
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        super.updateByUuid(staff);
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 导入员工
     * @author : 姜永辉
     * @date : 2023/3/1 14:40
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> importStaffList(List<StaffVO> list) {
        if (CollectionUtils.isEmpty(list) || list.size() == 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.INSERT_FAIL);
        }

        return ResponseResultUtil.success();
    }

    /**
     * @desc : 登录后获取信息
     * @author : 周兴
     * @date : 2024/3/4 11:41
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Dictionary<String, Object>> getInfoAfterLogin(Map<String, Object> param) {
        // 先根据userId查询当前企业的员工信息
        StaffResponse staff = staffMapper.selectByUserId(param.get("userId").toString(), Integer.parseInt(param.get("cpId").toString()));
        if (staff != null) {
            // 提示不允许登录
            if (staff.getFlgCanLogin() == null || !staff.getFlgCanLogin()) {
                return ResponseResultUtil.error(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.STAFF_CAN_NOT_LOGIN.getMessage());
            }
            // 离职状态不允许登录
            if (staff.getHrStatus() != 1) {
                return ResponseResultUtil.error(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.STAFF_OUT_NOT_LOGIN.getMessage());
            }
            // 存Redis
            authUtils.saveStaff(new StaffEntity().setStaffId(staff.getStaffId())
                    .setWxUserId(staff.getWxUserId())
                    .setStaffCode(staff.getStaffCode())
                    .setStaffName(staff.getStaffName())
                    .setGradeCode(staff.getGradeCode())
                    .setCpId(Integer.parseInt(param.get("cpId").toString()))
                    .setAppCode(param.get("appCode").toString()));
            // 更新员工登录状态
            this.updateByUuid(new Staff().setStaffId(staff.getStaffId()).setFlgCanLogin(true));
        } else {
            return ResponseResultUtil.error(ErrorCodeEnum.STAFF_NOT_EXIST.getCode(), ErrorCodeEnum.STAFF_NOT_EXIST.getMessage());
        }

        // 获取菜单
        List menuList = commonMapper.getMenuByUser(param);
        // 获取常用菜单
        ResponseResultVO<?> comMenuList = comMenuService.selectMenu(new ComMenuQuery().setStaffId(staff.getStaffId())
                .setAppCode(param.get("appCode").toString()));
        // 获取所有参数
        Map<String, Object> allSettingValue = commonMapper.getAllSettingValue();
        Dictionary<String, Object> dic = new Hashtable<>();
        dic.put("menuList", menuList);
        dic.put("comMenuList", comMenuList.getData());
        dic.put("dataKindList", commonMapper.getDataKind(param));
        dic.put("settingValue", allSettingValue);
        dic.put("staff", staff);
        // 判断是否到期 返回服务器的时间
        dic.put("nowDate", LocalDate.now());
        return ResponseResultUtil.success(dic);
    }

    /**
     * @desc : 退出登录
     * @author : 周兴
     * @date : 2024-03-18 09:03
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> logout(Map<String, Object> param) {
        // 更新员工登录状态
//        this.updateByUuid(new Staff().setStaffId(param.get("staffId").toString()).setFlgCanLogin(false));
        return ResponseResultUtil.success(true);
    }


    /**
     * @desc : 生成幽灵标识的数据
     * @author : 常皓宁
     * @date : 2024/6/19 10:53
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insertGhostStaff(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStaffCode(staff.getStaffCode());
        staffQuery.setCpId(staff.getCpId());
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses == null || staffResponses.size() == 0) {
            return ResponseResultUtil.error(-200, "绑定员工不存在");
        } else {
            for (StaffResponse staffResponse : staffResponses) {
                // 获取编码和主键UuId
                Map<String, Object> codeMap = commonService.getUniqueNoteCode(
                        Constant.docNameConstant.STAFF.getName(), staff.getCpId(), true);
                staff.setStaffId(codeMap.get("outId").toString());
                staff.setStaffCode(codeMap.get("outNote").toString());
                staff.setStaffName(staff.getStaffName());
                staff.setStaffPhone(staff.getStaffPhone());
                staff.setOrgId(staffResponse.getOrgId());
                staff.setRoleIds(staffResponse.getRoleIds());
                staff.setHrStatus(staffResponse.getHrStatus());
                staff.setFlgCanLogin(staffResponse.getFlgCanLogin());
                staff.setWxUserId(staff.getWxUserId());
                staff.setLoginType(staffResponse.getLoginType());
                staff.setFlgInit(false);
                staff.setFlgGhost(true);
                super.insert(staff);
            }
            return ResponseResultUtil.success();
        }
    }

    /**
     * @desc : 删除幽灵标识数据
     * @author : 常皓宁
     * @date : 2024/6/19 10:53
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> deleteGhostStaff(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStaffName(staff.getStaffName());
        staffQuery.setStaffPhone(staff.getStaffPhone());
        staffQuery.setCpId(staff.getCpId());
        int a = staffMapper.deleteGhostStaff(staffQuery);
        if (a > 0) {
            return ResponseResultUtil.success();
        } else {
            return ResponseResultUtil.error(-200, "绑定员工不存在");
        }
    }

    /**
     * @desc : 更新负责人标识
     * @author : 刘尧
     * @date : 2024/6/21 16:24
     */
    public ResponseResultVO updateFlgInit(Map<String, Object> params) {
        boolean updateBool = staffMapper.updateFlgInit(params);
        if (updateBool) {
            updateBool = staffMapper.updateFlgInitById(String.valueOf(params.get("owner")));
            return ResponseResultUtil.success(updateBool);
        }
        return ResponseResultUtil.error();
    }
}
