1
This commit is contained in:
@@ -97,5 +97,63 @@ public class SocialMediaController extends BaseController
|
|||||||
return AjaxResult.error("生成完整内容失败: " + e.getMessage());
|
return AjaxResult.error("生成完整内容失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取提示词模板列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/prompt/list")
|
||||||
|
public AjaxResult listPromptTemplates()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return socialMediaService.listPromptTemplates();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取提示词模板列表失败", e);
|
||||||
|
return AjaxResult.error("获取失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个提示词模板
|
||||||
|
*/
|
||||||
|
@GetMapping("/prompt/{key}")
|
||||||
|
public AjaxResult getPromptTemplate(@PathVariable String key)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return socialMediaService.getPromptTemplate(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取提示词模板失败", e);
|
||||||
|
return AjaxResult.error("获取失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存提示词模板
|
||||||
|
*/
|
||||||
|
@Log(title = "保存提示词模板", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/prompt/save")
|
||||||
|
public AjaxResult savePromptTemplate(@RequestBody Map<String, Object> request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return socialMediaService.savePromptTemplate(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("保存提示词模板失败", e);
|
||||||
|
return AjaxResult.error("保存失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除提示词模板(恢复默认)
|
||||||
|
*/
|
||||||
|
@Log(title = "删除提示词模板", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/prompt/{key}")
|
||||||
|
public AjaxResult deletePromptTemplate(@PathVariable String key)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return socialMediaService.deletePromptTemplate(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("删除提示词模板失败", e);
|
||||||
|
return AjaxResult.error("删除失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -217,6 +217,79 @@ public class HttpUtils
|
|||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向指定 URL 发送DELETE方法的请求
|
||||||
|
*
|
||||||
|
* @param url 发送请求的 URL
|
||||||
|
* @return 所代表远程资源的响应结果
|
||||||
|
*/
|
||||||
|
public static String sendDelete(String url)
|
||||||
|
{
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
BufferedReader in = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
log.info("sendDelete - {}", url);
|
||||||
|
URL realUrl = new URL(url);
|
||||||
|
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) realUrl.openConnection();
|
||||||
|
conn.setRequestMethod("DELETE");
|
||||||
|
conn.setRequestProperty("accept", "*/*");
|
||||||
|
conn.setRequestProperty("connection", "Keep-Alive");
|
||||||
|
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
|
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||||
|
conn.setConnectTimeout(10000);
|
||||||
|
conn.setReadTimeout(20000);
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
int responseCode = conn.getResponseCode();
|
||||||
|
InputStream inputStream = (responseCode >= 200 && responseCode < 300)
|
||||||
|
? conn.getInputStream()
|
||||||
|
: conn.getErrorStream();
|
||||||
|
|
||||||
|
if (inputStream != null)
|
||||||
|
{
|
||||||
|
in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||||
|
String line;
|
||||||
|
while ((line = in.readLine()) != null)
|
||||||
|
{
|
||||||
|
result.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("recv - {}", result);
|
||||||
|
}
|
||||||
|
catch (ConnectException e)
|
||||||
|
{
|
||||||
|
log.error("调用HttpUtils.sendDelete ConnectException, url=" + url, e);
|
||||||
|
}
|
||||||
|
catch (SocketTimeoutException e)
|
||||||
|
{
|
||||||
|
log.error("调用HttpUtils.sendDelete SocketTimeoutException, url=" + url, e);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
log.error("调用HttpUtils.sendDelete IOException, url=" + url, e);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.error("调用HttpUtils.sendDelete Exception, url=" + url, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.error("调用in.close Exception, url=" + url, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static String sendSSLPost(String url, String param)
|
public static String sendSSLPost(String url, String param)
|
||||||
{
|
{
|
||||||
return sendSSLPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
return sendSSLPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||||
|
|||||||
@@ -43,5 +43,25 @@ public interface ISocialMediaService
|
|||||||
*/
|
*/
|
||||||
Map<String, Object> generateCompleteContent(String productImageUrl, String productName,
|
Map<String, Object> generateCompleteContent(String productImageUrl, String productName,
|
||||||
Object originalPrice, Object finalPrice, String style);
|
Object originalPrice, Object finalPrice, String style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取提示词模板列表
|
||||||
|
*/
|
||||||
|
com.ruoyi.common.core.domain.AjaxResult listPromptTemplates();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个提示词模板
|
||||||
|
*/
|
||||||
|
com.ruoyi.common.core.domain.AjaxResult getPromptTemplate(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存提示词模板
|
||||||
|
*/
|
||||||
|
com.ruoyi.common.core.domain.AjaxResult savePromptTemplate(Map<String, Object> request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除提示词模板(恢复默认)
|
||||||
|
*/
|
||||||
|
com.ruoyi.common.core.domain.AjaxResult deletePromptTemplate(String key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ package com.ruoyi.jarvis.service.impl;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.http.HttpUtils;
|
import com.ruoyi.common.utils.http.HttpUtils;
|
||||||
import com.ruoyi.jarvis.service.ISocialMediaService;
|
import com.ruoyi.jarvis.service.ISocialMediaService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -23,9 +26,31 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
|||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(SocialMediaServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(SocialMediaServiceImpl.class);
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
// jarvis_java 服务地址
|
// jarvis_java 服务地址
|
||||||
private final static String JARVIS_BASE_URL = "http://192.168.8.88:6666";
|
private final static String JARVIS_BASE_URL = "http://192.168.8.88:6666";
|
||||||
|
|
||||||
|
// Redis Key 前缀
|
||||||
|
private static final String REDIS_KEY_PREFIX = "social_media:prompt:";
|
||||||
|
|
||||||
|
// 模板键名列表
|
||||||
|
private static final String[] TEMPLATE_KEYS = {
|
||||||
|
"keywords",
|
||||||
|
"content:xhs",
|
||||||
|
"content:douyin",
|
||||||
|
"content:both"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 模板说明
|
||||||
|
private static final Map<String, String> TEMPLATE_DESCRIPTIONS = new HashMap<String, String>() {{
|
||||||
|
put("keywords", "关键词提取提示词模板\n占位符:%s - 商品名称");
|
||||||
|
put("content:xhs", "小红书文案生成提示词模板\n占位符:%s - 商品名称,%s - 价格信息,%s - 关键词信息");
|
||||||
|
put("content:douyin", "抖音文案生成提示词模板\n占位符:%s - 商品名称,%s - 价格信息,%s - 关键词信息");
|
||||||
|
put("content:both", "通用文案生成提示词模板\n占位符:%s - 商品名称,%s - 价格信息,%s - 关键词信息");
|
||||||
|
}};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提取商品标题关键词
|
* 提取商品标题关键词
|
||||||
*/
|
*/
|
||||||
@@ -226,6 +251,153 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取提示词模板列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AjaxResult listPromptTemplates() {
|
||||||
|
try {
|
||||||
|
Map<String, Object> templates = new HashMap<>();
|
||||||
|
|
||||||
|
for (String key : TEMPLATE_KEYS) {
|
||||||
|
Map<String, Object> templateInfo = new HashMap<>();
|
||||||
|
templateInfo.put("key", key);
|
||||||
|
templateInfo.put("description", TEMPLATE_DESCRIPTIONS.get(key));
|
||||||
|
|
||||||
|
String template = getTemplateFromRedis(key);
|
||||||
|
templateInfo.put("template", template);
|
||||||
|
templateInfo.put("isDefault", template == null);
|
||||||
|
|
||||||
|
templates.put(key, templateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AjaxResult.success(templates);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取提示词模板列表失败", e);
|
||||||
|
return AjaxResult.error("获取失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个提示词模板
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AjaxResult getPromptTemplate(String key) {
|
||||||
|
try {
|
||||||
|
if (!isValidKey(key)) {
|
||||||
|
return AjaxResult.error("无效的模板键名");
|
||||||
|
}
|
||||||
|
|
||||||
|
String template = getTemplateFromRedis(key);
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("key", key);
|
||||||
|
data.put("description", TEMPLATE_DESCRIPTIONS.get(key));
|
||||||
|
data.put("template", template);
|
||||||
|
data.put("isDefault", template == null);
|
||||||
|
|
||||||
|
return AjaxResult.success(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取提示词模板失败", e);
|
||||||
|
return AjaxResult.error("获取失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存提示词模板
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AjaxResult savePromptTemplate(Map<String, Object> request) {
|
||||||
|
try {
|
||||||
|
String key = (String) request.get("key");
|
||||||
|
String template = (String) request.get("template");
|
||||||
|
|
||||||
|
if (!isValidKey(key)) {
|
||||||
|
return AjaxResult.error("无效的模板键名");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(template)) {
|
||||||
|
return AjaxResult.error("模板内容不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (redisTemplate == null) {
|
||||||
|
return AjaxResult.error("Redis未配置,无法保存模板");
|
||||||
|
}
|
||||||
|
|
||||||
|
String redisKey = REDIS_KEY_PREFIX + key;
|
||||||
|
String templateValue = template.trim();
|
||||||
|
if (StringUtils.isEmpty(templateValue)) {
|
||||||
|
return AjaxResult.error("模板内容不能为空");
|
||||||
|
}
|
||||||
|
redisTemplate.opsForValue().set(redisKey, templateValue);
|
||||||
|
|
||||||
|
log.info("保存提示词模板成功: {}", key);
|
||||||
|
return AjaxResult.success("保存成功");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("保存提示词模板失败", e);
|
||||||
|
return AjaxResult.error("保存失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除提示词模板(恢复默认)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AjaxResult deletePromptTemplate(String key) {
|
||||||
|
try {
|
||||||
|
if (!isValidKey(key)) {
|
||||||
|
return AjaxResult.error("无效的模板键名");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (redisTemplate == null) {
|
||||||
|
return AjaxResult.error("Redis未配置,无法删除模板");
|
||||||
|
}
|
||||||
|
|
||||||
|
String redisKey = REDIS_KEY_PREFIX + key;
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
|
||||||
|
log.info("删除提示词模板成功: {}", key);
|
||||||
|
return AjaxResult.success("删除成功,已恢复默认模板");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("删除提示词模板失败", e);
|
||||||
|
return AjaxResult.error("删除失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 Redis 获取模板
|
||||||
|
*/
|
||||||
|
private String getTemplateFromRedis(String key) {
|
||||||
|
if (redisTemplate == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String redisKey = REDIS_KEY_PREFIX + key;
|
||||||
|
String template = redisTemplate.opsForValue().get(redisKey);
|
||||||
|
return StringUtils.isNotEmpty(template) ? template : null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("读取Redis模板失败: {}", key, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证模板键名是否有效
|
||||||
|
*/
|
||||||
|
private boolean isValidKey(String key) {
|
||||||
|
if (StringUtils.isEmpty(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String validKey : TEMPLATE_KEYS) {
|
||||||
|
if (validKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析Double值
|
* 解析Double值
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user