社区feed流/topsales

This commit is contained in:
spllzh
2025-09-25 20:55:31 +08:00
parent 8286e68dd2
commit 9554631571
17 changed files with 1352 additions and 1 deletions

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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()
);
}
}

View File

@@ -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"));
}
}