<template>
|
<div class="w100 h100 flex items-center flex-column box-border pr-1">
|
<div class="w100 box-border px-[18px] py-0 flex-0">
|
<el-button
|
@click="newChatRoomClick"
|
icon="ele-Plus"
|
color="#1c86ff"
|
class="flex items-center box-border mb-3 justify-center add_room cursor-pointer w-[124px] h-[32.88px] rounded-s-md text-white opacity-100"
|
>
|
新建对话
|
</el-button>
|
</div>
|
<div
|
class="flex flex-col flex-auto w-[210.98px] rounded-t-lg box-border mb-3 relative opacity-100 shadow-lg shadow-[[#0e0e0f]-500/50"
|
>
|
<div class="group flex-0 relative w100 h-[34px] bg-[#2b2c30]">
|
<el-input clearable v-model="queryParams.title" placeholder="搜索" class="set-input">
|
<template #prefix>
|
<el-icon><search /></el-icon>
|
</template>
|
</el-input>
|
<div
|
class="absolute hidden top-[100%] w-[84px] z-[1001] left-0 group-hover:block overflow-hidden rounded-md text-sm text-gray-500 bg-[#fff] py-1.5"
|
>
|
<div
|
class="w100 relative hover:bg-[#e6f1ff]"
|
v-for="item in Object.keys(dateFilterMap)"
|
:key="item"
|
@click="filterDateClick(Number(item))"
|
>
|
<div
|
class="size-2 absolute left-2 rounded-full bg-[#2a82e4]"
|
:style="{ display: item === activeDateFilter + '' ? 'block' : 'none' }"
|
style="top: calc(50% - 0.25rem)"
|
></div>
|
<div class="w100 relative h-[28px] flex items-center justify-center cursor-pointer">{{ dateFilterMap[item] }}</div>
|
</div>
|
</div>
|
</div>
|
|
<div class="flex-auto text-[#ccc] flex flex-col items-center mt-6 overflow-y-auto set-scroll" ref="chatRoomRef">
|
<div
|
:class="{ 'bg-[#41424a]': item.id === activeRoomId }"
|
class="group flex items-center w-full h-10 rounded-md cursor-pointer px-2 py-2 flex-0"
|
v-for="(item, index) in queryData"
|
:key="index"
|
@click="roomClick(item)"
|
>
|
<div class="ywifont ywicon-xiaoxi1 flex-0 mr-2.5"></div>
|
<div class="flex-auto text-ellipsis text-nowrap text-sm group-hover:text-[#0084ff]">{{ item.title }}</div>
|
<div class="text-gray-100 flex items-center space-x-2 ml-1">
|
<div class="ywifont invisible ywicon-bianji group-hover:visible !text-sm" @click.stop="editChat(item)"></div>
|
<el-popconfirm title="确定删除聊天记录?" @confirm.stop="confirmDeleteChatRoom(item)" width="180">
|
<template #reference>
|
<div class="ywifont invisible ywicon-shanchu3 group-hover:visible"></div>
|
</template>
|
</el-popconfirm>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { Search } from '@element-plus/icons-vue';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
import moment from 'moment';
|
import { computed, onMounted, ref, watch } from 'vue';
|
import type { ChatRoomItem } from './types';
|
import { DeleteHistoryGroups, setHistoryGroupTitle } from '/@/api/ai/chat';
|
import { useSearch } from '/@/hooks/useSearch';
|
import { DateFilter, dateFilterMap } from '/@/model/types/date';
|
import { activeRoomId, chatRoomList, gotoAnswerPage, newChatRoomClick } from '/@/stores/chatRoom';
|
import { debounce, getRecentDateRange } from '/@/utils/util';
|
const chatRoomRef = ref<HTMLDivElement>(null);
|
const queryParams = ref({
|
title: '',
|
});
|
|
const roomClick = (room: ChatRoomItem) => {
|
activeRoomId.value = room.id;
|
|
gotoAnswerPage(room);
|
};
|
|
const confirmDeleteChatRoom = async (room: ChatRoomItem) => {
|
const res = await DeleteHistoryGroups({
|
history_group_id: room.id,
|
});
|
|
const foundIndex = chatRoomList.value.findIndex((item) => item === room);
|
chatRoomList.value.splice(foundIndex, 1);
|
if (chatRoomList.value.length === 0) {
|
newChatRoomClick();
|
return;
|
}
|
roomClick(chatRoomList.value[0]);
|
chatRoomRef.value.firstElementChild?.scrollIntoView();
|
};
|
const editChat = (room: ChatRoomItem) => {
|
ElMessageBox.prompt('', '重命名', {
|
confirmButtonText: '确认',
|
cancelButtonText: '取消',
|
inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
|
inputValue: room.title,
|
inputErrorMessage: '请输入新的名称',
|
})
|
.then(async (edit) => {
|
const res = await setHistoryGroupTitle({
|
history_group_id: room.id,
|
title: edit.value,
|
});
|
if (res.json_ok) {
|
const foundIndex = chatRoomList.value.findIndex((item) => item.id === room.id);
|
chatRoomList.value[foundIndex].title = edit.value;
|
chatRoomRef.value.firstElementChild?.scrollIntoView();
|
}
|
})
|
.catch(({ value }) => {
|
ElMessage({
|
type: 'info',
|
message: '取消修改',
|
});
|
});
|
};
|
//#region ====================== 日期筛选 ======================
|
|
const activeDateFilter = ref<DateFilter>(DateFilter.All);
|
const filterDateClick = (dateFilter: DateFilter) => {
|
activeDateFilter.value = dateFilter;
|
};
|
|
const filteredChatRoomList = computed(() => {
|
if (activeDateFilter.value === DateFilter.All) return chatRoomList.value;
|
else {
|
let dayCount = null;
|
switch (activeDateFilter.value) {
|
case DateFilter.AWeek:
|
dayCount = 7;
|
break;
|
|
case DateFilter.AMonth:
|
dayCount = 30;
|
|
break;
|
case DateFilter.ThreeMonth:
|
dayCount = 90;
|
break;
|
}
|
|
const [startDay, endDay] = getRecentDateRange(dayCount);
|
const data = chatRoomList.value.filter((item) => moment(item.createTime).isBetween(startDay, endDay));
|
return data;
|
}
|
});
|
//#endregion
|
|
//#region ====================== 搜索聊天室 ======================
|
const { query, queryData } = useSearch(filteredChatRoomList, queryParams);
|
|
const debounceQuery = debounce(query);
|
|
watch(
|
() => queryParams.value.title,
|
(val) => {
|
debounceQuery();
|
}
|
);
|
//#endregion
|
|
onMounted(async () => {
|
// const res = await GetHistoryGroups();
|
// const resData = (res?.groups || []) as any[];
|
// // 按最晚时间到最早时间
|
// chatRoomList.value = resData
|
// ?.toSorted((a, b) => {
|
// return b.create_time.localeCompare(a.create_time);
|
// })
|
// .map((item) => {
|
// return {
|
// id: item.group_id,
|
// title: item.group_title,
|
// createTime: item.create_time,
|
// isInitial: Number(item.chat_count) === 0,
|
// };
|
// });
|
// if (!chatRoomList.value || chatRoomList.value.length === 0) {
|
// newChatRoomClick();
|
// } else {
|
// const toClickRoom = activeChatRoom.value ?? chatRoomList.value[0];
|
// roomClick(toClickRoom);
|
// }
|
});
|
</script>
|
<style scoped lang="scss">
|
.set-input {
|
:deep(.el-input__wrapper) {
|
width: 100%;
|
height: 100%;
|
font-size: 12px;
|
font-weight: 400;
|
letter-spacing: 0;
|
color: #e5e5e5;
|
border-radius: 6px;
|
border: 1px solid transparent;
|
box-sizing: border-box;
|
line-height: 34px;
|
// padding-left: 31px;
|
padding-right: 10px;
|
background-color: transparent;
|
cursor: pointer;
|
transition: color 0.2s ease-in-out;
|
box-shadow: unset;
|
}
|
:deep(.el-input__inner) {
|
&::placeholder {
|
color: white;
|
}
|
color: white;
|
}
|
}
|
::-webkit-scrollbar {
|
height: 0;
|
width: 0;
|
color: transparent;
|
}
|
</style>
|