|
@@ -10,43 +10,78 @@
|
|
|
<!-- <i class="fas fa-chevron-left mr-2"></i> -->
|
|
|
返回
|
|
|
</div>
|
|
|
- <div
|
|
|
- class="chat-box rounded-lg p-4 w-1/2"
|
|
|
- style="backdropFilter: blur(5px);background: rgba(0, 0, 0, 0.5); height: 550px;"
|
|
|
- >
|
|
|
- <div class="text-white mb-4 flex">
|
|
|
- <div class="pt-2">
|
|
|
- <img
|
|
|
- src="@/assets/images/1.png"
|
|
|
- class="rounded-full mr-2 w-14"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="message fex-1 ml-4 mt-2 p-2 rounded-r-md rounded-bl-md text-xs">
|
|
|
- <p class="mt-2 ">
|
|
|
- 这段时间一直有些自我怀疑,又是新的一天,对我们这个年纪的我来说,又是不容易的一天。他说他在自己的世界中,自己是公认的老好人,至于他在玩电脑,还在玩手机,我真心希望了。现实中,他的游戏世界只有自己。
|
|
|
- </p>
|
|
|
- <p class="mt-2 text-sm">
|
|
|
- 世界的温暖和他的温柔,......什么?什么?"他问道,脸上露出自嘲的笑容。他完全不认识我了。......,他是什么人?"他有点不愿意相信,他脸上露出的温暖感觉的笑容,我喜......那,他的手的温度。
|
|
|
- </p>
|
|
|
+ <div class="content">
|
|
|
+ <div class="leftImg">
|
|
|
+ <img src="https://fallfor.ai/public/img/uploads/11/img_1715399022390_00024-654400262.jpg" alt="">
|
|
|
+ <div class="aiInfo">
|
|
|
+ <span class="photo">
|
|
|
+ <img src="https://fallfor.ai/public/img/uploads/11/img_1715399064396_1 (2).gif">
|
|
|
+ </span>
|
|
|
+ <div class="info">
|
|
|
+ <div class="name">Juniper</div>
|
|
|
+ <div class="tags">
|
|
|
+ <span class="tag">Female</span>
|
|
|
+ <span class="tag">Dominant</span>
|
|
|
+ <span class="tag">Submissive</span>
|
|
|
+ </div>
|
|
|
+ <div class="infoContent">继母会做任何事情让你接受她。</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="absolute left-2 right-2 bottom-4 ">
|
|
|
- <div class="flex items-center text-gray-400 text-xs mb-4 ">
|
|
|
- <span>@Leon S Kennedy - Resident Evil</span>
|
|
|
+ <div class="chat-box">
|
|
|
+ <div class="messages">
|
|
|
+ <template v-for="(item, index) in returnMessage">
|
|
|
+ <div v-if="item.user == 'ai'" class="text-white mb-4 flex" :key="index">
|
|
|
+ <!-- ai返回的信息 -->
|
|
|
+ <div class="pt-2 photo">
|
|
|
+ <img
|
|
|
+ src="@/assets/images/1.png"
|
|
|
+ class="rounded-full w-14"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="message fex-1 ml-4 mt-2 p-2 rounded-r-md rounded-bl-md text-xs" >
|
|
|
+ <div v-show="messageLoading" class="loadingMessage" >
|
|
|
+ <div v-loading="messageLoading" element-loading-background="rgba(0, 0, 0, 0.0)"></div>
|
|
|
+ </div>
|
|
|
+ <p v-show="!messageLoading" >{{ item.text }}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 用户发送的信息 -->
|
|
|
+ <div v-if="item.user == 'me'" class="text-white mb-4 flex me" :key="index">
|
|
|
+ <div class="pt-2 photo">
|
|
|
+ <img
|
|
|
+ src="@/assets/images/1.png"
|
|
|
+ class="rounded-full w-14"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="message fex-1 mr-4 mt-2 p-2 rounded-l-md rounded-br-md text-xs">
|
|
|
+ <p>{{ item.text }}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
- <div class="flex">
|
|
|
- <input
|
|
|
- type="text"
|
|
|
- placeholder="输入消息..."
|
|
|
- class="flex-1 py-2 px-4 rounded-l-lg text-sm text-white bg-gray-700 focus:outline-none"
|
|
|
- v-model="content"
|
|
|
- />
|
|
|
- <button @click="getStreamChatWithWeb" class="buttonBg1 text-white px-4 rounded-r-lg text-sm">
|
|
|
- 发送
|
|
|
- </button>
|
|
|
+
|
|
|
+ <div class="absolute left-2 right-2 bottom-4 ">
|
|
|
+ <!-- <div class="flex items-center text-gray-400 text-xs mb-4 ">
|
|
|
+ <span>@Leon S Kennedy - Resident Evil</span>
|
|
|
+ </div> -->
|
|
|
+ <div class="flex">
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ placeholder="输入消息..."
|
|
|
+ class="flex-1 py-2 px-4 rounded-l-lg text-sm text-white focus:outline-none"
|
|
|
+ style="background: #ffffff0f; border: 1px solid #5b5b5e;"
|
|
|
+ v-model="content"
|
|
|
+ @keydown="Enterkey"
|
|
|
+ />
|
|
|
+ <button @click="getStreamChatWithWeb" class="buttonBg1 text-white px-4 rounded-r-lg text-sm">
|
|
|
+ 发送
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -56,6 +91,8 @@ import { streamChatWithWebApi } from "@/api/chat.js"
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
+ messageLoading: true,
|
|
|
+ returnMessage: [],
|
|
|
content: ''
|
|
|
}
|
|
|
},
|
|
@@ -63,24 +100,50 @@ export default {
|
|
|
goBack() {
|
|
|
this.$router.back()
|
|
|
},
|
|
|
+ Enterkey(e) {
|
|
|
+ if (e.keyCode == 13) {
|
|
|
+ this.getStreamChatWithWeb()
|
|
|
+ }
|
|
|
+ },
|
|
|
async getStreamChatWithWeb() {
|
|
|
+ this.messageLoading = true
|
|
|
if (!this.content) {
|
|
|
return
|
|
|
}
|
|
|
+ this.returnMessage.push({
|
|
|
+ user: 'me',
|
|
|
+ text: this.content
|
|
|
+ })
|
|
|
let params = {
|
|
|
content: this.content
|
|
|
}
|
|
|
+ this.returnMessage.push({
|
|
|
+ user: 'ai',
|
|
|
+ text: ''
|
|
|
+ })
|
|
|
let res = await streamChatWithWebApi(params)
|
|
|
- console.log(res, 'res');
|
|
|
- const reader = res.getReader()
|
|
|
+ this.messageLoading = false
|
|
|
+ // 新增一条ai信息
|
|
|
+ if (res.status != 200) {
|
|
|
+ this.$message.error(res.statusText)
|
|
|
+ this.returnMessage.splice(this.returnMessage.length - 1, 1)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 清空输入框的值
|
|
|
+ this.content = ''
|
|
|
+
|
|
|
+ console.log(res, 'res.body');
|
|
|
+ const reader = res.body.getReader()
|
|
|
const decoder=new TextDecoder()
|
|
|
while(1){
|
|
|
- const {done,value} = await reader.read()
|
|
|
+ const {done, value} = await reader.read()
|
|
|
if(done){
|
|
|
break;
|
|
|
}
|
|
|
const txt = decoder.decode(value)
|
|
|
console.log(txt, 'txt');
|
|
|
+
|
|
|
+ this.returnMessage[this.returnMessage.length - 1].text += txt
|
|
|
//txt就是一个一个的字 然后添加到页面上就可以了
|
|
|
}
|
|
|
}
|
|
@@ -93,7 +156,158 @@ export default {
|
|
|
.chat {
|
|
|
min-height: 100vh;
|
|
|
}
|
|
|
+.content {
|
|
|
+ margin-top: 30px;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ display: flex;
|
|
|
+ height: 90vh;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100vw;
|
|
|
+
|
|
|
+ >.leftImg {
|
|
|
+ border-radius: 16px 16px 16px 16px;
|
|
|
+ height: 95%;
|
|
|
+ position: relative;
|
|
|
+ min-width: 380px;
|
|
|
+
|
|
|
+ >img {
|
|
|
+ border: 6px solid;
|
|
|
+ border-image: linear-gradient(180deg, #b48733, #e8cf97, #b48733) 6 6;
|
|
|
+ height: 99%;
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ >.aiInfo {
|
|
|
+ background-color: #ffffff1a;
|
|
|
+ border-radius: 24px 24px 24px 24px;
|
|
|
+ bottom: -70px;
|
|
|
+ display: flex;
|
|
|
+ height: 193px;
|
|
|
+ justify-content: center;
|
|
|
+ left: 50%;
|
|
|
+ position: absolute;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ >.photo {
|
|
|
+ width: 64px;
|
|
|
+ height: 64px;
|
|
|
+ font-size: 18px;
|
|
|
+ position: absolute;
|
|
|
+ top: -20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ color: #fff;
|
|
|
+ line-height: 1.5714285714285714;
|
|
|
+ list-style: none;
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
|
+ display: inline-flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-align: center;
|
|
|
+ vertical-align: middle;
|
|
|
+ background: rgba(0, 0, 0, 0.25);
|
|
|
+ border: 1px solid transparent;
|
|
|
+ border-radius: 50%;
|
|
|
+ }
|
|
|
+ >.info {
|
|
|
+ padding-top: 50px;
|
|
|
+ width: 80%;
|
|
|
+ >.name {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 22px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 31px;
|
|
|
+ text-align: center;
|
|
|
+ text-transform: none;
|
|
|
+ }
|
|
|
+ >.tags {
|
|
|
+ padding-bottom: 8px;
|
|
|
+ text-align: center;
|
|
|
+ >.tag {
|
|
|
+ margin-right: 4px;
|
|
|
+ background: #ffffff1a;
|
|
|
+ border-radius: 4px 4px 4px 4px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 17px;
|
|
|
+ border-color: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.infoContent {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 16px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 500;
|
|
|
+ height: 80px;
|
|
|
+ line-height: 22px;
|
|
|
+ overflow-y: auto;
|
|
|
+ text-align: center;
|
|
|
+ text-transform: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ >.chat-box {
|
|
|
+ margin-left: 5px;
|
|
|
+ position: relative;
|
|
|
+ background-color: #ffffff1a;
|
|
|
+ background-position: 50%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: auto;
|
|
|
+ border: 1px solid #635677 !important;
|
|
|
+ border-radius: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ color: #fff !important;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 95%;
|
|
|
+ // margin: 0 auto;
|
|
|
+ width: 1010px;
|
|
|
+ padding: 25px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.messages {
|
|
|
+ height: calc(100% - 68px );
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+.messages::-webkit-scrollbar {
|
|
|
+ width: 0px;
|
|
|
+}
|
|
|
.message {
|
|
|
- background: #414141;
|
|
|
+ background: #ffffff0f;
|
|
|
+ border: 1px solid #5b5b5e;
|
|
|
+ max-width: calc(100% - 56px);
|
|
|
+ // flex: 1;
|
|
|
+ min-width: 80px;
|
|
|
+}
|
|
|
+.photo {
|
|
|
+ width: 56px;
|
|
|
+}
|
|
|
+.me {
|
|
|
+ flex-direction: row-reverse;
|
|
|
}
|
|
|
+.loadingMessage {
|
|
|
+ position: relative;
|
|
|
+ // display: flex;
|
|
|
+ // justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style scoped>
|
|
|
+ .loadingMessage >>> .el-loading-parent--relative {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ }
|
|
|
+ .loadingMessage >>> .el-loading-spinner {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
</style>
|