|
@@ -16,7 +16,13 @@
|
|
|
<span class="dot"></span>
|
|
|
</span>
|
|
|
</div>
|
|
|
- <div v-else class="content">{{ message.content }}</div>
|
|
|
+ <div v-else class="content">{{ message.content }}
|
|
|
+ <span class="loading-indicator" v-if="sendLoading && index === messages.length - 1">
|
|
|
+ <span class="dot"></span>
|
|
|
+ <span class="dot"></span>
|
|
|
+ <span class="dot"></span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
<div class="timestamp ">{{ message.timestamp }}
|
|
|
<span v-if="message.add" style="cursor: pointer;" @click="handleInput">填充</span>
|
|
|
</div>
|
|
@@ -52,7 +58,7 @@
|
|
|
|
|
|
<div class="card-btn">
|
|
|
<el-tooltip content="总结当前页面" placement="top">
|
|
|
- <el-button round @click="handleCardButtonClick" :disabled="!taklToHtml">总结</el-button>
|
|
|
+ <el-button round @click="handleSummary" :disabled="!taklToHtml">总结</el-button>
|
|
|
</el-tooltip>
|
|
|
|
|
|
<el-tooltip content="选择后,在输入框描述填表流程" placement="top">
|
|
@@ -81,18 +87,25 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import {ref, onMounted, nextTick, inject, useTemplateRef} from 'vue'
|
|
|
-import {ElScrollbar, ElAvatar, ElInput, ElButton} from 'element-plus'
|
|
|
+import { ref, onMounted, nextTick, inject, useTemplateRef } from "vue";
|
|
|
+import { ElScrollbar, ElAvatar, ElInput, ElButton } from "element-plus";
|
|
|
import moment from "moment";
|
|
|
-import { buildExcelUnderstandingPrompt ,getFileContent} from '@/utils/ai-service.js'
|
|
|
-import * as XLSX from "xlsx";
|
|
|
-import {ElMessage} from 'element-plus';
|
|
|
-import {useMsg} from '@/entrypoints/sidepanel/hook/useMsg.ts';
|
|
|
+import {
|
|
|
+ buildExcelUnderstandingPrompt,
|
|
|
+ getFileSummaryPrompt,
|
|
|
+ getSummaryPrompt,
|
|
|
+ getFileContent,
|
|
|
+ buildObjPrompt
|
|
|
+} from "@/utils/ai-service.js";
|
|
|
+import { storeToRefs } from "pinia";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+import { useMsg } from "@/entrypoints/sidepanel/hook/useMsg.ts";
|
|
|
import Tools from "@/entrypoints/sidepanel/component/tools.vue";
|
|
|
-import historyComponent from '@/entrypoints/sidepanel/component/historyComponent.vue';
|
|
|
-import {useSummary} from '@/entrypoints/sidepanel/hook/useSummary.ts'
|
|
|
-import {mockData, startMsg, mockData2} from "@/entrypoints/sidepanel/mock"
|
|
|
-import {useAutoResizeTextarea} from '@/entrypoints/sidepanel/hook/useAutoResizeTextarea.ts';
|
|
|
+import historyComponent from "@/entrypoints/sidepanel/component/historyComponent.vue";
|
|
|
+import { mockData, startMsg, mockData2 } from "@/entrypoints/sidepanel/mock";
|
|
|
+import { useAutoResizeTextarea } from "@/entrypoints/sidepanel/hook/useAutoResizeTextarea.ts";
|
|
|
+import { getPageInfo, getXlsxValue, handleInput } from "./utils/index.js";
|
|
|
+import { useMsgStore } from "@/store/modules/msg.ts";
|
|
|
|
|
|
// 滚动条引用
|
|
|
const scrollbar = ref(null);
|
|
@@ -101,28 +114,47 @@ const isShowPage = ref(false);
|
|
|
const tareRef = useTemplateRef("textareaRef");
|
|
|
const drawerRef = useTemplateRef("historyComponentRef");
|
|
|
// 获取父组件提供的 Hook 实例
|
|
|
-const {registerStore, useStore} = inject('indexedDBHook');
|
|
|
+const { registerStore, useStore } = inject("indexedDBHook");
|
|
|
+const { pageInfoList, messages, msgUuid } = storeToRefs(useMsgStore());
|
|
|
const {
|
|
|
- msgUuid,
|
|
|
- messages,
|
|
|
- inputMessage,
|
|
|
- indexTemp,
|
|
|
taklToHtml,
|
|
|
- pageInfo,
|
|
|
sendLoading,
|
|
|
type,
|
|
|
- addMessage,
|
|
|
- sendRequese,
|
|
|
- getPageInfo,
|
|
|
streamRes,
|
|
|
- handleInput,
|
|
|
- getFileValue
|
|
|
-} = useMsg(scrollbar, xlsxData, fetchDataAndProcess);
|
|
|
-const { handleCardButtonClick } = useSummary(addMessage, sendRequese);
|
|
|
+ getFormKeyAndValue,
|
|
|
+ handleSend
|
|
|
+} = useMsg(scrollbar);
|
|
|
+const inputMessage = ref("");
|
|
|
+const pageInfo = ref("");
|
|
|
+
|
|
|
+const addMessage = (msg, raw) => {
|
|
|
+ if (!msg) return;
|
|
|
+ const newMessage = reactive({
|
|
|
+ id: messages.value.length + 1,
|
|
|
+ username: "我",
|
|
|
+ rawContent: raw ?? msg,
|
|
|
+ content: msg,
|
|
|
+ timestamp: moment().format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ isSelf: true,
|
|
|
+ avatar: "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png",
|
|
|
+ addToHistory: !taklToHtml.value
|
|
|
+ });
|
|
|
+ messages.value.push(newMessage);
|
|
|
+ useStore(msgUuid.value).add(newMessage);
|
|
|
+ nextTick(() => {
|
|
|
+ scrollbar.value?.setScrollTop(99999);
|
|
|
+ });
|
|
|
+ return newMessage;
|
|
|
+};
|
|
|
+const handleSummary = async () => {
|
|
|
+ const res = await getPageInfo();
|
|
|
+ addMessage("总结页面", getSummaryPrompt(res.content));
|
|
|
+ handleSend();
|
|
|
+};
|
|
|
|
|
|
function handelIntelligentFillingClick() {
|
|
|
- inputMessage.value = '/智能填表 '
|
|
|
- type.value = '2'
|
|
|
+ inputMessage.value = "/智能填表 ";
|
|
|
+ type.value = "2";
|
|
|
}
|
|
|
|
|
|
function handleCurrentData(e) {
|
|
@@ -134,17 +166,18 @@ function handleCurrentData(e) {
|
|
|
// 添加indexDB Store配置
|
|
|
msgUuid.value = e;
|
|
|
useStore(e).getAll().then((res) => {
|
|
|
- messages.value = res
|
|
|
+ messages.value = res;
|
|
|
nextTick(() => {
|
|
|
- scrollbar.value?.setScrollTop(99999)
|
|
|
- })
|
|
|
- })
|
|
|
+ scrollbar.value?.setScrollTop(99999);
|
|
|
+ });
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
async function readClick() {
|
|
|
isShowPage.value = true;
|
|
|
taklToHtml.value = true;
|
|
|
const tempPageInfo = await getPageInfo();
|
|
|
+ pageInfo.value = tempPageInfo;
|
|
|
pageInfoList.value.push(tempPageInfo);
|
|
|
}
|
|
|
|
|
@@ -154,28 +187,31 @@ function deletePageInfo(i) {
|
|
|
isShowPage.value = false;
|
|
|
taklToHtml.value = false;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
function addNewDialogue() {
|
|
|
messages.value = [];
|
|
|
- msgUuid.value = 'D' + Date.now().toString();
|
|
|
+ msgUuid.value = "D" + Date.now().toString();
|
|
|
registerStore({
|
|
|
name: msgUuid.value,
|
|
|
- keyPath: 'id',
|
|
|
- })
|
|
|
+ keyPath: "id"
|
|
|
+ });
|
|
|
messages.value.push(startMsg);
|
|
|
useStore(msgUuid.value).add(startMsg);
|
|
|
}
|
|
|
|
|
|
async function handleAsk() {
|
|
|
if (sendLoading.value) return;
|
|
|
- addMessage(inputMessage.value.trim(), true);
|
|
|
- inputMessage.value = '';
|
|
|
+ addMessage(inputMessage.value.trim());
|
|
|
+ handleSend(inputMessage.value.trim());
|
|
|
+ inputMessage.value = "";
|
|
|
+ // streamRes(taklToHtml)
|
|
|
}
|
|
|
|
|
|
function handleCapture() {
|
|
|
ElMessage({
|
|
|
- message: '开发中...',
|
|
|
+ message: "开发中...",
|
|
|
grouping: true,
|
|
|
showClose: true
|
|
|
});
|
|
@@ -185,518 +221,110 @@ function hisRecords() {
|
|
|
drawerRef.value.drawer = true;
|
|
|
}
|
|
|
|
|
|
-// let formMap = []
|
|
|
-let formInfo = []
|
|
|
-const flag = ref(false) //true调用算法接口
|
|
|
-
|
|
|
-const handleUpload = (file) => {
|
|
|
- if (type.value === '2') {
|
|
|
+const handleUpload = async (file) => {
|
|
|
+ if (type.value === "2") {
|
|
|
chrome.runtime.sendMessage({
|
|
|
- type: 'FROM_SIDE_PANEL_TO_GET_PAGE_FORM',
|
|
|
+ type: "FROM_SIDE_PANEL_TO_GET_PAGE_FORM"
|
|
|
}, async (response) => {
|
|
|
if (chrome.runtime.lastError) {
|
|
|
console.error("消息发送错误:", chrome.runtime.lastError);
|
|
|
} else {
|
|
|
- addMessage(`已上传文件:${file.name}`, false)
|
|
|
- const fileExtension = file.name.split('.').pop().toLowerCase();
|
|
|
- if (response.status === 'error') return ElMessage({message:response.message,type: 'error', duration: 4 * 1000, grouping: true})
|
|
|
- formInfo = response.data
|
|
|
- if (fileExtension === 'xlsx') {
|
|
|
- const reader = new FileReader();
|
|
|
- reader.readAsArrayBuffer(file);
|
|
|
- reader.onload = async (e) => {
|
|
|
- const data = new Uint8Array(e.target.result);
|
|
|
- const workbook = XLSX.read(data, {
|
|
|
- type: "array",
|
|
|
- cellDates: false,
|
|
|
- cellNF: true,
|
|
|
- cellText: true,
|
|
|
- dateNF: 'yyyy-mm-dd'
|
|
|
- });
|
|
|
-
|
|
|
- // 修复日期处理
|
|
|
- const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
|
|
|
-
|
|
|
- // 转换为JSON数据
|
|
|
- const readData = XLSX.utils.sheet_to_json(firstSheet, {
|
|
|
- header: 1,
|
|
|
- raw: false,
|
|
|
- defval: "",
|
|
|
- dateNF: 'yyyy-mm-dd'
|
|
|
- });
|
|
|
- console.log(readData, 58);
|
|
|
-
|
|
|
- readData[0].forEach((header, i) => {
|
|
|
- // if (!xlsxData.value[header]) xlsxData.value[header] = []
|
|
|
- xlsxData.value[header] = readData[1][i]
|
|
|
- })
|
|
|
- if (type.value === '2') {
|
|
|
- await streamRes(buildExcelUnderstandingPrompt(readData, file?.name, response), false)
|
|
|
- }
|
|
|
- };
|
|
|
+ const fileExtension = file.name.split(".").pop().toLowerCase();
|
|
|
+ if (response.status === "error") return ElMessage({
|
|
|
+ message: response.message,
|
|
|
+ type: "error",
|
|
|
+ duration: 4 * 1000,
|
|
|
+ grouping: true
|
|
|
+ });
|
|
|
+ if (fileExtension === "xlsx") {
|
|
|
+ const readData = await getXlsxValue(file);
|
|
|
+ readData[0].forEach((header, i) => {
|
|
|
+ // if (!xlsxData.value[header]) xlsxData.value[header] = []
|
|
|
+ xlsxData.value[header] = readData[1][i];
|
|
|
+ });
|
|
|
+ addMessage(`已上传文件:${file.name}`, buildExcelUnderstandingPrompt(readData[0], file?.name, response.data));
|
|
|
+ const a = await streamRes();
|
|
|
+ handleInput(xlsxData.value, JSON.parse(a.split("json")[1].split("```")[0]));
|
|
|
} else {
|
|
|
- await getFileValue(file, response.data)
|
|
|
-
|
|
|
- // const keys = Object.keys(res)
|
|
|
- // const values = Object.values(res)
|
|
|
- // readData[0].forEach((header, i) => {
|
|
|
- // if (!xlsxData.value[header]) xlsxData.value[header] = []
|
|
|
- // xlsxData.value[header].push(readData[1][i])
|
|
|
- // })
|
|
|
- // console.log(res);
|
|
|
+ const { data, msg } = await getFileValue(file);
|
|
|
+ const res2 = await getFormKeyAndValue(data, response.data);
|
|
|
+ xlsxData.value = res2.data;
|
|
|
+ msg.rawContent = buildObjPrompt(res2.data, response.data);
|
|
|
+ console.log();
|
|
|
+
|
|
|
+ const a = await streamRes();
|
|
|
+ handleInput(xlsxData.value, JSON.parse(a.split("json")[1].split("```")[0]));
|
|
|
+ console.log(xlsxData.value);
|
|
|
+ console.log(type.value);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
- return true
|
|
|
+ return true;
|
|
|
});
|
|
|
-
|
|
|
}
|
|
|
- if (type.value === '') {
|
|
|
-
|
|
|
- }
|
|
|
-}
|
|
|
-let str = ''
|
|
|
-async function fetchDataAndProcess(input, obj) {
|
|
|
- if (input.startsWith('/智能填表')) {
|
|
|
- input = input.split('/智能填表')[1]
|
|
|
- }
|
|
|
- str = input
|
|
|
- console.log(str);
|
|
|
- const pageInfo = await getPageInfo();
|
|
|
- await new Promise(res => setTimeout(() => {
|
|
|
- res()
|
|
|
- }, 2000))
|
|
|
- // const res = await hepl({
|
|
|
- // input_data: input,
|
|
|
- // body: pageInfo.content.mainContent
|
|
|
- // })
|
|
|
- console.log(pageInfo.title);
|
|
|
-
|
|
|
- const res = await new Promise((resolve, reject) => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve({ data:pageInfo.title === '智能招采' ? mockData[indexTemp.value] :mockData2[indexTemp.value] })
|
|
|
- }, 1000)
|
|
|
- })
|
|
|
- if (!res.data.tag || res.data.tag === 'undefined') {
|
|
|
- ElMessage({ message: '未找到标签,请重试', type: 'error', duration: 4 * 1000, grouping: true })
|
|
|
- obj.content = '未找到标签,请重试'
|
|
|
- type.value = ''
|
|
|
- return
|
|
|
+ if (type.value === "") {
|
|
|
+ const fileVaue = await getFileValue(file);
|
|
|
+ // streamRes()
|
|
|
}
|
|
|
- await handleClick(res.data, obj);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-async function handleClick(res, msgObj) {
|
|
|
- await new Promise(resolve => setTimeout(resolve, 2000))
|
|
|
- msgObj.content = `点击${res.tag}元素`
|
|
|
- chrome.runtime.sendMessage({
|
|
|
- type: 'FROM_SIDE_PANEL_TO_ACTION',
|
|
|
- data: res
|
|
|
- }, async ({ data, status }) => {
|
|
|
- if (chrome.runtime.lastError) {
|
|
|
- console.error("消息发送错误:", chrome.runtime.lastError);
|
|
|
- rej(chrome.runtime.lastError)
|
|
|
- } else {
|
|
|
- if (status === 'error') {
|
|
|
- msgObj.content = data
|
|
|
- type.value = ''
|
|
|
- return
|
|
|
- }
|
|
|
- if (res.next === '是') {
|
|
|
- const arr = str.split(',')
|
|
|
- arr.shift()
|
|
|
- str = arr.join(',')
|
|
|
- indexTemp.value++
|
|
|
- fetchDataAndProcess(str, msgObj)
|
|
|
- } else {
|
|
|
- if (type.value === '2') {
|
|
|
- await new Promise((resolve, reject) => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve()
|
|
|
- }, 2000)
|
|
|
- })
|
|
|
- msgObj.content = `请上传数据`
|
|
|
- ElMessage({ message: '请上传数据', type: 'success', duration: 4 * 1000, grouping: true })
|
|
|
- } else {
|
|
|
- msgObj.content = `执行完毕`
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return true
|
|
|
- });
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-const isHoveringTitle = ref(false)
|
|
|
-
|
|
|
+};
|
|
|
+let str = "";
|
|
|
+
|
|
|
+async function getFileValue(file) {
|
|
|
+ const msg = addMessage(`文件上传中`);
|
|
|
+ sendLoading.value = true;
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.append("file", file);
|
|
|
+ const res = await getFileContent(formData);
|
|
|
+ sendLoading.value = false;
|
|
|
+ msg.content = `已上传文件:${file.name}`;
|
|
|
+ msg.rawContent = res.data;
|
|
|
+ return {
|
|
|
+ data: res.data,
|
|
|
+ msg
|
|
|
+ };
|
|
|
+}
|
|
|
+}
|
|
|
+const isHoveringTitle = ref(false);
|
|
|
// 组件挂载时滚动到底部
|
|
|
onMounted(() => {
|
|
|
useAutoResizeTextarea(tareRef, inputMessage);
|
|
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
- if (message.type === 'TO_SIDE_PANEL_PAGE_INFO') {
|
|
|
- pageInfo.value = message.data
|
|
|
- console.log(pageInfo.value);
|
|
|
-
|
|
|
+ if (message.type === "TO_SIDE_PANEL_PAGE_INFO") {
|
|
|
+ pageInfo.value = message.data;
|
|
|
// 转发到 content.js
|
|
|
chrome.tabs.sendMessage(sender.tab.id, {
|
|
|
- type: 'TO_CONTENT_SCRIPT',
|
|
|
+ type: "TO_CONTENT_SCRIPT",
|
|
|
data: message.data
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
- if (message.type === 'TO_SIDE_PANEL_PAGE_CHANGE') {
|
|
|
- pageInfo.value = message.data
|
|
|
+ if (message.type === "TO_SIDE_PANEL_PAGE_CHANGE") {
|
|
|
+ pageInfo.value = message.data;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 添加标题悬停事件监听
|
|
|
nextTick(() => {
|
|
|
- const titleWrapper = document.querySelector('.title-wrapper')
|
|
|
+ const titleWrapper = document.querySelector(".title-wrapper");
|
|
|
if (titleWrapper) {
|
|
|
- titleWrapper.addEventListener('mouseenter', () => {
|
|
|
- isHoveringTitle.value = true
|
|
|
- })
|
|
|
- titleWrapper.addEventListener('mouseleave', () => {
|
|
|
- isHoveringTitle.value = false
|
|
|
- })
|
|
|
+ titleWrapper.addEventListener("mouseenter", () => {
|
|
|
+ isHoveringTitle.value = true;
|
|
|
+ });
|
|
|
+ titleWrapper.addEventListener("mouseleave", () => {
|
|
|
+ isHoveringTitle.value = false;
|
|
|
+ });
|
|
|
}
|
|
|
- scrollbar.value?.setScrollTop(99999)
|
|
|
- })
|
|
|
-
|
|
|
+ scrollbar.value?.setScrollTop(99999);
|
|
|
+ });
|
|
|
// 添加indexDB Store配置
|
|
|
- msgUuid.value = 'D' + Date.now().toString();
|
|
|
+ msgUuid.value = "D" + Date.now().toString();
|
|
|
registerStore({
|
|
|
name: msgUuid.value,
|
|
|
- keyPath: 'id',
|
|
|
- })
|
|
|
+ keyPath: "id"
|
|
|
+ });
|
|
|
messages.value.push(startMsg);
|
|
|
useStore(msgUuid.value).add(startMsg);
|
|
|
-})
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.els {
|
|
|
- white-space: nowrap; /* 强制文本不换行 */
|
|
|
- overflow: hidden; /* 隐藏溢出内容 */
|
|
|
- text-overflow: ellipsis; /* 显示省略号 */
|
|
|
-}
|
|
|
-
|
|
|
-.chat-container {
|
|
|
- border-radius: 14px;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- border: 1px solid #dcdfe6;
|
|
|
- background-color: #F0F0F0;
|
|
|
- //background-color: #ffffff;
|
|
|
-}
|
|
|
-
|
|
|
-.message-list {
|
|
|
- flex: 1;
|
|
|
- padding: 16px;
|
|
|
- overflow: auto;
|
|
|
-}
|
|
|
-
|
|
|
-.messages {
|
|
|
- min-height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
-}
|
|
|
-
|
|
|
-.message-item {
|
|
|
- display: flex;
|
|
|
- margin-bottom: 20px;
|
|
|
- gap: 12px;
|
|
|
- color: #333;
|
|
|
- align-items: flex-start;
|
|
|
- animation: fadeIn 0.3s ease-in-out;
|
|
|
-}
|
|
|
-
|
|
|
-@keyframes fadeIn {
|
|
|
- from {
|
|
|
- opacity: 0;
|
|
|
- transform: translateY(10px);
|
|
|
- }
|
|
|
-
|
|
|
- to {
|
|
|
- opacity: 1;
|
|
|
- transform: translateY(0);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.message-item.self {
|
|
|
- flex-direction: row-reverse;
|
|
|
-}
|
|
|
-
|
|
|
-.message-content {
|
|
|
- max-width: 80%;
|
|
|
-}
|
|
|
-
|
|
|
-.username {
|
|
|
- font-size: 14px;
|
|
|
- color: #606266;
|
|
|
- margin-bottom: 4px;
|
|
|
-}
|
|
|
-
|
|
|
-.content {
|
|
|
- padding: 12px;
|
|
|
- min-height: 40px;
|
|
|
- background-color: #F0F4F8;
|
|
|
- border-radius: 12px;
|
|
|
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
|
- word-break: break-all;
|
|
|
- line-height: 1.5;
|
|
|
- font-size: 14px;
|
|
|
-}
|
|
|
-
|
|
|
-.content :deep(pre) {
|
|
|
- margin: 10px 0;
|
|
|
- border-radius: 8px;
|
|
|
-}
|
|
|
-
|
|
|
-.content :deep(code) {
|
|
|
- font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
|
|
|
-}
|
|
|
-
|
|
|
-.content :deep(p) {
|
|
|
- margin: 8px 0;
|
|
|
-}
|
|
|
-
|
|
|
-.content :deep(ul),
|
|
|
-.content :deep(ol) {
|
|
|
- padding-left: 20px;
|
|
|
- margin: 8px 0;
|
|
|
-}
|
|
|
-
|
|
|
-.content :deep(blockquote) {
|
|
|
- border-left: 4px solid #ddd;
|
|
|
- padding-left: 10px;
|
|
|
- color: #666;
|
|
|
- margin: 8px 0;
|
|
|
-}
|
|
|
-
|
|
|
-.self .content {
|
|
|
- background: #409eff;
|
|
|
- color: white;
|
|
|
- border-bottom-right-radius: 4px;
|
|
|
-}
|
|
|
-
|
|
|
-.other .content {
|
|
|
- border-bottom-left-radius: 4px;
|
|
|
-}
|
|
|
-
|
|
|
-.timestamp {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- font-size: 12px;
|
|
|
- color: #909399;
|
|
|
- margin-top: 6px;
|
|
|
-}
|
|
|
-
|
|
|
-.timestamp span {
|
|
|
- transition: color 0.2s;
|
|
|
-}
|
|
|
-
|
|
|
-.timestamp span:hover {
|
|
|
- color: #409eff;
|
|
|
-}
|
|
|
-
|
|
|
-.info-card {
|
|
|
- margin: 10px;
|
|
|
-}
|
|
|
-
|
|
|
-.card-icon {
|
|
|
- color: #409eff;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-@keyframes scrollTitle {
|
|
|
- 0% {
|
|
|
- transform: translateX(0);
|
|
|
- }
|
|
|
-
|
|
|
- 100% {
|
|
|
- transform: translateX(-100%);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.upload :deep(.el-icon) {
|
|
|
- transition: color 0.3s;
|
|
|
-}
|
|
|
-
|
|
|
-.can-hover :deep(.el-icon:hover) {
|
|
|
- color: #409eff !important;
|
|
|
-}
|
|
|
-
|
|
|
-.el-check-tag {
|
|
|
- margin-right: 8px;
|
|
|
- transition: all 0.3s;
|
|
|
-}
|
|
|
-
|
|
|
-.el-check-tag:hover {
|
|
|
- transform: scale(1.05);
|
|
|
-}
|
|
|
-
|
|
|
-/* 加载中的消息样式 */
|
|
|
-.loading-content {
|
|
|
- min-height: 40px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: flex-start;
|
|
|
-}
|
|
|
-
|
|
|
-.loading-indicator {
|
|
|
- display: inline-block;
|
|
|
- align-items: center;
|
|
|
- gap: 4px;
|
|
|
- margin-left: 2px;
|
|
|
-
|
|
|
- .dot {
|
|
|
- width: 4px;
|
|
|
- height: 4px;
|
|
|
- margin: 0 2px;
|
|
|
- background-color: gray;
|
|
|
- border-radius: 50%;
|
|
|
- display: inline-block;
|
|
|
- animation: pulse 1.5s infinite ease-in-out;
|
|
|
- }
|
|
|
-
|
|
|
- .dot:nth-child(2) {
|
|
|
- animation-delay: 0.3s;
|
|
|
- }
|
|
|
-
|
|
|
- .dot:nth-child(3) {
|
|
|
- animation-delay: 0.6s;
|
|
|
- }
|
|
|
-
|
|
|
- @keyframes pulse {
|
|
|
-
|
|
|
- 0%,
|
|
|
- 100% {
|
|
|
- transform: scale(0.8);
|
|
|
- opacity: 0.6;
|
|
|
- }
|
|
|
-
|
|
|
- 50% {
|
|
|
- transform: scale(1.2);
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-.input-area {
|
|
|
- padding: 8px 10px;
|
|
|
- color: black;
|
|
|
- background-color: #fff;
|
|
|
- border: 1px solid rgba(102, 102, 102, 0.3);
|
|
|
- border-radius: 16px;
|
|
|
- margin: 0 12px 12px;
|
|
|
-
|
|
|
- .card_list {
|
|
|
- display: flex;
|
|
|
- flex-wrap: nowrap;
|
|
|
- overflow-x: auto;
|
|
|
- padding: 4px 0;
|
|
|
-
|
|
|
- .card_width {
|
|
|
- width: 124px !important;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .card-content {
|
|
|
- flex-shrink: 0;
|
|
|
- width: fit-content;
|
|
|
- max-width: 260px;
|
|
|
- height: 50px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 6px;
|
|
|
- padding: 8px 6px;
|
|
|
- margin: 0 8px 6px 0;
|
|
|
- background: #fff;
|
|
|
- border-radius: 10px;
|
|
|
- border: 1px solid rgba(0, 0, 0, 0.2);
|
|
|
- font-size: 14px;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- .title-wrapper {
|
|
|
- display: flex;
|
|
|
- //width: fit-content;
|
|
|
- width: calc(100% - 30px);
|
|
|
- flex-direction: column;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- .title-scroller {
|
|
|
- display: inline-block;
|
|
|
- white-space: nowrap;
|
|
|
- color: #000000;
|
|
|
- font-size: 14px;
|
|
|
- font-weight: 900;
|
|
|
- }
|
|
|
-
|
|
|
- .url-scroller {
|
|
|
- font-size: 12px;
|
|
|
- color: #909399;
|
|
|
- }
|
|
|
-
|
|
|
- .title-scroller.scroll {
|
|
|
- animation: scrollTitle 10s linear infinite;
|
|
|
- }
|
|
|
-
|
|
|
- .closeIcon {
|
|
|
- display: none;
|
|
|
- position: absolute;
|
|
|
- right: -5px;
|
|
|
- top: -5px;
|
|
|
- background-color: #ffffff;
|
|
|
- border-radius: 50%;
|
|
|
- z-index: 1;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- .card-content:hover {
|
|
|
- .closeIcon {
|
|
|
- display: block;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .card-btn {
|
|
|
- padding: 0 0 4px;
|
|
|
-
|
|
|
- .op {
|
|
|
- margin-right: 3px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .chat_area_op {
|
|
|
- margin-top: 3px;
|
|
|
- display: flex;
|
|
|
- justify-content: end;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.input-area:hover {
|
|
|
- border-color: rgba(102, 102, 102, 0.4);
|
|
|
-}
|
|
|
-
|
|
|
-.input-area :deep(.el-textarea__inner) {
|
|
|
- border-radius: 8px;
|
|
|
- transition: border-color 0.3s;
|
|
|
- resize: none;
|
|
|
- box-shadow: none;
|
|
|
-}
|
|
|
-
|
|
|
-.input-area :deep(.el-textarea__inner) {
|
|
|
- padding: 0 4px;
|
|
|
- margin-top: 3px;
|
|
|
-}
|
|
|
-
|
|
|
-.input-area :deep(.el-textarea__inner:focus) {
|
|
|
- border-color: #409eff;
|
|
|
- box-shadow: none;
|
|
|
-}
|
|
|
+@import '@/entrypoints/sidepanel/css/chat.scss';
|
|
|
</style>
|