package com.gree.mall.manager.logic.engin;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.engin.ProjectRepairBean;
import com.gree.mall.manager.bean.engin.ProjectRepairVO;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.IsYesNoEnum;
import com.gree.mall.manager.enums.base.BaseEnum;
import com.gree.mall.manager.enums.material.WebsitGoodsTypeEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.common.WechatLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.oss.OSSUtil;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.exceptions.PersistenceException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class ProjectRepairLogic {

    @Value("${wechat.mp.url}")
    private String WECHAT_MP_URL;

    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final RpProjectRepairService rpProjectRepairService;
    private final RpProjectRepairProductService rpProjectRepairProductService;
    private final RpProjectRepairByService rpProjectRepairByService;
    private final RpProjectRepairWebsitService rpProjectRepairWebsitService;
    private final RpProjectRepairItemService rpProjectRepairItemService;
    private final RpProjectRepairOperatorLogService rpProjectRepairOperatorLogService;
    private final OSSUtil ossUtil;
    private final WechatLogic wechatLogic;

    private final String defaultImgUrl = "https://train-2023.oss-cn-shenzhen.aliyuncs.com/2024-01/1705460926412fc7973c2-8c88-4226-8f0c-4ef60664113e.jpg";



    public IPage<ProjectRepairVO> list(ZfireParamBean zfireParamBean) {
        FieldUtils.supplyParam(zfireParamBean, ProjectRepairVO.class, commonLogic.getAdminUser());
        zfireParamBean.setAdminWebsitIds(zfireParamBean.getAdminWebsitIds());
        IPage<ProjectRepairVO> page = commonMapper.projectRepairList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);

        return page;
    }

    public ProjectRepairBean detail(String id) {
        ProjectRepairBean bean = new ProjectRepairBean();
        RpProjectRepair repair = rpProjectRepairService.getById(id);
        BeanUtils.copyProperties(repair, bean);

        List<OrderSmallType> typeList = new ArrayList();
        if (StringUtils.isNotBlank(repair.getOrderSmallType())) {
            String[] idList = repair.getOrderSmallType().split("/");
            String[] textList = repair.getOrderSmallTypeText().split("/");
            for (int i = 0; i < idList.length; i++) {
                OrderSmallType type = new OrderSmallType();
                type.setId(idList[i])
                        .setOrderSmallTypeText(textList[i]);
                typeList.add(type);
            }
        }
        bean.setTypeList(typeList);

        List<RpProjectRepairProduct> productList = rpProjectRepairProductService.lambdaQuery()
                .eq(RpProjectRepairProduct::getProjectRepairId, id)
                .list();
        List<RpProjectRepairBy> byList = rpProjectRepairByService.lambdaQuery()
                .eq(RpProjectRepairBy::getProjectRepairId, id)
                .list();
        List<RpProjectRepairWebsit> websitList = rpProjectRepairWebsitService.lambdaQuery()
                .eq(RpProjectRepairWebsit::getProjectRepairId, id)
                .list();
        List<RpProjectRepairItem> itemList = rpProjectRepairItemService.lambdaQuery()
                .eq(RpProjectRepairItem::getProjectRepairId, id)
                .list();
        List<RpProjectRepairOperatorLog> operatorLogList = rpProjectRepairOperatorLogService.lambdaQuery()
                .eq(RpProjectRepairOperatorLog::getProjectRepairId, id)
                .orderByDesc(RpProjectRepairOperatorLog::getCreateTime)
                .list();
        bean.setProductList(productList);
        bean.setByList(byList);
        bean.setWebsitList(websitList);
        bean.setItemList(itemList);
        bean.setOperatorLogList(operatorLogList);


        return bean;
    }

    @Transactional
    public void save(ProjectRepairBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        AdminCompanyWechat companyWechat = adminUser.getAdminCompanyWechat();
        if (CollectionUtil.isEmpty(bean.getTypeList())) {
            throw new RemoteServiceException("请选择工单类型");
        }

        if (bean.getIsAllFee().equals(IsYesNoEnum.NO.getKey()) && StringUtils.isBlank(bean.getFeePayMethod())) {
            throw new RemoteServiceException("请选择费用支付方式");
        }

        if (StringUtils.isBlank(bean.getId())) {
            // 添加
            RpProjectRepair repair = new RpProjectRepair();
            BeanUtils.copyProperties(bean, repair);

            repair.setId(IdWorker.getIdStr())
                    .setCompanyWechatId(companyWechat.getCompanyWechatId())
                    .setCompanyWechatName(companyWechat.getCompanyName());

            this.mergeOrderType(repair, null, bean.getTypeList());

//            String miniUrl = wechatLogic.getQrcode("ENGIN_PROJECT_REPAIR", repair.getId(), null, repair.getCompanyWechatId());
//            repair.setServiceCode(miniUrl);

            // https://xxxxxx/packageHome/pages/maintenance/create?appid=xxxxxx&projectId=xxxxxx
            byte[] bytes = QrCodeUtil.generatePng(WECHAT_MP_URL + "packageHome/pages/maintenance/create?appid="
                    + companyWechat.getSubAppId() + "&projectId=" + repair.getId(), 300, 300);

            long currentTime = System.currentTimeMillis();
            String filePath = ossUtil.getFilePath() + "/" + currentTime + UUID.randomUUID() + ".png";
            ossUtil.uploadFile(filePath, bytes);
            repair.setServiceCode(ossUtil.getAccessUrl() + filePath);


            repair.insert();

            bean.setId(repair.getId());

            if (CollectionUtil.isNotEmpty(bean.getProductList())) {
                int index = 0;
                for (RpProjectRepairProduct product : bean.getProductList()) {
                    try {
                        index++;
                        product.setProjectRepairId(bean.getId());
                        this.productSave(product, adminUser);
                    } catch (SQLIntegrityConstraintViolationException | PersistenceException se) {
                        throw new RemoteServiceException("项目设备第" + index + "行, 品牌,产品大类,产品小米不能重复");
                    } catch (Exception e) {
                        throw new RemoteServiceException("项目设备第" + index + "行, " + e.getMessage());
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(bean.getByList())) {
                int index = 0;
                long count = bean.getByList().stream().filter(v -> v.getFeeExamine().equals(IsYesNoEnum.YES.getKey())).count();
                if (count == 0) {
                    throw new RemoteServiceException("项目人员必须有一个费用审批为\"是\"");
                }
                for (RpProjectRepairBy by : bean.getByList()) {
                    try {
                        index++;
                        by.setProjectRepairId(bean.getId());
                        this.bySave(by, adminUser);
                    } catch (Exception e) {
                        throw new RemoteServiceException("项目人员第" + index + "行, " + e.getMessage());
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(bean.getWebsitList())) {
                int index = 0;
                for (RpProjectRepairWebsit websit : bean.getWebsitList()) {
                    try {
                        index++;
                        websit.setProjectRepairId(bean.getId());
                        this.websitSave(websit, adminUser);
                    } catch (Exception e) {
                        throw new RemoteServiceException("服务网点第" + index + "行, " + e.getMessage());
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(bean.getWebsitList())) {
                int index = 0;
                for (RpProjectRepairWebsit websit : bean.getWebsitList()) {
                    try {
                        index++;
                        websit.setProjectRepairId(bean.getId());
                        this.websitSave(websit, adminUser);
                    } catch (Exception e) {
                        throw new RemoteServiceException("服务网点第" + index + "行, " + e.getMessage());
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(bean.getItemList())) {
                // 检查唯一
                this.checkItemUnique(bean.getItemList());
                int index = 0;
                for (RpProjectRepairItem item : bean.getItemList()) {
                    WebsitGoodsTypeEnum typeEnum = BaseEnum.keyToEnumNotNull(WebsitGoodsTypeEnum.class, item.getGoodsType());
                    try {
                        index++;
                        item.setProjectRepairId(bean.getId());
                        this.itemSave(item, adminUser);
                    } catch (Exception e) {
                        throw new RemoteServiceException(typeEnum.getRemark() + "配置第" + index + "行, " + e.getMessage());
                    }
                }
            }
        } else {
            // 编辑
            RpProjectRepair oldRepair = rpProjectRepairService.lambdaQuery()
                    .eq(RpProjectRepair::getCompanyWechatId, adminUser.getCompanyWechatId())
                    .eq(RpProjectRepair::getId, bean.getId())
                    .one();

            if (Objects.isNull(oldRepair)) {
                throw new RemoteServiceException(bean.getId() + " 工程维护单据不存在");
            }

            this.mergeOrderType(null, bean, bean.getTypeList());

            this.compareParams(bean, oldRepair);

            List<RpProjectRepairOperatorLog> operatorLogList = new ArrayList<>();
            List<RpProjectRepairProduct> productList = this.checkProductList(bean, oldRepair, operatorLogList, adminUser);
            if (CollectionUtil.isNotEmpty(productList)) {
                // 检查品牌产品大类产品小类唯一
                Map<String, List<RpProjectRepairProduct>> keyMap = productList.stream()
                        .collect(Collectors.groupingBy(v -> v.getBrandId() + "-" + v.getMainId() + "-" + v.getSmallId()));
                for (Map.Entry<String, List<RpProjectRepairProduct>> entry : keyMap.entrySet()) {
                    if (entry.getValue().size() > 1) {
                        RpProjectRepairProduct product = entry.getValue().get(0);
                        throw new RemoteServiceException(product.getBrandName() + "," + product.getMainName() + "," + product.getSmallName() + ", 品牌,产品大类,产品小米不能重复");
                    }
                }

                rpProjectRepairProductService.saveOrUpdateBatch(productList);
            }

            List<RpProjectRepairBy> byList = this.checkByList(bean, oldRepair, operatorLogList, adminUser);
            if (CollectionUtil.isNotEmpty(byList)) {
                rpProjectRepairByService.saveOrUpdateBatch(byList);
            }

            List<RpProjectRepairWebsit> websitList = this.checkWebsitList(bean, oldRepair, operatorLogList, adminUser);
            rpProjectRepairWebsitService.lambdaUpdate()
                    .eq(RpProjectRepairWebsit::getProjectRepairId, oldRepair.getId())
                    .remove();
            if (CollectionUtil.isNotEmpty(websitList)) {
                rpProjectRepairWebsitService.saveOrUpdateBatch(websitList);
            }

            if (CollectionUtil.isNotEmpty(operatorLogList)) {
                rpProjectRepairOperatorLogService.saveBatch(operatorLogList);
            }

            List<RpProjectRepairItem> itemList = this.checkItemList(bean, oldRepair, operatorLogList, adminUser);
            rpProjectRepairItemService.lambdaUpdate()
                    .eq(RpProjectRepairItem::getProjectRepairId, oldRepair.getId())
                    .remove();
            if (CollectionUtil.isNotEmpty(itemList)) {
                // 检查唯一
                this.checkItemUnique(itemList);
                rpProjectRepairItemService.saveOrUpdateBatch(itemList);
            }
        }


    }

    private void checkItemUnique(List<RpProjectRepairItem> itemList) {
        Map<String, List<RpProjectRepairItem>> keyMap = itemList.stream()
                .collect(Collectors.groupingBy(RpProjectRepairItem::getGoodsId));
        for (Map.Entry<String, List<RpProjectRepairItem>> entry : keyMap.entrySet()) {
            if (entry.getValue().size() > 1) {
                RpProjectRepairItem product = entry.getValue().get(0);
                WebsitGoodsTypeEnum anEnum = BaseEnum.keyToEnumNotNull(WebsitGoodsTypeEnum.class, product.getGoodsType());
                throw new RemoteServiceException(anEnum.getRemark() + "配置里的 " + product.getGoodsName() + ", 商品不能重复");
            }
        }
    }

    private void mergeOrderType(RpProjectRepair repair, ProjectRepairBean bean, List<OrderSmallType> typeList) {
        StringBuilder typeIdSb = new StringBuilder();
        StringBuilder textIdSb = new StringBuilder();
        for (OrderSmallType type : typeList) {
            if (StringUtils.isBlank(type.getId())) {
                throw new RemoteServiceException("工单类型不能为空");
            }
            typeIdSb.append(type.getId()).append("/");
            textIdSb.append(type.getOrderSmallTypeText()).append("/");
        }
        if (Objects.nonNull(repair)) {
            repair.setOrderSmallType(typeIdSb.deleteCharAt(typeIdSb.lastIndexOf("/")).toString())
                    .setOrderSmallTypeText(textIdSb.deleteCharAt(textIdSb.lastIndexOf("/")).toString());
        } else {
            bean.setOrderSmallType(typeIdSb.deleteCharAt(typeIdSb.lastIndexOf("/")).toString());
            bean.setOrderSmallTypeText(textIdSb.deleteCharAt(textIdSb.lastIndexOf("/")).toString());
        }
    }

    private void compareParams(ProjectRepairBean bean, RpProjectRepair oldRepair) {
        StringBuilder sb = new StringBuilder();
        if (!StrUtil.trim(bean.getProjectName()).equals(StrUtil.trim(oldRepair.getProjectName()))) {
            sb.append("原项目名称: ")
                    .append(StrUtil.trim(oldRepair.getProjectName()))
                    .append(" 新项目名称: ")
                    .append(StrUtil.trim(bean.getProjectName()))
                    .append(", ");
            oldRepair.setProjectName(bean.getProjectName());
        }

        if (!StrUtil.trim(bean.getManger()).equals(StrUtil.trim(oldRepair.getManger()))) {
            sb.append("原负责人: ")
                    .append(StrUtil.trim(oldRepair.getManger()))
                    .append(" 新负责人: ")
                    .append(StrUtil.trim(bean.getManger()))
                    .append(", ");
            oldRepair.setManger(bean.getManger());
        }

        if (!StrUtil.trim(bean.getMobile()).equals(StrUtil.trim(oldRepair.getMobile()))) {
            sb.append("原联系电话: ")
                    .append(StrUtil.trim(oldRepair.getMobile()))
                    .append(" 新联系电话: ")
                    .append(StrUtil.trim(bean.getMobile()))
                    .append(", ");
            oldRepair.setMobile(bean.getMobile());
        }

        if (bean.getStartTime().getTime() != oldRepair.getStartTime().getTime()) {
            sb.append("原维保开始时间: ")
                    .append(DateUtil.formatDate(bean.getStartTime()))
                    .append(" 新维保开始时间: ")
                    .append(DateUtil.formatDate(oldRepair.getStartTime()))
                    .append(", ");
            oldRepair.setStartTime(bean.getStartTime());
        }

        if (bean.getEndTime().getTime() != oldRepair.getEndTime().getTime()) {
            sb.append("原维保结束时间: ")
                    .append(DateUtil.formatDate(bean.getEndTime()))
                    .append(" 新维保结束时间: ")
                    .append(DateUtil.formatDate(oldRepair.getEndTime()))
                    .append(", ");
            oldRepair.setEndTime(bean.getEndTime());
        }

        if (!StrUtil.trim(bean.getOrderSmallTypeText()).equals(StrUtil.trim(oldRepair.getOrderSmallTypeText()))) {
            sb.append("原工单类型: ")
                    .append(StrUtil.trim(oldRepair.getOrderSmallTypeText()))
                    .append(" 新工单类型: ")
                    .append(StrUtil.trim(bean.getOrderSmallTypeText()))
                    .append(", ");
            oldRepair.setOrderSmallType(bean.getOrderSmallType());
            oldRepair.setOrderSmallTypeText(bean.getOrderSmallTypeText());
        }

        if (ObjectUtil.notEqual(bean.getIsAllFee(), oldRepair.getIsAllFee())) {
            sb.append("原包含全部费用: ")
                    .append(oldRepair.getIsAllFee())
                    .append(" 新包含全部费用: ")
                    .append(bean.getIsAllFee())
                    .append(", ");
            oldRepair.setIsAllFee(bean.getIsAllFee());
        }

        if (oldRepair.getIsAllFee().equals(IsYesNoEnum.NO.getKey())
                && ObjectUtil.notEqual(bean.getFeePayMethod(), ObjectUtil.defaultIfNull(oldRepair.getFeePayMethod(), ""))) {
            sb.append("原费用支付方式: ")
                    .append(ObjectUtil.defaultIfNull(oldRepair.getFeePayMethod(), ""))
                    .append(" 新费用支付方式: ")
                    .append(bean.getFeePayMethod())
                    .append(", ");
            oldRepair.setFeePayMethod(bean.getFeePayMethod());
        }

        if (ObjectUtil.notEqual(bean.getProvince(), oldRepair.getProvince())) {
            sb.append("原项目地址 省: ")
                    .append(oldRepair.getProvince())
                    .append(" 新项目地址 省: ")
                    .append(bean.getProvince())
                    .append(", ");
            oldRepair.setProvinceId(bean.getProvinceId());
            oldRepair.setProvince(bean.getProvince());
        }

        if (ObjectUtil.notEqual(bean.getCity(), oldRepair.getCity())) {
            sb.append("原项目地址 市: ")
                    .append(oldRepair.getCity())
                    .append(" 新项目地址 市: ")
                    .append(bean.getCity())
                    .append(", ");
            oldRepair.setCityId(bean.getCityId());
            oldRepair.setCity(bean.getCity());
        }

        if (ObjectUtil.notEqual(bean.getArea(), oldRepair.getArea())) {
            sb.append("原项目地址 区: ")
                    .append(oldRepair.getArea())
                    .append(" 新项目地址 区: ")
                    .append(bean.getArea())
                    .append(", ");
            oldRepair.setAreaId(bean.getAreaId());
            oldRepair.setArea(bean.getArea());
        }

        if (ObjectUtil.notEqual(bean.getStreet(), oldRepair.getStreet())) {
            sb.append("原项目地址 街道: ")
                    .append(oldRepair.getStreet())
                    .append(" 新项目地址 街道: ")
                    .append(bean.getStreet())
                    .append(", ");
            oldRepair.setStreetId(bean.getStreetId());
            oldRepair.setStreet(bean.getStreet());
        }

        if (ObjectUtil.notEqual(bean.getAddress(), oldRepair.getAddress())) {
            sb.append("原项目地址: ")
                    .append(oldRepair.getAddress())
                    .append(" 新项目地址: ")
                    .append(bean.getAddress())
                    .append(", ");
            oldRepair.setAddress(bean.getAddress())
                    .setLat(bean.getLat())
                    .setLng(bean.getLng());
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("项目信息")
                    .setContent(updStr)
                    .insert();
        }

        oldRepair.updateById();
    }

    private List<RpProjectRepairProduct> checkProductList(ProjectRepairBean bean, RpProjectRepair oldRepair, List<RpProjectRepairOperatorLog> operatorLogList, AdminUserCom adminUser) {
        List<RpProjectRepairProduct> afterProductList = new ArrayList<>();
        // 设备检查
        List<RpProjectRepairProduct> oldProductList = rpProjectRepairProductService.lambdaQuery()
                .eq(RpProjectRepairProduct::getProjectRepairId, oldRepair.getId())
                .list();
        // 筛选出存在的设备记录
        List<RpProjectRepairProduct> existProductList = bean.getProductList().stream()
                .filter(v -> StringUtils.isNotBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(existProductList)) {
            // 记录id全空 全删除
            this.productAddOrDel(oldRepair, oldProductList, operatorLogList, false, afterProductList, adminUser);
        } else {
            // 半删半改, 对比修改的设备记录
            Map<String, RpProjectRepairProduct> existProductMap = existProductList.stream()
                    .collect(Collectors.toMap(RpProjectRepairProduct::getId, Function.identity()));
            List<RpProjectRepairProduct> updList = new ArrayList<>();
            List<RpProjectRepairProduct> delList = new ArrayList<>();
            for (RpProjectRepairProduct product : oldProductList) {
                if (existProductMap.containsKey(product.getId())) {
                    updList.add(product);
                } else {
                    delList.add(product);
                }
            }

            if (CollectionUtil.isNotEmpty(updList)) {
                // 修改记录
                this.productUpdate(oldRepair, updList, existProductMap, operatorLogList, afterProductList, adminUser);
            }

            if (CollectionUtil.isNotEmpty(delList)) {
                // 添加记录
                this.productAddOrDel(oldRepair, delList, operatorLogList, false, afterProductList, adminUser);
            }
        }

        // 筛选出添加的设备记录
        List<RpProjectRepairProduct> addProductList = bean.getProductList().stream()
                .filter(v -> StringUtils.isBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(addProductList)) {
            // 添加记录
            this.productAddOrDel(oldRepair, addProductList, operatorLogList, true, afterProductList, adminUser);
        }

        return afterProductList;
    }

    private void productUpdate(RpProjectRepair oldRepair, List<RpProjectRepairProduct> updList,
                               Map<String, RpProjectRepairProduct> existProductMap,
                               List<RpProjectRepairOperatorLog> operatorLogList,
                               List<RpProjectRepairProduct> afterProductList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        int index = 0;
        for (RpProjectRepairProduct oldProduct : updList) {
            StringBuilder recordSb = new StringBuilder();
            RpProjectRepairProduct newProduct = existProductMap.get(oldProduct.getId());
            this.checkProductParams(newProduct);

            if (ObjectUtil.notEqual(oldProduct.getBrandName(), newProduct.getBrandName())) {
                recordSb.append("原【品牌】: ")
                        .append(oldProduct.getBrandName())
                        .append(" 新【品牌】: ")
                        .append(newProduct.getBrandName())
                        .append(", ");

                oldProduct.setBrandId(newProduct.getBrandId())
                        .setBrandName(newProduct.getBrandName());
            }

            if (ObjectUtil.notEqual(oldProduct.getMainName(), newProduct.getMainName())) {
                recordSb.append("原【产品大类】: ")
                        .append(oldProduct.getMainName())
                        .append(" 新【产品大类】: ")
                        .append(newProduct.getMainName())
                        .append(", ");

                oldProduct.setMainId(newProduct.getMainId())
                        .setMainName(newProduct.getMainName());
            }

            if (ObjectUtil.notEqual(oldProduct.getSmallName(), newProduct.getSmallName())) {
                recordSb.append("原【产品小类】: ")
                        .append(oldProduct.getSmallName())
                        .append(" 新【产品小类】: ")
                        .append(newProduct.getSmallName())
                        .append(", ");
                oldProduct.setSmallId(newProduct.getSmallId())
                        .setSmallName(newProduct.getSmallName())
                        .setSmallImg(newProduct.getSmallImg());
            }

            if (ObjectUtil.notEqual(oldProduct.getNum(), newProduct.getNum())) {
                recordSb.append("原【设备套数】: ")
                        .append(oldProduct.getNum())
                        .append(" 新【设备套数】: ")
                        .append(newProduct.getNum())
                        .append(", ");
                oldProduct.setNum(newProduct.getNum());
            }
            oldProduct.setProductId(newProduct.getProductId())
                    .setProductName(newProduct.getProductName())
                    .setSeriesId(newProduct.getSeriesId())
                    .setSeriesName(newProduct.getSeriesName())
                    .setOutNum(newProduct.getOutNum())
                    .setInNum(newProduct.getInNum())
                    .setProductUpdateTime(DateUtil.date())
                    .setProductUpdateBy(adminUser.getNickName());

            afterProductList.add(oldProduct);

            if (recordSb.length() > 0) {
                if (index == 0) {
                    sb.append(StrUtil.sub(oldProduct.getId(), 15, oldProduct.getId().length()))
                            .append("序号修改: ");
                }
                sb.append(recordSb);
            }
            index++;
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("项目设备")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }
    }

    private void checkProductParams(RpProjectRepairProduct newProduct) {
        if (StringUtils.isBlank(newProduct.getBrandId()) || StringUtils.isBlank(newProduct.getBrandName())) {
            throw new RemoteServiceException("品牌不能为空");
        }
        if (StringUtils.isBlank(newProduct.getMainId()) || StringUtils.isBlank(newProduct.getMainName())) {
            throw new RemoteServiceException("产品大类不能为空");
        }
        if (StringUtils.isBlank(newProduct.getSmallId()) || StringUtils.isBlank(newProduct.getSmallName())) {
            throw new RemoteServiceException("产品小类不能为空");
        }
        if (Objects.isNull(newProduct.getNum())) {
            throw new RemoteServiceException("设备套数不能为空");
        }
        if (StringUtils.isBlank(newProduct.getSmallImg())) {
            if (newProduct.getMainId().equals("0") || newProduct.getSmallId().equals("0")) {
                newProduct.setSmallImg(defaultImgUrl);
            } else {
                throw new RemoteServiceException("小类图片不能为空");
            }
        }
    }

    private void productAddOrDel(RpProjectRepair oldRepair, List<RpProjectRepairProduct> handleProductList,
                                 List<RpProjectRepairOperatorLog> operatorLogList, boolean direction,
                                 List<RpProjectRepairProduct> afterProductList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        sb.append(direction ? "添加 " : "删除 ");
        DateTime curDate = DateUtil.date();
        for (RpProjectRepairProduct product : handleProductList) {
            StringBuilder recordSb = new StringBuilder();
            if (direction) {
                this.checkProductParams(product);
                product.setProjectRepairId(oldRepair.getId())
                        .setProductCreateTime(curDate)
                        .setProductCreateBy(adminUser.getNickName())
                        .setProductUpdateTime(curDate)
                        .setProductUpdateBy(adminUser.getNickName());
                afterProductList.add(product);
            }

            if (!direction) {
                recordSb.append(StrUtil.sub(product.getId(), 15, product.getId().length()))
                        .append("序号: ");
            }

            recordSb.append("【品牌】: ")
                    .append(product.getBrandName())
                    .append(" 【产品大类】: ")
                    .append(product.getMainName())
                    .append(" 【产品小类】: ")
                    .append(product.getSmallName())
                    .append(" 【设备套数】: ")
                    .append(product.getNum())
                    .append(", ");

            sb.append(recordSb);
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();

            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("项目设备")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }

        if (!direction) {
            rpProjectRepairProductService.removeByIds(handleProductList.stream()
                    .map(RpProjectRepairProduct::getId)
                    .collect(Collectors.toList()));
        }
    }

    private List<RpProjectRepairBy> checkByList(ProjectRepairBean bean, RpProjectRepair oldRepair, List<RpProjectRepairOperatorLog> operatorLogList, AdminUserCom adminUser) {
        List<RpProjectRepairBy> afterByList = new ArrayList<>();
        // 人员检查
        List<RpProjectRepairBy> oldByList = rpProjectRepairByService.lambdaQuery()
                .eq(RpProjectRepairBy::getProjectRepairId, oldRepair.getId())
                .list();
        // 筛选出存在的人员记录
        List<RpProjectRepairBy> existByList = bean.getByList().stream()
                .filter(v -> StringUtils.isNotBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(existByList)) {
            // 记录id全空 删除
            this.byAddOrDel(oldRepair, oldByList, operatorLogList, false, afterByList, adminUser);
        } else {
            // 半删半改, 对比修改的设备记录
            Map<String, RpProjectRepairBy> existByMap = existByList.stream()
                    .collect(Collectors.toMap(RpProjectRepairBy::getId, Function.identity()));
            List<RpProjectRepairBy> updList = new ArrayList<>();
            List<RpProjectRepairBy> delList = new ArrayList<>();
            for (RpProjectRepairBy by : oldByList) {
                if (existByMap.containsKey(by.getId())) {
                    updList.add(by);
                } else {
                    delList.add(by);
                }
            }

            if (CollectionUtil.isNotEmpty(updList)) {
                // 修改记录
                this.byUpdate(oldRepair, updList, existByMap, operatorLogList, afterByList, adminUser);
            }

            if (CollectionUtil.isNotEmpty(delList)) {
                // 添加记录
                this.byAddOrDel(oldRepair, delList, operatorLogList, false, afterByList, adminUser);
            }
        }

        // 筛选出添加的设备记录
        List<RpProjectRepairBy> addByList = bean.getByList().stream()
                .filter(v -> StringUtils.isBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(addByList)) {
            // 添加记录
            this.byAddOrDel(oldRepair, addByList, operatorLogList, true, afterByList, adminUser);
        }

        long count = afterByList.stream().filter(v -> v.getFeeExamine().equals(IsYesNoEnum.YES.getKey())).count();
        if (count == 0) {
            throw new RemoteServiceException("项目人员必须有一个费用审批为\"是\"");
        }
        return afterByList;
    }

    private void byUpdate(RpProjectRepair oldRepair, List<RpProjectRepairBy> updList, Map<String, RpProjectRepairBy> existByMap,
                          List<RpProjectRepairOperatorLog> operatorLogList, List<RpProjectRepairBy> afterByList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        for (RpProjectRepairBy oldBy : updList) {
            RpProjectRepairBy newBy = existByMap.get(oldBy.getId());
            this.checkByParams(newBy);

            if (ObjectUtil.notEqual(oldBy.getName(), newBy.getName())) {
                sb.append("原姓名: ")
                        .append(oldBy.getName())
                        .append(" 新姓名: ")
                        .append(newBy.getName())
                        .append(", ");

                oldBy.setName(newBy.getName());
            }

            if (ObjectUtil.notEqual(oldBy.getMobile(), newBy.getMobile())) {
                sb.append("原联系电话: ")
                        .append(oldBy.getMobile())
                        .append(" 新联系电话: ")
                        .append(newBy.getMobile())
                        .append(", ");

                oldBy.setMobile(newBy.getMobile());
            }

            if (ObjectUtil.notEqual(oldBy.getFeeExamine(), newBy.getFeeExamine())) {
                sb.append("原费用审批: ")
                        .append(BaseEnum.keyToEnum(IsYesNoEnum.class, oldBy.getFeeExamine()).getRemark())
                        .append(" 新费用审批: ")
                        .append(BaseEnum.keyToEnum(IsYesNoEnum.class, newBy.getFeeExamine()).getRemark())
                        .append(", ");
                oldBy.setFeeExamine(newBy.getFeeExamine());
            }

            oldBy.setByUpdateTime(DateUtil.date())
                    .setByUpdateBy(adminUser.getNickName());
            afterByList.add(oldBy);
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("项目人员")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }
    }

    private void checkByParams(RpProjectRepairBy newBy) {
        if (StringUtils.isBlank(newBy.getName())) {
            throw new RemoteServiceException("姓名不能为空");
        }
        if (StringUtils.isBlank(newBy.getMobile())) {
            throw new RemoteServiceException("联系电话不能为空");
        }
        if (StringUtils.isBlank(newBy.getFeeExamine())) {
            throw new RemoteServiceException("费用审批不能为空");
        }
    }

    private void byAddOrDel(RpProjectRepair oldRepair, List<RpProjectRepairBy> handleByList,
                            List<RpProjectRepairOperatorLog> operatorLogList, boolean direction,
                            List<RpProjectRepairBy> afterByList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        sb.append(direction ? "添加 " : "删除 ");
        DateTime curDate = DateUtil.date();
        for (RpProjectRepairBy by : handleByList) {
            if (direction) {
                this.checkByParams(by);
                by.setProjectRepairId(oldRepair.getId())
                        .setByCreateTime(curDate)
                        .setByCreateBy(adminUser.getNickName())
                        .setByUpdateTime(curDate)
                        .setByUpdateBy(adminUser.getNickName());
                afterByList.add(by);
            }

            sb.append("【姓名】: ")
                    .append(by.getName())
                    .append(" 【联系电话】: ")
                    .append(by.getMobile())
                    .append(" 【费用审批】: ")
                    .append(BaseEnum.keyToEnum(IsYesNoEnum.class, by.getFeeExamine()).getRemark())
                    .append(", ");
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();

            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("项目人员")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }

        if (!direction) {
            rpProjectRepairByService.removeByIds(handleByList.stream()
                    .map(RpProjectRepairBy::getId)
                    .collect(Collectors.toList()));
        }
    }

    private List<RpProjectRepairWebsit> checkWebsitList(ProjectRepairBean bean, RpProjectRepair oldRepair, List<RpProjectRepairOperatorLog> operatorLogList, AdminUserCom adminUser) {
        List<RpProjectRepairWebsit> afterWebsitList = new ArrayList<>();
        // 人员检查
        List<RpProjectRepairWebsit> oldWebsitList = rpProjectRepairWebsitService.lambdaQuery()
                .eq(RpProjectRepairWebsit::getProjectRepairId, oldRepair.getId())
                .list();
        // 筛选出存在的人员记录
        List<RpProjectRepairWebsit> existWebsitList = bean.getWebsitList().stream()
                .filter(v -> StringUtils.isNotBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(existWebsitList)) {
            // 记录id全空 删除
            this.websitAddOrDel(oldRepair, oldWebsitList, operatorLogList, false, afterWebsitList, adminUser);
        } else {
            // 半删半改, 对比修改的设备记录
            Map<String, RpProjectRepairWebsit> existWebsitMap = existWebsitList.stream()
                    .collect(Collectors.toMap(RpProjectRepairWebsit::getId, Function.identity()));
            List<RpProjectRepairWebsit> updList = new ArrayList<>();
            List<RpProjectRepairWebsit> delList = new ArrayList<>();
            for (RpProjectRepairWebsit websit : oldWebsitList) {
                if (existWebsitMap.containsKey(websit.getId())) {
                    updList.add(websit);
                } else {
                    delList.add(websit);
                }
            }

            if (CollectionUtil.isNotEmpty(updList)) {
                // 修改记录
                this.websitUpdate(oldRepair, updList, existWebsitMap, operatorLogList, afterWebsitList, adminUser);
            }

            if (CollectionUtil.isNotEmpty(delList)) {
                // 添加记录
                this.websitAddOrDel(oldRepair, delList, operatorLogList, false, afterWebsitList, adminUser);
            }
        }

        // 筛选出添加的设备记录
        List<RpProjectRepairWebsit> addWebsList = bean.getWebsitList().stream()
                .filter(v -> StringUtils.isBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(addWebsList)) {
            // 添加记录
            this.websitAddOrDel(oldRepair, addWebsList, operatorLogList, true, afterWebsitList, adminUser);
        }

        return afterWebsitList;
    }

    private void websitUpdate(RpProjectRepair oldRepair, List<RpProjectRepairWebsit> updList, Map<String, RpProjectRepairWebsit> existWebsitMap, List<RpProjectRepairOperatorLog> operatorLogList, List<RpProjectRepairWebsit> afterWebsitList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        for (RpProjectRepairWebsit oldWebsit : updList) {
            RpProjectRepairWebsit newWebsit = existWebsitMap.get(oldWebsit.getId());
            this.checkWebsitParams(newWebsit);

            if (ObjectUtil.notEqual(oldWebsit.getWebsitName(), newWebsit.getWebsitName())) {
                sb.append("原网点名称: ")
                        .append(oldWebsit.getWebsitName())
                        .append(" 新网点名称: ")
                        .append(newWebsit.getWebsitName())
                        .append(", ");

                oldWebsit.setWebsitName(newWebsit.getWebsitName());
            }

            oldWebsit.setLinkName(newWebsit.getLinkName())
                    .setMobile(newWebsit.getMobile())
                    .setAddress(newWebsit.getAddress())
                    .setWebsitUpdateTime(DateUtil.date())
                    .setWebsitUpdateBy(adminUser.getNickName());
            afterWebsitList.add(oldWebsit);
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("服务网点")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }
    }

    private void checkWebsitParams(RpProjectRepairWebsit newWebsit) {
        if (StringUtils.isBlank(newWebsit.getWebsitId()) || StringUtils.isBlank(newWebsit.getWebsitName())) {
            throw new RemoteServiceException("网点名称不能为空");
        }
    }

    private List<RpProjectRepairItem> checkItemList(ProjectRepairBean bean, RpProjectRepair oldRepair, List<RpProjectRepairOperatorLog> operatorLogList, AdminUserCom adminUser) {
        List<RpProjectRepairItem> afterProductList = new ArrayList<>();
        // 设备检查
        List<RpProjectRepairItem> oldProductList = rpProjectRepairItemService.lambdaQuery()
                .eq(RpProjectRepairItem::getProjectRepairId, oldRepair.getId())
                .list();
        // 筛选出存在的商品记录
        List<RpProjectRepairItem> existProductList = bean.getItemList().stream()
                .filter(v -> StringUtils.isNotBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(existProductList)) {
            // 记录id全空 全删除
            this.itemAddOrDel(oldRepair, oldProductList, operatorLogList, false, afterProductList, adminUser);
        } else {
            // 半删半改, 对比修改的设备记录
            Map<String, RpProjectRepairItem> existProductMap = existProductList.stream()
                    .collect(Collectors.toMap(RpProjectRepairItem::getId, Function.identity()));
            List<RpProjectRepairItem> updList = new ArrayList<>();
            List<RpProjectRepairItem> delList = new ArrayList<>();
            for (RpProjectRepairItem product : oldProductList) {
                if (existProductMap.containsKey(product.getId())) {
                    updList.add(product);
                } else {
                    delList.add(product);
                }
            }

            if (CollectionUtil.isNotEmpty(updList)) {
                // 修改记录
                this.itemUpdate(oldRepair, updList, existProductMap, operatorLogList, afterProductList, adminUser);
            }

            if (CollectionUtil.isNotEmpty(delList)) {
                // 添加记录
                this.itemAddOrDel(oldRepair, delList, operatorLogList, false, afterProductList, adminUser);
            }
        }

        // 筛选出添加的设备记录
        List<RpProjectRepairItem> addProductList = bean.getItemList().stream()
                .filter(v -> StringUtils.isBlank(v.getId()))
                .collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(addProductList)) {
            // 添加记录
            this.itemAddOrDel(oldRepair, addProductList, operatorLogList, true, afterProductList, adminUser);
        }

        return afterProductList;
    }

    private void itemUpdate(RpProjectRepair oldRepair, List<RpProjectRepairItem> updList, Map<String, RpProjectRepairItem> existProductMap,
                            List<RpProjectRepairOperatorLog> operatorLogList, List<RpProjectRepairItem> afterProductList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        int index = 0;
        for (RpProjectRepairItem oldProduct : updList) {
            StringBuilder recordSb = new StringBuilder();
            RpProjectRepairItem newProduct = existProductMap.get(oldProduct.getId());
            this.checkItemParams(newProduct);

            if (oldProduct.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey())) {
                if (ObjectUtil.notEqual(oldProduct.getParentCategoryName(), newProduct.getParentCategoryName())) {
                    recordSb.append("原【大类】: ")
                            .append(oldProduct.getParentCategoryName())
                            .append(" 新【大类】: ")
                            .append(newProduct.getParentCategoryName())
                            .append(", ");

                    oldProduct.setParentCategoryId(newProduct.getParentCategoryId())
                            .setParentCategoryName(newProduct.getParentCategoryName());
                }

                if (ObjectUtil.notEqual(oldProduct.getGoodsCategoryName(), newProduct.getGoodsCategoryName())) {
                    recordSb.append("原【小类】: ")
                            .append(oldProduct.getGoodsCategoryName())
                            .append(" 新【小类】: ")
                            .append(newProduct.getGoodsCategoryName())
                            .append(", ");
                    oldProduct.setGoodsCategoryId(newProduct.getGoodsCategoryId())
                            .setGoodsCategoryName(newProduct.getGoodsCategoryName());
                }

                if (ObjectUtil.notEqual(oldProduct.getGoodsName(), newProduct.getGoodsName())) {
                    recordSb.append("原【辅材名称】: ")
                            .append(oldProduct.getGoodsName())
                            .append(" 新【辅材名称】: ")
                            .append(newProduct.getGoodsName())
                            .append(", ");

                    oldProduct.setGoodsId(newProduct.getGoodsId())
                            .setGoodsName(newProduct.getGoodsName());
                }
            } else {
                if (ObjectUtil.notEqual(oldProduct.getBrandRelaName(), newProduct.getBrandRelaName())) {
                    recordSb.append("原【适用品牌】: ")
                            .append(oldProduct.getBrandRelaName())
                            .append(" 新【适用品牌】: ")
                            .append(newProduct.getBrandRelaName())
                            .append(", ");

                    oldProduct.setBrandRelaId(newProduct.getBrandRelaId())
                            .setBrandRelaName(newProduct.getBrandRelaName());
                }

                if (ObjectUtil.notEqual(oldProduct.getProductRelaName(), newProduct.getProductRelaName())) {
                    recordSb.append("原【适用产品大类】: ")
                            .append(oldProduct.getProductRelaName())
                            .append(" 新【适用产品大类】: ")
                            .append(newProduct.getProductRelaName())
                            .append(", ");

                    oldProduct.setProductRelaId(newProduct.getProductRelaId())
                            .setProductRelaName(newProduct.getProductRelaName());
                }

                if (ObjectUtil.notEqual(oldProduct.getGoodsName(), newProduct.getGoodsName())) {
                    recordSb.append("原【配件名称】: ")
                            .append(oldProduct.getGoodsName())
                            .append(" 新【配件名称】: ")
                            .append(newProduct.getGoodsName())
                            .append(", ");
                    oldProduct.setGoodsId(newProduct.getGoodsId())
                            .setGoodsName(newProduct.getGoodsName());
                }
            }

            if (ObjectUtil.notEqual(oldProduct.getNormAmount(), newProduct.getNormAmount())) {
                recordSb.append("原【收费标准】: ")
                        .append(oldProduct.getNormAmount())
                        .append(" 新【收费标准】: ")
                        .append(newProduct.getNormAmount())
                        .append(", ");
                oldProduct.setNormAmount(newProduct.getNormAmount());
            }

//            if (ObjectUtil.notEqual(oldProduct.getWorkerAmount(), newProduct.getWorkerAmount())) {
//                recordSb.append("原【师傅分账金额】: ")
//                        .append(oldProduct.getWorkerAmount())
//                        .append(" 新【师傅分账金额】: ")
//                        .append(newProduct.getWorkerAmount())
//                        .append(", ");
//                oldProduct.setWorkerAmount(newProduct.getWorkerAmount());
//            }
//
//            newProduct.setWebsitAmount(newProduct.getNormAmount().subtract(newProduct.getWorkerAmount()));
//            if (ObjectUtil.notEqual(oldProduct.getWebsitAmount(), newProduct.getWebsitAmount())) {
//                recordSb.append("原【商户分账金额】: ")
//                        .append(oldProduct.getWebsitAmount())
//                        .append(" 新【商户分账金额】: ")
//                        .append(newProduct.getWebsitAmount())
//                        .append(", ");
//                oldProduct.setWebsitAmount(newProduct.getWebsitAmount());
//            }
            oldProduct.setGoodsId(newProduct.getGoodsId())
                    .setGoodsName(newProduct.getGoodsName())
                    .setGoodsCode(newProduct.getGoodsCode())
                    .setGoodsBarcodeId(newProduct.getGoodsBarcodeId())
                    .setNormType(newProduct.getNormType())
                    .setGoodsSpecification(newProduct.getGoodsSpecification())
                    .setGoodsStockUnit(newProduct.getGoodsStockUnit())
                    .setProductUpdateTime(DateUtil.date())
                    .setProductUpdateBy(adminUser.getNickName());

            afterProductList.add(oldProduct);

            if (recordSb.length() > 0) {
                if (index == 0) {
                    sb.append(StrUtil.sub(oldProduct.getId(), 15, oldProduct.getId().length()))
                            .append("序号修改: ");
                }
                sb.append(recordSb);
            }
            index++;
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("配置明细")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }
    }

    private void itemAddOrDel(RpProjectRepair oldRepair, List<RpProjectRepairItem> handleProductList,
                              List<RpProjectRepairOperatorLog> operatorLogList, boolean direction,
                              List<RpProjectRepairItem> afterProductList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        sb.append(direction ? "添加 " : "删除 ");
        DateTime curDate = DateUtil.date();
        for (RpProjectRepairItem product : handleProductList) {
            StringBuilder recordSb = new StringBuilder();
            if (direction) {
                this.checkItemParams(product);
                product.setProjectRepairId(oldRepair.getId())
                        .setProductCreateTime(curDate)
                        .setProductCreateBy(adminUser.getNickName())
                        .setProductUpdateTime(curDate)
                        .setProductUpdateBy(adminUser.getNickName());
                afterProductList.add(product);
            }

            if (!direction) {
                recordSb.append(StrUtil.sub(product.getId(), 15, product.getId().length()))
                        .append("序号: ");
            }

            if (product.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey())) {
                recordSb.append(" 【大类】: ")
                        .append(product.getParentCategoryName())
                        .append(" 【小类】: ")
                        .append(product.getGoodsCategoryName())
                        .append("【辅材名称】: ")
                        .append(product.getGoodsName());
            } else {
                recordSb.append(" 【适用品牌】: ")
                        .append(product.getBrandRelaName())
                        .append(" 【适用产品大类】: ")
                        .append(product.getProductRelaName())
                        .append("【配件名称】: ")
                        .append(product.getGoodsName());
            }

            recordSb.append(" 【收费标准】: ")
                    .append(product.getNormAmount())
//                    .append(" 【师傅分账金额】: ")
//                    .append(product.getWorkerAmount())
//                    .append(" 【商户分账金额】: ")
//                    .append(product.getWebsitAmount())
                    .append(", ");

            sb.append(recordSb);
        }

        if (sb.length() > 0 && sb.lastIndexOf(", ") > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();

            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("配置明细")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }

        if (!direction) {
            rpProjectRepairItemService.removeByIds(handleProductList.stream()
                    .map(RpProjectRepairItem::getId)
                    .collect(Collectors.toList()));
        }
    }

    private void checkItemParams(RpProjectRepairItem item) {
        if (StringUtils.isBlank(item.getGoodsType())) {
            throw new RemoteServiceException("商品类型不能为空");
        }
        WebsitGoodsTypeEnum typeEnum = BaseEnum.keyToEnumNotNull(WebsitGoodsTypeEnum.class, item.getGoodsType());

        if (StringUtils.isBlank(item.getGoodsId()) || StringUtils.isBlank(item.getGoodsName())) {
            throw new RemoteServiceException(typeEnum.getRemark() + "名称不能为空");
        }

        if (Objects.isNull(item.getNormAmount()) || item.getNormAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new RemoteServiceException(typeEnum.getRemark() + "收费标准请输入有效数字");
        }

//        if (Objects.isNull(item.getWorkerAmount())
//                || item.getWorkerAmount().compareTo(BigDecimal.ZERO) < 0
//                || item.getNormAmount().subtract(item.getWorkerAmount()).compareTo(BigDecimal.ZERO) < 0) {
//            throw new RemoteServiceException(typeEnum.getRemark() + "师傅分账金额请输入有效数字");
//        }
    }

    private void websitAddOrDel(RpProjectRepair oldRepair, List<RpProjectRepairWebsit> handleWebsitList,
                                List<RpProjectRepairOperatorLog> operatorLogList, boolean direction,
                                List<RpProjectRepairWebsit> afterWebsitList, AdminUserCom adminUser) {
        StringBuilder sb = new StringBuilder();
        sb.append(direction ? "添加 " : "删除 ");
        DateTime curDate = DateUtil.date();
        for (RpProjectRepairWebsit websit : handleWebsitList) {
            if (direction) {
                this.checkWebsitParams(websit);
                websit.setProjectRepairId(oldRepair.getId())
                        .setWebsitCreateTime(curDate)
                        .setWebsitCreateBy(adminUser.getNickName())
                        .setWebsitUpdateTime(curDate)
                        .setWebsitUpdateBy(adminUser.getNickName());
                afterWebsitList.add(websit);
            }

            sb.append("【网点名称】: ")
                    .append(websit.getWebsitName())
                    .append(", ");
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();

            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldRepair.getId())
                    .setTypeText("服务网点")
                    .setContent(updStr);

            operatorLogList.add(operatorLog);
        }

        if (!direction) {
            rpProjectRepairWebsitService.removeByIds(handleWebsitList.stream()
                    .map(RpProjectRepairWebsit::getId)
                    .collect(Collectors.toList()));
        }
    }

    @Transactional
    public void productSave(RpProjectRepairProduct product, AdminUserCom adminUser) throws Exception {
        this.checkProductParams(product);

        if (StringUtils.isBlank(product.getId())) {
            // 添加记录
            DateTime curDate = DateUtil.date();
            product.setProductCreateTime(curDate)
                    .setProductCreateBy(adminUser.getNickName())
                    .setProductUpdateTime(curDate)
                    .setProductUpdateBy(adminUser.getNickName())
                    .insert();
        } else {
            // 编辑
            this.compareProductParams(product);
        }

    }

    private void compareProductParams(RpProjectRepairProduct product) {
        StringBuilder sb = new StringBuilder();
        List<RpProjectRepairProduct> products = rpProjectRepairProductService.lambdaQuery()
                .eq(RpProjectRepairProduct::getProjectRepairId, product.getProjectRepairId())
                .list();

        int idx = 0;
        RpProjectRepairProduct oldProduct = null;
        for (int i = 0; i < products.size(); i++) {
            if (products.get(i).getId().equals(product.getId())) {
                idx = i + 1;
                oldProduct = products.get(i);
            }
        }

        if (Objects.isNull(oldProduct)) {
            throw new RemoteServiceException("项目设备记录不存在");
        }

        if (ObjectUtil.notEqual(product.getBrandName(), oldProduct.getBrandName())) {
            sb.append("第").append(idx).append("行原品牌: ")
                    .append(oldProduct.getBrandName())
                    .append(" 新品牌: ")
                    .append(product.getBrandName())
                    .append(", ");

            oldProduct.setBrandId(product.getBrandId())
                    .setBrandName(product.getBrandName());
        }

        if (ObjectUtil.notEqual(product.getMainName(), oldProduct.getMainName())) {
            sb.append("第").append(idx).append("行原产品大类: ")
                    .append(oldProduct.getMainName())
                    .append(" 新产品大类: ")
                    .append(product.getMainName())
                    .append(", ");

            oldProduct.setMainId(product.getMainId())
                    .setMainName(product.getMainName());
        }

        if (ObjectUtil.notEqual(product.getSmallName(), oldProduct.getSmallName())) {
            sb.append("第").append(idx).append("行原产品小类: ")
                    .append(oldProduct.getSmallName())
                    .append(" 新产品小类: ")
                    .append(product.getSmallName())
                    .append(", ");
            oldProduct.setSmallId(product.getSmallId())
                    .setSmallName(product.getSmallName());
        }

        if (ObjectUtil.notEqual(product.getNum(), oldProduct.getNum())) {
            sb.append("第").append(idx).append("行原设备套数: ")
                    .append(oldProduct.getNum())
                    .append(" 新设备套数: ")
                    .append(product.getNum())
                    .append(", ");
            oldProduct.setNum(product.getNum());
        }
        oldProduct.setProductId(product.getProductId())
                .setProductName(product.getProductName())
                .setSeriesId(product.getSeriesId())
                .setSeriesName(product.getSeriesName())
                .setOutNum(product.getOutNum())
                .setInNum(product.getInNum());

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldProduct.getProjectRepairId())
                    .setTypeText("项目设备")
                    .setContent(updStr)
                    .insert();
        }

        oldProduct.updateById();
    }

//    @Transactional
//    public void productDel(String projectRepairId, String id) {
//        RpProjectRepairProduct oldProduct = rpProjectRepairProductService.lambdaQuery()
//                .eq(RpProjectRepairProduct::getProjectRepairId, projectRepairId)
//                .eq(RpProjectRepairProduct::getId, id)
//                .one();
//
//        RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
//        operatorLog.setProjectRepairId(oldProduct.getProjectRepairId())
//                .setTypeText("项目设备")
//                .setContent("删除 【品牌】: " + oldProduct.getBrandName()
//                        + " 【产品大类】: " + oldProduct.getMainName()
//                        + " 【产品小类】: " + oldProduct.getSmallName()
//                        + " 【设备套数】: " + oldProduct.getNum())
//                .insert();
//
//        oldProduct.deleteById();
//    }

    @Transactional
    public void bySave(RpProjectRepairBy by, AdminUserCom adminUser) throws Exception {
        this.checkByParams(by);

        if (StringUtils.isBlank(by.getId())) {
            // 添加记录
            DateTime curDate = DateUtil.date();
            by.setByCreateTime(curDate)
                    .setByCreateBy(adminUser.getNickName())
                    .setByUpdateTime(curDate)
                    .setByUpdateBy(adminUser.getNickName())
                    .insert();
        } else {
            // 编辑
            this.compareByParams(by);
        }
    }

    private void compareByParams(RpProjectRepairBy by) {
        StringBuilder sb = new StringBuilder();
        List<RpProjectRepairBy> byList = rpProjectRepairByService.lambdaQuery()
                .eq(RpProjectRepairBy::getProjectRepairId, by.getProjectRepairId())
                .list();

        int idx = 0;
        RpProjectRepairBy oldBy = null;
        for (int i = 0; i < byList.size(); i++) {
            if (byList.get(i).getId().equals(by.getId())) {
                idx = i + 1;
                oldBy = byList.get(i);
            }
        }

        if (Objects.isNull(oldBy)) {
            throw new RemoteServiceException("项目人员记录不存在");
        }

        if (ObjectUtil.notEqual(by.getName(), oldBy.getName())) {
            sb.append("第").append(idx).append("行原姓名: ")
                    .append(oldBy.getName())
                    .append(" 新姓名: ")
                    .append(by.getName())
                    .append(", ");

            oldBy.setName(by.getName());
        }

        if (ObjectUtil.notEqual(by.getMobile(), oldBy.getMobile())) {
            sb.append("第").append(idx).append("行原联系电话: ")
                    .append(oldBy.getMobile())
                    .append(" 新联系电话: ")
                    .append(by.getMobile())
                    .append(", ");

            oldBy.setMobile(by.getMobile());
        }

        if (ObjectUtil.notEqual(by.getFeeExamine(), oldBy.getFeeExamine())) {
            sb.append("第").append(idx).append("行原费用审批: ")
                    .append(BaseEnum.keyToEnum(IsYesNoEnum.class, oldBy.getFeeExamine()).getRemark())
                    .append(" 新费用审批: ")
                    .append(BaseEnum.keyToEnum(IsYesNoEnum.class, by.getFeeExamine()).getRemark())
                    .append(", ");
            oldBy.setFeeExamine(by.getFeeExamine());
        }

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldBy.getProjectRepairId())
                    .setTypeText("项目人员")
                    .setContent(updStr)
                    .insert();
        }

        oldBy.updateById();
    }

