实现会话置顶和最近会话排序

0 阅读2分钟

新增功能:

  • 重要会话可以置顶
  • 普通会话按最近活跃时间自动排序
  • 新消息后当前会话自动排到前面
  • 置顶会话永远优先显示

1) web/src/utils/session.js

export function createSession(title = '新对话') {
  return {
    id: crypto.randomUUID(),
    title,
    pinned: false,
    createdAt: Date.now(),
    updatedAt: Date.now(),
    messages: [
      {
        role: 'system',
        content: '你是一个温柔、聪明、会长期陪伴用户的AI伙伴。',
      },
      {
        role: 'assistant',
        content: '你好,我已经准备好了。你今天想聊什么?',
      },
    ],
  }
}

新增一个排序方法

export function sortSessions(list = []) {
  return [...list].sort((a, b) => {
    const aPinned = a.pinned ? 1 : 0
    const bPinned = b.pinned ? 1 : 0

    if (aPinned !== bPinned) {
      return bPinned - aPinned
    }

    return (b.updatedAt || 0) - (a.updatedAt || 0)
  })
}

loadSessions

    const normalized = sessions.map(item => ({
      pinned: false,
      ...item,
    }))
    return sortSessions(normalized)

2) web/src/App.vue

import

import { createSession, loadSessions, saveSessions, sortSessions } from './utils/session'

新增一个统一排序方法

const sortAllSessions = () => {
  sessions.value = sortSessions(sessions.value)
}

updateCurrentSession

const updateCurrentSession = updater => {
  sessions.value = sortSessions(
    sessions.value.map(item => {
      if (item.id !== currentSessionId.value) return item
      return updater(item)
    })
  )
}

handleCreateSession

const handleCreateSession = () => {
  const session = createSession(`新对话 ${sessions.value.length + 1}`)
  sessions.value = sortSessions([session, ...sessions.value])
  currentSessionId.value = session.id
}

handleRenameSession

const handleRenameSession = id => {
  const title = editingTitle.value.trim()
  if (!title) {
    editingSessionId.value = ''
    editingTitle.value = ''
    return
  }

  sessions.value = sortSessions(
    sessions.value.map(item =>
      item.id === id
        ? {
            ...item,
            title,
            updatedAt: Date.now(),
          }
        : item
    )
  )

  editingSessionId.value = ''
  editingTitle.value = ''
}

新增置顶方法

const handleTogglePinSession = id => {
  sessions.value = sortSessions(
    sessions.value.map(item =>
      item.id === id
        ? {
            ...item,
            pinned: !item.pinned,
          }
        : item
    )
  )
}

handleDeleteSession

  const nextSessions = sortSessions(sessions.value.filter(item => item.id !== id))

3)改模板

会话操作区

<div class="session-actions">
  <span
    class="action-btn"
    @click.stop="handleTogglePinSession(item.id)"
  >
    {{ item.pinned ? '取消置顶' : '置顶' }}
  </span>
  <span class="action-btn" @click.stop="handleStartRename(item)">改名</span>
  <span class="action-btn delete" @click.stop="handleDeleteSession(item.id)">删除</span>
</div>

会话标题区域

<template v-else>
  <div class="session-title-row">
    <div class="session-title">{{ item.title }}</div>
    <span v-if="item.pinned" class="pin-badge">置顶</span>
  </div>
</template>

4)补充样式

.session-title-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.pin-badge {
  flex-shrink: 0;
  font-size: 10px;
  line-height: 1;
  padding: 4px 6px;
  border-radius: 999px;
  background: #dbeafe;
  color: #1d4ed8;
}

.session-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

5)验证

最近会话排序

  1. 建 3 个会话
  2. 在第 3 个会话里发一条新消息
  3. 它应该自动排到普通会话最前面

置顶

  1. 对某个旧会话点“置顶”
  2. 它会立刻出现在最上面
  3. 即使别的会话有新消息,置顶会话仍优先

取消置顶

  1. 再点一次“取消置顶”
  2. 它会回到按 updatedAt 排序的位置

image.png

image.png

取消置顶

image.png


6)价值

现在会话系统已经有:

  • 新建
  • 删除
  • 改名
  • 搜索
  • 导出
  • 置顶
  • 最近活跃排序