HisCustomerRoomNoTask.java 7.72 KB
package com.infoloop.tianting.logic.async;

import com.infoloop.rpc.meizhongyiheservice.Customer;
import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification;
import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerRpcResponse;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.model.dto.OrderDbDTO;
import com.infoloop.tianting.server.WebSocketServer;
import com.infoloop.tianting.server.message.MessageTypeEnum;
import com.infoloop.tianting.server.message.NoticeTypeEnum;
import com.infoloop.tianting.server.message.SocketMessage;
import com.infoloop.tianting.server.message.data.CustomerAlterRoomNoData;
import com.infoloop.tianting.server.session.UserSessionKey;
import com.infoloop.tianting.server.session.UserTypeEnum;
import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient;
import com.infoloop.tianting.service.client.InventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MeiZhongYiHeServiceClient;
import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.infoloop.tianting.constant.ConfigConstants.ASYNC_EXECUTOR;

@Slf4j
@Component
@RequiredArgsConstructor
public class HisCustomerRoomNoTask {

    private final OperatorServiceRpcClient operatorServiceRpcClient;

    private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;

    private final InventoryServiceRpcClient inventoryServiceRpcClient;

    private final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient;

    private final OrderServiceRpcClient orderServiceRpcClient;

    private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;

    @Async(ASYNC_EXECUTOR)
    public void synchronization(LoginContextHolder.LoginInfo loginInfo) throws IOException {
        final var cOperatorById = operatorServiceRpcClient.getCOperatorById(loginInfo.getId());

        final var stallIdsList = clientResourceTagServiceRpcClient
                .getUserResources(cOperatorById.getEnterpriseId(), cOperatorById.getClientId(), cOperatorById.getId())
                .getStallIdsList();

        final var stalls = inventoryServiceRpcClient
                .getStallsByIds(cOperatorById.getEnterpriseId(), stallIdsList)
                .getClientsList();

        final var stallCodes = stalls.stream()
                .filter(e -> !e.getIsDelivery())
                .map(SingleClientRpcResponse::getCode)
                .collect(Collectors.toList());

        final var customersList = meiZhongYiHeServiceClient.getCustomersByCondition(stallCodes);
        final var hisCustomerIds = customersList.stream().map(Customer::getCustomerId).collect(Collectors.toList());

        final var customerMap = customersList.stream()
                .collect(Collectors.toMap(Customer::getCustomerId, Function.identity(), (a, b) -> a));

        final var queryOrderDto = OrderDbDTO.QueryOrderByConditionDto.builder()
                .shouldFilterStallIds(true)
                .stallIds(stallIdsList)
                .shouldFilterStatues(true)
                .statues(List.of(OrderStatusEnum.TO_PREPARE, OrderStatusEnum.PREPARING))
                .build();

        final var orders = orderServiceRpcClient.getOrdersByCondition(queryOrderDto);

        final var clientCustomerMap = clientCustomerServiceRpcClient.getClientCustomersByHISCustomerIds(hisCustomerIds)
                .getResponsesList()
                .stream()
                .collect(Collectors.toMap(SingleClientCustomerRpcResponse::getId, Function.identity(), (a, b) -> a));

        final var alterRoomNoCustomers = orders.stream()
                .map(order -> {
                    final var singleClientCustomerRpcResponse = clientCustomerMap.get(order.getCustomerId());
                    if (singleClientCustomerRpcResponse == null) {
                        return null;
                    }
                    final var customer = customerMap.get(singleClientCustomerRpcResponse.getHISCustomerId());
                    if (customer == null) {
                        log.error("customer is null for HIS customerId: {}", singleClientCustomerRpcResponse.getHISCustomerId());
                        return null;
                    }
                    final var syncRoomNo = customer.getCustomerHospitalRecord().getRoomNo();
                    if (!syncRoomNo.equals(order.getRoomNo())) {
                        return CustomerAlterRoomNoData.AlterRoomNoCustomer.builder()
                                .orderId(order.getId())
                                .customerId(singleClientCustomerRpcResponse.getId())
                                .roomNo(order.getRoomNo())
                                .alterRoomNo(syncRoomNo)
                                .build();
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 记录找不到 HIS 客户 ID 的错误日志
        final var missingCustomerIds = orders.stream()
                .map(order -> clientCustomerMap.get(order.getCustomerId()))
                .filter(Objects::nonNull)
                .map(SingleClientCustomerRpcResponse::getHISCustomerId)
                .filter(hisId -> !customerMap.containsKey(hisId))
                .collect(Collectors.toList());

        if (!missingCustomerIds.isEmpty()) {
            log.error("customer is null for HIS customerIds: {}", missingCustomerIds);
        }

        if (alterRoomNoCustomers.isEmpty()) {
            return;
        }

        final var isUpdated = orderServiceRpcClient.batchUpdateClientCustomerOrders(
                loginInfo,
                alterRoomNoCustomers.stream()
                        .map(e -> ClientCustomerOrderModification.newBuilder()
                                .setId(e.getOrderId())
                                .setShouldUpdateSyncRoomNo(true)
                                .setSyncRoomNo(e.getAlterRoomNo())
                                .build())
                        .collect(Collectors.toList()));

        if (!isUpdated) {
            log.error("OrderServiceRpcClient.batchUpdateClientCustomerOrders error");
            return;
        }

        final var affectedCustomers = alterRoomNoCustomers.stream()
                .map(CustomerAlterRoomNoData.AlterRoomNoCustomer::getCustomerId)
                .distinct()
                .count();

        final var data = SocketMessage.<CustomerAlterRoomNoData>builder()
                .type(MessageTypeEnum.CUSTOMER)
                .noticeType(NoticeTypeEnum.CUSTOMER_ALTER_ROOM_NO)
                .subject(NoticeTypeEnum.CUSTOMER_ALTER_ROOM_NO.getDescription())
                .message("有" + affectedCustomers + " 个客户房间号发生了变更,系统已显示最新房间号。")
                .data(CustomerAlterRoomNoData.builder().alterRoomNoCustomers(alterRoomNoCustomers).build())
                .build();

        WebSocketServer.sendMessageToUser(
                UserSessionKey.builder()
                        .userId(String.valueOf(loginInfo.getId()))
                        .userType(UserTypeEnum.CLIENT)
                        .build(),
                data
        );
    }
}