Browse Source

fix: demo2

master
高志龙 1 year ago
parent
commit
1feb224701
  1. 9
      index.html
  2. 226
      main.js
  3. 96
      public/style.css
  4. 3
      public/tts/index.js
  5. 92
      util.js

9
index.html

@ -7,7 +7,7 @@
<link rel="stylesheet" href="/style.css"/>
<title>Wails App</title>
</head>
<body onload="onReadly()" style="overflow: hidden; ">
<body style="overflow: hidden; ">
<div id="bg" style="margin: auto;height: 100vh; position: relative;">
<video id="bgVideo" muted autoplay loop height="100%">
<source src="./assets/bg.mp4" type="video/mp4">
@ -36,12 +36,11 @@
<div id="txtBg" class="content">
<ul id="cont">
<li class="left">
<span></span>
<span>红帽</span>
</li>
<li class="left">
<div>您好呀,有什么需要帮助的吗?</div>
</li>
</ul>
</div>
@ -54,8 +53,8 @@
</div>
</div>
<div id="mark" style="width: 100vw;height: 100vh; background:rgba(0,0,0,0.7); position:absolute; top:0px; backdrop-filter:blur(10px); display: none;">
<div id="mark" style="width: 100vw;height: 100vh; background:rgba(0,0,0,0.7); position:absolute; top:0px; display: none; backdrop-filter:blur(10px); align-items: center;justify-content: center;">
</div>
<script src="/iflyrec/crypto-js.js"></script>

226
main.js

