会话管理增强

0 阅读1分钟

加 3 个能力:

  • 删除会话
  • 重命名会话
  • 删除会话时同步清掉后端记忆

继续,下一步做一个很实用的功能:


1)server/memory_store.py

新增:

def delete_session_memories(session_id: str):
    if not session_id:
        return

    data = _load()
    if session_id in data:
        del data[session_id]
        _save(data)

2)server/app.py

先补充 import

from memory_store import get_session_memories, add_session_memories, delete_session_memories

新增删除会话记忆接口

@app.delete("/api/session/{session_id}")
def delete_session(session_id: str):
    if not session_id:
        raise HTTPException(status_code=400, detail="session_id不能为空")

    delete_session_memories(session_id)
    return {"ok": True}

3)web/src/App.vue

先改 import

import { computed, ref, watch, onMounted, nextTick } from 'vue'

新增状态

const editingSessionId = ref('')
const editingTitle = ref('')

新增方法

放在 handleSwitchSession 下面:

const handleStartRename = item => {
  editingSessionId.value = item.id
  editingTitle.value = item.title
}

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

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

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

const handleDeleteSession = async id => {
  if (sessions.value.length === 1) {
    window.alert('至少保留一个会话')
    return
  }

  const ok = window.confirm('确认删除这个会话吗?删除后记忆也会一起清除。')
  if (!ok) return

  try {
    await axios.delete(`http://127.0.0.1:8000/api/session/${id}`)
  } catch (error) {
    console.error(error)
  }

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

  if (currentSessionId.value === id) {
    currentSessionId.value = nextSessions[0]?.id || ''
    await nextTick()
    fetchMemories()
  }
}

更新左侧会话列表模板

<div
  v-for="item in sessions"
  :key="item.id"
  :class="['session-item', currentSessionId === item.id ? 'active' : '']"
  @click="handleSwitchSession(item.id)"
>
  <div class="session-top">
    <template v-if="editingSessionId === item.id">
      <input
        v-model="editingTitle"
        class="session-input"
        @click.stop
        @keydown.enter="handleRenameSession(item.id)"
        @blur="handleRenameSession(item.id)"
      />
    </template>
    <template v-else>
      <div class="session-title">{{ item.title }}</div>
    </template>

    <div class="session-actions">
      <span class="action-btn" @click.stop="handleStartRename(item)">改名</span>
      <span class="action-btn delete" @click.stop="handleDeleteSession(item.id)">删除</span>
    </div>
  </div>
  <div class="session-time">{{ formatTime(item.updatedAt) }}</div>
</div>

新增样式

追加到 style 里:

.session-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.session-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.action-btn {
  font-size: 12px;
  color: #6b7280;
  cursor: pointer;
}

.action-btn:hover {
  color: #111827;
}

.action-btn.delete:hover {
  color: #dc2626;
}

.session-input {
  width: 100%;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  padding: 6px 8px;
  font-size: 14px;
  outline: none;
  box-sizing: border-box;
}

4)验证

删除会话

  • 左侧点“删除”
  • 当前会话消失
  • 切到下一个会话
  • 对应记忆也被后端清掉

image.png

image.png

image.png

重命名

  • 左侧点“改名”
  • 输入新标题
  • 回车或失焦保存

image.png

nice !