Showing
21 changed files
with
519 additions
and
23 deletions
| 1 | package com.infoloop.tianting.controller; | 1 | package com.infoloop.tianting.controller; |
| 2 | 2 | ||
| 3 | import com.github.xiaoymin.knife4j.annotations.ApiSupport; | 3 | import com.github.xiaoymin.knife4j.annotations.ApiSupport; |
| 4 | +import com.infoloop.tianting.annotation.RepeatSubmit; | ||
| 4 | import com.infoloop.tianting.model.dto.OrderDbDTO; | 5 | import com.infoloop.tianting.model.dto.OrderDbDTO; |
| 5 | import com.infoloop.tianting.model.dto.OrderDbDTO.BatchUpdateOrderDetailResponse; | 6 | import com.infoloop.tianting.model.dto.OrderDbDTO.BatchUpdateOrderDetailResponse; |
| 6 | import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDto; | 7 | import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDto; |
| ... | @@ -67,6 +68,7 @@ public class OrderController { | ... | @@ -67,6 +68,7 @@ public class OrderController { |
| 67 | @ApiOperation(value = "创建订单") | 68 | @ApiOperation(value = "创建订单") |
| 68 | @PostMapping("/orders") | 69 | @PostMapping("/orders") |
| 69 | @ResponseStatus(HttpStatus.OK) | 70 | @ResponseStatus(HttpStatus.OK) |
| 71 | + @RepeatSubmit(prefix = "createOrder") | ||
| 70 | public CreateOrderResponse createOrder(@Valid @RequestBody CreateOrderDto createOrderDto) { | 72 | public CreateOrderResponse createOrder(@Valid @RequestBody CreateOrderDto createOrderDto) { |
| 71 | return orderService.createOrder(createOrderDto); | 73 | return orderService.createOrder(createOrderDto); |
| 72 | } | 74 | } |
| ... | @@ -74,12 +76,11 @@ public class OrderController { | ... | @@ -74,12 +76,11 @@ public class OrderController { |
| 74 | @ApiOperation(value = "院区端创建订单") | 76 | @ApiOperation(value = "院区端创建订单") |
| 75 | @PostMapping("/operator/orders") | 77 | @PostMapping("/operator/orders") |
| 76 | @ResponseStatus(HttpStatus.OK) | 78 | @ResponseStatus(HttpStatus.OK) |
| 77 | - public CreateOrderResponse createOrderByOperator( | 79 | + @RepeatSubmit(prefix = "createOrder") |
| 78 | - @Valid @RequestBody OrderDbDTO.OperatorCreateOrderDto createOrderDto) { | 80 | + public CreateOrderResponse createOrderByOperator(@Valid @RequestBody OrderDbDTO.OperatorCreateOrderDto createOrderDto) { |
| 79 | return orderService.orderCreation(createOrderDto); | 81 | return orderService.orderCreation(createOrderDto); |
| 80 | } | 82 | } |
| 81 | 83 | ||
| 82 | - // @SaIgnore | ||
| 83 | @ApiOperation(value = "修改订单") | 84 | @ApiOperation(value = "修改订单") |
| 84 | @PatchMapping("/orders/modification") | 85 | @PatchMapping("/orders/modification") |
| 85 | @ResponseStatus(HttpStatus.OK) | 86 | @ResponseStatus(HttpStatus.OK) |
| ... | @@ -87,12 +88,10 @@ public class OrderController { | ... | @@ -87,12 +88,10 @@ public class OrderController { |
| 87 | return orderService.updateOrder(updateOrderDto); | 88 | return orderService.updateOrder(updateOrderDto); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | - // @SaIgnore | ||
| 91 | @ApiOperation(value = "批量修改订单详情") | 91 | @ApiOperation(value = "批量修改订单详情") |
| 92 | @PatchMapping("/order_details/modification") | 92 | @PatchMapping("/order_details/modification") |
| 93 | @ResponseStatus(HttpStatus.OK) | 93 | @ResponseStatus(HttpStatus.OK) |
| 94 | - public BatchUpdateOrderDetailResponse batchUpdateOrderDetails( | 94 | + public BatchUpdateOrderDetailResponse batchUpdateOrderDetails(@Valid @RequestBody OrderDbDTO.OrderDetailBatchUpdateDto updateDto) { |
| 95 | - @Valid @RequestBody OrderDbDTO.OrderDetailBatchUpdateDto updateDto) { | ||
| 96 | return orderService.batchUpdateOrderDetails(updateDto); | 95 | return orderService.batchUpdateOrderDetails(updateDto); |
| 97 | } | 96 | } |
| 98 | 97 | ... | ... |
| ... | @@ -8,7 +8,6 @@ import com.infoloop.tianting.model.dto.SkuSellQuantityDTO; | ... | @@ -8,7 +8,6 @@ import com.infoloop.tianting.model.dto.SkuSellQuantityDTO; |
| 8 | import com.infoloop.tianting.model.vo.SkuSellQuantityStatisticsVO; | 8 | import com.infoloop.tianting.model.vo.SkuSellQuantityStatisticsVO; |
| 9 | import com.infoloop.tianting.model.vo.SkuSellQuantityVO; | 9 | import com.infoloop.tianting.model.vo.SkuSellQuantityVO; |
| 10 | import com.infoloop.tianting.service.SkuService; | 10 | import com.infoloop.tianting.service.SkuService; |
| 11 | -import com.infoloop.tianting.utils.PageUtil; | ||
| 12 | import io.swagger.annotations.Api; | 11 | import io.swagger.annotations.Api; |
| 13 | import io.swagger.annotations.ApiOperation; | 12 | import io.swagger.annotations.ApiOperation; |
| 14 | import lombok.RequiredArgsConstructor; | 13 | import lombok.RequiredArgsConstructor; |
| ... | @@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; | ... | @@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; |
| 25 | import org.springframework.web.bind.annotation.RestController; | 24 | import org.springframework.web.bind.annotation.RestController; |
| 26 | 25 | ||
| 27 | import javax.validation.Valid; | 26 | import javax.validation.Valid; |
| 28 | -import java.util.Collections; | ||
| 29 | import java.util.List; | 27 | import java.util.List; |
| 30 | 28 | ||
| 31 | @Api(tags = "sku") | 29 | @Api(tags = "sku") |
| ... | @@ -41,7 +39,7 @@ public class SkuController { | ... | @@ -41,7 +39,7 @@ public class SkuController { |
| 41 | @ApiOperation(value = "根据sku ids获取") | 39 | @ApiOperation(value = "根据sku ids获取") |
| 42 | @PostMapping("/skus") | 40 | @PostMapping("/skus") |
| 43 | @ResponseStatus(HttpStatus.OK) | 41 | @ResponseStatus(HttpStatus.OK) |
| 44 | - public List<SkuDto> getOrderByCustomerId(@Valid @RequestBody SkuIdsDto skuIdsDto) { | 42 | + public List<SkuDto> getSkusByIds(@Valid @RequestBody SkuIdsDto skuIdsDto) { |
| 45 | return skuService.getSkusByIds(skuIdsDto.getIds()); | 43 | return skuService.getSkusByIds(skuIdsDto.getIds()); |
| 46 | } | 44 | } |
| 47 | 45 | ||
| ... | @@ -49,29 +47,28 @@ public class SkuController { | ... | @@ -49,29 +47,28 @@ public class SkuController { |
| 49 | @GetMapping("/stall/{stallId}/skusellquantities/statistics") | 47 | @GetMapping("/stall/{stallId}/skusellquantities/statistics") |
| 50 | @ResponseStatus(HttpStatus.OK) | 48 | @ResponseStatus(HttpStatus.OK) |
| 51 | public SkuSellQuantityStatisticsVO querySkuSellQuantityStatistics(@PathVariable("stallId") int stallId) { | 49 | public SkuSellQuantityStatisticsVO querySkuSellQuantityStatistics(@PathVariable("stallId") int stallId) { |
| 52 | - return SkuSellQuantityStatisticsVO.builder().build(); | 50 | + return skuService.querySkuSellQuantityStatistics(stallId); |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | @ApiOperation(value = "分页查询菜品售卖量") | 53 | @ApiOperation(value = "分页查询菜品售卖量") |
| 56 | @PostMapping("/skusellquantities/query") | 54 | @PostMapping("/skusellquantities/query") |
| 57 | @ResponseStatus(HttpStatus.OK) | 55 | @ResponseStatus(HttpStatus.OK) |
| 58 | public PageResult<SkuSellQuantityVO> querySkuSellQuantity(@Valid @RequestBody SkuSellQuantityDTO.QuerySkuSellQuantityDTO querySkuSellQuantityDTO) { | 56 | public PageResult<SkuSellQuantityVO> querySkuSellQuantity(@Valid @RequestBody SkuSellQuantityDTO.QuerySkuSellQuantityDTO querySkuSellQuantityDTO) { |
| 59 | - SkuSellQuantityVO skuSellQuantityVO = SkuSellQuantityVO.builder().build(); | 57 | + return skuService.querySkuSellQuantity(querySkuSellQuantityDTO); |
| 60 | - return PageUtil.buildEmpty(skuSellQuantityVO); | ||
| 61 | } | 58 | } |
| 62 | 59 | ||
| 63 | @ApiOperation(value = "批量设置菜品售卖量") | 60 | @ApiOperation(value = "批量设置菜品售卖量") |
| 64 | @PutMapping("/stall/{stallId}/skusellquantities/batchset") | 61 | @PutMapping("/stall/{stallId}/skusellquantities/batchset") |
| 65 | @ResponseStatus(HttpStatus.CREATED) | 62 | @ResponseStatus(HttpStatus.CREATED) |
| 66 | - public void batchSetSkuSellQuantity(@PathVariable("stallId") int stallId, | 63 | + public boolean batchSetSkuSellQuantity(@PathVariable("stallId") int stallId, |
| 67 | - @Valid @RequestBody SkuSellQuantityDTO.BatchSetSkuSellQuantityDTO batchSetSkuSellQuantityDTO) { | 64 | + @Valid @RequestBody SkuSellQuantityDTO.BatchSetSkuSellQuantityDTO batchSetSkuSellQuantityDTO) { |
| 68 | - | 65 | + return skuService.batchSetSkuSellQuantity(stallId, batchSetSkuSellQuantityDTO); |
| 69 | } | 66 | } |
| 70 | 67 | ||
| 71 | @ApiOperation(value = "根据菜品ids批量查询菜品售卖量") | 68 | @ApiOperation(value = "根据菜品ids批量查询菜品售卖量") |
| 72 | @PostMapping("/skusellquantities/querybyskuids") | 69 | @PostMapping("/skusellquantities/querybyskuids") |
| 73 | @ResponseStatus(HttpStatus.OK) | 70 | @ResponseStatus(HttpStatus.OK) |
| 74 | public List<SkuSellQuantityVO> querySkuSellQuantityBySkuIds(@Valid @RequestBody SkuSellQuantityDTO.QuerySkuSellQuantityBySkuIdsDTO querySkuSellQuantityBySkuIdsDTO) { | 71 | public List<SkuSellQuantityVO> querySkuSellQuantityBySkuIds(@Valid @RequestBody SkuSellQuantityDTO.QuerySkuSellQuantityBySkuIdsDTO querySkuSellQuantityBySkuIdsDTO) { |
| 75 | - return Collections.emptyList(); | 72 | + return skuService.querySkuSellQuantityBySkuIds(querySkuSellQuantityBySkuIdsDTO); |
| 76 | } | 73 | } |
| 77 | } | 74 | } | ... | ... |
| ... | @@ -29,6 +29,10 @@ public enum ErrorCodeEnum implements BaseEnum { | ... | @@ -29,6 +29,10 @@ public enum ErrorCodeEnum implements BaseEnum { |
| 29 | ORDER_COUNT_LIMIT(406000005, "已超过该餐单预定次数"), | 29 | ORDER_COUNT_LIMIT(406000005, "已超过该餐单预定次数"), |
| 30 | 30 | ||
| 31 | QUERY_CLIENT_CUSTOMER_ERROR(406000006, "获取当日在住客户失败"), | 31 | QUERY_CLIENT_CUSTOMER_ERROR(406000006, "获取当日在住客户失败"), |
| 32 | + | ||
| 33 | + SKUS_SOLD_OUT_TODAY(406000007, "下单菜品今日售罄"), | ||
| 34 | + | ||
| 35 | + ORDER_CANCEL(406000008, "订单已自动取消") | ||
| 32 | ; | 36 | ; |
| 33 | private final int code; | 37 | private final int code; |
| 34 | 38 | ... | ... |
| 1 | +package com.infoloop.tianting.logic.delay; | ||
| 2 | + | ||
| 3 | +import lombok.extern.slf4j.Slf4j; | ||
| 4 | +import org.redisson.api.RBlockingQueue; | ||
| 5 | +import org.redisson.api.RedissonClient; | ||
| 6 | + | ||
| 7 | +import java.util.concurrent.ExecutorService; | ||
| 8 | +import java.util.concurrent.Executors; | ||
| 9 | +import java.util.concurrent.TimeUnit; | ||
| 10 | + | ||
| 11 | +@Slf4j | ||
| 12 | +public class DelayTaskQueueExecutor<T> { | ||
| 13 | + | ||
| 14 | + private final RedissonClient redissonClient; | ||
| 15 | + private final RBlockingQueue<T> blockingDeque; | ||
| 16 | + private final Processor<T> processor; | ||
| 17 | + private final ExecutorService executorService; | ||
| 18 | + private volatile boolean running = true; | ||
| 19 | + | ||
| 20 | + public interface Processor<T> { | ||
| 21 | + void process(T task) throws InterruptedException; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public DelayTaskQueueExecutor(String threadName, RedissonClient redissonClient, RBlockingQueue<T> blockingDeque, Processor<T> processor) { | ||
| 25 | + this.redissonClient = redissonClient; | ||
| 26 | + this.blockingDeque = blockingDeque; | ||
| 27 | + this.processor = processor; | ||
| 28 | + this.executorService = Executors.newSingleThreadExecutor(r -> { | ||
| 29 | + Thread t = new Thread(r); | ||
| 30 | + t.setName(threadName); | ||
| 31 | + return t; | ||
| 32 | + }); | ||
| 33 | + this.executorService.submit(this::looper); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public void looper() { | ||
| 37 | + while (running) { | ||
| 38 | + try { | ||
| 39 | + if (redissonClient.isShutdown()) { | ||
| 40 | + shutdown(); | ||
| 41 | + return; | ||
| 42 | + } | ||
| 43 | + T task = blockingDeque.take(); | ||
| 44 | + processor.process(task); | ||
| 45 | + } catch (InterruptedException e) { | ||
| 46 | + Thread.currentThread().interrupt(); | ||
| 47 | + break; | ||
| 48 | + } catch (Exception e) { | ||
| 49 | + log.error("Task processing error in thread: {}", Thread.currentThread().getName(), e); | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + public void shutdown() { | ||
| 55 | + running = false; | ||
| 56 | + executorService.shutdown(); | ||
| 57 | + try { | ||
| 58 | + if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { | ||
| 59 | + log.warn("Executor did not terminate in the specified time."); | ||
| 60 | + executorService.shutdownNow(); | ||
| 61 | + } | ||
| 62 | + } catch (InterruptedException e) { | ||
| 63 | + log.error("Shutdown interrupted", e); | ||
| 64 | + executorService.shutdownNow(); | ||
| 65 | + Thread.currentThread().interrupt(); | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | +} |
| 1 | +package com.infoloop.tianting.logic.delay; | ||
| 2 | + | ||
| 3 | +import lombok.RequiredArgsConstructor; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.redisson.api.RBlockingQueue; | ||
| 6 | +import org.redisson.api.RDelayedQueue; | ||
| 7 | +import org.redisson.api.RedissonClient; | ||
| 8 | +import org.springframework.stereotype.Service; | ||
| 9 | + | ||
| 10 | +import java.util.List; | ||
| 11 | +import java.util.Map; | ||
| 12 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 13 | +import java.util.concurrent.TimeUnit; | ||
| 14 | +import java.util.function.Consumer; | ||
| 15 | + | ||
| 16 | +@Slf4j | ||
| 17 | +@Service | ||
| 18 | +@RequiredArgsConstructor | ||
| 19 | +public class DelayedQueue<T> { | ||
| 20 | + | ||
| 21 | + private final RedissonClient redissonClient; | ||
| 22 | + | ||
| 23 | + private final Map<String, RDelayedQueue<T>> delayedQueues = new ConcurrentHashMap<>(); | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * 初始化队列,传入队列名称和处理逻辑 | ||
| 27 | + */ | ||
| 28 | + public void initQueue(String queueName, Consumer<T> processMessage) { | ||
| 29 | + RBlockingQueue<T> blockingQueue = redissonClient.getBlockingQueue(queueName); | ||
| 30 | + RDelayedQueue<T> delayedQueue = redissonClient.getDelayedQueue(blockingQueue); | ||
| 31 | + delayedQueues.put(queueName, delayedQueue); | ||
| 32 | + DelayTaskQueueExecutor.Processor<T> processor = task -> { | ||
| 33 | + try { | ||
| 34 | + processMessage.accept(task); | ||
| 35 | + } catch (Exception e) { | ||
| 36 | + log.error("Error processing task: {}", task, e); | ||
| 37 | + } | ||
| 38 | + }; | ||
| 39 | + new DelayTaskQueueExecutor<>(queueName + " DELAY TASK", redissonClient, blockingQueue, processor); | ||
| 40 | + log.info("Initialized delay queue for {}", queueName); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public void addToQueue(String queueName, T message, long delay, TimeUnit timeUnit) { | ||
| 44 | + RDelayedQueue<T> queue = getDelayedQueue(queueName); | ||
| 45 | + queue.offer(message, delay, timeUnit); | ||
| 46 | + log.info("Added to queue: {}, msg: {}, delay: {} {}", queueName, message, delay, timeUnit); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + public void addToQueue(String queueName, List<T> messages, long delay, TimeUnit timeUnit) { | ||
| 50 | + RDelayedQueue<T> queue = getDelayedQueue(queueName); | ||
| 51 | + messages.forEach(message -> { | ||
| 52 | + queue.offer(message, delay, timeUnit); | ||
| 53 | + log.info("Added to queue: {}, msg: {}, delay: {} {}", queueName, message, delay, timeUnit); | ||
| 54 | + }); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + private RDelayedQueue<T> getDelayedQueue(String queueName) { | ||
| 58 | + RDelayedQueue<T> queue = delayedQueues.get(queueName); | ||
| 59 | + if (queue == null) { | ||
| 60 | + throw new IllegalArgumentException("Queue not initialized: " + queueName); | ||
| 61 | + } | ||
| 62 | + return queue; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | +} |
| 1 | +package com.infoloop.tianting.logic.delay; | ||
| 2 | + | ||
| 3 | +import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; | ||
| 4 | +import com.infoloop.tianting.logic.delay.param.AutoCancelParam; | ||
| 5 | +import com.infoloop.tianting.model.bo.AddSkusSellQuantityBO; | ||
| 6 | +import com.infoloop.tianting.service.client.OrderServiceRpcClient; | ||
| 7 | +import lombok.RequiredArgsConstructor; | ||
| 8 | +import lombok.extern.slf4j.Slf4j; | ||
| 9 | +import org.springframework.stereotype.Component; | ||
| 10 | + | ||
| 11 | +import javax.annotation.PostConstruct; | ||
| 12 | +import java.util.stream.Collectors; | ||
| 13 | + | ||
| 14 | +@Slf4j | ||
| 15 | +@Component | ||
| 16 | +@RequiredArgsConstructor | ||
| 17 | +public class OrderAutoCancelDelayTask { | ||
| 18 | + | ||
| 19 | + private final DelayedQueue<AutoCancelParam> delayedQueue; | ||
| 20 | + | ||
| 21 | + private final OrderServiceRpcClient orderServiceRpcClient; | ||
| 22 | + | ||
| 23 | + public static final String AUTO_CANCEL_ORDER_DELAY_QUEUE = "AUTO_CANCEL_ORDER_QUEUE"; | ||
| 24 | + | ||
| 25 | + @PostConstruct | ||
| 26 | + public void init() { | ||
| 27 | + delayedQueue.initQueue(AUTO_CANCEL_ORDER_DELAY_QUEUE, this::execute); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + private void execute(AutoCancelParam param) { | ||
| 31 | + try { | ||
| 32 | + final var orderById = orderServiceRpcClient.getOrderById(param.getOrderId()); | ||
| 33 | + if (orderById == null) { | ||
| 34 | + log.error("Order not found, orderId: {}", param.getOrderId()); | ||
| 35 | + return; | ||
| 36 | + } | ||
| 37 | + if (orderById.getPayStatus() == PayStatusEnum.PAY_CANCELED) { | ||
| 38 | + log.info("Order {} already canceled, skipping.", param.getOrderId()); | ||
| 39 | + return; | ||
| 40 | + } | ||
| 41 | + if (orderById.getPayStatus() == PayStatusEnum.IN_PROGRESS || orderById.getPayStatus() == PayStatusEnum.SUCCEED) { | ||
| 42 | + log.info("Order {} already successful, skipping.", param.getOrderId()); | ||
| 43 | + return; | ||
| 44 | + } | ||
| 45 | + final var isUpdated = orderServiceRpcClient.updateClientCustomerOrderCancel(orderById.getEnterpriseId(), orderById.getId()); | ||
| 46 | + if (isUpdated) { | ||
| 47 | + final var orderDetails = orderServiceRpcClient.getOrderDetailsByOrderId(orderById.getId()); | ||
| 48 | + final var isSuccess = orderServiceRpcClient.addSkusSellQuantities(orderById.getEnterpriseId(), orderById.getStallId(), orderDetails.stream().map(e -> AddSkusSellQuantityBO.builder() | ||
| 49 | + .skuId(e.getSkuId()) | ||
| 50 | + .quantity(-e.getCount()) | ||
| 51 | + .build()).collect(Collectors.toList())); | ||
| 52 | + log.info("Order {} addSkusSellQuantities result: {}", param.getOrderId(), isSuccess); | ||
| 53 | + } | ||
| 54 | + } catch (Exception e) { | ||
| 55 | + log.error("OrderAutoCancelDelayTask execute error", e); | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | +} |
| ... | @@ -41,6 +41,9 @@ public class SkuSellQuantityDTO { | ... | @@ -41,6 +41,9 @@ public class SkuSellQuantityDTO { |
| 41 | @ApiModelProperty("菜品售卖状态") | 41 | @ApiModelProperty("菜品售卖状态") |
| 42 | @NotNull | 42 | @NotNull |
| 43 | private SkuSellQuantityStatus status; | 43 | private SkuSellQuantityStatus status; |
| 44 | + | ||
| 45 | + @ApiModelProperty("关键字") | ||
| 46 | + private String keyword; | ||
| 44 | } | 47 | } |
| 45 | 48 | ||
| 46 | @Data | 49 | @Data | ... | ... |
| ... | @@ -11,7 +11,7 @@ import lombok.Data; | ... | @@ -11,7 +11,7 @@ import lombok.Data; |
| 11 | public class SkuSellQuantityStatisticsVO { | 11 | public class SkuSellQuantityStatisticsVO { |
| 12 | 12 | ||
| 13 | @ApiModelProperty("全部") | 13 | @ApiModelProperty("全部") |
| 14 | - private Long total; | 14 | + private int total; |
| 15 | 15 | ||
| 16 | @ApiModelProperty("售罄") | 16 | @ApiModelProperty("售罄") |
| 17 | private Long soldOut; | 17 | private Long soldOut; | ... | ... |
| ... | @@ -6,6 +6,7 @@ import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto; | ... | @@ -6,6 +6,7 @@ import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto; |
| 6 | import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDetailDto; | 6 | import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDetailDto; |
| 7 | import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDto; | 7 | import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDto; |
| 8 | import com.infoloop.tianting.model.dto.MenuDbDTO.MenuRefDto; | 8 | import com.infoloop.tianting.model.dto.MenuDbDTO.MenuRefDto; |
| 9 | + | ||
| 9 | import java.util.List; | 10 | import java.util.List; |
| 10 | 11 | ||
| 11 | public interface MenuService { | 12 | public interface MenuService { |
| ... | @@ -21,4 +22,6 @@ public interface MenuService { | ... | @@ -21,4 +22,6 @@ public interface MenuService { |
| 21 | List<MenuRefDto> getClientCustomerMenuRefsByCustomerId(Integer enterpriseId, Integer customerId); | 22 | List<MenuRefDto> getClientCustomerMenuRefsByCustomerId(Integer enterpriseId, Integer customerId); |
| 22 | 23 | ||
| 23 | BatchCreateMenuRefsResponseDto batchCreateMenuRefs(BatchCreateMenuRefsDto batchCreateMenuRefsDto); | 24 | BatchCreateMenuRefsResponseDto batchCreateMenuRefs(BatchCreateMenuRefsDto batchCreateMenuRefsDto); |
| 25 | + | ||
| 26 | + List<Integer> queryMenuSkuIdsByStallId(int enterpriseId, int stallId); | ||
| 24 | } | 27 | } | ... | ... |
| 1 | package com.infoloop.tianting.service; | 1 | package com.infoloop.tianting.service; |
| 2 | 2 | ||
| 3 | import com.infoloop.tianting.model.common.OrderPageResult; | 3 | import com.infoloop.tianting.model.common.OrderPageResult; |
| 4 | -import com.infoloop.tianting.model.common.PageResult; | ||
| 5 | import com.infoloop.tianting.model.dto.OrderDbDTO.BatchUpdateOrderDetailResponse; | 4 | import com.infoloop.tianting.model.dto.OrderDbDTO.BatchUpdateOrderDetailResponse; |
| 6 | -import com.infoloop.tianting.model.dto.OrderDbDTO.getMenuOrderCountDto; | ||
| 7 | import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDto; | 5 | import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDto; |
| 8 | import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderResponse; | 6 | import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderResponse; |
| 9 | import com.infoloop.tianting.model.dto.OrderDbDTO.OperatorCreateOrderDto; | 7 | import com.infoloop.tianting.model.dto.OrderDbDTO.OperatorCreateOrderDto; |
| ... | @@ -15,6 +13,8 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; | ... | @@ -15,6 +13,8 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; |
| 15 | import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto; | 13 | import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto; |
| 16 | import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto; | 14 | import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto; |
| 17 | import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderResponse; | 15 | import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderResponse; |
| 16 | +import com.infoloop.tianting.model.dto.OrderDbDTO.getMenuOrderCountDto; | ||
| 17 | + | ||
| 18 | import java.util.List; | 18 | import java.util.List; |
| 19 | 19 | ||
| 20 | public interface OrderService { | 20 | public interface OrderService { | ... | ... |
| 1 | package com.infoloop.tianting.service; | 1 | package com.infoloop.tianting.service; |
| 2 | 2 | ||
| 3 | +import com.infoloop.tianting.model.common.PageResult; | ||
| 3 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto; | 4 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto; |
| 5 | +import com.infoloop.tianting.model.dto.SkuSellQuantityDTO; | ||
| 6 | +import com.infoloop.tianting.model.vo.SkuSellQuantityStatisticsVO; | ||
| 7 | +import com.infoloop.tianting.model.vo.SkuSellQuantityVO; | ||
| 8 | + | ||
| 9 | +import javax.validation.Valid; | ||
| 4 | import java.util.List; | 10 | import java.util.List; |
| 5 | 11 | ||
| 6 | public interface SkuService { | 12 | public interface SkuService { |
| 7 | 13 | ||
| 8 | List<SkuDto> getSkusByIds(List<Integer> ids); | 14 | List<SkuDto> getSkusByIds(List<Integer> ids); |
| 9 | 15 | ||
| 16 | + SkuSellQuantityStatisticsVO querySkuSellQuantityStatistics(int stallId); | ||
| 17 | + | ||
| 18 | + PageResult<SkuSellQuantityVO> querySkuSellQuantity(SkuSellQuantityDTO.QuerySkuSellQuantityDTO querySkuSellQuantityDTO); | ||
| 19 | + | ||
| 20 | + boolean batchSetSkuSellQuantity(int stallId, SkuSellQuantityDTO.BatchSetSkuSellQuantityDTO batchSetSkuSellQuantityDTO); | ||
| 21 | + | ||
| 22 | + List<SkuSellQuantityVO> querySkuSellQuantityBySkuIds(SkuSellQuantityDTO.@Valid QuerySkuSellQuantityBySkuIdsDTO querySkuSellQuantityBySkuIdsDTO); | ||
| 10 | } | 23 | } | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -8,8 +8,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; | ... | @@ -8,8 +8,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; |
| 8 | import com.fasterxml.jackson.databind.PropertyNamingStrategy; | 8 | import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
| 9 | import com.fasterxml.jackson.dataformat.xml.XmlMapper; | 9 | import com.fasterxml.jackson.dataformat.xml.XmlMapper; |
| 10 | import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification; | 10 | import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification; |
| 11 | +import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; | ||
| 11 | import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; | 12 | import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; |
| 12 | import com.infoloop.tianting.config.BusinessConfig; | 13 | import com.infoloop.tianting.config.BusinessConfig; |
| 14 | +import com.infoloop.tianting.exception.ClientEndExceptions; | ||
| 15 | +import com.infoloop.tianting.exception.ErrorCodeEnum; | ||
| 13 | import com.infoloop.tianting.model.dto.PayDTO.PayInformRequestDto; | 16 | import com.infoloop.tianting.model.dto.PayDTO.PayInformRequestDto; |
| 14 | import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto; | 17 | import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto; |
| 15 | import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto; | 18 | import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto; |
| ... | @@ -49,6 +52,11 @@ public class PayServiceClient { | ... | @@ -49,6 +52,11 @@ public class PayServiceClient { |
| 49 | private String clientId; | 52 | private String clientId; |
| 50 | 53 | ||
| 51 | public PayResponseDto payInform(PayInformRequestDto payRequestDto) { | 54 | public PayResponseDto payInform(PayInformRequestDto payRequestDto) { |
| 55 | + final var orderById = orderServiceRpcClient.getOrderById(Integer.valueOf(payRequestDto.getOrderId())); | ||
| 56 | + if (orderById == null || orderById.getPayStatus() == PayStatusEnum.PAY_CANCELED || orderById.getStatus() == OrderStatusEnum.ORDER_CANCELED) { | ||
| 57 | + log.info("Order {} not found or canceled, skipping.", payRequestDto.getOrderId()); | ||
| 58 | + throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.ORDER_CANCEL); | ||
| 59 | + } | ||
| 52 | String url = businessConfig.getPayUrl(); | 60 | String url = businessConfig.getPayUrl(); |
| 53 | String requestDate = DateUtil.formatDate(LocalDateTime.now(), DateUtil.YMDHMS); | 61 | String requestDate = DateUtil.formatDate(LocalDateTime.now(), DateUtil.YMDHMS); |
| 54 | ThirdPartyPayInformRequestDto jsonData = buildRequestData(payRequestDto, requestDate); | 62 | ThirdPartyPayInformRequestDto jsonData = buildRequestData(payRequestDto, requestDate); | ... | ... |
| ... | @@ -2,6 +2,7 @@ package com.infoloop.tianting.service.client; | ... | @@ -2,6 +2,7 @@ package com.infoloop.tianting.service.client; |
| 2 | 2 | ||
| 3 | import com.infoloop.tianting.GeDishSkuByIdsRpcResponse; | 3 | import com.infoloop.tianting.GeDishSkuByIdsRpcResponse; |
| 4 | import com.infoloop.tianting.GetSkusByIdsRpcRequest; | 4 | import com.infoloop.tianting.GetSkusByIdsRpcRequest; |
| 5 | +import com.infoloop.tianting.SingleSkuResponse; | ||
| 5 | import com.infoloop.tianting.SkuServiceProtoRpcGrpc; | 6 | import com.infoloop.tianting.SkuServiceProtoRpcGrpc; |
| 6 | import lombok.RequiredArgsConstructor; | 7 | import lombok.RequiredArgsConstructor; |
| 7 | import org.springframework.beans.factory.annotation.Autowired; | 8 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | @@ -21,4 +22,12 @@ public class SkuServiceRpcClient { | ... | @@ -21,4 +22,12 @@ public class SkuServiceRpcClient { |
| 21 | .build(); | 22 | .build(); |
| 22 | return skuServiceProtoRpcBlockingStub.getDishSkusByIds(request); | 23 | return skuServiceProtoRpcBlockingStub.getDishSkusByIds(request); |
| 23 | } | 24 | } |
| 25 | + | ||
| 26 | + public List<SingleSkuResponse> getSkusByIds(List<Integer> ids) { | ||
| 27 | + final var request = GetSkusByIdsRpcRequest.newBuilder() | ||
| 28 | + .addAllIds(ids) | ||
| 29 | + .setIncludeDeleted(false) | ||
| 30 | + .build(); | ||
| 31 | + return skuServiceProtoRpcBlockingStub.getSkusByIds(request).getResponseList(); | ||
| 32 | + } | ||
| 24 | } | 33 | } | ... | ... |
| 1 | package com.infoloop.tianting.service.impl; | 1 | package com.infoloop.tianting.service.impl; |
| 2 | 2 | ||
| 3 | +import com.infoloop.tianting.context.LoginContextHolder; | ||
| 4 | +import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse; | ||
| 5 | +import com.infoloop.tianting.menuservice.SingleMenuRpcResponse; | ||
| 3 | import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsDto; | 6 | import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsDto; |
| 4 | import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto; | 7 | import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto; |
| 5 | import com.infoloop.tianting.model.dto.MenuDbDTO.DishRuleJson; | 8 | import com.infoloop.tianting.model.dto.MenuDbDTO.DishRuleJson; |
| ... | @@ -197,4 +200,10 @@ public class MenuServiceImpl implements MenuService { | ... | @@ -197,4 +200,10 @@ public class MenuServiceImpl implements MenuService { |
| 197 | .build(); | 200 | .build(); |
| 198 | } | 201 | } |
| 199 | 202 | ||
| 203 | + @Override | ||
| 204 | + public List<Integer> queryMenuSkuIdsByStallId(int enterpriseId, int stallId) { | ||
| 205 | + final var menuIds = menuServiceRpcClient.queryPublishedMenusByStallId(LoginContextHolder.getEnterpriseId(), stallId).getResponsesList().stream().map(SingleMenuRpcResponse::getId).collect(Collectors.toList()); | ||
| 206 | + return menuServiceRpcClient.queryMenuDetailsByMenuIds(LoginContextHolder.getEnterpriseId(), menuIds).getResponsesList().stream().map(SingleMenuDetailRpcResponse::getSkuId).distinct().collect(Collectors.toList()); | ||
| 207 | + } | ||
| 208 | + | ||
| 200 | } | 209 | } | ... | ... |
| ... | @@ -118,10 +118,7 @@ public class OrderServiceImpl implements OrderService { | ... | @@ -118,10 +118,7 @@ public class OrderServiceImpl implements OrderService { |
| 118 | createOrderDto.setCreationSource(OrderSourceEnum.STALL.getNumber()); | 118 | createOrderDto.setCreationSource(OrderSourceEnum.STALL.getNumber()); |
| 119 | createOrderDto.setEnterpriseId(operatorLoginInfo.getEnterpriseId()); | 119 | createOrderDto.setEnterpriseId(operatorLoginInfo.getEnterpriseId()); |
| 120 | // createOrderDto.setStallId(); | 120 | // createOrderDto.setStallId(); |
| 121 | - var onlinePay = false; | 121 | + var onlinePay = menu.getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE; |
| 122 | - if (menu.getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE) { | ||
| 123 | - onlinePay = true; | ||
| 124 | - } | ||
| 125 | createOrderDto.setOnlinePay(onlinePay); | 122 | createOrderDto.setOnlinePay(onlinePay); |
| 126 | OrderTypeEnum orderType; | 123 | OrderTypeEnum orderType; |
| 127 | if (menu.getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.RESERVATION) { | 124 | if (menu.getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.RESERVATION) { | ... | ... |
| 1 | package com.infoloop.tianting.service.impl; | 1 | package com.infoloop.tianting.service.impl; |
| 2 | 2 | ||
| 3 | +import com.infoloop.tianting.SingleSkuResponse; | ||
| 4 | +import com.infoloop.tianting.clientcustomerorderservice.SingleSkuSellQuantityRpcResponse; | ||
| 5 | +import com.infoloop.tianting.context.LoginContextHolder; | ||
| 6 | +import com.infoloop.tianting.enums.SkuSellQuantityStatus; | ||
| 7 | +import com.infoloop.tianting.model.bo.SkuSellQuantityBO; | ||
| 8 | +import com.infoloop.tianting.model.common.PageResult; | ||
| 3 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDetailSingleResponseDto; | 9 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDetailSingleResponseDto; |
| 4 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto; | 10 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto; |
| 5 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuSpecialDetailSingleResponseDto; | 11 | import com.infoloop.tianting.model.dto.SkuDbDTO.SkuSpecialDetailSingleResponseDto; |
| 12 | +import com.infoloop.tianting.model.dto.SkuSellQuantityDTO; | ||
| 13 | +import com.infoloop.tianting.model.vo.SkuSellQuantityStatisticsVO; | ||
| 14 | +import com.infoloop.tianting.model.vo.SkuSellQuantityVO; | ||
| 15 | +import com.infoloop.tianting.service.MenuService; | ||
| 6 | import com.infoloop.tianting.service.SkuService; | 16 | import com.infoloop.tianting.service.SkuService; |
| 17 | +import com.infoloop.tianting.service.client.OrderServiceRpcClient; | ||
| 7 | import com.infoloop.tianting.service.client.SkuServiceRpcClient; | 18 | import com.infoloop.tianting.service.client.SkuServiceRpcClient; |
| 8 | import com.infoloop.tianting.utils.DateUtil; | 19 | import com.infoloop.tianting.utils.DateUtil; |
| 20 | +import com.infoloop.tianting.utils.PageUtil; | ||
| 9 | import lombok.RequiredArgsConstructor; | 21 | import lombok.RequiredArgsConstructor; |
| 10 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | import org.springframework.stereotype.Service; | 24 | import org.springframework.stereotype.Service; |
| 13 | 25 | ||
| 26 | +import java.util.Comparator; | ||
| 14 | import java.util.List; | 27 | import java.util.List; |
| 28 | +import java.util.function.Function; | ||
| 15 | import java.util.stream.Collectors; | 29 | import java.util.stream.Collectors; |
| 16 | 30 | ||
| 17 | @Slf4j | 31 | @Slf4j |
| 18 | @Service | 32 | @Service |
| 19 | @RequiredArgsConstructor(onConstructor = @__(@Autowired)) | 33 | @RequiredArgsConstructor(onConstructor = @__(@Autowired)) |
| 20 | public class SkuServiceImpl implements SkuService { | 34 | public class SkuServiceImpl implements SkuService { |
| 35 | + | ||
| 36 | + private final MenuService menuService; | ||
| 37 | + | ||
| 21 | private final SkuServiceRpcClient skuServiceRpcClient; | 38 | private final SkuServiceRpcClient skuServiceRpcClient; |
| 22 | 39 | ||
| 40 | + private final OrderServiceRpcClient orderServiceRpcClient; | ||
| 41 | + | ||
| 23 | @Override | 42 | @Override |
| 24 | public List<SkuDto> getSkusByIds(List<Integer> ids) { | 43 | public List<SkuDto> getSkusByIds(List<Integer> ids) { |
| 25 | final var response = skuServiceRpcClient.getDishSkusByIds(ids); | 44 | final var response = skuServiceRpcClient.getDishSkusByIds(ids); |
| ... | @@ -56,4 +75,133 @@ public class SkuServiceImpl implements SkuService { | ... | @@ -56,4 +75,133 @@ public class SkuServiceImpl implements SkuService { |
| 56 | .build() | 75 | .build() |
| 57 | ).collect(Collectors.toList()); | 76 | ).collect(Collectors.toList()); |
| 58 | } | 77 | } |
| 78 | + | ||
| 79 | + @Override | ||
| 80 | + public SkuSellQuantityStatisticsVO querySkuSellQuantityStatistics(int stallId) { | ||
| 81 | + final var skuIds = menuService.queryMenuSkuIdsByStallId(LoginContextHolder.getEnterpriseId(), stallId); | ||
| 82 | + final var responses = orderServiceRpcClient.querySkuSellQuantitiesByStall(LoginContextHolder.getEnterpriseId(), stallId); | ||
| 83 | + final var skuSellQuantitiesMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity())); | ||
| 84 | + final var soldOut = skuIds.stream() | ||
| 85 | + .filter(e -> skuSellQuantitiesMap.get(e) == null || skuSellQuantitiesMap.get(e).getMaxSellQuantity() == skuSellQuantitiesMap.get(e).getTodaySellQuantity()) | ||
| 86 | + .count(); | ||
| 87 | + final int total = skuIds.size(); | ||
| 88 | + return SkuSellQuantityStatisticsVO.builder() | ||
| 89 | + .total(total) | ||
| 90 | + .soldOut(soldOut) | ||
| 91 | + .onSale(total - soldOut) | ||
| 92 | + .build(); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + @Override | ||
| 96 | + public PageResult<SkuSellQuantityVO> querySkuSellQuantity(SkuSellQuantityDTO.QuerySkuSellQuantityDTO querySkuSellQuantityDTO) { | ||
| 97 | + final var stallId = querySkuSellQuantityDTO.getStallId(); | ||
| 98 | + final var enterpriseId = LoginContextHolder.getEnterpriseId(); | ||
| 99 | + final var skuIds = menuService.queryMenuSkuIdsByStallId(enterpriseId, stallId); | ||
| 100 | + var responses = orderServiceRpcClient.querySkuSellQuantitiesByStall(enterpriseId, stallId); | ||
| 101 | + final var skuSellQuantityMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity())); | ||
| 102 | + responses = skuIds.stream() | ||
| 103 | + .map(skuId -> { | ||
| 104 | + var response = skuSellQuantityMap.get(skuId); | ||
| 105 | + if (response == null) { | ||
| 106 | + response = SingleSkuSellQuantityRpcResponse.newBuilder() | ||
| 107 | + .setSkuId(skuId) | ||
| 108 | + .setMaxSellQuantity(0) | ||
| 109 | + .setTodaySellQuantity(0) | ||
| 110 | + .build(); | ||
| 111 | + } | ||
| 112 | + return response; | ||
| 113 | + }) | ||
| 114 | + .collect(Collectors.toList()); | ||
| 115 | + if (querySkuSellQuantityDTO.getStatus() != SkuSellQuantityStatus.ALL) { | ||
| 116 | + responses = responses.stream() | ||
| 117 | + .filter(e -> { | ||
| 118 | + switch (querySkuSellQuantityDTO.getStatus()) { | ||
| 119 | + case SOLD_OUT: | ||
| 120 | + return e.getMaxSellQuantity() == e.getTodaySellQuantity(); | ||
| 121 | + case ON_SALE: | ||
| 122 | + return e.getMaxSellQuantity() != e.getTodaySellQuantity(); | ||
| 123 | + default: | ||
| 124 | + return true; | ||
| 125 | + } | ||
| 126 | + }) | ||
| 127 | + .collect(Collectors.toList()); | ||
| 128 | + } | ||
| 129 | + final var skuList = skuServiceRpcClient.getSkusByIds(responses.stream().map(SingleSkuSellQuantityRpcResponse::getSkuId).collect(Collectors.toList())); | ||
| 130 | + final var skuMap = skuList.stream().collect(Collectors.toMap(SingleSkuResponse::getId, Function.identity())); | ||
| 131 | + final var keyword = querySkuSellQuantityDTO.getKeyword(); | ||
| 132 | + if (keyword != null && !keyword.isEmpty()) { | ||
| 133 | + responses = responses.stream() | ||
| 134 | + .filter(e -> { | ||
| 135 | + var sku = skuMap.get(e.getSkuId()); | ||
| 136 | + return sku != null && (sku.getCode().contains(keyword) || sku.getName().contains(keyword)); | ||
| 137 | + }) | ||
| 138 | + .collect(Collectors.toList()); | ||
| 139 | + } | ||
| 140 | + final var skuSellQuantityVOS = responses.stream() | ||
| 141 | + .map(e -> { | ||
| 142 | + var sku = skuMap.get(e.getSkuId()); | ||
| 143 | + return SkuSellQuantityVO.builder() | ||
| 144 | + .skuId(e.getSkuId()) | ||
| 145 | + .skuName(sku != null ? sku.getName() : "") | ||
| 146 | + .skuCode(sku != null ? sku.getCode() : "") | ||
| 147 | + .maxSellQuantity(e.getMaxSellQuantity()) | ||
| 148 | + .todaySellQuantity(e.getTodaySellQuantity()) | ||
| 149 | + .soldOut(e.getMaxSellQuantity() == e.getTodaySellQuantity()) | ||
| 150 | + .build(); | ||
| 151 | + }) | ||
| 152 | + .sorted(Comparator.comparing(SkuSellQuantityVO::getSkuCode)) | ||
| 153 | + .collect(Collectors.toList()); | ||
| 154 | + return PageUtil.subListPage(skuSellQuantityVOS, querySkuSellQuantityDTO.getPageNo(), querySkuSellQuantityDTO.getPageSize()); | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + @Override | ||
| 158 | + public boolean batchSetSkuSellQuantity(int stallId, SkuSellQuantityDTO.BatchSetSkuSellQuantityDTO batchSetSkuSellQuantityDTO) { | ||
| 159 | + final var responses = orderServiceRpcClient.querySkuSellQuantitiesByStallAndSkuIds(LoginContextHolder.getEnterpriseId(), stallId, batchSetSkuSellQuantityDTO.getSkuIds()); | ||
| 160 | + final var skuMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity())); | ||
| 161 | + final var skuSellQuantityBOs = batchSetSkuSellQuantityDTO.getSkuIds().stream().map(skuId -> SkuSellQuantityBO.builder() | ||
| 162 | + .id(skuMap.get(skuId) == null ? null : skuMap.get(skuId).getId()) | ||
| 163 | + .skuId(skuId) | ||
| 164 | + .maxSellQuantity(batchSetSkuSellQuantityDTO.getMaxSellQuantity()) | ||
| 165 | + .build() | ||
| 166 | + ).collect(Collectors.toList()); | ||
| 167 | + return orderServiceRpcClient.batchSaveSkuSellQuantities(LoginContextHolder.getEnterpriseId(), stallId, skuSellQuantityBOs); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + @Override | ||
| 171 | + public List<SkuSellQuantityVO> querySkuSellQuantityBySkuIds(SkuSellQuantityDTO.QuerySkuSellQuantityBySkuIdsDTO querySkuSellQuantityBySkuIdsDTO) { | ||
| 172 | + final var stallId = querySkuSellQuantityBySkuIdsDTO.getStallId(); | ||
| 173 | + final var enterpriseId = LoginContextHolder.getEnterpriseId(); | ||
| 174 | + final var skuIds = menuService.queryMenuSkuIdsByStallId(enterpriseId, stallId); | ||
| 175 | + var responses = orderServiceRpcClient.querySkuSellQuantitiesByStall(enterpriseId, stallId); | ||
| 176 | + final var skuSellQuantityMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity())); | ||
| 177 | + responses = skuIds.stream() | ||
| 178 | + .map(skuId -> { | ||
| 179 | + var response = skuSellQuantityMap.get(skuId); | ||
| 180 | + if (response == null) { | ||
| 181 | + response = SingleSkuSellQuantityRpcResponse.newBuilder() | ||
| 182 | + .setSkuId(skuId) | ||
| 183 | + .setMaxSellQuantity(0) | ||
| 184 | + .setTodaySellQuantity(0) | ||
| 185 | + .build(); | ||
| 186 | + } | ||
| 187 | + return response; | ||
| 188 | + }) | ||
| 189 | + .collect(Collectors.toList()); | ||
| 190 | + final var skuList = skuServiceRpcClient.getSkusByIds(responses.stream().map(SingleSkuSellQuantityRpcResponse::getSkuId).collect(Collectors.toList())); | ||
| 191 | + final var skuMap = skuList.stream().collect(Collectors.toMap(SingleSkuResponse::getId, Function.identity())); | ||
| 192 | + return responses.stream() | ||
| 193 | + .map(e -> { | ||
| 194 | + var sku = skuMap.get(e.getSkuId()); | ||
| 195 | + return SkuSellQuantityVO.builder() | ||
| 196 | + .skuId(e.getSkuId()) | ||
| 197 | + .skuName(sku != null ? sku.getName() : "") | ||
| 198 | + .skuCode(sku != null ? sku.getCode() : "") | ||
| 199 | + .maxSellQuantity(e.getMaxSellQuantity()) | ||
| 200 | + .todaySellQuantity(e.getTodaySellQuantity()) | ||
| 201 | + .soldOut(e.getMaxSellQuantity() == e.getTodaySellQuantity()) | ||
| 202 | + .build(); | ||
| 203 | + }) | ||
| 204 | + .sorted(Comparator.comparing(SkuSellQuantityVO::getSkuCode)) | ||
| 205 | + .collect(Collectors.toList()); | ||
| 206 | + } | ||
| 59 | } | 207 | } | ... | ... |
| ... | @@ -33,6 +33,14 @@ service ClientCustomerOrderServiceRpc { | ... | @@ -33,6 +33,14 @@ service ClientCustomerOrderServiceRpc { |
| 33 | // 操作记录 | 33 | // 操作记录 |
| 34 | rpc GetOrderOperationRecordsByOrderId (GetOrderOperationRecordsByOrderIdRequest) returns (GetOrderOperationRecordsByOrderIdResponse) {} | 34 | rpc GetOrderOperationRecordsByOrderId (GetOrderOperationRecordsByOrderIdRequest) returns (GetOrderOperationRecordsByOrderIdResponse) {} |
| 35 | rpc BatchCreateOrderOperationRecords (BatchCreateOrderOperationRecordsRequest) returns (BatchCreateOrderOperationRecordsResponse) {} | 35 | rpc BatchCreateOrderOperationRecords (BatchCreateOrderOperationRecordsRequest) returns (BatchCreateOrderOperationRecordsResponse) {} |
| 36 | + | ||
| 37 | + | ||
| 38 | + // sku菜品库存 | ||
| 39 | + rpc QuerySkuSellQuantitiesByStall(QuerySkuSellQuantitiesByStallRpcRequest) returns (QuerySkuSellQuantitiesByStallRpcResponse) {} | ||
| 40 | + rpc QuerySkuSellQuantitiesByStallAndSkuIds(QuerySkuSellQuantitiesByStallAndSkuIdsRpcRequest) returns (QuerySkuSellQuantitiesByStallAndSkuIdsRpcResponse) {} | ||
| 41 | + rpc BatchSaveSkuSellQuantities(BatchSaveSkuSellQuantitiesRpcRequest) returns (BatchSaveSkuSellQuantitiesRpcResponse) {} | ||
| 42 | + rpc AddSkusSellQuantities(AddSkusSellQuantitiesRpcRequest) returns (AddSkusSellQuantitiesRpcResponse) {} | ||
| 43 | + | ||
| 36 | } | 44 | } |
| 37 | 45 | ||
| 38 | enum OrderStatusEnum { | 46 | enum OrderStatusEnum { |
| ... | @@ -608,3 +616,71 @@ message BatchCreateOrderOperationRecordsResponse { | ... | @@ -608,3 +616,71 @@ message BatchCreateOrderOperationRecordsResponse { |
| 608 | bool isCreated = 1; | 616 | bool isCreated = 1; |
| 609 | repeated int32 ids = 2; | 617 | repeated int32 ids = 2; |
| 610 | } | 618 | } |
| 619 | + | ||
| 620 | +message SingleSkuSellQuantityRpcResponse { | ||
| 621 | + int32 id = 1; | ||
| 622 | + int32 enterpriseId = 2; | ||
| 623 | + int32 stallId = 3; | ||
| 624 | + int32 skuId = 4; | ||
| 625 | + int32 maxSellQuantity = 5; | ||
| 626 | + int32 todaySellQuantity = 6; | ||
| 627 | + int32 createdBy = 7; | ||
| 628 | + int64 createdAt = 8; | ||
| 629 | + int32 creationSource = 9; | ||
| 630 | + int32 updatedBy = 10; | ||
| 631 | + int64 updatedAt = 11; | ||
| 632 | + int32 updateSource = 12; | ||
| 633 | + bool isDeleted = 13; | ||
| 634 | +} | ||
| 635 | + | ||
| 636 | +message QuerySkuSellQuantitiesByStallRpcRequest { | ||
| 637 | + int32 enterpriseId = 1; | ||
| 638 | + int32 stallId = 2; | ||
| 639 | +} | ||
| 640 | + | ||
| 641 | +message QuerySkuSellQuantitiesByStallRpcResponse { | ||
| 642 | + repeated SingleSkuSellQuantityRpcResponse responses = 1; | ||
| 643 | +} | ||
| 644 | + | ||
| 645 | +message QuerySkuSellQuantitiesByStallAndSkuIdsRpcRequest { | ||
| 646 | + int32 enterpriseId = 1; | ||
| 647 | + int32 stallId = 2; | ||
| 648 | + repeated int32 skuIds = 3; | ||
| 649 | +} | ||
| 650 | + | ||
| 651 | +message QuerySkuSellQuantitiesByStallAndSkuIdsRpcResponse { | ||
| 652 | + repeated SingleSkuSellQuantityRpcResponse responses = 1; | ||
| 653 | +} | ||
| 654 | + | ||
| 655 | +message BatchSaveSkuSellQuantitiesRpcRequest { | ||
| 656 | + repeated SkuSellQuantityModification skuSellQuantityModifications = 1; | ||
| 657 | + int32 enterpriseId = 2; | ||
| 658 | + int32 updatedBy = 3; | ||
| 659 | + int32 updateSource = 4; | ||
| 660 | +} | ||
| 661 | + | ||
| 662 | +message SkuSellQuantityModification { | ||
| 663 | + int32 id = 1; | ||
| 664 | + int32 stallId = 2; | ||
| 665 | + int32 skuId = 3; | ||
| 666 | + int32 maxSellQuantity = 4; | ||
| 667 | +} | ||
| 668 | + | ||
| 669 | +message BatchSaveSkuSellQuantitiesRpcResponse { | ||
| 670 | + bool isSaved = 1; | ||
| 671 | +} | ||
| 672 | + | ||
| 673 | +message AddSkusSellQuantitiesRpcRequest { | ||
| 674 | + int32 enterpriseId = 1; | ||
| 675 | + int32 stallId = 2; | ||
| 676 | + repeated SkuSellQuantity skuSellQuantities = 3; | ||
| 677 | +} | ||
| 678 | + | ||
| 679 | +message SkuSellQuantity { | ||
| 680 | + int32 skuId = 1; | ||
| 681 | + int32 quantity = 2; | ||
| 682 | +} | ||
| 683 | + | ||
| 684 | +message AddSkusSellQuantitiesRpcResponse { | ||
| 685 | + bool isAdded = 1; | ||
| 686 | +} | ... | ... |
-
Please register or login to post a comment