Compare commits

..

9 Commits

Author SHA1 Message Date
jia 7d5556f4c1 新增关闭功能 2023-11-01 15:08:17 +08:00
weipengfei e658558d4b 更新讯飞页面,修复bug 2023-09-26 19:08:35 +08:00
weipengfei b9e940e4b8 删除目录的同时取消跟踪 2023-09-26 15:05:50 +08:00
weipengfei 03c232d1c3 更新 2023-09-26 14:54:22 +08:00
weipengfei 21fdf942a7 更新 2023-09-26 14:25:33 +08:00
weipengfei fdaa22276b 种植 2023-09-26 14:22:35 +08:00
weipengfei ebed1f6087 情感咨询 2023-09-26 14:19:29 +08:00
weipengfei d5d5500290 新增情感 2023-09-26 14:00:12 +08:00
weipengfei 43c75b62fd 新增教育咨询 2023-09-26 13:49:59 +08:00
22 changed files with 3029 additions and 814 deletions

2
.gitignore vendored
View File

@ -1,6 +1,5 @@
.DS_Store .DS_Store
node_modules node_modules
unpackage*
/dist /dist
.hbuilderx .hbuilderx
@ -26,3 +25,4 @@ build.sh
.idea .idea
unpackage unpackage
*.bak *.bak
/unpackage

View File

