package cn.van.business.util; import cn.van.business.enums.ValidCodeConverter; import cn.van.business.model.jd.GoodsInfoVO; import cn.van.business.model.jd.OrderRow; import cn.van.business.repository.OrderRowRepository; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.util.DateUtils; import com.jd.open.api.sdk.DefaultJdClient; import com.jd.open.api.sdk.JdClient; import com.jd.open.api.sdk.domain.kplunion.OrderService.request.query.OrderRowReq; import com.jd.open.api.sdk.domain.kplunion.OrderService.response.query.GoodsInfo; import com.jd.open.api.sdk.domain.kplunion.OrderService.response.query.OrderRowResp; import com.jd.open.api.sdk.domain.kplunion.promotioncommon.PromotionService.request.get.PromotionCodeReq; import com.jd.open.api.sdk.request.kplunion.UnionOpenOrderRowQueryRequest; import com.jd.open.api.sdk.request.kplunion.UnionOpenPromotionCommonGetRequest; import com.jd.open.api.sdk.response.kplunion.UnionOpenOrderRowQueryResponse; import com.jd.open.api.sdk.response.kplunion.UnionOpenPromotionCommonGetResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.SetOperations; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import static java.lang.Thread.sleep; /** * @author Leo * @version 1.0 * @create 2024/11/5 17:40 * @description: */ @Component public class JDUtils { private static final String SERVER_URL = "https://api.jd.com/routerjson"; // van论坛 private static final String APP_KEY = "98e21c89ae5610240ec3f5f575f86a59"; private static final String SECRET_KEY = "3dcb6b23a1104639ac433fd07adb6dfb"; // 导购的 //private static final String APP_KEY = "faf410cb9587dc80dc7b31e321d7d322"; //private static final String SECRET_KEY = // "a4fb15d7bedd4316b97b4e96e4effc1c"; //accessToken private static final String ACCESS_TOKEN = ""; //标记唯一订单行:订单+sku维度的唯一标识 private static final String ORDER_ROW_KEY = "jd:order:row:"; private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Autowired private StringRedisTemplate redisTemplate; @Autowired private OrderRowRepository orderRowRepository; @Autowired private WXUtil wxUtil; /** * 将 响应参数转化为 OrderRow,并返回 */ private static OrderRow createOrderRow(OrderRowResp orderRowResp) { OrderRow orderRow = new OrderRow(); orderRow.setOrderId(orderRowResp.getOrderId()); orderRow.setSkuId(orderRowResp.getSkuId()); orderRow.setSkuName(orderRowResp.getSkuName()); orderRow.setItemId(orderRowResp.getItemId()); orderRow.setSkuNum(orderRowResp.getSkuNum()); orderRow.setPrice(orderRowResp.getPrice()); orderRow.setActualCosPrice(orderRowResp.getActualCosPrice()); orderRow.setActualFee(orderRowResp.getActualFee()); orderRow.setEstimateCosPrice(orderRowResp.getEstimateCosPrice()); orderRow.setEstimateFee(orderRowResp.getEstimateFee()); orderRow.setSubSideRate(orderRowResp.getSubSideRate()); orderRow.setSubsidyRate(orderRowResp.getSubsidyRate()); orderRow.setCommissionRate(orderRowResp.getCommissionRate()); orderRow.setFinalRate(orderRowResp.getFinalRate()); orderRow.setOrderTime(DateUtils.parseDate(orderRowResp.getOrderTime())); orderRow.setFinishTime(DateUtils.parseDate(orderRowResp.getFinishTime())); orderRow.setOrderTag(orderRowResp.getOrderTag()); orderRow.setOrderEmt(orderRowResp.getOrderEmt()); orderRow.setUnionId(orderRowResp.getUnionId()); orderRow.setUnionRole(orderRowResp.getUnionRole()); orderRow.setUnionAlias(orderRowResp.getUnionAlias()); orderRow.setUnionTag(orderRowResp.getUnionTag()); orderRow.setTraceType(orderRowResp.getTraceType()); orderRow.setValidCode(orderRowResp.getValidCode()); orderRow.setPayMonth(orderRowResp.getPayMonth()); orderRow.setSiteId(orderRowResp.getSiteId()); orderRow.setParentId(orderRowResp.getParentId()); GoodsInfo goodsInfo = orderRowResp.getGoodsInfo(); GoodsInfoVO goodsInfoVO = new GoodsInfoVO(); goodsInfoVO.setShopId(String.valueOf(goodsInfo.getShopId())); goodsInfoVO.setShopName(goodsInfo.getShopName()); goodsInfoVO.setOwner(goodsInfo.getOwner()); goodsInfoVO.setProductId(String.valueOf(goodsInfo.getProductId())); goodsInfoVO.setImageUrl(goodsInfo.getImageUrl()); orderRow.setGoodsInfo(goodsInfoVO); orderRow.setCallerItemId(orderRowResp.getCallerItemId()); orderRow.setPid(orderRowResp.getPid()); orderRow.setCid1(orderRowResp.getCid1()); orderRow.setCid2(orderRowResp.getCid2()); orderRow.setCid3(orderRowResp.getCid3()); orderRow.setChannelId(orderRowResp.getChannelId()); orderRow.setProPriceAmount(orderRowResp.getProPriceAmount()); orderRow.setSkuFrozenNum(orderRowResp.getSkuFrozenNum()); orderRow.setSkuReturnNum(orderRowResp.getSkuReturnNum()); orderRow.setSkuTag(orderRowResp.getSkuTag()); orderRow.setPositionId(orderRowResp.getPositionId()); orderRow.setPopId(orderRowResp.getPopId()); orderRow.setRid(orderRowResp.getRid()); orderRow.setPlus(orderRowResp.getPlus()); orderRow.setCpActId(orderRowResp.getCpActId()); orderRow.setGiftCouponKey(orderRowResp.getGiftCouponKey()); orderRow.setModifyTime(new Date()); orderRow.setSign(orderRowResp.getSign()); orderRow.setBalanceExt(orderRowResp.getBalanceExt()); orderRow.setExpressStatus(orderRowResp.getExpressStatus()); orderRow.setExt1(orderRowResp.getExt1()); orderRow.setSubUnionId(orderRowResp.getSubUnionId()); orderRow.setGiftCouponOcsAmount(orderRowResp.getGiftCouponOcsAmount()); orderRow.setTraceType(orderRowResp.getTraceType()); orderRow.setExpressStatus(orderRowResp.getExpressStatus()); orderRow.setTraceType(orderRowResp.getTraceType()); orderRow.setId(orderRowResp.getId()); orderRow.setValidCode(orderRowResp.getValidCode()); orderRow.setExpressStatus(orderRowResp.getExpressStatus()); orderRow.setTraceType(orderRowResp.getTraceType()); return orderRow; } private static List filterOrdersByDate(List orderRows, int daysBack) { LocalDate now = LocalDate.now(); return orderRows.stream() .filter(order -> { // 将 Date 转换为 LocalDate LocalDate orderDate = order.getOrderTime().toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate(); // 计算是否在给定的天数内 return !orderDate.isBefore(now.minusDays(daysBack)) && !orderDate.isAfter(now); }) .collect(Collectors.toList()); } private static Stream getStreamForWeiGui(List todayOrders) { return todayOrders.stream().filter( orderRow -> orderRow.getValidCode() == 2 || orderRow.getValidCode() == 13 || orderRow.getValidCode() == 25 || orderRow.getValidCode() == 26 || orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28 || orderRow.getValidCode() == 29); } /** * 拉取最新的订单 1440分钟 */ @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次 public void fetchLatestOrder() throws Exception { LocalDateTime now = LocalDateTime.now(); LocalDateTime lastMinute = now.minusMinutes(10).withSecond(0).withNano(0); UnionOpenOrderRowQueryResponse response = fetchOrdersForDateTime(lastMinute, true); // 真实代表实时订单 if (response != null) { int code = response.getQueryResult().getCode(); if (code == 200) { if (response.getQueryResult().getCode() == 200) { OrderRowResp[] orderRowResps = response.getQueryResult().getData(); if (orderRowResps == null) { return; } for (OrderRowResp orderRowResp : orderRowResps) { // 固化到数据库 OrderRow orderRow = createOrderRow(orderRowResp); // 订单号不存在就保存,存在就更新订单状态 orderRowRepository.save(orderRow); } } } } } @Scheduled(cron = "0 * * * * ?") // 每分钟执行一次 public void sendOrderToWx() { int[] parm = {-1}; List orderRows = orderRowRepository.findByValidCodeNotInOrderByOrderTimeDesc(parm); if (!orderRows.isEmpty()) { for (OrderRow orderRow : orderRows) { orderToWx(orderRow, true); } } } /** * 指令 */ public void sendOrderToWxByOrderJD(String order) throws Exception { int[] parm = {-1}; List orderRows = orderRowRepository.findByValidCodeNotInOrderByOrderTimeDesc(parm); /** * 菜单: * 今日统计 * 昨日统计 * 最近七天统计 * 最近一个月统计 * 今天订单 * 昨天订单 * */ StringBuilder content = new StringBuilder(); switch (order) { case "菜单": content.append("菜单:京+命令 \n 如: 京今日统计\r"); content.append("今日统计\r"); content.append("昨天统计\r"); content.append("七日统计\r"); content.append("一个月统计\r"); content.append("两个月统计\r"); content.append("三个月统计\r"); content.append("今日订单\r"); content.append("昨日订单\r"); content.append("刷新三天\r"); content.append("刷新两个月\r"); content.append("违规排行\r"); break; case "今日统计": { List todayOrders = filterOrdersByDate(orderRows, 0); // 订单总数,已付款,已取消,佣金总计 content.append("今日统计:"); content.append("订单总数:").append(todayOrders.size()).append("\r"); content.append("已付款:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(todayOrders).count()).append("\r"); content.append("已付款佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(todayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); break; } case "昨日统计": { List yesterdayOrders = filterOrdersByDate(orderRows, 1); List todayOrders = filterOrdersByDate(orderRows, 0); yesterdayOrders.removeAll(todayOrders); content.append("昨日统计:"); content.append("订单总数:").append(yesterdayOrders.size()).append("\r"); content.append("已付款:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(yesterdayOrders).count()).append("\r"); content.append("已付款佣金:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(yesterdayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); break; } case "七日统计": { List last7DaysOrders = filterOrdersByDate(orderRows, 7); content.append("七日统计:"); content.append("订单总数:").append(last7DaysOrders.size()).append("\r"); content.append("已付款:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(last7DaysOrders)).append("\r"); content.append("已付款佣金:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(last7DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last7DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); break; } case "一个月统计": { List last30DaysOrders = filterOrdersByDate(orderRows, 30); content.append("一个月统计:"); content.append("订单总数:").append(last30DaysOrders.size()).append("\r"); content.append("已付款:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(last30DaysOrders).count()).append("\r"); content.append("已付款佣金:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(last30DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last30DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); break; } case "两个月统计": { List last60DaysOrders = filterOrdersByDate(orderRows, 60); content.append("两个月统计:"); content.append("订单总数:").append(last60DaysOrders.size()).append("\r"); content.append("已付款:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(last60DaysOrders).count()).append("\r"); content.append("已付款佣金:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(last60DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last60DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); break; } case "三个月统计": { List last90DaysOrders = filterOrdersByDate(orderRows, 90); content.append("订单总数:").append(last90DaysOrders.size()).append("\r"); content.append("已付款:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(last90DaysOrders).count()).append("\r"); content.append("已付款佣金:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(last90DaysOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(last90DaysOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); break; } case "今日订单": { List todayOrders = filterOrdersByDate(orderRows, 0); // 订单总数,已付款,已取消,佣金总计 content.append("今日统计:"); content.append("订单总数:").append(todayOrders.size()).append("\r"); content.append("已付款:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(todayOrders).count()).append("\r"); content.append("已付款佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(todayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); for (OrderRow orderRow : todayOrders) { orderToWx(orderRow, false); } break; } case "昨日订单": { List yesterdayOrders = filterOrdersByDate(orderRows, 1); List todayOrders = filterOrdersByDate(orderRows, 0); yesterdayOrders.removeAll(todayOrders); content.append("昨日统计:"); content.append("订单总数:").append(yesterdayOrders.size()).append("\r"); content.append("已付款:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).count()).append("\r"); content.append("已取消:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() != 16 && orderRow.getValidCode() != 17).count()).append("\r"); content.append("已完成:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).count()).append("\r"); content.append("违规:").append(getStreamForWeiGui(yesterdayOrders).count()).append("\r"); content.append("已付款佣金:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum()).append("\r"); content.append("已完成佣金:").append(yesterdayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum()); content.append("\r" + "违规佣金:").append(getStreamForWeiGui(yesterdayOrders).mapToDouble(orderRow -> orderRow.getEstimateCosPrice() * orderRow.getCommissionRate() * 0.01).sum()); for (OrderRow orderRow : yesterdayOrders) { orderToWx(orderRow, false); } break; } case "刷新三天": { long start = System.currentTimeMillis(); int count = 0; LocalDateTime startDate = LocalDateTime.now().minusDays(3).withMinute(0).withSecond(0).withNano(0); LocalDateTime lastHour = LocalDateTime.now().minusHours(1).withMinute(0).withSecond(0).withNano(0); while (!startDate.isEqual(lastHour)) { startDate = startDate.plusHours(1); UnionOpenOrderRowQueryResponse response = fetchOrdersForDateTime(startDate, false); if (response != null) { int code = response.getQueryResult().getCode(); if (code == 200) { if (response.getQueryResult().getCode() == 200) { OrderRowResp[] orderRowResps = response.getQueryResult().getData(); if (orderRowResps == null) { continue; } for (OrderRowResp orderRowResp : orderRowResps) { // 固化到数据库 OrderRow orderRow = createOrderRow(orderRowResp); // 订单号不存在就保存,存在就更新订单状态 orderRowRepository.save(orderRow); count++; } } } } } content.append("刷新三天成功,耗时").append((System.currentTimeMillis() - start) / 1000).append("秒\r").append("刷新订单数:").append(count); } case "刷新两个月": { long start = System.currentTimeMillis(); fetchHistoricalOrders(); content.append("刷新两个月,耗时").append((System.currentTimeMillis() - start) / 1000).append("秒\r"); } case "违规排行": { content.append("违规排行:"); List oneYearOrders = filterOrdersByDate(orderRows, 365); // 计算出skuId 违规的前7个排行 Map skuIdViolationCountMap = oneYearOrders.stream().filter(orderRow -> orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28 || orderRow.getValidCode() == 2).filter(orderRow -> orderRow.getSkuName() != null).collect(Collectors.groupingBy(OrderRow::getSkuName, Collectors.counting())); List> sortedViolationCounts = skuIdViolationCountMap.entrySet().stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()); Integer num = 0; for (Map.Entry entry : sortedViolationCounts) { num++; String skuName = entry.getKey(); Long count = entry.getValue(); content.append(num).append(",商品:").append(skuName).append("\r\r").append(" 违规次数:").append(count).append("\r"); } } break; default: sendOrderToWxByOrderJD("菜单"); } if (content.length() > 0) { wxUtil.sendTextMessage(WXUtil.super_admin_wxid, content.toString(), 1, WXUtil.super_admin_wxid); } } private void orderToWx(OrderRow orderRow, Boolean isAutoFlush) { // 查询订单状态 Integer newValidCode = orderRow.getValidCode(); String oldValidCode = redisTemplate.opsForValue().get(ORDER_ROW_KEY + orderRow.getId()); Integer lastValidCode = 0; // 更新 Redis 状态 redisTemplate.opsForValue().set(ORDER_ROW_KEY + orderRow.getId(), String.valueOf(orderRow.getValidCode())); if (Util.isNotEmpty(oldValidCode)) { lastValidCode = Integer.valueOf(oldValidCode); } // 如果订单状态没变化,就不发送 if (isAutoFlush && lastValidCode.equals(newValidCode)) { } else { String content; content = getFormattedOrderInfo(orderRow, Util.isEmpty(oldValidCode) ? -100 : Integer.parseInt(oldValidCode)); // 推送 wxUtil.sendTextMessage(WXUtil.super_admin_wxid, content, 1, WXUtil.super_admin_wxid); } } public String getFormattedOrderInfo(OrderRow orderRow, Integer oldValidCode) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ValidCodeConverter converter = new ValidCodeConverter(); String orderInfo = //+ "订单+sku:" + orderRow.getId() + "\r" "订单号:" + orderRow.getOrderId() + "(" + (orderRow.getPlus() == 1 ? "plus" : "非plus") + ")\r" + "最新订单状态:" + (converter.getCodeDescription(orderRow.getValidCode())) + "\r" + "商品名称:" + orderRow.getSkuName() + "\r" + "商品单价:" + orderRow.getPrice() + "\r" + "商品数量:" + orderRow.getSkuNum() + "\r" + "商品总价:" + (orderRow.getPrice() * orderRow.getSkuNum()) + "\r" + "预估计佣金额:" + orderRow.getEstimateCosPrice() + "\n" + "佣金比例:" + orderRow.getCommissionRate() + "%\r\r" + "推客的预估佣金:" + orderRow.getEstimateFee() + "\r" + "实际计算佣金的金额:" + orderRow.getActualCosPrice() + "\r" + "下单时间:" + formatter.format(orderRow.getOrderTime()) + "\r" + "完成时间:" + (orderRow.getFinishTime() != null ? formatter.format(orderRow.getFinishTime()) : "未完成") + "\r\n"; if (oldValidCode != -100) { orderInfo = "订单状态从 :" + (converter.getCodeDescription(oldValidCode)) + " --变成-- " + (converter.getCodeDescription(orderRow.getValidCode())) + "\r" + orderInfo; } return orderInfo; } /** * 根据指定的日期时间拉取订单 */ public UnionOpenOrderRowQueryResponse fetchOrdersForDateTime(LocalDateTime startTime, boolean isRealTime) throws Exception { LocalDateTime endTime = isRealTime ? startTime.plusMinutes(10) : startTime.plusHours(1); String key = startTime.format(DATE_TIME_FORMATTER); String hourRange = isRealTime ? "minute" : "hour"; SetOperations setOps = redisTemplate.opsForSet(); // 检查是否标记为已拉取 //if (Boolean.TRUE.equals(setOps.isMember(key, hourRange))) { // System.out.println(dateTime.format(DATE_TIME_FORMATTER) + " 已经拉取,跳过"); // return null; //} // 调用 API 以拉取订单 UnionOpenOrderRowQueryResponse unionOpenOrderRowQueryResponse = getUnionOpenOrderRowQueryResponse(startTime, endTime); // 标记已拉取 setOps.add(key, hourRange); // 打印方法调用和开始结束时间 System.out.println("拉取订单:" + "开始时间:" + startTime.format(DATE_TIME_FORMATTER) + "结束时间:" + endTime.format(DATE_TIME_FORMATTER)); return unionOpenOrderRowQueryResponse; } /** * 获取订单列表 * * @param start 开始时间 * @param end 结束时间 * @return * @throws Exception */ public UnionOpenOrderRowQueryResponse getUnionOpenOrderRowQueryResponse(LocalDateTime start, LocalDateTime end) throws Exception { String startTime = start.format(DATE_TIME_FORMATTER); String endTime = end.format(DATE_TIME_FORMATTER); // 模拟 API 调用 //System.out.println("调用API - 从 " + startTime // + " 到 " + endTime); // 实际的 API 调用逻辑应在这里进行 JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, APP_KEY, SECRET_KEY); UnionOpenOrderRowQueryRequest request = new UnionOpenOrderRowQueryRequest(); OrderRowReq orderReq = new OrderRowReq(); orderReq.setPageIndex(1); orderReq.setPageSize(200); orderReq.setStartTime(startTime); orderReq.setEndTime(endTime); orderReq.setType(1); request.setOrderReq(orderReq); request.setVersion("1.0"); request.setSignmethod("md5"); // 时间戳,格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8。API服务端允许客户端请求最大时间误差为10分钟 Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); request.setTimestamp(simpleDateFormat.format(date)); return client.execute(request); } /** * 转链 */ String transfer(String url) throws Exception { JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, APP_KEY, SECRET_KEY); UnionOpenPromotionCommonGetRequest request = new UnionOpenPromotionCommonGetRequest(); request.setVersion("1.0"); request.setSignmethod("md5"); PromotionCodeReq promotionCodeReq = new PromotionCodeReq(); promotionCodeReq.setMaterialId(url); promotionCodeReq.setSiteId( "4101253066"); promotionCodeReq.setSceneId(1); promotionCodeReq.setCommand(1); promotionCodeReq.setProType(5); request.setPromotionCodeReq(promotionCodeReq); UnionOpenPromotionCommonGetResponse response = client.execute(request); String jsonString = JSON.toJSONString(response); System.out.println(jsonString); // //System.out.println(request.getAppJsonParams()); //System.out.println(request.getPromotionCodeReq()); // //System.out.println("--------"); //System.out.println(response.getGetResult().getCode()); //System.out.println(response.getGetResult().getMessage()); //System.out.println(response.getGetResult().getData().getClickURL()); //System.out.println(response.getGetResult().getData().getJCommand()); return response.getGetResult().getData().getClickURL(); } // 拉取历史订单 2880 次请求 @Scheduled(cron = "0 0 * * * ?") public void fetchHistoricalOrders() throws Exception { // 从设定的开始日期到昨天的同一时间 System.out.println("开始拉取历史订单"); // 拉最近两个月的订单 // 获取当前时间,并调整为整点开始 LocalDateTime startDate = LocalDateTime.now().minusMonths(2).truncatedTo(ChronoUnit.HOURS); LocalDateTime now = LocalDateTime.now(); LocalDateTime lastHour = now.truncatedTo(ChronoUnit.HOURS); while (!startDate.isEqual(lastHour)) { startDate = startDate.plusHours(1); UnionOpenOrderRowQueryResponse response = fetchOrdersForDateTime(startDate, false); // 假的代表历史订单 if (response != null) { int code = response.getQueryResult().getCode(); if (code == 200) { if (response.getQueryResult().getCode() == 200) { OrderRowResp[] orderRowResps = response.getQueryResult().getData(); if (orderRowResps == null) { continue; } for (OrderRowResp orderRowResp : orderRowResps) { // 固化到数据库 OrderRow orderRow = createOrderRow(orderRowResp); // 订单号不存在就保存,存在就更新订单状态 orderRowRepository.save(orderRow); sleep(300); } } } } } } }