zhuyifan

feat(settlement): 新增按订单维度结算及分餐表导出功能、新增忌口备注字段并支持更新

- 在 ClientCustomerOrderService.proto 中新增忌口备注字段 avoidRemark
- 在 KdsDTO 中增加 mealTime 字段用于指定查询日期- 修改 KdsServiceImpl 中获取订单逻辑,使用 mealTime 替代当前日期
- 在 OrderDbDTO 中添加 avoidRemark 字段以存储忌口信息
- 更新 OrderServiceImpl 映射逻辑,包含 avoidRemark 字段
- 在 OrderServiceRpcClient 中实现 avoidRemark 的更新逻辑
...@@ -48,8 +48,8 @@ public class KdsController { ...@@ -48,8 +48,8 @@ public class KdsController {
48 @ApiOperation(value = "kds获取餐别详情") 48 @ApiOperation(value = "kds获取餐别详情")
49 @PostMapping("/kds/mealDetails") 49 @PostMapping("/kds/mealDetails")
50 @ResponseStatus(HttpStatus.OK) 50 @ResponseStatus(HttpStatus.OK)
51 - public List<KdsMealDetailDto> getMealDetail() { 51 + public List<KdsMealDetailDto> getMealDetail(@Valid @RequestBody KdsDTO.KdsMealDetailQueryDto queryDto) {
52 - return kdsService.getMealDetail(); 52 + return kdsService.getMealDetail(queryDto);
53 } 53 }
54 54
55 } 55 }
......
...@@ -8,6 +8,7 @@ import lombok.Getter; ...@@ -8,6 +8,7 @@ import lombok.Getter;
8 public enum SettlementDimensionEnum { 8 public enum SettlementDimensionEnum {
9 BY_SKU(1, "菜品"), 9 BY_SKU(1, "菜品"),
10 BY_MEAL(2, "餐别"), 10 BY_MEAL(2, "餐别"),
11 + BY_ORDER(3, "订单")
11 ; 12 ;
12 13
13 /** 14 /**
......
...@@ -30,6 +30,7 @@ public class KdsDTO { ...@@ -30,6 +30,7 @@ public class KdsDTO {
30 private Integer price; 30 private Integer price;
31 private String roomNo; 31 private String roomNo;
32 private String remark; 32 private String remark;
33 + private String avoidRemark;
33 private CustomerNotice customerNotice; 34 private CustomerNotice customerNotice;
34 private String adjustSkuRemark; 35 private String adjustSkuRemark;
35 private String mealTime; 36 private String mealTime;
...@@ -38,6 +39,8 @@ public class KdsDTO { ...@@ -38,6 +39,8 @@ public class KdsDTO {
38 private ClientDto client; 39 private ClientDto client;
39 private ClientDto stall; 40 private ClientDto stall;
40 private CustomerDetailDto customer; 41 private CustomerDetailDto customer;
42 + private Integer menuId;
43 + private String menuName;
41 } 44 }
42 45
43 @Data 46 @Data
...@@ -77,6 +80,7 @@ public class KdsDTO { ...@@ -77,6 +80,7 @@ public class KdsDTO {
77 private String tableCode; 80 private String tableCode;
78 private Integer totalCount; 81 private Integer totalCount;
79 private String remark; 82 private String remark;
83 + private String avoidRemark;
80 private String mealTime; 84 private String mealTime;
81 private CustomerNotice customerNotice; 85 private CustomerNotice customerNotice;
82 private Integer totalPrice; 86 private Integer totalPrice;
...@@ -87,6 +91,8 @@ public class KdsDTO { ...@@ -87,6 +91,8 @@ public class KdsDTO {
87 private ClientDto client; 91 private ClientDto client;
88 private CustomerDetailDto customer; 92 private CustomerDetailDto customer;
89 private List<KdsOrderLocationDetailDto> orderDetailList; 93 private List<KdsOrderLocationDetailDto> orderDetailList;
94 + private Integer menuId;
95 + private String menuName;
90 } 96 }
91 97
92 @Data 98 @Data
...@@ -97,6 +103,7 @@ public class KdsDTO { ...@@ -97,6 +103,7 @@ public class KdsDTO {
97 public static class KdsOrderSkuQueryDto { 103 public static class KdsOrderSkuQueryDto {
98 private ServeStatusEnum serveStatus; 104 private ServeStatusEnum serveStatus;
99 private Integer mealId; 105 private Integer mealId;
106 + private String mealTime;
100 } 107 }
101 108
102 @Data 109 @Data
...@@ -107,12 +114,22 @@ public class KdsDTO { ...@@ -107,12 +114,22 @@ public class KdsDTO {
107 public static class KdsOrderLocationQueryDto { 114 public static class KdsOrderLocationQueryDto {
108 private OrderStatusEnum orderStatus; 115 private OrderStatusEnum orderStatus;
109 private Integer mealId; 116 private Integer mealId;
117 + private String mealTime;
110 } 118 }
111 119
112 @Data 120 @Data
113 @Builder 121 @Builder
114 @AllArgsConstructor 122 @AllArgsConstructor
115 @NoArgsConstructor 123 @NoArgsConstructor
124 + @ApiModel(description = "KdsMealDetailQueryDto")
125 + public static class KdsMealDetailQueryDto {
126 + private String mealTime;
127 + }
128 +
129 + @Data
130 + @Builder
131 + @AllArgsConstructor
132 + @NoArgsConstructor
116 @ApiModel(description = "KdsMealDetailDto") 133 @ApiModel(description = "KdsMealDetailDto")
117 public static class KdsMealDetailDto { 134 public static class KdsMealDetailDto {
118 private Integer mealId; 135 private Integer mealId;
......
...@@ -64,6 +64,16 @@ public class OrderDbDTO { ...@@ -64,6 +64,16 @@ public class OrderDbDTO {
64 } 64 }
65 65
66 @Data 66 @Data
67 + @ApiModel(description = "查询订单Dto")
68 + public static class QueryOrderDto {
69 + private Integer enterpriseId;
70 + private Integer clientId;
71 + private OrderStatusEnum status;
72 + private String keyword;
73 + private List<Integer> stallIds;
74 + }
75 +
76 + @Data
67 @ApiModel(description = "查询已撤销订单Dto") 77 @ApiModel(description = "查询已撤销订单Dto")
68 public static class QueryRefundOrderByPaginationDto { 78 public static class QueryRefundOrderByPaginationDto {
69 private Integer enterpriseId; 79 private Integer enterpriseId;
...@@ -155,6 +165,7 @@ public class OrderDbDTO { ...@@ -155,6 +165,7 @@ public class OrderDbDTO {
155 private String tableCode; 165 private String tableCode;
156 private Integer updatedBy; 166 private Integer updatedBy;
157 private OrderSourceEnum updatedSource; 167 private OrderSourceEnum updatedSource;
168 + private String avoidRemark;
158 } 169 }
159 170
160 171
...@@ -440,6 +451,9 @@ public class OrderDbDTO { ...@@ -440,6 +451,9 @@ public class OrderDbDTO {
440 @ApiModelProperty(value = "备注") 451 @ApiModelProperty(value = "备注")
441 private String remark; 452 private String remark;
442 453
454 + @ApiModelProperty(value = "忌口备注")
455 + private String avoidRemark;
456 +
443 @ApiModelProperty(value = "下单客户当时的忌口、医嘱") 457 @ApiModelProperty(value = "下单客户当时的忌口、医嘱")
444 private CustomerNotice customerNoticeJson; 458 private CustomerNotice customerNoticeJson;
445 459
......
...@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModel; ...@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModel;
5 import lombok.Builder; 5 import lombok.Builder;
6 import lombok.Data; 6 import lombok.Data;
7 7
8 +import java.math.BigDecimal;
8 import java.time.LocalDateTime; 9 import java.time.LocalDateTime;
9 import java.util.ArrayList; 10 import java.util.ArrayList;
10 import java.util.List; 11 import java.util.List;
...@@ -75,7 +76,55 @@ public class SettlementDTO { ...@@ -75,7 +76,55 @@ public class SettlementDTO {
75 private Map<String, Map<String, Map<String, List<SettlementMenuMealDto>>>> classifyOrders; 76 private Map<String, Map<String, Map<String, List<SettlementMenuMealDto>>>> classifyOrders;
76 } 77 }
77 78
78 -} 79 + @Data
80 + @Builder
81 + @ApiModel(description = "SettlementDataByOrderDto")
82 + public static class SettlementDataByOrderDto {
83 + private List<SettlementOrderDetail> classifyOrders;
84 + }
85 +
86 + @Data
87 + @Builder
88 + @ApiModel(description = "SettlementOrderDetail")
89 + public static class SettlementOrderDetail {
90 + private String mealTime;
91 + private String code;
92 + private String mealName;
93 + private String roomNo;
94 + private String customerName;
95 + private String HISCustomerNo;
96 + private List<String> avoids;
97 + private List<String> doctors;
98 + private String menuName;
99 + private String skuName;
100 + private Integer count;
101 + private BigDecimal price;
102 + private BigDecimal totalPrice;
103 + private String remark;
104 + private String avoidRemark;
105 + private String onlinePay;
106 + }
79 107
108 + @Data
109 + @Builder
110 + @ApiModel(description = "SeparateMealDetail")
111 + public static class SeparateMealDetail {
112 + private Integer orderId;
113 + private String mealName;
114 + private String roomNo;
115 + private String customerName;
116 + private String menuName;
117 + private String skuName;
118 + private Integer count;
119 + private String avoids;
120 + private String remark;
121 + }
80 122
81 -
...\ No newline at end of file ...\ No newline at end of file
123 + @Data
124 + @Builder
125 + @ApiModel(description = "SeparateMealDataDto")
126 + public static class SeparateMealDataDto {
127 + private List<SeparateMealDetail> mealDetails;
128 + }
129 +
130 +}
......
1 +package com.infoloop.tianting.model.enums.desc;
2 +
3 +import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
4 +
5 +public enum OnlinePayDescEnum implements BaseProtoDescEnum<OnlinePayEnum> {
6 +
7 + UNKNOWN(OnlinePayEnum.UNKNOWN, "未知"),
8 + ONLINE(OnlinePayEnum.ONLINE, "在线"),
9 + OFFLINE(OnlinePayEnum.OFFLINE, "线下"),
10 + LEAVE_HOSPITAL(OnlinePayEnum.LEAVE_HOSPITAL, "出院"),
11 + EMPLOYEE_CARD(OnlinePayEnum.EMPLOYEE_CARD, "员工卡"),
12 + PAPER_VERIFICATION(OnlinePayEnum.PAPER_VERIFICATION, "纸质核销"),
13 + CASH(OnlinePayEnum.CASH, "现金"),
14 + MEAL_CARD(OnlinePayEnum.MEAL_CARD, "餐卡"),
15 + BAND_CARD(OnlinePayEnum.BAND_CARD, "银行卡"),
16 + ALIPAY(OnlinePayEnum.ALIPAY, "支付宝"),
17 + WECHATPAY(OnlinePayEnum.WECHATPAY, "微信支付");
18 +
19 + private final OnlinePayEnum protoEnum;
20 + private final String desc;
21 +
22 + OnlinePayDescEnum(OnlinePayEnum protoEnum, String desc) {
23 + this.protoEnum = protoEnum;
24 + this.desc = desc;
25 + }
26 +
27 + @Override
28 + public OnlinePayEnum getProtoEnum() {
29 + return protoEnum;
30 + }
31 +
32 + @Override
33 + public String getDesc() {
34 + return desc;
35 + }
36 +}
1 package com.infoloop.tianting.service; 1 package com.infoloop.tianting.service;
2 2
3 +import com.infoloop.tianting.model.dto.KdsDTO;
3 import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto; 4 import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto;
4 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto; 5 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto;
5 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationQueryDto; 6 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationQueryDto;
...@@ -14,5 +15,5 @@ public interface KdsService { ...@@ -14,5 +15,5 @@ public interface KdsService {
14 15
15 List<KdsOrderLocationDto> getOrderDetailByLocation(KdsOrderLocationQueryDto queryDto); 16 List<KdsOrderLocationDto> getOrderDetailByLocation(KdsOrderLocationQueryDto queryDto);
16 17
17 - List<KdsMealDetailDto> getMealDetail(); 18 + List<KdsMealDetailDto> getMealDetail(KdsDTO.KdsMealDetailQueryDto queryDto);
18 } 19 }
......
1 package com.infoloop.tianting.service; 1 package com.infoloop.tianting.service;
2 2
3 +import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderDto;
3 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto; 4 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto;
4 5
5 import java.io.ByteArrayOutputStream; 6 import java.io.ByteArrayOutputStream;
6 7
7 public interface SettlementService { 8 public interface SettlementService {
8 ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest); 9 ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest);
10 + ByteArrayOutputStream exportSeparateMealsExcel(QueryOrderDto queryOrderDto);
9 } 11 }
......
...@@ -31,6 +31,7 @@ import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; ...@@ -31,6 +31,7 @@ import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
31 import com.infoloop.tianting.clientcustomerorderservice.OrderTypeEnum; 31 import com.infoloop.tianting.clientcustomerorderservice.OrderTypeEnum;
32 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; 32 import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
33 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByConditionRpcRequest; 33 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByConditionRpcRequest;
34 +import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByConditionRpcResponse;
34 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcRequest; 35 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcRequest;
35 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcResponse; 36 import com.infoloop.tianting.clientcustomerorderservice.QueryClientCustomerOrdersByPaginationRpcResponse;
36 import com.infoloop.tianting.clientcustomerorderservice.QuerySkuSellQuantitiesByStallAndSkuIdsRpcRequest; 37 import com.infoloop.tianting.clientcustomerorderservice.QuerySkuSellQuantitiesByStallAndSkuIdsRpcRequest;
...@@ -57,6 +58,7 @@ import com.infoloop.tianting.model.bo.AddSkusSellQuantityBO; ...@@ -57,6 +58,7 @@ import com.infoloop.tianting.model.bo.AddSkusSellQuantityBO;
57 import com.infoloop.tianting.model.bo.SkuSellQuantityBO; 58 import com.infoloop.tianting.model.bo.SkuSellQuantityBO;
58 import com.infoloop.tianting.model.dto.OperationDTO.BatchOperationDto; 59 import com.infoloop.tianting.model.dto.OperationDTO.BatchOperationDto;
59 import com.infoloop.tianting.model.dto.OperationDTO.SingleOperationDto; 60 import com.infoloop.tianting.model.dto.OperationDTO.SingleOperationDto;
61 +import com.infoloop.tianting.model.dto.OrderDbDTO;
60 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDetailDto; 62 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDetailDto;
61 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDto; 63 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderDto;
62 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderResponse; 64 import com.infoloop.tianting.model.dto.OrderDbDTO.CreateOrderResponse;
...@@ -180,6 +182,8 @@ public class OrderServiceRpcClient { ...@@ -180,6 +182,8 @@ public class OrderServiceRpcClient {
180 .setTableCode(tableCode) 182 .setTableCode(tableCode)
181 .setShouldUpdateRoomNo(updateOrderDto.isShouldUpdateRoomNo()) 183 .setShouldUpdateRoomNo(updateOrderDto.isShouldUpdateRoomNo())
182 .setRoomNo(roomNo) 184 .setRoomNo(roomNo)
185 + .setShouldUpdateAvoidRemark(updateOrderDto.getAvoidRemark() != null)
186 + .setAvoidRemark(updateOrderDto.getAvoidRemark() == null ? "" : updateOrderDto.getAvoidRemark())
183 .build(); 187 .build();
184 final var request = UpdateClientCustomerOrderRpcRequest.newBuilder() 188 final var request = UpdateClientCustomerOrderRpcRequest.newBuilder()
185 .setEnterpriseId(updateOrderDto.getEnterpriseId()) 189 .setEnterpriseId(updateOrderDto.getEnterpriseId())
...@@ -188,7 +192,7 @@ public class OrderServiceRpcClient { ...@@ -188,7 +192,7 @@ public class OrderServiceRpcClient {
188 .setModification(modification) 192 .setModification(modification)
189 .build(); 193 .build();
190 final UpdateClientCustomerOrderRpcResponse updateClientCustomerOrderRpcResponse = orderServiceRpcBlockingStub.updateClientCustomerOrder(request); 194 final UpdateClientCustomerOrderRpcResponse updateClientCustomerOrderRpcResponse = orderServiceRpcBlockingStub.updateClientCustomerOrder(request);
191 - if (updateClientCustomerOrderRpcResponse.getIsUpdated() && updateOrderDto.getStatus() == OrderStatusEnum.ORDER_CANCELED) { 195 + if (updateClientCustomerOrderRpcResponse.getIsUpdated() && updateOrderDto.getStatus() != null && updateOrderDto.getStatus() == OrderStatusEnum.ORDER_CANCELED) {
192 final var orderById = getOrderById(updateOrderDto.getId()); 196 final var orderById = getOrderById(updateOrderDto.getId());
193 if (orderById != null && orderById.getCloseTimeType() == CloseTimeType.IMMEDIATELY) { 197 if (orderById != null && orderById.getCloseTimeType() == CloseTimeType.IMMEDIATELY) {
194 final var orderDetails = getOrderDetailsByOrderId(orderById.getId()); 198 final var orderDetails = getOrderDetailsByOrderId(orderById.getId());
...@@ -484,6 +488,17 @@ public class OrderServiceRpcClient { ...@@ -484,6 +488,17 @@ public class OrderServiceRpcClient {
484 return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request); 488 return orderServiceRpcBlockingStub.queryClientCustomerOrdersByPagination(request);
485 } 489 }
486 490
491 + public QueryClientCustomerOrdersByConditionRpcResponse queryClientCustomerOrdersByCondition(OrderDbDTO.QueryOrderDto queryOrderDto) {
492 + final var request = QueryClientCustomerOrdersByConditionRpcRequest.newBuilder()
493 + .setShouldFilterStatus(true)
494 + .setStatus(queryOrderDto.getStatus())
495 + .setEnterpriseId(queryOrderDto.getEnterpriseId())
496 + .setShouldFilterClientIds(true).addClientIds(queryOrderDto.getClientId())
497 + .setShouldFilterStallIds(true).addAllStallIds(queryOrderDto.getStallIds())
498 + .build();
499 + return orderServiceRpcBlockingStub.queryClientCustomerOrdersByCondition(request);
500 + }
501 +
487 public QueryClientCustomerOrdersByPaginationRpcResponse queryRefundClientCustomerOrdersByPagination( 502 public QueryClientCustomerOrdersByPaginationRpcResponse queryRefundClientCustomerOrdersByPagination(
488 QueryRefundOrderByPaginationDto queryOrderDto) { 503 QueryRefundOrderByPaginationDto queryOrderDto) {
489 final var request = QueryClientCustomerOrdersByPaginationRpcRequest.newBuilder() 504 final var request = QueryClientCustomerOrdersByPaginationRpcRequest.newBuilder()
......
...@@ -6,7 +6,9 @@ import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; ...@@ -6,7 +6,9 @@ import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
6 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse; 6 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
7 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse; 7 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
8 import com.infoloop.tianting.context.LoginContextHolder; 8 import com.infoloop.tianting.context.LoginContextHolder;
9 +import com.infoloop.tianting.menuservice.SingleMenuRpcResponse;
9 import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto; 10 import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto;
11 +import com.infoloop.tianting.model.dto.KdsDTO;
10 import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto; 12 import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto;
11 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDetailDto; 13 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDetailDto;
12 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto; 14 import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto;
...@@ -22,6 +24,7 @@ import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient; ...@@ -22,6 +24,7 @@ import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
22 import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; 24 import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
23 import com.infoloop.tianting.service.client.EnterpriseResourceServiceRpcClient; 25 import com.infoloop.tianting.service.client.EnterpriseResourceServiceRpcClient;
24 import com.infoloop.tianting.service.client.MealServiceRpcClient; 26 import com.infoloop.tianting.service.client.MealServiceRpcClient;
27 +import com.infoloop.tianting.service.client.MenuServiceRpcClient;
25 import com.infoloop.tianting.service.client.OrderServiceRpcClient; 28 import com.infoloop.tianting.service.client.OrderServiceRpcClient;
26 import com.infoloop.tianting.service.client.SkuServiceRpcClient; 29 import com.infoloop.tianting.service.client.SkuServiceRpcClient;
27 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient; 30 import com.infoloop.tianting.service.client.WOperatorServiceRpcClient;
...@@ -33,8 +36,10 @@ import org.springframework.stereotype.Service; ...@@ -33,8 +36,10 @@ import org.springframework.stereotype.Service;
33 36
34 import java.time.LocalDate; 37 import java.time.LocalDate;
35 import java.time.LocalDateTime; 38 import java.time.LocalDateTime;
39 +import java.time.LocalTime;
36 import java.util.ArrayList; 40 import java.util.ArrayList;
37 import java.util.List; 41 import java.util.List;
42 +import java.util.function.Function;
38 import java.util.stream.Collectors; 43 import java.util.stream.Collectors;
39 44
40 @Slf4j 45 @Slf4j
...@@ -49,14 +54,14 @@ public class KdsServiceImpl implements KdsService { ...@@ -49,14 +54,14 @@ public class KdsServiceImpl implements KdsService {
49 private final SkuServiceRpcClient skuServiceRpcClient; 54 private final SkuServiceRpcClient skuServiceRpcClient;
50 private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient; 55 private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
51 private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient; 56 private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
57 + private final MenuServiceRpcClient menuServiceRpcClient;
52 58
53 @Override 59 @Override
54 public List<KdsOrderSkuDto> getOrderDetailBySku(KdsOrderSkuQueryDto queryDto) { 60 public List<KdsOrderSkuDto> getOrderDetailBySku(KdsOrderSkuQueryDto queryDto) {
55 // 获取当日所有的订单 和 订单明细 61 // 获取当日所有的订单 和 订单明细
56 - LocalDate today = LocalDate.now(); 62 + LocalDate today = LocalDate.parse(queryDto.getMealTime(), DateUtil.YYYY_MM_DD);
57 LocalDateTime todayZero = today.atStartOfDay(); 63 LocalDateTime todayZero = today.atStartOfDay();
58 - LocalDate tomorrow = today.plusDays(1); 64 + LocalDateTime todayEnd = today.atTime(LocalTime.MAX);
59 - LocalDateTime tomorrowZero = tomorrow.atStartOfDay();
60 final var operatorLoginInfo = LoginContextHolder.getLoginInfo(); 65 final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
61 boolean shouldFilterStallIds = false; 66 boolean shouldFilterStallIds = false;
62 List<Integer> stallIds = new ArrayList<>(); 67 List<Integer> stallIds = new ArrayList<>();
...@@ -73,7 +78,7 @@ public class KdsServiceImpl implements KdsService { ...@@ -73,7 +78,7 @@ public class KdsServiceImpl implements KdsService {
73 .shouldFilterMealTimeStart(true) 78 .shouldFilterMealTimeStart(true)
74 .mealTimeStart(todayZero) 79 .mealTimeStart(todayZero)
75 .shouldFilterMealTimeEnd(true) 80 .shouldFilterMealTimeEnd(true)
76 - .mealTimeEnd(tomorrowZero) 81 + .mealTimeEnd(todayEnd)
77 .shouldFilterPayStatus(true) 82 .shouldFilterPayStatus(true)
78 .payStatus(PayStatusEnum.SUCCEED) 83 .payStatus(PayStatusEnum.SUCCEED)
79 .build(); 84 .build();
...@@ -118,6 +123,9 @@ public class KdsServiceImpl implements KdsService { ...@@ -118,6 +123,9 @@ public class KdsServiceImpl implements KdsService {
118 .collect(Collectors.toList()); 123 .collect(Collectors.toList());
119 final var skus = skuServiceRpcClient.getDishSkusByIds(skuIds).getResponseList(); 124 final var skus = skuServiceRpcClient.getDishSkusByIds(skuIds).getResponseList();
120 125
126 + final var menuIds = orderList.stream().map(SingleClientCustomerOrderRpcResponse::getMenuId).distinct().toList();
127 + final var menuMap = menuServiceRpcClient.getMenusByIds(operator.getEnterpriseId(), menuIds).getResponsesList().stream().collect(Collectors.toMap(SingleMenuRpcResponse::getId, Function.identity()));
128 +
121 List<KdsOrderSkuDto> kdsOrderSkuList = new ArrayList<>(); 129 List<KdsOrderSkuDto> kdsOrderSkuList = new ArrayList<>();
122 for (Integer menuDetailId : menuDetailIds) { 130 for (Integer menuDetailId : menuDetailIds) {
123 // 找出该menuDetailId 的所有orderDetail 131 // 找出该menuDetailId 的所有orderDetail
...@@ -168,8 +176,11 @@ public class KdsServiceImpl implements KdsService { ...@@ -168,8 +176,11 @@ public class KdsServiceImpl implements KdsService {
168 .count(detail.getCount()) 176 .count(detail.getCount())
169 .orderDetailId(detail.getId()) 177 .orderDetailId(detail.getId())
170 .remark(order.get().getRemark()) 178 .remark(order.get().getRemark())
179 + .avoidRemark(order.get().getAvoidRemark())
171 .orderId(order.get().getId()) 180 .orderId(order.get().getId())
172 .roomNo(order.get().getSyncRoomNo().isEmpty() ? order.get().getRoomNo() : order.get().getSyncRoomNo()) 181 .roomNo(order.get().getSyncRoomNo().isEmpty() ? order.get().getRoomNo() : order.get().getSyncRoomNo())
182 + .menuId(order.get().getMenuId())
183 + .menuName(menuMap.get(order.get().getMenuId()) == null ? "" : menuMap.get(order.get().getMenuId()).getName())
173 .tableCode(order.get().getTableCode()) 184 .tableCode(order.get().getTableCode())
174 .customerNotice(CustomerNotice.builder() 185 .customerNotice(CustomerNotice.builder()
175 .doctors(order.get().getCustomerNoticeJson().getDoctorsList()) 186 .doctors(order.get().getCustomerNoticeJson().getDoctorsList())
...@@ -208,9 +219,9 @@ public class KdsServiceImpl implements KdsService { ...@@ -208,9 +219,9 @@ public class KdsServiceImpl implements KdsService {
208 } 219 }
209 220
210 @Override 221 @Override
211 - public List<KdsMealDetailDto> getMealDetail() { 222 + public List<KdsMealDetailDto> getMealDetail(KdsDTO.KdsMealDetailQueryDto queryDto) {
212 // 获取当日用餐的所有的订单 和 订单明细 223 // 获取当日用餐的所有的订单 和 订单明细
213 - LocalDate today = LocalDate.now(); 224 + LocalDate today = LocalDate.parse(queryDto.getMealTime(), DateUtil.YYYY_MM_DD);
214 LocalDateTime todayZero = today.atStartOfDay(); 225 LocalDateTime todayZero = today.atStartOfDay();
215 LocalDate tomorrow = today.plusDays(1); 226 LocalDate tomorrow = today.plusDays(1);
216 LocalDateTime tomorrowZero = tomorrow.atStartOfDay().minusMinutes(1); 227 LocalDateTime tomorrowZero = tomorrow.atStartOfDay().minusMinutes(1);
...@@ -235,6 +246,8 @@ public class KdsServiceImpl implements KdsService { ...@@ -235,6 +246,8 @@ public class KdsServiceImpl implements KdsService {
235 .mealTimeStart(todayZero) 246 .mealTimeStart(todayZero)
236 .shouldFilterMealTimeEnd(true) 247 .shouldFilterMealTimeEnd(true)
237 .mealTimeEnd(tomorrowZero) 248 .mealTimeEnd(tomorrowZero)
249 + .shouldFilterPayStatus(true)
250 + .payStatus(PayStatusEnum.SUCCEED)
238 .build(); 251 .build();
239 252
240 final var orderList = orderServiceRpcClient.getOrdersByCondition(queryOrderDto); 253 final var orderList = orderServiceRpcClient.getOrdersByCondition(queryOrderDto);
...@@ -281,10 +294,9 @@ public class KdsServiceImpl implements KdsService { ...@@ -281,10 +294,9 @@ public class KdsServiceImpl implements KdsService {
281 @Override 294 @Override
282 public List<KdsOrderLocationDto> getOrderDetailByLocation(KdsOrderLocationQueryDto queryDto) { 295 public List<KdsOrderLocationDto> getOrderDetailByLocation(KdsOrderLocationQueryDto queryDto) {
283 // 获取当日用餐的所有的订单 和 订单明细 296 // 获取当日用餐的所有的订单 和 订单明细
284 - LocalDate today = LocalDate.now(); 297 + LocalDate today = LocalDate.parse(queryDto.getMealTime(), DateUtil.YYYY_MM_DD);
285 LocalDateTime todayZero = today.atStartOfDay(); 298 LocalDateTime todayZero = today.atStartOfDay();
286 - LocalDate tomorrow = today.plusDays(1); 299 + LocalDateTime todayEnd = today.atTime(LocalTime.MAX);
287 - LocalDateTime tomorrowZero = tomorrow.atStartOfDay().minusMinutes(1);
288 300
289 final var operatorLoginInfo = LoginContextHolder.getLoginInfo(); 301 final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
290 302
...@@ -305,7 +317,7 @@ public class KdsServiceImpl implements KdsService { ...@@ -305,7 +317,7 @@ public class KdsServiceImpl implements KdsService {
305 .shouldFilterMealTimeStart(true) 317 .shouldFilterMealTimeStart(true)
306 .mealTimeStart(todayZero) 318 .mealTimeStart(todayZero)
307 .shouldFilterMealTimeEnd(true) 319 .shouldFilterMealTimeEnd(true)
308 - .mealTimeEnd(tomorrowZero) 320 + .mealTimeEnd(todayEnd)
309 .shouldFilterStatus(true) 321 .shouldFilterStatus(true)
310 .status(queryDto.getOrderStatus()) 322 .status(queryDto.getOrderStatus())
311 .shouldFilterPayStatus(true) 323 .shouldFilterPayStatus(true)
...@@ -339,6 +351,12 @@ public class KdsServiceImpl implements KdsService { ...@@ -339,6 +351,12 @@ public class KdsServiceImpl implements KdsService {
339 final var filteredOrderDetailList = orderDetailList.stream() 351 final var filteredOrderDetailList = orderDetailList.stream()
340 .filter(od -> od.getMealId() == queryDto.getMealId() && od.getServeStatus() != ServeStatusEnum.SERVE_REJECT) 352 .filter(od -> od.getMealId() == queryDto.getMealId() && od.getServeStatus() != ServeStatusEnum.SERVE_REJECT)
341 .collect(Collectors.toList()); 353 .collect(Collectors.toList());
354 +
355 +
356 + final var menuIds = orderList.stream().map(SingleClientCustomerOrderRpcResponse::getMenuId).distinct().toList();
357 + final var menuMap = menuServiceRpcClient.getMenusByIds(operator.getEnterpriseId(), menuIds).getResponsesList().stream().collect(Collectors.toMap(SingleMenuRpcResponse::getId, Function.identity()));
358 +
359 +
342 List<KdsOrderLocationDto> kdsOrderLocationList = new ArrayList<>(); 360 List<KdsOrderLocationDto> kdsOrderLocationList = new ArrayList<>();
343 361
344 for (SingleClientCustomerOrderRpcResponse order : orderList) { 362 for (SingleClientCustomerOrderRpcResponse order : orderList) {
...@@ -395,9 +413,12 @@ public class KdsServiceImpl implements KdsService { ...@@ -395,9 +413,12 @@ public class KdsServiceImpl implements KdsService {
395 final var kdsOrder = KdsOrderLocationDto.builder() 413 final var kdsOrder = KdsOrderLocationDto.builder()
396 .totalCount(order.getTotalNum()) 414 .totalCount(order.getTotalNum())
397 .remark(order.getRemark()) 415 .remark(order.getRemark())
416 + .avoidRemark(order.getAvoidRemark())
398 .orderId(order.getId()) 417 .orderId(order.getId())
399 .roomNo(order.getSyncRoomNo().isEmpty() ? order.getRoomNo() : order.getSyncRoomNo()) 418 .roomNo(order.getSyncRoomNo().isEmpty() ? order.getRoomNo() : order.getSyncRoomNo())
400 .tableCode(order.getTableCode()) 419 .tableCode(order.getTableCode())
420 + .menuId(order.getMenuId())
421 + .menuName(menuMap.get(order.getMenuId()) == null ? "" : menuMap.get(order.getMenuId()).getName())
401 .customerNotice(CustomerNotice.builder() 422 .customerNotice(CustomerNotice.builder()
402 .doctors(order.getCustomerNoticeJson().getDoctorsList()) 423 .doctors(order.getCustomerNoticeJson().getDoctorsList())
403 .avoids(order.getCustomerNoticeJson().getAvoidsList()) 424 .avoids(order.getCustomerNoticeJson().getAvoidsList())
......
...@@ -487,6 +487,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -487,6 +487,7 @@ public class OrderServiceImpl implements OrderService {
487 .mealTime(DateUtil.formatDate(r.getMealTime())) 487 .mealTime(DateUtil.formatDate(r.getMealTime()))
488 .orderType(r.getOrderTypeValue()) 488 .orderType(r.getOrderTypeValue())
489 .remark(r.getRemark()) 489 .remark(r.getRemark())
490 + .avoidRemark(r.getAvoidRemark())
490 .isDeleted(r.getIsDeleted()) 491 .isDeleted(r.getIsDeleted())
491 .isRead(r.getIsRead()) 492 .isRead(r.getIsRead())
492 .creationSource(r.getCreationSource().getNumber()) 493 .creationSource(r.getCreationSource().getNumber())
......
1 package com.infoloop.tianting.service.impl; 1 package com.infoloop.tianting.service.impl;
2 2
3 +import cn.hutool.core.date.LocalDateTimeUtil;
4 +import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse;
5 +import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
3 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 6 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
7 +import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
4 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; 8 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
5 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse; 9 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
6 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse; 10 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
11 +import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerRpcResponse;
7 import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse; 12 import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
8 import com.infoloop.tianting.context.LoginContextHolder; 13 import com.infoloop.tianting.context.LoginContextHolder;
9 import com.infoloop.tianting.enums.SettlementDimensionEnum; 14 import com.infoloop.tianting.enums.SettlementDimensionEnum;
...@@ -12,35 +17,53 @@ import com.infoloop.tianting.exception.ErrorCodeEnum; ...@@ -12,35 +17,53 @@ import com.infoloop.tianting.exception.ErrorCodeEnum;
12 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse; 17 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse;
13 import com.infoloop.tianting.menuservice.SingleMenuRpcResponse; 18 import com.infoloop.tianting.menuservice.SingleMenuRpcResponse;
14 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 19 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
20 +import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderDto;
21 +import com.infoloop.tianting.model.dto.SettlementDTO;
22 +import com.infoloop.tianting.model.dto.SettlementDTO.SeparateMealDataDto;
23 +import com.infoloop.tianting.model.dto.SettlementDTO.SeparateMealDetail;
15 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataByMealDto; 24 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataByMealDto;
16 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataDto; 25 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataDto;
17 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto; 26 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto;
18 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto; 27 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto;
19 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto; 28 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto;
29 +import com.infoloop.tianting.model.enums.desc.BaseProtoDescEnum;
30 +import com.infoloop.tianting.model.enums.desc.OnlinePayDescEnum;
20 import com.infoloop.tianting.service.SettlementService; 31 import com.infoloop.tianting.service.SettlementService;
32 +import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
21 import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; 33 import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
22 import com.infoloop.tianting.service.client.MealServiceRpcClient; 34 import com.infoloop.tianting.service.client.MealServiceRpcClient;
23 import com.infoloop.tianting.service.client.MenuServiceRpcClient; 35 import com.infoloop.tianting.service.client.MenuServiceRpcClient;
24 import com.infoloop.tianting.service.client.OrderServiceRpcClient; 36 import com.infoloop.tianting.service.client.OrderServiceRpcClient;
25 import com.infoloop.tianting.service.client.SkuServiceRpcClient; 37 import com.infoloop.tianting.service.client.SkuServiceRpcClient;
38 +import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse;
26 import com.infoloop.tianting.utils.DateUtil; 39 import com.infoloop.tianting.utils.DateUtil;
27 import lombok.RequiredArgsConstructor; 40 import lombok.RequiredArgsConstructor;
28 import lombok.extern.slf4j.Slf4j; 41 import lombok.extern.slf4j.Slf4j;
42 +import org.apache.poi.ss.usermodel.BorderStyle;
29 import org.apache.poi.ss.usermodel.Cell; 43 import org.apache.poi.ss.usermodel.Cell;
44 +import org.apache.poi.ss.usermodel.CellStyle;
45 +import org.apache.poi.ss.usermodel.Font;
46 +import org.apache.poi.ss.usermodel.HorizontalAlignment;
47 +import org.apache.poi.ss.usermodel.IndexedColors;
30 import org.apache.poi.ss.usermodel.Row; 48 import org.apache.poi.ss.usermodel.Row;
31 import org.apache.poi.ss.usermodel.Sheet; 49 import org.apache.poi.ss.usermodel.Sheet;
50 +import org.apache.poi.ss.usermodel.VerticalAlignment;
32 import org.apache.poi.ss.usermodel.Workbook; 51 import org.apache.poi.ss.usermodel.Workbook;
33 import org.apache.poi.ss.util.CellRangeAddress; 52 import org.apache.poi.ss.util.CellRangeAddress;
53 +import org.apache.poi.ss.util.RegionUtil;
34 import org.apache.poi.xssf.usermodel.XSSFWorkbook; 54 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
35 import org.springframework.beans.factory.annotation.Autowired; 55 import org.springframework.beans.factory.annotation.Autowired;
36 import org.springframework.stereotype.Service; 56 import org.springframework.stereotype.Service;
37 57
38 import java.io.ByteArrayOutputStream; 58 import java.io.ByteArrayOutputStream;
39 import java.io.IOException; 59 import java.io.IOException;
60 +import java.math.BigDecimal;
61 +import java.math.RoundingMode;
40 import java.time.LocalDate; 62 import java.time.LocalDate;
41 import java.time.LocalDateTime; 63 import java.time.LocalDateTime;
42 import java.time.temporal.ChronoUnit; 64 import java.time.temporal.ChronoUnit;
43 import java.util.ArrayList; 65 import java.util.ArrayList;
66 +import java.util.Collections;
44 import java.util.Comparator; 67 import java.util.Comparator;
45 import java.util.HashMap; 68 import java.util.HashMap;
46 import java.util.List; 69 import java.util.List;
...@@ -57,6 +80,7 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -57,6 +80,7 @@ public class SettlementServiceImpl implements SettlementService {
57 private final SkuServiceRpcClient skuServiceRpcClient; 80 private final SkuServiceRpcClient skuServiceRpcClient;
58 private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient; 81 private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
59 private final MealServiceRpcClient mealServiceRpcClient; 82 private final MealServiceRpcClient mealServiceRpcClient;
83 + private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
60 84
61 public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto) 85 public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto)
62 throws IOException { 86 throws IOException {
...@@ -272,9 +296,557 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -272,9 +296,557 @@ public class SettlementServiceImpl implements SettlementService {
272 public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) { 296 public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) {
273 if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) { 297 if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) {
274 return generateOrderSettlementExcelBySku(settlementRequest); 298 return generateOrderSettlementExcelBySku(settlementRequest);
275 - } else { 299 + } else if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_MEAL)) {
276 return generateOrderSettlementExcelByMeal(settlementRequest); 300 return generateOrderSettlementExcelByMeal(settlementRequest);
301 + } else if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_ORDER)) {
302 + return generateOrderSettlementExcelByOrder(settlementRequest);
277 } 303 }
304 + return null;
305 + }
306 +
307 + private ByteArrayOutputStream generateOrderSettlementExcelByOrder(SettlementRequestDto settlementRequest) {
308 + // 参数校验
309 + if (settlementRequest == null || settlementRequest.getTimeStart() == null || settlementRequest.getTimeEnd() == null) {
310 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
311 + }
312 +
313 + // 计算日期范围
314 + final var startDate = settlementRequest.getTimeStart().plusHours(8).toLocalDate().atStartOfDay();
315 + final var endDate = settlementRequest.getTimeEnd().plusHours(8).toLocalDate().plusDays(1).atStartOfDay();
316 +
317 + // 获取企业ID
318 + final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
319 + final int enterpriseId = LoginContextHolder.hasLogin() ? operatorLoginInfo.getEnterpriseId() : settlementRequest.getEnterpriseId();
320 +
321 + // 构建查询条件
322 + final var queryOrderDto = QueryOrderByConditionDto.builder()
323 + .enterpriseId(enterpriseId)
324 + .shouldFilterCreatedAtTimeStart(true)
325 + .createdAtTimeStart(startDate)
326 + .shouldFilterCreatedAtTimeEnd(true)
327 + .createdAtTimeEnd(endDate)
328 + .shouldFilterStallIds(settlementRequest.getStallIds() != null && !settlementRequest.getStallIds().isEmpty())
329 + .stallIds(settlementRequest.getStallIds() != null ? settlementRequest.getStallIds() : Collections.emptyList())
330 + .build();
331 +
332 + // 查询订单列表
333 + final var orderList = orderServiceRpcClient.getOrdersByCondition(queryOrderDto);
334 + if (orderList == null || orderList.isEmpty()) {
335 + log.warn("未查询到订单数据,enterpriseId: {}, startDate: {}, endDate: {}", enterpriseId, startDate, endDate);
336 + return createEmptyExcelByOrder();
337 + }
338 +
339 + // 筛选有效订单ID
340 + List<Integer> orderIds = orderList.stream()
341 + .filter(Objects::nonNull)
342 + .filter(o -> {
343 + // 在线支付订单需要支付成功
344 + if (o.getOnlinePay() != null && o.getOnlinePay() == OnlinePayEnum.ONLINE) {
345 + return o.getPayStatus() != null && o.getPayStatus() == PayStatusEnum.SUCCEED;
346 + } else {
347 + // 非在线支付订单需要未取消
348 + return o.getStatus() != null && o.getStatus() != OrderStatusEnum.ORDER_CANCELED;
349 + }
350 + })
351 + .map(SingleClientCustomerOrderRpcResponse::getId)
352 + .filter(Objects::nonNull)
353 + .distinct()
354 + .collect(Collectors.toList());
355 +
356 + if (orderIds.isEmpty()) {
357 + log.warn("筛选后无有效订单,enterpriseId: {}", enterpriseId);
358 + return createEmptyExcelByOrder();
359 + }
360 +
361 + // 构建订单映射
362 + final var orderMap = orderList.stream()
363 + .filter(Objects::nonNull)
364 + .filter(o -> o.getId() != 0)
365 + .collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1));
366 +
367 + // 查询订单详情
368 + final var orderDetailList = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
369 + if (orderDetailList == null || orderDetailList.isEmpty()) {
370 + log.warn("未查询到订单详情数据,orderIds: {}", orderIds);
371 + return createEmptyExcelByOrder();
372 + }
373 +
374 + // 订单详情按订单ID分组
375 + final var orderDetailGroupByOrderId = orderDetailList.stream()
376 + .filter(Objects::nonNull)
377 + .filter(d -> d.getServeStatus() != null && !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
378 + .collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
379 +
380 + // 获取SKU数据
381 + List<Integer> skuIds = orderDetailList.stream()
382 + .filter(Objects::nonNull)
383 + .filter(d -> d.getServeStatus() != null && !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
384 + .map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
385 + .filter(Objects::nonNull)
386 + .distinct()
387 + .collect(Collectors.toList());
388 +
389 + final var skuResponse = skuServiceRpcClient.getDishSkusByIds(skuIds);
390 + final List<SingleDishSkuByIdsRpcResponse> skus = skuResponse != null ? skuResponse.getResponseList() : new ArrayList<>();
391 + final var skuMap = skus.stream()
392 + .filter(Objects::nonNull)
393 + .filter(s -> s.getId() != 0)
394 + .collect(Collectors.toMap(SingleDishSkuByIdsRpcResponse::getId, s -> s, (s1, s2) -> s1));
395 +
396 + // 获取餐别数据
397 + final var mealResponse = mealServiceRpcClient.getAllMeals(enterpriseId);
398 + final List<SingleMealRpcResponse> meals = mealResponse != null ? mealResponse.getResponsesList() : new ArrayList<>();
399 + final var mealMap = meals.stream()
400 + .filter(Objects::nonNull)
401 + .filter(m -> m.getId() != 0)
402 + .collect(Collectors.toMap(SingleMealRpcResponse::getId, m -> m, (m1, m2) -> m1));
403 +
404 + // 获取菜单数据
405 + List<Integer> menuIds = orderList.stream()
406 + .filter(Objects::nonNull)
407 + .map(SingleClientCustomerOrderRpcResponse::getMenuId)
408 + .filter(id -> id != 0)
409 + .distinct()
410 + .collect(Collectors.toList());
411 +
412 + final var menuResponse = menuServiceRpcClient.getMenusByIds(enterpriseId, menuIds);
413 + final List<SingleMenuRpcResponse> menuList = menuResponse != null ? menuResponse.getResponsesList() : new ArrayList<>();
414 + final var menuMap = menuList.stream()
415 + .filter(Objects::nonNull)
416 + .filter(m -> m.getId() != 0)
417 + .collect(Collectors.toMap(SingleMenuRpcResponse::getId, m -> m, (m1, m2) -> m1));
418 +
419 + // 获取菜单详情数据
420 + final var menuDetailResponse = menuServiceRpcClient.queryMenuDetailsByMenuIds(enterpriseId, menuIds);
421 + final List<SingleMenuDetailRpcResponse> menuDetailList = menuDetailResponse != null ? menuDetailResponse.getResponsesList() : new ArrayList<>();
422 + final var menuDetailMap = menuDetailList.stream()
423 + .filter(Objects::nonNull)
424 + .filter(m -> m.getId() != 0)
425 + .collect(Collectors.toMap(SingleMenuDetailRpcResponse::getId, m -> m, (m1, m2) -> m1));
426 +
427 + // 获取客户数据
428 + List<Integer> customerIds = orderList.stream()
429 + .filter(Objects::nonNull)
430 + .map(SingleClientCustomerOrderRpcResponse::getCustomerId)
431 + .filter(id -> id != 0)
432 + .distinct()
433 + .collect(Collectors.toList());
434 +
435 + final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(enterpriseId, customerIds);
436 + final List<SingleClientCustomerRpcResponse> customers = customerResponse != null ? customerResponse.getResponsesList() : new ArrayList<>();
437 + final var customerMap = customers.stream()
438 + .filter(Objects::nonNull)
439 + .filter(c -> c.getId() != 0)
440 + .collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1));
441 +
442 + // 构建结算订单明细
443 + final var classifyOrders = new ArrayList<SettlementDTO.SettlementOrderDetail>();
444 + for (Integer orderId : orderIds) {
445 + final var orderDetails = orderDetailGroupByOrderId.getOrDefault(orderId, Collections.emptyList());
446 + final var order = orderMap.get(orderId);
447 +
448 + // 订单为空则跳过
449 + if (order == null) {
450 + log.warn("订单不存在,orderId: {}", orderId);
451 + continue;
452 + }
453 +
454 + // 获取菜单信息
455 + final var menu = menuMap.get(order.getMenuId());
456 + final String menuName = menu != null ? menu.getName() : "";
457 +
458 + // 获取客户信息
459 + final var customer = customerMap.get(order.getCustomerId());
460 + final String customerName = customer != null ? customer.getName() : "";
461 + final String hisCustomerNo = customer != null ? customer.getHISCustomerNo() : "";
462 +
463 + // 处理每个订单详情
464 + for (SingleClientCustomerOrderDetailRpcResponse orderDetail : orderDetails) {
465 + if (orderDetail == null) {
466 + continue;
467 + }
468 +
469 + // 安全获取餐别名称
470 + String mealName = getMealNameSafely(orderDetail, menuDetailMap, mealMap);
471 +
472 + // 安全获取SKU名称
473 + String skuName = getSkuNameSafely(orderDetail, skuMap);
474 +
475 + // 安全获取房间号
476 + String roomNo = getRoomNoSafely(order);
477 +
478 + // 安全获取忌口和医嘱
479 + List<String> avoids = getAvoidsSafely(order);
480 + List<String> doctors = getDoctorsSafely(order);
481 +
482 + // 安全获取在线支付描述
483 + String onlinePayDesc = getOnlinePayDescSafely(order);
484 +
485 + // 构建订单详情
486 + SettlementDTO.SettlementOrderDetail settlementOrderDetail = SettlementDTO.SettlementOrderDetail.builder()
487 + .mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "")
488 + .code(order.getOrderCode() != null ? order.getOrderCode() : "")
489 + .mealName(mealName)
490 + .roomNo(roomNo)
491 + .customerName(customerName)
492 + .HISCustomerNo(hisCustomerNo)
493 + .avoids(avoids)
494 + .doctors(doctors)
495 + .menuName(menuName)
496 + .skuName(skuName)
497 + .count(orderDetail.getCount() != 0 ? orderDetail.getCount() : 0)
498 + .price(calculatePrice(orderDetail.getPrice()))
499 + .totalPrice(calculateTotalPrice(orderDetail.getPrice(), orderDetail.getCount()))
500 + .remark(order.getRemark() != null ? order.getRemark() : "")
501 + .avoidRemark(order.getAvoidRemark() != null ? order.getAvoidRemark() : "")
502 + .onlinePay(onlinePayDesc)
503 + .build();
504 + classifyOrders.add(settlementOrderDetail);
505 + }
506 + }
507 +
508 + // 构建结算数据
509 + final var settlementDataByOrderDto = SettlementDTO.SettlementDataByOrderDto.builder()
510 + .classifyOrders(classifyOrders)
511 + .build();
512 +
513 + // 生成Excel
514 + try {
515 + return writeToExcelByOrder(settlementDataByOrderDto);
516 + } catch (IOException e) {
517 + log.error("生成按订单结算Excel失败", e);
518 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
519 + }
520 + }
521 +
522 + /**
523 + * 安全获取餐别名称
524 + */
525 + private String getMealNameSafely(SingleClientCustomerOrderDetailRpcResponse orderDetail,
526 + Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap,
527 + Map<Integer, SingleMealRpcResponse> mealMap) {
528 + if (orderDetail == null || orderDetail.getMenuDetailId() == 0) {
529 + return "";
530 + }
531 +
532 + final var menuDetail = menuDetailMap.get(orderDetail.getMenuDetailId());
533 + if (menuDetail == null || menuDetail.getMealId() == 0) {
534 + return "";
535 + }
536 +
537 + final var meal = mealMap.get(menuDetail.getMealId());
538 + return meal != null && meal.getName() != null ? meal.getName() : "";
539 + }
540 +
541 + /**
542 + * 安全获取SKU名称
543 + */
544 + private String getSkuNameSafely(SingleClientCustomerOrderDetailRpcResponse orderDetail,
545 + Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) {
546 + if (orderDetail == null || orderDetail.getSkuId() == 0) {
547 + return "";
548 + }
549 +
550 + final var sku = skuMap.get(orderDetail.getSkuId());
551 + return sku != null && sku.getName() != null ? sku.getName() : "";
552 + }
553 +
554 + /**
555 + * 安全获取房间号
556 + */
557 + private String getRoomNoSafely(SingleClientCustomerOrderRpcResponse order) {
558 + if (order == null) {
559 + return "";
560 + }
561 +
562 + String syncRoomNo = order.getSyncRoomNo();
563 + if (syncRoomNo != null && !syncRoomNo.isEmpty()) {
564 + return syncRoomNo;
565 + }
566 +
567 + String roomNo = order.getRoomNo();
568 + return roomNo != null ? roomNo : "";
569 + }
570 +
571 + /**
572 + * 安全获取忌口列表
573 + */
574 + private List<String> getAvoidsSafely(SingleClientCustomerOrderRpcResponse order) {
575 + if (order == null || order.getCustomerNoticeJson() == null) {
576 + return Collections.emptyList();
577 + }
578 +
579 + List<String> avoids = order.getCustomerNoticeJson().getAvoidsList();
580 + return avoids != null ? avoids : Collections.emptyList();
581 + }
582 +
583 + /**
584 + * 安全获取医嘱列表
585 + */
586 + private List<String> getDoctorsSafely(SingleClientCustomerOrderRpcResponse order) {
587 + if (order == null || order.getCustomerNoticeJson() == null) {
588 + return Collections.emptyList();
589 + }
590 +
591 + List<String> doctors = order.getCustomerNoticeJson().getDoctorsList();
592 + return doctors != null ? doctors : Collections.emptyList();
593 + }
594 +
595 + /**
596 + * 安全获取在线支付描述
597 + */
598 + private String getOnlinePayDescSafely(SingleClientCustomerOrderRpcResponse order) {
599 + if (order == null || order.getOnlinePay() == null) {
600 + return "";
601 + }
602 +
603 + try {
604 + String desc = BaseProtoDescEnum.getDescByProtoEnum(order.getOnlinePay(), OnlinePayDescEnum.class);
605 + return desc != null ? desc : "";
606 + } catch (Exception e) {
607 + log.warn("获取在线支付描述失败,orderId: {}", order.getId(), e);
608 + return "";
609 + }
610 + }
611 +
612 + /**
613 + * 计算单价
614 + */
615 + private BigDecimal calculatePrice(Integer price) {
616 + if (price == null) {
617 + return BigDecimal.ZERO;
618 + }
619 + return new BigDecimal(price).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
620 + }
621 +
622 + /**
623 + * 计算总价
624 + */
625 + private BigDecimal calculateTotalPrice(Integer price, Integer count) {
626 + if (price == null || count == null) {
627 + return BigDecimal.ZERO;
628 + }
629 + return new BigDecimal(price)
630 + .multiply(new BigDecimal(count))
631 + .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
632 + }
633 +
634 + /**
635 + * 创建空的订单Excel
636 + */
637 + private ByteArrayOutputStream createEmptyExcelByOrder() {
638 + try {
639 + final var emptyData = SettlementDTO.SettlementDataByOrderDto.builder()
640 + .classifyOrders(Collections.emptyList())
641 + .build();
642 + return writeToExcelByOrder(emptyData);
643 + } catch (IOException e) {
644 + log.error("创建空Excel失败", e);
645 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
646 + }
647 + }
648 +
649 + /**
650 + * 按订单维度生成Excel
651 + */
652 + private static ByteArrayOutputStream writeToExcelByOrder(SettlementDTO.SettlementDataByOrderDto settlementDataDto)
653 + throws IOException {
654 + Workbook workbook = new XSSFWorkbook();
655 + Sheet sheet = workbook.createSheet("客人结算");
656 +
657 + // 创建表头样式(黑色边框)
658 + CellStyle headerStyle = workbook.createCellStyle();
659 + headerStyle.setBorderTop(BorderStyle.THIN);
660 + headerStyle.setBorderBottom(BorderStyle.THIN);
661 + headerStyle.setBorderLeft(BorderStyle.THIN);
662 + headerStyle.setBorderRight(BorderStyle.THIN);
663 + headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
664 + headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
665 + headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
666 + headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
667 +
668 + // 创建数据行样式(浅灰色边框)
669 + CellStyle dataStyle = workbook.createCellStyle();
670 + dataStyle.setBorderTop(BorderStyle.THIN);
671 + dataStyle.setBorderBottom(BorderStyle.THIN);
672 + dataStyle.setBorderLeft(BorderStyle.THIN);
673 + dataStyle.setBorderRight(BorderStyle.THIN);
674 + dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
675 + dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
676 + dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
677 + dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
678 +
679 + int rowNum = 0;
680 +
681 + // 创建表头
682 + Row titleRow = sheet.createRow(rowNum++);
683 + int columnNum = 0;
684 +
685 + Cell cell0 = titleRow.createCell(columnNum++);
686 + cell0.setCellValue("用餐时间");
687 + cell0.setCellStyle(headerStyle);
688 +
689 + Cell cell1 = titleRow.createCell(columnNum++);
690 + cell1.setCellValue("订单号");
691 + cell1.setCellStyle(headerStyle);
692 +
693 + Cell cell2 = titleRow.createCell(columnNum++);
694 + cell2.setCellValue("餐别");
695 + cell2.setCellStyle(headerStyle);
696 +
697 + Cell cell3 = titleRow.createCell(columnNum++);
698 + cell3.setCellValue("房间号");
699 + cell3.setCellStyle(headerStyle);
700 +
701 + Cell cell4 = titleRow.createCell(columnNum++);
702 + cell4.setCellValue("客户姓名");
703 + cell4.setCellStyle(headerStyle);
704 +
705 + Cell cell5 = titleRow.createCell(columnNum++);
706 + cell5.setCellValue("客户腕带号");
707 + cell5.setCellStyle(headerStyle);
708 +
709 + Cell cell6 = titleRow.createCell(columnNum++);
710 + cell6.setCellValue("忌口信息");
711 + cell6.setCellStyle(headerStyle);
712 +
713 + Cell cell7 = titleRow.createCell(columnNum++);
714 + cell7.setCellValue("医嘱信息");
715 + cell7.setCellStyle(headerStyle);
716 +
717 + Cell cell8 = titleRow.createCell(columnNum++);
718 + cell8.setCellValue("餐单名称");
719 + cell8.setCellStyle(headerStyle);
720 +
721 + Cell cell9 = titleRow.createCell(columnNum++);
722 + cell9.setCellValue("菜品名称");
723 + cell9.setCellStyle(headerStyle);
724 +
725 + Cell cell10 = titleRow.createCell(columnNum++);
726 + cell10.setCellValue("菜品份数");
727 + cell10.setCellStyle(headerStyle);
728 +
729 + Cell cell11 = titleRow.createCell(columnNum++);
730 + cell11.setCellValue("菜品单价");
731 + cell11.setCellStyle(headerStyle);
732 +
733 + Cell cell12 = titleRow.createCell(columnNum++);
734 + cell12.setCellValue("菜品金额");
735 + cell12.setCellStyle(headerStyle);
736 +
737 + Cell cell13 = titleRow.createCell(columnNum++);
738 + cell13.setCellValue("备注");
739 + cell13.setCellStyle(headerStyle);
740 +
741 + Cell cell14 = titleRow.createCell(columnNum++);
742 + cell14.setCellValue("支付方式");
743 + cell14.setCellStyle(headerStyle);
744 +
745 + // 填充数据
746 + final var classifyOrders = settlementDataDto.getClassifyOrders();
747 + if (classifyOrders != null) {
748 + for (SettlementDTO.SettlementOrderDetail orderDetail : classifyOrders) {
749 + Row dataRow = sheet.createRow(rowNum++);
750 + columnNum = 0;
751 +
752 + Cell dataCell0 = dataRow.createCell(columnNum++);
753 + dataCell0.setCellValue(orderDetail.getMealTime() != null ? orderDetail.getMealTime() : "");
754 + dataCell0.setCellStyle(dataStyle);
755 +
756 + Cell dataCell1 = dataRow.createCell(columnNum++);
757 + dataCell1.setCellValue(orderDetail.getCode() != null ? orderDetail.getCode() : "");
758 + dataCell1.setCellStyle(dataStyle);
759 +
760 + Cell dataCell2 = dataRow.createCell(columnNum++);
761 + dataCell2.setCellValue(orderDetail.getMealName() != null ? orderDetail.getMealName() : "");
762 + dataCell2.setCellStyle(dataStyle);
763 +
764 + Cell dataCell3 = dataRow.createCell(columnNum++);
765 + dataCell3.setCellValue(orderDetail.getRoomNo() != null ? orderDetail.getRoomNo() : "");
766 + dataCell3.setCellStyle(dataStyle);
767 +
768 + Cell dataCell4 = dataRow.createCell(columnNum++);
769 + dataCell4.setCellValue(orderDetail.getCustomerName() != null ? orderDetail.getCustomerName() : "");
770 + dataCell4.setCellStyle(dataStyle);
771 +
772 + Cell dataCell5 = dataRow.createCell(columnNum++);
773 + dataCell5.setCellValue(orderDetail.getHISCustomerNo() != null ? orderDetail.getHISCustomerNo() : "");
774 + dataCell5.setCellStyle(dataStyle);
775 +
776 + // 忌口列表转字符串
777 + String avoidsStr = orderDetail.getAvoids() != null ? String.join(", ", orderDetail.getAvoids()) : "";
778 + Cell dataCell6 = dataRow.createCell(columnNum++);
779 + dataCell6.setCellValue(avoidsStr);
780 + dataCell6.setCellStyle(dataStyle);
781 +
782 + // 医嘱列表转字符串
783 + String doctorsStr = orderDetail.getDoctors() != null ? String.join(", ", orderDetail.getDoctors()) : "";
784 + Cell dataCell7 = dataRow.createCell(columnNum++);
785 + dataCell7.setCellValue(doctorsStr);
786 + dataCell7.setCellStyle(dataStyle);
787 +
788 + Cell dataCell8 = dataRow.createCell(columnNum++);
789 + dataCell8.setCellValue(orderDetail.getMenuName() != null ? orderDetail.getMenuName() : "");
790 + dataCell8.setCellStyle(dataStyle);
791 +
792 + Cell dataCell9 = dataRow.createCell(columnNum++);
793 + dataCell9.setCellValue(orderDetail.getSkuName() != null ? orderDetail.getSkuName() : "");
794 + dataCell9.setCellStyle(dataStyle);
795 +
796 + Cell dataCell10 = dataRow.createCell(columnNum++);
797 + dataCell10.setCellValue(orderDetail.getCount() != null ? orderDetail.getCount() : 0);
798 + dataCell10.setCellStyle(dataStyle);
799 +
800 + // 价格
801 + Cell dataCell11 = dataRow.createCell(columnNum++);
802 + if (orderDetail.getPrice() != null) {
803 + dataCell11.setCellValue(orderDetail.getPrice().doubleValue());
804 + } else {
805 + dataCell11.setCellValue(0.0);
806 + }
807 + dataCell11.setCellStyle(dataStyle);
808 +
809 + // 总价
810 + Cell dataCell12 = dataRow.createCell(columnNum++);
811 + if (orderDetail.getTotalPrice() != null) {
812 + dataCell12.setCellValue(orderDetail.getTotalPrice().doubleValue());
813 + } else {
814 + dataCell12.setCellValue(0.0);
815 + }
816 + dataCell12.setCellStyle(dataStyle);
817 +
818 + // 合并备注和忌口备注,用分号分割,备注在前
819 + String remark = orderDetail.getRemark() != null ? orderDetail.getRemark() : "";
820 + String avoidRemark = orderDetail.getAvoidRemark() != null ? orderDetail.getAvoidRemark() : "";
821 + String combinedRemark = "";
822 + if (!remark.isEmpty() && !avoidRemark.isEmpty()) {
823 + combinedRemark = remark + ";" + avoidRemark;
824 + } else if (!remark.isEmpty()) {
825 + combinedRemark = remark;
826 + } else if (!avoidRemark.isEmpty()) {
827 + combinedRemark = avoidRemark;
828 + }
829 + Cell dataCell13 = dataRow.createCell(columnNum++);
830 + dataCell13.setCellValue(combinedRemark);
831 + dataCell13.setCellStyle(dataStyle);
832 +
833 + Cell dataCell14 = dataRow.createCell(columnNum++);
834 + dataCell14.setCellValue(orderDetail.getOnlinePay() != null ? orderDetail.getOnlinePay() : "");
835 + dataCell14.setCellStyle(dataStyle);
836 + }
837 + }
838 +
839 + // 自动调整列宽
840 + for (int i = 0; i < 15; i++) {
841 + sheet.autoSizeColumn(i);
842 + }
843 +
844 + // 将工作簿内容写入字节数组输出流
845 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
846 + workbook.write(outputStream);
847 + workbook.close();
848 +
849 + return outputStream;
278 } 850 }
279 851
280 public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) { 852 public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) {
...@@ -541,4 +1113,334 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -541,4 +1113,334 @@ public class SettlementServiceImpl implements SettlementService {
541 1113
542 } 1114 }
543 1115
1116 + @Override
1117 + public ByteArrayOutputStream exportSeparateMealsExcel(QueryOrderDto queryOrderDto) {
1118 + // 参数校验
1119 + if (queryOrderDto == null) {
1120 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1121 + }
1122 +
1123 + final int enterpriseId = queryOrderDto.getEnterpriseId();
1124 +
1125 + // 查询订单列表
1126 + final var queryClientCustomerOrdersByConditionRpcResponse = orderServiceRpcClient.queryClientCustomerOrdersByCondition(queryOrderDto);
1127 + final var orderList = queryClientCustomerOrdersByConditionRpcResponse.getResponsesList();
1128 + if (orderList.isEmpty()) {
1129 + log.warn("未查询到订单数据,enterpriseId: {}", enterpriseId);
1130 + return null;
1131 + }
1132 +
1133 + // 获取订单IDs
1134 + List<Integer> orderIds = orderList.stream()
1135 + .map(SingleClientCustomerOrderRpcResponse::getId)
1136 + .collect(Collectors.toList());
1137 +
1138 + // 构建订单映射
1139 + final var orderMap = orderList.stream()
1140 + .filter(Objects::nonNull)
1141 + .filter(o -> o.getId() != 0)
1142 + .collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1));
1143 +
1144 + // 查询订单详情
1145 + final var orderDetailList = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
1146 + if (orderDetailList == null || orderDetailList.isEmpty()) {
1147 + log.warn("未查询到订单详情数据,orderIds: {}", orderIds);
1148 + return null;
1149 + }
1150 +
1151 + // 订单详情按订单ID分组
1152 + final var orderDetailGroupByOrderId = orderDetailList.stream()
1153 + .filter(Objects::nonNull)
1154 + .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
1155 + .collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
1156 +
1157 + // 获取SKU数据
1158 + List<Integer> skuIds = orderDetailList.stream()
1159 + .filter(Objects::nonNull)
1160 + .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
1161 + .map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
1162 + .distinct()
1163 + .collect(Collectors.toList());
1164 +
1165 + final var skuResponse = skuServiceRpcClient.getDishSkusByIds(skuIds);
1166 + final List<SingleDishSkuByIdsRpcResponse> skus = skuResponse != null ? skuResponse.getResponseList() : new ArrayList<>();
1167 + final var skuMap = skus.stream()
1168 + .collect(Collectors.toMap(SingleDishSkuByIdsRpcResponse::getId, s -> s, (s1, s2) -> s1));
1169 +
1170 + // 获取餐别数据
1171 + final var mealResponse = mealServiceRpcClient.getAllMeals(enterpriseId);
1172 + final List<SingleMealRpcResponse> meals = mealResponse != null ? mealResponse.getResponsesList() : new ArrayList<>();
1173 + final var mealMap = meals.stream()
1174 + .filter(Objects::nonNull)
1175 + .filter(m -> m.getId() != 0)
1176 + .collect(Collectors.toMap(SingleMealRpcResponse::getId, m -> m, (m1, m2) -> m1));
1177 +
1178 + // 获取菜单数据
1179 + List<Integer> menuIds = orderList.stream()
1180 + .map(SingleClientCustomerOrderRpcResponse::getMenuId)
1181 + .distinct()
1182 + .collect(Collectors.toList());
1183 +
1184 + final var menuResponse = menuServiceRpcClient.getMenusByIds(enterpriseId, menuIds);
1185 + final List<SingleMenuRpcResponse> menuList = menuResponse != null ? menuResponse.getResponsesList() : new ArrayList<>();
1186 + final var menuMap = menuList.stream()
1187 + .collect(Collectors.toMap(SingleMenuRpcResponse::getId, m -> m, (m1, m2) -> m1));
1188 +
1189 + // 获取菜单详情数据
1190 + final var menuDetailResponse = menuServiceRpcClient.queryMenuDetailsByMenuIds(enterpriseId, menuIds);
1191 + final List<SingleMenuDetailRpcResponse> menuDetailList = menuDetailResponse != null ? menuDetailResponse.getResponsesList() : new ArrayList<>();
1192 + final var menuDetailMap = menuDetailList.stream()
1193 + .collect(Collectors.toMap(SingleMenuDetailRpcResponse::getId, m -> m, (m1, m2) -> m1));
1194 +
1195 + // 获取客户数据
1196 + List<Integer> customerIds = orderList.stream()
1197 + .map(SingleClientCustomerOrderRpcResponse::getCustomerId)
1198 + .filter(id -> id != 0)
1199 + .distinct()
1200 + .collect(Collectors.toList());
1201 +
1202 + final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(enterpriseId, customerIds);
1203 + final List<SingleClientCustomerRpcResponse> customers = customerResponse != null ? customerResponse.getResponsesList() : new ArrayList<>();
1204 + final var customerMap = customers.stream()
1205 + .collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1));
1206 +
1207 + // 构建分餐表明细
1208 + final var mealDetails = new ArrayList<SeparateMealDetail>();
1209 + for (Integer orderId : orderIds) {
1210 + final var orderDetails = orderDetailGroupByOrderId.getOrDefault(orderId, Collections.emptyList());
1211 + final var order = orderMap.get(orderId);
1212 +
1213 + // 订单为空则跳过
1214 + if (order == null) {
1215 + log.warn("订单不存在,orderId: {}", orderId);
1216 + continue;
1217 + }
1218 +
1219 + // 获取菜单信息
1220 + final var menu = menuMap.get(order.getMenuId());
1221 + final String menuName = menu != null ? menu.getName() : "";
1222 +
1223 + // 获取客户信息
1224 + final var customer = customerMap.get(order.getCustomerId());
1225 + final String customerName = customer != null ? customer.getName() : "";
1226 +
1227 + // 安全获取房间号
1228 + String roomNo = getRoomNoSafely(order);
1229 +
1230 + // 处理每个订单详情
1231 + for (SingleClientCustomerOrderDetailRpcResponse orderDetail : orderDetails) {
1232 + if (orderDetail == null) {
1233 + continue;
1234 + }
1235 +
1236 + // 安全获取餐别名称
1237 + String mealName = getMealNameSafely(orderDetail, menuDetailMap, mealMap);
1238 +
1239 + // 安全获取SKU名称
1240 + String skuName = getSkuNameSafely(orderDetail, skuMap);
1241 +
1242 + // 安全获取忌口信息(列表转字符串)
1243 + List<String> avoidsList = getAvoidsSafely(order);
1244 + String avoidsStr = String.join(", ", avoidsList);
1245 +
1246 + String remark = order.getRemark();
1247 + String avoidRemark = order.getAvoidRemark();
1248 + String combinedRemark = "";
1249 + if (!remark.isEmpty() && !avoidRemark.isEmpty()) {
1250 + combinedRemark = remark + ";" + avoidRemark;
1251 + } else if (!remark.isEmpty()) {
1252 + combinedRemark = remark;
1253 + } else if (!avoidRemark.isEmpty()) {
1254 + combinedRemark = avoidRemark;
1255 + }
1256 +
1257 + // 构建分餐表明细
1258 + SeparateMealDetail mealDetail = SeparateMealDetail.builder()
1259 + .orderId(orderId)
1260 + .mealName(mealName)
1261 + .roomNo(roomNo)
1262 + .customerName(customerName)
1263 + .menuName(menuName)
1264 + .skuName(skuName)
1265 + .count(orderDetail.getCount() != 0 ? orderDetail.getCount() : 0)
1266 + .avoids(avoidsStr)
1267 + .remark(combinedRemark)
1268 + .build();
1269 + mealDetails.add(mealDetail);
1270 + }
1271 + }
1272 +
1273 + // 构建分餐表数据
1274 + final var separateMealDataDto = SeparateMealDataDto.builder()
1275 + .mealDetails(mealDetails)
1276 + .build();
1277 +
1278 + // 生成Excel
1279 + try {
1280 + return writeToExcelBySeparateMeal(separateMealDataDto);
1281 + } catch (IOException e) {
1282 + log.error("生成分餐表Excel失败", e);
1283 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1284 + }
1285 + }
1286 +
1287 + /**
1288 + * 生成分餐表Excel
1289 + */
1290 + private static ByteArrayOutputStream writeToExcelBySeparateMeal(SeparateMealDataDto separateMealDataDto)
1291 + throws IOException {
1292 + Workbook workbook = new XSSFWorkbook();
1293 + Sheet sheet = workbook.createSheet("分餐表");
1294 +
1295 + // 创建标题样式(合并单元格标题)
1296 + CellStyle titleStyle = workbook.createCellStyle();
1297 + titleStyle.setAlignment(HorizontalAlignment.CENTER);
1298 + titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
1299 + titleStyle.setBorderTop(BorderStyle.THIN);
1300 + titleStyle.setBorderBottom(BorderStyle.THIN);
1301 + titleStyle.setBorderLeft(BorderStyle.THIN);
1302 + titleStyle.setBorderRight(BorderStyle.THIN);
1303 + titleStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
1304 + titleStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
1305 + titleStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
1306 + titleStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
1307 + Font titleFont = workbook.createFont();
1308 + titleFont.setBold(true);
1309 + titleFont.setFontHeightInPoints((short) 16);
1310 + titleStyle.setFont(titleFont);
1311 +
1312 + // 创建表头样式(黑色边框)
1313 + CellStyle headerStyle = workbook.createCellStyle();
1314 + headerStyle.setBorderTop(BorderStyle.THIN);
1315 + headerStyle.setBorderBottom(BorderStyle.THIN);
1316 + headerStyle.setBorderLeft(BorderStyle.THIN);
1317 + headerStyle.setBorderRight(BorderStyle.THIN);
1318 + headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
1319 + headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
1320 + headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
1321 + headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
1322 +
1323 + // 创建数据行样式(浅灰色边框)
1324 + CellStyle dataStyle = workbook.createCellStyle();
1325 + dataStyle.setBorderTop(BorderStyle.THIN);
1326 + dataStyle.setBorderBottom(BorderStyle.THIN);
1327 + dataStyle.setBorderLeft(BorderStyle.THIN);
1328 + dataStyle.setBorderRight(BorderStyle.THIN);
1329 + dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1330 + dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1331 + dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1332 + dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1333 +
1334 + int rowNum = 0;
1335 +
1336 + // 第一行:创建合并单元格标题
1337 + Row mainTitleRow = sheet.createRow(rowNum++);
1338 + Cell mainTitleCell = mainTitleRow.createCell(0);
1339 + mainTitleCell.setCellValue("住院客户分餐表");
1340 + mainTitleCell.setCellStyle(titleStyle);
1341 +
1342 + // 合并第一行的8列
1343 + CellRangeAddress titleRegion = new CellRangeAddress(0, 0, 0, 7);
1344 + sheet.addMergedRegion(titleRegion);
1345 +
1346 + // 为合并区域设置边框
1347 + RegionUtil.setBorderTop(BorderStyle.THIN, titleRegion, sheet);
1348 + RegionUtil.setBorderBottom(BorderStyle.THIN, titleRegion, sheet);
1349 + RegionUtil.setBorderLeft(BorderStyle.THIN, titleRegion, sheet);
1350 + RegionUtil.setBorderRight(BorderStyle.THIN, titleRegion, sheet);
1351 + RegionUtil.setTopBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1352 + RegionUtil.setBottomBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1353 + RegionUtil.setLeftBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1354 + RegionUtil.setRightBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1355 +
1356 + // 第二行:创建表头
1357 + Row titleRow = sheet.createRow(rowNum++);
1358 + int columnNum = 0;
1359 +
1360 + Cell cell0 = titleRow.createCell(columnNum++);
1361 + cell0.setCellValue("餐别");
1362 + cell0.setCellStyle(headerStyle);
1363 +
1364 + Cell cell1 = titleRow.createCell(columnNum++);
1365 + cell1.setCellValue("房间号");
1366 + cell1.setCellStyle(headerStyle);
1367 +
1368 + Cell cell2 = titleRow.createCell(columnNum++);
1369 + cell2.setCellValue("客户姓名");
1370 + cell2.setCellStyle(headerStyle);
1371 +
1372 + Cell cell3 = titleRow.createCell(columnNum++);
1373 + cell3.setCellValue("餐单名称");
1374 + cell3.setCellStyle(headerStyle);
1375 +
1376 + Cell cell4 = titleRow.createCell(columnNum++);
1377 + cell4.setCellValue("菜品名称");
1378 + cell4.setCellStyle(headerStyle);
1379 +
1380 + Cell cell5 = titleRow.createCell(columnNum++);
1381 + cell5.setCellValue("菜品数量");
1382 + cell5.setCellStyle(headerStyle);
1383 +
1384 + Cell cell6 = titleRow.createCell(columnNum++);
1385 + cell6.setCellValue("忌口信息");
1386 + cell6.setCellStyle(headerStyle);
1387 +
1388 + Cell cell7 = titleRow.createCell(columnNum++);
1389 + cell7.setCellValue("备注");
1390 + cell7.setCellStyle(headerStyle);
1391 +
1392 + // 填充数据
1393 + final var mealDetails = separateMealDataDto.getMealDetails();
1394 + if (mealDetails != null) {
1395 + for (SeparateMealDetail mealDetail : mealDetails) {
1396 + Row dataRow = sheet.createRow(rowNum++);
1397 + columnNum = 0;
1398 +
1399 + Cell dataCell0 = dataRow.createCell(columnNum++);
1400 + dataCell0.setCellValue(mealDetail.getMealName() != null ? mealDetail.getMealName() : "");
1401 + dataCell0.setCellStyle(dataStyle);
1402 +
1403 + Cell dataCell1 = dataRow.createCell(columnNum++);
1404 + dataCell1.setCellValue(mealDetail.getRoomNo() != null ? mealDetail.getRoomNo() : "");
1405 + dataCell1.setCellStyle(dataStyle);
1406 +
1407 + Cell dataCell2 = dataRow.createCell(columnNum++);
1408 + dataCell2.setCellValue(mealDetail.getCustomerName() != null ? mealDetail.getCustomerName() : "");
1409 + dataCell2.setCellStyle(dataStyle);
1410 +
1411 + Cell dataCell3 = dataRow.createCell(columnNum++);
1412 + dataCell3.setCellValue(mealDetail.getMenuName() != null ? mealDetail.getMenuName() : "");
1413 + dataCell3.setCellStyle(dataStyle);
1414 +
1415 + Cell dataCell4 = dataRow.createCell(columnNum++);
1416 + dataCell4.setCellValue(mealDetail.getSkuName() != null ? mealDetail.getSkuName() : "");
1417 + dataCell4.setCellStyle(dataStyle);
1418 +
1419 + Cell dataCell5 = dataRow.createCell(columnNum++);
1420 + dataCell5.setCellValue(mealDetail.getCount() != null ? mealDetail.getCount() : 0);
1421 + dataCell5.setCellStyle(dataStyle);
1422 +
1423 + Cell dataCell6 = dataRow.createCell(columnNum++);
1424 + dataCell6.setCellValue(mealDetail.getAvoids() != null ? mealDetail.getAvoids() : "");
1425 + dataCell6.setCellStyle(dataStyle);
1426 +
1427 + Cell dataCell7 = dataRow.createCell(columnNum++);
1428 + dataCell7.setCellValue(mealDetail.getRemark() != null ? mealDetail.getRemark() : "");
1429 + dataCell7.setCellStyle(dataStyle);
1430 + }
1431 + }
1432 +
1433 + // 自动调整列宽
1434 + for (int i = 0; i < 8; i++) {
1435 + sheet.autoSizeColumn(i);
1436 + }
1437 +
1438 + // 将工作簿内容写入字节数组输出流
1439 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
1440 + workbook.write(outputStream);
1441 + workbook.close();
1442 +
1443 + return outputStream;
1444 + }
1445 +
544 } 1446 }
......
...@@ -2,6 +2,8 @@ package com.infoloop.tianting.streamController; ...@@ -2,6 +2,8 @@ package com.infoloop.tianting.streamController;
2 2
3 import cn.dev33.satoken.annotation.SaIgnore; 3 import cn.dev33.satoken.annotation.SaIgnore;
4 import com.github.xiaoymin.knife4j.annotations.ApiSupport; 4 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
5 +import com.infoloop.tianting.enums.SettlementDimensionEnum;
6 +import com.infoloop.tianting.model.dto.OrderDbDTO;
5 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto; 7 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto;
6 import com.infoloop.tianting.service.SettlementService; 8 import com.infoloop.tianting.service.SettlementService;
7 import io.swagger.annotations.Api; 9 import io.swagger.annotations.Api;
...@@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
21 23
22 import javax.validation.Valid; 24 import javax.validation.Valid;
23 import java.io.ByteArrayOutputStream; 25 import java.io.ByteArrayOutputStream;
26 +import java.time.format.DateTimeFormatter;
24 27
25 @Api(tags = "结算") 28 @Api(tags = "结算")
26 @ApiSupport(order = 0) 29 @ApiSupport(order = 0)
...@@ -29,35 +32,59 @@ import java.io.ByteArrayOutputStream; ...@@ -29,35 +32,59 @@ import java.io.ByteArrayOutputStream;
29 @RestController 32 @RestController
30 @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 33 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
31 public class SettlementController { 34 public class SettlementController {
32 - private final SettlementService settlementService; 35 + private final SettlementService settlementService;
33 - 36 +
34 - @SaIgnore 37 + @SaIgnore
35 - @ApiOperation(value = "企业端结算账单生成excel") 38 + @ApiOperation(value = "企业端结算账单生成excel")
36 - @PostMapping("/enterprise/settlement/generate-excel") 39 + @PostMapping("/enterprise/settlement/generate-excel")
37 - @ResponseStatus(HttpStatus.OK) 40 + @ResponseStatus(HttpStatus.OK)
38 - public ResponseEntity<byte[]> enterpriseSettlementGenerateExcel(@Valid @RequestBody SettlementRequestDto settlementRequestDto) { 41 + public ResponseEntity<byte[]> enterpriseSettlementGenerateExcel(@Valid @RequestBody SettlementRequestDto settlementRequestDto) {
39 - ByteArrayOutputStream outputStream = settlementService.generateOrderSettlementExcel(settlementRequestDto); 42 + ByteArrayOutputStream outputStream = settlementService.generateOrderSettlementExcel(settlementRequestDto);
40 - HttpHeaders headers = new HttpHeaders(); 43 + HttpHeaders headers = new HttpHeaders();
41 - headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); 44 + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
42 - headers.setContentDispositionFormData("attachment", "订单数据.xlsx"); 45 + headers.setContentDispositionFormData("attachment", "订单数据.xlsx");
43 - return ResponseEntity.ok() 46 + return ResponseEntity.ok()
44 - .headers(headers) 47 + .headers(headers)
45 - .body(outputStream.toByteArray()); 48 + .body(outputStream.toByteArray());
46 - } 49 + }
47 50
48 @ApiOperation(value = "结算账单生成excel") 51 @ApiOperation(value = "结算账单生成excel")
49 @PostMapping("/settlement/generate-excel") 52 @PostMapping("/settlement/generate-excel")
50 @ResponseStatus(HttpStatus.OK) 53 @ResponseStatus(HttpStatus.OK)
51 - public ResponseEntity<byte[]> settlementGenerateExcel( 54 + public ResponseEntity<byte[]> settlementGenerateExcel(@Valid @RequestBody SettlementRequestDto settlementRequestDto) {
52 - @Valid @RequestBody SettlementRequestDto settlementRequestDto) { 55 + ByteArrayOutputStream outputStream = settlementService.generateOrderSettlementExcel(
53 - ByteArrayOutputStream outputStream = settlementService.generateOrderSettlementExcel( 56 + settlementRequestDto);
54 - settlementRequestDto); 57 +
55 - HttpHeaders headers = new HttpHeaders(); 58 + String fileName;
56 - headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); 59 + if (settlementRequestDto.getDimension() == SettlementDimensionEnum.BY_ORDER) {
57 - headers.setContentDispositionFormData("attachment", "订单数据.xlsx"); 60 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
58 - 61 + String startDate = settlementRequestDto.getTimeStart().format(formatter);
59 - return ResponseEntity.ok() 62 + String endDate = settlementRequestDto.getTimeEnd().format(formatter);
60 - .headers(headers) 63 + fileName = String.format("结算报表_%s_%s.xlsx", startDate, endDate);
61 - .body(outputStream.toByteArray()); 64 + } else {
65 + fileName = "订单数据.xlsx";
66 + }
67 +
68 + HttpHeaders headers = new HttpHeaders();
69 + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
70 + headers.setContentDispositionFormData("attachment", fileName);
71 +
72 + return ResponseEntity.ok()
73 + .headers(headers)
74 + .body(outputStream.toByteArray());
75 + }
76 +
77 + @ApiOperation(value = "院区端订单导出")
78 + @PostMapping("/separateMeals/export")
79 + @ResponseStatus(HttpStatus.OK)
80 + public ResponseEntity<byte[]> exportSeparateMeals(@Valid @RequestBody OrderDbDTO.QueryOrderDto queryOrderDto) {
81 + ByteArrayOutputStream outputStream = settlementService.exportSeparateMealsExcel(queryOrderDto);
82 + HttpHeaders headers = new HttpHeaders();
83 + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
84 + headers.setContentDispositionFormData("attachment", "分餐表.xlsx");
85 + return ResponseEntity.ok()
86 + .headers(headers)
87 + .body(outputStream.toByteArray());
62 } 88 }
89 +
63 } 90 }
......
...@@ -89,6 +89,11 @@ enum OnlinePayEnum { ...@@ -89,6 +89,11 @@ enum OnlinePayEnum {
89 LEAVE_HOSPITAL = 3;//出院 89 LEAVE_HOSPITAL = 3;//出院
90 EMPLOYEE_CARD = 4; //员工卡 90 EMPLOYEE_CARD = 4; //员工卡
91 PAPER_VERIFICATION = 5; //纸质核销 91 PAPER_VERIFICATION = 5; //纸质核销
92 + CASH = 6;//现金
93 + MEAL_CARD = 7;//餐卡
94 + BAND_CARD = 8;//银行卡
95 + ALIPAY = 9;//支付宝
96 + WECHATPAY = 10;//微信支付
92 } 97 }
93 98
94 enum ServeStatusEnum { 99 enum ServeStatusEnum {
...@@ -141,6 +146,7 @@ message SingleClientCustomerOrderRpcResponse { ...@@ -141,6 +146,7 @@ message SingleClientCustomerOrderRpcResponse {
141 bool isAllocation = 35; 146 bool isAllocation = 35;
142 string syncRoomNo = 36; 147 string syncRoomNo = 36;
143 bool isCanceled = 37; 148 bool isCanceled = 37;
149 + string avoidRemark = 38;
144 } 150 }
145 151
146 message GetClientCustomerOrderByIdRpcRequest { 152 message GetClientCustomerOrderByIdRpcRequest {
...@@ -385,6 +391,8 @@ message ClientCustomerOrderModification { ...@@ -385,6 +391,8 @@ message ClientCustomerOrderModification {
385 string syncRoomNo = 55; 391 string syncRoomNo = 55;
386 bool shouldUpdateIsCanceled = 56; 392 bool shouldUpdateIsCanceled = 56;
387 bool isCanceled = 57; 393 bool isCanceled = 57;
394 + bool shouldUpdateAvoidRemark = 58;
395 + string avoidRemark = 59;
388 } 396 }
389 397
390 message UpdateClientCustomerOrderRpcRequest { 398 message UpdateClientCustomerOrderRpcRequest {
......