汇总当天订单的数据
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.rj.controller;
|
package com.rj.controller;
|
||||||
|
|
||||||
|
import com.rj.dto.LbOrderRowGenerateSumRequest;
|
||||||
import com.rj.dto.LbOrderRowSyncFromHxrRequest;
|
import com.rj.dto.LbOrderRowSyncFromHxrRequest;
|
||||||
import com.rj.entity.LbOrderRow;
|
import com.rj.entity.LbOrderRow;
|
||||||
import com.rj.service.ILbOrderRowService;
|
import com.rj.service.ILbOrderRowService;
|
||||||
@@ -89,8 +90,28 @@ public class LbOrderRowController {
|
|||||||
request.getBuyTimeStart(),
|
request.getBuyTimeStart(),
|
||||||
request.getBuyTimeEnd(),
|
request.getBuyTimeEnd(),
|
||||||
request.getTenantId(),
|
request.getTenantId(),
|
||||||
request.getIsResell(),
|
request.getIsResell());
|
||||||
request.getDataType());
|
Boolean success = (Boolean) result.get("success");
|
||||||
|
if (success != null && success) {
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
return ResponseEntity.badRequest().body(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/generate-daily-sum")
|
||||||
|
@Operation(
|
||||||
|
summary = "按日汇总生成 sum_data",
|
||||||
|
description =
|
||||||
|
"按购买时间区间、租户 id 查询 lb_order_row 明细,每天生成一条 sum_data(today_total_money_sum、"
|
||||||
|
+ "today_unresell_count、today_order_count 等)并写入表")
|
||||||
|
public ResponseEntity<Map<String, Object>> generateDailySum(
|
||||||
|
@Parameter(description = "汇总条件", required = true) @RequestBody
|
||||||
|
LbOrderRowGenerateSumRequest request) {
|
||||||
|
Map<String, Object> result =
|
||||||
|
lbOrderRowService.generateDailySumData(
|
||||||
|
request.getBuyTimeStart(),
|
||||||
|
request.getBuyTimeEnd(),
|
||||||
|
request.getTenantId());
|
||||||
Boolean success = (Boolean) result.get("success");
|
Boolean success = (Boolean) result.get("success");
|
||||||
if (success != null && success) {
|
if (success != null && success) {
|
||||||
return ResponseEntity.ok(result);
|
return ResponseEntity.ok(result);
|
||||||
|
|||||||
21
src/main/java/com/rj/dto/LbOrderRowGenerateSumRequest.java
Normal file
21
src/main/java/com/rj/dto/LbOrderRowGenerateSumRequest.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.rj.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按购买时间区间与租户,将 {@code lb_order_row} 明细按日汇总为 {@code sum_data} 并写入表。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "LB 订单按日汇总生成 sum_data 请求")
|
||||||
|
public class LbOrderRowGenerateSumRequest {
|
||||||
|
|
||||||
|
@Schema(description = "购买时间起(buy_time 下限),可空表示不限制")
|
||||||
|
private String buyTimeStart;
|
||||||
|
|
||||||
|
@Schema(description = "购买时间止(buy_time 上限),可空表示不限制")
|
||||||
|
private String buyTimeEnd;
|
||||||
|
|
||||||
|
@Schema(description = "租户 id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String tenantId;
|
||||||
|
}
|
||||||
@@ -21,7 +21,4 @@ public class LbOrderRowSyncFromHxrRequest {
|
|||||||
|
|
||||||
@Schema(description = "转卖状态筛选(对应后台 is_resell)", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "转卖状态筛选(对应后台 is_resell)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Integer isResell;
|
private Integer isResell;
|
||||||
|
|
||||||
@Schema(description = "写入 lb_order_row.data_type;为空时默认使用 isResell 的字符串值")
|
|
||||||
private String dataType;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ public interface ILbOrderRowService extends IService<LbOrderRow> {
|
|||||||
String buyTimeStart,
|
String buyTimeStart,
|
||||||
String buyTimeEnd,
|
String buyTimeEnd,
|
||||||
String tenantId,
|
String tenantId,
|
||||||
Integer isResell,
|
Integer isResell);
|
||||||
String dataType);
|
|
||||||
|
/**
|
||||||
|
* 按购买时间区间与租户查询明细,按天汇总为 {@code sum_data} 写入 {@code lb_order_row}。
|
||||||
|
*/
|
||||||
|
Map<String, Object> generateDailySumData(String buyTimeStart, String buyTimeEnd, String tenantId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,13 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -26,6 +31,19 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
|||||||
/** 与 hxr.admin.order-select-url 中 {@code limit} 一致,用于判断是否还有下一页 */
|
/** 与 hxr.admin.order-select-url 中 {@code limit} 一致,用于判断是否还有下一页 */
|
||||||
private static final int HXR_ORDER_PAGE_SIZE = 90;
|
private static final int HXR_ORDER_PAGE_SIZE = 90;
|
||||||
|
|
||||||
|
/** 从第三方同步的订单明细默认 data_type */
|
||||||
|
private static final String SYNC_DATA_TYPE_DETAIL = "detail_data";
|
||||||
|
|
||||||
|
private static final String SUM_DATA_TYPE = "sum_data";
|
||||||
|
|
||||||
|
private static final long SUM_PLACEHOLDER_USER_ID = 10000L;
|
||||||
|
|
||||||
|
private static final String SUM_ORDER_SN = "order_sn_10000";
|
||||||
|
|
||||||
|
private static final DateTimeFormatter DAY_TIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
private static final DateTimeFormatter DAY_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HxrAdminOrderSelectService hxrAdminOrderSelectService;
|
private HxrAdminOrderSelectService hxrAdminOrderSelectService;
|
||||||
|
|
||||||
@@ -201,7 +219,7 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Map<String, Object> syncFromHxrAdmin(
|
public Map<String, Object> syncFromHxrAdmin(
|
||||||
String buyTimeStart, String buyTimeEnd, String tenantId, Integer isResell, String dataType) {
|
String buyTimeStart, String buyTimeEnd, String tenantId, Integer isResell) {
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
if (tenantId == null || tenantId.trim().isEmpty()) {
|
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||||||
@@ -212,7 +230,6 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
|||||||
|
|
||||||
|
|
||||||
String tid = tenantId.trim();
|
String tid = tenantId.trim();
|
||||||
String rowDataType = resolveSyncDataType(dataType, isResell);
|
|
||||||
HxrOrderSelectResponse firstBody = null;
|
HxrOrderSelectResponse firstBody = null;
|
||||||
int page = 1;
|
int page = 1;
|
||||||
int totalSynced = 0;
|
int totalSynced = 0;
|
||||||
@@ -248,13 +265,9 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal todayTotalMoneySum = parseMoney(firstBody.allMoney());
|
|
||||||
int todayOrderCount = firstBody.count();
|
|
||||||
int todayUnresellCount = countUnresell(rows);
|
|
||||||
List<LbOrderRow> entities = new ArrayList<>(rows.size());
|
List<LbOrderRow> entities = new ArrayList<>(rows.size());
|
||||||
for (HxrOrderRow row : rows) {
|
for (HxrOrderRow row : rows) {
|
||||||
entities.add(toLbOrderRow(
|
entities.add(toLbOrderRow(row, tid));
|
||||||
row, tid, rowDataType, todayTotalMoneySum, todayOrderCount, todayUnresellCount));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean ok = this.saveOrUpdateBatch(entities);
|
boolean ok = this.saveOrUpdateBatch(entities);
|
||||||
@@ -300,21 +313,155 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String resolveSyncDataType(String dataType, Integer isResell) {
|
@Override
|
||||||
if (dataType != null && !dataType.trim().isEmpty()) {
|
@Transactional(rollbackFor = Exception.class)
|
||||||
return dataType.trim();
|
public Map<String, Object> generateDailySumData(
|
||||||
|
String buyTimeStart, String buyTimeEnd, String tenantId) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
try {
|
||||||
|
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "tenantId不能为空");
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return isResell == null ? null : String.valueOf(isResell);
|
String tid = tenantId.trim();
|
||||||
|
|
||||||
|
LambdaQueryWrapper<LbOrderRow> w = new LambdaQueryWrapper<>();
|
||||||
|
w.eq(LbOrderRow::getTenantId, tid);
|
||||||
|
w.eq(LbOrderRow::getDataType, SYNC_DATA_TYPE_DETAIL);
|
||||||
|
if (buyTimeStart != null && !buyTimeStart.trim().isEmpty()) {
|
||||||
|
w.ge(LbOrderRow::getBuyTime, buyTimeStart.trim());
|
||||||
|
}
|
||||||
|
if (buyTimeEnd != null && !buyTimeEnd.trim().isEmpty()) {
|
||||||
|
w.le(LbOrderRow::getBuyTime, buyTimeEnd.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int countUnresell(List<HxrOrderRow> rows) {
|
List<LbOrderRow> details = this.list(w);
|
||||||
int n = 0;
|
if (details.isEmpty()) {
|
||||||
for (HxrOrderRow row : rows) {
|
result.put("success", true);
|
||||||
if (row.isResell() == 0) {
|
result.put("message", "时间范围内无明细数据");
|
||||||
n++;
|
result.put("generated", 0);
|
||||||
|
result.put("sourceCount", 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<LocalDate, List<LbOrderRow>> byDay = new LinkedHashMap<>();
|
||||||
|
int skippedNoBuyTime = 0;
|
||||||
|
for (LbOrderRow row : details) {
|
||||||
|
LocalDate day = parseBuyTimeToDate(row.getBuyTime());
|
||||||
|
if (day == null) {
|
||||||
|
skippedNoBuyTime++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byDay.computeIfAbsent(day, k -> new ArrayList<>()).add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byDay.isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "明细 buy_time 均无法解析为日期,无法汇总");
|
||||||
|
result.put("skippedNoBuyTime", skippedNoBuyTime);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String nowStr = LocalDateTime.now().format(DAY_TIME_FMT);
|
||||||
|
List<LbOrderRow> sumRows = new ArrayList<>(byDay.size());
|
||||||
|
for (Map.Entry<LocalDate, List<LbOrderRow>> entry : byDay.entrySet()) {
|
||||||
|
sumRows.add(buildDailySumRow(tid, entry.getKey(), entry.getValue(), nowStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ok = this.saveOrUpdateBatch(sumRows);
|
||||||
|
result.put("success", ok);
|
||||||
|
result.put("message", ok ? "按日汇总完成" : "保存失败");
|
||||||
|
result.put("generated", ok ? sumRows.size() : 0);
|
||||||
|
result.put("sourceCount", details.size());
|
||||||
|
result.put("skippedNoBuyTime", skippedNoBuyTime);
|
||||||
|
if (ok) {
|
||||||
|
result.put("data", sumRows);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "汇总异常:" + e.getMessage());
|
||||||
|
result.put("generated", 0);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
|
||||||
|
private LbOrderRow buildDailySumRow(
|
||||||
|
String tenantId, LocalDate day, List<LbOrderRow> dayRows, String nowStr) {
|
||||||
|
BigDecimal moneySum = BigDecimal.ZERO;
|
||||||
|
int unresellCount = 0;
|
||||||
|
for (LbOrderRow row : dayRows) {
|
||||||
|
if (row.getTotalMoney() != null) {
|
||||||
|
moneySum = moneySum.add(row.getTotalMoney());
|
||||||
|
}
|
||||||
|
if (row.getIsResell() == null || row.getIsResell() != 1) {
|
||||||
|
unresellCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String payTime = day.atStartOfDay().format(DAY_TIME_FMT);
|
||||||
|
Long id = resolveSumRowId(tenantId, payTime);
|
||||||
|
|
||||||
|
LbOrderRow sum = new LbOrderRow();
|
||||||
|
sum.setId(id);
|
||||||
|
sum.setTenantId(tenantId);
|
||||||
|
sum.setDataType(SUM_DATA_TYPE);
|
||||||
|
sum.setTodayTotalMoneySum(moneySum);
|
||||||
|
sum.setTodayUnresellCount(unresellCount);
|
||||||
|
sum.setTodayOrderCount(dayRows.size());
|
||||||
|
sum.setSellerId(SUM_PLACEHOLDER_USER_ID);
|
||||||
|
sum.setBuyerId(SUM_PLACEHOLDER_USER_ID);
|
||||||
|
sum.setOrderSn(SUM_ORDER_SN);
|
||||||
|
sum.setTotalMoney(moneySum);
|
||||||
|
sum.setIsResell(1);
|
||||||
|
sum.setStatus(1);
|
||||||
|
sum.setIsShow(1);
|
||||||
|
sum.setPayTime(payTime);
|
||||||
|
sum.setBuyTime(payTime);
|
||||||
|
sum.setMerchandiseId(0L);
|
||||||
|
sum.setCreatedAt(nowStr);
|
||||||
|
sum.setUpdatedAt(nowStr);
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 同一天、同一租户已存在 sum_data 则复用其 id,否则生成占位 id */
|
||||||
|
private Long resolveSumRowId(String tenantId, String payTime) {
|
||||||
|
LambdaQueryWrapper<LbOrderRow> w = new LambdaQueryWrapper<>();
|
||||||
|
w.eq(LbOrderRow::getTenantId, tenantId)
|
||||||
|
.eq(LbOrderRow::getDataType, SUM_DATA_TYPE)
|
||||||
|
.eq(LbOrderRow::getPayTime, payTime)
|
||||||
|
.last("LIMIT 1");
|
||||||
|
LbOrderRow existing = this.getOne(w, false);
|
||||||
|
if (existing != null && existing.getId() != null) {
|
||||||
|
return existing.getId();
|
||||||
|
}
|
||||||
|
LocalDate day = LocalDate.parse(payTime.substring(0, 10), DAY_FMT);
|
||||||
|
long dayKey = day.getYear() * 10000L + day.getMonthValue() * 100L + day.getDayOfMonth();
|
||||||
|
int tenantSlot = Math.floorMod(tenantId.hashCode(), 10000);
|
||||||
|
return 10_000_000_000_000_000L + dayKey * 10_000L + tenantSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalDate parseBuyTimeToDate(String buyTime) {
|
||||||
|
if (buyTime == null || buyTime.trim().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String text = buyTime.trim();
|
||||||
|
try {
|
||||||
|
return LocalDateTime.parse(text, DAY_TIME_FMT).toLocalDate();
|
||||||
|
} catch (DateTimeParseException ignored) {
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return LocalDate.parse(text.substring(0, Math.min(10, text.length())), DAY_FMT);
|
||||||
|
} catch (DateTimeParseException ignored) {
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return LocalDateTime.parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toLocalDate();
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BigDecimal parseMoney(String money) {
|
private static BigDecimal parseMoney(String money) {
|
||||||
@@ -328,22 +475,15 @@ public class LbOrderRowServiceImpl extends ServiceImpl<LbOrderRowMapper, LbOrder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LbOrderRow toLbOrderRow(
|
private static LbOrderRow toLbOrderRow(HxrOrderRow row, String tenantId) {
|
||||||
HxrOrderRow row,
|
|
||||||
String tenantId,
|
|
||||||
String dataType,
|
|
||||||
BigDecimal todayTotalMoneySum,
|
|
||||||
Integer todayOrderCount,
|
|
||||||
Integer todayUnresellCount) {
|
|
||||||
LbOrderRow e = new LbOrderRow();
|
LbOrderRow e = new LbOrderRow();
|
||||||
e.setId(row.id());
|
e.setId(row.id());
|
||||||
e.setDataType("detail_data");
|
|
||||||
e.setOldId(row.oldId());
|
e.setOldId(row.oldId());
|
||||||
e.setTenantId(tenantId);
|
e.setTenantId(tenantId);
|
||||||
e.setDataType(dataType);
|
e.setDataType(SYNC_DATA_TYPE_DETAIL);
|
||||||
e.setTodayTotalMoneySum(todayTotalMoneySum);
|
e.setTodayTotalMoneySum(BigDecimal.ZERO);
|
||||||
e.setTodayOrderCount(todayOrderCount);
|
e.setTodayOrderCount(0);
|
||||||
e.setTodayUnresellCount(todayUnresellCount);
|
e.setTodayUnresellCount(0);
|
||||||
e.setSellerId(row.sellerId());
|
e.setSellerId(row.sellerId());
|
||||||
e.setBuyerId(row.buyerId());
|
e.setBuyerId(row.buyerId());
|
||||||
e.setOrderSn(row.orderSn());
|
e.setOrderSn(row.orderSn());
|
||||||
|
|||||||
Reference in New Issue
Block a user