社区feed流/topsales
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.rj.service.biz;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.rj.entity.bz.CommunityFeedAnalysisResult;
|
||||
import com.rj.dto.CommunityFeedDTO;
|
||||
import com.rj.dto.DifyWorkflowResponseDto;
|
||||
|
||||
public interface ICommunityFeedAnalysisResultService extends IService<CommunityFeedAnalysisResult> {
|
||||
boolean saveResult(CommunityFeedAnalysisResult result);
|
||||
CommunityFeedAnalysisResult getByWorkflowId(String workflowId);
|
||||
DifyWorkflowResponseDto callAiFeedWorkflow(CommunityFeedDTO requestDto);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.rj.service.biz;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.rj.dto.TopSalesScoreRequestDto;
|
||||
import com.rj.dto.DifyWorkflowResponseDto;
|
||||
import com.rj.entity.bz.TopSalesScoreResult;
|
||||
|
||||
public interface ITopSalesScoreResultService extends IService<TopSalesScoreResult> {
|
||||
DifyWorkflowResponseDto callAndSave(TopSalesScoreRequestDto requestDto);
|
||||
TopSalesScoreResult getByWorkflowId(String workflowId);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.rj.service.biz.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.rj.dto.CommunityFeedDTO;
|
||||
import com.rj.dto.DifyWorkflowResponseDto;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rj.entity.bz.CommunityFeedAnalysisResult;
|
||||
import com.rj.service.DifyWorkflowService;
|
||||
import com.rj.mapper.CommunityFeedAnalysisResultMapper;
|
||||
import com.rj.service.biz.ICommunityFeedAnalysisResultService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CommunityFeedAnalysisResultServiceImpl
|
||||
extends ServiceImpl<CommunityFeedAnalysisResultMapper, CommunityFeedAnalysisResult>
|
||||
implements ICommunityFeedAnalysisResultService {
|
||||
|
||||
@Autowired
|
||||
private DifyWorkflowService difyWorkflowService;
|
||||
|
||||
@Override
|
||||
public boolean saveResult(CommunityFeedAnalysisResult result) {
|
||||
try {
|
||||
log.info("保存社区Feed分析结果:{}", result);
|
||||
return this.save(result);
|
||||
} catch (Exception e) {
|
||||
log.error("保存社区Feed分析结果异常", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommunityFeedAnalysisResult getByWorkflowId(String workflowId) {
|
||||
return this.getOne(new LambdaQueryWrapper<CommunityFeedAnalysisResult>()
|
||||
.eq(CommunityFeedAnalysisResult::getWorkflowId, workflowId)
|
||||
.last("limit 1"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DifyWorkflowResponseDto callAiFeedWorkflow(CommunityFeedDTO requestDto) {
|
||||
Map<String, Object> inputs = new HashMap<>();
|
||||
inputs.put("targetContent", requestDto.getTargetContent());
|
||||
inputs.put("targetId", requestDto.getTargetId());
|
||||
inputs.put("targetType", requestDto.getTargetType());
|
||||
|
||||
DifyWorkflowService.DifyWorkflowRequest request =
|
||||
new DifyWorkflowService.DifyWorkflowRequest(inputs, requestDto.getTargetId());
|
||||
|
||||
DifyWorkflowService.DifyWorkflowResponse response =
|
||||
difyWorkflowService.callAiFeedWorkflow(request);
|
||||
|
||||
try {
|
||||
JSONObject data = response.getData();
|
||||
if (data != null) {
|
||||
CommunityFeedAnalysisResult entity = new CommunityFeedAnalysisResult();
|
||||
|
||||
// 顶层通用信息
|
||||
entity.setWorkflowId(data.getString("workflow_id"));
|
||||
entity.setStatus(data.getString("status"));
|
||||
entity.setTotalTokens(data.getInteger("total_tokens"));
|
||||
if (data.containsKey("elapsed_time")) {
|
||||
try {
|
||||
entity.setElapsedTime(data.getBigDecimal("elapsed_time"));
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
entity.setElapsedTime(new BigDecimal(String.valueOf(data.get("elapsed_time"))));
|
||||
} catch (Exception ig) {
|
||||
log.warn("elapsed_time 解析失败: {}", data.get("elapsed_time"));
|
||||
}
|
||||
}
|
||||
}
|
||||
entity.setError(data.getString("error"));
|
||||
|
||||
// 解析 outputs.feedAiResult(可能是 ```json 包裹的字符串)
|
||||
JSONObject outputs = data.getJSONObject("outputs");
|
||||
if (outputs != null && outputs.containsKey("feedAiResult")) {
|
||||
String feedAiResult = outputs.getString("feedAiResult");
|
||||
if (feedAiResult != null) {
|
||||
// 清理 ```json 代码块
|
||||
String cleaned = feedAiResult.trim();
|
||||
if (cleaned.startsWith("```json")) {
|
||||
cleaned = cleaned.substring(7).trim();
|
||||
} else if (cleaned.startsWith("```")) {
|
||||
cleaned = cleaned.substring(3).trim();
|
||||
}
|
||||
if (cleaned.endsWith("```")) {
|
||||
cleaned = cleaned.substring(0, cleaned.length() - 3).trim();
|
||||
}
|
||||
try {
|
||||
JSONObject scoreJson = JSON.parseObject(cleaned);
|
||||
entity.setLengthScore(scoreJson.getInteger("length"));
|
||||
entity.setImageScore(scoreJson.getInteger("image"));
|
||||
entity.setTopicsScore(scoreJson.getInteger("topics"));
|
||||
entity.setEmotionScore(scoreJson.getInteger("emotion"));
|
||||
entity.setThemeScore(scoreJson.getInteger("theme"));
|
||||
entity.setFluencyScore(scoreJson.getInteger("fluency"));
|
||||
entity.setContentScore(scoreJson.getInteger("contentScore"));
|
||||
entity.setEvaluationReason(scoreJson.getString("evaluationReason"));
|
||||
} catch (Exception ignore) {
|
||||
log.warn("解析feedAiResult为JSON失败,cleaned: {}", cleaned);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 源内容:从请求与 outputs 回填
|
||||
entity.setSrcContent(requestDto.getTargetContent());
|
||||
if (outputs != null) {
|
||||
entity.setSrcId(outputs.getString("targetId"));
|
||||
entity.setSrcType(outputs.getString("targetType"));
|
||||
}
|
||||
|
||||
// 时间字段
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
entity.setCreatedAt(now);
|
||||
entity.setUpdatedAt(now);
|
||||
|
||||
boolean saved = this.save(entity);
|
||||
log.info("AI-Feed分析结果保存{}: {}", saved ? "成功" : "失败", entity);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("保存AI-Feed分析结果到DB失败", e);
|
||||
}
|
||||
|
||||
return DifyWorkflowResponseDto.success(
|
||||
response.getWorkflowRunId(),
|
||||
response.getTaskId(),
|
||||
response.getData(),
|
||||
response.getMetadata()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.rj.service.biz.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.rj.dto.DifyWorkflowResponseDto;
|
||||
import com.rj.dto.TopSalesScoreRequestDto;
|
||||
import com.rj.entity.bz.TopSalesScoreResult;
|
||||
import com.rj.mapper.TopSalesScoreResultMapper;
|
||||
import com.rj.service.DifyWorkflowService;
|
||||
import com.rj.service.biz.ITopSalesScoreResultService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TopSalesScoreResultServiceImpl
|
||||
extends ServiceImpl<TopSalesScoreResultMapper, TopSalesScoreResult>
|
||||
implements ITopSalesScoreResultService {
|
||||
|
||||
@Autowired
|
||||
private DifyWorkflowService difyWorkflowService;
|
||||
|
||||
@Override
|
||||
public DifyWorkflowResponseDto callAndSave(TopSalesScoreRequestDto requestDto) {
|
||||
DifyWorkflowService.DifyWorkflowResponse response = null;
|
||||
try {
|
||||
log.info("[TopSales] 开始调用工作流,chat长度={}", requestDto.getChat() == null ? 0 : requestDto.getChat().length());
|
||||
JSONObject inputs = new JSONObject();
|
||||
inputs.put("chat", requestDto.getChat());
|
||||
DifyWorkflowService.DifyWorkflowRequest req = new DifyWorkflowService.DifyWorkflowRequest(inputs, "topsales_user");
|
||||
response = difyWorkflowService.callTopSalesScoringWorkflow(req);
|
||||
|
||||
JSONObject data = response.getData();
|
||||
if (data != null) {
|
||||
log.info("[TopSales] 响应data: {}", data);
|
||||
TopSalesScoreResult entity = new TopSalesScoreResult();
|
||||
entity.setWorkflowId(data.getString("workflow_id"));
|
||||
entity.setStatus(data.getString("status"));
|
||||
entity.setTotalTokens(data.getInteger("total_tokens"));
|
||||
try {
|
||||
entity.setElapsedTime(data.getBigDecimal("elapsed_time"));
|
||||
} catch (Exception ex) {
|
||||
Object et = data.get("elapsed_time");
|
||||
if (et != null) {
|
||||
entity.setElapsedTime(new BigDecimal(String.valueOf(et)));
|
||||
}
|
||||
}
|
||||
|
||||
// 输出在 data.outputs.text
|
||||
JSONObject outputs = data.getJSONObject("outputs");
|
||||
if (outputs != null) {
|
||||
String text = outputs.getString("text");
|
||||
if (text != null) {
|
||||
String cleaned = text.trim();
|
||||
if (cleaned.startsWith("```json")) cleaned = cleaned.substring(7).trim();
|
||||
if (cleaned.startsWith("```")) cleaned = cleaned.substring(3).trim();
|
||||
if (cleaned.endsWith("```")) cleaned = cleaned.substring(0, cleaned.length() - 3).trim();
|
||||
log.info("[TopSales] 清理后的text: {}", cleaned);
|
||||
try {
|
||||
JSONObject score = JSON.parseObject(cleaned);
|
||||
// 同时兼容中文与英文snake_case键
|
||||
entity.setNaturalnessScore(firstInt(score, "自然度分数", "naturalness_score"));
|
||||
entity.setCoherenceScore(firstInt(score, "连贯性分数", "coherence_score"));
|
||||
entity.setFluencyScore(firstInt(score, "流畅度分数", "fluency_score"));
|
||||
entity.setAdvisorAggressivenessScore(firstInt(score, "顾问攻击性分数", "advisor_aggressiveness_score"));
|
||||
entity.setAdvisorConsistencyScore(firstInt(score, "顾问一致性分数", "advisor_consistency_score"));
|
||||
entity.setGreetingReceptionScore(firstInt(score, "欢迎接待分数", "greeting_reception_score"));
|
||||
entity.setBrandIntroductionScore(firstInt(score, "品牌介绍分数", "brand_introduction_score"));
|
||||
entity.setCustomerNeedsUnderstandingScore(firstInt(score, "了解客户用车需求分数", "customer_needs_understanding_score"));
|
||||
entity.setBudgetUnderstandingScore(firstInt(score, "了解客户经济预算分数", "budget_understanding_score"));
|
||||
entity.setRecommendationScore(firstInt(score, "推荐配置或车型分数", "recommendation_score"));
|
||||
entity.setSafetyIntroductionScore(firstInt(score, "重点介绍安全性分数", "safety_introduction_score"));
|
||||
entity.setHealthEnvironmentIntroductionScore(firstInt(score, "重点介绍健康环保分数", "health_environment_introduction_score"));
|
||||
entity.setTechnologyIntroductionScore(firstInt(score, "重点介绍科技性分数", "technology_introduction_score"));
|
||||
entity.setTestDriveInvitationScore(firstInt(score, "邀请试驾分数", "test_drive_invitation_score"));
|
||||
entity.setNegotiationDealScore(firstInt(score, "商谈成交分数", "negotiation_deal_score"));
|
||||
} catch (Exception ex) {
|
||||
log.warn("TopSales 输出解析失败,text= {}", text);
|
||||
}
|
||||
}
|
||||
// 回填源内容字段(允许外部覆盖)
|
||||
String srcContent = requestDto.getSrcContent() == null || requestDto.getSrcContent().trim().isEmpty()
|
||||
? requestDto.getChat()
|
||||
: requestDto.getSrcContent();
|
||||
entity.setSrcContent(srcContent);
|
||||
entity.setSrcId(requestDto.getSrcId() != null ? requestDto.getSrcId() : data.getString("id"));
|
||||
entity.setSrcDesc(requestDto.getSrcDesc() != null ? requestDto.getSrcDesc() : "topsales_all_dim_score");
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
entity.setCreatedAt(now);
|
||||
entity.setUpdatedAt(now);
|
||||
boolean saved = this.save(entity);
|
||||
log.info("TopSales评分结果保存{}: {}", saved ? "成功" : "失败", entity);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("调用并保存TopSales评分结果异常", e);
|
||||
}
|
||||
|
||||
return DifyWorkflowResponseDto.success(
|
||||
response != null ? response.getWorkflowRunId() : null,
|
||||
response != null ? response.getTaskId() : null,
|
||||
response != null ? response.getData() : null,
|
||||
response != null ? response.getMetadata() : null
|
||||
);
|
||||
}
|
||||
|
||||
private Integer parseInt(String s) {
|
||||
try {
|
||||
if (s == null) return null;
|
||||
return Integer.parseInt(s.trim());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer firstInt(JSONObject obj, String... keys) {
|
||||
for (String k : keys) {
|
||||
String v = obj.getString(k);
|
||||
Integer parsed = parseInt(v);
|
||||
if (parsed != null) return parsed;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TopSalesScoreResult getByWorkflowId(String workflowId) {
|
||||
return this.getOne(new LambdaQueryWrapper<TopSalesScoreResult>()
|
||||
.eq(TopSalesScoreResult::getWorkflowId, workflowId)
|
||||
.last("limit 1"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user