package com.sckw.product.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sckw.contract.api.RemoteContractService;
import com.sckw.contract.api.model.vo.TradeContractGoodsDto;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.exception.CustomPromptException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.ClientTypeEnum;
import com.sckw.core.model.enums.EntTypeEnum;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.model.vo.TableBottom;
import com.sckw.core.model.vo.TableStatisticRes;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.*;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.excel.utils.DateUtil;
import com.sckw.fleet.api.RemoteFleetService;
import com.sckw.fleet.api.model.vo.TmsTruckAxleNumVO;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.order.api.model.OrderSaleVo;
import com.sckw.payment.api.dubbo.PayCenterDubboService;
import com.sckw.payment.api.model.constant.ChannelEnum;
import com.sckw.payment.api.model.dto.WalletDto;
import com.sckw.payment.api.model.dto.common.R;
import com.sckw.product.api.model.GoodsDetails;
import com.sckw.product.api.model.GoodsNumStsParam;
import com.sckw.product.dao.KwpGoodsMapper;
import com.sckw.product.dao.KwpGoodsViewLogMapper;
import com.sckw.product.enums.GoodsStatusEnum;
import com.sckw.product.model.*;
import com.sckw.product.model.vo.req.*;
import com.sckw.product.model.vo.res.*;
import com.sckw.product.repository.KwpGoodsRepository;
import com.sckw.redis.constant.RedisConstant;
import com.sckw.redis.utils.RedissonUtils;
import com.sckw.stream.enums.MessageEnum;
import com.sckw.stream.model.SckwMessage;
import com.sckw.stream.model.UserInfo;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.RemoteUserService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @desc: 商品service
 * @author: yzc
 * @date: 2023-06-25 14:47
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class KwpGoodsService {

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteUserService remoteUserService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private PayCenterDubboService payCenterDubboService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteFleetService remoteFleetService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private TradeOrderInfoService tradeOrderInfoService;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteContractService remoteContractService;


    private final KwpGoodsMapper kwpGoodsMapper;
    private final KwpGoodsViewLogMapper kwpGoodsViewLogMapper;
    private final KwpGoodsViewLogService kwpGoodsViewLogService;
    private final KwpGoodsAddressService kwpGoodsAddressService;
    private final KwpGoodsAttributeService kwpGoodsAttributeService;
    private final KwpGoodsImageService kwpGoodsImageService;
    private final KwpGoodsPriceRangeService kwpGoodsPriceRangeService;
    private final KwpGoodsUnitService kwpGoodsUnitService;
    private final StreamBridge streamBridge;
    private final KwpGoodsRepository kwpGoodsRepository;
    private final RedisTemplate<String, Object> redisTemplate;
    private final KwpSearchLogService kwpSearchLogService;
    @Value("${goods.url.list.pc}")
    private String pcGoodsListUrl;
    @Value("${goods.url.list.app}")
    private String appGoodsListUrl;


    /**
     * @desc: 添加草稿商品
     * @author: yzc
     * @date: 2023-07-03 9:30
     * @Param param:
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public void addDraft(AddGoodsDraftParam param) {
        if (nameDuplicationJudgment(param.getName(), param.getSupplyEntId(), null)) {
            throw new BusinessException("已存在相同商品名称！");
        }
        //添加商品信息
        KwpGoods goods = BeanUtils.copyProperties(param, KwpGoods.class);
        AddressInfo address = param.getAddressInfo();
        if (Objects.nonNull(address)) {
            goods.setAreaCode(address.getCityCode()).setAddressName(address.getName());
        }
        goods.setEntId(LoginUserHolder.getEntId()).setThumb(FileUtils.replaceAll(goods.getThumb())).setStatus(GoodsStatusEnum.SAVED.getCode());
        kwpGoodsMapper.insert(goods);
        //添加商品其他信息
        addGoodsOtherInfo(goods.getId(), BeanUtils.copyProperties(param, AddGoodsParam.class));
    }

    /**
     * @desc: 添加上架商品
     * @author: yzc
     * @date: 2023-07-03 9:30
     * @Param param:
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public void addShelves(AddGoodsParam param) {
//        if (nameDuplicationJudgment(param.getName(), param.getSupplyEntId(), null)) {
//            throw new BusinessException("已存在相同商品名称！");
//        }
        //添加商品信息
        KwpGoods goods = BeanUtils.copyProperties(param, KwpGoods.class);
        AddressInfo address = param.getAddressInfo();
        goods.setCode(param.getCode()).setAreaCode(address.getCityCode()).setAddressName(address.getName()).setThumb(goods.getThumb()).setEntId(LoginUserHolder.getEntId()).setAddedTime(new Date()).setPriceUnit("元").setStatus(GoodsStatusEnum.PUT_ON_SHELVES.getCode());
        kwpGoodsMapper.insert(goods);
        //添加商品其他信息
        addGoodsOtherInfo(goods.getId(), param);
    }

    /**
     * @desc: 添加商品其他信息
     * @author: yzc
     * @date: 2023-07-05 11:45
     * @Param goodsId:
     * @Param addGoodsParam:
     * @return: void
     */
    private void addGoodsOtherInfo(Long goodsId, AddGoodsParam addGoodsParam) {
        //添加商品地址信息
        KwpGoodsAddress address = BeanUtils.copyProperties(addGoodsParam.getAddressInfo(), KwpGoodsAddress.class);
        if (Objects.nonNull(address)) {
            address.setGoodsId(goodsId);
            kwpGoodsAddressService.insert(address);
        }
        //添加商品属性信息
        List<GoodsAttributes> attributes = addGoodsParam.getAttributes();
        if (CollectionUtils.isNotEmpty(attributes)) {
            List<KwpGoodsAttribute> list = new ArrayList<>(attributes.size());
            attributes.forEach(e -> {
                KwpGoodsAttribute attribute = BeanUtils.copyProperties(e, KwpGoodsAttribute.class);
                attribute.setGoodsId(goodsId);
                list.add(attribute);
            });
            kwpGoodsAttributeService.insertBatch(list);
        }
        //添加商品图片信息
        List<GoodsImages> images = addGoodsParam.getImages();
        if (CollectionUtils.isNotEmpty(images)) {
            List<KwpGoodsImage> list = new ArrayList<>(images.size());
            images.forEach(e -> {
                KwpGoodsImage image = BeanUtils.copyProperties(e, KwpGoodsImage.class);
                image.setImage(FileUtils.replaceAll(e.getImage()));
                image.setGoodsId(goodsId);
                list.add(image);
            });
            kwpGoodsImageService.insertBatch(list);
        }
        //添加商品价格
        BigDecimal price = addGoodsParam.getPrice();
        if (price != null) {
            KwpGoodsPriceRange priceRange = new KwpGoodsPriceRange();
            priceRange.setGoodsId(goodsId);
            priceRange.setPrice(price);
            kwpGoodsPriceRangeService.insertBatch(Lists.newArrayList(priceRange));
        }
        //添加商品辅助单位信息
        List<GoodsUnitParam> assistUnit = addGoodsParam.getAssistUnit();
        if (CollectionUtils.isNotEmpty(assistUnit)) {
            List<KwpGoodsUnit> units = new ArrayList<>(assistUnit.size());
            assistUnit.forEach(e -> {
                KwpGoodsUnit unit = BeanUtils.copyProperties(e, KwpGoodsUnit.class);
                unit.setGoodsId(goodsId);
                units.add(unit);
            });
            kwpGoodsUnitService.insertBatch(units);
        }
    }

    public GoodsDetailVo getDetail2(Long id, String keywords, Integer source, HttpServletRequest request) {
        KwpGoods goods = kwpGoodsMapper.selectById(id);
        if (Objects.isNull(goods)) {
            throw new BusinessException("当前商品不存在！");
        }
        GoodsDetailVo detail = BeanUtils.copyProperties(goods, GoodsDetailVo.class);
        GoodsEntInfo goodsEntInfo = new GoodsEntInfo();

        kwpGoodsViewLogService.saveLog(id, detail.getName(), detail.getGoodsType(), keywords, source, request);

        Map<Long, EntCacheResDto> entMap = remoteSystemService.queryEntCacheMapByIds(Arrays.asList(detail.getEntId(), goods.getSupplyEntId()));
//        EntCacheResDto ent = entMap.get(detail.getEntId());
//        if (Objects.nonNull(ent)) {
//            goodsEntInfo.setEnt(ent.getFirmName());
//            goodsEntInfo.setEntHead(ent.getHead());
//            goodsEntInfo.setEntBusiness(ent.getBusiness());
//            goodsEntInfo.setEntAddress(ent.getCityName());
//        }
        EntCacheResDto supplyEnt = entMap.get(goods.getSupplyEntId());
        if (Objects.nonNull(supplyEnt)) {
            goodsEntInfo.setEnt(supplyEnt.getFirmName());
            goodsEntInfo.setEntHead(supplyEnt.getHead());
            goodsEntInfo.setEntBusiness(supplyEnt.getBusiness());
            goodsEntInfo.setEntAddress(supplyEnt.getCityName() + (StrUtil.isNotEmpty(supplyEnt.getDetailAddress()) ? supplyEnt.getDetailAddress() : ""));
            goodsEntInfo.setContacts(supplyEnt.getLegalName());
            goodsEntInfo.setPhone(supplyEnt.getPhone());
            goodsEntInfo.setWebsite(supplyEnt.getWebsite());
        }
        UserCacheResDto managerInfo = remoteSystemService.queryUserCacheById(detail.getManager());
        if (Objects.nonNull(managerInfo)) {
            detail.setManagerName(managerInfo.getName());
        }
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.TAX_RATE.getType(), DictTypeEnum.GOODS_STATUS.getType(), DictTypeEnum.ADDRESS_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> productNameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> goodsStatusMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> addressMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> goodsMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        if (CollectionUtils.isNotEmpty(dict)) {
            productNameMap = dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType());
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            goodsStatusMap = dict.get(DictTypeEnum.GOODS_STATUS.getType());
            addressMap = dict.get(DictTypeEnum.ADDRESS_TYPE.getType());
            goodsMap = dict.get(DictTypeEnum.GOODS_SPEC.getType());
        }
        List<SysDictResDto> types = remoteSystemService.queryDictFrontAll(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), detail.getGoodsType());
        if (CollectionUtils.isNotEmpty(types)) {
            detail.setGoodsTypes(types.stream().map(SysDictResDto::getValue).toList()).setGoodsTypeLabels(String.join(Global.RIGHT_SLASH, types.stream().map(SysDictResDto::getLabel).toList()));
        }
        detail.setGoodsTypeLabel(CollectionUtils.isNotEmpty(productNameMap) ? productNameMap.get(detail.getGoodsType()) : null).setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(detail.getUnit()) : null).setSpec(CollectionUtils.isNotEmpty(goodsMap) ? goodsMap.get(detail.getSpec()) : null).setStatusLabel(CollectionUtils.isNotEmpty(goodsStatusMap) ? goodsStatusMap.get(String.valueOf(detail.getStatus())) : null);
        //商品图片信息
        if (Objects.nonNull(goods.getThumb())) {
            detail.setThumb(goods.getThumb());
        }
        List<KwpGoodsImage> goodsImages = kwpGoodsImageService.getByGoodsId(id);
        List<GoodsImagesDetail> images = BeanUtils.copyToList(goodsImages, GoodsImagesDetail.class);
        //商品价格
        List<KwpGoodsPriceRange> priceRanges = kwpGoodsPriceRangeService.getByGoodsId(id);
        BigDecimal price = Optional.ofNullable(priceRanges).filter(list -> !list.isEmpty()).map(list -> list.get(0)).map(KwpGoodsPriceRange::getPrice).orElse(null);

        //商品属性信息
        List<KwpGoodsAttribute> attributesList = kwpGoodsAttributeService.getByGoodsId(id);
        List<GoodsAttributesDetail> attributes = BeanUtils.copyToList(attributesList, GoodsAttributesDetail.class);
        //商品地址信息
        KwpGoodsAddress goodsAddress = kwpGoodsAddressService.getByGoodsId(id);
        AddressInfoDetail addressInfo = BeanUtils.copyProperties(goodsAddress, AddressInfoDetail.class);
        if (Objects.nonNull(addressInfo)) {
            addressInfo.setTypeName(CollectionUtils.isNotEmpty(addressMap) ? addressMap.get(addressInfo.getType()) : null);
        }
        detail.setImages(images).setPrice(price).setGoodsEntInfo(goodsEntInfo).setAttributes(attributes).setAddressInfo(addressInfo);
        Long entId = LoginUserHolder.getEntId();
        detail.setSignFlag(false);
        if (Objects.nonNull(entId)) {
            TradeContractGoodsDto tradeContractResDto = remoteContractService.queryTradeContractNew(entId, id, LocalDateTime.now());
            if (Objects.nonNull(tradeContractResDto)) {
                detail.setSignPrice(tradeContractResDto.getPrice());
                detail.setSignFlag(true);
            }
        }
        return detail;
    }

    /**
     * @desc: 获取商品详情
     * @author: yzc
     * @date: 2023-08-15 14:28
     * @Param id:
     * @return: com.sckw.product.model.vo.res.GoodsDetail
     */
    public GoodsDetail getDetail(Long id) {
        GoodsDetail detail = detail(id);
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getGoodsType, detail.getGoodsType()).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO).ne(KwpGoods::getId, id).last("LIMIT 4");
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return detail;
        }
        Map<String, String> unitMap;
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.UNIT_TYPE.getType()));
        if (CollectionUtils.isNotEmpty(dict)) {
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
        } else {
            unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }
        List<Long> goodsIds = list.stream().map(KwpGoods::getId).toList();
        Map<Long, List<KwpGoodsPriceRange>> map = kwpGoodsPriceRangeService.getByGoodsIds(goodsIds).stream().collect(Collectors.groupingBy(KwpGoodsPriceRange::getGoodsId));
        List<RecommendGoods> recommendGoodsList = new ArrayList<>();
        list.forEach(e -> {
            RecommendGoods recommendGoods = BeanUtils.copyProperties(e, RecommendGoods.class);
            List<KwpGoodsPriceRange> prices = map.get(recommendGoods.getId());
            recommendGoods.setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(recommendGoods.getUnit()) : null).setPrice(CollectionUtils.isNotEmpty(prices) ? prices.get(0).getPrice() : null).setThumb(FileUtils.splice(e.getThumb()));
            recommendGoodsList.add(recommendGoods);
        });
        detail.setRecommendGoodsList(recommendGoodsList);
        return detail;
    }

    /**
     * @desc: 获取商品详情
     * @author: yzc
     * @date: 2023-07-05 11:57
     * @Param id:
     * @return: com.sckw.product.model.vo.res.GoodsDetail
     */
    public GoodsDetail detail(Long id) {
        KwpGoods goods = kwpGoodsMapper.selectById(id);
        if (Objects.isNull(goods)) {
            throw new BusinessException("当前商品不存在！");
        }
        GoodsDetail detail = BeanUtils.copyProperties(goods, GoodsDetail.class);
        Map<Long, EntCacheResDto> entMap = remoteSystemService.queryEntCacheMapByIds(Arrays.asList(detail.getEntId(), detail.getSupplyEntId()));
        EntCacheResDto ent = entMap.get(detail.getEntId());
        if (Objects.nonNull(ent)) {
            detail.setEnt(ent.getFirmName()).setEntHead(ent.getHead()).setEntBusiness(ent.getBusiness()).setEntAddress(ent.getCityName());
        }
        EntCacheResDto supplyEnt = entMap.get(detail.getSupplyEntId());
        if (Objects.nonNull(supplyEnt)) {
            detail.setSupplyEnt(supplyEnt.getFirmName());
        }
        UserCacheResDto managerInfo = remoteSystemService.queryUserCacheById(detail.getManager());
        if (Objects.nonNull(managerInfo)) {
            detail.setManagerName(managerInfo.getName());
        }
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.TAX_RATE.getType(), DictTypeEnum.GOODS_STATUS.getType(), DictTypeEnum.ADDRESS_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> productNameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> goodsStatusMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> addressMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> goodsSpecMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        if (CollectionUtils.isNotEmpty(dict)) {
            productNameMap = dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType());
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            goodsStatusMap = dict.get(DictTypeEnum.GOODS_STATUS.getType());
            addressMap = dict.get(DictTypeEnum.ADDRESS_TYPE.getType());
            goodsSpecMap = dict.get(DictTypeEnum.GOODS_SPEC.getType());
        }
        List<SysDictResDto> types = remoteSystemService.queryDictFrontAll(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), detail.getGoodsType());
        if (CollectionUtils.isNotEmpty(types)) {
            detail.setGoodsTypes(types.stream().map(SysDictResDto::getValue).toList()).setGoodsTypeLabels(String.join(Global.RIGHT_SLASH, types.stream().map(SysDictResDto::getLabel).toList()));
        }
        detail.setGoodsTypeLabel(CollectionUtils.isNotEmpty(productNameMap) ? productNameMap.get(detail.getGoodsType()) : null).setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(detail.getUnit()) : null).setStatusLabel(CollectionUtils.isNotEmpty(goodsStatusMap) ? goodsStatusMap.get(String.valueOf(detail.getStatus())) : null).setSpecLabel(CollectionUtils.isNotEmpty(goodsSpecMap) ? goodsSpecMap.get(String.valueOf(detail.getSpec())) : null);
        //商品图片信息
        if (Objects.nonNull(goods.getThumb())) {
            detail.setThumb(goods.getThumb());
        }
        List<KwpGoodsImage> goodsImages = kwpGoodsImageService.getByGoodsId(id);
        List<GoodsImagesDetail> images = BeanUtils.copyToList(goodsImages, GoodsImagesDetail.class);
        //商品价格
        List<KwpGoodsPriceRange> priceRanges = kwpGoodsPriceRangeService.getByGoodsId(id);
        BigDecimal price = Optional.ofNullable(priceRanges).filter(list -> !list.isEmpty()).map(list -> list.get(0)).map(KwpGoodsPriceRange::getPrice).orElse(null);

        //商品属性信息
        List<KwpGoodsAttribute> attributesList = kwpGoodsAttributeService.getByGoodsId(id);
        List<GoodsAttributesDetail> attributes = BeanUtils.copyToList(attributesList, GoodsAttributesDetail.class);
        //商品地址信息
        KwpGoodsAddress goodsAddress = kwpGoodsAddressService.getByGoodsId(id);
        AddressInfoDetail addressInfo = BeanUtils.copyProperties(goodsAddress, AddressInfoDetail.class);
        if (Objects.nonNull(addressInfo)) {
            addressInfo.setTypeName(CollectionUtils.isNotEmpty(addressMap) ? addressMap.get(addressInfo.getType()) : null);
        }
        //商品辅助单位信息
        List<GoodsUnitDetail> assistUnit = kwpGoodsUnitService.findGoodsUnitDetail(id);
        if (CollectionUtils.isNotEmpty(assistUnit)) {
            //数据组装
            Map<String, String> finalUnitMap = unitMap;
            assistUnit.forEach(e -> {
                e.setFromUnitName(finalUnitMap != null ? finalUnitMap.get(e.getFromUnit()) : null);
                e.setToUnitName(finalUnitMap != null ? finalUnitMap.get(e.getToUnit()) : null);
            });
        }
        detail.setImages(images).setPrice(price).setAttributes(attributes).setAddressInfo(addressInfo).setAssistUnit(assistUnit);

        //轴数
        if (StringUtils.isNotBlank(goods.getCarAxis())) {
            detail.setCarAxis(goods.getCarAxis());
            List<String> axleNumStrId = Arrays.asList(goods.getCarAxis().split(","));
            List<Integer> axleNumIds = axleNumStrId.stream().map(str -> Integer.parseInt(str.trim())).collect(Collectors.toList());
            List<TmsTruckAxleNumVO> carAxisInfo = remoteFleetService.getCarAxisInfoList(axleNumIds);
            String carAxisName = carAxisInfo.stream().map(TmsTruckAxleNumVO::getName).collect(Collectors.joining(","));
            detail.setCarAxisName(carAxisName);
        }

        return detail;
    }


    /**
     * @desc: 更新商品信息
     * @author: yzc
     * @date: 2023-07-06 8:50
     * @Param param:
     * @return: void
     */
    public void update(UpdateGoodsParam param) {
//        if (Boolean.TRUE.equals(nameDuplicationJudgment(param.getName(), param.getSupplyEntId(), param.getId()))) {
//            throw new BusinessException("已存在相同商品名称！");
//        }
        KwpGoods goods = getGoodsById(param.getId());
        if (Objects.isNull(goods)) {
            throw new BusinessException("当前商品不存在！");
        }
        if (Objects.equals(goods.getStatus(), GoodsStatusEnum.PUT_ON_SHELVES.getCode()) || Objects.equals(goods.getStatus(), GoodsStatusEnum.TAKE_OFF_SHELVES.getCode())) {
            String msg = judgeParameters(param);
            if (StringUtils.isNotBlank(msg)) {
                throw new BusinessException(msg);
            }
        }
        AddressInfo address = param.getAddressInfo();
        Integer areaCode = Objects.isNull(address) ? null : address.getCityCode();
        String addressName = Objects.isNull(address) ? null : address.getName();
        LambdaUpdateWrapper<KwpGoods> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(KwpGoods::getName, param.getName()).set(KwpGoods::getGoodsType, param.getGoodsType()).set(KwpGoods::getUnit, param.getUnit()).set(KwpGoods::getSpec, param.getSpec()).set(KwpGoods::getCode, param.getCode()).set(KwpGoods::getCarAxis, param.getCarAxis()).set(KwpGoods::getContent, param.getContent()).set(KwpGoods::getSupplyEntId, param.getSupplyEntId()).set(KwpGoods::getRemark, param.getRemark()).set(KwpGoods::getThumb, param.getThumb()).set(KwpGoods::getAreaCode, areaCode).set(KwpGoods::getAddressName, addressName).eq(KwpGoods::getId, param.getId());
        kwpGoodsMapper.update(null, wrapper);
        updateGoodsOtherInfo(param);
    }

    /**
     * @desc: 更新商品其他信息
     * @author: yzc
     * @date: 2023-07-06 14:53
     * @Param param:
     * @return: void
     */
    private void updateGoodsOtherInfo(UpdateGoodsParam param) {
        Long goodsId = param.getId();
        //更新商品地址信息
        kwpGoodsAddressService.delByGoodsIds(Collections.singletonList(goodsId));
        if (Objects.nonNull(param.getAddressInfo())) {
            KwpGoodsAddress address = BeanUtils.copyProperties(param.getAddressInfo(), KwpGoodsAddress.class);
            address.setGoodsId(goodsId);
            kwpGoodsAddressService.insert(address);
        }

        //更新商品属性信息
        kwpGoodsAttributeService.delByGoodsIds(Collections.singletonList(goodsId));
        if (CollectionUtils.isNotEmpty(param.getAttributes())) {
            List<KwpGoodsAttribute> list = new ArrayList<>(param.getAttributes().size());
            param.getAttributes().forEach(e -> {
                KwpGoodsAttribute attribute = BeanUtils.copyProperties(e, KwpGoodsAttribute.class);
                attribute.setGoodsId(goodsId);
                list.add(attribute);
            });
            kwpGoodsAttributeService.insertBatch(list);
        }

        //更新商品图片信息
        kwpGoodsImageService.delByGoodsIds(Collections.singletonList(goodsId));
        if (CollectionUtils.isNotEmpty(param.getImages())) {
            List<KwpGoodsImage> list = new ArrayList<>(param.getImages().size());
            param.getImages().forEach(e -> {
                KwpGoodsImage image = BeanUtils.copyProperties(e, KwpGoodsImage.class);
                image.setGoodsId(goodsId).setImage(FileUtils.replaceAll(image.getImage()));
                list.add(image);
            });
            kwpGoodsImageService.insertBatch(list);
        }

        //更新商品价格梯度信息
        kwpGoodsPriceRangeService.delByGoodsIds(Collections.singletonList(goodsId));
        if (param.getPrice() != null) {
            KwpGoodsPriceRange priceRange = new KwpGoodsPriceRange();
            priceRange.setGoodsId(goodsId);
            priceRange.setPrice(param.getPrice());
            kwpGoodsPriceRangeService.insertBatch(Lists.newArrayList(priceRange));
        }

        //更新商品辅助单位信息
        kwpGoodsUnitService.delByGoodsIds(Collections.singletonList(goodsId));
        List<GoodsUnitParam> assistUnit = param.getAssistUnit();
        if (CollectionUtils.isNotEmpty(assistUnit)) {
            List<KwpGoodsUnit> units = new ArrayList<>(assistUnit.size());
            assistUnit.forEach(e -> {
                KwpGoodsUnit unit = BeanUtils.copyProperties(e, KwpGoodsUnit.class);
                unit.setGoodsId(goodsId);
                units.add(unit);
            });
            kwpGoodsUnitService.insertBatch(units);
        }
    }

    /**
     * @desc: 参数校验
     * @author: yzc
     * @date: 2023-07-06 14:33
     * @Param param:
     * @return: void
     */
    private String judgeParameters(UpdateGoodsParam param) {
        if (StringUtils.isBlank(param.getName())) {
            return "商品名称不能为空！";
        }
        if (StringUtils.isBlank(param.getGoodsType())) {
            return "商品类型不能为空！";
        }
        if (StringUtils.isBlank(param.getUnit())) {
            return "计量单位不能为空！";
        }

        List<GoodsAttributes> attributes = param.getAttributes();
        if (CollectionUtils.isNotEmpty(attributes)) {
            for (GoodsAttributes e : attributes) {
                if (StringUtils.isBlank(e.getName()) || StringUtils.isBlank(e.getVal())) {
                    return "参数名称或参数值不能为空！";
                }
            }
        }
        List<GoodsImages> images = param.getImages();
        if (CollectionUtils.isNotEmpty(images)) {
            for (GoodsImages e : images) {
                String imagePath = FileUtils.replaceAll(e.getImage());
                if (StringUtils.isBlank(imagePath)) {
                    return "商品图片地址不能为空！";
                }
                if (Objects.isNull(e.getSort())) {
                    return "商品图片排序不能为空！";
                }
            }
        }

        AddressInfo address = param.getAddressInfo();
        if (Objects.isNull(address)) {
            return "地址信息不能为空！";
        }
        if (StringUtils.isBlank(address.getName())) {
            return "地址名称不能为空";
        }
        if (StringUtils.isBlank(address.getType())) {
            return "地址类型不能为空！";
        }
        if (StringUtils.isBlank(address.getContacts())) {
            return "联系人不能为空！";
        }
        if (StringUtils.isBlank(address.getPhone())) {
            return "联系电话不能为空！";
        }
        if (Objects.isNull(address.getCityCode())) {
            return "所在地区code不能为空！";
        }
        if (StringUtils.isBlank(address.getCityName()) || address.getCityName().length() > 500) {
            return "所属区域名称不能为空最长50字符！";
        }
        if (Objects.isNull(address.getLat())) {
            return "纬度不能为空！";
        }
        if (Objects.isNull(address.getLng())) {
            return "经度不能为空！";
        }
        if (Objects.isNull(param.getSupplyEntId())) {
            return "供应企业不能为空！";
        }
        return null;
    }

    /**
     * @desc: 分页查询商品信息
     * @author: yzc
     * @date: 2023-07-05 11:58
     * @Param params:
     * @return: java.util.List<com.sckw.product.model.vo.res.GoodsList>
     */
    public PageResult select(SelectGoodsListParam params) {
        LambdaQueryWrapper<KwpGoods> wrapper = buildWrapper(BeanUtils.copyProperties(params, ExportStatisticGoodsListParam.class));
        Page<KwpGoods> page = new Page<>(params.getPage(), params.getPageSize());
        IPage<KwpGoods> goodsIpage = kwpGoodsMapper.selectPage(page, wrapper);
        List<KwpGoods> list = goodsIpage.getRecords();
        if (CollectionUtils.isEmpty(list)) {
            return PageResult.build(params.getPage(), params.getPageSize(), goodsIpage.getTotal(), Collections.emptyList());
        }
        List<GoodsList> result = buildGoodLists(list);
        return PageResult.build(params.getPage(), params.getPageSize(), goodsIpage.getTotal(), result);
    }

    /**
     * @desc: 统计查询
     * @author: yzc
     * @date: 2023-07-05 17:55
     * @Param params:
     * @return: com.sckw.core.model.vo.TableStatisticRes
     */
    public TableStatisticRes statistic(StatisticGoodsListParam params) {
        TableStatisticRes res = new TableStatisticRes();
        LambdaQueryWrapper<KwpGoods> wrapper = buildWrapper(BeanUtils.copyProperties(params, ExportStatisticGoodsListParam.class));
        List<KwpGoods> goodsList = kwpGoodsMapper.selectList(wrapper);
        Map<Integer, List<KwpGoods>> map = goodsList.stream().collect(Collectors.groupingBy(KwpGoods::getStatus));
        List<TableTop> tableTops = new ArrayList<>();
        TableTop all = new TableTop();
        all.setName("全部").setTotal(CollectionUtils.isEmpty(goodsList) ? 0 : goodsList.size());
        tableTops.add(all);
        GoodsStatusEnum.getSortList().forEach(e -> {
            List<KwpGoods> list = map.get(e.getCode());
            int total = CollectionUtils.isEmpty(list) ? 0 : list.size();
            TableTop tableTop = new TableTop();
            tableTop.setName(e.getMsg()).setValue(e.getCode()).setTotal(total);
            tableTops.add(tableTop);
        });
        TableBottom tableBottom = new TableBottom();
        tableBottom.setTotal(CollectionUtils.isEmpty(goodsList) ? 0 : goodsList.size());
        res.setTableTops(tableTops).setTableBottom(tableBottom);
        return res;
    }

    /**
     * @desc: 导出
     * @author: yzc
     * @date: 2023-07-06 9:07
     * @Param params:
     * @return: void
     */
    public List<GoodsListExport> export(ExportStatisticGoodsListParam params) {
        LambdaQueryWrapper<KwpGoods> wrapper = buildWrapper(params);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        return getExportResults(list);

    }

    /**
     * @desc: 获取导出结果
     * @author: yzc
     * @date: 2023-09-18 15:19
     * @Param list:
     * @return: java.util.List<com.sckw.product.model.GoodsListExport>
     */
    public List<GoodsListExport> getExportResults(List<KwpGoods> list) {
        List<GoodsList> goodsLists = buildGoodLists(list);
        List<GoodsListExport> result = new ArrayList<>(list.size());
        goodsLists.forEach(e -> {
            GoodsListExport export = BeanUtils.copyProperties(e, GoodsListExport.class);
            export.setAmount(Objects.isNull(e.getAmount()) ? null : String.valueOf(e.getAmount())).setAddedTime(Objects.isNull(e.getAddedTime()) ? null : DateUtil.getDateTime(e.getAddedTime())).setShelfTime(Objects.isNull(e.getShelfTime()) ? null : DateUtil.getDateTime(e.getShelfTime())).setCreateTime(Objects.isNull(e.getCreateTime()) ? null : DateUtil.getDateTime(e.getCreateTime()));
            result.add(export);
        });
        return result;
    }

    /**
     * @desc: 构建查询条件
     * @author: yzc
     * @date: 2023-08-10 15:36
     * @Param params:
     * @return: com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.sckw.product.model.KwpGoods>
     */
    private LambdaQueryWrapper<KwpGoods> buildWrapper(ExportStatisticGoodsListParam params) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(params.getIds())) {
            List<Long> ids = StringUtils.splitStrToList(params.getIds(), ",", Long.class);
            wrapper.in(KwpGoods::getId, ids);
        } else {
            if (Objects.nonNull(params.getStartCreateTime())) {
                wrapper.ge(KwpGoods::getCreateTime, params.getStartCreateTime());
            }
            if (Objects.nonNull(params.getEndCreateTime())) {
                wrapper.le(KwpGoods::getCreateTime, params.getEndCreateTime());
            }
            wrapper.eq(Objects.nonNull(params.getSupplyEntId()), KwpGoods::getSupplyEntId, params.getSupplyEntId()).eq(Objects.nonNull(params.getPrepaidLimit()), KwpGoods::getPrepaidLimit, params.getPrepaidLimit()).eq(Objects.nonNull(params.getStatus()), KwpGoods::getStatus, params.getStatus());
            if (StringUtils.isNotBlank(params.getGoodsType()) && StringUtils.isNotBlank(params.getGoodsTypeValue())) {
                List<SysDictResDto> goodsTypeList = remoteSystemService.queryDictBottom(params.getGoodsType(), params.getGoodsTypeValue());
                if (CollectionUtils.isNotEmpty(goodsTypeList)) {
                    List<String> goodsTypes = goodsTypeList.stream().map(SysDictResDto::getValue).toList();
                    wrapper.in(KwpGoods::getGoodsType, goodsTypes);
                }
            }
            String keywords = params.getKeywords();
            if (StringUtils.isNotBlank(keywords)) {
                //模糊匹配商品名称、仓储地址
                wrapper.and(e -> e.like(KwpGoods::getName, keywords.trim()).or().like(KwpGoods::getAddressName, keywords.trim()));
            }
        }
        wrapper.eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO).orderByDesc(KwpGoods::getCreateTime);
        return wrapper;
    }

    /**
     * @desc: 构建商品列表
     * @author: yzc
     * @date: 2023-08-10 15:35
     * @Param list:
     * @return: java.util.List<com.sckw.product.model.vo.res.GoodsList>
     */
    public List<GoodsList> buildGoodLists(List<KwpGoods> list) {
        List<GoodsList> result = new ArrayList<>(list.size());
        List<Long> goodsIds = new ArrayList<>(list.size());
        List<Long> supplyEntIds = new ArrayList<>(list.size());
        List<Long> userIds = new ArrayList<>();
        list.forEach(e -> {
            goodsIds.add(e.getId());
            if (Objects.nonNull(e.getSupplyEntId())) {
                supplyEntIds.add(e.getSupplyEntId());
            }
            if (Objects.nonNull(e.getManager())) {
                userIds.add(e.getManager());
            }
            if (Objects.nonNull(e.getCreateBy())) {
                userIds.add(e.getCreateBy());
            }
        });

        //价格信息
        Map<Long, List<KwpGoodsPriceRange>> priceRangeMap = kwpGoodsPriceRangeService.getByGoodsIds(goodsIds).stream().collect(Collectors.groupingBy(KwpGoodsPriceRange::getGoodsId));
        //用户信息
        Map<Long, UserCacheResDto> userMap = remoteSystemService.queryUserCacheMapByIds(userIds);
        //供应企业信息
        List<EntCacheResDto> entList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(supplyEntIds)) {
            entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        }
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.TAX_RATE.getType(), DictTypeEnum.GOODS_STATUS.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> productNameMap, unitMap, goodsStatusMap, goodsSpecMap;
        if (CollectionUtils.isNotEmpty(dict)) {
            productNameMap = dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType());
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            goodsStatusMap = dict.get(DictTypeEnum.GOODS_STATUS.getType());
            goodsSpecMap = dict.get(DictTypeEnum.GOODS_SPEC.getType());
        } else {
            productNameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            goodsStatusMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            goodsSpecMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        list.forEach(e -> {
            Long id = e.getId();
            GoodsList goodsList = BeanUtils.copyProperties(e, GoodsList.class);
            UserCacheResDto createUser = userMap.get(e.getCreateBy());
            goodsList.setStatusLabel(CollectionUtils.isNotEmpty(goodsStatusMap) ? goodsStatusMap.get(String.valueOf(goodsList.getStatus())) : null).setGoodsTypeLabel(CollectionUtils.isNotEmpty(productNameMap) ? productNameMap.get(goodsList.getGoodsType()) : null).setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(goodsList.getUnit()) : null).setSpecLabel(CollectionUtils.isNotEmpty(goodsSpecMap) ? goodsSpecMap.get(goodsList.getSpec()) : null).setSupplyEnt(entMap.get(e.getSupplyEntId())).setThumb(FileUtils.splice(e.getThumb())).setCreateByName(Objects.nonNull(createUser) ? createUser.getName() : null);

            List<KwpGoodsPriceRange> priceRanges = priceRangeMap.get(id);
            BigDecimal price = Optional.ofNullable(priceRanges).filter(priceRangeList -> !priceRangeList.isEmpty()).map(priceRangeList -> priceRangeList.get(0)).map(KwpGoodsPriceRange::getPrice).orElse(null);
            goodsList.setPrice(price);

            result.add(goodsList);
        });
        return result;
    }

    /**
     * @desc: 单个上架
     * @author: yzc
     * @date: 2023-07-06 8:56
     * @Param id:
     * @return: void
     */
    public void batchPutOnShelves(List<Long> ids) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(KwpGoods::getId, ids).eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO);
        List<KwpGoods> goodsList = kwpGoodsMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(goodsList)) {
            throw new BusinessException("商品不存在！");
        }
        //校验
        boolean hasPutOnShelves = goodsList.stream().anyMatch(good -> Objects.equals(GoodsStatusEnum.PUT_ON_SHELVES.getCode(), good.getStatus()));
        if (hasPutOnShelves) {
            throw new BusinessException("上架操作仅针对“已下架”“草稿”状态的单据！");
        }

        for (KwpGoods goods : goodsList) {
            if (Objects.equals(GoodsStatusEnum.SAVED.getCode(), goods.getStatus())) {
                UpdateGoodsParam updateParam = BeanUtils.copyProperties(goods, UpdateGoodsParam.class);
                updateParam.setAttributes(BeanUtils.copyToList(kwpGoodsAttributeService.getByGoodsId(goods.getId()), GoodsAttributes.class));
                //价格
                List<KwpGoodsPriceRange> priceRanges = kwpGoodsPriceRangeService.getByGoodsId(goods.getId());
                BigDecimal price = Optional.ofNullable(priceRanges).filter(priceRangeList -> !priceRangeList.isEmpty()).map(priceRangeList -> priceRangeList.get(0)).map(KwpGoodsPriceRange::getPrice).orElse(null);
                updateParam.setPrice(price);
                updateParam.setImages(BeanUtils.copyToList(kwpGoodsImageService.getByGoodsId(goods.getId()), GoodsImages.class));
                updateParam.setAddressInfo(BeanUtils.copyProperties(kwpGoodsAddressService.getByGoodsId(goods.getId()), AddressInfo.class));
                String msg = judgeParameters(updateParam);
                if (StringUtils.isNotBlank(msg)) {
                    throw new CustomPromptException(HttpStatus.GOODS_PUT_ON_SHELVES_FAIL_CODE, msg);
                }
            }

            LambdaUpdateWrapper<KwpGoods> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).set(KwpGoods::getAddedTime, new Date()).eq(KwpGoods::getId, goods.getId());
            kwpGoodsMapper.update(null, updateWrapper);
        }
        goodsList.forEach(e -> {
            sendMsg(MessageEnum.PRODUCT_ON_SHELVES, e);
        });
    }

    /**
     * @desc: 发送消息提醒
     * @author: yzc
     * @date: 2023-09-05 11:53
     * @Param msgEnum:
     * @Param goods:
     * @return: void
     */
    private void sendMsg(MessageEnum msgEnum, KwpGoods goods) {
        log.info("发送消息提醒, msgEnum：{}, goods：{}", JSON.toJSONString(msgEnum), JSON.toJSONString(goods));
//        Map<String, Object> map = CollectionUtils.createHashMap();
//        map.put("productName", goods.getName());
//        //给创建人发消息
//        List<UserInfo> userInfos = new ArrayList<>();
//        UserInfo createUser = new UserInfo();
//        createUser.setUserId(goods.getCreateBy()).setEntId(goods.getEntId());
//        userInfos.add(createUser);
//        HashMap<String, String> urlMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
//        urlMap.put(ClientTypeEnum.app.getValue(), appGoodsListUrl);
//        urlMap.put(ClientTypeEnum.pc.getValue(), pcGoodsListUrl);
//        SckwMessage msg = new SckwMessage(msgEnum);
//        msg.setParams(map).setMsgUrls(urlMap).setUserInfos(userInfos).setCreateBy(LoginUserHolder.getUserId());
//        log.info(msgEnum.getTitle() + "消息：{}", JSON.toJSONString(msg));
//        streamBridge.send("sckw-message", JSON.toJSONString(msg));
    }


    /**
     * @desc: 批量下架
     * @author: yzc
     * @date: 2023-07-06 8:56
     * @Param ids:
     * @return: void
     */
    public void batchTakeOffShelves(List<Long> ids) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(KwpGoods::getId, ids).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (!Objects.equals(ids.size(), list.size())) {
            throw new BusinessException("下架操作仅针对“已上架”状态的单据");
        }
        LambdaUpdateWrapper<KwpGoods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(KwpGoods::getStatus, GoodsStatusEnum.TAKE_OFF_SHELVES.getCode()).set(KwpGoods::getShelfTime, new Date()).in(KwpGoods::getId, ids);
        kwpGoodsMapper.update(null, updateWrapper);
