diff --git a/App.vue b/App.vue index df129b48a9471f606fd788d15d74c7d625acf8c1..3bc9b2f7a9cef91181fa482c4d05923e9ceeac97 100644 --- a/App.vue +++ b/App.vue @@ -1,7 +1,24 @@ - diff --git a/manifest.json b/manifest.json index f2ba392f68f5554952225132254929e266ee0de6..2825a84e131b4cffbc5e637e18c0fff61b842512 100644 --- a/manifest.json +++ b/manifest.json @@ -68,10 +68,10 @@ "uniStatistics" : { "enable" : false }, - "vueVersion" : "2", + "vueVersion" : "3", "h5" : { "unipush" : { - "enable" : true + "enable" : false } } } diff --git a/pages.json b/pages.json index 7e36c75a5c92eefa26d3972f8316ad6fb00d86e4..795418b914655a049a8f2cf9db7678f8276b3a0c 100644 --- a/pages.json +++ b/pages.json @@ -4,7 +4,7 @@ "path" : "pages/chat/chat", "style" : { - "navigationBarTitleText": "uni-ai", + "navigationBarTitleText": "uni-ai-chat", "enablePullDownRefresh": false } } diff --git a/pages/chat/chat.vue b/pages/chat/chat.vue index 205e9e9a5f57622d20cf5bf39f696b6e6eaa41d3..b7dc78475bf8df789c27fb8cde47ed5a2ce215e1 100644 --- a/pages/chat/chat.vue +++ b/pages/chat/chat.vue @@ -1,19 +1,19 @@ @@ -52,7 +74,8 @@ msgList: [], content: "", sseIndex: 0, - stream:false + stream:false, + isWidescreen:false } }, computed: { @@ -113,7 +136,7 @@ //按下了shift ctrl alt windows键 adjunctKeydown = true; } - if (e.keyCode == 13 && adjunctKeydown) { + if (e.keyCode == 13 && !adjunctKeydown) { this.beforeSendMsg(); } }; @@ -124,13 +147,59 @@ } }; } - // #endif + // #endif + + // 添加惰性函数,检查是否开通push + this.changeStream.check = async ()=>{ + uni.getPushClientId({ + fail:()=> { + this.stream = false + uni.showModal({ + content: '你暂未开通uni-push。不支持此功能', + showCancel: false, + confirmText:"查看详情", + complete() { + let url = "https://uniapp.dcloud.net.cn/uniCloud/uni-ai-chat.html#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9" + // #ifndef H5 + uni.setClipboardData({ + data:url, + showToast:false, + success() { + uni.showToast({ + title: '已复制文档链接,请到浏览器粘贴浏览', + icon: 'none', + duration:5000 + }); + } + }) + // #endif + // #ifdef H5 + window.open(url) + // #endif + + } + }); + console.log('你暂未开通uni-push。不支持此功能。详情:https://uniapp.dcloud.net.cn/uniCloud/uni-ai-chat.html#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9'); + }, + success:()=>{ + this.changeStream.check = ()=>{} + } + }) + } + + uni.createMediaQueryObserver(this).observe({ + minWidth: 650, + }, matches => { + this.isWidescreen = matches; + }) }, methods: { // updateLastMsg(){ // }, changeStream(e){ + this.changeStream.check() + // console.log('e',e.detail.value); this.stream = e.detail.value }, @@ -302,6 +371,25 @@ } }); + }, + toStreamMD(){ + let url = "https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html#chat-completion-stream" + // #ifndef H5 + uni.setClipboardData({ + data:url, + showToast:false, + success() { + uni.showToast({ + title: '已复制文档链接,请到浏览器粘贴浏览', + icon: 'none', + duration:5000 + }); + } + }) + // #endif + // #ifdef H5 + window.open(url) + // #endif } } } @@ -312,13 +400,10 @@ view, textarea, button, - .page, - /* #ifdef H5 */ - .page * - /* #endif */ + .page { display: flex; - box-sizing: border-box; + box-sizing: border-box; } /* #endif */ @@ -329,38 +414,34 @@ .page, .container { background-color: #efefef; - width: 750rpx; - flex: 1; + flex: 1; + /* #ifdef H5 */ height: calc(100vh - 44px); /* #endif */ - /* #ifndef H5 */ - height: 100vh; - /* #endif */ flex-direction: column; - align-items: center; - } + align-items: center; + justify-content: center; + } /* #ifndef APP-NVUE */ .container { - background-color: #FAFAFA; - } - .container, - .container * { - max-width: 550px; + background-color: #FAFAFA; } /* #endif */ .foot-box { width: 750rpx; display: flex; - justify-content: space-around; - align-items: self-start; + flex-direction: column; padding: 10px 0px; background-color: #FFF; + } + .foot-box-content{ + justify-content: space-around; } - .textarea-box { + .textarea-box { padding: 8px 10px; background-color: #f9f9f9; border-radius: 5px; @@ -368,11 +449,11 @@ .textarea-box .textarea { max-height: 100px; - width: 460rpx; font-size: 14px; /* #ifndef APP-NVUE */ overflow: auto; - /* #endif */ + /* #endif */ + width: 450rpx; } /* #ifndef APP-NVUE */ @@ -388,7 +469,6 @@ .trash, .send { - /* border: 1px solid #000; */ width: 50px; height: 30px; justify-content: center; @@ -397,12 +477,11 @@ } .trash { - width: 30rpx; - margin-left: 20rpx; + width: 30rpx; + margin-left: 10rpx; } .send { - background-color: #2eaf4d; color: #FFF; border-radius: 4px; display: flex; @@ -463,7 +542,9 @@ } .content { - max-width: 500rpx; + /* #ifndef APP-NVUE */ + max-width: 550rpx; + /* #endif */ background-color: #FFF; border-radius: 5px; padding: 12px 10px; @@ -507,33 +588,134 @@ justify-content: center; } - .set-stream{ - position: fixed; - left: 0px; - top: 0; + #set-stream{ z-index: 999; padding:0 5px; justify-content: center; align-items: center; + position: fixed; + bottom: 50px; + right: 0; + } + #set-stream .title{ + font-size: 12px; + position: relative; + left: 10rpx; } + #set-stream switch{ + transform: scale(0.5); + } + /* #ifdef H5 */ - @media screen and (min-width:600px){ - .textarea-box{ - flex:1 + @media screen and (min-width:650px){ + .foot-box{ + border-top: solid 1px #dde0e2; + } + .page{ + width: 100vw; + flex-direction: row; + } + .page * { + max-width: 950px; + } + + .container, { + box-shadow: 0 0 5px #e0e1e7; + margin-top: 44px; + border-radius: 10px; + overflow: hidden; + } + + .container .header{ + height: 44px; + line-height: 44px; + border-bottom: 1px solid #F0F0F0; + width: 100vw; + justify-content: center; + font-weight: 500; + } + + .content { + background-color: #f9f9f9; + } + + .foot-box, + .foot-box-content, + .msg-list, + .msg-item, + // .create_time, + .noData, + .textarea-box, + .textarea, + textarea-box { + width: 100% !important; } - .trash, - .send-btn-box{ - flex-shrink: 0; - width: 100px; + + .create_time-box { + margin-top: 15px; justify-content: center; - padding: 0; - margin: 0; } - .trash{ - width: 60px; + .create_time{ + display: flex; + } + + .textarea-box, + .textarea, + textarea, + textarea-box { + height: 120px; + } + + .container, + .foot-box, + .textarea-box { + background-color: #FFF; + } + + .foot-box-content{ + flex-direction: column; + justify-content: center; + align-items: flex-end; + padding-bottom: 0; + } + + .menu { + padding:0 10px; + } + .menu-item{ + height:20px; + justify-content: center; + align-items: center; + align-content: center; + display: flex; + margin-right: 10px; + cursor: pointer; + } + .trash { + opacity: 0.8; + } + .trash image{ + height: 15px; + } + + .set-stream .title { + font-size: 12px; + } + .set-stream switch { + transform: scale(0.6); + position: relative; + left: -5px; + } + + .textarea-box,.textarea-box *{ + // border: 1px solid #000; } - .textarea-box .textarea { - width: 100%; + + .send-btn-box .send-btn-tip{ + color: #919396; + margin-right: 8px; + font-size: 12px; + line-height: 28px; } } /* #endif */ diff --git a/redme.md b/redme.md index 518fd1cd81a472b279bc1991d4549346a3738e3f..dd3a08fae06607be31c969cac549df3dd869dc20 100644 --- a/redme.md +++ b/redme.md @@ -1,4 +1,7 @@ + ## 简介 +> 仅支持3.8.0及以上版本的HBuilderX + uni-ai-chat是基于[uni-ai](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html)的云端一体AI项目模板 视频效果: @@ -6,6 +9,16 @@ uni-ai-chat是基于[uni-ai](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html) 包含一个前端页面(路径:`/pages/chat/chat.vue`)和一个云对象(路径:`uniCloud/cloudfunctions/uni-ai-chat/index.obj.js`) +## 响应流程图 + + +- 普通响应的流程较为简单,全流程基于 HTTP 网络请求。其缺陷是,当访问 AI 聊天接口时,如果生成的回复内容过大,响应时间会很长,导致前端用户需要等待很长时间才能收到结果。详情请参考:[stream的优势](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html#chat-completion-stream)。 + +- 流式响应的使用需客户端先通过 `new uniCloud.SSEChannel()` 创建 SSE 通道,并获得 `channel` 值(详情请参考:[https://uniapp.dcloud.net.cn/uniCloud/sse-channel.html#create-sse-channel](https://uniapp.dcloud.net.cn/uniCloud/sse-channel.html#create-sse-channel))。在客户端向 uniCloud 云对象发起请求时,需要将该 `channel` 值作为参数一同携带;然后 uniCloud 云对象与 uni-ai 建立 流式响应[(stream)](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html#chat-completion-stream) 通讯,云对象监听 uni-ai 返回的分片数据,在接收到数据后再通过 sse-channel ([反序列化消息通道](https://uniapp.dcloud.net.cn/uniCloud/sse-channel.html#cloud-deserialize-channel))向客户端推送消息。 + +### 注意事项 @heed +- 使用`sse-channel`需要先[开通uni-push](https://uniapp.dcloud.net.cn/unipush-v2.html#%E7%AC%AC%E4%B8%80%E6%AD%A5-%E5%BC%80%E9%80%9A) +- 目前uni-push2.0不支持本地调试(后续版本会支持),需要在HBuilderX控制台,更改`连接本地云函数`为`连接云端云函数`。 ## 体验步骤 @@ -14,11 +27,4 @@ uni-ai-chat是基于[uni-ai](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html) 3. 打开`uni-ai-chat`插件下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-ai-chat](https://ext.dcloud.net.cn/plugin?name=uni-ai-chat) 4. 点击`使用HBuilderX导入示例项目` 5. 对项目根目录uniCloud点右键选择“云服务空间初始化向导”界面按提示部署项目 -6. 在uni-app项目点右键,关联之前创建的服务空间。 - -## 注意事项 - -uni-ai-chat支持[流式响应](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html#%E6%B5%81%E5%BC%8F%E5%93%8D%E5%BA%94-chat-completion-stream) -模式,该模式会接收uni-ai的流式响应的数据,通过sse-channel[(云函数(云对象)请求中的中间状态通知通道)](https://uniapp.dcloud.net.cn/uniCloud/sse-channel.html)向客户端推送消息, -而使用`sse-channel`需要先[开通uni-push](https://uniapp.dcloud.net.cn/unipush-v2.html#%E7%AC%AC%E4%B8%80%E6%AD%A5-%E5%BC%80%E9%80%9A) -,目前uni-push2.0不支持本地调试(后续版本会支持),需要在HBuilderX控制台,更改`连接本地云函数`为`连接云端云函数`。 +6. 在uni-app项目点右键,关联之前创建的服务空间。 \ No newline at end of file diff --git a/static/remove.png b/static/remove.png new file mode 100644 index 0000000000000000000000000000000000000000..b770a82410adf038ba6922b490865a13c80d7bec Binary files /dev/null and b/static/remove.png differ