From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/ai/chat/index/components/message/MessageWebSearch.vue | 190 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 190 insertions(+), 0 deletions(-)
diff --git a/src/views/ai/chat/index/components/message/MessageWebSearch.vue b/src/views/ai/chat/index/components/message/MessageWebSearch.vue
new file mode 100644
index 0000000..f77e1ca
--- /dev/null
+++ b/src/views/ai/chat/index/components/message/MessageWebSearch.vue
@@ -0,0 +1,190 @@
+<!-- 鑱旂綉鎼滅储缁撴灉缁勪欢 -->
+<template>
+ <!-- 鑱旂綉鎼滅储缁撴灉鍒楄〃 -->
+ <div
+ v-if="webSearchPages && webSearchPages.length > 0"
+ class="mt-10px p-10px rounded-8px bg-[#f5f5f5]"
+ >
+ <!-- 鏍囬鏍忥細鍙偣鍑诲睍寮�/鏀惰捣 -->
+ <div
+ class="text-14px text-[#666] mb-8px flex items-center justify-between cursor-pointer hover:text-[#409eff]"
+ @click="toggleExpanded"
+ >
+ <div class="flex items-center">
+ <Icon icon="ep:search" class="mr-5px" />
+ 鑱旂綉鎼滅储缁撴灉 ({{ webSearchPages.length }} 鏉�)
+ </div>
+ <Icon
+ :icon="isExpanded ? 'ep:arrow-up' : 'ep:arrow-down'"
+ class="text-12px transition-transform duration-200"
+ />
+ </div>
+
+ <!-- 鍙睍寮�鐨勬悳绱㈢粨鏋滃垪琛� -->
+ <div v-show="isExpanded" class="flex flex-col gap-8px transition-all duration-200 ease-in-out">
+ <div
+ v-for="(result, index) in webSearchPages"
+ :key="index"
+ class="p-10px bg-white rounded-6px cursor-pointer transition-all hover:bg-[#e6f4ff]"
+ @click="handleClick(result)"
+ >
+ <div class="flex items-start gap-8px">
+ <!-- 缃戠珯鍥炬爣 -->
+ <div class="flex-shrink-0 w-16px h-16px mt-2px">
+ <img
+ v-if="result.icon"
+ :src="result.icon"
+ :alt="result.name"
+ class="w-full h-full object-contain rounded-2px"
+ @error="handleImageError"
+ />
+ <Icon v-else icon="ep:link" class="w-full h-full text-[#666]" />
+ </div>
+
+ <!-- 鍐呭鍖哄煙 -->
+ <div class="flex-1 min-w-0">
+ <!-- 鏍囬鍜屾潵婧� -->
+ <div class="flex items-center gap-4px mb-4px">
+ <span class="text-12px text-[#999] truncate">{{ result.name }}</span>
+ </div>
+
+ <!-- 涓绘爣棰� -->
+ <div class="text-14px text-[#1a73e8] font-medium mb-4px line-clamp-2 leading-[1.4]">
+ {{ result.title }}
+ </div>
+
+ <!-- 鎻忚堪 -->
+ <div class="text-13px text-[#666] line-clamp-2 leading-[1.4] mb-4px">
+ {{ result.snippet }}
+ </div>
+
+ <!-- URL -->
+ <div class="text-12px text-[#006621] truncate">
+ {{ result.url }}
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鑱旂綉鎼滅储璇︽儏寮圭獥 -->
+ <el-popover
+ v-model:visible="dialogVisible"
+ :width="600"
+ trigger="click"
+ placement="top-start"
+ :offset="55"
+ popper-class="web-search-popover"
+ >
+ <template #reference>
+ <div ref="resultRef"></div>
+ </template>
+ <template #default>
+ <div v-if="selectedResult">
+ <!-- 鏍囬鍖哄煙 -->
+ <div class="flex items-start gap-8px mb-12px">
+ <div class="flex-shrink-0 w-20px h-20px mt-2px">
+ <img
+ v-if="selectedResult.icon"
+ :src="selectedResult.icon"
+ :alt="selectedResult.name"
+ class="w-full h-full object-contain rounded-2px"
+ @error="handleImageError"
+ />
+ <Icon v-else icon="ep:link" class="w-full h-full text-[#666]" />
+ </div>
+ <div class="flex-1 min-w-0">
+ <div class="text-16px font-bold text-[#333] mb-4px line-clamp-2">
+ {{ selectedResult.title }}
+ </div>
+ <div class="text-12px text-[#999] mb-4px">{{ selectedResult.name }}</div>
+ <div class="text-12px text-[#006621] break-all">{{ selectedResult.url }}</div>
+ </div>
+ </div>
+
+ <!-- 鍐呭鍖哄煙 -->
+ <div class="max-h-[60vh] overflow-y-auto">
+ <!-- 绠�鐭弿杩� -->
+ <div class="mb-12px">
+ <div class="text-14px font-medium text-[#333] mb-6px">绠�鐭弿杩�</div>
+ <div class="text-14px leading-[1.6] text-[#666] bg-[#f8f9fa] p-10px rounded-6px">
+ {{ selectedResult.snippet }}
+ </div>
+ </div>
+
+ <!-- 鍐呭鎽樿 -->
+ <div v-if="selectedResult.summary">
+ <div class="text-14px font-medium text-[#333] mb-6px">鍐呭鎽樿</div>
+ <div
+ class="text-14px leading-[1.6] text-[#333] bg-[#f8f9fa] p-10px rounded-6px whitespace-pre-wrap"
+ >
+ {{ selectedResult.summary }}
+ </div>
+ </div>
+ </div>
+
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <div class="flex justify-end gap-8px mt-12px pt-12px border-t border-[#eee]">
+ <el-button size="small" @click="dialogVisible = false">鍏抽棴</el-button>
+ <el-button type="primary" size="small" @click="openUrl(selectedResult.url)">
+ 璁块棶鍘熸枃
+ </el-button>
+ </div>
+ </div>
+ </template>
+ </el-popover>
+</template>
+
+<script setup lang="ts">
+defineProps<{
+ webSearchPages: {
+ name: string // 鍚嶇О
+ icon: string // 鍥炬爣
+ title: string // 鏍囬
+ url: string // URL
+ snippet: string // 鍐呭鐨勭畝鐭弿杩�
+ summary: string // 鍐呭鐨勬枃鏈憳瑕�
+ }[]
+}>()
+
+const isExpanded = ref(false) // 鏄惁灞曞紑鎼滅储缁撴灉
+const selectedResult = ref<{
+ name: string
+ icon: string
+ title: string
+ url: string
+ snippet: string
+ summary: string
+} | null>(null) // 閫変腑鐨勬悳绱㈢粨鏋�
+const dialogVisible = ref(false) // 璇︽儏寮圭獥
+const resultRef = ref<HTMLElement>() // 璇︽儏寮圭獥 Ref
+
+/** 鍒囨崲灞曞紑/鏀惰捣鐘舵�� */
+const toggleExpanded = () => {
+ isExpanded.value = !isExpanded.value
+}
+
+/** 鐐瑰嚮鎼滅储缁撴灉澶勭悊 */
+const handleClick = (result: any) => {
+ selectedResult.value = result
+ dialogVisible.value = true
+}
+
+/** 澶勭悊鍥剧墖鍔犺浇閿欒 */
+const handleImageError = (event: Event) => {
+ const img = event.target as HTMLImageElement
+ img.style.display = 'none'
+}
+
+/** 鎵撳紑URL */
+const openUrl = (url: string) => {
+ window.open(url, '_blank')
+}
+</script>
+
+<style scoped>
+.web-search-popover {
+ max-width: 600px;
+}
+</style>
--
Gitblit v1.8.0