wangyingyang

add order cancel

...@@ -16,4 +16,5 @@ public class BusinessConfig { ...@@ -16,4 +16,5 @@ public class BusinessConfig {
16 private String clientCustomerQueryUrl; 16 private String clientCustomerQueryUrl;
17 private String payUrl; 17 private String payUrl;
18 private String payClientId; 18 private String payClientId;
19 + private String cancelPayUrl;
19 } 20 }
......
...@@ -35,4 +35,11 @@ public class ClientOrderController { ...@@ -35,4 +35,11 @@ public class ClientOrderController {
35 return orderService.getOrdersByPagination(queryOrderDto); 35 return orderService.getOrdersByPagination(queryOrderDto);
36 } 36 }
37 37
38 + @ApiOperation(value = "院区端已撤销订单")
39 + @PostMapping("/client/orders/canceled/pagination")
40 + @ResponseStatus(HttpStatus.OK)
41 + public OrderPageResult<OrderDto> getCanceledOrderByByPagination(@Valid @RequestBody OrderDbDTO.QueryCanceledOrderByPaginationDto queryOrderDto) {
42 + return orderService.getCanceledOrdersByPagination(queryOrderDto);
43 + }
44 +
38 } 45 }
......
...@@ -53,4 +53,11 @@ public class PayController { ...@@ -53,4 +53,11 @@ public class PayController {
53 return payServiceClient.callback(paymentCallbackDTO); 53 return payServiceClient.callback(paymentCallbackDTO);
54 } 54 }
55 55
56 + @SaIgnore
57 + @ApiOperation(value = "支付撤销")
58 + @PostMapping(value = "/pay/cancel")
59 + @ResponseStatus(HttpStatus.OK)
60 + public boolean cancel(@Valid @RequestBody PayDTO.PayCancelRequestDto payCancelRequestDto) {
61 + return payServiceClient.cancelOrder(payCancelRequestDto);
62 + }
56 } 63 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -64,6 +64,17 @@ public class OrderDbDTO { ...@@ -64,6 +64,17 @@ public class OrderDbDTO {
64 } 64 }
65 65
66 @Data 66 @Data
67 + @ApiModel(description = "查询已撤销订单Dto")
68 + public static class QueryCanceledOrderByPaginationDto {
69 + private Integer enterpriseId;
70 + private Integer clientId;
71 + private Integer pn;
72 + private Integer pz;
73 + private String keyword;
74 + private List<Integer> stallIds;
75 + }
76 +
77 + @Data
67 @Builder 78 @Builder
68 @ApiModel(description = "订单不同状态的数量Dto") 79 @ApiModel(description = "订单不同状态的数量Dto")
69 public static class OrderCountByStatusDto { 80 public static class OrderCountByStatusDto {
...@@ -455,12 +466,18 @@ public class OrderDbDTO { ...@@ -455,12 +466,18 @@ public class OrderDbDTO {
455 @ApiModelProperty(value = "是否已读") 466 @ApiModelProperty(value = "是否已读")
456 private Boolean isRead; 467 private Boolean isRead;
457 468
469 + @ApiModelProperty(value = "是否已撤销")
470 + private Boolean isCanceled;
471 +
458 @ApiModelProperty(value = "截单类型") 472 @ApiModelProperty(value = "截单类型")
459 private Integer closeTimeType; 473 private Integer closeTimeType;
460 474
461 @ApiModelProperty(value = "订单所属用户的信息") 475 @ApiModelProperty(value = "订单所属用户的信息")
462 private CustomerDetailDto customer; 476 private CustomerDetailDto customer;
463 477
478 + @ApiModelProperty(value = "该订单的忌口冲突、医嘱信息")
479 + private List<String> orderNotice;
480 +
464 // @ApiModelProperty(value = "订单菜品详情列表") 481 // @ApiModelProperty(value = "订单菜品详情列表")
465 // private List<OrderDetailDto> orderDetailDtos; 482 // private List<OrderDetailDto> orderDetailDtos;
466 } 483 }
......
...@@ -26,6 +26,17 @@ public class PayDTO { ...@@ -26,6 +26,17 @@ public class PayDTO {
26 } 26 }
27 27
28 @Data 28 @Data
29 + @ApiModel(description = "支付请求dto")
30 + @NoArgsConstructor
31 + @AllArgsConstructor
32 + public static class PayCancelRequestDto {
33 +// private String clientId;
34 + private Integer orderId;
35 + private String hospitalCode;
36 +// private String price;
37 + }
38 +
39 + @Data
29 @ApiModel(description = "支付MiniPay结果") 40 @ApiModel(description = "支付MiniPay结果")
30 @NoArgsConstructor 41 @NoArgsConstructor
31 @AllArgsConstructor 42 @AllArgsConstructor
...@@ -76,6 +87,15 @@ public class PayDTO { ...@@ -76,6 +87,15 @@ public class PayDTO {
76 } 87 }
77 88
78 @Data 89 @Data
90 + @ApiModel(description = "取消支付响应")
91 + @NoArgsConstructor
92 + @AllArgsConstructor
93 + public static class CancelPayResponseDto {
94 + private Integer code;
95 + private String message;
96 + }
97 +
98 + @Data
79 @Builder 99 @Builder
80 @ApiModel(description = "第三方支付平台通知请求dto") 100 @ApiModel(description = "第三方支付平台通知请求dto")
81 @NoArgsConstructor 101 @NoArgsConstructor
......
...@@ -9,6 +9,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.OrderAndDetailsDto; ...@@ -9,6 +9,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.OrderAndDetailsDto;
9 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailBatchUpdateDto; 9 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailBatchUpdateDto;
10 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailDto; 10 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailDto;
11 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDto; 11 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDto;
12 +import com.infoloop.tianting.model.dto.OrderDbDTO.QueryCanceledOrderByPaginationDto;
12 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 13 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
13 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto; 14 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto;
14 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto; 15 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto;
...@@ -21,6 +22,8 @@ public interface OrderService { ...@@ -21,6 +22,8 @@ public interface OrderService {
21 OrderAndDetailsDto getOrdersByCustomerId(Integer customerId); 22 OrderAndDetailsDto getOrdersByCustomerId(Integer customerId);
22 OrderAndDetailsDto getOrdersByCondition(QueryOrderByConditionDto queryOrderDto); 23 OrderAndDetailsDto getOrdersByCondition(QueryOrderByConditionDto queryOrderDto);
23 OrderPageResult<OrderDto> getOrdersByPagination(QueryOrderByPaginationDto queryOrderDto); 24 OrderPageResult<OrderDto> getOrdersByPagination(QueryOrderByPaginationDto queryOrderDto);
25 + OrderPageResult<OrderDto> getCanceledOrdersByPagination(
26 + QueryCanceledOrderByPaginationDto queryOrderDto);
24 List<OrderDetailDto> getOrderDetailsByOrderId(Integer orderId); 27 List<OrderDetailDto> getOrderDetailsByOrderId(Integer orderId);
25 CreateOrderResponse createOrder(CreateOrderDto createOrderDto); 28 CreateOrderResponse createOrder(CreateOrderDto createOrderDto);
26 CreateOrderResponse orderCreation(OperatorCreateOrderDto createOrderDto); 29 CreateOrderResponse orderCreation(OperatorCreateOrderDto createOrderDto);
......
...@@ -64,6 +64,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.MealDetailDto; ...@@ -64,6 +64,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.MealDetailDto;
64 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailBatchUpdateDto; 64 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailBatchUpdateDto;
65 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailDto; 65 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailDto;
66 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailOperationDto; 66 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailOperationDto;
67 +import com.infoloop.tianting.model.dto.OrderDbDTO.QueryCanceledOrderByPaginationDto;
67 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 68 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
68 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto; 69 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto;
69 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto; 70 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto;
...@@ -461,6 +462,8 @@ public class OrderServiceRpcClient { ...@@ -461,6 +462,8 @@ public class OrderServiceRpcClient {
461 .setKeyword(queryOrderDto.getKeyword() == null ? "" : queryOrderDto.getKeyword()) 462 .setKeyword(queryOrderDto.getKeyword() == null ? "" : queryOrderDto.getKeyword())
462 .setPageNo(queryOrderDto.getPn()) 463 .setPageNo(queryOrderDto.getPn())
463 .setPageSize(queryOrderDto.getPz()) 464 .setPageSize(queryOrderDto.getPz())
465 + .setShouldFilterStatus(true)
466 + .setShouldFilterIsCanceled(false)
464 .setStatus(queryOrderDto.getStatus()) 467 .setStatus(queryOrderDto.getStatus())
465 .setEnterpriseId(queryOrderDto.getEnterpriseId()) 468 .setEnterpriseId(queryOrderDto.getEnterpriseId())
466 .setClientId(queryOrderDto.getClientId()) 469 .setClientId(queryOrderDto.getClientId())
...@@ -469,6 +472,22 @@ public class OrderServiceRpcClient { ...@@ -469,6 +472,22 @@ public class OrderServiceRpcClient {
469 return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request); 472 return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request);
470 } 473 }
471 474
475 + public QueryClientCustomerOrdersByPaginationRpcResponse queryCanceledClientCustomerOrdersByPagination(
476 + QueryCanceledOrderByPaginationDto queryOrderDto) {
477 + final var request = QueryClientCustomerOrdersByPaginationRpcRequest.newBuilder()
478 + .setKeyword(queryOrderDto.getKeyword() == null ? "" : queryOrderDto.getKeyword())
479 + .setPageNo(queryOrderDto.getPn())
480 + .setPageSize(queryOrderDto.getPz())
481 + .setShouldFilterStatus(false)
482 + .setShouldFilterIsCanceled(true)
483 + .setIsCanceled(true)
484 + .setEnterpriseId(queryOrderDto.getEnterpriseId())
485 + .setClientId(queryOrderDto.getClientId())
486 + .addAllStallIds(queryOrderDto.getStallIds())
487 + .build();
488 + return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request);
489 + }
490 +
472 public List<SingleClientCustomerOrderDetailRpcResponse> getOrderDetailsByOrderId(Integer orderId) { 491 public List<SingleClientCustomerOrderDetailRpcResponse> getOrderDetailsByOrderId(Integer orderId) {
473 return orderServiceRpcBlockingStub.getClientCustomerOrderDetailsByOrderIds( 492 return orderServiceRpcBlockingStub.getClientCustomerOrderDetailsByOrderIds(
474 GetClientCustomerOrderDetailsByOrderIdsRpcRequest.newBuilder() 493 GetClientCustomerOrderDetailsByOrderIdsRpcRequest.newBuilder()
......
...@@ -2,12 +2,15 @@ package com.infoloop.tianting.service.client; ...@@ -2,12 +2,15 @@ package com.infoloop.tianting.service.client;
2 2
3 import cn.hutool.core.convert.Convert; 3 import cn.hutool.core.convert.Convert;
4 import com.fasterxml.jackson.annotation.JsonInclude; 4 import com.fasterxml.jackson.annotation.JsonInclude;
5 +import com.fasterxml.jackson.core.JsonParser.Feature;
5 import com.fasterxml.jackson.core.JsonProcessingException; 6 import com.fasterxml.jackson.core.JsonProcessingException;
6 import com.fasterxml.jackson.databind.DeserializationFeature; 7 import com.fasterxml.jackson.databind.DeserializationFeature;
8 +import com.fasterxml.jackson.databind.MapperFeature;
7 import com.fasterxml.jackson.databind.ObjectMapper; 9 import com.fasterxml.jackson.databind.ObjectMapper;
8 import com.fasterxml.jackson.databind.PropertyNamingStrategy; 10 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
9 import com.fasterxml.jackson.dataformat.xml.XmlMapper; 11 import com.fasterxml.jackson.dataformat.xml.XmlMapper;
10 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification; 12 import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification;
13 +import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
11 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 14 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
12 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; 15 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
13 import com.infoloop.tianting.clientresourcetagservice.SingleResourceLabelEntityRefsResponse; 16 import com.infoloop.tianting.clientresourcetagservice.SingleResourceLabelEntityRefsResponse;
...@@ -15,6 +18,8 @@ import com.infoloop.tianting.config.BusinessConfig; ...@@ -15,6 +18,8 @@ import com.infoloop.tianting.config.BusinessConfig;
15 import com.infoloop.tianting.context.LoginContextHolder; 18 import com.infoloop.tianting.context.LoginContextHolder;
16 import com.infoloop.tianting.exception.ClientEndExceptions; 19 import com.infoloop.tianting.exception.ClientEndExceptions;
17 import com.infoloop.tianting.exception.ErrorCodeEnum; 20 import com.infoloop.tianting.exception.ErrorCodeEnum;
21 +import com.infoloop.tianting.model.dto.PayDTO.CancelPayResponseDto;
22 +import com.infoloop.tianting.model.dto.PayDTO.PayCancelRequestDto;
18 import com.infoloop.tianting.model.dto.PayDTO.PayInformRequestDto; 23 import com.infoloop.tianting.model.dto.PayDTO.PayInformRequestDto;
19 import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto; 24 import com.infoloop.tianting.model.dto.PayDTO.PayResponseDto;
20 import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto; 25 import com.infoloop.tianting.model.dto.PayDTO.ThirdPartyPayInformRequestDto;
...@@ -32,8 +37,15 @@ import com.infoloop.tianting.server.session.UserTypeEnum; ...@@ -32,8 +37,15 @@ import com.infoloop.tianting.server.session.UserTypeEnum;
32 import com.infoloop.tianting.utils.DateUtil; 37 import com.infoloop.tianting.utils.DateUtil;
33 import com.infoloop.tianting.utils.EncryptionUtil; 38 import com.infoloop.tianting.utils.EncryptionUtil;
34 import com.infoloop.tianting.utils.JsonUtil; 39 import com.infoloop.tianting.utils.JsonUtil;
40 +import java.net.URLEncoder;
41 +import java.nio.charset.StandardCharsets;
35 import lombok.RequiredArgsConstructor; 42 import lombok.RequiredArgsConstructor;
36 import lombok.extern.slf4j.Slf4j; 43 import lombok.extern.slf4j.Slf4j;
44 +import okhttp3.OkHttpClient;
45 +import okhttp3.Request;
46 +import okhttp3.Response;
47 +import org.apache.commons.codec.binary.Base64;
48 +import org.apache.commons.codec.digest.DigestUtils;
37 import org.springframework.beans.factory.annotation.Autowired; 49 import org.springframework.beans.factory.annotation.Autowired;
38 import org.springframework.http.HttpEntity; 50 import org.springframework.http.HttpEntity;
39 import org.springframework.http.HttpHeaders; 51 import org.springframework.http.HttpHeaders;
...@@ -53,196 +65,347 @@ import java.util.ArrayList; ...@@ -53,196 +65,347 @@ import java.util.ArrayList;
53 import java.util.List; 65 import java.util.List;
54 import java.util.stream.Collectors; 66 import java.util.stream.Collectors;
55 67
56 -
57 @Slf4j 68 @Slf4j
58 @Service 69 @Service
59 @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 70 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
60 public class PayServiceClient { 71 public class PayServiceClient {
61 72
62 - private final RestTemplate restTemplate; 73 + private final RestTemplate restTemplate;
63 74
64 - private final BusinessConfig businessConfig; 75 + private final BusinessConfig businessConfig;
65 76
66 - private final OrderServiceRpcClient orderServiceRpcClient; 77 + private final OrderServiceRpcClient orderServiceRpcClient;
67 78
68 - private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient; 79 + private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;
69 80
70 - private final EnterpriseResourceServiceRpcClient enterpriseResourceServiceRpcClient; 81 + private final EnterpriseResourceServiceRpcClient enterpriseResourceServiceRpcClient;
71 82
72 - private final XmlMapper xmlMapper = new XmlMapper(); 83 + private final XmlMapper xmlMapper = new XmlMapper();
73 84
74 - public PayResponseDto payInform(PayInformRequestDto payRequestDto) { 85 + private final OkHttpClient client = new OkHttpClient();
75 - final var orderById = orderServiceRpcClient.getOrderById(Integer.valueOf(payRequestDto.getOrderId()));
76 - if (orderById == null || orderById.getPayStatus() == PayStatusEnum.PAY_CANCELED || orderById.getStatus() == OrderStatusEnum.ORDER_CANCELED) {
77 - log.info("Order {} not found or canceled, skipping.", payRequestDto.getOrderId());
78 - throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.ORDER_CANCEL);
79 - }
80 - String url = MessageFormat.format(businessConfig.getPayUrl(), businessConfig.getPayClientId());
81 - String requestDate = DateUtil.formatDate(LocalDateTime.now(), DateUtil.YMDHMS);
82 - ThirdPartyPayInformRequestDto jsonData = buildRequestData(payRequestDto, requestDate);
83 - String jsonDataString;
84 - try {
85 - ObjectMapper objectMapper = new ObjectMapper();
86 - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
87 - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
88 - objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
89 - jsonDataString = objectMapper.writeValueAsString(jsonData);
90 - } catch (JsonProcessingException e) {
91 - log.error("Failed to serialize request data", e);
92 - throw new IllegalArgumentException("支付信息获取失败: JSON 解析错误");
93 - }
94 - HttpEntity<String> requestEntity = new HttpEntity<>(jsonDataString, createHeaders());
95 - log.info("payInform request: {}", jsonDataString);
96 - ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
97 - return processResponse(responseEntity);
98 - }
99 86
100 - private ThirdPartyPayInformRequestDto buildRequestData(PayInformRequestDto payRequestDto, String requestDate) { 87 + public PayResponseDto payInform(PayInformRequestDto payRequestDto) {
101 - ThirdPartyPayInformRequestDto jsonData = new ThirdPartyPayInformRequestDto(); 88 + final var orderById =
102 - jsonData.setClientId(businessConfig.getPayClientId()); 89 + orderServiceRpcClient.getOrderById(Integer.valueOf(payRequestDto.getOrderId()));
103 - jsonData.setTradeId(payRequestDto.getOrderId()); 90 + if (orderById == null
104 - jsonData.setRequestDate(requestDate); 91 + || orderById.getPayStatus() == PayStatusEnum.PAY_CANCELED
105 - jsonData.setRequestSource("OFWXApplet"); 92 + || orderById.getStatus() == OrderStatusEnum.ORDER_CANCELED) {
106 - jsonData.setPayerOpenId(LoginContextHolder.getOpenId()); 93 + log.info("Order {} not found or canceled, skipping.", payRequestDto.getOrderId());
107 - jsonData.setHospitalCode(payRequestDto.getHospitalCode()); 94 + throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.ORDER_CANCEL);
108 - jsonData.setPID(payRequestDto.getPhone());
109 - jsonData.setRemark("");
110 - jsonData.setTransAmount(payRequestDto.getPrice());
111 - jsonData.setTradeDesc("");
112 - jsonData.setSign(EncryptionUtil.sha1Encryption(businessConfig.getPayClientId() + payRequestDto.getOrderId() + requestDate + businessConfig.getPayClientId()));
113 - return jsonData;
114 } 95 }
96 + String url = MessageFormat.format(businessConfig.getPayUrl(), businessConfig.getPayClientId());
97 + String requestDate = DateUtil.formatDate(LocalDateTime.now(), DateUtil.YMDHMS);
98 + ThirdPartyPayInformRequestDto jsonData = buildRequestData(payRequestDto, requestDate);
99 + String jsonDataString;
100 + try {
101 + ObjectMapper objectMapper = new ObjectMapper();
102 + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
103 + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
104 + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
105 + jsonDataString = objectMapper.writeValueAsString(jsonData);
106 + } catch (JsonProcessingException e) {
107 + log.error("Failed to serialize request data", e);
108 + throw new IllegalArgumentException("支付信息获取失败: JSON 解析错误");
109 + }
110 + HttpEntity<String> requestEntity = new HttpEntity<>(jsonDataString, createHeaders());
111 + log.info("payInform request: {}", jsonDataString);
112 + ResponseEntity<String> responseEntity =
113 + restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
114 + return processResponse(responseEntity);
115 + }
116 +
117 + private ThirdPartyPayInformRequestDto buildRequestData(
118 + PayInformRequestDto payRequestDto, String requestDate) {
119 + ThirdPartyPayInformRequestDto jsonData = new ThirdPartyPayInformRequestDto();
120 + jsonData.setClientId(businessConfig.getPayClientId());
121 + jsonData.setTradeId(payRequestDto.getOrderId());
122 + jsonData.setRequestDate(requestDate);
123 + jsonData.setRequestSource("OFWXApplet");
124 + jsonData.setPayerOpenId(LoginContextHolder.getOpenId());
125 + jsonData.setHospitalCode(payRequestDto.getHospitalCode());
126 + jsonData.setPID(LoginContextHolder.getOpenId());
127 + jsonData.setRemark("");
128 + jsonData.setTransAmount(payRequestDto.getPrice());
129 + jsonData.setTradeDesc("");
130 + jsonData.setSign(
131 + EncryptionUtil.sha1Encryption(
132 + businessConfig.getPayClientId()
133 + + payRequestDto.getOrderId()
134 + + requestDate
135 + + businessConfig.getPayClientId()));
136 + return jsonData;
137 + }
138 +
139 + private HttpHeaders createHeaders() {
140 + HttpHeaders headers = new HttpHeaders();
141 + headers.setContentType(MediaType.APPLICATION_JSON);
142 + return headers;
143 + }
115 144
116 - private HttpHeaders createHeaders() { 145 + private PayResponseDto processResponse(ResponseEntity<String> responseEntity) {
117 - HttpHeaders headers = new HttpHeaders(); 146 + if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
118 - headers.setContentType(MediaType.APPLICATION_JSON); 147 + log.error("payInform failed with response: {}", responseEntity.getBody());
119 - return headers; 148 + throw new IllegalArgumentException("支付信息获取失败");
120 } 149 }
150 + try {
151 + log.info("processResponse response: {}", responseEntity.getBody());
152 + return xmlMapper.readValue(responseEntity.getBody(), PayResponseDto.class);
153 + } catch (Exception e) {
154 + log.error("Failed to parse XML response", e);
155 + throw new RuntimeException("支付信息结果解析失败", e);
156 + }
157 + }
121 158
122 - private PayResponseDto processResponse(ResponseEntity<String> responseEntity) { 159 + public boolean callback(PaymentCallbackDTO paymentCallbackDTO) {
123 - if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) { 160 + log.info("callback request received: {}", paymentCallbackDTO);
124 - log.error("payInform failed with response: {}", responseEntity.getBody()); 161 + try {
125 - throw new IllegalArgumentException("支付信息获取失败"); 162 + final var paymentCallbackResult =
163 + xmlMapper.readValue(paymentCallbackDTO.getPayResult(), PaymentCallbackResult.class);
164 + log.info("Parsed paymentCallbackResult: {}", paymentCallbackResult);
165 + final var orderId = Integer.parseInt(paymentCallbackResult.getTradeId());
166 + final var orderById = orderServiceRpcClient.getOrderById(orderId);
167 + if (orderById == null) {
168 + log.error("Order not found, orderId: {}", orderId);
169 + return false;
170 + }
171 + if (orderById.getPayStatus() != PayStatusEnum.TO_PAY
172 + && orderById.getPayStatus() != PayStatusEnum.IN_PROGRESS) {
173 + log.error("Order status is not TO_PAY or IN_PROGRESS, orderId: {}", orderId);
174 + return true;
175 + }
176 + long payTime;
177 + try {
178 + payTime =
179 + DateUtil.parseDate(paymentCallbackResult.getTransDate(), "yyyyMMddHHmmss").getTime();
180 + } catch (ParseException e) {
181 + log.error("Failed to parse TransDate: {}", paymentCallbackResult.getTransDate(), e);
182 + throw new IllegalArgumentException("支付时间格式错误: " + paymentCallbackResult.getTransDate(), e);
183 + }
184 + BigDecimal realAmount;
185 + try {
186 + realAmount = Convert.toBigDecimal(paymentCallbackResult.getRealAmount());
187 + if (realAmount == null) {
188 + throw new NumberFormatException("RealAmount is null or empty");
126 } 189 }
127 - try { 190 + } catch (NumberFormatException e) {
128 - log.info("processResponse response: {}", responseEntity.getBody()); 191 + log.error("Invalid RealAmount value: {}", paymentCallbackResult.getRealAmount(), e);
129 - return xmlMapper.readValue(responseEntity.getBody(), PayResponseDto.class); 192 + throw new IllegalArgumentException("支付金额错误: " + paymentCallbackResult.getRealAmount(), e);
130 - } catch (Exception e) { 193 + }
131 - log.error("Failed to parse XML response", e); 194 + final var build =
132 - throw new RuntimeException("支付信息结果解析失败", e); 195 + ClientCustomerOrderModification.newBuilder()
196 + .setId(orderId)
197 + .setShouldUpdatePayTime(true)
198 + .setPayTime(payTime)
199 + .setShouldUpdatePayPrice(true)
200 + .setPayPrice(realAmount.multiply(new BigDecimal("100")).intValue())
201 + .setShouldUpdatePayStatus(true)
202 + .setPayStatus(PayStatusEnum.SUCCEED)
203 + .setShouldUpdateStatus(true)
204 + .setStatus(OrderStatusEnum.PREPARING)
205 + .setShouldUpdateTransactionId(true)
206 + .setTransactionId(paymentCallbackResult.getTransSN())
207 + .build();
208 + final var updateResponse =
209 + orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build);
210 + log.info("callback updateClientCustomerOrder result: {}", updateResponse.getIsUpdated());
211 + if (updateResponse.getIsUpdated()) {
212 + final var orderPaymentSuccessData =
213 + OrderPaymentSuccessData.builder()
214 + .orderId(orderById.getId())
215 + .orderCode(orderById.getOrderCode())
216 + .createTime(DateUtil.formatDate(orderById.getCreatedAt(), DateUtil.Y_M_D_H_M_S))
217 + .payTime(DateUtil.formatDate(orderById.getPayTime(), DateUtil.Y_M_D_H_M_S))
218 + .build();
219 + final var data =
220 + SocketMessage.<OrderPaymentSuccessData>builder()
221 + .type(MessageTypeEnum.ORDER)
222 + .noticeType(NoticeTypeEnum.ORDER_PAYMENT_SUCCESS)
223 + .subject(NoticeTypeEnum.ORDER_PAYMENT_SUCCESS.getDescription())
224 + .message("您的订单:" + orderById.getOrderCode() + " 支付成功啦,快去查看吧~")
225 + .data(orderPaymentSuccessData)
226 + .build();
227 + WebSocketServer.sendMessageToUser(
228 + UserSessionKey.builder()
229 + .userId(orderById.getOpenId())
230 + .userType(UserTypeEnum.MICRO)
231 + .build(),
232 + data);
233 + if (LocalDate.now().equals(DateUtil.toLocalDate(orderById.getMealTime()))) {
234 + final var orderCreateSuccessData =
235 + OrderCreateSuccessData.builder().orderId(orderById.getId()).build();
236 + final var createOrderData =
237 + SocketMessage.<OrderCreateSuccessData>builder()
238 + .type(MessageTypeEnum.ORDER)
239 + .noticeType(NoticeTypeEnum.ORDER_CREATED)
240 + .subject(NoticeTypeEnum.ORDER_CREATED.getDescription())
241 + .message("有新的订单下单成功啦,快去查看吧~")
242 + .data(orderCreateSuccessData)
243 + .build();
244 + final var clientOperatorIds =
245 + clientResourceTagServiceRpcClient
246 + .getOperatorIdsByStallIds(List.of(orderById.getStallId())).stream()
247 + .map(SingleResourceLabelEntityRefsResponse::getEntityId)
248 + .distinct()
249 + .collect(Collectors.toList());
250 + final var enterpriseOperatorIds =
251 + enterpriseResourceServiceRpcClient.getOperatorIdsByStallId(
252 + orderById.getEnterpriseId(), orderById.getStallId());
253 + final var userAuthData = new ArrayList<UserAuthData>();
254 + userAuthData.addAll(
255 + clientOperatorIds.stream()
256 + .map(
257 + e ->
258 + UserAuthData.builder()
259 + .operatorId(e)
260 + .userType(UserTypeEnum.CLIENT)
261 + .build())
262 + .collect(Collectors.toList()));
263 + userAuthData.addAll(
264 + enterpriseOperatorIds.stream()
265 + .map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.KDS).build())
266 + .collect(Collectors.toList()));
267 + log.info("received userAuthData:{}", JsonUtil.writeAsJson(userAuthData));
268 + try {
269 + WebSocketServer.sendMessageByUserTypes(
270 + List.of(UserTypeEnum.CLIENT, UserTypeEnum.KDS), userAuthData, createOrderData);
271 + } catch (IOException e) {
272 + log.error("Failed to send message to user", e);
273 + }
133 } 274 }
275 + }
276 + return updateResponse.getIsUpdated();
277 + } catch (JsonProcessingException e) {
278 + log.error("Failed to parse XML response, raw XML: {}", paymentCallbackDTO.getPayResult(), e);
279 + throw new RuntimeException("支付通知结果解析失败", e);
280 + } catch (Exception e) {
281 + log.error("Unexpected error in callback, request: {}", paymentCallbackDTO, e);
282 + throw new RuntimeException("支付通知处理失败", e);
134 } 283 }
284 + }
135 285
136 - public boolean callback(PaymentCallbackDTO paymentCallbackDTO) { 286 + public boolean waiting(Integer orderId) {
137 - log.info("callback request received: {}", paymentCallbackDTO); 287 + final var orderById = orderServiceRpcClient.getOrderById(orderId);
138 - try { 288 + if (orderById == null) {
139 - final var paymentCallbackResult = xmlMapper.readValue(paymentCallbackDTO.getPayResult(), PaymentCallbackResult.class); 289 + log.error("waiting Order not found, orderId: {}", orderId);
140 - log.info("Parsed paymentCallbackResult: {}", paymentCallbackResult); 290 + return false;
141 - final var orderId = Integer.parseInt(paymentCallbackResult.getTradeId());
142 - final var orderById = orderServiceRpcClient.getOrderById(orderId);
143 - if (orderById == null) {
144 - log.error("Order not found, orderId: {}", orderId);
145 - return false;
146 - }
147 - if (orderById.getPayStatus() != PayStatusEnum.TO_PAY && orderById.getPayStatus() != PayStatusEnum.IN_PROGRESS) {
148 - log.error("Order status is not TO_PAY or IN_PROGRESS, orderId: {}", orderId);
149 - return true;
150 - }
151 - long payTime;
152 - try {
153 - payTime = DateUtil.parseDate(paymentCallbackResult.getTransDate(), "yyyyMMddHHmmss").getTime();
154 - } catch (ParseException e) {
155 - log.error("Failed to parse TransDate: {}", paymentCallbackResult.getTransDate(), e);
156 - throw new IllegalArgumentException("支付时间格式错误: " + paymentCallbackResult.getTransDate(), e);
157 - }
158 - BigDecimal realAmount;
159 - try {
160 - realAmount = Convert.toBigDecimal(paymentCallbackResult.getRealAmount());
161 - if (realAmount == null) {
162 - throw new NumberFormatException("RealAmount is null or empty");
163 - }
164 - } catch (NumberFormatException e) {
165 - log.error("Invalid RealAmount value: {}", paymentCallbackResult.getRealAmount(), e);
166 - throw new IllegalArgumentException("支付金额错误: " + paymentCallbackResult.getRealAmount(), e);
167 - }
168 - final var build = ClientCustomerOrderModification.newBuilder()
169 - .setId(orderId)
170 - .setShouldUpdatePayTime(true).setPayTime(payTime)
171 - .setShouldUpdatePayPrice(true).setPayPrice(realAmount.multiply(new BigDecimal("100")).intValue())
172 - .setShouldUpdatePayStatus(true).setPayStatus(PayStatusEnum.SUCCEED)
173 - .setShouldUpdateStatus(true).setStatus(OrderStatusEnum.PREPARING)
174 - .setShouldUpdateTransactionId(true).setTransactionId(paymentCallbackResult.getTransSN())
175 - .build();
176 - final var updateResponse = orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build);
177 - log.info("callback updateClientCustomerOrder result: {}", updateResponse.getIsUpdated());
178 - if (updateResponse.getIsUpdated()) {
179 - final var orderPaymentSuccessData = OrderPaymentSuccessData.builder()
180 - .orderId(orderById.getId())
181 - .orderCode(orderById.getOrderCode())
182 - .createTime(DateUtil.formatDate(orderById.getCreatedAt(), DateUtil.Y_M_D_H_M_S))
183 - .payTime(DateUtil.formatDate(orderById.getPayTime(), DateUtil.Y_M_D_H_M_S))
184 - .build();
185 - final var data = SocketMessage.<OrderPaymentSuccessData>builder()
186 - .type(MessageTypeEnum.ORDER)
187 - .noticeType(NoticeTypeEnum.ORDER_PAYMENT_SUCCESS)
188 - .subject(NoticeTypeEnum.ORDER_PAYMENT_SUCCESS.getDescription())
189 - .message("您的订单:" + orderById.getOrderCode() + " 支付成功啦,快去查看吧~")
190 - .data(orderPaymentSuccessData)
191 - .build();
192 - WebSocketServer.sendMessageToUser(UserSessionKey.builder()
193 - .userId(orderById.getOpenId())
194 - .userType(UserTypeEnum.MICRO)
195 - .build(), data);
196 - if (LocalDate.now().equals(DateUtil.toLocalDate(orderById.getMealTime()))) {
197 - final var orderCreateSuccessData = OrderCreateSuccessData.builder()
198 - .orderId(orderById.getId())
199 - .build();
200 - final var createOrderData = SocketMessage.<OrderCreateSuccessData>builder()
201 - .type(MessageTypeEnum.ORDER)
202 - .noticeType(NoticeTypeEnum.ORDER_CREATED)
203 - .subject(NoticeTypeEnum.ORDER_CREATED.getDescription())
204 - .message("有新的订单下单成功啦,快去查看吧~")
205 - .data(orderCreateSuccessData)
206 - .build();
207 - final var clientOperatorIds = clientResourceTagServiceRpcClient.getOperatorIdsByStallIds(List.of(orderById.getStallId())).stream().map(SingleResourceLabelEntityRefsResponse::getEntityId).distinct().collect(Collectors.toList());
208 - final var enterpriseOperatorIds = enterpriseResourceServiceRpcClient.getOperatorIdsByStallId(orderById.getEnterpriseId(), orderById.getStallId());
209 - final var userAuthData = new ArrayList<UserAuthData>();
210 - userAuthData.addAll(clientOperatorIds.stream().map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.CLIENT).build()).collect(Collectors.toList()));
211 - userAuthData.addAll(enterpriseOperatorIds.stream().map(e -> UserAuthData.builder().operatorId(e).userType(UserTypeEnum.KDS).build()).collect(Collectors.toList()));
212 - log.info("received userAuthData:{}", JsonUtil.writeAsJson(userAuthData));
213 - try {
214 - WebSocketServer.sendMessageByUserTypes(List.of(UserTypeEnum.CLIENT, UserTypeEnum.KDS), userAuthData, createOrderData);
215 - } catch (IOException e) {
216 - log.error("Failed to send message to user", e);
217 - }
218 - }
219 - }
220 - return updateResponse.getIsUpdated();
221 - } catch (JsonProcessingException e) {
222 - log.error("Failed to parse XML response, raw XML: {}", paymentCallbackDTO.getPayResult(), e);
223 - throw new RuntimeException("支付通知结果解析失败", e);
224 - } catch (Exception e) {
225 - log.error("Unexpected error in callback, request: {}", paymentCallbackDTO, e);
226 - throw new RuntimeException("支付通知处理失败", e);
227 - }
228 } 291 }
292 + if (orderById.getPayStatus() != PayStatusEnum.TO_PAY) {
293 + log.info("waiting Order {} already processed, skipping.", orderId);
294 + return false;
295 + }
296 + final var build =
297 + ClientCustomerOrderModification.newBuilder()
298 + .setId(orderId)
299 + .setShouldUpdatePayStatus(true)
300 + .setPayStatus(PayStatusEnum.IN_PROGRESS)
301 + .build();
302 + final var updateResponse =
303 + orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build);
304 + log.info("waiting updateClientCustomerOrder result: {}", updateResponse.getIsUpdated());
305 + return updateResponse.getIsUpdated();
306 + }
229 307
230 - public boolean waiting(Integer orderId) { 308 + public boolean cancelOrder(PayCancelRequestDto payCancelRequestDto) {
231 - final var orderById = orderServiceRpcClient.getOrderById(orderId); 309 + Integer orderId = payCancelRequestDto.getOrderId();
232 - if (orderById == null) { 310 + final var orderById = orderServiceRpcClient.getOrderById(orderId);
233 - log.error("waiting Order not found, orderId: {}", orderId); 311 + if (orderById == null) {
234 - return false; 312 + log.error("Order not found, orderId: {}", orderId);
235 - } 313 + return false;
236 - if (orderById.getPayStatus() != PayStatusEnum.TO_PAY) { 314 + }
237 - log.info("waiting Order {} already processed, skipping.", orderId); 315 + if (orderById.getOnlinePay() != OnlinePayEnum.ONLINE) {
238 - return false; 316 + log.info("Order {} is not online pay.", orderId);
239 - } 317 + return false;
240 - final var build = ClientCustomerOrderModification.newBuilder() 318 + }
319 + if (orderById.getPayStatus() != PayStatusEnum.SUCCEED) {
320 + log.info("Order {} pay is not succeed.", orderId);
321 + return false;
322 + }
323 + LocalDate today = LocalDate.now();
324 + LocalDate tomorrow = today.plusDays(1);
325 + LocalDateTime tomorrowZero = tomorrow.atStartOfDay();
326 + LocalDateTime orderPayTime = DateUtil.toLocalDateTime(orderById.getPayTime());
327 + if (!orderPayTime.isBefore(tomorrowZero)) {
328 + log.info("Order {} pay is beyond cancel time.", orderId);
329 + return false;
330 + }
331 +
332 + String appId = businessConfig.getPayClientId();
333 +
334 + // 构建paycontent
335 + String payTime = DateUtil.formatDate(orderById.getPayTime(), DateUtil.YMDHMS);
336 +
337 + String payContentStr =
338 + orderById.getId()
339 + + "^"
340 + + "01(退款)"
341 + + "^"
342 + + ""
343 + + "^"
344 + + orderById.getOpenId()
345 + + "^"
346 + + orderById.getOrderCode()
347 + + "^"
348 + + orderById.getPayPrice()
349 + + "^"
350 + + payTime
351 + + "^"
352 + + orderById.getTransactionId()
353 + + "^"
354 + + payCancelRequestDto.getHospitalCode()
355 + + "^"
356 + + ""
357 + + "^"
358 + + LoginContextHolder.getId()
359 + + "^"
360 + + LoginContextHolder.getName();
361 + String payContent =
362 + URLEncoder.encode(
363 + Base64.encodeBase64String(payContentStr.getBytes()), StandardCharsets.UTF_8);
364 +
365 + // 构建signinfo
366 + String signInfoStr = appId + orderById.getId() + payTime + businessConfig.getPayClientId();
367 + String signInfo = DigestUtils.sha1Hex(signInfoStr.getBytes());
368 +
369 + // 构建请求
370 + // 设置请求体的媒体类型为JSON
371 + try {
372 + // MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
373 + // RequestBody body = RequestBody.create(mediaType, jsonDataString);
374 +
375 + String url = businessConfig.getCancelPayUrl() + "?" + "appid=" + appId + "&paycontent=" + payContent + "&signinfo=" + signInfo;
376 + Request request =
377 + new Request.Builder().url(url).get().build();
378 +
379 + Response payResponse = client.newCall(request).execute();
380 + if (payResponse.code() != 200) {
381 + return false;
382 + }
383 + String cancelPayJsonData = payResponse.body().string();
384 + log.info("pay json:" + cancelPayJsonData);
385 + ObjectMapper objectMapper = new ObjectMapper();
386 + objectMapper.configure(Feature.ALLOW_MISSING_VALUES, true);
387 + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
388 + objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES, false);
389 +
390 + CancelPayResponseDto payResponseDto =
391 + objectMapper.readValue(cancelPayJsonData, CancelPayResponseDto.class);
392 +
393 + if (payResponseDto.getCode() != 0) {
394 + return false;
395 + } else {
396 + // 更新订单撤销状态
397 + final var build =
398 + ClientCustomerOrderModification.newBuilder()
241 .setId(orderId) 399 .setId(orderId)
242 - .setShouldUpdatePayStatus(true).setPayStatus(PayStatusEnum.IN_PROGRESS) 400 + .setShouldUpdateIsCanceled(true)
401 + .setIsCanceled(true)
243 .build(); 402 .build();
244 - final var updateResponse = orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build); 403 + orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build);
245 - log.info("waiting updateClientCustomerOrder result: {}", updateResponse.getIsUpdated()); 404 + return true;
246 - return updateResponse.getIsUpdated(); 405 + }
406 + } catch (Exception e) {
407 + log.error(e.getStackTrace().toString());
408 + return false;
247 } 409 }
410 + }
248 } 411 }
......
...@@ -7,6 +7,7 @@ import com.infoloop.tianting.clientcustomerorderservice.CloseTimeType; ...@@ -7,6 +7,7 @@ import com.infoloop.tianting.clientcustomerorderservice.CloseTimeType;
7 import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum; 7 import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum;
8 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 8 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
9 import com.infoloop.tianting.clientcustomerorderservice.OrderTypeEnum; 9 import com.infoloop.tianting.clientcustomerorderservice.OrderTypeEnum;
10 +import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
10 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse; 11 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
11 import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerLabelRefRpcResponse; 12 import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerLabelRefRpcResponse;
12 import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerRpcResponse; 13 import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerRpcResponse;
...@@ -16,8 +17,10 @@ import com.infoloop.tianting.deliveryruleservice.SingleClientLabelRpcResponse; ...@@ -16,8 +17,10 @@ import com.infoloop.tianting.deliveryruleservice.SingleClientLabelRpcResponse;
16 import com.infoloop.tianting.exception.ClientEndExceptions; 17 import com.infoloop.tianting.exception.ClientEndExceptions;
17 import com.infoloop.tianting.exception.ErrorCodeEnum; 18 import com.infoloop.tianting.exception.ErrorCodeEnum;
18 import com.infoloop.tianting.menuservice.CloseTimeTypeEnum; 19 import com.infoloop.tianting.menuservice.CloseTimeTypeEnum;
20 +import com.infoloop.tianting.menuservice.SingleClientCustomerMenuRefRpcResponse;
19 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse; 21 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse;
20 import com.infoloop.tianting.model.common.OrderPageResult; 22 import com.infoloop.tianting.model.common.OrderPageResult;
23 +import com.infoloop.tianting.model.dto.ClientCustomerDbDTO.CurrentClientCustomerDto;
21 import com.infoloop.tianting.model.dto.ClientLabelDTO.HisAllergy; 24 import com.infoloop.tianting.model.dto.ClientLabelDTO.HisAllergy;
22 import com.infoloop.tianting.model.dto.ClientLabelDTO.HisMedicalAdviceDto; 25 import com.infoloop.tianting.model.dto.ClientLabelDTO.HisMedicalAdviceDto;
23 import com.infoloop.tianting.model.dto.ClientLabelDTO.QueryLabelsDto; 26 import com.infoloop.tianting.model.dto.ClientLabelDTO.QueryLabelsDto;
...@@ -35,6 +38,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.OrderCountByStatusDto; ...@@ -35,6 +38,7 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.OrderCountByStatusDto;
35 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailBatchUpdateDto; 38 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailBatchUpdateDto;
36 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailDto; 39 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDetailDto;
37 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDto; 40 import com.infoloop.tianting.model.dto.OrderDbDTO.OrderDto;
41 +import com.infoloop.tianting.model.dto.OrderDbDTO.QueryCanceledOrderByPaginationDto;
38 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 42 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
39 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto; 43 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByPaginationDto;
40 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto; 44 import com.infoloop.tianting.model.dto.OrderDbDTO.UpdateOrderDto;
...@@ -50,6 +54,7 @@ import com.infoloop.tianting.service.client.OrderServiceRpcClient; ...@@ -50,6 +54,7 @@ import com.infoloop.tianting.service.client.OrderServiceRpcClient;
50 import com.infoloop.tianting.service.client.SkuServiceRpcClient; 54 import com.infoloop.tianting.service.client.SkuServiceRpcClient;
51 import com.infoloop.tianting.utils.DateUtil; 55 import com.infoloop.tianting.utils.DateUtil;
52 import com.infoloop.tianting.utils.PageUtil; 56 import com.infoloop.tianting.utils.PageUtil;
57 +import java.util.Arrays;
53 import lombok.RequiredArgsConstructor; 58 import lombok.RequiredArgsConstructor;
54 import lombok.extern.slf4j.Slf4j; 59 import lombok.extern.slf4j.Slf4j;
55 import org.springframework.beans.factory.annotation.Autowired; 60 import org.springframework.beans.factory.annotation.Autowired;
...@@ -318,6 +323,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -318,6 +323,7 @@ public class OrderServiceImpl implements OrderService {
318 .updateSource(r.getUpdateSource().getNumber()) 323 .updateSource(r.getUpdateSource().getNumber())
319 .updatedAt(DateUtil.formatDate(r.getUpdatedAt())) 324 .updatedAt(DateUtil.formatDate(r.getUpdatedAt()))
320 .updatedBy(r.getUpdatedBy()) 325 .updatedBy(r.getUpdatedBy())
326 + .isCanceled(r.getIsCanceled())
321 .build()).collect(Collectors.toList()); 327 .build()).collect(Collectors.toList());
322 final var ids = orders.stream().map(OrderDto::getId).collect(Collectors.toList()); 328 final var ids = orders.stream().map(OrderDto::getId).collect(Collectors.toList());
323 final var detailsResponse = orderServiceRpcClient.getOrderDetailsByOrderIds(ids); 329 final var detailsResponse = orderServiceRpcClient.getOrderDetailsByOrderIds(ids);
...@@ -391,6 +397,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -391,6 +397,7 @@ public class OrderServiceImpl implements OrderService {
391 .updateSource(r.getUpdateSource().getNumber()) 397 .updateSource(r.getUpdateSource().getNumber())
392 .updatedAt(DateUtil.formatDate(r.getUpdatedAt())) 398 .updatedAt(DateUtil.formatDate(r.getUpdatedAt()))
393 .updatedBy(r.getUpdatedBy()) 399 .updatedBy(r.getUpdatedBy())
400 + .isCanceled(r.getIsCanceled())
394 .build()).collect(Collectors.toList()); 401 .build()).collect(Collectors.toList());
395 final var ids = orders.stream().map(OrderDto::getId).collect(Collectors.toList()); 402 final var ids = orders.stream().map(OrderDto::getId).collect(Collectors.toList());
396 final var detailsResponse = orderServiceRpcClient.getOrderDetailsByOrderIds(ids); 403 final var detailsResponse = orderServiceRpcClient.getOrderDetailsByOrderIds(ids);
...@@ -437,7 +444,28 @@ public class OrderServiceImpl implements OrderService { ...@@ -437,7 +444,28 @@ public class OrderServiceImpl implements OrderService {
437 final var customerIds = response.getResponsesList().stream().map(SingleClientCustomerOrderRpcResponse::getCustomerId).collect(Collectors.toList()); 444 final var customerIds = response.getResponsesList().stream().map(SingleClientCustomerOrderRpcResponse::getCustomerId).collect(Collectors.toList());
438 final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds( 445 final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(
439 queryOrderDto.getEnterpriseId(), customerIds); 446 queryOrderDto.getEnterpriseId(), customerIds);
440 - final var results = response.getResponsesList().stream().map(r -> OrderDto.builder() 447 + final var orderIds = response.getResponsesList().stream().map(SingleClientCustomerOrderRpcResponse::getId).collect(Collectors.toList());
448 + final var orderDetails = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
449 + final var results = response.getResponsesList().stream().map(r -> {
450 + final var curOrderDetails = orderDetails.stream().filter(d ->
451 + d.getOrderId() == r.getId()).collect(Collectors.toList());
452 + List<String> orderNotice = new ArrayList<>();
453 + for (SingleClientCustomerOrderDetailRpcResponse detail: curOrderDetails) {
454 + final var avoids = detail.getMealDetailJson().getAvoidsList();
455 + final var existAvoids = r.getCustomerNoticeJson().getAvoidsList().stream().anyMatch(avoids::contains);
456 + if (existAvoids) {
457 + orderNotice.add("忌口冲突");
458 + break;
459 + }
460 + }
461 + String[] keywords = {"禁食", "禁水", "禁食水"};
462 + final var result = Arrays.stream(keywords)
463 + .filter(keyword -> r.getCustomerNoticeJson().getDoctorsList().stream().anyMatch(str -> str.contains(keyword)))
464 + .findFirst();
465 + if (result != null) {
466 + orderNotice.add("医嘱包含" + result);
467 + }
468 + return OrderDto.builder()
441 .id(r.getId()) 469 .id(r.getId())
442 .enterpriseId(r.getEnterpriseId()) 470 .enterpriseId(r.getEnterpriseId())
443 .clientId(r.getClientId()) 471 .clientId(r.getClientId())
...@@ -453,8 +481,8 @@ public class OrderServiceImpl implements OrderService { ...@@ -453,8 +481,8 @@ public class OrderServiceImpl implements OrderService {
453 .adjustRoomNo(!r.getSyncRoomNo().isEmpty()) 481 .adjustRoomNo(!r.getSyncRoomNo().isEmpty())
454 .status(r.getStatus()) 482 .status(r.getStatus())
455 .customerNoticeJson(CustomerNotice.builder() 483 .customerNoticeJson(CustomerNotice.builder()
456 - .avoids(r.getCustomerNoticeJson().getAvoidsList()) 484 + .avoids(r.getCustomerNoticeJson().getAvoidsList())
457 - .doctors(r.getCustomerNoticeJson().getDoctorsList()).build()) 485 + .doctors(r.getCustomerNoticeJson().getDoctorsList()).build())
458 .onlinePay(r.getOnlinePay()) 486 .onlinePay(r.getOnlinePay())
459 .payStatus(r.getPayStatusValue()) 487 .payStatus(r.getPayStatusValue())
460 .payPrice(r.getPayPrice()) 488 .payPrice(r.getPayPrice())
...@@ -472,8 +500,11 @@ public class OrderServiceImpl implements OrderService { ...@@ -472,8 +500,11 @@ public class OrderServiceImpl implements OrderService {
472 .updatedBy(r.getUpdatedBy()) 500 .updatedBy(r.getUpdatedBy())
473 .closeTimeType(r.getCloseTimeTypeValue()) 501 .closeTimeType(r.getCloseTimeTypeValue())
474 .totalNum(r.getTotalNum()) 502 .totalNum(r.getTotalNum())
503 + .isCanceled(r.getIsCanceled())
475 .customer(getCustomerDetail(r.getCustomerId(), customerResponse.getResponsesList())) 504 .customer(getCustomerDetail(r.getCustomerId(), customerResponse.getResponsesList()))
476 - .build()).collect(Collectors.toList()); 505 + .orderNotice(orderNotice)
506 + .build();
507 + }).collect(Collectors.toList());
477 final var orderCountByStatus = OrderCountByStatusDto.builder() 508 final var orderCountByStatus = OrderCountByStatusDto.builder()
478 .allServedCount(response.getCountByStatus().getAllServedCount()) 509 .allServedCount(response.getCountByStatus().getAllServedCount())
479 .canceledCount(response.getCountByStatus().getCanceledCount()) 510 .canceledCount(response.getCountByStatus().getCanceledCount())
...@@ -485,6 +516,77 @@ public class OrderServiceImpl implements OrderService { ...@@ -485,6 +516,77 @@ public class OrderServiceImpl implements OrderService {
485 queryOrderDto.getPn(), queryOrderDto.getPz(), orderCountByStatus); 516 queryOrderDto.getPn(), queryOrderDto.getPz(), orderCountByStatus);
486 } 517 }
487 518
519 + @Override
520 + public OrderPageResult<OrderDto> getCanceledOrdersByPagination(
521 + QueryCanceledOrderByPaginationDto queryOrderDto) {
522 + final var response = orderServiceRpcClient.queryCanceledClientCustomerOrdersByPagination(queryOrderDto);
523 + final var customerIds = response.getResponsesList().stream().map(SingleClientCustomerOrderRpcResponse::getCustomerId).collect(Collectors.toList());
524 + final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(
525 + queryOrderDto.getEnterpriseId(), customerIds);
526 + final var orderIds = response.getResponsesList().stream().map(SingleClientCustomerOrderRpcResponse::getId).collect(Collectors.toList());
527 + final var orderDetails = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
528 + final var results = response.getResponsesList().stream().map(r -> {
529 + final var curOrderDetails = orderDetails.stream().filter(d ->
530 + d.getOrderId() == r.getId()).collect(Collectors.toList());
531 + List<String> orderNotice = new ArrayList<>();
532 + for (SingleClientCustomerOrderDetailRpcResponse detail: curOrderDetails) {
533 + final var avoids = detail.getMealDetailJson().getAvoidsList();
534 + final var existAvoids = r.getCustomerNoticeJson().getAvoidsList().stream().anyMatch(avoids::contains);
535 + if (existAvoids) {
536 + orderNotice.add("忌口冲突");
537 + break;
538 + }
539 + }
540 + String[] keywords = {"禁食", "禁水", "禁食水"};
541 + final var result = Arrays.stream(keywords)
542 + .filter(keyword -> r.getCustomerNoticeJson().getDoctorsList().stream().anyMatch(str -> str.contains(keyword)))
543 + .findFirst();
544 + if (result != null) {
545 + orderNotice.add("医嘱包含" + result);
546 + }
547 + return OrderDto.builder()
548 + .id(r.getId())
549 + .enterpriseId(r.getEnterpriseId())
550 + .clientId(r.getClientId())
551 + .stallId(r.getStallId())
552 + .customerId(r.getCustomerId())
553 + .openId(r.getOpenId())
554 + .address(r.getAddress())
555 + .orderCode(r.getOrderCode())
556 + .menuId(r.getMenuId())
557 + .pickupCode(r.getPickupCode())
558 + .tableCode(r.getTableCode())
559 + .roomNo(r.getSyncRoomNo().isEmpty() ? r.getRoomNo() : r.getSyncRoomNo())
560 + .adjustRoomNo(!r.getSyncRoomNo().isEmpty())
561 + .status(r.getStatus())
562 + .customerNoticeJson(CustomerNotice.builder()
563 + .avoids(r.getCustomerNoticeJson().getAvoidsList())
564 + .doctors(r.getCustomerNoticeJson().getDoctorsList()).build())
565 + .onlinePay(r.getOnlinePay())
566 + .payStatus(r.getPayStatusValue())
567 + .payPrice(r.getPayPrice())
568 + .payTime(DateUtil.formatDate(r.getPayTime()))
569 + .mealTime(DateUtil.formatDate(r.getMealTime()))
570 + .orderType(r.getOrderTypeValue())
571 + .remark(r.getRemark())
572 + .isDeleted(r.getIsDeleted())
573 + .isRead(r.getIsRead())
574 + .creationSource(r.getCreationSource().getNumber())
575 + .createdBy(r.getCreatedBy())
576 + .createdAt(DateUtil.formatDate(r.getCreatedAt()))
577 + .updateSource(r.getUpdateSource().getNumber())
578 + .updatedAt(DateUtil.formatDate(r.getUpdatedAt()))
579 + .updatedBy(r.getUpdatedBy())
580 + .closeTimeType(r.getCloseTimeTypeValue())
581 + .totalNum(r.getTotalNum())
582 + .isCanceled(r.getIsCanceled())
583 + .customer(getCustomerDetail(r.getCustomerId(), customerResponse.getResponsesList()))
584 + .orderNotice(orderNotice)
585 + .build();
586 + }).collect(Collectors.toList());
587 + return PageUtil.from(results, response.getTotal(), response.getPages(),
588 + queryOrderDto.getPn(), queryOrderDto.getPz(), OrderCountByStatusDto.builder().build());
589 + }
488 private CustomerDetailDto getCustomerDetail(Integer customerId, 590 private CustomerDetailDto getCustomerDetail(Integer customerId,
489 List<SingleClientCustomerRpcResponse> customers) { 591 List<SingleClientCustomerRpcResponse> customers) {
490 final var filterCustomers = customers.stream().filter(c -> c.getId() == customerId) 592 final var filterCustomers = customers.stream().filter(c -> c.getId() == customerId)
......
...@@ -158,4 +158,8 @@ public final class DateUtil extends DateUtils { ...@@ -158,4 +158,8 @@ public final class DateUtil extends DateUtils {
158 return Instant.ofEpochMilli(timestamp).atZone(CHINA_ZONE).toLocalDate(); 158 return Instant.ofEpochMilli(timestamp).atZone(CHINA_ZONE).toLocalDate();
159 } 159 }
160 160
161 + public static LocalDateTime toLocalDateTime(long timestamp) {
162 + return Instant.ofEpochMilli(timestamp).atZone(CHINA_ZONE).toLocalDateTime();
163 + }
164 +
161 } 165 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -139,6 +139,7 @@ message SingleClientCustomerOrderRpcResponse { ...@@ -139,6 +139,7 @@ message SingleClientCustomerOrderRpcResponse {
139 bool isConfirm = 34; 139 bool isConfirm = 34;
140 bool isAllocation = 35; 140 bool isAllocation = 35;
141 string syncRoomNo = 36; 141 string syncRoomNo = 36;
142 + bool isCanceled = 37;
142 } 143 }
143 144
144 message GetClientCustomerOrderByIdRpcRequest { 145 message GetClientCustomerOrderByIdRpcRequest {
...@@ -173,12 +174,15 @@ message GetClientCustomerOrdersByCustomerIdRpcResponse { ...@@ -173,12 +174,15 @@ message GetClientCustomerOrdersByCustomerIdRpcResponse {
173 174
174 message QueryClientCustomerOrdersByPaginationRpcRequest { 175 message QueryClientCustomerOrdersByPaginationRpcRequest {
175 string keyword = 1; 176 string keyword = 1;
176 - OrderStatusEnum status = 2; 177 + bool shouldFilterStatus = 2;
177 - int32 clientId = 3; 178 + OrderStatusEnum status = 3;
178 - int32 enterpriseId = 4; 179 + int32 clientId = 4;
179 - int32 pageNo = 5; 180 + int32 enterpriseId = 5;
180 - int32 pageSize = 6; 181 + int32 pageNo = 6;
181 - repeated int32 stallIds = 7; 182 + int32 pageSize = 7;
183 + repeated int32 stallIds = 8;
184 + bool shouldFilterIsCanceled = 9;
185 + bool isCanceled = 10;
182 } 186 }
183 187
184 message OrderCountByStatus { 188 message OrderCountByStatus {
...@@ -246,6 +250,8 @@ message QueryClientCustomerOrdersByConditionRpcRequest { ...@@ -246,6 +250,8 @@ message QueryClientCustomerOrdersByConditionRpcRequest {
246 bool isAllocation = 47; 250 bool isAllocation = 47;
247 bool shouldFilterStatues = 48; 251 bool shouldFilterStatues = 48;
248 repeated OrderStatusEnum statues = 49; 252 repeated OrderStatusEnum statues = 49;
253 + bool shouldFilterIsCanceled = 50;
254 + bool isCanceled = 51;
249 } 255 }
250 256
251 message QueryClientCustomerOrdersByConditionRpcResponse { 257 message QueryClientCustomerOrdersByConditionRpcResponse {
...@@ -375,6 +381,8 @@ message ClientCustomerOrderModification { ...@@ -375,6 +381,8 @@ message ClientCustomerOrderModification {
375 bool isAllocation = 53; 381 bool isAllocation = 53;
376 bool shouldUpdateSyncRoomNo = 54; 382 bool shouldUpdateSyncRoomNo = 54;
377 string syncRoomNo = 55; 383 string syncRoomNo = 55;
384 + bool shouldUpdateIsCanceled = 56;
385 + bool isCanceled = 57;
378 } 386 }
379 387
380 message UpdateClientCustomerOrderRpcRequest { 388 message UpdateClientCustomerOrderRpcRequest {
......
...@@ -80,6 +80,7 @@ business-config.hisCustomerQueryUrl = https://nutri.amcare.com.cn/v3/hiscustomer ...@@ -80,6 +80,7 @@ business-config.hisCustomerQueryUrl = https://nutri.amcare.com.cn/v3/hiscustomer
80 business-config.clientCustomerQueryUrl = https://nutri.amcare.com.cn/v3/clientcustomers/current/query 80 business-config.clientCustomerQueryUrl = https://nutri.amcare.com.cn/v3/clientcustomers/current/query
81 business-config.payUrl = http://10.2.5.162:21051/API/Microapp/CreateOrder?appid={0} 81 business-config.payUrl = http://10.2.5.162:21051/API/Microapp/CreateOrder?appid={0}
82 business-config.payClientId = Order 82 business-config.payClientId = Order
83 +business-config.cancelPayUrl = http://10.2.5.162:21051/frame/requestbase64
83 84
84 ##Actuator\u914D\u7F6E 85 ##Actuator\u914D\u7F6E
85 management.server.port=8088 86 management.server.port=8088
......