YingXingAI/components/ChatHistory.vue

271 lines
6.0 KiB
Vue
Raw Permalink Normal View History

<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"
:scroll-into-view="scrollToView"
:show-scrollbar="false"
scroll-with-animation="true"
>
<!-- 使用新的数据结构渲染聊天历史 -->
<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"
:id="'chat-item-' + item.id"
:class="{
2025-07-11 13:43:04 +08:00
'chat-item-active': item.isActiveChat,
}"
@click="selectChatItem(groupIndex, index, item.id)"
>
2025-07-11 13:43:04 +08:00
<!-- currentActiveGroup === groupIndex &&
currentActiveIndex === index, -->
<text class="chat-text">{{ item.title }}</text>
</view>
</view>
<!-- 添加底部空白区域 -->
<view class="bottom-space"></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,
activeItemId: "", // 存储当前激活项的ID
scrollToView: "", // 用于scroll-into-view属性
};
},
watch: {
show: {
handler(newVal) {
this.showPopup = newVal;
},
immediate: true,
},
showPopup(val) {
if (val !== this.show) {
this.$emit("update:show", val);
}
},
// 监听聊天历史数据变化,找到激活项并滚动
chatHistoryList3: {
handler() {
this.$nextTick(() => {
this.scrollToActiveItem();
});
},
deep: true,
immediate: true,
},
},
methods: {
// 滚动到激活的聊天项
scrollToActiveItem() {
// 查找激活的聊天项
let activeItemFound = false;
for (
let groupIndex = 0;
groupIndex < this.chatHistoryList3.length;
groupIndex++
) {
const group = this.chatHistoryList3[groupIndex];
for (let index = 0; index < group.conversation.length; index++) {
const item = group.conversation[index];
if (item.isActiveChat) {
activeItemFound = true;
this.activeItemId = `chat-item-${item.id}`;
// 设置scrollToView的值使scroll-view自动滚动到该元素
this.scrollToView = this.activeItemId;
break;
}
}
if (activeItemFound) break;
}
},
selectChatItem(groupIndex, index, conversationId) {
2025-07-11 13:43:04 +08:00
// 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: 0 32rpx;
height: 140rpx;
line-height: 120rpx;
.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 - 360rpx);
padding-bottom: 20rpx;
.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;
margin-bottom: 4rpx;
position: relative;
overflow: hidden;
.chat-text {
font-size: 28rpx;
color: #303030;
font-family: PingFang SC;
}
&-active {
background-color: #4f6aff;
box-shadow: 0 2rpx 8rpx rgba(79, 106, 255, 0.3);
.chat-text {
color: #fff;
}
}
}
}
.bottom-space {
height: 30rpx;
width: 100%;
}
.drawer-footer {
margin-top: 20rpx;
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>