1
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
package cn.van.business.controller.jd;
|
||||
|
||||
import cn.van.business.controller.wx.WXListener;
|
||||
import cn.van.business.util.JDProductService;
|
||||
import cn.van.business.util.JDUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -19,7 +23,11 @@ import java.util.List;
|
||||
@Controller
|
||||
@RequestMapping("/jd")
|
||||
@RestController
|
||||
@Slf4j
|
||||
public class JDInnerController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JDInnerController.class);
|
||||
|
||||
|
||||
private final static String skey = "2192057370ef8140c201079969c956a3";
|
||||
private boolean checkSkey(String skey) {
|
||||
return skey.equals(this.skey);
|
||||
@@ -32,7 +40,8 @@ public class JDInnerController {
|
||||
}
|
||||
|
||||
@RequestMapping("/generatePromotionContent")
|
||||
public HashMap<String, List<String>> generatePromotionContent(String message) {
|
||||
public HashMap<String, List<String>> generatePromotionContent(String message,String skey) {
|
||||
loo
|
||||
if (!checkSkey(skey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
408
src/main/java/cn/van/business/util/JDProductService.java
Normal file
408
src/main/java/cn/van/business/util/JDProductService.java
Normal file
@@ -0,0 +1,408 @@
|
||||
package cn.van.business.util;
|
||||
|
||||
import cn.van.business.model.cj.XbMessage;
|
||||
import cn.van.business.model.cj.XbMessageItem;
|
||||
import cn.van.business.repository.XbMessageItemRepository;
|
||||
import cn.van.business.repository.XbMessageRepository;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
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.GoodsService.request.query.GoodsReq;
|
||||
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.promotionbysubunioni.PromotionService.request.get.PromotionCodeReq;
|
||||
import com.jd.open.api.sdk.request.kplunion.UnionOpenCouponGiftGetRequest;
|
||||
import com.jd.open.api.sdk.request.kplunion.UnionOpenGoodsQueryRequest;
|
||||
import com.jd.open.api.sdk.request.kplunion.UnionOpenPromotionBysubunionidGetRequest;
|
||||
import com.jd.open.api.sdk.response.kplunion.UnionOpenCouponGiftGetResponse;
|
||||
import com.jd.open.api.sdk.response.kplunion.UnionOpenGoodsQueryResponse;
|
||||
import com.jd.open.api.sdk.response.kplunion.UnionOpenPromotionBysubunionidGetResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static cn.van.business.util.JDUtil.*;
|
||||
|
||||
/**
|
||||
* 京东商品服务类,抽取来源于JDUtil
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class JDProductService {
|
||||
|
||||
// 京东开放平台配置
|
||||
private static final String LPF_APP_KEY_WZ = "98e21c89ae5610240ec3f5f575f86a59";
|
||||
private static final String LPF_SECRET_KEY_WZ = "3dcb6b23a1104639ac433fd07adb6dfb";
|
||||
private static final String SERVER_URL = "https://api.jd.com/routerjson";
|
||||
private static final String ACCESS_TOKEN = "";
|
||||
private static final Logger logger = LoggerFactory.getLogger(JDProductService.class);
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final XbMessageRepository xbMessageRepository;
|
||||
private final XbMessageItemRepository xbMessageItemRepository;
|
||||
@Autowired
|
||||
public JDProductService(StringRedisTemplate redisTemplate, XbMessageRepository xbMessageRepository, XbMessageItemRepository xbMessageItemRepository) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.xbMessageRepository = xbMessageRepository;
|
||||
this.xbMessageItemRepository = xbMessageItemRepository;
|
||||
}
|
||||
/**
|
||||
* 生成转链和方案的方法
|
||||
*
|
||||
* @param message 方案内容,包含商品链接
|
||||
* @param fromWxid
|
||||
* @return 处理后的方案,附带商品信息
|
||||
*/
|
||||
public synchronized HashMap<String, List<String>> generatePromotionContent(String message) {
|
||||
HashMap<String, List<String>> finallyMessage = new HashMap<>();
|
||||
List<String> textList = new ArrayList<>();
|
||||
List<String> imagesList = new ArrayList<>();
|
||||
List<String> dataList = new ArrayList<>();
|
||||
// 最终的方案
|
||||
List<String> finalWenAn = new ArrayList<>();
|
||||
// 提取方案中的所有 u.jd.com 链接
|
||||
List<String> urlList = new ArrayList<>();
|
||||
List<String> priceList = new ArrayList<>();
|
||||
|
||||
// 提取方案中的所有 u.jd.com 链接
|
||||
List<String> urls = extractUJDUrls(message);
|
||||
if (urls.isEmpty()) {
|
||||
textList.add("方案中未找到有效的商品链接,请检查格式是否正确。");
|
||||
finallyMessage.put("text", textList);
|
||||
return finallyMessage;
|
||||
}
|
||||
|
||||
|
||||
// 如果需要图片和SKU名称,则代表要把图片下载发过去,还有对应的skuName
|
||||
StringBuilder couponInfo = null;
|
||||
ArrayList<HashMap<String, String>> resultList = new ArrayList<>();
|
||||
|
||||
String format = null;
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
|
||||
|
||||
for (String url : urls) {
|
||||
try {
|
||||
// 重置。不然会一直追加文本内容
|
||||
couponInfo = new StringBuilder();
|
||||
// 新建格式好日期
|
||||
format = dateFormat.format(new Date());
|
||||
// 查询商品信息
|
||||
GoodsQueryResult productInfo = queryProductInfoByUJDUrl(url);
|
||||
if (productInfo == null || productInfo.getCode() != 200) {
|
||||
couponInfo.append("链接查询失败:").append(url).append("\n");
|
||||
continue;
|
||||
}
|
||||
long totalCount = productInfo.getTotalCount();
|
||||
if (totalCount == 0) {
|
||||
//couponInfo.append("链接类型:优惠券\n\n");
|
||||
} else {
|
||||
couponInfo.append(url).append("\n");
|
||||
urlList.add(url);
|
||||
couponInfo.append("链接类型:商品\n\n");
|
||||
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(productInfo.getData()[0]));
|
||||
jsonObject.put("url", url);
|
||||
dataList.add(jsonObject.toString());
|
||||
|
||||
HashMap<String, String> itemMap = new HashMap<>();
|
||||
itemMap.put("url", url);
|
||||
itemMap.put("materialUrl", productInfo.getData()[0].getMaterialUrl());
|
||||
itemMap.put("oriItemId", productInfo.getData()[0].getOriItemId());
|
||||
itemMap.put("owner", productInfo.getData()[0].getOwner());
|
||||
itemMap.put("shopId", String.valueOf(productInfo.getData()[0].getShopInfo().getShopId()));
|
||||
itemMap.put("shopName", productInfo.getData()[0].getShopInfo().getShopName());
|
||||
itemMap.put("skuName", productInfo.getData()[0].getSkuName());
|
||||
String replaceAll = itemMap.get("skuName").replaceAll("以旧|政府|换新|领取|国家|补贴|15%|20%|国补|立减|【|】", "");
|
||||
itemMap.put("spuid", String.valueOf(productInfo.getData()[0].getSpuid()));
|
||||
itemMap.put("commission", String.valueOf(productInfo.getData()[0].getCommissionInfo().getCommission()));
|
||||
itemMap.put("commissionShare", String.valueOf(productInfo.getData()[0].getCommissionInfo().getCommissionShare()));
|
||||
//for (HashMap.Entry<String, String> entry : itemMap.entrySet()) {
|
||||
//couponInfo.append(" ").append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
|
||||
//}
|
||||
couponInfo.append("店铺: ").append(itemMap.get("shopName")).append("\n").append("标题: ").append(replaceAll).append("\n").append("自营 POP: ").append(itemMap.get("owner").equals("g") ? " 自营 " : " POP ").append("\n").append("佣金比例: ").append(itemMap.get("commissionShare")).append("\n").append("佣金: ").append(itemMap.get("commission")).append("\n");
|
||||
|
||||
|
||||
//StringBuilder images = new StringBuilder();
|
||||
if (productInfo.getData()[0].getImageInfo() != null) {
|
||||
//images.append(" ").append("图片信息:\n");
|
||||
//int index = 1;
|
||||
|
||||
for (UrlInfo image : productInfo.getData()[0].getImageInfo().getImageList()) {
|
||||
//images.append("图片 ").append(index++).append("\n").append(image.getUrl()).append("\n");
|
||||
imagesList.add(image.getUrl());
|
||||
}
|
||||
}
|
||||
//textList.add(String.valueOf(images));
|
||||
resultList.add(itemMap);
|
||||
String title = "";
|
||||
|
||||
|
||||
try {
|
||||
if (!message.equals(url)) {
|
||||
String[] lines = message.split("\\r?\\n");
|
||||
if (lines.length > 0) {
|
||||
title = lines[0];
|
||||
// 有的换行了
|
||||
if (lines[1].length() > 3 && !lines[1].contains("u.jd")) {
|
||||
title = title + lines[1];
|
||||
}
|
||||
logger.info("文案首行 {}", title);
|
||||
title = title.replaceAll("@|所有人", "");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("文案首行异常", e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*直接生成闲鱼的商品文案*/
|
||||
StringBuilder sb1 = new StringBuilder();
|
||||
|
||||
sb1.append("(标价到手) ").append(title).append(replaceAll).append("\n").append(WENAN_FANAN_LQD.replaceAll("更新", format + "更新"));
|
||||
//textList.add("闲鱼方案的文案:\n");
|
||||
textList.add(String.valueOf(sb1));
|
||||
StringBuilder sb2 = new StringBuilder();
|
||||
sb2.append("(一键代下) ").append(title).append(replaceAll).append("\n").append(WENAN_ZCXS);
|
||||
//textList.add("闲鱼正常销售:\n");
|
||||
textList.add(String.valueOf(sb2));
|
||||
StringBuilder sb3 = new StringBuilder();
|
||||
sb3.append("(标价到手) ").append(title).append(replaceAll).append("\n").append(WENAN_FANAN_HG.replaceAll("更新", format + "更新"));
|
||||
textList.add(String.valueOf(sb3));
|
||||
|
||||
StringBuilder sb4 = new StringBuilder();
|
||||
sb4.append("【教你下单】 ").append(title).append(replaceAll).append("\n").append(WENAN_FANAN_BX.replaceAll("信息更新日期:", "信息更新日期:" + format));
|
||||
textList.add(String.valueOf(sb4));
|
||||
}
|
||||
|
||||
|
||||
textList.add(String.valueOf(couponInfo));
|
||||
finallyMessage.put("data", dataList);
|
||||
finallyMessage.put("urlList", urlList);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("处理商品链接时发生异常:{}", url, e);
|
||||
couponInfo.append(" 处理商品链接时发生异常:").append(url).append("\n");
|
||||
textList.add(String.valueOf(couponInfo));
|
||||
finallyMessage.put("text", textList);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 因为在这里转链返回,没有什么意义,后面走转链不转链,会重新发方案
|
||||
* */
|
||||
StringBuilder wenan = new StringBuilder();
|
||||
|
||||
wenan = new StringBuilder().append(format).append(FANAN_COMMON).append(message);
|
||||
|
||||
|
||||
finalWenAn.add(String.valueOf(wenan));
|
||||
|
||||
finallyMessage.put("text", textList);
|
||||
finallyMessage.put("images", imagesList);
|
||||
finallyMessage.put("finalWenAn", finalWenAn);
|
||||
|
||||
return finallyMessage;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询商品信息
|
||||
*
|
||||
* @param uJDUrl 京东商品链接
|
||||
* @return 商品查询结果
|
||||
* @throws Exception 查询异常
|
||||
*/
|
||||
public GoodsQueryResult queryProductInfoByUJDUrl(String uJDUrl) throws Exception {
|
||||
UnionOpenGoodsQueryResponse response = getUnionOpenGoodsQueryRequest(uJDUrl);
|
||||
if (response == null || response.getQueryResult() == null) {
|
||||
return null;
|
||||
}
|
||||
GoodsQueryResult queryResult = response.getQueryResult();
|
||||
if (queryResult.getCode() != 200) {
|
||||
return null;
|
||||
}
|
||||
return queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用京东开放平台接口查询商品信息
|
||||
*
|
||||
* @param uJDUrl 京东商品链接
|
||||
* @return 京东商品查询响应
|
||||
* @throws Exception 查询异常
|
||||
*/
|
||||
public UnionOpenGoodsQueryResponse getUnionOpenGoodsQueryRequest(String uJDUrl) throws Exception {
|
||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ);
|
||||
|
||||
UnionOpenGoodsQueryRequest request = new UnionOpenGoodsQueryRequest();
|
||||
GoodsReq goodsReq = new GoodsReq();
|
||||
goodsReq.setKeyword(uJDUrl);
|
||||
goodsReq.setSceneId(1);
|
||||
request.setGoodsReqDTO(goodsReq);
|
||||
request.setVersion("1.0");
|
||||
request.setSignmethod("md5");
|
||||
|
||||
// 时间戳,格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8
|
||||
Date date = new Date();
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
request.setTimestamp(simpleDateFormat.format(date));
|
||||
|
||||
UnionOpenGoodsQueryResponse execute = client.execute(request);
|
||||
return execute;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建礼金
|
||||
*
|
||||
* @param skuId 商品SKU ID
|
||||
* @param amount 礼金金额
|
||||
* @param quantity 礼金数量
|
||||
* @param owner 商品所有者(g:自营, pop:POP商家)
|
||||
* @param skuName 商品名称
|
||||
* @return 礼金Key
|
||||
* @throws Exception 创建异常
|
||||
*/
|
||||
public String createGiftCoupon(String skuId, double amount, int quantity, String owner, String skuName) throws Exception {
|
||||
log.debug("准备创建礼金:SKU={}, 金额={}元,数量={}, Owner={}", skuId, amount, quantity, owner);
|
||||
|
||||
// 参数校验
|
||||
if (skuId == null || amount <= 0 || quantity <= 0) {
|
||||
log.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");
|
||||
|
||||
log.debug("请求参数:{}", JSON.toJSONString(request));
|
||||
|
||||
UnionOpenCouponGiftGetResponse response = client.execute(request);
|
||||
log.debug("API响应:{}", JSON.toJSONString(response));
|
||||
|
||||
if ("0".equals(response.getCode()) && response.getGetResult().getCode() == 200) {
|
||||
String giftKey = response.getGetResult().getData().getGiftCouponKey();
|
||||
log.debug("礼金创建成功:批次ID={}, 返回数据:{}", giftKey, response.getGetResult().getData());
|
||||
return giftKey;
|
||||
} else {
|
||||
log.error("礼金创建失败:错误码={}, 错误信息={}", response.getCode(), response.getMsg());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转链接口:通过商品链接、领券链接、活动链接获取普通推广链接或优惠券二合一推广链接
|
||||
*
|
||||
* @param url 原始链接
|
||||
* @param giftCouponKey 礼金Key(可选)
|
||||
* @return 转换后的短链接
|
||||
*/
|
||||
public String transfer(String url, String giftCouponKey) {
|
||||
JdClient client = new DefaultJdClient(SERVER_URL, ACCESS_TOKEN, LPF_APP_KEY_WZ, LPF_SECRET_KEY_WZ);
|
||||
|
||||
UnionOpenPromotionBysubunionidGetRequest request = new UnionOpenPromotionBysubunionidGetRequest();
|
||||
PromotionCodeReq promotionCodeReq = new PromotionCodeReq();
|
||||
promotionCodeReq.setSceneId(1);
|
||||
promotionCodeReq.setMaterialId(url);
|
||||
|
||||
if (giftCouponKey != null) {
|
||||
promotionCodeReq.setGiftCouponKey(giftCouponKey);
|
||||
}
|
||||
|
||||
request.setPromotionCodeReq(promotionCodeReq);
|
||||
request.setVersion("1.0");
|
||||
|
||||
UnionOpenPromotionBysubunionidGetResponse response;
|
||||
try {
|
||||
response = client.execute(request);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
String result = "";
|
||||
if (response != null) {
|
||||
if ("0".equals(response.getCode()) && response.getGetResult().getCode() == 200) {
|
||||
result = response.getGetResult().getData().getShortURL();
|
||||
}
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将礼金信息写入Redis
|
||||
*
|
||||
* @param skuId 商品SKU ID
|
||||
* @param giftKey 礼金Key
|
||||
* @param skuName 商品名称
|
||||
* @param owner 商品所有者
|
||||
*/
|
||||
public void saveGiftCouponToRedis(String skuId, String giftKey, String skuName, String owner) {
|
||||
String key = "gift_coupon:" + skuId;
|
||||
String hashKey = giftKey;
|
||||
LocalDateTime expireTime = LocalDateTime.now().plus("g".equals(owner) ? 1 : 7, TimeUnit.DAYS.toChronoUnit());
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("giftKey", giftKey);
|
||||
data.put("skuName", skuName);
|
||||
data.put("owner", owner);
|
||||
data.put("expireTime", expireTime.format(DateTimeFormatter.ISO_DATE_TIME));
|
||||
|
||||
// 存入 Redis Hash
|
||||
redisTemplate.opsForHash().put(key, hashKey, JSON.toJSONString(data));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user