feat: 添加聊天历史组件及相关功能,优化消息发送逻辑

This commit is contained in:
yangzhe 2025-07-10 16:41:28 +08:00
parent 25ab27317d
commit aef3a3069d
7 changed files with 566 additions and 361 deletions

119
App.vue
View File

@ -1,31 +1,29 @@
<script> <script>
import router from "./static/common/js/router"; import router from "./static/common/js/router";
import config from "./static/common/js/config.js" import config from "./static/common/js/config.js";
var jweixin = require("jweixin-module"); var jweixin = require("jweixin-module");
export default { export default {
data() { data() {
return { return {
show: false, show: false,
} };
}, },
globalData: {}, globalData: {},
created() { created() {},
},
onLaunch() { onLaunch() {
if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') { if (typeof window.entryUrl === "undefined" || window.entryUrl === "") {
window.entryUrl = location.href.split('#')[0] window.entryUrl = location.href.split("#")[0];
} }
router.initApp(this); router.initApp(this);
// //
let isUrl = this._route.fullPath.split('?')[0] let isUrl = this._route.fullPath.split("?")[0];
let notNeed = config.whiteList.includes(isUrl) let notNeed = config.whiteList.includes(isUrl);
if (notNeed) { if (notNeed) {
uni.navigateTo({ uni.navigateTo({
url: this._route.fullPath, url: this._route.fullPath,
}); });
return return;
} }
var that = this; var that = this;
uni.getSystemInfo({ uni.getSystemInfo({
@ -36,7 +34,20 @@ export default {
} }
}, },
}); });
return
debugger;
if (!that.vuex_user) {
this.$u.vuex("vuex_user", "");
this.$u.vuex("vuex_token", "");
uni.clearStorage();
uni.navigateTo({
url: "/pages/login/login/index",
});
return;
}
return;
if (!that.vuex_user.isFill) { if (!that.vuex_user.isFill) {
this.$u.vuex("vuex_msgList", ""); this.$u.vuex("vuex_msgList", "");
this.$u.vuex("vuex_user", ""); this.$u.vuex("vuex_user", "");
@ -51,10 +62,8 @@ export default {
uni.navigateTo({ uni.navigateTo({
url: "/pages/login/roleSelection", url: "/pages/login/roleSelection",
}); });
return return;
} }
}, },
// onShow(){ // onShow(){
// console.log('onShow') // console.log('onShow')
@ -100,14 +109,14 @@ export default {
type: "gcj02", // wgs84gps openLocation'gcj02' type: "gcj02", // wgs84gps openLocation'gcj02'
success: (res) => { success: (res) => {
uni.hideLoading(); uni.hideLoading();
that.$u.vuex('vuex_userLocation', res) that.$u.vuex("vuex_userLocation", res);
var data = { var data = {
userId: that.vuex_user.id, userId: that.vuex_user.id,
longitude: res.longitude + "", longitude: res.longitude + "",
latitude: res.latitude + "", latitude: res.latitude + "",
}; };
that.$u.api.upPosition(data) that.$u.api.upPosition(data);
}, },
fail: function (res) { fail: function (res) {
uni.hideLoading(); uni.hideLoading();
@ -126,16 +135,15 @@ export default {
isHighAccuracy: true, isHighAccuracy: true,
highAccuracyExpireTime: 3000, highAccuracyExpireTime: 3000,
success: (res) => { success: (res) => {
uni.hideLoading(); uni.hideLoading();
this.$u.vuex('vuex_userLocation', res) this.$u.vuex("vuex_userLocation", res);
var data = { var data = {
userId: this.vuex_user.id, userId: this.vuex_user.id,
longitude: res.longitude + "", longitude: res.longitude + "",
latitude: res.latitude + "", latitude: res.latitude + "",
}; };
this.$u.api.upPosition(data) this.$u.api.upPosition(data);
}, },
fail: (err) => { fail: (err) => {
uni.hideLoading(); uni.hideLoading();
@ -165,13 +173,15 @@ export default {
// console.log(that.$connection.connection.transport.webSocket._webSocket.url) // console.log(that.$connection.connection.transport.webSocket._webSocket.url)
// that.connectionId = that.$connection.connection.transport.url.split( // that.connectionId = that.$connection.connection.transport.url.split(
// "=")[1] // "=")[1]
that.connectionId = that.$connection.connection.transport.webSocket._webSocket.url.split( that.connectionId =
"=")[1] that.$connection.connection.transport.webSocket._webSocket.url.split(
that.CharLogin() "="
)[1];
that.CharLogin();
}) })
.catch((e) => { .catch((e) => {
// //
that.$connection.sto that.$connection.sto;
console.log("websocket连接失败", e); console.log("websocket连接失败", e);
return start(5000); return start(5000);
}); });
@ -180,55 +190,54 @@ export default {
return start(5000); return start(5000);
} }
}, ms); }, ms);
})(0) })(0);
// //
this.$connection.on("ReceiveMessage", (user, message, type) => { this.$connection.on("ReceiveMessage", (user, message, type) => {
if (this._route.fullPath.indexOf("dialogBox") < 0) {
if (this._route.fullPath.indexOf('dialogBox') < 0) {
var tab = this.vuex_tabbar; var tab = this.vuex_tabbar;
tab[1].isDot = true; tab[1].isDot = true;
this.$u.vuex('vuex_tabbar', tab); this.$u.vuex("vuex_tabbar", tab);
var msgList = this.vuex_tabbar var msgList = this.vuex_tabbar;
var msgList = this.vuex_msgList var msgList = this.vuex_msgList;
// //
if (type == 4) { if (type == 4) {
user = 'admin' user = "admin";
} }
if (type == 3) { if (type == 3) {
user += 'user' user += "user";
} }
if (msgList.indexOf(user) < 0) { if (msgList.indexOf(user) < 0) {
msgList += (user + ','); msgList += user + ",";
} }
this.$u.vuex('vuex_msgList', msgList) this.$u.vuex("vuex_msgList", msgList);
} }
}); });
// //
this.$connection.on("SystemMessage", (title, content, time) => { this.$connection.on("SystemMessage", (title, content, time) => {
if (this._route.fullPath.indexOf('sysList') < 0) { if (this._route.fullPath.indexOf("sysList") < 0) {
var tab = this.vuex_tabbar; var tab = this.vuex_tabbar;
tab[1].isDot = true; tab[1].isDot = true;
this.$u.vuex('vuex_tabbar', tab); this.$u.vuex("vuex_tabbar", tab);
var msgList = this.vuex_tabbar var msgList = this.vuex_tabbar;
var msgList = this.vuex_msgList var msgList = this.vuex_msgList;
if (msgList.indexOf('SystemMessage') < 0) { if (msgList.indexOf("SystemMessage") < 0) {
msgList += 'SystemMessage,'; msgList += "SystemMessage,";
} }
this.$u.vuex('vuex_msgList', msgList) this.$u.vuex("vuex_msgList", msgList);
} }
}); });
// //
this.$connection.on("InteractMessage", (data, type) => { this.$connection.on("InteractMessage", (data, type) => {
if (this._route.fullPath.indexOf('interactionList') < 0) { if (this._route.fullPath.indexOf("interactionList") < 0) {
var tab = this.vuex_tabbar; var tab = this.vuex_tabbar;
tab[1].isDot = true; tab[1].isDot = true;
this.$u.vuex('vuex_tabbar', tab); this.$u.vuex("vuex_tabbar", tab);
var msgList = this.vuex_tabbar var msgList = this.vuex_tabbar;
var msgList = this.vuex_msgList var msgList = this.vuex_msgList;
if (msgList.indexOf('InteractMessage') < 0) { if (msgList.indexOf("InteractMessage") < 0) {
msgList += 'InteractMessage,'; msgList += "InteractMessage,";
} }
this.$u.vuex('vuex_msgList', msgList) this.$u.vuex("vuex_msgList", msgList);
} }
}); });
}, },
@ -237,22 +246,19 @@ export default {
if (this.vuex_user.id) { if (this.vuex_user.id) {
this.$connection this.$connection
.invoke("login", this.connectionId, this.vuex_user.id) .invoke("login", this.connectionId, this.vuex_user.id)
.then((res) => { .then((res) => {})
.catch((err) => {});
})
.catch((err) => {
});
// //
// this.getLocation() // this.getLocation()
} else { } else {
setTimeout(() => { setTimeout(() => {
this.CharLogin() this.CharLogin();
}, 1000) }, 1000);
} }
}, },
}, },
mounted() { mounted() {
this.charLink() this.charLink();
}, },
}; };
</script> </script>
@ -305,7 +311,7 @@ uni-modal .uni-modal__btn:after {
uni-modal .uni-modal__btn_default { uni-modal .uni-modal__btn_default {
background: #e6f6ff; background: #e6f6ff;
color: #3CB5FB !important; color: #3cb5fb !important;
margin-right: 20rpx; margin-right: 20rpx;
} }
@ -322,7 +328,6 @@ uni-modal .uni-modal__btn_primary {
color: #ffffff !important; color: #ffffff !important;
} }
uni-modal .uni-modal { uni-modal .uni-modal {
padding: 40rpx; padding: 40rpx;
box-sizing: border-box; box-sizing: border-box;

View File

@ -93,6 +93,10 @@ const install = (Vue, vm) => {
/** 首页ai对话 */ /** 首页ai对话 */
// 发送消息 // 发送消息
let SendMessageApi = (params = {}) => vm.$u.post('api/ChatAI/CreateChat', params); let SendMessageApi = (params = {}) => vm.$u.post('api/ChatAI/CreateChat', params);
// 获取历史对话列表
let GetConversationPage = (params = {}) => vm.$u.get('api/ChatAI/GetConversationPage', params);
// 获取对话详情
let GetConversationDetail = (params = {}) => vm.$u.get('api/ChatAI/GetHistoricalConversations', params);
/** 登录 */ /** 登录 */
// 获取图形验证码 // 获取图形验证码
@ -144,7 +148,9 @@ const install = (Vue, vm) => {
SendMessageApi, SendMessageApi,
GetCaptcha, GetCaptcha,
GetStuVerifyCode, GetStuVerifyCode,
StuLogin StuLogin,
GetConversationPage,
GetConversationDetail
}; };
} }

