From 6269dc7a50d5028fa616b339cfe790b6e0d5d16e Mon Sep 17 00:00:00 2001 From: xin <1099200748@qq.com> Date: Wed, 16 Jul 2025 18:20:58 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' into xin --- oying-system/src/main/java/com/oying/modules/sh/service/impl/OrderServiceImpl.java | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 275 insertions(+), 24 deletions(-) diff --git a/oying-system/src/main/java/com/oying/modules/sh/service/impl/OrderServiceImpl.java b/oying-system/src/main/java/com/oying/modules/sh/service/impl/OrderServiceImpl.java index 79ddf58..6042c17 100644 --- a/oying-system/src/main/java/com/oying/modules/sh/service/impl/OrderServiceImpl.java +++ b/oying-system/src/main/java/com/oying/modules/sh/service/impl/OrderServiceImpl.java @@ -1,60 +1,315 @@ package com.oying.modules.sh.service.impl; -import com.oying.modules.sh.domain.Order; +import com.alibaba.fastjson2.JSONObject; +import com.oying.exception.BadRequestException; +import com.oying.modules.hwc.domain.HwcResponse; +import com.oying.modules.hwc.service.SwiftPassService; +import com.oying.modules.pc.product.domain.Product; +import com.oying.modules.pc.product.domain.enums.ProductStatusEnum; +import com.oying.modules.pc.product.service.ProductService; +import com.oying.modules.pc.store.domain.Store; +import com.oying.modules.pc.store.domain.enums.StoreStatusEnum; +import com.oying.modules.pc.store.service.StoreService; +import com.oying.modules.sh.domain.*; import com.oying.modules.sh.domain.request.GeneratorOrder; +import com.oying.modules.sh.domain.request.ProductOrder; +import com.oying.modules.sh.domain.request.StatusOrder; import com.oying.modules.sh.domain.request.SubmitOrder; -import com.oying.utils.FileUtil; +import com.oying.modules.sh.domain.vo.OrderInfo; +import com.oying.modules.sh.domain.vo.OrderResponse; +import com.oying.modules.sh.domain.vo.ProductInfo; +import com.oying.modules.sh.service.*; +import com.oying.utils.*; +import com.oying.utils.enums.*; import lombok.RequiredArgsConstructor; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.oying.modules.sh.service.OrderService; import com.oying.modules.sh.domain.dto.OrderQueryCriteria; import com.oying.modules.sh.mapper.OrderMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.oying.utils.PageUtil; +import java.math.BigDecimal; +import java.sql.Timestamp; import java.util.*; import java.io.IOException; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import com.oying.utils.PageResult; - /** -* @description 服务实现 -* @author lixin -* @date 2025-06-11 -**/ + * @author lixin + * @description 服务实现 + * @date 2025-06-11 + **/ @Service @RequiredArgsConstructor public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService { private final OrderMapper orderMapper; + private final UserAddressService userAddressService; + private final ProductService productService; + private final SwiftPassService swiftPassService; + private final OrderProductSnapshotService productSnapshotService; + private final OrderAddressSnapshotService addressSnapshotService; + private final RedisUtils redisUtils; + private final StoreService storeService; + private final OrderOperationLogService operationLogService; + private final static String DESCRIBE = "哦应:"; @Override - public PageResult<Order> queryAll(OrderQueryCriteria criteria, Page<Object> page){ - return PageUtil.toPage(orderMapper.findAll(criteria, page)); + public PageResult<Order> queryAll(OrderQueryCriteria criteria, Page<Object> page) { + criteria.setOffset(page.offset()); + List<Order> list = orderMapper.findAll(criteria, criteria.getBlurry()); + Long total = orderMapper.countAll(criteria, criteria.getBlurry()); + return PageUtil.toPage(list, total); } @Override - public List<Order> queryAll(OrderQueryCriteria criteria){ - return orderMapper.findAll(criteria); + public List<Order> queryAll(OrderQueryCriteria criteria) { + return orderMapper.findAll(criteria, criteria.getBlurry()); } @Override - public Order submitOrder(SubmitOrder submit) { - return null; + @Transactional(rollbackFor = Exception.class) + public synchronized Order submitOrder(SubmitOrder submit, HttpServletRequest request) { + switch (submit.getPayType()) { + case HWC: + case HWC2: + break; + default: + throw new BadRequestException("支付类型暂未开放"); + } + GeneratorOrder generator = new GeneratorOrder(); + generator.setProducts(submit.getProducts()); + generator.setStoreId(submit.getStoreId()); + OrderInfo info = generatorOrder(generator); + Store store = info.getStore(); + UserAddress address = userAddressService.getById(submit.getAddressId(), store.getLongitude(), store.getLatitude()); + if (address == null) { + throw new BadRequestException("没找到用户地址"); + } + if (!(address.getDistance().compareTo(BigDecimal.valueOf(store.getRadius())) <= 0)) { + throw new BadRequestException("超出配送范围"); + } + String orderNum = redisUtils.generateOrderSn(GenerateEnum.ORDER.getKey()); + // 总金额 + BigDecimal amount = BigDecimal.ZERO; + // 商品快照 + List<OrderProductSnapshot> snapshots = new ArrayList<>(); + for (ProductInfo productInfo : info.getProducts()) { + Product product = productInfo.getProduct(); + OrderProductSnapshot snapshot = new OrderProductSnapshot(); + snapshot.setOrderNum(orderNum); + snapshot.setStoreId(submit.getStoreId()); + snapshot.setProductId(product.getProductId()); + snapshot.setProductBarcode(product.getBarcode()); + snapshot.setProductName(product.getName()); + snapshot.setProductTitle(product.getTitle()); + snapshot.setProductMainImage(product.getMainImageUrl()); + snapshot.setParamData(JSONObject.toJSONString(productInfo.getProductLabels())); + snapshot.setUnitPrice(product.getPrice()); + snapshot.setDetailCount(productInfo.getCount()); + snapshot.setOriginalPrice(product.getPrice()); + snapshot.setPaidPrice(product.getPrice()); + BigDecimal decimal = BigDecimalUtils.multiply(product.getPrice(), productInfo.getCount()); + amount = BigDecimalUtils.add(amount, decimal); + snapshot.setActuallyPayPrice(decimal); + snapshot.setPayState(PayStateEnum.NOTPAY.getKey()); + snapshots.add(snapshot); + } + Timestamp now = DateUtil.getTimeStamp(); + // 下单后30分钟失效 + Timestamp time = DateUtil.addMinute(now, 30); + String expire = DateUtil.localDateTimeFormat(time.toLocalDateTime(), DateUtil.SDF_YMDHMS); + String openid = SecurityUtils.getCurrentOpenid(); + if (openid == null || openid.isEmpty()) { + throw new BadRequestException("OPENID错误"); + } + // 订单信息 + Order order = new Order(); + order.setOrderNum(orderNum); + order.setOrderStoreNum(redisUtils.generateOrderSn(Math.toIntExact(submit.getStoreId())).substring(orderNum.length() - 4)); + order.setOrderStatus(OrderStatusEnum.ZERO.getKey()); + order.setOrderStatusDescribe(OrderStatusEnum.ZERO.getValue()); + order.setOrderRemark(submit.getRemark() != null ? submit.getRemark() : ""); + order.setOrderTime(submit.getDateTime()); + order.setSendPrice(store.getDeliveryFee()); + order.setSendType(SendTypeEnum.LY.getKey()); + order.setUserId(SecurityUtils.getCurrentUserId()); + order.setUsername(SecurityUtils.getCurrentUsername()); + order.setStoreId(submit.getStoreId()); + order.setStoreName(store.getStoreName()); + order.setStoreLogo(store.getLogoImageUrl()); + order.setStoreAddress(store.getAddress()); + order.setStoreLongitude(BigDecimal.valueOf(store.getLongitude())); + order.setStoreLatitude(BigDecimal.valueOf(store.getLatitude())); + order.setOrderDescribe(DESCRIBE + submit.getStoreId()); + order.setOriginalPrice(amount); + order.setPaidPrice(amount); + order.setActuallyPayPrice(amount); + order.setOpenid(openid); + order.setPayType(submit.getPayType().getKey()); + order.setExpireTime(expire); + order.setOpenid(openid); + Long total = BigDecimalUtils.yuanToCents(amount); + if (total > 0) { + HwcResponse response = swiftPassService.pay(StringUtils.getIp(request), total.toString(), expire, + DESCRIBE + submit.getStoreId(), openid, orderNum, submit.getPayType()); + //微信支付下单放回值 + order.setAppId(response.getAppId()); + order.setTimestamp(response.getTimeStamp()); + order.setNonceStr(response.getNonceStr()); + order.setPackageVal(response.getPackageVal()); + order.setSignType(response.getSignType()); + order.setPaySign(response.getPaySign()); + order.setPayState(PayStateEnum.NOTPAY.getKey()); + order.setPayMessage(PayStateEnum.NOTPAY.getValue()); + order.setPayTime(null); + } else { + order.setPayState(PayStateEnum.SUCCESS.getKey()); + order.setPayMessage(PayStateEnum.SUCCESS.getValue()); + order.setPayTime(DateUtil.localDateTimeFormat(now.toLocalDateTime(), DateUtil.SDF_YMDHMS)); + } + + OrderAddressSnapshot addressSnapshot = getOrderAddressSnapshot(orderNum, address); + + + addressSnapshotService.save(addressSnapshot); + orderMapper.insert(order); + productSnapshotService.saveBatch(snapshots); + + order.setProductSnapshots(new HashSet<>(snapshots)); + OrderResponse response = new OrderResponse(order, addressSnapshot, null); + + operationLogService.create(response, OrderStatusEnum.ZERO, null); + return order; + } + + private static OrderAddressSnapshot getOrderAddressSnapshot(String orderNum, UserAddress address) { + OrderAddressSnapshot snapshot = new OrderAddressSnapshot(); + snapshot.setOrderNum(orderNum); + snapshot.setReceiverName(address.getReceiverName()); + snapshot.setReceiverPhone(address.getReceiverPhone()); + snapshot.setProvince(address.getProvince() != null ? address.getProvince() : ""); + snapshot.setCity(address.getCity() != null ? address.getCity() : ""); + snapshot.setDistrict(address.getDistrict() != null ? address.getDistrict() : ""); + snapshot.setStreet(address.getStreet() != null ? address.getStreet() : ""); + snapshot.setShortAddress(address.getShortAddress()); + snapshot.setDetail(address.getDetail()); + snapshot.setLongitude(address.getLongitude()); + snapshot.setLatitude(address.getLatitude()); + snapshot.setTag(address.getTag()); + return snapshot; } @Override - public Map<String, Object> generatorOrder(GeneratorOrder generator) { - return Collections.emptyMap(); + @Transactional(rollbackFor = Exception.class) + public synchronized OrderInfo generatorOrder(GeneratorOrder criteria) { + // 门店信息 + Store store = storeService.getById(criteria.getStoreId()); + if (!store.getBusinessStatus().equals(StoreStatusEnum.OPEN.getValue())) { + throw new BadRequestException("停止营业"); + } + List<ProductInfo> products = new ArrayList<>(); + BigDecimal amount = BigDecimal.ZERO; + for (ProductOrder productOrder : criteria.getProducts()) { + Product product = productService.getById(productOrder.getProductId()); + if (product == null) { + throw new BadRequestException("商品不存在"); + } + if (!product.getStoreId().equals(criteria.getStoreId())) { + throw new BadRequestException("不支持跨门店下单"); + } + if (!product.getStatus().equals(ProductStatusEnum.AVAILABLE.getValue())) { + ProductStatusEnum statusEnum = ProductStatusEnum.get(product.getStatus()); + throw new BadRequestException(product.getName() + ":" + (statusEnum != null ? statusEnum.getReasonPhrase() : "状态")); + } + if (productOrder.getCount() > product.getStockQuantity()) { + throw new BadRequestException("商品库存不足"); + } + if (productOrder.getCount() < product.getMinPurchaseQuantity()) { + throw new BadRequestException("起售数量不足"); + } + ProductInfo info = new ProductInfo(); + info.setProduct(product); + info.setProductLabels(product.getLabels()); + info.setCount(productOrder.getCount()); + products.add(info); + amount = BigDecimalUtils.add(amount, BigDecimalUtils.multiply(product.getPrice(), productOrder.getCount())); + } + if (!(amount.compareTo(store.getDeliveryMinimum()) >= 0)) { + throw new BadRequestException("起送金额:" + store.getDeliveryMinimum()); + } + OrderInfo info = new OrderInfo(); + info.setStore(store); + info.setProducts(products); + info.setAmount(amount); + info.setPayAmount(amount); + info.setPromotionAmount(BigDecimal.ZERO); + info.setUserAddresses(userAddressService.queryUserAddress(store.getLongitude(), store.getLatitude())); + return info; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void statusOrder(StatusOrder statusOrder) { + operationLog(getByOrderNum(statusOrder.getOrderNum()), statusOrder.getStatus(), null); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public OrderResponse getByOrderNum(String orderNum) { + return new OrderResponse(orderMapper.getByOrderNum(orderNum), + addressSnapshotService.queryByOrderNum(orderNum), + operationLogService.getByOrderNum(orderNum)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void operationLog(OrderResponse order, OrderStatusEnum stateEnum, String cardName) { + operationLogService.create(order, stateEnum, cardName); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePayStatus(String orderNum, PayStateEnum payState, String payMessage, String payTime) { + orderMapper.updatePayStatus(orderNum, payState.getKey(), payMessage, payTime); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void cancel(String orderNum) { + OrderResponse response = getByOrderNum(orderNum); + Order order = response.getOrder(); + if (order == null) { + throw new BadRequestException("订单不存在"); + } + if (!SecurityUtils.getCurrentUserId().equals(order.getUserId())) { + throw new BadRequestException("不能修改他人订单"); + } + if (!order.getPayState().equals(PayStateEnum.NOTPAY.getKey())) { + throw new BadRequestException(PayStateEnum.getValue(order.getPayState())); + } + PayTypeEnum anEnum = PayTypeEnum.find(order.getPayType()); + switch (anEnum) { + case HWC: + case HWC2: + JSONObject object = swiftPassService.query(orderNum, anEnum); + if (object.getString("trade_state").equals(PayStateEnum.NOTPAY.getKey())) { + throw new BadRequestException(PayStateEnum.getValue(order.getPayState())); + } + swiftPassService.closeOrder(orderNum, anEnum); + break; + } + operationLogService.create(response, OrderStatusEnum.NINE, null); + orderMapper.updateCloseStatus(orderNum, PayStateEnum.CLOSED.getKey(), PayStateEnum.CLOSED.getValue()); } @Override @Transactional(rollbackFor = Exception.class) public void create(Order resources) { orderMapper.insert(resources); + throw new BadRequestException("未开放"); } @Override @@ -79,6 +334,7 @@ map.put("订单号", order.getOrderNum()); map.put("用户id", order.getUserId()); map.put("门店ID", order.getStoreId()); + map.put("门店", order.getStoreName()); map.put("描述", order.getOrderDescribe()); map.put("原金额", order.getOriginalPrice()); map.put("折扣价", order.getPaidPrice()); @@ -87,14 +343,9 @@ map.put("消息", order.getPayMessage()); map.put("支付类型", order.getPayType()); map.put("支付时间", order.getPayTime()); - map.put("订单失效时间RFC3339", order.getExpireTime()); + map.put("订单失效时间", order.getExpireTime()); map.put("openid", order.getOpenid()); map.put("APPID", order.getAppId()); - map.put("时间戳", order.getTimestamp()); - map.put(" nonceStr", order.getNonceStr()); - map.put(" packageVal", order.getPackageVal()); - map.put(" signType", order.getSignType()); - map.put("签名", order.getPaySign()); map.put("创建人", order.getCreateBy()); map.put("创建时间", order.getCreateTime()); map.put("修改者", order.getUpdateBy()); -- Gitblit v1.9.3