diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index eb4100f7..2bc55fa6 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -96,7 +96,11 @@ "chat_search": "Search", "thinking": "Thinking", "thinking_step": "Thought Process", - "ask_again": "Regenerate" + "ask_again": "Regenerate", + "today": "Today", + "week": "This Week", + "earlier": "Earlier", + "no_time": "No Time" }, "ds": { "title": "Data Source", diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json index ca4c7d84..5163a6e9 100644 --- a/frontend/src/i18n/zh-CN.json +++ b/frontend/src/i18n/zh-CN.json @@ -103,7 +103,11 @@ "chat_search": "搜索", "thinking": "思考中", "thinking_step": "思考过程", - "ask_again": "重新生成" + "ask_again": "重新生成", + "today": "今天", + "week": "7天内", + "earlier": "更早以前", + "no_time": "没有时间" }, "ds": { "title": "数据源", diff --git a/frontend/src/views/chat/ChatList.vue b/frontend/src/views/chat/ChatList.vue index 3a9ee8aa..d6d1f714 100644 --- a/frontend/src/views/chat/ChatList.vue +++ b/frontend/src/views/chat/ChatList.vue @@ -2,6 +2,10 @@ import { Delete, EditPen, MoreFilled } from '@element-plus/icons-vue' import { type Chat, chatApi } from '@/api/chat.ts' import { computed } from 'vue' +import dayjs from 'dayjs' +import { getDate } from '@/utils/utils.ts' +import { groupBy } from 'lodash-es' +import { useI18n } from 'vue-i18n' const props = withDefaults( defineProps<{ @@ -16,6 +20,64 @@ const props = withDefaults( } ) +const { t } = useI18n() + +function groupByDate(chat: Chat) { + const todayStart = dayjs(dayjs().format('YYYY-MM-DD') + ' 00:00:00').toDate() + const todayEnd = dayjs(dayjs().format('YYYY-MM-DD') + ' 23:59:59').toDate() + const weekStart = dayjs(dayjs().subtract(7, 'day').format('YYYY-MM-DD') + ' 00:00:00').toDate() + + const time = getDate(chat.create_time) + + if (time) { + if (time >= todayStart && time <= todayEnd) { + return t('qa.today') + } + if (time < todayStart && time >= weekStart) { + return t('qa.week') + } + if (time < weekStart) { + return t('qa.earlier') + } + } + + return t('qa.no_time') +} + +const computedChatGroup = computed(() => { + return groupBy(props.chatList, groupByDate) +}) + +const computedChatList = computed(() => { + const _list = [] + if (computedChatGroup.value[t('qa.today')]) { + _list.push({ + key: t('qa.today'), + list: computedChatGroup.value[t('qa.today')], + }) + } + if (computedChatGroup.value[t('qa.week')]) { + _list.push({ + key: t('qa.week'), + list: computedChatGroup.value[t('qa.week')], + }) + } + if (computedChatGroup.value[t('qa.earlier')]) { + _list.push({ + key: t('qa.earlier'), + list: computedChatGroup.value[t('qa.earlier')], + }) + } + if (computedChatGroup.value[t('qa.no_time')]) { + _list.push({ + key: t('qa.no_time'), + list: computedChatGroup.value[t('qa.no_time')], + }) + } + + return _list +}) + const emits = defineEmits(['chatSelected', 'chatRenamed', 'chatDeleted', 'update:loading']) const _loading = computed({ @@ -106,28 +168,31 @@ function handleCommand(command: string | number | object, chat: Chat) { - - - {{ chat.brief ?? 'Untitled' }} - - handleCommand(cmd, chat)"> - - - - - - Rename - Delete - - - - - - + + {{ group.key }} + + + {{ chat.brief ?? 'Untitled' }} + + handleCommand(cmd, chat)"> + + + + + + Rename + Delete + + + + + + + @@ -144,15 +209,31 @@ function handleCommand(command: string | number | object, chat: Chat) { display: flex; flex-direction: column; - gap: 8px; + gap: 16px; + + .group { + display: flex; + flex-direction: column; + + .group-title { + padding: 0 8px; + color: rgba(100, 106, 115, 1); + line-height: 20px; + font-weight: 500; + font-size: 12px; + + margin-bottom: 4px; + } + } .chat-list-item { width: 100%; - height: 42px; + height: 40px; cursor: pointer; border-radius: 6px; - line-height: 1em; + line-height: 22px; font-size: 14px; + font-weight: 400; display: flex; align-items: center; diff --git a/frontend/src/views/chat/ChatListContainer.vue b/frontend/src/views/chat/ChatListContainer.vue index af3aca6f..edda76cf 100644 --- a/frontend/src/views/chat/ChatListContainer.vue +++ b/frontend/src/views/chat/ChatListContainer.vue @@ -194,6 +194,7 @@ function onChatRenamed(chat: Chat) { name="quick-search" autocomplete="off" :placeholder="t('qa.chat_search')" + clearable />