优惠卷计算逻辑
This commit is contained in:
@@ -121,6 +121,23 @@ public class LbUserCouponController {
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
|
||||
@GetMapping("/calculateMonthlyAmount")
|
||||
@Operation(summary = "计算用户本月从开始日期到月末的优惠券金额")
|
||||
public ResponseEntity<Map<String, Object>> calculateMonthlyAmount(
|
||||
@Parameter(description = "用户ID", required = true)
|
||||
@RequestParam String userId,
|
||||
@Parameter(description = "用户昵称")
|
||||
@RequestParam(required = false) String userNickname,
|
||||
@Parameter(description = "开始日期,格式 yyyy-MM-dd")
|
||||
@RequestParam(required = false) String startDate) {
|
||||
Map<String, Object> result = lbUserCouponService.calculateUserMonthlyAmount(userId, userNickname, startDate);
|
||||
Boolean success = (Boolean) result.get("success");
|
||||
if (success != null && success) {
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(summary = "导出用户优惠券Excel", description = "按照分页查询的相同条件导出用户优惠券数据")
|
||||
public void export(
|
||||
|
||||
@@ -47,6 +47,16 @@ public interface ILbUserCouponService extends IService<LbUserCoupon> {
|
||||
*/
|
||||
Map<String, Object> monthlyStatistic(String tenantId, String couponDateStart, String couponDateEnd);
|
||||
|
||||
/**
|
||||
* 计算用户本月从开始日期到月末的优惠券金额
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userNickname 用户昵称
|
||||
* @param startDate 开始日期,格式 yyyy-MM-dd
|
||||
* @return 计算结果
|
||||
*/
|
||||
Map<String, Object> calculateUserMonthlyAmount(String userId, String userNickname, String startDate);
|
||||
|
||||
/**
|
||||
* 导出用户优惠券Excel
|
||||
*
|
||||
|
||||
@@ -668,7 +668,7 @@ public class LbGoodsServiceImpl extends ServiceImpl<LbGoodsMapper, LbGoods> impl
|
||||
if (buyResult.success()) {
|
||||
successCount++;
|
||||
successTotalAmount += goods.getTotalMoney().intValue();
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(3000);
|
||||
} else {
|
||||
failCount++;
|
||||
if (buyResult.orderAlreadyGrabbed()) {
|
||||
|
||||
@@ -32,12 +32,14 @@ import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Duration;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -444,6 +446,72 @@ public class LbUserCouponServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
private List<LbUserCoupon> fillMissingWeekdayRecords(List<LbUserCoupon> records, LocalDate start, LocalDate end) {
|
||||
if (records == null || records.isEmpty()) {
|
||||
return records;
|
||||
}
|
||||
|
||||
Map<String, LbUserCoupon> userInfoMap = new LinkedHashMap<>();
|
||||
Map<String, Set<LocalDate>> userDateMap = new HashMap<>();
|
||||
|
||||
for (LbUserCoupon record : records) {
|
||||
String userId = record.getUserId();
|
||||
if (userId == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!userInfoMap.containsKey(userId)) {
|
||||
userInfoMap.put(userId, record);
|
||||
}
|
||||
|
||||
userDateMap.computeIfAbsent(userId, k -> new LinkedHashSet<>());
|
||||
if (record.getCouponDate() != null) {
|
||||
userDateMap.get(userId).add(record.getCouponDate());
|
||||
}
|
||||
}
|
||||
|
||||
List<LbUserCoupon> result = new ArrayList<>(records);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
for (Map.Entry<String, LbUserCoupon> entry : userInfoMap.entrySet()) {
|
||||
String userId = entry.getKey();
|
||||
LbUserCoupon template = entry.getValue();
|
||||
Set<LocalDate> existingDates = userDateMap.getOrDefault(userId, new LinkedHashSet<>());
|
||||
|
||||
LocalDate current = start;
|
||||
while (!current.isAfter(end)) {
|
||||
DayOfWeek dayOfWeek = current.getDayOfWeek();
|
||||
if (dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY) {
|
||||
if (!existingDates.contains(current)) {
|
||||
LbUserCoupon missingRecord = new LbUserCoupon();
|
||||
missingRecord.setId(UUID.randomUUID().toString());
|
||||
missingRecord.setTenantId(template.getTenantId());
|
||||
missingRecord.setUserId(userId);
|
||||
missingRecord.setUserPhone(template.getUserPhone());
|
||||
missingRecord.setUserNickname(template.getUserNickname());
|
||||
missingRecord.setParentPhone(template.getParentPhone());
|
||||
missingRecord.setParentNickname(template.getParentNickname());
|
||||
missingRecord.setCouponAmount(BigDecimal.ZERO);
|
||||
missingRecord.setCouponDate(current);
|
||||
missingRecord.setDataType(template.getDataType());
|
||||
missingRecord.setCreateTime(now);
|
||||
missingRecord.setUpdateTime(now);
|
||||
result.add(missingRecord);
|
||||
}
|
||||
}
|
||||
current = current.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
result.sort((a, b) -> {
|
||||
BigDecimal amountA = a.getCouponAmount() != null ? a.getCouponAmount() : BigDecimal.ZERO;
|
||||
BigDecimal amountB = b.getCouponAmount() != null ? b.getCouponAmount() : BigDecimal.ZERO;
|
||||
return amountB.compareTo(amountA);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> add(LbUserCoupon entity) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
@@ -627,14 +695,34 @@ public class LbUserCouponServiceImpl
|
||||
|
||||
queryWrapper.orderByDesc(LbUserCoupon::getCouponAmount);
|
||||
|
||||
Page<LbUserCoupon> page = this.page(new Page<>(current, size), queryWrapper);
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("data", page.getRecords());
|
||||
result.put("total", page.getTotal());
|
||||
result.put("current", page.getCurrent());
|
||||
result.put("size", page.getSize());
|
||||
result.put("pages", page.getPages());
|
||||
if (start != null && end != null) {
|
||||
List<LbUserCoupon> allRecords = this.list(queryWrapper);
|
||||
List<LbUserCoupon> filledRecords = fillMissingWeekdayRecords(allRecords, start, end);
|
||||
|
||||
int total = filledRecords.size();
|
||||
int pages = (total + size - 1) / size;
|
||||
int fromIndex = (current - 1) * size;
|
||||
int toIndex = Math.min(fromIndex + size, total);
|
||||
|
||||
List<LbUserCoupon> pageRecords = fromIndex < total ? filledRecords.subList(fromIndex, toIndex) : new ArrayList<>();
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("data", pageRecords);
|
||||
result.put("total", (long) total);
|
||||
result.put("current", (long) current);
|
||||
result.put("size", (long) size);
|
||||
result.put("pages", (long) pages);
|
||||
} else {
|
||||
Page<LbUserCoupon> page = this.page(new Page<>(current, size), queryWrapper);
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("data", page.getRecords());
|
||||
result.put("total", page.getTotal());
|
||||
result.put("current", page.getCurrent());
|
||||
result.put("size", page.getSize());
|
||||
result.put("pages", page.getPages());
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("用户优惠券分页查询异常", e);
|
||||
@@ -726,6 +814,63 @@ public class LbUserCouponServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> calculateUserMonthlyAmount(String userId, String userNickname, String startDate) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
if (userId == null || userId.trim().isEmpty()) {
|
||||
result.put("success", false);
|
||||
result.put("message", "userId不能为空");
|
||||
return result;
|
||||
}
|
||||
|
||||
LocalDate start = parseDate(startDate);
|
||||
if (startDate != null && !startDate.trim().isEmpty() && start == null) {
|
||||
result.put("success", false);
|
||||
result.put("message", "startDate 格式错误,请使用 yyyy-MM-dd");
|
||||
return result;
|
||||
}
|
||||
if (start == null) {
|
||||
start = LocalDate.now();
|
||||
}
|
||||
|
||||
LocalDate end = start.withDayOfMonth(start.lengthOfMonth());
|
||||
|
||||
LambdaQueryWrapper<LbUserCoupon> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(LbUserCoupon::getUserId, userId.trim());
|
||||
if (userNickname != null && !userNickname.trim().isEmpty()) {
|
||||
queryWrapper.like(LbUserCoupon::getUserNickname, userNickname.trim());
|
||||
}
|
||||
queryWrapper.eq(LbUserCoupon::getDataType, "data_detail");
|
||||
queryWrapper.ge(LbUserCoupon::getCouponDate, start);
|
||||
queryWrapper.le(LbUserCoupon::getCouponDate, end);
|
||||
|
||||
List<LbUserCoupon> records = this.list(queryWrapper);
|
||||
BigDecimal totalAmount = records.stream()
|
||||
.map(r -> r.getCouponAmount() != null ? r.getCouponAmount() : BigDecimal.ZERO)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
List<LbUserCoupon> filledRecords = fillMissingWeekdayRecords(records, start, end);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "计算成功");
|
||||
result.put("userId", userId);
|
||||
result.put("userNickname", userNickname);
|
||||
result.put("startDate", start.format(DATE_FORMATTER));
|
||||
result.put("endDate", end.format(DATE_FORMATTER));
|
||||
result.put("totalAmount", totalAmount);
|
||||
result.put("recordCount", records.size());
|
||||
result.put("dailyDetail", filledRecords);
|
||||
return result;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("计算用户本月优惠券金额异常", e);
|
||||
result.put("success", false);
|
||||
result.put("message", "计算异常:" + e.getMessage());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportExcel(String tenantId,
|
||||
String userId,
|
||||
|
||||
Reference in New Issue
Block a user