feat(order): 添加送水订单配送时间和完整下单流程
- 在GltTicketOrder实体中新增sendTime字段用于记录配送时间 - 移除送水订单查询接口的权限验证要求,开放查询功能 - 实现完整的下单流程:验证登录用户、扣减水票、写入核销记录、创建订单 - 新增createWithWriteOff方法处理事务性下单操作,确保数据一致性 - 添加数据库行锁机制防止并发扣减问题 - 优化水票相关接口描述,明确为可用水票总数 - 移除水票日志添加接口的权限验证和操作日志注解
This commit is contained in:
@@ -1,14 +1,24 @@
|
||||
package com.gxwebsoft.glt.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.exception.BusinessException;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.glt.entity.GltTicketOrder;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicket;
|
||||
import com.gxwebsoft.glt.entity.GltUserTicketLog;
|
||||
import com.gxwebsoft.glt.mapper.GltTicketOrderMapper;
|
||||
import com.gxwebsoft.glt.mapper.GltUserTicketMapper;
|
||||
import com.gxwebsoft.glt.param.GltTicketOrderParam;
|
||||
import com.gxwebsoft.glt.service.GltTicketOrderService;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketLogService;
|
||||
import com.gxwebsoft.glt.service.GltUserTicketService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -20,6 +30,17 @@ import java.util.List;
|
||||
@Service
|
||||
public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper, GltTicketOrder> implements GltTicketOrderService {
|
||||
|
||||
public static final int CHANGE_TYPE_WRITE_OFF = 20;
|
||||
|
||||
@Resource
|
||||
private GltUserTicketMapper gltUserTicketMapper;
|
||||
|
||||
@Resource
|
||||
private GltUserTicketService gltUserTicketService;
|
||||
|
||||
@Resource
|
||||
private GltUserTicketLogService gltUserTicketLogService;
|
||||
|
||||
@Override
|
||||
public PageResult<GltTicketOrder> pageRel(GltTicketOrderParam param) {
|
||||
PageParam<GltTicketOrder, GltTicketOrderParam> page = new PageParam<>(param);
|
||||
@@ -44,4 +65,98 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
|
||||
return param.getOne(baseMapper.selectListRel(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public GltTicketOrder createWithWriteOff(GltTicketOrder gltTicketOrder, Integer userId, Integer tenantId) {
|
||||
if (gltTicketOrder == null) {
|
||||
throw new BusinessException("订单参数不能为空");
|
||||
}
|
||||
if (userId == null) {
|
||||
throw new BusinessException("请先登录");
|
||||
}
|
||||
Integer userTicketId = gltTicketOrder.getUserTicketId();
|
||||
if (userTicketId == null) {
|
||||
throw new BusinessException("userTicketId不能为空");
|
||||
}
|
||||
int totalNum = gltTicketOrder.getTotalNum() == null ? 0 : gltTicketOrder.getTotalNum();
|
||||
if (totalNum <= 0) {
|
||||
throw new BusinessException("totalNum必须大于0");
|
||||
}
|
||||
if (tenantId == null) {
|
||||
throw new BusinessException("租户信息缺失");
|
||||
}
|
||||
|
||||
// 1) 校验水票归属当前用户 + 正常状态,并锁定记录,避免并发扣减导致日志不准确
|
||||
GltUserTicket userTicket = gltUserTicketMapper.selectByIdForUpdate(userTicketId, userId, tenantId);
|
||||
if (userTicket == null) {
|
||||
throw new BusinessException("水票不存在、已失效或无权限");
|
||||
}
|
||||
int availableQty = userTicket.getAvailableQty() == null ? 0 : userTicket.getAvailableQty();
|
||||
int usedQty = userTicket.getUsedQty() == null ? 0 : userTicket.getUsedQty();
|
||||
if (availableQty < totalNum) {
|
||||
throw new BusinessException("水票数量不足");
|
||||
}
|
||||
|
||||
// 2) 更新 glt_user_ticket: availableQty -= totalNum, usedQty += totalNum
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
int availableAfter = availableQty - totalNum;
|
||||
int usedAfter = usedQty + totalNum;
|
||||
userTicket.setAvailableQty(availableAfter);
|
||||
userTicket.setUsedQty(usedAfter);
|
||||
userTicket.setUpdateTime(now);
|
||||
if (!gltUserTicketService.updateById(userTicket)) {
|
||||
throw new BusinessException("扣减水票失败");
|
||||
}
|
||||
|
||||
// 4) 插入 glt_ticket_order(storeId/addressId/totalNum/buyerRemarks…)
|
||||
gltTicketOrder.setUserId(userId);
|
||||
// 订单基础字段由后端兜底,避免前端误传/恶意传参
|
||||
gltTicketOrder.setStatus(0);
|
||||
gltTicketOrder.setDeleted(0);
|
||||
gltTicketOrder.setTenantId(tenantId);
|
||||
if (gltTicketOrder.getSortNumber() == null) {
|
||||
gltTicketOrder.setSortNumber(0);
|
||||
}
|
||||
if (gltTicketOrder.getCreateTime() == null) {
|
||||
gltTicketOrder.setCreateTime(now);
|
||||
}
|
||||
gltTicketOrder.setUpdateTime(now);
|
||||
if (!this.save(gltTicketOrder)) {
|
||||
throw new BusinessException("创建订单失败");
|
||||
}
|
||||
|
||||
// 3) 插入 glt_user_ticket_log(核销记录)
|
||||
GltUserTicketLog log = new GltUserTicketLog();
|
||||
log.setUserTicketId(userTicketId);
|
||||
log.setChangeType(CHANGE_TYPE_WRITE_OFF);
|
||||
log.setChangeAvailable(-totalNum);
|
||||
log.setChangeFrozen(0);
|
||||
log.setChangeUsed(totalNum);
|
||||
log.setAvailableAfter(availableAfter);
|
||||
log.setFrozenAfter(userTicket.getFrozenQty() == null ? 0 : userTicket.getFrozenQty());
|
||||
log.setUsedAfter(usedAfter);
|
||||
log.setOrderId(gltTicketOrder.getId());
|
||||
log.setOrderNo(gltTicketOrder.getId() == null ? null : String.valueOf(gltTicketOrder.getId()));
|
||||
log.setUserId(userId);
|
||||
log.setSortNumber(0);
|
||||
String comments = gltTicketOrder.getComments();
|
||||
if (StrUtil.isBlank(comments)) {
|
||||
comments = gltTicketOrder.getBuyerRemarks();
|
||||
}
|
||||
if (StrUtil.isBlank(comments)) {
|
||||
comments = "水票下单核销";
|
||||
}
|
||||
log.setComments(comments);
|
||||
log.setStatus(0);
|
||||
log.setDeleted(0);
|
||||
log.setTenantId(tenantId);
|
||||
log.setCreateTime(now);
|
||||
log.setUpdateTime(now);
|
||||
if (!gltUserTicketLogService.save(log)) {
|
||||
throw new BusinessException("写入核销记录失败");
|
||||
}
|
||||
|
||||
return gltTicketOrder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user