Browse Source

数字人

mathMan
风继续吹 9 months ago
parent
commit
97457b0628
8 changed files with 479 additions and 874 deletions
  1. +3
    -641
      App.vue
  2. +476
    -233
      pages/index/guide.vue
  3. BIN
      static/image/recordingIcon.png
  4. BIN
      static/image/servehead.png
  5. BIN
      static/image/textInput.png
  6. BIN
      static/image/voiceInput.png
  7. BIN
      static/image/voiceing.png
  8. BIN
      static/image/voiceplay.png

+ 3
- 641
App.vue View File

@@ -1,653 +1,15 @@
<script>
import Vue from 'vue';
const domainObj = require('./utils/domain.js');
//app.js
var config = require("./config");
export default {
onLaunch(options) {
this.setTabbarItems() // 设置tabbar
// 获取用户信息
uni.getSystemInfo({
success: function(e) {
console.log(e, 'phoneInfo')
// #ifdef MP-WEIXIN
Vue.prototype.StatusBar = e.statusBarHeight;
let custom = wx.getMenuButtonBoundingClientRect();
Vue.prototype.Custom = custom;
Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight;
Vue.prototype.windowHeight = e.safeArea.height
// #endif
Vue.mixin({
data() {
return {
StatusBar: Vue.prototype.StatusBar,
CustomBar: Vue.prototype.CustomBar,
windowHeight: Vue.prototype.windowHeight,
LOADING: false,
bulidIngObj: uni.getStorageSync('buildingID'),
};
},
onLoad() {
this.setTabbarItems()
},
methods: {

// 设置底部导航栏
setTabbarItems() {
const tabbarList = [{
iconPath: "/static/images/tabBar/jiedais.png",
selectedIconPath: "/static/images/tabBar/jiedaiActives.png",
text: "接待"
},
{
iconPath: "/static/images/tabBar/kehus.png",
selectedIconPath: "/static/images/tabBar/kehuActives.png",
text: "客户"
},
{
iconPath: "/static/images/tabBar/works.png",
selectedIconPath: "/static/images/tabBar/workActives.png",
text: "工作台"
},
{
iconPath: "/static/images/tabBar/xuexis.png",
selectedIconPath: "/static/images/tabBar/xuexiActives.png",
text: "学习"
},
{
iconPath: "/static/images/tabBar/mes.png",
selectedIconPath: "/static/images/tabBar/meActives.png",
text: "我的"
}
]
if (domainObj.domain == 'zh.aihxz.com') {
tabbarList.forEach((item, index) => {
uni.setTabBarItem({
index: index,
iconPath: item.iconPath,
selectedIconPath: item.selectedIconPath
})
})
}
},

//实时统计
getTabBarBadge() {
uni.request({
url: config.service.realTimeStatistics,
method: "POST",
header: {
'content-type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync(
'weapp_session_login_data').token
},
data: {
houseId: uni.getStorageSync('buildingID').id
},
success: (data) => {

if (data.data.data == null) {
uni.removeTabBarBadge({
index: 0,
})
return
} else {
uni.removeTabBarBadge({
index: 0,
})
if (data.data.data.receivingCustomer > 0) {
uni.setTabBarBadge({
index: 0,
text: `${data.data.data.receivingCustomer}`
})
}
}
},
fail: () => {
uni.removeTabBarBadge({
index: 0,
})
}
})
},

upDateBulidIngObj() {
this.bulidIngObj = uni.getStorageSync('buildingID')
},
addLookingCount(id) {
uni.request({
url: config.service.addLookingCount,
method: "POST",
header: {
'content-type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync(
'weapp_session_login_data').token
},
data: {
houseId: uni.getStorageSync(
'buildingID').id,
houseName: uni.getStorageSync(
'buildingID').name,
recordId: id
},
})
},

sendLog(data) {
uni.request({
url: config.service.addLog,
method: "POST",
header: {
'content-type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync(
'weapp_session_login_data').token
},
data: {
houseId: data.houseId || uni.getStorageSync(
'buildingID').id,
houseName: data.houseName || uni.getStorageSync(
'buildingID').name,
serviceId: "test",
recordId: data.id
},
success: (data) => {
}
})
},
// 时分秒转换为秒
TIMEEVENT(e) {
var time = e;
var len = time.split(':')
if (len.length == 3) {
var hour = time.split(':')[0];
var min = time.split(':')[1];
var sec = time.split(':')[2];
return Number(hour * 3600) + Number(min * 60) + Number(sec);
}
if (len.length == 2) {
var min = time.split(':')[0];
var sec = time.split(':')[1];
return Number(min * 60) + Number(sec);
}
if (len.length == 1) {
var sec = time.split(':')[0];
return Number(sec);
}
},

// 目前使用页面为录音页面
SPEAKERSTYLE(index) {
let obj = {
color: '',
}
switch (index) {
case 1:
obj.color = '#60CBEC';
break;
case 2:
obj.color = '#EC8B47';
break;
case 3:
obj.color = '#4F861E';
break;
case 5:
obj.color = '#4980C8';
break;
case 6:
obj.color = '#60CBEC';
break;
case 7:
obj.color = '#EC8B47';
break;
case 8:
obj.color = '#4F861E';
break;
default:
obj.color = '#9F61C8';
break;
}
return obj
},

// 检测权限 返回 Boolean类型
CHECKAUTHORITY(name = '') {
let menu = uni.getStorageSync('weapp_session_Menu_data')
return menu[name] === undefined ? false : menu[name]
},
},

filters: {
// ASCII码转换 大写字母A是65 演讲人是从1开始所以num+64
toCapital(num) {
let str = ''
if (num) {
str = String.fromCharCode(num + 64)
}
return str
}
}
});
}
});