//        list.forEach(e -> {
//            sendMsg(MessageEnum.PRODUCT_REMOVED_SHELVES, e);
//        });
    }

    /**
     * @desc: 批量删除
     * @author: yzc
     * @date: 2023-07-06 8:56
     * @Param ids:
     * @return: void
     */
    public void batchDelete(List<Long> ids) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(KwpGoods::getId, ids).eq(KwpGoods::getStatus, 0).eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (!Objects.equals(ids.size(), list.size())) {
            throw new BusinessException("删除操作仅针对“草稿”状态的单据");
        }
        LambdaUpdateWrapper<KwpGoods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(KwpGoods::getDelFlag, Global.YES).in(KwpGoods::getId, ids);
        kwpGoodsMapper.update(null, updateWrapper);
        //不作删除，防止订单详情查不出相关信息或查出以往被删除的相关信息
//        kwpGoodsAddressService.delByGoodsIds(ids);
//        kwpGoodsAttributeService.delByGoodsIds(ids);
//        kwpGoodsImageService.delByGoodsIds(ids);
//        kwpGoodsPriceRangeService.delByGoodsIds(ids);
    }


    /**
     * @desc: 建材市场分页查询
     * @author: yzc
     * @date: 2023-07-06 9:38
     * @Param params:
     * @return: com.sckw.core.model.page.PageResult
     */
    public PageResult buildingMaterialsMarketList(BuildingMaterialsMarketListParam params, HttpServletRequest request) {
        Page<KwpGoods> page = new Page<>(params.getPage(), params.getPageSize());
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(params.getKeywords())) {
            kwpSearchLogService.saveLog(params.getKeywords(), 1, request);
            redisTemplate.opsForZSet().incrementScore(RedisConstant.HOT_KEY, params.getKeywords(), 1);
            redisTemplate.expire(RedisConstant.HOT_KEY, DateTimeUtil.getTime(), TimeUnit.SECONDS);
        }
        wrapper.eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO);
        if (StringUtils.isNotBlank(params.getGoodsType()) && StringUtils.isNotBlank(params.getGoodsTypeValue())) {
            List<SysDictResDto> goodsTypeList = remoteSystemService.queryDictBottom(params.getGoodsType(), params.getGoodsTypeValue());
            if (CollectionUtils.isNotEmpty(goodsTypeList)) {
                List<String> goodsTypes = goodsTypeList.stream().map(SysDictResDto::getValue).toList();
                wrapper.in(KwpGoods::getGoodsType, goodsTypes);
            }
        }
        if (Objects.nonNull(params.getAreaCode()) && Objects.nonNull(params.getAreaLevel())) {
            switch (params.getAreaLevel()) {
                case 1 ->
                        wrapper.likeRight(KwpGoods::getAreaCode, String.valueOf(params.getAreaCode()).substring(0, 2));
                case 2 ->
                        wrapper.likeRight(KwpGoods::getAreaCode, String.valueOf(params.getAreaCode()).substring(0, 4));
                case 3 -> wrapper.eq(KwpGoods::getAreaCode, params.getAreaCode());
            }
        }
        if (StringUtils.isNotBlank(params.getKeywords())) {
            List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByName(params.getKeywords());
            List<Long> entIds = entList.stream().map(EntCacheResDto::getId).toList();
            wrapper.and(kwpGoodsLambdaQueryWrapper -> kwpGoodsLambdaQueryWrapper.like(KwpGoods::getName, params.getKeywords()).or(CollUtil.isNotEmpty(entIds)).in(CollUtil.isNotEmpty(entIds), KwpGoods::getSupplyEntId, entIds));
        }
        wrapper.eq(StrUtil.isNotBlank(params.getSpec()), KwpGoods::getSpec, params.getSpec());
        Long entId = LoginUserHolder.getEntId();
        if (Objects.nonNull(entId)) {
            if (Objects.nonNull(params.getSign())) {//查询签约或未签约商品
                List<Long> longs = remoteContractService.queryNewSignGoods(entId, LocalDateTime.now());
                if (Objects.equals(params.getSign(), 1)) {
                    if (CollUtil.isNotEmpty(longs)) {
                        wrapper.in(KwpGoods::getId, longs);
                    } else {
                        wrapper.eq(KwpGoods::getId, 0L);
                    }
                } else {
                    wrapper.notIn(CollUtil.isNotEmpty(longs), KwpGoods::getId, longs);
                }
            }
        }

        if (Objects.nonNull(params.getContractId())) {
            List<Long> longs = remoteContractService.queryTradeContractInfo(params.getContractId());
            wrapper.in(CollUtil.isNotEmpty(longs), KwpGoods::getId, longs);
        }
        wrapper.orderByAsc(KwpGoods::getId);
        Page<KwpGoods> kwpGoodsPage = kwpGoodsMapper.selectPage(page, wrapper);
        List<KwpGoods> list = kwpGoodsPage.getRecords();
        if (CollectionUtils.isEmpty(list)) {
            return PageResult.build(params.getPage(), params.getPageSize(), kwpGoodsPage.getTotal(), Collections.emptyList());
        }
        List<BuildingMaterialsMarketList> result = new ArrayList<>(list.size());
        List<Long> goodsIds = new ArrayList<>(list.size());
        List<Long> supplyEntIds = new ArrayList<>(list.size());
        list.forEach(e -> {
            goodsIds.add(e.getId());
            if (Objects.nonNull(e.getSupplyEntId())) {
                supplyEntIds.add(e.getSupplyEntId());
            }
        });
        //地址信息
        Map<Long, KwpGoodsAddress> addressMap = kwpGoodsAddressService.getByGoodsIds(goodsIds).stream().collect(Collectors.toMap(KwpGoodsAddress::getGoodsId, e -> e, (k1, k2) -> k1));
        //价格梯度信息
        Map<Long, List<KwpGoodsPriceRange>> priceRangeMap = kwpGoodsPriceRangeService.getByGoodsIds(goodsIds).stream().collect(Collectors.groupingBy(KwpGoodsPriceRange::getGoodsId));
        //供应企业信息
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> productNameMap, unitMap, specMap;
        if (CollectionUtils.isNotEmpty(dict)) {
            productNameMap = dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType());
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            specMap = dict.get(DictTypeEnum.GOODS_SPEC.getType());
        } else {
            productNameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            specMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }
        list.forEach(e -> {
            BuildingMaterialsMarketList materials = BeanUtils.copyProperties(e, BuildingMaterialsMarketList.class);
            KwpGoodsAddress address = addressMap.get(e.getId());
            List<KwpGoodsPriceRange> priceRanges = priceRangeMap.get(e.getId());
            materials.setGoodsTypeLabel(CollectionUtils.isNotEmpty(productNameMap) ? productNameMap.get(e.getGoodsType()) : null).setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(e.getUnit()) : null).setSpec(CollectionUtils.isNotEmpty(specMap) ? specMap.get(e.getSpec()) : null).setAddressName(Objects.isNull(address) ? null : address.getCityName()).setDetailAddress(Objects.isNull(address) ? null : address.getDetailAddress()).setPrice(CollectionUtils.isEmpty(priceRanges) ? null : priceRanges.get(0).getPrice()).setThumb(FileUtils.splice(e.getThumb())).setSupplyEnt(entMap.get(e.getSupplyEntId()));
            materials.setSignFlag(false);
            if (Objects.nonNull(entId)) {
                TradeContractGoodsDto tradeContractResDto = remoteContractService.queryTradeContractNew(entId, e.getId(), LocalDateTime.now());
                if (Objects.nonNull(tradeContractResDto)) {
                    materials.setSignPrice(tradeContractResDto.getPrice());
                    materials.setSignFlag(true);
                }
            }
            result.add(materials);
        });
        return PageResult.build(params.getPage(), params.getPageSize(), kwpGoodsPage.getTotal(), result);
    }

    /**
     * @desc: 商品下拉列表
     * @author: yzc
     * @date: 2023-07-06 8:45
     * @Param params:
     * @return: java.util.List<com.sckw.product.model.vo.res.GoodsDropList>
     */
    public List<GoodsDropList> dropList(GoodsDropListReq params, HttpServletRequest request) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        if (Objects.equals(params.getOrderType(), 2)) {
            Long supplyEntId = params.getSupplyEntId();
            if (Objects.isNull(supplyEntId)) {
                throw new BusinessException("供应单位不能为空！");
            }
            wrapper.eq(KwpGoods::getSupplyEntId, supplyEntId);
        }
        wrapper.like(StringUtils.isNotBlank(params.getName()), KwpGoods::getName, params.getName()).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO).orderByDesc(KwpGoods::getAddedTime);

        //专场逻辑
        String accessSpecial = request.getHeader("Access-Special");
        //是否主平台
        boolean mainPlatform = remoteSystemService.queryMainPlatform(accessSpecial);
        //if (!mainPlatform) {
        List<Long> entIds = remoteSystemService.queryEntIdsByCode(accessSpecial, String.valueOf(EntTypeEnum.SUPPLIER.getCode()));
        //entIds.remove(LoginUserHolder.getEntId());
        wrapper.in(KwpGoods::getEntId, entIds);
        //}

        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        //数据组装
        List<Long> supplyEntIds = list.stream().map(KwpGoods::getSupplyEntId).distinct().toList();
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        List<GoodsDropList> result = new ArrayList<>();
        list.forEach(e -> {
            GoodsDropList goodsDropList = BeanUtils.copyProperties(e, GoodsDropList.class);
            goodsDropList.setSupplyEnt(entMap.get(e.getSupplyEntId()));
            result.add(goodsDropList);
        });

        return result;
    }

    /**
     * @desc: 根据商品id获取当前企业商品信息
     * @author: yzc
     * @date: 2023-07-05 14:25
     * @Param id:
     * @return: com.sckw.product.model.KwpGoods
     */
    public KwpGoods getGoodsById(Long id) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<KwpGoods> last = wrapper.eq(KwpGoods::getId, id).eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getDelFlag, Global.NO).last("LIMIT 1");
        return kwpGoodsMapper.selectOne(last);
    }

    /**
     * @desc: 根据商品id获取上架商品信息
     * @author: yzc
     * @date: 2023-07-13 15:08
     * @Param id:
     * @return: com.sckw.product.model.KwpGoods
     */
    public KwpGoods getOnShelfGoodsById(Long id) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<KwpGoods> last = wrapper.eq(KwpGoods::getId, id).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO).last("LIMIT 1");
        return kwpGoodsMapper.selectOne(last);
    }

    /**
     * @desc: 根据商品id获取商品信息
     * @author: yzc
     * @date: 2023-07-20 11:16
     * @Param ids:
     * @return: java.util.List<com.sckw.product.model.KwpGoods>
     */
    public KwpGoods selectById(Long id) {
        KwpGoods goods = kwpGoodsMapper.selectById(id);
        if (Objects.nonNull(goods)) {
            goods.setThumb(FileUtils.splice(goods.getThumb()));
        }
        return goods;
    }


    /**
     * @desc: 根据商品ids获取商品信息
     * @author: yzc
     * @date: 2023-07-20 11:16
     * @Param ids:
     * @return: java.util.List<com.sckw.product.model.KwpGoods>
     */
    public List<KwpGoods> selectByIds(List<Long> ids) {
        List<KwpGoods> list = kwpGoodsMapper.selectBatchIds(ids);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(e -> {
                e.setThumb(FileUtils.splice(e.getThumb()));
            });
        }
        return CollectionUtils.emptyIfNull(list);
    }

    /**
     * @desc: 更新
     * @author: yzc
     * @date: 2023-07-13 15:11
     * @Param goods:
     * @return: void
     */
    public void updateById(KwpGoods goods) {
        kwpGoodsMapper.updateById(goods);
    }

    /**
     * @desc: 获取商品预计最大可购数量
     * @author: yzc
     * @date: 2023-07-31 17:41
     * @Param param:
     * @return: java.math.BigDecimal
     */
    public BigDecimal maxPurchaseNum(MaxPurchaseNumParam param) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<KwpGoods> last = wrapper.eq(KwpGoods::getId, param.getGoodsId()).eq(KwpGoods::getDelFlag, Global.NO).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).last("LIMIT 1");
        KwpGoods goods = kwpGoodsMapper.selectOne(last);
        if (Objects.isNull(goods)) {
            throw new BusinessException("商品不存在或已下架！");
        }
        BigDecimal amount = goods.getAmount();
        if (Objects.isNull(param.getTrading()) || !param.getTrading().startsWith("1")) {
            return amount;
        }
        if (Objects.isNull(param.getProcureEntId()) || Objects.isNull(param.getSupplyEntId())) {
            throw new BusinessException("采购或供应单位信息不能为空！");
        }
        List<Long> entIds = Arrays.asList(param.getProcureEntId(), param.getSupplyEntId());
        Map<Long, EntCacheResDto> entMap = remoteSystemService.queryEntTreeByIds(entIds);
        EntCacheResDto procure = entMap.get(param.getProcureEntId());
        if (Objects.isNull(procure) || Objects.isNull(procure.getId())) {
            log.error("采购单位：{}找不到对应一级企业信息", param.getProcureEntId());
            throw new BusinessException("采购单位一级企业信息不存在！");
        }
        EntCacheResDto supply = entMap.get(param.getSupplyEntId());
        if (Objects.isNull(supply) || Objects.isNull(supply.getId())) {
            log.error("供应单位：{}找不到对应一级企业信息", param.getSupplyEntId());
            throw new BusinessException("供应单位一级企业信息不存在！");
        }
        R<List<WalletDto>> wallet = payCenterDubboService.wallet(procure.getId(), ChannelEnum.getByCode(param.getTrading()), supply.getId());
        if (Objects.isNull(wallet) || Objects.equals(wallet.getCode(), 0)) {
            throw new BusinessException("校验预付钱包异常，请联系管理员！");
        }
        List<WalletDto> data = wallet.getData();
        if (CollectionUtils.isEmpty(data)) {
            throw new BusinessException("检测尚未创建对应预付款清单，请先创建！");
        }
        long money = data.get(0).getApMoney();
        BigDecimal divide = new BigDecimal(money).divide(param.getUtilPrice().multiply(new BigDecimal("100")), 2, RoundingMode.HALF_UP);
        return amount.compareTo(divide) < 0 ? amount : divide;
    }

    /**
     * @desc: 更新商品库存
     * @author: yzc
     * @date: 2023-08-03 17:06
     * @Param param:
     * @return: void
     */
    public void updateAmount(UpdateAmountParam param) {
        Long id = param.getId();
        BigDecimal updateAmount = param.getUpdateAmount();
        String lockKey = String.format(RedisConstant.GOODS_UPDATE_AMOUNT_KEY, id);
        if (Boolean.FALSE.equals(RedissonUtils.tryLock(lockKey, 5L, 10L))) {
            throw new BusinessException("业务繁忙，请稍后再试！");
        }
        try {
            LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(KwpGoods::getId, id).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO).last("LIMIT 1");
            KwpGoods goods = kwpGoodsMapper.selectOne(wrapper);
            if (Objects.isNull(goods)) {
                throw new BusinessException("商品不存在或已下架！");
            }
            BigDecimal amount = goods.getAmount();
            BigDecimal finalAmount = Objects.equals(param.getUpdateType(), 0) ? amount.add(updateAmount) : amount.subtract(updateAmount);
            if (finalAmount.compareTo(BigDecimal.ZERO) <= 0) {
                throw new BusinessException("库存数量更新后不能小于等于零！");
            }
            goods.setAmount(finalAmount);
            kwpGoodsMapper.updateById(goods);
        } finally {
            RedissonUtils.unlock(lockKey);
        }
    }

    /**
     * @desc: 根据客服经理id获取未删除非草稿的商品数量
     * @author: yzc
     * @date: 2023-08-15 10:47
     * @Param managerId:
     * @return: java.lang.Long
     */

    public Long getCountByManager(Long managerId) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getManager, managerId).eq(KwpGoods::getDelFlag, Global.NO).ne(KwpGoods::getStatus, GoodsStatusEnum.SAVED.getCode());
        return kwpGoodsMapper.selectCount(wrapper);
    }

    /**
     * @desc: 商品名称判重
     * @author: yzc
     * @date: 2023-08-16 15:24
     * @Param name:
     * @Param supplyEntId:
     * @Param id:
     * @return: java.lang.Boolean
     */
    public Boolean nameDuplicationJudgment(String name, Long supplyEntId, Long id) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getSupplyEntId, supplyEntId).eq(KwpGoods::getName, name).eq(KwpGoods::getDelFlag, Global.NO);
        if (Objects.nonNull(id)) {
            wrapper.ne(KwpGoods::getId, id);
        }
        Long count = kwpGoodsMapper.selectCount(wrapper);
        return Objects.nonNull(count) && count > 0L;
    }

    /**
     * @desc: 根据供应企业id获取未删除非草稿的商品数量
     * @author: yzc
     * @date: 2023-08-29 9:51
     * @Param supplyEntId:  供应企业id
     * @return: java.lang.Long
     */
    public Long getCountBySupplyEnt(Long supplyEntId) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getSupplyEntId, supplyEntId).eq(KwpGoods::getDelFlag, Global.NO).ne(KwpGoods::getStatus, GoodsStatusEnum.SAVED.getCode());
        return kwpGoodsMapper.selectCount(wrapper);
    }

    /**
     * @desc: 获取商品价格
     * @author: yzc
     * @date: 2023-09-05 10:54
     * @Param param:
     * @return: java.math.BigDecimal
     */
    public BigDecimal getPrice(GetPriceParam param) {
        List<KwpGoodsPriceRange> priceRanges = kwpGoodsPriceRangeService.getByGoodsId(param.getGoodsId());
        if (CollectionUtils.isEmpty(priceRanges)) {
            throw new BusinessException("商品价格信息异常！");
        }
        //价格区间空挡四舍五入取整，保证数量在价格区间段
        BigDecimal num = param.getNum().setScale(0, RoundingMode.HALF_UP);
        BigDecimal notLimit = null;
        BigDecimal price = null;
        for (KwpGoodsPriceRange e : priceRanges) {
            if (num.compareTo(e.getStartAmount()) >= 0) {
                BigDecimal endAmount = e.getEndAmount();
                if (num.compareTo(endAmount) <= 0) {
                    price = e.getPrice();
                    break;
                }
                if (endAmount.compareTo(new BigDecimal("-1.00")) == 0) {
                    notLimit = e.getPrice();
                }
            }
        }
        return Objects.nonNull(price) ? price : notLimit;
    }


    /**
     * @desc: 根据一级企业和商品单位统计上架商品数量
     * @author: yzc
     * @date: 2023-09-11 15:42
     * @Param param:
     * @return: java.lang.Long
     */
    public Long getOnShelfGoodsNum(GoodsNumStsParam param) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getEntId, param.getTopEntId()).eq(StringUtils.isNotBlank(param.getUnit()), KwpGoods::getUnit, param.getUnit()).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO);
        if (Objects.nonNull(param.getEndDate())) {
            wrapper.le(KwpGoods::getShelfTime, param.getEndDate());
        }
        Long count = kwpGoodsMapper.selectCount(wrapper);
        return Objects.isNull(count) ? 0L : count;
    }

    /**
     * @desc: 获取工作台商品列表
     * @author: yzc
     * @date: 2023-09-13 18:38
     * @return: java.util.List<com.sckw.product.model.KwpGoods>
     */
    public List<KwpGoods> getWorkbenchList() {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(KwpGoods::getEntId, LoginUserHolder.getEntId()).eq(KwpGoods::getStatus, GoodsStatusEnum.PUT_ON_SHELVES.getCode()).eq(KwpGoods::getDelFlag, Global.NO).orderByDesc(KwpGoods::getCreateTime).last("LIMIT 10");
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        return CollUtil.emptyIfNull(list);
    }

    public com.sckw.product.api.model.KwpGoods getGoodsByGoodsName(String goodsName) {
        List<KwpGoods> kwpGoods = kwpGoodsMapper.selectList(new LambdaQueryWrapper<KwpGoods>().eq(KwpGoods::getName, goodsName).eq(KwpGoods::getDelFlag, 0).orderByDesc(KwpGoods::getCreateTime));
        com.sckw.product.api.model.KwpGoods goods = new com.sckw.product.api.model.KwpGoods();
        if (kwpGoods.size() > 0) {
            KwpGoods kwpGoods1 = kwpGoods.get(0);
            org.springframework.beans.BeanUtils.copyProperties(kwpGoods1, goods);
        }
        return goods;
    }

    public List<Long> selectIdsTaxRateAndLikeGoodsName(String name, String taxRate) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(taxRate), KwpGoods::getTaxRate, taxRate).like(StringUtils.isNotBlank(name), KwpGoods::getName, name);
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list.stream().map(KwpGoods::getId).toList();
    }

    public GoodsInfoResp getGoods(GoodsInfoReq req) {
        log.info("查询商品信息，请求参数 :{}", JSON.toJSONString(req));
        //查询上商品信息
        Long entId = StringUtils.isNotBlank(req.getEntId()) ? Long.valueOf(req.getEntId()) : null;
        List<KwpGoods> goods = kwpGoodsRepository.queryByEntIdAndGoodsName(entId, req.getGoodsName());
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(goods)) {
            return new GoodsInfoResp();
        }
        List<String> types = Arrays.asList(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType());
        //组装商品参数
        Map<String, Map<String, String>> finalValueAndDictResDtoMap = remoteSystemService.queryDictByType(types);

        List<GoodsInfoResp.GoodsInfo> goodsInfos = goods.stream().filter(e -> Objects.equals(e.getStatus(), GoodsStatusEnum.PUT_ON_SHELVES.getCode())).map(x -> KwpGoodsService.getGoodsInfo(x, finalValueAndDictResDtoMap)).collect(Collectors.toList());
        GoodsInfoResp goodsInfoResp = new GoodsInfoResp();
        goodsInfoResp.setGoodsInfoRespList(goodsInfos);
        return goodsInfoResp;
    }

    private static GoodsInfoResp.GoodsInfo getGoodsInfo(KwpGoods x, Map<String, Map<String, String>> valueAndDictResDtoMap) {
        GoodsInfoResp.GoodsInfo goodsInfo = new GoodsInfoResp.GoodsInfo();
        goodsInfo.setGoodsId(x.getId());

        Map<String, String> productNameMap = valueAndDictResDtoMap.getOrDefault(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), new HashMap<>());
        Map<String, String> goodsSpecMap = valueAndDictResDtoMap.getOrDefault(DictTypeEnum.GOODS_SPEC.getType(), new HashMap<>());
        String productType = productNameMap.getOrDefault(x.getGoodsType(), "");
        goodsInfo.setGoodsName(x.getName() + "/" + productType + "/" + goodsSpecMap.getOrDefault(x.getSpec(), ""));

        Map<String, String> unitMap = valueAndDictResDtoMap.getOrDefault(DictTypeEnum.UNIT_TYPE.getType(), new HashMap<>());
        goodsInfo.setAmountUnit(unitMap.get(x.getUnit()));
        goodsInfo.setPriceUnit(x.getPriceUnit());
        return goodsInfo;
    }

    public Set<Object> hotKeys() {
        return redisTemplate.opsForZSet().reverseRange(RedisConstant.HOT_KEY, 0, 9);
    }

    private List<BuildingMaterialsMarketList> tran(List<KwpGoods> list) {
        List<BuildingMaterialsMarketList> result = new ArrayList<>(list.size());
        list = new ArrayList<>(list.stream().collect(Collectors.toMap(KwpGoods::getId,
                Function.identity(),
                (existing, replacement) -> existing
        )).values());
        List<Long> goodsIds = new ArrayList<>(list.size());
        List<Long> supplyEntIds = new ArrayList<>(list.size());
        list.forEach(e -> {
            goodsIds.add(e.getId());
            if (Objects.nonNull(e.getSupplyEntId())) {
                supplyEntIds.add(e.getSupplyEntId());
            }
        });

        //地址信息
        Map<Long, KwpGoodsAddress> addressMap = kwpGoodsAddressService.getByGoodsIds(goodsIds).stream().collect(Collectors.toMap(KwpGoodsAddress::getGoodsId, e -> e, (k1, k2) -> k1));
        //价格梯度信息
        Map<Long, List<KwpGoodsPriceRange>> priceRangeMap = kwpGoodsPriceRangeService.getByGoodsIds(goodsIds).stream().collect(Collectors.groupingBy(KwpGoodsPriceRange::getGoodsId));
        //供应企业信息
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream().collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> productNameMap, unitMap, goodsMap;
        if (CollectionUtils.isNotEmpty(dict)) {
            productNameMap = dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType());
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            goodsMap = dict.get(DictTypeEnum.GOODS_SPEC.getType());
        } else {
            productNameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            goodsMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }
        Long entId = LoginUserHolder.getEntId();

        list.forEach(e -> {
            BuildingMaterialsMarketList materials = BeanUtils.copyProperties(e, BuildingMaterialsMarketList.class);
            KwpGoodsAddress address = addressMap.get(e.getId());
            List<KwpGoodsPriceRange> priceRanges = priceRangeMap.get(e.getId());
            materials.setGoodsTypeLabel(CollectionUtils.isNotEmpty(productNameMap) ? productNameMap.get(e.getGoodsType()) : null).setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(e.getUnit()) : null).setSpec(CollectionUtils.isNotEmpty(goodsMap) ? goodsMap.get(e.getSpec()) : null).setAddressName(Objects.isNull(address) ? null : address.getCityName()).setDetailAddress(Objects.isNull(address) ? null : address.getDetailAddress()).setPrice(CollectionUtils.isEmpty(priceRanges) ? null : priceRanges.get(0).getPrice()).setThumb(FileUtils.splice(e.getThumb())).setSupplyEnt(entMap.get(e.getSupplyEntId()));
            materials.setSignFlag(false);
            if (Objects.nonNull(entId)) {
                TradeContractGoodsDto tradeContractResDto = remoteContractService.queryTradeContractNew(entId, e.getId(), LocalDateTime.now());
                if (Objects.nonNull(tradeContractResDto)) {
                    materials.setSignPrice(tradeContractResDto.getPrice());
                    materials.setSignFlag(true);
                }
            }
            result.add(materials);
        });
        return result;
    }

    public List<BuildingMaterialsMarketList> hootGoods() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime start = now.minusDays(30);
        Map<Long, BigDecimal> res = new HashMap<>();
        Map<Long, OrderSaleVo> sale = new HashMap<>();
        Map<Long, GoodsViewLogVo> view = new HashMap<>();
        //30天销售量 60%
        List<OrderSaleVo> orderSaleVos = tradeOrderInfoService.queryRecentSale(start, now);
        //30天浏览量 40%
        List<GoodsViewLogVo> goodsViewLogVos = kwpGoodsViewLogMapper.searchViewCount(start, now);
        if (CollUtil.isNotEmpty(goodsViewLogVos)) {
            view = goodsViewLogVos.stream().collect(Collectors.toMap(GoodsViewLogVo::getGoodsId, e -> e, (a, b) -> a));
        }
        if (CollUtil.isNotEmpty(orderSaleVos)) {
            sale = orderSaleVos.stream().collect(Collectors.toMap(OrderSaleVo::getGoodsId, e -> e, (a, b) -> a));
        }

        for (Map.Entry<Long, OrderSaleVo> one : sale.entrySet()) {
            BigDecimal mul = NumberUtil.mul(one.getValue().getAmount(), new BigDecimal("0.6"));
            GoodsViewLogVo goodsViewLogVo = view.get(one.getKey());
            BigDecimal mul2 = new BigDecimal("0");
            if (Objects.nonNull(goodsViewLogVo)) {
                mul2 = NumberUtil.mul(goodsViewLogVo.getCount(), new BigDecimal("0.4"));
            }
            res.put(one.getKey(), NumberUtil.add(mul, mul2));
        }
        for (Map.Entry<Long, GoodsViewLogVo> two : view.entrySet()) {
            BigDecimal bigDecimal = res.get(two.getKey());
            //校验是否已经计算比重值
            if (Objects.isNull(bigDecimal)) {
                BigDecimal mul = NumberUtil.mul(two.getValue().getCount(), new BigDecimal("0.4"));
                OrderSaleVo orderSaleVo = sale.get(two.getKey());
                BigDecimal mul2 = new BigDecimal("0");
                if (Objects.nonNull(orderSaleVo)) {
                    mul2 = NumberUtil.mul(orderSaleVo.getAmount(), new BigDecimal("0.6"));
                }
                res.put(two.getKey(), NumberUtil.add(mul, mul2));
            }
        }
        //所有的商品id
        Set<Long> longs = res.keySet();
        if (CollUtil.isEmpty(longs)) { //查询商品信息，按创建时间倒叙取数据
            List<KwpGoods> kwpGoods = kwpGoodsMapper.selectList(new LambdaQueryWrapper<KwpGoods>().eq(KwpGoods::getDelFlag, 0).orderByDesc(KwpGoods::getCreateTime).last("limit 10"));
            if (CollectionUtils.isEmpty(kwpGoods)) {
                return Collections.emptyList();
            }
            return tran(kwpGoods);
        }
        if (CollUtil.size(longs) < 10) {//不足10个，查询商品信息，补足10个
            List<KwpGoods> add = kwpGoodsMapper.selectBatchIds(longs);

            List<KwpGoods> kwpGoods = kwpGoodsMapper.selectList(new LambdaQueryWrapper<KwpGoods>().eq(KwpGoods::getDelFlag, 0).orderByDesc(KwpGoods::getCreateTime).last("limit " + (10 - CollUtil.size(longs))));
            add.addAll(kwpGoods);
            return tran(add);
        }
        List<KwpGoods> add = kwpGoodsMapper.selectBatchIds(CollUtil.sub(longs, 0, 10));

        return tran(add);
    }

    public List<Long> selectByPara(String goodsName, List<String> goodsType, String goodsSpec) {
        LambdaQueryWrapper<KwpGoods> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> w.like(StringUtils.isNotBlank(goodsName), KwpGoods::getName, goodsName).or().in(CollUtil.isNotEmpty(goodsType), KwpGoods::getGoodsType, goodsType).or().like(StringUtils.isNotBlank(goodsSpec), KwpGoods::getSpec, goodsSpec));
        List<KwpGoods> list = kwpGoodsMapper.selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list.stream().map(KwpGoods::getId).toList();
    }


    public GoodsDetails getDetails(Long id) {
        KwpGoods goods = kwpGoodsMapper.selectById(id);
        if (Objects.isNull(goods)) {
            return null;
        }
        GoodsDetails detail = BeanUtils.copyProperties(goods, GoodsDetails.class);

        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.UNIT_TYPE.getType(), DictTypeEnum.TAX_RATE.getType(), DictTypeEnum.GOODS_STATUS.getType(), DictTypeEnum.ADDRESS_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
        Map<String, String> productNameMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> unitMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> goodsStatusMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        Map<String, String> goodsSpecMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        if (CollectionUtils.isNotEmpty(dict)) {
            productNameMap = dict.get(DictTypeEnum.PRODUCT_NAME_TYPE.getType());
            unitMap = dict.get(DictTypeEnum.UNIT_TYPE.getType());
            goodsStatusMap = dict.get(DictTypeEnum.GOODS_STATUS.getType());
            goodsSpecMap = dict.get(DictTypeEnum.GOODS_SPEC.getType());
        }
        detail.setGoodsTypeLabel(CollectionUtils.isNotEmpty(productNameMap) ? productNameMap.get(detail.getGoodsType()) : null).setUnitLabel(CollectionUtils.isNotEmpty(unitMap) ? unitMap.get(detail.getUnit()) : null).setStatusLabel(CollectionUtils.isNotEmpty(goodsStatusMap) ? goodsStatusMap.get(String.valueOf(detail.getStatus())) : null).setSpecLabel(CollectionUtils.isNotEmpty(goodsSpecMap) ? goodsSpecMap.get(String.valueOf(detail.getSpec())) : null);

        return detail;
    }
}
