zhuyifan

fix(order): optimize dish replacement logic and update payment transaction ID

...@@ -60,4 +60,5 @@ public class PayController { ...@@ -60,4 +60,5 @@ public class PayController {
60 public String cancel(@Valid @RequestBody PayDTO.PayRefundRequestDto payRefundRequestDto) { 60 public String cancel(@Valid @RequestBody PayDTO.PayRefundRequestDto payRefundRequestDto) {
61 return payServiceClient.orderPayRefund(payRefundRequestDto); 61 return payServiceClient.orderPayRefund(payRefundRequestDto);
62 } 62 }
63 +
63 } 64 }
...\ No newline at end of file ...\ No newline at end of file
......
1 +package com.infoloop.tianting.model.bo;
2 +
3 +import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
4 +import lombok.Data;
5 +
6 +@Data
7 +public class OrderDetailBO {
8 +
9 + private int id;
10 +
11 + public int skuId;
12 +
13 + private String skuName;
14 +
15 + private Integer price;
16 +
17 + private int count;
18 +
19 + private String adjustSkuRemark;
20 +
21 + private ServeStatusEnum serveStatus;
22 +}
...@@ -520,6 +520,7 @@ public class OrderDbDTO { ...@@ -520,6 +520,7 @@ public class OrderDbDTO {
520 private Integer count; 520 private Integer count;
521 private String adjustSkuRemark; 521 private String adjustSkuRemark;
522 private String serveStatus; 522 private String serveStatus;
523 + private Integer price;
523 } 524 }
524 525
525 526
...@@ -730,6 +731,10 @@ public class OrderDbDTO { ...@@ -730,6 +731,10 @@ public class OrderDbDTO {
730 @Builder.Default 731 @Builder.Default
731 private Boolean shouldUpdateServeStatus = false; 732 private Boolean shouldUpdateServeStatus = false;
732 733
734 + @ApiModelProperty(value = "价格")
735 + @Builder.Default
736 + private Integer price = null;
737 +
733 @ApiModelProperty(value = "出餐状态: 默认未出餐=1; 不出餐=2; 已出餐=3") 738 @ApiModelProperty(value = "出餐状态: 默认未出餐=1; 不出餐=2; 已出餐=3")
734 @Builder.Default 739 @Builder.Default
735 private ServeStatusEnum serveStatus = ServeStatusEnum.SERVE_NOT_START; 740 private ServeStatusEnum serveStatus = ServeStatusEnum.SERVE_NOT_START;
......
...@@ -9,6 +9,8 @@ import lombok.Builder; ...@@ -9,6 +9,8 @@ import lombok.Builder;
9 import lombok.Data; 9 import lombok.Data;
10 import lombok.NoArgsConstructor; 10 import lombok.NoArgsConstructor;
11 11
12 +import java.util.List;
13 +
12 @Data 14 @Data
13 @ApiModel(description = "支付DTO") 15 @ApiModel(description = "支付DTO")
14 public class PayDTO { 16 public class PayDTO {
...@@ -31,6 +33,7 @@ public class PayDTO { ...@@ -31,6 +33,7 @@ public class PayDTO {
31 @AllArgsConstructor 33 @AllArgsConstructor
32 public static class PayRefundRequestDto { 34 public static class PayRefundRequestDto {
33 private Integer orderId; 35 private Integer orderId;
36 + private List<Integer> orderDetailIds;
34 private String hospitalCode; 37 private String hospitalCode;
35 } 38 }
36 39
......
...@@ -18,6 +18,9 @@ public class PaymentCallbackResult { ...@@ -18,6 +18,9 @@ public class PaymentCallbackResult {
18 @JacksonXmlProperty(localName = "TransSN") 18 @JacksonXmlProperty(localName = "TransSN")
19 private String transSN; 19 private String transSN;
20 20
21 + @JacksonXmlProperty(localName = "TradeReferenceNo")
22 + private String tradeReferenceNo;
23 +
21 @JacksonXmlProperty(localName = "TransType") 24 @JacksonXmlProperty(localName = "TransType")
22 private String transType; 25 private String transType;
23 26
......
...@@ -103,6 +103,8 @@ public class SettlementDTO { ...@@ -103,6 +103,8 @@ public class SettlementDTO {
103 private String remark; 103 private String remark;
104 private String avoidRemark; 104 private String avoidRemark;
105 private String onlinePay; 105 private String onlinePay;
106 + private String operationType;
107 + private String transactionId;
106 } 108 }
107 109
108 @Data 110 @Data
......
...@@ -22,6 +22,8 @@ import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderBy ...@@ -22,6 +22,8 @@ import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderBy
22 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderDetailsByIdsRpcRequest; 22 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderDetailsByIdsRpcRequest;
23 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderDetailsByOrderIdsRpcRequest; 23 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrderDetailsByOrderIdsRpcRequest;
24 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrdersByCustomerIdRpcRequest; 24 import com.infoloop.tianting.clientcustomerorderservice.GetClientCustomerOrdersByCustomerIdRpcRequest;
25 +import com.infoloop.tianting.clientcustomerorderservice.GetOrderOperationRecordsByOrderIdsRequest;
26 +import com.infoloop.tianting.clientcustomerorderservice.GetOrderOperationRecordsByOrderIdsResponse;
25 import com.infoloop.tianting.clientcustomerorderservice.MealDetail; 27 import com.infoloop.tianting.clientcustomerorderservice.MealDetail;
26 import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum; 28 import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
27 import com.infoloop.tianting.clientcustomerorderservice.OrderOperationRecordCreation; 29 import com.infoloop.tianting.clientcustomerorderservice.OrderOperationRecordCreation;
...@@ -240,8 +242,10 @@ public class OrderServiceRpcClient { ...@@ -240,8 +242,10 @@ public class OrderServiceRpcClient {
240 final var operator = operatorServiceRpcClient.getCOperatorById(operatorLoginInfo.getId()); 242 final var operator = operatorServiceRpcClient.getCOperatorById(operatorLoginInfo.getId());
241 final var idsOfNeedUpdateMenuDetails = new ArrayList<Integer>(); 243 final var idsOfNeedUpdateMenuDetails = new ArrayList<Integer>();
242 final var idsOfAddCount = new ArrayList<Integer>(); 244 final var idsOfAddCount = new ArrayList<Integer>();
245 + final var idsOfNoReject = new ArrayList<Integer>();
243 List<OrderDetailDto> originalOrderDetails = new ArrayList<>(); 246 List<OrderDetailDto> originalOrderDetails = new ArrayList<>();
244 List<OrderDetailDto> newOrderDetails; 247 List<OrderDetailDto> newOrderDetails;
248 + final var orderDetailsMap = orderDetailBatchUpdateDto.getDetails().stream().collect(Collectors.toMap(OrderDbDTO.OrderDetailUpdateDto::getId, Function.identity()));
245 final var modifications = orderDetailBatchUpdateDto.getDetails().stream().map(d -> { 249 final var modifications = orderDetailBatchUpdateDto.getDetails().stream().map(d -> {
246 var mealDetail = MealDetail.newBuilder().build(); 250 var mealDetail = MealDetail.newBuilder().build();
247 Integer menuDetailId = 0; 251 Integer menuDetailId = 0;
...@@ -280,9 +284,11 @@ public class OrderServiceRpcClient { ...@@ -280,9 +284,11 @@ public class OrderServiceRpcClient {
280 .build(); 284 .build();
281 } 285 }
282 } 286 }
283 -
284 ServeStatusEnum serveStatus = ServeStatusEnum.UNKNOWN_SERVE_STATUS; 287 ServeStatusEnum serveStatus = ServeStatusEnum.UNKNOWN_SERVE_STATUS;
285 if (d.getShouldUpdateServeStatus()) { 288 if (d.getShouldUpdateServeStatus()) {
289 + if (d.getServeStatus() == ServeStatusEnum.SERVE_REJECT) {
290 + idsOfNoReject.add(d.getId());
291 + }
286 serveStatus = d.getServeStatus(); 292 serveStatus = d.getServeStatus();
287 } 293 }
288 Integer count = 0; 294 Integer count = 0;
...@@ -319,7 +325,8 @@ public class OrderServiceRpcClient { ...@@ -319,7 +325,8 @@ public class OrderServiceRpcClient {
319 .build(); 325 .build();
320 final var totalIds = new ArrayList<>(idsOfNeedUpdateMenuDetails); 326 final var totalIds = new ArrayList<>(idsOfNeedUpdateMenuDetails);
321 totalIds.addAll(idsOfAddCount); 327 totalIds.addAll(idsOfAddCount);
322 - if (!idsOfNeedUpdateMenuDetails.isEmpty() || !idsOfAddCount.isEmpty()) { 328 + totalIds.addAll(idsOfNoReject);
329 + if (!totalIds.isEmpty()) {
323 final var orgionalResponseList = getClientCustomerOrderDetailsByIds(totalIds); 330 final var orgionalResponseList = getClientCustomerOrderDetailsByIds(totalIds);
324 originalOrderDetails = orgionalResponseList.stream().map(d -> OrderDetailDto.builder() 331 originalOrderDetails = orgionalResponseList.stream().map(d -> OrderDetailDto.builder()
325 .id(d.getId()) 332 .id(d.getId())
...@@ -357,7 +364,7 @@ public class OrderServiceRpcClient { ...@@ -357,7 +364,7 @@ public class OrderServiceRpcClient {
357 } 364 }
358 final var res = orderServiceRpcBlockingStub.batchUpdateClientCustomerOrderDetails(request); 365 final var res = orderServiceRpcBlockingStub.batchUpdateClientCustomerOrderDetails(request);
359 if (res.getIsUpdated()) { 366 if (res.getIsUpdated()) {
360 - if (!idsOfNeedUpdateMenuDetails.isEmpty() || !idsOfAddCount.isEmpty()) { 367 + if (!totalIds.isEmpty()) {
361 final var newResponseList = getClientCustomerOrderDetailsByIds(totalIds); 368 final var newResponseList = getClientCustomerOrderDetailsByIds(totalIds);
362 newOrderDetails = newResponseList.stream().map(d -> 369 newOrderDetails = newResponseList.stream().map(d ->
363 OrderDetailDto.builder() 370 OrderDetailDto.builder()
...@@ -392,15 +399,21 @@ public class OrderServiceRpcClient { ...@@ -392,15 +399,21 @@ public class OrderServiceRpcClient {
392 .updateSource(d.getUpdateSource().getNumber()) 399 .updateSource(d.getUpdateSource().getNumber())
393 .updatedAt(DateUtil.formatDate(d.getUpdatedAt())) 400 .updatedAt(DateUtil.formatDate(d.getUpdatedAt()))
394 .updatedBy(d.getUpdatedBy()) 401 .updatedBy(d.getUpdatedBy())
395 - .build()).collect(Collectors.toList()); 402 + .build()).toList();
396 // 替换菜品的操作记录 403 // 替换菜品的操作记录
397 List<SingleOperationDto> operations = new ArrayList<>(); 404 List<SingleOperationDto> operations = new ArrayList<>();
398 for (OrderDetailDto originalDetail : originalOrderDetails) { 405 for (OrderDetailDto originalDetail : originalOrderDetails) {
406 + if (!totalIds.contains(originalDetail.getId())) {
407 + continue;
408 + }
409 + final var orderDetailUpdateDto = orderDetailsMap.get(originalDetail.getId());
399 OrderOperationType orderOperationType = OrderOperationType.UNKNOWN_OPERATION_TYPE; 410 OrderOperationType orderOperationType = OrderOperationType.UNKNOWN_OPERATION_TYPE;
400 if (idsOfNeedUpdateMenuDetails.contains(originalDetail.getId())) { 411 if (idsOfNeedUpdateMenuDetails.contains(originalDetail.getId())) {
401 orderOperationType = OrderOperationType.REPLACE_DISHES; 412 orderOperationType = OrderOperationType.REPLACE_DISHES;
402 } else if (idsOfAddCount.contains(originalDetail.getId())) { 413 } else if (idsOfAddCount.contains(originalDetail.getId())) {
403 orderOperationType = OrderOperationType.ADD_DISHES; 414 orderOperationType = OrderOperationType.ADD_DISHES;
415 + } else if (idsOfNoReject.contains(originalDetail.getId())) {
416 + orderOperationType = OrderOperationType.NOT_SERVE;
404 } 417 }
405 String originalDetailStr; 418 String originalDetailStr;
406 String newDetailStr = ""; 419 String newDetailStr = "";
...@@ -413,6 +426,7 @@ public class OrderServiceRpcClient { ...@@ -413,6 +426,7 @@ public class OrderServiceRpcClient {
413 .count(newDetail.get().getCount()) 426 .count(newDetail.get().getCount())
414 .adjustSkuRemark(newDetail.get().getAdjustSkuRemark()) 427 .adjustSkuRemark(newDetail.get().getAdjustSkuRemark())
415 .serveStatus(newDetail.get().getServeStatus().name()) 428 .serveStatus(newDetail.get().getServeStatus().name())
429 + .price(orderDetailUpdateDto.getPrice() == null ? newDetail.get().getPrice() : orderDetailUpdateDto.getPrice())
416 .build(); 430 .build();
417 newDetailStr = JsonUtil.writeAsJson(List.of(newOrderDetailOperation)); 431 newDetailStr = JsonUtil.writeAsJson(List.of(newOrderDetailOperation));
418 } 432 }
...@@ -423,6 +437,7 @@ public class OrderServiceRpcClient { ...@@ -423,6 +437,7 @@ public class OrderServiceRpcClient {
423 .count(originalDetail.getCount()) 437 .count(originalDetail.getCount())
424 .adjustSkuRemark(originalDetail.getAdjustSkuRemark()) 438 .adjustSkuRemark(originalDetail.getAdjustSkuRemark())
425 .serveStatus(originalDetail.getServeStatus().name()) 439 .serveStatus(originalDetail.getServeStatus().name())
440 + .price(originalDetail.getPrice())
426 .build(); 441 .build();
427 originalDetailStr = JsonUtil.writeAsJson(List.of(originalOrderDetailOperation)); 442 originalDetailStr = JsonUtil.writeAsJson(List.of(originalOrderDetailOperation));
428 final var operation = SingleOperationDto.builder() 443 final var operation = SingleOperationDto.builder()
...@@ -471,7 +486,6 @@ public class OrderServiceRpcClient { ...@@ -471,7 +486,6 @@ public class OrderServiceRpcClient {
471 .setCreationSource(batchOperationDto.getCreationSource()) 486 .setCreationSource(batchOperationDto.getCreationSource())
472 .build(); 487 .build();
473 return orderServiceRpcBlockingStub.batchCreateOrderOperationRecords(request); 488 return orderServiceRpcBlockingStub.batchCreateOrderOperationRecords(request);
474 -
475 } 489 }
476 490
477 public QueryClientCustomerOrdersByPaginationRpcResponse queryClientCustomerOrdersByPagination(QueryOrderByPaginationDto queryOrderDto) { 491 public QueryClientCustomerOrdersByPaginationRpcResponse queryClientCustomerOrdersByPagination(QueryOrderByPaginationDto queryOrderDto) {
...@@ -489,6 +503,14 @@ public class OrderServiceRpcClient { ...@@ -489,6 +503,14 @@ public class OrderServiceRpcClient {
489 return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request); 503 return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request);
490 } 504 }
491 505
506 + public GetOrderOperationRecordsByOrderIdsResponse getOrderOperationRecordsByOrderIds(int enterpriseId, List<Integer> orderIds) {
507 + final var request = GetOrderOperationRecordsByOrderIdsRequest.newBuilder()
508 + .setEnterpriseId(enterpriseId)
509 + .addAllOrderIds(orderIds)
510 + .build();
511 + return orderServiceRpcBlockingStub.getOrderOperationRecordsByOrderIds(request);
512 + }
513 +
492 public QueryClientCustomerOrdersByConditionRpcResponse queryClientCustomerOrdersByCondition(OrderDbDTO.QueryOrderDto queryOrderDto) { 514 public QueryClientCustomerOrdersByConditionRpcResponse queryClientCustomerOrdersByCondition(OrderDbDTO.QueryOrderDto queryOrderDto) {
493 final var request = QueryClientCustomerOrdersByConditionRpcRequest.newBuilder() 515 final var request = QueryClientCustomerOrdersByConditionRpcRequest.newBuilder()
494 .setShouldFilterStatus(true) 516 .setShouldFilterStatus(true)
......
...@@ -38,6 +38,8 @@ import lombok.RequiredArgsConstructor; ...@@ -38,6 +38,8 @@ import lombok.RequiredArgsConstructor;
38 import lombok.extern.slf4j.Slf4j; 38 import lombok.extern.slf4j.Slf4j;
39 import org.apache.commons.codec.binary.Base64; 39 import org.apache.commons.codec.binary.Base64;
40 import org.apache.commons.codec.digest.DigestUtils; 40 import org.apache.commons.codec.digest.DigestUtils;
41 +import org.apache.commons.collections4.CollectionUtils;
42 +import org.apache.commons.lang3.StringUtils;
41 import org.springframework.beans.factory.annotation.Autowired; 43 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.http.HttpEntity; 44 import org.springframework.http.HttpEntity;
43 import org.springframework.http.HttpHeaders; 45 import org.springframework.http.HttpHeaders;
...@@ -200,8 +202,8 @@ public class PayServiceClient { ...@@ -200,8 +202,8 @@ public class PayServiceClient {
200 .setPayStatus(PayStatusEnum.SUCCEED) 202 .setPayStatus(PayStatusEnum.SUCCEED)
201 .setShouldUpdateStatus(true) 203 .setShouldUpdateStatus(true)
202 .setStatus(OrderStatusEnum.PREPARING) 204 .setStatus(OrderStatusEnum.PREPARING)
203 - .setShouldUpdateTransactionId(true) 205 + .setShouldUpdateTransactionId(StringUtils.isNotEmpty(paymentCallbackResult.getTradeReferenceNo()))
204 - .setTransactionId(paymentCallbackResult.getTransSN()) 206 + .setTransactionId(StringUtils.isNotEmpty(paymentCallbackResult.getTradeReferenceNo()) ? paymentCallbackResult.getTradeReferenceNo() : "")
205 .build(); 207 .build();
206 final var updateResponse = 208 final var updateResponse =
207 orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build); 209 orderServiceRpcClient.updateClientCustomerOrderPaymentResult(orderById, build);
...@@ -346,6 +348,11 @@ public class PayServiceClient { ...@@ -346,6 +348,11 @@ public class PayServiceClient {
346 log.info("Order {} pay is beyond cancel time.", orderId); 348 log.info("Order {} pay is beyond cancel time.", orderId);
347 throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.ORDER_PAY_REFUND_FAILED); 349 throw ClientEndExceptions.BusinessException.build(ErrorCodeEnum.ORDER_PAY_REFUND_FAILED);
348 } 350 }
351 + BigDecimal detailPrice = BigDecimal.ZERO;
352 + if (CollectionUtils.isNotEmpty(payRefundRequestDto.getOrderDetailIds())) {
353 + final var orderDetails = orderServiceRpcClient.getClientCustomerOrderDetailsByIds(payRefundRequestDto.getOrderDetailIds());
354 + detailPrice = orderDetails.stream().filter(e -> e.getPrice() > 0).map(e -> new BigDecimal(e.getPrice()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add);
355 + }
349 356
350 String appId = businessConfig.getPayClientId(); 357 String appId = businessConfig.getPayClientId();
351 358
...@@ -355,9 +362,9 @@ public class PayServiceClient { ...@@ -355,9 +362,9 @@ public class PayServiceClient {
355 .minusHours(8) 362 .minusHours(8)
356 .format(DateUtil.YMDHMS); 363 .format(DateUtil.YMDHMS);
357 364
358 - BigDecimal price = 365 + BigDecimal price = detailPrice.compareTo(BigDecimal.ZERO) == 0 ?
359 - new BigDecimal(orderById.getPayPrice()) 366 + new BigDecimal(orderById.getPayPrice()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).negate()
360 - .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).negate(); 367 + : detailPrice.negate();
361 368
362 String payContentStr = 369 String payContentStr =
363 orderById.getId() 370 orderById.getId()
......
...@@ -2,8 +2,11 @@ package com.infoloop.tianting.service.impl; ...@@ -2,8 +2,11 @@ package com.infoloop.tianting.service.impl;
2 2
3 import cn.hutool.core.collection.CollectionUtil; 3 import cn.hutool.core.collection.CollectionUtil;
4 import cn.hutool.core.date.LocalDateTimeUtil; 4 import cn.hutool.core.date.LocalDateTimeUtil;
5 +import com.fasterxml.jackson.core.type.TypeReference;
5 import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse; 6 import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse;
6 import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum; 7 import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
8 +import com.infoloop.tianting.clientcustomerorderservice.OrderOperationRecord;
9 +import com.infoloop.tianting.clientcustomerorderservice.OrderOperationType;
7 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 10 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
8 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; 11 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
9 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; 12 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
...@@ -17,6 +20,7 @@ import com.infoloop.tianting.exception.ClientEndExceptions.BusinessException; ...@@ -17,6 +20,7 @@ import com.infoloop.tianting.exception.ClientEndExceptions.BusinessException;
17 import com.infoloop.tianting.exception.ErrorCodeEnum; 20 import com.infoloop.tianting.exception.ErrorCodeEnum;
18 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse; 21 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse;
19 import com.infoloop.tianting.menuservice.SingleMenuRpcResponse; 22 import com.infoloop.tianting.menuservice.SingleMenuRpcResponse;
23 +import com.infoloop.tianting.model.bo.OrderDetailBO;
20 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 24 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
21 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderDto; 25 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderDto;
22 import com.infoloop.tianting.model.dto.SettlementDTO; 26 import com.infoloop.tianting.model.dto.SettlementDTO;
...@@ -39,8 +43,10 @@ import com.infoloop.tianting.service.client.OrderServiceRpcClient; ...@@ -39,8 +43,10 @@ import com.infoloop.tianting.service.client.OrderServiceRpcClient;
39 import com.infoloop.tianting.service.client.SkuServiceRpcClient; 43 import com.infoloop.tianting.service.client.SkuServiceRpcClient;
40 import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse; 44 import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse;
41 import com.infoloop.tianting.utils.DateUtil; 45 import com.infoloop.tianting.utils.DateUtil;
46 +import com.infoloop.tianting.utils.JsonUtil;
42 import lombok.RequiredArgsConstructor; 47 import lombok.RequiredArgsConstructor;
43 import lombok.extern.slf4j.Slf4j; 48 import lombok.extern.slf4j.Slf4j;
49 +import org.apache.commons.lang3.StringUtils;
44 import org.apache.poi.ss.usermodel.BorderStyle; 50 import org.apache.poi.ss.usermodel.BorderStyle;
45 import org.apache.poi.ss.usermodel.Cell; 51 import org.apache.poi.ss.usermodel.Cell;
46 import org.apache.poi.ss.usermodel.CellStyle; 52 import org.apache.poi.ss.usermodel.CellStyle;
...@@ -71,7 +77,9 @@ import java.util.HashMap; ...@@ -71,7 +77,9 @@ import java.util.HashMap;
71 import java.util.List; 77 import java.util.List;
72 import java.util.Map; 78 import java.util.Map;
73 import java.util.Objects; 79 import java.util.Objects;
80 +import java.util.function.Function;
74 import java.util.stream.Collectors; 81 import java.util.stream.Collectors;
82 +import java.util.stream.Stream;
75 83
76 @Slf4j 84 @Slf4j
77 @Service 85 @Service
...@@ -295,6 +303,408 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -295,6 +303,408 @@ public class SettlementServiceImpl implements SettlementService {
295 return dateList; 303 return dateList;
296 } 304 }
297 305
306 + /**
307 + * 按订单维度生成Excel
308 + */
309 + private static ByteArrayOutputStream writeToExcelByOrder(SettlementDTO.SettlementDataByOrderDto settlementDataDto)
310 + throws IOException {
311 + Workbook workbook = new XSSFWorkbook();
312 + Sheet sheet = workbook.createSheet("客人结算");
313 +
314 + // 创建表头样式(黑色边框)
315 + CellStyle headerStyle = workbook.createCellStyle();
316 + headerStyle.setBorderTop(BorderStyle.THIN);
317 + headerStyle.setBorderBottom(BorderStyle.THIN);
318 + headerStyle.setBorderLeft(BorderStyle.THIN);
319 + headerStyle.setBorderRight(BorderStyle.THIN);
320 + headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
321 + headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
322 + headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
323 + headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
324 +
325 + // 创建数据行样式(浅灰色边框)
326 + CellStyle dataStyle = workbook.createCellStyle();
327 + dataStyle.setBorderTop(BorderStyle.THIN);
328 + dataStyle.setBorderBottom(BorderStyle.THIN);
329 + dataStyle.setBorderLeft(BorderStyle.THIN);
330 + dataStyle.setBorderRight(BorderStyle.THIN);
331 + dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
332 + dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
333 + dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
334 + dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
335 +
336 + int rowNum = 0;
337 +
338 + // 创建表头
339 + Row titleRow = sheet.createRow(rowNum++);
340 + int columnNum = 0;
341 +
342 + Cell cell0 = titleRow.createCell(columnNum++);
343 + cell0.setCellValue("用餐时间");
344 + cell0.setCellStyle(headerStyle);
345 +
346 + Cell cell1 = titleRow.createCell(columnNum++);
347 + cell1.setCellValue("订单号");
348 + cell1.setCellStyle(headerStyle);
349 +
350 + Cell cell2 = titleRow.createCell(columnNum++);
351 + cell2.setCellValue("餐别");
352 + cell2.setCellStyle(headerStyle);
353 +
354 + Cell cell3 = titleRow.createCell(columnNum++);
355 + cell3.setCellValue("房间号");
356 + cell3.setCellStyle(headerStyle);
357 +
358 + Cell cell4 = titleRow.createCell(columnNum++);
359 + cell4.setCellValue("客户姓名");
360 + cell4.setCellStyle(headerStyle);
361 +
362 + Cell cell5 = titleRow.createCell(columnNum++);
363 + cell5.setCellValue("客户腕带号");
364 + cell5.setCellStyle(headerStyle);
365 +
366 + Cell cell6 = titleRow.createCell(columnNum++);
367 + cell6.setCellValue("忌口信息");
368 + cell6.setCellStyle(headerStyle);
369 +
370 + Cell cell7 = titleRow.createCell(columnNum++);
371 + cell7.setCellValue("医嘱信息");
372 + cell7.setCellStyle(headerStyle);
373 +
374 + Cell cell8 = titleRow.createCell(columnNum++);
375 + cell8.setCellValue("餐单名称");
376 + cell8.setCellStyle(headerStyle);
377 +
378 + Cell cell9 = titleRow.createCell(columnNum++);
379 + cell9.setCellValue("菜品名称");
380 + cell9.setCellStyle(headerStyle);
381 +
382 + Cell cell10 = titleRow.createCell(columnNum++);
383 + cell10.setCellValue("菜品份数");
384 + cell10.setCellStyle(headerStyle);
385 +
386 + Cell cell11 = titleRow.createCell(columnNum++);
387 + cell11.setCellValue("菜品单价");
388 + cell11.setCellStyle(headerStyle);
389 +
390 + Cell cell12 = titleRow.createCell(columnNum++);
391 + cell12.setCellValue("菜品金额");
392 + cell12.setCellStyle(headerStyle);
393 +
394 + Cell cell13 = titleRow.createCell(columnNum++);
395 + cell13.setCellValue("菜品状态");
396 + cell13.setCellStyle(headerStyle);
397 +
398 + Cell cell14 = titleRow.createCell(columnNum++);
399 + cell14.setCellValue("交易码");
400 + cell14.setCellStyle(headerStyle);
401 +
402 + Cell cell15 = titleRow.createCell(columnNum++);
403 + cell15.setCellValue("备注");
404 + cell15.setCellStyle(headerStyle);
405 +
406 + Cell cell16 = titleRow.createCell(columnNum++);
407 + cell16.setCellValue("支付方式");
408 + cell16.setCellStyle(headerStyle);
409 +
410 + // 填充数据
411 + final var classifyOrders = settlementDataDto.getClassifyOrders();
412 + if (classifyOrders != null) {
413 + for (SettlementDTO.SettlementOrderDetail orderDetail : classifyOrders) {
414 + Row dataRow = sheet.createRow(rowNum++);
415 + columnNum = 0;
416 +
417 + Cell dataCell0 = dataRow.createCell(columnNum++);
418 + dataCell0.setCellValue(orderDetail.getMealTime() != null ? orderDetail.getMealTime() : "");
419 + dataCell0.setCellStyle(dataStyle);
420 +
421 + Cell dataCell1 = dataRow.createCell(columnNum++);
422 + dataCell1.setCellValue(orderDetail.getCode() != null ? orderDetail.getCode() : "");
423 + dataCell1.setCellStyle(dataStyle);
424 +
425 + Cell dataCell2 = dataRow.createCell(columnNum++);
426 + dataCell2.setCellValue(orderDetail.getMealName() != null ? orderDetail.getMealName() : "");
427 + dataCell2.setCellStyle(dataStyle);
428 +
429 + Cell dataCell3 = dataRow.createCell(columnNum++);
430 + dataCell3.setCellValue(orderDetail.getRoomNo() != null ? orderDetail.getRoomNo() : "");
431 + dataCell3.setCellStyle(dataStyle);
432 +
433 + Cell dataCell4 = dataRow.createCell(columnNum++);
434 + dataCell4.setCellValue(orderDetail.getCustomerName() != null ? orderDetail.getCustomerName() : "");
435 + dataCell4.setCellStyle(dataStyle);
436 +
437 + Cell dataCell5 = dataRow.createCell(columnNum++);
438 + dataCell5.setCellValue(orderDetail.getHISCustomerNo() != null ? orderDetail.getHISCustomerNo() : "");
439 + dataCell5.setCellStyle(dataStyle);
440 +
441 + // 忌口列表转字符串
442 + String avoidsStr = orderDetail.getAvoids() != null ? String.join(", ", orderDetail.getAvoids()) : "";
443 + Cell dataCell6 = dataRow.createCell(columnNum++);
444 + dataCell6.setCellValue(avoidsStr);
445 + dataCell6.setCellStyle(dataStyle);
446 +
447 + // 医嘱列表转字符串
448 + String doctorsStr = orderDetail.getDoctors() != null ? String.join(", ", orderDetail.getDoctors()) : "";
449 + Cell dataCell7 = dataRow.createCell(columnNum++);
450 + dataCell7.setCellValue(doctorsStr);
451 + dataCell7.setCellStyle(dataStyle);
452 +
453 + Cell dataCell8 = dataRow.createCell(columnNum++);
454 + dataCell8.setCellValue(orderDetail.getMenuName() != null ? orderDetail.getMenuName() : "");
455 + dataCell8.setCellStyle(dataStyle);
456 +
457 + Cell dataCell9 = dataRow.createCell(columnNum++);
458 + dataCell9.setCellValue(orderDetail.getSkuName() != null ? orderDetail.getSkuName() : "");
459 + dataCell9.setCellStyle(dataStyle);
460 +
461 + Cell dataCell10 = dataRow.createCell(columnNum++);
462 + dataCell10.setCellValue(orderDetail.getCount() != null ? orderDetail.getCount() : 0);
463 + dataCell10.setCellStyle(dataStyle);
464 +
465 + // 价格
466 + Cell dataCell11 = dataRow.createCell(columnNum++);
467 + if (orderDetail.getPrice() != null) {
468 + dataCell11.setCellValue(orderDetail.getPrice().doubleValue());
469 + } else {
470 + dataCell11.setCellValue(0.0);
471 + }
472 + dataCell11.setCellStyle(dataStyle);
473 +
474 + // 总价
475 + Cell dataCell12 = dataRow.createCell(columnNum++);
476 + if (orderDetail.getTotalPrice() != null) {
477 + dataCell12.setCellValue(orderDetail.getTotalPrice().doubleValue());
478 + } else {
479 + dataCell12.setCellValue(0.0);
480 + }
481 + dataCell12.setCellStyle(dataStyle);
482 +
483 + // 状态
484 + Cell dataCell13 = dataRow.createCell(columnNum++);
485 + dataCell13.setCellValue(orderDetail.getOperationType());
486 + dataCell13.setCellStyle(dataStyle);
487 +
488 + Cell dataCell14 = dataRow.createCell(columnNum++);
489 + dataCell14.setCellValue(orderDetail.getTransactionId() != null ? orderDetail.getTransactionId() : "");
490 + dataCell14.setCellStyle(dataStyle);
491 +
492 + // 合并备注和忌口备注,用分号分割,备注在前
493 + String remark = orderDetail.getRemark() != null ? orderDetail.getRemark() : "";
494 + String avoidRemark = orderDetail.getAvoidRemark() != null ? orderDetail.getAvoidRemark() : "";
495 + String combinedRemark = "";
496 + if (!remark.isEmpty() && !avoidRemark.isEmpty()) {
497 + combinedRemark = remark + ";" + avoidRemark;
498 + } else if (!remark.isEmpty()) {
499 + combinedRemark = remark;
500 + } else if (!avoidRemark.isEmpty()) {
501 + combinedRemark = avoidRemark;
502 + }
503 + Cell dataCell15 = dataRow.createCell(columnNum++);
504 + dataCell15.setCellValue(combinedRemark);
505 + dataCell15.setCellStyle(dataStyle);
506 +
507 + Cell dataCell16 = dataRow.createCell(columnNum++);
508 + dataCell16.setCellValue(orderDetail.getOnlinePay() != null ? orderDetail.getOnlinePay() : "");
509 + dataCell16.setCellStyle(dataStyle);
510 + }
511 + }
512 +
513 + // 自动调整列宽
514 + for (int i = 0; i < 17; i++) {
515 + sheet.autoSizeColumn(i);
516 + }
517 +
518 + // 将工作簿内容写入字节数组输出流
519 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
520 + workbook.write(outputStream);
521 + workbook.close();
522 +
523 + return outputStream;
524 + }
525 +
526 + /**
527 + * 生成分餐表Excel
528 + */
529 + private static ByteArrayOutputStream writeToExcelBySeparateMeal(SeparateMealDataDto separateMealDataDto)
530 + throws IOException {
531 + Workbook workbook = new XSSFWorkbook();
532 + Sheet sheet = workbook.createSheet("分餐表");
533 +
534 + // 创建标题样式(合并单元格标题)
535 + CellStyle titleStyle = workbook.createCellStyle();
536 + titleStyle.setAlignment(HorizontalAlignment.CENTER);
537 + titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
538 + titleStyle.setBorderTop(BorderStyle.THIN);
539 + titleStyle.setBorderBottom(BorderStyle.THIN);
540 + titleStyle.setBorderLeft(BorderStyle.THIN);
541 + titleStyle.setBorderRight(BorderStyle.THIN);
542 + titleStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
543 + titleStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
544 + titleStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
545 + titleStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
546 + Font titleFont = workbook.createFont();
547 + titleFont.setBold(true);
548 + titleFont.setFontHeightInPoints((short) 16);
549 + titleStyle.setFont(titleFont);
550 +
551 + // 创建表头样式(黑色边框)
552 + CellStyle headerStyle = workbook.createCellStyle();
553 + headerStyle.setBorderTop(BorderStyle.THIN);
554 + headerStyle.setBorderBottom(BorderStyle.THIN);
555 + headerStyle.setBorderLeft(BorderStyle.THIN);
556 + headerStyle.setBorderRight(BorderStyle.THIN);
557 + headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
558 + headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
559 + headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
560 + headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
561 +
562 + // 创建数据行样式(浅灰色边框)
563 + CellStyle dataStyle = workbook.createCellStyle();
564 + dataStyle.setBorderTop(BorderStyle.THIN);
565 + dataStyle.setBorderBottom(BorderStyle.THIN);
566 + dataStyle.setBorderLeft(BorderStyle.THIN);
567 + dataStyle.setBorderRight(BorderStyle.THIN);
568 + dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
569 + dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
570 + dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
571 + dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
572 +
573 + int rowNum = 0;
574 +
575 + // 第一行:创建合并单元格标题
576 + Row mainTitleRow = sheet.createRow(rowNum++);
577 + Cell mainTitleCell = mainTitleRow.createCell(0);
578 + mainTitleCell.setCellValue("住院客户分餐表");
579 + mainTitleCell.setCellStyle(titleStyle);
580 +
581 + // 合并第一行的8列
582 + CellRangeAddress titleRegion = new CellRangeAddress(0, 0, 0, 8);
583 + sheet.addMergedRegion(titleRegion);
584 +
585 + // 为合并区域设置边框
586 + RegionUtil.setBorderTop(BorderStyle.THIN, titleRegion, sheet);
587 + RegionUtil.setBorderBottom(BorderStyle.THIN, titleRegion, sheet);
588 + RegionUtil.setBorderLeft(BorderStyle.THIN, titleRegion, sheet);
589 + RegionUtil.setBorderRight(BorderStyle.THIN, titleRegion, sheet);
590 + RegionUtil.setTopBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
591 + RegionUtil.setBottomBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
592 + RegionUtil.setLeftBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
593 + RegionUtil.setRightBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
594 +
595 + // 第二行:创建表头
596 + Row titleRow = sheet.createRow(rowNum++);
597 + int columnNum = 0;
598 +
599 + Cell cell0 = titleRow.createCell(columnNum++);
600 + cell0.setCellValue("餐别");
601 + cell0.setCellStyle(headerStyle);
602 +
603 + Cell cell1 = titleRow.createCell(columnNum++);
604 + cell1.setCellValue("房间号");
605 + cell1.setCellStyle(headerStyle);
606 +
607 + Cell cell2 = titleRow.createCell(columnNum++);
608 + cell2.setCellValue("客户姓名");
609 + cell2.setCellStyle(headerStyle);
610 +
611 + Cell cell3 = titleRow.createCell(columnNum++);
612 + cell3.setCellValue("医嘱信息");
613 + cell3.setCellStyle(headerStyle);
614 +
615 + Cell cell4 = titleRow.createCell(columnNum++);
616 + cell4.setCellValue("餐单名称");
617 + cell4.setCellStyle(headerStyle);
618 +
619 + Cell cell5 = titleRow.createCell(columnNum++);
620 + cell5.setCellValue("菜品名称");
621 + cell5.setCellStyle(headerStyle);
622 +
623 + Cell cell6 = titleRow.createCell(columnNum++);
624 + cell6.setCellValue("菜品数量");
625 + cell6.setCellStyle(headerStyle);
626 +
627 + Cell cell7 = titleRow.createCell(columnNum++);
628 + cell7.setCellValue("忌口信息");
629 + cell7.setCellStyle(headerStyle);
630 +
631 + Cell cell8 = titleRow.createCell(columnNum++);
632 + cell8.setCellValue("备注");
633 + cell8.setCellStyle(headerStyle);
634 +
635 + // 填充数据
636 + final var mealDetails = separateMealDataDto.getMealDetails();
637 + if (mealDetails != null) {
638 + for (SeparateMealDetail mealDetail : mealDetails) {
639 + Row dataRow = sheet.createRow(rowNum++);
640 + columnNum = 0;
641 +
642 + Cell dataCell0 = dataRow.createCell(columnNum++);
643 + dataCell0.setCellValue(mealDetail.getMealName() != null ? mealDetail.getMealName() : "");
644 + dataCell0.setCellStyle(dataStyle);
645 +
646 + Cell dataCell1 = dataRow.createCell(columnNum++);
647 + dataCell1.setCellValue(mealDetail.getRoomNo() != null ? mealDetail.getRoomNo() : "");
648 + dataCell1.setCellStyle(dataStyle);
649 +
650 + Cell dataCell2 = dataRow.createCell(columnNum++);
651 + dataCell2.setCellValue(mealDetail.getCustomerName() != null ? mealDetail.getCustomerName() : "");
652 + dataCell2.setCellStyle(dataStyle);
653 +
654 + Cell dataCell3 = dataRow.createCell(columnNum++);
655 + dataCell3.setCellValue(mealDetail.getDoctors() != null ? mealDetail.getDoctors() : "");
656 + dataCell3.setCellStyle(dataStyle);
657 +
658 + Cell dataCell4 = dataRow.createCell(columnNum++);
659 + dataCell4.setCellValue(mealDetail.getMenuName() != null ? mealDetail.getMenuName() : "");
660 + dataCell4.setCellStyle(dataStyle);
661 +
662 + Cell dataCell5 = dataRow.createCell(columnNum++);
663 + dataCell5.setCellValue(mealDetail.getSkuName() != null ? mealDetail.getSkuName() : "");
664 + dataCell5.setCellStyle(dataStyle);
665 +
666 + Cell dataCell6 = dataRow.createCell(columnNum++);
667 + dataCell6.setCellValue(mealDetail.getCount() != null ? mealDetail.getCount() : 0);
668 + dataCell6.setCellStyle(dataStyle);
669 +
670 + Cell dataCell7 = dataRow.createCell(columnNum++);
671 + dataCell7.setCellValue(mealDetail.getAvoids() != null ? mealDetail.getAvoids() : "");
672 + dataCell7.setCellStyle(dataStyle);
673 +
674 + Cell dataCell8 = dataRow.createCell(columnNum++);
675 + dataCell8.setCellValue(mealDetail.getRemark() != null ? mealDetail.getRemark() : "");
676 + dataCell8.setCellStyle(dataStyle);
677 + }
678 + }
679 +
680 + // 自动调整列宽
681 + for (int i = 0; i < 9; i++) {
682 + sheet.autoSizeColumn(i);
683 + }
684 +
685 + // 将工作簿内容写入字节数组输出流
686 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
687 + workbook.write(outputStream);
688 + workbook.close();
689 +
690 + return outputStream;
691 + }
692 +
693 + /**
694 + * 创建空的分餐表Excel(无数据)
695 + */
696 + private static ByteArrayOutputStream createEmptyExcelBySeparateMeal() {
697 + try {
698 + SeparateMealDataDto emptyData = SeparateMealDataDto.builder()
699 + .mealDetails(new ArrayList<>())
700 + .build();
701 + return writeToExcelBySeparateMeal(emptyData);
702 + } catch (IOException e) {
703 + log.error("创建空分餐表Excel失败", e);
704 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
705 + }
706 + }
707 +
298 @Override 708 @Override
299 public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) { 709 public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) {
300 if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) { 710 if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) {
...@@ -369,13 +779,11 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -369,13 +779,11 @@ public class SettlementServiceImpl implements SettlementService {
369 .collect(Collectors.toList()); 779 .collect(Collectors.toList());
370 780
371 if (orderIds.isEmpty()) { 781 if (orderIds.isEmpty()) {
372 - log.warn("筛选后无有效订单,enterpriseId: {}", enterpriseId);
373 return createEmptyExcelByOrder(); 782 return createEmptyExcelByOrder();
374 } 783 }
375 784
376 // 构建订单映射 785 // 构建订单映射
377 - final var orderMap = orderList.stream() 786 + final var orderMap = orderList.stream().filter(o -> o.getId() != 0)
378 - .filter(o -> o.getId() != 0)
379 .collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1)); 787 .collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1));
380 788
381 // 查询订单详情 789 // 查询订单详情
...@@ -384,86 +792,60 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -384,86 +792,60 @@ public class SettlementServiceImpl implements SettlementService {
384 log.warn("未查询到订单详情数据,orderIds: {}", orderIds); 792 log.warn("未查询到订单详情数据,orderIds: {}", orderIds);
385 return createEmptyExcelByOrder(); 793 return createEmptyExcelByOrder();
386 } 794 }
387 -
388 // 订单详情按订单ID分组 795 // 订单详情按订单ID分组
389 - final var orderDetailGroupByOrderId = orderDetailList.stream() 796 + final var orderDetailGroupByOrderId = orderDetailList.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
390 - .filter(Objects::nonNull)
391 - .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
392 - .collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
393 797
394 - // 获取SKU数据 798 + final var orderOperationRecordsByOrderIds = orderServiceRpcClient.getOrderOperationRecordsByOrderIds(LoginContextHolder.getEnterpriseId(), orderIds).getResponsesList();
395 - List<Integer> skuIds = orderDetailList.stream() 799 +
800 + // 订单操作记录按订单ID分组
801 + final var orderOperationRecordByOrderId = orderOperationRecordsByOrderIds.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(OrderOperationRecord::getOrderId));
802 +
803 + List<Integer> skuIds = Stream.concat(
804 + orderOperationRecordsByOrderIds.stream()
805 + .filter(e -> StringUtils.isNoneBlank(e.getOriginalOrderDetailJson()))
806 + .flatMap(e -> JsonUtil.readJsonAs(e.getOriginalOrderDetailJson(), new TypeReference<List<OrderDetailBO>>() {}).stream())
807 + .map(OrderDetailBO::getSkuId),
808 + orderDetailList.stream()
396 .filter(Objects::nonNull) 809 .filter(Objects::nonNull)
397 - .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
398 .map(SingleClientCustomerOrderDetailRpcResponse::getSkuId) 810 .map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
811 + )
399 .distinct() 812 .distinct()
400 .collect(Collectors.toList()); 813 .collect(Collectors.toList());
401 814
402 final var skuResponse = skuServiceRpcClient.getDishSkusByIds(skuIds); 815 final var skuResponse = skuServiceRpcClient.getDishSkusByIds(skuIds);
403 - final List<SingleDishSkuByIdsRpcResponse> skus = skuResponse != null ? skuResponse.getResponseList() : new ArrayList<>(); 816 + final List<SingleDishSkuByIdsRpcResponse> skus = skuResponse.getResponseList();
404 - final var skuMap = skus.stream() 817 + final var skuMap = skus.stream().collect(Collectors.toMap(SingleDishSkuByIdsRpcResponse::getId, s -> s, (s1, s2) -> s1));
405 - .filter(Objects::nonNull)
406 - .filter(s -> s.getId() != 0)
407 - .collect(Collectors.toMap(SingleDishSkuByIdsRpcResponse::getId, s -> s, (s1, s2) -> s1));
408 818
409 // 获取餐别数据 819 // 获取餐别数据
410 final var mealResponse = mealServiceRpcClient.getAllMeals(enterpriseId); 820 final var mealResponse = mealServiceRpcClient.getAllMeals(enterpriseId);
411 final List<SingleMealRpcResponse> meals = mealResponse != null ? mealResponse.getResponsesList() : new ArrayList<>(); 821 final List<SingleMealRpcResponse> meals = mealResponse != null ? mealResponse.getResponsesList() : new ArrayList<>();
412 - final var mealMap = meals.stream() 822 + final var mealMap = meals.stream().collect(Collectors.toMap(SingleMealRpcResponse::getId, m -> m, (m1, m2) -> m1));
413 - .filter(Objects::nonNull)
414 - .filter(m -> m.getId() != 0)
415 - .collect(Collectors.toMap(SingleMealRpcResponse::getId, m -> m, (m1, m2) -> m1));
416 823
417 // 获取菜单数据 824 // 获取菜单数据
418 - List<Integer> menuIds = orderList.stream() 825 + List<Integer> menuIds = orderList.stream().map(SingleClientCustomerOrderRpcResponse::getMenuId).distinct().collect(Collectors.toList());
419 - .filter(Objects::nonNull)
420 - .map(SingleClientCustomerOrderRpcResponse::getMenuId)
421 - .filter(id -> id != 0)
422 - .distinct()
423 - .collect(Collectors.toList());
424 -
425 final var menuResponse = menuServiceRpcClient.getMenusByIds(enterpriseId, menuIds); 826 final var menuResponse = menuServiceRpcClient.getMenusByIds(enterpriseId, menuIds);
426 final List<SingleMenuRpcResponse> menuList = menuResponse != null ? menuResponse.getResponsesList() : new ArrayList<>(); 827 final List<SingleMenuRpcResponse> menuList = menuResponse != null ? menuResponse.getResponsesList() : new ArrayList<>();
427 - final var menuMap = menuList.stream() 828 + final var menuMap = menuList.stream().collect(Collectors.toMap(SingleMenuRpcResponse::getId, m -> m, (m1, m2) -> m1));
428 - .filter(Objects::nonNull)
429 - .filter(m -> m.getId() != 0)
430 - .collect(Collectors.toMap(SingleMenuRpcResponse::getId, m -> m, (m1, m2) -> m1));
431 829
432 // 获取菜单详情数据 830 // 获取菜单详情数据
433 final var menuDetailResponse = menuServiceRpcClient.queryMenuDetailsByMenuIds(enterpriseId, menuIds); 831 final var menuDetailResponse = menuServiceRpcClient.queryMenuDetailsByMenuIds(enterpriseId, menuIds);
434 - final List<SingleMenuDetailRpcResponse> menuDetailList = menuDetailResponse != null ? menuDetailResponse.getResponsesList() : new ArrayList<>(); 832 + final List<SingleMenuDetailRpcResponse> menuDetailList = menuDetailResponse.getResponsesList();
435 - final var menuDetailMap = menuDetailList.stream() 833 + final var menuDetailMap = menuDetailList.stream().collect(Collectors.toMap(SingleMenuDetailRpcResponse::getId, m -> m, (m1, m2) -> m1));
436 - .filter(Objects::nonNull)
437 - .filter(m -> m.getId() != 0)
438 - .collect(Collectors.toMap(SingleMenuDetailRpcResponse::getId, m -> m, (m1, m2) -> m1));
439 834
440 // 获取客户数据 835 // 获取客户数据
441 - List<Integer> customerIds = orderList.stream() 836 + List<Integer> customerIds = orderList.stream().map(SingleClientCustomerOrderRpcResponse::getCustomerId).distinct().collect(Collectors.toList());
442 - .filter(Objects::nonNull)
443 - .map(SingleClientCustomerOrderRpcResponse::getCustomerId)
444 - .filter(id -> id != 0)
445 - .distinct()
446 - .collect(Collectors.toList());
447 -
448 final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(enterpriseId, customerIds); 837 final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(enterpriseId, customerIds);
449 - final List<SingleClientCustomerRpcResponse> customers = customerResponse != null ? customerResponse.getResponsesList() : new ArrayList<>(); 838 + final List<SingleClientCustomerRpcResponse> customers = customerResponse.getResponsesList();
450 - final var customerMap = customers.stream() 839 + final var customerMap = customers.stream().collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1));
451 - .filter(Objects::nonNull)
452 - .filter(c -> c.getId() != 0)
453 - .collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1));
454 840
455 // 构建结算订单明细 841 // 构建结算订单明细
456 final var classifyOrders = new ArrayList<SettlementDTO.SettlementOrderDetail>(); 842 final var classifyOrders = new ArrayList<SettlementDTO.SettlementOrderDetail>();
457 for (Integer orderId : orderIds) { 843 for (Integer orderId : orderIds) {
458 final var orderDetails = orderDetailGroupByOrderId.getOrDefault(orderId, Collections.emptyList()); 844 final var orderDetails = orderDetailGroupByOrderId.getOrDefault(orderId, Collections.emptyList());
459 final var order = orderMap.get(orderId); 845 final var order = orderMap.get(orderId);
460 -
461 - // 订单为空则跳过
462 if (order == null) { 846 if (order == null) {
463 - log.warn("订单不存在,orderId: {}", orderId);
464 continue; 847 continue;
465 } 848 }
466 -
467 // 获取菜单信息 849 // 获取菜单信息
468 final var menu = menuMap.get(order.getMenuId()); 850 final var menu = menuMap.get(order.getMenuId());
469 final String menuName = menu != null ? menu.getName() : ""; 851 final String menuName = menu != null ? menu.getName() : "";
...@@ -473,33 +855,111 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -473,33 +855,111 @@ public class SettlementServiceImpl implements SettlementService {
473 final String customerName = customer != null ? customer.getName() : ""; 855 final String customerName = customer != null ? customer.getName() : "";
474 final String hisCustomerNo = customer != null ? customer.getHISCustomerNo() : ""; 856 final String hisCustomerNo = customer != null ? customer.getHISCustomerNo() : "";
475 857
476 - // 处理每个订单详情 858 + final var orderOperationRecords = orderOperationRecordByOrderId.getOrDefault(orderId, Collections.emptyList());
477 - for (SingleClientCustomerOrderDetailRpcResponse orderDetail : orderDetails) { 859 +
478 - if (orderDetail == null) { 860 + Map<Integer, OrderDetailBO> addOriginalDetailMap = orderOperationRecords.stream()
479 - continue; 861 + .filter(e -> e.getType() == OrderOperationType.ADD_DISHES)
862 + .flatMap(e -> JsonUtil.readJsonAs(e.getOriginalOrderDetailJson(), new TypeReference<List<OrderDetailBO>>() {
863 + }).stream())
864 + .collect(Collectors.toMap(OrderDetailBO::getId, Function.identity(), (a, b) -> a));
865 +
866 + Map<Integer, OrderDetailBO> replaceOriginalDetailMap = orderOperationRecords.stream()
867 + .filter(e -> e.getType() == OrderOperationType.REPLACE_DISHES)
868 + .flatMap(e -> JsonUtil.readJsonAs(e.getOriginalOrderDetailJson(), new TypeReference<List<OrderDetailBO>>() {
869 + }).stream())
870 + .collect(Collectors.toMap(OrderDetailBO::getId, Function.identity(), (a, b) -> a));
871 +
872 + Map<Integer, OrderDetailBO> replaceAdjustDetailMap = orderOperationRecords.stream()
873 + .filter(e -> e.getType() == OrderOperationType.REPLACE_DISHES)
874 + .flatMap(e -> JsonUtil.readJsonAs(e.getAdjustOrderDetailJson(), new TypeReference<List<OrderDetailBO>>() {
875 + }).stream())
876 + .collect(Collectors.toMap(OrderDetailBO::getId, Function.identity(), (a, b) -> a));
877 +
878 + for (SingleClientCustomerOrderDetailRpcResponse orderDetail : orderDetails) {
879 + // 1. 先处理加餐
880 + if (addOriginalDetailMap.containsKey(orderDetail.getId())
881 + && addOriginalDetailMap.get(orderDetail.getId()).getCount() != orderDetail.getCount()) {
882 + final var orderDetailBO = addOriginalDetailMap.get(orderDetail.getId());
883 + SettlementDTO.SettlementOrderDetail beforeChange = buildSettlementOrderDetail(
884 + order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetailBO.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
885 + classifyOrders.add(beforeChange);
886 + SettlementDTO.SettlementOrderDetail afterChange = buildSettlementOrderDetail(
887 + order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetail.getCount() - orderDetailBO.getCount(), orderDetail.getPrice(), "加餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
888 + classifyOrders.add(afterChange);
889 + }
890 +
891 + // 2. 再处理换菜
892 + if (replaceOriginalDetailMap.containsKey(orderDetail.getId())
893 + && !Objects.equals(replaceOriginalDetailMap.get(orderDetail.getId()).getSkuId(), orderDetail.getSkuId())) {
894 + final var orderDetailBO = replaceOriginalDetailMap.get(orderDetail.getId());
895 + final var orderDetailAdjustBO = replaceAdjustDetailMap.get(orderDetail.getId());
896 + SettlementDTO.SettlementOrderDetail beforeChange = buildSettlementOrderDetail(
897 + order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetailBO.getCount(), orderDetailBO.getPrice(), "换菜前", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
898 + classifyOrders.add(beforeChange);
899 + SettlementDTO.SettlementOrderDetail afterChange = buildSettlementOrderDetail(
900 + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetailAdjustBO.getPrice(), "换菜后", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
901 + classifyOrders.add(afterChange);
902 + }
903 +
904 + // 3. 判断已退款
905 + if (orderDetail.getServeStatus() == ServeStatusEnum.SERVE_REJECT) {
906 + SettlementDTO.SettlementOrderDetail refundRecord1 = buildSettlementOrderDetail(
907 + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
908 + classifyOrders.add(refundRecord1);
909 + SettlementDTO.SettlementOrderDetail refundRecord2 = buildSettlementOrderDetail(
910 + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), -orderDetail.getCount(), orderDetail.getPrice(), "已退款", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
911 + classifyOrders.add(refundRecord2);
912 + }
913 +
914 + // 4. 如果既不是加餐,也不是换菜,也不是退款,才记录“订餐”
915 + boolean isNormal = !(addOriginalDetailMap.containsKey(orderDetail.getId())
916 + && addOriginalDetailMap.get(orderDetail.getId()).getCount() != orderDetail.getCount())
917 + && !(replaceOriginalDetailMap.containsKey(orderDetail.getId())
918 + && !Objects.equals(replaceOriginalDetailMap.get(orderDetail.getId()).getSkuId(), orderDetail.getSkuId()))
919 + && orderDetail.getServeStatus() != ServeStatusEnum.SERVE_REJECT;
920 +
921 + if (isNormal) {
922 + SettlementDTO.SettlementOrderDetail normalRecord = buildSettlementOrderDetail(
923 + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap);
924 + classifyOrders.add(normalRecord);
925 + }
926 + }
927 +
480 } 928 }
481 929
482 - // 安全获取餐别名称 930 + // 构建结算数据
483 - String mealName = getMealNameSafely(orderDetail, menuDetailMap, mealMap); 931 + final var settlementDataByOrderDto = SettlementDTO.SettlementDataByOrderDto.builder()
932 + .classifyOrders(classifyOrders)
933 + .build();
484 934
485 - // 安全获取SKU名称 935 + // 生成Excel
486 - String skuName = getSkuNameSafely(orderDetail, skuMap); 936 + try {
937 + return writeToExcelByOrder(settlementDataByOrderDto);
938 + } catch (IOException e) {
939 + log.error("生成按订单结算Excel失败", e);
940 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
941 + }
942 + }
487 943
488 - // 安全获取房间号 944 + private SettlementDTO.SettlementOrderDetail buildSettlementOrderDetail(SingleClientCustomerOrderRpcResponse order,
945 + int menuDetailId,
946 + int skuId,
947 + int count,
948 + Integer price,
949 + String operationType,
950 + String menuName,
951 + String customerName,
952 + String hisCustomerNo,
953 + Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap,
954 + Map<Integer, SingleMealRpcResponse> mealMap,
955 + Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) {
956 + String mealName = getMealNameSafely(menuDetailId, menuDetailMap, mealMap);
957 + String skuName = getSkuNameSafely(skuId, skuMap);
489 String roomNo = getRoomNoSafely(order); 958 String roomNo = getRoomNoSafely(order);
490 -
491 - // 安全获取忌口和医嘱
492 List<String> avoids = getAvoidsSafely(order); 959 List<String> avoids = getAvoidsSafely(order);
493 List<String> doctors = getDoctorsSafely(order); 960 List<String> doctors = getDoctorsSafely(order);
494 -
495 - // 安全获取在线支付描述
496 String onlinePayDesc = getOnlinePayDescSafely(order); 961 String onlinePayDesc = getOnlinePayDescSafely(order);
497 - 962 + return SettlementDTO.SettlementOrderDetail.builder()
498 - // 构建订单详情
499 - order.getOrderCode();
500 - order.getRemark();
501 - order.getAvoidRemark();
502 - SettlementDTO.SettlementOrderDetail settlementOrderDetail = SettlementDTO.SettlementOrderDetail.builder()
503 .mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "") 963 .mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "")
504 .code(order.getOrderCode()) 964 .code(order.getOrderCode())
505 .mealName(mealName) 965 .mealName(mealName)
...@@ -510,42 +970,28 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -510,42 +970,28 @@ public class SettlementServiceImpl implements SettlementService {
510 .doctors(doctors) 970 .doctors(doctors)
511 .menuName(menuName) 971 .menuName(menuName)
512 .skuName(skuName) 972 .skuName(skuName)
513 - .count(orderDetail.getCount() != 0 ? orderDetail.getCount() : 0) 973 + .count(count)
514 - .price(calculatePrice(orderDetail.getPrice())) 974 + .price(calculatePrice(price))
515 - .totalPrice(calculateTotalPrice(orderDetail.getPrice(), orderDetail.getCount())) 975 + .totalPrice(calculateTotalPrice(price, count))
516 .remark(order.getRemark()) 976 .remark(order.getRemark())
517 .avoidRemark(order.getAvoidRemark()) 977 .avoidRemark(order.getAvoidRemark())
518 .onlinePay(onlinePayDesc) 978 .onlinePay(onlinePayDesc)
979 + .operationType(operationType)
980 + .transactionId(operationType.equals("已退款") ? "" : order.getTransactionId())
519 .build(); 981 .build();
520 - classifyOrders.add(settlementOrderDetail);
521 - }
522 - }
523 -
524 - // 构建结算数据
525 - final var settlementDataByOrderDto = SettlementDTO.SettlementDataByOrderDto.builder()
526 - .classifyOrders(classifyOrders)
527 - .build();
528 -
529 - // 生成Excel
530 - try {
531 - return writeToExcelByOrder(settlementDataByOrderDto);
532 - } catch (IOException e) {
533 - log.error("生成按订单结算Excel失败", e);
534 - throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
535 - }
536 } 982 }
537 983
538 /** 984 /**
539 * 安全获取餐别名称 985 * 安全获取餐别名称
540 */ 986 */
541 - private String getMealNameSafely(SingleClientCustomerOrderDetailRpcResponse orderDetail, 987 + private String getMealNameSafely(int menuDetailId,
542 Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap, 988 Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap,
543 Map<Integer, SingleMealRpcResponse> mealMap) { 989 Map<Integer, SingleMealRpcResponse> mealMap) {
544 - if (orderDetail == null || orderDetail.getMenuDetailId() == 0) { 990 + if (menuDetailId == 0) {
545 return ""; 991 return "";
546 } 992 }
547 993
548 - final var menuDetail = menuDetailMap.get(orderDetail.getMenuDetailId()); 994 + final var menuDetail = menuDetailMap.get(menuDetailId);
549 if (menuDetail == null || menuDetail.getMealId() == 0) { 995 if (menuDetail == null || menuDetail.getMealId() == 0) {
550 return ""; 996 return "";
551 } 997 }
...@@ -557,13 +1003,12 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -557,13 +1003,12 @@ public class SettlementServiceImpl implements SettlementService {
557 /** 1003 /**
558 * 安全获取SKU名称 1004 * 安全获取SKU名称
559 */ 1005 */
560 - private String getSkuNameSafely(SingleClientCustomerOrderDetailRpcResponse orderDetail, 1006 + private String getSkuNameSafely(int skuId,
561 Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) { 1007 Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) {
562 - if (orderDetail == null || orderDetail.getSkuId() == 0) { 1008 + if (skuId == 0) {
563 return ""; 1009 return "";
564 } 1010 }
565 - 1011 + final var sku = skuMap.get(skuId);
566 - final var sku = skuMap.get(orderDetail.getSkuId());
567 return sku != null ? sku.getName() : ""; 1012 return sku != null ? sku.getName() : "";
568 } 1013 }
569 1014
...@@ -602,264 +1047,61 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -602,264 +1047,61 @@ public class SettlementServiceImpl implements SettlementService {
602 return Collections.emptyList(); 1047 return Collections.emptyList();
603 } 1048 }
604 1049
605 - return order.getCustomerNoticeJson().getDoctorsList(); 1050 + return order.getCustomerNoticeJson().getDoctorsList();
606 - }
607 -
608 - /**
609 - * 安全获取在线支付描述
610 - */
611 - private String getOnlinePayDescSafely(SingleClientCustomerOrderRpcResponse order) {
612 - if (order == null) {
613 - return "";
614 - }
615 -
616 - try {
617 - String desc = BaseProtoDescEnum.getDescByProtoEnum(order.getOnlinePay(), OnlinePayDescEnum.class);
618 - return desc != null ? desc : "";
619 - } catch (Exception e) {
620 - log.warn("获取在线支付描述失败,orderId: {}", order.getId(), e);
621 - return "";
622 - }
623 - }
624 -
625 - /**
626 - * 计算单价
627 - */
628 - private BigDecimal calculatePrice(Integer price) {
629 - if (price == null) {
630 - return BigDecimal.ZERO;
631 - }
632 - return new BigDecimal(price).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
633 - }
634 -
635 - /**
636 - * 计算总价
637 - */
638 - private BigDecimal calculateTotalPrice(Integer price, Integer count) {
639 - if (price == null || count == null) {
640 - return BigDecimal.ZERO;
641 - }
642 - return new BigDecimal(price)
643 - .multiply(new BigDecimal(count))
644 - .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
645 - }
646 -
647 - /**
648 - * 创建空的订单Excel
649 - */
650 - private ByteArrayOutputStream createEmptyExcelByOrder() {
651 - try {
652 - final var emptyData = SettlementDTO.SettlementDataByOrderDto.builder()
653 - .classifyOrders(Collections.emptyList())
654 - .build();
655 - return writeToExcelByOrder(emptyData);
656 - } catch (IOException e) {
657 - log.error("创建空Excel失败", e);
658 - throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
659 - }
660 - }
661 -
662 - /**
663 - * 按订单维度生成Excel
664 - */
665 - private static ByteArrayOutputStream writeToExcelByOrder(SettlementDTO.SettlementDataByOrderDto settlementDataDto)
666 - throws IOException {
667 - Workbook workbook = new XSSFWorkbook();
668 - Sheet sheet = workbook.createSheet("客人结算");
669 -
670 - // 创建表头样式(黑色边框)
671 - CellStyle headerStyle = workbook.createCellStyle();
672 - headerStyle.setBorderTop(BorderStyle.THIN);
673 - headerStyle.setBorderBottom(BorderStyle.THIN);
674 - headerStyle.setBorderLeft(BorderStyle.THIN);
675 - headerStyle.setBorderRight(BorderStyle.THIN);
676 - headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
677 - headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
678 - headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
679 - headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
680 -
681 - // 创建数据行样式(浅灰色边框)
682 - CellStyle dataStyle = workbook.createCellStyle();
683 - dataStyle.setBorderTop(BorderStyle.THIN);
684 - dataStyle.setBorderBottom(BorderStyle.THIN);
685 - dataStyle.setBorderLeft(BorderStyle.THIN);
686 - dataStyle.setBorderRight(BorderStyle.THIN);
687 - dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
688 - dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
689 - dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
690 - dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
691 -
692 - int rowNum = 0;
693 -
694 - // 创建表头
695 - Row titleRow = sheet.createRow(rowNum++);
696 - int columnNum = 0;
697 -
698 - Cell cell0 = titleRow.createCell(columnNum++);
699 - cell0.setCellValue("用餐时间");
700 - cell0.setCellStyle(headerStyle);
701 -
702 - Cell cell1 = titleRow.createCell(columnNum++);
703 - cell1.setCellValue("订单号");
704 - cell1.setCellStyle(headerStyle);
705 -
706 - Cell cell2 = titleRow.createCell(columnNum++);
707 - cell2.setCellValue("餐别");
708 - cell2.setCellStyle(headerStyle);
709 -
710 - Cell cell3 = titleRow.createCell(columnNum++);
711 - cell3.setCellValue("房间号");
712 - cell3.setCellStyle(headerStyle);
713 -
714 - Cell cell4 = titleRow.createCell(columnNum++);
715 - cell4.setCellValue("客户姓名");
716 - cell4.setCellStyle(headerStyle);
717 -
718 - Cell cell5 = titleRow.createCell(columnNum++);
719 - cell5.setCellValue("客户腕带号");
720 - cell5.setCellStyle(headerStyle);
721 -
722 - Cell cell6 = titleRow.createCell(columnNum++);
723 - cell6.setCellValue("忌口信息");
724 - cell6.setCellStyle(headerStyle);
725 -
726 - Cell cell7 = titleRow.createCell(columnNum++);
727 - cell7.setCellValue("医嘱信息");
728 - cell7.setCellStyle(headerStyle);
729 -
730 - Cell cell8 = titleRow.createCell(columnNum++);
731 - cell8.setCellValue("餐单名称");
732 - cell8.setCellStyle(headerStyle);
733 -
734 - Cell cell9 = titleRow.createCell(columnNum++);
735 - cell9.setCellValue("菜品名称");
736 - cell9.setCellStyle(headerStyle);
737 -
738 - Cell cell10 = titleRow.createCell(columnNum++);
739 - cell10.setCellValue("菜品份数");
740 - cell10.setCellStyle(headerStyle);
741 -
742 - Cell cell11 = titleRow.createCell(columnNum++);
743 - cell11.setCellValue("菜品单价");
744 - cell11.setCellStyle(headerStyle);
745 -
746 - Cell cell12 = titleRow.createCell(columnNum++);
747 - cell12.setCellValue("菜品金额");
748 - cell12.setCellStyle(headerStyle);
749 -
750 - Cell cell13 = titleRow.createCell(columnNum++);
751 - cell13.setCellValue("备注");
752 - cell13.setCellStyle(headerStyle);
753 -
754 - Cell cell14 = titleRow.createCell(columnNum++);
755 - cell14.setCellValue("支付方式");
756 - cell14.setCellStyle(headerStyle);
757 -
758 - // 填充数据
759 - final var classifyOrders = settlementDataDto.getClassifyOrders();
760 - if (classifyOrders != null) {
761 - for (SettlementDTO.SettlementOrderDetail orderDetail : classifyOrders) {
762 - Row dataRow = sheet.createRow(rowNum++);
763 - columnNum = 0;
764 -
765 - Cell dataCell0 = dataRow.createCell(columnNum++);
766 - dataCell0.setCellValue(orderDetail.getMealTime() != null ? orderDetail.getMealTime() : "");
767 - dataCell0.setCellStyle(dataStyle);
768 -
769 - Cell dataCell1 = dataRow.createCell(columnNum++);
770 - dataCell1.setCellValue(orderDetail.getCode() != null ? orderDetail.getCode() : "");
771 - dataCell1.setCellStyle(dataStyle);
772 -
773 - Cell dataCell2 = dataRow.createCell(columnNum++);
774 - dataCell2.setCellValue(orderDetail.getMealName() != null ? orderDetail.getMealName() : "");
775 - dataCell2.setCellStyle(dataStyle);
776 -
777 - Cell dataCell3 = dataRow.createCell(columnNum++);
778 - dataCell3.setCellValue(orderDetail.getRoomNo() != null ? orderDetail.getRoomNo() : "");
779 - dataCell3.setCellStyle(dataStyle);
780 -
781 - Cell dataCell4 = dataRow.createCell(columnNum++);
782 - dataCell4.setCellValue(orderDetail.getCustomerName() != null ? orderDetail.getCustomerName() : "");
783 - dataCell4.setCellStyle(dataStyle);
784 -
785 - Cell dataCell5 = dataRow.createCell(columnNum++);
786 - dataCell5.setCellValue(orderDetail.getHISCustomerNo() != null ? orderDetail.getHISCustomerNo() : "");
787 - dataCell5.setCellStyle(dataStyle);
788 -
789 - // 忌口列表转字符串
790 - String avoidsStr = orderDetail.getAvoids() != null ? String.join(", ", orderDetail.getAvoids()) : "";
791 - Cell dataCell6 = dataRow.createCell(columnNum++);
792 - dataCell6.setCellValue(avoidsStr);
793 - dataCell6.setCellStyle(dataStyle);
794 -
795 - // 医嘱列表转字符串
796 - String doctorsStr = orderDetail.getDoctors() != null ? String.join(", ", orderDetail.getDoctors()) : "";
797 - Cell dataCell7 = dataRow.createCell(columnNum++);
798 - dataCell7.setCellValue(doctorsStr);
799 - dataCell7.setCellStyle(dataStyle);
800 -
801 - Cell dataCell8 = dataRow.createCell(columnNum++);
802 - dataCell8.setCellValue(orderDetail.getMenuName() != null ? orderDetail.getMenuName() : "");
803 - dataCell8.setCellStyle(dataStyle);
804 -
805 - Cell dataCell9 = dataRow.createCell(columnNum++);
806 - dataCell9.setCellValue(orderDetail.getSkuName() != null ? orderDetail.getSkuName() : "");
807 - dataCell9.setCellStyle(dataStyle);
808 -
809 - Cell dataCell10 = dataRow.createCell(columnNum++);
810 - dataCell10.setCellValue(orderDetail.getCount() != null ? orderDetail.getCount() : 0);
811 - dataCell10.setCellStyle(dataStyle);
812 -
813 - // 价格
814 - Cell dataCell11 = dataRow.createCell(columnNum++);
815 - if (orderDetail.getPrice() != null) {
816 - dataCell11.setCellValue(orderDetail.getPrice().doubleValue());
817 - } else {
818 - dataCell11.setCellValue(0.0);
819 - }
820 - dataCell11.setCellStyle(dataStyle);
821 -
822 - // 总价
823 - Cell dataCell12 = dataRow.createCell(columnNum++);
824 - if (orderDetail.getTotalPrice() != null) {
825 - dataCell12.setCellValue(orderDetail.getTotalPrice().doubleValue());
826 - } else {
827 - dataCell12.setCellValue(0.0);
828 } 1051 }
829 - dataCell12.setCellStyle(dataStyle);
830 1052
831 - // 合并备注和忌口备注,用分号分割,备注在前 1053 + /**
832 - String remark = orderDetail.getRemark() != null ? orderDetail.getRemark() : ""; 1054 + * 安全获取在线支付描述
833 - String avoidRemark = orderDetail.getAvoidRemark() != null ? orderDetail.getAvoidRemark() : ""; 1055 + */
834 - String combinedRemark = ""; 1056 + private String getOnlinePayDescSafely(SingleClientCustomerOrderRpcResponse order) {
835 - if (!remark.isEmpty() && !avoidRemark.isEmpty()) { 1057 + if (order == null) {
836 - combinedRemark = remark + ";" + avoidRemark; 1058 + return "";
837 - } else if (!remark.isEmpty()) {
838 - combinedRemark = remark;
839 - } else if (!avoidRemark.isEmpty()) {
840 - combinedRemark = avoidRemark;
841 } 1059 }
842 - Cell dataCell13 = dataRow.createCell(columnNum++);
843 - dataCell13.setCellValue(combinedRemark);
844 - dataCell13.setCellStyle(dataStyle);
845 1060
846 - Cell dataCell14 = dataRow.createCell(columnNum++); 1061 + try {
847 - dataCell14.setCellValue(orderDetail.getOnlinePay() != null ? orderDetail.getOnlinePay() : ""); 1062 + String desc = BaseProtoDescEnum.getDescByProtoEnum(order.getOnlinePay(), OnlinePayDescEnum.class);
848 - dataCell14.setCellStyle(dataStyle); 1063 + return desc != null ? desc : "";
1064 + } catch (Exception e) {
1065 + log.warn("获取在线支付描述失败,orderId: {}", order.getId(), e);
1066 + return "";
849 } 1067 }
850 } 1068 }
851 1069
852 - // 自动调整列宽 1070 + /**
853 - for (int i = 0; i < 15; i++) { 1071 + * 计算单价
854 - sheet.autoSizeColumn(i); 1072 + */
1073 + private BigDecimal calculatePrice(Integer price) {
1074 + if (price == null) {
1075 + return BigDecimal.ZERO;
1076 + }
1077 + return new BigDecimal(price).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
855 } 1078 }
856 1079
857 - // 将工作簿内容写入字节数组输出流 1080 + /**
858 - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 1081 + * 计算总价
859 - workbook.write(outputStream); 1082 + */
860 - workbook.close(); 1083 + private BigDecimal calculateTotalPrice(Integer price, Integer count) {
1084 + if (price == null || count == null) {
1085 + return BigDecimal.ZERO;
1086 + }
1087 + return new BigDecimal(price)
1088 + .multiply(new BigDecimal(count))
1089 + .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
1090 + }
861 1091
862 - return outputStream; 1092 + /**
1093 + * 创建空的订单Excel
1094 + */
1095 + private ByteArrayOutputStream createEmptyExcelByOrder() {
1096 + try {
1097 + final var emptyData = SettlementDTO.SettlementDataByOrderDto.builder()
1098 + .classifyOrders(Collections.emptyList())
1099 + .build();
1100 + return writeToExcelByOrder(emptyData);
1101 + } catch (IOException e) {
1102 + log.error("创建空Excel失败", e);
1103 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1104 + }
863 } 1105 }
864 1106
865 public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) { 1107 public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) {
...@@ -1249,10 +1491,10 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -1249,10 +1491,10 @@ public class SettlementServiceImpl implements SettlementService {
1249 } 1491 }
1250 1492
1251 // 安全获取餐别名称 1493 // 安全获取餐别名称
1252 - String mealName = getMealNameSafely(orderDetail, menuDetailMap, mealMap); 1494 + String mealName = getMealNameSafely(orderDetail.getMenuDetailId(), menuDetailMap, mealMap);
1253 1495
1254 // 安全获取SKU名称 1496 // 安全获取SKU名称
1255 - String skuName = getSkuNameSafely(orderDetail, skuMap); 1497 + String skuName = getSkuNameSafely(orderDetail.getSkuId(), skuMap);
1256 1498
1257 // 安全获取忌口信息(列表转字符串) 1499 // 安全获取忌口信息(列表转字符串)
1258 List<String> avoidsList = getAvoidsSafely(order); 1500 List<String> avoidsList = getAvoidsSafely(order);
...@@ -1304,186 +1546,4 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -1304,186 +1546,4 @@ public class SettlementServiceImpl implements SettlementService {
1304 } 1546 }
1305 } 1547 }
1306 1548
1307 - /**
1308 - * 生成分餐表Excel
1309 - */
1310 - private static ByteArrayOutputStream writeToExcelBySeparateMeal(SeparateMealDataDto separateMealDataDto)
1311 - throws IOException {
1312 - Workbook workbook = new XSSFWorkbook();
1313 - Sheet sheet = workbook.createSheet("分餐表");
1314 -
1315 - // 创建标题样式(合并单元格标题)
1316 - CellStyle titleStyle = workbook.createCellStyle();
1317 - titleStyle.setAlignment(HorizontalAlignment.CENTER);
1318 - titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
1319 - titleStyle.setBorderTop(BorderStyle.THIN);
1320 - titleStyle.setBorderBottom(BorderStyle.THIN);
1321 - titleStyle.setBorderLeft(BorderStyle.THIN);
1322 - titleStyle.setBorderRight(BorderStyle.THIN);
1323 - titleStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
1324 - titleStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
1325 - titleStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
1326 - titleStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
1327 - Font titleFont = workbook.createFont();
1328 - titleFont.setBold(true);
1329 - titleFont.setFontHeightInPoints((short) 16);
1330 - titleStyle.setFont(titleFont);
1331 -
1332 - // 创建表头样式(黑色边框)
1333 - CellStyle headerStyle = workbook.createCellStyle();
1334 - headerStyle.setBorderTop(BorderStyle.THIN);
1335 - headerStyle.setBorderBottom(BorderStyle.THIN);
1336 - headerStyle.setBorderLeft(BorderStyle.THIN);
1337 - headerStyle.setBorderRight(BorderStyle.THIN);
1338 - headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
1339 - headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
1340 - headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
1341 - headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
1342 -
1343 - // 创建数据行样式(浅灰色边框)
1344 - CellStyle dataStyle = workbook.createCellStyle();
1345 - dataStyle.setBorderTop(BorderStyle.THIN);
1346 - dataStyle.setBorderBottom(BorderStyle.THIN);
1347 - dataStyle.setBorderLeft(BorderStyle.THIN);
1348 - dataStyle.setBorderRight(BorderStyle.THIN);
1349 - dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1350 - dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1351 - dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1352 - dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1353 -
1354 - int rowNum = 0;
1355 -
1356 - // 第一行:创建合并单元格标题
1357 - Row mainTitleRow = sheet.createRow(rowNum++);
1358 - Cell mainTitleCell = mainTitleRow.createCell(0);
1359 - mainTitleCell.setCellValue("住院客户分餐表");
1360 - mainTitleCell.setCellStyle(titleStyle);
1361 -
1362 - // 合并第一行的8列
1363 - CellRangeAddress titleRegion = new CellRangeAddress(0, 0, 0, 8);
1364 - sheet.addMergedRegion(titleRegion);
1365 -
1366 - // 为合并区域设置边框
1367 - RegionUtil.setBorderTop(BorderStyle.THIN, titleRegion, sheet);
1368 - RegionUtil.setBorderBottom(BorderStyle.THIN, titleRegion, sheet);
1369 - RegionUtil.setBorderLeft(BorderStyle.THIN, titleRegion, sheet);
1370 - RegionUtil.setBorderRight(BorderStyle.THIN, titleRegion, sheet);
1371 - RegionUtil.setTopBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1372 - RegionUtil.setBottomBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1373 - RegionUtil.setLeftBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1374 - RegionUtil.setRightBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1375 -
1376 - // 第二行:创建表头
1377 - Row titleRow = sheet.createRow(rowNum++);
1378 - int columnNum = 0;
1379 -
1380 - Cell cell0 = titleRow.createCell(columnNum++);
1381 - cell0.setCellValue("餐别");
1382 - cell0.setCellStyle(headerStyle);
1383 -
1384 - Cell cell1 = titleRow.createCell(columnNum++);
1385 - cell1.setCellValue("房间号");
1386 - cell1.setCellStyle(headerStyle);
1387 -
1388 - Cell cell2 = titleRow.createCell(columnNum++);
1389 - cell2.setCellValue("客户姓名");
1390 - cell2.setCellStyle(headerStyle);
1391 -
1392 - Cell cell3 = titleRow.createCell(columnNum++);
1393 - cell3.setCellValue("医嘱信息");
1394 - cell3.setCellStyle(headerStyle);
1395 -
1396 - Cell cell4 = titleRow.createCell(columnNum++);
1397 - cell4.setCellValue("餐单名称");
1398 - cell4.setCellStyle(headerStyle);
1399 -
1400 - Cell cell5 = titleRow.createCell(columnNum++);
1401 - cell5.setCellValue("菜品名称");
1402 - cell5.setCellStyle(headerStyle);
1403 -
1404 - Cell cell6 = titleRow.createCell(columnNum++);
1405 - cell6.setCellValue("菜品数量");
1406 - cell6.setCellStyle(headerStyle);
1407 -
1408 - Cell cell7 = titleRow.createCell(columnNum++);
1409 - cell7.setCellValue("忌口信息");
1410 - cell7.setCellStyle(headerStyle);
1411 -
1412 - Cell cell8 = titleRow.createCell(columnNum++);
1413 - cell8.setCellValue("备注");
1414 - cell8.setCellStyle(headerStyle);
1415 -
1416 - // 填充数据
1417 - final var mealDetails = separateMealDataDto.getMealDetails();
1418 - if (mealDetails != null) {
1419 - for (SeparateMealDetail mealDetail : mealDetails) {
1420 - Row dataRow = sheet.createRow(rowNum++);
1421 - columnNum = 0;
1422 -
1423 - Cell dataCell0 = dataRow.createCell(columnNum++);
1424 - dataCell0.setCellValue(mealDetail.getMealName() != null ? mealDetail.getMealName() : "");
1425 - dataCell0.setCellStyle(dataStyle);
1426 -
1427 - Cell dataCell1 = dataRow.createCell(columnNum++);
1428 - dataCell1.setCellValue(mealDetail.getRoomNo() != null ? mealDetail.getRoomNo() : "");
1429 - dataCell1.setCellStyle(dataStyle);
1430 -
1431 - Cell dataCell2 = dataRow.createCell(columnNum++);
1432 - dataCell2.setCellValue(mealDetail.getCustomerName() != null ? mealDetail.getCustomerName() : "");
1433 - dataCell2.setCellStyle(dataStyle);
1434 -
1435 - Cell dataCell3 = dataRow.createCell(columnNum++);
1436 - dataCell3.setCellValue(mealDetail.getDoctors() != null ? mealDetail.getDoctors() : "");
1437 - dataCell3.setCellStyle(dataStyle);
1438 -
1439 - Cell dataCell4 = dataRow.createCell(columnNum++);
1440 - dataCell4.setCellValue(mealDetail.getMenuName() != null ? mealDetail.getMenuName() : "");
1441 - dataCell4.setCellStyle(dataStyle);
1442 -
1443 - Cell dataCell5 = dataRow.createCell(columnNum++);
1444 - dataCell5.setCellValue(mealDetail.getSkuName() != null ? mealDetail.getSkuName() : "");
1445 - dataCell5.setCellStyle(dataStyle);
1446 -
1447 - Cell dataCell6 = dataRow.createCell(columnNum++);
1448 - dataCell6.setCellValue(mealDetail.getCount() != null ? mealDetail.getCount() : 0);
1449 - dataCell6.setCellStyle(dataStyle);
1450 -
1451 - Cell dataCell7 = dataRow.createCell(columnNum++);
1452 - dataCell7.setCellValue(mealDetail.getAvoids() != null ? mealDetail.getAvoids() : "");
1453 - dataCell7.setCellStyle(dataStyle);
1454 -
1455 - Cell dataCell8 = dataRow.createCell(columnNum++);
1456 - dataCell8.setCellValue(mealDetail.getRemark() != null ? mealDetail.getRemark() : "");
1457 - dataCell8.setCellStyle(dataStyle);
1458 - }
1459 - }
1460 -
1461 - // 自动调整列宽
1462 - for (int i = 0; i < 9; i++) {
1463 - sheet.autoSizeColumn(i);
1464 - }
1465 -
1466 - // 将工作簿内容写入字节数组输出流
1467 - ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
1468 - workbook.write(outputStream);
1469 - workbook.close();
1470 -
1471 - return outputStream;
1472 - }
1473 -
1474 - /**
1475 - * 创建空的分餐表Excel(无数据)
1476 - */
1477 - private static ByteArrayOutputStream createEmptyExcelBySeparateMeal() {
1478 - try {
1479 - SeparateMealDataDto emptyData = SeparateMealDataDto.builder()
1480 - .mealDetails(new ArrayList<>())
1481 - .build();
1482 - return writeToExcelBySeparateMeal(emptyData);
1483 - } catch (IOException e) {
1484 - log.error("创建空分餐表Excel失败", e);
1485 - throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1486 - }
1487 - }
1488 -
1489 } 1549 }
......
...@@ -2,6 +2,7 @@ package com.infoloop.tianting.utils; ...@@ -2,6 +2,7 @@ package com.infoloop.tianting.utils;
2 2
3 import com.fasterxml.jackson.annotation.JsonInclude; 3 import com.fasterxml.jackson.annotation.JsonInclude;
4 import com.fasterxml.jackson.core.JsonProcessingException; 4 import com.fasterxml.jackson.core.JsonProcessingException;
5 +import com.fasterxml.jackson.core.type.TypeReference;
5 import com.fasterxml.jackson.databind.DeserializationFeature; 6 import com.fasterxml.jackson.databind.DeserializationFeature;
6 import com.fasterxml.jackson.databind.JsonNode; 7 import com.fasterxml.jackson.databind.JsonNode;
7 import com.fasterxml.jackson.databind.ObjectMapper; 8 import com.fasterxml.jackson.databind.ObjectMapper;
...@@ -41,6 +42,14 @@ public class JsonUtil { ...@@ -41,6 +42,14 @@ public class JsonUtil {
41 } 42 }
42 } 43 }
43 44
45 + public static <T> T readJsonAs(final String json, final TypeReference<T> typeRef) {
46 + try {
47 + return OBJECT_MAPPER.readValue(json, typeRef);
48 + } catch (IOException e) {
49 + throw new RuntimeException(e);
50 + }
51 + }
52 +
44 public static <T> T convertValue(final Object object, final Class<T> clazz) { 53 public static <T> T convertValue(final Object object, final Class<T> clazz) {
45 return OBJECT_MAPPER.convertValue(object, clazz); 54 return OBJECT_MAPPER.convertValue(object, clazz);
46 } 55 }
......
...@@ -32,6 +32,7 @@ service ClientCustomerOrderServiceRpc { ...@@ -32,6 +32,7 @@ service ClientCustomerOrderServiceRpc {
32 32
33 // 操作记录 33 // 操作记录
34 rpc GetOrderOperationRecordsByOrderId (GetOrderOperationRecordsByOrderIdRequest) returns (GetOrderOperationRecordsByOrderIdResponse) {} 34 rpc GetOrderOperationRecordsByOrderId (GetOrderOperationRecordsByOrderIdRequest) returns (GetOrderOperationRecordsByOrderIdResponse) {}
35 + rpc GetOrderOperationRecordsByOrderIds (GetOrderOperationRecordsByOrderIdsRequest) returns (GetOrderOperationRecordsByOrderIdsResponse) {}
35 rpc BatchCreateOrderOperationRecords (BatchCreateOrderOperationRecordsRequest) returns (BatchCreateOrderOperationRecordsResponse) {} 36 rpc BatchCreateOrderOperationRecords (BatchCreateOrderOperationRecordsRequest) returns (BatchCreateOrderOperationRecordsResponse) {}
36 37
37 38
...@@ -624,6 +625,15 @@ message GetOrderOperationRecordsByOrderIdResponse { ...@@ -624,6 +625,15 @@ message GetOrderOperationRecordsByOrderIdResponse {
624 repeated OrderOperationRecord responses = 1; 625 repeated OrderOperationRecord responses = 1;
625 } 626 }
626 627
628 +message GetOrderOperationRecordsByOrderIdsRequest {
629 + int32 enterpriseId = 1;
630 + repeated int32 orderIds = 2;
631 +}
632 +
633 +message GetOrderOperationRecordsByOrderIdsResponse {
634 + repeated OrderOperationRecord responses = 1;
635 +}
636 +
627 message OrderOperationRecordCreation { 637 message OrderOperationRecordCreation {
628 int32 orderId = 1; 638 int32 orderId = 1;
629 OrderOperationType type = 2; 639 OrderOperationType type = 2;
......