优化:收货信息设计方案

This commit is contained in:
2025-08-10 23:18:31 +08:00
parent 0ba7c44d28
commit 5804d7bbbf
4 changed files with 401 additions and 8 deletions

View File

@@ -5,10 +5,7 @@ import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.config.OrderConfigProperties;
import com.gxwebsoft.shop.dto.OrderCreateRequest;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.entity.ShopGoodsSku;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.entity.ShopOrderGoods;
import com.gxwebsoft.shop.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@@ -47,6 +44,9 @@ public class OrderBusinessService {
@Resource
private OrderConfigProperties orderConfig;
@Resource
private ShopUserAddressService shopUserAddressService;
/**
* 创建订单
*
@@ -63,19 +63,22 @@ public class OrderBusinessService {
// 2. 构建订单对象
ShopOrder shopOrder = buildShopOrder(request, loginUser);
// 3. 应用业务规则
// 3. 处理收货地址信息
processDeliveryAddress(shopOrder, request, loginUser);
// 4. 应用业务规则
applyBusinessRules(shopOrder, loginUser);
// 4. 保存订单
// 5. 保存订单
boolean saved = shopOrderService.save(shopOrder);
if (!saved) {
throw new BusinessException("订单保存失败");
}
// 5. 保存订单商品
// 6. 保存订单商品
saveOrderGoods(request, shopOrder);
// 6. 创建微信支付订单
// 7. 创建微信支付订单
try {
return shopOrderService.createWxOrder(shopOrder);
} catch (Exception e) {
@@ -274,6 +277,107 @@ public class OrderBusinessService {
return shopOrder;
}
/**
* 处理收货地址信息
* 优先级:前端传入地址 > 指定地址ID > 用户默认地址
*/
private void processDeliveryAddress(ShopOrder shopOrder, OrderCreateRequest request, User loginUser) {
try {
// 1. 如果前端已经传入了完整的收货地址信息,直接使用
if (isAddressInfoComplete(request)) {
log.info("使用前端传入的收货地址信息用户ID{}", loginUser.getUserId());
return;
}
// 2. 如果指定了地址ID获取该地址信息
if (request.getAddressId() != null) {
ShopUserAddress userAddress = shopUserAddressService.getById(request.getAddressId());
if (userAddress != null && userAddress.getUserId().equals(loginUser.getUserId())) {
copyAddressToOrder(userAddress, shopOrder, request);
log.info("使用指定地址ID{}用户ID{}", request.getAddressId(), loginUser.getUserId());
return;
}
log.warn("指定的地址ID不存在或不属于当前用户地址ID{}用户ID{}",
request.getAddressId(), loginUser.getUserId());
}
// 3. 获取用户默认收货地址
ShopUserAddress defaultAddress = shopUserAddressService.getDefaultAddress(loginUser.getUserId());
if (defaultAddress != null) {
copyAddressToOrder(defaultAddress, shopOrder, request);
log.info("使用用户默认收货地址地址ID{}用户ID{}", defaultAddress.getId(), loginUser.getUserId());
return;
}
// 4. 如果没有默认地址,获取用户的第一个地址
List<ShopUserAddress> userAddresses = shopUserAddressService.getUserAddresses(loginUser.getUserId());
if (!userAddresses.isEmpty()) {
ShopUserAddress firstAddress = userAddresses.get(0);
copyAddressToOrder(firstAddress, shopOrder, request);
log.info("使用用户第一个收货地址地址ID{}用户ID{}", firstAddress.getId(), loginUser.getUserId());
return;
}
// 5. 如果用户没有任何收货地址,抛出异常
throw new BusinessException("请先添加收货地址");
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("处理收货地址信息失败用户ID{}", loginUser.getUserId(), e);
throw new BusinessException("处理收货地址信息失败:" + e.getMessage());
}
}
/**
* 检查前端传入的地址信息是否完整
*/
private boolean isAddressInfoComplete(OrderCreateRequest request) {
return request.getAddress() != null && !request.getAddress().trim().isEmpty() &&
request.getRealName() != null && !request.getRealName().trim().isEmpty();
}
/**
* 将用户地址信息复制到订单中(创建快照)
*/
private void copyAddressToOrder(ShopUserAddress userAddress, ShopOrder shopOrder, OrderCreateRequest request) {
// 保存地址ID引用关系
shopOrder.setAddressId(userAddress.getId());
request.setAddressId(userAddress.getId());
// 创建地址信息快照
if (request.getAddress() == null || request.getAddress().trim().isEmpty()) {
// 构建完整地址
StringBuilder fullAddress = new StringBuilder();
if (userAddress.getProvince() != null) fullAddress.append(userAddress.getProvince());
if (userAddress.getCity() != null) fullAddress.append(userAddress.getCity());
if (userAddress.getRegion() != null) fullAddress.append(userAddress.getRegion());
if (userAddress.getAddress() != null) fullAddress.append(userAddress.getAddress());
shopOrder.setAddress(fullAddress.toString());
request.setAddress(fullAddress.toString());
}
// 复制收货人信息
if (request.getRealName() == null || request.getRealName().trim().isEmpty()) {
shopOrder.setRealName(userAddress.getName());
request.setRealName(userAddress.getName());
}
// 复制经纬度信息
if (request.getAddressLat() == null && userAddress.getLat() != null) {
shopOrder.setAddressLat(userAddress.getLat());
request.setAddressLat(userAddress.getLat());
}
if (request.getAddressLng() == null && userAddress.getLng() != null) {
shopOrder.setAddressLng(userAddress.getLng());
request.setAddressLng(userAddress.getLng());
}
log.debug("地址信息快照创建完成 - 地址ID{},收货人:{},地址:{}",
userAddress.getId(), userAddress.getName(), shopOrder.getAddress());
}
/**
* 应用业务规则
*/

View File

@@ -39,4 +39,20 @@ public interface ShopUserAddressService extends IService<ShopUserAddress> {
*/
ShopUserAddress getByIdRel(Integer id);
/**
* 获取用户默认收货地址
*
* @param userId 用户ID
* @return ShopUserAddress
*/
ShopUserAddress getDefaultAddress(Integer userId);
/**
* 获取用户所有收货地址
*
* @param userId 用户ID
* @return List<ShopUserAddress>
*/
List<ShopUserAddress> getUserAddresses(Integer userId);
}

View File

@@ -1,5 +1,6 @@
package com.gxwebsoft.shop.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.shop.mapper.ShopUserAddressMapper;
import com.gxwebsoft.shop.service.ShopUserAddressService;
@@ -44,4 +45,24 @@ public class ShopUserAddressServiceImpl extends ServiceImpl<ShopUserAddressMappe
return param.getOne(baseMapper.selectListRel(param));
}
@Override
public ShopUserAddress getDefaultAddress(Integer userId) {
LambdaQueryWrapper<ShopUserAddress> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ShopUserAddress::getUserId, userId)
.eq(ShopUserAddress::getIsDefault, true)
.orderByDesc(ShopUserAddress::getCreateTime)
.last("LIMIT 1");
return getOne(wrapper);
}
@Override
public List<ShopUserAddress> getUserAddresses(Integer userId) {
LambdaQueryWrapper<ShopUserAddress> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ShopUserAddress::getUserId, userId)
.orderByDesc(ShopUserAddress::getIsDefault)
.orderByAsc(ShopUserAddress::getSortNumber)
.orderByDesc(ShopUserAddress::getCreateTime);
return list(wrapper);
}
}