package com.xinelu.applet.service.nursingstationgoods.impl;

import com.xinelu.applet.dto.nursingstationgoods.GoodAttributeDetailsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodDetails;
import com.xinelu.applet.dto.nursingstationgoods.GoodsList;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderPatient;
import com.xinelu.applet.dto.nursingstationgoods.GoodsOrderStationDTO;
import com.xinelu.applet.mapper.nursingstationgoods.NursingStationGoodsMapper;
import com.xinelu.applet.service.nursingstationgoods.INursingStationGoodsService;
import com.xinelu.applet.vo.coupon.CouponVO;
import com.xinelu.applet.vo.nursingstationgoods.UpdateDefaultAddressVO;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.common.enums.CouponUseStatusEnum;
import com.xinelu.common.enums.GooodsOrderStatusEnum;
import com.xinelu.common.enums.OrderTypeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.PageServiceUtil;
import com.xinelu.common.utils.RedisDistributedLockUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.goodsAttributeDetails.GoodsAttributeDetails;
import com.xinelu.manage.domain.goodsCategory.GoodsCategory;
import com.xinelu.manage.domain.goodsOrder.GoodsOrder;
import com.xinelu.manage.domain.goodsOrderDetails.GoodsOrderDetails;
import com.xinelu.manage.domain.receiveAddressInfo.ReceiveAddressInfo;
import com.xinelu.manage.domain.sysarea.SysArea;
import com.xinelu.manage.mapper.goodsAttributeDetails.GoodsAttributeDetailsMapper;
import com.xinelu.manage.mapper.goodsOrder.GoodsOrderMapper;
import com.xinelu.manage.mapper.goodsOrderDetails.GoodsOrderDetailsMapper;
import com.xinelu.manage.mapper.patientcouponreceive.PatientCouponReceiveMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.receiveAddressInfo.ReceiveAddressInfoMapper;
import com.xinelu.manage.mapper.sysarea.SysAreaMapper;
import com.xinelu.manage.vo.goodsCategory.GoodsCategoryNameVO;
import com.xinelu.manage.vo.patientcouponreceive.PatientCouponReceiveVO;
import com.xinelu.manage.vo.patientinfo.PatientInfoVO;
import com.xinelu.manage.vo.receiveAddressInfo.ReceiveAddressInfoVO;
import com.xinelu.manage.vo.sysarea.SysAreaVO;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author ljh
 * @version 1.0
 * Create by 2022/10/17 13:38
 */
@Slf4j
@Service
public class NursingStationGoodsServiceImpl implements INursingStationGoodsService {
    @Resource
    private NursingStationGoodsMapper nursingStationGoodsMapper;
    @Resource
    private RegexUtil regexUtil;
    @Resource
    private SysAreaMapper sysAreaMapper;
    @Resource
    private GoodsOrderMapper goodsOrderMapper;
    @Resource
    private RedisDistributedLockUtils redisDistributedLockUtils;
    @Resource
    private GoodsAttributeDetailsMapper goodsAttributeDetailsMapper;
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private ReceiveAddressInfoMapper receiveAddressInfoMapper;
    @Resource
    private PageServiceUtil pageServiceUtil;
    @Resource
    private PatientCouponReceiveMapper patientCouponReceiveMapper;
    @Resource
    private GoodsOrderDetailsMapper goodsOrderDetailsMapper;

    /**
     * 所在省的级别
     */
    private static final int PROVINCE_AREA_LEVEL = 1;

    /**
     * 所在市的级别
     */
    private static final int CITY_AREA_LEVEL = 2;

    /**
     * 查询商城分类
     *
     * @param goodsCategory 商品分类信息表
     * @return java.util.List<com.xinyilu.base.domain.goodsCategory.GoodsCategory>
     **/
    @Override
    public List<GoodsCategory> getGoodsCategoryList(GoodsCategory goodsCategory) {
        return nursingStationGoodsMapper.getGoodsCategoryList(goodsCategory);
    }

    /**
     * 查询商品二级分类信息列表
     *
     * @param goodsCategoryId 商品分类信息
     * @return 商品分类信息集合
     */
    @Override
    public AjaxResult getGoodsCategoryNameList(Long goodsCategoryId) {
        //查询当前分类下属所有分类id集合
        List<Integer> childCategoryIds = this.getChildCategoryIds(goodsCategoryId);
        GoodsCategoryNameVO goodsCategoryNameVO = new GoodsCategoryNameVO();
        goodsCategoryNameVO.setGoodsCategoryNameId(childCategoryIds);
        goodsCategoryNameVO.setCategoryLevel(1);
        return AjaxResult.success(nursingStationGoodsMapper.getGoodsCategoryNameList(goodsCategoryNameVO));
    }

