fix: 逻辑修改

This commit is contained in:
white 2024-09-27 13:24:02 +08:00
parent 849fc15748
commit d596b818e2
16 changed files with 932 additions and 809 deletions

View File

@ -463,7 +463,9 @@
this.$store.commit('api/setUserInfo', res); this.$store.commit('api/setUserInfo', res);
}); });
this.onRefresh(); uni.reLaunch({
url: '/pages/index/index'
})
} }
} }
} }

View File

@ -38,18 +38,24 @@
style="width: 100% height: 10px"> style="width: 100% height: 10px">
</audio> </audio>
<div class="status">
<div class="btn">正在听…</div>
</div>
<div id="AiButton"> <div id="AiButton">
<!-- 录制 --> <!-- 录制 -->
<img class="startRec" src="https://img.agrimedia.cn/bmsc/apps/start-tuya.png"> <div class="buttons startRec">开始</div>
<!-- 录制中 --> <!-- 录制中 -->
<img class="runRec" src="https://img.agrimedia.cn/bmsc/apps/runnig-tuya.png"> <div class="buttons runRec">暂停</div>
<!-- 停止 --> <!-- 停止 -->
<img class="endRec" src="https://img.agrimedia.cn/bmsc/apps/end-tuya.png"> <div class="buttons endRec">停止</div>
</div> </div>
<!-- 讯飞测试 --> <!-- 讯飞测试 -->
<div style="opacity: 1"> <div class="voice">
<div class="voice-box"> <div class="voice-box scroll-text">
<input class="voice-input" type="search" name="voice" id="voice-txt" style="pointer-events: none"/> <input class="voice-input" type="search" name="voice" id="voice-txt" style="pointer-events: none"/>
</div> </div>
</div> </div>
@ -141,6 +147,11 @@
const speakingTimeInSeconds = speakingTime * 60; const speakingTimeInSeconds = speakingTime * 60;
return speakingTimeInSeconds; return speakingTimeInSeconds;
} }
// 映射的字段
function Reflection(str) {
}
</script> </script>
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
@ -152,7 +163,6 @@
bloodOxygen: "血氧", bloodOxygen: "血氧",
bloodPressure: '血压', bloodPressure: '血压',
bloodLiquid: "血脂", bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率', pulseReat: '心率',
bodyTemperature: '体温', bodyTemperature: '体温',
ECGData: '心电图', ECGData: '心电图',
@ -220,6 +230,9 @@
// 个人信息 // 个人信息
var user = userInfo(JSON.parse(getURLParameter('user'))); var user = userInfo(JSON.parse(getURLParameter('user')));
var apitoken = getURLParameter('token');
var deviceId = getURLParameter('deviceId');
// 获取微软token // 获取微软token
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", { fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
@ -278,117 +291,107 @@
this.stop(); this.stop();
// voice.stop(); // voice.stop();
const params = { msg: text } const params = { msg: text };
/* // 判断关键字是否存在
* 拿到匹配的文字下标 const result = parseHealthQuery(params.msg);
*/ if (result) {
DetailDay(result.dataKey, result.date).then(res => {
var QSindex = containsKeywordRegex(params.msg); let TargetData = res.data.data;
if (QSindex == 0) {
const obj = arrayOfObjects.filter(item => item.type == "bloodGlucose"); var QSindex = containsKeywordRegex(params.msg);
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升` Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)},data_msg为值hour_minute为检测时间 #限制回复用户的内容中不要出现Null。#限制:回复不要带英文,要都转化成汉语。#限制监测结果为Null的数据不做分析回复。`
} else {
speed(`血糖数据为空, 请连接或同步设备数据`) /*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
endRec.style.opacity = 'none';
}
};
xhr.send(data);
isCallbackExecuted = true;
return return
} })
} } else {
// 如果不存在关键字,就直接走下面
if (QSindex == 1) {
const obj = arrayOfObjects.filter(item => item.type == "SleepDatas");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近睡眠时长为${minutesToHoursMinutesStringSimplified(obj[0].data_msg[0].sleepTotalTime)}分钟`
} else {
speed(`睡眠数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 2) {
const obj = arrayOfObjects.filter(item => item.type == "bloodOxygen");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
} else {
speed(`血氧数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 3) {
const obj = arrayOfObjects.filter(item => item.type == "bloodPressure");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
} else {
speed(`血压数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 4 || QSindex == 11) {
const obj = arrayOfObjects.filter(item => item.type == "bloodLiquid");
if (obj[0].data_msg.cholesterol) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血脂状况为,
尿酸为${obj[0].data_msg.uricAcidVal/10},
总胆固醇为${obj[0].data_msg.cholesterol/100},
甘油三酯为${obj[0].data_msg.triacylglycerol/100},
高密度脂蛋白为${obj[0].data_msg.highDensity/100},
低密度脂蛋白为${obj[0].data_msg.lowDensity/100}, `
} else {
speed(`血脂数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 6) {
const obj = arrayOfObjects.filter(item => item.type == "pulseReat");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的心率为${obj[0].data_msg[0]}, `
} else {
speed(`心率数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 7) {
const obj = arrayOfObjects.filter(item => item.type == "bodyTemperature");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
} else {
speed(`体温数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 8) {
const obj = arrayOfObjects.filter(item => item.type == "ECGData");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
} else {
speed(`心电图数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 9) {
const obj = arrayOfObjects.filter(item => item.type == "bodyData");
if (obj[0].data_msg.BMI) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
} else {
speed(`身体成分数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 10) {
const obj = arrayOfObjects.filter(item => item.type == "stepIndex");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的运动为${obj[0].data_msg.step}步数,
${obj[0].data_msg.calorie/10}千卡,
${obj[0].data_msg.distance/1000}公里`
} else {
speed(`运动数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 99999) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true); xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
var data = JSON.stringify({ var data = JSON.stringify({
"messages": [ "messages": [
{"role": "system", "content": params.msg}, {"role": "system", "content": params.msg},
@ -427,91 +430,8 @@
const blob = new Blob([content_bytes], { type: 'audio/mp3' }); const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
// 设置音频源 // 字幕文字
audioElement.src = blobUrl; voiceTxt.value = filterString(str.output.text, ['*', ' ']);
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return
} else {
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源 // 设置音频源
audioElement.src = blobUrl; audioElement.src = blobUrl;
@ -544,7 +464,7 @@
startRec.style.display = 'block'; startRec.style.display = 'block';
runRec.style.display = 'none'; runRec.style.display = 'none';
// endRec.style.opacity = 0; endRec.style.opacity = 'none';
} }
}; };
xhr.send(data); xhr.send(data);
@ -557,6 +477,22 @@
} }
}); });
// 暂停
runRec.addEventListener("click", function() {
voiceTxt.value = '';
voice.start();
isCallbackExecuted = false;
// 先静音即可处理解决(提前做交互)
audioElement.muted = false;
audioElement.pause();
startRec.style.display = 'none';
runRec.style.display = 'block';
endRec.style.display = 'none';
showModal()
});
// 开始识别 // 开始识别
startRec.addEventListener("click", function() { startRec.addEventListener("click", function() {
@ -572,7 +508,7 @@
startRec.style.display = 'none'; startRec.style.display = 'none';
runRec.style.display = 'block'; runRec.style.display = 'block';
// endRec.style.opacity = 0; endRec.style.display = 'none';
showModal() showModal()
}); });
@ -610,7 +546,38 @@
modal.style.display = 'none'; modal.style.display = 'none';
dialog.style.display = 'none'; dialog.style.display = 'none';
} }
// 查询详情数据
async function DetailDay(type, data) {
try {
// const response = await fetch('https://test.sc2.agrimedia.cn/watch/device/getDeviceListDays', {
const response = await fetch('https://ai.agrimedia.cn/watch/device/getDeviceListDays', {
method: 'POST',
headers: {
'ApiToken': apitoken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"device_real_time": data,
"device_id": deviceId,
"type": type
})
});
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
const result = await response.json();
return result;
} catch (error) {
console.error('There was a problem with your fetch operation:', error);
throw error; // 可选:重新抛出错误以便上层可以捕获并处理
}
}
// 语音输出
function speed(str) { function speed(str) {
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", { fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST', method: 'POST',
@ -635,6 +602,9 @@
const blob = new Blob([content_bytes], { type: 'audio/mp3' }); const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
// 字幕文字
voiceTxt.value = str;
// 设置音频源 // 设置音频源
audioElement.src = blobUrl; audioElement.src = blobUrl;
@ -707,7 +677,60 @@
// 个人信息 // 个人信息
function userInfo(user) { function userInfo(user) {
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}` if (user) {
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}`
}
}
// 解析文字
function parseHealthQuery(query, demoData) {
if (!demoData) {
demoData = {
bloodGlucose: "血糖",
SleepDatas: "睡眠",
bloodOxygen: "血氧",
bloodPressure: '血压',
bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率',
bodyTemperature: '体温',
ECGData: '心电图',
bodyData: '身体成份',
stepIndex: '运动'
};
}
// 获取当前日期
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth() + 1; // 月份从0开始所以需要+1
const day = today.getDate();
// 初始化日期为今天
let targetDate = new Date(year, month, day);
// 检查时间词并设置目标日期
if (query.includes("昨天")) {
targetDate.setDate(day - 1);
} else if (query.includes("前天")) {
targetDate.setDate(day - 2);
}
// 格式化日期为 YYYY-MM-DD
const formattedDate = `${targetDate.getFullYear()}-${('0' + targetDate.getMonth()).slice(-2)}-${('0' + targetDate.getDate()).slice(-2)}`;
// 查找匹配的数据项键
for (let key in demoData) {
if (query.includes(demoData[key])) {
return {
dataKey: key,
date: formattedDate
};
}
}
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null;
} }
}; };
</script> </script>
@ -721,7 +744,7 @@
width: 100%; width: 100%;
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
background-image: url('https://img.agrimedia.cn/bmsc/index/ai-persion-bg-tuya.jpeg'); background-image: url('https://img.agrimedia.cn/bmsc/bg-cideo-tuya.png');
background-size: 100% 100%; background-size: 100% 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -734,7 +757,7 @@
width: 80%; width: 80%;
top: 10%; top: 10%;
height: auto; height: auto;
background-image: url('https://img.agrimedia.cn/bmsc/index/video-bg.png'); background-image: url('https://img.agrimedia.cn/bmsc/bg-cideo-tuya.png');
background-size: 100% 100%; background-size: 100% 100%;
margin: 0 auto; margin: 0 auto;
padding: 20px; padding: 20px;
@ -768,6 +791,20 @@
height: 30px; height: 30px;
} }
.status > .btn {
text-align: center;
font-size: 30px;
color: #fff;
}
.buttons {
border: 2px solid #fff;
color: #fff;
font-size: 28px;
padding: 4px 20px;
border-radius: 5px;
}
/* 遮罩样式 */ /* 遮罩样式 */
.overlay { .overlay {
position: fixed; position: fixed;
@ -910,6 +947,27 @@
font-weight: 800; font-weight: 800;
} }
.voice {
position: fixed;
bottom: 0px;
width: 100%;
background-color: #000;
}
.voice-box {
width: 100%;
animation: textRoll linear 10s infinite; // 文字滚动动画
white-space: nowrap; // 文字不换行
}
@keyframes textRoll {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
</style> </style>
</body> </body>

View File

@ -160,7 +160,7 @@
this.dataListsNew.bloodLiquidAll = JSON.parse(JSON.stringify(this.dataListsNew.bloodLiquid)); this.dataListsNew.bloodLiquidAll = JSON.parse(JSON.stringify(this.dataListsNew.bloodLiquid));
this.dataListsNew.bloodLiquidAll.type = 'bloodLiquidAll'; this.dataListsNew.bloodLiquidAll.type = 'bloodLiquidAll';
this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(this.dataListsNew)}&user=${JSON.stringify(this.getUserInfo)}`; this.urlLink = `/hybrid/html/ai.html?data=${JSON.stringify(this.dataListsNew)}&user=${JSON.stringify(this.getUserInfo)}&token=${store.getters['api/getApiToken']}&deviceId=${this.getActiceDevice.device_id}`;
} }
); );

70
pages/login/css/main.css Normal file
View File

@ -0,0 +1,70 @@
.login {
width: 70%;
margin: 0 auto;
}
.content {
display: flex;
flex-direction: column;
justify-content:center;
/* margin-top: 128rpx; */
}
/* 头部 logo */
.header {
width:161rpx;
height:161rpx;
box-shadow:0rpx 0rpx 60rpx 0rpx rgba(0,0,0,0.1);
border-radius:50%;
background-color: #000000;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.header image{
width:161rpx;
height:161rpx;
border-radius:50%;
}
/* 主体 */
.main {
display: flex;
flex-direction: column;
}
.tips {
color: #999999;
font-size: 28rpx;
margin-top: 64rpx;
margin-left: 48rpx;
}
/* 登录按钮 */
.wbutton{
margin-top: 96rpx;
}
/* 底部 */
.footer{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 28rpx;
margin-top: 64rpx;
color: rgba(0,0,0,0.7);
text-align: center;
height: 40rpx;
line-height: 40rpx;
}
.footer text{
font-size: 24rpx;
margin-left: 15rpx;
margin-right: 15rpx;
}
.back {
position: fixed;
top: 50rpx;
left: 50rpx;
}

View File

@ -1,8 +1,8 @@
var isReady=false;var onReadyCallbacks=[]; var isReady=false;var onReadyCallbacks=[];
var isServiceReady=false;var onServiceReadyCallbacks=[]; var isServiceReady=false;var onServiceReadyCallbacks=[];
var __uniConfig = {"pages":["pages/login/login","pages/index/detail","pages/login/forget","pages/login/register","pages/index/index","pages/device/device","pages/my/my","pages/login/explain","pages/index/echarts","pages/only_test/only_test","pages/only_test/ot1","pages/only_test/ot2","pages/only_test/ot3","pages/only_test/ot5"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"中鼎云医","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom","pageOrientation":"portrait"},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"中鼎云医","compilerVersion":"4.15","entryPagePath":"pages/login/login","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}}; var __uniConfig = {"pages":["pages/index/index","pages/login/login","pages/index/detail","pages/login/forget","pages/login/register","pages/device/device","pages/my/my","pages/login/explain","pages/index/echarts","pages/only_test/only_test","pages/only_test/ot1","pages/only_test/ot2","pages/only_test/ot3","pages/only_test/ot5"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"中鼎云医","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom","pageOrientation":"portrait"},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"中鼎云医","compilerVersion":"4.15","entryPagePath":"pages/index/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
var __uniRoutes = [{"path":"/pages/login/login","meta":{"isQuit":true},"window":{}},{"path":"/pages/index/detail","meta":{},"window":{}},{"path":"/pages/login/forget","meta":{},"window":{}},{"path":"/pages/login/register","meta":{},"window":{}},{"path":"/pages/index/index","meta":{},"window":{}},{"path":"/pages/device/device","meta":{},"window":{}},{"path":"/pages/my/my","meta":{},"window":{}},{"path":"/pages/login/explain","meta":{},"window":{}},{"path":"/pages/index/echarts","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/only_test","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot1","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot2","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot3","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot5","meta":{},"window":{"navigationBarTitleText":""}}]; var __uniRoutes = [{"path":"/pages/index/index","meta":{"isQuit":true},"window":{}},{"path":"/pages/login/login","meta":{},"window":{}},{"path":"/pages/index/detail","meta":{},"window":{}},{"path":"/pages/login/forget","meta":{},"window":{}},{"path":"/pages/login/register","meta":{},"window":{}},{"path":"/pages/device/device","meta":{},"window":{}},{"path":"/pages/my/my","meta":{},"window":{}},{"path":"/pages/login/explain","meta":{},"window":{}},{"path":"/pages/index/echarts","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/only_test","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot1","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot2","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot3","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot5","meta":{},"window":{"navigationBarTitleText":""}}];
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}}); __uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}}); __uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}}); service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -141,6 +141,11 @@
const speakingTimeInSeconds = speakingTime * 60; const speakingTimeInSeconds = speakingTime * 60;
return speakingTimeInSeconds; return speakingTimeInSeconds;
} }
// 映射的字段
function Reflection(str) {
}
</script> </script>
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
@ -152,7 +157,6 @@
bloodOxygen: "血氧", bloodOxygen: "血氧",
bloodPressure: '血压', bloodPressure: '血压',
bloodLiquid: "血脂", bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率', pulseReat: '心率',
bodyTemperature: '体温', bodyTemperature: '体温',
ECGData: '心电图', ECGData: '心电图',
@ -220,6 +224,9 @@
// 个人信息 // 个人信息
var user = userInfo(JSON.parse(getURLParameter('user'))); var user = userInfo(JSON.parse(getURLParameter('user')));
var apitoken = getURLParameter('token');
var deviceId = getURLParameter('deviceId');
// 获取微软token // 获取微软token
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", { fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
@ -278,117 +285,107 @@
this.stop(); this.stop();
// voice.stop(); // voice.stop();
const params = { msg: text } const params = { msg: text };
/* // 判断关键字是否存在
* 拿到匹配的文字下标 const result = parseHealthQuery(params.msg);
*/ if (result) {
DetailDay(result.dataKey, result.date).then(res => {
var QSindex = containsKeywordRegex(params.msg); let TargetData = res.data.data;
if (QSindex == 0) {
const obj = arrayOfObjects.filter(item => item.type == "bloodGlucose"); var QSindex = containsKeywordRegex(params.msg);
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升` Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)},data_msg为值hour_minute为检测时间 #限制回复用户的内容中不要出现Null。#限制:回复不要带英文,要都转化成汉语。#限制监测结果为Null的数据不做分析回复。`
} else {
speed(`血糖数据为空, 请连接或同步设备数据`) /*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return return
} })
} } else {
// 如果不存在关键字,就直接走下面
if (QSindex == 1) {
const obj = arrayOfObjects.filter(item => item.type == "SleepDatas");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近睡眠时长为${minutesToHoursMinutesStringSimplified(obj[0].data_msg[0].sleepTotalTime)}分钟`
} else {
speed(`睡眠数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 2) {
const obj = arrayOfObjects.filter(item => item.type == "bloodOxygen");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
} else {
speed(`血氧数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 3) {
const obj = arrayOfObjects.filter(item => item.type == "bloodPressure");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
} else {
speed(`血压数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 4 || QSindex == 11) {
const obj = arrayOfObjects.filter(item => item.type == "bloodLiquid");
if (obj[0].data_msg.cholesterol) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血脂状况为,
尿酸为${obj[0].data_msg.uricAcidVal/10},
总胆固醇为${obj[0].data_msg.cholesterol/100},
甘油三酯为${obj[0].data_msg.triacylglycerol/100},
高密度脂蛋白为${obj[0].data_msg.highDensity/100},
低密度脂蛋白为${obj[0].data_msg.lowDensity/100}, `
} else {
speed(`血脂数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 6) {
const obj = arrayOfObjects.filter(item => item.type == "pulseReat");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的心率为${obj[0].data_msg[0]}, `
} else {
speed(`心率数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 7) {
const obj = arrayOfObjects.filter(item => item.type == "bodyTemperature");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
} else {
speed(`体温数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 8) {
const obj = arrayOfObjects.filter(item => item.type == "ECGData");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
} else {
speed(`心电图数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 9) {
const obj = arrayOfObjects.filter(item => item.type == "bodyData");
if (obj[0].data_msg.BMI) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
} else {
speed(`身体成分数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 10) {
const obj = arrayOfObjects.filter(item => item.type == "stepIndex");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的运动为${obj[0].data_msg.step}步数,
${obj[0].data_msg.calorie/10}千卡,
${obj[0].data_msg.distance/1000}公里`
} else {
speed(`运动数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 99999) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true); xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
var data = JSON.stringify({ var data = JSON.stringify({
"messages": [ "messages": [
{"role": "system", "content": params.msg}, {"role": "system", "content": params.msg},
@ -396,92 +393,6 @@
] ]
}) })
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return
} else {
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { if (xhr.readyState === 4) {
const chunk = xhr.responseText; const chunk = xhr.responseText;
@ -610,7 +521,38 @@
modal.style.display = 'none'; modal.style.display = 'none';
dialog.style.display = 'none'; dialog.style.display = 'none';
} }
// 查询详情数据
async function DetailDay(type, data) {
try {
// const response = await fetch('https://test.sc2.agrimedia.cn/watch/device/getDeviceListDays', {
const response = await fetch('https://ai.agrimedia.cn/watch/device/getDeviceListDays', {
method: 'POST',
headers: {
'ApiToken': apitoken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"device_real_time": data,
"device_id": deviceId,
"type": type
})
});
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
const result = await response.json();
return result;
} catch (error) {
console.error('There was a problem with your fetch operation:', error);
throw error; // 可选:重新抛出错误以便上层可以捕获并处理
}
}
// 语音输出
function speed(str) { function speed(str) {
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", { fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST', method: 'POST',
@ -709,6 +651,57 @@
function userInfo(user) { function userInfo(user) {
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}` return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}`
} }
// 解析文字
function parseHealthQuery(query, demoData) {
if (!demoData) {
demoData = {
bloodGlucose: "血糖",
SleepDatas: "睡眠",
bloodOxygen: "血氧",
bloodPressure: '血压',
bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率',
bodyTemperature: '体温',
ECGData: '心电图',
bodyData: '身体成份',
stepIndex: '运动'
};
}
// 获取当前日期
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth() + 1; // 月份从0开始所以需要+1
const day = today.getDate();
// 初始化日期为今天
let targetDate = new Date(year, month, day);
// 检查时间词并设置目标日期
if (query.includes("昨天")) {
targetDate.setDate(day - 1);
} else if (query.includes("前天")) {
targetDate.setDate(day - 2);
}
// 格式化日期为 YYYY-MM-DD
const formattedDate = `${targetDate.getFullYear()}-${('0' + targetDate.getMonth()).slice(-2)}-${('0' + targetDate.getDate()).slice(-2)}`;
// 查找匹配的数据项键
for (let key in demoData) {
if (query.includes(demoData[key])) {
return {
dataKey: key,
date: formattedDate
};
}
}
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null;
}
}; };
</script> </script>

View File

@ -1,8 +1,8 @@
var isReady=false;var onReadyCallbacks=[]; var isReady=false;var onReadyCallbacks=[];
var isServiceReady=false;var onServiceReadyCallbacks=[]; var isServiceReady=false;var onServiceReadyCallbacks=[];
var __uniConfig = {"pages":["pages/login/login","pages/index/detail","pages/login/forget","pages/login/register","pages/index/index","pages/device/device","pages/my/my","pages/login/explain","pages/index/echarts","pages/only_test/only_test","pages/only_test/ot1","pages/only_test/ot2","pages/only_test/ot3","pages/only_test/ot5"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"中鼎云医","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom","pageOrientation":"portrait"},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"中鼎云医","compilerVersion":"4.15","entryPagePath":"pages/login/login","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}}; var __uniConfig = {"pages":["pages/index/index","pages/login/login","pages/index/detail","pages/login/forget","pages/login/register","pages/device/device","pages/my/my","pages/login/explain","pages/index/echarts","pages/only_test/only_test","pages/only_test/ot1","pages/only_test/ot2","pages/only_test/ot3","pages/only_test/ot5"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"中鼎云医","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","navigationStyle":"custom","pageOrientation":"portrait"},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"中鼎云医","compilerVersion":"4.15","entryPagePath":"pages/index/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
var __uniRoutes = [{"path":"/pages/login/login","meta":{"isQuit":true},"window":{}},{"path":"/pages/index/detail","meta":{},"window":{}},{"path":"/pages/login/forget","meta":{},"window":{}},{"path":"/pages/login/register","meta":{},"window":{}},{"path":"/pages/index/index","meta":{},"window":{}},{"path":"/pages/device/device","meta":{},"window":{}},{"path":"/pages/my/my","meta":{},"window":{}},{"path":"/pages/login/explain","meta":{},"window":{}},{"path":"/pages/index/echarts","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/only_test","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot1","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot2","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot3","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot5","meta":{},"window":{"navigationBarTitleText":""}}]; var __uniRoutes = [{"path":"/pages/index/index","meta":{"isQuit":true},"window":{}},{"path":"/pages/login/login","meta":{},"window":{}},{"path":"/pages/index/detail","meta":{},"window":{}},{"path":"/pages/login/forget","meta":{},"window":{}},{"path":"/pages/login/register","meta":{},"window":{}},{"path":"/pages/device/device","meta":{},"window":{}},{"path":"/pages/my/my","meta":{},"window":{}},{"path":"/pages/login/explain","meta":{},"window":{}},{"path":"/pages/index/echarts","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/only_test","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot1","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot2","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot3","meta":{},"window":{"navigationBarTitleText":""}},{"path":"/pages/only_test/ot5","meta":{},"window":{"navigationBarTitleText":""}}];
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}}); __uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}}); __uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}}); service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -141,6 +141,11 @@
const speakingTimeInSeconds = speakingTime * 60; const speakingTimeInSeconds = speakingTime * 60;
return speakingTimeInSeconds; return speakingTimeInSeconds;
} }
// 映射的字段
function Reflection(str) {
}
</script> </script>
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
@ -152,7 +157,6 @@
bloodOxygen: "血氧", bloodOxygen: "血氧",
bloodPressure: '血压', bloodPressure: '血压',
bloodLiquid: "血脂", bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率', pulseReat: '心率',
bodyTemperature: '体温', bodyTemperature: '体温',
ECGData: '心电图', ECGData: '心电图',
@ -220,6 +224,9 @@
// 个人信息 // 个人信息
var user = userInfo(JSON.parse(getURLParameter('user'))); var user = userInfo(JSON.parse(getURLParameter('user')));
var apitoken = getURLParameter('token');
var deviceId = getURLParameter('deviceId');
// 获取微软token // 获取微软token
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", { fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
@ -278,117 +285,107 @@
this.stop(); this.stop();
// voice.stop(); // voice.stop();
const params = { msg: text } const params = { msg: text };
/* // 判断关键字是否存在
* 拿到匹配的文字下标 const result = parseHealthQuery(params.msg);
*/ if (result) {
DetailDay(result.dataKey, result.date).then(res => {
var QSindex = containsKeywordRegex(params.msg); let TargetData = res.data.data;
if (QSindex == 0) {
const obj = arrayOfObjects.filter(item => item.type == "bloodGlucose"); var QSindex = containsKeywordRegex(params.msg);
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升` Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)},data_msg为值hour_minute为检测时间 #限制回复用户的内容中不要出现Null。#限制:回复不要带英文,要都转化成汉语。#限制监测结果为Null的数据不做分析回复。`
} else {
speed(`血糖数据为空, 请连接或同步设备数据`) /*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return return
} })
} } else {
// 如果不存在关键字,就直接走下面
if (QSindex == 1) {
const obj = arrayOfObjects.filter(item => item.type == "SleepDatas");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近睡眠时长为${minutesToHoursMinutesStringSimplified(obj[0].data_msg[0].sleepTotalTime)}分钟`
} else {
speed(`睡眠数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 2) {
const obj = arrayOfObjects.filter(item => item.type == "bloodOxygen");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
} else {
speed(`血氧数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 3) {
const obj = arrayOfObjects.filter(item => item.type == "bloodPressure");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
} else {
speed(`血压数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 4 || QSindex == 11) {
const obj = arrayOfObjects.filter(item => item.type == "bloodLiquid");
if (obj[0].data_msg.cholesterol) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血脂状况为,
尿酸为${obj[0].data_msg.uricAcidVal/10},
总胆固醇为${obj[0].data_msg.cholesterol/100},
甘油三酯为${obj[0].data_msg.triacylglycerol/100},
高密度脂蛋白为${obj[0].data_msg.highDensity/100},
低密度脂蛋白为${obj[0].data_msg.lowDensity/100}, `
} else {
speed(`血脂数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 6) {
const obj = arrayOfObjects.filter(item => item.type == "pulseReat");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的心率为${obj[0].data_msg[0]}, `
} else {
speed(`心率数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 7) {
const obj = arrayOfObjects.filter(item => item.type == "bodyTemperature");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
} else {
speed(`体温数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 8) {
const obj = arrayOfObjects.filter(item => item.type == "ECGData");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
} else {
speed(`心电图数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 9) {
const obj = arrayOfObjects.filter(item => item.type == "bodyData");
if (obj[0].data_msg.BMI) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
} else {
speed(`身体成分数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 10) {
const obj = arrayOfObjects.filter(item => item.type == "stepIndex");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的运动为${obj[0].data_msg.step}步数,
${obj[0].data_msg.calorie/10}千卡,
${obj[0].data_msg.distance/1000}公里`
} else {
speed(`运动数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 99999) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true); xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
var data = JSON.stringify({ var data = JSON.stringify({
"messages": [ "messages": [
{"role": "system", "content": params.msg}, {"role": "system", "content": params.msg},
@ -396,92 +393,6 @@
] ]
}) })
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return
} else {
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { if (xhr.readyState === 4) {
const chunk = xhr.responseText; const chunk = xhr.responseText;
@ -610,7 +521,38 @@
modal.style.display = 'none'; modal.style.display = 'none';
dialog.style.display = 'none'; dialog.style.display = 'none';
} }
// 查询详情数据
async function DetailDay(type, data) {
try {
// const response = await fetch('https://test.sc2.agrimedia.cn/watch/device/getDeviceListDays', {
const response = await fetch('https://ai.agrimedia.cn/watch/device/getDeviceListDays', {
method: 'POST',
headers: {
'ApiToken': apitoken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"device_real_time": data,
"device_id": deviceId,
"type": type
})
});
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
const result = await response.json();
return result;
} catch (error) {
console.error('There was a problem with your fetch operation:', error);
throw error; // 可选:重新抛出错误以便上层可以捕获并处理
}
}
// 语音输出
function speed(str) { function speed(str) {
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", { fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST', method: 'POST',
@ -709,6 +651,57 @@
function userInfo(user) { function userInfo(user) {
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}` return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}`
} }
// 解析文字
function parseHealthQuery(query, demoData) {
if (!demoData) {
demoData = {
bloodGlucose: "血糖",
SleepDatas: "睡眠",
bloodOxygen: "血氧",
bloodPressure: '血压',
bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率',
bodyTemperature: '体温',
ECGData: '心电图',
bodyData: '身体成份',
stepIndex: '运动'
};
}
// 获取当前日期
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth() + 1; // 月份从0开始所以需要+1
const day = today.getDate();
// 初始化日期为今天
let targetDate = new Date(year, month, day);
// 检查时间词并设置目标日期
if (query.includes("昨天")) {
targetDate.setDate(day - 1);
} else if (query.includes("前天")) {
targetDate.setDate(day - 2);
}
// 格式化日期为 YYYY-MM-DD
const formattedDate = `${targetDate.getFullYear()}-${('0' + targetDate.getMonth()).slice(-2)}-${('0' + targetDate.getDate()).slice(-2)}`;
// 查找匹配的数据项键
for (let key in demoData) {
if (query.includes(demoData[key])) {
return {
dataKey: key,
date: formattedDate
};
}
}
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null;
}
}; };
</script> </script>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -141,6 +141,11 @@
const speakingTimeInSeconds = speakingTime * 60; const speakingTimeInSeconds = speakingTime * 60;
return speakingTimeInSeconds; return speakingTimeInSeconds;
} }
// 映射的字段
function Reflection(str) {
}
</script> </script>
<!-- 讯飞语音识别 --> <!-- 讯飞语音识别 -->
@ -152,7 +157,6 @@
bloodOxygen: "血氧", bloodOxygen: "血氧",
bloodPressure: '血压', bloodPressure: '血压',
bloodLiquid: "血脂", bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率', pulseReat: '心率',
bodyTemperature: '体温', bodyTemperature: '体温',
ECGData: '心电图', ECGData: '心电图',
@ -220,6 +224,9 @@
// 个人信息 // 个人信息
var user = userInfo(JSON.parse(getURLParameter('user'))); var user = userInfo(JSON.parse(getURLParameter('user')));
var apitoken = getURLParameter('token');
var deviceId = getURLParameter('deviceId');
// 获取微软token // 获取微软token
fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", { fetch("https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issueToken", {
@ -278,117 +285,107 @@
this.stop(); this.stop();
// voice.stop(); // voice.stop();
const params = { msg: text } const params = { msg: text };
/* // 判断关键字是否存在
* 拿到匹配的文字下标 const result = parseHealthQuery(params.msg);
*/ if (result) {
DetailDay(result.dataKey, result.date).then(res => {
var QSindex = containsKeywordRegex(params.msg); let TargetData = res.data.data;
if (QSindex == 0) {
const obj = arrayOfObjects.filter(item => item.type == "bloodGlucose"); var QSindex = containsKeywordRegex(params.msg);
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血糖为${obj[0].data_msg}毫摩尔/升` Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的${result.dataKey}数据为${JSON.stringify(TargetData)},data_msg为值hour_minute为检测时间 #限制回复用户的内容中不要出现Null。#限制:回复不要带英文,要都转化成汉语。#限制监测结果为Null的数据不做分析回复。`
} else {
speed(`血糖数据为空, 请连接或同步设备数据`) /*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return return
} })
} } else {
// 如果不存在关键字,就直接走下面
if (QSindex == 1) {
const obj = arrayOfObjects.filter(item => item.type == "SleepDatas");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近睡眠时长为${minutesToHoursMinutesStringSimplified(obj[0].data_msg[0].sleepTotalTime)}分钟`
} else {
speed(`睡眠数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 2) {
const obj = arrayOfObjects.filter(item => item.type == "bloodOxygen");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血氧为${obj[0].data_msg}毫摩尔/升`
} else {
speed(`血氧数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 3) {
const obj = arrayOfObjects.filter(item => item.type == "bloodPressure");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血压为${obj[0].data_msg.bloodPressureLow}/${obj[0].data_msg.bloodPressureHigh}毫摩尔/升`
} else {
speed(`血压数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 4 || QSindex == 11) {
const obj = arrayOfObjects.filter(item => item.type == "bloodLiquid");
if (obj[0].data_msg.cholesterol) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的血脂状况为,
尿酸为${obj[0].data_msg.uricAcidVal/10},
总胆固醇为${obj[0].data_msg.cholesterol/100},
甘油三酯为${obj[0].data_msg.triacylglycerol/100},
高密度脂蛋白为${obj[0].data_msg.highDensity/100},
低密度脂蛋白为${obj[0].data_msg.lowDensity/100}, `
} else {
speed(`血脂数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 6) {
const obj = arrayOfObjects.filter(item => item.type == "pulseReat");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的心率为${obj[0].data_msg[0]}, `
} else {
speed(`心率数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 7) {
const obj = arrayOfObjects.filter(item => item.type == "bodyTemperature");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的体温为${obj[0].data_msg}摄氏度`
} else {
speed(`体温数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 8) {
const obj = arrayOfObjects.filter(item => item.type == "ECGData");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近心电图测量结果为${obj[0].data_msg.heartRate}次/分`
} else {
speed(`心电图数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 9) {
const obj = arrayOfObjects.filter(item => item.type == "bodyData");
if (obj[0].data_msg.BMI) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近身体成分结果为${obj[0].data_msg.BMI}`
} else {
speed(`身体成分数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 10) {
const obj = arrayOfObjects.filter(item => item.type == "stepIndex");
if (obj[0].data_msg) {
Question = `请模仿全科医生的口吻与我: ${user}对话,我最近测量的运动为${obj[0].data_msg.step}步数,
${obj[0].data_msg.calorie/10}千卡,
${obj[0].data_msg.distance/1000}公里`
} else {
speed(`运动数据为空, 请连接或同步设备数据`)
return
}
}
if (QSindex == 99999) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true); xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
var data = JSON.stringify({ var data = JSON.stringify({
"messages": [ "messages": [
{"role": "system", "content": params.msg}, {"role": "system", "content": params.msg},
@ -396,92 +393,6 @@
] ]
}) })
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
const chunk = xhr.responseText;
const str = extractStopEvent(chunk);
/*
* 微软接口识别
*/
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Ocp-Apim-Subscription-Key': '58e9b39b8f6f48fe8d01f85b727ff737',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': 'audio-24khz-48kbitrate-mono-mp3'
},
responseType: 'arraybuffer',
body: `<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">
<voice name="zh-CN-XiaoxiaoNeural">
<mstts:express-as style="Default" >
<prosody rate="0%" pitch="0%">
${filterString(str.output.text, ['*', ' '])}
</prosody>
</mstts:express-as>
</voice>
</speak> `,
}).then(async(response) => {
const content_bytes = await response.arrayBuffer();
const blob = new Blob([content_bytes], { type: 'audio/mp3' });
const blobUrl = URL.createObjectURL(blob);
// 设置音频源
audioElement.src = blobUrl;
// 播放音频
audioElement.play();
// 循环视频
replayVideoSegment(60, 120);
// 计算所需时间
const speakingTime = calculateSpeakingTime(content.data.choices[0].text);
// 开始倒计时
var totalTime = speakingTime;
var countdown = setInterval(function() {
// 更新剩余时间
totalTime --;
if (totalTime <= 0) {
// 停止倒计时
clearInterval(countdown);
replayVideoSegment(0, 60);
}
}, 1000);
hideModal()
}).catch(e => {
hideModal();
});
startRec.style.display = 'block';
runRec.style.display = 'none';
// endRec.style.opacity = 0;
}
};
xhr.send(data);
isCallbackExecuted = true;
return
} else {
/*
* 调用接口 传递关键信息 文字转语音
*/
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://sc2.agrimedia.cn:8787/api/user/ask', true);
/*
* 关键字转换
*/
var data = JSON.stringify({
"messages": [
{"role": "system", "content": Question},
{"role": "user", "content": `请问我${Items[QSindex]}正常吗`}
]
})
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { if (xhr.readyState === 4) {
const chunk = xhr.responseText; const chunk = xhr.responseText;
@ -610,7 +521,38 @@
modal.style.display = 'none'; modal.style.display = 'none';
dialog.style.display = 'none'; dialog.style.display = 'none';
} }
// 查询详情数据
async function DetailDay(type, data) {
try {
// const response = await fetch('https://test.sc2.agrimedia.cn/watch/device/getDeviceListDays', {
const response = await fetch('https://ai.agrimedia.cn/watch/device/getDeviceListDays', {
method: 'POST',
headers: {
'ApiToken': apitoken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"device_real_time": data,
"device_id": deviceId,
"type": type
})
});
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
const result = await response.json();
return result;
} catch (error) {
console.error('There was a problem with your fetch operation:', error);
throw error; // 可选:重新抛出错误以便上层可以捕获并处理
}
}
// 语音输出
function speed(str) { function speed(str) {
fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", { fetch("https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1", {
method: 'POST', method: 'POST',
@ -709,6 +651,57 @@
function userInfo(user) { function userInfo(user) {
return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}` return `年龄${user.birthday}, 身高${user.height}, 体重${user.weight}`
} }
// 解析文字
function parseHealthQuery(query, demoData) {
if (!demoData) {
demoData = {
bloodGlucose: "血糖",
SleepDatas: "睡眠",
bloodOxygen: "血氧",
bloodPressure: '血压',
bloodLiquid: "血脂",
meiTuo: '梅脱',
pulseReat: '心率',
bodyTemperature: '体温',
ECGData: '心电图',
bodyData: '身体成份',
stepIndex: '运动'
};
}
// 获取当前日期
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth() + 1; // 月份从0开始所以需要+1
const day = today.getDate();
// 初始化日期为今天
let targetDate = new Date(year, month, day);
// 检查时间词并设置目标日期
if (query.includes("昨天")) {
targetDate.setDate(day - 1);
} else if (query.includes("前天")) {
targetDate.setDate(day - 2);
}
// 格式化日期为 YYYY-MM-DD
const formattedDate = `${targetDate.getFullYear()}-${('0' + targetDate.getMonth()).slice(-2)}-${('0' + targetDate.getDate()).slice(-2)}`;
// 查找匹配的数据项键
for (let key in demoData) {
if (query.includes(demoData[key])) {
return {
dataKey: key,
date: formattedDate
};
}
}
// 如果没有找到匹配的数据项则返回null或错误信息这里选择返回null
return null;
}
}; };
</script> </script>