继续写这个接口的商品信息,够用了
This commit is contained in:
@@ -6,7 +6,6 @@ import cn.van.business.model.jd.ProductOrder;
|
|||||||
import cn.van.business.repository.OrderRowRepository;
|
import cn.van.business.repository.OrderRowRepository;
|
||||||
import cn.van.business.repository.ProductOrderRepository;
|
import cn.van.business.repository.ProductOrderRepository;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.jd.open.api.sdk.DefaultJdClient;
|
import com.jd.open.api.sdk.DefaultJdClient;
|
||||||
import com.jd.open.api.sdk.JdClient;
|
import com.jd.open.api.sdk.JdClient;
|
||||||
@@ -56,6 +55,7 @@ import static cn.van.business.util.WXUtil.super_admins;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class JDUtil {
|
public class JDUtil {
|
||||||
|
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
/**
|
/**
|
||||||
* 密钥配置
|
* 密钥配置
|
||||||
*/
|
*/
|
||||||
@@ -66,18 +66,12 @@ public class JDUtil {
|
|||||||
// 导购的
|
// 导购的
|
||||||
private static final String LPF_APP_KEY_DG = "faf410cb9587dc80dc7b31e321d7d322";
|
private static final String LPF_APP_KEY_DG = "faf410cb9587dc80dc7b31e321d7d322";
|
||||||
private static final String LPF_SECRET_KEY_DG = "a4fb15d7bedd4316b97b4e96e4effc1c";
|
private static final String LPF_SECRET_KEY_DG = "a4fb15d7bedd4316b97b4e96e4effc1c";
|
||||||
|
|
||||||
private static final String LL_APP_KEY_DG = "9c2011409f0fc906b73432dd3687599d";
|
private static final String LL_APP_KEY_DG = "9c2011409f0fc906b73432dd3687599d";
|
||||||
private static final String LL_SECRET_KEY_DG = "3ceddff403e544a8a2eacc727cf05dab";
|
private static final String LL_SECRET_KEY_DG = "3ceddff403e544a8a2eacc727cf05dab";
|
||||||
|
|
||||||
|
|
||||||
private static final String SERVER_URL = "https://api.jd.com/routerjson";
|
private static final String SERVER_URL = "https://api.jd.com/routerjson";
|
||||||
//accessToken
|
//accessToken
|
||||||
private static final String ACCESS_TOKEN = "";
|
private static final String ACCESS_TOKEN = "";
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(JDUtil.class);
|
private static final Logger logger = LoggerFactory.getLogger(JDUtil.class);
|
||||||
|
|
||||||
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
||||||
private static final String INTERACTION_STATE_PREFIX = "interaction_state:";
|
private static final String INTERACTION_STATE_PREFIX = "interaction_state:";
|
||||||
private static final long TIMEOUT_MINUTES = 1;
|
private static final long TIMEOUT_MINUTES = 1;
|
||||||
private final StringRedisTemplate redisTemplate;
|
private final StringRedisTemplate redisTemplate;
|
||||||
@@ -522,14 +516,21 @@ public class JDUtil {
|
|||||||
* 接口描述:通过商品链接、领券链接、活动链接获取普通推广链接或优惠券二合一推广链接
|
* 接口描述:通过商品链接、领券链接、活动链接获取普通推广链接或优惠券二合一推广链接
|
||||||
* jd.union.open.promotion.bysubunionid.get
|
* jd.union.open.promotion.bysubunionid.get
|
||||||
*/
|
*/
|
||||||
String transfer(String url) throws Exception {
|
String transfer(String url) {
|
||||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_DG, LPF_SECRET_KEY_DG);
|
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_DG, LPF_SECRET_KEY_DG);
|
||||||
|
|
||||||
UnionOpenPromotionBysubunionidGetRequest request = new UnionOpenPromotionBysubunionidGetRequest();
|
UnionOpenPromotionBysubunionidGetRequest request = new UnionOpenPromotionBysubunionidGetRequest();
|
||||||
PromotionCodeReq promotionCodeReq = new PromotionCodeReq();
|
PromotionCodeReq promotionCodeReq = new PromotionCodeReq();
|
||||||
|
promotionCodeReq.setMaterialId(url);
|
||||||
|
promotionCodeReq.setSceneId(1);
|
||||||
request.setPromotionCodeReq(promotionCodeReq);
|
request.setPromotionCodeReq(promotionCodeReq);
|
||||||
request.setVersion("1.0");
|
request.setVersion("1.0");
|
||||||
UnionOpenPromotionBysubunionidGetResponse response = client.execute(request);
|
UnionOpenPromotionBysubunionidGetResponse response = null;
|
||||||
|
try {
|
||||||
|
response = client.execute(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {
|
* {
|
||||||
@@ -597,10 +598,11 @@ public class JDUtil {
|
|||||||
// return response;
|
// return response;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public void handleUserInteraction(String fromWxid, String message) {
|
private void handleUserInteraction(String fromWxid, String message) {
|
||||||
String key = INTERACTION_STATE_PREFIX + fromWxid;
|
String key = INTERACTION_STATE_PREFIX + fromWxid;
|
||||||
String stateJson = redisTemplate.opsForValue().get(key);
|
String stateJson = redisTemplate.opsForValue().get(key);
|
||||||
UserInteractionState state;
|
UserInteractionState state;
|
||||||
|
|
||||||
if (stateJson == null) {
|
if (stateJson == null) {
|
||||||
state = new UserInteractionState();
|
state = new UserInteractionState();
|
||||||
logger.debug("New interaction state created for user: {}", fromWxid);
|
logger.debug("New interaction state created for user: {}", fromWxid);
|
||||||
@@ -620,30 +622,64 @@ public class JDUtil {
|
|||||||
state = new UserInteractionState();
|
state = new UserInteractionState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.updateLastInteractionTime();
|
state.updateLastInteractionTime();
|
||||||
|
|
||||||
switch (state.getCurrentState()) {
|
switch (state.getCurrentState()) {
|
||||||
case INIT:
|
case INIT:
|
||||||
if ("礼金".equals(message)) {
|
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(GIFT_MONEY_FLOW);
|
state.setCurrentState(GIFT_MONEY_FLOW);
|
||||||
state.setCurrentStep(STEP_PRODUCT_LINK);
|
state.setCurrentStep(STEP_PRODUCT_LINK);
|
||||||
wxUtil.sendTextMessage(fromWxid, "请输入商品链接:", 1, fromWxid);
|
wxUtil.sendTextMessage(fromWxid, "请输入商品链接:", 1, fromWxid);
|
||||||
logger.info("进入礼金开通流程 - 商品链接步骤");
|
logger.info("进入礼金开通流程 - 商品链接步骤");
|
||||||
}
|
} else if ("登记".equals(message)) {
|
||||||
if ("登记".equals(message)) {
|
|
||||||
// 开始登记新的订单
|
|
||||||
state.setCurrentState(DISINFECTANT_CABINET);
|
state.setCurrentState(DISINFECTANT_CABINET);
|
||||||
state.setCurrentField("orderId");
|
state.setCurrentField("orderId");
|
||||||
wxUtil.sendTextMessage(fromWxid, "请输入订单号:", 1, fromWxid);
|
wxUtil.sendTextMessage(fromWxid, "请输入订单号:", 1, fromWxid);
|
||||||
logger.debug("User {} entered DISINFECTANT_CABINET state", fromWxid);
|
logger.debug("User {} entered DISINFECTANT_CABINET state", fromWxid);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PRODUCT_PROMOTION:
|
||||||
|
if ("content".equals(state.getCurrentField())) {
|
||||||
|
// 第一次输入文案
|
||||||
|
state.getCollectedFields().put("content", message);
|
||||||
|
state.setCurrentField("option");
|
||||||
|
wxUtil.sendTextMessage(fromWxid, "请选择操作:\n回复 1 - 需要图片和 SKU 名称\n回复 2 - 仅进行转链", 1, fromWxid);
|
||||||
|
logger.info("转链流程 - 等待用户选择操作");
|
||||||
|
} else if ("option".equals(state.getCurrentField())) {
|
||||||
|
// 第二次选择操作
|
||||||
|
if ("1".equals(message)) {
|
||||||
|
// 需要图片和 SKU 名称
|
||||||
|
String content = state.getCollectedFields().get("content");
|
||||||
|
String result = generatePromotionContent(content, true);
|
||||||
|
wxUtil.sendTextMessage(fromWxid, "处理结果:\n" + result, 1, fromWxid);
|
||||||
|
state.reset();
|
||||||
|
} else if ("2".equals(message)) {
|
||||||
|
// 仅进行转链
|
||||||
|
String content = state.getCollectedFields().get("content");
|
||||||
|
String result = generatePromotionContent(content, false);
|
||||||
|
wxUtil.sendTextMessage(fromWxid, "处理结果:\n" + result, 1, fromWxid);
|
||||||
|
state.reset();
|
||||||
|
} else {
|
||||||
|
wxUtil.sendTextMessage(fromWxid, "无效的选择,请重新输入:\n回复 1 - 需要图片和 SKU 名称\n回复 2 - 仅进行转链", 1, fromWxid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case GIFT_MONEY_FLOW:
|
case GIFT_MONEY_FLOW:
|
||||||
handleGiftMoneyFlow(fromWxid, message, state);
|
handleGiftMoneyFlow(fromWxid, message, state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRODUCT_ORDER_REGISTRATION:
|
case PRODUCT_ORDER_REGISTRATION:
|
||||||
handleProductOrderRegistration(fromWxid, message, state);
|
handleProductOrderRegistration(fromWxid, message, state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxUtil.sendTextMessage(fromWxid, "无效的状态,请重新开始对话", 1, fromWxid);
|
wxUtil.sendTextMessage(fromWxid, "无效的状态,请重新开始对话", 1, fromWxid);
|
||||||
state.setCurrentState(INIT);
|
state.setCurrentState(INIT);
|
||||||
@@ -657,7 +693,8 @@ public class JDUtil {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Error saving interaction state: {}", e.getMessage());
|
logger.error("Error saving interaction state: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 新增礼金流程处理方法
|
// 新增礼金流程处理方法
|
||||||
private void handleGiftMoneyFlow(String fromWxid, String message, UserInteractionState state) {
|
private void handleGiftMoneyFlow(String fromWxid, String message, UserInteractionState state) {
|
||||||
@@ -762,22 +799,20 @@ public class JDUtil {
|
|||||||
state.reset();
|
state.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* 生成转链和文案的方法
|
* 生成转链和文案的方法
|
||||||
*
|
*
|
||||||
* @param message 文案内容,包含商品链接
|
* @param message 文案内容,包含商品链接
|
||||||
* @return 处理后的文案,附带商品信息
|
* @return 处理后的文案,附带商品信息
|
||||||
*/
|
*/
|
||||||
public String generatePromotionContent(String message,Boolean needImagesAndSkuName) {
|
public String generatePromotionContent(String message, Boolean needImagesAndSkuName) {
|
||||||
// 提取文案中的所有 u.jd.com 链接
|
// 提取文案中的所有 u.jd.com 链接
|
||||||
List<String> urls = extractUJDUrls(message);
|
List<String> urls = extractUJDUrls(message);
|
||||||
if (urls.isEmpty()) {
|
if (urls.isEmpty()) {
|
||||||
return "文案中未找到有效的商品链接,请检查格式是否正确。\n" + message;
|
return "文案中未找到有效的商品链接,请检查格式是否正确。\n" + message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 存储解析后的商品信息
|
|
||||||
StringBuilder enrichedContent = new StringBuilder();
|
|
||||||
enrichedContent.append("✨ 商品推广文案:\n\n").append(message).append("\n\n");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {
|
* {
|
||||||
@@ -1015,6 +1050,28 @@ public String generatePromotionContent(String message,Boolean needImagesAndSkuNa
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
// 如果需要图片和SKU名称,则代表要把图片下载发过去,还有对应的skuName
|
||||||
|
StringBuilder enrichedContent = new StringBuilder();
|
||||||
|
ArrayList<HashMap<String, String>> resultList = new ArrayList<>();
|
||||||
|
for (String url : urls) {
|
||||||
|
try {
|
||||||
|
// 查询商品信息
|
||||||
|
GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url);
|
||||||
|
if (productInfo == null || productInfo.getCode() != 200) {
|
||||||
|
enrichedContent.append("商品链接查询失败:").append(url).append("\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
long totalCount = productInfo.getTotalCount();
|
||||||
|
HashMap<String, String> itemMap = new HashMap<>();
|
||||||
|
itemMap.put("url", url);
|
||||||
|
|
||||||
|
if (totalCount == 0) {
|
||||||
|
itemMap.put("type", "coupon");
|
||||||
|
} else {
|
||||||
|
itemMap.put("type", "goods");
|
||||||
|
//itemMap.put("data", JSONObject.toJSONString(productInfo.getData()));
|
||||||
|
|
||||||
//"materialUrl": "jingfen.jd.com/detail/BsrqLq5CfIziE7BSl3ItPp8q_3DFaNVYJqfkRRLc7HR.html",
|
//"materialUrl": "jingfen.jd.com/detail/BsrqLq5CfIziE7BSl3ItPp8q_3DFaNVYJqfkRRLc7HR.html",
|
||||||
//"oriItemId": "BMrqLq5CfIz9X04KC3ItPp8q_3DFaNVYJqfkRRLc7HR",
|
//"oriItemId": "BMrqLq5CfIz9X04KC3ItPp8q_3DFaNVYJqfkRRLc7HR",
|
||||||
//"owner": "g",
|
//"owner": "g",
|
||||||
@@ -1026,25 +1083,13 @@ public String generatePromotionContent(String message,Boolean needImagesAndSkuNa
|
|||||||
//},
|
//},
|
||||||
//"skuName": "松下(Panasonic)白月光4.0Ultra 洗烘套装 10kg滚筒洗衣机+变频热泵烘干机 除毛升级2.0 水氧SPA护理 8532N+8532NR",
|
//"skuName": "松下(Panasonic)白月光4.0Ultra 洗烘套装 10kg滚筒洗衣机+变频热泵烘干机 除毛升级2.0 水氧SPA护理 8532N+8532NR",
|
||||||
//"spuid": 100137629936,
|
//"spuid": 100137629936,
|
||||||
ArrayList<HashMap<String, String>> resultList = new ArrayList<>();
|
itemMap.put("materialUrl", productInfo.getData()[0].getMaterialUrl());
|
||||||
for (String url : urls) {
|
itemMap.put("oriItemId", productInfo.getData()[0].getOriItemId());
|
||||||
try {
|
itemMap.put("owner", productInfo.getData()[0].getOwner());
|
||||||
// 查询商品信息
|
itemMap.put("shopId", String.valueOf(productInfo.getData()[0].getShopInfo().getShopId()));
|
||||||
GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url);
|
itemMap.put("shopName", productInfo.getData()[0].getShopInfo().getShopName());
|
||||||
if (productInfo == null || productInfo.getCode() != 200) {
|
itemMap.put("skuName", productInfo.getData()[0].getSkuName());
|
||||||
enrichedContent.append("⚠️ 商品链接查询失败:").append(url).append("\n");
|
itemMap.put("spuid", String.valueOf(productInfo.getData()[0].getSpuid()));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long totalCount = productInfo.getTotalCount();
|
|
||||||
HashMap<String, String> itemMap = new HashMap<>();
|
|
||||||
itemMap.put("url", url);
|
|
||||||
|
|
||||||
if (totalCount == 0) {
|
|
||||||
itemMap.put("type", "coupon");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
itemMap.put("type", "goods");
|
|
||||||
itemMap.put("data", JSONObject.toJSONString(productInfo.getData()));
|
|
||||||
}
|
}
|
||||||
resultList.add(itemMap);
|
resultList.add(itemMap);
|
||||||
|
|
||||||
@@ -1053,17 +1098,33 @@ public String generatePromotionContent(String message,Boolean needImagesAndSkuNa
|
|||||||
enrichedContent.append("❌ 处理商品链接时发生异常:").append(url).append("\n");
|
enrichedContent.append("❌ 处理商品链接时发生异常:").append(url).append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (resultList.isEmpty()){
|
||||||
|
enrichedContent.append("❌ 处理商品链接时发生异常:").append("\n");
|
||||||
|
return enrichedContent.toString();
|
||||||
|
}
|
||||||
|
if(!needImagesAndSkuName){
|
||||||
|
// 完成转链后替换链接为u.jd.com链接,文案不修改就返回
|
||||||
|
for (HashMap<String, String> stringStringHashMap : resultList) {
|
||||||
|
String url = stringStringHashMap.get("url");
|
||||||
|
String transferUrl = transfer(url);
|
||||||
|
stringStringHashMap.put("transferUrl", transferUrl);
|
||||||
|
message = message.replace(url, transferUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//enrichedContent.append("商品推广文案:\n\n").append(message).append("\n\n");
|
||||||
|
|
||||||
|
|
||||||
return enrichedContent.toString();
|
return enrichedContent.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提取文案中的所有 u.jd.com 链接
|
* 提取文案中的所有 u.jd.com 链接
|
||||||
*
|
*
|
||||||
* @param message 文案内容
|
* @param message 文案内容
|
||||||
* @return 包含所有 u.jd.com 链接的列表
|
* @return 包含所有 u.jd.com 链接的列表
|
||||||
*/
|
*/
|
||||||
private List<String> extractUJDUrls(String message) {
|
private List<String> extractUJDUrls(String message) {
|
||||||
List<String> urls = new ArrayList<>();
|
List<String> urls = new ArrayList<>();
|
||||||
Pattern pattern = Pattern.compile("https://u\\.jd\\.com/[^\\s]+");
|
Pattern pattern = Pattern.compile("https://u\\.jd\\.com/[^\\s]+");
|
||||||
Matcher matcher = pattern.matcher(message);
|
Matcher matcher = pattern.matcher(message);
|
||||||
@@ -1073,13 +1134,12 @@ private List<String> extractUJDUrls(String message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过这个可以将u.jd.*** 查询到对应的商品信息 和 商品图片,甚至可以查询到是不是自营的商品
|
* 通过这个可以将u.jd.*** 查询到对应的商品信息 和 商品图片,甚至可以查询到是不是自营的商品
|
||||||
*
|
*/
|
||||||
* */
|
|
||||||
public UnionOpenGoodsQueryResponse getUnionOpenGoodsQueryRequest(String uJDUrl) throws Exception {
|
public UnionOpenGoodsQueryResponse getUnionOpenGoodsQueryRequest(String uJDUrl) throws Exception {
|
||||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_APP_KEY_WZ);
|
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_APP_KEY_WZ);
|
||||||
|
|
||||||
@@ -1153,7 +1213,7 @@ private List<String> extractUJDUrls(String message) {
|
|||||||
|
|
||||||
|
|
||||||
// 新增礼金创建方法
|
// 新增礼金创建方法
|
||||||
public String createGiftCoupon(String skuId, double amount, int quantity, String owner) throws Exception {
|
public String createGiftCoupon(String skuId, double amount, int quantity, String owner) throws Exception {
|
||||||
logger.debug("准备创建礼金:SKU={}, 金额={}元,数量={}, Owner={}", skuId, amount, quantity, owner);
|
logger.debug("准备创建礼金:SKU={}, 金额={}元,数量={}, Owner={}", skuId, amount, quantity, owner);
|
||||||
|
|
||||||
// 参数校验
|
// 参数校验
|
||||||
@@ -1209,7 +1269,7 @@ public String createGiftCoupon(String skuId, double amount, int quantity, String
|
|||||||
logger.error("礼金创建失败:错误码={}, 错误信息={}", response.getCode(), response.getMsg());
|
logger.error("礼金创建失败:错误码={}, 错误信息={}", response.getCode(), response.getMsg());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 修改activateGiftMoney方法调用真实接口
|
// 修改activateGiftMoney方法调用真实接口
|
||||||
@@ -1389,7 +1449,7 @@ public String createGiftCoupon(String skuId, double amount, int quantity, String
|
|||||||
|
|
||||||
// 推荐使用枚举管理状态
|
// 推荐使用枚举管理状态
|
||||||
public enum ProcessState {
|
public enum ProcessState {
|
||||||
INIT, GIFT_MONEY_FLOW, DISINFECTANT_CABINET, PRODUCT_ORDER_REGISTRATION
|
INIT, GIFT_MONEY_FLOW, DISINFECTANT_CABINET, PRODUCT_ORDER_REGISTRATION,PRODUCT_PROMOTION
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum GiftMoneyStep {
|
public enum GiftMoneyStep {
|
||||||
|
|||||||
Reference in New Issue
Block a user