翻译模型

This commit is contained in:
spllzh
2025-10-12 20:46:59 +08:00
parent 5f2c952a6e
commit 71c0a04b53
24 changed files with 532 additions and 303 deletions

View File

@@ -159,5 +159,6 @@ public class PasswordUtil {

View File

@@ -143,5 +143,6 @@ public class ServiceManager {

View File

@@ -120,5 +120,6 @@ public class AliyunConfig {

View File

@@ -0,0 +1,291 @@
package com.rj.controller;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.lang.System;
import java.util.Collections;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.TranslationOptions;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
/**
* 翻译、法律、意图理解控制器
*
* @author 李中华
* @date 2025/1/3
*/
@Slf4j
@RestController
@RequestMapping("/api/translation")
@Tag(name = "文本模型AI服务", description = "翻译、法律咨询、意图理解API接口")
public class TextModelController {
/**
* 翻译请求DTO
*/
@Data
public static class TranslationRequest {
@NotBlank(message = "原语言文字不能为空")
private String sourceText;
@NotBlank(message = "目标语言不能为空")
private String targetLanguage;
@NotBlank(message = "原语言不能为空")
private String sourceLanguage;
@NotBlank(message = "大模型名称")
private String model;
}
/**
* 法律咨询请求DTO
*/
@Data
public static class LegalRequest {
@NotBlank(message = "法律问题不能为空")
private String question;
private String category;
private String jurisdiction;
@NotBlank(message = "大模型名称")
private String model;
}
/**
* 意图理解请求DTO
*/
@Data
public static class IntentRequest {
@NotBlank(message = "输入文本不能为空")
private String text;
private String context;
private String domain;
@NotBlank(message = "大模型名称")
private String model;
}
/**
* 翻译接口
*/
@PostMapping("/translate")
@Operation(summary = "文本翻译", description = "将文本从源语言翻译到目标语言")
public ResponseEntity<Map<String, Object>> translate(
@Parameter(description = "翻译请求参数") @Valid @RequestBody TranslationRequest request) {
Map<String, Object> result = new HashMap<>();
try {
log.info("开始翻译,模型: {}, 目标语言: {}, 文本长度: {}",
request.getModel(), request.getTargetLanguage(), request.getSourceText().length());
// 模拟翻译处理(实际项目中应该调用翻译服务)
String translatedText = performTranslation(
request.getSourceText(),
request.getModel(),
request.getTargetLanguage()
);
result.put("success", true);
result.put("message", "翻译成功");
result.put("sourceText", request.getSourceText());
result.put("translatedText", translatedText);
result.put("sourceLanguage", request.getSourceLanguage());
result.put("targetLanguage", request.getTargetLanguage());
result.put("translationConfidence", 0.95);
result.put("processingTimeMs", 1200);
result.put("requestId", generateRequestId());
result.put("timestamp", LocalDateTime.now());
log.info("翻译完成,目标文本长度: {}", translatedText.length());
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("翻译失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "翻译失败: " + e.getMessage());
result.put("error", e.getClass().getSimpleName());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 法律咨询接口
*/
@PostMapping("/legal")
@Operation(summary = "法律咨询", description = "提供法律问题咨询和建议")
public ResponseEntity<Map<String, Object>> legalConsultation(
@Parameter(description = "法律咨询请求参数") @Valid @RequestBody LegalRequest request) {
Map<String, Object> result = new HashMap<>();
try {
log.info("开始法律咨询,问题类别: {}, 管辖区域: {}, 问题长度: {}",
request.getCategory(), request.getJurisdiction(), request.getQuestion().length());
// 模拟法律咨询处理实际项目中应该调用AI法律服务
Map<String, Object> legalResponse = performLegalConsultation(request);
result.put("success", true);
result.put("message", "法律咨询完成");
result.put("question", request.getQuestion());
result.put("answer", legalResponse.get("answer"));
result.put("category", legalResponse.get("category"));
result.put("jurisdiction", legalResponse.get("jurisdiction"));
result.put("confidence", legalResponse.get("confidence"));
result.put("relatedLaws", legalResponse.get("relatedLaws"));
result.put("suggestions", legalResponse.get("suggestions"));
result.put("processingTimeMs", 2500);
result.put("requestId", generateRequestId());
result.put("timestamp", LocalDateTime.now());
log.info("法律咨询完成,回答长度: {}", legalResponse.get("answer").toString().length());
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("法律咨询失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "法律咨询失败: " + e.getMessage());
result.put("error", e.getClass().getSimpleName());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 意图理解接口
*/
@PostMapping("/intent")
@Operation(summary = "意图理解", description = "分析文本的意图和情感")
public ResponseEntity<Map<String, Object>> intentAnalysis(
@Parameter(description = "意图理解请求参数") @Valid @RequestBody IntentRequest request) {
Map<String, Object> result = new HashMap<>();
try {
log.info("开始意图分析,领域: {}, 上下文: {}, 文本长度: {}",
request.getDomain(), request.getContext(), request.getText().length());
// 模拟意图理解处理实际项目中应该调用NLP服务
Map<String, Object> intentResponse = performIntentAnalysis(request);
result.put("success", true);
result.put("message", "意图分析完成");
result.put("text", request.getText());
result.put("intent", intentResponse.get("intent"));
result.put("confidence", intentResponse.get("confidence"));
result.put("entities", intentResponse.get("entities"));
result.put("sentiment", intentResponse.get("sentiment"));
result.put("emotion", intentResponse.get("emotion"));
result.put("domain", intentResponse.get("domain"));
result.put("processingTimeMs", 800);
result.put("requestId", generateRequestId());
result.put("timestamp", LocalDateTime.now());
log.info("意图分析完成,识别意图: {}", intentResponse.get("intent"));
return ResponseEntity.ok(result);
} catch (Exception e) {
log.error("意图分析失败: {}", e.getMessage(), e);
result.put("success", false);
result.put("message", "意图分析失败: " + e.getMessage());
result.put("error", e.getClass().getSimpleName());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 执行翻译的模拟方法
*/
private String performTranslation(String sourceText, String model, String targetLanguage) {
Generation gen = new Generation();
Message userMsg = Message.builder()
.role(Role.USER.getValue())
.content(sourceText)
.build();
TranslationOptions options = TranslationOptions.builder()
.sourceLang("auto")
// .targetLang("English")
.targetLang(targetLanguage)
.build();
GenerationParam param = GenerationParam.builder()
// 若没有配置环境变量请用阿里云百炼API Key将下行替换为.apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// .model("qwen-mt-plus")
.model(model)
.messages(Collections.singletonList(userMsg))
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.translationOptions(options)
.build();
try {
GenerationResult call = gen.call(param);
String content = call.getOutput().getChoices().get(0).getMessage().getContent();
log.info("翻译完成,结果长度: {} ,内容是:{} ", content.length(),content);
return content;
} catch (NoApiKeyException e) {
throw new RuntimeException(e);
} catch (InputRequiredException e) {
throw new RuntimeException(e);
}
}
/**
* 执行法律咨询的模拟方法
*/
private Map<String, Object> performLegalConsultation(LegalRequest request) {
Map<String, Object> response = new HashMap<>();
response.put("answer", "根据您的问题,我建议您咨询专业律师。这是一个复杂的法律问题,需要详细分析具体情况。");
response.put("category", request.getCategory() != null ? request.getCategory() : "一般法律咨询");
response.put("jurisdiction", request.getJurisdiction() != null ? request.getJurisdiction() : "中国大陆");
response.put("confidence", 0.85);
response.put("relatedLaws", new String[]{"民法典", "合同法", "劳动法"});
response.put("suggestions", new String[]{"收集相关证据", "咨询专业律师", "了解相关法律条文"});
return response;
}
/**
* 执行意图分析的模拟方法
*/
private Map<String, Object> performIntentAnalysis(IntentRequest request) {
Map<String, Object> response = new HashMap<>();
response.put("intent", "查询信息");
response.put("confidence", 0.92);
response.put("entities", new String[]{"时间", "地点", "人物"});
response.put("sentiment", "中性");
response.put("emotion", "平静");
response.put("domain", request.getDomain() != null ? request.getDomain() : "通用");
return response;
}
/**
* 生成请求ID
*/
private String generateRequestId() {
return "REQ_" + System.currentTimeMillis() + "_" + (int)(Math.random() * 1000);
}
}

View File

@@ -1,5 +1,12 @@
package com.rj.controller;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rj.entity.VideoImageAnalysis;
@@ -607,7 +614,13 @@ public class VideoImageAnalysisController {
analysis.setUpdatedAt(now);
// 调用阿里云AI服务进行实际分析
Map<String, Object> aiResult = performAiAnalysisWithDetails(model, type, userQuestion, analysis.getVideoImageTempUrl());
Map<String, Object> aiResult=null;
if ("video".equals(type) ){
aiResult = performAiAnalysisWithDetailsForVideo(model, type, userQuestion, analysis.getVideoImageTempUrl());
}else {
aiResult = performAiAnalysisWithDetails(model, type, userQuestion, analysis.getVideoImageTempUrl());
}
String aiResponse = (String) aiResult.get("content");
analysis.setResponseContent(aiResponse);
@@ -619,10 +632,15 @@ public class VideoImageAnalysisController {
// 记录AI分析结果和token使用情况
analysis.setFinishReason("stop");
analysis.setUsagePromptTokens((Integer) aiResult.getOrDefault("promptTokens", 0));
analysis.setUsageCompletionTokens((Integer) aiResult.getOrDefault("completionTokens", 0));
analysis.setUsageTotalTokens((Integer) aiResult.getOrDefault("totalTokens", 0));
try {
analysis.setUsagePromptTokens((Integer) aiResult.getOrDefault("promptTokens", Integer.valueOf(0)));
analysis.setUsageCompletionTokens((Integer) aiResult.getOrDefault("completionTokens", Integer.valueOf(0)));
analysis.setUsageTotalTokens((Integer) aiResult.getOrDefault("totalTokens", Integer.valueOf(0)));
} catch (Exception e) {
log.error("获取token使用情况失败:{}" ,e );
}
// 保存分析记录
boolean success = videoImageAnalysisService.saveVideoImageAnalysis(analysis);
@@ -706,7 +724,46 @@ public class VideoImageAnalysisController {
throw new RuntimeException("提取对象名失败: " + e.getMessage());
}
}
private Map<String, Object> performAiAnalysisWithDetailsForVideo(String model, String type, String userQuestion, String fileUrl) {
MultiModalConversation conv = new MultiModalConversation();
Map<String, Object> result = new HashMap<>();
// fps 可参数控制视频抽帧频率,表示每隔 1/fps 秒抽取一帧完整用法请参见https://help.aliyun.com/zh/model-studio/use-qwen-by-calling-api?#2ed5ee7377fum
Map<String, Object> params = new HashMap<>();
// params.put("video", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241115/cqqkru/1.mp4");
params.put("video",fileUrl);
params.put("fps", 2);
MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(
params,
Collections.singletonMap("text", userQuestion))).build();
MultiModalConversationParam param = MultiModalConversationParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.model(model)
.messages(Arrays.asList(userMessage))
.build();
result.put("requestData", userMessage.toString());
MultiModalConversationResult callResult = null;
try {
callResult = conv.call(param);
} catch (NoApiKeyException e) {
throw new RuntimeException(e);
} catch (UploadFileException e) {
throw new RuntimeException(e);
}
result.put("responseData", callResult.toString());
System.out.println(callResult.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text"));
result.put("content",callResult.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text") );
result.put("promptTokens",callResult.getUsage().getInputTokens() );
result.put("completionTokens",callResult.getUsage().getOutputTokensDetails() );
result.put("totalTokens",callResult.getUsage().getTotalTokens() );
return result;
}
/**
* 执行AI分析 - 调用阿里云通义千问API返回详细信息
*/
@@ -737,27 +794,19 @@ public class VideoImageAnalysisController {
imageContent.put("type", type);
if (type.equals("video")) {
/**
* [{
* "role": "user",
* "content": [
* {
* "type": "video",
* "video": [
* "https://img.alicdn.com/imgextra/i3/O1CN01K3SgGo1eqmlUgeE9b_!!6000000003923-0-tps-3840-2160.jpg",
* "https://img.alicdn.com/imgextra/i4/O1CN01BjZvwg1Y23CF5qIRB_!!6000000003000-0-tps-3840-2160.jpg",
* "https://img.alicdn.com/imgextra/i4/O1CN01Ib0clU27vTgBdbVLQ_!!6000000007859-0-tps-3840-2160.jpg",
* "https://img.alicdn.com/imgextra/i1/O1CN01aygPLW1s3EXCdSN4X_!!6000000005710-0-tps-3840-2160.jpg"]
* },
* {
* "type": "text",
* "text": "描述这个视频的具体过程"
* }]}]
*/
// 检查是否提供了图片序列
if (fileUrl == null || fileUrl.trim().isEmpty()) {
throw new RuntimeException("视频分析需要提供图片序列,当前未提供任何文件");
}
// 检查是否为图片序列通过URL数量判断
// 这里假设如果fileUrl包含多个URL用逗号分隔则为图片序列
// 满足要求的图片序列
Map<String, Object> videoContent = new HashMap<>();
videoContent.put("video", Arrays.asList(fileUrl));
content.add(videoContent);
imageContent.put("video", Arrays.asList(fileUrl));
content.add(imageContent);
}else if (type.equals("image_url")) {
} else if (type.equals("image_url")) {
/**
* [{"role": "user","content": [
* {"type": "image_url",
@@ -789,11 +838,12 @@ public class VideoImageAnalysisController {
// 创建HTTP实体
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
// 保存请求数据到结果中
String requestDataJson = objectMapper.writeValueAsString(requestBody);
log.info("调用阿里云AI分析APIURL{}, 请求体:{}", apiUrl, requestDataJson);
log.info("调用阿里云AI分析API 请求体:{}", requestDataJson);
Map<String, Object> result = new HashMap<>();
result.put("requestData", requestDataJson);
// 发送请求
ResponseEntity<String> response = restTemplate.exchange(
apiUrl,
@@ -801,13 +851,12 @@ public class VideoImageAnalysisController {
entity,
String.class
);
log.info("阿里云AI分析API响应状态{}", response.getStatusCode());
log.info("阿里云AI分析API响应内容{}", response.getBody());
// 保存响应数据
String responseDataJson = response.getBody();
result.put("responseData", responseDataJson);
if (response.getStatusCode().is2xxSuccessful()) {
// 解析响应
JsonNode responseJson = objectMapper.readTree(response.getBody());
@@ -819,7 +868,7 @@ public class VideoImageAnalysisController {
// 记录token使用情况
JsonNode usage = responseJson.path("usage");
Map<String, Object> result = new HashMap<>();
result.put("content", contentText);
if (!usage.isMissingNode()) {
@@ -839,9 +888,7 @@ public class VideoImageAnalysisController {
result.put("totalTokens", 0);
}
// 添加请求和响应数据
result.put("requestData", requestDataJson);
result.put("responseData", responseDataJson);
return result;
} else {

View File

@@ -381,5 +381,6 @@ public class MenuController {

View File

@@ -351,5 +351,6 @@ public class RoleController {

View File

@@ -357,5 +357,6 @@ public class UserRoleController {

View File

@@ -123,5 +123,6 @@ public class DifyWorkflowResponseDto {

View File

@@ -66,5 +66,6 @@ public interface CustomerProfileAnalysisMapper extends BaseMapper<CustomerProfil

View File

@@ -87,5 +87,6 @@ public interface ICustomerProfileAnalysisService extends IService<CustomerProfil

View File

@@ -122,5 +122,6 @@ public class CustomerProfileAnalysisServiceImpl extends ServiceImpl<CustomerProf

View File

@@ -94,5 +94,6 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM

View File

@@ -94,5 +94,6 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR

View File

@@ -94,5 +94,6 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i