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) | ... | ... |
| ... | @@ -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 | ; | ... | ... |
| ... | @@ -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 | +} |
| ... | @@ -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 | ... | ... |
-
Please register or login to post a comment