This commit is contained in:
许允枞 2025-03-07 17:58:40 +08:00
parent c125ef96b9
commit a6a14e8ebb
6 changed files with 464 additions and 51 deletions

View File

@ -4,7 +4,11 @@ import com.alibaba.fastjson2.JSONObject;
import com.dc.app.domain.enums.PlatformTypeEnum;
import com.dc.app.domain.request.GetDcTypeRequest;
import com.dc.app.domain.response.NearbyDriverResponse;
import com.dc.common.config.DCConfig;
import com.dc.common.core.domain.AjaxResult;
import com.dc.common.utils.file.FileUploadUtils;
import com.dc.common.utils.file.FileUtils;
import com.dc.framework.config.ServerConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
@ -12,10 +16,14 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.io.File;
import java.util.List;
import static com.dc.system.until.AsrV2.loadAsBase64;
@Slf4j
@RestController
@RequestMapping("/base64Api")
@ -24,6 +32,9 @@ public class Base64Api {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private ServerConfig serverConfig;
@PostMapping("inputBase64")
public AjaxResult inputBase64(@RequestBody JSONObject query) {
//创建uuid作为key存储 query中的base64
@ -31,4 +42,32 @@ public class Base64Api {
redisTemplate.opsForValue().set(uuid,query.getString("base64"));
return AjaxResult.success("success",uuid);
}
/**
* 通用上传请求单个
*/
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
{
// 上传文件路径
String filePath = DCConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
fileName = fileName.replace("/profile/upload", "");
String url = serverConfig.getUrl() + fileName;
// 获取文件的 Base64 编码
String path = filePath + File.separator + fileName;
path = path.replace("profile", "");
String base64 = loadAsBase64(path);
AjaxResult ajax = AjaxResult.success();
ajax.put("base64", base64);
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
}

View File

@ -0,0 +1,48 @@
package com.dc.app.controller;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dc.app.service.ChatService;
import com.dc.common.core.domain.AjaxResult;
import com.dc.system.mapper.SysConfigMapper;
import com.dc.system.until.AuthV3Util;
import com.dc.system.until.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: 聊天界面
* @Author: 86187
* @Date: 2025/03/06 15:37
* @Version: 1.0
*/
@RestController
@RequestMapping("/chatHttpApi")
public class ChatHttpApi {
@Autowired
private ChatService chatService;
/**
* 翻译
* @param requestData
* @return
* @throws Exception
*/
@PostMapping("/getChatInfo")
public AjaxResult getChatInfo(@RequestBody Map<String, String> requestData) throws Exception {
if ("Chinese".equals(requestData.get("lang").toString())) {
return AjaxResult.success(requestData.get("q").toString());
}
requestData.put("to", "zh-CHS");
return AjaxResult.success(chatService.textTranslators(requestData));
}
}

View File

@ -1,18 +1,20 @@
package com.dc.app.service;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dc.app.controller.ChatApi;
import com.dc.common.core.domain.AjaxResult;
import com.dc.system.mapper.SysConfigMapper;
import com.dc.system.until.AuthV3Util;
import com.dc.system.until.HttpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
@ -68,9 +70,10 @@ public class ChatService {
put("Swedish", "sv");
put("Thai", "th");
put("Turkish", "tr");
put("Chinese", "zh-CHS");
}};
private static Map<String,String> sendFlagMap =new HashMap<>();
private static Map<String, String> sendFlagMap = new HashMap<>();
@Autowired
private RedisTemplate<String, String> redisTemplate;
private final OkHttpClient client = new OkHttpClient.Builder()
@ -80,44 +83,102 @@ public class ChatService {
public void sendChatRequest(JSONObject requestData) {
try {
if (requestData.getJSONObject("inputs").getString("type").equals("image")||requestData.getJSONObject("inputs").getString("type").equals("voice")){
requestData.put("query",redisTemplate.opsForValue().get(requestData.getString("query")));
}
if (requestData.getJSONObject("inputs").getString("type").equals("voice")){
String appKey = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_KEY");
String appSecret = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_SECRET");
//如果是语言则直接走有道自己进行翻译 不需要走大模型
Map<String, String> params = new HashMap<String, String>();
String langType = langMap.get(requestData.getJSONObject("inputs").getString("lang"));
params.put("appKey", appKey);
String q = requestData.getString("query");
params.put("q", q);
params.put("format", "wav");
params.put("rate", "16000");
params.put("channel", "1");
params.put("docType", "json");
params.put("type", "1");
String salt = UUID.randomUUID().toString();
params.put("salt", salt);
params.put("langType", langType);
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
params.put("curtime", curtime);
String signStr = appKey + truncate(q) + salt + curtime + appSecret;
String sign = getDigest(signStr);
params.put("sign", sign);
params.put("signType", "v2");
JSONObject res = JSONObject.parseObject(doRequest("https://openapi.youdao.com/asrapi", params));
if(res.getString("errorCode").equals("0")){
JSONArray jsonArray = res.getJSONArray("result");
requestData.put("query",jsonArray.get(0));
JSONObject temp =new JSONObject();
temp.put("type","text");
requestData.put("inputs",temp);
}
Map<String, String> requestMap = new HashMap<>();
requestMap.put("q", requestData.getString("query"));
requestMap.put("lang", requestData.getJSONObject("inputs").getString("sayLang"));
requestMap.put("to", langMap.get(requestData.getJSONObject("inputs").getString("lang")));
if ("Bearer app-EcJaT2EkUjHNJsax9SwESQuK".equals(requestData.getString("token"))) {
if (requestData.getJSONObject("inputs").getString("type").equals("image")) {// || requestData.getJSONObject("inputs").getString("type").equals("voice")
// requestData.put("query", redisTemplate.opsForValue().get(requestData.getString("query")));
requestMap.put("q", redisTemplate.opsForValue().get(requestData.getString("query")));
JSONObject jsonObject = imageTranslators(requestMap);
String answer = jsonObject.getString("render_image");
JSONArray resRegionsArray = jsonObject.getJSONArray("resRegions");
List<String> javaList = resRegionsArray.toJavaList(String.class);
String tranContent = "";
for (String s : javaList) {
JSONObject jsonObject1 = JSONObject.parseObject(s);
String string = jsonObject1.getString("tranContent");
tranContent = string + "\n" + tranContent;
}
Map map = new HashMap();
map.put("answer", answer);
map.put("tranContent", tranContent);
// Map 转换为 JSON
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(map);
chatApi.sendMessage(jsonString, requestData.getString("socketId"));
return;
}
if (requestData.getJSONObject("inputs").getString("type").equals("voice")) {
String sayLang = requestData.getJSONObject("inputs").getString("sayLang");
String lang = requestData.getJSONObject("inputs").getString("lang");
String appKey = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_KEY");
String appSecret = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_SECRET");
//如果是语言则直接走有道自己进行翻译 不需要走大模型
Map<String, String> params = new HashMap<String, String>();
params.put("appKey", appKey);
String q = redisTemplate.opsForValue().get(requestData.getString("query"));
params.put("q", q);
params.put("format", "mp3");
params.put("rate", "16000");
params.put("channel", "1");
params.put("docType", "json");
params.put("type", "1");
String salt = UUID.randomUUID().toString();
params.put("salt", salt);
params.put("langType", requestData.getJSONObject("inputs").getString("sayLang"));
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
params.put("curtime", curtime);
String signStr = appKey + truncate(q) + salt + curtime + appSecret;
String sign = getDigest(signStr);
params.put("sign", sign);
params.put("signType", "v2");
JSONObject res = JSONObject.parseObject(doRequest("https://openapi.youdao.com/asrapi", params));
if (res.getString("errorCode").equals("0")) {
JSONArray result = res.getJSONArray("result");
if (result != null && !result.isEmpty()) {
String resultStr = String.join(",", result.toJavaList(String.class));
JSONArray jsonArray = res.getJSONArray("result");
requestData.put("query", resultStr);
JSONObject temp = new JSONObject();
temp.put("type", "text");
temp.put("lang", requestData.getJSONObject("inputs").getString("lang"));
requestData.put("inputs", temp);
//翻译
Map<String, String[]> data = new HashMap<>();
data.put("q", new String[]{resultStr});
data.put("from", new String[]{sayLang});
data.put("to", new String[]{langMap.get(lang).toString()});
AuthV3Util.addAuthParams(appKey, appSecret, data);
byte[] result1 = HttpUtil.doPost("https://openapi.youdao.com/api", null, data, "application/json");
// 打印返回结果
if (result != null) {
JSONObject jsonObject = JSONObject.parseObject(new String(result1, StandardCharsets.UTF_8));
// 获取translation数组
JSONArray translationArray = jsonObject.getJSONArray("translation");
String join = String.join(",", translationArray.toJavaList(String.class));
chatApi.sendMessage(join, requestData.getString("socketId"));
}
}
}
return;
} else if (requestData.getJSONObject("inputs").getString("type").equals("text")) {
try {
String result = textTranslators(requestMap);
chatApi.sendMessage(result, requestData.getString("socketId"));
} catch (Exception e) {
e.printStackTrace();
} finally {
return;
}
}
return;
}
String url = "http://flintown.cn:8080/v1/chat-messages";
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
log.info("Request body: {}", requestData.toJSONString());
RequestBody body = RequestBody.create(mediaType, requestData.toJSONString());
Request request = new Request.Builder()
@ -168,8 +229,20 @@ public class ChatService {
showToast("Request failed");
}
}
public static boolean base64ToFile(String base64, String filePath) {
try (FileOutputStream fos = new FileOutputStream(filePath)) {
byte[] decodedBytes = Base64.getDecoder().decode(base64);
fos.write(decodedBytes);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
// 处理 SSE 事件
private void processSseEvent(String event,String socketId) {
private void processSseEvent(String event, String socketId) {
if (event.startsWith("data: ")) {
String data = event.substring("data: ".length()).trim();
if (!data.isEmpty()) {
@ -181,16 +254,16 @@ public class ChatService {
chatApi.sendMessage(answer, socketId);
}
if (jsonData.containsKey("conversation_id")&&sendFlagMap.get(socketId).equals("0")) {
if (jsonData.containsKey("conversation_id") && sendFlagMap.get(socketId).equals("0")) {
String conversation_id = jsonData.getString("conversation_id");
System.out.println("New conversation_id: " + conversation_id);
JSONObject res =new JSONObject();
res.put("conversation_id",conversation_id);
JSONObject res = new JSONObject();
res.put("conversation_id", conversation_id);
chatApi.sendMessage(JSONObject.toJSONString(res), socketId);
sendFlagMap.put(socketId,"1");
sendFlagMap.put(socketId, "1");
}
if (jsonData.containsKey("event")&&jsonData.getString("event").equals("workflow_finished")) {
String answer ="workflow_finished";
if (jsonData.containsKey("event") && jsonData.getString("event").equals("workflow_finished")) {
String answer = "workflow_finished";
System.out.println("end answer: " + answer);
chatApi.sendMessage(answer, socketId);
@ -199,18 +272,17 @@ public class ChatService {
System.out.println("Parse error: " + e.getMessage());
}
}
}else{
} else {
try {
JSONObject jsonObject = JSONObject.parseObject(event);
if (jsonObject.getString("event").equals("message")){
if (jsonObject.getString("event").equals("message")) {
JSONObject answer1 = jsonObject.getJSONObject("answer");
String response = answer1.getString("response");
System.out.println("New answer: " + response);
chatApi.sendMessage(response, socketId);
}
}catch (Exception e){
} catch (Exception e) {
}
}
@ -222,6 +294,66 @@ public class ChatService {
System.out.println("Toast: " + message);
}
/**
* 有道翻译(文本)
*
* @param requestData
* @return
* @throws Exception
*/
public String textTranslators(Map<String, String> requestData) throws Exception {
requestData.put("url", "https://openapi.youdao.com/api");
JSONObject jsonObject = translatorsCommon(requestData);
// 获取translation数组
JSONArray translationArray = jsonObject.getJSONArray("translation");
return String.join(",", translationArray.toJavaList(String.class));
}
/**
* 有道翻译(图片)
*
* @param requestData
* @return
* @throws Exception
*/
public JSONObject imageTranslators(Map<String, String> requestData) throws Exception {
requestData.put("url", "https://openapi.youdao.com/ocrtransapi");
requestData.put("render", "1");
JSONObject jsonObject = translatorsCommon(requestData);
return jsonObject;
}
/**
* 有道通用调用接口
*
* @param requestData 请求数据
* @return
* @throws Exception
*/
public JSONObject translatorsCommon(Map<String, String> requestData) throws Exception {
String appKey = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_KEY");
String appSecret = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_SECRET");
//翻译
Map<String, String[]> data = new HashMap<>();
data.put("q", new String[]{requestData.get("q")});
data.put("from", new String[]{requestData.get("lang")});
if (requestData.get("to") != null) {
data.put("to", new String[]{requestData.get("to")});
}
// 图片翻译时需要的参数
if (requestData.get("render") != null) {
data.put("render", new String[]{requestData.get("render")});
}
AuthV3Util.addAuthParams(appKey, appSecret, data);
byte[] result1 = HttpUtil.doPost(requestData.get("url"), null, data, "application/json");
// 打印返回结果
if (result1 != null) {
return JSONObject.parseObject(new String(result1, StandardCharsets.UTF_8));
}
return null;
}
public static void main(String[] args) {
ChatService chatService = new ChatService();

View File

@ -0,0 +1,90 @@
package com.dc.system.until;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.UUID;
public class AuthV3Util {
/**
* 添加鉴权相关参数 -
* appKey : 应用ID
* salt : 随机值
* curtime : 当前时间戳()
* signType : 签名版本
* sign : 请求签名
*
* @param appKey 您的应用ID
* @param appSecret 您的应用密钥
* @param paramsMap 请求参数表
*/
public static void addAuthParams(String appKey, String appSecret, Map<String, String[]> paramsMap)
throws NoSuchAlgorithmException {
String[] qArray = paramsMap.get("q");
if (qArray == null) {
qArray = paramsMap.get("img");
}
StringBuilder q = new StringBuilder();
for (String item : qArray) {
q.append(item);
}
String salt = UUID.randomUUID().toString();
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String sign = calculateSign(appKey, appSecret, q.toString(), salt, curtime);
paramsMap.put("appKey", new String[]{appKey});
paramsMap.put("salt", new String[]{salt});
paramsMap.put("curtime", new String[]{curtime});
paramsMap.put("signType", new String[]{"v3"});
paramsMap.put("sign", new String[]{sign});
}
/**
* 计算鉴权签名 -
* 计算方式 : sign = sha256(appKey + input(q) + salt + curtime + appSecret)
*
* @param appKey 您的应用ID
* @param appSecret 您的应用密钥
* @param q 请求内容
* @param salt 随机值
* @param curtime 当前时间戳()
* @return 鉴权签名sign
*/
public static String calculateSign(String appKey, String appSecret, String q, String salt, String curtime)
throws NoSuchAlgorithmException {
String strSrc = appKey + getInput(q) + salt + curtime + appSecret;
return encrypt(strSrc);
}
private static String encrypt(String strSrc) throws NoSuchAlgorithmException {
byte[] bt = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bt);
byte[] bts = md.digest();
StringBuilder des = new StringBuilder();
for (byte b : bts) {
String tmp = (Integer.toHexString(b & 0xFF));
if (tmp.length() == 1) {
des.append("0");
}
des.append(tmp);
}
return des.toString();
}
private static String getInput(String input) {
if (input == null) {
return null;
}
String result;
int len = input.length();
if (len <= 20) {
result = input;
} else {
String startStr = input.substring(0, 10);
String endStr = input.substring(len - 10, len);
result = startStr + len + endStr;
}
return result;
}
}

View File

@ -0,0 +1,103 @@
package com.dc.system.until;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
public class HttpUtil {
private static OkHttpClient httpClient = new OkHttpClient.Builder().build();
public static byte[] doGet(String url, Map<String, String[]> header, Map<String, String[]> params, String expectContentType) {
Request.Builder builder = new Request.Builder();
addHeader(builder, header);
addUrlParam(builder, url, params);
return requestExec(builder.build(), expectContentType);
}
public static byte[] doPost(String url, Map<String, String[]> header, Map<String, String[]> body, String expectContentType) {
Request.Builder builder = new Request.Builder().url(url);
addHeader(builder, header);
addBodyParam(builder, body, "POST");
return requestExec(builder.build(), expectContentType);
}
private static void addHeader(Request.Builder builder, Map<String, String[]> header) {
if (header == null) {
return;
}
for (String key : header.keySet()) {
String[] values = header.get(key);
if (values != null) {
for (String value : values) {
builder.addHeader(key, value);
}
}
}
}
private static void addUrlParam(Request.Builder builder, String url, Map<String, String[]> params) {
if (params == null) {
return;
}
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
for (String key : params.keySet()) {
String[] values = params.get(key);
if (values != null) {
for (String value : values) {
urlBuilder.addQueryParameter(key, value);
}
}
}
builder.url(urlBuilder.build());
}
private static void addBodyParam(Request.Builder builder, Map<String, String[]> body, String method) {
if (body == null) {
return;
}
FormBody.Builder formBodyBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
for (String key : body.keySet()) {
String[] values = body.get(key);
if (values != null) {
for (String value : values) {
formBodyBuilder.add(key, value);
}
}
}
builder.method(method, formBodyBuilder.build());
}
private static byte[] requestExec(Request request, String expectContentType) {
Objects.requireNonNull(request, "okHttp request is null");
try (Response response = httpClient.newCall(request).execute()) {
if (response.code() == 200) {
ResponseBody body = response.body();
if (body != null) {
String contentType = response.header("Content-Type");
if (contentType != null && !contentType.contains(expectContentType)) {
String res = new String(body.bytes(), StandardCharsets.UTF_8);
System.out.println(res);
return null;
}
return body.bytes();
}
System.out.println("response body is null");
} else {
System.out.println("request failed, http code: " + response.code());
}
} catch (IOException ioException) {
System.out.println("request exec error: " + ioException.getMessage());
}
return null;
}
}

View File

@ -36,7 +36,8 @@ public class MimeTypeUtils
// 视频格式
"mp4", "avi", "rmvb",
// pdf
"pdf" };
"pdf",
"mp3"};
public static String getExtension(String prefix)
{