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

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.infoloop.rpc.meizhongyiheservice.Customer;
import com.infoloop.tianting.clientcustomerorderservice.ClientCustomerOrderModification;
import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordModification;
import com.infoloop.tianting.clientcustomerservice.ClientCustomerOperationRecordCreation;
import com.infoloop.tianting.clientcustomerservice.ClientCustomerOperationRecordTypeEnum;
import com.infoloop.tianting.clientcustomerservice.SingleClientCustomerHospitalRecordRpcResponse;
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.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient;
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 ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;

    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 = clientInventoryServiceRpcClient.getStallsByIds(cOperatorById.getEnterpriseId(), stallIdsList).getClientsList();

        final var queryOrderDto = OrderDbDTO.QueryOrderByConditionDto.builder()
                .enterpriseId(loginInfo.getEnterpriseId())
                .shouldFilterStallIds(true)
                .stallIds(stallIdsList)
                .shouldFilterStatues(true)
                .statues(List.of(OrderStatusEnum.TO_PREPARE, OrderStatusEnum.PREPARING))
                .build();
        final var orders = orderServiceRpcClient.getOrdersByCondition(queryOrderDto);
        if (orders.isEmpty()) {
            return;
        }

        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()));

        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()) && !syncRoomNo.equals(order.getSyncRoomNo())) {
                        log.info("customer roomNo alter for orderId: {}, roomNo: {}, syncRoomNo: {}", order.getId(), order.getRoomNo(), syncRoomNo);
                        return CustomerAlterRoomNoData.AlterRoomNoCustomer.builder()
                                .orderId(order.getId())
                                .customerId(singleClientCustomerRpcResponse.getId())
                                .roomNo(order.getRoomNo())
                                .alterRoomNo(syncRoomNo)
                                .build();
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        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 customerIds = alterRoomNoCustomers.stream()
                .map(CustomerAlterRoomNoData.AlterRoomNoCustomer::getCustomerId)
                .distinct()
                .collect(Collectors.toList());

        final var clientCustomerHospitalRecordMap = clientCustomerServiceRpcClient.getClientCustomerHospitalRecordsByCustomerIds(loginInfo.getEnterpriseId(), customerIds).stream().collect(Collectors.toMap(SingleClientCustomerHospitalRecordRpcResponse::getCustomerId, Function.identity()));

        clientCustomerServiceRpcClient.batchUpdateClientCustomerHospitalRecords(
                loginInfo,
                alterRoomNoCustomers.stream()
                        .map(e -> {
                            final var hospitalRecordRpcResponse = clientCustomerHospitalRecordMap.get(e.getCustomerId());
                            return ClientCustomerHospitalRecordModification.newBuilder()
                                    .setId(hospitalRecordRpcResponse.getId())
                                    .setShouldUpdateRoomNo(true)
                                    .setRoomNo(e.getAlterRoomNo())
                                    .build();
                        })
                        .collect(Collectors.toList()));

        final var gson = new Gson();
        final var uniqueAlterRoomNoCustomers = alterRoomNoCustomers.stream().collect(Collectors.toMap(CustomerAlterRoomNoData.AlterRoomNoCustomer::getCustomerId, Function.identity(), (existing, replacement) -> existing)).values();
        final var creations = uniqueAlterRoomNoCustomers.stream()
                .map(customer -> {
                    var originalJson = new JsonObject();
                    originalJson.addProperty("roomNo", customer.getRoomNo());
                    var adjustJson = new JsonObject();
                    adjustJson.addProperty("roomNo", customer.getAlterRoomNo());
                    return ClientCustomerOperationRecordCreation.newBuilder()
                            .setClientCustomerId(customer.getCustomerId())
                            .setOperator(loginInfo.getName())
                            .setType(ClientCustomerOperationRecordTypeEnum.CLIENT_CUSTOMER_OPERATION_RECORD_TYPE_UPDATE_ROOM_NO)
                            .setShouldCreateOriginalJson(true)
                            .setOriginalJson(gson.toJson(originalJson))
                            .setShouldCreateAdjustJson(true)
                            .setAdjustJson(gson.toJson(adjustJson))
                            .build();
                })
                .collect(Collectors.toList());
        clientCustomerServiceRpcClient.batchCreateClientCustomerOperationRecords(loginInfo, creations);

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

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