| | |
| | | package com.ruoyi.order.service.impl; |
| | | |
| | | import cn.hutool.http.HttpRequest; |
| | | import cn.hutool.http.HttpUtil; |
| | | import cn.hutool.json.JSONUtil; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.api.feignClient.*; |
| | | import com.ruoyi.account.api.model.*; |
| | | import com.ruoyi.account.api.vo.CouponInfoVo; |
| | | import com.ruoyi.account.api.vo.PaymentUserCoupon; |
| | | import com.ruoyi.account.api.vo.PaymentUserCouponVo; |
| | | |
| | | import com.ruoyi.common.core.constant.ExpressCompanyMap; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.HttpUtils; |
| | | |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.core.utils.uuid.QRCodeGenerator; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.order.enums.OrderStatus; |
| | | import com.ruoyi.order.event.ConfirmDeliveryEvent; |
| | | |
| | | import com.ruoyi.order.mapper.OrderGoodMapper; |
| | | import com.ruoyi.order.mapper.OrderMapper; |
| | | import com.ruoyi.order.model.Order; |
| | | import com.ruoyi.order.model.OrderGood; |
| | | import com.ruoyi.order.service.OrderGoodService; |
| | | import com.ruoyi.order.service.OrderService; |
| | | import com.ruoyi.order.util.ExpressDeliveryUtil; |
| | | |
| | | import com.ruoyi.order.util.payment.PaymentUtil; |
| | | import com.ruoyi.order.util.payment.model.RefundCallbackResult; |
| | | import com.ruoyi.order.util.payment.model.RefundResult; |
| | | import com.ruoyi.order.util.vo.MapTrackKD100Vo; |
| | | import com.ruoyi.order.util.vo.QueryKD100ListVo; |
| | | import com.ruoyi.order.util.payment.model.*; |
| | | |
| | | import com.ruoyi.order.vo.*; |
| | | import com.ruoyi.other.api.domain.*; |
| | | import com.ruoyi.other.api.feignClient.*; |
| | |
| | | import com.ruoyi.system.api.feignClient.SysConfigClient; |
| | | import com.ruoyi.system.api.feignClient.SysUserClient; |
| | | import com.ruoyi.system.api.model.LoginUser; |
| | | import lombok.SneakyThrows; |
| | | import org.apache.poi.ss.usermodel.CellType; |
| | | import org.apache.poi.ss.usermodel.Row; |
| | | import org.apache.poi.ss.usermodel.Sheet; |
| | | import org.apache.poi.ss.usermodel.Workbook; |
| | | import org.apache.poi.xssf.streaming.SXSSFWorkbook; |
| | | import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
| | | import org.jetbrains.annotations.Nullable; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.net.MalformedURLException; |
| | | import java.net.URL; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.OffsetDateTime; |
| | | |
| | | import java.time.ZoneOffset; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | | |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | * @author luodangjia |
| | | * @since 2024-11-21 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService { |
| | | @Resource |
| | |
| | | private OrderGoodService orderGoodService; |
| | | |
| | | @Resource |
| | | private UserPointClient userPointClient; |
| | | |
| | | @Resource |
| | | private RedisTemplate redisTemplate; |
| | | |
| | | @Resource |
| | | private ShopBalanceStatment shopBalanceStatment; |
| | | |
| | | @Resource |
| | | private SystemConfigClient systemConfigClient; |
| | |
| | | } |
| | | |
| | | // 商品 |
| | | List<OrderGood> orderGoods = orderGoodMapper.selectList(new LambdaQueryWrapper<OrderGood>() |
| | | .eq(OrderGood::getOrderId, orderId)); |
| | | OrderGood orderGood = orderGoodMapper.selectOne(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, orderId)); |
| | | String goodJson = orderGood.getGoodJson(); |
| | | Goods goods = JSONObject.parseObject(goodJson, Goods.class); |
| | | |
| | | List<OrderGoodsVO> goodsList = new ArrayList<>(); |
| | | for (OrderGood orderGood : orderGoods) { |
| | | String goodJson = orderGood.getGoodJson(); |
| | | Goods goods = JSONObject.parseObject(goodJson, Goods.class); |
| | | OrderGoodsVO orderGoodsVO = new OrderGoodsVO(); |
| | | orderGoodsVO.setGoodsId(orderGood.getGoodsId()); |
| | | orderGoodsVO.setNum(orderGood.getNum()); |
| | | orderGoodsVO.setGoodsName(goods.getName()); |
| | | orderGoodsVO.setType(goods.getType()); |
| | | orderGoodsVO.setGoodsPic(goods.getHomePagePicture()); |
| | | orderGoodsVO.setSellingPrice(orderGood.getSellingPrice()); |
| | | orderGoodsVO.setIntegral(orderGood.getIntegral()); |
| | | orderGoodsVO.setOriginalPrice(goods.getOriginalPrice()); |
| | | goodsList.add(orderGoodsVO); |
| | | } |
| | | // 优惠券 |
| | | String couponJson = order.getCouponJson(); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | if (StringUtils.isNotEmpty(couponJson)) { |
| | | jsonObject = JSONObject.parseObject(couponJson); |
| | | } |
| | | OrderGoodsVO orderGoodsVO = new OrderGoodsVO(); |
| | | BeanUtils.copyProperties(orderGood, orderGoodsVO); |
| | | orderGoodsVO.setGoodsName(goods.getName()); |
| | | orderGoodsVO.setGoodsPic(goods.getHomePagePicture()); |
| | | |
| | | OrderDetailVO orderDetailVO = new OrderDetailVO(); |
| | | orderDetailVO.setDistributionMode(order.getDistributionMode()); |
| | | orderDetailVO.setOrderGoodsVO(orderGoodsVO); |
| | | Shop shop = shopR.getData(); |
| | | orderDetailVO.setId(order.getId()); |
| | | orderDetailVO.setOrderStatus(order.getOrderStatus()); |
| | |
| | | orderDetailVO.setOrderNumber(order.getOrderNumber()); |
| | | orderDetailVO.setCreateTime(order.getCreateTime()); |
| | | orderDetailVO.setTotalAmount(order.getTotalAmount()); |
| | | orderDetailVO.setCouponName(jsonObject.getString("couponName")); |
| | | orderDetailVO.setCouponAmount(order.getDiscountTotalAmount()); |
| | | orderDetailVO.setExpressAmount(order.getExpressAmount()); |
| | | orderDetailVO.setPointAmount(order.getGetPoint()); |
| | | orderDetailVO.setPaymentAmount(order.getPaymentAmount()); |
| | | orderDetailVO.setGoodsList(goodsList); |
| | | orderDetailVO.setShopName(shop.getName()); |
| | | orderDetailVO.setShopAddress(shop.getAddress()); |
| | | orderDetailVO.setLongitude(shop.getLongitude()); |
| | | orderDetailVO.setLatitude(shop.getLatitude()); |
| | | orderDetailVO.setShopId(shop.getId()); |
| | | if (StringUtils.isNotEmpty(order.getExpressResult())) { |
| | | MapTrackKD100Vo mapTrackKD100Vo = JSON.parseObject(order.getExpressResult(), MapTrackKD100Vo.class); |
| | | List<QueryKD100ListVo> data = mapTrackKD100Vo.getData(); |
| | | orderDetailVO.setExpress(null != data && data.size() > 0 ? data.get(0).getContext() : ""); |
| | | } |
| | | |
| | | // 生成核销码BASE64 |
| | | try { |
| | | String base64 = QRCodeGenerator.generateQRCodeBase64(String.valueOf(order.getId()), 124, 124); |
| | |
| | | order.setEndTime(LocalDateTime.now()); |
| | | order.setCancellerAppUserId(loginUserApplet.getUserid()); |
| | | if (StringUtils.isNotEmpty(technicianId) && !"null".equals(technicianId)) { |
| | | order.setTechnicianId(Integer.valueOf(technicianId)); |
| | | // order.setTechnicianId(Integer.valueOf(technicianId)); |
| | | } |
| | | orderMapper.updateById(order); |
| | | } |
| | |
| | | return R.fail("订单取消失败"); |
| | | } |
| | | order.setOrderStatus(5); |
| | | //todo 商品销售数量 |
| | | R r = refundPayMoney(order); |
| | | if (200 == r.getCode()) { |
| | | this.updateById(order); |
| | | } |
| | | R r2 = userPointClient.deleteUserPointCopy(orderId, Arrays.asList(8));//门店业绩 |
| | | if (200 != r2.getCode()) { // 项目没有分布式事务,此处报错可能会导致数据不一致 |
| | | throw new RuntimeException("订单取消失败"); |
| | | } |
| | | return r; |
| | | } |
| | |
| | | */ |
| | | public R refundPayMoney(Order order) { |
| | | //开始退款 |
| | | Integer payMethod = order.getPayMethod(); |
| | | BigDecimal expressAmount = order.getExpressAmount() == null ? BigDecimal.ZERO : order.getExpressAmount(); |
| | | BigDecimal paymentAmount = order.getPaymentAmount().add(expressAmount); |
| | | |
| | | BigDecimal paymentAmount = order.getPaymentAmount(); |
| | | AppUser appUser = appUserClient.getAppUserById(order.getAppUserId()); |
| | | if (1 == payMethod) { |
| | | |
| | | if (BigDecimal.ZERO.compareTo(order.getPaymentAmount()) < 0) {//支付的金额是否大于0 |
| | | //微信退款 |
| | | RefundResult refund = PaymentUtil.refund(order.getOrderNumber(), "R" + order.getOrderNumber(), paymentAmount.doubleValue(), "/order/order/refundPayMoneyCallback"); |
| | | if ("100".equals(refund.getRa_Status())) { |
| | |
| | | return R.fail(refund.getRc_CodeMsg()); |
| | | } |
| | | } |
| | | if (2 == payMethod) { |
| | | BigDecimal balance = appUser.getBalance(); |
| | | appUser.setBalance(balance.add(paymentAmount).setScale(2, RoundingMode.HALF_EVEN)); |
| | | appUser.setShopAmount(appUser.getShopAmount().subtract(paymentAmount).setScale(2, RoundingMode.HALF_EVEN)); |
| | | //查询最后一次的消费订单 |
| | | Order order1 = this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getAppUserId, order.getAppUserId()).eq(Order::getPayStatus, 2) |
| | | .eq(Order::getDelFlag, 0).in(Order::getOrderStatus, Arrays.asList(1, 2, 3, 4, 8)).ne(Order::getId, order.getId()).last(" order by create_time desc limit 0, 1")); |
| | | if (null != order1) { |
| | | appUser.setLastShopTime(order1.getCreateTime()); |
| | | } else { |
| | | appUser.setLastShopTime(null); |
| | | } |
| | | } |
| | | if (3 == payMethod) { |
| | | //开始运费退款,积分支付,运费是单独进行支付的,所以需要单独退款 |
| | | if (null != order.getExpressAmount() && BigDecimal.ZERO.compareTo(order.getExpressAmount()) < 0) { |
| | | if (1 == order.getExpressPayMethod()) { |
| | | //微信退款 |
| | | RefundResult refund = PaymentUtil.refund(order.getOrderNumber(), "R" + order.getOrderNumber(), expressAmount.doubleValue(), "/order/order/refundExpressPayMoneyCallback"); |
| | | if ("100".equals(refund.getRa_Status())) { |
| | | order.setRefundStatus(1); |
| | | return R.ok(); |
| | | } else { |
| | | return R.fail(refund.getRc_CodeMsg()); |
| | | } |
| | | } |
| | | if (2 == order.getExpressPayMethod()) { |
| | | BigDecimal balance = appUser.getBalance(); |
| | | appUser.setBalance(balance.add(expressAmount).setScale(2, RoundingMode.HALF_EVEN)); |
| | | } |
| | | } |
| | | |
| | | if (0 != order.getPoint()) {//使用的积分是否为0 |
| | | Integer lavePoint = appUser.getLavePoint(); |
| | | //积分退款 |
| | | appUser.setLavePoint(appUser.getLavePoint() + order.getPoint()); |
| | |
| | | UserPoint userPoint1 = new UserPoint(); |
| | | userPoint1.setType(11); |
| | | userPoint1.setObjectId(order.getId()); |
| | | List<UserPoint> data = userPointClient.getUserPointList(userPoint1).getData();//用户积分流水 |
| | | Integer transferablePoint = order.getPoint(); |
| | | if (data.size() > 0) { |
| | | UserPoint userPoint = data.get(0); |
| | | transferablePoint = Integer.valueOf(userPoint.getExtention()); |
| | | } |
| | | appUser.setTransferablePoint(appUser.getTransferablePoint() + transferablePoint); |
| | | |
| | | //构建积分流水明细 |
| | | if (order.getPoint() > 0) { |
| | | UserPoint userPoint = new UserPoint(); |
| | | userPoint.setType(11); |
| | | userPoint.setHistoricalPoint(lavePoint); |
| | | userPoint.setVariablePoint(order.getPoint()); |
| | | userPoint.setBalance(appUser.getLavePoint()); |
| | | userPoint.setCreateTime(LocalDateTime.now()); |
| | | userPoint.setAppUserId(order.getAppUserId()); |
| | | userPoint.setObjectId(order.getId()); |
| | | userPointClient.saveUserPoint(userPoint); |
| | | } |
| | | appUserClient.editAppUserById(appUser); |
| | | } |
| | | |
| | | order.setRefundStatus(2); |
| | | order.setRefundTime(LocalDateTime.now()); |
| | | orderMapper.updateById(order); |
| | | //todo 退款后店铺积分流水以及退款前店铺积分流水 |
| | | /* shopPointClient.deleteShopPointCopy(order.getId(), Arrays.asList(1,2,3)); |
| | | shopBalanceStatementClient.deleteShopBalanceStatementCopy(order.getId(), Arrays.asList(1,2,3)); |
| | | appUserGiveawayTemporaryClient.delAppUserGiveawayTemporary(order.getId()); |
| | | shopGiveawayTemporaryClient.delShopGiveawayTemporary(order.getId());*/ |
| | | return R.ok(); |
| | | } |
| | | |
| | |
| | | orderInfo.setUserName(appUser.getName()); |
| | | orderInfo.setPhone(appUser.getPhone()); |
| | | } |
| | | orderInfo.setOrderType(order.getOrderType() == 1 ? "服务" : (StringUtils.isNotEmpty(order.getAddressJson()) ? "单品-快递配送" : "单品-上门自提")); |
| | | |
| | | Shop shop = shopClient.getShopById(order.getShopId()).getData(); |
| | | if (null != shop) { |
| | | orderInfo.setShopName(shop.getName()); |
| | | } |
| | | orderInfo.setPaymentMethod(order.getPayMethod()); |
| | | orderInfo.setTotalAmount(order.getTotalAmount()); |
| | | orderInfo.setDiscountAmount(order.getDiscountTotalAmount()); |
| | | orderInfo.setExpressAmount(order.getExpressAmount()); |
| | | |
| | | orderInfo.setPaymentAmount(order.getPaymentAmount()); |
| | | orderInfo.setGetPoint(order.getGetPoint()); |
| | | if (StringUtils.isNotEmpty(order.getExpressJson()) && !order.getExpressJson().equals("NULL")){ |
| | | JSONObject jsonObject = JSON.parseObject(order.getExpressJson()); |
| | | orderInfo.setExpressCompany(jsonObject.getString("com")); |
| | | orderInfo.setExpressNumber(jsonObject.getString("num")); |
| | | } |
| | | |
| | | |
| | | List<OrderGood> orderGoods = orderGoodMapper.selectList(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, orderId).eq(OrderGood::getDelFlag, 0)); |
| | | int sum = orderGoods.stream().mapToInt(OrderGood::getNum).sum(); |
| | |
| | | confirmOrderVo.setShopName(shop.getShopName()); |
| | | confirmOrderVo.setPurchaseLimitNum(good.getPurchaseLimit()); |
| | | confirmOrderVo.setOriginalPrice(good.getOriginalPrice()); |
| | | //todo 实时计算用户可用积分 |
| | | |
| | | |
| | | confirmOrderVo.setResidualPoint(appUser.getAvailablePoint()); |
| | | //插入价格 |
| | |
| | | confirmOrderVo.setPoint(good.getIntegral()); |
| | | |
| | | //计算活动价格信息 |
| | | Price price = getPrice(goodId, 1); |
| | | Price price = getPrice(goodId); |
| | | if (null != price) { |
| | | confirmOrderVo.setCash(price.getCash()); |
| | | confirmOrderVo.setOrderPoint(price.getPoint()); |
| | |
| | | confirmOrderVo.setIsPurchaseLimit(false); |
| | | confirmOrderVo.setPurchaseLimitNum(-1); |
| | | }else{ |
| | | //todo 查当前用户的订单 |
| | | // 查当前用户的订单 |
| | | List<Order> orders = this.list(new LambdaQueryWrapper<Order>().eq(Order::getAppUserId, appUser.getId()).eq(Order::getDelFlag, 0).in(Order::getOrderStatus, Arrays.asList(4, 8))); |
| | | List<Long> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList()); |
| | | int sum = 0; |
| | |
| | | |
| | | return confirmOrderVo; |
| | | } |
| | | |
| | | /** |
| | | * 订单支付 |
| | | * |
| | | */ |
| | | @Override |
| | | public R orderPayment(OrderPayment orderPayment) { |
| | | Long userid = tokenService.getLoginUserApplet().getUserid(); |
| | | AppUser appUser = appUserClient.getAppUserById(userid); |
| | | int type=1;//商品类型 1=普通商品,2=秒杀商品 |
| | | //商品信息 |
| | | Goods goods = goodsClient.getGoodsById(orderPayment.getGoodId()).getData(); |
| | | if (null == goods || 1==goods.getDelFlag()){ |
| | | return R.fail( "商品不存在"); |
| | | } |
| | | if(goods.getStatus() == 1){ |
| | | return R.fail(goods.getName() + "商品已被下架"); |
| | | } |
| | | |
| | | //是否在秒杀活动中 |
| | | GetSeckillActivityInfo info = new GetSeckillActivityInfo(); |
| | | info.setGoodsId(orderPayment.getGoodId()); |
| | | GoodsSeckill goodsSeckill = seckillActivityInfoClient.getSeckillActivityInfo(info).getData(); |
| | | |
| | | if (null != goodsSeckill){ |
| | | //秒杀商品 |
| | | type=2; |
| | | //判断当前数量是否已经超出限购数量(需要计算已经购买的数量) |
| | | Integer goodsSaleNum = orderMapper.getGoodsSaleNum(orderPayment.getGoodId(), 2, userid);//已购买数量 |
| | | SeckillActivityInfo activityInfo = seckillActivityInfoClient.getSeckillActivityInfoById(goodsSeckill.getSeckillActivityInfoId()).getData(); |
| | | if(null != activityInfo.getMaxNum() && -1 != activityInfo.getMaxNum() && (goodsSaleNum + 1) > activityInfo.getMaxNum()){ |
| | | return R.fail(goods.getName() + "已超出秒杀活动购买上限"); |
| | | } |
| | | //价格 |
| | | goods.setSellingPrice(goodsSeckill.getSellingPrice());//秒杀活动价格 |
| | | goods.setIntegral(goodsSeckill.getIntegral());//秒杀活动积分价格 |
| | | }else { |
| | | //普通商品 |
| | | //判断当前数量是否已经超出限购数量(需要计算已经购买的数量) |
| | | Integer goodsSaleNum = orderMapper.getGoodsSaleNum(orderPayment.getGoodId(), 1, userid);//已购买数量 |
| | | //普通商品 |
| | | if(null != goods.getPurchaseLimit() && -1 != goods.getPurchaseLimit() && (goodsSaleNum + 1) > goods.getPurchaseLimit()){ |
| | | return R.fail(goods.getName() + "已超出购买上限"); |
| | | } |
| | | } |
| | | |
| | | //判断支付方式是否正确 |
| | | if(1 != orderPayment.getPaymentType() && 3 != orderPayment.getPaymentType()){ |
| | | return R.fail("支付方式不正确"); |
| | | } |
| | | |
| | | //现金支付的订单总金额 |
| | | BigDecimal orderMoney = BigDecimal.ZERO; |
| | | //积分支付的订单积分 |
| | | Integer orderPoint = 0; |
| | | |
| | | //现金的实际支付金额 |
| | | BigDecimal paymentMoney = BigDecimal.ZERO; |
| | | //积分抵扣金额 |
| | | BigDecimal pointDeductionAmount = BigDecimal.ZERO; |
| | | |
| | | if(3 != orderPayment.getPaymentType()){ |
| | | //现金支付 |
| | | orderMoney = goods.getSellingPrice(); |
| | | paymentMoney=orderMoney.setScale(2, RoundingMode.HALF_EVEN);; |
| | | |
| | | //是否使用积分抵扣 |
| | | if (orderPayment.getIsPointDeduction() == 1) { |
| | | //积分抵扣金额 |
| | | Integer availablePoint = appUser.getAvailablePoint();//用户可用积分 |
| | | BigDecimal maxPointDeductionAmount = getCashByPoint(availablePoint);//最大可抵扣金额 |
| | | pointDeductionAmount=maxPointDeductionAmount.min(orderMoney);//实际抵扣金额 |
| | | // 计算实际支付金额 |
| | | paymentMoney = orderMoney.subtract(pointDeductionAmount).setScale(2, RoundingMode.HALF_EVEN); |
| | | //计算消耗积分 |
| | | orderPoint=getPoint(pointDeductionAmount); |
| | | } |
| | | }else{ |
| | | //积分支付 |
| | | orderPoint=goods.getIntegral(); |
| | | Integer availablePoint = appUser.getAvailablePoint();//用户可用积分 |
| | | if(availablePoint.compareTo(orderPoint) < 0){ |
| | | return R.fail("账户可用积分不足"); |
| | | } |
| | | } |
| | | //构建订单 |
| | | Order order = new Order(); |
| | | order.setAppUserId(appUser.getId()); |
| | | order.setNum(1); |
| | | order.setGoodPics(goods.getHomePagePicture()); |
| | | order.setGoodName(goods.getName()); |
| | | order.setOrderStatus( 3 );//待使用 |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | order.setOrderNumber("QJS" + getNumber(3) + sdf.format(new Date())); |
| | | order.setTotalAmount(orderMoney.setScale(2, RoundingMode.HALF_EVEN));//订单总金额 |
| | | order.setPointDeductionAmount(pointDeductionAmount.setScale(2, RoundingMode.HALF_EVEN)); |
| | | order.setPaymentAmount(paymentMoney);//实际支付价格 |
| | | order.setPoint(orderPoint);//使用积分 |
| | | order.setPayMethod(orderPayment.getPaymentType());//支付方式 |
| | | order.setPayStatus(1); |
| | | order.setShopId(orderPayment.getShopId()); |
| | | order.setDelFlag(0); |
| | | order.setCreateTime(LocalDateTime.now()); |
| | | |
| | | orderMapper.insert(order); |
| | | |
| | | //构建订单明细数据 |
| | | OrderGood orderGood = new OrderGood(); |
| | | orderGood.setGoodsId(goods.getId()); |
| | | orderGood.setOrderId(order.getId()); |
| | | orderGood.setNum(1); |
| | | orderGood.setType(type); |
| | | if (2==type){ |
| | | orderGood.setSeckillJson(JSON.toJSONString(goodsSeckill)); |
| | | } |
| | | orderGood.setGoodJson(JSON.toJSONString(goods)); |
| | | orderGood.setDelFlag(0); |
| | | orderGood.setCreateTime(LocalDateTime.now()); |
| | | orderGood.setCashPayment(orderPayment.getPaymentType()==1 ? 1 : 0); |
| | | orderGood.setPointPayment(orderPayment.getPaymentType()==3 ? 1 : 0); |
| | | orderGood.setSellingPrice(goods.getSellingPrice()); |
| | | orderGood.setIntegral(goods.getIntegral()); |
| | | orderGoodService.save(orderGood); |
| | | |
| | | //开始构建支付信息 |
| | | if(BigDecimal.ZERO.compareTo(paymentMoney) > 0){ |
| | | paymentMoney = BigDecimal.ZERO; |
| | | } |
| | | //判断积分是否为零,积分支付 |
| | | if (0 != order.getPoint()){ |
| | | //积分支付 |
| | | Integer lavePoint = appUser.getLavePoint(); |
| | | //扣减订单支付积分 |
| | | appUser.setLavePoint(appUser.getLavePoint() - orderPoint); |
| | | appUser.setAvailablePoint(appUser.getAvailablePoint() - orderPoint); |
| | | //可转赠积分 |
| | | Integer transferablePoint = appUser.getTransferablePoint(); |
| | | Integer tra = 0; |
| | | if(transferablePoint > 0){ |
| | | tra = transferablePoint - orderPoint; |
| | | appUser.setTransferablePoint(tra >= 0 ? tra : 0); |
| | | }else{ |
| | | appUser.setTransferablePoint(appUser.getTransferablePoint() - orderPoint); |
| | | } |
| | | //构建积分流水记录 |
| | | if(orderPoint > 0){ |
| | | UserPoint userPoint = new UserPoint(); |
| | | userPoint.setType(11); |
| | | userPoint.setHistoricalPoint(lavePoint); |
| | | userPoint.setVariablePoint(orderPoint); |
| | | userPoint.setBalance(appUser.getLavePoint()); |
| | | userPoint.setCreateTime(LocalDateTime.now()); |
| | | userPoint.setAppUserId(appUser.getId()); |
| | | userPoint.setObjectId(order.getId()); |
| | | userPoint.setExtention((tra >= 0 ? orderPoint : transferablePoint) + ""); |
| | | userPointClient.saveUserPoint(userPoint); |
| | | } |
| | | |
| | | appUser.setLastShopTime(LocalDateTime.now()); |
| | | appUserClient.editAppUserById(appUser); |
| | | /* //变更等级 |
| | | applicationEventPublisher.publishEvent(new PayEvent(JSON.toJSONString(appUser)));*/ |
| | | |
| | | } |
| | | //判断需要支付的金额是否大于0 |
| | | if ( BigDecimal.ZERO.compareTo(paymentMoney) < 0){ |
| | | //调起微信支付 |
| | | String goodsNames = goods.getName(); |
| | | UniPayResult uniPayResult = PaymentUtil.uniPay(order.getOrderNumber(), paymentMoney.doubleValue(), "购买单品商品", |
| | | goodsNames, "", "/order/order/orderPaymentCallback", appUser.getWxOpenid(), null); |
| | | if(null == uniPayResult || !"100".equals(uniPayResult.getRa_Code())){ |
| | | return R.fail(null == uniPayResult ? "支付失败" : uniPayResult.getRb_CodeMsg()); |
| | | } |
| | | String rc_result = uniPayResult.getRc_Result(); |
| | | JSONObject jsonObject = JSON.parseObject(rc_result); |
| | | jsonObject.put("orderId", order.getId().toString()); |
| | | //将支付数据添加到redis队列中,便于定时任务去校验是否完成支付,没有完成支付支付,15分钟后关闭订单。 |
| | | long second = LocalDateTime.now().plusMinutes(15).toEpochSecond(ZoneOffset.UTC); |
| | | redisTemplate.opsForZSet().add("OrderPayment", order.getOrderNumber(), second); |
| | | return R.ok(jsonObject.toJSONString()); |
| | | |
| | | } |
| | | |
| | | //不需要微信支付,直接修改订支付状态 |
| | | order.setPayStatus(2); |
| | | orderMapper.updateById(order); |
| | | //商品销量增加 |
| | | goodsClient.editGoodsNum(orderGood.getGoodsId(), 1); |
| | | |
| | | //todo 门店增加冻结资金 |
| | | |
| | | return R.ok(order.getId().toString()); |
| | | } |
| | | |
| | | /** |
| | | * 订单支付回调通知 |
| | | */ |
| | | @Override |
| | | public R orderPaymentCallback(UniPayCallbackResult uniPayCallbackResult) { |
| | | Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, uniPayCallbackResult.getR2_OrderNo())); |
| | | if(null == order || order.getPayStatus() == 2){ |
| | | return R.ok(); |
| | | } |
| | | |
| | | AppUser appUser = appUserClient.getAppUserById(order.getAppUserId()); |
| | | BigDecimal paymentMoney = order.getPaymentAmount(); |
| | | //构建积分流水记录 |
| | | appUser.setShopAmount(appUser.getShopAmount().add(paymentMoney).setScale(2, RoundingMode.HALF_EVEN));//消费总金额 |
| | | appUser.setLastShopTime(LocalDateTime.now()); |
| | | appUserClient.editAppUserById(appUser); |
| | | |
| | | //修改订支付状态 |
| | | order.setPayStatus(2); |
| | | //待使用 |
| | | order.setOrderStatus(3); |
| | | String r7TrxNo = uniPayCallbackResult.getR9_BankTrxNo(); |
| | | order.setSerialNumber(r7TrxNo); |
| | | orderMapper.updateById(order); |
| | | |
| | | //商店余额改变,增加冻结余额 |
| | | Shop shop = shopClient.getShopById(order.getShopId()).getData(); |
| | | |
| | | |
| | | |
| | | //商品销量增加 |
| | | OrderGood orderGood = orderGoodService.getOne(new LambdaQueryWrapper<OrderGood>().eq(OrderGood::getOrderId, order.getId())); |
| | | goodsClient.editGoodsNum(orderGood.getGoodsId(), 1); |
| | | |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 定时任务关闭订单 |
| | | */ |
| | | @Override |
| | | public void closeOrder() { |
| | | //订单支付数据 |
| | | long second = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC); |
| | | Set<String> orderPayment = redisTemplate.opsForZSet().rangeByScore("OrderPayment", 0, second); |
| | | if(orderPayment.size() > 0){ |
| | | List<Order> list = orderMapper.selectList(new LambdaQueryWrapper<Order>().in(Order::getOrderNumber, orderPayment)); |
| | | for (Order order : list) { |
| | | if(null == order || order.getPayStatus() != 1){ |
| | | redisTemplate.opsForZSet().remove("OrderPayment", order.getOrderNumber()); |
| | | continue; |
| | | } |
| | | //开始执行关闭订单操作 |
| | | CloseOrderResult closeOrderResult = PaymentUtil.closeOrder(order.getOrderNumber()); |
| | | if((null == closeOrderResult || !closeOrderResult.getRa_Status().equals("100")) && |
| | | Arrays.asList("0", "4", "101", "10080000", "10080002", "10083004", "10083005").contains(closeOrderResult.getRb_Code())){ |
| | | redisTemplate.opsForZSet().add("OrderPayment", order.getOrderNumber(), 0); |
| | | log.error("关闭订单失败:{}---->{}", order.getOrderNumber(), JSON.toJSONString(closeOrderResult)); |
| | | } |
| | | redisTemplate.opsForZSet().remove("OrderPayment", order.getOrderNumber()); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | public String getNumber(Integer size){ |
| | | StringBuilder str = new StringBuilder(); |
| | | for (int i = 0; i < size; i++) { |
| | | str.append(Double.valueOf(Math.random() * 10).intValue()); |
| | | } |
| | | return str.toString(); |
| | | } |
| | | /** |
| | | * 根据商品的价格配置体系获取商品当前的价格 |
| | | * @param goodsId |
| | | * @param type 1普通商品,2秒杀商品 |
| | | * @return |
| | | */ |
| | | public Price getPrice( Integer goodsId, Integer type){ |
| | | //判断是否有在秒杀活动时间中 |
| | | public Price getPrice( Integer goodsId){ |
| | | //判断是否有在秒杀活动时间中的商品 |
| | | Price price = new Price(); |
| | | GetSeckillActivityInfo getSeckillActivityInfo = new GetSeckillActivityInfo(); |
| | | getSeckillActivityInfo.setGoodsId(goodsId); |
| | | GoodsSeckill goodsSeckill = seckillActivityInfoClient.getSeckillActivityInfo(getSeckillActivityInfo).getData(); |
| | | //没有秒杀活动或者添加的普通商品则使用秒杀活动价格 |
| | | if(null == goodsSeckill || type == 1){ |
| | | //没有秒杀活动 |
| | | if(null == goodsSeckill ){ |
| | | return null; |
| | | } |
| | | //秒杀活动价格 |
| | | price.setCash(goodsSeckill.getSellingPrice()); |
| | | //计算对应积分 |
| | | price.setPoint(getPoint(price.getCash())); |
| | | //结束时间 |
| | | price.setEndTimeStamp(goodsSeckill.getEndTime()); |
| | | return price; |
| | | } |