提交 ab792e10 编写于 作者: DCloud_JSON's avatar DCloud_JSON

- 优化 网络错误等因素导致发送失败后,点击重试按钮 消息状态图标没有立即变成发送中的问题 - 优化...

- 优化 网络错误等因素导致发送失败后,点击重试按钮 消息状态图标没有立即变成发送中的问题 - 优化 自动过滤历史消息中的涉敏内容,防止因上文涉敏而造成后续对话都涉敏的问题 - 修复 消息发出后,uni-ai未答复时直接刷新界面 会卡住的问题
上级 81bba47a
...@@ -199,7 +199,7 @@ module.exports = async (obj) => { ...@@ -199,7 +199,7 @@ module.exports = async (obj) => {
1. 新建组件`earned-score-pay`实现支付并回调支付结果 1. 新建组件`earned-score-pay`实现支付并回调支付结果
2. 在chat页面(路径:`pages/chat/chat.vue`)搜索 `uni-ad-rewarded-video`修改同位置代码块如下: 2. 在chat页面(路径:`pages/chat/chat.vue`)搜索 `uni-ad-rewarded-video`修改同位置代码块如下:
```html ```html
<view v-if="index == msgList.length-1 && msg.insufficientPoints"> <view v-if="index == msgList.length-1 && msg.insufficientScore">
<uni-ad-rewarded-video v-if="adpid" :adpid="adpid" @onAdClose="onAdClose"></uni-ad-rewarded-video> <uni-ad-rewarded-video v-if="adpid" :adpid="adpid" @onAdClose="onAdClose"></uni-ad-rewarded-video>
<earned-score-pay @success="paySuccess"></earned-score-pay> <earned-score-pay @success="paySuccess"></earned-score-pay>
</view> </view>
...@@ -232,8 +232,7 @@ module.exports = async (obj) => { ...@@ -232,8 +232,7 @@ module.exports = async (obj) => {
DCloud基于`uni-ai`提供了很多开源模板,除了本项目`uni-ai-chat`,还有: DCloud基于`uni-ai`提供了很多开源模板,除了本项目`uni-ai-chat`,还有:
- [uni-cms](uni-cms.md),一款集成了ai生成文章内容的开源内容管理系统。 - [uni-cms](uni-cms.md),一款集成了ai生成文章内容的开源内容管理系统。
- [uni-im](uni-cms.md),一款集成了ai的大型im系统,包括私聊群聊好友等丰富功能。
## 交流群 ## 交流群
更多问题欢迎加入uni-ai官方交流群 qq群号:[699680439](https://qm.qq.com/cgi-bin/qm/qr?k=P_JoYXY56vNfb78uNHwwzqpODwl9e89B&jump_from=webapi&authKey=GDp321q9ZYW4V0ZQcejXikwMnNRs4KVBcQXMADs8lvC0hifSH9ORHsyERy6vO4bA) 更多问题欢迎加入uni-ai官方交流群 QQ群号:[699680439](https://qm.qq.com/cgi-bin/qm/qr?k=P_JoYXY56vNfb78uNHwwzqpODwl9e89B&jump_from=webapi&authKey=GDp321q9ZYW4V0ZQcejXikwMnNRs4KVBcQXMADs8lvC0hifSH9ORHsyERy6vO4bA)
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
- 修复 消息发出后uni-ai回复未完成时,点击清空后没有终止会话,引起卡在ai正在回复中的问题 - 修复 消息发出后uni-ai回复未完成时,点击清空后没有终止会话,引起卡在ai正在回复中的问题
- 修复 流式响应模式 uni-ai回复的代码块不完整时 内容会出现多余的字符(<span class="cursor">|</span>)的问题 - 修复 流式响应模式 uni-ai回复的代码块不完整时 内容会出现多余的字符(<span class="cursor">|</span>)的问题
- 修复 服务端超时等错误时,客户端卡在ai正在回复中的问题 - 修复 服务端超时等错误时,客户端卡在ai正在回复中的问题
- 优化 网络错误等因素导致发送失败后,点击重试按钮 消息状态图标没有立即变成发送中的问题
- 优化 自动过滤历史消息中的涉敏内容,防止因上文涉敏而造成后续对话都涉敏的问题
- 修复 消息发出后,uni-ai未答复时直接刷新界面 会卡住的问题
## 1.0.2(2023-04-26) ## 1.0.2(2023-04-26)
- 修改错误的HBuilderX版本要求的提示 - 修改错误的HBuilderX版本要求的提示
## 1.0.1(2023-04-25) ## 1.0.1(2023-04-25)
- 新增内容安全识别 - 新增内容安全识别
- 不再提供stream设置ui,自动根据是否开通并启用uni-push设置 - 不再提供stream设置ui,自动根据是否开通并启用uni-push设置
## 1.0.0(2023-04-24) ## 1.0.0(2023-04-24)
1.0.0 1.0.0
\ No newline at end of file
...@@ -59,12 +59,12 @@ ...@@ -59,12 +59,12 @@
if (richTextBox) { if (richTextBox) {
richTextBox.$el.addEventListener('contextmenu', (e) => { richTextBox.$el.addEventListener('contextmenu', (e) => {
if (!document.getSelection().toString()) { if (!document.getSelection().toString()) {
console.log(e); // console.log(e);
this.top = e.y + 'px' this.top = e.y + 'px'
this.left = e.x + 'px' this.left = e.x + 'px'
console.log(e.x); // console.log(e.x);
console.log(e.y); // console.log(e.y);
e.preventDefault() e.preventDefault()
} }
}) })
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<view class="content"> <view class="content">
<!-- <text class="copy" @click="copy">复制</text> --> <!-- <text class="copy" @click="copy">复制</text> -->
<uni-ai-msg :md="msg.content" :show-cursor="index == msgList.length-1 && msg.isAi && sseIndex"></uni-ai-msg> <uni-ai-msg :md="msg.content" :show-cursor="index == msgList.length-1 && msg.isAi && sseIndex"></uni-ai-msg>
<view v-if="index == msgList.length-1 && adpid && msg.insufficientPoints"> <view v-if="index == msgList.length-1 && adpid && msg.insufficientScore">
<uni-ad-rewarded-video :adpid="adpid" @onAdClose="onAdClose"></uni-ad-rewarded-video> <uni-ad-rewarded-video :adpid="adpid" @onAdClose="onAdClose"></uni-ad-rewarded-video>
</view> </view>
</view> </view>
...@@ -79,12 +79,6 @@ ...@@ -79,12 +79,6 @@
}, },
computed: { computed: {
inputBoxDisabled() { inputBoxDisabled() {
console.log('inputBoxDisabled',{
"sseIndex":this.sseIndex,
"length":this.msgList.length,
"length2":this.msgList.length%2
});
if (this.sseIndex !== 0) { if (this.sseIndex !== 0) {
return true return true
} }
...@@ -137,6 +131,17 @@ ...@@ -137,6 +131,17 @@
// } // }
this.msgList = uni.getStorageSync('uni-ai-msg') || [] this.msgList = uni.getStorageSync('uni-ai-msg') || []
// 如果上一次对话中 最后一条消息ai未回复。则一启动就自动重发。
let length = this.msgList.length
if(length){
let lastMsg = this.msgList[length - 1]
if(!lastMsg.isAi){
this.retriesSendMsg()
}
}
// this.msgList.pop() // this.msgList.pop()
// console.log('this.msgList', this.msgList); // console.log('this.msgList', this.msgList);
...@@ -177,6 +182,12 @@ ...@@ -177,6 +182,12 @@
}) })
// #endif // #endif
}, },
// onUnload() {
// if(sseChannel){
// console.log('onUnload','sseChannel.close()');
// sseChannel.close()
// }
// },
methods: { methods: {
//检查是否开通uni-push;决定是否启用stream //检查是否开通uni-push;决定是否启用stream
async checkIsOpenPush(){ async checkIsOpenPush(){
...@@ -245,6 +256,7 @@ ...@@ -245,6 +256,7 @@
async retriesSendMsg() { async retriesSendMsg() {
// 检查是否开通uni-push;决定是否启用stream // 检查是否开通uni-push;决定是否启用stream
await this.checkIsOpenPush() await this.checkIsOpenPush()
this.updateLastMsg({state:0})
this.send() this.send()
}, },
async beforeSendMsg() { async beforeSendMsg() {
...@@ -320,6 +332,9 @@ ...@@ -320,6 +332,9 @@
// 如果未总结过就直接从末尾拿10条 // 如果未总结过就直接从末尾拿10条
msgs = msgs.splice(-10) msgs = msgs.splice(-10)
} }
// 过滤涉敏问题
msgs = msgs.filter(msg=>!msg.illegal)
messages = msgs.map(item => { messages = msgs.map(item => {
let role = "user" let role = "user"
...@@ -358,12 +373,12 @@ ...@@ -358,12 +373,12 @@
}) })
sseChannel.on('end', (e) => { // 监听end事件,如果云端执行end时传了message,会在客户端end事件内收到传递的消息 sseChannel.on('end', (e) => { // 监听end事件,如果云端执行end时传了message,会在客户端end事件内收到传递的消息
// console.log('on end', e); // console.log('on end', e);
if(e && (e.summarize || e.insufficientPoints)){ if(e && (e.summarize || e.insufficientScore)){
this.updateLastMsg(lastMsg=>{ this.updateLastMsg(lastMsg=>{
if(e.summarize){ if(e.summarize){
lastMsg.summarize = e.summarize lastMsg.summarize = e.summarize
}else if (e.insufficientPoints){ }else if (e.insufficientScore){
lastMsg.insufficientPoints lastMsg.insufficientScore
} }
}) })
} }
...@@ -387,12 +402,17 @@ ...@@ -387,12 +402,17 @@
// console.log(res, res.reply); // console.log(res, res.reply);
// 判断长度,防止请求未返回时,历史对话已被清空。引起对话顺序错误 导致 对话输入框卡住 // 判断长度,防止请求未返回时,历史对话已被清空。引起对话顺序错误 导致 对话输入框卡住
if(!skip_callback){ if(!skip_callback){
let {"reply":content,summarize,insufficientScore,illegal} = res.data
if(illegal){
this.updateLastMsg({illegal:true})
}
this.msgList.push({ this.msgList.push({
isAi: true,
content: res.data.reply,
summarize: res.data.summarize,
create_time: Date.now(), create_time: Date.now(),
insufficientPoints:res.data.insufficientPoints isAi: true,
content,
summarize,
insufficientScore,
illegal
}) })
this.showLastMsg() this.showLastMsg()
}else{ }else{
......
...@@ -10,7 +10,7 @@ const userscollection = db.collection('uni-id-users') ...@@ -10,7 +10,7 @@ const userscollection = db.collection('uni-id-users')
const uniIdCommon = require('uni-id-common') const uniIdCommon = require('uni-id-common')
module.exports = { module.exports = {
_before:async function() { _before:async function() {
// 这里是云函数的前置方法,你可以在这里加入你需要逻辑,比如: // 这里是云函数的前置方法,你可以在这里加入你需要逻辑,比如:
/* /*
例如:使用uni-id-pages(链接地址:https://ext.dcloud.net.cn/plugin?id=8577)搭建账户体系。 例如:使用uni-id-pages(链接地址:https://ext.dcloud.net.cn/plugin?id=8577)搭建账户体系。
...@@ -45,7 +45,7 @@ module.exports = { ...@@ -45,7 +45,7 @@ module.exports = {
let {data:[{score}]} = await userscollection.doc(this.current_uid).field({'score':1}).get() let {data:[{score}]} = await userscollection.doc(this.current_uid).field({'score':1}).get()
console.log('score----',score); console.log('score----',score);
if(score == 0 || score < 0){ //并发的情况下可能花超过 if(score == 0 || score < 0){ //并发的情况下可能花超过
throw "insufficientPoints" throw "insufficientScore"
} }
await userscollection.doc(this.current_uid) await userscollection.doc(this.current_uid)
.update({ .update({
...@@ -54,6 +54,7 @@ module.exports = { ...@@ -54,6 +54,7 @@ module.exports = {
} }
// 从配置中心获取内容安全配置 // 从配置中心获取内容安全配置
console.log('config.contentSecurity',config.contentSecurity);
if (config.contentSecurity) { if (config.contentSecurity) {
const UniSecCheck = safeRequire('uni-sec-check') const UniSecCheck = safeRequire('uni-sec-check')
const uniSecCheck = new UniSecCheck({ const uniSecCheck = new UniSecCheck({
...@@ -63,7 +64,11 @@ module.exports = { ...@@ -63,7 +64,11 @@ module.exports = {
this.textSecCheck = async (content)=>{ this.textSecCheck = async (content)=>{
let {sseChannel} = this.getParams()[0]||{} let {sseChannel} = this.getParams()[0]||{}
if(sseChannel){ if(sseChannel){
throw "流式响应模式,内容安全识别功能无效" throw {
errSubject: 'uni-ai-chat',
errCode: "sec-check",
errMsg: "流式响应模式,内容安全识别功能无效"
}
} }
// 检测文本 // 检测文本
const checkRes = await uniSecCheck.textSecCheck({ const checkRes = await uniSecCheck.textSecCheck({
...@@ -99,29 +104,34 @@ module.exports = { ...@@ -99,29 +104,34 @@ module.exports = {
} }
}, },
async _after(error, result) { async _after(error, result) {
console.log('_after',{error,result});
if(error){ if(error){
if(error == "isSecCheck" ) { if(error.errCode && error.errMsg) {
// 符合响应体规范的错误,直接返回
return error
}else if(error == "isSecCheck" ) {
return { return {
"data": { "data": {
"reply": "内容涉及敏感" "reply": "内容涉及敏感",
"illegal":true
}, },
"errCode": 0 "errCode": 0
} }
}else if(error == 'insufficientPoints'){ }else if(error == 'insufficientScore'){
let reply = "积分不足,请看完激励视频广告后再试" let reply = "积分不足,请看完激励视频广告后再试"
let {sseChannel} = this.getParams()[0]||{} let {sseChannel} = this.getParams()[0]||{}
if(sseChannel){ if(sseChannel){
const channel = uniCloud.deserializeSSEChannel(sseChannel) const channel = uniCloud.deserializeSSEChannel(sseChannel)
await channel.write(reply) await channel.write(reply)
await channel.end({ await channel.end({
"insufficientPoints":true "insufficientScore":true
}) })
}else{ }else{
return { return {
"data": { "data": {
reply, reply,
"insufficientPoints":true "insufficientScore":true
}, },
"errCode": 0 "errCode": 0
} }
...@@ -137,7 +147,8 @@ module.exports = { ...@@ -137,7 +147,8 @@ module.exports = {
}catch(e){ }catch(e){
return { return {
"data": { "data": {
"reply": "内容涉及敏感" "reply": "内容涉及敏感",
"illegal":true
}, },
"errCode": 0 "errCode": 0
} }
...@@ -190,17 +201,17 @@ module.exports = { ...@@ -190,17 +201,17 @@ module.exports = {
res.on('message', async (message) => { res.on('message', async (message) => {
reply += message reply += message
await channel.write(message) await channel.write(message)
// console.log('---message----', message) console.log('---message----', message)
}) })
}else{ }else{
res.on('line', async (line) => { res.on('line', async (line) => {
await channel.write(reply? ("\n\n " + line) : line) await channel.write(reply? ("\n\n " + line) : line)
reply += line reply += line
// console.log('---line----', line) console.log('---line----', line)
}) })
} }
res.on('end', async () => { res.on('end', async () => {
// console.log('---end----',reply) console.log('---end----',reply)
messages.push({ messages.push({
"content": reply, "content": reply,
"role": "assistant" "role": "assistant"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册