You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

497 lines
14 KiB

<template>
<view class="page1">
<view class="voice-model" v-if="recordState == true">
<img src="/static/images/maikefeng.png" alt="">
<view class="voice-text">语音识别中...</view>
</view>
<view class="top" ref="top">
<view @tap="backPage" style="width: 40px;height: 40px;position: absolute;top: 100rpx;left: 30rpx;">
<uni-icons type="left" color="#000" size="27"></uni-icons>
</view>
<view class="title">对话</view>
</view>
<view class="content" :style="{height:height - 165 +'px'}">
<view class="prompt">
<view class="prompt-title">
<view class="hello-right"></view>
<view class="ai-bot"></view>
<view class="hello-left">
<text style="font-size: 40rpx;font-weight: 800;line-height: 56rpx;color: #fff;">Hi</text>
</view>
</view>
<view class="prompt-title-text">
<text>欢迎使用Ai助手,为了提高语音及文字识别准确率,建议您按照以下规则操作:</text>
<text style="color: #FF9797;">1.语音规则:(颜色在前,尺码在后)</text>
<text>例1:“货号87-12白色M码10件”</text>
<text>例2:“货号87-12,所有颜色所有尺码10件”</text>
<text style="color: #FF9797;">2.建议您不同商品用“货号”两字分隔</text>
<text>例:“<text style="color: #FF9797;">货号87-12</text>白色M码10件,<text style="color: #FF9797;">货号ZK001</text>黑色L码10件”</text>
<text>3.如需手动输入,则要点击“确认”按钮发送对话</text>
<text>4.录入完成后点击开始识别按钮进行AI识别</text>
<text>5.点击可查看<text @tap="goTutorial" style="color: blue;">使用教程</text></text>
</view>
</view>
<view class="prompt" style="height: 80rpx;line-height: 80rpx;padding-left: 20rpx;">
<text>您当前选择的客户是:{{khName.name}}</text>
</view>
<view style="width: 100%;height: 100rpx;text-align: center;font-size: 11px;color: #777;line-height: 100rpx;">
点击可编辑语音输入的内容~
</view>
<view style="width: 526rpx;float: right;margin-right:20rpx;text-align: left;padding-bottom: 60rpx;">
<view style="width: 526rpx;display: block;float: right;" v-for="(item,index) in msgList" :key="index">
<view @tap="editTextBtn(item,index)" style="display: inline-block;width: auto;height: auto;min-height: 40px;background: linear-gradient(127.96deg, #6585fa 0%, #6ad5fe 100%);color: #fff;padding: 20rpx 10px;border-radius: 10px;border-bottom-right-radius: 0;margin-bottom: 20px;float: right;">
{{item.text}}
</view>
</view>
</view>
</view>
<view @tap="addReg" style="width: 150rpx;position: absolute;bottom: 86px;z-index: 99;right: 10px;height: 60rpx;text-align: center;line-height: 60rpx;color: #fff;border-radius: 5px;background: linear-gradient(90deg, #FF9797, #FFC1E0);">
开始识别
</view>
<view class="bottom">
<view style="width:10%;height:90rpx;line-height:90rpx;margin-top:20rpx;text-align: center;">
<uni-icons v-if="isVoice" @tap="switchChat(false)" type="chat" size="26"></uni-icons>
<uni-icons v-if="!isVoice" @tap="switchChat(true)" type="mic" size="26"></uni-icons>
</view>
<view style="width: 76%;height: 90rpx;line-height: 90rpx;text-align: center;background: #eee;margin-top: 10px;border-radius: 10px;font-size: 30rpx;color: #777;">
<view v-if="isVoice" @touchstart="kaishi" @touchend="jieshu">
<text>按住 说话</text>
</view>
<view v-if="!isVoice" style="width: 100%;height: 90rpx;line-height: 90rpx;border-radius: 10px;text-align: left;padding-left: 20rpx;">
<input type="text" v-model="editText" placeholder="请输入对话内容" style="height: 90rpx;">
</view>
</view>
<view v-if="!isVoice" @tap="inputSaveText" style="width:12%;background: linear-gradient(90deg, #60F3FF, #088FEB);height:70rpx;line-height:70rpx;text-align:center;margin:15px 0 0 1%;color:#fff;border-radius:5px;">
确定
</view>
</view>
<!-- 弹出规格选择 -->
<uni-popup ref="popup" background-color="#fff">
<view class="popup-content">
<view class="popup-title">
<text>修改当前内容</text>
<uni-icons @tap='close' type="closeempty" color='red' size="16"
style="height:40rpx;line-height: 40rpx;position: absolute !important;bottom:0;right: 30rpx;"></uni-icons>
</view>
<view class="popup-container">
<textarea maxlength="-1" v-model="editText" style="padding: 20rpx;width:100%;border:1px solid #eee;"></textarea>
<view class="popup-bottom">
<view @tap="saveText" style="width: 100%;height: 70rpx;line-height: 70rpx;text-align: center;border-radius: 0;background: linear-gradient(90deg, #60F3FF, #088FEB);color: #fff;">
确认无误
</view>
</view>
</view>
</view>
</uni-popup>
<view class="mask-model" v-if="isNoVoice">貌似没有检测到您上次的语音录入信息,正在反复识别中</view>
</view>
</template>
<script>
var plugin = requirePlugin("WechatSI")
let manager = plugin.getRecordRecognitionManager()
export default {
components: {},
data() {
return {
isVoice:true,
isNoVoice:false,
height:0,
khName:{},
msgList:[],
editText:'',
index:'',
recordState: false
}
},
onShow() {
},
onLoad(option) {
this.height = wx.getSystemInfoSync().windowHeight
this.khName = JSON.parse(option.khName)
this.initRecord();
},
methods: {
switchChat(type){
this.isVoice = type
},
editTextBtn(item,index){
this.editText = item.text
this.index = index
this.$refs.popup.open()
},
saveText(){
this.msgList[this.index].text = this.editText
this.$forceUpdate()
this.editText = ''
this.close()
},
close(){
this.$refs.popup.close()
},
//正则匹配处理“2十9”等情况
convertStringCorrectly(str) {
var regexForSingleTen = /(\d+)十(?!\d)/g;
var regexForFollowedByDigit = /(\d+)十(?=\d)/g;
var step1Result = str.replace(regexForSingleTen, '$10');
var finalResult = step1Result.replace(regexForFollowedByDigit, '$1');
return finalResult;
},
spliceMsg(res){
let regex = /嗯|啊|儿|阿|恩/g;
return res.replace(regex, '')
},
convertChineseToArabic(str) {
const chineseNumToArabic = {
'零': 0, '一': 1, '二': 2, '两': 2, '三': 3,
'四': 4, '五': 5, '六': 6, '七': 7, '八': 8,
'九': 9,'杠':'-','刚':'-','军色':'均色','叉':'X','井':'#',
'时间':'10件','事件':'10件','世间':'10件','实践':'10件','实件':'10件',
'景':'#','警':'#','颈':'#','括号':'货号','名城':'名称','明城':'名称','名成':'名称','名程':'名称',
};
const regex = /(零|一|二|两|三|四|五|六|七|八|九|杠|刚|军色|叉|井|时间|事件|世间|实践|实件|景|警|颈|括号|名城|名程|名成|明城)/g;
return str.replace(regex, match => chineseNumToArabic[match]);
},
inputSaveText(){
let convertedStr = this.convertChineseToArabic(this.editText);
if(convertedStr.indexOf('点') != -1){
convertedStr = this.replaceCharAfterNumber(convertedStr,'点','.')
}
if(convertedStr.indexOf('货号,') != -1){
convertedStr = convertedStr.replace(/货号,/g,'货号')
}
if(convertedStr.indexOf('货号') != -1){
convertedStr = convertedStr.replace(/货号/g,'货号:')
}
if(convertedStr.indexOf(',数量') != -1){
convertedStr = convertedStr.replace(/,数量/g,'数量')
}
if(convertedStr.indexOf('数量,') != -1){
convertedStr = convertedStr.replace(/数量,/g,'数量')
}
if(convertedStr.indexOf('数量') != -1){
convertedStr = convertedStr.replace(/数量/g,',数量:')
}
convertedStr = this.convertStringCorrectly(convertedStr)
convertedStr = this.spliceMsg(convertedStr)
if(convertedStr.indexOf(',') == 0){
convertedStr = convertedStr.substr(1)
}
if (convertedStr.startsWith("号")) {
convertedStr = "货号" + convertedStr.substr(1);
}
let getMsg = convertedStr
if(this.editText == ''){
return;
}
let data = {
text:getMsg
}
this.msgList.push(data)
this.editText = ''
},
//按住语音识别,开始
kaishi() {
if(this.isNoVoice == false){
this.recordState = true
uni.vibrateShort();
manager.start({
duration: 60000,
lang: "zh_CN"
});
}
},
//松开语音识别,结束
jieshu() {
this.recordState = false
manager.stop()
},
replaceCharAfterNumber(str, charToFind, charToReplace) {
const regex = new RegExp(`\\d${charToFind}`, 'g');
return str.replace(regex, (match) => {
return match.replace(charToFind, charToReplace);
});
},
//语音识别功能初始化
initRecord() {
let that = this;
manager.stop()
// 识别结束事件
manager.onStop = (res) => {
let convertedStr = this.convertChineseToArabic(res.result);
if(convertedStr.indexOf('点') != -1){
convertedStr = that.replaceCharAfterNumber(convertedStr,'点','.')
}
if(convertedStr.indexOf('货号,') != -1){
convertedStr = convertedStr.replace(/货号,/g,'货号')
}
if(convertedStr.indexOf('货号') != -1){
convertedStr = convertedStr.replace(/货号/g,'货号:')
}
if(convertedStr.indexOf(',数量') != -1){
convertedStr = convertedStr.replace(/,数量/g,'数量')
}
if(convertedStr.indexOf('数量,') != -1){
convertedStr = convertedStr.replace(/数量,/g,'数量')
}
if(convertedStr.indexOf('数量') != -1){
convertedStr = convertedStr.replace(/数量/g,',数量:')
}
convertedStr = this.convertStringCorrectly(convertedStr)
convertedStr = this.spliceMsg(convertedStr)
if(convertedStr.indexOf(',') == 0){
convertedStr = convertedStr.substr(1)
}
if (convertedStr.indexOf('号') == 0) {
convertedStr = "货号" + convertedStr.substr(1);
}
let data = {
text:convertedStr
}
that.msgList.push(data)
that.$forceUpdate()
}
// 识别错误事件
manager.onError = (res) => {
if(res.retcode == '-30011'){
that.isNoVoice = true
}
if(res.retcode == '-30004'){
// uni.hideLoading()
that.isNoVoice = false
uni.hideToast()
uni.showToast({
title: "未识别到声音信息,请重新录入",
icon: 'none'
})
}
if (res.retcode == '-40001') {
uni.showToast({
title: '使用次数超限制,请联系管理员!',
icon: 'none'
})
}
}
},
addReg() {
if(this.msgList.length <= 0){
this.tui.toast("小助手没有检测到可识别的内容哦~")
return
}
this.tui.request("/app/sale/saveOrder", "POST", {
userId:this.khName.id,
userName:this.khName.name,
aiFlag:1,
status: 7,
area:this.khName.area,
city:this.khName.city,
province:this.khName.province,
receiveAddress:this.khName.address
}, false, false).then((res) => {
if (res.code == 200) {
this.goHangOrder(res.result.id)
} else {
this.tui.toast(res.message)
}
}).catch((res) => {
this.tui.toast(res)
})
},
goHangOrder(saleId){
let text = ' '
for(let i=0;i<this.msgList.length;i++){
this.msgList[i].text
text += this.msgList[i].text + ' '
}
this.tui.request("/app/sale/buyAiSync", "POST", {
aiMsg:text,
saleId:saleId,
}, false, true).then((res) => {
if(res.code == 200){
uni.navigateBack({
delta: 1
})
}
}).catch((res) => {
this.tui.toast(res)
})
},
backPage(){
uni.navigateBack({
delta: 1
})
},
goTutorial(){
uni.navigateTo({
url: `/package2/other/tutorialList`
})
}
}
}
</script>
<style lang="scss">
page,
.page1 {
height:100%;
background: #F1F5FB;
}
.top {
width: 100%;
height: 180rpx;
opacity: 1;
overflow: hidden;
display: flex;
}
.title{
color: #000;
height: 80rpx;
line-height: 80rpx;
margin-top: 94rpx;
width: 100%;
text-align: center;
font-size: 32rpx;
font-weight: bold;
}
.content{
overflow:scroll;
}
.bottom{
width: 100%;
height: 150rpx;
display: flex;
background: #fff;
}
.prompt {
background: #fff;
width: 75%;
height: auto;
border-radius: 10px;
display: block;
overflow: hidden;
border-bottom-left-radius: 0;
margin: 20rpx 0 0 20rpx;
padding-bottom: 20rpx;
}
.prompt-title {
position: relative;
width: 300rpx;
margin: 40rpx 40rpx 20rpx 40rpx;
}
.prompt-title-text {
display: flex;
flex-direction: column;
color: #777;
font-size: 26rpx;
width: 90%;
margin: 0 auto;
line-height: 40rpx;
}
.ai-bot {
position: absolute;
top: -8rpx;
left: 10rpx;
width: 70rpx;
height: 60rpx;
background-size: 100% !important;
background: url(https://jewel-shop.oss-cn-beijing.aliyuncs.com/66dc640d9e8f4749a234d9ef2af1b257.png) no-repeat;
}
.hello-right {
position: absolute;
left: 5px;
bottom: 0rpx;
width: 120rpx;
height: 2px;
opacity: 1;
background: linear-gradient(180deg, #6585fa 0%, #6ad5fe 100%);
}
.hello-left {
width: 102rpx;
height: 56rpx;
opacity: 1;
margin-left: 100rpx;
background: linear-gradient(127.96deg, #6585fa 0%, #6ad5fe 100%);
border-radius: 3px;
text-align: center;
-webkit-transform: skewX(8deg);
transform: skewX(-6deg);
}
.popup-content {
align-items: center;
justify-content: center;
padding: 15px;
width: 500rpx;
height: 550rpx;
background-color: #fff;
}
.voice-model {
width: 300rpx;
height: 300rpx;
display: flex;
justify-content: center;
flex-flow: column;
position: fixed;
left: 50%;
top: 45%;
background: rgba(0, 0, 0, 0.5);
border-radius: 20rpx;
color: #fff;
text-align: center;
margin-left: -150rpx;
z-index: 99;
}
.voice-model img {
width: 200rpx;
height: 200rpx;
margin: 0 auto;
}
.popup-title {
font-size: 36rpx;
font-weight: bold;
text-align: center;
position: relative;
}
.popup-container {
margin-top: 20rpx;
}
.popup-bottom {
display: flex;
height: 80rpx;
color: #fff;
line-height: 80rpx;
margin-top: 50rpx;
}
.mask-model{
width: 60%;
height: 100rpx;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
text-align: center;
background: rgba(0,0,0,0.7);
color: #eee;
padding: 5px;
border-radius: 5px;
z-index: 99;
}
</style>