//    @Transactional
//    public void byDel(String projectRepairId, String id) {
//        RpProjectRepairBy oldBy = rpProjectRepairByService.lambdaQuery()
//                .eq(RpProjectRepairBy::getProjectRepairId, projectRepairId)
//                .eq(RpProjectRepairBy::getId, id)
//                .one();
//
//        RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
//        operatorLog.setProjectRepairId(oldBy.getProjectRepairId())
//                .setTypeText("项目人员")
//                .setContent("删除 【姓名】: " + oldBy.getName()
//                        + " 【联系电话】: " + oldBy.getMobile()
//                        + " 【费用审批】: " + BaseEnum.keyToEnum(IsYesNoEnum.class, oldBy.getFeeExamine()).getRemark())
//                .insert();
//
//        oldBy.deleteById();
//    }

    @Transactional
    public RpProjectRepairWebsit websitSave(RpProjectRepairWebsit websit, AdminUserCom adminUser) throws Exception {
        this.checkWebsitParams(websit);

        if (StringUtils.isBlank(websit.getId())) {
            // 添加记录
            DateTime curDate = DateUtil.date();
            websit.setWebsitCreateTime(curDate)
                    .setWebsitCreateBy(adminUser.getNickName())
                    .setWebsitUpdateTime(curDate)
                    .setWebsitUpdateBy(adminUser.getNickName())
                    .insert();
        } else {
            // 编辑
            this.compareWebsitParams(websit);
        }
        return websit;
    }

    @Transactional
    public RpProjectRepairItem itemSave(RpProjectRepairItem item, AdminUserCom adminUser) {
        this.checkItemParams(item);

        if (StringUtils.isBlank(item.getId())) {
            // 添加记录
            DateTime curDate = DateUtil.date();
            item.setProductCreateTime(curDate)
                    .setProductCreateBy(adminUser.getNickName())
                    .setProductUpdateTime(curDate)
                    .setProductUpdateBy(adminUser.getNickName())
                    .insert();
        } else {
            // 编辑
            this.compareItemParams(item);
        }
        return item;
    }

    private void compareItemParams(RpProjectRepairItem item) {
//        StringBuilder sb = new StringBuilder();
//        List<RpProjectRepairItem> itemList = rpProjectRepairItemService.lambdaQuery()
//                .eq(RpProjectRepairItem::getProjectRepairId, item.getProjectRepairId())
//                .list();
//
//        int idx = 0;
//        RpProjectRepairItem oldItem = null;
//        for (int i = 0; i < itemList.size(); i++) {
//            if (itemList.get(i).getId().equals(item.getId())) {
//                idx = i + 1;
//                oldItem = itemList.get(i);
//            }
//        }
//
//        WebsitGoodsTypeEnum typeEnum = BaseEnum.keyToEnumNotNull(WebsitGoodsTypeEnum.class, item.getGoodsType());
//        if (Objects.isNull(oldItem)) {
//            throw new RemoteServiceException(typeEnum.getRemark() + "配置记录不存在");
//        }
//
//        if (ObjectUtil.notEqual(item.getWebsitName(), oldItem.getWebsitName())) {
//            sb.append("第").append(idx).append("行原网点名称: ")
//                    .append(oldItem.getWebsitName())
//                    .append(" 新网点名称: ")
//                    .append(item.getWebsitName())
//                    .append(", ");
//
//            oldItem.setWebsitName(item.getWebsitName());
//        }
//        oldItem.setLinkName(item.getLinkName())
//                .setMobile(item.getMobile())
//                .setAddress(item.getAddress());
//
//        if (sb.length() > 0) {
//            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
//            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
//            operatorLog.setProjectRepairId(oldItem.getProjectRepairId())
//                    .setTypeText("项目人员")
//                    .setContent(updStr)
//                    .insert();
//        }
//
//        oldItem.updateById();
    }

    private void compareWebsitParams(RpProjectRepairWebsit websit) {
        StringBuilder sb = new StringBuilder();
        List<RpProjectRepairWebsit> websitList = rpProjectRepairWebsitService.lambdaQuery()
                .eq(RpProjectRepairWebsit::getProjectRepairId, websit.getProjectRepairId())
                .list();

        int idx = 0;
        RpProjectRepairWebsit oldWebsit = null;
        for (int i = 0; i < websitList.size(); i++) {
            if (websitList.get(i).getId().equals(websit.getId())) {
                idx = i + 1;
                oldWebsit = websitList.get(i);
            }
        }

        if (Objects.isNull(oldWebsit)) {
            throw new RemoteServiceException("服务网点记录不存在");
        }

        if (ObjectUtil.notEqual(websit.getWebsitName(), oldWebsit.getWebsitName())) {
            sb.append("第").append(idx).append("行原网点名称: ")
                    .append(oldWebsit.getWebsitName())
                    .append(" 新网点名称: ")
                    .append(websit.getWebsitName())
                    .append(", ");

            oldWebsit.setWebsitName(websit.getWebsitName());
        }
        oldWebsit.setLinkName(websit.getLinkName())
                .setMobile(websit.getMobile())
                .setAddress(websit.getAddress());

        if (sb.length() > 0) {
            String updStr = sb.deleteCharAt(sb.lastIndexOf(", ")).toString();
            RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
            operatorLog.setProjectRepairId(oldWebsit.getProjectRepairId())
                    .setTypeText("项目人员")
                    .setContent(updStr)
                    .insert();
        }

        oldWebsit.updateById();
    }

