From af3547b4b34c961e166e0195ff1ee799a7ba2c4f Mon Sep 17 00:00:00 2001 From: Frankie Huang Date: Tue, 6 May 2025 01:14:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E7=8E=AF=E5=A2=83=E7=9A=84=E6=96=87=E7=AB=A0=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=92=8C=E4=BF=9D=E5=AD=98=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 33 +++++++++++----- src/components/MainEditor.vue | 2 +- src/components/UI/SelectFolder.vue | 50 +++++++++++++------------ src/utils/userHandler.js | 60 ++++++++++++++++++++++++++++-- 4 files changed, 108 insertions(+), 37 deletions(-) diff --git a/src/App.vue b/src/App.vue index daef869..f2c9f5e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -27,6 +27,7 @@ import { invoke } from "@tauri-apps/api/core"; import { readTextFile, writeTextFile, writeFile, exists } from '@tauri-apps/plugin-fs'; import { save } from '@tauri-apps/plugin-dialog'; import { Message, Notice } from 'view-ui-plus' +import { GetSingleArticle, UpdateArticle } from '/src/utils/userHandler'; // 原始示例数据,仅供参考 const greetMsg = ref(""); @@ -93,13 +94,21 @@ watch(markdownCode, (newMarkdownCode) => { console.log("code be updated"); }) async function readFileContent(filePath) { + if (window.__TAURI_INTERNALS__ === undefined) { + // 调用接口读取 currentFilePath 文件内容 + const match = filePath.match(/(\d+)$/); + const articleID = match ? parseInt(match[1], 10) : null; + GetSingleArticle(articleID).then((data) => { + markdownCode.value = data.mdCode; + currentFilePath.value = filePath; + Message.success('已读取文件内容,并加载到编辑器中:' + filePath); + }).catch((error) => { + Message.error(`调用异常: ${error}`); + }); + return; + } try { - let fileContent = ''; - if (window.__TAURI_INTERNALS__ === undefined) { - fileContent = "# this is " + filePath; - } else { - fileContent = await readTextFile(filePath); - } + const fileContent = await readTextFile(filePath); markdownCode.value = fileContent; currentFilePath.value = filePath; Message.success('已读取文件内容,并加载到编辑器中:' + filePath); @@ -115,16 +124,22 @@ async function writeFileContent(markdownCode) { } try { if (window.__TAURI_INTERNALS__ === undefined) { - // TODO 调用接口更新 currentFilePath 文件内容 - Message.warning('暂未实现接口'); + // 调用接口更新 currentFilePath 文件内容 + const match = currentFilePath.value.match(/(\d+)$/); + const articleID = match ? parseInt(match[1], 10) : null; + UpdateArticle(articleID, null, markdownCode).then((data) => { + Message.success('更新成功'); + }).catch((error) => { + Message.error(`更新异常: ${error}`); + }); } else { const exist = await exists(currentFilePath.value); if (!exist) { throw new Error(currentFilePath.value + " 文件不存在."); } await writeTextFile(currentFilePath.value, markdownCode); + Message.success('文件更新成功:' + currentFilePath.value); } - Message.success('文件更新成功:' + currentFilePath.value); } catch (err) { Message.error('文件更新失败:' + err); } diff --git a/src/components/MainEditor.vue b/src/components/MainEditor.vue index 9eed338..509ea29 100644 --- a/src/components/MainEditor.vue +++ b/src/components/MainEditor.vue @@ -55,7 +55,7 @@ import { ThemeSwitch, PreviewThemeSwitch, ExportPDF } from '@vavt/v3-extension'; import { lineNumbers } from '@codemirror/view'; import LinkAttr from 'markdown-it-link-attributes'; import { ref, reactive, watch, nextTick, onMounted } from "vue"; -import { Message, Modal } from 'view-ui-plus' +import { Message, Modal } from 'view-ui-plus'; import { encode as plantumlEncoder } from 'plantuml-encoder'; import { SubmitArticle, UpdateArticle } from '/src/utils/userHandler'; diff --git a/src/components/UI/SelectFolder.vue b/src/components/UI/SelectFolder.vue index 57a5aed..804e41b 100644 --- a/src/components/UI/SelectFolder.vue +++ b/src/components/UI/SelectFolder.vue @@ -35,6 +35,8 @@ import { join } from '@tauri-apps/api/path'; import { open } from '@tauri-apps/plugin-dialog'; import { readDir } from '@tauri-apps/plugin-fs'; +import { GetUserArticle } from '/src/utils/userHandler'; +import { Message } from 'view-ui-plus'; export default { props: { @@ -59,6 +61,29 @@ export default { }, methods: { async exposeTreeData(folderPath) { + if (window.__TAURI_INTERNALS__ === undefined) { + GetUserArticle().then((data) => { + folderPath = '/Users/' + data.username; + const folderTreeData = { + "path": folderPath, + "name": data.username, + "nodes": [], + "directory": true, + }; + data.articles.forEach((article) => { + folderTreeData.nodes.push({ + "path": folderPath + '/' + article.article_id, + "name": article.article_id + '.md', + "suffix": "md", + "directory": false, + }); + }) + this.$emit('folder-selected', folderTreeData); + }).catch((error) => { + Message.error(`调用异常: ${error}`); + }); + return; + } if (folderPath != null && folderPath.length > 0) { const folderTreeData = await this.readDirRecursively(folderPath); this.$emit('folder-selected', folderTreeData); @@ -66,10 +91,7 @@ export default { }, async selectFolder() { if (window.__TAURI_INTERNALS__ === undefined) { - // TODO 请求后端接口,选择目录 - // 告诉父组件,rootPath 的值已变化 - this.$emit('update:rootPath', '/root') - await this.exposeTreeData('/root') + // 非 Tauri 环境下,会默认加载用户数据列表,不支持选择目录 return; } const folderPath = await open( @@ -86,26 +108,6 @@ export default { }, // 遍历文件夹,返回文件树 async readDirRecursively(folderPath) { - if (window.__TAURI_INTERNALS__ === undefined) { - // TODO 请求后端接口,获取目录树 - const folderTreeData = { - "path": folderPath, - "name": folderPath.split('/').pop(), - "nodes": [{ - "path": '/root/test.md', - "name": 'test.md', - "suffix": "md", - "directory": false, - },{ - "path": '/root/test1.md', - "name": 'test1.md', - "suffix": "md", - "directory": false, - }], - "directory": true, - } - return folderTreeData; - } // 拼接得到当前文件夹路径 let folderTreeNode = { "path": folderPath, diff --git a/src/utils/userHandler.js b/src/utils/userHandler.js index 9c3811b..057875f 100644 --- a/src/utils/userHandler.js +++ b/src/utils/userHandler.js @@ -177,15 +177,44 @@ const SubmitArticle = (title, mdCode) => { } const UpdateArticle = (id, title, mdCode) => { + return new Promise((resolve, reject) => { + const PHPSESSID = getPHPSessionFromCookie(); + let body = { + 'func': 'update_article', + 'id': id, + } + if (title !== null && title !== undefined) { + body.title = title; + } + if (mdCode !== null && mdCode !== undefined) { + body.mdCode = mdCode; + } + fetch('https://myafei.cn/php/ajax.php?PHPSESSID=' + PHPSESSID, { + method: 'POST', + body: JSON.stringify(body), + }).then(response => { + if (!response.ok) throw new Error(`HTTP 错误: ${response.status}`); + return response.json(); + }).then(data => { + if (data.status == 0) { + resolve(data); + } else { + reject(new Error(data.error)); + } + }).catch(error => { + reject(error); + }); + }); +} + +const GetSingleArticle = (id) => { return new Promise((resolve, reject) => { const PHPSESSID = getPHPSessionFromCookie(); fetch('https://myafei.cn/php/ajax.php?PHPSESSID=' + PHPSESSID, { method: 'POST', body: JSON.stringify({ - 'func': 'update_article', + 'func': 'init_submit', 'id': id, - 'title': title, - 'mdCode': mdCode, }), }).then(response => { if (!response.ok) throw new Error(`HTTP 错误: ${response.status}`); @@ -202,6 +231,29 @@ const UpdateArticle = (id, title, mdCode) => { }); } +const GetUserArticle = (id, title, mdCode) => { + return new Promise((resolve, reject) => { + const PHPSESSID = getPHPSessionFromCookie(); + fetch('https://myafei.cn/php/ajax.php?PHPSESSID=' + PHPSESSID, { + method: 'POST', + body: JSON.stringify({ + 'func': 'get_articles', + }), + }).then(response => { + if (!response.ok) throw new Error(`HTTP 错误: ${response.status}`); + return response.json(); + }).then(data => { + if (data.status == 0) { + resolve(data); + } else { + // 未登录不抛出异常 + } + }).catch(error => { + reject(error); + }); + }); +} + export { SignIn, SignUp, @@ -210,4 +262,6 @@ export { Logout, SubmitArticle, UpdateArticle, + GetSingleArticle, + GetUserArticle, }; \ No newline at end of file