流程
This commit is contained in:
		| @ -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)); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -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)); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -62,4 +62,9 @@ public class DishOrderDO extends BaseDO { | ||||
|      * 支付方式 | ||||
|      */ | ||||
|     private String payMethods; | ||||
|  | ||||
|     /** | ||||
|      * 餐盘编号 | ||||
|      */ | ||||
|     private String diningPlatesNum; | ||||
| } | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
|         // 获取指定日期所在月份的第一天 | ||||
|  | ||||
| @ -80,5 +80,6 @@ public interface DiningPlatesService { | ||||
|      * 绑定 | ||||
|      * @return | ||||
|      */ | ||||
|     Boolean  bind(String diningPlatesNum); | ||||
|     Boolean  bind(String diningPlatesNum,String cardId); | ||||
|  | ||||
| } | ||||
| @ -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; | ||||
|     } | ||||
| } | ||||
| @ -75,7 +75,7 @@ public interface OrderService { | ||||
|      * 更改用户的支付状态 | ||||
|      * @return | ||||
|      */ | ||||
|     void updateStatus(List<Long> users); | ||||
|     void updateBatch(List<DishOrderDO> orderDOS); | ||||
|  | ||||
|     /** | ||||
|      * 根据时间获取用户的订单 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 zengtao01
					zengtao01