210
components/ChatHistory.vue Normal file
View File

@ -0,0 +1,210 @@
<template>
<u-popup v-model="showPopup" width="550rpx">
<view class="drawer-container">
<view class="drawer-header">
<text class="drawer-title" @click="handleCreateConversation">
<u-icon
class="drawer-title-icon"
name="plus"
size="32rpx"
color="#666666"
></u-icon>
新建对话
</text>
</view>
<scroll-view scroll-y class="chat-history-list">
<!-- 使用新的数据结构渲染聊天历史 -->
<view
v-for="(group, groupIndex) in chatHistoryList3"
:key="'group-' + group.id + groupIndex"
>
<!-- 日期标题 -->
<view class="chat-day">
<text class="day-text">{{ group.id }}</text>
</view>
<!-- 该日期下的对话列表 -->
<view
class="chat-item"
v-for="(item, index) in group.conversation"
:key="'conv-' + groupIndex + '-' + index"
:class="{
'chat-item-active':
currentActiveGroup === groupIndex &&
currentActiveIndex === index,
}"
@click="selectChatItem(groupIndex, index, item.id)"
>
<text class="chat-text">{{ item.title }}</text>
</view>
</view>
</scroll-view>
<view class="drawer-footer">
<view class="user-info">
<image
class="user-avatar"
src="/static/common/images/avatar.png"
></image>
<text class="user-name">{{ userName || "晓德塔," }}</text>
</view>
<view class="settings">
<u-icon name="setting" size="40rpx" color="#999"></u-icon>
</view>
</view>
</view>
</u-popup>
</template>
<script>
export default {
name: "ChatHistory",
props: {
show: {
type: Boolean,
default: false,
},
chatHistoryList3: {
type: Array,
default: () => [],
},
activeIndex: {
type: Number,
default: 0,
},
userName: {
type: String,
default: "",
},
},
data() {
return {
showPopup: false,
currentActiveGroup: -1,
currentActiveIndex: -1,
};
},
watch: {
show: {
handler(newVal) {
this.showPopup = newVal;
},
immediate: true,
},
showPopup(val) {
if (val !== this.show) {
this.$emit("update:show", val);
}
},
},
methods: {
selectChatItem(groupIndex, index, conversationId) {
this.currentActiveGroup = groupIndex;
this.currentActiveIndex = index;
//
this.$emit("select-conversation", {
conversationId,
});
},
handleCreateConversation() {
this.$emit("create-conversation");
},
},
};
</script>
<style lang="scss" scoped>
.drawer-container {
padding: 32rpx;
display: flex;
flex-direction: column;
height: 100vh;
background-color: #ffffff;
.drawer-header {
padding: 40rpx 32rpx;
.drawer-title {
font-family: DouyinSans;
font-weight: bold;
font-size: 32rpx;
color: #666666;
.drawer-title-icon {
margin-right: 10rpx;
}
}
}
.chat-history-list {
flex: 1;
height: calc(100vh - 200rpx);
.chat-day {
display: flex;
margin: 20rpx 0 20rpx 30rpx;
.day-text {
font-size: 24rpx;
color: #999999;
font-family: PingFang SC;
margin-bottom: 10rpx;
}
}
.chat-item {
padding: 24rpx 30rpx;
border-radius: 16rpx;
.chat-text {
font-size: 28rpx;
color: #303030;
font-family: PingFang SC;
}
&-active {
background-color: #4f6aff;
.chat-text {
color: #fff;
}
}
}
}
.drawer-footer {
height: 130rpx;
border: 1rpx solid #eeeeee;
border-radius: 12rpx;
padding: 0 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
.user-info {
display: flex;
align-items: center;
.user-avatar {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
margin-right: 30rpx;
}
.user-name {
font-size: 28rpx;
font-weight: bold;
font-family: DouyinSans;
color: #333;
}
}
.settings {
padding: 10rpx;
}
}
}
</style>

