From 02373b97be92e57c3b65d428569b2209c72be748 Mon Sep 17 00:00:00 2001
From: 13405411873 <1994398261@qq.com>
Date: Mon, 3 Mar 2025 14:31:40 +0800
Subject: [PATCH] =?UTF-8?q?=E9=98=B6=E6=AE=B5=E6=80=A7=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
dc-App/pages/Chat/newChat.vue | 112 ++++----
dc-App/pages/busNavigation/busNavigation.nvue | 247 ++++++++++++++----
.../app/domain/response/BusLinesResponse.java | 4 +
.../java/com/dc/app/service/ChatService.java | 84 +++++-
.../system/controller/YoudaoController.java | 9 +
.../java/com/dc/system/domain/TtsRequest.java | 9 +
.../com/dc/system/service/YoudaoService.java | 7 +
.../system/service/impl/AmapServiceImpl.java | 39 ++-
.../impl/YoudaoServiceServiceImpl.java | 40 ++-
.../main/java/com/dc/system/until/AsrV2.java | 101 +++++++
.../java/com/dc/system/until/OcrUtil.java | 9 +
.../web/controller/tool/YOUDAOHttpUtil.java | 98 +++++++
.../common/utils/youdaoUtils/AuthV3Util.java | 32 ++-
.../dc/common/utils/youdaoUtils/FileUtil.java | 9 +-
14 files changed, 680 insertions(+), 120 deletions(-)
create mode 100644 dc-Vue/dc-admin/src/main/java/com/dc/system/domain/TtsRequest.java
create mode 100644 dc-Vue/dc-admin/src/main/java/com/dc/system/until/AsrV2.java
create mode 100644 dc-Vue/dc-admin/src/main/java/com/dc/web/controller/tool/YOUDAOHttpUtil.java
diff --git a/dc-App/pages/Chat/newChat.vue b/dc-App/pages/Chat/newChat.vue
index 84f17b6..d406688 100644
--- a/dc-App/pages/Chat/newChat.vue
+++ b/dc-App/pages/Chat/newChat.vue
@@ -1,11 +1,11 @@
-
+
{{info.title}}
-
+
{{lang}}
@@ -14,7 +14,7 @@
-
+
@@ -24,7 +24,7 @@
{{item.query}}
-
+
@@ -36,17 +36,19 @@
-
-
+
+
-
+
-
-
-
- Voice
- text
- {{item.answer}}
+
+
+
+
+ Voice
+
+
+ {{item.answer}}
@@ -70,6 +72,7 @@
} from './msgSocket'
import requestChat from '../../utils/requestChat'
import permision from "@/js_sdk/wa-permission/permission.js"
+ import request from '../../utils/request'
//音频播放
const innerAudioContext = uni.createInnerAudioContext();
// 录音
@@ -77,10 +80,11 @@
export default {
data() {
return {
+ audioSrc: '', // 用于存储音频的 URL
+ clickIdx:null,
//是否长按事件
- islongPress:false,
timer:null,//长按计时器
- show:false,
+ show:'0',
columns: [
['Arabic-阿拉伯语',
'German-德语',
@@ -146,40 +150,45 @@
submit,
},
methods: {
- longpress(){
- this.islongPress = true;
- this.show = true
- console.log("长按事件");
- },
- //点击事件
- clickSprink(){
+ async voiceTxt(text){
+ let res = await request({
+ url: 'youDaoApi/tts',
+ method: 'post',
+ data: {
+ q: text,
+ voiceName: this.lang ,
+ }
+ })
+ this.playBase64Mp3(res.data)
+ this.show = false
+
+ },
+ // 播放 base64 编码的 MP3 文件
+ playBase64Mp3(base64Data) {
+ innerAudioContext.src = config.baseUrl+base64Data; // 不推荐,仅用于演示
+ innerAudioContext.play();
+ // 注意:如果你使用的是音频组件,确保在模板中正确绑定和使用它
+ },
+ clickContent(index){
+ if(this.info.conversation=='Translator'){
+ // 非长按
+ this.show = '0'
+ this.clickIdx = null
+ }
+ },
+ //点击事件
+ clickSprink(index){
+ if(this.info.conversation=='Translator'){
// 非长按
- if(this.islongPress == false){
- console.log("点击事件");
- }else if(this.islongPress == true){
-
-
- console.log("长按事件",this.show);
-
- }
- },
- //手指触摸动作开始
- touchstart(){
- this.timer = setTimeout(()=>{
- this.longpress();
- },1000)
- },
- //手指触摸动作结束
- touchend(){
- //延时执行为了防止 click() 还未判断 islongPress 的值就被置为 fasle
- clearTimeout(this.timer);
setTimeout(() => {
- this.islongPress = false
- }, 200)
- },
+ this.show = '1'
+ this.clickIdx = index
+ }, 10); // 延时200毫秒,即0.2秒
+
+ }
+ },
// 回调参数为包含columnIndex、value、values
langConfirm(e) {
- console.log('confirm', e)
this.lang = e.value[0].split('-')[0]
this.langShow = false
},
@@ -221,30 +230,25 @@
this.goBottom()
uni.setStorageSync(this.storeList + '_' + this.info.conversation, this.messagesList)
}else{
- console.log('触发首页的消息回调', res);
if (res.data.indexOf("conversation_id") > -1) {
uni.setStorageSync(this.info.conversation, JSON.parse(res.data).conversation_id);
} else if (res.data.indexOf("workflow_finished") > -1) {
//代表结束
uni.setStorageSync(this.storeList + '_' + this.info.conversation, this.messagesList)
-
+
} else {
this.messagesList[this.messagesList.length - 1].answer = this.messagesList[this
.messagesList.length - 1].answer + res.data
this.goBottom()
}
}
-
+
})
}
},
//缓存中获取历史消息
getMessageByStore() {
- if (!uni.getStorageSync(this.info.conversation)) {
- return;
- }
-
let tempList = uni.getStorageSync(this.storeList + '_' + this.info.conversation)||[]
if (tempList && tempList.length > 30) {
//截取最新的30条
@@ -463,7 +467,7 @@
background: #3d3d3d;
display: flex;
align-items: center;
-
+
color: #fff;
border-radius: 8px;
}
@@ -681,4 +685,4 @@
align-items: center;
line-height: 29px;
}
-
\ No newline at end of file
+
diff --git a/dc-App/pages/busNavigation/busNavigation.nvue b/dc-App/pages/busNavigation/busNavigation.nvue
index 653e946..8b628ad 100644
--- a/dc-App/pages/busNavigation/busNavigation.nvue
+++ b/dc-App/pages/busNavigation/busNavigation.nvue
@@ -2,38 +2,40 @@
-
+
+
- 1 h22min
+ {{Number.parseInt(allData.duration/60)||0}}min
- Arrival time
- 1 h22min
+ walk distance
+ {{allData.walkingDistance?Number.parseFloat(allData.walkingDistance/1000).toFixed(2):0}}km
-
-
-
-
+
+
-
- Rail Transit Line 2
+
+
+ {{it.enName.split('(')[0]||''}}
+
+
- Walk 805 meters
- 5$
- 15 Stations
+ all cost
+ ¥{{allData.cost=='[]'?0:allData.cost}}
+
My Location
-
+
+
+
+
- Walk 621 meters (9 minutes)
+ Walk {{item.walking.distance}} meters ({{Number.parseInt(item.walking.duration/60)}} minutes)
- Walk
+ Walk
+
+
+
+
+
+
+
+
+
+ {{it.departureStop.enName}} station
+
+
+ {{it.enName}}
+
+
+
+
+ {{it.viaStops.length}} station ({{Number.parseInt(it.duration/60)}} min)
+
+
+ {{it.arrivalStop.enName}} station
+
+
+
+
+
+
+
+ destination
+
+
+
+
+
+
+
+
+
+
+ {{Number.parseInt(allData.duration/60)||0}}分钟
+
+
+ 步行距离
+ {{allData.walkingDistance?Number.parseFloat(allData.walkingDistance/1000).toFixed(2):0}}km
+
+
+
+
+
+
+
+
+ {{it.name.split('(')[0]||''}}
+
+
-
+
+
+
+
+ 总花费
+ ¥{{allData.cost}}
+
+
+
+
+
+
+
+ 我的位置
+
+
+
+
+
+
+
+ 步行 {{item.walking.distance}} 米 ({{Number.parseInt(item.walking.duration/60)}} 分钟)
+
+
+ 导航
+
+
+
+
@@ -65,31 +154,31 @@
- Zhudian Subway Station, Exit G
+ {{it.departureStop.name}} 站点
- Line 2
-
+ {{it.name}}
- Wangfuzhuang Direction
+
- 13 stops (33 min)
- 上车站 首06.02 末23.47
+ {{it.viaStops.length}} 站 ({{Number.parseInt(it.duration/60)}} 分钟)
+
- Wangfuzhuang Direction
+ {{it.arrivalStop.name}} 站点
-
-
-
-
-
- Start Navigation
+
+
+
+
+ 终点
+
+
@@ -100,13 +189,16 @@
export default {
data() {
return {
-
+ lang:'en',
translateY: 0,
longPressTimer: null, // 长按定时器
isDragging: false, // 是否正在拖动
colorList:[
- "#fcd803",
- "#009bc2"
+ "#f9d402",
+ "#009bc2",
+ "#000000",
+ "#c34100",
+ "#006a00",
],
//打车预估路线
polyline: [],
@@ -126,7 +218,8 @@
distance: 0,
duration: 0,
cost:0,
- points:[]
+ points:[],
+ allData:{}
}
},
@@ -143,7 +236,7 @@
},
computed: {
windowHeight() {
- return uni.getSystemInfoSync().windowHeight;
+ return uni.getSystemInfoSync().windowHeight/3;
},
windowWidth() {
return uni.getSystemInfoSync().windowWidth;
@@ -151,6 +244,37 @@
},
methods: {
+ changeLan(){
+ if(this.lang == 'en'){
+ this.lang = 'zh'
+ }else{
+ this.lang = 'en'
+ }
+ },
+ walkLine(data){
+ let endInfo = {}
+ endInfo.location = [data.endLocationLng, data.endLocationLat]
+ uni.getLocation({
+ // 谷歌使用wgs84 其他使用gcj02
+ type: 'gcj02', // 使用国测局坐标系
+ geocode: true,
+ success: function(res) {
+ let staInfo = {}
+ staInfo.location = [res.longitude, res.latitude]
+ uni.navigateTo({
+ url: '/pages/index/PedestrianNavigation?startPoint=' + staInfo
+ .location +
+ '&endPoint=' + endInfo.location
+ })
+ },
+ fail: function(err) {
+ uni.showToast({
+ title: 'Failed to get location',
+ icon: 'none'
+ })
+ }
+ });
+ },
upper(e) {
console.log('Scroll to top');
},
@@ -177,7 +301,7 @@
endLocationLat: this.endPoint[1],
}
}).then(res => {
-
+ that.allData = res.data
that.duration = res.data.duration/60
that.distance = res.data.walkingDistance/1000
that.cost = res.data.cost
@@ -252,7 +376,7 @@
that.markers.push({
id:busIt.departureStop.id,
label:{
- content:busIt.name,
+ content:busIt.enName,
fontSize:8,
color:'#145e07'
},
@@ -391,8 +515,9 @@
z-index: 99999;
}
.bz_icon{
- width: 100rpx;
- height: 40rpx;
+ box-sizing: border-box;
+ padding: 18rpx 18rpx;
+
border-radius: 8rpx ;
display: flex;
@@ -430,7 +555,7 @@
margin-right: 32rpx;
}
.c_b_box{
- margin: 28rpx 0rpx;
+ margin: 10rpx 0rpx;
flex-direction: row;
align-items: center;
justify-content: space-between;
@@ -447,7 +572,7 @@
.contenr_{
min-height: 160rpx;
position: fixed;
- bottom: 160rpx;
+ bottom: 0rpx;
width: 750rpx;
background: #fff;
@@ -474,6 +599,11 @@
.c_c_box{
margin-bottom: 16rpx;
}
+ .c_box{
+ box-sizing: border-box;
+ padding: 0px 32rpx;
+
+ }
.text_1{
font-size: 32rpx;
color: #333333;
@@ -489,6 +619,11 @@
font-size: 28rpx;
color: #FFFFFF;
}
+ .text_line{
+ font-weight: 500;
+ font-size: 23rpx;
+ color: #FFFFFF;
+ }
.text_4{
font-weight: 400;
font-size: 24rpx;
@@ -503,7 +638,7 @@
}
.c_c_title{
- width: 280rpx;
+ width: 260rpx;
height: 48rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
background: #fcd702;
@@ -513,7 +648,7 @@
margin: 0px 5rpx;
}
.contenr_bottom{
- margin-top: 40rpx;
+ // margin-top: 40rpx;
box-sizing: border-box;
padding: 32rpx;
padding-bottom: 0px;
@@ -521,7 +656,7 @@
}
.contenr_bottom_d{
box-sizing: border-box;
- padding: 32rpx;
+ padding: 11rpx;
padding-top: 0px;
flex-direction: row;
@@ -561,4 +696,26 @@
.botton_size{
margin-top: 100rpx;
}
+ .fy_icon{
+ position: fixed;
+ right: 15px;
+ top: 15px;
+ width: 80rpx;
+ height: 80rpx;
+ }
+ ::v-deep .amap-logo {
+ opacity: 0 !important;
+ }
+ ::v-deep .amap-copyright {
+ opacity: 0 !important;
+ }
+ ::v-deep .BMap_cpyCtrl {
+ display: none !important;
+ }
+ ::v-deep .anchorBL {
+ display: none !important;
+ }
+
+
+
\ No newline at end of file
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/app/domain/response/BusLinesResponse.java b/dc-Vue/dc-admin/src/main/java/com/dc/app/domain/response/BusLinesResponse.java
index 0d1e893..a36d7ed 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/app/domain/response/BusLinesResponse.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/app/domain/response/BusLinesResponse.java
@@ -6,6 +6,7 @@ import java.util.List;
@Data
public class BusLinesResponse {
private String name; // 公交路线名称
+ private String enName;
private String id; // 公交路线ID
private String type; // 公交类型
private int distance; // 行驶距离(米)
@@ -27,6 +28,7 @@ public class BusLinesResponse {
@Data
public static class DepartureStop {
private String name;
+ private String enName;
private String id;
/**
* 经度,不能为空
@@ -43,6 +45,7 @@ public class BusLinesResponse {
@Data
public static class ArrivalStop {
private String name;
+ private String enName;
private String id;
/**
* 经度,不能为空
@@ -59,6 +62,7 @@ public class BusLinesResponse {
@Data
public static class ViaStop {
private String name;
+ private String enName;
private String id;
/**
* 经度,不能为空
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/app/service/ChatService.java b/dc-Vue/dc-admin/src/main/java/com/dc/app/service/ChatService.java
index 2aa1784..c8db41c 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/app/service/ChatService.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/app/service/ChatService.java
@@ -6,14 +6,13 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+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.system.mapper.SysConfigMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,11 +21,55 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import static com.dc.system.until.AsrV2.*;
+
@Service
@Slf4j
public class ChatService {
@Resource
private ChatApi chatApi;
+ @Resource
+ SysConfigMapper sysConfigMapper;
+
+ static Map langMap = new HashMap() {{
+ put("Arabic", "ar");
+ put("Bahasa (Indonesia)", "in");
+ put("Cantonese", "yue");
+ put("Catalan", "ca");
+ put("Czech", "cs");
+ put("Danish", "da");
+ put("Dutch", "nl");
+ put("Dutch (Belgium)", "nl-BEL");
+ put("English", "en");
+ put("Finnish", "fi");
+ put("French", "fr");
+ put("French (Canada)", "fr-CAN");
+ put("German", "de");
+ put("Greek", "el");
+ put("Hebrew", "he");
+ put("Hindi", "hi");
+ put("Hungarian", "hu");
+ put("Italian", "it");
+ put("Japanese", "ja");
+ put("Korean", "ko");
+ put("Mandarin (China)", "zh-CHS");
+ put("Mandarin (Taiwan)", "zh-TWN");
+ put("Norwegian", "no");
+ put("Polish", "pl");
+ put("Portuguese (Brazil)", "pt-BRA");
+ put("Portuguese (Portugal)", "pt");
+ put("Romanian", "ro");
+ put("Russian", "ru");
+ put("Slovak", "sk");
+ put("Spanish (Castilian)", "es-ESP");
+ put("Spanish (Columbia)", "es-COL");
+ put("Spanish (Mexico)", "es-MEX");
+ put("Spanish", "es"); // 修正重复项
+ put("Swedish", "sv");
+ put("Thai", "th");
+ put("Turkish", "tr");
+ }};
+
private static Map sendFlagMap =new HashMap<>();
@Autowired
private RedisTemplate redisTemplate;
@@ -40,6 +83,39 @@ public class ChatService {
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 params = new HashMap();
+ 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);
+ }
+
+ }
String url = "http://flintown.cn:8080/v1/chat-messages";
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(mediaType, requestData.toJSONString());
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/controller/YoudaoController.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/controller/YoudaoController.java
index 1be33a5..3d84585 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/system/controller/YoudaoController.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/controller/YoudaoController.java
@@ -2,10 +2,12 @@ package com.dc.system.controller;
import com.alibaba.fastjson2.JSONObject;
import com.dc.common.core.domain.AjaxResult;
+import com.dc.system.domain.TtsRequest;
import com.dc.system.service.YoudaoService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
@@ -21,5 +23,12 @@ public class YoudaoController {
List res = youdaoService.textOcr(params.getString("base64"));
return AjaxResult.success(res);
}
+
+
+ @PostMapping("tts")
+ public AjaxResult tts(@RequestBody TtsRequest ttsRequest, HttpServletResponse response) throws IOException, NoSuchAlgorithmException {
+ String res = youdaoService.tts(ttsRequest,response);
+ return AjaxResult.success("ok",res);
+ }
}
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/domain/TtsRequest.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/domain/TtsRequest.java
new file mode 100644
index 0000000..86287ad
--- /dev/null
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/domain/TtsRequest.java
@@ -0,0 +1,9 @@
+package com.dc.system.domain;
+
+import lombok.Data;
+
+@Data
+public class TtsRequest {
+ private String q;
+ private String voiceName;
+}
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/service/YoudaoService.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/service/YoudaoService.java
index 5f631f9..792a65a 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/system/service/YoudaoService.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/service/YoudaoService.java
@@ -1,9 +1,16 @@
package com.dc.system.service;
+import com.dc.system.domain.TtsRequest;
+
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
public interface YoudaoService {
List textOcr(String base64) throws NoSuchAlgorithmException, IOException;
+ String tts(TtsRequest ttsRequest, HttpServletResponse response) throws IOException, NoSuchAlgorithmException;
+
+
+
}
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/AmapServiceImpl.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/AmapServiceImpl.java
index 2711438..ccf4704 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/AmapServiceImpl.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/AmapServiceImpl.java
@@ -15,10 +15,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
@Slf4j
@Service
@@ -71,6 +68,40 @@ public class AmapServiceImpl implements AmapService {
}
res.setSegments(segments);
// 路线翻译
+ List names = new ArrayList<>();
+ for (BusTransitResponse.Segment segment : res.getSegments()) {
+ List bus = segment.getBus();
+ for (BusLinesResponse busLinesResponse : bus) {
+ names.add(busLinesResponse.getName());
+ names.add(busLinesResponse.getDepartureStop().getName());
+ names.add(busLinesResponse.getArrivalStop().getName());
+ List viaStops = busLinesResponse.getViaStops();
+ for (BusLinesResponse.ViaStop viaStop : viaStops) {
+ names.add(viaStop.getName());
+ }
+ }
+ }
+
+ // 调用翻译接口逐个翻译每个字段
+ if (!names.isEmpty()) {
+ String translatedInstruction = mapAndFy.translateNames(names);
+ String tempStr = mapAndFy.extractTranslations(translatedInstruction);
+ List tempList = Arrays.asList(tempStr.split("%&&"));
+ int i=0;
+ for (BusTransitResponse.Segment segment : res.getSegments()) {
+ List bus = segment.getBus();
+ for (BusLinesResponse busLinesResponse : bus) {
+ busLinesResponse.setEnName(tempList.get(i++));
+ busLinesResponse.getDepartureStop().setEnName(tempList.get(i++));
+ busLinesResponse.getArrivalStop().setEnName(tempList.get(i++));
+ List viaStops = busLinesResponse.getViaStops();
+ for (BusLinesResponse.ViaStop viaStop : viaStops) {
+ viaStop.setEnName(tempList.get(i++));
+ }
+ }
+ }
+
+ }
return res;
}
private AmapResponse dealWalk(JSONObject walking) throws Exception {
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/YoudaoServiceServiceImpl.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/YoudaoServiceServiceImpl.java
index 7896f28..9fbff4c 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/YoudaoServiceServiceImpl.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/service/impl/YoudaoServiceServiceImpl.java
@@ -3,22 +3,22 @@ package com.dc.system.service.impl;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
+import com.dc.common.config.DCConfig;
import com.dc.common.utils.youdaoUtils.AuthV3Util;
+import com.dc.common.utils.youdaoUtils.FileUtil;
+import com.dc.system.domain.TtsRequest;
import com.dc.system.mapper.SysConfigMapper;
import com.dc.system.service.YoudaoService;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.util.EntityUtils;
+import com.dc.web.controller.tool.YOUDAOHttpUtil;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Base64;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -27,10 +27,12 @@ import java.util.List;
import java.util.Map;
import static com.dc.system.until.OcrUtil.createRequestParams;
+import static com.dc.system.until.OcrUtil.createTTSParams;
@Service
public class YoudaoServiceServiceImpl implements YoudaoService {
private final String orcPath = "https://openapi.youdao.com/ocrapi";
+ private final String ttsPath = "https://openapi.youdao.com/ttsapi";
@Resource
SysConfigMapper sysConfigMapper;
@Override
@@ -58,5 +60,23 @@ public class YoudaoServiceServiceImpl implements YoudaoService {
return result;
}
+ @Override
+ public String tts(TtsRequest ttsRequest, HttpServletResponse response) throws IOException, NoSuchAlgorithmException {
+ ttsRequest.setVoiceName("youxiaomei");
+ List result = new ArrayList<>();
+ String appKey = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_KEY");
+ String appSecret = sysConfigMapper.getcheckConfigKeyUnique("YOUDAO_APP_SECRET");
+ // 添加请求参数
+ Map params = createTTSParams(ttsRequest.getQ(), ttsRequest.getVoiceName());
+ // 添加鉴权相关参数
+ AuthV3Util.addTTSAuthParams(appKey, appSecret, params);
+ byte[] post = YOUDAOHttpUtil.doPost(ttsPath, null, params, "audio");
+ // 上传文件路径
+ String tempPath = java.util.UUID.randomUUID().toString().replace("-", "");
+ String filePath = DCConfig.getUploadPath()+File.separator+"tts"+File.separator +tempPath +".mp3";
+ FileUtil.saveFile(filePath, post, false);
+ return "profile/upload/tts"+File.separator +tempPath +".mp3";
+ }
+
}
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/until/AsrV2.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/until/AsrV2.java
new file mode 100644
index 0000000..4aa37b3
--- /dev/null
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/until/AsrV2.java
@@ -0,0 +1,101 @@
+package com.dc.system.until;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.UUID;
+import java.util.Base64;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+public class AsrV2 {
+ public static String truncate(String q) {
+ if (q == null) {
+ return null;
+ }
+ int len = q.length();
+ String result;
+ return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
+ }
+
+ public static String loadAsBase64(String filename) {
+ InputStream in = null;
+ byte[] data = null;
+ try {
+ in = new FileInputStream(filename);
+ data = new byte[in.available()];
+ in.read(data);
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return Base64.getEncoder().encodeToString(data);
+ }
+
+ public static String doRequest(String url, Map requestParams) throws Exception{
+ String result = null;
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ HttpPost httpPost = new HttpPost(url);
+ List params = new ArrayList();
+ for (String key : requestParams.keySet()) {
+ params.add(new BasicNameValuePair(key, requestParams.get(key)));
+ }
+ httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
+ CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
+ try {
+ HttpEntity httpEntity = httpResponse.getEntity();
+ result = EntityUtils.toString(httpEntity, "utf-8");
+ EntityUtils.consume(httpEntity);
+ } finally {
+ try {
+ if (httpResponse != null) {
+ httpResponse.close();
+ }
+ } catch(IOException e) {
+ System.out.println("## release resouce error ##" + e);
+ }
+ }
+ return result;
+ }
+
+ public static String getDigest(String string) {
+ if (string == null) {
+ return null;
+ }
+ char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ byte[] btInput = string.getBytes(UTF_8);
+ try {
+ MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
+ mdInst.update(btInput);
+ byte[] md = mdInst.digest();
+ int j = md.length;
+ char str[] = new char[j * 2];
+ int k = 0;
+ for (byte byte0 : md) {
+ str[k++] = hexDigits[byte0 >>> 4 & 0xf];
+ str[k++] = hexDigits[byte0 & 0xf];
+ }
+ return new String(str);
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ }
+}
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/system/until/OcrUtil.java b/dc-Vue/dc-admin/src/main/java/com/dc/system/until/OcrUtil.java
index e5a166d..d7ea7b1 100644
--- a/dc-Vue/dc-admin/src/main/java/com/dc/system/until/OcrUtil.java
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/system/until/OcrUtil.java
@@ -31,4 +31,13 @@ public class OcrUtil {
put("imageType", imageType);
}};
}
+
+
+
+ public static Map createTTSParams(String q, String voiceName) throws IOException {
+ return new HashMap() {{
+ put("q", new String[]{q});
+ put("voiceName", new String[]{voiceName} );
+ }};
+ }
}
diff --git a/dc-Vue/dc-admin/src/main/java/com/dc/web/controller/tool/YOUDAOHttpUtil.java b/dc-Vue/dc-admin/src/main/java/com/dc/web/controller/tool/YOUDAOHttpUtil.java
new file mode 100644
index 0000000..b784c45
--- /dev/null
+++ b/dc-Vue/dc-admin/src/main/java/com/dc/web/controller/tool/YOUDAOHttpUtil.java
@@ -0,0 +1,98 @@
+package com.dc.web.controller.tool;
+
+import okhttp3.*;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Objects;
+
+public class YOUDAOHttpUtil {
+
+ private static OkHttpClient httpClient = new OkHttpClient.Builder().build();
+
+ public static byte[] doGet(String url, Map header, Map 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 header, Map 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 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 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 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;
+ }
+}
diff --git a/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/AuthV3Util.java b/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/AuthV3Util.java
index 774ef8a..3f9eddf 100644
--- a/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/AuthV3Util.java
+++ b/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/AuthV3Util.java
@@ -1,5 +1,8 @@
package com.dc.common.utils.youdaoUtils;
+import cn.hutool.core.util.ObjectUtil;
+import org.apache.commons.lang3.StringUtils;
+
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
@@ -21,7 +24,14 @@ public class AuthV3Util {
*/
public static void addAuthParams(String appKey, String appSecret, Map paramsMap)
throws NoSuchAlgorithmException {
- String qArray = paramsMap.get("img").toString();
+ String qArray="";
+ if(ObjectUtil.isNotEmpty(paramsMap.get("q"))){
+ qArray = paramsMap.get("q").toString();
+ }
+
+ if (StringUtils.isEmpty(qArray)) {
+ qArray = paramsMap.get("img").toString();
+ }
String salt = UUID.randomUUID().toString();
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String sign = calculateSign(appKey, appSecret, qArray, salt, curtime);
@@ -32,6 +42,26 @@ public class AuthV3Util {
paramsMap.put("sign",sign);
}
+ public static void addTTSAuthParams(String appKey, String appSecret, Map 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)
diff --git a/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/FileUtil.java b/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/FileUtil.java
index 5ebdc36..fcb7ceb 100644
--- a/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/FileUtil.java
+++ b/dc-Vue/dc-common/src/main/java/com/dc/common/utils/youdaoUtils/FileUtil.java
@@ -21,9 +21,14 @@ public class FileUtil {
public static String saveFile(String path, byte[] data, boolean needDecode) throws IOException {
File file = new File(path);
- if (!file.exists()) {
- file.createNewFile();
+ if (!file.exists())
+ {
+ if (!file.getParentFile().exists())
+ {
+ file.getParentFile().mkdirs();
+ }
}
+ file.createNewFile();
byte[] bytes = data;
if (needDecode) {
String base64 = new String(data, StandardCharsets.UTF_8);