package com.oying.modules.sh.service.impl;
|
|
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.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.SubmitOrder;
|
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.GenerateEnum;
|
import com.oying.utils.enums.OrderStatusEnum;
|
import com.oying.utils.enums.PayStateEnum;
|
import com.oying.utils.enums.PayTypeEnum;
|
import lombok.RequiredArgsConstructor;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
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 java.math.BigDecimal;
|
import java.sql.Timestamp;
|
import java.util.*;
|
import java.io.IOException;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
|
/**
|
* @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) {
|
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, criteria.getBlurry());
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public synchronized Order submitOrder(SubmitOrder submit, HttpServletRequest request) {
|
switch (submit.getPayType()) {
|
case HWC:
|
case HWC2:
|
break;
|
default:
|
throw new BadRequestException("支付类型暂未开放");
|
}
|
String orderNum = redisUtils.generateOrderSn(GenerateEnum.ORDER.getKey());
|
// 总金额
|
BigDecimal amount = BigDecimal.ZERO;
|
GeneratorOrder generator = new GeneratorOrder();
|
generator.setProducts(submit.getProducts());
|
generator.setStoreId(submit.getStoreId());
|
OrderInfo info = generatorOrder(generator);
|
// 商品快照
|
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错误");
|
}
|
|
// 门店信息
|
Store store = storeService.getById(submit.getStoreId());
|
if (amount.compareTo(store.getDeliveryMinimum()) >= 0) {
|
throw new BadRequestException("起送金额:" + store.getDeliveryMinimum());
|
}
|
// 订单信息
|
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.setUserId(SecurityUtils.getCurrentUserId());
|
order.setUsername(SecurityUtils.getCurrentUsername());
|
order.setStoreId(submit.getStoreId());
|
order.setStoreName(store.getStoreName());
|
order.setStoreLogo(store.getLogoImageUrl());
|
order.setSendPrice(store.getDeliveryFee());
|
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));
|
}
|
UserAddress address = userAddressService.getById(submit.getAddressId());
|
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);
|
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
|
@Transactional(rollbackFor = Exception.class)
|
public synchronized OrderInfo generatorOrder(GeneratorOrder criteria) {
|
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()));
|
}
|
OrderInfo info = new OrderInfo();
|
info.setProducts(products);
|
info.setAmount(amount);
|
info.setPayAmount(amount);
|
info.setPromotionAmount(BigDecimal.ZERO);
|
info.setUserAddresses(userAddressService.queryUserAddress());
|
return info;
|
}
|
|
@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) {
|
operationLogService.create(order, stateEnum);
|
}
|
|
@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 closeOrder(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);
|
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
|
@Transactional(rollbackFor = Exception.class)
|
public void update(Order resources) {
|
Order order = getById(resources.getOrderId());
|
order.copy(resources);
|
orderMapper.updateById(order);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void deleteAll(List<Long> ids) {
|
orderMapper.deleteBatchIds(ids);
|
}
|
|
@Override
|
public void download(List<Order> all, HttpServletResponse response) throws IOException {
|
List<Map<String, Object>> list = new ArrayList<>();
|
for (Order order : all) {
|
Map<String, Object> map = new LinkedHashMap<>();
|
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());
|
map.put("实付金额", order.getActuallyPayPrice());
|
map.put("支付状态", order.getPayState());
|
map.put("消息", order.getPayMessage());
|
map.put("支付类型", order.getPayType());
|
map.put("支付时间", order.getPayTime());
|
map.put("订单失效时间RFC3339", order.getExpireTime());
|
map.put("openid", order.getOpenid());
|
map.put("APPID", order.getAppId());
|
map.put("创建人", order.getCreateBy());
|
map.put("创建时间", order.getCreateTime());
|
map.put("修改者", order.getUpdateBy());
|
map.put("修改时间", order.getUpdateTime());
|
list.add(map);
|
}
|
FileUtil.downloadExcel(list, response);
|
}
|
}
|