评论+ds
This commit is contained in:
@@ -3,6 +3,7 @@ package cn.van.business.util;
|
||||
|
||||
import cn.van.business.model.jd.OrderRow;
|
||||
import cn.van.business.repository.OrderRowRepository;
|
||||
import cn.van.business.util.ds.DeepSeekClientUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
@@ -30,6 +31,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
@@ -76,6 +78,8 @@ public class JDUtil {
|
||||
private static final String ACCESS_TOKEN = "";
|
||||
private static final Logger logger = LoggerFactory.getLogger(JDUtil.class);
|
||||
private static final String INTERACTION_STATE_PREFIX = "interaction_state:";
|
||||
private static final String COMMENT_TEMPLATES = "comment_templates";
|
||||
private static final String COMMENT_TEMPLATES_DS = "我需要为我的商品模拟一些商品评论。你协助我生成评价内容,100字以内即可。我会为你提供其他真实用户的评论:";
|
||||
private static final long TIMEOUT_MINUTES = 10;
|
||||
private static final String WENAN_FANAN_LQD = "提供方法自己下单\n" + "全程都是自己的账号下单\n" + "标价就是下单的到手价\n" + "本人有耐心,会一步一步提供教程\n" + "以后有什么质量问题都是用自己的账号走京东售后\n" + "\n" + "更新\n" + "\n" + "用你自己的账号下单\n" + "官方店铺 提供方法自己下单\n" + "——————————————————————————————————————————\n" + "同行可长久合作,可提供神级家电线报\n" + "\n" + "配合家电线报可以自己下单,不用找代购和代下,订单和利润都掌握在自己手中。\n" + "\n" + "一次入会永久使用,包含家电帮,雷神价,韭菜帮,河南&湖南帮,各种暗号帮后返等内部独家家电线报\n" + "\n" + "JD采销采购不定时发放独家优惠券\n" + "\n" + "基本上你能看到的京东家电低价都是从这些渠道里面出来。\n" + "\n" + "2025年家电项目新方向,配合家电线报下单,秒省1K+。";
|
||||
private static final String WENAN_FANAN_HG = "手把手教你实现超值下单,无需依赖他人!全程使用个人专属账号操作,所见即所得,页面标价即为最终到手价。别担心操作难题,我会全程贴心指导,每一步都细致讲解,助你轻松下单。后续若出现任何质量问题,凭借个人账号就能直接对接JD官方售后,售后无忧。\n" + "更新\n" + "采用自主账号下单模式,官方店铺商品随心购,专业方法全程提供!\n" + "——————————————————————————————————————————\n" + "诚邀同行建立长期合作关系,海量独家家电优惠线报倾囊相授!\n" + "借助这些优质家电线报,无需寻求代购代下服务,自己就能轻松下单,订单信息与收益牢牢掌握在手中。\n" + "一次加入,终身受益!涵盖家电帮、雷神价、韭菜帮、河南 & 湖南帮等众多渠道,还有各类暗号帮后返等内部专属家电优惠信息一网打尽。\n" + "JD采销团队会不定时发放独家隐藏优惠券,市面上那些令人心动的JD家电低价好物,大多都源自这些渠道!\n" + "2025 年家电选购新趋势,依托线报下单,轻松省下千元开支,开启超值购物之旅!";
|
||||
@@ -102,6 +106,7 @@ public class JDUtil {
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final OrderRowRepository orderRowRepository;
|
||||
private final OrderUtil orderUtil;
|
||||
private final DeepSeekClientUtil deepSeekClientUtil;
|
||||
// 添加ObjectMapper来序列化和反序列化UserInteractionState
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final ConcurrentHashMap<String, UserInteractionState> userInteractionStates = new ConcurrentHashMap<>();
|
||||
@@ -109,11 +114,12 @@ public class JDUtil {
|
||||
|
||||
// 构造函数中注入StringRedisTemplate
|
||||
@Autowired
|
||||
public JDUtil(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil) {
|
||||
public JDUtil(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, WXUtil wxUtil, OrderUtil orderUtil, DeepSeekClientUtil deepSeekClientUtil) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.orderRowRepository = orderRowRepository;
|
||||
this.wxUtil = wxUtil;
|
||||
this.orderUtil = orderUtil;
|
||||
this.deepSeekClientUtil = deepSeekClientUtil;
|
||||
}
|
||||
|
||||
private List<OrderRow> filterOrdersByDate(List<OrderRow> orderRows, int daysBack) {
|
||||
@@ -1615,7 +1621,6 @@ public class JDUtil {
|
||||
// 设置当前状态为生成评论流程
|
||||
state.setCurrentState(UserInteractionState.ProcessState.COMMENT_GENERATION);
|
||||
state.setCurrentField("commentTypeSelection");
|
||||
|
||||
// 提示用户选择评论类型
|
||||
wxUtil.sendTextMessage(fromWxid, "请选择要生成的评论类型:\n回复 1 - 消毒柜评论\n回复 2 - 油烟机评论", 1, fromWxid, false);
|
||||
logger.info("进入生成评论流程 - 用户: {}", fromWxid);
|
||||
@@ -1637,7 +1642,16 @@ public class JDUtil {
|
||||
* 处理生成评论流程中的用户交互
|
||||
*/
|
||||
private void handleCommentInteraction(String fromWxid, String message, UserInteractionState state) {
|
||||
String key = INTERACTION_STATE_PREFIX + fromWxid;
|
||||
String superOrder = "";
|
||||
try {
|
||||
String[] split = message.split("/n");
|
||||
if (split.length != 0) {
|
||||
message = split[0];
|
||||
for (int i = 1; i < split.length; i++) {
|
||||
superOrder += split[i] + " ";
|
||||
}
|
||||
}
|
||||
} String key = INTERACTION_STATE_PREFIX + fromWxid;
|
||||
logger.info("处理生成评论流程中的用户交互 - 用户: {}, 状态: {}", fromWxid, state);
|
||||
try {
|
||||
// 检查当前状态是否为生成评论流程
|
||||
@@ -1648,10 +1662,16 @@ public class JDUtil {
|
||||
// 根据用户输入生成对应的评论
|
||||
switch (message) {
|
||||
case "1":
|
||||
generateComment(fromWxid, "消毒柜");
|
||||
generateComment(fromWxid, "1", superOrder);
|
||||
break;
|
||||
case "1+":
|
||||
generateComment(fromWxid, "1+", superOrder);
|
||||
break;
|
||||
case "2":
|
||||
generateComment(fromWxid, "油烟机");
|
||||
generateComment(fromWxid, "2", superOrder);
|
||||
break;
|
||||
case "2+":
|
||||
generateComment(fromWxid, "2+", superOrder);
|
||||
break;
|
||||
default:
|
||||
wxUtil.sendTextMessage(fromWxid, "无效的选择,请回复 1 或 2", 1, fromWxid, false);
|
||||
@@ -1670,15 +1690,33 @@ public class JDUtil {
|
||||
/**
|
||||
* 生成评论内容
|
||||
*/
|
||||
private void generateComment(String fromWxid, String productType) {
|
||||
// 这里可以调用缓存或AI生成文案,目前先返回固定模板
|
||||
String commentTemplate = "这是一条关于%s的评论:\n" + "1. 性能非常出色,使用体验极佳。\n" + "2. 安装方便,操作简单。\n" + "3. 售后服务到位,值得信赖。\n" + "感谢您的购买与支持!";
|
||||
|
||||
String comment = String.format(commentTemplate, productType);
|
||||
wxUtil.sendTextMessage(fromWxid, comment, 1, fromWxid, false);
|
||||
|
||||
// 重置状态
|
||||
resetState(fromWxid, loadOrCreateState(INTERACTION_STATE_PREFIX + fromWxid));
|
||||
private void generateComment(String fromWxid, String productType, String superOrder) {
|
||||
if (productType.equals("1") || productType.equals("2")) {
|
||||
// 这里可以调用缓存或AI生成文案,目前先返回固定模板
|
||||
//用redis的 list存放评论模板,
|
||||
List<String> commentTemplates = redisTemplate.opsForList().range(COMMENT_TEMPLATES + productType, 0, -1);
|
||||
if (commentTemplates == null || commentTemplates.isEmpty()) {
|
||||
wxUtil.sendTextMessage(fromWxid, "暂无评论模板,请先添加评论模板", 1, fromWxid, false);
|
||||
return;
|
||||
}
|
||||
String comment = commentTemplates.get(new Random().nextInt(commentTemplates.size()));
|
||||
String deepSeekResponse = "ds响应失败";
|
||||
try {
|
||||
deepSeekResponse = deepSeekClientUtil.getDeepSeekResponse(comment);
|
||||
} catch (IOException e) {
|
||||
logger.error("生成评论异常 - 用户: {}, ", fromWxid, e);
|
||||
}
|
||||
wxUtil.sendTextMessage(fromWxid, deepSeekResponse, 1, fromWxid, false);
|
||||
// 重置状态
|
||||
resetState(fromWxid, loadOrCreateState(INTERACTION_STATE_PREFIX + fromWxid));
|
||||
} else {
|
||||
if (!superOrder.isEmpty()) {
|
||||
superOrder = superOrder.replace("+", "");
|
||||
// 追加评论模板到redis
|
||||
redisTemplate.opsForList().leftPush(COMMENT_TEMPLATES + productType, superOrder);
|
||||
wxUtil.sendTextMessage(fromWxid, "评论模板添加成功", 1, fromWxid, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package cn.van.business.util.ds;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.Method;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class DeepSeekClientUtil {
|
||||
private static final String DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions"; // 确认 API 地址
|
||||
private static final String DEEPSEEK_API_KEY = "d99b8cc6b7414cc88a5d950a3ff7585e"; // 替换为你的密钥
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper(); // Jackson JSON 解析器
|
||||
|
||||
/**
|
||||
* 调用 DeepSeek API 并返回第一次回复的文本内容
|
||||
*
|
||||
* @param inputText 用户输入的文本
|
||||
* @return API 返回的第一个回复内容
|
||||
* @throws IOException 如果网络请求或 JSON 解析失败
|
||||
* @throws IllegalArgumentException 如果输入为空或过长
|
||||
*/
|
||||
public String getDeepSeekResponse(String inputText) throws IOException {
|
||||
// 1. 输入校验
|
||||
if (inputText == null || inputText.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("输入文本不能为空");
|
||||
}
|
||||
if (inputText.length() > 10000) { // 可根据 API 限制调整
|
||||
throw new IllegalArgumentException("输入文本过长");
|
||||
}
|
||||
|
||||
// 2. 构建请求体(使用 Jackson 生成 JSON)
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("model", "deepseek-chat");
|
||||
requestBody.put("messages", new Map[]{Map.of("role", "user", "content", inputText)});
|
||||
requestBody.put("temperature", 0.7);
|
||||
|
||||
String jsonBody = objectMapper.writeValueAsString(requestBody);
|
||||
|
||||
// 3. 使用 Hutool HTTP 发送请求
|
||||
HttpResponse response = HttpRequest.of(DEEPSEEK_API_URL).method(Method.POST).header("Content-Type", "application/json").header("Authorization", "Bearer " + DEEPSEEK_API_KEY).header("Accept", "application/json").body(jsonBody).execute();
|
||||
|
||||
// 4. 检查 HTTP 状态码
|
||||
if (response.getStatus() != 200) {
|
||||
throw new IOException("API 调用失败,HTTP 状态码: " + response.getStatus());
|
||||
}
|
||||
|
||||
// 5. 解析 JSON 响应(使用 Jackson)
|
||||
JsonNode rootNode = objectMapper.readTree(response.body());
|
||||
JsonNode choices = rootNode.path("choices");
|
||||
if (choices.isEmpty()) {
|
||||
throw new IOException("API 返回数据格式异常,未找到回复内容");
|
||||
}
|
||||
|
||||
// 6. 提取第一个回复的 content
|
||||
return choices.get(0).path("message").path("content").asText();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user