zhuyifan

菜品售卖量接口

Showing 41 changed files with 987 additions and 158 deletions
...@@ -44,6 +44,11 @@ public @interface RepeatSubmit { ...@@ -44,6 +44,11 @@ public @interface RepeatSubmit {
44 String message() default "不允许重复提交,请稍后再试"; 44 String message() default "不允许重复提交,请稍后再试";
45 45
46 /** 46 /**
47 + * 是否根据登录用户ID加锁
48 + */
49 + boolean isLockByLoginUser() default true;
50 +
51 + /**
47 * 方法执行完自动释放锁 52 * 方法执行完自动释放锁
48 */ 53 */
49 boolean methodAutoUnlock() default true; 54 boolean methodAutoUnlock() default true;
......
...@@ -110,7 +110,11 @@ public class RepeatSubmitAspect { ...@@ -110,7 +110,11 @@ public class RepeatSubmitAspect {
110 } 110 }
111 } 111 }
112 } 112 }
113 + if (requestLock.isLockByLoginUser()) {
113 final var operatorId = LoginContextHolder.hasLogin() ? LoginContextHolder.getId() : null; 114 final var operatorId = LoginContextHolder.hasLogin() ? LoginContextHolder.getId() : null;
114 return requestLock.prefix() + (operatorId != null ? CommonConstants.COLON + operatorId : "") + (sb.length() > 0 ? CommonConstants.UNDERLINE + sb : ""); 115 return requestLock.prefix() + (operatorId != null ? CommonConstants.COLON + operatorId : "") + (sb.length() > 0 ? CommonConstants.UNDERLINE + sb : "");
116 + } else {
117 + return requestLock.prefix() + (sb.length() > 0 ? CommonConstants.UNDERLINE + sb : "");
118 + }
115 } 119 }
116 } 120 }
......
...@@ -15,4 +15,5 @@ public class BusinessConfig { ...@@ -15,4 +15,5 @@ public class BusinessConfig {
15 private String hisCustomerQueryUrl; 15 private String hisCustomerQueryUrl;
16 private String clientCustomerQueryUrl; 16 private String clientCustomerQueryUrl;
17 private String payUrl; 17 private String payUrl;
18 + private String payClientId;
18 } 19 }
......
...@@ -9,7 +9,7 @@ import io.lettuce.core.resource.ClientResources; ...@@ -9,7 +9,7 @@ import io.lettuce.core.resource.ClientResources;
9 import io.lettuce.core.tracing.BraveTracing; 9 import io.lettuce.core.tracing.BraveTracing;
10 import org.redisson.Redisson; 10 import org.redisson.Redisson;
11 import org.redisson.api.RedissonClient; 11 import org.redisson.api.RedissonClient;
12 -import org.redisson.client.codec.StringCodec; 12 +import org.redisson.codec.JsonJacksonCodec;
13 import org.redisson.config.Config; 13 import org.redisson.config.Config;
14 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.beans.factory.annotation.Qualifier; 15 import org.springframework.beans.factory.annotation.Qualifier;
...@@ -68,7 +68,7 @@ public class RedisConfig { ...@@ -68,7 +68,7 @@ public class RedisConfig {
68 @Value(REDIS_PORT) final String port, 68 @Value(REDIS_PORT) final String port,
69 @Value(REDIS_DATABASE) final int dbToken) { 69 @Value(REDIS_DATABASE) final int dbToken) {
70 final var config = new Config(); 70 final var config = new Config();
71 - config.setCodec(StringCodec.INSTANCE); 71 + config.setCodec(new JsonJacksonCodec());
72 72
73 config.useSingleServer() 73 config.useSingleServer()
74 .setAddress("redis://" + url + ":" + port) 74 .setAddress("redis://" + url + ":" + port)
......
...@@ -15,8 +15,15 @@ import org.springframework.http.converter.StringHttpMessageConverter; ...@@ -15,8 +15,15 @@ import org.springframework.http.converter.StringHttpMessageConverter;
15 import org.springframework.web.client.DefaultResponseErrorHandler; 15 import org.springframework.web.client.DefaultResponseErrorHandler;
16 import org.springframework.web.client.RestTemplate; 16 import org.springframework.web.client.RestTemplate;
17 17
18 +import javax.net.ssl.SSLContext;
19 +import javax.net.ssl.TrustManager;
20 +import javax.net.ssl.X509TrustManager;
18 import java.io.IOException; 21 import java.io.IOException;
19 import java.nio.charset.StandardCharsets; 22 import java.nio.charset.StandardCharsets;
23 +import java.security.KeyManagementException;
24 +import java.security.NoSuchAlgorithmException;
25 +import java.security.SecureRandom;
26 +import java.security.cert.X509Certificate;
20 import java.util.ArrayList; 27 import java.util.ArrayList;
21 import java.util.concurrent.TimeUnit; 28 import java.util.concurrent.TimeUnit;
22 29
...@@ -40,8 +47,26 @@ public class RestTemplateConfig { ...@@ -40,8 +47,26 @@ public class RestTemplateConfig {
40 private Integer keepAliveDuration; 47 private Integer keepAliveDuration;
41 48
42 @Bean 49 @Bean
43 - public OkHttpClient okHttpClient() { 50 + public OkHttpClient okHttpClient() throws NoSuchAlgorithmException, KeyManagementException {
51 + TrustManager[] trustAllCertificates = new TrustManager[]{
52 + new X509TrustManager() {
53 + @Override
54 + public void checkClientTrusted(X509Certificate[] chain, String authType) {}
55 +
56 + @Override
57 + public void checkServerTrusted(X509Certificate[] chain, String authType) {}
58 +
59 + @Override
60 + public X509Certificate[] getAcceptedIssuers() {
61 + return new X509Certificate[0];
62 + }
63 + }
64 + };
65 + SSLContext sslContext = SSLContext.getInstance("TLS");
66 + sslContext.init(null, trustAllCertificates, new SecureRandom());
44 return new OkHttpClient.Builder() 67 return new OkHttpClient.Builder()
68 + .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCertificates[0])
69 + .hostnameVerifier((hostname, session) -> true)
45 .connectTimeout(connectTimeout, TimeUnit.SECONDS) 70 .connectTimeout(connectTimeout, TimeUnit.SECONDS)
46 .readTimeout(readTimeout, TimeUnit.SECONDS) 71 .readTimeout(readTimeout, TimeUnit.SECONDS)
47 .writeTimeout(writeTimeout, TimeUnit.SECONDS) 72 .writeTimeout(writeTimeout, TimeUnit.SECONDS)
......
...@@ -56,4 +56,6 @@ public interface CommonConstants { ...@@ -56,4 +56,6 @@ public interface CommonConstants {
56 56
57 String LOGIN_SOURCE = "loginSource"; 57 String LOGIN_SOURCE = "loginSource";
58 58
59 + String OPEN_ID = "openId";
60 +
59 } 61 }
......
...@@ -37,6 +37,10 @@ public class LoginContextHolder { ...@@ -37,6 +37,10 @@ public class LoginContextHolder {
37 return CONTEXT_HOLDER.get().getEnterpriseId(); 37 return CONTEXT_HOLDER.get().getEnterpriseId();
38 } 38 }
39 39
40 + public static String getOpenId() {
41 + return CONTEXT_HOLDER.get().getOpenId();
42 + }
43 +
40 public static void clear() { 44 public static void clear() {
41 CONTEXT_HOLDER.remove(); 45 CONTEXT_HOLDER.remove();
42 } 46 }
...@@ -54,7 +58,8 @@ public class LoginContextHolder { ...@@ -54,7 +58,8 @@ public class LoginContextHolder {
54 58
55 private String name; 59 private String name;
56 60
57 - private String openid; 61 + @Builder.Default
62 + private String openId = "";
58 63
59 } 64 }
60 65
......
...@@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; ...@@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
18 import org.springframework.web.bind.annotation.RestController; 18 import org.springframework.web.bind.annotation.RestController;
19 19
20 import javax.validation.Valid; 20 import javax.validation.Valid;
21 +import java.security.NoSuchAlgorithmException;
21 22
22 @Api(tags = "登陆") 23 @Api(tags = "登陆")
23 @ApiSupport(order = -1) 24 @ApiSupport(order = -1)
...@@ -32,7 +33,7 @@ public class LoginController { ...@@ -32,7 +33,7 @@ public class LoginController {
32 @ApiOperation(value = "登陆") 33 @ApiOperation(value = "登陆")
33 @PostMapping("/login") 34 @PostMapping("/login")
34 @ResponseStatus(HttpStatus.OK) 35 @ResponseStatus(HttpStatus.OK)
35 - public SaTokenInfo login(@Valid @RequestBody PermissionDTO.LoginDto loginDto) { 36 + public SaTokenInfo login(@Valid @RequestBody PermissionDTO.LoginDto loginDto) throws NoSuchAlgorithmException {
36 return loginService.login(loginDto); 37 return loginService.login(loginDto);
37 } 38 }
38 } 39 }
......
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;
...@@ -64,9 +65,10 @@ public class OrderController { ...@@ -64,9 +65,10 @@ public class OrderController {
64 return orderService.getOrderDetailsByOrderId(orderId); 65 return orderService.getOrderDetailsByOrderId(orderId);
65 } 66 }
66 67
67 - @ApiOperation(value = "创建订单") 68 + @ApiOperation(value = "小程序创建订单")
68 @PostMapping("/orders") 69 @PostMapping("/orders")
69 @ResponseStatus(HttpStatus.OK) 70 @ResponseStatus(HttpStatus.OK)
71 + @RepeatSubmit(prefix = "createOrder", isLockByLoginUser = false)
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", isLockByLoginUser = false)
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,20 +88,17 @@ public class OrderController { ...@@ -87,20 +88,17 @@ 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
99 @ApiOperation(value = "获取已预定该餐单的次数") 98 @ApiOperation(value = "获取已预定该餐单的次数")
100 @PostMapping("/order/check") 99 @PostMapping("/order/check")
101 @ResponseStatus(HttpStatus.OK) 100 @ResponseStatus(HttpStatus.OK)
102 - public Integer checkOrder( 101 + public Integer checkOrder(@Valid @RequestBody OrderDbDTO.getMenuOrderCountDto checkIfOrderedDto) {
103 - @Valid @RequestBody OrderDbDTO.getMenuOrderCountDto checkIfOrderedDto) {
104 return orderService.getMenuOrderCount(checkIfOrderedDto); 102 return orderService.getMenuOrderCount(checkIfOrderedDto);
105 } 103 }
106 104
......
...@@ -31,7 +31,6 @@ public class PayController { ...@@ -31,7 +31,6 @@ public class PayController {
31 31
32 private final PayServiceClient payServiceClient; 32 private final PayServiceClient payServiceClient;
33 33
34 - @SaIgnore
35 @ApiOperation(value = "支付信息") 34 @ApiOperation(value = "支付信息")
36 @PostMapping("/pay/inform") 35 @PostMapping("/pay/inform")
37 @ResponseStatus(HttpStatus.OK) 36 @ResponseStatus(HttpStatus.OK)
...@@ -39,7 +38,6 @@ public class PayController { ...@@ -39,7 +38,6 @@ public class PayController {
39 return payServiceClient.payInform(payInformRequestDto); 38 return payServiceClient.payInform(payInformRequestDto);
40 } 39 }
41 40
42 - @SaIgnore
43 @ApiOperation(value = "支付中") 41 @ApiOperation(value = "支付中")
44 @PostMapping("/order/{orderId}/pay/waiting") 42 @PostMapping("/order/{orderId}/pay/waiting")
45 @ResponseStatus(HttpStatus.OK) 43 @ResponseStatus(HttpStatus.OK)
......
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.model.common.PageResult;
4 import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto; 5 import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto;
5 import com.infoloop.tianting.model.dto.SkuDbDTO.SkuIdsDto; 6 import com.infoloop.tianting.model.dto.SkuDbDTO.SkuIdsDto;
7 +import com.infoloop.tianting.model.dto.SkuSellQuantityDTO;
8 +import com.infoloop.tianting.model.vo.SkuSellQuantityStatisticsVO;
9 +import com.infoloop.tianting.model.vo.SkuSellQuantityVO;
6 import com.infoloop.tianting.service.SkuService; 10 import com.infoloop.tianting.service.SkuService;
7 import io.swagger.annotations.Api; 11 import io.swagger.annotations.Api;
8 import io.swagger.annotations.ApiOperation; 12 import io.swagger.annotations.ApiOperation;
...@@ -11,7 +15,10 @@ import lombok.extern.slf4j.Slf4j; ...@@ -11,7 +15,10 @@ import lombok.extern.slf4j.Slf4j;
11 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.http.HttpStatus; 16 import org.springframework.http.HttpStatus;
13 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
18 +import org.springframework.web.bind.annotation.GetMapping;
19 +import org.springframework.web.bind.annotation.PathVariable;
14 import org.springframework.web.bind.annotation.PostMapping; 20 import org.springframework.web.bind.annotation.PostMapping;
21 +import org.springframework.web.bind.annotation.PutMapping;
15 import org.springframework.web.bind.annotation.RequestBody; 22 import org.springframework.web.bind.annotation.RequestBody;
16 import org.springframework.web.bind.annotation.ResponseStatus; 23 import org.springframework.web.bind.annotation.ResponseStatus;
17 import org.springframework.web.bind.annotation.RestController; 24 import org.springframework.web.bind.annotation.RestController;
...@@ -32,7 +39,36 @@ public class SkuController { ...@@ -32,7 +39,36 @@ public class SkuController {
32 @ApiOperation(value = "根据sku ids获取") 39 @ApiOperation(value = "根据sku ids获取")
33 @PostMapping("/skus") 40 @PostMapping("/skus")
34 @ResponseStatus(HttpStatus.OK) 41 @ResponseStatus(HttpStatus.OK)
35 - public List<SkuDto> getOrderByCustomerId(@Valid @RequestBody SkuIdsDto skuIdsDto) { 42 + public List<SkuDto> getSkusByIds(@Valid @RequestBody SkuIdsDto skuIdsDto) {
36 return skuService.getSkusByIds(skuIdsDto.getIds()); 43 return skuService.getSkusByIds(skuIdsDto.getIds());
37 } 44 }
45 +
46 + @ApiOperation(value = "获取菜品售卖量统计")
47 + @GetMapping("/stall/{stallId}/skusellquantities/statistics")
48 + @ResponseStatus(HttpStatus.OK)
49 + public SkuSellQuantityStatisticsVO querySkuSellQuantityStatistics(@PathVariable("stallId") int stallId) {
50 + return skuService.querySkuSellQuantityStatistics(stallId);
51 + }
52 +
53 + @ApiOperation(value = "分页查询菜品售卖量")
54 + @PostMapping("/skusellquantities/query")
55 + @ResponseStatus(HttpStatus.OK)
56 + public PageResult<SkuSellQuantityVO> querySkuSellQuantity(@Valid @RequestBody SkuSellQuantityDTO.QuerySkuSellQuantityDTO querySkuSellQuantityDTO) {
57 + return skuService.querySkuSellQuantity(querySkuSellQuantityDTO);
58 + }
59 +
60 + @ApiOperation(value = "批量设置菜品售卖量")
61 + @PutMapping("/stall/{stallId}/skusellquantities/batchset")
62 + @ResponseStatus(HttpStatus.CREATED)
63 + public boolean batchSetSkuSellQuantity(@PathVariable("stallId") int stallId,
64 + @Valid @RequestBody SkuSellQuantityDTO.BatchSetSkuSellQuantityDTO batchSetSkuSellQuantityDTO) {
65 + return skuService.batchSetSkuSellQuantity(stallId, batchSetSkuSellQuantityDTO);
66 + }
67 +
68 + @ApiOperation(value = "根据菜品ids批量查询菜品售卖量")
69 + @PostMapping("/skusellquantities/querybyskuids")
70 + @ResponseStatus(HttpStatus.OK)
71 + public List<SkuSellQuantityVO> querySkuSellQuantityBySkuIds(@Valid @RequestBody SkuSellQuantityDTO.QuerySkuSellQuantityBySkuIdsDTO querySkuSellQuantityBySkuIdsDTO) {
72 + return skuService.querySkuSellQuantityBySkuIds(querySkuSellQuantityBySkuIdsDTO);
73 + }
38 } 74 }
......
1 package com.infoloop.tianting.enums; 1 package com.infoloop.tianting.enums;
2 2
3 -import com.infoloop.tianting.exception.BaseEnum;
4 import lombok.AllArgsConstructor; 3 import lombok.AllArgsConstructor;
5 import lombok.Getter; 4 import lombok.Getter;
6 5
7 @Getter 6 @Getter
8 @AllArgsConstructor 7 @AllArgsConstructor
9 public enum LoginSourceEnum{ 8 public enum LoginSourceEnum{
10 - CUSTOMER(1, "小程序住院客户"), 9 + CUSTOMER(1, "住院客户"),
11 - MINI_PROGRAM(2, "小程序非住院客户"), 10 + MINI_PROGRAM(2, "阳光厅客户"),
12 OPERATOR(3, "院区端"), 11 OPERATOR(3, "院区端"),
13 KDS(4, "KDS"), 12 KDS(4, "KDS"),
14 ; 13 ;
......
1 +package com.infoloop.tianting.enums;
2 +
3 +public enum SkuSellQuantityStatus {
4 +
5 + ALL,
6 + SOLD_OUT,
7 + ON_SALE
8 +}
...@@ -29,6 +29,12 @@ public enum ErrorCodeEnum implements BaseEnum { ...@@ -29,6 +29,12 @@ 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, "下单菜品\n{0}\n今日已售罄"),
34 +
35 + SKUS_STOCK_NO_ENOUGH_TODAY(406000007, "下单菜品\n{0}\n库存不足"),
36 +
37 + ORDER_CANCEL(406000008, "订单已自动取消")
32 ; 38 ;
33 private final int code; 39 private final int code;
34 40
......
...@@ -12,15 +12,12 @@ import com.infoloop.tianting.enums.LoginSourceEnum; ...@@ -12,15 +12,12 @@ import com.infoloop.tianting.enums.LoginSourceEnum;
12 import com.infoloop.tianting.exception.ClientEndExceptions; 12 import com.infoloop.tianting.exception.ClientEndExceptions;
13 import com.infoloop.tianting.exception.ErrorCodeEnum; 13 import com.infoloop.tianting.exception.ErrorCodeEnum;
14 import com.infoloop.tianting.model.common.ResponseResult; 14 import com.infoloop.tianting.model.common.ResponseResult;
15 -import com.infoloop.tianting.service.ClientCustomerService;
16 import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient; 15 import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
17 import com.infoloop.tianting.service.client.OperatorServiceRpcClient; 16 import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
18 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient; 17 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient;
19 import com.infoloop.tianting.utils.ResponseUtil; 18 import com.infoloop.tianting.utils.ResponseUtil;
20 import lombok.RequiredArgsConstructor; 19 import lombok.RequiredArgsConstructor;
21 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
22 -import org.apache.tomcat.jni.Error;
23 -import org.springframework.beans.factory.annotation.Autowired;
24 import org.springframework.http.HttpStatus; 21 import org.springframework.http.HttpStatus;
25 import org.springframework.stereotype.Component; 22 import org.springframework.stereotype.Component;
26 import org.springframework.web.method.HandlerMethod; 23 import org.springframework.web.method.HandlerMethod;
...@@ -70,7 +67,9 @@ public class LoginInterceptor extends HandlerInterceptorAdapter { ...@@ -70,7 +67,9 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
70 StpUtil.checkLogin(); 67 StpUtil.checkLogin();
71 final var enterpriseId = Convert.toInt(StpUtil.getExtra(CommonConstants.ENTERPRISE_ID)); 68 final var enterpriseId = Convert.toInt(StpUtil.getExtra(CommonConstants.ENTERPRISE_ID));
72 final var loginSource = Convert.toInt(StpUtil.getExtra(CommonConstants.LOGIN_SOURCE)); 69 final var loginSource = Convert.toInt(StpUtil.getExtra(CommonConstants.LOGIN_SOURCE));
70 + log.info("Login success, enterpriseId: {}, loginSource: {}", enterpriseId, loginSource);
73 if (loginSource.equals(LoginSourceEnum.CUSTOMER.getValue())) { 71 if (loginSource.equals(LoginSourceEnum.CUSTOMER.getValue())) {
72 + final var openId = Convert.toStr(StpUtil.getExtra(CommonConstants.OPEN_ID));
74 final var loginId = StpUtil.getLoginIdAsInt(); 73 final var loginId = StpUtil.getLoginIdAsInt();
75 final var customer = clientCustomerServiceRpcClient.getClientCustomerById(enterpriseId, loginId); 74 final var customer = clientCustomerServiceRpcClient.getClientCustomerById(enterpriseId, loginId);
76 if (customer == null) { 75 if (customer == null) {
...@@ -78,7 +77,8 @@ public class LoginInterceptor extends HandlerInterceptorAdapter { ...@@ -78,7 +77,8 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
78 ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.VALIDATE_FAILED)); 77 ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.VALIDATE_FAILED));
79 return false; 78 return false;
80 } 79 }
81 - builder.id(loginId).enterpriseId(enterpriseId).name(customer.getResponse().getName()); 80 + log.info("Customer login success, customerId: {}, enterpriseId: {}, openId:{}", loginId, enterpriseId, openId);
81 + builder.id(loginId).enterpriseId(enterpriseId).name(customer.getResponse().getName()).openId(openId);
82 return true; 82 return true;
83 } else if (loginSource.equals(LoginSourceEnum.OPERATOR.getValue())){ 83 } else if (loginSource.equals(LoginSourceEnum.OPERATOR.getValue())){
84 final var loginId = StpUtil.getLoginIdAsInt(); 84 final var loginId = StpUtil.getLoginIdAsInt();
...@@ -101,7 +101,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter { ...@@ -101,7 +101,7 @@ public class LoginInterceptor extends HandlerInterceptorAdapter {
101 return true; 101 return true;
102 } else { 102 } else {
103 final var loginId = StpUtil.getLoginIdAsString(); 103 final var loginId = StpUtil.getLoginIdAsString();
104 - builder.openid(loginId).enterpriseId(enterpriseId); 104 + builder.openId(loginId).enterpriseId(enterpriseId);
105 return true; 105 return true;
106 } 106 }
107 } 107 }
......
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.CloseTimeType;
4 +import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
5 +import com.infoloop.tianting.logic.delay.param.AutoCancelParam;
6 +import com.infoloop.tianting.model.bo.AddSkusSellQuantityBO;
7 +import com.infoloop.tianting.service.client.OrderServiceRpcClient;
8 +import lombok.RequiredArgsConstructor;
9 +import lombok.extern.slf4j.Slf4j;
10 +import org.springframework.stereotype.Component;
11 +
12 +import javax.annotation.PostConstruct;
13 +import java.util.stream.Collectors;
14 +
15 +@Slf4j
16 +@Component
17 +@RequiredArgsConstructor
18 +public class OrderAutoCancelDelayTask {
19 +
20 + private final DelayedQueue<AutoCancelParam> delayedQueue;
21 +
22 + private final OrderServiceRpcClient orderServiceRpcClient;
23 +
24 + public static final String AUTO_CANCEL_ORDER_DELAY_QUEUE = "AUTO_CANCEL_ORDER_QUEUE";
25 +
26 + @PostConstruct
27 + public void init() {
28 + delayedQueue.initQueue(AUTO_CANCEL_ORDER_DELAY_QUEUE, this::execute);
29 + }
30 +
31 + private void execute(AutoCancelParam param) {
32 + try {
33 + final var orderById = orderServiceRpcClient.getOrderById(param.getOrderId());
34 + if (orderById == null) {
35 + log.error("Order not found, orderId: {}", param.getOrderId());
36 + return;
37 + }
38 + if (orderById.getPayStatus() == PayStatusEnum.PAY_CANCELED) {
39 + log.info("Order {} already canceled, skipping.", param.getOrderId());
40 + return;
41 + }
42 + if (orderById.getPayStatus() != PayStatusEnum.TO_PAY) {
43 + log.info("Order {} not to pay, skipping.", param.getOrderId());
44 + return;
45 + }
46 + final var isUpdated = orderServiceRpcClient.updateClientCustomerOrderCancel(orderById.getEnterpriseId(), orderById.getId());
47 + if (isUpdated && orderById.getCloseTimeType() == CloseTimeType.IMMEDIATELY) {
48 + // 立即点餐需回滚库存
49 + final var orderDetails = orderServiceRpcClient.getOrderDetailsByOrderId(orderById.getId());
50 + final var isSuccess = orderServiceRpcClient.addSkusSellQuantities(orderById.getEnterpriseId(), orderById.getStallId(), orderDetails.stream().map(e -> AddSkusSellQuantityBO.builder()
51 + .skuId(e.getSkuId())
52 + .quantity(-e.getCount())
53 + .build()).collect(Collectors.toList()));
54 + log.info("Order {} returnSkusSellQuantities result: {}", param.getOrderId(), isSuccess);
55 + }
56 + } catch (Exception e) {
57 + log.error("OrderAutoCancelDelayTask execute error", e);
58 + }
59 + }
60 +
61 +}
1 +package com.infoloop.tianting.logic.delay.param;
2 +
3 +import lombok.Data;
4 +
5 +@Data
6 +public class AutoCancelParam {
7 +
8 + private int orderId;
9 +
10 +}
1 +package com.infoloop.tianting.model.bo;
2 +
3 +import lombok.Builder;
4 +import lombok.Data;
5 +
6 +@Data
7 +@Builder
8 +public class AddSkusSellQuantityBO {
9 +
10 + private int skuId;
11 +
12 + private int quantity;
13 +}
1 +package com.infoloop.tianting.model.bo;
2 +
3 +import lombok.Builder;
4 +import lombok.Data;
5 +
6 +@Data
7 +@Builder
8 +public class SkuSellQuantityBO {
9 +
10 + private Integer id;
11 +
12 + private int skuId;
13 +
14 + private int maxSellQuantity;
15 +}
...@@ -3,19 +3,16 @@ package com.infoloop.tianting.model.common; ...@@ -3,19 +3,16 @@ package com.infoloop.tianting.model.common;
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
5 import lombok.Data; 5 import lombok.Data;
6 -import lombok.Singular;
7 6
7 +import javax.validation.constraints.NotEmpty;
8 import java.util.List; 8 import java.util.List;
9 9
10 @Data 10 @Data
11 @ApiModel(description = "公共参数") 11 @ApiModel(description = "公共参数")
12 -public class Param { 12 +public class IdsParam {
13 13
14 @ApiModelProperty(value = "ids") 14 @ApiModelProperty(value = "ids")
15 - @Singular("id") 15 + @NotEmpty(message = "ids不能为空")
16 private List<Integer> ids; 16 private List<Integer> ids;
17 17
18 - @ApiModelProperty(value = "keyword")
19 - private String keyword;
20 -
21 } 18 }
......
1 package com.infoloop.tianting.model.dto; 1 package com.infoloop.tianting.model.dto;
2 2
3 +import com.infoloop.tianting.annotation.RequestKeyParam;
3 import com.infoloop.tianting.clientcustomerorderservice.CloseTimeType; 4 import com.infoloop.tianting.clientcustomerorderservice.CloseTimeType;
4 import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum; 5 import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum;
5 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 6 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
7 +import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
6 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; 8 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
7 -import com.infoloop.tianting.menuservice.CloseTimeTypeEnum;
8 import com.infoloop.tianting.model.common.PageInfo; 9 import com.infoloop.tianting.model.common.PageInfo;
9 import io.swagger.annotations.ApiModel; 10 import io.swagger.annotations.ApiModel;
10 import io.swagger.annotations.ApiModelProperty; 11 import io.swagger.annotations.ApiModelProperty;
11 -import io.swagger.models.auth.In;
12 -import java.time.LocalDateTime;
13 -import java.util.ArrayList;
14 -import java.util.List;
15 -import java.util.Optional;
16 -import javax.validation.Valid;
17 -import jdk.jfr.StackTrace;
18 import lombok.AllArgsConstructor; 12 import lombok.AllArgsConstructor;
19 import lombok.Builder; 13 import lombok.Builder;
20 -import lombok.Builder.Default;
21 import lombok.Data; 14 import lombok.Data;
22 import lombok.NoArgsConstructor; 15 import lombok.NoArgsConstructor;
23 import lombok.ToString; 16 import lombok.ToString;
24 17
18 +import javax.validation.Valid;
19 +import java.time.LocalDateTime;
20 +import java.util.ArrayList;
21 +import java.util.List;
22 +
25 @Data 23 @Data
26 @ApiModel(description = "订单DTO") 24 @ApiModel(description = "订单DTO")
27 public class OrderDbDTO { 25 public class OrderDbDTO {
...@@ -204,6 +202,8 @@ public class OrderDbDTO { ...@@ -204,6 +202,8 @@ public class OrderDbDTO {
204 @Builder 202 @Builder
205 @ApiModel(description = "创建订单视图") 203 @ApiModel(description = "创建订单视图")
206 public static class OperatorCreateOrderDto { 204 public static class OperatorCreateOrderDto {
205 +
206 + @RequestKeyParam
207 @ApiModelProperty(value = "档口 ID") 207 @ApiModelProperty(value = "档口 ID")
208 private Integer stallId; 208 private Integer stallId;
209 209
...@@ -216,6 +216,9 @@ public class OrderDbDTO { ...@@ -216,6 +216,9 @@ public class OrderDbDTO {
216 @ApiModelProperty(value = "用餐日期") 216 @ApiModelProperty(value = "用餐日期")
217 private LocalDateTime mealTime; 217 private LocalDateTime mealTime;
218 218
219 + @ApiModelProperty(value = "桌号")
220 + private String tableCode;
221 +
219 @ApiModelProperty(value = "备注") 222 @ApiModelProperty(value = "备注")
220 private String remark; 223 private String remark;
221 224
...@@ -235,6 +238,7 @@ public class OrderDbDTO { ...@@ -235,6 +238,7 @@ public class OrderDbDTO {
235 @ApiModelProperty(value = "院区 ID") 238 @ApiModelProperty(value = "院区 ID")
236 private Integer clientId; 239 private Integer clientId;
237 240
241 + @RequestKeyParam
238 @ApiModelProperty(value = "档口 ID") 242 @ApiModelProperty(value = "档口 ID")
239 private Integer stallId; 243 private Integer stallId;
240 244
...@@ -244,12 +248,6 @@ public class OrderDbDTO { ...@@ -244,12 +248,6 @@ public class OrderDbDTO {
244 @ApiModelProperty(value = "客户 ID") 248 @ApiModelProperty(value = "客户 ID")
245 private Integer customerId; 249 private Integer customerId;
246 250
247 - @ApiModelProperty(value = "需要创建阳光厅点餐客户open ID")
248 - private Boolean shouldCreateOpenId;
249 -
250 - @ApiModelProperty(value = "阳光厅点餐客户 ID")
251 - private String openId;
252 -
253 @ApiModelProperty(value = "状态订单;待备餐=1,备餐中=2,部分出餐=3,已出餐=4,已取消=5") 251 @ApiModelProperty(value = "状态订单;待备餐=1,备餐中=2,部分出餐=3,已出餐=4,已取消=5")
254 private Integer status; 252 private Integer status;
255 253
...@@ -496,6 +494,12 @@ public class OrderDbDTO { ...@@ -496,6 +494,12 @@ public class OrderDbDTO {
496 @ApiModelProperty(value = "菜品展示名称") 494 @ApiModelProperty(value = "菜品展示名称")
497 private String showName; 495 private String showName;
498 496
497 + @ApiModelProperty(value = "订单状态")
498 + private OrderStatusEnum status;
499 +
500 + @ApiModelProperty(value = "订单支付状态")
501 + private PayStatusEnum payStatus;
502 +
499 @ApiModelProperty(value = "菜品详情,菜品主料、口味、能量、脂肪、蛋白质、碳水化合物、忌口、医嘱等") 503 @ApiModelProperty(value = "菜品详情,菜品主料、口味、能量、脂肪、蛋白质、碳水化合物、忌口、医嘱等")
500 private MealDetailDto mealDetailJson; 504 private MealDetailDto mealDetailJson;
501 505
...@@ -535,6 +539,7 @@ public class OrderDbDTO { ...@@ -535,6 +539,7 @@ public class OrderDbDTO {
535 @ToString 539 @ToString
536 @ApiModel(description = "订单详情信息,即菜品细节") 540 @ApiModel(description = "订单详情信息,即菜品细节")
537 public static class OperatorCreateOrderDetailDto { 541 public static class OperatorCreateOrderDetailDto {
542 +
538 @ApiModelProperty(value = "餐单详情 id,即菜品") 543 @ApiModelProperty(value = "餐单详情 id,即菜品")
539 private Integer menuDetailId; 544 private Integer menuDetailId;
540 545
......
...@@ -20,7 +20,6 @@ public class PayDTO { ...@@ -20,7 +20,6 @@ public class PayDTO {
20 public static class PayInformRequestDto { 20 public static class PayInformRequestDto {
21 private String clientId; 21 private String clientId;
22 private String orderId; 22 private String orderId;
23 - private String openId;
24 private String hospitalCode; 23 private String hospitalCode;
25 private String price; 24 private String price;
26 private String phone; 25 private String phone;
......
1 +package com.infoloop.tianting.model.dto;
2 +
3 +import com.infoloop.tianting.enums.SkuSellQuantityStatus;
4 +import com.infoloop.tianting.model.common.PageInfo;
5 +import io.swagger.annotations.ApiModel;
6 +import io.swagger.annotations.ApiModelProperty;
7 +import lombok.Data;
8 +import lombok.EqualsAndHashCode;
9 +
10 +import javax.validation.constraints.NotEmpty;
11 +import javax.validation.constraints.NotNull;
12 +import java.util.List;
13 +
14 +@Data
15 +@ApiModel(description = "SkuSellQuantityDTO")
16 +public class SkuSellQuantityDTO {
17 +
18 + @Data
19 + @ApiModel(description = "批量设置菜品售卖量")
20 + public static class BatchSetSkuSellQuantityDTO {
21 +
22 + @ApiModelProperty("菜品 Ids")
23 + @NotEmpty
24 + private List<Integer> skuIds;
25 +
26 + @ApiModelProperty("最大售卖数量")
27 + @NotNull
28 + private Integer maxSellQuantity;
29 + }
30 +
31 +
32 + @EqualsAndHashCode(callSuper = true)
33 + @Data
34 + @ApiModel(description = "分页查询菜品售卖量")
35 + public static class QuerySkuSellQuantityDTO extends PageInfo {
36 +
37 + @ApiModelProperty("档口Id")
38 + @NotNull
39 + private Integer stallId;
40 +
41 + @ApiModelProperty("菜品售卖状态")
42 + @NotNull
43 + private SkuSellQuantityStatus status;
44 +
45 + @ApiModelProperty("关键字")
46 + private String keyword;
47 + }
48 +
49 + @Data
50 + @ApiModel(description = "根据菜品 Ids 查询菜品售卖量")
51 + public static class QuerySkuSellQuantityBySkuIdsDTO {
52 +
53 + @ApiModelProperty("档口Id")
54 + @NotNull
55 + private Integer stallId;
56 +
57 + @ApiModelProperty("菜品售卖状态")
58 + @NotEmpty
59 + private List<Integer> skuIds;
60 + }
61 +
62 +}
1 +package com.infoloop.tianting.model.vo;
2 +
3 +import io.swagger.annotations.ApiModel;
4 +import io.swagger.annotations.ApiModelProperty;
5 +import lombok.Builder;
6 +import lombok.Data;
7 +
8 +@Data
9 +@ApiModel
10 +@Builder
11 +public class SkuSellQuantityStatisticsVO {
12 +
13 + @ApiModelProperty("全部")
14 + private int total;
15 +
16 + @ApiModelProperty("售罄")
17 + private Long soldOut;
18 +
19 + @ApiModelProperty("在售")
20 + private Long onSale;
21 +}
1 +package com.infoloop.tianting.model.vo;
2 +
3 +import io.swagger.annotations.ApiModel;
4 +import io.swagger.annotations.ApiModelProperty;
5 +import lombok.Builder;
6 +import lombok.Data;
7 +
8 +
9 +@Data
10 +@ApiModel
11 +@Builder
12 +public class SkuSellQuantityVO {
13 +
14 + @ApiModelProperty("菜品Id")
15 + private Integer skuId;
16 +
17 + @ApiModelProperty("菜品名称")
18 + private String skuName;
19 +
20 + @ApiModelProperty("菜品编号")
21 + private String skuCode;
22 +
23 + @ApiModelProperty("最大售卖数量")
24 + private int maxSellQuantity;
25 +
26 + @ApiModelProperty("今日售卖数量")
27 + private int todaySellQuantity;
28 +
29 + @ApiModelProperty("是否售罄")
30 + private Boolean soldOut;
31 +
32 +}
...@@ -3,6 +3,8 @@ package com.infoloop.tianting.service; ...@@ -3,6 +3,8 @@ package com.infoloop.tianting.service;
3 import cn.dev33.satoken.stp.SaTokenInfo; 3 import cn.dev33.satoken.stp.SaTokenInfo;
4 import com.infoloop.tianting.model.dto.PermissionDTO.LoginDto; 4 import com.infoloop.tianting.model.dto.PermissionDTO.LoginDto;
5 5
6 +import java.security.NoSuchAlgorithmException;
7 +
6 public interface LoginService { 8 public interface LoginService {
7 - SaTokenInfo login(LoginDto loginDto); 9 + SaTokenInfo login(LoginDto loginDto) throws NoSuchAlgorithmException;
8 } 10 }
......
...@@ -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 }
......
1 package com.infoloop.tianting.service.client; 1 package com.infoloop.tianting.service.client;
2 2
3 import com.infoloop.tianting.SingleResponse; 3 import com.infoloop.tianting.SingleResponse;
4 +import com.infoloop.tianting.SingleSkuResponse;
4 import com.infoloop.tianting.SingleSpecialResponse; 5 import com.infoloop.tianting.SingleSpecialResponse;
6 +import com.infoloop.tianting.clientcustomerorderservice.AddSkusSellQuantitiesRpcRequest;
5 import com.infoloop.tianting.clientcustomerorderservice.BatchCreateOrderOperationRecordsRequest; 7 import com.infoloop.tianting.clientcustomerorderservice.BatchCreateOrderOperationRecordsRequest;
6 import com.infoloop.tianting.clientcustomerorderservice.BatchCreateOrderOperationRecordsResponse; 8 import com.infoloop.tianting.clientcustomerorderservice.BatchCreateOrderOperationRecordsResponse;
9 +import com.infoloop.tianting.clientcustomerorderservice.BatchSaveSkuSellQuantitiesRpcRequest;
7 import com.infoloop.tianting.clientcustomerorderservice.BatchUpdateClientCustomerOrderDetailsRpcRequest; 10 import com.infoloop.tianting.clientcustomerorderservice.BatchUpdateClientCustomerOrderDetailsRpcRequest;
8 import com.infoloop.tianting.clientcustomerorderservice.BatchUpdateClientCustomerOrderDetailsRpcResponse; 11 import com.infoloop.tianting.clientcustomerorderservice.BatchUpdateClientCustomerOrderDetailsRpcResponse;
9 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderCreation; 12 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderCreation;
...@@ -13,7 +16,6 @@ import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModif ...@@ -13,7 +16,6 @@ import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModif
13 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderServiceRpcGrpc; 16 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderServiceRpcGrpc;
14 import com.infoloop.tianting.clientcustomerorderservice.CloseTimeType; 17 import com.infoloop.tianting.clientcustomerorderservice.CloseTimeType;
15 import com.infoloop.tianting.clientcustomerorderservice.CreateClientCustomerOrderRpcRequest; 18 import com.infoloop.tianting.clientcustomerorderservice.CreateClientCustomerOrderRpcRequest;
16 -import com.infoloop.tianting.clientcustomerorderservice.CreateClientCustomerOrderRpcResponse;
17 import com.infoloop.tianting.clientcustomerorderservice.CustomerNotice; 19 import com.infoloop.tianting.clientcustomerorderservice.CustomerNotice;
18 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderByIdRpcRequest; 20 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderByIdRpcRequest;
19 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderDetailsByIdsRpcRequest; 21 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderDetailsByIdsRpcRequest;
...@@ -28,13 +30,27 @@ import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; ...@@ -28,13 +30,27 @@ import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
28 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByConditionRpcRequest; 30 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByConditionRpcRequest;
29 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcRequest; 31 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcRequest;
30 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcResponse; 32 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcResponse;
33 +import com.infoloop.tianting.clientcustomerorderservice.QuerySkuSellQuantitiesByStallAndSkuIdsRpcRequest;
34 +import com.infoloop.tianting.clientcustomerorderservice.QuerySkuSellQuantitiesByStallRpcRequest;
31 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; 35 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
32 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse; 36 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
33 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse; 37 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
38 +import com.infoloop.tianting.clientcustomerorderservice.SingleSkuSellQuantityRpcResponse;
39 +import com.infoloop.tianting.clientcustomerorderservice.SkuSellQuantity;
40 +import com.infoloop.tianting.clientcustomerorderservice.SkuSellQuantityModification;
34 import com.infoloop.tianting.clientcustomerorderservice.UpdateClientCustomerOrderRpcRequest; 41 import com.infoloop.tianting.clientcustomerorderservice.UpdateClientCustomerOrderRpcRequest;
35 import com.infoloop.tianting.clientcustomerorderservice.UpdateClientCustomerOrderRpcResponse; 42 import com.infoloop.tianting.clientcustomerorderservice.UpdateClientCustomerOrderRpcResponse;
36 import com.infoloop.tianting.context.LoginContextHolder; 43 import com.infoloop.tianting.context.LoginContextHolder;
37 import com.infoloop.tianting.enums.OrderTypeEnum; 44 import com.infoloop.tianting.enums.OrderTypeEnum;
45 +import com.infoloop.tianting.exception.ClientEndExceptions;
46 +import com.infoloop.tianting.exception.ErrorCodeEnum;
47 +import com.infoloop.tianting.logic.delay.DelayedQueue;
48 +import com.infoloop.tianting.logic.delay.OrderAutoCancelDelayTask;
49 +import com.infoloop.tianting.logic.delay.param.AutoCancelParam;
50 +import com.infoloop.tianting.menuservice.CloseTimeTypeEnum;
51 +import com.infoloop.tianting.menuservice.ModeOfPaymentEnum;
52 +import com.infoloop.tianting.model.bo.AddSkusSellQuantityBO;
53 +import com.infoloop.tianting.model.bo.SkuSellQuantityBO;
38 import com.infoloop.tianting.model.dto.OperationDTO.BatchOperationDto; 54 import com.infoloop.tianting.model.dto.OperationDTO.BatchOperationDto;
39 import com.infoloop.tianting.model.dto.OperationDTO.SingleOperationDto; 55 import com.infoloop.tianting.model.dto.OperationDTO.SingleOperationDto;
40 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDetailDto; 56 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDetailDto;
...@@ -51,6 +67,7 @@ import com.infoloop.tianting.utils.DateUtil; ...@@ -51,6 +67,7 @@ import com.infoloop.tianting.utils.DateUtil;
51 import com.infoloop.tianting.utils.JsonUtil; 67 import com.infoloop.tianting.utils.JsonUtil;
52 import lombok.RequiredArgsConstructor; 68 import lombok.RequiredArgsConstructor;
53 import lombok.extern.slf4j.Slf4j; 69 import lombok.extern.slf4j.Slf4j;
70 +import org.redisson.api.RAtomicLong;
54 import org.redisson.api.RedissonClient; 71 import org.redisson.api.RedissonClient;
55 import org.springframework.beans.factory.annotation.Autowired; 72 import org.springframework.beans.factory.annotation.Autowired;
56 import org.springframework.stereotype.Service; 73 import org.springframework.stereotype.Service;
...@@ -59,7 +76,10 @@ import javax.annotation.Nullable; ...@@ -59,7 +76,10 @@ import javax.annotation.Nullable;
59 import java.time.LocalDate; 76 import java.time.LocalDate;
60 import java.time.ZoneOffset; 77 import java.time.ZoneOffset;
61 import java.util.ArrayList; 78 import java.util.ArrayList;
79 +import java.util.HashMap;
62 import java.util.List; 80 import java.util.List;
81 +import java.util.concurrent.TimeUnit;
82 +import java.util.function.Function;
63 import java.util.stream.Collectors; 83 import java.util.stream.Collectors;
64 84
65 @Slf4j 85 @Slf4j
...@@ -72,6 +92,7 @@ public class OrderServiceRpcClient { ...@@ -72,6 +92,7 @@ public class OrderServiceRpcClient {
72 private final SkuServiceRpcClient skuServiceRpcClient; 92 private final SkuServiceRpcClient skuServiceRpcClient;
73 private final OperatorServiceRpcClient operatorServiceRpcClient; 93 private final OperatorServiceRpcClient operatorServiceRpcClient;
74 private final RedissonClient redissonClient; 94 private final RedissonClient redissonClient;
95 + private final DelayedQueue<AutoCancelParam> delayedQueue;
75 96
76 @Nullable 97 @Nullable
77 public SingleClientCustomerOrderRpcResponse getOrderById(Integer orderId) { 98 public SingleClientCustomerOrderRpcResponse getOrderById(Integer orderId) {
...@@ -149,6 +170,23 @@ public class OrderServiceRpcClient { ...@@ -149,6 +170,23 @@ public class OrderServiceRpcClient {
149 return orderServiceRpcBlockingStub.updateClientCustomerOrder(request); 170 return orderServiceRpcBlockingStub.updateClientCustomerOrder(request);
150 } 171 }
151 172
173 + public boolean updateClientCustomerOrderCancel(int enterpriseId, int id) {
174 + final var modification = ClientCustomerOrderModification.newBuilder()
175 + .setId(id)
176 + .setShouldUpdateStatus(true)
177 + .setStatus(OrderStatusEnum.ORDER_CANCELED)
178 + .setShouldUpdatePayStatus(true)
179 + .setPayStatus(PayStatusEnum.PAY_CANCELED)
180 + .build();
181 + final var request = UpdateClientCustomerOrderRpcRequest.newBuilder()
182 + .setEnterpriseId(enterpriseId)
183 + .setUpdatedBy(0)
184 + .setUpdateSource(OrderSourceEnum.STALL)
185 + .setModification(modification)
186 + .build();
187 + return orderServiceRpcBlockingStub.updateClientCustomerOrder(request).getIsUpdated();
188 + }
189 +
152 public UpdateClientCustomerOrderRpcResponse updateClientCustomerOrderPaymentResult(SingleClientCustomerOrderRpcResponse order, ClientCustomerOrderModification modification) { 190 public UpdateClientCustomerOrderRpcResponse updateClientCustomerOrderPaymentResult(SingleClientCustomerOrderRpcResponse order, ClientCustomerOrderModification modification) {
153 final var request = UpdateClientCustomerOrderRpcRequest.newBuilder() 191 final var request = UpdateClientCustomerOrderRpcRequest.newBuilder()
154 .setEnterpriseId(order.getEnterpriseId()) 192 .setEnterpriseId(order.getEnterpriseId())
...@@ -160,16 +198,15 @@ public class OrderServiceRpcClient { ...@@ -160,16 +198,15 @@ public class OrderServiceRpcClient {
160 } 198 }
161 199
162 200
163 - public BatchUpdateClientCustomerOrderDetailsRpcResponse batchUpdateClientCustomerOrderDetails( 201 + public BatchUpdateClientCustomerOrderDetailsRpcResponse batchUpdateClientCustomerOrderDetails(OrderDetailBatchUpdateDto orderDetailBatchUpdateDto) {
164 - OrderDetailBatchUpdateDto orderDetailBatchUpdateDto) {
165 final var operatorLoginInfo = LoginContextHolder.getLoginInfo(); 202 final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
166 final var operator = operatorServiceRpcClient.getCOperatorById(operatorLoginInfo.getId()); 203 final var operator = operatorServiceRpcClient.getCOperatorById(operatorLoginInfo.getId());
167 - List<Integer> idsOfNeedUpdateMenuDetails = new ArrayList<>(); 204 + final var idsOfNeedUpdateMenuDetails = new ArrayList<Integer>();
168 - List<Integer> idsOfAddCount = new ArrayList<>(); 205 + final var idsOfAddCount = new ArrayList<Integer>();
169 - List<OrderDetailDto> orgionalOrderDetails = new ArrayList<>(); 206 + List<OrderDetailDto> originalOrderDetails = new ArrayList<>();
170 List<OrderDetailDto> newOrderDetails; 207 List<OrderDetailDto> newOrderDetails;
171 final var modifications = orderDetailBatchUpdateDto.getDetails().stream().map(d -> { 208 final var modifications = orderDetailBatchUpdateDto.getDetails().stream().map(d -> {
172 - MealDetail mealDetail = MealDetail.newBuilder().build(); 209 + var mealDetail = MealDetail.newBuilder().build();
173 Integer menuDetailId = 0; 210 Integer menuDetailId = 0;
174 int mealId = 0; 211 int mealId = 0;
175 int categoryId = 0; 212 int categoryId = 0;
...@@ -178,8 +215,7 @@ public class OrderServiceRpcClient { ...@@ -178,8 +215,7 @@ public class OrderServiceRpcClient {
178 if (d.getShouldUpdateMenuDetailId()) { 215 if (d.getShouldUpdateMenuDetailId()) {
179 idsOfNeedUpdateMenuDetails.add(d.getId()); 216 idsOfNeedUpdateMenuDetails.add(d.getId());
180 menuDetailId = d.getMenuDetailId(); 217 menuDetailId = d.getMenuDetailId();
181 - final var menuDetail = menuServiceRpcClient.getMenuDetailById( 218 + final var menuDetail = menuServiceRpcClient.getMenuDetailById(operatorLoginInfo.getEnterpriseId(), menuDetailId).getResponse();
182 - operatorLoginInfo.getEnterpriseId(), menuDetailId).getResponse();
183 mealId = menuDetail.getMealId(); 219 mealId = menuDetail.getMealId();
184 categoryId = menuDetail.getCategoryId(); 220 categoryId = menuDetail.getCategoryId();
185 skuId = menuDetail.getSkuId(); 221 skuId = menuDetail.getSkuId();
...@@ -190,8 +226,7 @@ public class OrderServiceRpcClient { ...@@ -190,8 +226,7 @@ public class OrderServiceRpcClient {
190 final var skuAvoids = rpcSkus.get(0).getAvoidsList().stream().map(SingleResponse::getName).collect(Collectors.toList()); 226 final var skuAvoids = rpcSkus.get(0).getAvoidsList().stream().map(SingleResponse::getName).collect(Collectors.toList());
191 final var tastes = rpcSkus.get(0).getTastesList().stream().map(SingleResponse::getName).collect(Collectors.toList()); 227 final var tastes = rpcSkus.get(0).getTastesList().stream().map(SingleResponse::getName).collect(Collectors.toList());
192 final var efficacies = rpcSkus.get(0).getEfficaciesList().stream().map(SingleResponse::getName).collect(Collectors.toList()); 228 final var efficacies = rpcSkus.get(0).getEfficaciesList().stream().map(SingleResponse::getName).collect(Collectors.toList());
193 - final var allergies = rpcSkus.get(0).getAllergiesList().stream().map( 229 + final var allergies = rpcSkus.get(0).getAllergiesList().stream().map(SingleSpecialResponse::getName).collect(Collectors.toList());
194 - SingleSpecialResponse::getName).collect(Collectors.toList());
195 final var skuDoctors = rpcSkus.get(0).getDoctorsList().stream().map(SingleSpecialResponse::getName).collect(Collectors.toList()); 230 final var skuDoctors = rpcSkus.get(0).getDoctorsList().stream().map(SingleSpecialResponse::getName).collect(Collectors.toList());
196 mealDetail = MealDetail.newBuilder() 231 mealDetail = MealDetail.newBuilder()
197 .setBasicMaterials(rpcSkus.get(0).getBasicMaterials()) 232 .setBasicMaterials(rpcSkus.get(0).getBasicMaterials())
...@@ -249,8 +284,7 @@ public class OrderServiceRpcClient { ...@@ -249,8 +284,7 @@ public class OrderServiceRpcClient {
249 totalIds.addAll(idsOfAddCount); 284 totalIds.addAll(idsOfAddCount);
250 if (!idsOfNeedUpdateMenuDetails.isEmpty() || !idsOfAddCount.isEmpty()) { 285 if (!idsOfNeedUpdateMenuDetails.isEmpty() || !idsOfAddCount.isEmpty()) {
251 final var orgionalResponseList = getClientCustomerOrderDetailsByIds(totalIds); 286 final var orgionalResponseList = getClientCustomerOrderDetailsByIds(totalIds);
252 - orgionalOrderDetails = orgionalResponseList.stream().map(d -> 287 + originalOrderDetails = orgionalResponseList.stream().map(d -> OrderDetailDto.builder()
253 - OrderDetailDto.builder()
254 .id(d.getId()) 288 .id(d.getId())
255 .count(d.getCount()) 289 .count(d.getCount())
256 .categoryId(d.getCategoryId()) 290 .categoryId(d.getCategoryId())
...@@ -287,7 +321,6 @@ public class OrderServiceRpcClient { ...@@ -287,7 +321,6 @@ public class OrderServiceRpcClient {
287 final var res = orderServiceRpcBlockingStub.batchUpdateClientCustomerOrderDetails(request); 321 final var res = orderServiceRpcBlockingStub.batchUpdateClientCustomerOrderDetails(request);
288 if (res.getIsUpdated()) { 322 if (res.getIsUpdated()) {
289 if (!idsOfNeedUpdateMenuDetails.isEmpty() || !idsOfAddCount.isEmpty()) { 323 if (!idsOfNeedUpdateMenuDetails.isEmpty() || !idsOfAddCount.isEmpty()) {
290 -
291 final var newResponseList = getClientCustomerOrderDetailsByIds(totalIds); 324 final var newResponseList = getClientCustomerOrderDetailsByIds(totalIds);
292 newOrderDetails = newResponseList.stream().map(d -> 325 newOrderDetails = newResponseList.stream().map(d ->
293 OrderDetailDto.builder() 326 OrderDetailDto.builder()
...@@ -323,19 +356,18 @@ public class OrderServiceRpcClient { ...@@ -323,19 +356,18 @@ public class OrderServiceRpcClient {
323 .updatedAt(DateUtil.formatDate(d.getUpdatedAt())) 356 .updatedAt(DateUtil.formatDate(d.getUpdatedAt()))
324 .updatedBy(d.getUpdatedBy()) 357 .updatedBy(d.getUpdatedBy())
325 .build()).collect(Collectors.toList()); 358 .build()).collect(Collectors.toList());
326 -
327 // 替换菜品的操作记录 359 // 替换菜品的操作记录
328 List<SingleOperationDto> operations = new ArrayList<>(); 360 List<SingleOperationDto> operations = new ArrayList<>();
329 - for (OrderDetailDto orgionalDetail : orgionalOrderDetails) { 361 + for (OrderDetailDto originalDetail : originalOrderDetails) {
330 OrderOperationType orderOperationType = OrderOperationType.UNKNOWN_OPERATION_TYPE; 362 OrderOperationType orderOperationType = OrderOperationType.UNKNOWN_OPERATION_TYPE;
331 - if (idsOfNeedUpdateMenuDetails.contains(orgionalDetail.getId())) { 363 + if (idsOfNeedUpdateMenuDetails.contains(originalDetail.getId())) {
332 orderOperationType = OrderOperationType.REPLACE_DISHES; 364 orderOperationType = OrderOperationType.REPLACE_DISHES;
333 - } else if (idsOfAddCount.contains(orgionalDetail.getId())) { 365 + } else if (idsOfAddCount.contains(originalDetail.getId())) {
334 orderOperationType = OrderOperationType.ADD_DISHES; 366 orderOperationType = OrderOperationType.ADD_DISHES;
335 } 367 }
336 - String orgionalDetailStr = ""; 368 + String originalDetailStr;
337 String newDetailStr = ""; 369 String newDetailStr = "";
338 - final var newDetail = newOrderDetails.stream().filter(n -> n.getId().equals(orgionalDetail.getId())).findFirst(); 370 + final var newDetail = newOrderDetails.stream().filter(n -> n.getId().equals(originalDetail.getId())).findFirst();
339 if (newDetail.isPresent()) { 371 if (newDetail.isPresent()) {
340 final var newOrderDetailOperation = OrderDetailOperationDto.builder() 372 final var newOrderDetailOperation = OrderDetailOperationDto.builder()
341 .id(newDetail.get().getId()) 373 .id(newDetail.get().getId())
...@@ -347,23 +379,23 @@ public class OrderServiceRpcClient { ...@@ -347,23 +379,23 @@ public class OrderServiceRpcClient {
347 .build(); 379 .build();
348 newDetailStr = JsonUtil.writeAsJson(List.of(newOrderDetailOperation)); 380 newDetailStr = JsonUtil.writeAsJson(List.of(newOrderDetailOperation));
349 } 381 }
350 - final var orgionalOrderDetailOperation = OrderDetailOperationDto.builder() 382 + final var originalOrderDetailOperation = OrderDetailOperationDto.builder()
351 - .id(orgionalDetail.getId()) 383 + .id(originalDetail.getId())
352 - .skuId(orgionalDetail.getSkuId()) 384 + .skuId(originalDetail.getSkuId())
353 - .skuName(orgionalDetail.getShowName()) 385 + .skuName(originalDetail.getShowName())
354 - .count(orgionalDetail.getCount()) 386 + .count(originalDetail.getCount())
355 - .adjustSkuRemark(orgionalDetail.getAdjustSkuRemark()) 387 + .adjustSkuRemark(originalDetail.getAdjustSkuRemark())
356 - .serveStatus(orgionalDetail.getServeStatus().name()) 388 + .serveStatus(originalDetail.getServeStatus().name())
357 .build(); 389 .build();
358 - orgionalDetailStr = JsonUtil.writeAsJson(List.of(orgionalOrderDetailOperation)); 390 + originalDetailStr = JsonUtil.writeAsJson(List.of(originalOrderDetailOperation));
359 final var operation = SingleOperationDto.builder() 391 final var operation = SingleOperationDto.builder()
360 - .orderId(orgionalDetail.getOrderId()) 392 + .orderId(originalDetail.getOrderId())
361 .shouldCreateAdjustOrderDetailJson(true) 393 .shouldCreateAdjustOrderDetailJson(true)
362 .shouldCreateOriginalOrderDetailJson(true) 394 .shouldCreateOriginalOrderDetailJson(true)
363 .shouldCreateAdjustOrderJson(false) 395 .shouldCreateAdjustOrderJson(false)
364 .shouldCreateOriginalOrderJson(false) 396 .shouldCreateOriginalOrderJson(false)
365 .adjustOrderDetailJson(newDetailStr) 397 .adjustOrderDetailJson(newDetailStr)
366 - .originalOrderDetailJson(orgionalDetailStr) 398 + .originalOrderDetailJson(originalDetailStr)
367 .type(orderOperationType) 399 .type(orderOperationType)
368 .build(); 400 .build();
369 operations.add(operation); 401 operations.add(operation);
...@@ -381,9 +413,7 @@ public class OrderServiceRpcClient { ...@@ -381,9 +413,7 @@ public class OrderServiceRpcClient {
381 return res; 413 return res;
382 } 414 }
383 415
384 - public BatchCreateOrderOperationRecordsResponse batchCreateOrderOperationRecords( 416 + public BatchCreateOrderOperationRecordsResponse batchCreateOrderOperationRecords(BatchOperationDto batchOperationDto) {
385 - BatchOperationDto batchOperationDto) {
386 -
387 final var request = BatchCreateOrderOperationRecordsRequest.newBuilder() 417 final var request = BatchCreateOrderOperationRecordsRequest.newBuilder()
388 .addAllCreations(batchOperationDto.getCreations().stream().map(c -> 418 .addAllCreations(batchOperationDto.getCreations().stream().map(c ->
389 OrderOperationRecordCreation.newBuilder() 419 OrderOperationRecordCreation.newBuilder()
...@@ -407,8 +437,7 @@ public class OrderServiceRpcClient { ...@@ -407,8 +437,7 @@ public class OrderServiceRpcClient {
407 437
408 } 438 }
409 439
410 - public QueryClientCustomerOrdersByPaginationRpcResponse queryClientCustomerOrdersByPagination( 440 + public QueryClientCustomerOrdersByPaginationRpcResponse queryClientCustomerOrdersByPagination(QueryOrderByPaginationDto queryOrderDto) {
411 - QueryOrderByPaginationDto queryOrderDto) {
412 final var request = QueryClientCustomerOrdersByPaginationRpcRequest.newBuilder() 441 final var request = QueryClientCustomerOrdersByPaginationRpcRequest.newBuilder()
413 .setKeyword(queryOrderDto.getKeyword() == null ? "" : queryOrderDto.getKeyword()) 442 .setKeyword(queryOrderDto.getKeyword() == null ? "" : queryOrderDto.getKeyword())
414 .setPageNo(queryOrderDto.getPn()) 443 .setPageNo(queryOrderDto.getPn())
...@@ -450,7 +479,7 @@ public class OrderServiceRpcClient { ...@@ -450,7 +479,7 @@ public class OrderServiceRpcClient {
450 String currentDate = DateUtil.formatDate(today, DateUtil.YYYY_MM_DD); 479 String currentDate = DateUtil.formatDate(today, DateUtil.YYYY_MM_DD);
451 String redisKey = REDIS_KEY_PREFIX + currentDate; 480 String redisKey = REDIS_KEY_PREFIX + currentDate;
452 // 获取分布式原子Long对象,用于原子自增操作 481 // 获取分布式原子Long对象,用于原子自增操作
453 - org.redisson.api.RAtomicLong atomicLong = redissonClient.getAtomicLong(redisKey); 482 + RAtomicLong atomicLong = redissonClient.getAtomicLong(redisKey);
454 // 原子自增并获取当前值 483 // 原子自增并获取当前值
455 long counter = atomicLong.incrementAndGet(); 484 long counter = atomicLong.incrementAndGet();
456 return String.format("%04d", (int) counter); 485 return String.format("%04d", (int) counter);
...@@ -497,11 +526,9 @@ public class OrderServiceRpcClient { ...@@ -497,11 +526,9 @@ public class OrderServiceRpcClient {
497 .addAllDoctors(createOrderDto.getCustomerNoticeJson().getDoctors()) 526 .addAllDoctors(createOrderDto.getCustomerNoticeJson().getDoctors())
498 .build(); 527 .build();
499 528
500 - //判断用餐时间是否是当天 529 + final var menuById = menuServiceRpcClient.getMenuById(createOrderDto.getEnterpriseId(), createOrderDto.getMenuId());
501 - final var mealDate = createOrderDto.getMealTime().toLocalDate();
502 - final var todayDate = LocalDate.now();
503 OrderStatusEnum orderStatus = OrderStatusEnum.TO_PREPARE; 530 OrderStatusEnum orderStatus = OrderStatusEnum.TO_PREPARE;
504 - if (mealDate.equals(todayDate)) { 531 + if (menuById.getResponse().getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE && menuById.getResponse().getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.IMMEDIATELY) {
505 orderStatus = OrderStatusEnum.PREPARING; 532 orderStatus = OrderStatusEnum.PREPARING;
506 } 533 }
507 534
...@@ -512,19 +539,20 @@ public class OrderServiceRpcClient { ...@@ -512,19 +539,20 @@ public class OrderServiceRpcClient {
512 .setStatus(orderStatus) 539 .setStatus(orderStatus)
513 .setAddress(createOrderDto.getAddress()) 540 .setAddress(createOrderDto.getAddress())
514 .setClientId(createOrderDto.getClientId()) 541 .setClientId(createOrderDto.getClientId())
515 - .setShouldCreateOpenId(createOrderDto.getShouldCreateOpenId()) 542 + .setShouldCreateOpenId(!LoginContextHolder.getOpenId().isEmpty())
516 - .setOpenId(createOrderDto.getOpenId()) 543 + .setOpenId(LoginContextHolder.getOpenId())
517 .setShouldCreateRoomNo(!createOrderDto.getRoomNo().isEmpty()) 544 .setShouldCreateRoomNo(!createOrderDto.getRoomNo().isEmpty())
518 .setRoomNo(createOrderDto.getRoomNo()) 545 .setRoomNo(createOrderDto.getRoomNo())
519 - .setShouldCreateTableCode(createOrderDto.getOrderType().equals(OrderTypeEnum.DINE_IN.getValue())) 546 + .setShouldCreateTableCode(createOrderDto.getOrderType().equals(OrderTypeEnum.DINE_IN.getValue()) || !createOrderDto.getTableCode().isEmpty())
520 .setTableCode(createOrderDto.getTableCode()) 547 .setTableCode(createOrderDto.getTableCode())
548 + .setShouldCreateOnlinePay(true)
521 .setOnlinePay(createOrderDto.getOnlinePay()) 549 .setOnlinePay(createOrderDto.getOnlinePay())
522 .setShouldCreatePayStatus(createOrderDto.getOnlinePay()) 550 .setShouldCreatePayStatus(createOrderDto.getOnlinePay())
523 .setPayStatus(PayStatusEnum.TO_PAY) 551 .setPayStatus(PayStatusEnum.TO_PAY)
524 .setMenuId(createOrderDto.getMenuId()) 552 .setMenuId(createOrderDto.getMenuId())
525 .setTotalNum(createOrderDto.getTotalNum()) 553 .setTotalNum(createOrderDto.getTotalNum())
526 .setPayPrice(createOrderDto.getPayPrice()) 554 .setPayPrice(createOrderDto.getPayPrice())
527 - .setMealTime(mealDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()) 555 + .setMealTime(LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli())
528 .setShouldCreateTableCode(createOrderDto.getCloseTimeType().equals(CloseTimeType.IMMEDIATELY)) 556 .setShouldCreateTableCode(createOrderDto.getCloseTimeType().equals(CloseTimeType.IMMEDIATELY))
529 .setShouldCreatePickupCode(createOrderDto.getCloseTimeType().equals(CloseTimeType.IMMEDIATELY)) 557 .setShouldCreatePickupCode(createOrderDto.getCloseTimeType().equals(CloseTimeType.IMMEDIATELY))
530 .setPickupCode(generatePickupCode()) 558 .setPickupCode(generatePickupCode())
...@@ -536,14 +564,99 @@ public class OrderServiceRpcClient { ...@@ -536,14 +564,99 @@ public class OrderServiceRpcClient {
536 .setShouldCreateOrderDetails(true) 564 .setShouldCreateOrderDetails(true)
537 .addAllOrderDetails(orderDetails) 565 .addAllOrderDetails(orderDetails)
538 .build(); 566 .build();
539 - CreateClientCustomerOrderRpcResponse orderResponse = orderServiceRpcBlockingStub 567 +
568 + if (menuById.getResponse().getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.IMMEDIATELY) {
569 + final var skuIds = createOrderDto.getOrderDetailDtos().stream().map(CreateOrderDetailDto::getSkuId).collect(Collectors.toList());
570 + final var skuSellQuantities = this.querySkuSellQuantitiesByStallAndSkuIds(createOrderDto.getEnterpriseId(), createOrderDto.getStallId(), skuIds);
571 + final var skuSellQuantityMap = skuSellQuantities.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity()));
572 + final var skuMap = skuServiceRpcClient.getSkusByIds(skuIds).stream().collect(Collectors.toMap(SingleSkuResponse::getId, Function.identity()));
573 + final var soldOutSkus = new ArrayList<String>();
574 + final var skuStockMap = new HashMap<String, Integer>();
575 + for (var orderDetail : createOrderDto.getOrderDetailDtos()) {
576 + final var skuSellQuantityRpcResponse = skuSellQuantityMap.get(orderDetail.getSkuId());
577 + if (skuSellQuantityRpcResponse == null) {
578 + log.error("skuSellQuantityRpcResponse is null; stallId:{}, skuId:{}", createOrderDto.getStallId(), orderDetail.getSkuId());
579 + soldOutSkus.add(skuMap.get(orderDetail.getSkuId()).getName());
580 + continue;
581 + }
582 + if ((skuSellQuantityRpcResponse.getTodaySellQuantity() + orderDetail.getCount()) > skuSellQuantityRpcResponse.getMaxSellQuantity()) {
583 + log.error("skuSellQuantityRpcResponse stock no enough; stallId:{}, skuId:{}, count:{}", createOrderDto.getStallId(), orderDetail.getSkuId(), orderDetail.getCount());
584 + skuStockMap.put(skuMap.get(orderDetail.getSkuId()).getName(), skuSellQuantityRpcResponse.getMaxSellQuantity() - skuSellQuantityRpcResponse.getTodaySellQuantity());
585 + }
586 + }
587 + if (!soldOutSkus.isEmpty()) {
588 + throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.SKUS_SOLD_OUT_TODAY, String.join(",", soldOutSkus));
589 + }
590 + if (!skuStockMap.isEmpty()) {
591 + final var noEnoughSkus = String.join(", ", skuStockMap.keySet());
592 + throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.SKUS_STOCK_NO_ENOUGH_TODAY, noEnoughSkus);
593 + }
594 + }
595 + final var orderResponse = orderServiceRpcBlockingStub
540 .createClientCustomerOrder(CreateClientCustomerOrderRpcRequest.newBuilder() 596 .createClientCustomerOrder(CreateClientCustomerOrderRpcRequest.newBuilder()
541 .setCreation(creation) 597 .setCreation(creation)
542 .setCreationSource(OrderSourceEnum.forNumber(createOrderDto.getCreationSource())) 598 .setCreationSource(OrderSourceEnum.forNumber(createOrderDto.getCreationSource()))
543 .setEnterpriseId(createOrderDto.getEnterpriseId()) 599 .setEnterpriseId(createOrderDto.getEnterpriseId())
544 .setCreatedBy(createOrderDto.getCreatedBy()) 600 .setCreatedBy(createOrderDto.getCreatedBy())
545 .build()); 601 .build());
602 + if (orderResponse.getIsCreated()) {
603 + //立即点餐需要扣除库存
604 + if (menuById.getResponse().getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.IMMEDIATELY) {
605 + final var isSuccess = this.addSkusSellQuantities(createOrderDto.getEnterpriseId(), createOrderDto.getStallId(),
606 + orderDetails.stream().map(e -> AddSkusSellQuantityBO.builder()
607 + .skuId(e.getSkuId())
608 + .quantity(e.getCount())
609 + .build()).collect(Collectors.toList()));
610 + log.info("Order {} addSkusSellQuantities result: {}", orderResponse.getId(), isSuccess);
611 + }
612 + //在线支付需要延迟取消订单
613 + if (menuById.getResponse().getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE) {
614 + final var autoCancelParam = new AutoCancelParam();
615 + autoCancelParam.setOrderId(orderResponse.getId());
616 + delayedQueue.addToQueue(OrderAutoCancelDelayTask.AUTO_CANCEL_ORDER_DELAY_QUEUE, autoCancelParam, 10, TimeUnit.MINUTES);
617 + }
618 + }
546 return CreateOrderResponse.builder().id(orderResponse.getId()).isCreated(true).build(); 619 return CreateOrderResponse.builder().id(orderResponse.getId()).isCreated(true).build();
547 } 620 }
548 621
622 +
623 + public List<SingleSkuSellQuantityRpcResponse> querySkuSellQuantitiesByStall(int enterpriseId, int stallId) {
624 + return orderServiceRpcBlockingStub.querySkuSellQuantitiesByStall(QuerySkuSellQuantitiesByStallRpcRequest.newBuilder()
625 + .setEnterpriseId(enterpriseId)
626 + .setStallId(stallId)
627 + .build()).getResponsesList();
628 + }
629 +
630 + public List<SingleSkuSellQuantityRpcResponse> querySkuSellQuantitiesByStallAndSkuIds(int enterpriseId, int stallId, List<Integer> skuIds) {
631 + return orderServiceRpcBlockingStub.querySkuSellQuantitiesByStallAndSkuIds(QuerySkuSellQuantitiesByStallAndSkuIdsRpcRequest.newBuilder()
632 + .setEnterpriseId(enterpriseId)
633 + .setStallId(stallId)
634 + .addAllSkuIds(skuIds)
635 + .build()).getResponsesList();
636 + }
637 +
638 + public boolean batchSaveSkuSellQuantities(int enterpriseId, int stallId, List<SkuSellQuantityBO> skuSellQuantityBOs) {
639 + return orderServiceRpcBlockingStub.batchSaveSkuSellQuantities(BatchSaveSkuSellQuantitiesRpcRequest.newBuilder()
640 + .setEnterpriseId(enterpriseId)
641 + .setUpdatedBy(stallId)
642 + .addAllSkuSellQuantityModifications(skuSellQuantityBOs.stream().map(e -> SkuSellQuantityModification.newBuilder()
643 + .setId(e.getId() == null ? 0 : e.getId())
644 + .setStallId(stallId)
645 + .setSkuId(e.getSkuId())
646 + .setMaxSellQuantity(e.getMaxSellQuantity())
647 + .build()).collect(Collectors.toList()))
648 + .build()).getIsSaved();
649 + }
650 +
651 + public boolean addSkusSellQuantities(int enterpriseId, int stallId, List<AddSkusSellQuantityBO> skuSellQuantityBOs) {
652 + return orderServiceRpcBlockingStub.addSkusSellQuantities(AddSkusSellQuantitiesRpcRequest.newBuilder()
653 + .setEnterpriseId(enterpriseId)
654 + .setStallId(stallId)
655 + .addAllSkuSellQuantities(skuSellQuantityBOs.stream().map(e -> SkuSellQuantity.newBuilder()
656 + .setSkuId(e.getSkuId())
657 + .setQuantity(e.getQuantity())
658 + .build()).collect(Collectors.toList()))
659 + .build()).getIsAdded();
660 + }
661 +
549 } 662 }
......
...@@ -8,8 +8,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -8,8 +8,12 @@ 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.context.LoginContextHolder;
15 +import com.infoloop.tianting.exception.ClientEndExceptions;
16 +import com.infoloop.tianting.exception.ErrorCodeEnum;
13 import com.infoloop.tianting.model.dto.PayDTO.PayInformRequestDto; 17 import com.infoloop.tianting.model.dto.PayDTO.PayInformRequestDto;
14 import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto; 18 import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto;
15 import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto; 19 import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto;
...@@ -20,7 +24,6 @@ import com.infoloop.tianting.utils.EncryptionUtil; ...@@ -20,7 +24,6 @@ import com.infoloop.tianting.utils.EncryptionUtil;
20 import lombok.RequiredArgsConstructor; 24 import lombok.RequiredArgsConstructor;
21 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Autowired; 26 import org.springframework.beans.factory.annotation.Autowired;
23 -import org.springframework.beans.factory.annotation.Value;
24 import org.springframework.http.HttpEntity; 27 import org.springframework.http.HttpEntity;
25 import org.springframework.http.HttpHeaders; 28 import org.springframework.http.HttpHeaders;
26 import org.springframework.http.HttpMethod; 29 import org.springframework.http.HttpMethod;
...@@ -30,6 +33,7 @@ import org.springframework.stereotype.Service; ...@@ -30,6 +33,7 @@ import org.springframework.stereotype.Service;
30 import org.springframework.web.client.RestTemplate; 33 import org.springframework.web.client.RestTemplate;
31 34
32 import java.math.BigDecimal; 35 import java.math.BigDecimal;
36 +import java.text.MessageFormat;
33 import java.text.ParseException; 37 import java.text.ParseException;
34 import java.time.LocalDateTime; 38 import java.time.LocalDateTime;
35 39
...@@ -44,12 +48,16 @@ public class PayServiceClient { ...@@ -44,12 +48,16 @@ public class PayServiceClient {
44 private final BusinessConfig businessConfig; 48 private final BusinessConfig businessConfig;
45 49
46 private final OrderServiceRpcClient orderServiceRpcClient; 50 private final OrderServiceRpcClient orderServiceRpcClient;
51 +
47 private final XmlMapper xmlMapper = new XmlMapper(); 52 private final XmlMapper xmlMapper = new XmlMapper();
48 - @Value("${payment.client-id:Order0001}")
49 - private String clientId;
50 53
51 public PayResponseDto payInform(PayInformRequestDto payRequestDto) { 54 public PayResponseDto payInform(PayInformRequestDto payRequestDto) {
52 - String url = businessConfig.getPayUrl(); 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 + }
60 + String url = MessageFormat.format(businessConfig.getPayUrl(), businessConfig.getPayClientId());
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);
55 String jsonDataString; 63 String jsonDataString;
...@@ -71,17 +79,17 @@ public class PayServiceClient { ...@@ -71,17 +79,17 @@ public class PayServiceClient {
71 79
72 private ThirdPartyPayInformRequestDto buildRequestData(PayInformRequestDto payRequestDto, String requestDate) { 80 private ThirdPartyPayInformRequestDto buildRequestData(PayInformRequestDto payRequestDto, String requestDate) {
73 ThirdPartyPayInformRequestDto jsonData = new ThirdPartyPayInformRequestDto(); 81 ThirdPartyPayInformRequestDto jsonData = new ThirdPartyPayInformRequestDto();
74 - jsonData.setClientId(clientId); 82 + jsonData.setClientId(businessConfig.getPayClientId());
75 jsonData.setTradeId(payRequestDto.getOrderId()); 83 jsonData.setTradeId(payRequestDto.getOrderId());
76 jsonData.setRequestDate(requestDate); 84 jsonData.setRequestDate(requestDate);
77 jsonData.setRequestSource("OFWXApplet"); 85 jsonData.setRequestSource("OFWXApplet");
78 - jsonData.setPayerOpenId(payRequestDto.getOpenId()); 86 + jsonData.setPayerOpenId(LoginContextHolder.getOpenId());
79 jsonData.setHospitalCode(payRequestDto.getHospitalCode()); 87 jsonData.setHospitalCode(payRequestDto.getHospitalCode());
80 jsonData.setPID(payRequestDto.getPhone()); 88 jsonData.setPID(payRequestDto.getPhone());
81 jsonData.setRemark(""); 89 jsonData.setRemark("");
82 jsonData.setTransAmount(payRequestDto.getPrice()); 90 jsonData.setTransAmount(payRequestDto.getPrice());
83 jsonData.setTradeDesc(""); 91 jsonData.setTradeDesc("");
84 - jsonData.setSign(EncryptionUtil.sha1Encryption(clientId + payRequestDto.getOrderId() + requestDate + clientId)); 92 + jsonData.setSign(EncryptionUtil.sha1Encryption(businessConfig.getPayClientId() + payRequestDto.getOrderId() + requestDate + businessConfig.getPayClientId()));
85 return jsonData; 93 return jsonData;
86 } 94 }
87 95
......
...@@ -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 }
......
...@@ -18,6 +18,9 @@ import lombok.extern.slf4j.Slf4j; ...@@ -18,6 +18,9 @@ import lombok.extern.slf4j.Slf4j;
18 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
20 20
21 +import java.security.MessageDigest;
22 +import java.security.NoSuchAlgorithmException;
23 +
21 @Slf4j 24 @Slf4j
22 @Service 25 @Service
23 @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 26 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
...@@ -29,78 +32,82 @@ public class LoginServiceImpl implements LoginService { ...@@ -29,78 +32,82 @@ public class LoginServiceImpl implements LoginService {
29 private final WOperatorServiceRpcClient wOperatorServiceRpcClient; 32 private final WOperatorServiceRpcClient wOperatorServiceRpcClient;
30 33
31 @Override 34 @Override
32 - public SaTokenInfo login(LoginDto loginDto) { 35 + public SaTokenInfo login(LoginDto loginDto) throws NoSuchAlgorithmException {
33 if (loginDto.isShouldLoginWithOpenCode()) { 36 if (loginDto.isShouldLoginWithOpenCode()) {
34 final var wxUserOpenIdDto = wxMiniProgramHttpClient.getUserOpenIdByCode(loginDto.getOpenCode()); 37 final var wxUserOpenIdDto = wxMiniProgramHttpClient.getUserOpenIdByCode(loginDto.getOpenCode());
35 - StpUtil.login( 38 + StpUtil.login(wxUserOpenIdDto.getOpenid(), SaLoginModel.create()
36 - wxUserOpenIdDto.getOpenid(),
37 - SaLoginModel.create()
38 .setExtra(CommonConstants.ENTERPRISE_ID, loginDto.getEnterpriseId()) 39 .setExtra(CommonConstants.ENTERPRISE_ID, loginDto.getEnterpriseId())
39 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue()) 40 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
40 .build()); 41 .build());
41 return StpUtil.getTokenInfo(); 42 return StpUtil.getTokenInfo();
42 } else if (loginDto.isShouldLoginWithHisCustomerId()) { 43 } else if (loginDto.isShouldLoginWithHisCustomerId()) {
43 - var customer = 44 + var customer = clientCustomerServiceRpcClient.getClientCustomerByHISCustomerId(loginDto.getHisCustomerId()).getResponse();
44 - clientCustomerServiceRpcClient
45 - .getClientCustomerByHISCustomerId(loginDto.getHisCustomerId())
46 - .getResponse();
47 if (customer.getId() == 0) { 45 if (customer.getId() == 0) {
48 // 根据hisCustomerId拿不到用户的话再去根据合同号去his查一次,即认为是月子中心客户 46 // 根据hisCustomerId拿不到用户的话再去根据合同号去his查一次,即认为是月子中心客户
49 - customer = 47 + customer = clientCustomerServiceRpcClient.getClientCustomerByContactNo(loginDto.getHisCustomerId()).getResponse();
50 - clientCustomerServiceRpcClient
51 - .getClientCustomerByContactNo(loginDto.getHisCustomerId())
52 - .getResponse();
53 if (customer.getId() == 0) { 48 if (customer.getId() == 0) {
54 throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.VALIDATE_FAILED.name()); 49 throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.VALIDATE_FAILED.name());
55 } else { 50 } else {
56 - var record = 51 + var record = clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerId(customer.getEnterpriseId(), customer.getId());
57 - clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerId( 52 + if (!record.hasResponse() || record.getResponse().getHospitalStatus() != ClientCustomerHospitalRecordHospitalStatusEnum.CURRENT) {
58 - customer.getEnterpriseId(), customer.getId()); 53 + throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.VALIDATE_FAILED.name());
59 - if (!record.hasResponse()
60 - || record.getResponse().getHospitalStatus()
61 - != ClientCustomerHospitalRecordHospitalStatusEnum.CURRENT) {
62 - throw ClientEndExceptions.IncorrectRequestValue.build(
63 - ErrorCodeEnum.VALIDATE_FAILED.name());
64 } 54 }
65 } 55 }
56 + } else {
57 + var record = clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerId(customer.getEnterpriseId(), customer.getId());
58 + if (!record.hasResponse() || record.getResponse().getHospitalStatus() != ClientCustomerHospitalRecordHospitalStatusEnum.CURRENT) {
59 + throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.VALIDATE_FAILED.name());
66 } 60 }
67 - StpUtil.login( 61 + }
68 - customer.getId(), 62 + final var wxUserOpenIdDto = wxMiniProgramHttpClient.getUserOpenIdByCode(loginDto.getOpenCode());
69 - SaLoginModel.create() 63 + StpUtil.login(customer.getId(), SaLoginModel.create()
70 .setExtra(CommonConstants.ENTERPRISE_ID, customer.getEnterpriseId()) 64 .setExtra(CommonConstants.ENTERPRISE_ID, customer.getEnterpriseId())
71 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue()) 65 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
66 + .setExtra(CommonConstants.OPEN_ID, wxUserOpenIdDto.getOpenid())
72 .build()); 67 .build());
73 return StpUtil.getTokenInfo(); 68 return StpUtil.getTokenInfo();
74 } else if (loginDto.isShouldLoginWithOperatorPhone()) { 69 } else if (loginDto.isShouldLoginWithOperatorPhone()) {
75 - final var operator = 70 + final var operator = operatorServiceRpcClient.getCOperatorByMobileOrEmail(loginDto.getOperatorPhone());
76 - operatorServiceRpcClient.getCOperatorByMobileOrEmail(loginDto.getOperatorPhone());
77 if (operator.getId() == 0) { 71 if (operator.getId() == 0) {
78 throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.UNAUTHORIZED.name()); 72 throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.UNAUTHORIZED.name());
79 } 73 }
80 - StpUtil.login( 74 + if (!operator.getPassword().equals(sha1Hash(loginDto.getPassword()))) {
81 - operator.getId(), 75 + throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.VALIDATE_FAILED.name());
82 - SaLoginModel.create() 76 + }
77 + StpUtil.login(operator.getId(), SaLoginModel.create()
83 .setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId()) 78 .setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId())
84 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue()) 79 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
85 .build()); 80 .build());
86 return StpUtil.getTokenInfo(); 81 return StpUtil.getTokenInfo();
87 } else { 82 } else {
88 - final var operator = 83 + final var operator = wOperatorServiceRpcClient.getWOperatorByEmail(loginDto.getEmail()).getResponse();
89 - wOperatorServiceRpcClient.getWOperatorByEmail(loginDto.getEmail()).getResponse();
90 if (operator.getId() == 0) { 84 if (operator.getId() == 0) {
91 throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.UNAUTHORIZED.name()); 85 throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.UNAUTHORIZED.name());
92 } 86 }
93 -// if (!operator.getPassword().equals(loginDto.getPassword())) { 87 + if (!operator.getPassword().equals(sha1Hash(loginDto.getPassword()))) {
94 -// throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.VALIDATE_FAILED.name()); 88 + throw ClientEndExceptions.AuthenticationFailure.build(ErrorCodeEnum.VALIDATE_FAILED.name());
95 -// } 89 + }
96 - StpUtil.login( 90 + StpUtil.login(operator.getId(), SaLoginModel.create()
97 - operator.getId(),
98 - SaLoginModel.create()
99 .setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId()) 91 .setExtra(CommonConstants.ENTERPRISE_ID, operator.getEnterpriseId())
100 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue()) 92 .setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
101 .build()); 93 .build());
102 return StpUtil.getTokenInfo(); 94 return StpUtil.getTokenInfo();
103 } 95 }
104 } 96 }
97 +
98 + public static String sha1Hash(String input) throws NoSuchAlgorithmException {
99 + MessageDigest md = MessageDigest.getInstance("SHA-1");
100 + md.update(input.getBytes());
101 + byte[] digest = md.digest();
102 + return bytesToHex(digest);
103 + }
104 +
105 + private static String bytesToHex(byte[] bytes) {
106 + StringBuilder sb = new StringBuilder();
107 + for (byte b : bytes) {
108 + sb.append(String.format("%02x", b));
109 + }
110 + return sb.toString();
111 + }
105 } 112 }
106 113
......
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 }
......
...@@ -56,7 +56,6 @@ import lombok.extern.slf4j.Slf4j; ...@@ -56,7 +56,6 @@ import lombok.extern.slf4j.Slf4j;
56 import org.springframework.beans.factory.annotation.Autowired; 56 import org.springframework.beans.factory.annotation.Autowired;
57 import org.springframework.stereotype.Service; 57 import org.springframework.stereotype.Service;
58 58
59 -import java.time.LocalDate;
60 import java.util.ArrayList; 59 import java.util.ArrayList;
61 import java.util.List; 60 import java.util.List;
62 import java.util.stream.Collectors; 61 import java.util.stream.Collectors;
...@@ -93,8 +92,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -93,8 +92,7 @@ public class OrderServiceImpl implements OrderService {
93 final var record = clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerId(customer.getEnterpriseId(), customer.getId()).getResponse(); 92 final var record = clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerId(customer.getEnterpriseId(), customer.getId()).getResponse();
94 CreateOrderDto createOrderDto = new CreateOrderDto(); 93 CreateOrderDto createOrderDto = new CreateOrderDto();
95 createOrderDto.setShouldCreateCustomerId(true); 94 createOrderDto.setShouldCreateCustomerId(true);
96 - createOrderDto.setShouldCreateOpenId(false); 95 + createOrderDto.setTableCode(operatorCreateOrderDto.getTableCode());
97 - createOrderDto.setOpenId("");
98 createOrderDto.setCustomerId(operatorCreateOrderDto.getCustomerId()); 96 createOrderDto.setCustomerId(operatorCreateOrderDto.getCustomerId());
99 createOrderDto.setStallId(operatorCreateOrderDto.getStallId()); 97 createOrderDto.setStallId(operatorCreateOrderDto.getStallId());
100 createOrderDto.setMenuId(operatorCreateOrderDto.getMenuId()); 98 createOrderDto.setMenuId(operatorCreateOrderDto.getMenuId());
...@@ -111,16 +109,11 @@ public class OrderServiceImpl implements OrderService { ...@@ -111,16 +109,11 @@ public class OrderServiceImpl implements OrderService {
111 if (placeOrderCount != 0 && menuOrderCount >= placeOrderCount) { 109 if (placeOrderCount != 0 && menuOrderCount >= placeOrderCount) {
112 throw ClientEndExceptions.OperationForbidden.build(ErrorCodeEnum.ORDER_COUNT_LIMIT.name()); 110 throw ClientEndExceptions.OperationForbidden.build(ErrorCodeEnum.ORDER_COUNT_LIMIT.name());
113 } 111 }
114 - createOrderDto.setCloseTimeType( 112 + createOrderDto.setCloseTimeType(CloseTimeType.forNumber(menu.getOrderRuleJson().getCloseTimeType().getNumber()));
115 - CloseTimeType.forNumber(menu.getOrderRuleJson().getCloseTimeType().getNumber()));
116 createOrderDto.setRoomNo(record.getRoomNo()); 113 createOrderDto.setRoomNo(record.getRoomNo());
117 createOrderDto.setCreationSource(OrderSourceEnum.STALL.getNumber()); 114 createOrderDto.setCreationSource(OrderSourceEnum.STALL.getNumber());
118 createOrderDto.setEnterpriseId(operatorLoginInfo.getEnterpriseId()); 115 createOrderDto.setEnterpriseId(operatorLoginInfo.getEnterpriseId());
119 -// createOrderDto.setStallId(); 116 + var onlinePay = menu.getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE;
120 - var onlinePay = false;
121 - if (menu.getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE) {
122 - onlinePay = true;
123 - }
124 createOrderDto.setOnlinePay(onlinePay); 117 createOrderDto.setOnlinePay(onlinePay);
125 OrderTypeEnum orderType; 118 OrderTypeEnum orderType;
126 if (menu.getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.RESERVATION) { 119 if (menu.getOrderRuleJson().getCloseTimeType() == CloseTimeTypeEnum.RESERVATION) {
...@@ -130,7 +123,6 @@ public class OrderServiceImpl implements OrderService { ...@@ -130,7 +123,6 @@ public class OrderServiceImpl implements OrderService {
130 } 123 }
131 createOrderDto.setOrderType(orderType.getNumber()); 124 createOrderDto.setOrderType(orderType.getNumber());
132 createOrderDto.setShouldCreateCustomerId(true); 125 createOrderDto.setShouldCreateCustomerId(true);
133 - createOrderDto.setShouldCreateOpenId(false);
134 126
135 final var labelRefs = clientCustomerServiceRpcClient.getCustomerLabelsByCustomerId(customer.getEnterpriseId(), customer.getId()).getResponsesList(); 127 final var labelRefs = clientCustomerServiceRpcClient.getCustomerLabelsByCustomerId(customer.getEnterpriseId(), customer.getId()).getResponsesList();
136 final var labelIds = labelRefs.stream().map(SingleClientCustomerLabelRefRpcResponse::getLabelId).collect(Collectors.toList()); 128 final var labelIds = labelRefs.stream().map(SingleClientCustomerLabelRefRpcResponse::getLabelId).collect(Collectors.toList());
...@@ -160,14 +152,11 @@ public class OrderServiceImpl implements OrderService { ...@@ -160,14 +152,11 @@ public class OrderServiceImpl implements OrderService {
160 .doctors(Stream.of(doctors, dietDoctors).flatMap(List::stream).collect(Collectors.toList())) 152 .doctors(Stream.of(doctors, dietDoctors).flatMap(List::stream).collect(Collectors.toList()))
161 .build(); 153 .build();
162 createOrderDto.setCustomerNoticeJson(customerNotice); 154 createOrderDto.setCustomerNoticeJson(customerNotice);
163 -
164 - createOrderDto.setTableCode("");
165 createOrderDto.setUpdatedBy(operatorLoginInfo.getId()); 155 createOrderDto.setUpdatedBy(operatorLoginInfo.getId());
166 createOrderDto.setUpdateSource(OrderSourceEnum.STALL.getNumber()); 156 createOrderDto.setUpdateSource(OrderSourceEnum.STALL.getNumber());
167 List<CreateOrderDetailDto> orderDetailDtoList = new ArrayList<>(); 157 List<CreateOrderDetailDto> orderDetailDtoList = new ArrayList<>();
168 final var menuDetails = menuServiceRpcClient.queryMenuDetailsByMenuId(menu.getEnterpriseId(), operatorCreateOrderDto.getMenuId()).getResponsesList(); 158 final var menuDetails = menuServiceRpcClient.queryMenuDetailsByMenuId(menu.getEnterpriseId(), operatorCreateOrderDto.getMenuId()).getResponsesList();
169 - final var skuIds = 159 + final var skuIds = menuDetails.stream()
170 - menuDetails.stream()
171 .map(SingleMenuDetailRpcResponse::getSkuId) 160 .map(SingleMenuDetailRpcResponse::getSkuId)
172 .collect(Collectors.toList()); 161 .collect(Collectors.toList());
173 final var rpcSkus = skuServiceRpcClient.getDishSkusByIds(skuIds).getResponseList(); 162 final var rpcSkus = skuServiceRpcClient.getDishSkusByIds(skuIds).getResponseList();
...@@ -231,8 +220,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -231,8 +220,7 @@ public class OrderServiceImpl implements OrderService {
231 } 220 }
232 221
233 @Override 222 @Override
234 - public BatchUpdateOrderDetailResponse batchUpdateOrderDetails( 223 + public BatchUpdateOrderDetailResponse batchUpdateOrderDetails(OrderDetailBatchUpdateDto batchUpdateDto) {
235 - OrderDetailBatchUpdateDto batchUpdateDto) {
236 final var response = orderServiceRpcClient.batchUpdateClientCustomerOrderDetails(batchUpdateDto); 224 final var response = orderServiceRpcClient.batchUpdateClientCustomerOrderDetails(batchUpdateDto);
237 return BatchUpdateOrderDetailResponse.builder() 225 return BatchUpdateOrderDetailResponse.builder()
238 .isUpdated(response.getIsUpdated()) 226 .isUpdated(response.getIsUpdated())
...@@ -243,7 +231,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -243,7 +231,7 @@ public class OrderServiceImpl implements OrderService {
243 public Integer getMenuOrderCount(getMenuOrderCountDto checkIfOrdered) { 231 public Integer getMenuOrderCount(getMenuOrderCountDto checkIfOrdered) {
244 final var operatorLoginInfo = LoginContextHolder.getLoginInfo(); 232 final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
245 final var mealTimeStart = checkIfOrdered.getMealTime().toLocalDate().atStartOfDay(); 233 final var mealTimeStart = checkIfOrdered.getMealTime().toLocalDate().atStartOfDay();
246 - LocalDate tomorrow = checkIfOrdered.getMealTime().toLocalDate().plusDays(1); 234 + final var tomorrow = checkIfOrdered.getMealTime().toLocalDate().plusDays(1);
247 final var mealTimeEnd = tomorrow.atStartOfDay(); 235 final var mealTimeEnd = tomorrow.atStartOfDay();
248 final var queryOrderDto = QueryOrderByConditionDto.builder() 236 final var queryOrderDto = QueryOrderByConditionDto.builder()
249 .enterpriseId(operatorLoginInfo.getEnterpriseId()) 237 .enterpriseId(operatorLoginInfo.getEnterpriseId())
...@@ -265,6 +253,10 @@ public class OrderServiceImpl implements OrderService { ...@@ -265,6 +253,10 @@ public class OrderServiceImpl implements OrderService {
265 253
266 @Override 254 @Override
267 public List<OrderDetailDto> getOrderDetailsByOrderId(Integer orderId) { 255 public List<OrderDetailDto> getOrderDetailsByOrderId(Integer orderId) {
256 + final var orderById = orderServiceRpcClient.getOrderById(orderId);
257 + if (orderById == null) {
258 + return List.of();
259 + }
268 final var responseList = orderServiceRpcClient.getOrderDetailsByOrderId(orderId); 260 final var responseList = orderServiceRpcClient.getOrderDetailsByOrderId(orderId);
269 return responseList.stream().map(d -> 261 return responseList.stream().map(d ->
270 OrderDetailDto.builder() 262 OrderDetailDto.builder()
...@@ -276,6 +268,8 @@ public class OrderServiceImpl implements OrderService { ...@@ -276,6 +268,8 @@ public class OrderServiceImpl implements OrderService {
276 .orderId(d.getOrderId()) 268 .orderId(d.getOrderId())
277 .price(d.getPrice()) 269 .price(d.getPrice())
278 .showName(d.getShowName()) 270 .showName(d.getShowName())
271 + .status(orderById.getStatus())
272 + .payStatus(orderById.getPayStatus())
279 .mealDetailJson(MealDetailDto.builder() 273 .mealDetailJson(MealDetailDto.builder()
280 .allergies(d.getMealDetailJson().getAllergiesList()) 274 .allergies(d.getMealDetailJson().getAllergiesList())
281 .basicMaterials(d.getMealDetailJson().getBasicMaterials()) 275 .basicMaterials(d.getMealDetailJson().getBasicMaterials())
......
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 }
......
...@@ -2,13 +2,23 @@ package com.infoloop.tianting.utils; ...@@ -2,13 +2,23 @@ package com.infoloop.tianting.utils;
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; 4 import com.infoloop.tianting.model.common.PageResult;
5 -
6 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderCountByStatusDto; 5 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderCountByStatusDto;
6 +
7 import java.util.LinkedList; 7 import java.util.LinkedList;
8 import java.util.List; 8 import java.util.List;
9 9
10 public class PageUtil { 10 public class PageUtil {
11 11
12 + public static <T> PageResult<T> buildEmpty(T t) {
13 + PageResult<T> pageRet = new PageResult<>();
14 + pageRet.setTotalCount(0);
15 + pageRet.setDataList(List.of(t));
16 + pageRet.setPageNo(0);
17 + pageRet.setPageSize(0);
18 + pageRet.setTotalPage(0);
19 + return pageRet;
20 + }
21 +
12 /** 22 /**
13 * 自定义分页 23 * 自定义分页
14 */ 24 */
......
...@@ -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 +}
......
...@@ -75,7 +75,8 @@ miniprogram.appSecret=5b309517bf918abf760b2195e91b99f3 ...@@ -75,7 +75,8 @@ miniprogram.appSecret=5b309517bf918abf760b2195e91b99f3
75 75
76 business-config.hisCustomerQueryUrl = https://nutri.amcare.com.cn/v3/hiscustomers/current/query 76 business-config.hisCustomerQueryUrl = https://nutri.amcare.com.cn/v3/hiscustomers/current/query
77 business-config.clientCustomerQueryUrl = https://nutri.amcare.com.cn/v3/clientcustomers/current/query 77 business-config.clientCustomerQueryUrl = https://nutri.amcare.com.cn/v3/clientcustomers/current/query
78 -business-config.payUrl = http://10.2.5.162:21051/API/Microapp/CreateOrder?appid=Order0001 78 +business-config.payUrl = http://10.2.5.162:21051/API/Microapp/CreateOrder?appid={0}
79 +business-config.payClientId = Order
79 80
80 ##Actuator\u914D\u7F6E 81 ##Actuator\u914D\u7F6E
81 management.server.port=8088 82 management.server.port=8088
......