1
This commit is contained in:
@@ -156,6 +156,50 @@ public class SocialMediaController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取大模型接入配置(API 地址、密钥等,与 Jarvis 共用 Redis)
|
||||
*/
|
||||
@GetMapping("/llm-config")
|
||||
public AjaxResult getLlmConfig()
|
||||
{
|
||||
try {
|
||||
return socialMediaService.getLlmConfig();
|
||||
} catch (Exception e) {
|
||||
logger.error("获取大模型接入配置失败", e);
|
||||
return AjaxResult.error("获取失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存大模型接入配置
|
||||
*/
|
||||
@Log(title = "保存大模型接入配置", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/llm-config/save")
|
||||
public AjaxResult saveLlmConfig(@RequestBody Map<String, Object> request)
|
||||
{
|
||||
try {
|
||||
return socialMediaService.saveLlmConfig(request);
|
||||
} catch (Exception e) {
|
||||
logger.error("保存大模型接入配置失败", e);
|
||||
return AjaxResult.error("保存失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除大模型接入配置(Jarvis 使用 yml 默认 Ollama)
|
||||
*/
|
||||
@Log(title = "重置大模型接入配置", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/llm-config")
|
||||
public AjaxResult resetLlmConfig()
|
||||
{
|
||||
try {
|
||||
return socialMediaService.resetLlmConfig();
|
||||
} catch (Exception e) {
|
||||
logger.error("重置大模型接入配置失败", e);
|
||||
return AjaxResult.error("重置失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 闲鱼文案(手动):根据标题+可选型号生成代下单、教你下单文案,不依赖JD接口
|
||||
*/
|
||||
|
||||
@@ -72,5 +72,20 @@ public interface ISocialMediaService
|
||||
* @return 包含代下单、教你下单两种文案的 Map
|
||||
*/
|
||||
Map<String, Object> generateXianyuWenan(String title, String remark);
|
||||
|
||||
/**
|
||||
* 获取社媒大模型接入配置(与 Jarvis 共用 Redis,供 OpenAI 兼容接口或 Ollama)
|
||||
*/
|
||||
com.ruoyi.common.core.domain.AjaxResult getLlmConfig();
|
||||
|
||||
/**
|
||||
* 保存社媒大模型接入配置
|
||||
*/
|
||||
com.ruoyi.common.core.domain.AjaxResult saveLlmConfig(Map<String, Object> request);
|
||||
|
||||
/**
|
||||
* 清除 Redis 中的接入配置,Jarvis 侧回退为 application.yml 默认 Ollama
|
||||
*/
|
||||
com.ruoyi.common.core.domain.AjaxResult resetLlmConfig();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,15 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
||||
put("content:both", "通用文案生成提示词模板\n占位符:%s - 商品名称,%s - 价格信息,%s - 关键词信息");
|
||||
}};
|
||||
|
||||
/** 与 Jarvis_java SocialMediaLlmClient 使用相同 Redis 键 */
|
||||
private static final String LLM_KEY_MODE = "social_media:llm:mode";
|
||||
private static final String LLM_KEY_BASE_URL = "social_media:llm:base_url";
|
||||
private static final String LLM_KEY_API_KEY = "social_media:llm:api_key";
|
||||
private static final String LLM_KEY_MODEL = "social_media:llm:model";
|
||||
|
||||
private static final String LLM_MODE_OLLAMA = "ollama";
|
||||
private static final String LLM_MODE_OPENAI = "openai";
|
||||
|
||||
/** 闲鱼文案-通用基础说明 */
|
||||
private static final String WENAN_BASE =
|
||||
"全新未拆封正品,包邮包安装,支持查验后再签收。\n"
|
||||
@@ -433,6 +442,121 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult getLlmConfig() {
|
||||
try {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
if (redisTemplate == null) {
|
||||
data.put("redisAvailable", false);
|
||||
data.put("mode", LLM_MODE_OLLAMA);
|
||||
data.put("baseUrl", "");
|
||||
data.put("model", "");
|
||||
data.put("hasApiKey", false);
|
||||
data.put("apiKeyMasked", null);
|
||||
return AjaxResult.success(data);
|
||||
}
|
||||
data.put("redisAvailable", true);
|
||||
String modeRaw = StringUtils.trim(redisTemplate.opsForValue().get(LLM_KEY_MODE));
|
||||
String mode = StringUtils.isEmpty(modeRaw) ? LLM_MODE_OLLAMA : modeRaw.toLowerCase();
|
||||
data.put("mode", mode);
|
||||
data.put("baseUrl", StringUtils.trim(redisTemplate.opsForValue().get(LLM_KEY_BASE_URL)));
|
||||
data.put("model", StringUtils.trim(redisTemplate.opsForValue().get(LLM_KEY_MODEL)));
|
||||
String rawKey = redisTemplate.opsForValue().get(LLM_KEY_API_KEY);
|
||||
boolean hasKey = StringUtils.isNotEmpty(StringUtils.trim(rawKey));
|
||||
data.put("hasApiKey", hasKey);
|
||||
data.put("apiKeyMasked", maskLlmApiKey(rawKey));
|
||||
return AjaxResult.success(data);
|
||||
} catch (Exception e) {
|
||||
log.error("读取大模型接入配置失败", e);
|
||||
return AjaxResult.error("读取失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String maskLlmApiKey(String secret) {
|
||||
if (StringUtils.isEmpty(StringUtils.trim(secret))) {
|
||||
return null;
|
||||
}
|
||||
String s = secret.trim();
|
||||
if (s.length() <= 4) {
|
||||
return "****";
|
||||
}
|
||||
return "****" + s.substring(s.length() - 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult saveLlmConfig(Map<String, Object> request) {
|
||||
try {
|
||||
if (redisTemplate == null) {
|
||||
return AjaxResult.error("Redis未配置,无法保存");
|
||||
}
|
||||
String mode = request.get("mode") == null ? "" : request.get("mode").toString().trim().toLowerCase();
|
||||
if (!LLM_MODE_OLLAMA.equals(mode) && !LLM_MODE_OPENAI.equals(mode)) {
|
||||
return AjaxResult.error("接入方式只能是 ollama 或 openai");
|
||||
}
|
||||
String baseUrl = request.get("baseUrl") == null ? "" : request.get("baseUrl").toString().trim();
|
||||
String model = request.get("model") == null ? "" : request.get("model").toString().trim();
|
||||
|
||||
if (LLM_MODE_OPENAI.equals(mode)) {
|
||||
if (StringUtils.isEmpty(baseUrl)) {
|
||||
return AjaxResult.error("OpenAI 兼容模式须填写 Chat Completions 完整地址(如 https://api.openai.com/v1/chat/completions)");
|
||||
}
|
||||
if (StringUtils.isEmpty(model)) {
|
||||
return AjaxResult.error("OpenAI 兼容模式须填写模型名称");
|
||||
}
|
||||
}
|
||||
|
||||
boolean clearApiKey = Boolean.TRUE.equals(request.get("clearApiKey"))
|
||||
|| "true".equalsIgnoreCase(String.valueOf(request.get("clearApiKey")));
|
||||
if (clearApiKey) {
|
||||
redisTemplate.delete(LLM_KEY_API_KEY);
|
||||
}
|
||||
|
||||
Object apiKeyObj = request.get("apiKey");
|
||||
if (!clearApiKey && apiKeyObj != null) {
|
||||
String newKey = apiKeyObj.toString().trim();
|
||||
if (StringUtils.isNotEmpty(newKey)) {
|
||||
redisTemplate.opsForValue().set(LLM_KEY_API_KEY, newKey);
|
||||
}
|
||||
}
|
||||
|
||||
redisTemplate.opsForValue().set(LLM_KEY_MODE, mode);
|
||||
if (StringUtils.isEmpty(baseUrl)) {
|
||||
redisTemplate.delete(LLM_KEY_BASE_URL);
|
||||
} else {
|
||||
redisTemplate.opsForValue().set(LLM_KEY_BASE_URL, baseUrl);
|
||||
}
|
||||
if (StringUtils.isEmpty(model)) {
|
||||
redisTemplate.delete(LLM_KEY_MODEL);
|
||||
} else {
|
||||
redisTemplate.opsForValue().set(LLM_KEY_MODEL, model);
|
||||
}
|
||||
|
||||
log.info("保存大模型接入配置成功, mode={}", mode);
|
||||
return AjaxResult.success("保存成功");
|
||||
} catch (Exception e) {
|
||||
log.error("保存大模型接入配置失败", e);
|
||||
return AjaxResult.error("保存失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult resetLlmConfig() {
|
||||
try {
|
||||
if (redisTemplate == null) {
|
||||
return AjaxResult.error("Redis未配置");
|
||||
}
|
||||
redisTemplate.delete(LLM_KEY_MODE);
|
||||
redisTemplate.delete(LLM_KEY_BASE_URL);
|
||||
redisTemplate.delete(LLM_KEY_API_KEY);
|
||||
redisTemplate.delete(LLM_KEY_MODEL);
|
||||
log.info("已清除大模型接入 Redis 配置");
|
||||
return AjaxResult.success("已恢复为 Jarvis 默认 Ollama 配置");
|
||||
} catch (Exception e) {
|
||||
log.error("清除大模型接入配置失败", e);
|
||||
return AjaxResult.error("清除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据标题(+可选型号备注)生成闲鱼文案(代下单、教你下单),不依赖JD接口
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user