dongyukun
21 小时以前 e295922209fb87c6dcd68ea1560fd16c3e6d808c
src/views/ai/dashboard/components/conversation/CommonConversationList.vue
@@ -1,8 +1,8 @@
<!--  AI 对话  -->
<template>
  <el-aside width="260px" class="conversation-container h-100%">
  <el-aside width="280px" class="conversation-container h-100%">
    <!-- 左顶部:对话 -->
    <div class="h-100%">
    <div class="h-80%">
      <div class="conversation-title">
        <img
          src="@/assets/ai/zhuanlu/conversation_big.png"
@@ -12,7 +12,7 @@
        对话列表
      </div>
<!--      <hr class="line"/>-->
      <el-button class="w-1/1 btn-new-conversation" type="primary" @click="createConversation">
      <el-button class="w-1/1 btn-new-conversation" type="primary" @click="createNewConversation">
        <img
          src="@/assets/ai/zhuanlu/conversation_big.png"
          class="mr-8px w-[1.5em] h-[1.5em]"
@@ -82,8 +82,6 @@
            </div>
          </div>
        </div>
        <!-- 底部占位  -->
        <div class="h-160px w-100%"></div>
      </div>
    </div>
@@ -102,12 +100,13 @@
import { ChatConversationApi, ChatConversationVO } from '@/api/ai/chat/conversation'
import { Bottom, Top } from '@element-plus/icons-vue'
import roleAvatarDefaultImg from '@/assets/ai/zhuanlu/assistant.png'
import {ChatMessageVO} from "@/api/ai/chat/message";
import {formatToDate, formatToDateTime} from "@/utils/dateUtil";
const message = useMessage() // 消息弹窗
// 定义属性
const searchName = ref<string>('') // 对话搜索
const modelName = ref<string>('common') // 对话搜索
const activeConversationId = ref<number | null>(null) // 选中的对话,默认为 null
const hoverConversationId = ref<number | null>(null) // 悬浮上去的对话
const conversationList = ref([] as ChatConversationVO[]) // 对话列表
@@ -120,6 +119,17 @@
  activeId: {
    type: String || null,
    required: true
  },
  modelName: {
    type: String || null,
    required: true
  },
  quickAccess: {
    type: Boolean || null,
    required: true
  },
  defaultMessage: {
    type: Object as PropType<ChatMessageVO>
  }
})
@@ -169,10 +179,7 @@
    }, 50)
    // 1.1 获取 对话数据
    conversationList.value = await ChatConversationApi.getChatConversationEnergyList(modelName.value)
    if(conversationList.value.length == 0) {
      await createConversation()
    }
    conversationList.value = await ChatConversationApi.getChatConversationEnergyList(props.modelName)
    // 1.2 排序
    conversationList.value.sort((a, b) => {
      return b.createTime - a.createTime
@@ -184,7 +191,7 @@
      return
    }
    // 2. 对话根据时间分组(置顶、今天、一天前、三天前、七天前、30 天前)
    // 2. 对话根据时间分组(置顶、今天、昨天、三天前、七天前、30 天前)
    conversationMap.value = await getConversationGroupByCreateTime(conversationList.value)
  } finally {
    // 清理定时器
@@ -203,7 +210,7 @@
  const groupMap = {
    置顶: [],
    今天: [],
    一天前: [],
    昨天: [],
    三天前: [],
    七天前: [],
    三十天前: []
@@ -212,9 +219,11 @@
  const now = Date.now()
  // 定义时间间隔常量(单位:毫秒)
  const oneDay = 24 * 60 * 60 * 1000
  const threeDays = 3 * oneDay
  const sevenDays = 7 * oneDay
  const thirtyDays = 30 * oneDay
  //今天
  const today = formatToDate(new Date())
  const yesterday = formatToDate(new Date().setDate(new Date().getDate() - 1))
  for (const conversation of list) {
    // 置顶
    if (conversation.pinned) {
@@ -223,11 +232,13 @@
    }
    // 计算时间差(单位:毫秒)
    const diff = now - conversation.createTime
    let conversationDate = formatToDate(conversation.createTime)
    let titleDate = conversation.title.split(' ')[0]
    // 根据时间间隔判断
    if (diff < oneDay) {
    if (titleDate == today) {
      groupMap['今天'].push(conversation)
    } else if (diff < threeDays) {
      groupMap['一天前'].push(conversation)
    } else if (titleDate == yesterday) {
      groupMap['昨天'].push(conversation)
    } else if (diff < sevenDays) {
      groupMap['三天前'].push(conversation)
    } else if (diff < thirtyDays) {
@@ -240,17 +251,22 @@
}
/** 新建对话 */
const createConversation = async () => {
const createNewConversation = async () => {
  await createConversation(null)
}
/** 新建对话 */
const createConversation = async (title: String) => {
  // 1. 新建对话
  const conversationId = await ChatConversationApi.createChatConversationEnergy(
    {modelName: modelName.value} as unknown as ChatConversationVO
    {modelName: props.modelName, title: title} as unknown as ChatConversationVO
  )
  // 2. 获取对话内容
  await getChatConversationList()
  // 3. 选中对话
  await handleConversationClick(conversationId)
  // 4. 回调
  emits('onConversationCreate')
  // // 4. 回调
  // emits('onConversationCreate')
}
/** 修改对话的标题 */
@@ -344,15 +360,28 @@
onMounted(async () => {
  // 获取 对话列表
  await getChatConversationList()
  // 默认选中
  if (props.activeId) {
    activeConversationId.value = props.activeId
  } else {
    // 首次默认选中第一个
  if(!props.quickAccess) {
    // 默认选中
    if (props.activeId) {
      activeConversationId.value = props.activeId
    } else {
      // 首次默认选中第一个
      if (conversationList.value.length) {
        activeConversationId.value = conversationList.value[0].id
        // 回调 onConversationClick
        await emits('onConversationClick', conversationList.value[0])
      }
    }
  } else if(props.defaultMessage) {
    let tempTitle = formatToDateTime(new Date(props.defaultMessage.createTime))
    if (conversationList.value.length) {
      activeConversationId.value = conversationList.value[0].id
      // 回调 onConversationClick
      await emits('onConversationClick', conversationList.value[0])
      conversationList.value.forEach((item) => {
        if(item.title === tempTitle) {
          activeConversationId.value = item.id
          // 回调 onConversationClick
          emits('onConversationClick', item)
        }
      })
    }
  }
})
@@ -395,16 +424,30 @@
  }
  .conversation-list {
    overflow: auto;
    overflow-y: auto;
    height: 100%;
    margin-top: 10px;
    /* Firefox */
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
    /* WebKit */
    &::-webkit-scrollbar {
      width: 6px;
      background: transparent;
    }
    &::-webkit-scrollbar-thumb {
      border-radius: 4px;
      background: rgba(0, 0, 0, 0.15);
      transition: background 0.3s;
      &:hover { background: rgba(0, 0, 0, 0.25); }
    }
    .classify-title {
      padding-top: 10px;
      b {
        color: white;
      }
    }
    .conversation-item {
      margin-top: 5px;
    }
@@ -443,10 +486,9 @@
      }
      .title {
        padding: 2px 10px;
        padding: 2px 5px;
        max-width: 220px;
        font-size: 14px;
        font-weight: 400;
        font-size: 13px;
        color: rgba(0, 0, 0, 0.77);
        overflow: hidden;
        white-space: nowrap;
@@ -478,17 +520,19 @@
    }
  }
  // 角色仓库、清空未设置对话
  // 清空未设置对话
  .tool-box {
    bottom: 0;
    display: flex;
    padding: 0 20px;
    width: 90%;
    margin-left: 5%;
    background-color: rgba(69,133,255,0.2);
    box-shadow: 0 0 1px 1px rgba(69,133,255,0.4);
    line-height: 35px;
    justify-content: space-between;
    align-items: center;
    color: var(--el-text-color);
    border-radius: 2px;
    div {
      display: flex;
      margin-left: 20%;