View File

@ -54,7 +54,7 @@
</view> --> </view> -->
<view class="start-chat"> <view class="start-chat">
<button class="chat-button" @click="isChat = true"> <button class="chat-button" @click="handleStartChat">
<image <image
class="chat-icon" class="chat-icon"
src="/static/common/images/icon_chat.png" src="/static/common/images/icon_chat.png"
@ -116,25 +116,22 @@
<view class="chat-content"> <view class="chat-content">
<!-- 消息循环渲染 --> <!-- 消息循环渲染 -->
<block <block
v-for="(group, groupIndex) in messageGroups" v-for="(message, index) in messageGroups"
:key="'group-' + groupIndex" :key="'msg-' + index"
> >
<!-- 时间 --> <!-- 时间 -->
<view class="message-time" v-if="group.time">{{ group.time }}</view> <view class="message-time" v-if="message.timeLabel === 1">
{{ message.displayTime }}
</view>
<!-- 消息列表 -->
<block
v-for="(message, messageIndex) in group.messages"
:key="'msg-' + groupIndex + '-' + messageIndex"
>
<!-- 用户消息 --> <!-- 用户消息 -->
<view <view
class="message-right" class="message-right"
v-if="message.isUser" v-if="message.interactMode === 0"
:id="'msg-' + message.id" :id="'msg-' + message.id"
> >
<view class="message-content"> <view class="message-content">
<text>{{ message.content }}</text> <text>{{ message.message }}</text>
</view> </view>
<image <image
class="user-avatar" class="user-avatar"
@ -144,19 +141,21 @@
</view> </view>
<!-- AI消息 --> <!-- AI消息 -->
<view class="message-left" v-else :id="'msg-' + message.id"> <view
class="message-left"
v-if="message.interactMode === 1"
:id="'msg-' + message.id"
>
<image <image
class="ai-avatar" class="ai-avatar"
src="/static/common/images/avatar_ai.png" src="/static/common/images/avatar_ai.png"
mode="scaleToFill" mode="scaleToFill"
/> />
<view class="message-content"> <view class="message-content">
<!-- <text space="nbsp" decode>{{ message.content }}</text> --> <markdown-viewer :content="message.message" />
<markdown-viewer :content="message.content" />
</view> </view>
</view> </view>
</block> </block>
</block>
</view> </view>
</scroll-view> </scroll-view>
@ -206,6 +205,7 @@
v-model="messageValue" v-model="messageValue"
type="text" type="text"
class="chat-input" class="chat-input"
:focus="true"
placeholder="请输入内容" placeholder="请输入内容"
placeholder-style="color: #adadad;" placeholder-style="color: #adadad;"
@confirm="sendMessageFn" @confirm="sendMessageFn"
@ -223,56 +223,13 @@
</view> </view>
<!-- 对话弹出层 --> <!-- 对话弹出层 -->
<u-popup v-model="popupShow" width="550rpx"> <chat-history
<view class="drawer-container"> :show.sync="popupShow"
<scroll-view scroll-y class="chat-history-list"> :chat-history-list3="chatHistoryList3"
<view class="chat-day"> :user-name="vuex_user ? vuex_user.Name : ''"
<text class="day-text">周三</text> @select-conversation="handleSelectConversation"
</view> @create-conversation="handleCreateConversation"
<view ></chat-history>
class="chat-item"
v-for="(item, index) in chatHistoryList"
:key="index"
:class="{ 'chat-item-active': index === activeIndex }"
@click="selectChatItem(index)"
>
<text class="chat-text">{{ item.content }}</text>
</view>
<view class="chat-day">
<text class="day-text">6/27</text>
</view>
<view
class="chat-item"
v-for="(item, index) in chatHistoryList2"
:key="'history2-' + index"
:class="{
'chat-item-active':
index + chatHistoryList.length === activeIndex,
}"
@click="selectChatItem(index + chatHistoryList.length)"
>
<text class="chat-text">{{ item.content }}</text>
</view>
</scroll-view>
<view class="drawer-footer">
<view class="user-info">
<image
class="user-avatar"
src="/static/common/avatar/male.png"
></image>
<!-- <u-avatar
class="user-avatar"
src="/static/common/avatar/user-avatar.png"
></u-avatar> -->
<text class="user-name">晓德塔</text>
</view>
<view class="settings">
<u-icon name="setting" size="40rpx" color="#999"></u-icon>
</view>
</view>
</view>
</u-popup>
<!-- 完善信息弹出层 --> <!-- 完善信息弹出层 -->
<perfect-info :show.sync="perfectInfoShow"></perfect-info> <perfect-info :show.sync="perfectInfoShow"></perfect-info>
@ -290,6 +247,7 @@ import MarkdownViewer from "@/components/markdown-viewer/markdown-viewer";
import CustomTabBar from "@/components/custom-tab-bar/custom-tab-bar.vue"; import CustomTabBar from "@/components/custom-tab-bar/custom-tab-bar.vue";
import AdvicePhone from "@/components/AdvicePhone.vue"; import AdvicePhone from "@/components/AdvicePhone.vue";
import PerfectInfo from "@/components/PerfectInfo.vue"; import PerfectInfo from "@/components/PerfectInfo.vue";
import ChatHistory from "@/components/ChatHistory.vue"; //
export default { export default {
components: { components: {
@ -297,10 +255,12 @@ export default {
AdvicePhone, AdvicePhone,
MarkdownViewer, MarkdownViewer,
PerfectInfo, PerfectInfo,
ChatHistory, //
}, },
data() { data() {
return { return {
isChat: false, isChat: false,
currentConversationId: "",
advicePhoneShow: false, advicePhoneShow: false,
perfectInfoShow: false, perfectInfoShow: false,
@ -326,22 +286,37 @@ export default {
}, },
], ],
popupShow: false, popupShow: false,
chatHistoryList: [ chatHistoryList3: [
{ content: "学校哪些专业比较好?" }, // {
{ content: "如何报考学校综合合录取评澳市评招生?" }, // "id": "",
{ content: "学校有新华专业?" }, // "conversation": [
], // {
chatHistoryList2: [ // "title": "",
{ content: "学校哪些专业比较好?" }, // "id": "0d03f23c-9c5b-45ac-ae95-be51e9383a62",
{ content: "如何报考学校综合合录取评澳市评招生?" }, // "startTime": "2025-07-10T15:28:02.832316"
{ content: "如何报考学校综合合录取评澳市评招生?" }, // },
{ content: "如何报考学校综合合录取评澳市评招生?" }, // {
{ content: "如何报考学校综合合录取评澳市评招生?" }, // "title": "线",
{ content: "学校有新华专业?" }, // "id": "771ab434-348c-4a35-bd03-adebc21436d8",
{ content: "学校有新华专业?" }, // "startTime": "2025-07-10T15:11:32.885001"
{ content: "学校有新华专业?" }, // }
{ content: "学校有新华专业?" }, // ]
{ content: "学校有新华专业?" }, // },
// {
// "id": "",
// "conversation": [
// {
// "title": "",
// "id": "0d03f23c-9c5b-45ac-ae95-be51e9383a62",
// "startTime": "2025-07-09T15:28:02.832316"
// },
// {
// "title": "线",
// "id": "771ab434-348c-4a35-bd03-adebc21436d8",
// "startTime": "2025-07-09T15:11:32.885001"
// }
// ]
// }
], ],
activeIndex: 0, activeIndex: 0,
commonQuestions: [ commonQuestions: [
@ -352,57 +327,31 @@ export default {
"我什么时候能推知道自己是否被录取?", "我什么时候能推知道自己是否被录取?",
], ],
scrollToView: "", scrollToView: "",
// messageGroups
messageGroups: [ messageGroups: [
// { // {
// time: "2025-07-01 10:00:00", // id: "9cac8661-bf09-4b63-ab15-1a0a36b921e0",
// messages: [ // message: "线",
// { id: 1, content: "?", isUser: true }, // sendDate: "2025-07-10T15:11:32.886075",
// { // isSend: true,
// id: 2, // isRead: false,
// content: // interactMode: 0,
// "", // messageType: 0,
// isUser: false, // timeLabel: 1,
// }, // displayTime: "15:11",
// { id: 3, content: "", isUser: true },
// {
// id: 4,
// content:
// "95%IT",
// isUser: false,
// },
// ],
// }, // },
// { // {
// time: "2025-07-02 09:15:36", // id: "02306fc3-c821-4a23-ad66-0bd77d154105",
// messages: [ // message:
// { id: 5, content: "", isUser: true }, // "2025线线2023-2024线\n\n线西www.jxnee.edu.cn0790-6764666/6765666",
// { // sendDate: "2025-07-10T15:11:32.88644",
// id: 6, // isSend: true,
// content: // isRead: false,
// " -- -- -- -- -- --", // interactMode: 1,
// isUser: false, // messageType: 0,
// timeLabel: 0,
// displayTime: "",
// }, // },
// { id: 7, content: "", isUser: true },
// {
// id: 8,
// content:
// "\n1. \n2. \n3. 24\n4. ()\n5. ()\n\n便",
// isUser: false,
// },
// ],
// },
{
time: "",
messages: [
// { id: 5, content: "", isUser: true },
// {
// id: 6,
// content:
// " -- -- -- -- -- --",
// isUser: false,
// },
],
},
], ],
scrollTop: 0, scrollTop: 0,
@ -443,59 +392,15 @@ export default {
}); });
}, },
methods: { methods: {
// Markdown使
testMarkdownRender() {
const markdownSample = `# 这是标题
## 这是二级标题
这是**加粗文本***斜体文本*
> 这是引用文本
- 列表项1
- 列表项2
- 列表项3
\`\`\`javascript
//
function hello() {
console.log('Hello World!');
}
\`\`\`
[这是链接](https://www.example.com)
| 表头1 | 表头2 |
| ----- | ----- |
| 内容1 | 内容2 |
| 内容3 | 内容4 |
`;
this.messageGroups[0].messages.push({
id: this.messageGroups[0].messages.length + 1,
content: "测试Markdown渲染",
isUser: true,
});
setTimeout(() => {
this.messageGroups[0].messages.push({
id: `test-${Date.now()}`,
content: markdownSample,
isUser: false,
});
}, 500);
},
handleLeftClick() { handleLeftClick() {
this.$refs.uToast.show({ this.$u.api.GetConversationPage().then((res) => {
title: "暂未开放", this.chatHistoryList3 = res.data;
type: "warning", console.log("this.chatHistoryList3", this.chatHistoryList3);
});
return;
this.popupShow = true; this.popupShow = true;
});
}, },
selectChatItem(index) { selectChatItem(index) {
this.activeIndex = index; this.activeIndex = index;
}, },
@ -538,44 +443,121 @@ export default {
} }
}, },
//
sendMessageFn() { sendMessageFn() {
if (!this.messageValue) { if (!this.messageValue) {
return; return;
} }
const sendMessage = this.messageValue; const sendMessage = this.messageValue;
console.log("发送消息", sendMessage); console.log("发送消息", sendMessage);
this.messageGroups[0].messages.push({
id: this.messageGroups[0].messages.length + 1, //
content: sendMessage, const userMessage = {
isUser: true, id: Math.random().toString(36).substring(2, 15),
}); message: sendMessage,
sendDate: "",
isSend: true,
isRead: false,
interactMode: 0, //
messageType: 0,
timeLabel: 0,
displayTime: "",
};
//
this.messageGroups.push(userMessage);
this.messageValue = ""; this.messageValue = "";
this.$u.api this.$u.api
.SendMessageApi({ .SendMessageApi({
query: sendMessage, query: sendMessage,
conversationId: "", conversationId: this.currentConversationId,
}) })
.then((res) => { .then((res) => {
console.log("res.....", res); console.log("res.....", res);
const data = res.data; const data = res.data;
// Markdown // AI
let content = data.content; const aiMessage = {
id:
data.conversationId ||
Math.random().toString(36).substring(2, 15),
message: data.content,
sendDate: "",
isSend: true,
isRead: false,
interactMode: 1, // AI
messageType: 0,
timeLabel: 0,
displayTime: "",
};
// Markdown //
// Markdown this.messageGroups.push(aiMessage);
// content = content.replace(/\n/g, "\n\n"); });
},
this.messageGroups[0].messages.push({ //
id: data.conversationId, formatTime(date) {
content: content, const hours = date.getHours().toString().padStart(2, "0");
isUser: false, const minutes = date.getMinutes().toString().padStart(2, "0");
return `${hours}:${minutes}`;
},
//
handleSelectConversation(data) {
//
this.popupShow = false;
console.log("选中的对话:", data);
// conversationId
const conversationId = data.conversationId;
this.currentConversationId = conversationId;
this.isChat = true;
this.messageGroups = [];
this.$u.api
.GetConversationDetail({
"Item1.Id": conversationId,
PageIndex: "1",
PageSize: "20",
})
.then((res) => {
console.log("GetConversationDetail.....", res.item2);
// sendDate(interactMode=0)
this.messageGroups = res.item2.sort((a, b) => {
const timeA = new Date(a.sendDate).getTime();
const timeB = new Date(b.sendDate).getTime();
// interactMode01
if (timeA === timeB) {
return a.interactMode - b.interactMode;
}
//
return timeA - timeB;
}); });
}); });
}, },
handleCreateConversation() {
//
this.popupShow = false;
this.isChat = true;
this.currentConversationId = "";
this.messageGroups = [];
},
handleStartChat() {
this.isChat = true;
this.currentConversationId = "";
this.messageGroups = [];
},
}, },
}; };
</script> </script>