@ -4,7 +4,7 @@ import { btnStatus,recorder,getWebSocketUrl,connectWebSocket } from "./recorder.
import { createAlova } from 'alova';
import adapterFetch from 'alova/fetch';
let { onchangeSize,initDate,setScrollPosition,addBackItemText,addItemImg,addItemSmallImg,addItemBigImg,addredHot,addBackItemAction,addWrapper,addClickItemImg } = QMUtil;
let { onchangeSize,initDate,setScrollPosition,addBackItemText,addItemImg,addItemSmallImg,addItemBigImg,addredHot,addBackItemAction,addBackShopAction,addWrapper,addClickItemImg,addClickWCList,addQRCode, washroom } = QMUtil;
const alovaInstance = createAlova({
requestAdapter: adapterFetch(),
@ -14,6 +14,7 @@ const alovaInstance = createAlova({
window.cli = null
window.woNode = null
window.woVoice = null
window.isSearch=false;
window.onload = () => {
onchangeSize();
@ -40,14 +41,17 @@ let addMy = () => {
}
window.audioStart = () => {
window.stopTTS();
//开始识别
if (btnStatus === "UNDEFINED" || btnStatus === "CLOSED") {
connectWebSocket();
document.getElementById("stopBnt").style.display = "block";
document.getElementById("startBnt").style.display = "none";
addMy(); //添加我气泡
setScrollPosition();
if(!window.isSearch){
window.stopTTS();
if (btnStatus === "UNDEFINED" || btnStatus === "CLOSED") {
connectWebSocket();
document.getElementById("stopBnt").style.display = "block";
document.getElementById("startBnt").style.display = "none";
addMy(); //添加我气泡
setScrollPosition();
}
//callAiModel("电影院在哪里");
}
}
@ -65,6 +69,7 @@ window.content = [{"logo":"./assets/con1.png","img":"./assets/conDail.png"},{"lo
//接收模型回复处理内容
function callBack(str){
window.isSearch = false;
document.getElementById("ing").remove();
console.log(str);
let obj = str;
@ -73,48 +78,111 @@ function callBack(str){
addredHot();
}
switch(obj.data.type){
case "shopNotFound" :
addredHot();
addBackItemText("此品牌在我商场未入驻。");
break;
case undefined:
break;
case "shopList" :
if(typeof obj.data.value.length == "number"){
obj.data.value.forEach((item, index)=>{
addBackItemAction(item);
});
}else{
addBackItemText(obj.data.value.text || "为您推荐以下店铺");
obj.data.value.content.forEach((item, index)=>{
addBackItemAction(item);
});
}
if(obj.data.value.text){
addBackItemText(obj.data.value.text);
}else{
if(obj.data.value.content && obj.data.value.content.length>0){
let opt = {
value:"",
txt:"为您推荐以下店铺"
}
obj.data.value.content.sort((a,b)=>{
if(a.buildingOrder != b.buildingOrder){
return a.buildingOrder - b.buildingOrder;
}else{
return a.floorOrder - b.floorOrder;
}
});
obj.data.value.content.forEach((item,index)=>{
let floor=item.building+item.floor+"楼";
if(!opt.value){
opt.value = floor;
opt.txt += floor+item.name+", ";
}else{
if(opt.value == floor){
opt.txt += item.name+", ";
}else{
opt.txt += floor+item.name+", ";
}
}
})
opt.txt = opt.txt.substring(0, opt.txt.length-2);
addBackItemText(opt.txt);
}
}
if(obj.data.value.content && obj.data.value.content.length>0){
let div = addWrapper();
addBackShopAction(div, obj.data.value.content, null);
}
break;
case "activity" :
if(typeof obj.data.value.length == "number"){
obj.data.value.forEach((item, index)=>{
addBackItemAction(item);
});
}else{
addBackItemText(obj.data.value.text || "为您推荐以下活动");
obj.data.value.content.forEach((item, index)=>{
addBackItemAction(item);
});
}
addBackItemText(obj.data.value.text || "为您推荐以下活动");
obj.data.value.content.forEach((item, index)=>{
addBackItemAction(item);
});
break;
case "shop" :
if(obj.data.value.length !=0){
addBackItemText(`${obj.data.value[0].name}位于商场 ${obj.data.value[0].house_number},\n下方为您推荐导航线路`);
addItemImg("./assets/map.png");
if(typeof obj.data.value != "string"){
if(obj.data.value.length !=0){
let opt = {
value:"",
txt:""
}
obj.data.value.sort((a,b)=>{
if(a.buildingOrder != b.buildingOrder){
return a.buildingOrder - b.buildingOrder;
}else{
return a.floorOrder - b.floorOrder;
}
});
obj.data.value.forEach((item,index)=>{
let floor=item.building+item.floor+"楼";
if(!opt.value){
opt.value = floor;
opt.txt += floor+", ";
}else{
if(opt.value != floor){
opt.txt += floor+", ";
}
}
})
opt.txt = opt.txt.substring(0, opt.txt.length-2);
if(obj.data.value.length === 1){
addBackItemText(`${obj.data.value[0].name} 位于商场 ${opt.txt},\n下方为您推荐导航路线`);
addItemImg("./assets/map.png");
addQRCode();
if(obj.data.recommend && obj.data.recommend.length>0){
addBackItemText("相关品牌推荐:","",false);
let div = addWrapper();
addBackShopAction(div, obj.data.recommend, null);
}
}else{
addBackItemText(`${obj.data.query} 位于商场 ${opt.txt}`);
let div = addWrapper();
addBackShopAction(div, obj.data.value, null);
}
}else{
addBackItemText(`您的问题我还在持续学习中.`);
}
}else{
addBackItemText(`您的问题我还在持续学习中.`);
addBackItemText(obj.data.value);
}
break;
case "facility" :
if(typeof obj.data.value.length == "number"){
addBackItemText(`下方为您推荐导航到${obj.data.value}的线路`);
addItemImg("./assets/map1.png");
if(obj.data.value === "服务台"){
addBackItemText(`客服中心在二期七楼,下方为您推荐导航到${obj.data.value}的路线`);
}else{
addBackItemText(`下方为您推荐导航到${obj.data.value}的线路`);
addItemImg("./assets/map1.png");
addBackItemText(`下方为您推荐导航到最近${obj.data.value}的路线`);
}
addItemImg("./assets/map1.png");
addQRCode();
break;
case "weather" :
addBackItemText(`${obj.data.value.city}今天天气${obj.data.value.dayweather},最高温度${obj.data.value.daytemp_float}`);
@ -129,20 +197,35 @@ function callBack(str){
}
break;
case "qrcode" : //二维码
obj.data.value.text && addBackItemText(obj.data.value.text);
if(obj.data.value.content && obj.data.value.content.length>0){
addItemSmallImg(obj.data.value.content[0].logo);
}
if(obj.data.value.text || obj.data.value.content){
obj.data.value.text && addBackItemText(obj.data.value.text);
if(obj.data.value.content && obj.data.value.content.length>0){
addItemSmallImg(obj.data.value.content[0].logo);
}
}else{
addBackItemText("您的问题我还在持续学习中.");
}
break;
case "coupon" : //优惠券
if(obj.data.value.text){
addBackItemText(obj.data.value.text);
let div = addWrapper();
window.content.forEach((item)=>{
addClickItemImg(div, item.logo, item.img, 165, 212, window.clickCoupon);
});
if(obj.data.value.text || window.content.length>0){
obj.data.value.text && addBackItemText(obj.data.value.text);
if(window.content.length>0){
let div = addWrapper();
window.content.forEach((item)=>{
addClickItemImg(div, item.logo, item.img, 165, 212, window.clickCoupon);
});
}
}else{
addBackItemText("您的问题我还在持续学习中.");
}
break;
case "washroom" : //洗手间
addBackItemText(`下方为您推荐导航到最近洗手间的路线`);
addItemImg("./assets/map1.png");
addQRCode();
addBackItemText(`网红洗手间推荐:`,"",false);
addClickWCList(addWrapper(),window.clickWashroom);
break;
case "video" : //视频
obj.data.value.text && addBackItemText(obj.data.value.text);
if(obj.data.value.content && obj.data.value.content.length>0){
@ -195,6 +278,32 @@ window.clickVideo = function(event){
window.hello();
})
}
//点击洗手间
window.clickWashroom = function(event){
console.log(event.target.dataset.floor);
window.isplayHello = false; //停止播放招呼语音
window.stopTTS();
let mark = document.getElementById("mark");
mark.style.display = "flex";
let div = document.createElement("div");
div.className = "wcdail";
div.innerHTML = `<div class="hotroom">
<img style="border-radius: 12px;position: absolute;" src="${event.target.dataset.img}" width="255" />
<div class="wccontent">
<span class="wctitle">洗手间-${event.target.dataset.name}</span>
<span class="wcaddress"><img src="./assets/wc/add_icon.png"/>${event.target.dataset.floor}</span>
</div>
</div>
<img src="./assets/wc/wc_nav.png" />`;
mark.appendChild(div);
mark.addEventListener("click", ()=>{
div.remove();
mark.style.display = "none";
window.isplayHello = true;
window.hello();
})
}
let getAiData = async (msg) => {
const response = await alovaInstance.Post('http://dify.123.1000my.com:59222/v1/workflows/run', {
@ -207,22 +316,34 @@ let getAiData = async (msg) => {
headers: {
'Authorization': 'Bearer app-Fzon9DlAGNVwJSSrjF1gCiw4'
}
}).catch(error => {
let res = {
code:200,
data: {
"type": "other",
"value": "您的问题我还在持续学习中."
}
}
callBack(res)
return;
});
console.log(response)
let res = {
code:200,
data: {
"type": response.data?.outputs?.type,
"value": response.data?.outputs?.value
"value": response.data?.outputs?.value,
"recommend": response.data?.outputs?.recommend,
"query": response.data?.outputs?.query
}
}
callBack(res)
}
function callAiModel(msg){
console.log(msg)
window.isSearch = true;
// 调用模型
addBackItemText("思考中...","ing",false)
addBackItemText("思考中...","ing",false);
setScrollPosition();
// 调用api
getAiData(msg);
@ -230,7 +351,6 @@ function callAiModel(msg){
//停止识别后动作
window.audioStop = () => {
console.log("audioStop")
//停止识别
if (btnStatus === "CONNECTING" || btnStatus === "OPEN") {
// 结束录音
@ -257,8 +377,8 @@ window.hello=()=>{
clearTimeout(window.timer);
if(window.isplayHello){
window.isHello=true;
window.startTTS("您好呀,我是德基广场数字客服小,请问有什么需要帮助的吗?");
document.getElementById("cont").innerHTML = `<li class="left"><span>小</span></li><li class="left"><div>您好呀,有什么需要帮助的吗?</div></li>`;
window.startTTS("您好呀,我是德基广场数字客服小红帽,请问有什么需要帮助的吗?");
document.getElementById("cont").innerHTML = `<li class="left"><span>小红帽</span></li><li class="left"><div>您好呀,有什么需要帮助的吗?</div></li>`;
}
},60000);
}

96
public/style.css

@ -106,4 +106,98 @@ li.right div {
}
.scroll-wrapper::-webkit-scrollbar {
display: none;
}
}
.hotroom{
display: flex;
padding: 0px 101px 48px 48px;
align-items: flex-end;
gap: 50px;
align-self: stretch;
border-radius: 12px 12px 0px 0px;
border-bottom: 1px solid #D4D4D4;
background: #F2F2F2;
height: 190px;
}
.wctitle{
color: rgba(0, 0, 0, 0.80);
font-size: 48px;
font-style: normal;
font-weight: 700;
line-height: normal;
}
.wcaddress{
color: rgba(0, 0, 0, 0.80);
font-size: 24px;
font-style: normal;
font-weight: 700;
line-height: 44px;
display: flex;
align-items: center;
flex-direction: row;
gap: 20px;
}
.wcdail{
display: flex;
width: 930px;
flex-direction: column;
border-radius: 12px;
}
.wccontent{
display: flex;
padding-left: 305px;
flex-direction: column;
gap: 18px;
}
.shop-list{
background: #FFF;
position: relative;
width: 150px;
height: 150px;
display: inline-flex;
flex-direction: column;
padding: 10px 10px 2px 10px;
align-items: center;
gap: 10px;
border-radius: 4px;
margin-right: 12px;
}
.shop-item{
display: flex;
flex-direction: row;
justify-content: space-between;
align-self: stretch;
align-items: center;
font-size: 14px;
font-style: normal;
font-weight: 700;
line-height: 22px;
}
.shop-name{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 95px;
}
.shop-add{
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
max-width: 65px;
color:rgba(0, 0, 0, 0.60);
}
.shop-tip{
padding: 4px 8px;
border-radius: 2px;
background: linear-gradient(90deg, #9A7C4D 0%, #CFA876 100%), #B59362;
height: 23px;
position: absolute;
left: 2px;
top: 2px;
color: #FFF;
}

3
public/tts/index.js

@ -58,10 +58,9 @@ function connectWebSocket(str) {
aue: "raw",
auf: "audio/L16;rate=16000",
vcn: "x4_mengmengneutral",
speed: 50, //语速
speed: 60, //语速
volume: 80, //音量
pitch: 50, //音高
bgs: 1,
tte:"UTF8",
},
data: {

92
util.js

@ -66,22 +66,22 @@ var QMUtil = {
},200);
},
addAvdi:function (){
let wli = document.createElement("li");
wli.className = "left"
wli.innerHTML="<div>更多精彩内容请关注德基广场小程序</div>";
document.getElementById("cont").appendChild(wli);
addQRCode:function (){
let wli1 = document.createElement("li");
wli1.className = "left"
wli1.innerHTML="<div>扫描下方二维码查看详细路线</div>";
document.getElementById("cont").appendChild(wli1);
let wli2 = document.createElement("li");
wli2.className = "left"
wli2.innerHTML='<div><img src="./assets/face.svg" width="80" /></div>';
wli2.innerHTML='<div><img src="./assets/er.png" width="150" /></div>';
document.getElementById("cont").appendChild(wli2);
setScrollPosition();
},
addredHot:function (){
let aili = document.createElement("li");
aili.className = "left"
aili.innerHTML="<span>小</span>";
aili.innerHTML="<span>小红帽</span>";
document.getElementById("cont").appendChild(aili);
},
//活动
@ -101,10 +101,24 @@ var QMUtil = {
<span style="color:#000; overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: ${num};line-clamp: ${num};-webkit-box-orient: vertical;">${obj.intro}</span>
</div>`;
},
//店铺
addBackShopAction:function (div,list,clickFun){
list.forEach((item, index)=>{
let all = document.createElement("div");
all.className="shop-list";
all.innerHTML = `<img src="${item.logo}" height="110" width="110" />
<div class="shop-item">
<span class="shop-name">${item.name}</span>
<span class="shop-add">${item.building+item.floor}</span>
</div>
<div class="shop-tip">${item.industryName?item.industryName:item.industryFname}</div>`;
div.appendChild(all);
});
},
//文本
addBackItemText:function (msg, idName="", isTTS=true){
let li = document.createElement("li");
li.id = idName
idName && (li.id = idName);
li.className = "left"
document.getElementById("cont").appendChild(li);
let div = document.createElement("div");
@ -112,9 +126,9 @@ var QMUtil = {
if(typeof msg == "string"){
div.innerText = msg;
}else if(typeof msg.length == "number"){
div.innerText = msg[0].name || "我在持续学习中...";
div.innerText = msg[0].name || "您的问题在持续学习中.";
}else{
div.innerText = msg.name || "我在持续学习中...";
div.innerText = msg.name || "您的问题在持续学习中.";
}
if(isTTS){
window.isHello = false;
@ -164,6 +178,20 @@ var QMUtil = {
}
div.appendChild(img);
},
addClickWCList:function(div,clickFun){
QMUtil.washroom.forEach((item, index)=>{
let img = document.createElement("img");
img.className = "scroll-img";
item.width = 160;
img.height = 160;
img.src = item.url;
img.dataset.name = item.name;
img.dataset.floor = item.floor;
img.dataset.img = item.img;
img.addEventListener("click", clickFun);
div.appendChild(img);
})
},
addWrapper:function (){
let li = document.createElement("li");
@ -178,7 +206,47 @@ var QMUtil = {
"APPID":"5c2055f8",
"API_SECRET":"2bc7168506a38cf1a7a52fb3ba63d873",
"API_KEY":"2d1e9e5604d66089bda42ff4797201c1"
}
},
washroom:[
{
"name": "蓝调俱乐部",
"floor": "一期二楼",
"img":"./assets/wc/0102.png",
"url":"./assets/wc/t_02.png"
},
{
"name": "赛博奇幻夜",
"floor": "一期三楼",
"img":"./assets/wc/0103.png",
"url":"./assets/wc/t_03.png"
},
{
"name": "禅韵流光庭",
"floor": "一期四楼",
"img":"./assets/wc/0104.png",
"url":"./assets/wc/t_04.png"
},
{
"name": "印象波普厅",
"floor": "一期五楼",
"img":"./assets/wc/0105.png",
"url":"./assets/wc/t_05.png"
},
{
"name": "庇护所花园",
"floor": "一期六楼",
"img":"./assets/wc/0106.png",
"url":"./assets/wc/t_06.png"
},
{
"name": "游墨字句间",
"floor": "一期七楼",
"img":"./assets/wc/0107.png",
"url":"./assets/wc/t_07.png"
}
]
}
export default QMUtil;

Loading…
Cancel
Save