尝试精简
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
package cn.van.business.util;
|
||||
|
||||
import static cn.van.business.util.JDUtil.UserInteractionState.GiftMoneyStep.STEP_QUANTITY;
|
||||
|
||||
/**
|
||||
* @author Leo
|
||||
* @version 1.0
|
||||
* @create 2025/4/4 20:46
|
||||
* @description:
|
||||
*/
|
||||
|
||||
// 实现金额处理步骤
|
||||
class AmountStepHandler implements FlowStepHandler {
|
||||
public void handle(JDUtil util, String wxid, String input, JDUtil.UserInteractionState state) {
|
||||
if (!util.isValidAmount(input)) {
|
||||
util.wxUtil.sendTextMessage(wxid, "金额格式错误", 1, wxid,false);
|
||||
return;
|
||||
}
|
||||
state.getCollectedFields().put("amount", input);
|
||||
state.setCurrentStep(STEP_QUANTITY);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package cn.van.business.util;
|
||||
|
||||
/**
|
||||
* @author Leo
|
||||
* @version 1.0
|
||||
* @create 2025/4/4 20:45
|
||||
* @description:
|
||||
*/
|
||||
public interface FlowStepHandler {
|
||||
void handle(JDUtil util, String wxid, String input, JDUtil.UserInteractionState state);
|
||||
}
|
||||
@@ -8,14 +8,9 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jd.open.api.sdk.DefaultJdClient;
|
||||
import com.jd.open.api.sdk.JdClient;
|
||||
import com.jd.open.api.sdk.domain.kplunion.CouponService.request.get.CreateGiftCouponReq;
|
||||
import com.jd.open.api.sdk.domain.kplunion.CouponService.request.stop.StopGiftCouponReq;
|
||||
import com.jd.open.api.sdk.domain.kplunion.GoodsService.request.query.BigFieldGoodsReq;
|
||||
import com.jd.open.api.sdk.domain.kplunion.GoodsService.request.query.GoodsReq;
|
||||
import com.jd.open.api.sdk.domain.kplunion.GoodsService.response.query.BigfieldQueryResult;
|
||||
import com.jd.open.api.sdk.domain.kplunion.GoodsService.response.query.GoodsQueryResult;
|
||||
import com.jd.open.api.sdk.domain.kplunion.GoodsService.response.query.UrlInfo;
|
||||
import com.jd.open.api.sdk.domain.kplunion.OrderService.request.query.OrderRowReq;
|
||||
import com.jd.open.api.sdk.domain.kplunion.promotionbysubunioni.PromotionService.request.get.PromotionCodeReq;
|
||||
import com.jd.open.api.sdk.request.kplunion.*;
|
||||
import com.jd.open.api.sdk.response.kplunion.*;
|
||||
@@ -29,10 +24,6 @@ import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
@@ -203,65 +194,6 @@ public void sendOrderToWxByOrderDefault(String order, String fromWxid) {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 处理“礼”指令,直接进入礼金创建流程
|
||||
*/
|
||||
private void handleGiftCommand(String fromWxid) {
|
||||
try {
|
||||
// 从缓存中获取消息内容
|
||||
String cachedMessage = cacheMap.get("giftMessage" + fromWxid);
|
||||
if (cachedMessage == null || cachedMessage.trim().isEmpty()) {
|
||||
wxUtil.sendTextMessage(fromWxid, "未找到商品链接,请重新输入包含商品链接的消息。", 1, fromWxid, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取 u.jd.com 链接
|
||||
List<String> urls = extractUJDUrls(cachedMessage);
|
||||
if (urls.isEmpty()) {
|
||||
wxUtil.sendTextMessage(fromWxid, "未找到有效的商品链接,请检查输入格式。", 1, fromWxid, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询商品信息,筛选有效商品
|
||||
List<GoodsQueryResult> validProducts = new ArrayList<>();
|
||||
for (String url : urls) {
|
||||
try {
|
||||
GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url);
|
||||
if (productInfo != null && productInfo.getCode() == 200 && productInfo.getTotalCount() > 0) {
|
||||
validProducts.add(productInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("查询商品信息失败:{}", url, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (validProducts.isEmpty()) {
|
||||
wxUtil.sendTextMessage(fromWxid, "未找到有效的商品信息,请检查链接是否正确。", 1, fromWxid, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 缓存商品信息
|
||||
String key = INTERACTION_STATE_PREFIX + fromWxid;
|
||||
UserInteractionState state = loadOrCreateState(key);
|
||||
|
||||
state.setCurrentState(UserInteractionState.ProcessState.GIFT_MONEY_FLOW);
|
||||
state.setCurrentStep(UserInteractionState.GiftMoneyStep.STEP_AMOUNT);
|
||||
state.getCollectedFields().clear();
|
||||
state.getCollectedFields().put("productIndex", "0"); // 当前处理的商品索引
|
||||
state.getCollectedFields().put("totalProducts", String.valueOf(validProducts.size())); // 总商品数
|
||||
cacheMap.put("validProducts" + fromWxid, JSON.toJSONString(validProducts));
|
||||
|
||||
saveState(key, state);
|
||||
|
||||
// 提示用户输入金额
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入开通金额(1-50元,支持小数点后两位):", 1, fromWxid, false);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("处理礼金指令异常 - 用户: {}", fromWxid, e);
|
||||
wxUtil.sendTextMessage(fromWxid, "处理请求时发生异常,请重试", 1, fromWxid, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 礼金创建流程 - 循环处理商品
|
||||
*/
|
||||
@@ -712,42 +644,6 @@ private void processGiftMoneyFlow(String wxid, String message, UserInteractionSt
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public UnionOpenOrderRowQueryResponse getUnionOpenOrderRowQueryResponse(LocalDateTime start, LocalDateTime end, Integer pageIndex, String appKey, String secretKey) 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, appKey, secretKey);
|
||||
UnionOpenOrderRowQueryRequest request = new UnionOpenOrderRowQueryRequest();
|
||||
OrderRowReq orderReq = new OrderRowReq();
|
||||
orderReq.setPageIndex(pageIndex);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口描述:通过商品链接、领券链接、活动链接获取普通推广链接或优惠券二合一推广链接
|
||||
@@ -911,85 +807,6 @@ private void handleUserInteraction(String fromWxid, String message) {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGiftMoneyFlow(String wxid, String message, UserInteractionState state) {
|
||||
if (!state.validateStep(state.getCurrentStep())) {
|
||||
wxUtil.sendTextMessage(wxid, "流程顺序异常,请重新开始", 1, wxid, false);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state.getCurrentStep()) {
|
||||
case STEP_AMOUNT:
|
||||
processAmountInput(wxid, message, state);
|
||||
break;
|
||||
|
||||
case STEP_QUANTITY:
|
||||
processQuantityInput(wxid, message, state);
|
||||
break;
|
||||
|
||||
default:
|
||||
state.setCurrentStep(STEP_AMOUNT);
|
||||
wxUtil.sendTextMessage(wxid, "请输入金额(1-50元):", 1, wxid, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void processAmountInput(String wxid, String message, UserInteractionState state) {
|
||||
if (!isValidAmount(message)) {
|
||||
wxUtil.sendTextMessage(wxid, "金额格式错误,请输入1-50元", 1, wxid, false);
|
||||
return;
|
||||
}
|
||||
|
||||
state.getCollectedFields().put("amount", message);
|
||||
state.setCurrentStep(STEP_QUANTITY);
|
||||
wxUtil.sendTextMessage(wxid, "请输入数量(1-100):", 1, wxid, false);
|
||||
}
|
||||
|
||||
private void processQuantityInput(String wxid, String message, UserInteractionState state) {
|
||||
if (!isValidQuantity(message)) {
|
||||
wxUtil.sendTextMessage(wxid, "数量格式错误,请输入1-100的整数", 1, wxid, false);
|
||||
return;
|
||||
}
|
||||
String cachedData = cacheMap.get("productData" + wxid);
|
||||
String finalWenAn = cacheMap.get("finalWenAn" + wxid);
|
||||
if (cachedData == null) {
|
||||
wxUtil.sendTextMessage(wxid, "数据丢失,请重新开始流程", 1, wxid, false);
|
||||
resetState(wxid, state);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject jsonObject = JSON.parseObject(cachedData);
|
||||
String skuId = jsonObject.getString("materialUrl");
|
||||
String owner = jsonObject.getString("owner");
|
||||
String skuName = jsonObject.getString("skuName");
|
||||
double amount = Double.parseDouble(state.getCollectedFields().get("amount"));
|
||||
int quantity = Integer.parseInt(message);
|
||||
|
||||
String giftKey = createGiftCoupon(skuId, amount, quantity, owner, skuName);
|
||||
if (giftKey == null) {
|
||||
wxUtil.sendTextMessage(wxid, "礼金创建失败,请重试", 1, wxid, false);
|
||||
return;
|
||||
}
|
||||
// 记录成功日志
|
||||
logger.info("礼金创建成功 - 用户: {}, SKU: {}, 金额: {}, 数量: {}",
|
||||
wxid, skuId, amount, quantity);
|
||||
// 生成转链
|
||||
String transferUrl = transfer(skuId, giftKey);
|
||||
wxUtil.sendTextMessage(wxid, "附带礼金的链接:\n" + transferUrl, 1, wxid, false);
|
||||
wxUtil.sendTextMessage(wxid, "附带礼金的方案:\n", 1, wxid, false);
|
||||
|
||||
wxUtil.sendTextMessage(wxid, finalWenAn.replaceAll(jsonObject.getString("url"), transferUrl), 1, wxid, true);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("礼金处理异常 - 用户: {}", wxid, e);
|
||||
wxUtil.sendTextMessage(wxid, "处理异常,请重试", 1, wxid, false);
|
||||
} finally {
|
||||
resetState(wxid, state);
|
||||
cacheMap.remove("text" + wxid);
|
||||
cacheMap.remove("finalWenAn" + wxid);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理用户输入的推广方案内容
|
||||
@@ -1222,21 +1039,6 @@ public HashMap<String, List<String>> generatePromotionContent(String message) {
|
||||
return finalMessage;
|
||||
}
|
||||
|
||||
|
||||
private String downloadImage(String imageUrl, String destinationFile) {
|
||||
try (BufferedInputStream in = new BufferedInputStream(new URL(imageUrl).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(destinationFile)) {
|
||||
byte[] dataBuffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
||||
}
|
||||
return destinationFile;
|
||||
} catch (IOException e) {
|
||||
logger.error("Error downloading image from URL: {}", imageUrl, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取方案中的所有 u.jd.com 链接
|
||||
*
|
||||
@@ -1298,171 +1100,6 @@ public HashMap<String, List<String>> generatePromotionContent(String message) {
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
// 在JDUtil类中新增方法实现商品详情查询接口
|
||||
public UnionOpenGoodsBigfieldQueryResponse getUnionOpenGoodsBigfieldQueryResponse(String skuId) throws
|
||||
Exception {
|
||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ);
|
||||
|
||||
UnionOpenGoodsBigfieldQueryRequest request = new UnionOpenGoodsBigfieldQueryRequest();
|
||||
BigFieldGoodsReq goodsReq = new BigFieldGoodsReq();
|
||||
goodsReq.setSkuIds(List.of(Long.parseLong(skuId)).toArray(new Long[0])); // 传入skuId集合
|
||||
/**
|
||||
* 查询域集合,不填写则查询全部,目目前支持:categoryInfo(类目信息),imageInfo(图片信息),
|
||||
* baseBigFieldInfo(基础大字段信息),bookBigFieldInfo(图书大字段信息),
|
||||
* videoBigFieldInfo(影音大字段信息),detailImages(商详图)*/
|
||||
//goodsReq.setFields(new String[]{"categoryInfo", "imageInfo", "baseBigFieldInfo"}); // 设置需要查询的字段
|
||||
goodsReq.setSceneId(2); // 设置场景ID
|
||||
|
||||
request.setGoodsReq(goodsReq);
|
||||
request.setVersion("1.0");
|
||||
request.setSignmethod("md5");
|
||||
request.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
|
||||
return client.execute(request);
|
||||
}
|
||||
|
||||
// 修改parseSkuFromUrl方法提取SKU
|
||||
private String parseSkuFromUrl(String url) {
|
||||
Matcher m = Pattern.compile("item.jd.com/(\\d+).html").matcher(url);
|
||||
return m.find() ? m.group(1) : null;
|
||||
}
|
||||
|
||||
public BigfieldQueryResult queryProductInfo(String skuId) throws Exception {
|
||||
UnionOpenGoodsBigfieldQueryResponse response = getUnionOpenGoodsBigfieldQueryResponse(skuId);
|
||||
if (response == null || response.getQueryResult() == null) {
|
||||
return null;
|
||||
}
|
||||
BigfieldQueryResult queryResult = response.getQueryResult();
|
||||
if (queryResult.getCode() != 200) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
// 新增礼金创建方法
|
||||
public String createGiftCoupon(String skuId, double amount, int quantity, String owner, String skuName) throws Exception {
|
||||
logger.debug("准备创建礼金:SKU={}, 金额={}元,数量={}, Owner={}", skuId, amount, quantity, owner);
|
||||
|
||||
// 参数校验
|
||||
if (skuId == null || amount <= 0 || quantity <= 0) {
|
||||
logger.error("礼金创建失败:参数错误,SKU={}, 金额={}元,数量={}", skuId, amount, quantity);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 设置默认值
|
||||
owner = (owner != null) ? owner : "g";
|
||||
|
||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ);
|
||||
|
||||
UnionOpenCouponGiftGetRequest request = new UnionOpenCouponGiftGetRequest();
|
||||
CreateGiftCouponReq couponReq = new CreateGiftCouponReq();
|
||||
couponReq.setSkuMaterialId(skuId); // 使用SKU或链接
|
||||
couponReq.setDiscount(amount);
|
||||
couponReq.setAmount(quantity);
|
||||
|
||||
// 自营的只能设置一天,pop的只能设置7天,默认为自营
|
||||
String startTime;
|
||||
String endTime;
|
||||
if ("pop".equals(owner)) {
|
||||
startTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
|
||||
endTime = LocalDateTime.now().plusDays(6).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
|
||||
couponReq.setEffectiveDays(7);
|
||||
|
||||
} else {
|
||||
startTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
|
||||
endTime = LocalDateTime.now().plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
|
||||
couponReq.setEffectiveDays(1);
|
||||
|
||||
}
|
||||
|
||||
couponReq.setReceiveStartTime(startTime);
|
||||
couponReq.setReceiveEndTime(endTime);
|
||||
couponReq.setIsSpu(1);
|
||||
couponReq.setExpireType(1);
|
||||
couponReq.setShare(-1);
|
||||
if (skuName.length() >= 25) {
|
||||
skuName = skuName.substring(0, 25);
|
||||
}
|
||||
// 新建格式日期
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
skuName = skuName + " " + dateFormat.format(new Date());
|
||||
|
||||
couponReq.setCouponTitle(skuName);
|
||||
couponReq.setContentMatch(1);
|
||||
|
||||
request.setCouponReq(couponReq);
|
||||
request.setVersion("1.0");
|
||||
|
||||
logger.debug("请求参数:{}", JSON.toJSONString(request));
|
||||
|
||||
UnionOpenCouponGiftGetResponse response = client.execute(request);
|
||||
logger.debug("API响应:{}", JSON.toJSONString(response));
|
||||
|
||||
if ("0".equals(response.getCode()) && response.getGetResult().getCode() == 200) {
|
||||
String giftKey = response.getGetResult().getData().getGiftCouponKey();
|
||||
logger.debug("礼金创建成功:批次ID={}, 返回数据:{}", giftKey, response.getGetResult().getData());
|
||||
return giftKey;
|
||||
} else {
|
||||
logger.error("礼金创建失败:错误码={}, 错误信息={}", response.getCode(), response.getMsg());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 修改activateGiftMoney方法调用真实接口
|
||||
private boolean activateGiftMoney(String skuId, double amount, int quantity, String owner) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 新增礼金停止方法(可选)
|
||||
public boolean stopGiftCoupon(String giftKey) throws Exception {
|
||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ);
|
||||
|
||||
|
||||
UnionOpenCouponGiftStopRequest request = new UnionOpenCouponGiftStopRequest();
|
||||
StopGiftCouponReq couponReq = new StopGiftCouponReq();
|
||||
couponReq.setGiftCouponKey(giftKey);
|
||||
|
||||
request.setCouponReq(couponReq);
|
||||
request.setVersion("1.0");
|
||||
request.setSignmethod("md5");
|
||||
request.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
|
||||
UnionOpenCouponGiftStopResponse response = client.execute(request);
|
||||
return "200".equals(response.getCode());
|
||||
}
|
||||
|
||||
boolean isValidAmount(String input) {
|
||||
// 新增:直接处理 null 或空字符串
|
||||
if (input == null || input.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
double amount = Double.parseDouble(input);
|
||||
return amount >= 1 && amount <= 50;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidQuantity(String input) {
|
||||
if (input == null || input.trim().isEmpty()) {
|
||||
logger.error("数量为空或无效: {}", input);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
int quantity = Integer.parseInt(input);
|
||||
if (quantity < 1 || quantity > 100) {
|
||||
logger.error("数量超出范围: {}", quantity);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error("数量格式错误: {}", input, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 将状态存储迁移到Redis
|
||||
public void saveState(String wxid, UserInteractionState state) {
|
||||
String key = INTERACTION_STATE_PREFIX + wxid;
|
||||
@@ -1504,16 +1141,6 @@ public HashMap<String, List<String>> generatePromotionContent(String message) {
|
||||
updateLastInteractionTime();
|
||||
}
|
||||
|
||||
// 在UserInteractionState类中增加状态校验方法
|
||||
public boolean validateStep(GiftMoneyStep expectedStep) {
|
||||
return this.currentStep != null && this.currentStep.getCode() == expectedStep.getCode();
|
||||
}
|
||||
|
||||
// 在UserInteractionState中增加恢复方法
|
||||
public void restoreState(Map<String, String> backup) {
|
||||
this.collectedFields.putAll(backup);
|
||||
this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER);
|
||||
}
|
||||
|
||||
// 推荐使用枚举管理状态
|
||||
public enum ProcessState {
|
||||
|
||||
Reference in New Issue
Block a user