diff --git a/package.json b/package.json index 4dd44da..96989a6 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,12 @@ "echarts": "^5.4.3", "highlight.js": "^11.8.0", "lodash-es": "^4.17.21", + "mammoth": "^1.6.0", "markdown-it": "^13.0.1", "markdown-it-link-attributes": "^4.0.1", "md5": "^2.3.0", "mitt": "^3.0.1", + "pdfjs-dist": "2.6.347", "pinia": "^2.1.3", "qrcode.vue": "^3.4.1", "resize-observer-polyfill": "^1.5.1", diff --git a/src/assets/css/base.css b/src/assets/css/base.css index 72abe2b..229d55d 100644 --- a/src/assets/css/base.css +++ b/src/assets/css/base.css @@ -57,9 +57,11 @@ margin: 0; font-weight: normal; } - +html{ + height: 100%; +} body { - height: 100vh; + height: 100%; /* min-height: 100vh; */ color: var(--color-text); background: var(--color-background); diff --git a/src/assets/images/cultivate_01.png b/src/assets/images/cultivate_01.png new file mode 100644 index 0000000..5c49b58 Binary files /dev/null and b/src/assets/images/cultivate_01.png differ diff --git a/src/icons/svg/上下滑动.svg b/src/icons/svg/上下滑动.svg new file mode 100644 index 0000000..a5f6321 --- /dev/null +++ b/src/icons/svg/上下滑动.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/删除文件夹.svg b/src/icons/svg/删除文件夹.svg new file mode 100644 index 0000000..ca53626 --- /dev/null +++ b/src/icons/svg/删除文件夹.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/文件.svg b/src/icons/svg/文件.svg new file mode 100644 index 0000000..dbef125 --- /dev/null +++ b/src/icons/svg/文件.svg @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/io/request.js b/src/io/request.js index d6f4d1e..ddda6e7 100644 --- a/src/io/request.js +++ b/src/io/request.js @@ -61,10 +61,10 @@ service.interceptors.response.use( error => { const authModal = useAuthModal(); const userInfo = useUserInfo(); - + if (error.message == 'canceled') return Promise.reject(error) const res = error.response?.data - + const { requestBaseUrl } = error.config if (requestBaseUrl == 'chat') { if (res.errcode == 401) { @@ -73,6 +73,9 @@ service.interceptors.response.use( userInfo.updateUserInfo({}); localCache.remove('auth'); localCache.remove('userInfo'); + } else if (res.errcode == 10011) { + localCache.remove('auth'); + localCache.remove('userInfo'); } else { showToast(res.errmsg || 'Error') } diff --git a/src/layouts/index.vue b/src/layouts/index.vue index 92cc625..aab9078 100644 --- a/src/layouts/index.vue +++ b/src/layouts/index.vue @@ -1,43 +1,58 @@ \ No newline at end of file + diff --git a/src/main.js b/src/main.js index 8b1e32b..d039d3e 100644 --- a/src/main.js +++ b/src/main.js @@ -19,7 +19,7 @@ function platCheck() { const userAgent = navigator.userAgent.toLowerCase(); const mobileKeywords = ['iphone', 'ipod', 'android', 'silk', 'blackberry', 'bb10', 'phone', 'mobile', 'kindle', 'opera mini', 'mobile safari', 'windows phone']; const isMobileDevice = mobileKeywords.some(keyword => userAgent.includes(keyword)); - if (!isMobileDevice) { + if (!isMobileDevice && import.meta.env.PROD) { let _href = window.location.href; let _origin = window.location.origin; window.location.href = _href.replace(_origin, import.meta.env.VITE_PC_HOST); diff --git a/src/router/index.js b/src/router/index.js index 915292a..fe878d0 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -16,6 +16,7 @@ const router = createRouter({ meta: { title: "首页", // 页面标题 group: 'home', // 导航归属 + footer: false, }, component: () => import("@/views/home/index.vue"), }, @@ -33,7 +34,7 @@ const router = createRouter({ component: () => import("@/views/chat/index.vue"), meta: { title: 'AI助理', - footer: false, + } }] }, diff --git a/src/stores/chat.js b/src/stores/chat.js index 6d48873..a1b63bf 100644 --- a/src/stores/chat.js +++ b/src/stores/chat.js @@ -100,12 +100,21 @@ export const useChat = defineStore("chat-store", { requestBaseUrl: 'chat', }).then((res) => { const { messages } = res; + const chat = this.chat.find(item => item.id === uuid) + const localMessages = chat?.messages ?? [] const temp = messages.map((item) => { var key = Object.keys(item)[0]; + + + const localItem = (localMessages.find(item => Object.keys(item)[0] == key) ?? {})[key] ?? {} + + const { role } = item[key] - const obj = Object.assign({}, { ...item[key] }, { loading: false, inversion: role == 'user' }) + const obj = Object.assign({}, localItem, { ...item[key] }, { + loading: false, inversion: role == 'user' + }) return { - [key]: obj + [key]: obj, }; }); this.setChat(uuid, { ...res, messages: temp }) diff --git a/src/utils/docxUtils.js b/src/utils/docxUtils.js new file mode 100644 index 0000000..7e5376d --- /dev/null +++ b/src/utils/docxUtils.js @@ -0,0 +1,10 @@ +import mammoth from 'mammoth'; +import { readFileAsArrayBuffer } from './fileUtils' + +export default async function extractDocxText(file) { + const arrayBuffer = await readFileAsArrayBuffer(file) + const options = {} + const result = await mammoth.extractRawText({ arrayBuffer }, options) + return result.value +} + diff --git a/src/utils/fileUtils.js b/src/utils/fileUtils.js new file mode 100644 index 0000000..9795b36 --- /dev/null +++ b/src/utils/fileUtils.js @@ -0,0 +1,28 @@ +export const readFileAsArrayBuffer = (file) => { + return new Promise((resolve, reject) => { + const reader = new FileReader() + reader.onload = () => { + resolve(reader.result) + } + reader.onerror = () => { + reject(new Error('Error reading the file.')) + } + reader.readAsArrayBuffer(file) + }) +} + +export function getFileInfo(file) { + const fileName = file.name; + const fileExtension = getFileExtension(fileName); + const fileSize = file.size; + + return { + name: fileName, + extension: fileExtension, + size: fileSize + }; +} +export function getFileExtension(fileName) { + const parts = fileName.split('.'); + return parts[parts.length - 1].toLowerCase(); +} \ No newline at end of file diff --git a/src/utils/pdfUtils.js b/src/utils/pdfUtils.js new file mode 100644 index 0000000..25a5f6d --- /dev/null +++ b/src/utils/pdfUtils.js @@ -0,0 +1,28 @@ +import * as pdfjsLib from 'pdfjs-dist' +import * as pdfWorkerMin from 'pdfjs-dist/build/pdf.worker.min?url' + +import { readFileAsArrayBuffer } from './fileUtils' + +pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorkerMin.default + + +export default async function extractTextFromPDF(file) { + + const arrayBuffer = await readFileAsArrayBuffer(file) + + const loadingTask = pdfjsLib.getDocument(arrayBuffer); + const pdfDocument = await loadingTask.promise; + const numPages = pdfDocument.numPages; + + let text = ''; + + for (let pageNum = 1; pageNum <= numPages; pageNum++) { + const page = await pdfDocument.getPage(pageNum); + const pageText = await page.getTextContent(); + + pageText.items.forEach(item => { + text += item.str + ' '; + }); + } + return text; +} diff --git a/src/views/assistant/index.vue b/src/views/assistant/index.vue index 30b557c..abb5f27 100644 --- a/src/views/assistant/index.vue +++ b/src/views/assistant/index.vue @@ -1,16 +1,19 @@