//    @Transactional
//    public void websitDel(String projectRepairId, String id) {
//        RpProjectRepairWebsit oldWebsit = rpProjectRepairWebsitService.lambdaQuery()
//                .eq(RpProjectRepairWebsit::getProjectRepairId, projectRepairId)
//                .eq(RpProjectRepairWebsit::getId, id)
//                .one();
//
//        RpProjectRepairOperatorLog operatorLog = new RpProjectRepairOperatorLog();
//        operatorLog.setProjectRepairId(oldWebsit.getProjectRepairId())
//                .setTypeText("服务网点")
//                .setContent("删除 【网点名称】: " + oldWebsit.getWebsitName())
//                .insert();
//
//        oldWebsit.deleteById();
//    }


    /**
     * 工程维保-去重后的品牌
     * @param projectRepairId
     * @return
     */
    public List<RpProjectRepairProduct> brand(String projectRepairId){
        List<RpProjectRepairProduct> list = rpProjectRepairProductService.lambdaQuery()
                .select(RpProjectRepairProduct::getBrandId,RpProjectRepairProduct::getBrandName)
                .eq(RpProjectRepairProduct::getProjectRepairId, projectRepairId)
                .list().stream().distinct().collect(Collectors.toList());
        return list;
    }

    /**
     * 工程维保-去重后的产品大类
     * @param projectRepairId
     * @return
     */
    public List<RpProjectRepairProduct> main(String projectRepairId,String brandId){
        List<RpProjectRepairProduct> list = rpProjectRepairProductService.lambdaQuery()
                .select(RpProjectRepairProduct::getMainId, RpProjectRepairProduct::getMainName)
                .eq(RpProjectRepairProduct::getProjectRepairId, projectRepairId)
                .eq(StringUtils.isNotBlank(brandId),RpProjectRepairProduct::getBrandId, brandId)
                .list().stream().distinct().collect(Collectors.toList());
        return list;
    }

    /**
     * 工程维保-去重后的产品小类
     * @param projectRepairId
     * @return
     */
    public List<RpProjectRepairProduct> small(String projectRepairId,String brandId,String mainId){
        List<RpProjectRepairProduct> list = rpProjectRepairProductService.lambdaQuery()
                .select(RpProjectRepairProduct::getSmallId, RpProjectRepairProduct::getSmallName)
                .eq(RpProjectRepairProduct::getProjectRepairId, projectRepairId)
                .eq(StringUtils.isNotBlank(brandId),RpProjectRepairProduct::getBrandId, brandId)
                .eq(StringUtils.isNotBlank(mainId),RpProjectRepairProduct::getMainId,mainId)
                .list().stream().distinct().collect(Collectors.toList());
        return list;
    }





}
