|
@@ -1,22 +1,33 @@
|
|
|
package org.dromara.order.dubbo;
|
|
package org.dromara.order.dubbo;
|
|
|
|
|
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
import org.apache.dubbo.config.annotation.DubboService;
|
|
import org.apache.dubbo.config.annotation.DubboService;
|
|
|
import org.dromara.common.core.enums.OrderStatus;
|
|
import org.dromara.common.core.enums.OrderStatus;
|
|
|
|
|
+import org.dromara.customer.api.RemoteCustomerService;
|
|
|
import org.dromara.order.domain.OrderMain;
|
|
import org.dromara.order.domain.OrderMain;
|
|
|
|
|
+import org.dromara.order.domain.OrderProduct;
|
|
|
import org.dromara.order.domain.OrderReturn;
|
|
import org.dromara.order.domain.OrderReturn;
|
|
|
import org.dromara.order.service.IOrderMainService;
|
|
import org.dromara.order.service.IOrderMainService;
|
|
|
|
|
+import org.dromara.order.service.IOrderProductService;
|
|
|
import org.dromara.order.service.IOrderReturnService;
|
|
import org.dromara.order.service.IOrderReturnService;
|
|
|
import org.dromara.product.api.RemoteOrderInfoService;
|
|
import org.dromara.product.api.RemoteOrderInfoService;
|
|
|
|
|
+import org.dromara.product.api.domain.dto.HotProductRankingDto;
|
|
|
|
|
+import org.dromara.product.api.domain.dto.LatestOrderDto;
|
|
|
|
|
+import org.dromara.product.api.domain.dto.OrderAmountTrendDto;
|
|
|
import org.dromara.product.api.domain.dto.OrderStatusCountDto;
|
|
import org.dromara.product.api.domain.dto.OrderStatusCountDto;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Objects;
|
|
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @author
|
|
* @author
|
|
@@ -32,6 +43,11 @@ public class RemoteOrderInfoServiceImpl implements RemoteOrderInfoService {
|
|
|
|
|
|
|
|
private final IOrderReturnService orderReturnService;
|
|
private final IOrderReturnService orderReturnService;
|
|
|
|
|
|
|
|
|
|
+ private final IOrderProductService orderProductService;
|
|
|
|
|
+
|
|
|
|
|
+ @DubboReference
|
|
|
|
|
+ private RemoteCustomerService remoteCustomerService;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 获取订单各个状态的数量
|
|
* 获取订单各个状态的数量
|
|
|
*/
|
|
*/
|
|
@@ -41,50 +57,187 @@ public class RemoteOrderInfoServiceImpl implements RemoteOrderInfoService {
|
|
|
// 订单数量
|
|
// 订单数量
|
|
|
orderStatusCount.setOrderCount(
|
|
orderStatusCount.setOrderCount(
|
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
|
- .eq(OrderMain::getDataSource, itemKey)
|
|
|
|
|
- ));
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
|
|
+ ));
|
|
|
// 已完成订单数量
|
|
// 已完成订单数量
|
|
|
orderStatusCount.setCompletedCount(
|
|
orderStatusCount.setCompletedCount(
|
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
|
- .eq(OrderMain::getDataSource, itemKey)
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
.eq(OrderMain::getOrderStatus, OrderStatus.COMPLETED)
|
|
.eq(OrderMain::getOrderStatus, OrderStatus.COMPLETED)
|
|
|
- ));
|
|
|
|
|
|
|
+ ));
|
|
|
// 待付款订单数量
|
|
// 待付款订单数量
|
|
|
orderStatusCount.setWaitPayCount(
|
|
orderStatusCount.setWaitPayCount(
|
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
|
- .eq(OrderMain::getDataSource, itemKey)
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
.eq(OrderMain::getOrderStatus, OrderStatus.PENDING_PAYMENT)
|
|
.eq(OrderMain::getOrderStatus, OrderStatus.PENDING_PAYMENT)
|
|
|
- ));
|
|
|
|
|
|
|
+ ));
|
|
|
// 待发货订单数量
|
|
// 待发货订单数量
|
|
|
orderStatusCount.setWaitDeliverCount(
|
|
orderStatusCount.setWaitDeliverCount(
|
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
orderMainService.count(Wrappers.<OrderMain>lambdaQuery()
|
|
|
- .eq(OrderMain::getDataSource, itemKey)
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
.eq(OrderMain::getOrderStatus, OrderStatus.PENDING_SHIPMENT)
|
|
.eq(OrderMain::getOrderStatus, OrderStatus.PENDING_SHIPMENT)
|
|
|
- ));
|
|
|
|
|
|
|
+ ));
|
|
|
// 售后订单数量
|
|
// 售后订单数量
|
|
|
orderStatusCount.setWaitDeliverCount(
|
|
orderStatusCount.setWaitDeliverCount(
|
|
|
orderReturnService.count(Wrappers.<OrderReturn>lambdaQuery()
|
|
orderReturnService.count(Wrappers.<OrderReturn>lambdaQuery()
|
|
|
- .eq(OrderReturn::getDataSource, itemKey)
|
|
|
|
|
- ));
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderReturn::getDataSource, itemKey)
|
|
|
|
|
+ ));
|
|
|
// 订单总金额
|
|
// 订单总金额
|
|
|
List<OrderMain> orderMains = orderMainService.list(Wrappers.<OrderMain>lambdaQuery()
|
|
List<OrderMain> orderMains = orderMainService.list(Wrappers.<OrderMain>lambdaQuery()
|
|
|
- .eq(OrderMain::getDataSource, itemKey)
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
.select(OrderMain::getTotalAmount)
|
|
.select(OrderMain::getTotalAmount)
|
|
|
);
|
|
);
|
|
|
- if(ObjectUtil.isNotEmpty(orderMains)){
|
|
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(orderMains)) {
|
|
|
orderStatusCount.setOrderAmount(orderMains.stream().map(OrderMain::getTotalAmount).filter(Objects::nonNull).reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
|
|
orderStatusCount.setOrderAmount(orderMains.stream().map(OrderMain::getTotalAmount).filter(Objects::nonNull).reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
|
|
|
}
|
|
}
|
|
|
// 售后订单金额 如果为null 则为0
|
|
// 售后订单金额 如果为null 则为0
|
|
|
List<OrderReturn> orderReturns = orderReturnService.list(Wrappers.<OrderReturn>lambdaQuery()
|
|
List<OrderReturn> orderReturns = orderReturnService.list(Wrappers.<OrderReturn>lambdaQuery()
|
|
|
- .eq(OrderReturn::getDataSource, itemKey)
|
|
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderReturn::getDataSource, itemKey)
|
|
|
.select(OrderReturn::getAfterSaleAmount)
|
|
.select(OrderReturn::getAfterSaleAmount)
|
|
|
);
|
|
);
|
|
|
- if(ObjectUtil.isNotEmpty(orderReturns)){
|
|
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(orderReturns)) {
|
|
|
orderStatusCount.setRefundAmount(
|
|
orderStatusCount.setRefundAmount(
|
|
|
- orderReturns.stream().map(OrderReturn::getAfterSaleAmount).filter(Objects::nonNull).reduce(BigDecimal::add).orElse(BigDecimal.ZERO)
|
|
|
|
|
|
|
+ orderReturns.stream().map(OrderReturn::getAfterSaleAmount).filter(Objects::nonNull).reduce(BigDecimal::add).orElse(BigDecimal.ZERO)
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return orderStatusCount;
|
|
return orderStatusCount;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取最新订单列表
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<LatestOrderDto> getLatestOrders(String itemKey, int limit) {
|
|
|
|
|
+ // 查询最新N条一级订单(currentLevel=1),按创建时间倒序
|
|
|
|
|
+ List<OrderMain> orderMains = orderMainService.list(Wrappers.<OrderMain>lambdaQuery()
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
|
|
+ .eq(OrderMain::getCurrentLevel, 1)
|
|
|
|
|
+ .orderByDesc(OrderMain::getCreateTime)
|
|
|
|
|
+ .last("LIMIT " + limit)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (CollUtil.isEmpty(orderMains)) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 收集所有订单ID
|
|
|
|
|
+ Set<Long> orderIds = orderMains.stream()
|
|
|
|
|
+ .map(OrderMain::getId)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+
|
|
|
|
|
+ // 查询订单商品
|
|
|
|
|
+ List<OrderProduct> orderProducts = orderProductService.list(Wrappers.<OrderProduct>lambdaQuery()
|
|
|
|
|
+ .in(OrderProduct::getOrderId, orderIds)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 按订单ID分组(取每个订单的第一个商品名称)
|
|
|
|
|
+ Map<Long, String> orderProductMap = orderProducts.stream()
|
|
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
|
|
+ OrderProduct::getOrderId,
|
|
|
|
|
+ Collectors.collectingAndThen(
|
|
|
|
|
+ Collectors.toList(),
|
|
|
|
|
+ list -> list.isEmpty() ? "" : list.get(0).getProductName()
|
|
|
|
|
+ )
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
+
|
|
|
|
|
+ // 收集所有客户ID,远程批量查询客户名称
|
|
|
|
|
+ Set<Long> customerIds = orderMains.stream()
|
|
|
|
|
+ .map(OrderMain::getCustomerId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ Map<Long, String> customerNameMap = CollUtil.isEmpty(customerIds)
|
|
|
|
|
+ ? Collections.emptyMap()
|
|
|
|
|
+ : remoteCustomerService.selectCustomerNameByIds(customerIds);
|
|
|
|
|
+
|
|
|
|
|
+ return orderMains.stream().map(order -> {
|
|
|
|
|
+ LatestOrderDto dto = new LatestOrderDto();
|
|
|
|
|
+ dto.setOrderNo(order.getOrderNo());
|
|
|
|
|
+ dto.setCustomerName(customerNameMap.getOrDefault(order.getCustomerId(), ""));
|
|
|
|
|
+ dto.setProductName(orderProductMap.getOrDefault(order.getId(), ""));
|
|
|
|
|
+ dto.setAmount(order.getTotalAmount());
|
|
|
|
|
+ dto.setOrderStatus(order.getOrderStatus());
|
|
|
|
|
+ if (order.getOrderTime() != null) {
|
|
|
|
|
+ dto.setOrderTime(order.getOrderTime().toInstant()
|
|
|
|
|
+ .atZone(java.time.ZoneId.systemDefault())
|
|
|
|
|
+ .toLocalDateTime().format(formatter));
|
|
|
|
|
+ }
|
|
|
|
|
+ return dto;
|
|
|
|
|
+ }).collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取本月订单金额趋势
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<OrderAmountTrendDto> getOrderAmountTrend(String itemKey) {
|
|
|
|
|
+ // 获取本月第一天
|
|
|
|
|
+ LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
|
|
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
|
|
+
|
|
|
|
|
+ List<OrderMain> orderMains = orderMainService.list(Wrappers.<OrderMain>lambdaQuery()
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderMain::getDataSource, itemKey)
|
|
|
|
|
+ .ge(OrderMain::getCreateTime, java.sql.Date.valueOf(firstDayOfMonth))
|
|
|
|
|
+ .lt(OrderMain::getCreateTime, java.sql.Date.valueOf(today.plusDays(1)))
|
|
|
|
|
+ .select(OrderMain::getCreateTime, OrderMain::getTotalAmount)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // 按天分组汇总
|
|
|
|
|
+ Map<LocalDate, BigDecimal> dailyAmountMap = new LinkedHashMap<>();
|
|
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d日");
|
|
|
|
|
+
|
|
|
|
|
+ // 初始化本月所有日期
|
|
|
|
|
+ LocalDate current = firstDayOfMonth;
|
|
|
|
|
+ while (!current.isAfter(today)) {
|
|
|
|
|
+ dailyAmountMap.put(current, BigDecimal.ZERO);
|
|
|
|
|
+ current = current.plusDays(1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 汇总每天金额
|
|
|
|
|
+ for (OrderMain order : orderMains) {
|
|
|
|
|
+ if (order.getCreateTime() != null && order.getTotalAmount() != null) {
|
|
|
|
|
+ LocalDate orderDate = order.getCreateTime().toInstant()
|
|
|
|
|
+ .atZone(java.time.ZoneId.systemDefault())
|
|
|
|
|
+ .toLocalDate();
|
|
|
|
|
+ dailyAmountMap.merge(orderDate, order.getTotalAmount(), BigDecimal::add);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return dailyAmountMap.entrySet().stream()
|
|
|
|
|
+ .map(entry -> new OrderAmountTrendDto(entry.getKey().format(formatter), entry.getValue()))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取热销商品排行榜
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<HotProductRankingDto> getHotProductRankings(String itemKey, int limit) {
|
|
|
|
|
+ // 查询所有订单商品,按商品名称分组汇总销量
|
|
|
|
|
+ List<OrderProduct> orderProducts = orderProductService.list(Wrappers.<OrderProduct>lambdaQuery()
|
|
|
|
|
+ .eq(StrUtil.isNotBlank(itemKey), OrderProduct::getDataSource, itemKey)
|
|
|
|
|
+ .select(OrderProduct::getProductName, OrderProduct::getOrderQuantity)
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (CollUtil.isEmpty(orderProducts)) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 按商品名称分组汇总销量
|
|
|
|
|
+ Map<String, Long> productSalesMap = orderProducts.stream()
|
|
|
|
|
+ .filter(p -> p.getProductName() != null && p.getOrderQuantity() != null)
|
|
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
|
|
+ OrderProduct::getProductName,
|
|
|
|
|
+ Collectors.reducing(0L, OrderProduct::getOrderQuantity, Long::sum)
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ // 按销量降序排列,取前N条
|
|
|
|
|
+ return productSalesMap.entrySet().stream()
|
|
|
|
|
+ .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
|
|
|
|
|
+ .limit(limit)
|
|
|
|
|
+ .map(entry -> new HotProductRankingDto(entry.getKey(), entry.getValue()))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|