@ -13,7 +13,7 @@
"type" : "uniCloud" "type" : "uniCloud"
}, },
{ {
"playground" : "standard", "playground" : "custom",
"type" : "uni-app:app-android" "type" : "uni-app:app-android"
}, },
{ {

View File

@ -2,6 +2,11 @@
export default { export default {
onLaunch: function(info) { onLaunch: function(info) {
console.log('App Launch'); console.log('App Launch');
uni.sendHostEvent('log',info, (ret) => {
//
console.log('消息成功app' + JSON.stringify(info));
});
if (info.referrerInfo?.extraData?.uniMP) { if (info.referrerInfo?.extraData?.uniMP) {
uni.setStorageSync('uniMP', info.referrerInfo?.extraData?.uniMP); uni.setStorageSync('uniMP', info.referrerInfo?.extraData?.uniMP);
uni.setStorageSync('APP_token', info.referrerInfo?.extraData?.token); uni.setStorageSync('APP_token', info.referrerInfo?.extraData?.token);
@ -24,4 +29,5 @@
<style> <style>
/*每个页面公共css */ /*每个页面公共css */
</style> </style>

View File

@ -18,6 +18,36 @@ export function ttWss(data) {
return requesta.post(`index/tts`, data); return requesta.post(`index/tts`, data);
} }
//图片识别
export function ttocr(data) {
return request.post(`xun_fei/ocr`, data);
}
// base64 转 二进制流(blob)
export function dataURLtoBlob(dataurl) {
// console.log(dataurl);
// let str = "data:audio/wav;base64," + dataurl.slice(2)
// console.log(str);
let mime = "audio/wav"
// var arr = str.split(","),
// mime = arr[0].match(/:(.*?);/),
// let bstr = atob(arr[1])
let bstr = atob(dataurl)
let n = bstr.length
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
console.log(u8arr)
// return new Blob([u8arr], {
// type: mime,
// });
}
// -防抖 // -防抖
export function debounce(fn, wait) { export function debounce(fn, wait) {
let delay = wait || 500 let delay = wait || 500

View File

@ -0,0 +1,92 @@
<template>
<view class="contentgb">
<view class="return_top">
<view class="z-bootm-img1" @click="returnbom()">
<image src="@/static/icon/fb1.png" mode="aspectFit"></image>
</view>
<view class="z-bootm-l"></view>
<view class="z-bootm-img2" @click="returnbom()">
<image src="@/static/icon/fb2.png" mode="aspectFit"></image>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
returnbom() {
uni.sendHostEvent('closeApp', (ret) => {
//
console.log('关闭应用' + JSON.stringify(ret));
});
}
}
}
</script>
<style lang="scss" scoped>
.contentgb {
width: 166rpx;
height: 56rpx;
.return_top {
width: 166rpx;
height: 56rpx;
background: rgba(255, 255, 255, 0.6);
border-radius: 44rpx 44rpx;
position: relative;
.z-bootm-img1 {
width: 41rpx;
height: 13rpx;
position: absolute;
top: 20rpx;
left: 25rpx;
image {
width: 100%;
height: 100%;
}
}
.z-bootm-l {
width: 1px;
height: 32rpx;
background: rgba(0, 0, 0, 0.2);
margin: auto 0;
position: absolute;
top: 10rpx;
left: 85rpx;
}
.z-bootm-img2 {
width: 38rpx;
height: 34rpx;
margin-top: -15rpx;
margin-left: -15rpx;
position: absolute;
right: 25rpx;
top: 25rpx;
image {
width: 100%;
height: 100%;
}
}
}
}
</style>

View File

@ -0,0 +1,444 @@
<template>
<view class="qiqb-ctx" v-bind:class="{'on':show}">
<view class="qiqb-ctx-box">
<!-- <text @click="show=false"></text> -->
<canvas canvas-id="ctx" style="width:330px;height:300px" v-show="img_show"></canvas>
</view>
<view class="qiqb-ctx-btns u-border-bottom">
<view>分享至</view>
<view>长按海报可转发分享</view>
<view>
<!-- <text>微信好友</text><text>分享朋友圈</text> -->
<text @click="down">保存图片</text>
</view>
</view>
<view class="qiqb-ctx-close" @click="show=false">取消</view>
</view>
</template>
<!-- https://crmeb-test.shop.lihaink.cn/api/upload/image/field -->
<script>
export default {
name: "share",
data() {
return {
show: false,
img_show: true,
mode: 'img',
list: [],
pext1: '',
pext2: ''
}
},
onLoad() {
uni.$on('add', function(res) {
console.log(res.listData) // B
})
},
mounted() {
// console.log(this.list,'222222')
},
methods: {
//
refresh(index) {
this.list = index;
this.pext1 = index[index.length - 2].content
this.pext2 = index[index.length - 1].content
// console.log(this.list)
},
init() { // opt
uni.showLoading({
title: '生成中'
})
let self = this
let ctx = uni.createCanvasContext('ctx')
//
self.drawBg(ctx, 330, 300, 8, '#fff')
//
uni.downloadFile({
url: 'http://banbai.oss-cn-beijing.aliyuncs.com/20230524/96e80fb572e35d4acebdce67dbd41f30.jpg',
success: function(e) {
let img = e.tempFilePath //
uni.downloadFile({
url: 'http://banbai.oss-cn-beijing.aliyuncs.com/20230524/96e80fb572e35d4acebdce67dbd41f30.jpg',
success: function(e) {
let photo = e.tempFilePath //
uni.downloadFile({
url: 'http://banbai.oss-cn-beijing.aliyuncs.com/20230606/f0738e1ff432c08b369ca5e4b906a34a.png',
success: function(e) {
uni.hideLoading()
let qrcode = e.tempFilePath //
self.drawTxtOne(ctx, '农业咨询小程序', 220, 35, 100,
'#222', 12, false)
//
self.drawImg(ctx,
'https://lihai001.oss-cn-chengdu.aliyuncs.com/storage/202310/20231013091310.png',
170, 10, 40, 40, 20)
self.drawImg(ctx,
'https://lihai001.oss-cn-chengdu.aliyuncs.com/storage/202310/20231013091059.png',
10, 50, 40, 40, 20)
self.drawImg(ctx,
'https://lihai001.oss-cn-chengdu.aliyuncs.com/storage/202310/20231013091310.png',
10, 118, 40, 40, 20)
//
// self.drawImg(ctx, img, 10, 120, 210, 260, 8)
//
self.drawImg(ctx,
'https://lihai001.oss-cn-chengdu.aliyuncs.com/storage/202310/ai_qr_20231013091327.jpg',
174, 195, 100, 100, 0)
//
self.drawTxtOne(ctx, self.pext1, 60, 70, 100,
'#222', 12, false)
// self.drawTxtTwo(ctx, self.pext1, 60, 64, 80,
// '#222', 13)
// self.drawTxtTwo(ctx, self.pext1, 60,64,
// 190, 20, '#222', 12)
//
// self.drawTxtOne(ctx, '', 60, 80, 100,
// '#666', 9, false)
//
self.drawTxtFour(ctx,
self.pext2,
60, 120,
190, 20, '#222', 12)
//
self.drawTxtOne(ctx, '下载二维码', 15, 250, 100,
'#666', 11, false)
//
// self.drawTxtOne(ctx, '', 15, 350, 100,
// '#ED3327', 11, false)
//
// self.drawTxtOne(ctx, '86.00', 82, 350, 100,
// '#ED3327', 11, true)
//
// self.drawTxtDel(ctx, ':20', 15, 370, 4,
// '#818181', 10, false)
//
ctx.draw()
self.show = true
}
})
}
})
}
})
},
down() {
uni.showLoading({
title: '保存中'
})
uni.canvasToTempFilePath({
canvasId: 'ctx',
quality: 1,
success: (res) => {
uni.hideLoading()
console.log(res)
this.$emit('down', res)
this.show = false
//
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
console.log('保存')
uni.showModal({
title: '保存成功'
})
}
})
}
})
},
//
drawBg(ctx, w, h, r, color) {
let x = 0
let y = 0
ctx.setFillStyle(color)
ctx.save()
ctx.beginPath()
ctx.moveTo(x + r, y)
ctx.arcTo(x + w, y, x + w, y + h, r)
ctx.arcTo(x + w, y + h, x, y + h, r)
ctx.arcTo(x, y + h, x, y, r)
ctx.arcTo(x, y, x + w, y, r)
ctx.closePath()
ctx.fill()
},
//
drawImg(ctx, img, x, y, w, h, r) {
let self = this
ctx.save()
ctx.beginPath()
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)
ctx.clip()
ctx.drawImage(img, x, y, w, h)
ctx.restore()
},
//
drawTxtOne(ctx, text, x, y, maxWidth, color, size, bold) {
ctx.save()
ctx.beginPath()
let chr = text.split("")
let temp = ""
let row = []
ctx.setFontSize(size)
ctx.setFillStyle(color)
for (let a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < maxWidth) {
temp += chr[a]
}
}
row.push(temp)
if (ctx.measureText(temp).width > maxWidth) row[0] = row[0] + '...'
for (var b = 0; b < row.length; b++) {
ctx.fillStyle = color
if (bold) {
ctx.font = 'normal bold ' + size + 'px sans-serif'
} else {
ctx.font = 'normal ' + size + 'px sans-serif'
}
ctx.fillText(row[b], x, y)
}
},
//
drawTxtTwo(ctx, text, x, y, maxWidth, lineHeight, color, size) {
ctx.save()
ctx.beginPath()
let chr = text.split("")
let temp = ""
let row = []
ctx.setFontSize(size)
ctx.setFillStyle(color)
for (let a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < maxWidth) {
temp += chr[a];
} else {
a--
row.push(temp)
temp = ""
}
}
row.push(temp)
if (row.length > 2) {
let rowCut = row.slice(0, 2)
let rowPart = rowCut[1]
let test = ""
let empty = []
for (var a = 0; a < rowPart.length; a++) {
if (ctx.measureText(test).width < maxWidth) {
test += rowPart[a]
} else {
break
}
}
empty.push(test)
var group = empty[0] + "..."
rowCut.splice(1, 1, group)
row = rowCut
}
for (var b = 0; b < row.length; b++) {
ctx.fillStyle = color
ctx.font = 'normal ' + size + 'px sans-serif'
ctx.fillText(row[b], x, y + b * lineHeight, 300)
}
},
drawTxtFour(ctx, text, x, y, maxWidth, lineHeight, color, size) {
ctx.save()
ctx.beginPath()
let chr = text.split("")
let temp = ""
let row = []
ctx.setFontSize(size)
ctx.setFillStyle(color)
for (let a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < maxWidth) {
temp += chr[a];
} else {
a--
row.push(temp)
temp = ""
}
}
row.push(temp)
if (row.length > 4) {
let rowCut = row.slice(0, 4)
let rowPart = rowCut[1]
let test = ""
let empty = []
for (var a = 0; a < rowPart.length; a++) {
if (ctx.measureText(test).width < maxWidth) {
test += rowPart[a]
} else {
break
}
}
empty.push(test)
var group = empty[0] + "..."
rowCut.splice(1, 1, group)
row = rowCut
}
for (var b = 0; b < row.length; b++) {
ctx.fillStyle = color
ctx.font = 'normal ' + size + 'px sans-serif'
ctx.fillText(row[b], x, y + b * lineHeight, 300)
}
},
// 线
drawTxtDel(ctx, txt, x, y, h, color, size) {
ctx.fillStyle = color
ctx.font = 'normal ' + size + 'px sans-serif'
ctx.fillText(txt, x, y)
ctx.beginPath()
let width = ctx.measureText(txt).width;
ctx.rect(x, y - h, width, 1)
ctx.fillStyle = color
ctx.fill()
}
}
}
</script>
<style>
.qiqb-ctx {
position: fixed;
top: 0;
right: 0;
bottom: 0;
bottom: 0;
left: 0;
z-index: -1;
display: flex;
background: rgba(0, 0, 0, .6);
opacity: 0;
transition: all .3s;
flex-direction: column;
align-items: flex-end;
justify-content: flex-end
}
.qiqb-ctx.on {
z-index: 2000;
opacity: 1
}
.qiqb-ctx-box {
position: relative;
display: flex;
padding: 30upx 0 40upx;
width: 750upx;
justify-content: center
}
.qiqb-ctx-box text {
position: absolute;
top: -40upx;
right: 145upx;
display: inline-flex;
width: 47upx;
height: 47upx;
background: url('img/close.png');
background-size: 100% 100%
}
.qiqb-ctx-btns {
display: flex;
width: 750upx;
height: 330upx;
border-radius: 20upx 20upx 0 0;
background: #fff;
flex-direction: row;
flex-direction: column;
align-items: center
}
.qiqb-ctx-btns view:nth-child(1) {
display: flex;
padding-top: 10upx;
height: 80upx;
font-weight: 700;
font-size: 30upx;
align-items: center
}
.qiqb-ctx-btns view:nth-child(2) {
height: 80upx;
color: #666;
font-size: 24upx
}
.qiqb-ctx-btns view:nth-child(3) {
display: flex;
padding-bottom: 30upx;
font-size: 26upx;
flex-direction: row;
align-items: center
}
.qiqb-ctx-btns view:nth-child(3) text {
display: flex;
width: 250upx;
flex-direction: column;
align-items: center;
justify-content: center
}
.qiqb-ctx-btns view:nth-child(3) text:nth-child(1)::before {
display: inline-flex;
margin-bottom: 20upx;
width: 86upx;
height: 86upx;
background: url('img/3.png');
background-size: 100% 100%;
content: ''
}
.qiqb-ctx-btns view:nth-child(3) text:nth-child(2)::before {
display: inline-flex;
margin-bottom: 20upx;
width: 86upx;
height: 86upx;
background: url('img/1.png');
background-size: 100% 100%;
content: ''
}
.qiqb-ctx-btns view:nth-child(3) text:nth-child(3)::before {
display: inline-flex;
margin-bottom: 20upx;
width: 86upx;
height: 86upx;
background: url('img/2.png');
background-size: 100% 100%;
content: ''
}
.qiqb-ctx-close {
display: flex;
padding-bottom: 50upx;
width: 100%;
height: 150upx;
background: #fff;
font-size: 32upx;
align-items: center;
justify-content: center
}
</style>

