This commit is contained in:
zengtao01
2024-04-07 17:45:54 +08:00
parent 24d68316eb
commit c9d7ba76bb
20 changed files with 340 additions and 24 deletions

View File

@ -34,4 +34,10 @@ public class AppDiningPlatesController {
return success(BeanUtils.toBean(pageResult, DiningPlatesRespVO.class));
}
@GetMapping("/bind")
@Operation(summary = "绑定餐盘")
public CommonResult<Boolean> bind(String diningPlatesNum,String cardId) {
return success(diningPlatesService.bind(diningPlatesNum,cardId));
}
}

View File

@ -45,7 +45,6 @@ public class AppOrderDetailController {
@PostMapping("/create")
@Operation(summary = "创建订单明细")
@PreAuthorize("@ss.hasPermission('member:order-detail:create')")
public CommonResult<Long> createOrderDetail(@Valid @RequestBody AppOrderDetailSaveReqVO createReqVO) {
return success(orderDetailService.createOrderDetail(createReqVO));
}
@ -70,7 +69,6 @@ public class AppOrderDetailController {
@GetMapping("/get")
@Operation(summary = "获得订单明细")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:order-detail:query')")
public CommonResult<OrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
OrderDetailDO orderDetail = orderDetailService.getOrderDetail(id);
return success(BeanUtils.toBean(orderDetail, OrderDetailRespVO.class));

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.controller.app.orderdetail.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 订单明细新增/修改 Request VO")
@ -16,6 +17,7 @@ public class AppOrderDetailSaveReqVO {
private Long orderId;
@Schema(description = "菜品ID", example = "1216")
@NotNull(message = "菜品ID 不能为空")
private Long dishesId;
@Schema(description = "菜品", example = "王五")
@ -27,4 +29,8 @@ public class AppOrderDetailSaveReqVO {
@Schema(description = "热量")
private Double heat;
@Schema(description = "餐盘编号")
private String diningPlatesNum;
}

View File

@ -62,4 +62,9 @@ public class DishOrderDO extends BaseDO {
* 支付方式
*/
private String payMethods;
/**
* 餐盘编号
*/
private String diningPlatesNum;
}

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.member.service.card.CardService;
import cn.iocoder.yudao.module.member.service.diningplates.DiningPlatesService;
import cn.iocoder.yudao.module.member.service.order.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@ -35,11 +36,13 @@ public class BalanceDeductionJob implements JobHandler {
private OrderService orderService;
@Resource
private CardService cardService;
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 20分钟之后自动解绑并扣款
*/
private static final Integer EXPIRATION_TIME = 20;
private static final Integer EXPIRATION_TIME = 1;
/**
* 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
@ -57,27 +60,33 @@ public class BalanceDeductionJob implements JobHandler {
List<Long> ids = diningPlatesToCharging.stream().map(DiningPlatesDO::getId).collect(Collectors.toList());
List<Long> users = diningPlatesToCharging.stream().map(DiningPlatesDO::getUserId).collect(Collectors.toList());
//先更改状态防止重复消费
platesService.updatePayFlag(ids,DiningPlatesDO.PAY);
//platesService.updatePayFlag(ids,DiningPlatesDO.PAY);
//获取用户订单
List<DishOrderDO> toPay = orderService.getToPay(users);
//扣除余额
List<CardDO> list = new ArrayList<>();
toPay.forEach(dishOrderDO -> {
//新的总价
BigDecimal total = new BigDecimal(stringRedisTemplate.opsForValue().get(dishOrderDO.getDiningPlatesNum()));
Long userId = dishOrderDO.getUserId();
CardDO cardDO = new CardDO();
cardDO.setType(TimePeriodEnum.getTimePeriod(LocalDateTime.now()));
BigDecimal oldMoney = cardService.getMoneyByUserId(userId);
cardDO.setMoney(oldMoney.subtract(dishOrderDO.getTotalMoney()).setScale(2, BigDecimal.ROUND_HALF_UP));
cardDO.setMoney(oldMoney.subtract(total).setScale(2, BigDecimal.ROUND_HALF_UP));
cardDO.setUserId(userId);
cardDO.setChangeMoney(dishOrderDO.getTotalMoney());
cardDO.setChangeMoney(total);
cardDO.setFlag(CardDO.MINUS);
list.add(cardDO);
dishOrderDO.setTotalMoney(total);
dishOrderDO.setOrderStatus(DishOrderDO.COMPLETE);
stringRedisTemplate.delete(dishOrderDO.getDiningPlatesNum());
});
cardService.insertBatch(list);
size = list.size();
//餐盘解绑、更改订单状态
//餐盘解绑
platesService.updateBind(ids);
orderService.updateStatus(users);
//更新订单状态和总价
orderService.updateBatch(toPay);
}
log.info("[execute][扣款定时任务扣款数量 ({}) 个]", size);

View File

@ -148,7 +148,7 @@ public class CardServiceImpl implements CardService {
@Override
public AppCardMonthVO getMonthMoney(Long userId,String flag, String time) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDate parse = LocalDate.parse(time, dateFormatter);
// 获取指定日期所在月份的第一天

View File

@ -80,5 +80,6 @@ public interface DiningPlatesService {
* 绑定
* @return
*/
Boolean bind(String diningPlatesNum);
Boolean bind(String diningPlatesNum,String cardId);
}

View File

@ -1,14 +1,19 @@
package cn.iocoder.yudao.module.member.service.diningplates;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.controller.admin.diningplates.vo.DiningPlatesPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.diningplates.vo.DiningPlatesSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.diningplates.DiningPlatesDO;
import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.diningplates.DiningPlatesMapper;
import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -31,6 +36,12 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
@Resource
private DiningPlatesMapper diningPlatesMapper;
@Resource
private MemberUserMapper memberUserMapper;
@Resource
private DishOrderMapper dishOrderMapper;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Long createDiningPlates(DiningPlatesSaveReqVO createReqVO) {
@ -115,14 +126,30 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean bind(String diningPlatesNum) {
public Boolean bind(String diningPlatesNum,String cardId) {
DiningPlatesDO diningPlatesDO = diningPlatesMapper.selectOne(Wrappers.<DiningPlatesDO>lambdaQuery()
.eq(DiningPlatesDO::getDiningPlatesNum, diningPlatesNum)
.last("limit 1"));
diningPlatesDO.setUserId(SecurityFrameworkUtils.getLoginUserId());
if(diningPlatesDO.getUserId()!=null){
throw new ServiceException(20001,"餐盘已被绑定");
}
MemberUserDO memberUserDO = memberUserMapper.selectOne(Wrappers.<MemberUserDO>lambdaQuery()
.eq(MemberUserDO::getCardId, cardId)
.last("limit 1"));
diningPlatesDO.setUserId(memberUserDO.getId());
diningPlatesDO.setStatus(DiningPlatesDO.USE);
diningPlatesDO.setBindingTime(LocalDateTime.now());
int i = diningPlatesMapper.updateById(diningPlatesDO);
//创建初始订单
DishOrderDO dishOrderDO = new DishOrderDO();
dishOrderDO.setDiningPlatesNum(diningPlatesNum);
dishOrderDO.setOrderStatus(DishOrderDO.INCOMPLETE);
dishOrderDO.setUserId(memberUserDO.getId());
dishOrderMapper.insert(dishOrderDO);
//设置总价
stringRedisTemplate.opsForValue().set(diningPlatesNum,"0");
return i>0;
}
}

View File

@ -75,7 +75,7 @@ public interface OrderService {
* 更改用户的支付状态
* @return
*/
void updateStatus(List<Long> users);
void updateBatch(List<DishOrderDO> orderDOS);
/**
* 根据时间获取用户的订单

View File

@ -198,11 +198,8 @@ public class OrderServiceImpl implements OrderService {
}
@Override
public void updateStatus(List<Long> users) {
dishOrderMapper.update(Wrappers.<DishOrderDO>lambdaUpdate()
.in(DishOrderDO::getUserId, users)
.eq(DishOrderDO::getOrderStatus, DishOrderDO.INCOMPLETE)
.set(DishOrderDO::getOrderStatus,DishOrderDO.COMPLETE));
public void updateBatch(List<DishOrderDO> orderDOS) {
dishOrderMapper.updateBatch(orderDOS);
}
@Override

View File

@ -1,17 +1,31 @@
package cn.iocoder.yudao.module.member.service.orderdetail;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailRespVO;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO;
import cn.iocoder.yudao.module.member.dal.dataobject.orderdetail.OrderDetailDO;
import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper;
import cn.iocoder.yudao.module.member.dal.mysql.orderdetail.OrderDetailMapper;
import cn.iocoder.yudao.module.system.api.carteen.CarteenApi;
import cn.iocoder.yudao.module.system.api.carteen.dto.CarteenRespDto;
import cn.iocoder.yudao.module.system.api.dish.DishesApi;
import cn.iocoder.yudao.module.system.api.dish.dto.DishesRespDto;
import cn.iocoder.yudao.module.system.api.dishesnutrition.DishesNutritionApi;
import cn.iocoder.yudao.module.system.api.dishesnutrition.dto.DishesNutritionRespDTO;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -29,11 +43,63 @@ public class OrderDetailServiceImpl implements OrderDetailService {
@Resource
private OrderDetailMapper orderDetailMapper;
@Resource
private CarteenApi carteenApi;
@Resource
private DishesNutritionApi dishesNutritionApi;
@Resource
private DishOrderMapper dishOrderMapper;
@Resource
private DishesApi dishesApi;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createOrderDetail(AppOrderDetailSaveReqVO createReqVO) {
//todo:计算热量
// 插入
DishesRespDto dish = dishesApi.getDish(createReqVO.getDishesId());
DishesNutritionRespDTO dishEnergy = dishesNutritionApi.getDishEnergy(createReqVO.getDishesId());
//餐盘号去获取订单
DishOrderDO dishOrderDO = dishOrderMapper.selectOne(Wrappers.<DishOrderDO>lambdaQuery().eq(DishOrderDO::getDiningPlatesNum, createReqVO.getDiningPlatesNum())
.eq(DishOrderDO::getOrderStatus, DishOrderDO.INCOMPLETE)
.orderByDesc(DishOrderDO::getCreateTime)
.last("limit 1"));
if(dishOrderDO==null){
throw new ServiceException(20002,"该餐盘订单已完成,请重新绑定餐盘");
}
// 插入数据
OrderDetailDO orderDetail = BeanUtils.toBean(createReqVO, OrderDetailDO.class);
//判定门店资料是否录入
if(dishOrderDO.getStoreId()==null){
CarteenRespDto carteen = carteenApi.getCarteen(createReqVO.getDishesId());
dishOrderDO.setStoreId(carteen.getId()).setStoreName(carteen.getStoresName());
dishOrderMapper.updateById(dishOrderDO);
}
//计算新总价
String old = stringRedisTemplate.opsForValue().get(createReqVO.getDiningPlatesNum());
BigDecimal oldBigDecimal = new BigDecimal(old);
//
BigDecimal newPrice = dish.getDishesBasePrice().multiply(createReqVO.getWeight())
.add(oldBigDecimal).setScale(2, RoundingMode.HALF_UP);
stringRedisTemplate.opsForValue().set(createReqVO.getDiningPlatesNum(),newPrice.toString());
//计算热量
if( dishEnergy !=null && StrUtil.isNotEmpty(dishEnergy.getDishesNumber())){
BigDecimal dishesNumber = new BigDecimal(dishEnergy.getDishesNumber());
BigDecimal nutritionNumber = new BigDecimal(dishEnergy.getNutritionNumber());
if(BigDecimal.ZERO.compareTo(dishesNumber)!=0){
BigDecimal bigDecimal = createReqVO.getWeight().divide(dishesNumber).multiply(nutritionNumber).setScale(2, RoundingMode.HALF_UP);
orderDetail.setHeat(bigDecimal.doubleValue());
}
}
orderDetail.setOrderId(dishOrderDO.getId()).setDishesName(dish.getDishesName()).setDishUrl(dish.getDishesImageUrl());
orderDetailMapper.insert(orderDetail);
// 返回
return orderDetail.getId();

View File

@ -406,7 +406,7 @@ public class MemberUserServiceImpl implements MemberUserService {
//获取日期的订单
String start = time+" 00:00:00";
String end = time+" 23:59:59";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime startTime = LocalDateTime.parse(start, formatter);
LocalDateTime endTime = LocalDateTime.parse(end, formatter);
@ -464,7 +464,7 @@ public class MemberUserServiceImpl implements MemberUserService {
//获取日期的订单
String newStart = start + " 00:00:00";
String newEnd = end + " 23:59:59";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime startTime = LocalDateTime.parse(newStart, formatter);
LocalDateTime endTime = LocalDateTime.parse(newEnd, formatter);