zhuyifan

Merge branch 'feature/2025-10-23' into 'master'

Feature/2025 10 23



See merge request !11
...@@ -57,6 +57,8 @@ public class LoginContextHolder { ...@@ -57,6 +57,8 @@ public class LoginContextHolder {
57 57
58 private Integer enterpriseId; 58 private Integer enterpriseId;
59 59
60 + private Integer clientId;
61 +
60 private String name; 62 private String name;
61 63
62 @Builder.Default 64 @Builder.Default
......
...@@ -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 /**
......
...@@ -93,7 +93,7 @@ public class LoginInterceptor implements HandlerInterceptor { ...@@ -93,7 +93,7 @@ public class LoginInterceptor implements HandlerInterceptor {
93 ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN)); 93 ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
94 return false; 94 return false;
95 } 95 }
96 - builder.id(loginId).enterpriseId(enterpriseId).name(customer.getResponse().getName()).openId(openId).loginSource(LoginSourceEnum.CUSTOMER); 96 + builder.id(loginId).enterpriseId(enterpriseId).clientId(customer.getResponse().getClientId()).name(customer.getResponse().getName()).openId(openId).loginSource(LoginSourceEnum.CUSTOMER);
97 return true; 97 return true;
98 } else if (loginSource.equals(LoginSourceEnum.OPERATOR.getValue())){ 98 } else if (loginSource.equals(LoginSourceEnum.OPERATOR.getValue())){
99 final var loginId = StpUtil.getLoginIdAsInt(); 99 final var loginId = StpUtil.getLoginIdAsInt();
...@@ -103,7 +103,7 @@ public class LoginInterceptor implements HandlerInterceptor { ...@@ -103,7 +103,7 @@ public class LoginInterceptor implements HandlerInterceptor {
103 ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN)); 103 ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
104 return false; 104 return false;
105 } 105 }
106 - builder.id(loginId).enterpriseId(enterpriseId).name(opeartor.getName()).loginSource(LoginSourceEnum.OPERATOR); 106 + builder.id(loginId).enterpriseId(enterpriseId).clientId(opeartor.getClientId()).name(opeartor.getName()).loginSource(LoginSourceEnum.OPERATOR);
107 return true; 107 return true;
108 } else if (loginSource.equals(LoginSourceEnum.KDS.getValue())) { 108 } else if (loginSource.equals(LoginSourceEnum.KDS.getValue())) {
109 final var loginId = StpUtil.getLoginIdAsInt(); 109 final var loginId = StpUtil.getLoginIdAsInt();
......
...@@ -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,6 +114,16 @@ public class KdsDTO { ...@@ -107,6 +114,16 @@ 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;
118 + }
119 +
120 + @Data
121 + @Builder
122 + @AllArgsConstructor
123 + @NoArgsConstructor
124 + @ApiModel(description = "KdsMealDetailQueryDto")
125 + public static class KdsMealDetailQueryDto {
126 + private String mealTime;
110 } 127 }
111 128
112 @Data 129 @Data
......
...@@ -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 + }
79 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 + }
80 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 + }
81 122
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, "POS-银行卡"),
16 + ALIPAY(OnlinePayEnum.ALIPAY, "POS-支付宝"),
17 + WECHATPAY(OnlinePayEnum.WECHATPAY, "POS-微信");
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.collection.CollectionUtil;
4 +import cn.hutool.core.date.LocalDateTimeUtil;
5 +import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse;
6 +import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
3 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; 7 import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
8 +import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum;
4 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; 9 import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
5 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse; 10 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
6 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse; 11 import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
12 +import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerRpcResponse;
7 import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse; 13 import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
8 import com.infoloop.tianting.context.LoginContextHolder; 14 import com.infoloop.tianting.context.LoginContextHolder;
9 import com.infoloop.tianting.enums.SettlementDimensionEnum; 15 import com.infoloop.tianting.enums.SettlementDimensionEnum;
...@@ -12,35 +18,55 @@ import com.infoloop.tianting.exception.ErrorCodeEnum; ...@@ -12,35 +18,55 @@ import com.infoloop.tianting.exception.ErrorCodeEnum;
12 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse; 18 import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse;
13 import com.infoloop.tianting.menuservice.SingleMenuRpcResponse; 19 import com.infoloop.tianting.menuservice.SingleMenuRpcResponse;
14 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto; 20 import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
21 +import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderDto;
22 +import com.infoloop.tianting.model.dto.SettlementDTO;
23 +import com.infoloop.tianting.model.dto.SettlementDTO.SeparateMealDataDto;
24 +import com.infoloop.tianting.model.dto.SettlementDTO.SeparateMealDetail;
15 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataByMealDto; 25 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataByMealDto;
16 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataDto; 26 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataDto;
17 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto; 27 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto;
18 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto; 28 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto;
19 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto; 29 import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto;
30 +import com.infoloop.tianting.model.enums.desc.BaseProtoDescEnum;
31 +import com.infoloop.tianting.model.enums.desc.OnlinePayDescEnum;
20 import com.infoloop.tianting.service.SettlementService; 32 import com.infoloop.tianting.service.SettlementService;
33 +import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
21 import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; 34 import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
35 +import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient;
22 import com.infoloop.tianting.service.client.MealServiceRpcClient; 36 import com.infoloop.tianting.service.client.MealServiceRpcClient;
23 import com.infoloop.tianting.service.client.MenuServiceRpcClient; 37 import com.infoloop.tianting.service.client.MenuServiceRpcClient;
24 import com.infoloop.tianting.service.client.OrderServiceRpcClient; 38 import com.infoloop.tianting.service.client.OrderServiceRpcClient;
25 import com.infoloop.tianting.service.client.SkuServiceRpcClient; 39 import com.infoloop.tianting.service.client.SkuServiceRpcClient;
40 +import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse;
26 import com.infoloop.tianting.utils.DateUtil; 41 import com.infoloop.tianting.utils.DateUtil;
27 import lombok.RequiredArgsConstructor; 42 import lombok.RequiredArgsConstructor;
28 import lombok.extern.slf4j.Slf4j; 43 import lombok.extern.slf4j.Slf4j;
44 +import org.apache.poi.ss.usermodel.BorderStyle;
29 import org.apache.poi.ss.usermodel.Cell; 45 import org.apache.poi.ss.usermodel.Cell;
46 +import org.apache.poi.ss.usermodel.CellStyle;
47 +import org.apache.poi.ss.usermodel.Font;
48 +import org.apache.poi.ss.usermodel.HorizontalAlignment;
49 +import org.apache.poi.ss.usermodel.IndexedColors;
30 import org.apache.poi.ss.usermodel.Row; 50 import org.apache.poi.ss.usermodel.Row;
31 import org.apache.poi.ss.usermodel.Sheet; 51 import org.apache.poi.ss.usermodel.Sheet;
52 +import org.apache.poi.ss.usermodel.VerticalAlignment;
32 import org.apache.poi.ss.usermodel.Workbook; 53 import org.apache.poi.ss.usermodel.Workbook;
33 import org.apache.poi.ss.util.CellRangeAddress; 54 import org.apache.poi.ss.util.CellRangeAddress;
55 +import org.apache.poi.ss.util.RegionUtil;
34 import org.apache.poi.xssf.usermodel.XSSFWorkbook; 56 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
35 import org.springframework.beans.factory.annotation.Autowired; 57 import org.springframework.beans.factory.annotation.Autowired;
36 import org.springframework.stereotype.Service; 58 import org.springframework.stereotype.Service;
37 59
38 import java.io.ByteArrayOutputStream; 60 import java.io.ByteArrayOutputStream;
39 import java.io.IOException; 61 import java.io.IOException;
62 +import java.math.BigDecimal;
63 +import java.math.RoundingMode;
40 import java.time.LocalDate; 64 import java.time.LocalDate;
41 import java.time.LocalDateTime; 65 import java.time.LocalDateTime;
66 +import java.time.ZoneId;
42 import java.time.temporal.ChronoUnit; 67 import java.time.temporal.ChronoUnit;
43 import java.util.ArrayList; 68 import java.util.ArrayList;
69 +import java.util.Collections;
44 import java.util.Comparator; 70 import java.util.Comparator;
45 import java.util.HashMap; 71 import java.util.HashMap;
46 import java.util.List; 72 import java.util.List;
...@@ -57,6 +83,8 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -57,6 +83,8 @@ public class SettlementServiceImpl implements SettlementService {
57 private final SkuServiceRpcClient skuServiceRpcClient; 83 private final SkuServiceRpcClient skuServiceRpcClient;
58 private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient; 84 private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
59 private final MealServiceRpcClient mealServiceRpcClient; 85 private final MealServiceRpcClient mealServiceRpcClient;
86 + private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
87 + private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;
60 88
61 public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto) 89 public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto)
62 throws IOException { 90 throws IOException {
...@@ -272,11 +300,569 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -272,11 +300,569 @@ public class SettlementServiceImpl implements SettlementService {
272 public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) { 300 public ByteArrayOutputStream generateOrderSettlementExcel(SettlementRequestDto settlementRequest) {
273 if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) { 301 if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_SKU)) {
274 return generateOrderSettlementExcelBySku(settlementRequest); 302 return generateOrderSettlementExcelBySku(settlementRequest);
275 - } else { 303 + } else if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_MEAL)) {
276 return generateOrderSettlementExcelByMeal(settlementRequest); 304 return generateOrderSettlementExcelByMeal(settlementRequest);
305 + } else if (settlementRequest.getDimension().equals(SettlementDimensionEnum.BY_ORDER)) {
306 + return generateOrderSettlementExcelByOrder(settlementRequest);
307 + }
308 + return null;
309 + }
310 +
311 + private ByteArrayOutputStream generateOrderSettlementExcelByOrder(SettlementRequestDto settlementRequest) {
312 + // 参数校验
313 + if (settlementRequest == null || settlementRequest.getTimeStart() == null || settlementRequest.getTimeEnd() == null) {
314 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
315 + }
316 +
317 + final var loginInfo = LoginContextHolder.getLoginInfo();
318 + final var userResources = clientResourceTagServiceRpcClient.getUserResources(loginInfo.getEnterpriseId(), loginInfo.getClientId(), loginInfo.getId());
319 +
320 + // 计算日期范围
321 + final var startDate = settlementRequest.getTimeStart().plusHours(8).toLocalDate().atStartOfDay();
322 + final var endDate = settlementRequest.getTimeEnd()
323 + .plusHours(8)
324 + .toLocalDate()
325 + .atTime(23, 59, 59, 999_000_000);
326 +
327 + // 获取企业ID
328 + final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
329 + final int enterpriseId = LoginContextHolder.hasLogin() ? operatorLoginInfo.getEnterpriseId() : settlementRequest.getEnterpriseId();
330 +
331 + final var stallIds = new ArrayList<Integer>();
332 + if (CollectionUtil.isEmpty(settlementRequest.getStallIds())) {
333 + stallIds.addAll(userResources.getStallIdsList());
334 + } else {
335 + stallIds.addAll(settlementRequest.getStallIds());
336 + }
337 +
338 + // 构建查询条件
339 + final var queryOrderDto = QueryOrderByConditionDto.builder()
340 + .enterpriseId(enterpriseId)
341 + .shouldFilterMealTimeStart(true)
342 + .mealTimeStart(startDate)
343 + .shouldFilterMealTimeEnd(true)
344 + .mealTimeEnd(endDate)
345 + .shouldFilterStallIds(true)
346 + .stallIds(stallIds)
347 + .build();
348 +
349 + // 查询订单列表
350 + final var orderList = orderServiceRpcClient.getOrdersByCondition(queryOrderDto);
351 + if (orderList == null || orderList.isEmpty()) {
352 + log.warn("未查询到订单数据,enterpriseId: {}, startDate: {}, endDate: {}", enterpriseId, startDate, endDate);
353 + return createEmptyExcelByOrder();
354 + }
355 +
356 + // 筛选有效订单ID
357 + List<Integer> orderIds = orderList.stream()
358 + .filter(Objects::nonNull)
359 + .filter(o -> {
360 + // 在线支付订单需要支付成功
361 + if (o.getOnlinePay() == OnlinePayEnum.ONLINE) {
362 + return o.getPayStatus() == PayStatusEnum.SUCCEED;
363 + } else {
364 + // 非在线支付订单需要未取消
365 + return o.getStatus() != OrderStatusEnum.ORDER_CANCELED;
366 + }
367 + })
368 + .map(SingleClientCustomerOrderRpcResponse::getId)
369 + .distinct()
370 + .collect(Collectors.toList());
371 +
372 + if (orderIds.isEmpty()) {
373 + log.warn("筛选后无有效订单,enterpriseId: {}", enterpriseId);
374 + return createEmptyExcelByOrder();
375 + }
376 +
377 + // 构建订单映射
378 + final var orderMap = orderList.stream()
379 + .filter(o -> o.getId() != 0)
380 + .collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1));
381 +
382 + // 查询订单详情
383 + final var orderDetailList = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
384 + if (orderDetailList == null || orderDetailList.isEmpty()) {
385 + log.warn("未查询到订单详情数据,orderIds: {}", orderIds);
386 + return createEmptyExcelByOrder();
387 + }
388 +
389 + // 订单详情按订单ID分组
390 + final var orderDetailGroupByOrderId = orderDetailList.stream()
391 + .filter(Objects::nonNull)
392 + .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
393 + .collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
394 +
395 + // 获取SKU数据
396 + List<Integer> skuIds = orderDetailList.stream()
397 + .filter(Objects::nonNull)
398 + .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
399 + .map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
400 + .distinct()
401 + .collect(Collectors.toList());
402 +
403 + final var skuResponse = skuServiceRpcClient.getDishSkusByIds(skuIds);
404 + final List<SingleDishSkuByIdsRpcResponse> skus = skuResponse != null ? skuResponse.getResponseList() : new ArrayList<>();
405 + final var skuMap = skus.stream()
406 + .filter(Objects::nonNull)
407 + .filter(s -> s.getId() != 0)
408 + .collect(Collectors.toMap(SingleDishSkuByIdsRpcResponse::getId, s -> s, (s1, s2) -> s1));
409 +
410 + // 获取餐别数据
411 + final var mealResponse = mealServiceRpcClient.getAllMeals(enterpriseId);
412 + final List<SingleMealRpcResponse> meals = mealResponse != null ? mealResponse.getResponsesList() : new ArrayList<>();
413 + final var mealMap = meals.stream()
414 + .filter(Objects::nonNull)
415 + .filter(m -> m.getId() != 0)
416 + .collect(Collectors.toMap(SingleMealRpcResponse::getId, m -> m, (m1, m2) -> m1));
417 +
418 + // 获取菜单数据
419 + List<Integer> menuIds = orderList.stream()
420 + .filter(Objects::nonNull)
421 + .map(SingleClientCustomerOrderRpcResponse::getMenuId)
422 + .filter(id -> id != 0)
423 + .distinct()
424 + .collect(Collectors.toList());
425 +
426 + final var menuResponse = menuServiceRpcClient.getMenusByIds(enterpriseId, menuIds);
427 + final List<SingleMenuRpcResponse> menuList = menuResponse != null ? menuResponse.getResponsesList() : new ArrayList<>();
428 + final var menuMap = menuList.stream()
429 + .filter(Objects::nonNull)
430 + .filter(m -> m.getId() != 0)
431 + .collect(Collectors.toMap(SingleMenuRpcResponse::getId, m -> m, (m1, m2) -> m1));
432 +
433 + // 获取菜单详情数据
434 + final var menuDetailResponse = menuServiceRpcClient.queryMenuDetailsByMenuIds(enterpriseId, menuIds);
435 + final List<SingleMenuDetailRpcResponse> menuDetailList = menuDetailResponse != null ? menuDetailResponse.getResponsesList() : new ArrayList<>();
436 + final var menuDetailMap = menuDetailList.stream()
437 + .filter(Objects::nonNull)
438 + .filter(m -> m.getId() != 0)
439 + .collect(Collectors.toMap(SingleMenuDetailRpcResponse::getId, m -> m, (m1, m2) -> m1));
440 +
441 + // 获取客户数据
442 + List<Integer> customerIds = orderList.stream()
443 + .filter(Objects::nonNull)
444 + .map(SingleClientCustomerOrderRpcResponse::getCustomerId)
445 + .filter(id -> id != 0)
446 + .distinct()
447 + .collect(Collectors.toList());
448 +
449 + final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(enterpriseId, customerIds);
450 + final List<SingleClientCustomerRpcResponse> customers = customerResponse != null ? customerResponse.getResponsesList() : new ArrayList<>();
451 + final var customerMap = customers.stream()
452 + .filter(Objects::nonNull)
453 + .filter(c -> c.getId() != 0)
454 + .collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1));
455 +
456 + // 构建结算订单明细
457 + final var classifyOrders = new ArrayList<SettlementDTO.SettlementOrderDetail>();
458 + for (Integer orderId : orderIds) {
459 + final var orderDetails = orderDetailGroupByOrderId.getOrDefault(orderId, Collections.emptyList());
460 + final var order = orderMap.get(orderId);
461 +
462 + // 订单为空则跳过
463 + if (order == null) {
464 + log.warn("订单不存在,orderId: {}", orderId);
465 + continue;
466 + }
467 +
468 + // 获取菜单信息
469 + final var menu = menuMap.get(order.getMenuId());
470 + final String menuName = menu != null ? menu.getName() : "";
471 +
472 + // 获取客户信息
473 + final var customer = customerMap.get(order.getCustomerId());
474 + final String customerName = customer != null ? customer.getName() : "";
475 + final String hisCustomerNo = customer != null ? customer.getHISCustomerNo() : "";
476 +
477 + // 处理每个订单详情
478 + for (SingleClientCustomerOrderDetailRpcResponse orderDetail : orderDetails) {
479 + if (orderDetail == null) {
480 + continue;
481 + }
482 +
483 + // 安全获取餐别名称
484 + String mealName = getMealNameSafely(orderDetail, menuDetailMap, mealMap);
485 +
486 + // 安全获取SKU名称
487 + String skuName = getSkuNameSafely(orderDetail, skuMap);
488 +
489 + // 安全获取房间号
490 + String roomNo = getRoomNoSafely(order);
491 +
492 + // 安全获取忌口和医嘱
493 + List<String> avoids = getAvoidsSafely(order);
494 + List<String> doctors = getDoctorsSafely(order);
495 +
496 + // 安全获取在线支付描述
497 + String onlinePayDesc = getOnlinePayDescSafely(order);
498 +
499 + // 构建订单详情
500 + order.getOrderCode();
501 + order.getRemark();
502 + order.getAvoidRemark();
503 + SettlementDTO.SettlementOrderDetail settlementOrderDetail = SettlementDTO.SettlementOrderDetail.builder()
504 + .mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "")
505 + .code(order.getOrderCode())
506 + .mealName(mealName)
507 + .roomNo(roomNo)
508 + .customerName(customerName)
509 + .HISCustomerNo(hisCustomerNo)
510 + .avoids(avoids)
511 + .doctors(doctors)
512 + .menuName(menuName)
513 + .skuName(skuName)
514 + .count(orderDetail.getCount() != 0 ? orderDetail.getCount() : 0)
515 + .price(calculatePrice(orderDetail.getPrice()))
516 + .totalPrice(calculateTotalPrice(orderDetail.getPrice(), orderDetail.getCount()))
517 + .remark(order.getRemark())
518 + .avoidRemark(order.getAvoidRemark())
519 + .onlinePay(onlinePayDesc)
520 + .build();
521 + classifyOrders.add(settlementOrderDetail);
522 + }
523 + }
524 +
525 + // 构建结算数据
526 + final var settlementDataByOrderDto = SettlementDTO.SettlementDataByOrderDto.builder()
527 + .classifyOrders(classifyOrders)
528 + .build();
529 +
530 + // 生成Excel
531 + try {
532 + return writeToExcelByOrder(settlementDataByOrderDto);
533 + } catch (IOException e) {
534 + log.error("生成按订单结算Excel失败", e);
535 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
536 + }
537 + }
538 +
539 + /**
540 + * 安全获取餐别名称
541 + */
542 + private String getMealNameSafely(SingleClientCustomerOrderDetailRpcResponse orderDetail,
543 + Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap,
544 + Map<Integer, SingleMealRpcResponse> mealMap) {
545 + if (orderDetail == null || orderDetail.getMenuDetailId() == 0) {
546 + return "";
547 + }
548 +
549 + final var menuDetail = menuDetailMap.get(orderDetail.getMenuDetailId());
550 + if (menuDetail == null || menuDetail.getMealId() == 0) {
551 + return "";
552 + }
553 +
554 + final var meal = mealMap.get(menuDetail.getMealId());
555 + return meal != null ? meal.getName() : "";
556 + }
557 +
558 + /**
559 + * 安全获取SKU名称
560 + */
561 + private String getSkuNameSafely(SingleClientCustomerOrderDetailRpcResponse orderDetail,
562 + Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) {
563 + if (orderDetail == null || orderDetail.getSkuId() == 0) {
564 + return "";
565 + }
566 +
567 + final var sku = skuMap.get(orderDetail.getSkuId());
568 + return sku != null ? sku.getName() : "";
569 + }
570 +
571 + /**
572 + * 安全获取房间号
573 + */
574 + private String getRoomNoSafely(SingleClientCustomerOrderRpcResponse order) {
575 + if (order == null) {
576 + return "";
577 + }
578 +
579 + String syncRoomNo = order.getSyncRoomNo();
580 + if (!syncRoomNo.isEmpty()) {
581 + return syncRoomNo;
582 + }
583 +
584 + return order.getRoomNo();
585 + }
586 +
587 + /**
588 + * 安全获取忌口列表
589 + */
590 + private List<String> getAvoidsSafely(SingleClientCustomerOrderRpcResponse order) {
591 + if (order == null) {
592 + return Collections.emptyList();
593 + }
594 +
595 + return order.getCustomerNoticeJson().getAvoidsList();
596 + }
597 +
598 + /**
599 + * 安全获取医嘱列表
600 + */
601 + private List<String> getDoctorsSafely(SingleClientCustomerOrderRpcResponse order) {
602 + if (order == null) {
603 + return Collections.emptyList();
604 + }
605 +
606 + return order.getCustomerNoticeJson().getDoctorsList();
607 + }
608 +
609 + /**
610 + * 安全获取在线支付描述
611 + */
612 + private String getOnlinePayDescSafely(SingleClientCustomerOrderRpcResponse order) {
613 + if (order == null) {
614 + return "";
615 + }
616 +
617 + try {
618 + String desc = BaseProtoDescEnum.getDescByProtoEnum(order.getOnlinePay(), OnlinePayDescEnum.class);
619 + return desc != null ? desc : "";
620 + } catch (Exception e) {
621 + log.warn("获取在线支付描述失败,orderId: {}", order.getId(), e);
622 + return "";
623 + }
624 + }
625 +
626 + /**
627 + * 计算单价
628 + */
629 + private BigDecimal calculatePrice(Integer price) {
630 + if (price == null) {
631 + return BigDecimal.ZERO;
632 + }
633 + return new BigDecimal(price).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
634 + }
635 +
636 + /**
637 + * 计算总价
638 + */
639 + private BigDecimal calculateTotalPrice(Integer price, Integer count) {
640 + if (price == null || count == null) {
641 + return BigDecimal.ZERO;
642 + }
643 + return new BigDecimal(price)
644 + .multiply(new BigDecimal(count))
645 + .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
646 + }
647 +
648 + /**
649 + * 创建空的订单Excel
650 + */
651 + private ByteArrayOutputStream createEmptyExcelByOrder() {
652 + try {
653 + final var emptyData = SettlementDTO.SettlementDataByOrderDto.builder()
654 + .classifyOrders(Collections.emptyList())
655 + .build();
656 + return writeToExcelByOrder(emptyData);
657 + } catch (IOException e) {
658 + log.error("创建空Excel失败", e);
659 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
660 + }
661 + }
662 +
663 + /**
664 + * 按订单维度生成Excel
665 + */
666 + private static ByteArrayOutputStream writeToExcelByOrder(SettlementDTO.SettlementDataByOrderDto settlementDataDto)
667 + throws IOException {
668 + Workbook workbook = new XSSFWorkbook();
669 + Sheet sheet = workbook.createSheet("客人结算");
670 +
671 + // 创建表头样式(黑色边框)
672 + CellStyle headerStyle = workbook.createCellStyle();
673 + headerStyle.setBorderTop(BorderStyle.THIN);
674 + headerStyle.setBorderBottom(BorderStyle.THIN);
675 + headerStyle.setBorderLeft(BorderStyle.THIN);
676 + headerStyle.setBorderRight(BorderStyle.THIN);
677 + headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
678 + headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
679 + headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
680 + headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
681 +
682 + // 创建数据行样式(浅灰色边框)
683 + CellStyle dataStyle = workbook.createCellStyle();
684 + dataStyle.setBorderTop(BorderStyle.THIN);
685 + dataStyle.setBorderBottom(BorderStyle.THIN);
686 + dataStyle.setBorderLeft(BorderStyle.THIN);
687 + dataStyle.setBorderRight(BorderStyle.THIN);
688 + dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
689 + dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
690 + dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
691 + dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
692 +
693 + int rowNum = 0;
694 +
695 + // 创建表头
696 + Row titleRow = sheet.createRow(rowNum++);
697 + int columnNum = 0;
698 +
699 + Cell cell0 = titleRow.createCell(columnNum++);
700 + cell0.setCellValue("用餐时间");
701 + cell0.setCellStyle(headerStyle);
702 +
703 + Cell cell1 = titleRow.createCell(columnNum++);
704 + cell1.setCellValue("订单号");
705 + cell1.setCellStyle(headerStyle);
706 +
707 + Cell cell2 = titleRow.createCell(columnNum++);
708 + cell2.setCellValue("餐别");
709 + cell2.setCellStyle(headerStyle);
710 +
711 + Cell cell3 = titleRow.createCell(columnNum++);
712 + cell3.setCellValue("房间号");
713 + cell3.setCellStyle(headerStyle);
714 +
715 + Cell cell4 = titleRow.createCell(columnNum++);
716 + cell4.setCellValue("客户姓名");
717 + cell4.setCellStyle(headerStyle);
718 +
719 + Cell cell5 = titleRow.createCell(columnNum++);
720 + cell5.setCellValue("客户腕带号");
721 + cell5.setCellStyle(headerStyle);
722 +
723 + Cell cell6 = titleRow.createCell(columnNum++);
724 + cell6.setCellValue("忌口信息");
725 + cell6.setCellStyle(headerStyle);
726 +
727 + Cell cell7 = titleRow.createCell(columnNum++);
728 + cell7.setCellValue("医嘱信息");
729 + cell7.setCellStyle(headerStyle);
730 +
731 + Cell cell8 = titleRow.createCell(columnNum++);
732 + cell8.setCellValue("餐单名称");
733 + cell8.setCellStyle(headerStyle);
734 +
735 + Cell cell9 = titleRow.createCell(columnNum++);
736 + cell9.setCellValue("菜品名称");
737 + cell9.setCellStyle(headerStyle);
738 +
739 + Cell cell10 = titleRow.createCell(columnNum++);
740 + cell10.setCellValue("菜品份数");
741 + cell10.setCellStyle(headerStyle);
742 +
743 + Cell cell11 = titleRow.createCell(columnNum++);
744 + cell11.setCellValue("菜品单价");
745 + cell11.setCellStyle(headerStyle);
746 +
747 + Cell cell12 = titleRow.createCell(columnNum++);
748 + cell12.setCellValue("菜品金额");
749 + cell12.setCellStyle(headerStyle);
750 +
751 + Cell cell13 = titleRow.createCell(columnNum++);
752 + cell13.setCellValue("备注");
753 + cell13.setCellStyle(headerStyle);
754 +
755 + Cell cell14 = titleRow.createCell(columnNum++);
756 + cell14.setCellValue("支付方式");
757 + cell14.setCellStyle(headerStyle);
758 +
759 + // 填充数据
760 + final var classifyOrders = settlementDataDto.getClassifyOrders();
761 + if (classifyOrders != null) {
762 + for (SettlementDTO.SettlementOrderDetail orderDetail : classifyOrders) {
763 + Row dataRow = sheet.createRow(rowNum++);
764 + columnNum = 0;
765 +
766 + Cell dataCell0 = dataRow.createCell(columnNum++);
767 + dataCell0.setCellValue(orderDetail.getMealTime() != null ? orderDetail.getMealTime() : "");
768 + dataCell0.setCellStyle(dataStyle);
769 +
770 + Cell dataCell1 = dataRow.createCell(columnNum++);
771 + dataCell1.setCellValue(orderDetail.getCode() != null ? orderDetail.getCode() : "");
772 + dataCell1.setCellStyle(dataStyle);
773 +
774 + Cell dataCell2 = dataRow.createCell(columnNum++);
775 + dataCell2.setCellValue(orderDetail.getMealName() != null ? orderDetail.getMealName() : "");
776 + dataCell2.setCellStyle(dataStyle);
777 +
778 + Cell dataCell3 = dataRow.createCell(columnNum++);
779 + dataCell3.setCellValue(orderDetail.getRoomNo() != null ? orderDetail.getRoomNo() : "");
780 + dataCell3.setCellStyle(dataStyle);
781 +
782 + Cell dataCell4 = dataRow.createCell(columnNum++);
783 + dataCell4.setCellValue(orderDetail.getCustomerName() != null ? orderDetail.getCustomerName() : "");
784 + dataCell4.setCellStyle(dataStyle);
785 +
786 + Cell dataCell5 = dataRow.createCell(columnNum++);
787 + dataCell5.setCellValue(orderDetail.getHISCustomerNo() != null ? orderDetail.getHISCustomerNo() : "");
788 + dataCell5.setCellStyle(dataStyle);
789 +
790 + // 忌口列表转字符串
791 + String avoidsStr = orderDetail.getAvoids() != null ? String.join(", ", orderDetail.getAvoids()) : "";
792 + Cell dataCell6 = dataRow.createCell(columnNum++);
793 + dataCell6.setCellValue(avoidsStr);
794 + dataCell6.setCellStyle(dataStyle);
795 +
796 + // 医嘱列表转字符串
797 + String doctorsStr = orderDetail.getDoctors() != null ? String.join(", ", orderDetail.getDoctors()) : "";
798 + Cell dataCell7 = dataRow.createCell(columnNum++);
799 + dataCell7.setCellValue(doctorsStr);
800 + dataCell7.setCellStyle(dataStyle);
801 +
802 + Cell dataCell8 = dataRow.createCell(columnNum++);
803 + dataCell8.setCellValue(orderDetail.getMenuName() != null ? orderDetail.getMenuName() : "");
804 + dataCell8.setCellStyle(dataStyle);
805 +
806 + Cell dataCell9 = dataRow.createCell(columnNum++);
807 + dataCell9.setCellValue(orderDetail.getSkuName() != null ? orderDetail.getSkuName() : "");
808 + dataCell9.setCellStyle(dataStyle);
809 +
810 + Cell dataCell10 = dataRow.createCell(columnNum++);
811 + dataCell10.setCellValue(orderDetail.getCount() != null ? orderDetail.getCount() : 0);
812 + dataCell10.setCellStyle(dataStyle);
813 +
814 + // 价格
815 + Cell dataCell11 = dataRow.createCell(columnNum++);
816 + if (orderDetail.getPrice() != null) {
817 + dataCell11.setCellValue(orderDetail.getPrice().doubleValue());
818 + } else {
819 + dataCell11.setCellValue(0.0);
820 + }
821 + dataCell11.setCellStyle(dataStyle);
822 +
823 + // 总价
824 + Cell dataCell12 = dataRow.createCell(columnNum++);
825 + if (orderDetail.getTotalPrice() != null) {
826 + dataCell12.setCellValue(orderDetail.getTotalPrice().doubleValue());
827 + } else {
828 + dataCell12.setCellValue(0.0);
829 + }
830 + dataCell12.setCellStyle(dataStyle);
831 +
832 + // 合并备注和忌口备注,用分号分割,备注在前
833 + String remark = orderDetail.getRemark() != null ? orderDetail.getRemark() : "";
834 + String avoidRemark = orderDetail.getAvoidRemark() != null ? orderDetail.getAvoidRemark() : "";
835 + String combinedRemark = "";
836 + if (!remark.isEmpty() && !avoidRemark.isEmpty()) {
837 + combinedRemark = remark + ";" + avoidRemark;
838 + } else if (!remark.isEmpty()) {
839 + combinedRemark = remark;
840 + } else if (!avoidRemark.isEmpty()) {
841 + combinedRemark = avoidRemark;
842 + }
843 + Cell dataCell13 = dataRow.createCell(columnNum++);
844 + dataCell13.setCellValue(combinedRemark);
845 + dataCell13.setCellStyle(dataStyle);
846 +
847 + Cell dataCell14 = dataRow.createCell(columnNum++);
848 + dataCell14.setCellValue(orderDetail.getOnlinePay() != null ? orderDetail.getOnlinePay() : "");
849 + dataCell14.setCellStyle(dataStyle);
277 } 850 }
278 } 851 }
279 852
853 + // 自动调整列宽
854 + for (int i = 0; i < 15; i++) {
855 + sheet.autoSizeColumn(i);
856 + }
857 +
858 + // 将工作簿内容写入字节数组输出流
859 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
860 + workbook.write(outputStream);
861 + workbook.close();
862 +
863 + return outputStream;
864 + }
865 +
280 public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) { 866 public ByteArrayOutputStream generateOrderSettlementExcelBySku(SettlementRequestDto settlementRequest) {
281 final var startDate = settlementRequest.getTimeStart().plusHours(8).toLocalDate().atStartOfDay(); 867 final var startDate = settlementRequest.getTimeStart().plusHours(8).toLocalDate().atStartOfDay();
282 final var endDate = settlementRequest.getTimeEnd().plusHours(8).toLocalDate().plusDays(1).atStartOfDay(); 868 final var endDate = settlementRequest.getTimeEnd().plusHours(8).toLocalDate().plusDays(1).atStartOfDay();
...@@ -541,4 +1127,364 @@ public class SettlementServiceImpl implements SettlementService { ...@@ -541,4 +1127,364 @@ public class SettlementServiceImpl implements SettlementService {
541 1127
542 } 1128 }
543 1129
1130 + @Override
1131 + public ByteArrayOutputStream exportSeparateMealsExcel(QueryOrderDto queryOrderDto) {
1132 + // 参数校验
1133 + if (queryOrderDto == null) {
1134 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1135 + }
1136 +
1137 + final int enterpriseId = queryOrderDto.getEnterpriseId();
1138 +
1139 + // 查询订单列表
1140 + final var queryClientCustomerOrdersByConditionRpcResponse = orderServiceRpcClient.queryClientCustomerOrdersByCondition(queryOrderDto);
1141 +
1142 + // 今天开始时间的时间戳(毫秒)
1143 + final long todayStartTimestamp = LocalDate.now().atStartOfDay()
1144 + .atZone(ZoneId.systemDefault())
1145 + .toInstant()
1146 + .toEpochMilli();
1147 +
1148 + final var orderList = queryClientCustomerOrdersByConditionRpcResponse.getResponsesList()
1149 + .stream()
1150 + .filter(e -> {
1151 + boolean payStatusMatch = e.getPayStatus() == PayStatusEnum.SUCCEED|| e.getPayStatus() == PayStatusEnum.PAY_CANCELED;
1152 + // 过滤时间:只查询今天和以后的订单
1153 + boolean timeMatch = e.getMealTime() >= todayStartTimestamp;
1154 + return payStatusMatch && timeMatch;
1155 + })
1156 + .toList();
1157 + if (orderList.isEmpty()) {
1158 + log.warn("未查询到订单数据,enterpriseId: {}", enterpriseId);
1159 + return createEmptyExcelBySeparateMeal();
1160 + }
1161 +
1162 + // 获取订单IDs
1163 + List<Integer> orderIds = orderList.stream()
1164 + .map(SingleClientCustomerOrderRpcResponse::getId)
1165 + .collect(Collectors.toList());
1166 +
1167 + // 构建订单映射
1168 + final var orderMap = orderList.stream()
1169 + .filter(Objects::nonNull)
1170 + .filter(o -> o.getId() != 0)
1171 + .collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1));
1172 +
1173 + // 查询订单详情
1174 + final var orderDetailList = orderServiceRpcClient.getOrderDetailsByOrderIds(orderIds);
1175 + if (orderDetailList == null || orderDetailList.isEmpty()) {
1176 + log.warn("未查询到订单详情数据,orderIds: {}", orderIds);
1177 + return createEmptyExcelBySeparateMeal();
1178 + }
1179 +
1180 + // 订单详情按订单ID分组
1181 + final var orderDetailGroupByOrderId = orderDetailList.stream()
1182 + .filter(Objects::nonNull)
1183 + .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
1184 + .collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
1185 +
1186 + // 获取SKU数据
1187 + List<Integer> skuIds = orderDetailList.stream()
1188 + .filter(Objects::nonNull)
1189 + .filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
1190 + .map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
1191 + .distinct()
1192 + .collect(Collectors.toList());
1193 +
1194 + final var skuResponse = skuServiceRpcClient.getDishSkusByIds(skuIds);
1195 + final List<SingleDishSkuByIdsRpcResponse> skus = skuResponse != null ? skuResponse.getResponseList() : new ArrayList<>();
1196 + final var skuMap = skus.stream()
1197 + .collect(Collectors.toMap(SingleDishSkuByIdsRpcResponse::getId, s -> s, (s1, s2) -> s1));
1198 +
1199 + // 获取餐别数据
1200 + final var mealResponse = mealServiceRpcClient.getAllMeals(enterpriseId);
1201 + final List<SingleMealRpcResponse> meals = mealResponse != null ? mealResponse.getResponsesList() : new ArrayList<>();
1202 + final var mealMap = meals.stream()
1203 + .filter(Objects::nonNull)
1204 + .filter(m -> m.getId() != 0)
1205 + .collect(Collectors.toMap(SingleMealRpcResponse::getId, m -> m, (m1, m2) -> m1));
1206 +
1207 + // 获取菜单数据
1208 + List<Integer> menuIds = orderList.stream()
1209 + .map(SingleClientCustomerOrderRpcResponse::getMenuId)
1210 + .distinct()
1211 + .collect(Collectors.toList());
1212 +
1213 + final var menuResponse = menuServiceRpcClient.getMenusByIds(enterpriseId, menuIds);
1214 + final List<SingleMenuRpcResponse> menuList = menuResponse != null ? menuResponse.getResponsesList() : new ArrayList<>();
1215 + final var menuMap = menuList.stream()
1216 + .collect(Collectors.toMap(SingleMenuRpcResponse::getId, m -> m, (m1, m2) -> m1));
1217 +
1218 + // 获取菜单详情数据
1219 + final var menuDetailResponse = menuServiceRpcClient.queryMenuDetailsByMenuIds(enterpriseId, menuIds);
1220 + final List<SingleMenuDetailRpcResponse> menuDetailList = menuDetailResponse != null ? menuDetailResponse.getResponsesList() : new ArrayList<>();
1221 + final var menuDetailMap = menuDetailList.stream()
1222 + .collect(Collectors.toMap(SingleMenuDetailRpcResponse::getId, m -> m, (m1, m2) -> m1));
1223 +
1224 + // 获取客户数据
1225 + List<Integer> customerIds = orderList.stream()
1226 + .map(SingleClientCustomerOrderRpcResponse::getCustomerId)
1227 + .filter(id -> id != 0)
1228 + .distinct()
1229 + .collect(Collectors.toList());
1230 +
1231 + final var customerResponse = clientCustomerServiceRpcClient.getClientCustomersByIds(enterpriseId, customerIds);
1232 + final List<SingleClientCustomerRpcResponse> customers = customerResponse != null ? customerResponse.getResponsesList() : new ArrayList<>();
1233 + final var customerMap = customers.stream()
1234 + .collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1));
1235 +
1236 + // 构建分餐表明细
1237 + final var mealDetails = new ArrayList<SeparateMealDetail>();
1238 + for (Integer orderId : orderIds) {
1239 + final var orderDetails = orderDetailGroupByOrderId.getOrDefault(orderId, Collections.emptyList());
1240 + final var order = orderMap.get(orderId);
1241 +
1242 + // 订单为空则跳过
1243 + if (order == null) {
1244 + log.warn("订单不存在,orderId: {}", orderId);
1245 + continue;
1246 + }
1247 +
1248 + // 获取菜单信息
1249 + final var menu = menuMap.get(order.getMenuId());
1250 + final String menuName = menu != null ? menu.getName() : "";
1251 +
1252 + // 获取客户信息
1253 + final var customer = customerMap.get(order.getCustomerId());
1254 + final String customerName = customer != null ? customer.getName() : "";
1255 +
1256 + // 安全获取房间号
1257 + String roomNo = getRoomNoSafely(order);
1258 +
1259 + // 处理每个订单详情
1260 + for (SingleClientCustomerOrderDetailRpcResponse orderDetail : orderDetails) {
1261 + if (orderDetail == null) {
1262 + continue;
1263 + }
1264 +
1265 + // 安全获取餐别名称
1266 + String mealName = getMealNameSafely(orderDetail, menuDetailMap, mealMap);
1267 +
1268 + // 安全获取SKU名称
1269 + String skuName = getSkuNameSafely(orderDetail, skuMap);
1270 +
1271 + // 安全获取忌口信息(列表转字符串)
1272 + List<String> avoidsList = getAvoidsSafely(order);
1273 + String avoidsStr = String.join(", ", avoidsList);
1274 +
1275 + String remark = order.getRemark();
1276 + String avoidRemark = order.getAvoidRemark();
1277 + String combinedRemark = "";
1278 + if (!remark.isEmpty() && !avoidRemark.isEmpty()) {
1279 + combinedRemark = remark + ";" + avoidRemark;
1280 + } else if (!remark.isEmpty()) {
1281 + combinedRemark = remark;
1282 + } else if (!avoidRemark.isEmpty()) {
1283 + combinedRemark = avoidRemark;
1284 + }
1285 +
1286 + // 构建分餐表明细
1287 + SeparateMealDetail mealDetail = SeparateMealDetail.builder()
1288 + .orderId(orderId)
1289 + .mealName(mealName)
1290 + .roomNo(roomNo)
1291 + .customerName(customerName)
1292 + .menuName(menuName)
1293 + .skuName(skuName)
1294 + .count(orderDetail.getCount() != 0 ? orderDetail.getCount() : 0)
1295 + .avoids(avoidsStr)
1296 + .remark(combinedRemark)
1297 + .build();
1298 + mealDetails.add(mealDetail);
1299 + }
1300 + }
1301 +
1302 + // 构建分餐表数据
1303 + final var separateMealDataDto = SeparateMealDataDto.builder()
1304 + .mealDetails(mealDetails)
1305 + .build();
1306 +
1307 + // 生成Excel
1308 + try {
1309 + return writeToExcelBySeparateMeal(separateMealDataDto);
1310 + } catch (IOException e) {
1311 + log.error("生成分餐表Excel失败", e);
1312 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1313 + }
1314 + }
1315 +
1316 + /**
1317 + * 生成分餐表Excel
1318 + */
1319 + private static ByteArrayOutputStream writeToExcelBySeparateMeal(SeparateMealDataDto separateMealDataDto)
1320 + throws IOException {
1321 + Workbook workbook = new XSSFWorkbook();
1322 + Sheet sheet = workbook.createSheet("分餐表");
1323 +
1324 + // 创建标题样式(合并单元格标题)
1325 + CellStyle titleStyle = workbook.createCellStyle();
1326 + titleStyle.setAlignment(HorizontalAlignment.CENTER);
1327 + titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
1328 + titleStyle.setBorderTop(BorderStyle.THIN);
1329 + titleStyle.setBorderBottom(BorderStyle.THIN);
1330 + titleStyle.setBorderLeft(BorderStyle.THIN);
1331 + titleStyle.setBorderRight(BorderStyle.THIN);
1332 + titleStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
1333 + titleStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
1334 + titleStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
1335 + titleStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
1336 + Font titleFont = workbook.createFont();
1337 + titleFont.setBold(true);
1338 + titleFont.setFontHeightInPoints((short) 16);
1339 + titleStyle.setFont(titleFont);
1340 +
1341 + // 创建表头样式(黑色边框)
1342 + CellStyle headerStyle = workbook.createCellStyle();
1343 + headerStyle.setBorderTop(BorderStyle.THIN);
1344 + headerStyle.setBorderBottom(BorderStyle.THIN);
1345 + headerStyle.setBorderLeft(BorderStyle.THIN);
1346 + headerStyle.setBorderRight(BorderStyle.THIN);
1347 + headerStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
1348 + headerStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
1349 + headerStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
1350 + headerStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
1351 +
1352 + // 创建数据行样式(浅灰色边框)
1353 + CellStyle dataStyle = workbook.createCellStyle();
1354 + dataStyle.setBorderTop(BorderStyle.THIN);
1355 + dataStyle.setBorderBottom(BorderStyle.THIN);
1356 + dataStyle.setBorderLeft(BorderStyle.THIN);
1357 + dataStyle.setBorderRight(BorderStyle.THIN);
1358 + dataStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1359 + dataStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1360 + dataStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1361 + dataStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
1362 +
1363 + int rowNum = 0;
1364 +
1365 + // 第一行:创建合并单元格标题
1366 + Row mainTitleRow = sheet.createRow(rowNum++);
1367 + Cell mainTitleCell = mainTitleRow.createCell(0);
1368 + mainTitleCell.setCellValue("住院客户分餐表");
1369 + mainTitleCell.setCellStyle(titleStyle);
1370 +
1371 + // 合并第一行的8列
1372 + CellRangeAddress titleRegion = new CellRangeAddress(0, 0, 0, 7);
1373 + sheet.addMergedRegion(titleRegion);
1374 +
1375 + // 为合并区域设置边框
1376 + RegionUtil.setBorderTop(BorderStyle.THIN, titleRegion, sheet);
1377 + RegionUtil.setBorderBottom(BorderStyle.THIN, titleRegion, sheet);
1378 + RegionUtil.setBorderLeft(BorderStyle.THIN, titleRegion, sheet);
1379 + RegionUtil.setBorderRight(BorderStyle.THIN, titleRegion, sheet);
1380 + RegionUtil.setTopBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1381 + RegionUtil.setBottomBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1382 + RegionUtil.setLeftBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1383 + RegionUtil.setRightBorderColor(IndexedColors.BLACK.getIndex(), titleRegion, sheet);
1384 +
1385 + // 第二行:创建表头
1386 + Row titleRow = sheet.createRow(rowNum++);
1387 + int columnNum = 0;
1388 +
1389 + Cell cell0 = titleRow.createCell(columnNum++);
1390 + cell0.setCellValue("餐别");
1391 + cell0.setCellStyle(headerStyle);
1392 +
1393 + Cell cell1 = titleRow.createCell(columnNum++);
1394 + cell1.setCellValue("房间号");
1395 + cell1.setCellStyle(headerStyle);
1396 +
1397 + Cell cell2 = titleRow.createCell(columnNum++);
1398 + cell2.setCellValue("客户姓名");
1399 + cell2.setCellStyle(headerStyle);
1400 +
1401 + Cell cell3 = titleRow.createCell(columnNum++);
1402 + cell3.setCellValue("餐单名称");
1403 + cell3.setCellStyle(headerStyle);
1404 +
1405 + Cell cell4 = titleRow.createCell(columnNum++);
1406 + cell4.setCellValue("菜品名称");
1407 + cell4.setCellStyle(headerStyle);
1408 +
1409 + Cell cell5 = titleRow.createCell(columnNum++);
1410 + cell5.setCellValue("菜品数量");
1411 + cell5.setCellStyle(headerStyle);
1412 +
1413 + Cell cell6 = titleRow.createCell(columnNum++);
1414 + cell6.setCellValue("忌口信息");
1415 + cell6.setCellStyle(headerStyle);
1416 +
1417 + Cell cell7 = titleRow.createCell(columnNum++);
1418 + cell7.setCellValue("备注");
1419 + cell7.setCellStyle(headerStyle);
1420 +
1421 + // 填充数据
1422 + final var mealDetails = separateMealDataDto.getMealDetails();
1423 + if (mealDetails != null) {
1424 + for (SeparateMealDetail mealDetail : mealDetails) {
1425 + Row dataRow = sheet.createRow(rowNum++);
1426 + columnNum = 0;
1427 +
1428 + Cell dataCell0 = dataRow.createCell(columnNum++);
1429 + dataCell0.setCellValue(mealDetail.getMealName() != null ? mealDetail.getMealName() : "");
1430 + dataCell0.setCellStyle(dataStyle);
1431 +
1432 + Cell dataCell1 = dataRow.createCell(columnNum++);
1433 + dataCell1.setCellValue(mealDetail.getRoomNo() != null ? mealDetail.getRoomNo() : "");
1434 + dataCell1.setCellStyle(dataStyle);
1435 +
1436 + Cell dataCell2 = dataRow.createCell(columnNum++);
1437 + dataCell2.setCellValue(mealDetail.getCustomerName() != null ? mealDetail.getCustomerName() : "");
1438 + dataCell2.setCellStyle(dataStyle);
1439 +
1440 + Cell dataCell3 = dataRow.createCell(columnNum++);
1441 + dataCell3.setCellValue(mealDetail.getMenuName() != null ? mealDetail.getMenuName() : "");
1442 + dataCell3.setCellStyle(dataStyle);
1443 +
1444 + Cell dataCell4 = dataRow.createCell(columnNum++);
1445 + dataCell4.setCellValue(mealDetail.getSkuName() != null ? mealDetail.getSkuName() : "");
1446 + dataCell4.setCellStyle(dataStyle);
1447 +
1448 + Cell dataCell5 = dataRow.createCell(columnNum++);
1449 + dataCell5.setCellValue(mealDetail.getCount() != null ? mealDetail.getCount() : 0);
1450 + dataCell5.setCellStyle(dataStyle);
1451 +
1452 + Cell dataCell6 = dataRow.createCell(columnNum++);
1453 + dataCell6.setCellValue(mealDetail.getAvoids() != null ? mealDetail.getAvoids() : "");
1454 + dataCell6.setCellStyle(dataStyle);
1455 +
1456 + Cell dataCell7 = dataRow.createCell(columnNum++);
1457 + dataCell7.setCellValue(mealDetail.getRemark() != null ? mealDetail.getRemark() : "");
1458 + dataCell7.setCellStyle(dataStyle);
1459 + }
1460 + }
1461 +
1462 + // 自动调整列宽
1463 + for (int i = 0; i < 8; i++) {
1464 + sheet.autoSizeColumn(i);
1465 + }
1466 +
1467 + // 将工作簿内容写入字节数组输出流
1468 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
1469 + workbook.write(outputStream);
1470 + workbook.close();
1471 +
1472 + return outputStream;
1473 + }
1474 +
1475 + /**
1476 + * 创建空的分餐表Excel(无数据)
1477 + */
1478 + private static ByteArrayOutputStream createEmptyExcelBySeparateMeal() {
1479 + try {
1480 + SeparateMealDataDto emptyData = SeparateMealDataDto.builder()
1481 + .mealDetails(new ArrayList<>())
1482 + .build();
1483 + return writeToExcelBySeparateMeal(emptyData);
1484 + } catch (IOException e) {
1485 + log.error("创建空分餐表Excel失败", e);
1486 + throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
1487 + }
1488 + }
1489 +
544 } 1490 }
......
...@@ -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)
...@@ -48,16 +51,40 @@ public class SettlementController { ...@@ -48,16 +51,40 @@ public class SettlementController {
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) {
53 ByteArrayOutputStream outputStream = settlementService.generateOrderSettlementExcel( 55 ByteArrayOutputStream outputStream = settlementService.generateOrderSettlementExcel(
54 settlementRequestDto); 56 settlementRequestDto);
57 +
58 + String fileName;
59 + if (settlementRequestDto.getDimension() == SettlementDimensionEnum.BY_ORDER) {
60 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
61 + String startDate = settlementRequestDto.getTimeStart().format(formatter);
62 + String endDate = settlementRequestDto.getTimeEnd().format(formatter);
63 + fileName = String.format("结算报表_%s_%s.xlsx", startDate, endDate);
64 + } else {
65 + fileName = "订单数据.xlsx";
66 + }
67 +
55 HttpHeaders headers = new HttpHeaders(); 68 HttpHeaders headers = new HttpHeaders();
56 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); 69 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
57 - headers.setContentDispositionFormData("attachment", "订单数据.xlsx"); 70 + headers.setContentDispositionFormData("attachment", fileName);
58 71
59 return ResponseEntity.ok() 72 return ResponseEntity.ok()
60 .headers(headers) 73 .headers(headers)
61 .body(outputStream.toByteArray()); 74 .body(outputStream.toByteArray());
62 } 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());
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 {
......