重构前
This commit is contained in:
@@ -2,9 +2,7 @@ package cn.van.business.util;
|
||||
|
||||
|
||||
import cn.van.business.model.jd.OrderRow;
|
||||
import cn.van.business.model.jd.ProductOrder;
|
||||
import cn.van.business.repository.OrderRowRepository;
|
||||
import cn.van.business.repository.ProductOrderRepository;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -34,6 +32,7 @@ import org.springframework.stereotype.Component;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -41,18 +40,15 @@ import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.van.business.util.JDUtil.UserInteractionState.GiftMoneyStep.*;
|
||||
import static cn.van.business.util.JDUtil.UserInteractionState.ProcessState.DISINFECTANT_CABINET;
|
||||
import static cn.van.business.util.JDUtil.UserInteractionState.ProcessState.INIT;
|
||||
import static cn.van.business.util.JDUtil.UserInteractionState.ProductOrderStep.*;
|
||||
import static cn.van.business.util.JDUtil.UserInteractionState.ProcessState.*;
|
||||
import static cn.van.business.util.WXUtil.super_admins;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author Leo
|
||||
@@ -84,21 +80,19 @@ public class JDUtil {
|
||||
private static final long TIMEOUT_MINUTES = 1;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final OrderRowRepository orderRowRepository;
|
||||
private final ProductOrderRepository productOrderRepository;
|
||||
private final WXUtil wxUtil;
|
||||
private final OrderUtil orderUtil;
|
||||
// 添加ObjectMapper来序列化和反序列化UserInteractionState
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private final ConcurrentHashMap<String, UserInteractionState> userInteractionStates = new ConcurrentHashMap<>();
|
||||
private HashMap<String, String> cacheMap = new HashMap<>();
|
||||
|
||||
|
||||
// 构造函数中注入StringRedisTemplate
|
||||
@Autowired
|
||||
public JDUtil(StringRedisTemplate redisTemplate, ProductOrderRepository productOrderRepository, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil) {
|
||||
public JDUtil(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.orderRowRepository = orderRowRepository;
|
||||
this.productOrderRepository = productOrderRepository;
|
||||
this.wxUtil = wxUtil;
|
||||
this.orderUtil = orderUtil;
|
||||
}
|
||||
@@ -625,30 +619,23 @@ public class JDUtil {
|
||||
|
||||
private void handleUserInteraction(String fromWxid, String message) {
|
||||
String key = INTERACTION_STATE_PREFIX + fromWxid;
|
||||
String stateJson = redisTemplate.opsForValue().get(key);
|
||||
UserInteractionState state;
|
||||
UserInteractionState state = userInteractionStates.get(key);
|
||||
|
||||
if (stateJson == null) {
|
||||
if (state == null) {
|
||||
state = new UserInteractionState();
|
||||
logger.debug("New interaction state created for user: {}", fromWxid);
|
||||
} else {
|
||||
try {
|
||||
state = objectMapper.readValue(stateJson, UserInteractionState.class);
|
||||
// 检查是否超时
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime lastInteractionTime = LocalDateTime.parse(state.getLastInteractionTime(), DATE_TIME_FORMATTER);
|
||||
if (ChronoUnit.MINUTES.between(lastInteractionTime, now) > TIMEOUT_MINUTES) {
|
||||
redisTemplate.delete(key);
|
||||
userInteractionStates.remove(key);
|
||||
logger.debug("Deleted timeout state for user: {}", fromWxid);
|
||||
state = new UserInteractionState();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error parsing interaction state: {}", e.getMessage());
|
||||
state = new UserInteractionState();
|
||||
}
|
||||
}
|
||||
|
||||
state.updateLastInteractionTime();
|
||||
userInteractionStates.put(key, state); // 确保状态保存
|
||||
|
||||
switch (state.getCurrentState()) {
|
||||
case INIT:
|
||||
@@ -657,17 +644,6 @@ public class JDUtil {
|
||||
state.setCurrentField("content");
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入推广文案(包含商品链接):", 1, fromWxid);
|
||||
logger.info("进入转链流程 - 文案输入步骤");
|
||||
} else if ("礼金".equals(message)) {
|
||||
state.setCurrentState(UserInteractionState.ProcessState.PRODUCT_PROMOTION);
|
||||
state.setCurrentField("content");
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入推广文案(包含商品链接):", 1, fromWxid);
|
||||
logger.info("进入转链流程 - 文案输入步骤");
|
||||
|
||||
} else if ("登记".equals(message)) {
|
||||
state.setCurrentState(DISINFECTANT_CABINET);
|
||||
state.setCurrentField("orderId");
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入订单号:", 1, fromWxid);
|
||||
logger.debug("User {} entered DISINFECTANT_CABINET state", fromWxid);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -694,36 +670,32 @@ public class JDUtil {
|
||||
logger.error("Error generating promotion content: {}", e.getMessage());
|
||||
}
|
||||
cacheMap.put("text" + fromWxid, messagesAll.get("data").get(0));
|
||||
// 询问是否需要继续转链
|
||||
// 直接进入确认开通礼金的步骤
|
||||
state.setCurrentField("confirm");
|
||||
wxUtil.sendTextMessage(fromWxid, "是否需要开通礼金?\n回复 1 - 是\n回复 2 - 否", 1, fromWxid);
|
||||
logger.info("转链流程 - 等待用户确认是否需要开通礼金");
|
||||
state.setCurrentField("confirm");
|
||||
} else if ("confirm".equals(state.getCurrentField())) {
|
||||
logger.info("转链流程 - 用户确认是否需要开通礼金:{}", message);
|
||||
if ("1".equals(message)) {
|
||||
state.setCurrentState(UserInteractionState.ProcessState.PRODUCT_PROMOTION);
|
||||
state.setCurrentField("content");
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入推广文案(包含商品链接):", 1, fromWxid);
|
||||
logger.info("进入转链流程 - 文案输入步骤");
|
||||
// ▼▼▼ 关键修改:明确设置初始步骤 ▼▼▼
|
||||
state.setCurrentState(UserInteractionState.ProcessState.GIFT_MONEY_FLOW);
|
||||
state.setCurrentStep(UserInteractionState.GiftMoneyStep.STEP_AMOUNT);
|
||||
state.getCollectedFields().clear();
|
||||
userInteractionStates.put(key, state); // 立即持久化状态
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入开通金额(元):", 1, fromWxid);
|
||||
} else if ("2".equals(message)) {
|
||||
wxUtil.sendTextMessage(fromWxid, "开通礼金流程已取消", 1, fromWxid);
|
||||
cacheMap.remove("text" + fromWxid);
|
||||
|
||||
|
||||
} else {
|
||||
wxUtil.sendTextMessage(fromWxid, "无效的选择,请重新输入:\n回复 1 - 是\n回复 2 - 否", 1, fromWxid);
|
||||
}
|
||||
state.reset(); // 重置状态
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case GIFT_MONEY_FLOW:
|
||||
handleGiftMoneyFlow(fromWxid, message, state);
|
||||
break;
|
||||
|
||||
case PRODUCT_ORDER_REGISTRATION:
|
||||
handleProductOrderRegistration(fromWxid, message, state);
|
||||
createPromotionWithGift(fromWxid, message);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -733,113 +705,72 @@ public class JDUtil {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(state), TIMEOUT_MINUTES, TimeUnit.MINUTES);
|
||||
logger.debug("Saved interaction state for user {}: {}", fromWxid, state);
|
||||
} catch (Exception e) {
|
||||
logger.error("Error saving interaction state: {}", e.getMessage());
|
||||
}
|
||||
userInteractionStates.put(key, state);
|
||||
logger.debug("Updated interaction state for user {}: {}", fromWxid, JSON.toJSONString(state));
|
||||
}
|
||||
|
||||
// 新增方法:处理文案中的链接并进行转链
|
||||
private String transferContentWithLinks(String message) {
|
||||
List<String> urls = extractUJDUrls(message);
|
||||
if (urls.isEmpty()) {
|
||||
return "文案中未找到有效的商品链接,请检查格式是否正确。\n" + message;
|
||||
}
|
||||
|
||||
StringBuilder enrichedContent = new StringBuilder();
|
||||
for (String url : urls) {
|
||||
String transferUrl = transfer(url,null);
|
||||
if (transferUrl != null) {
|
||||
enrichedContent.append("原链接:").append(url).append("\n")
|
||||
.append("转链后链接:").append(transferUrl).append("\n");
|
||||
private void createPromotionWithGift(String fromWxid, String message) {
|
||||
String key = INTERACTION_STATE_PREFIX + fromWxid;
|
||||
UserInteractionState state = userInteractionStates.get(key);
|
||||
|
||||
// 修改点3:在createPromotionWithGift方法开始处增加状态校验
|
||||
if (state == null || state.getCurrentStep() == null) {
|
||||
logger.warn("非法状态访问: {}", fromWxid);
|
||||
wxUtil.sendTextMessage(fromWxid, "⚠️ 会话超时,请重新开始流程", 1, fromWxid);
|
||||
return;
|
||||
} else {
|
||||
enrichedContent.append("链接转链失败:").append(url).append("\n");
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime lastInteractionTime = LocalDateTime.parse(state.getLastInteractionTime(), DATE_TIME_FORMATTER);
|
||||
if (ChronoUnit.MINUTES.between(lastInteractionTime, now) > TIMEOUT_MINUTES) {
|
||||
userInteractionStates.remove(key);
|
||||
logger.debug("Deleted timeout state for user: {}", fromWxid);
|
||||
state = new UserInteractionState();
|
||||
}
|
||||
}
|
||||
return enrichedContent.toString();
|
||||
}
|
||||
|
||||
// 新增礼金流程处理方法
|
||||
private void handleGiftMoneyFlow(String fromWxid, String message, UserInteractionState state) {
|
||||
if (cacheMap.get("text"+fromWxid) != null){
|
||||
message = cacheMap.get("text"+fromWxid);
|
||||
}
|
||||
if (state.getCurrentStep() == null) {
|
||||
state.setCurrentStep(STEP_PRODUCT_LINK);
|
||||
wxUtil.sendTextMessage(fromWxid, "流程异常,已重置。请输入商品链接:", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
|
||||
if ("礼金".equals(message)) {
|
||||
state.reset();
|
||||
logger.debug("用户 {} 重置礼金流程", fromWxid); // 新增
|
||||
wxUtil.sendTextMessage(fromWxid, "流程已重置,请重新开始", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
state.updateLastInteractionTime();
|
||||
userInteractionStates.put(key, state); // 确保状态保存
|
||||
|
||||
try {
|
||||
String skuId = "";
|
||||
double amount = 0.0;
|
||||
String owner = "pop";
|
||||
switch (state.getCurrentStep()) {
|
||||
case STEP_PRODUCT_LINK:
|
||||
if (cacheMap.get("text"+fromWxid) != null) {
|
||||
String data = cacheMap.get("text" + fromWxid);
|
||||
JSONObject jsonObject = JSONObject.parseObject(data);
|
||||
skuId = jsonObject.getString("materialUrl");
|
||||
String owner1 = jsonObject.getString("owner");
|
||||
if (owner1 != null && owner1.equals("g")){
|
||||
owner = "g";
|
||||
}
|
||||
|
||||
}else {
|
||||
skuId = parseSkuFromUrl(message);
|
||||
}
|
||||
logger.debug("用户 {} 输入商品链接:{}, 解析出SKU: {}", fromWxid, message, skuId); // 新增
|
||||
if (skuId == null) {
|
||||
wxUtil.sendTextMessage(fromWxid, "商品链接格式错误,请重新输入", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
//BigfieldQueryResult queryResult = queryProductInfo(skuId);
|
||||
//logger.debug("商品ID {} 查询结果:{}", skuId, queryResult); // 新增
|
||||
//if (queryResult == null) {
|
||||
// wxUtil.sendTextMessage(fromWxid, "⚠️ 商品信息查询失败,可能链接无效", 1, fromWxid);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//BigFieldGoodsResp productInfo = queryResult.getData()[0];
|
||||
//owner = productInfo.getOwner();
|
||||
//state.getCollectedFields().put("skuId", skuId);
|
||||
//state.getCollectedFields().put("productInfo", productInfo.getBaseBigFieldInfo().getWdis());
|
||||
//state.getCollectedFields().put("owner", owner);
|
||||
//
|
||||
//logger.debug("商品信息已收集:SKU={}, Owner={}, WDIS={}", skuId, owner, productInfo.getBaseBigFieldInfo().getWdis()); // 新增
|
||||
//String productInfo = skuId;
|
||||
state.getCollectedFields().put("skuId", skuId);
|
||||
case STEP_CONFIRM_GIFT:
|
||||
if ("1".equals(message)) {
|
||||
state.setCurrentStep(STEP_AMOUNT);
|
||||
String prompt = "请输入开通金额(元):";
|
||||
wxUtil.sendTextMessage(fromWxid, prompt, 1, fromWxid);
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入开通金额(元):", 1, fromWxid);
|
||||
} else if ("2".equals(message)) {
|
||||
// 不开通礼金,直接生成转链
|
||||
String cachedData = cacheMap.get("text" + fromWxid);
|
||||
if (cachedData != null) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(cachedData);
|
||||
String skuId = jsonObject.getString("materialUrl");
|
||||
String transferUrl = transfer(skuId, null);
|
||||
wxUtil.sendTextMessage(fromWxid, "转链后的链接:\n" + transferUrl, 1, fromWxid);
|
||||
} else {
|
||||
wxUtil.sendTextMessage(fromWxid, "未找到缓存的商品链接,请重新开始流程", 1, fromWxid);
|
||||
}
|
||||
state.reset();
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
} else {
|
||||
wxUtil.sendTextMessage(fromWxid, "无效的选择,请重新输入:\n回复 1 - 是\n回复 2 - 否", 1, fromWxid);
|
||||
}
|
||||
break;
|
||||
|
||||
case STEP_AMOUNT:
|
||||
logger.debug("用户 {} 输入金额:{}", fromWxid, message);
|
||||
// 强制检查空值
|
||||
if (message == null || message.trim().isEmpty()) {
|
||||
wxUtil.sendTextMessage(fromWxid, "金额不能为空,请输入数字(如:100.00)", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
// 校验格式
|
||||
if (!isValidAmount(message)) {
|
||||
wxUtil.sendTextMessage(fromWxid, "金额格式错误,请输入数字(如:100.00)", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
// 转换并保留两位小数
|
||||
amount = Double.parseDouble(message);
|
||||
double amount = Double.parseDouble(message);
|
||||
String formattedAmount = String.format("%.2f", amount);
|
||||
state.getCollectedFields().put("amount", formattedAmount);
|
||||
state.setCurrentStep(STEP_QUANTITY);
|
||||
userInteractionStates.put(key, state); // ▼▼▼ 保存点2 ▼▼▼
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入数量(1-100):", 1, fromWxid);
|
||||
break;
|
||||
|
||||
@@ -856,42 +787,63 @@ public class JDUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug("礼金参数准备完成:SKU={},金额={}元,数量={},Owner={}", state.getCollectedFields().get("skuId"), amount, quantity, state.getCollectedFields().get("owner")); // 新增
|
||||
// 从缓存中获取 amount
|
||||
String amountStr = state.getCollectedFields().get("amount");
|
||||
if (amountStr == null || amountStr.trim().isEmpty()) {
|
||||
wxUtil.sendTextMessage(fromWxid, "未找到金额,请重新开始流程", 1, fromWxid);
|
||||
state.reset();
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
return;
|
||||
}
|
||||
amount = Double.parseDouble(amountStr);
|
||||
|
||||
String giftKey = createGiftCoupon(state.getCollectedFields().get("skuId"),
|
||||
Double.parseDouble(state.getCollectedFields().get("amount")),
|
||||
quantity,
|
||||
owner);
|
||||
logger.debug("礼金参数准备完成:金额={}元,数量={}", amount, quantity); // 新增
|
||||
|
||||
String cachedData = cacheMap.get("text" + fromWxid);
|
||||
if (cachedData != null) {
|
||||
JSONObject jsonObject = JSONObject.parseObject(cachedData);
|
||||
String skuId = jsonObject.getString("materialUrl");
|
||||
String giftKey = createGiftCoupon(skuId, amount, quantity, "pop");
|
||||
if (giftKey == null) {
|
||||
logger.error("用户 {} 礼金创建失败:SKU={}, 金额={}, 数量={}, Owner={}", fromWxid, skuId, amount, quantity, owner); // 新增
|
||||
logger.error("用户 {} 礼金创建失败:SKU={}, 金额={}元,数量={}", fromWxid, skuId, amount, quantity); // 新增
|
||||
wxUtil.sendTextMessage(fromWxid, "❌ 礼金创建失败,请检查商品是否符合要求", 1, fromWxid);
|
||||
state.reset();
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("用户 {} 礼金创建成功:批次ID={}, 参数:SKU={}, 金额={}元,数量={}, Owner={}", fromWxid, giftKey, skuId, amount, quantity, owner); // 新增关键成功日志
|
||||
logger.info("用户 {} 礼金创建成功:批次ID={}, 参数:SKU={}, 金额={}元,数量={}", fromWxid, giftKey, skuId, amount, quantity); // 新增关键成功日志
|
||||
state.getCollectedFields().put("giftKey", giftKey);
|
||||
|
||||
// 需要调用转链,传入礼金批次ID,返回转链和文案
|
||||
if (cacheMap.get("text"+fromWxid) != null) {
|
||||
String data = cacheMap.get("text" + fromWxid);
|
||||
JSONObject jsonObject = JSONObject.parseObject(data);
|
||||
skuId = jsonObject.getString("materialUrl");
|
||||
String transfer = transfer(skuId, giftKey);
|
||||
wxUtil.sendTextMessage(fromWxid, "附带礼金的链接:\n" + transfer, 1, fromWxid);
|
||||
|
||||
|
||||
// 生成转链
|
||||
String transferUrl = transfer(skuId, giftKey);
|
||||
wxUtil.sendTextMessage(fromWxid, "附带礼金的链接:\n" + transferUrl, 1, fromWxid);
|
||||
state.reset();
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
} else {
|
||||
wxUtil.sendTextMessage(fromWxid, "未找到缓存的商品链接,请重新开始流程", 1, fromWxid);
|
||||
state.reset();
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
state.setCurrentStep(STEP_CONFIRM_GIFT);
|
||||
wxUtil.sendTextMessage(fromWxid, "是否需要开通礼金?\n回复 1 - 是\n回复 2 - 否", 1, fromWxid);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("礼金流程异常,用户 {} 当前步骤:{}", fromWxid, state.getCurrentStep(), e); // 新增
|
||||
logger.error("转链和礼金流程异常,用户 {} 当前步骤:{}", fromWxid, state.getCurrentStep(), e);
|
||||
wxUtil.sendTextMessage(fromWxid, "❌ 系统异常,请稍后重试", 1, fromWxid);
|
||||
state.reset();
|
||||
userInteractionStates.put(key, state); // 在外部保存
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 生成转链和文案的方法
|
||||
*
|
||||
@@ -1257,6 +1209,7 @@ public class JDUtil {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取文案中的所有 u.jd.com 链接
|
||||
*
|
||||
@@ -1469,100 +1422,23 @@ public class JDUtil {
|
||||
|
||||
|
||||
private boolean isValidQuantity(String input) {
|
||||
return input.matches("^\\d+$");
|
||||
if (input == null || input.trim().isEmpty()) {
|
||||
logger.error("数量为空或无效: {}", input);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void handleProductOrderRegistration(String fromWxid, String message, UserInteractionState state) {
|
||||
switch (state.getCurrentProductOrderStep()) {
|
||||
case STEP_ORDER_ID:
|
||||
if (!message.matches("^\\d{10,20}$")) {
|
||||
wxUtil.sendTextMessage(fromWxid, "⚠️ 订单号格式错误(需10-20位数字)", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
state.getCollectedFields().put("orderId", message);
|
||||
state.setCurrentProductOrderStep(STEP_PRODUCT_INFO);
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入商品信息(格式:商品名称-类型编号)\n类型对照:1-家电 2-数码 3-服饰\n示例:格力空调-1", 1, fromWxid);
|
||||
break;
|
||||
|
||||
case STEP_PRODUCT_INFO:
|
||||
String[] productInfo = message.split("-");
|
||||
if (productInfo.length != 2 || !productInfo[1].matches("[1-3]")) {
|
||||
wxUtil.sendTextMessage(fromWxid, "❌ 格式错误或类型编号无效", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
state.getCollectedFields().put("skuName", productInfo[0]);
|
||||
state.getCollectedFields().put("skuType", productInfo[1]);
|
||||
|
||||
state.setCurrentProductOrderStep(UserInteractionState.ProductOrderStep.STEP_RECIPIENT_INFO);
|
||||
wxUtil.sendTextMessage(fromWxid, "请输入收件信息(格式:姓名-电话-地址)\n示例:张三-13812345678-北京市朝阳区", 1, fromWxid);
|
||||
break;
|
||||
|
||||
case STEP_RECIPIENT_INFO:
|
||||
String[] recipientInfo = message.split("-");
|
||||
if (recipientInfo.length < 3) {
|
||||
wxUtil.sendTextMessage(fromWxid, "❌ 格式错误,请按示例格式输入", 1, fromWxid);
|
||||
return;
|
||||
}
|
||||
state.getCollectedFields().put("recipientName", recipientInfo[0]);
|
||||
state.getCollectedFields().put("recipientPhone", recipientInfo[1]);
|
||||
state.getCollectedFields().put("recipientAddress", String.join("-", Arrays.copyOfRange(recipientInfo, 2, recipientInfo.length)));
|
||||
|
||||
// 生成确认信息
|
||||
String confirmMsg = buildConfirmMessage(state);
|
||||
wxUtil.sendTextMessage(fromWxid, confirmMsg, 1, fromWxid);
|
||||
state.setCurrentProductOrderStep(STEP_REVIEW_CONFIRM);
|
||||
break;
|
||||
|
||||
case STEP_REVIEW_CONFIRM:
|
||||
if ("确认".equals(message)) {
|
||||
boolean success = saveFullProductOrder(state, fromWxid);
|
||||
wxUtil.sendTextMessage(fromWxid, success ? "✅ 订单登记成功!" : "❌ 保存失败,请联系管理员", 1, fromWxid);
|
||||
state.reset();
|
||||
} else {
|
||||
state.setCurrentProductOrderStep(STEP_ORDER_ID);
|
||||
wxUtil.sendTextMessage(fromWxid, "请重新输入订单号:", 1, fromWxid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String buildConfirmMessage(UserInteractionState state) {
|
||||
return "📋 请确认登记信息:\n" + "────────────────\n" + "▪ 订单号:" + state.getCollectedFields().get("orderId") + "\n" + "▪ 商品名称:" + state.getCollectedFields().get("skuName") + "\n" + "▪ 商品类型:" + getTypeDesc(state.getCollectedFields().get("skuType")) + "\n" + "▪ 收件人:" + state.getCollectedFields().get("recipientName") + "\n" + "▪ 联系方式:" + state.getCollectedFields().get("recipientPhone") + "\n" + "▪ 收货地址:" + state.getCollectedFields().get("recipientAddress") + "\n" + "────────────────\n" + "回复【确认】提交,其他内容重新开始";
|
||||
}
|
||||
|
||||
private boolean saveFullProductOrder(UserInteractionState state, String fromWxid) {
|
||||
try {
|
||||
ProductOrder order = new ProductOrder();
|
||||
order.setOrderId(state.getCollectedFields().get("orderId"));
|
||||
order.setSkuName(state.getCollectedFields().get("skuName"));
|
||||
order.setSkuType(Integer.valueOf(state.getCollectedFields().get("skuType")));
|
||||
order.setRecipientName(state.getCollectedFields().get("recipientName"));
|
||||
order.setRecipientPhone(state.getCollectedFields().get("recipientPhone"));
|
||||
order.setRecipientAddress(state.getCollectedFields().get("recipientAddress"));
|
||||
order.setOrderTime(new Date()); // 设置下单时间为当前时间
|
||||
order.setWhoOrder(state.getCollectedFields().get("recipientName")); // 关联管理员信息
|
||||
order.setIsReviewed(false); // 默认是否晒图登记
|
||||
order.setIsCashbackReceived(false); // 默认是否返现到账
|
||||
order.setFromWxid(fromWxid); // 设置当前交互的wxid
|
||||
|
||||
productOrderRepository.save(order);
|
||||
logger.info("订单登记成功:{}", order);
|
||||
int quantity = Integer.parseInt(input);
|
||||
if (quantity < 1 || quantity > 100) {
|
||||
logger.error("数量超出范围: {}", quantity);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logger.error("订单保存异常:{}", e.getMessage());
|
||||
} catch (NumberFormatException e) {
|
||||
logger.error("数量格式错误: {}", input, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private String getTypeDesc(String skuType) {
|
||||
return switch (skuType) {
|
||||
case "1" -> "家电";
|
||||
case "2" -> "数码";
|
||||
case "3" -> "服饰";
|
||||
default -> "未知类型";
|
||||
};
|
||||
}
|
||||
|
||||
// 定义一个内部类来存储用户交互状态
|
||||
@Getter
|
||||
@@ -1573,9 +1449,9 @@ public class JDUtil {
|
||||
private ProcessState currentState;
|
||||
private Map<String, String> collectedFields; // 用于存储收集到的字段值
|
||||
private String currentField; // 当前正在询问的字段
|
||||
private ProductOrderStep currentProductOrderStep;
|
||||
|
||||
public UserInteractionState() {
|
||||
this.currentStep = GiftMoneyStep.STEP_CONFIRM_GIFT; // 初始
|
||||
this.lastInteractionTime = LocalDateTime.now().format(DATE_TIME_FORMATTER);
|
||||
this.currentState = INIT;
|
||||
this.collectedFields = new HashMap<>();
|
||||
@@ -1590,25 +1466,31 @@ public class JDUtil {
|
||||
public void reset() {
|
||||
this.currentState = INIT;
|
||||
this.collectedFields.clear();
|
||||
this.currentStep = STEP_PRODUCT_LINK; // 明确重置步骤
|
||||
this.currentProductOrderStep = null;
|
||||
this.currentStep = STEP_CONFIRM_GIFT ; // 明确重置步骤
|
||||
updateLastInteractionTime();
|
||||
}
|
||||
|
||||
|
||||
// 推荐使用枚举管理状态
|
||||
public enum ProcessState {
|
||||
INIT, GIFT_MONEY_FLOW, DISINFECTANT_CABINET, PRODUCT_ORDER_REGISTRATION, PRODUCT_PROMOTION
|
||||
INIT, GIFT_MONEY_FLOW, PRODUCT_PROMOTION
|
||||
}
|
||||
|
||||
public enum GiftMoneyStep {
|
||||
STEP_PRODUCT_LINK, STEP_AMOUNT, STEP_QUANTITY
|
||||
STEP_CONFIRM_GIFT(0), // 显式指定序号
|
||||
STEP_AMOUNT(1),
|
||||
STEP_QUANTITY(2);
|
||||
private final int code;
|
||||
|
||||
GiftMoneyStep(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
// 在UserInteractionState类中新增步骤枚举
|
||||
public enum ProductOrderStep {
|
||||
STEP_ORDER_ID, STEP_PRODUCT_INFO, STEP_RECIPIENT_INFO, STEP_REVIEW_CONFIRM, STEP_CASHBACK_TRACK
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -61,5 +61,5 @@ rocketmq:
|
||||
consume-thread-max: 64 # 消费线程池最大线程数
|
||||
consume-message-batch-max-size: 64 # 批量消费最大消息数
|
||||
isRunning:
|
||||
wx: false
|
||||
jd: false
|
||||
wx: true
|
||||
jd: true
|
||||
|
||||
Reference in New Issue
Block a user