SkuServiceImpl.java 12 KB
package com.infoloop.tianting.service.impl;

import com.infoloop.tianting.SingleSkuResponse;
import com.infoloop.tianting.clientcustomerorderservice.SingleSkuSellQuantityRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.SkuSellQuantityStatus;
import com.infoloop.tianting.model.bo.SkuSellQuantityBO;
import com.infoloop.tianting.model.common.PageResult;
import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDetailSingleResponseDto;
import com.infoloop.tianting.model.dto.SkuDbDTO.SkuDto;
import com.infoloop.tianting.model.dto.SkuDbDTO.SkuSpecialDetailSingleResponseDto;
import com.infoloop.tianting.model.dto.SkuSellQuantityDTO;
import com.infoloop.tianting.model.vo.SkuSellQuantityStatisticsVO;
import com.infoloop.tianting.model.vo.SkuSellQuantityVO;
import com.infoloop.tianting.service.MenuService;
import com.infoloop.tianting.service.SkuService;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
import com.infoloop.tianting.service.client.SkuServiceRpcClient;
import com.infoloop.tianting.utils.DateUtil;
import com.infoloop.tianting.utils.PageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SkuServiceImpl implements SkuService {

    private final MenuService menuService;

    private final SkuServiceRpcClient skuServiceRpcClient;

    private final OrderServiceRpcClient orderServiceRpcClient;

    @Override
    public List<SkuDto> getSkusByIds(List<Integer> ids) {
        final var response = skuServiceRpcClient.getDishSkusByIds(ids);
        return response.getResponseList().stream().map(sku ->
                SkuDto.builder()
                        .id(sku.getId())
                        .categoryId(sku.getCategoryId())
                        .name(sku.getName())
                        .enterpriseId(sku.getEnterpriseId())
                        .description(sku.getDescription())
                        .code(sku.getCode())
                        .alias(sku.getAlias())
                        .imageUrl(sku.getImageUrl())
                        .basicMaterials(sku.getBasicMaterials())
                        .carbohydrate(sku.getCarbohydrate())
                        .createdAt(DateUtil.formatDate(sku.getCreatedAt()))
                        .energy(sku.getEnergy())
                        .fat(sku.getFat())
                        .protein(sku.getProtein())
                        .skuList(sku.getSkusList().stream().map(subSku -> SkuDetailSingleResponseDto.builder().id(subSku.getId()).name(subSku.getName()).build()).collect(
                                Collectors.toList()))
                        .tasteList(sku.getTastesList().stream().map(taste -> SkuDetailSingleResponseDto.builder().id(taste.getId()).name(taste.getName()).build()).collect(
                                Collectors.toList()))
                        .efficacyList(sku.getEfficaciesList().stream().map(efficacy -> SkuDetailSingleResponseDto.builder().id(efficacy.getId()).name(efficacy.getName()).build()).collect(
                                Collectors.toList()))
                        .doctorList(sku.getDoctorsList().stream().map(doctor -> SkuSpecialDetailSingleResponseDto
                                .builder().id(doctor.getId()).code(doctor.getCode()).name(doctor.getName()).build()).collect(
                                Collectors.toList()))
                        .avoidList(sku.getAvoidsList().stream().map(avoid -> SkuDetailSingleResponseDto.builder().id(avoid.getId()).name(avoid.getName()).build()).collect(
                                Collectors.toList()))
                        .allergyList(sku.getAllergiesList().stream().map(allergy -> SkuSpecialDetailSingleResponseDto.builder().id(allergy.getId()).name(allergy.getName()).build()).collect(
                                Collectors.toList()))
                        .cecommendList(sku.getCecommendsList().stream().map(cecommend -> SkuDetailSingleResponseDto.builder().id(cecommend.getId()).name(cecommend.getName()).build()).collect(Collectors.toList()))
                        .build()
        ).collect(Collectors.toList());
    }

    @Override
    public SkuSellQuantityStatisticsVO querySkuSellQuantityStatistics(int stallId) {
        final var skuIds = menuService.queryMenuSkuIdsByStallId(LoginContextHolder.getEnterpriseId(), stallId);
        final var responses = orderServiceRpcClient.querySkuSellQuantitiesByStall(LoginContextHolder.getEnterpriseId(), stallId);
        final var skuSellQuantitiesMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity()));
        final var soldOut = skuIds.stream()
                .filter(e -> skuSellQuantitiesMap.get(e) == null || skuSellQuantitiesMap.get(e).getMaxSellQuantity() == skuSellQuantitiesMap.get(e).getTodaySellQuantity())
                .count();
        final int total = skuIds.size();
        return SkuSellQuantityStatisticsVO.builder()
                .total(total)
                .soldOut(soldOut)
                .onSale(total - soldOut)
                .build();
    }

    @Override
    public PageResult<SkuSellQuantityVO> querySkuSellQuantity(SkuSellQuantityDTO.QuerySkuSellQuantityDTO querySkuSellQuantityDTO) {
        final var stallId = querySkuSellQuantityDTO.getStallId();
        final var enterpriseId = LoginContextHolder.getEnterpriseId();
        final var skuIds = menuService.queryMenuSkuIdsByStallId(enterpriseId, stallId);
        var responses = orderServiceRpcClient.querySkuSellQuantitiesByStall(enterpriseId, stallId);
        final var skuSellQuantityMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity()));
        responses = skuIds.stream()
                .map(skuId -> {
                    var response = skuSellQuantityMap.get(skuId);
                    if (response == null) {
                        response = SingleSkuSellQuantityRpcResponse.newBuilder()
                                .setSkuId(skuId)
                                .setMaxSellQuantity(0)
                                .setTodaySellQuantity(0)
                                .build();
                    }
                    return response;
                })
                .collect(Collectors.toList());
        if (querySkuSellQuantityDTO.getStatus() != SkuSellQuantityStatus.ALL) {
            responses = responses.stream()
                    .filter(e -> {
                        if (querySkuSellQuantityDTO.getStatus() == SkuSellQuantityStatus.SOLD_OUT) {
                            return e.getMaxSellQuantity() == e.getTodaySellQuantity();
                        } else if (querySkuSellQuantityDTO.getStatus() == SkuSellQuantityStatus.ON_SALE) {
                            return e.getMaxSellQuantity() != e.getTodaySellQuantity();
                        }
                        return true;
                    })
                    .collect(Collectors.toList());
        }
        final var skuList = skuServiceRpcClient.getSkusByIds(responses.stream().map(SingleSkuSellQuantityRpcResponse::getSkuId).collect(Collectors.toList()));
        final var skuMap = skuList.stream().collect(Collectors.toMap(SingleSkuResponse::getId, Function.identity()));
        final var keyword = querySkuSellQuantityDTO.getKeyword();
        if (keyword != null && !keyword.isEmpty()) {
            responses = responses.stream()
                    .filter(e -> {
                        var sku = skuMap.get(e.getSkuId());
                        return sku != null && (sku.getCode().contains(keyword) || sku.getName().contains(keyword));
                    })
                    .collect(Collectors.toList());
        }
        final var skuSellQuantityVOS = responses.stream()
                .map(e -> {
                    var sku = skuMap.get(e.getSkuId());
                    return SkuSellQuantityVO.builder()
                            .skuId(e.getSkuId())
                            .skuName(sku != null ? sku.getName() : "")
                            .skuCode(sku != null ? sku.getCode() : "")
                            .maxSellQuantity(e.getMaxSellQuantity())
                            .todaySellQuantity(e.getTodaySellQuantity())
                            .soldOut(e.getMaxSellQuantity() == e.getTodaySellQuantity())
                            .build();
                })
                .sorted(Comparator.comparing(SkuSellQuantityVO::getSkuCode))
                .collect(Collectors.toList());
        return PageUtil.subListPage(skuSellQuantityVOS, querySkuSellQuantityDTO.getPageNo(), querySkuSellQuantityDTO.getPageSize());
    }

    @Override
    public boolean batchSetSkuSellQuantity(int stallId, SkuSellQuantityDTO.BatchSetSkuSellQuantityDTO batchSetSkuSellQuantityDTO) {
        final var responses = orderServiceRpcClient.querySkuSellQuantitiesByStallAndSkuIds(LoginContextHolder.getEnterpriseId(), stallId, batchSetSkuSellQuantityDTO.getSkuIds());
        final var skuMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity()));
        final var skuSellQuantityBOs = batchSetSkuSellQuantityDTO.getSkuIds().stream().map(skuId -> SkuSellQuantityBO.builder()
                .id(skuMap.get(skuId) == null ? null : skuMap.get(skuId).getId())
                .skuId(skuId)
                .maxSellQuantity(batchSetSkuSellQuantityDTO.getMaxSellQuantity())
                .build()
        ).collect(Collectors.toList());
        return orderServiceRpcClient.batchSaveSkuSellQuantities(LoginContextHolder.getEnterpriseId(), stallId, skuSellQuantityBOs);
    }

    @Override
    public List<SkuSellQuantityVO> querySkuSellQuantityBySkuIds(SkuSellQuantityDTO.QuerySkuSellQuantityBySkuIdsDTO querySkuSellQuantityBySkuIdsDTO) {
        final var stallId = querySkuSellQuantityBySkuIdsDTO.getStallId();
        final var enterpriseId = LoginContextHolder.getEnterpriseId();
        final var skuIds = menuService.queryMenuSkuIdsByStallId(enterpriseId, stallId);
        var responses = orderServiceRpcClient.querySkuSellQuantitiesByStall(enterpriseId, stallId);
        final var skuSellQuantityMap = responses.stream().collect(Collectors.toMap(SingleSkuSellQuantityRpcResponse::getSkuId, Function.identity()));
        responses = skuIds.stream()
                .map(skuId -> {
                    var response = skuSellQuantityMap.get(skuId);
                    if (response == null) {
                        response = SingleSkuSellQuantityRpcResponse.newBuilder()
                                .setSkuId(skuId)
                                .setMaxSellQuantity(0)
                                .setTodaySellQuantity(0)
                                .build();
                    }
                    return response;
                })
                .collect(Collectors.toList());
        final var skuList = skuServiceRpcClient.getSkusByIds(responses.stream().map(SingleSkuSellQuantityRpcResponse::getSkuId).collect(Collectors.toList()));
        final var skuMap = skuList.stream().collect(Collectors.toMap(SingleSkuResponse::getId, Function.identity()));
        return responses.stream()
                .map(e -> {
                    var sku = skuMap.get(e.getSkuId());
                    return SkuSellQuantityVO.builder()
                            .skuId(e.getSkuId())
                            .skuName(sku != null ? sku.getName() : "")
                            .skuCode(sku != null ? sku.getCode() : "")
                            .maxSellQuantity(e.getMaxSellQuantity())
                            .todaySellQuantity(e.getTodaySellQuantity())
                            .soldOut(e.getMaxSellQuantity() == e.getTodaySellQuantity())
                            .build();
                })
                .sorted(Comparator.comparing(SkuSellQuantityVO::getSkuCode))
                .collect(Collectors.toList());
    }
}