Showing
12 changed files
with
529 additions
and
177 deletions
| ... | @@ -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 | ... | ... |
-
Please register or login to post a comment