diff --git a/src/main/java/cn/van/business/controller/jd/JDInnerController.java b/src/main/java/cn/van/business/controller/jd/JDInnerController.java index 555e700..edc07e9 100644 --- a/src/main/java/cn/van/business/controller/jd/JDInnerController.java +++ b/src/main/java/cn/van/business/controller/jd/JDInnerController.java @@ -420,6 +420,68 @@ public class JDInnerController { } } + /** + * 批量创建礼金券并生成包含礼金的推广链接 + * 入参:{ skey, skuId/materialUrl, amount, quantity, batchSize, owner, skuName } + * 返回:{ results: [ {index, success, giftCouponKey, shortURL, error} ], total, successCount, failCount } + */ + @PostMapping("/batchCreateGiftCoupons") + public Object batchCreateGiftCoupons(@RequestBody Map body) { + String skey = body.get("skey") != null ? String.valueOf(body.get("skey")) : null; + if (checkSkey(skey)) { + return error("invalid skey"); + } + + String skuId = body.get("skuId") != null ? String.valueOf(body.get("skuId")) : null; + String materialUrl = body.get("materialUrl") != null ? String.valueOf(body.get("materialUrl")) : null; + String owner = body.get("owner") != null ? String.valueOf(body.get("owner")) : "g"; + String skuName = body.get("skuName") != null ? String.valueOf(body.get("skuName")) : ""; + double amount = parseDouble(body.get("amount"), 1.0); + int quantity = parseInt(body.get("quantity"), 1); + int batchSize = parseInt(body.get("batchSize"), 20); + + String idOrUrl = skuId != null && !skuId.trim().isEmpty() ? skuId : materialUrl; + if (idOrUrl == null || idOrUrl.trim().isEmpty()) { + return error("skuId or materialUrl is required"); + } + if (amount <= 0 || quantity <= 0) { + return error("amount and quantity must be positive"); + } + if (batchSize <= 0 || batchSize > 100) { + return error("batchSize must be between 1 and 100"); + } + + logger.info("批量创建礼金券请求 - idOrUrl={}, amount={}, quantity={}, batchSize={}, owner={}, skuName={}", + idOrUrl, amount, quantity, batchSize, owner, skuName); + + try { + List> results = jdProductService.batchCreateGiftCouponsWithLinks( + idOrUrl, amount, quantity, batchSize, owner, skuName); + + int successCount = 0; + int failCount = 0; + for (Map result : results) { + if (Boolean.TRUE.equals(result.get("success"))) { + successCount++; + } else { + failCount++; + } + } + + JSONObject resp = new JSONObject(); + resp.put("results", results); + resp.put("total", batchSize); + resp.put("successCount", successCount); + resp.put("failCount", failCount); + + logger.info("批量创建礼金券完成 - 总数={}, 成功={}, 失败={}", batchSize, successCount, failCount); + return resp; + } catch (Exception e) { + logger.error("batchCreateGiftCoupons error", e); + return error("batchCreateGiftCoupons failed: " + e.getMessage()); + } + } + /** * 手动清理Redis中超过93天的旧数据 * 请求参数:{ skey } diff --git a/src/main/java/cn/van/business/util/JDProductService.java b/src/main/java/cn/van/business/util/JDProductService.java index 675b84c..308a059 100644 --- a/src/main/java/cn/van/business/util/JDProductService.java +++ b/src/main/java/cn/van/business/util/JDProductService.java @@ -451,4 +451,94 @@ public class JDProductService { return errorMap; } } + + /** + * 批量创建礼金券并生成包含礼金的推广链接 + * + * @param skuId 商品SKU ID或materialUrl + * @param amount 礼金金额(单位:元) + * @param quantity 每个礼金券的数量 + * @param batchSize 批量创建的个数(默认20) + * @param owner 商品类型(g=自营,pop=POP) + * @param skuName 商品名称 + * @return 批量创建结果列表,包含giftCouponKey和shortURL + */ + public List> batchCreateGiftCouponsWithLinks(String skuId, double amount, int quantity, int batchSize, String owner, String skuName) { + log.info("开始批量创建礼金券 - SKU={}, 金额={}元, 数量={}, 批次大小={}, Owner={}", skuId, amount, quantity, batchSize, owner); + + List> results = new ArrayList<>(); + int successCount = 0; + int failCount = 0; + + for (int i = 0; i < batchSize; i++) { + Map result = new HashMap<>(); + result.put("index", i + 1); + result.put("success", false); + + try { + // 创建礼金券 + String giftCouponKey = createGiftCoupon(skuId, amount, quantity, owner, skuName); + + if (giftCouponKey == null || giftCouponKey.trim().isEmpty()) { + log.error("批量创建礼金券失败 [{}/{}] - giftCouponKey为空", i + 1, batchSize); + result.put("error", "礼金创建失败,giftCouponKey为空"); + result.put("giftCouponKey", null); + result.put("shortURL", null); + failCount++; + } else { + log.info("批量创建礼金券成功 [{}/{}] - giftCouponKey={}", i + 1, batchSize, giftCouponKey); + + // 保存到Redis + try { + saveGiftCouponToRedis(skuId, giftCouponKey, skuName, owner); + } catch (Exception e) { + log.warn("保存礼金到Redis失败,但礼金创建成功 - giftCouponKey={}, error={}", giftCouponKey, e.getMessage()); + } + + // 生成包含礼金的推广链接 + String shortURL = null; + try { + // 使用materialUrl或skuId作为原始链接 + String originalUrl = skuId; + // transfer方法支持SKU ID或materialUrl直接传入 + shortURL = transfer(originalUrl, giftCouponKey); + + if (shortURL == null || shortURL.trim().isEmpty()) { + log.warn("生成推广链接失败 - giftCouponKey={}, 礼金创建成功但转链失败", giftCouponKey); + } else { + log.info("生成推广链接成功 [{}/{}] - giftCouponKey={}, shortURL={}", i + 1, batchSize, giftCouponKey, shortURL); + } + } catch (Exception e) { + log.error("生成推广链接异常 - giftCouponKey={}, error={}", giftCouponKey, e.getMessage(), e); + } + + result.put("success", true); + result.put("giftCouponKey", giftCouponKey); + result.put("shortURL", shortURL); + successCount++; + } + } catch (Exception e) { + log.error("批量创建礼金券异常 [{}/{}] - error={}", i + 1, batchSize, e.getMessage(), e); + result.put("error", "创建异常: " + e.getMessage()); + result.put("giftCouponKey", null); + result.put("shortURL", null); + failCount++; + } + + results.add(result); + + // 避免请求过快,每创建一张礼金后稍作延迟 + if (i < batchSize - 1) { + try { + Thread.sleep(100); // 延迟100ms + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.warn("批量创建礼金券延迟被中断"); + } + } + } + + log.info("批量创建礼金券完成 - 总数={}, 成功={}, 失败={}", batchSize, successCount, failCount); + return results; + } }