// 新版本更新
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate(function(res) {
if (res.hasUpdate) {
updateManager.onUpdateReady(function() {
uni.showModal({
title: '更新提示',
cancelColor: "#999999",
content: '新版本已经准备好,是否重启应用?',
success: function(res) {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function() {
uni.showModal({
title: '已经有新版本了哟~',
cancelColor: "#999999",
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~'
})
})
}
})
} else {
uni.showModal({
title: '提示',
cancelColor: "#999999",
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}

// 判断token
const token = uni.getStorageSync("weapp_session_login_data")
if (typeof token.token != "string") {
return
}
uni.request({
url: config.service.getUser,
method: "GET",
header: {
'content-type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync('weapp_session_login_data').token
},
success: (res) => {
let rescor = res.data.data;
// return
if (res.statusCode == 401) {
uni.showToast({
title: '登录过期请重新登录',
icon: "none",
duration: 2000,
})
uni.navigateTo({
url: `/pages/login/index`
})
return
}
if (rescor.user.total == 0) {
uni.showToast({
title: '暂无绑定项目',
duration: 2000,
icon: "none"
});
return
} else {
let lopan = {
id: rescor.houseList[0].id,
name: rescor.houseList[0].propertyName
}
let users = rescor.user
users.zkProperties = rescor.houseList
uni.setStorageSync("weapp_session_userInfo_data", users); //写入缓存
}
}
})


this.$u.get(config.service.notReadNum, {
id: uni.getStorageSync('weapp_session_userInfo_data').accountId,
projectId: uni.getStorageSync('buildingID').id
}).then(res => {
if (res > 0) {
uni.setTabBarBadge({ //显示数字
index: 4, //tabbar下标
text: res || 0 //数字
})
} else {
uni.removeTabBarBadge({
index: 4
})
}
}).catch(e => {
uni.removeTabBarBadge({
index: 4
})
})
wx.setInnerAudioOption({
obeyMuteSwitch: false
});
onLaunch() {
},


onShow(options) {
const token = uni.getStorageSync("weapp_session_login_data")
if (typeof token.token != "string") {
return
} else {}
onShow() {
},


methods: {
// 设置底部导航栏
setTabbarItems() {
const tabbarList = [{
iconPath: "/static/images/tabBar/jiedais.png",
selectedIconPath: "/static/images/tabBar/jiedaiActives.png",
text: "接待"
},
{
iconPath: "/static/images/tabBar/kehus.png",
selectedIconPath: "/static/images/tabBar/kehuActives.png",
text: "客户"
},
{
iconPath: "/static/images/tabBar/works.png",
selectedIconPath: "/static/images/tabBar/workActives.png",
text: "工作台"
},
{
iconPath: "/static/images/tabBar/xuexis.png",
selectedIconPath: "/static/images/tabBar/xuexiActives.png",
text: "学习"
},
{
iconPath: "/static/images/tabBar/mes.png",
selectedIconPath: "/static/images/tabBar/meActives.png",
text: "我的"
}
]
if (domainObj.domain == 'zh.aihxz.com') {
tabbarList.forEach((item, index) => {
uni.setTabBarItem({
index: index,
iconPath: item.iconPath,
selectedIconPath: item.selectedIconPath
})
})
}
}
}
};
</script>

<style>
@import "./app.css";
</style>
<style lang="scss">
@import "uview-ui/index.scss";

/*每个页面公共css */
//图表样式等
.single {
width: 100%;
background: #FFFFFF;

.title {
width: 100%;
height: 80rpx;
display: flex;
align-items: center;

.title1 {
flex: 2;
font-size: 30rpx;
font-weight: 500;
color: #333333;
line-height: 80rpx;
padding-left: 30rpx;
font-family: PingFangSC-Medium, PingFang SC;
}

.title3 {
flex: 3;
height: 90rpx;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 30rpx;

.title3-box {
display: flex;
align-items: center;
width: 25%;
justify-content: center;

.activecltab {
color: #2671E2;
border-bottom: 4rpx solid #2671E2;
}
}
}

.title2 {
flex: 2;
display: flex;
justify-content: flex-end;
align-items: center;
height: 42rpx;
font-size: 30rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 42rpx;
margin-right: 30rpx;

.righttochoose {
width: 24rpx;
height: 12rpx;
margin-left: 12rpx;
}
}
}

.swiper-box {
width: 97%;
margin: 0 auto 26rpx;
}

.hejibox {
width: 100%;
height: 80rpx;
display: flex;

.heji {
width: 50%;
height: 100%;
font-size: 28rpx;
font-weight: 400;
color: #666666;
line-height: 80rpx;
text-indent: 30rpx;
}
}

.danwei {
width: 100%;
height: 40rpx;
font-size: 24rpx;
font-weight: 400;
color: #999999;
line-height: 40rpx;
text-indent: 30rpx;
}

.uchaserbox {
width: 95%;
height: 470rpx;
}

.jindu {
width: 100%;
min-height: 400rpx;

.jindu-box {
width: 100%;
padding: 0 30rpx;

.jindu-boxche {
width: 100%;
height: 40rpx;
display: flex;
align-items: center;
margin-bottom: 38rpx;

.jindu-name {
width: 120rpx;
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 40rpx;
}

.progress-cus {
flex: 1;
height: 30rpx;
margin-left: 10rpx;
background: #F0F1F2;

.color {
height: 30rpx;
background: linear-gradient(90deg, #3A82EF 0%, #7EB2FF 100%);
}

.color4 {
height: 30rpx;
background: linear-gradient(270deg, #6DC5B8 0%, #07B79D 100%);
}

.color1 {
height: 30rpx;
background: linear-gradient(270deg, #F88881 0%, #E6625B 100%); //1
}

.color2 {
height: 30rpx;
background: linear-gradient(270deg, #FFC940 0%, #FF981E 100%); //2
}

.color3 {
height: 30rpx;
background: linear-gradient(270deg, #FFE800 0%, #FFCC00 100%); //3
}
}

.jindu-zxl {
width: 120rpx;
font-size: 28rpx;
margin-left: 12rpx;
color: #333;
text-align: left;
line-height: 40rpx;
}
}
}
}
}

//时间切换的样式
.boxtittab {
width: 100;
height: 92rpx;
background: #FFFFFF;
display: flex;
align-items: center;

.tabbox {
flex: 1;
height: 100%;
text-align: center;
line-height: 92rpx;
color: #666666;
font-size: 28rpx;
font-weight: 400;
display: flex;
justify-content: center;

.activecllasscet {
width: 96rpx;
color: #2671E2;
font-weight: 600;
border-bottom: 4rpx solid #2671E2;
}
}
}

//多个格子的样式
.boxzonglan {
width: 100%;
min-height: 496rpx;
background: #FFFFFF;
padding: 30rpx 30rpx 30rpx 30rpx;

.zonglantit {
font-size: 30rpx;
color: #333333;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 500;
}

.zonglanbox {
width: 100%;
display: flex;
flex-wrap: wrap;
margin-top: 24rpx;
box-shadow: 0px 0px 12rpx 0px rgba(38, 113, 226, 0.1);
border-radius: 12rpx;

.grid {
width: 50%;
// height: 128rpx;
padding-bottom: 24rpx;
// border: 1rpx solid #E0E0E0;

.audonum {
color: #666666;
text-indent: 40rpx;
font-size: 28rpx;
margin-top: 20rpx;
line-height: 40rpx;
display: flex;
align-items: center;

.circle {
width: 20rpx;
height: 20rpx;
background: #FFFFFF;
border: 6rpx solid #2671E2;
margin-right: 12rpx;
margin-left: 30rpx;
border-radius: 50%;
}
}

.num {
color: #333333;
text-indent: 40rpx;
font-size: 44rpx;
font-weight: 600;
line-height: 50rpx;
margin-top: 18rpx;
}
}
}
}
</style>

+ 476
- 233
pages/index/guide.vue View File

@@ -1,144 +1,317 @@
<template>
<view class="boox">
<digital-human :width="0"
rootStyle="position: fixed; left: 50%; top: 100rpx; transform: translateX(-50%);z-index: -1;">
<view class="pages">
<digital-human :width="0" rootStyle="position: fixed; left: 50%; top: 100px; transform: translateX(-50%);">
</digital-human>

<view class="message-box">
<!-- 对话框 -->
<block v-for="(message, index) in messageList">
<view :class="{lside: message.direction == 'lside', rside: message.direction == 'rside'}" :key="index">
{{ message.text }}
<image class="bgs" src="https://qufang.oss-cn-beijing.aliyuncs.com/serverBg.jpg" mode="" />

<view class="server-box">
<view class="server-head">
<image class="servehead" src="@/static/image/servehead.png" mode="" />
<image class="voiceing" src="@/static/image/voiceing.png" mode="" />
</view>

<!-- 消息列表 -->
<scroll-view class="scroll-box" scroll-y :scroll-into-view="scrollId">
<!-- 循环体 -->
<block v-for="(item, index) in messageList">
<!-- 左侧 -->
<view :class="item.direction" :key="index" :id="`scrollId${index}`">
<view class="msg-text">
<view class="msg-texts">
{{ item.text }}
</view>
<image @tap="rePlayText(item.text)" v-if="item.direction == 'lside' && index !== 0 "
class="voiceplay" src="@/static/image/voiceplay.png" mode="" />
</view>
<view class="timer">{{ item.time }}</view>
</view>
</block>
</scroll-view>
<view class="send-box">

<view v-if="sendType" class="input-box">
<input v-model="inputText" class="inputs" placeholder-class="placestyle" type="text"
confirm-type="send" @confirm="sendChat" placeholder="输入你想咨询的问题或点击右边的麦克风和我聊天" />
</view>

<view v-else class="voice-box" @touchstart="touchStart" @touchend="touchEnd">
<text>{{ voiceState }}</text>
</view>

<view class="change-type">
<image @tap="changeSendType(false)" v-if="sendType" src="@/static/image/voiceInput.png" mode="" />
<image @tap="changeSendType(true)" v-else src="@/static/image/textInput.png" mode="" />
</view>
</block>
</view>
<view class="input-box" style="padding: 0 24rpx;">
<input style="border: 1rpx solid #00BFFF;height: 80rpx;padding: 0 24rpx;" placeholder="请输入" type="text"
confirm-type="search" @confirm="sendChat">

<view class="radio">
<!-- <image class="voice" @click.stop="changeVoiceShow" src="/static/images/recordingManagement/voice.png"
mode=""></image> -->

<cover-view class="voiceContent">
<cover-view class="box" @click.stop="" @touchstart="touchStart" @touchend="touchEnd">
<cover-view class="center">
<cover-image class="voice" src="/static/images/voice.png" mode="widthFix"></cover-image>
<cover-view class="text">
{{voiceState}}
</cover-view>
</cover-view>
</cover-view>
</cover-view>
</view>
</view>

<!--
<view class="topBox"
style="position: fixed;left: 50%; bottom: 0; transform: translateX(-50%);z-index: 999999;width: 100vw;height: 40vh;background-color: #1890FF;">
</view>
-->
<!-- <view class="booximg">
<image v-if="domainObj.domain == 'zh.aihxz.com'" class="img"
src="https://autoiot.oss-cn-beijing.aliyuncs.com/static/wabIndexs.png" mode=""></image>
<image v-else class="img" src="https://autoiot.oss-cn-beijing.aliyuncs.com/static/wabIndex.png" mode="">
</image>
</view>

<view class="center-dingwei">
<view class="dingwei-title" style="margin-top: 0">
<image class="dingwei-img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png"
mode=""></image>
<view class="desc">智能语音转写</view>
</view>
<view class="dingwei-title">
<image class="dingwei-img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png"
mode=""></image>
<view class="desc">高效的判客机制</view>
</view>
<view class="dingwei-title">
<image class="dingwei-img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png"
mode=""></image>
<view class="desc">全方位的客户跟进</view>
</view>
<view class="dingwei-title">
<image class="dingwei-img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png"
mode=""></image>
<view class="desc">专业的经纪管家</view>
</view>
<view class="dingwei-title">
<image class="dingwei-img" src="https://qufang.oss-cn-beijing.aliyuncs.com/zkgj/xcx/images2.png"
mode=""></image>
<view class="desc">在线实时沟通</view>
</view>
<view v-if="recording" class="luyin">
<image src="@/static/image/recordingIcon.png" mode="" />
<text>正在录音...</text>
</view>

<view @click="bindWxBLogin" class="button">
<view class="view">
立即去登录
</view>
</view> -->
</view>
</template>

<script>
var app = getApp();
var config = require("../../config");
const domainObj = require('@/utils/domain.js');

var plugins = requirePlugin("WechatSI");
const pluginConfig = { // 数字人配置
"asrConfig": {
"class": "TencentASR",
"secretKey": "",
"secretId": "AKIDyvwuvrfikhYK1dDj9Vlv154zmVAjFdt0",
"appId": 1310500600,
"partnerId": "0002",
"signatureUrl": "https://commercial-integration-asr-int-api.xiaoice.com/api/v3/asr/tencentSignature",
"hotWordId": "2ab7be50d11f11ecbfd6525400aec391",
"silenceTime": 240,
"engineModelType": "16k_zh",
"needVad": 1,
"filterDirty": 1,
"filterModal": 0,
"filterPunc": 1,
"vadSilenceTime": 240,
"convertNumMode": 1,
"wordInfo": 2
},
"character": "chenzheling-yellow",
"characterConfig": {
"characters": {
"chenzheling-yellow": {
"name": "chenzheling-yellow-half",
"id": "chenzheling-yellow",
"frameWidth": 740,
"frameHeight": 1260,
"faceWidth": 190,
"faceHeight": 300,
"facePositionLeft": 450,
"facePositionTop": 550,
"facePositionLeftOffset": -180,
"facePositionTopOffset": -430,
"frameRate": 25,
"defaultIdle": "A-idle",
"idles": {
"A-idle": {
"id": "A-idle",
"version": 6,
"frameImageLength": 227,
"frameImageType": "webp",
"resetFrameSingleNum": 8,
"resetFrames": [7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223],
"frameImageBackupType": "png"
}
},
"gestures": {},
"crops": {}
}
},
"sourcePath": "https://commercial-cdn.xiaoice.com/assets/images/characters",
"batch": 16,
"minLoadFrameNum": 100
},
"chatConfig": {
"class": "CXHubChat",
"url": "https://commercial-fab.xiaoice.com/api/hub/organizations/org-qufangwang/agents/64af7b6d6e1ba4813c4bd6ae/environments/draft/sessions",
"defaultReply": [{
"text": "对不起,我没听清~",
"gesture": ""
}],
"csChatUrl": "https://commercial-fab.xiaoice.com/api/hub/organizations/org-qufangwang/characters//sessions"
},
"logConfig": {
"class": "AliTraceLogger",
"metaData": {
"role": "prod",
"organizationId": "org-qufangwang",
"partnerId": "dh-api",
"agentId": "64af7b6d6e1ba4813c4bd6ae"
}
},
"talkConfig": {
"class": "CarouselTalk",
"url": "https://commercial-fab.xiaoice.com",
"options": {
"path": "/api/v1/carousel/avatars/chenzheling-yellow/socket.io",
"wsPath": "/api/v1/carousel/avatars/chenzheling-yellow/websocket",
"transports": ["websocket", "polling"],
"query": "?image_format=.webp&voice_id=64af7b6da9d616bd022f6b69"
},
"maxRetryTime": 5,
"retryTimeInterval": 100
}
}
const plugin = requirePlugin('digital-human-plugin').api; // 数字人实例
const plugins = requirePlugin("WechatSI");
let manager = plugins.getRecordRecognitionManager();

import human from './mathManIndex.js'

export default {
mixins: [human],
data() {
return {
domainObj: domainObj, // 域名

isRecording: false,
voiceState: "你可以这样说...",
sendType: true, // true 为文字输入 false 为语音输入
messageList: [], // 消息列表
inputText: '', // 文字输入
voiceState: '按住 说话', //
recording: false, // 展示录音提示框
scrollId: '', // 默认不滚动
};
},
onLoad() {
uni.showLoading({
title: '加载中...',
})
plugin.init({
...pluginConfig,
onReceivedAsrText: (text) => {},
onSuccess: (res) => {
console.log(res, 'onSuccess')
uni.hideLoading()
let text = 'Hi~我是专业房产顾问嘉欣,有问题可以问我呦,试试说句“你好”和我打个招呼吧'
plugin.human?.talkAsync(text)
this.messageList.push({
text: text,
direction: 'lside'
})
},
onFailed: res => {
uni.hideLoading()
console.log(res, 'onFailed')
},
onError: (res) => {
uni.hideLoading()
console.log(res, 'onError')
}
})

this.initRecord()
},

onShow() {
uni.request({
url: config.service.verify,
method: "GET",
header: {
'content-type': 'application/json',
'Authorization': 'Bearer ' + uni.getStorageSync('weapp_session_login_data').token
},
success: (data) => {
if (data.data.code == 10000) {
uni.switchTab({
url: '/pages/index/index'
});
}
}
// #ifdef MP-WEIXIN

// 内存告警处理
wx.onMemoryWarning((level) => {
plugin.clearCache()
})
wx.setInnerAudioOption({
// IOS静音键的情况下允许播放声音
obeyMuteSwitch: false,
// 播放声音时中断其他app端声音
mixWithOther: false,
})
// #endif
},
onHide() {},
methods: {
bindWxBLogin() {
wx.navigateTo({
url: '/pages/login/index'
});
/**
* 切换输入方式
*/
changeSendType(e) {
this.sendType = e
},

// // 模拟聊天回复接口
async getReply(text) {
console.log(this.setUid())
await uni.request({
url: `${pluginConfig.chatConfig.url}/${this.setUid()}`,
method: 'POST',
data: {
"text": text,
"currentSceneInfo": {
"sceneId": ""
}
},
success: async (res) => {
const replay = res.data.sceneInfo[0].audioText[0]
await plugin.human?.interrupt()
let arr = []
arr.push({
direction: 'rside',
text: text,
time: this.getTimeNow()
})
arr.push({
direction: 'lside',
text: res.data.sceneInfo[0].audioText[0],
time: this.getTimeNow()
})
this.messageList = [...this.messageList, ...arr]
this.inputText = ''
this.scrollId = `scrollId${this.messageList.length-1}`

await plugin.human?.talkAsync(replay)
}
})
},



/**
* 重播当前对话
*/
async rePlayText(e) {
console.log(e)
// 暂停当前对话(如果有)
await plugin.human?.interrupt()
await plugin.human?.talkAsync(e)
},


/**
* 获取当前时间
*/
getTimeNow() {
let now = new Date();
let year = now.getFullYear(); //获取完整的年份(4位,1970-????)
let month = now.getMonth() + 1; //获取当前月份(0-11,0代表1月)
let today = now.getDate(); //获取当前日(1-31)
let hour = now.getHours(); //获取当前小时数(0-23)
let minute = now.getMinutes(); //获取当前分钟数(0-59)
let second = now.getSeconds(); //获取当前秒数(0-59)
let nowTime = ''
nowTime = year + '-' + this.fillZero(month) + '-' + this.fillZero(today) + ' ' + this.fillZero(hour) +
':' +
this.fillZero(minute) + ':' + this.fillZero(second)
return nowTime
},
// 补零
fillZero(str) {
var realNum;
if (str < 10) {
realNum = '0' + str;
} else {
realNum = str;
}
return realNum;
},


/**
* 发送文字
*/
async sendChat(e) {
await this.getReply(e.detail.value)
},

/**
* 长按识别
*/
touchStart() {
this.recording = true
manager.start({
duration: 60000,
lang: "zh_CN"
});
},

/**
* 长按结束
* */
touchEnd() {
uni.showToast()
this.recording = false
manager.stop();
},
/**
@@ -147,171 +320,241 @@
*/
initRecord() {
manager.onStart = (res) => {
this.voiceState = "onStart:" + res.msg + "正在录音"
this.voiceState = "正在录音"
};
//有新的识别内容返回,则会调用此事件
manager.onRecognize = (res) => {
this.voiceState = res.result;
}
manager.onRecognize = (res) => {}

// 识别结束事件
manager.onStop = async (res) => {

this.voiceState = res.result;
await this.getReply(res.result)
if (res.result) {
await this.getReply(res.result)
}

this.voiceState = "按住 说话"
}

// 识别错误事件
manager.onError = (res) => {

this.voiceState = res.msg;
manager.onError = (res) => {}
},

}
// 简单生成uid
setUid() {
let uid = new Date().getTime() + Math.random().toString(36).substr(2);
return uid
},


}
};
</script>
<style lang="scss">
.boox {
<style lang="scss" scoped>
/* pages/intelligentvoiceassistant/intelligentvoiceassistant.wxss */
view {
box-sizing: border-box;
}

.pages {
position: relative;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: flex-end;
}

.bgs {
position: absolute;
z-index: 0;
width: 100%;
height: 100%;
}

.server-box {
position: relative;
z-index: 10;
width: calc(100%-1rpx);
height: 658rpx;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: saturate(180%) blur(20px);
border-radius: 32rpx 32rpx 0 0;
border: 1rpx solid #FFFFFF;
}

.title {
width: 100%;
position: absolute;
left: 0rpx;
top: 100rpx;
text-align: center;
color: #FFFFFF;
font-size: 32rpx;
font-weight: 500;
z-index: 1000;
}
.server-head {
margin: -130rpx 0 0 0;
padding: 0 32rpx;
width: 100%;
display: flex;
align-items: flex-end;
}

.booximg {
width: 100vw;
height: 100vh;
.servehead {
width: 192rpx;
height: 192rpx;
}

.img {
width: 100%;
height: 100%;
}
}
.voiceing {
margin-left: 12rpx;
width: 78rpx;
height: 50rpx;
}

.center-dingwei {
width: 100%;
position: absolute;
left: 0rpx;
bottom: 200rpx;

.dingwei-title {
height: 44rpx;
display: flex;
margin-left: 213rpx;
margin-top: 20rpx;
}

.dingwei-img {
width: 44rpx;
height: 44rpx;
}

.desc {
line-height: 44rpx;
margin-left: 10rpx;
font-size: 32rpx;
color: #333333;
}
}
/*
.close {
width: ;
} */

.button {
width: 100%;
position: absolute;
left: 0rpx;
bottom: 60rpx;

.view {
width: 630rpx;
height: 86rpx;
margin: 0 auto;
background: #2671E2;
box-shadow: 0px 2rpx 20rpx 0rpx rgba(38, 113, 226, 0.5);
border-radius: 49rpx;
color: #FFFFFF;
text-align: center;
line-height: 86rpx;
font-size: 32rpx;
}
}

.scroll-box {
width: 100%;
height: calc(658rpx - 192rpx + 130rpx - 104rpx);
}

.lside {
display: flex;
flex-direction: column;
align-items: flex-start;
}

// 语音输入
.message-box {
padding: 24rpx;
width: 100vw;
height: 50vh;
display: flex;
flex-direction: column;
justify-content: flex-end;
.rside {
display: flex;
flex-direction: column;
align-items: flex-end;
}

.lside {
display: flex;
justify-content: flex-start;
}
.msg-texts {
margin: 36rpx 32rpx 12rpx;
padding: 16rpx 28rpx;
background: #fff;
border-radius: 20rpx;
}

.rside {
display: flex;
justify-content: flex-end;
}
}
.lside .voiceplay {
margin: 0 32rpx 16rpx 16rpx;
}

.lside .msg-text {
display: flex;
align-items: flex-end;
}

.lside .msg-text .msg-texts {
margin: 36rpx 16rpx 12rpx 32rpx;
}

.voiceContent {
width: 100vw;
height: 90rpx;
display: flex;
justify-content: center;
align-items: center;

.box {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;

.center {
width: 100%;
height: 100%;
background: #1590E9;
display: flex;
align-items: center;
justify-content: center;

.voice {
width: 70rpx;
height: 70rpx;
}

.text {
color: #FFFFFF;
font-size: 36rpx;
margin-top: 24rpx;
}
}
}
.timer {
margin: 0 32rpx;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 33rpx;
}

}
.rside .msg-texts {
background: #2671E2;
color: #fff;
}

.send-box {
padding: 0 24rpx;
width: 100%;
height: 104rpx;
background: #5D6168;
display: flex;
align-items: center;
/* justify-content: center; */
}

.voice {
width: 44rpx;
height: 44rpx;
margin-left: 38rpx;
}
.change-type {
margin: 0 0 0 24rpx;
width: 72rpx;
height: 72rpx;
}

.change-type image {
width: 72rpx;
height: 72rpx;
}

.input-box,
.voice-box {
width: 606rpx;
height: 72rpx;
background: #FFFFFF;
border-radius: 12rpx;
}

.voice-box {
display: flex;
justify-content: center;
align-items: center;
}

.voice-box text {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 40rpx;
}

.inputs {
padding: 0 28rpx;
box-sizing: border-box;
width: 100%;
height: 100%;
font-size: 22rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
line-height: 30rpx;
}

.placestyle {
font-size: 22rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #CCCCCC;
line-height: 30rpx;
}


.luyin {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 100;
width: 280rpx;
height: 258rpx;
background: rgba(0, 0, 0, 0.7);
border-radius: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.luyin image {
margin: 0 0 20rpx 0;
width: 46rpx;
height: 62rpx;
}

.luyin text {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 40rpx;
}

.voiceplay {
flex-shrink: 0;
width: 64rpx;
height: 64rpx;
}
</style>

BIN
static/image/recordingIcon.png View File

Before After
Width: 92  |  Height: 124  |  Size: 3.4 KiB

BIN
static/image/servehead.png View File

Before After
Width: 384  |  Height: 384  |  Size: 32 KiB

BIN
static/image/textInput.png View File

Before After
Width: 144  |  Height: 144  |  Size: 1.4 KiB

BIN
static/image/voiceInput.png View File

Before After
Width: 144  |  Height: 144  |  Size: 1.4 KiB

BIN
static/image/voiceing.png View File

Before After
Width: 156  |  Height: 100  |  Size: 2.9 KiB

BIN
static/image/voiceplay.png View File

Before After
Width: 80  |  Height: 80  |  Size: 3.5 KiB

Loading…
Cancel
Save