You've already forked FrameTour-BE
feat(printer): 实现虚拟用户0元订单创建功能
- 新增CreateVirtualOrderRequest请求参数类 - 实现createVirtualOrder服务方法,支持根据source创建虚拟用户订单 - 自动生成虚拟用户ID并创建对应的人脸记录 - 创建member_print记录并设置照片数量 - 支持指定或自动选择景区内可用打印机 - 创建0元订单并触发购买后逻辑 - 返回订单相关信息包括orderId、faceId等 - 添加详细的日志记录便于调试和追踪 - 实现完整的异常处理和参数校验
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package com.ycwl.basic.model.printer.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 创建虚拟用户0元订单请求参数
|
||||
*/
|
||||
@Data
|
||||
public class CreateVirtualOrderRequest {
|
||||
/**
|
||||
* source记录ID
|
||||
*/
|
||||
private Long sourceId;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 打印机ID(可选)
|
||||
*/
|
||||
private Integer printerId;
|
||||
}
|
||||
@@ -105,4 +105,17 @@ public interface PrinterService {
|
||||
Integer addUserPhotoFromPuzzle(Long memberId, Long scenicId, Long faceId, String resultImageUrl, Long puzzleRecordId);
|
||||
|
||||
int handleReprint(Integer id, ReprintRequest request);
|
||||
|
||||
/**
|
||||
* 创建虚拟用户0元订单
|
||||
* 1. 根据source创建人脸记录(使用虚拟用户ID)
|
||||
* 2. 创建member_print记录
|
||||
* 3. 创建0元订单并触发购买后逻辑
|
||||
*
|
||||
* @param sourceId source记录ID
|
||||
* @param scenicId 景区ID
|
||||
* @param printerId 打印机ID(可选)
|
||||
* @return 订单信息
|
||||
*/
|
||||
Map<String, Object> createVirtualOrder(Long sourceId, Long scenicId, Integer printerId);
|
||||
}
|
||||
@@ -1571,4 +1571,125 @@ public class PrinterServiceImpl implements PrinterService {
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> createVirtualOrder(Long sourceId, Long scenicId, Integer printerId) {
|
||||
// 1. 查询source记录
|
||||
SourceEntity source = sourceMapper.getEntity(sourceId);
|
||||
FaceSampleEntity faceSample = faceSampleMapper.getEntity(source.getFaceSampleId());
|
||||
if (source == null) {
|
||||
throw new BaseException("Source记录不存在");
|
||||
}
|
||||
if (!scenicId.equals(source.getScenicId())) {
|
||||
throw new BaseException("Source记录不属于该景区");
|
||||
}
|
||||
if (faceSample == null) {
|
||||
throw new BaseException("人脸样本不存在");
|
||||
}
|
||||
|
||||
|
||||
// 2. 生成虚拟用户ID(使用雪花算法生成一个不在用户表中的ID)
|
||||
Long virtualMemberId = SnowFlakeUtil.getLongId();
|
||||
log.info("创建虚拟用户0元订单: virtualMemberId={}, sourceId={}, scenicId={}", virtualMemberId, sourceId, scenicId);
|
||||
|
||||
// 3. 创建人脸记录
|
||||
Long faceId = SnowFlakeUtil.getLongId();
|
||||
FaceEntity face = new FaceEntity();
|
||||
face.setId(faceId);
|
||||
face.setScenicId(scenicId);
|
||||
face.setMemberId(virtualMemberId);
|
||||
// 从source获取人脸URL
|
||||
face.setFaceUrl(faceSample.getFaceUrl());
|
||||
face.setCreateAt(new Date());
|
||||
faceMapper.add(face);
|
||||
log.info("创建人脸记录成功: faceId={}, virtualMemberId={}, origUrl={}", faceId, virtualMemberId, source.getUrl());
|
||||
|
||||
// 4. 创建member_print记录(参考addUserPhotoFromSource方法)
|
||||
Integer memberPrintId = addUserPhoto(virtualMemberId, scenicId, source.getUrl(), faceId, sourceId);
|
||||
if (memberPrintId == null) {
|
||||
throw new BaseException("创建member_print记录失败");
|
||||
}
|
||||
log.info("创建member_print记录成功: memberPrintId={}, faceId={}", memberPrintId, faceId);
|
||||
|
||||
// 设置打印数量为1
|
||||
setPhotoQuantity(virtualMemberId, scenicId, memberPrintId.longValue(), 1);
|
||||
|
||||
// 5. 验证打印机
|
||||
if (printerId == null) {
|
||||
List<PrinterResp> printerList = printerMapper.listByScenicId(scenicId);
|
||||
if (printerList.isEmpty()) {
|
||||
throw new BaseException("该景区没有可用的打印机");
|
||||
}
|
||||
if (printerList.size() != 1) {
|
||||
throw new BaseException("请选择打印机");
|
||||
}
|
||||
printerId = printerList.getFirst().getId();
|
||||
}
|
||||
PrinterEntity printer = printerMapper.getById(printerId);
|
||||
if (printer == null) {
|
||||
throw new BaseException("打印机不存在");
|
||||
}
|
||||
if (printer.getStatus() != 1) {
|
||||
throw new BaseException("打印机已停用");
|
||||
}
|
||||
if (!printer.getScenicId().equals(scenicId)) {
|
||||
throw new BaseException("打印机不属于该景区");
|
||||
}
|
||||
|
||||
// 6. 创建0元订单
|
||||
OrderEntity order = new OrderEntity();
|
||||
Long orderId = SnowFlakeUtil.getLongId();
|
||||
redisTemplate.opsForValue().set("printer_size:" + orderId, printer.getPreferPaper(), 60, TimeUnit.SECONDS);
|
||||
order.setId(orderId);
|
||||
order.setMemberId(virtualMemberId);
|
||||
order.setFaceId(faceId);
|
||||
order.setOpenId(""); // 虚拟用户没有openId
|
||||
order.setScenicId(scenicId);
|
||||
order.setType(3); // 照片打印类型
|
||||
|
||||
// 设置打印机
|
||||
batchSetUserPhotoListToPrinter(virtualMemberId, scenicId, printerId);
|
||||
|
||||
// 获取用户照片列表
|
||||
List<MemberPrintResp> userPhotoList = getUserPhotoList(virtualMemberId, scenicId, faceId);
|
||||
List<OrderItemEntity> orderItems = userPhotoList.stream().map(goods -> {
|
||||
OrderItemEntity orderItem = new OrderItemEntity();
|
||||
orderItem.setOrderId(orderId);
|
||||
orderItem.setGoodsId(Long.valueOf(goods.getId()));
|
||||
orderItem.setGoodsType(3);
|
||||
return orderItem;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
// 设置价格为0
|
||||
order.setPrice(BigDecimal.ZERO);
|
||||
order.setSlashPrice(BigDecimal.ZERO);
|
||||
order.setPayPrice(BigDecimal.ZERO);
|
||||
order.setFaceId(faceId);
|
||||
order.setStatus(OrderStateEnum.PAID.getState());
|
||||
order.setPayAt(new Date());
|
||||
|
||||
// 保存订单
|
||||
orderMapper.add(order);
|
||||
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
||||
if (addOrderItems == NumberConstant.ZERO) {
|
||||
log.error("订单明细添加失败");
|
||||
throw new BaseException("订单添加失败");
|
||||
}
|
||||
|
||||
log.info("创建0元订单成功: orderId={}, virtualMemberId={}, faceId={}", orderId, virtualMemberId, faceId);
|
||||
|
||||
// 7. 触发购买后逻辑(调用setUserIsBuyItem)
|
||||
setUserIsBuyItem(virtualMemberId, memberPrintId.longValue(), orderId);
|
||||
log.info("触发购买后逻辑完成: orderId={}", orderId);
|
||||
|
||||
// 8. 返回结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("orderId", orderId);
|
||||
result.put("faceId", faceId);
|
||||
result.put("virtualMemberId", virtualMemberId);
|
||||
result.put("memberPrintId", memberPrintId);
|
||||
result.put("needPay", false);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user