    /**
     * 根据商品分类id查询商品信息
     *
     * @param goodsList 商品信息
     * @return java.util.List<com.xinyilu.base.domain.goodsInfo.GoodsInfo>
     **/
    @Override
    public TableDataInfo getGoodsInfoList(GoodsList goodsList) {
        if (Objects.nonNull(goodsList) && Objects.isNull(goodsList.getGoodsCategoryId())) {
            throw new ServiceException("所选商品分类不能为空！");
        }
        //查询当前分类下属所有分类id集合
        List<Integer> childCategoryIds = this.getChildCategoryIds(goodsList.getGoodsCategoryId());
        goodsList.setGoodsCategoryIds(childCategoryIds);
        pageServiceUtil.startPage();
        List<GoodsList> goodsInfoList = nursingStationGoodsMapper.getGoodsInfoList(goodsList);
        return pageServiceUtil.getDataTable(goodsInfoList);
    }

    /**
     * 根据商品id查询商品详细信息
     *
     * @param goodsInfoId 商品详细id
     * @param patientId   用户信息
     * @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodDetails
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoodDetails getGoodsDetails(Long goodsInfoId, Long patientId) {
        GoodDetails goodsDetailsList = nursingStationGoodsMapper.getGoodsDetailsList(goodsInfoId);
        //获取集合属性中的最小值
        BigDecimal goodAttributeDetailsMin = goodsDetailsList.getGoodAttributeDetailsLists()
                .stream()
                .filter(Objects::nonNull)
                .filter(good -> Objects.nonNull(good.getGoodsPrice()))
                .map(GoodAttributeDetailsList::getGoodsPrice).min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
        goodsDetailsList.setMinGoodsPrice(goodAttributeDetailsMin);
        //查询用户未使用的优惠券信息
        if (Objects.nonNull(patientId)) {
            //数据库中查出的用户未使用的优惠券信息
            List<CouponVO> couponVOList = nursingStationGoodsMapper.selectCouponListByPatient(patientId, CouponUseStatusEnum.NOT_USED.getInfo());
            //用流筛选出用户未使用以及未过期的 优惠券信息
            List<CouponVO> couponVO = couponVOList.stream()
                    .filter(cou -> (Objects.nonNull(cou.getExpirationEndTime()))).filter(coupon -> (coupon.getExpirationEndTime().isAfter(LocalDateTime.now()))).collect(Collectors.toList());
            //未过期的优惠券塞入返回值中 返回
            goodsDetailsList.setCouponList(couponVO);
            //做差集取出用户未使用以及 过期的 优惠券信息
            List<CouponVO> couponSubtractList = new ArrayList<>(CollectionUtils.subtract(couponVOList, couponVO));
            if (CollectionUtils.isNotEmpty(couponSubtractList)) {
                //取出会员用户优惠券领取记录表id集合
                List<Long> couponIdList = couponSubtractList.stream()
                        .filter(coupon -> (Objects.nonNull(coupon.getPatientCouponReceiveId())))
                        .map(CouponVO::getPatientCouponReceiveId).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(couponIdList)) {
                    int receiveStatusList = patientCouponReceiveMapper.updateCouponReceiveStatusList(CouponUseStatusEnum.EXPIRED.getInfo(), couponIdList);
                    if (receiveStatusList < 0) {
                        throw new ServiceException("优惠券查询失败,请联系管理员！");
                    }
                }
            }
        }
        return goodsDetailsList;
    }

    /**
     * 根据被护理人id查询基本信息
     *
     * @param patientId 被护理人id
     * @return java.util.List<com.xinyilu.base.domain.receiveAddressInfo.ReceiveAddressInfo>
     **/
    @Override
    public AjaxResult getReceiveAddressInfoList(Long patientId) {
        //根据id查询所有的地址
        List<ReceiveAddressInfoVO> receiveAddressInfoList = nursingStationGoodsMapper.getReceiveAddressInfoList(patientId);
        //取出list集合中所有的AreaCode
        List<String> areaCodeList = receiveAddressInfoList.stream().filter(item -> StringUtils.isNotBlank(item.getAreaCode())).map(ReceiveAddressInfoVO::getAreaCode).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(areaCodeList)) {
            return AjaxResult.success(receiveAddressInfoList);
        }
        //查询所在的街道的区域信息
        Map<String, SysAreaVO> sysStreetAreaMap = sysAreaMapper.getNurseStationAreaByList(areaCodeList).stream().filter(item -> StringUtils.isNotBlank(item.getStreetCode())).collect(Collectors.toMap(SysAreaVO::getStreetCode, item -> item));
        //所在区的编码集合
        List<String> regionCodeList = new ArrayList<>();
        for (ReceiveAddressInfoVO receiveAddressInfoVO : receiveAddressInfoList) {
            SysAreaVO sysAreaVO = sysStreetAreaMap.getOrDefault(receiveAddressInfoVO.getAreaCode(), new SysAreaVO());
            if (Objects.isNull(sysAreaVO.getStreetCode())) {
                regionCodeList.add(receiveAddressInfoVO.getAreaCode());
                continue;
            }
            //拼接省市区街道地址信息
            String provinceName = StringUtils.isBlank(sysAreaVO.getProvinceName()) ? "" : sysAreaVO.getProvinceName();
            String cityName = StringUtils.isBlank(sysAreaVO.getCityName()) ? "" : sysAreaVO.getCityName();
            String regionName = StringUtils.isBlank(sysAreaVO.getRegionName()) ? "" : sysAreaVO.getRegionName();
            String streetName = StringUtils.isBlank(sysAreaVO.getStreetName()) ? "" : sysAreaVO.getStreetName();
            receiveAddressInfoVO.setAreaName(provinceName + cityName + regionName + streetName);
        }
        if (CollectionUtils.isNotEmpty(regionCodeList)) {
            //查询所有区的各级信息
            Map<String, SysAreaVO> sysRegionAreaMap = sysAreaMapper.getNurseStationGoodsAreaByList(regionCodeList).stream().filter(item -> StringUtils.isNotBlank(item.getRegionCode())).collect(Collectors.toMap(SysAreaVO::getRegionCode, item -> item));
            for (ReceiveAddressInfoVO receiveAddressInfoVO : receiveAddressInfoList) {
                SysAreaVO sysAreaVO = sysRegionAreaMap.getOrDefault(receiveAddressInfoVO.getAreaCode(), null);
                if (Objects.nonNull(sysAreaVO)) {
                    String provinceName = StringUtils.isBlank(sysAreaVO.getProvinceName()) ? "" : sysAreaVO.getProvinceName();
                    String cityName = StringUtils.isBlank(sysAreaVO.getCityName()) ? "" : sysAreaVO.getCityName();
                    String regionName = StringUtils.isBlank(sysAreaVO.getRegionName()) ? "" : sysAreaVO.getRegionName();
                    receiveAddressInfoVO.setAreaName(provinceName + cityName + regionName);
                }
            }
        }
        return AjaxResult.success(receiveAddressInfoList);
    }


    /**
     * 查询收货人地址信息
     *
     * @param id 收货人地址信息主键
     * @return 收货人地址信息
     */
    @Override
    public ReceiveAddressInfo selectReceiveAddressInfoById(Long id) {
        return nursingStationGoodsMapper.selectReceiveAddressInfoById(id);
    }

    /**
     * 新增收货人地址信息
     *
     * @param receiveAddressInfo 收货人地址信息
     * @return 结果
     */
    @Override
    public int insertReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo) {
        //设置创建人以及创建时间
        receiveAddressInfo.setCreateTime(LocalDateTime.now());
        receiveAddressInfo.setPatientId(receiveAddressInfo.getPatientId());
        if (StringUtils.isNotBlank(receiveAddressInfo.getReceivePhone())) {
            // 校验手机号是否正确
            boolean phone = regexUtil.regexPhone(receiveAddressInfo.getReceivePhone());
            if (BooleanUtils.isFalse(phone)) {
                throw new ServiceException("您输入的联系电话" + receiveAddressInfo.getReceivePhone() + "不正确，请重新输入！");
            }
        }
        //根据区域areaCode查询区域级别
        SysArea sysArea = sysAreaMapper.selectSysAreaById(null, receiveAddressInfo.getAreaCode());
        List<Integer> areaLevelList = Arrays.asList(PROVINCE_AREA_LEVEL, CITY_AREA_LEVEL);
        if (Objects.isNull(sysArea) || areaLevelList.contains(sysArea.getAreaLevel())) {
            throw new ServiceException("所在地区必须选择到所在区或者街道，请重新选择！");
        }
        return nursingStationGoodsMapper.insertReceiveAddressInfo(receiveAddressInfo);
    }


    /**
     * 修改收货人地址信息
     *
     * @param receiveAddressInfo 收货人地址信息
     * @return 结果
     */
    @Override
    public int updateReceiveAddressInfo(ReceiveAddressInfo receiveAddressInfo) {
        //设置修改人以及修改时间
        receiveAddressInfo.setUpdateTime(LocalDateTime.now());
        if (StringUtils.isNotBlank(receiveAddressInfo.getReceivePhone())) {
            // 校验手机号是否正确
            boolean phone = regexUtil.regexPhone(receiveAddressInfo.getReceivePhone());
            if (BooleanUtils.isFalse(phone)) {
                throw new ServiceException("您输入的联系电话" + receiveAddressInfo.getReceivePhone() + "不正确，请重新输入！");
            }
        }
        //根据区域areaCode查询区域级别
        SysArea sysArea = sysAreaMapper.selectSysAreaById(null, receiveAddressInfo.getAreaCode());
        List<Integer> areaLevelList = Arrays.asList(PROVINCE_AREA_LEVEL, CITY_AREA_LEVEL);
        if (Objects.isNull(sysArea) || areaLevelList.contains(sysArea.getAreaLevel())) {
            throw new ServiceException("所在地区必须选择到所在区或者街道，请重新选择！");
        }
        return nursingStationGoodsMapper.updateReceiveAddressInfo(receiveAddressInfo);
    }

    /**
     * 批量删除收货人地址信息
     *
     * @param ids 需要删除的收货人地址信息主键
     * @return 结果
     */
    @Override
    public int deleteReceiveAddressInfoByIds(Long[] ids) {
        return nursingStationGoodsMapper.deleteReceiveAddressInfoByIds(ids);
    }


    /**
     * 下级区域寻找上级区域
     *
     * @param areaCode 区域编码
     * @return com.xinyilu.base.domain.vo.sysarea.SysAreaVO
     **/
    @Override
    public SysAreaVO getSubordinateRegionsFindSuperiorRegions(String areaCode) {
        return nursingStationGoodsMapper.getSubordinateRegionsFindSuperiorRegions(areaCode);
    }

    /**
     * 新增商品订单以及详细信息
     *
     * @param goodsOrder 商品订单
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertNurseStationGoodsOrder(GoodsOrderStationDTO goodsOrder) {
        //校验优惠券等相关信息
        AjaxResult ajaxResult = checkAddGoodOrderParam(goodsOrder);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        //判断库存是否充足
        GoodsAttributeDetails goodsAttributeDetails = nursingStationGoodsMapper.selectGoodsAttributeDetailsGoodsStockById(goodsOrder.getGoodsAttributeDetailsId());
        if (Objects.isNull(goodsAttributeDetails.getGoodsStock()) || goodsAttributeDetails.getGoodsStock() == 0) {
            return AjaxResult.error("当前商品库存不足，无法购买！");
        }
        //库存数量
        AtomicInteger goodsStock = new AtomicInteger(goodsAttributeDetails.getGoodsStock());
        AtomicInteger goodsCount = new AtomicInteger(goodsOrder.getGoodsCount());
        if (goodsStock.get() < goodsCount.get()) {
            return AjaxResult.error("当前商品库存不足，无法购买！");
        }
        //生成订单信息
        String goodOrderNo = com.xinelu.common.utils.StringUtils.fillZeroByPatientId(goodsOrder.getPatientId(), 5) + System.nanoTime();
        this.insertGoodsOrder(goodsOrder, goodsCount, goodOrderNo);
        return AjaxResult.success(goodsOrderMapper.getGoodsOrderByOrderNo(goodOrderNo));
    }

    /**
     * 根据订单编号查询订单信息
     *
     * @param orderNo 订单信息编号
     * @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodsOrderPatient
     **/
    @Override
    public GoodsOrderPatient selectGoodsOrderPatient(String orderNo) {
        return nursingStationGoodsMapper.selectGoodsOrderPatient(orderNo);
    }

    /**
     * App和小程序确认收货
     *
     * @param orderNo 订单编号
     * @return 结果信息
     */
    @Override
    public AjaxResult confirmReceipt(String orderNo) {
        GoodsOrder goodsOrderByOrderNo = goodsOrderMapper.getGoodsOrderByOrderNo(orderNo);
        if (Objects.isNull(goodsOrderByOrderNo)) {
            return AjaxResult.error("当前订单信息不存在，请重新选择！");
        }
        if (!GooodsOrderStatusEnum.WAIT_RECEIVED_GOODS.getInfo().equals(goodsOrderByOrderNo.getOrderStatus())) {
            return AjaxResult.error("当前订单非待收货状态，无法确认收货！");
        }
        goodsOrderMapper.updateGoodsOrderStatus(GooodsOrderStatusEnum.RECEIVED_GOODS.getInfo(), orderNo);
        return AjaxResult.success();
    }

    /**
     * 微信小程序和会员App设置默认地址接口
     *
     * @param defaultAddressList 默认地址标识集合
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateDefaultAddress(List<UpdateDefaultAddressVO> defaultAddressList) {
        for (UpdateDefaultAddressVO updateDefaultAddressVO : defaultAddressList) {
            ReceiveAddressInfo receiveAddressInfo = new ReceiveAddressInfo();
            receiveAddressInfo.setId(updateDefaultAddressVO.getId());
            receiveAddressInfo.setUpdateTime(LocalDateTime.now());
            receiveAddressInfo.setDefaultAddressFlag(updateDefaultAddressVO.getDefaultAddressFlag());
            int updateReceiveCount = receiveAddressInfoMapper.updateReceiveAddressInfo(receiveAddressInfo);
            if (updateReceiveCount <= 0) {
                throw new ServiceException("设置默认收货地址失败，请联系管理员！");
            }
        }
        return AjaxResult.success();
    }

	/**
     * 根据当前分类id查询其下属所有子分类id集合
     *
     * @param categoryId 当前分类id
     * @return 子分类id集合
     */
    private List<Integer> getChildCategoryIds(Long categoryId) {
        //查询当前分类下属所有分类id集合
        String childrenCategoryIds = nursingStationGoodsMapper.getChildrenCategoryIds(categoryId);
        //分割 ，去除第一个“ ” 获取数据  转换类型
        String[] split;
        List<Integer> goodsCategoryIds = Lists.newArrayList();
        if (childrenCategoryIds.length() > 0) {
            split = StringUtils.split(childrenCategoryIds.substring(1), ",");
            goodsCategoryIds = Arrays.stream(split).map(Integer::valueOf).collect(Collectors.toList());
        }
        return goodsCategoryIds;
    }

    /**
     * 商品订单接口相关参数校验
     *
     * @param goodsOrder 商品订单信息
     * @return 校验结果
     */
    private AjaxResult checkAddGoodOrderParam(GoodsOrderStationDTO goodsOrder) {
        //判断当前会员信息是否存在
        PatientInfoVO patientInfo = patientInfoMapper.getPatientInfoById(goodsOrder.getPatientId());
        if (Objects.isNull(patientInfo)) {
            return AjaxResult.error("用户信息不存在，无法购买商品！");
        }
        if (Objects.nonNull(goodsOrder.getCouponId())) {
            //当前商品订单使用了优惠券
            PatientCouponReceiveVO patientCouponInfo = patientCouponReceiveMapper.getPatientCouponInfo(goodsOrder.getPatientId(), goodsOrder.getCouponId());
            if (Objects.isNull(patientCouponInfo)) {
                return AjaxResult.error("优惠券信息不存在，无法购买商品！");
            }
            //优惠券金额是否被篡改过
            if (Objects.nonNull(goodsOrder.getDiscountPrice()) && Objects.nonNull(patientCouponInfo.getCouponPrice()) && goodsOrder.getDiscountPrice().compareTo(patientCouponInfo.getCouponPrice()) != 0) {
                return AjaxResult.error("优惠券金额已被篡改过，无法使用'" + patientCouponInfo.getCouponTitle() + "'优惠券购买商品！");
            }
            //优惠券门槛是否被篡改过
            if (Objects.nonNull(goodsOrder.getCouponConsumePrice()) && Objects.nonNull(patientCouponInfo.getCouponConsumePrice()) && goodsOrder.getCouponConsumePrice().compareTo(patientCouponInfo.getCouponConsumePrice()) != 0) {
                return AjaxResult.error("优惠券使用门槛已被篡改过，无法使用'" + patientCouponInfo.getCouponTitle() + "'优惠券购买商品！");
            }
            //判断当前优惠券是否过期
            if (StringUtils.isNotBlank(patientCouponInfo.getUseStatus()) && CouponUseStatusEnum.USED.getInfo().equals(patientCouponInfo.getUseStatus())) {
                return AjaxResult.error("优惠券：'" + patientCouponInfo.getCouponTitle() + "'已使用，无法使用！");
            }
            boolean isUsedStatus = StringUtils.isNotBlank(patientCouponInfo.getUseStatus()) && CouponUseStatusEnum.EXPIRED.getInfo().equals(patientCouponInfo.getUseStatus());
            boolean expireTime = Objects.nonNull(patientCouponInfo.getExpirationEndTime()) && LocalDateTime.now().isAfter(patientCouponInfo.getExpirationEndTime());
            if (BooleanUtils.isTrue(isUsedStatus) || BooleanUtils.isTrue(expireTime)) {
                return AjaxResult.error("优惠券：'" + patientCouponInfo.getCouponTitle() + "'已过期，无法使用！");
            }
            //判断商品总金额是否大于使用优惠券使用门槛
            if (Objects.nonNull(goodsOrder.getGoodsCount()) && Objects.nonNull(goodsOrder.getGoodsPrice()) && Objects.nonNull(patientCouponInfo.getCouponConsumePrice())) {
                BigDecimal originalPrice = BigDecimal.valueOf(goodsOrder.getGoodsCount()).multiply(goodsOrder.getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN);
                if (Objects.nonNull(goodsOrder.getOriginalTotalPrice()) && originalPrice.compareTo(goodsOrder.getOriginalTotalPrice()) != 0) {
                    return AjaxResult.error("订单金额被篡改过，原始金额为：" + originalPrice + ", 篡改后金额为：" + goodsOrder.getOriginalTotalPrice() + "，无法购买！");
                }
                if (BooleanUtils.isFalse(originalPrice.compareTo(patientCouponInfo.getCouponConsumePrice()) >= 0)) {
                    return AjaxResult.error("订单金额未达到优惠券使用门槛，'" + patientCouponInfo.getCouponTitle() + "'优惠券无法使用！");
                }
            }
            //判断，商品数量 * 商品单价 - 优惠券金额 = 应付总价格
            if (Objects.nonNull(goodsOrder.getGoodsCount()) && Objects.nonNull(goodsOrder.getGoodsPrice()) && Objects.nonNull(goodsOrder.getDiscountPrice())) {
                BigDecimal originalPrice = BigDecimal.valueOf(goodsOrder.getGoodsCount()).multiply(goodsOrder.getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN);
                if (Objects.nonNull(goodsOrder.getOriginalTotalPrice()) && originalPrice.compareTo(goodsOrder.getOriginalTotalPrice()) != 0) {
                    return AjaxResult.error("订单金额被篡改过，原始金额为：" + originalPrice + ", 篡改后金额为：" + goodsOrder.getOriginalTotalPrice() + "，无法购买！");
                }
                BigDecimal totalPrice = originalPrice.subtract(goodsOrder.getDiscountPrice()).setScale(2, BigDecimal.ROUND_DOWN);
                if (totalPrice.compareTo(goodsOrder.getTotalPrice()) != 0) {
                    return AjaxResult.error("订单金额不正确，应付金额为：" + totalPrice + "元，支付金额为：" + goodsOrder.getTotalPrice() + "，无法购买！");
                }
            }
        } else {
            //未使用优惠券，计算：商品数量 * 商品单价 = 应付总价格
            if (Objects.nonNull(goodsOrder.getGoodsCount()) && Objects.nonNull(goodsOrder.getGoodsPrice()) && Objects.nonNull(goodsOrder.getTotalPrice())) {
                BigDecimal originalPrice = BigDecimal.valueOf(goodsOrder.getGoodsCount()).multiply(goodsOrder.getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN);
                if (Objects.nonNull(goodsOrder.getOriginalTotalPrice()) && originalPrice.compareTo(goodsOrder.getOriginalTotalPrice()) != 0) {
                    return AjaxResult.error("订单金额不正确，应付金额为：" + originalPrice + "元，支付金额为：" + goodsOrder.getOriginalTotalPrice() + "，无法购买！");
                }
                if (originalPrice.compareTo(goodsOrder.getTotalPrice()) != 0) {
                    return AjaxResult.error("订单金额不正确，应付金额为：" + originalPrice + "元，支付金额为：" + goodsOrder.getTotalPrice() + "，无法购买！");
                }
            }
        }
        return null;
    }

    /**
     * 商品订单接口-生成订单表和订单明细表信息
     *
     * @param goodsOrder  输入参数
     * @param goodsCount  库存原子数量
     * @param goodOrderNo 订单编号
     */
    private void insertGoodsOrder(GoodsOrderStationDTO goodsOrder, AtomicInteger goodsCount, String goodOrderNo) {
        //新增商品订单主表信息
        GoodsOrder good = new GoodsOrder();
        BeanUtils.copyBeanProp(good, goodsOrder);
        good.setPatientId(goodsOrder.getPatientId());
        good.setOrderNo(goodOrderNo);
        good.setOrderStatus(GooodsOrderStatusEnum.WAIT_PAY.getInfo());
        good.setRemark(StringUtils.isBlank(goodsOrder.getRemark()) ? "" : goodsOrder.getRemark());
        good.setOrderTime(LocalDateTime.now());
        good.setDelFlag(0);
        good.setOrderType(OrderTypeEnum.DIRECT_BUY.getInfo());
        good.setCreateTime(LocalDateTime.now());
        good.setOriginalTotalPrice(goodsOrder.getOriginalTotalPrice());
        int stationGoodsOrder = goodsOrderMapper.insertGoodsOrder(good);
        if (stationGoodsOrder <= 0) {
            throw new ServiceException("商品订单新增信息失败，请联系管理员！");
        }
        //新增商品订单明细表信息
        GoodsOrderDetails goodsOrderDetails = new GoodsOrderDetails();
        BeanUtils.copyBeanProp(goodsOrderDetails, goodsOrder);
        goodsOrderDetails.setGoodsOrderId(good.getId());
        goodsOrderDetails.setOrderNo(goodOrderNo);
        goodsOrderDetails.setDelFlag(0);
        goodsOrderDetails.setCreateTime(LocalDateTime.now());
        if (Objects.nonNull(goodsOrder.getCouponId())) {
            goodsOrderDetails.setCouponId(goodsOrder.getCouponId());
        }
        if (StringUtils.isNotBlank(goodsOrder.getCouponTitle())) {
            goodsOrderDetails.setCouponTitle(goodsOrderDetails.getCouponTitle());
        }
        if (Objects.nonNull(goodsOrderDetails.getDiscountPrice())) {
            goodsOrderDetails.setDiscountPrice(goodsOrderDetails.getDiscountPrice());
        }
        int orderDetails = goodsOrderDetailsMapper.insertGoodsOrderDetails(goodsOrderDetails);
        if (orderDetails <= 0) {
            throw new ServiceException("商品订单明细新增信息失败，请联系管理员！");
        }
        //修改优惠券的状态
        if (Objects.nonNull(goodsOrder.getCouponId())) {
            patientCouponReceiveMapper.updatePatientCouponUseStatus(goodsOrder.getPatientId(), goodsOrder.getCouponId(), CouponUseStatusEnum.USED.getInfo());
        }
        //减少库存数量
        String goodsStockKey = Constants.BUY_GOODS_REDUCE_STOCK_KEY + goodOrderNo + "_" + goodsOrderDetails.getId();
        boolean tryLock = redisDistributedLockUtils.tryLock(goodsStockKey, 5);
        if (!tryLock) {
            log.info("商品订单获取Redis锁失败，订单编号 =====> {}", goodOrderNo);
            throw new ServiceException("减少库存信息失败，请联系管理员！");
        }
        try {
            //减少库存数量
            int updateCount = goodsAttributeDetailsMapper.reduceGoodsStockCount(goodsOrder.getGoodsAttributeDetailsId(), goodsCount.get());
            if (updateCount < 1) {
                log.info("减少库存数量失败，订单编号：{}，商品属性明细id：{}，库存数量：{}", goodOrderNo, goodsOrder.getGoodsAttributeDetailsId(), goodsCount.get());
            }
        } catch (Exception e) {
            log.error("减少库存信息失败，失败原因为 ====> {}", e.getMessage());
            throw new ServiceException(e.getMessage());
        } finally {
            redisDistributedLockUtils.unlock(goodsStockKey);
        }
    }
}
