From c74a6f59490cfb9a0ee37f70427739b74e7fbd58 Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期三, 20 五月 2026 08:50:29 +0800
Subject: [PATCH] 代码生成
---
server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java | 576 +++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 494 insertions(+), 82 deletions(-)
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
index 819b776..9514975 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/DataBoardServiceImpl.java
@@ -6,6 +6,8 @@
import com.doumee.dao.business.*;
import com.doumee.dao.business.model.*;
import com.doumee.dao.dto.DataBoardQueryDTO;
+import com.doumee.dao.dto.FinanceQueryDTO;
+import com.doumee.dao.dto.TrendQueryDTO;
import com.doumee.dao.vo.*;
import com.doumee.service.business.DataBoardService;
import lombok.extern.slf4j.Slf4j;
@@ -37,14 +39,17 @@
private OtherOrdersMapper otherOrdersMapper;
@Autowired
private OrdersRefundMapper ordersRefundMapper;
+ @Autowired
+ private RevenueMapper revenueMapper;
@Override
public DataBoardVO overview(DataBoardQueryDTO query) {
+ query.resolveDateRange();
DataBoardVO vo = new DataBoardVO();
- // 浼氬憳鎬绘暟锛堜笉鍙楁椂闂�/闂ㄥ簵褰卞搷锛�
+ // 浼氬憳鎬绘暟锛堜笉鍙楁椂闂�/闂ㄥ簵褰卞搷锛寀serType=0 浼氬憳韬唤锛�
vo.setMemberCount(memberMapper.selectCount(new QueryWrapper<Member>().lambda()
.eq(Member::getDeleted, Constants.ZERO)
- .eq(Member::getStatus, Constants.ZERO)));
+ .eq(Member::getUserType, Constants.ZERO)));
// 闂ㄥ簵鎬绘暟锛坅uditStatus=3 姝e紡鐗堟湰锛�
vo.setShopCount(shopInfoMapper.selectCount(new QueryWrapper<ShopInfo>().lambda()
.eq(ShopInfo::getAuditStatus, Constants.THREE)
@@ -89,40 +94,63 @@
// 琛屾潕绫诲瀷鍗犳瘮
List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
- List<LuggageTypeItem> luggageTypeList = new ArrayList<>();
- if (!orderIds.isEmpty()) {
- List<OrdersDetail> details = ordersDetailMapper.selectList(new QueryWrapper<OrdersDetail>().lambda()
- .in(OrdersDetail::getOrderId, orderIds)
- .eq(OrdersDetail::getDeleted, Constants.ZERO));
- Map<String, List<OrdersDetail>> grouped = details.stream()
- .filter(d -> StringUtils.isNotBlank(d.getLuggageName()))
- .collect(Collectors.groupingBy(OrdersDetail::getLuggageName));
- for (Map.Entry<String, List<OrdersDetail>> entry : grouped.entrySet()) {
- LuggageTypeItem item = new LuggageTypeItem();
- item.setLuggageName(entry.getKey());
- item.setOrderCount((long) entry.getValue().stream().map(OrdersDetail::getOrderId).distinct().count());
- item.setLuggageCount((long) entry.getValue().stream()
- .mapToInt(d -> d.getNum() != null ? d.getNum() : 0).sum());
- luggageTypeList.add(item);
- }
+ vo.setLuggageTypeList(buildLuggageTypeList(orderIds));
+
+ // 闂ㄥ簵鍏ラ┗鐜囷細auditStatus=3 鐨勯棬搴楁暟 / 鍏ㄩ儴闂ㄥ簵鏁�
+ long totalShopCount = shopInfoMapper.selectCount(new QueryWrapper<ShopInfo>().lambda()
+ .eq(ShopInfo::getVersionType, Constants.ZERO)
+ .eq(ShopInfo::getDeleted, Constants.ZERO));
+ if (totalShopCount > 0) {
+ vo.setShopSettlementRate(BigDecimal.valueOf(vo.getShopCount())
+ .multiply(BigDecimal.valueOf(100))
+ .divide(BigDecimal.valueOf(totalShopCount), 2, RoundingMode.HALF_UP));
+ } else {
+ vo.setShopSettlementRate(BigDecimal.ZERO);
}
- vo.setLuggageTypeList(luggageTypeList);
+
+ // 鍙告満閫氳繃鐜囷細auditStatus=3 鐨勫徃鏈烘暟 / 鍏ㄩ儴鍙告満鏁�
+ long totalDriverCount = driverInfoMapper.selectCount(new QueryWrapper<DriverInfo>().lambda()
+ .eq(DriverInfo::getVersionType, Constants.ZERO)
+ .eq(DriverInfo::getDeleted, Constants.ZERO));
+ if (totalDriverCount > 0) {
+ vo.setDriverPassRate(BigDecimal.valueOf(vo.getDriverCount())
+ .multiply(BigDecimal.valueOf(100))
+ .divide(BigDecimal.valueOf(totalDriverCount), 2, RoundingMode.HALF_UP));
+ } else {
+ vo.setDriverPassRate(BigDecimal.ZERO);
+ }
+
+ // 鍛ㄦ湡閫�娆惧崟鏁�
+ if (!orderIds.isEmpty()) {
+ QueryWrapper<OrdersRefund> refundQw = new QueryWrapper<>();
+ refundQw.lambda()
+ .in(OrdersRefund::getOrderId, orderIds)
+ .eq(OrdersRefund::getStatus, Constants.ONE)
+ .eq(OrdersRefund::getDeleted, Constants.ZERO);
+ List<OrdersRefund> refundRecords = ordersRefundMapper.selectList(refundQw);
+ vo.setRefundOrderCount(refundRecords.stream()
+ .map(OrdersRefund::getOrderId).distinct().count());
+ } else {
+ vo.setRefundOrderCount(0L);
+ }
+
return vo;
}
@Override
- public List<MemberTrendVO> memberTrend() {
- Date startDate = get30DaysAgoStart();
+ public List<MemberTrendVO> memberTrend(TrendQueryDTO query) {
+ TrendDateRange range = parseTrendDateRange(query);
List<Member> members = memberMapper.selectList(new QueryWrapper<Member>().lambda()
.eq(Member::getDeleted, Constants.ZERO)
- .eq(Member::getStatus, Constants.ZERO)
- .ge(Member::getCreateTime, startDate));
+ .eq(Member::getUserType, Constants.ZERO)
+ .ge(Member::getCreateTime, range.startDate)
+ .le(Member::getCreateTime, range.endDate));
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ SimpleDateFormat sdf = new SimpleDateFormat(range.pattern);
Map<String, Long> map = members.stream()
.collect(Collectors.groupingBy(m -> sdf.format(m.getCreateTime()), Collectors.counting()));
- return buildDailyList(startDate, (date) -> {
+ return buildTrendList(range, (date) -> {
MemberTrendVO vo = new MemberTrendVO();
vo.setDate(date);
vo.setCount(map.getOrDefault(date, 0L));
@@ -131,24 +159,17 @@
}
@Override
- public List<OrderTrendVO> orderTrend() {
- Date startDate = get30DaysAgoStart();
+ public List<OrderTrendVO> orderTrend(TrendQueryDTO query) {
+ TrendDateRange range = parseTrendDateRange(query);
List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
- .eq(Orders::getDeleted, Constants.ZERO)
- .in(Orders::getStatus,
- Constants.OrderStatus.waitDeposit.getKey(),
- Constants.OrderStatus.deposited.getKey(),
- Constants.OrderStatus.accepted.getKey(),
- Constants.OrderStatus.delivering.getKey(),
- Constants.OrderStatus.arrived.getKey(),
- Constants.OrderStatus.overdue.getKey())
- .ge(Orders::getCreateTime, startDate));
+ .ge(Orders::getCreateTime, range.startDate)
+ .le(Orders::getCreateTime, range.endDate));
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ SimpleDateFormat sdf = new SimpleDateFormat(range.pattern);
Map<String, List<Orders>> grouped = orders.stream()
.collect(Collectors.groupingBy(o -> sdf.format(o.getCreateTime())));
- return buildDailyList(startDate, (date) -> {
+ return buildTrendList(range, (date) -> {
List<Orders> dayOrders = grouped.getOrDefault(date, Collections.emptyList());
OrderTrendVO vo = new OrderTrendVO();
vo.setDate(date);
@@ -159,35 +180,45 @@
}
@Override
- public List<RevenueTrendVO> revenueTrend() {
- Date startDate = get30DaysAgoStart();
+ public List<RevenueTrendVO> revenueTrend(TrendQueryDTO query) {
+ TrendDateRange range = parseTrendDateRange(query);
+ SimpleDateFormat sdf = new SimpleDateFormat(range.pattern);
List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
.eq(Orders::getDeleted, Constants.ZERO)
.in(Orders::getStatus,
- Constants.OrderStatus.waitDeposit.getKey(),
- Constants.OrderStatus.deposited.getKey(),
- Constants.OrderStatus.accepted.getKey(),
- Constants.OrderStatus.delivering.getKey(),
- Constants.OrderStatus.arrived.getKey(),
- Constants.OrderStatus.overdue.getKey())
- .ge(Orders::getCreateTime, startDate));
+ Constants.OrderStatus.waitDeposit.getKey(),
+ Constants.OrderStatus.deposited.getKey(),
+ Constants.OrderStatus.accepted.getKey(),
+ Constants.OrderStatus.delivering.getKey(),
+ Constants.OrderStatus.arrived.getKey(),
+ Constants.OrderStatus.overdue.getKey(),
+ Constants.OrderStatus.finished.getKey())
+ .ge(Orders::getCreateTime, range.startDate)
+ .le(Orders::getCreateTime, range.endDate));
- List<OtherOrders> otherOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
- .eq(OtherOrders::getType, 2)
- .eq(OtherOrders::getPayStatus, Constants.ONE)
- .eq(OtherOrders::getDeleted, Constants.ZERO)
- .ge(OtherOrders::getPayTime, startDate));
+ // 鏍规嵁绛涢�夊嚭鐨勮鍗曚富閿煡璇㈠凡鏀粯鐨勯�炬湡璐圭敤
+ List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+ Map<Integer, Long> overduePaidMap = new HashMap<>();
+ if (!orderIds.isEmpty()) {
+ List<OtherOrders> overdueOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
+ .eq(OtherOrders::getType, 2)
+ .eq(OtherOrders::getPayStatus, Constants.ONE)
+ .eq(OtherOrders::getDeleted, Constants.ZERO)
+ .in(OtherOrders::getOrderId, orderIds));
+ for (OtherOrders oo : overdueOrders) {
+ long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
+ overduePaidMap.merge(oo.getOrderId(), amt, Long::sum);
+ }
+ }
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Map<String, Long> localOrderRevenue = new HashMap<>();
Map<String, Long> remoteOrderRevenue = new HashMap<>();
for (Orders o : orders) {
String date = sdf.format(o.getCreateTime());
long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
- long overdue = (o.getOverdueStatus() != null && o.getOverdueStatus() == 2 && o.getOverdueAmount() != null)
- ? o.getOverdueAmount() : 0L;
+ long overdue = overduePaidMap.getOrDefault(o.getId(), 0L);
long rev = pay - refund + overdue;
if (Constants.equalsInteger(o.getType(), Constants.ZERO)) {
localOrderRevenue.merge(date, rev, Long::sum);
@@ -196,17 +227,10 @@
}
}
- Map<String, Long> otherRevenueMap = new HashMap<>();
- for (OtherOrders oo : otherOrders) {
- String date = sdf.format(oo.getPayTime());
- long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
- otherRevenueMap.merge(date, amt, Long::sum);
- }
-
- return buildDailyList(startDate, (date) -> {
+ return buildTrendList(range, (date) -> {
RevenueTrendVO vo = new RevenueTrendVO();
vo.setDate(date);
- long local = localOrderRevenue.getOrDefault(date, 0L) + otherRevenueMap.getOrDefault(date, 0L);
+ long local = localOrderRevenue.getOrDefault(date, 0L);
long remote = remoteOrderRevenue.getOrDefault(date, 0L);
vo.setLocalRevenue(BigDecimal.valueOf(local).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
vo.setRemoteRevenue(BigDecimal.valueOf(remote).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
@@ -216,6 +240,7 @@
@Override
public ShopPerformanceVO shopPerformance(DataBoardQueryDTO query) {
+ query.resolveDateRange();
ShopPerformanceVO vo = new ShopPerformanceVO();
// 1. 鎬昏鍗曟暟 + 钀ユ敹锛坰tatus 1-6锛�
@@ -282,6 +307,295 @@
return vo;
}
+ @Override
+ public List<LuggageTypeItem> luggageTypeList(DataBoardQueryDTO query) {
+ query.resolveDateRange();
+ List<Orders> orders = ordersMapper.selectList(buildOrderQueryWrapper(query));
+ List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+ return buildLuggageTypeList(orderIds);
+ }
+
+ @Override
+ public List<LuggageTypeItem> buildLuggageTypeList(List<Integer> orderIds) {
+ List<LuggageTypeItem> luggageTypeList = new ArrayList<>();
+ if (orderIds != null && !orderIds.isEmpty()) {
+ List<OrdersDetail> details = ordersDetailMapper.selectList(new QueryWrapper<OrdersDetail>().lambda()
+ .in(OrdersDetail::getOrderId, orderIds)
+ .eq(OrdersDetail::getDeleted, Constants.ZERO));
+ Map<String, List<OrdersDetail>> grouped = details.stream()
+ .filter(d -> StringUtils.isNotBlank(d.getLuggageName()))
+ .collect(Collectors.groupingBy(OrdersDetail::getLuggageName));
+ for (Map.Entry<String, List<OrdersDetail>> entry : grouped.entrySet()) {
+ LuggageTypeItem item = new LuggageTypeItem();
+ item.setLuggageName(entry.getKey());
+ item.setOrderCount((long) entry.getValue().stream().map(OrdersDetail::getOrderId).distinct().count());
+ item.setLuggageCount((long) entry.getValue().stream()
+ .mapToInt(d -> d.getNum() != null ? d.getNum() : 0).sum());
+ luggageTypeList.add(item);
+ }
+ }
+ return luggageTypeList;
+ }
+
+ @Override
+ public List<FinanceOverviewVO> financeOverview(FinanceQueryDTO query) {
+ // 琛ラ綈鏃ユ湡锛歴tartDate 鍙栨湀鍒濓紝endDate 鍙栨湀鏈�
+ Calendar startCal = Calendar.getInstance();
+ startCal.setTime(query.getStartDate());
+ startCal.set(Calendar.DAY_OF_MONTH, 1);
+ startCal.set(Calendar.HOUR_OF_DAY, 0);
+ startCal.set(Calendar.MINUTE, 0);
+ startCal.set(Calendar.SECOND, 0);
+ startCal.set(Calendar.MILLISECOND, 0);
+ query.setStartDate(startCal.getTime());
+
+ Calendar endCal = Calendar.getInstance();
+ endCal.setTime(query.getEndDate());
+ endCal.set(Calendar.DAY_OF_MONTH, endCal.getActualMaximum(Calendar.DAY_OF_MONTH));
+ endCal.set(Calendar.HOUR_OF_DAY, 23);
+ endCal.set(Calendar.MINUTE, 59);
+ endCal.set(Calendar.SECOND, 59);
+ endCal.set(Calendar.MILLISECOND, 999);
+ query.setEndDate(endCal.getTime());
+
+ List<Orders> orders = ordersMapper.selectList(buildFinanceOrderQueryWrapper(query));
+
+ // 鏍规嵁绛涢�夊嚭鐨勮鍗曚富閿煡璇㈠凡鏀粯鐨勯�炬湡璐圭敤
+ List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+ Map<Integer, Long> overduePaidMap = new HashMap<>();
+ if (!orderIds.isEmpty()) {
+ List<OtherOrders> overdueOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
+ .eq(OtherOrders::getType, 2)
+ .eq(OtherOrders::getPayStatus, Constants.ONE)
+ .eq(OtherOrders::getDeleted, Constants.ZERO)
+ .in(OtherOrders::getOrderId, orderIds));
+ for (OtherOrders oo : overdueOrders) {
+ long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
+ overduePaidMap.merge(oo.getOrderId(), amt, Long::sum);
+ }
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+ Map<String, List<Orders>> grouped = orders.stream()
+ .collect(Collectors.groupingBy(o -> sdf.format(o.getCreateTime())));
+
+ // 鐢熸垚瀹屾暣骞存湀鍒楄〃
+ List<String> months = new ArrayList<>();
+ Calendar loop = Calendar.getInstance();
+ loop.setTime(query.getStartDate());
+ loop.set(Calendar.DAY_OF_MONTH, 1);
+ Calendar monthEnd = Calendar.getInstance();
+ monthEnd.setTime(query.getEndDate());
+ while (!loop.after(monthEnd)) {
+ months.add(sdf.format(loop.getTime()));
+ loop.add(Calendar.MONTH, 1);
+ }
+
+ BigDecimal hundred = BigDecimal.valueOf(100);
+ List<FinanceOverviewVO> result = new ArrayList<>();
+ for (String month : months) {
+ List<Orders> monthOrders = grouped.getOrDefault(month, Collections.emptyList());
+ long storageRev = 0L, deliveryRev = 0L, shopFee = 0L, driverFeeTotal = 0L, refundTotal = 0L, overdueTotal = 0L;
+ for (Orders o : monthOrders) {
+ long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+ long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+ long overdue = overduePaidMap.getOrDefault(o.getId(), 0L);
+ long actual = pay - refund + overdue;
+ long depFee = o.getDepositShopFee() != null ? o.getDepositShopFee() : 0L;
+ long takeFee = o.getTakeShopFee() != null ? o.getTakeShopFee() : 0L;
+ long dFee = Constants.equalsInteger(o.getType(),Constants.ONE)&&o.getDriverFee() != null ? o.getDriverFee() : 0L;
+ if (Constants.equalsInteger(o.getType(), Constants.ZERO)) {
+ storageRev += actual;
+ shopFee += depFee;
+ } else {
+ deliveryRev += actual;
+ shopFee += depFee + takeFee;
+ }
+ driverFeeTotal += dFee;
+ refundTotal += refund;
+ overdueTotal += overdue;
+ }
+ long totalRev = storageRev + deliveryRev;
+ long netRev = totalRev - shopFee - driverFeeTotal;
+
+ FinanceOverviewVO vo = new FinanceOverviewVO();
+ vo.setDate(month);
+ vo.setStorageRevenue(BigDecimal.valueOf(storageRev).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setDeliveryRevenue(BigDecimal.valueOf(deliveryRev).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setTotalRevenue(BigDecimal.valueOf(totalRev).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setShopFeeTotal(BigDecimal.valueOf(shopFee).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setDriverFeeTotal(BigDecimal.valueOf(driverFeeTotal).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setRefundAmount(BigDecimal.valueOf(refundTotal).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setOverdueAmount(BigDecimal.valueOf(overdueTotal).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setNetRevenue(BigDecimal.valueOf(netRev).divide(hundred, 2, RoundingMode.HALF_UP));
+ result.add(vo);
+ }
+ return result;
+ }
+
+ @Override
+ public List<ShopTopVO> shopTop(TrendQueryDTO query) {
+ TrendDateRange range = parseTrendDateRange(query);
+ List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+ .eq(Orders::getDeleted, Constants.ZERO)
+ .eq(Orders::getStatus, Constants.OrderStatus.finished.getKey())
+ .ge(Orders::getCreateTime, range.startDate)
+ .le(Orders::getCreateTime, range.endDate));
+
+ // 鏍规嵁绛涢�夊嚭鐨勮鍗曚富閿煡璇㈠凡鏀粯鐨勯�炬湡璐圭敤
+ List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+ Map<Integer, Long> overduePaidMap = new HashMap<>();
+ if (!orderIds.isEmpty()) {
+ List<OtherOrders> overdueOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
+ .eq(OtherOrders::getType, 2)
+ .eq(OtherOrders::getPayStatus, Constants.ONE)
+ .eq(OtherOrders::getDeleted, Constants.ZERO)
+ .in(OtherOrders::getOrderId, orderIds));
+ for (OtherOrders oo : overdueOrders) {
+ long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
+ overduePaidMap.merge(oo.getOrderId(), amt, Long::sum);
+ }
+ }
+
+ // 鎸夐棬搴桰D褰掗泦: key = shopId
+ Map<Integer, long[]> map = new LinkedHashMap<>();
+ for (Orders o : orders) {
+ long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+ long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+ long overdue = overduePaidMap.getOrDefault(o.getId(), 0L);
+ boolean hasRefund = refund > 0;
+ long rev = pay - refund + overdue;
+
+ // 瀛樹欢闂ㄥ簵
+ if (o.getDepositShopId() != null) {
+ long depFee = o.getDepositShopFee() != null ? o.getDepositShopFee() : 0L;
+ long[] arr = map.computeIfAbsent(o.getDepositShopId(), k -> new long[4]); // [count, revenue, fee, refundCount]
+ arr[0]++;
+ arr[1] += rev;
+ arr[2] += depFee;
+ if (hasRefund) arr[3]++;
+ }
+ // 寮傚湴涓旀湁鍙栦欢闂ㄥ簵
+ if (Constants.equalsInteger(o.getType(), Constants.ONE) && o.getTakeShopId() != null) {
+ long takeFee = o.getTakeShopFee() != null ? o.getTakeShopFee() : 0L;
+ long[] arr = map.computeIfAbsent(o.getTakeShopId(), k -> new long[4]);
+ arr[0]++;
+ arr[1] += rev;
+ arr[2] += takeFee;
+ if (hasRefund) arr[3]++;
+ }
+ }
+
+ // 鎵归噺鏌ラ棬搴楀悕绉�
+ Set<Integer> shopIds = map.keySet();
+ Map<Integer, String> shopNameMap = new HashMap<>();
+ if (!shopIds.isEmpty()) {
+ List<ShopInfo> shops = shopInfoMapper.selectList(new QueryWrapper<ShopInfo>().lambda()
+ .in(ShopInfo::getId, shopIds)
+ .select(ShopInfo::getId, ShopInfo::getName));
+ for (ShopInfo s : shops) {
+ shopNameMap.put(s.getId(), s.getName());
+ }
+ }
+
+ BigDecimal hundred = BigDecimal.valueOf(100);
+ List<ShopTopVO> result = new ArrayList<>();
+ for (Map.Entry<Integer, long[]> entry : map.entrySet()) {
+ long[] arr = entry.getValue();
+ ShopTopVO vo = new ShopTopVO();
+ vo.setShopId(entry.getKey());
+ vo.setShopName(shopNameMap.getOrDefault(entry.getKey(), ""));
+ vo.setCompletedCount(arr[0]);
+ vo.setTotalRevenue(BigDecimal.valueOf(arr[1]).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setShopFeeTotal(BigDecimal.valueOf(arr[2]).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setRefundCount(arr[3]);
+ vo.setPenaltyAmount(BigDecimal.ZERO);
+ result.add(vo);
+ }
+ result.sort((a, b) -> Long.compare(b.getCompletedCount(), a.getCompletedCount()));
+ return result.size() > 10 ? result.subList(0, 10) : result;
+ }
+
+ @Override
+ public List<DriverTopVO> driverTop(TrendQueryDTO query) {
+ TrendDateRange range = parseTrendDateRange(query);
+ List<Orders> orders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda()
+// .eq(Orders::getDeleted, Constants.ZERO)
+ .in(Orders::getStatus,
+ Constants.OrderStatus.waitDeposit.getKey(),
+ Constants.OrderStatus.deposited.getKey(),
+ Constants.OrderStatus.accepted.getKey(),
+ Constants.OrderStatus.delivering.getKey(),
+ Constants.OrderStatus.arrived.getKey(),
+ Constants.OrderStatus.finished.getKey())
+ .eq(Orders::getType, Constants.ONE)
+ .ge(Orders::getCreateTime, range.startDate)
+ .le(Orders::getCreateTime, range.endDate));
+
+ System.out.println(
+ orders.stream().map(i->i.getDriverFee()).reduce(0L,Long::sum)
+ );
+
+ // 鏍规嵁绛涢�夊嚭鐨勮鍗曚富閿煡璇㈠凡鏀粯鐨勯�炬湡璐圭敤
+ List<Integer> orderIds = orders.stream().map(Orders::getId).collect(Collectors.toList());
+ Map<Integer, Long> overduePaidMap = new HashMap<>();
+ if (!orderIds.isEmpty()) {
+ List<OtherOrders> overdueOrders = otherOrdersMapper.selectList(new QueryWrapper<OtherOrders>().lambda()
+ .eq(OtherOrders::getType, 2)
+ .eq(OtherOrders::getPayStatus, Constants.ONE)
+ .eq(OtherOrders::getDeleted, Constants.ZERO)
+ .in(OtherOrders::getOrderId, orderIds));
+ for (OtherOrders oo : overdueOrders) {
+ long amt = oo.getPayAccount() != null ? oo.getPayAccount() : 0L;
+ overduePaidMap.merge(oo.getOrderId(), amt, Long::sum);
+ }
+ }
+
+ // 鎸夊徃鏈哄綊闆�: key = acceptDriver
+ Map<Integer, long[]> map = new LinkedHashMap<>();
+ for (Orders o : orders) {
+ if (o.getAcceptDriver() == null) continue;
+ long pay = o.getPayAmount() != null ? o.getPayAmount() : 0L;
+ long refund = o.getRefundAmount() != null ? o.getRefundAmount() : 0L;
+ long overdue = overduePaidMap.getOrDefault(o.getId(), 0L);
+ long dFee = o.getDriverFee() != null ? o.getDriverFee() : 0L;
+ long[] arr = map.computeIfAbsent(o.getAcceptDriver(), k -> new long[4]); // [count, revenue, fee, refundCount]
+ arr[0]++;
+ arr[1] += pay - refund + overdue;
+ arr[2] += dFee;
+ if (refund > 0) arr[3]++;
+ }
+
+ // 鎵归噺鏌ュ徃鏈哄鍚�
+ Set<Integer> driverIds = map.keySet();
+ Map<Integer, String> driverNameMap = new HashMap<>();
+ if (!driverIds.isEmpty()) {
+ List<DriverInfo> drivers = driverInfoMapper.selectList(new QueryWrapper<DriverInfo>().lambda()
+ .in(DriverInfo::getId, driverIds)
+ .select(DriverInfo::getMemberId, DriverInfo::getName));
+ for (DriverInfo d : drivers) {
+ driverNameMap.put(d.getMemberId(), d.getName());
+ }
+ }
+
+ BigDecimal hundred = BigDecimal.valueOf(100);
+ List<DriverTopVO> result = new ArrayList<>();
+ for (Map.Entry<Integer, long[]> entry : map.entrySet()) {
+ long[] arr = entry.getValue();
+ DriverTopVO vo = new DriverTopVO();
+ vo.setDriverId(entry.getKey());
+ vo.setDriverName(driverNameMap.getOrDefault(entry.getKey(), "鏈煡"));
+ vo.setCompletedCount(arr[0]);
+ vo.setTotalRevenue(BigDecimal.valueOf(arr[1]).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setDriverFeeTotal(BigDecimal.valueOf(arr[2]).divide(hundred, 2, RoundingMode.HALF_UP));
+ vo.setRefundCount(arr[3]);
+ vo.setPenaltyAmount(BigDecimal.ZERO);
+ result.add(vo);
+ }
+ result.sort((a, b) -> Long.compare(b.getCompletedCount(), a.getCompletedCount()));
+ return result.size() > 10 ? result.subList(0, 10) : result;
+ }
+
// ========== 绉佹湁鏂规硶 ==========
private QueryWrapper<Orders> buildOrderQueryWrapper(DataBoardQueryDTO query) {
@@ -294,7 +608,7 @@
Constants.OrderStatus.accepted.getKey(),
Constants.OrderStatus.delivering.getKey(),
Constants.OrderStatus.arrived.getKey(),
- Constants.OrderStatus.overdue.getKey());
+ Constants.OrderStatus.finished.getKey());
if (query.getStartDate() != null) {
qw.lambda().ge(Orders::getCreateTime, query.getStartDate());
}
@@ -308,30 +622,128 @@
return qw;
}
- private Date get30DaysAgoStart() {
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- cal.add(Calendar.DAY_OF_MONTH, -29);
- return cal.getTime();
+ private QueryWrapper<Orders> buildFinanceOrderQueryWrapper(FinanceQueryDTO query) {
+ QueryWrapper<Orders> qw = new QueryWrapper<>();
+ qw.lambda()
+ .eq(Orders::getDeleted, Constants.ZERO)
+ .in(Orders::getStatus,
+ Constants.OrderStatus.waitDeposit.getKey(),
+ Constants.OrderStatus.deposited.getKey(),
+ Constants.OrderStatus.accepted.getKey(),
+ Constants.OrderStatus.delivering.getKey(),
+ Constants.OrderStatus.arrived.getKey(),
+ Constants.OrderStatus.finished.getKey());
+ if (query.getStartDate() != null) {
+ qw.lambda().ge(Orders::getCreateTime, query.getStartDate());
+ }
+ if (query.getEndDate() != null) {
+ qw.lambda().le(Orders::getCreateTime, Utils.Date.getEnd(query.getEndDate()));
+ }
+ return qw;
+ }
+
+ private TrendDateRange parseTrendDateRange(TrendQueryDTO query) {
+ Calendar now = Calendar.getInstance();
+ TrendDateRange range = new TrendDateRange();
+
+ if (StringUtils.isNotBlank(query.getMonth())) {
+ // 鎸夋湀鏌ヨ锛歽yyy-MM
+ SimpleDateFormat parseSdf = new SimpleDateFormat("yyyy-MM");
+ Date monthDate;
+ try {
+ monthDate = parseSdf.parse(query.getMonth());
+ } catch (Exception e) {
+ throw new IllegalArgumentException("month 鏍煎紡閿欒锛屽簲涓� yyyy-MM");
+ }
+ Calendar monthCal = Calendar.getInstance();
+ monthCal.setTime(monthDate);
+
+ // 褰撴湀1鏃ヨ捣濮�
+ monthCal.set(Calendar.DAY_OF_MONTH, 1);
+ monthCal.set(Calendar.HOUR_OF_DAY, 0);
+ monthCal.set(Calendar.MINUTE, 0);
+ monthCal.set(Calendar.SECOND, 0);
+ monthCal.set(Calendar.MILLISECOND, 0);
+ range.startDate = monthCal.getTime();
+
+ // 鏈堟湯
+ monthCal.set(Calendar.DAY_OF_MONTH, monthCal.getActualMaximum(Calendar.DAY_OF_MONTH));
+ monthCal.set(Calendar.HOUR_OF_DAY, 23);
+ monthCal.set(Calendar.MINUTE, 59);
+ monthCal.set(Calendar.SECOND, 59);
+ monthCal.set(Calendar.MILLISECOND, 999);
+ Date monthEnd = monthCal.getTime();
+
+ // 涓嶈兘瓒呰繃褰撳墠鏃堕棿
+ range.endDate = monthEnd.after(now.getTime()) ? now.getTime() : monthEnd;
+ range.byMonth = true;
+ range.pattern = "MM-dd";
+ } else if (StringUtils.isNotBlank(query.getYear())) {
+ // 鎸夊勾鏌ヨ锛歽yyy
+ int year = Integer.parseInt(query.getYear());
+ Calendar yearStart = Calendar.getInstance();
+ yearStart.set(Calendar.YEAR, year);
+ yearStart.set(Calendar.MONTH, Calendar.JANUARY);
+ yearStart.set(Calendar.DAY_OF_MONTH, 1);
+ yearStart.set(Calendar.HOUR_OF_DAY, 0);
+ yearStart.set(Calendar.MINUTE, 0);
+ yearStart.set(Calendar.SECOND, 0);
+ yearStart.set(Calendar.MILLISECOND, 0);
+ range.startDate = yearStart.getTime();
+
+ Calendar yearEnd = Calendar.getInstance();
+ yearEnd.set(Calendar.YEAR, year);
+ yearEnd.set(Calendar.MONTH, Calendar.DECEMBER);
+ yearEnd.set(Calendar.DAY_OF_MONTH, 31);
+ yearEnd.set(Calendar.HOUR_OF_DAY, 23);
+ yearEnd.set(Calendar.MINUTE, 59);
+ yearEnd.set(Calendar.SECOND, 59);
+ yearEnd.set(Calendar.MILLISECOND, 999);
+ Date end = yearEnd.getTime();
+ range.endDate = end.after(now.getTime()) ? now.getTime() : end;
+ range.byMonth = false;
+ range.pattern = "MM";
+ } else {
+ throw new IllegalArgumentException("璇蜂紶鍏� month 鎴� year 鍙傛暟");
+ }
+ return range;
+ }
+
+ private static class TrendDateRange {
+ Date startDate;
+ Date endDate;
+ boolean byMonth; // true=鎸夋湀鏌�(鎸夋棩杩斿洖)锛宖alse=鎸夊勾鏌�(鎸夋湀杩斿洖)
+ String pattern; // SimpleDateFormat 鏍煎紡
}
@FunctionalInterface
- private interface DailyVOBuilder<T> {
+ private interface TrendVOBuilder<T> {
T build(String date);
}
- private <T> List<T> buildDailyList(Date startDate, DailyVOBuilder<T> builder) {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ private <T> List<T> buildTrendList(TrendDateRange range, TrendVOBuilder<T> builder) {
List<T> result = new ArrayList<>();
- Calendar loop = Calendar.getInstance();
- loop.setTime(startDate);
- Calendar end = Calendar.getInstance();
- while (!loop.after(end)) {
- result.add(builder.build(sdf.format(loop.getTime())));
- loop.add(Calendar.DAY_OF_MONTH, 1);
+ SimpleDateFormat sdf = new SimpleDateFormat(range.pattern);
+
+ if (range.byMonth) {
+ // 鎸夋棩寰幆
+ Calendar loop = Calendar.getInstance();
+ loop.setTime(range.startDate);
+ Calendar end = Calendar.getInstance();
+ end.setTime(range.endDate);
+ while (!loop.after(end)) {
+ result.add(builder.build(sdf.format(loop.getTime())));
+ loop.add(Calendar.DAY_OF_MONTH, 1);
+ }
+ } else {
+ // 鎸夋湀寰幆 1~12锛屼笉鑳借秴杩� endDate 鎵�鍦ㄦ湀
+ Calendar endCal = Calendar.getInstance();
+ endCal.setTime(range.endDate);
+ int endMonth = endCal.get(Calendar.MONTH); // 0-based
+ for (int m = 0; m <= endMonth; m++) {
+ String label = String.format("%02d", m + 1);
+ result.add(builder.build(label));
+ }
}
return result;
}
--
Gitblit v1.9.3