View File

@ -331,27 +331,27 @@ export default {
// //
login() { login() {
const res = { // const res = {
data: { // data: {
// // token:
// // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbiIsIlVzZXJJbmZvIjoie1wiSWRcIjpcImI1MjY5ZWQxLTViYzgtMTFmMC05YTg5LTAwMTYzZTJkMmRkM1wiLFwiTmFtZVwiOlwi6J-56ICB5biIXCIsXCJQaG9uZU51bWJlclwiOlwiMTM1ODg4ODg4ODhcIixcIlNleFwiOjEsXCJBY2NvdW50VHlwZVwiOjJ9IiwibmJmIjoxNzUyMTE4ODU0LCJleHAiOjE3NTIyMDUyNTR9.aF0Q-X3ebIld7RIKMMW68tXjmmR4OO08dXLAtHWuuwc",
// token: // token:
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbiIsIlVzZXJJbmZvIjoie1wiSWRcIjpcImI1MjY5ZWQxLTViYzgtMTFmMC05YTg5LTAwMTYzZTJkMmRkM1wiLFwiTmFtZVwiOlwi6J-56ICB5biIXCIsXCJQaG9uZU51bWJlclwiOlwiMTM1ODg4ODg4ODhcIixcIlNleFwiOjEsXCJBY2NvdW50VHlwZVwiOjJ9IiwibmJmIjoxNzUyMTE4ODU0LCJleHAiOjE3NTIyMDUyNTR9.aF0Q-X3ebIld7RIKMMW68tXjmmR4OO08dXLAtHWuuwc", // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJVc2VyIiwiVXNlckluZm8iOiJ7XCJJZFwiOlwiNTljNzIxNmMtMTRhZS00NmRmLTkxYTItNGYzMjFlZjM2YjQ5XCIsXCJOYW1lXCI6XCIxNzMzNTM3NDg4N1wiLFwiUGhvbmVOdW1iZXJcIjpcIjE3MzM1Mzc0ODg3XCIsXCJTZXhcIjoyLFwiQWNjb3VudFR5cGVcIjowfSIsIm5iZiI6MTc1MjExMDcwOSwiZXhwIjoxNzUyMTk3MTA5fQ.VDv2KjGq3s3BbZxZjB3P-BaeDU_1vIdqFEWGGvdpIxU",
token: // },
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJVc2VyIiwiVXNlckluZm8iOiJ7XCJJZFwiOlwiNTljNzIxNmMtMTRhZS00NmRmLTkxYTItNGYzMjFlZjM2YjQ5XCIsXCJOYW1lXCI6XCIxNzMzNTM3NDg4N1wiLFwiUGhvbmVOdW1iZXJcIjpcIjE3MzM1Mzc0ODg3XCIsXCJTZXhcIjoyLFwiQWNjb3VudFR5cGVcIjowfSIsIm5iZiI6MTc1MjExMDcwOSwiZXhwIjoxNzUyMTk3MTA5fQ.VDv2KjGq3s3BbZxZjB3P-BaeDU_1vIdqFEWGGvdpIxU", // };
},
};
const token = res.data.token; // const token = res.data.token;
// // //
const userInfo = getUserInfoFromJWT(token); // const userInfo = getUserInfoFromJWT(token);
// // //
this.$u.vuex("vuex_token", token); // this.$u.vuex("vuex_token", token);
this.$u.vuex("vuex_user", userInfo); // this.$u.vuex("vuex_user", userInfo);
// // //
uni.reLaunch({ // uni.reLaunch({
url: "/pages/home/index/index", // url: "/pages/home/index/index",
}); // });
return; // return;
// //
if (!this.validatePhone()) { if (!this.validatePhone()) {

View File

@ -14,5 +14,5 @@ export default {
'/pages/login/recognitionResult/recognitionFailed' '/pages/login/recognitionResult/recognitionFailed'
], ],
//登录页 //登录页
loginPage:"/pages/login/login/login" loginPage:"/pages/login/login/index"
} }

View File

@ -1,27 +1,29 @@
import config from "./config.js" import config from "./config.js";
const initApp = function(vm) { const initApp = function (vm) {
/** /**
* 页面跳转拦截器 * 页面跳转拦截器
*/ */
let that = vm; let that = vm;
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]; let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
list.forEach(item => { //用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器 list.forEach((item) => {
//用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器
uni.addInterceptor(item, { uni.addInterceptor(item, {
invoke(e) { // 调用前拦截 invoke(e) {
// 调用前拦截
//获取用户的token //获取用户的token
// console.log(e) // console.log(e)
const token = that.vuex_token, const token = that.vuex_token,
//获取要跳转的页面路径url去掉"?"和"?"后的参数) //获取要跳转的页面路径url去掉"?"和"?"后的参数)
url = e.url.split('?')[0]; url = e.url.split("?")[0];
let notNeed = config.whiteList.includes(url) let notNeed = config.whiteList.includes(url);
// 如果在whiteList里面就不需要登录 // 如果在whiteList里面就不需要登录
// console.log(notNeed) // console.log(notNeed)
if (notNeed) { if (notNeed) {
return e return e;
} else { } else {
//需要登录 //需要登录
if (token == '') { if (token == "") {
// uni.showToast({ // uni.showToast({
// title: '请先登录', // title: '请先登录',
// icon: 'none' // icon: 'none'
@ -30,27 +32,27 @@ const initApp = function(vm) {
// url: config.loginPage // url: config.loginPage
// }) // })
uni.navigateTo({ uni.navigateTo({
url: '/' url: "/pages/login/login/index",
}) });
return false return false;
} else { } else {
return e return e;
} }
} }
}, },
fail(err) { // 失败回调拦截 fail(err) {
console.log(err) // 失败回调拦截
console.log(err);
// if (Debug) { // if (Debug) {
// uni.showModal({ // uni.showModal({
// content: JSON.stringify(err), // content: JSON.stringify(err),
// showCancel: false // showCancel: false
// }); // });
// } // }
} },
}) });
}) });
} };
export default { export default {
initApp: initApp initApp: initApp,
} };