fix: 逻辑修改
This commit is contained in:
parent
849fc15748
commit
d596b818e2
|
|
@ -463,7 +463,9 @@
|
||||||
this.$store.commit('api/setUserInfo', res);
|
this.$store.commit('api/setUserInfo', res);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onRefresh();
|
uni.reLaunch({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue