Merge branch 'qa/2025-04-10' into 'master'
Qa/2025 04 10 See merge request !17
Showing
6 changed files
with
160 additions
and
21 deletions
| ... | @@ -83,9 +83,7 @@ public interface ConfigConstants { | ... | @@ -83,9 +83,7 @@ public interface ConfigConstants { |
| 83 | String MINI_PROGRAM_APP_SECRET = "${miniprogram.appSecret}"; | 83 | String MINI_PROGRAM_APP_SECRET = "${miniprogram.appSecret}"; |
| 84 | String MINI_PROGRAM_ORDER_REMINDER_TEMPLATE_ID = "${miniprogram.orderReminderTemplateId}"; | 84 | String MINI_PROGRAM_ORDER_REMINDER_TEMPLATE_ID = "${miniprogram.orderReminderTemplateId}"; |
| 85 | 85 | ||
| 86 | - // 公众号配置(用于订阅消息推送) | 86 | + // 公众号模板 ID(可选);appId/appSecret 见 WxOfficialAccountHttpClient 字段上的 @Value 默认值 |
| 87 | - String OFFICIAL_ACCOUNT_APP_ID = "${officialAccount.appId}"; | 87 | + String OFFICIAL_ACCOUNT_ORDER_REMINDER_TEMPLATE_ID = "${officialAccount.orderReminderTemplateId:}"; |
| 88 | - String OFFICIAL_ACCOUNT_APP_SECRET = "${officialAccount.appSecret}"; | ||
| 89 | - String OFFICIAL_ACCOUNT_ORDER_REMINDER_TEMPLATE_ID = "${officialAccount.orderReminderTemplateId}"; | ||
| 90 | 88 | ||
| 91 | } | 89 | } | ... | ... |
| ... | @@ -89,6 +89,10 @@ public class SettlementDTO { | ... | @@ -89,6 +89,10 @@ public class SettlementDTO { |
| 89 | public static class SettlementOrderDetail { | 89 | public static class SettlementOrderDetail { |
| 90 | private String mealTime; | 90 | private String mealTime; |
| 91 | private String code; | 91 | private String code; |
| 92 | + /** 支付完成时间,格式 yyyy-MM-dd HH:mm:ss,无则空 */ | ||
| 93 | + private String payTime; | ||
| 94 | + /** 下单人:院区端为操作员名称;住院小程序为客户姓名;阳光厅为客户手机号 */ | ||
| 95 | + private String orderer; | ||
| 92 | private String mealName; | 96 | private String mealName; |
| 93 | private String roomNo; | 97 | private String roomNo; |
| 94 | private String customerName; | 98 | private String customerName; | ... | ... |
| ... | @@ -2,12 +2,16 @@ package com.infoloop.tianting.service.client; | ... | @@ -2,12 +2,16 @@ package com.infoloop.tianting.service.client; |
| 2 | 2 | ||
| 3 | import com.infoloop.tianting.COperatorServiceProtoRpcGrpc; | 3 | import com.infoloop.tianting.COperatorServiceProtoRpcGrpc; |
| 4 | import com.infoloop.tianting.GetCOperatorByIdRpcRequest; | 4 | import com.infoloop.tianting.GetCOperatorByIdRpcRequest; |
| 5 | +import com.infoloop.tianting.GetCOperatorByIdsRpcRequest; | ||
| 5 | import com.infoloop.tianting.GetCOperatorByMobileOrEmailRpcRequest; | 6 | import com.infoloop.tianting.GetCOperatorByMobileOrEmailRpcRequest; |
| 6 | import com.infoloop.tianting.SingleCOperatorRpcResponse; | 7 | import com.infoloop.tianting.SingleCOperatorRpcResponse; |
| 7 | import lombok.RequiredArgsConstructor; | 8 | import lombok.RequiredArgsConstructor; |
| 8 | import org.springframework.beans.factory.annotation.Autowired; | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| 9 | import org.springframework.stereotype.Service; | 10 | import org.springframework.stereotype.Service; |
| 10 | 11 | ||
| 12 | +import java.util.Collections; | ||
| 13 | +import java.util.List; | ||
| 14 | + | ||
| 11 | @Service | 15 | @Service |
| 12 | @RequiredArgsConstructor(onConstructor = @__(@Autowired)) | 16 | @RequiredArgsConstructor(onConstructor = @__(@Autowired)) |
| 13 | public class OperatorServiceRpcClient { | 17 | public class OperatorServiceRpcClient { |
| ... | @@ -26,5 +30,15 @@ public class OperatorServiceRpcClient { | ... | @@ -26,5 +30,15 @@ public class OperatorServiceRpcClient { |
| 26 | return cOperatorServiceProtoRpcBlockingStub.getCOperatorById(request).getResponse(); | 30 | return cOperatorServiceProtoRpcBlockingStub.getCOperatorById(request).getResponse(); |
| 27 | } | 31 | } |
| 28 | 32 | ||
| 33 | + public List<SingleCOperatorRpcResponse> getCOperatorsByIds(List<Integer> ids) { | ||
| 34 | + if (ids == null || ids.isEmpty()) { | ||
| 35 | + return Collections.emptyList(); | ||
| 36 | + } | ||
| 37 | + return cOperatorServiceProtoRpcBlockingStub.getCOperatorByIds(GetCOperatorByIdsRpcRequest.newBuilder() | ||
| 38 | + .addAllIds(ids) | ||
| 39 | + .setIncludeDeleted(false) | ||
| 40 | + .build()) | ||
| 41 | + .getResponsesList(); | ||
| 42 | + } | ||
| 29 | 43 | ||
| 30 | } | 44 | } | ... | ... |
| ... | @@ -720,7 +720,7 @@ public class OrderServiceRpcClient { | ... | @@ -720,7 +720,7 @@ public class OrderServiceRpcClient { |
| 720 | if (menuById.getResponse().getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE) { | 720 | if (menuById.getResponse().getOrderRuleJson().getModeOfPayment() == ModeOfPaymentEnum.ONLINE) { |
| 721 | final var autoCancelParam = new AutoCancelParam(); | 721 | final var autoCancelParam = new AutoCancelParam(); |
| 722 | autoCancelParam.setOrderId(orderResponse.getId()); | 722 | autoCancelParam.setOrderId(orderResponse.getId()); |
| 723 | - delayedQueue.addToQueue(OrderAutoCancelDelayTask.AUTO_CANCEL_ORDER_DELAY_QUEUE, autoCancelParam, 10, TimeUnit.MINUTES); | 723 | + delayedQueue.addToQueue(OrderAutoCancelDelayTask.AUTO_CANCEL_ORDER_DELAY_QUEUE, autoCancelParam, 6, TimeUnit.HOURS); |
| 724 | } | 724 | } |
| 725 | } | 725 | } |
| 726 | return CreateOrderResponse.builder().id(orderResponse.getId()).isCreated(true).build(); | 726 | return CreateOrderResponse.builder().id(orderResponse.getId()).isCreated(true).build(); | ... | ... |
| ... | @@ -2,12 +2,13 @@ package com.infoloop.tianting.service.client; | ... | @@ -2,12 +2,13 @@ package com.infoloop.tianting.service.client; |
| 2 | 2 | ||
| 3 | import com.infoloop.tianting.model.dto.WxUserDto.SendSubscriptionMessageResponse; | 3 | import com.infoloop.tianting.model.dto.WxUserDto.SendSubscriptionMessageResponse; |
| 4 | import com.infoloop.tianting.model.dto.WxUserDto.WxUserTokenDto; | 4 | import com.infoloop.tianting.model.dto.WxUserDto.WxUserTokenDto; |
| 5 | +import org.springframework.lang.Nullable; | ||
| 5 | import com.infoloop.tianting.utils.JsonUtil; | 6 | import com.infoloop.tianting.utils.JsonUtil; |
| 6 | import lombok.RequiredArgsConstructor; | 7 | import lombok.RequiredArgsConstructor; |
| 7 | import lombok.extern.slf4j.Slf4j; | 8 | import lombok.extern.slf4j.Slf4j; |
| 8 | import org.apache.commons.lang3.StringUtils; | 9 | import org.apache.commons.lang3.StringUtils; |
| 9 | import org.springframework.beans.factory.annotation.Autowired; | 10 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | -import org.springframework.beans.factory.annotation.Value; | 11 | +import org.springframework.core.env.Environment; |
| 11 | import org.springframework.data.redis.core.StringRedisTemplate; | 12 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 12 | import org.springframework.http.HttpEntity; | 13 | import org.springframework.http.HttpEntity; |
| 13 | import org.springframework.http.HttpHeaders; | 14 | import org.springframework.http.HttpHeaders; |
| ... | @@ -16,13 +17,12 @@ import org.springframework.http.ResponseEntity; | ... | @@ -16,13 +17,12 @@ import org.springframework.http.ResponseEntity; |
| 16 | import org.springframework.stereotype.Service; | 17 | import org.springframework.stereotype.Service; |
| 17 | import org.springframework.web.client.RestTemplate; | 18 | import org.springframework.web.client.RestTemplate; |
| 18 | 19 | ||
| 20 | +import javax.annotation.PostConstruct; | ||
| 21 | + | ||
| 19 | import java.util.HashMap; | 22 | import java.util.HashMap; |
| 20 | import java.util.Map; | 23 | import java.util.Map; |
| 21 | import java.util.concurrent.TimeUnit; | 24 | import java.util.concurrent.TimeUnit; |
| 22 | 25 | ||
| 23 | -import static com.infoloop.tianting.constant.ConfigConstants.OFFICIAL_ACCOUNT_APP_ID; | ||
| 24 | -import static com.infoloop.tianting.constant.ConfigConstants.OFFICIAL_ACCOUNT_APP_SECRET; | ||
| 25 | - | ||
| 26 | /** | 26 | /** |
| 27 | * 微信公众号 HTTP 客户端 | 27 | * 微信公众号 HTTP 客户端 |
| 28 | * 用于发送公众号一次性订阅消息 | 28 | * 用于发送公众号一次性订阅消息 |
| ... | @@ -42,19 +42,36 @@ public class WxOfficialAccountHttpClient { | ... | @@ -42,19 +42,36 @@ public class WxOfficialAccountHttpClient { |
| 42 | 42 | ||
| 43 | private final RestTemplate restTemplate; | 43 | private final RestTemplate restTemplate; |
| 44 | private final StringRedisTemplate stringRedisTemplate; | 44 | private final StringRedisTemplate stringRedisTemplate; |
| 45 | + private final Environment environment; | ||
| 45 | 46 | ||
| 46 | - @Value(OFFICIAL_ACCOUNT_APP_ID) | 47 | + /** 由 {@link #bindOfficialAccountConfig()} 从 Environment 读取;缺失配置项时为空白,不触发占位符解析 */ |
| 47 | - private String appId; | 48 | + private String appId = ""; |
| 48 | 49 | ||
| 49 | - @Value(OFFICIAL_ACCOUNT_APP_SECRET) | 50 | + private String appSecret = ""; |
| 50 | - private String appSecret; | ||
| 51 | 51 | ||
| 52 | private final Object lock = new Object(); | 52 | private final Object lock = new Object(); |
| 53 | 53 | ||
| 54 | + @PostConstruct | ||
| 55 | + void bindOfficialAccountConfig() { | ||
| 56 | + this.appId = StringUtils.trimToEmpty(environment.getProperty("officialAccount.appId")); | ||
| 57 | + this.appSecret = StringUtils.trimToEmpty(environment.getProperty("officialAccount.appSecret")); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + private boolean isOfficialAccountConfigured() { | ||
| 61 | + return StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(appSecret); | ||
| 62 | + } | ||
| 63 | + | ||
| 54 | /** | 64 | /** |
| 55 | * 获取公众号 access_token(带缓存) | 65 | * 获取公众号 access_token(带缓存) |
| 66 | + * | ||
| 67 | + * @return token;未配置 appId/appSecret 时返回 null(不请求微信接口) | ||
| 56 | */ | 68 | */ |
| 69 | + @Nullable | ||
| 57 | public String fetchStableAccessToken() { | 70 | public String fetchStableAccessToken() { |
| 71 | + if (!isOfficialAccountConfigured()) { | ||
| 72 | + log.warn("未配置 officialAccount.appId / officialAccount.appSecret,跳过获取公众号 access_token"); | ||
| 73 | + return null; | ||
| 74 | + } | ||
| 58 | log.info("Fetching Official Account access token..."); | 75 | log.info("Fetching Official Account access token..."); |
| 59 | String cachedToken = stringRedisTemplate.opsForValue().get(ACCESS_TOKEN_CACHE_KEY); | 76 | String cachedToken = stringRedisTemplate.opsForValue().get(ACCESS_TOKEN_CACHE_KEY); |
| 60 | if (StringUtils.isNotEmpty(cachedToken)) { | 77 | if (StringUtils.isNotEmpty(cachedToken)) { |
| ... | @@ -117,8 +134,15 @@ public class WxOfficialAccountHttpClient { | ... | @@ -117,8 +134,15 @@ public class WxOfficialAccountHttpClient { |
| 117 | Map<String, Object> data, | 134 | Map<String, Object> data, |
| 118 | String url, | 135 | String url, |
| 119 | Map<String, String> miniprogram) { | 136 | Map<String, String> miniprogram) { |
| 137 | + if (!isOfficialAccountConfigured()) { | ||
| 138 | + log.warn("未配置公众号,跳过发送订阅消息 openId={}", openId); | ||
| 139 | + return new SendSubscriptionMessageResponse(-1, "微信公众号未配置"); | ||
| 140 | + } | ||
| 120 | try { | 141 | try { |
| 121 | String accessToken = fetchStableAccessToken(); | 142 | String accessToken = fetchStableAccessToken(); |
| 143 | + if (accessToken == null) { | ||
| 144 | + return new SendSubscriptionMessageResponse(-1, "未获取到公众号 access_token"); | ||
| 145 | + } | ||
| 122 | HttpHeaders headers = new HttpHeaders(); | 146 | HttpHeaders headers = new HttpHeaders(); |
| 123 | headers.setContentType(MediaType.APPLICATION_JSON); | 147 | headers.setContentType(MediaType.APPLICATION_JSON); |
| 124 | 148 | ... | ... |
| ... | @@ -3,10 +3,12 @@ package com.infoloop.tianting.service.impl; | ... | @@ -3,10 +3,12 @@ package com.infoloop.tianting.service.impl; |
| 3 | import cn.hutool.core.collection.CollectionUtil; | 3 | import cn.hutool.core.collection.CollectionUtil; |
| 4 | import cn.hutool.core.date.LocalDateTimeUtil; | 4 | import cn.hutool.core.date.LocalDateTimeUtil; |
| 5 | import com.fasterxml.jackson.core.type.TypeReference; | 5 | import com.fasterxml.jackson.core.type.TypeReference; |
| 6 | +import com.infoloop.tianting.SingleCOperatorRpcResponse; | ||
| 6 | import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse; | 7 | import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse; |
| 7 | import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum; | 8 | import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum; |
| 8 | import com.infoloop.tianting.clientcustomerorderservice.OrderOperationRecord; | 9 | import com.infoloop.tianting.clientcustomerorderservice.OrderOperationRecord; |
| 9 | import com.infoloop.tianting.clientcustomerorderservice.OrderOperationType; | 10 | import com.infoloop.tianting.clientcustomerorderservice.OrderOperationType; |
| 11 | +import com.infoloop.tianting.clientcustomerorderservice.OrderSourceEnum; | ||
| 10 | import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; | 12 | import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum; |
| 11 | import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; | 13 | import com.infoloop.tianting.clientcustomerorderservice.PayStatusEnum; |
| 12 | import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; | 14 | import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum; |
| ... | @@ -39,6 +41,7 @@ import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; | ... | @@ -39,6 +41,7 @@ import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient; |
| 39 | import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient; | 41 | import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient; |
| 40 | import com.infoloop.tianting.service.client.MealServiceRpcClient; | 42 | import com.infoloop.tianting.service.client.MealServiceRpcClient; |
| 41 | import com.infoloop.tianting.service.client.MenuServiceRpcClient; | 43 | import com.infoloop.tianting.service.client.MenuServiceRpcClient; |
| 44 | +import com.infoloop.tianting.service.client.OperatorServiceRpcClient; | ||
| 42 | import com.infoloop.tianting.service.client.OrderServiceRpcClient; | 45 | import com.infoloop.tianting.service.client.OrderServiceRpcClient; |
| 43 | import com.infoloop.tianting.service.client.SkuServiceRpcClient; | 46 | import com.infoloop.tianting.service.client.SkuServiceRpcClient; |
| 44 | import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse; | 47 | import com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse; |
| ... | @@ -92,6 +95,7 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -92,6 +95,7 @@ public class SettlementServiceImpl implements SettlementService { |
| 92 | private final MealServiceRpcClient mealServiceRpcClient; | 95 | private final MealServiceRpcClient mealServiceRpcClient; |
| 93 | private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient; | 96 | private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient; |
| 94 | private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient; | 97 | private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient; |
| 98 | + private final OperatorServiceRpcClient operatorServiceRpcClient; | ||
| 95 | 99 | ||
| 96 | public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto) | 100 | public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto) |
| 97 | throws IOException { | 101 | throws IOException { |
| ... | @@ -347,6 +351,14 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -347,6 +351,14 @@ public class SettlementServiceImpl implements SettlementService { |
| 347 | cell1.setCellValue("订单号"); | 351 | cell1.setCellValue("订单号"); |
| 348 | cell1.setCellStyle(headerStyle); | 352 | cell1.setCellStyle(headerStyle); |
| 349 | 353 | ||
| 354 | + Cell cellPayTime = titleRow.createCell(columnNum++); | ||
| 355 | + cellPayTime.setCellValue("支付时间"); | ||
| 356 | + cellPayTime.setCellStyle(headerStyle); | ||
| 357 | + | ||
| 358 | + Cell cellOrderer = titleRow.createCell(columnNum++); | ||
| 359 | + cellOrderer.setCellValue("下单人"); | ||
| 360 | + cellOrderer.setCellStyle(headerStyle); | ||
| 361 | + | ||
| 350 | Cell cell2 = titleRow.createCell(columnNum++); | 362 | Cell cell2 = titleRow.createCell(columnNum++); |
| 351 | cell2.setCellValue("餐别"); | 363 | cell2.setCellValue("餐别"); |
| 352 | cell2.setCellStyle(headerStyle); | 364 | cell2.setCellStyle(headerStyle); |
| ... | @@ -422,6 +434,14 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -422,6 +434,14 @@ public class SettlementServiceImpl implements SettlementService { |
| 422 | dataCell1.setCellValue(orderDetail.getCode() != null ? orderDetail.getCode() : ""); | 434 | dataCell1.setCellValue(orderDetail.getCode() != null ? orderDetail.getCode() : ""); |
| 423 | dataCell1.setCellStyle(dataStyle); | 435 | dataCell1.setCellStyle(dataStyle); |
| 424 | 436 | ||
| 437 | + Cell dataCellPayTime = dataRow.createCell(columnNum++); | ||
| 438 | + dataCellPayTime.setCellValue(orderDetail.getPayTime() != null ? orderDetail.getPayTime() : ""); | ||
| 439 | + dataCellPayTime.setCellStyle(dataStyle); | ||
| 440 | + | ||
| 441 | + Cell dataCellOrderer = dataRow.createCell(columnNum++); | ||
| 442 | + dataCellOrderer.setCellValue(orderDetail.getOrderer() != null ? orderDetail.getOrderer() : ""); | ||
| 443 | + dataCellOrderer.setCellStyle(dataStyle); | ||
| 444 | + | ||
| 425 | Cell dataCell2 = dataRow.createCell(columnNum++); | 445 | Cell dataCell2 = dataRow.createCell(columnNum++); |
| 426 | dataCell2.setCellValue(orderDetail.getMealName() != null ? orderDetail.getMealName() : ""); | 446 | dataCell2.setCellValue(orderDetail.getMealName() != null ? orderDetail.getMealName() : ""); |
| 427 | dataCell2.setCellStyle(dataStyle); | 447 | dataCell2.setCellStyle(dataStyle); |
| ... | @@ -511,7 +531,7 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -511,7 +531,7 @@ public class SettlementServiceImpl implements SettlementService { |
| 511 | } | 531 | } |
| 512 | 532 | ||
| 513 | // 自动调整列宽 | 533 | // 自动调整列宽 |
| 514 | - for (int i = 0; i < 17; i++) { | 534 | + for (int i = 0; i < 19; i++) { |
| 515 | sheet.autoSizeColumn(i); | 535 | sheet.autoSizeColumn(i); |
| 516 | } | 536 | } |
| 517 | 537 | ||
| ... | @@ -838,6 +858,16 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -838,6 +858,16 @@ public class SettlementServiceImpl implements SettlementService { |
| 838 | final List<SingleClientCustomerRpcResponse> customers = customerResponse.getResponsesList(); | 858 | final List<SingleClientCustomerRpcResponse> customers = customerResponse.getResponsesList(); |
| 839 | final var customerMap = customers.stream().collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1)); | 859 | final var customerMap = customers.stream().collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, c -> c, (c1, c2) -> c1)); |
| 840 | 860 | ||
| 861 | + final List<Integer> stallOperatorIds = orderIds.stream() | ||
| 862 | + .map(orderMap::get) | ||
| 863 | + .filter(Objects::nonNull) | ||
| 864 | + .filter(o -> o.getCreationSource() == OrderSourceEnum.STALL) | ||
| 865 | + .map(SingleClientCustomerOrderRpcResponse::getCreatedBy) | ||
| 866 | + .filter(id -> id > 0) | ||
| 867 | + .distinct() | ||
| 868 | + .collect(Collectors.toList()); | ||
| 869 | + final Map<Integer, String> operatorNameById = buildStallOperatorDisplayNameMap(stallOperatorIds); | ||
| 870 | + | ||
| 841 | // 构建结算订单明细 | 871 | // 构建结算订单明细 |
| 842 | final var classifyOrders = new ArrayList<SettlementDTO.SettlementOrderDetail>(); | 872 | final var classifyOrders = new ArrayList<SettlementDTO.SettlementOrderDetail>(); |
| 843 | for (Integer orderId : orderIds) { | 873 | for (Integer orderId : orderIds) { |
| ... | @@ -854,6 +884,8 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -854,6 +884,8 @@ public class SettlementServiceImpl implements SettlementService { |
| 854 | final var customer = customerMap.get(order.getCustomerId()); | 884 | final var customer = customerMap.get(order.getCustomerId()); |
| 855 | final String customerName = customer != null ? customer.getName() : ""; | 885 | final String customerName = customer != null ? customer.getName() : ""; |
| 856 | final String hisCustomerNo = customer != null ? customer.getHISCustomerNo() : ""; | 886 | final String hisCustomerNo = customer != null ? customer.getHISCustomerNo() : ""; |
| 887 | + final String payTimeStr = formatSettlementPayTime(order.getPayTime()); | ||
| 888 | + final String orderer = resolveSettlementOrderer(order, customer, operatorNameById); | ||
| 857 | 889 | ||
| 858 | final var orderOperationRecords = orderOperationRecordByOrderId.getOrDefault(orderId, Collections.emptyList()); | 890 | final var orderOperationRecords = orderOperationRecordByOrderId.getOrDefault(orderId, Collections.emptyList()); |
| 859 | 891 | ||
| ... | @@ -881,10 +913,10 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -881,10 +913,10 @@ public class SettlementServiceImpl implements SettlementService { |
| 881 | && addOriginalDetailMap.get(orderDetail.getId()).getCount() != orderDetail.getCount()) { | 913 | && addOriginalDetailMap.get(orderDetail.getId()).getCount() != orderDetail.getCount()) { |
| 882 | final var orderDetailBO = addOriginalDetailMap.get(orderDetail.getId()); | 914 | final var orderDetailBO = addOriginalDetailMap.get(orderDetail.getId()); |
| 883 | SettlementDTO.SettlementOrderDetail beforeChange = buildSettlementOrderDetail( | 915 | SettlementDTO.SettlementOrderDetail beforeChange = buildSettlementOrderDetail( |
| 884 | - order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetailBO.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 916 | + order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetailBO.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 885 | classifyOrders.add(beforeChange); | 917 | classifyOrders.add(beforeChange); |
| 886 | SettlementDTO.SettlementOrderDetail afterChange = buildSettlementOrderDetail( | 918 | SettlementDTO.SettlementOrderDetail afterChange = buildSettlementOrderDetail( |
| 887 | - order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetail.getCount() - orderDetailBO.getCount(), orderDetail.getPrice(), "加餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 919 | + order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetail.getCount() - orderDetailBO.getCount(), orderDetail.getPrice(), "加餐", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 888 | classifyOrders.add(afterChange); | 920 | classifyOrders.add(afterChange); |
| 889 | } | 921 | } |
| 890 | 922 | ||
| ... | @@ -894,20 +926,20 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -894,20 +926,20 @@ public class SettlementServiceImpl implements SettlementService { |
| 894 | final var orderDetailBO = replaceOriginalDetailMap.get(orderDetail.getId()); | 926 | final var orderDetailBO = replaceOriginalDetailMap.get(orderDetail.getId()); |
| 895 | final var orderDetailAdjustBO = replaceAdjustDetailMap.get(orderDetail.getId()); | 927 | final var orderDetailAdjustBO = replaceAdjustDetailMap.get(orderDetail.getId()); |
| 896 | SettlementDTO.SettlementOrderDetail beforeChange = buildSettlementOrderDetail( | 928 | SettlementDTO.SettlementOrderDetail beforeChange = buildSettlementOrderDetail( |
| 897 | - order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetailBO.getCount(), orderDetailBO.getPrice(), "换菜前", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 929 | + order, orderDetail.getMenuDetailId(), orderDetailBO.getSkuId(), orderDetailBO.getCount(), orderDetailBO.getPrice(), "换菜前", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 898 | classifyOrders.add(beforeChange); | 930 | classifyOrders.add(beforeChange); |
| 899 | SettlementDTO.SettlementOrderDetail afterChange = buildSettlementOrderDetail( | 931 | SettlementDTO.SettlementOrderDetail afterChange = buildSettlementOrderDetail( |
| 900 | - order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetailAdjustBO.getPrice(), "换菜后", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 932 | + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetailAdjustBO.getPrice(), "换菜后", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 901 | classifyOrders.add(afterChange); | 933 | classifyOrders.add(afterChange); |
| 902 | } | 934 | } |
| 903 | 935 | ||
| 904 | // 3. 判断已退款 | 936 | // 3. 判断已退款 |
| 905 | if (orderDetail.getServeStatus() == ServeStatusEnum.SERVE_REJECT) { | 937 | if (orderDetail.getServeStatus() == ServeStatusEnum.SERVE_REJECT) { |
| 906 | SettlementDTO.SettlementOrderDetail refundRecord1 = buildSettlementOrderDetail( | 938 | SettlementDTO.SettlementOrderDetail refundRecord1 = buildSettlementOrderDetail( |
| 907 | - order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 939 | + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 908 | classifyOrders.add(refundRecord1); | 940 | classifyOrders.add(refundRecord1); |
| 909 | SettlementDTO.SettlementOrderDetail refundRecord2 = buildSettlementOrderDetail( | 941 | SettlementDTO.SettlementOrderDetail refundRecord2 = buildSettlementOrderDetail( |
| 910 | - order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), -orderDetail.getCount(), orderDetail.getPrice(), "已退款", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 942 | + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), -orderDetail.getCount(), orderDetail.getPrice(), "已退款", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 911 | classifyOrders.add(refundRecord2); | 943 | classifyOrders.add(refundRecord2); |
| 912 | } | 944 | } |
| 913 | 945 | ||
| ... | @@ -920,7 +952,7 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -920,7 +952,7 @@ public class SettlementServiceImpl implements SettlementService { |
| 920 | 952 | ||
| 921 | if (isNormal) { | 953 | if (isNormal) { |
| 922 | SettlementDTO.SettlementOrderDetail normalRecord = buildSettlementOrderDetail( | 954 | SettlementDTO.SettlementOrderDetail normalRecord = buildSettlementOrderDetail( |
| 923 | - order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, menuDetailMap, mealMap, skuMap); | 955 | + order, orderDetail.getMenuDetailId(), orderDetail.getSkuId(), orderDetail.getCount(), orderDetail.getPrice(), "订餐", menuName, customerName, hisCustomerNo, payTimeStr, orderer, menuDetailMap, mealMap, skuMap); |
| 924 | classifyOrders.add(normalRecord); | 956 | classifyOrders.add(normalRecord); |
| 925 | } | 957 | } |
| 926 | } | 958 | } |
| ... | @@ -950,6 +982,8 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -950,6 +982,8 @@ public class SettlementServiceImpl implements SettlementService { |
| 950 | String menuName, | 982 | String menuName, |
| 951 | String customerName, | 983 | String customerName, |
| 952 | String hisCustomerNo, | 984 | String hisCustomerNo, |
| 985 | + String payTimeStr, | ||
| 986 | + String orderer, | ||
| 953 | Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap, | 987 | Map<Integer, SingleMenuDetailRpcResponse> menuDetailMap, |
| 954 | Map<Integer, SingleMealRpcResponse> mealMap, | 988 | Map<Integer, SingleMealRpcResponse> mealMap, |
| 955 | Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) { | 989 | Map<Integer, SingleDishSkuByIdsRpcResponse> skuMap) { |
| ... | @@ -962,6 +996,8 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -962,6 +996,8 @@ public class SettlementServiceImpl implements SettlementService { |
| 962 | return SettlementDTO.SettlementOrderDetail.builder() | 996 | return SettlementDTO.SettlementOrderDetail.builder() |
| 963 | .mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "") | 997 | .mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "") |
| 964 | .code(order.getOrderCode()) | 998 | .code(order.getOrderCode()) |
| 999 | + .payTime(payTimeStr != null ? payTimeStr : "") | ||
| 1000 | + .orderer(orderer != null ? orderer : "") | ||
| 965 | .mealName(mealName) | 1001 | .mealName(mealName) |
| 966 | .roomNo(roomNo) | 1002 | .roomNo(roomNo) |
| 967 | .customerName(customerName) | 1003 | .customerName(customerName) |
| ... | @@ -1067,6 +1103,69 @@ public class SettlementServiceImpl implements SettlementService { | ... | @@ -1067,6 +1103,69 @@ public class SettlementServiceImpl implements SettlementService { |
| 1067 | } | 1103 | } |
| 1068 | } | 1104 | } |
| 1069 | 1105 | ||
| 1106 | + private Map<Integer, String> buildStallOperatorDisplayNameMap(List<Integer> operatorIds) { | ||
| 1107 | + if (operatorIds == null || operatorIds.isEmpty()) { | ||
| 1108 | + return Collections.emptyMap(); | ||
| 1109 | + } | ||
| 1110 | + final List<SingleCOperatorRpcResponse> operators = operatorServiceRpcClient.getCOperatorsByIds(operatorIds); | ||
| 1111 | + final Map<Integer, String> map = new HashMap<>(); | ||
| 1112 | + for (SingleCOperatorRpcResponse op : operators) { | ||
| 1113 | + if (op != null && op.getId() != 0) { | ||
| 1114 | + map.put(op.getId(), stallOperatorDisplayName(op)); | ||
| 1115 | + } | ||
| 1116 | + } | ||
| 1117 | + return map; | ||
| 1118 | + } | ||
| 1119 | + | ||
| 1120 | + private static String stallOperatorDisplayName(SingleCOperatorRpcResponse op) { | ||
| 1121 | + if (op == null) { | ||
| 1122 | + return ""; | ||
| 1123 | + } | ||
| 1124 | + if (StringUtils.isNotBlank(op.getAlias())) { | ||
| 1125 | + return op.getAlias(); | ||
| 1126 | + } | ||
| 1127 | + if (StringUtils.isNotBlank(op.getName())) { | ||
| 1128 | + return op.getName(); | ||
| 1129 | + } | ||
| 1130 | + return ""; | ||
| 1131 | + } | ||
| 1132 | + | ||
| 1133 | + private static String formatSettlementPayTime(long payTimeMillis) { | ||
| 1134 | + if (payTimeMillis == 0L) { | ||
| 1135 | + return ""; | ||
| 1136 | + } | ||
| 1137 | + final String formatted = DateUtil.formatDate(payTimeMillis, DateUtil.Y_M_D_H_M_S); | ||
| 1138 | + return formatted != null ? formatted : ""; | ||
| 1139 | + } | ||
| 1140 | + | ||
| 1141 | + /** | ||
| 1142 | + * 院区端(STALL):操作员名称;住院部小程序(MINI_PROGRAM):客户姓名;阳光厅(MIDDLE_PLATFORM):客户手机号。 | ||
| 1143 | + */ | ||
| 1144 | + private static String resolveSettlementOrderer(SingleClientCustomerOrderRpcResponse order, | ||
| 1145 | + SingleClientCustomerRpcResponse customer, | ||
| 1146 | + Map<Integer, String> stallOperatorNameById) { | ||
| 1147 | + if (order == null) { | ||
| 1148 | + return ""; | ||
| 1149 | + } | ||
| 1150 | + return switch (order.getCreationSource()) { | ||
| 1151 | + case STALL -> { | ||
| 1152 | + int createdBy = order.getCreatedBy(); | ||
| 1153 | + if (createdBy <= 0 || stallOperatorNameById == null) { | ||
| 1154 | + yield ""; | ||
| 1155 | + } | ||
| 1156 | + String name = stallOperatorNameById.get(createdBy); | ||
| 1157 | + yield name != null ? name : ""; | ||
| 1158 | + } | ||
| 1159 | + case MINI_PROGRAM -> customer != null && StringUtils.isNotBlank(customer.getName()) | ||
| 1160 | + ? customer.getName() | ||
| 1161 | + : ""; | ||
| 1162 | + case MIDDLE_PLATFORM -> customer != null && StringUtils.isNotBlank(customer.getMobile()) | ||
| 1163 | + ? customer.getMobile() | ||
| 1164 | + : order.getOpenId(); | ||
| 1165 | + default -> ""; | ||
| 1166 | + }; | ||
| 1167 | + } | ||
| 1168 | + | ||
| 1070 | /** | 1169 | /** |
| 1071 | * 计算单价 | 1170 | * 计算单价 |
| 1072 | */ | 1171 | */ | ... | ... |
-
Please register or login to post a comment