View File

@ -39,7 +39,7 @@ function baseRequest(url, method, data, {
data: data || {}, data: data || {},
success: (res) => { success: (res) => {
// #ifdef APP-PLUS // #ifdef APP-PLUS
// console.log('app', Url + '/api/' + url, res.data);
// #endif // #endif
if (noVerify) if (noVerify)

View File

@ -40,7 +40,7 @@ function baseRequest(url, method, data, {
success: (res) => { success: (res) => {
// #ifdef APP-PLUS // #ifdef APP-PLUS
// console.log('app', Url + '/api/' + url, res.data); console.log('app', Url + '/api/' + url, res.data);
// #endif // #endif
if (noVerify) if (noVerify)

View File

@ -1,6 +1,6 @@
{ {
"name" : "农业咨询", "name" : "种植分析",
"appid" : "__UNI__9620511", "appid" : "__UNI__9EDFE40",
"description" : "", "description" : "",
"versionName" : "1.0.0", "versionName" : "1.0.0",
"versionCode" : "100", "versionCode" : "100",
@ -17,26 +17,34 @@
"delay" : 0 "delay" : 0
}, },
/* */ /* */
"modules" : {}, "modules" : {
"Record" : {},
"Speech" : {},
"Camera" : {}
},
/* */ /* */
"distribute" : { "distribute" : {
/* android */ /* android */
"android" : { "android" : {
"permissions" : [ "permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>", "<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
], ],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ] "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
@ -47,7 +55,25 @@
}, },
/* SDK */ /* SDK */
"sdkConfigs" : { "sdkConfigs" : {
"ad" : {} "ad" : {},
"speech" : {},
"share" : {}
}
},
"nativePlugins" : {
"YL-SpeechRecognition" : {
"__plugin_info__" : {
"name" : "YL-SpeechRecognition-语音合成,语音听写,基于科大讯飞,双端 - [试用版,仅用于自定义调试基座]",
"description" : "语音合成语音听写基于科大讯飞双端QQ453503875微信同",
"platforms" : "Android,iOS",
"url" : "https://ext.dcloud.net.cn/plugin?id=9512",
"android_package_name" : "",
"ios_bundle_id" : "",
"isCloud" : true,
"bought" : 0,
"pid" : "9512",
"parameters" : {}
}
} }
} }
}, },
@ -55,7 +81,7 @@
"quickapp" : {}, "quickapp" : {},
/* */ /* */
"mp-weixin" : { "mp-weixin" : {
"appid" : "", "appid" : "wx3267f87bc81f2890",
"setting" : { "setting" : {
"urlCheck" : false "urlCheck" : false
}, },

View File

@ -5,9 +5,10 @@
<view class="conten-top"> <view class="conten-top">
<view class="" style="position: absolute;left: 30rpx;"><i class="iconfont icon-xiangzuo" <view class="" style="position: absolute;left: 30rpx;"><i class="iconfont icon-xiangzuo"
style="font-size: 40rpx;text-align: left;"></i></view> style="font-size: 40rpx;text-align: left;"></i></view>
<view class="" style="font-size: 30rpx;"> <view class="" style="font-size: 30rpx;margin-top: 10rpx;">
农业咨询 种植分析
</view> </view>
<returntop class="container-retun" />
</view> </view>
<view style="padding-top:var(--status-bar-height);padding-bottom: 30rpx; margin-bottom: 30rpx;"></view> <view style="padding-top:var(--status-bar-height);padding-bottom: 30rpx; margin-bottom: 30rpx;"></view>
@ -22,13 +23,13 @@
您好 您好
</view> </view>
<view class="talk-list-con-title1"> <view class="talk-list-con-title1">
您可以和我说任何有关农业的问题<br /> 您可以和我说任何有关种植的问题<br />
例如下面的问题赶快试试吧 例如下面的问题赶快试试吧
</view> </view>
<view class="talk-list-con-title2"> <view class="talk-list-con-title2">
<text style="margin-top: 15rpx;"> 下方输入</text> <text style="margin-top: 15rpx;"> 下方输入</text>
<view class="" @click="sendDetail('冬季怎么保存蔬菜')"> <view class="" @click="sendDetail('怎么种植蔬菜')">
冬季怎么保存蔬菜 怎么种植蔬菜
<image src="../../static/icon/airight.png" mode=""></image> <image src="../../static/icon/airight.png" mode=""></image>
</view> </view>
</view> </view>
@ -36,7 +37,7 @@
</view> </view>
<view v-for="(item,index) in talkList" :key="index" :id="`msg-${item.id}`"> <view v-for="(item,index) in talkList" :key="index" :id="`msg-${item.id}`">
<view class="item flex_col" :class="item.type == 1 ? 'push':'pull' "> <view class="item flex_col" :class="item.type == 1 ? 'push':'pull' ">
<image :src="item.type==1?avatar:item.pic" mode="aspectFill" class="pic" v-if="item.pic"> <image :src="item.type==1?avatar:item.pic" mode="aspectFill" class="pic" v-if="item.pic">
</image> </image>
<view class="content" v-if="item.id=='@'"> <view class="content" v-if="item.id=='@'">
@ -49,9 +50,11 @@
<view class="" v-else> <view class="" v-else>
<view v-if="talkList.length-1==index" class="multiline-text"> <view v-if="talkList.length-1==index" class="multiline-text">
<view class="content"> <view class="content">
<view class="" v-if="item.type==3" style="border: 1px solid #2573fb;margin-left: 20rpx;"> <view class="" v-if="item.type==3"
<image :src="item.Image" mode="" style="width: 200rpx;height: 200rpx;" @click="previewImage(item.Image)"></image> style="border: 1px solid #2573fb;margin-left: 20rpx;">
<view class="">{{c_content}}</view> <image :src="item.Image" mode="" style="width: 200rpx;height: 200rpx;"
@click="previewImage(item.Image)"></image>
<view class="">{{c_content}}</view>
</view> </view>
<view class="" v-else> <view class="" v-else>
<bing-math v-if="c_content!=''" :key="`math-${item.id}`" class="bing-math1" <bing-math v-if="c_content!=''" :key="`math-${item.id}`" class="bing-math1"
@ -89,8 +92,10 @@
<!-- <rich-text :nodes="item.content"></rich-text> --> <!-- <rich-text :nodes="item.content"></rich-text> -->
<view class="" v-if="item.type==3" style="border: 1px solid #2573fb;margin-left: 20rpx;"> <view class="" v-if="item.type==3"
<image :src="item.Image" mode="" style="width: 200rpx;height: 200rpx;" @click="previewImage(item.Image)"></image> style="border: 1px solid #2573fb;margin-left: 20rpx;">
<image :src="item.Image" mode="" style="width: 200rpx;height: 200rpx;"
@click="previewImage(item.Image)"></image>
</view> </view>
<view class="" v-else> <view class="" v-else>
<view class="content multiline-text"> <view class="content multiline-text">
@ -245,7 +250,7 @@
import * as utf8 from "utf8" import * as utf8 from "utf8"
import BingMath from "@/components/bing-math/bing-math.vue" import BingMath from "@/components/bing-math/bing-math.vue"
import qiqbshare from "@/components/qiqb-share/qiqb-share.vue" import qiqbshare from "@/components/qiqb-share/qiqb-share.vue"
import returntop from '@/components/content-top/index.vue'
const recorderManager = uni.getRecorderManager() const recorderManager = uni.getRecorderManager()
const innerAudioContext = uni.createInnerAudioContext() const innerAudioContext = uni.createInnerAudioContext()
@ -254,12 +259,12 @@
'bing-math': BingMath, 'bing-math': BingMath,
'qiqbshare': qiqbshare, 'qiqbshare': qiqbshare,
returntop
}, },
data() { data() {
return { return {
wssType: 'nongye', // wssType: 'zhongzhi', //
avatarType: "/static/icon/ny.png", // AI avatarType: "/static/icon/zz.png", // AI
talkList: [], talkList: [],
ajax: { ajax: {
rows: 15, // rows: 15, //
@ -317,7 +322,7 @@
Imageurl: '', Imageurl: '',
content1: '', content1: '',
audioContext: null, // innerAudioContext audioContext: null, // innerAudioContext
} }
}, },
mounted() { mounted() {
@ -341,7 +346,7 @@
}, },
onLoad() { onLoad() {
let avatar = uni.getStorageSync('avatar'); let avatar = uni.getStorageSync('avatar');
avatar ? this.avatar = avatar : null; avatar ? this.avatar = avatar : null;
@ -369,7 +374,7 @@
// obeyMuteSwitch: false // obeyMuteSwitch: false
// }) // })
let that = this; let that = this;
recorderManager.onStop(function(res) { recorderManager.onStop(function(res) {
// , // ,
that.$nextTick(() => { that.$nextTick(() => {
@ -378,7 +383,7 @@
that.voicePath = res.tempFilePath; that.voicePath = res.tempFilePath;
}) })
}); });
}, },
watch: { watch: {
@ -475,7 +480,7 @@
sourceType: ['album'], //cameraalbum sourceType: ['album'], //cameraalbum
success: (res) => { success: (res) => {
// const tempFilePaths = res.tempFilePaths; // const tempFilePaths = res.tempFilePaths;
console.log(res.tempFilePaths,'2222222222') console.log(res.tempFilePaths, '2222222222')
uni.uploadFile({ uni.uploadFile({
url: HTTP_REQUEST_URL + '/api/upload/image', // url: HTTP_REQUEST_URL + '/api/upload/image', //
filePath: res.tempFilePaths[0], // filePath: res.tempFilePaths[0], //
@ -486,7 +491,7 @@
success: function(res) { success: function(res) {
let data = JSON.parse(res.data) let data = JSON.parse(res.data)
console.log(data,'222222222222') console.log(data, '222222222222')
if (data.code == 1) { if (data.code == 1) {
// this.File() // this.File()
let data1 = { let data1 = {
@ -584,24 +589,24 @@
} }
}); });
}, },
// //
previewImage(url){ previewImage(url) {
uni.previewImage({ uni.previewImage({
urls: [url], // urls: [url], //
current: url, // current: url, //
success: function() { success: function() {
console.log('预览图片成功'); console.log('预览图片成功');
}, },
fail: function(error) { fail: function(error) {
console.error('预览图片失败', error); console.error('预览图片失败', error);
} }
}); });
}, },
// //
imgfile(tempFilePath) { imgfile(tempFilePath) {
let that = this let that = this
that.content1='' that.content1 = ''
// console.log(tempFilePath, '2') // console.log(tempFilePath, '2')
ttocr({ ttocr({
image: tempFilePath image: tempFilePath
@ -615,7 +620,7 @@
that.gnishow = false that.gnishow = false
that.talkList = that.talkList.filter(item => item.id !== '@'); that.talkList = that.talkList.filter(item => item.id !== '@');
if (res.data.words.length > 0) { if (res.data.words.length > 0) {
for (let i in res.data.words) { for (let i in res.data.words) {
@ -732,7 +737,7 @@
}, },
// //
uploadFile(tempFilePath) { uploadFile(tempFilePath) {
let that = this let that = this
// console.log(tempFilePath) // console.log(tempFilePath)
uni.uploadFile({ uni.uploadFile({
@ -743,14 +748,14 @@
'content-type': 'multipart/form-data' 'content-type': 'multipart/form-data'
}, },
success: function(res) { success: function(res) {
let data = JSON.parse(res.data) let data = JSON.parse(res.data)
if (data.code == 1) { if (data.code == 1) {
uni.showToast({ uni.showToast({
title: '语音识别成功' title: '语音识别成功'
}); });
that.talkList = that.talkList.filter(item => item.id !== '@'); that.talkList = that.talkList.filter(item => item.id !== '@');
if (data.data.words.length > 0) { if (data.data.words.length > 0) {
that.content = data.data.words that.content = data.data.words
@ -762,16 +767,16 @@
title: '语音识别失败' title: '语音识别失败'
}); });
} }
}, },
fail: function(error) { fail: function(error) {
// //
that.deletespeech() that.deletespeech()
console.log(error, 11); console.log(error, 11);
uni.hideLoading(); uni.hideLoading();
} }
}) })
}, },
@ -810,32 +815,32 @@
}, },
start(e) { start(e) {
this.onFeedTap() this.onFeedTap()
this.touchT = new Date().getTime(); this.touchT = new Date().getTime();
this.islong = true this.islong = true
this.risshow = false this.risshow = false
this.$refs.popup.open('center') this.$refs.popup.open('center')
// //
this.timer = setInterval(() => { this.timer = setInterval(() => {
this.num++ this.num++
}, 1000) }, 1000)
this.btnStatus = 1 this.btnStatus = 1
recorderManager.start({ recorderManager.start({
//5, //5,
duration: 300000, duration: 300000,
// format: "pcm", // format: "pcm",
}); });
this.touchStartX = e.touches[0].pageX; // this.touchStartX = e.touches[0].pageX; //
this.touchStartY = e.touches[0].pageY; // this.touchStartY = e.touches[0].pageY; //
}, },
move(e) { move(e) {
let that = this; let that = this;
let moveX = this.touchMoveX - e.touches[0].pageX; let moveX = this.touchMoveX - e.touches[0].pageX;
let moveY = this.touchMoveY - e.touches[0].pageY; let moveY = this.touchMoveY - e.touches[0].pageY;
@ -866,15 +871,15 @@
this.touchE = new Date().getTime(); this.touchE = new Date().getTime();
if (this.islong) { if (this.islong) {
this.closePop() this.closePop()
this.islong = false this.islong = false
clearInterval(this.timer) clearInterval(this.timer)
this.btnStatus = 0 this.btnStatus = 0
recorderManager.stop(); recorderManager.stop();
// this.closePop() // this.closePop()
if (this.risshow == false && this.touchE - this.touchT > 3000) { if (this.risshow == false && this.touchE - this.touchT > 3000) {
let data = { let data = {
@ -883,7 +888,7 @@
"type": 2, "type": 2,
} }
this.talkList.push(data); this.talkList.push(data);
// ,,, // ,,,
setTimeout(() => { setTimeout(() => {
let obj = { let obj = {
@ -894,31 +899,31 @@
soundTime: this.num soundTime: this.num
}] }]
} }
if (this.voicePath.length > 0 && this.risshow == false) { if (this.voicePath.length > 0 && this.risshow == false) {
// this.huashow=true // this.huashow=true
this.TabItemTap() this.TabItemTap()
throttle(this.uploadFile(this.voicePath), 1000) throttle(this.uploadFile(this.voicePath), 1000)
} }
this.num = 0 this.num = 0
}, 500) }, 500)
} else { } else {
if (!this.risshow) { if (!this.risshow) {
uni.showModal({ uni.showModal({
title: "录音时长不超过3s" title: "录音时长不超过3s"
}) })
} }
} }
} }
}, },
@ -992,18 +997,18 @@
// //
palyaudio(items, i) { palyaudio(items, i) {
// console.log(this.talkList,items.audio_file,'000000') // console.log(this.talkList,items.audio_file,'000000')
if (this.audioContext) { if (this.audioContext) {
// //
this.audioContext.stop(); this.audioContext.stop();
this.audioContext = null; this.audioContext = null;
} }
this.talkList.forEach((item, index) => { this.talkList.forEach((item, index) => {
if (index != i) { if (index != i) {
item.playStatus = true item.playStatus = true
} }
// item.playStatus = (index == i); // item.playStatus = (index == i);
}); });
@ -1012,15 +1017,15 @@
this.talkList[i].playStatus = !this.talkList[i].playStatus this.talkList[i].playStatus = !this.talkList[i].playStatus
if (!this.talkList[i].playStatus) { if (!this.talkList[i].playStatus) {
if(items.audio_file.length>0){ if (items.audio_file.length > 0) {
innerAudioContext.src = items.audio_file; innerAudioContext.src = items.audio_file;
innerAudioContext.play() innerAudioContext.play()
this.talkList[i].playStatus = false this.talkList[i].playStatus = false
}else{ } else {
this.talkList[i].playStatus = true this.talkList[i].playStatus = true
} }
} else { } else {
innerAudioContext.pause() innerAudioContext.pause()
@ -1180,28 +1185,28 @@
}, },
// //
closeSocketTask() { closeSocketTask() {
try { try {
this.talkList = this.talkList.filter(item => item.id !== '@'); this.talkList = this.talkList.filter(item => item.id !== '@');
clearInterval(this.timer); clearInterval(this.timer);
this.talkList[this.talkList.length - 1].audio_file='' this.talkList[this.talkList.length - 1].audio_file = ''
this.talkList[this.talkList.length - 1].content = this.c_content + ''; this.talkList[this.talkList.length - 1].content = this.c_content + '';
// console.log(this.talkList[this.talkList.length - 1].content); // console.log(this.talkList[this.talkList.length - 1].content);
// this.c_content = ''; // this.c_content = '';
// this.n_content = ''; // this.n_content = '';
this.socketTask.close({ this.socketTask.close({
code: 500, // APPBUG,code1000,,code code: 500, // APPBUG,code1000,,code
complete: (res) => { complete: (res) => {
this.showStop = false; this.showStop = false;
console.log('主动断开', res); console.log('主动断开', res);
this.wsLiveFlag = false; this.wsLiveFlag = false;
} }
}) })
} catch (e) { } catch (e) {
//TODO handle the exception //TODO handle the exception
} }
}, },
// //
@ -1213,8 +1218,8 @@
}) })
return; return;
} }
// //
let data = { let data = {
"id": new Date().getTime(), "id": new Date().getTime(),
@ -1250,7 +1255,7 @@
}, },
send1() { send1() {
if (!this.content1) { if (!this.content1) {
uni.showToast({ uni.showToast({
@ -1335,7 +1340,7 @@
// } // }
// } // }
// }; // };
if (this.historyTextList.length > 9) this.params = JSON.parse(JSON.stringify(this if (this.historyTextList.length > 9) this.params = JSON.parse(JSON.stringify(this
.historyTextList .historyTextList
.splice(-9))); .splice(-9)));
@ -1363,11 +1368,11 @@
realThis.tempRes = realThis.tempRes + dataArray[i].content realThis.tempRes = realThis.tempRes + dataArray[i].content
} }
if(this.n_content.length>0){ if (this.n_content.length > 0) {
this.nums = this.talkList.length - 1 this.nums = this.talkList.length - 1
this.txtspeech(this.n_content, this.talkList.length - this.txtspeech(this.n_content, this.talkList.length -
1) 1)
this.showStop = true; this.showStop = true;
} }
this.cavshare(this.talkList) this.cavshare(this.talkList)
let temp = JSON.parse(res.data) let temp = JSON.parse(res.data)
@ -1392,7 +1397,7 @@
"role": "assistant", "role": "assistant",
"content": this.tempRes "content": this.tempRes
}) })
setTimeout(() => { setTimeout(() => {
let that = this let that = this
realThis.socketTask.close({ realThis.socketTask.close({
@ -1601,8 +1606,15 @@
top: 0; top: 0;
position: fixed; position: fixed;
z-index: 10; z-index: 10;
}
.container-retun {
position: absolute;
right: 20rpx;
padding-top: var(--status-bar-height);
top: 0;
}
}
.popup_box { .popup_box {
height: 100vh; height: 100vh;

2239
pages/index/index1.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,168 +0,0 @@
.h1 {
text-align: center;
}
body{
background-color: transparent !important;
}
.voice-box {
box-sizing : border-box;
display : flex;
justify-content: center;
margin : 50px auto;
padding : 50px;
width : 60%;
border-radius : 3px;
}
.voice-box input {
box-sizing : border-box;
padding : 10px;
width : 70%;
height : 50px;
font-size : 18px;
color : #187cff;
border : 1px solid #187cff;
border-radius: 3px 0px 0px 3px;
}
.voice-box button {
width : 30%;
height : 50px;
line-height : 50px;
font-size : 18px;
color : white;
background : #187cff;
border : none;
border-radius: 0px 3px 3px 0px;
cursor : pointer;
}
.voice-box button::before {
content : "";
display : inline-block;
width : 23px;
height : 26px;
vertical-align : middle;
background : url(../img/voice.png) no-repeat;
background-size: contain;
}
.fixed-box {
box-sizing: border-box;
display : none;
position : fixed;
top : 0px;
right : 0px;
bottom : 0px;
left : 0px;
border : .04rem solid #e0e7ff;
background: rgba(16, 22, 62, .2);
}
.fixed-close {
position : absolute;
top : 0px;
right : 0px;
padding : 24px;
width : 20px;
height : 20px;
border : none;
background : url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAABeklEQVRIibXWsWoVQRQA0LObgGCTFFr6env9h/yETSz0tclrBEUJWhjzAqkV/A9/QrC2CtgIYqk2DwvdMExm991ZJrdaZoY53Bnm3u0Wy80BPuI21jjRPjqc4il+4FG3WG4ucS9ZtMaqMfoej5OxLz3uZAuPcXaDKNzt/TuCPFrgYyi87fEK543xKfQFLvoEaYVvQ19DnwxO4euWaA5P4UcBPIzCbmHRcYLleDqfox9wGEG5nnGKRzOvRilnnOIDluPD/BT6HG/GNp+CI/j+HDQCR/BqlPE7LuGlO5+F1sARPIzWwh32Jub3K/YKw1PFYYgV3rWEI2iKh2r7NnhbGZzdWKaeU03tzZ/W8ARH/2TGMq5BZ7XUElzVZebiOTzU3ho0RUqts4in8Kwuk8Uqig/wti4TQSP41XgfQMNlMIBf9fPd/x8t0RTn+h/LEX52i+XmN241RtM4K+Dfe3y7QZTysV/u7D18+RkP8AfPxPpubXzCL9zHVzz5C8ecbD1n3xuUAAAAAElFTkSuQmCC) no-repeat center center;
background-size: 20px;
transition : all .5s;
cursor : pointer;
outline : none;
}
.fixed-close:hover {
transform : rotate(270deg);
-webkit-transform: rotate(270deg);
}
.fixed-main {
box-sizing : border-box;
position : absolute;
left : 20%;
bottom : 0px;
padding : 30px;
width : 60%;
height : 240px;
font-size : 18px;
background : white;
border : 2px solid #e0e7ff;
border-radius: 5px 5px 0px 0px;
overflow-y : auto;
}
.fixed-icon {
box-sizing : border-box;
display : flex;
justify-content: center;
align-items : center;
position : absolute;
top : 50%;
left : 50%;
margin-top : -50px;
margin-left : -50px;
width : 100px;
height : 100px;
background : linear-gradient(115deg, #56d8e4 5%, #9f01ea 95%);
border : 1px solid #e0e7ff;
border-radius : 50%;
}
.fixed-icon::before {
content : "";
position : absolute;
display : inline-block;
width : 100px;
height : 100px;
border : 1px solid #9f01ea;
box-shadow : 0px 0px 6px 0px #9f01ea;
border-radius: 50%;
animation : move 1.5s infinite;
}
.fixed-icon::after {
content : "";
position : absolute;
display : inline-block;
width : 100px;
height : 100px;
border : 1px solid #56d8e4;
box-shadow : 0px 0px 6px 0px #56d8e4;
border-radius: 50%;
animation : move 1.5s .5s infinite;
}
.fixed-icon img {
width : 30px;
height: 50px;
}
@keyframes move {
0% {
opacity : 1;
transform: scale(1);
}
100% {
opacity : 0;
transform: scale(2);
}
}
::-webkit-scrollbar {
width : 6px;
height : 6px;
background-color: #f9f9f9;
}
::-webkit-scrollbar-thumb {
border-radius : 6px;
background-color: #187cff;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,107 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum=1.0, user-scalable=no shrink-to-fit=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="./css/base.css" />
<!-- <script async src="https://hm.baidu.com/hm.js?85fad12bb9a6dab448f4eff0a19299a5"></script> -->
</head>
<body>
<section class="voice-box">
<input type="search" name="voice" id="voice-txt" />
<button id="start-btn">开始识别</button>
</section>
<section class="fixed-box" id="fixed-box">
<div class="fixed-main">
<button class="fixed-close" id="close-btn"></button>
<div id="fixed-txt">Hello! 请说出你想说话。。。!</div>
<div class="fixed-icon">
<img src="./img/voice.png" alt="" />
</div>
</div>
</section>
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js">
</script>
<script src="./js/crypto-js.min.js"></script>
<script src="./js/voice.js"></script>
<script>
window.onload = function() {
const voiceTxt = document.querySelector('#voice-txt');
const startBtn = document.querySelector('#start-btn');
const fixedBox = document.querySelector('#fixed-box');
const fixedTxt = document.querySelector('#fixed-txt');
const closeBtn = document.querySelector('#close-btn');
let times = null;
// 实例化迅飞语音听写流式版WebAPI
const voice = new Voice({
// 服务接口认证信息 注apiKey 和 apiSecret 的长度都差不多,请要填错哦,!
appId: '2eda6c2e',
apiSecret: 'MDEyMzE5YTc5YmQ5NjMwOTU1MWY4N2Y2',
apiKey: '12ec1f9d113932575fc4b114a2f60ffd',
// 注要获取以上3个参数请到迅飞开放平台https://www.xfyun.cn/services/voicedictation 【注这是我的迅飞语音听写流式版每天服务量500也就是调500次如果你需求里大请购买服务量https://www.xfyun.cn/services/voicedictation?target=price】
onWillStatusChange: function(oldStatus, newStatus) {
//可以在这里进行页面中一些交互逻辑处理倒计时语音听写只有60s,录音的动画,按钮交互等!
fixedBox.style.display = 'block';
},
onTextChange: function(text) {
//监听识别结果的变化
voiceTxt.value = text;
fixedTxt.innerText = text;
console.log(text,'11111')
// 3秒钟内没有说话就自动关闭
if (text) {
setTimeout(() => {
voice.stop();
uni.postMessage({
data: text
});
fixedBox.style.display = 'none';
}, 3000);
};
}
});
addUniEvenPassthrough()
addcloEvenPassthrough()
function addUniEvenPassthrough() {
window.uniEvent = function(info) {
console.log('addUniEvenPassthrough')
voice.start();
}
}
function addcloEvenPassthrough() {
window.closeEvent = function(info) {
console.log('addcloEvenPassthrough')
voice.stop();
fixedBox.style.display = 'none';
}
}
// 开始识别
startBtn['onclick'] = function() {
voice.start();
};
// 关闭识别
closeBtn['onclick'] = function() {
voice.stop();
fixedBox.style.display = 'none';
};
};
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,48 +0,0 @@
;(function () {
let self = this
self.onmessage = function (e) {
transAudioData.transcode(e.data)
}
let transAudioData = {
transcode(audioData) {
let output = transAudioData.to16kHz(audioData)
output = transAudioData.to16BitPCM(output)
output = Array.from(new Uint8Array(output.buffer))
self.postMessage(output)
// return output
},
to16kHz(audioData) {
var data = new Float32Array(audioData)
var fitCount = Math.round(data.length * (16000 / 44100))
var newData = new Float32Array(fitCount)
var springFactor = (data.length - 1) / (fitCount - 1)
newData[0] = data[0]
for (let i = 1; i < fitCount - 1; i++) {
var tmp = i * springFactor
var before = Math.floor(tmp).toFixed()
var after = Math.ceil(tmp).toFixed()
var atPoint = tmp - before
newData[i] = data[before] + (data[after] - data[before]) * atPoint
}
newData[fitCount - 1] = data[data.length - 1]
return newData
},
to16BitPCM(input) {
var dataLength = input.length * (16 / 8)
var dataBuffer = new ArrayBuffer(dataLength)
var dataView = new DataView(dataBuffer)
var offset = 0
for (var i = 0; i < input.length; i++, offset += 2) {
var s = Math.max(-1, Math.min(1, input[i]))
dataView.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true)
}
return dataView
}
}
})();

View File

@ -1,357 +0,0 @@
; (function (window, voice) {
"use strict";
if (typeof define === 'function' && define.amd) {
define(voice);
} else if (typeof exports === 'object') {
module.exports = voice();
} else {
window.Voice = voice();
};
}(typeof window !== "undefined" ? window : this, () => {
"use strict";
return class IatRecorder {
constructor(opts = {}) {
// 服务接口认证信息(语音听写流式版WebAPI)
this.appId = opts.appId || '';
this.apiKey = opts.apiKey || '';
this.apiSecret = opts.apiSecret || '';
// 识别监听方法
this.onTextChange = opts.onTextChange || Function();
this.onWillStatusChange = opts.onWillStatusChange || Function();
// 方言/语种
this.status = 'null'
this.language = opts.language || 'zh_cn'
this.accent = opts.accent || 'mandarin';
// 流媒体
this.streamRef = [];
// 记录音频数据
this.audioData = [];
// 记录听写结果
this.resultText = '';
// wpgs下的听写结果需要中间状态辅助记录
this.resultTextTemp = '';
// 音频数据多线程
this.init();
};
// WebSocket请求地址鉴权
getWebSocketUrl() {
return new Promise((resolve, reject) => {
// 请求地址根据语种不同变化
try {
const CryptoJS = require('crypto-js');
let url = 'wss://iat-api.xfyun.cn/v2/iat',
host = 'iat-api.xfyun.cn',
date = new Date().toGMTString(),
algorithm = 'hmac-sha256',
headers = 'host date request-line',
signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`,
signatureSha = CryptoJS.HmacSHA256(signatureOrigin, this.apiSecret),
signature = CryptoJS.enc.Base64.stringify(signatureSha),
authorizationOrigin = `api_key="${this.apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`,
authorization = btoa(authorizationOrigin);
resolve(`${url}?authorization=${authorization}&date=${date}&host=${host}`);
} catch (error) {
let url = 'wss://iat-api.xfyun.cn/v2/iat',
host = 'iat-api.xfyun.cn',
date = new Date().toGMTString(),
algorithm = 'hmac-sha256',
headers = 'host date request-line',
signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`,
signatureSha = CryptoJS.HmacSHA256(signatureOrigin, this.apiSecret),
signature = CryptoJS.enc.Base64.stringify(signatureSha),
authorizationOrigin = `api_key="${this.apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`,
authorization = btoa(authorizationOrigin);
resolve(`${url}?authorization=${authorization}&date=${date}&host=${host}`);
};
});
};
// 操作初始化
init() {
const self = this;
try {
if (!self.appId || !self.apiKey || !self.apiSecret) {
alert('请正确配置【迅飞语音听写流式版WebAPI】服务接口认证信息');
} else {
self.webWorker = new Worker('./js/transcode.worker.js');
self.webWorker.onmessage = function (event) {
self.audioData.push(...event.data);
};
}
} catch (error) {
alert('对不起:请在服务器环境下运行!');
console.error('请在服务器如WAMP、XAMPP、Phpstudy、http-server、WebServer等环境中运行', error);
};
console.log("%c ❤使用说明http://www.muguilin.com/blog/info/609bafc50d572b3fd79b058f", "font-size:32px; color:blue; font-weight: bold;");
};
// 修改录音听写状态
setStatus(status) {
this.onWillStatusChange && this.status !== status && this.onWillStatusChange(this.status, status);
this.status = status;
};
// 设置识别结果内容
setResultText({ resultText, resultTextTemp } = {}) {
this.onTextChange && this.onTextChange(resultTextTemp || resultText || '');
resultText !== undefined && (this.resultText = resultText);
resultTextTemp !== undefined && (this.resultTextTemp = resultTextTemp);
};
// 修改听写参数
setParams({ language, accent } = {}) {
language && (this.language = language)
accent && (this.accent = accent)
};
// 对处理后的音频数据进行base64编码
toBase64(buffer) {
let binary = '';
let bytes = new Uint8Array(buffer);
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
};
// 连接WebSocket
connectWebSocket() {
return this.getWebSocketUrl().then(url => {
let iatWS;
if ('WebSocket' in window) {
iatWS = new WebSocket(url);
} else if ('MozWebSocket' in window) {
iatWS = new MozWebSocket(url);
} else {
alert('浏览器不支持WebSocket!');
return false;
}
this.webSocket = iatWS;
this.setStatus('init');
iatWS.onopen = e => {
this.setStatus('ing');
console.log('连接成功')
// 重新开始录音
setTimeout(() => {
this.webSocketSend();
}, 500);
};
iatWS.onmessage = e => {
this.webSocketRes(e.data);
};
iatWS.onerror = e => {
this.recorderStop(e);
};
iatWS.onclose = e => {
this.recorderStop(e);
};
})
};
// 初始化浏览器录音
recorderInit() {
// 创建音频环境
try {
this.audioContext = this.audioContext ? this.audioContext : new (window.AudioContext || window.webkitAudioContext)();
this.audioContext.resume();
if (!this.audioContext) {
alert('浏览器不支持webAudioApi相关接口');
return false;
}
} catch (e) {
if (!this.audioContext) {
alert('浏览器不支持webAudioApi相关接口');
return false;
}
};
// 获取浏览器录音权限成功时回调
let getMediaSuccess = _ => {
// 创建一个用于通过JavaScript直接处理音频
this.scriptProcessor = this.audioContext.createScriptProcessor(0, 1, 1);
this.scriptProcessor.onaudioprocess = e => {
if (this.status === 'ing') {
// 多线程音频数据处理
try {
this.webWorker.postMessage(e.inputBuffer.getChannelData(0));
} catch (error) { }
}
}
// 创建一个新的MediaStreamAudioSourceNode 对象使来自MediaStream的音频可以被播放和操作
this.mediaSource = this.audioContext.createMediaStreamSource(this.streamRef);
this.mediaSource.connect(this.scriptProcessor);
this.scriptProcessor.connect(this.audioContext.destination);
this.connectWebSocket();
};
// 获取浏览器录音权限失败时回调
let getMediaFail = (e) => {
alert('对不起:录音权限获取失败!');
this.audioContext && this.audioContext.close();
this.audioContext = undefined;
// 关闭websocket
if (this.webSocket && this.webSocket.readyState === 1) {
this.webSocket.close();
}
};
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
// 获取浏览器录音权限
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
audio: true
}).then(stream => {
this.streamRef = stream;
getMediaSuccess();
}).catch(e => {
getMediaFail(e);
})
} else if (navigator.getUserMedia) {
navigator.getUserMedia({
audio: true
}, (stream) => {
this.streamRef = stream;
getMediaSuccess();
}, function (e) {
getMediaFail(e);
})
} else {
if (navigator.userAgent.toLowerCase().match(/chrome/) && location.origin.indexOf('https://') < 0) {
console.error('获取浏览器录音功能因安全性问题需要在localhost 或 127.0.0.1 或 https 下才能获取权限!');
} else {
alert('对不起:未识别到录音设备!');
}
this.audioContext && this.audioContext.close();
return false;
};
};
// 向webSocket发送数据(音频二进制数据经过Base64处理)
webSocketSend() {
if (this.webSocket.readyState !== 1) return false;
// 音频数据
const audioData = this.audioData.splice(0, 1280);
const params = {
common: {
app_id: this.appId,
},
business: {
language: this.language, //小语种可在控制台--语音听写(流式)--方言/语种处添加试用
domain: 'iat',
accent: this.accent, //中文方言可在控制台--语音听写(流式)--方言/语种处添加试用
vad_eos: 5000,
dwa: 'wpgs' //为使该功能生效,需到控制台开通动态修正功能(该功能免费)
},
data: {
status: 0,
format: 'audio/L16;rate=16000',
encoding: 'raw',
audio: this.toBase64(audioData)
}
};
// 发送数据
this.webSocket.send(JSON.stringify(params));
this.handlerInterval = setInterval(() => {
// websocket未连接
if (this.webSocket.readyState !== 1) {
this.audioData = [];
clearInterval(this.handlerInterval);
return false;
};
if (this.audioData.length === 0) {
if (this.status === 'end') {
this.webSocket.send(
JSON.stringify({
data: {
status: 2,
format: 'audio/L16;rate=16000',
encoding: 'raw',
audio: ''
}
})
);
this.audioData = [];
clearInterval(this.handlerInterval);
}
return false;
};
// 中间帧
this.webSocket.send(
JSON.stringify({
data: {
status: 1,
format: 'audio/L16;rate=16000',
encoding: 'raw',
audio: this.toBase64(this.audioData.splice(0, 1280))
}
})
);
}, 40);
};
// 识别结束 webSocket返回数据
webSocketRes(resultData) {
let jsonData = JSON.parse(resultData);
console.log(JSON.stringify( jsonData))
if (jsonData.data && jsonData.data.result) {
let data = jsonData.data.result;
let str = '';
let ws = data.ws;
for (let i = 0; i < ws.length; i++) {
str = str + ws[i].cw[0].w;
}
// 开启wpgs会有此字段(前提:在控制台开通动态修正功能)
// 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果替换范围为rg字段
if (data.pgs) {
if (data.pgs === 'apd') {
// 将resultTextTemp同步给resultText
this.setResultText({
resultText: this.resultTextTemp
});
}
// 将结果存储在resultTextTemp中
this.setResultText({
resultTextTemp: this.resultText + str
});
} else {
this.setResultText({
resultText: this.resultText + str
});
}
}
if (jsonData.code === 0 && jsonData.data.status === 2) {
this.webSocket.close();
}
if (jsonData.code !== 0) {
this.webSocket.close();
}
};
// 启动录音
recorderStart() {
if (!this.audioContext) {
this.recorderInit();
} else {
this.audioContext.resume();
this.connectWebSocket();
}
};
// 停止录音
recorderStop() {
if (!(/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgen))) {
// safari下suspend后再次resume录音内容将是空白设置safari下不做suspend
this.audioContext && this.audioContext.suspend();
}
this.setStatus('end');
try {
// this.streamRef.getTracks().map(track => track.stop()) || his.streamRef.getAudioTracks()[0].stop();
} catch (error) {
console.error('暂停失败!');
}
};
// 开始
start() {
console.log('startstartstartstartstartstart');
this.recorderStart();
this.setResultText({ resultText: '', resultTextTemp: '' });
};
// 停止
stop() {
this.recorderStop();
};
};
}));

BIN
static/icon/fb1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

BIN
static/icon/fb2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

47
type.md Normal file
View File

@ -0,0 +1,47 @@
# 讯飞星火大模型 小程序文档
### 农业咨询
参数:nongye
APPID:uni.UNI9620511
### 教育咨询
参数:jiaoyu
APPID:uni.UNI7AA205C
### 法律咨询
参数:falv
APPID:uni.UNI358D505
### 情感咨询
参数:qinggan
APPID:uni.UNI8080F14
### 种植分析
参数:zhongzhi
APPID:uni.UNI9EDFE40
### 养殖分析
参数:yangzhi
APPID:uni.UNI9EDFE40