From 314a71424828e8339f978c668ca766cd40cd9b75 Mon Sep 17 00:00:00 2001 From: YiLin <482244139@qq.com> Date: Fri, 31 Jul 2026 16:38:01 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=92=8C?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=89=93=E5=BC=80=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/Chat/Chat.vue | 35 +- pages/CloudDatabase/CloudDatabase.vue | 16 +- pages/WorkSpace/WorkSpace.vue | 37 +- pages/text/text.vue | 27 +- .../dist/dev/app-plus/app-config-service.js | 2 +- unpackage/dist/dev/app-plus/app-service.js | 467 ++++++++++-------- unpackage/dist/dev/app-plus/manifest.json | 2 +- utils/fileOpener.js | 124 +++++ 8 files changed, 413 insertions(+), 297 deletions(-) create mode 100644 utils/fileOpener.js diff --git a/pages/Chat/Chat.vue b/pages/Chat/Chat.vue index 0cbf474..38f9f55 100644 --- a/pages/Chat/Chat.vue +++ b/pages/Chat/Chat.vue @@ -346,6 +346,7 @@ chooseFile } from '@/uni_modules/lime-choose-file' import socketManager from '../../utils/socket'; +import { openFile as openFileNative, downloadAndOpen } from '@/utils/fileOpener.js' const friendSocketStore = useFriendSocketStore() // 连接实时通讯eriendsocket @@ -523,15 +524,7 @@ } // 打开文件 const openFile = (url) => { - uni.downloadFile({ - url: url, - success: (res) => { - uni.openDocument({ - filePath: res.tempFilePath, - showMenu: true - }) - } - }) + downloadAndOpen(url); } // 文件大小格式化 const formatFileSize = (size) => { @@ -906,12 +899,8 @@ success: (downloadRes) => { if (downloadRes.statusCode === 200) { hideDownloadToast() - uni.openDocument({ - filePath: downloadRes.tempFilePath, - showMenu: true, - fail: () => { - showDownloadToast('error', '无法打开此文件', 2500) - } + openFileNative(downloadRes.tempFilePath, () => { + showDownloadToast('error', '无法打开此文件', 2500) }) } else { showDownloadToast('error', '下载失败', 2500) @@ -1188,14 +1177,16 @@ if (reason === 'pc offline') { isThinking.value = false socketStore.authFailReason = '' - nextTick(() => { - uni.showModal({ - title: '提示', - content: 'PC端不在线,不可聊天', - showCancel: false, - confirmText: '知道了' - }) + uni.showToast({ + title: 'PC端不在线,请先登录', + icon: 'none', + duration: 500 }) + setTimeout(() => { + uni.reLaunch({ + url: '/pages/Login/Login' + }) + }, 500) } }) diff --git a/pages/CloudDatabase/CloudDatabase.vue b/pages/CloudDatabase/CloudDatabase.vue index 030b8a0..057d889 100644 --- a/pages/CloudDatabase/CloudDatabase.vue +++ b/pages/CloudDatabase/CloudDatabase.vue @@ -475,6 +475,7 @@ uploadCloudDbFile, deleteCloudDb } from '@/utils/cloud-api.js'; +import { openFile as openFileNative } from '@/utils/fileOpener.js' const userToken = ref(''); const userId = ref(''); @@ -826,19 +827,10 @@ } }; - // 使用系统默认应用打开 + // 打开文件(弹出应用选择菜单) const openFile = (filePath) => { - uni.openDocument({ - filePath: filePath, - success: () => uni.showToast({ - title: '打开成功', - icon: 'success' - }), - fail: (err) => { - console.error('打开文件失败:', err); - // 如果默认应用打开失败,尝试弹出选择菜单 - openFileWithMenu(filePath); - } + openFileNative(filePath, () => { + openFileWithMenu(filePath); }); }; diff --git a/pages/WorkSpace/WorkSpace.vue b/pages/WorkSpace/WorkSpace.vue index 9477c83..a014c6f 100644 --- a/pages/WorkSpace/WorkSpace.vue +++ b/pages/WorkSpace/WorkSpace.vue @@ -121,6 +121,7 @@ workspaceUploadFileByURL, updateWorkspaceFileName } from '@/utils/cloud-api.js' +import { openFile as openFileNative } from '@/utils/fileOpener.js' const UserToken = ref('') const workspaceId = ref('') @@ -435,40 +436,10 @@ } }; - // 使用系统默认应用打开 + // 打开文件(弹出应用选择菜单) const openFile = (filePath) => { - uni.openDocument({ - filePath: filePath, - success: () => uni.showToast({ - title: '打开成功', - icon: 'success' - }), - fail: (err) => { - console.error('打开文件失败:', err); - uni.showToast({ - title: '无法打开此文件', - icon: 'error' - }); - } - }); - }; - - // 选择其他应用打开 - const openFileWithMenu = (filePath) => { - uni.openDocument({ - filePath: filePath, - showMenu: true, - success: () => uni.showToast({ - title: '打开成功', - icon: 'success' - }), - fail: (err) => { - console.error('打开文件失败:', err); - uni.showToast({ - title: '无法打开此文件', - icon: 'error' - }); - } + openFileNative(filePath, () => { + uni.showToast({ title: '无法打开此文件', icon: 'error' }); }); }; diff --git a/pages/text/text.vue b/pages/text/text.vue index e53e8b2..582560f 100644 --- a/pages/text/text.vue +++ b/pages/text/text.vue @@ -325,6 +325,7 @@ chooseFile } from '@/uni_modules/lime-choose-file' import socketManager from '../../utils/socket'; +import { openFile as openFileNative } from '@/utils/fileOpener.js' const friendSocketStore = useFriendSocketStore() // 连接实时通讯eriendsocket @@ -490,15 +491,7 @@ } // 打开文件 const openFile = (url) => { - uni.downloadFile({ - url: url, - success: (res) => { - uni.openDocument({ - filePath: res.tempFilePath, - showMenu: true - }) - } - }) + downloadAndOpen(url); } // 文件大小格式化 const formatFileSize = (size) => { @@ -1131,14 +1124,16 @@ if (reason === 'pc offline') { isThinking.value = false socketStore.authFailReason = '' - nextTick(() => { - uni.showModal({ - title: '提示', - content: 'PC端不在线,不可聊天', - showCancel: false, - confirmText: '知道了' - }) + uni.showToast({ + title: 'PC端不在线', + icon: 'none', + duration: 1500 }) + setTimeout(() => { + uni.reLaunch({ + url: '/pages/Login/Login' + }) + }, 1500) } }) diff --git a/unpackage/dist/dev/app-plus/app-config-service.js b/unpackage/dist/dev/app-plus/app-config-service.js index 5416a50..a92dbeb 100644 --- a/unpackage/dist/dev/app-plus/app-config-service.js +++ b/unpackage/dist/dev/app-plus/app-config-service.js @@ -1,7 +1,7 @@ ;(function(){ let u=void 0,isReady=false,onReadyCallbacks=[],isServiceReady=false,onServiceReadyCallbacks=[]; - const __uniConfig = {"pages":[],"globalStyle":{"backgroundColor":"#F8F8F8","navigationBar":{"backgroundColor":"#F8F8F8","titleText":"uni-app","type":"default","titleColor":"#000000"},"isNVue":false},"nvue":{"compiler":"uni-app","styleCompiler":"uni-app","flex-direction":"column"},"renderer":"auto","appname":"test1","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":true},"compilerVersion":"5.07","entryPagePath":"pages/Login/Login","entryPageQuery":"","realEntryPagePath":"","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000},"locales":{},"darkmode":false,"themeConfig":{}}; + const __uniConfig = {"pages":[],"globalStyle":{"backgroundColor":"#F8F8F8","navigationBar":{"backgroundColor":"#F8F8F8","titleText":"uni-app","type":"default","titleColor":"#000000"},"isNVue":false},"nvue":{"compiler":"uni-app","styleCompiler":"uni-app","flex-direction":"column"},"renderer":"auto","appname":"宇恒一号","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":true},"compilerVersion":"5.07","entryPagePath":"pages/Login/Login","entryPageQuery":"","realEntryPagePath":"","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000},"locales":{},"darkmode":false,"themeConfig":{}}; const __uniRoutes = [{"path":"pages/Login/Login","meta":{"isQuit":true,"isEntry":true,"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"登录页面","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/Chat/Chat","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"聊天页面(主页面)","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/WorkSpace/WorkSpace","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"工作区文件管理","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/UserProfileModal/UserProfileModal","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/ContactPages/ContactPages","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/WorkSpace/TemplateSpace/TemplateSpace","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/CloudDatabase/CloudDatabase","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"云端数据","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/CloudDbDetail/CloudDbDetail","meta":{"titleNView":false,"bounce":"none","softinputMode":"adjustResize","navigationBar":{"titleText":"数据库详情","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/text/text","meta":{"navigationBar":{"titleText":"","type":"default"},"isNVue":false}},{"path":"pages/text/IntuitiveAipptViewer","meta":{"navigationBar":{"titleText":"","type":"default"},"isNVue":false}},{"path":"pages/WYXD/WYXD","meta":{"titleNView":false,"bounce":"none","navigationBar":{"titleText":"","style":"custom","type":"default"},"isNVue":false}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute)); __uniConfig.styles=[];//styles __uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}}); diff --git a/unpackage/dist/dev/app-plus/app-service.js b/unpackage/dist/dev/app-plus/app-service.js index c6b8b81..6ab1540 100644 --- a/unpackage/dist/dev/app-plus/app-service.js +++ b/unpackage/dist/dev/app-plus/app-service.js @@ -3357,7 +3357,7 @@ if (uni.restoreGlobal) { fileInput.type = "file"; fileInput.accept = ".json"; } - function openFile() { + function openFile2() { return new Promise((resolve, reject) => { fileInput.onchange = async () => { const files = fileInput.files; @@ -3373,7 +3373,7 @@ if (uni.restoreGlobal) { fileInput.click(); }); } - return openFile; + return openFile2; } async function actionGlobalOpenStateFile(pinia) { try { @@ -5630,6 +5630,90 @@ This will fail in production.`); const pkg = /* @__PURE__ */ initUTSPackageName(name, is_uni_modules); const cls = /* @__PURE__ */ initUTSIndexClassName(name, is_uni_modules); const chooseFile = /* @__PURE__ */ initUTSProxyFunction(false, { moduleName, moduleType, errMsg, main: true, package: pkg, class: cls, name: "chooseFileByJs", keepAlive: false, params: [{ "name": "options", "type": "UTSSDKModulesLimeChooseFileChooseFileOptionJSONObject" }], return: "" }); + function getMimeType(filePath) { + const ext = filePath.substring(filePath.lastIndexOf(".") + 1).toLowerCase(); + const mimeMap = { + "pdf": "application/pdf", + "doc": "application/msword", + "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "xls": "application/vnd.ms-excel", + "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "ppt": "application/vnd.ms-powerpoint", + "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "txt": "text/plain", + "html": "text/html", + "htm": "text/html", + "xml": "text/xml", + "json": "application/json", + "csv": "text/csv", + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "png": "image/png", + "gif": "image/gif", + "bmp": "image/bmp", + "webp": "image/webp", + "mp4": "video/mp4", + "mp3": "audio/mpeg", + "wav": "audio/wav", + "zip": "application/zip", + "rar": "application/x-rar-compressed", + "7z": "application/x-7z-compressed", + "apk": "application/vnd.android.package-archive" + }; + return mimeMap[ext] || "*/*"; + } + function openFile(filePath, onFail) { + try { + const main = plus.android.runtimeMainActivity(); + const Intent = plus.android.importClass("android.content.Intent"); + const Uri = plus.android.importClass("android.net.Uri"); + const File = plus.android.importClass("java.io.File"); + if (plus.os.sdkInt >= 24) { + const StrictMode = plus.android.importClass("android.os.StrictMode"); + StrictMode.disableDeathOnFileUriExposure(); + } + const file = new File(filePath); + if (!file.exists()) { + throw new Error("文件不存在: " + filePath); + } + const uri = Uri.fromFile(file); + const mimeType = getMimeType(filePath); + const intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(uri, mimeType); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + const chooser = Intent.createChooser(intent, "选择应用打开"); + main.startActivity(chooser); + formatAppLog("log", "at utils/fileOpener.js:83", "openFile success - chooser shown"); + } catch (e2) { + formatAppLog("error", "at utils/fileOpener.js:85", "openFile native failed, fallback:", e2); + uni.openDocument({ + filePath, + showMenu: true, + fail: typeof onFail === "function" ? onFail : () => { + } + }); + } + } + function downloadAndOpen$1(url, onFail) { + uni.downloadFile({ + url, + success: (res) => { + if (res.statusCode === 200) { + openFile(res.tempFilePath, onFail); + } else { + formatAppLog("error", "at utils/fileOpener.js:115", "下载失败, statusCode:", res.statusCode); + if (typeof onFail === "function") + onFail(); + } + }, + fail: (err) => { + formatAppLog("error", "at utils/fileOpener.js:120", "downloadFile fail:", err); + if (typeof onFail === "function") + onFail(); + } + }); + } const _sfc_main$a = { __name: "Chat", setup(__props, { expose: __expose }) { @@ -5639,7 +5723,7 @@ This will fail in production.`); if (friendSocketStore.isConnected) return; if (!userToken.value || !UserId.value) { - formatAppLog("warn", "at pages/Chat/Chat.vue:355", "Token或UserId未准备好"); + formatAppLog("warn", "at pages/Chat/Chat.vue:356", "Token或UserId未准备好"); return; } friendSocketStore.connect({ @@ -5730,7 +5814,7 @@ This will fail in production.`); ); return html; } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:488", "解析失败", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:489", "解析失败", e2); return content; } }; @@ -5750,16 +5834,8 @@ This will fail in production.`); urls: [url] }); }; - const openFile = (url) => { - uni.downloadFile({ - url, - success: (res) => { - uni.openDocument({ - filePath: res.tempFilePath, - showMenu: true - }); - } - }); + const openFile$1 = (url) => { + downloadAndOpen$1(url); }; const formatFileSize = (size) => { if (!size) @@ -5789,7 +5865,7 @@ This will fail in production.`); files }; } catch (e2) { - formatAppLog("error", "at pages/Chat/Chat.vue:565", "解析文件信息失败:", e2); + formatAppLog("error", "at pages/Chat/Chat.vue:558", "解析文件信息失败:", e2); return { textContent: content, files: [] @@ -5827,7 +5903,7 @@ This will fail in production.`); closeNewChatModal(); takeUserConversations(); } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:611", "新建普通会话失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:604", "新建普通会话失败:", error); uni.showToast({ title: "创建会话失败,请重试", icon: "none" @@ -5870,7 +5946,7 @@ This will fail in production.`); }; const previewFileArray = vue.ref([]); const uploadPhoto = () => { - formatAppLog("log", "at pages/Chat/Chat.vue:671", "点击了拍照上传"); + formatAppLog("log", "at pages/Chat/Chat.vue:664", "点击了拍照上传"); uni.chooseImage({ count: 1, sourceType: ["camera", "album"], @@ -5893,7 +5969,7 @@ This will fail in production.`); }); }, fail: (err) => { - formatAppLog("error", "at pages/Chat/Chat.vue:689", "选择图片失败", err); + formatAppLog("error", "at pages/Chat/Chat.vue:682", "选择图片失败", err); } }); }; @@ -5902,12 +5978,12 @@ This will fail in production.`); }; const fileList = vue.ref([]); const uploadFile = () => { - formatAppLog("log", "at pages/Chat/Chat.vue:700", "点击了上传文件"); + formatAppLog("log", "at pages/Chat/Chat.vue:693", "点击了上传文件"); chooseFile({ count: 5, type: "all", success: (res) => { - formatAppLog("log", "at pages/Chat/Chat.vue:705", "成功了"); + formatAppLog("log", "at pages/Chat/Chat.vue:698", "成功了"); fileList.value = res.tempFiles; previewFileArray.value.push(...res.tempFiles); uni.showToast({ @@ -5916,7 +5992,7 @@ This will fail in production.`); }); }, fail: (err) => { - formatAppLog("error", "at pages/Chat/Chat.vue:716", "选择失败:", err); + formatAppLog("error", "at pages/Chat/Chat.vue:709", "选择失败:", err); uni.showToast({ title: "选择失败", icon: "error" @@ -6079,12 +6155,8 @@ This will fail in production.`); success: (downloadRes) => { if (downloadRes.statusCode === 200) { hideDownloadToast(); - uni.openDocument({ - filePath: downloadRes.tempFilePath, - showMenu: true, - fail: () => { - showDownloadToast("error", "无法打开此文件", 2500); - } + openFile(downloadRes.tempFilePath, () => { + showDownloadToast("error", "无法打开此文件", 2500); }); } else { showDownloadToast("error", "下载失败", 2500); @@ -6118,7 +6190,7 @@ This will fail in production.`); previewFileArray.value = []; } catch (err) { uni.hideLoading(); - formatAppLog("error", "at pages/Chat/Chat.vue:951", "文件上传失败:", err); + formatAppLog("error", "at pages/Chat/Chat.vue:940", "文件上传失败:", err); uni.showToast({ title: "文件上传失败,请重试", icon: "error" @@ -6252,15 +6324,15 @@ This will fail in production.`); } }; const stopConversation = async () => { - formatAppLog("log", "at pages/Chat/Chat.vue:1121", "中断对话 - 当前会话ID:", currentSessionId.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1110", "中断对话 - 当前会话ID:", currentSessionId.value); try { await socketStore.send({ type: "stop", conversation_id: currentSessionId.value }); - formatAppLog("log", "at pages/Chat/Chat.vue:1127", "中断指令已发送成功"); + formatAppLog("log", "at pages/Chat/Chat.vue:1116", "中断指令已发送成功"); } catch (err) { - formatAppLog("error", "at pages/Chat/Chat.vue:1129", "中断指令发送失败:", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1118", "中断指令发送失败:", err); } if (streamingMessageId.value) { allmessages.value = allmessages.value.filter((m) => m._id !== streamingMessageId.value); @@ -6278,9 +6350,9 @@ This will fail in production.`); }); }; vue.watch(() => socketStore.isThinking, (newVal, oldVal) => { - formatAppLog("log", "at pages/Chat/Chat.vue:1153", "isThinking 变化:", oldVal, "→", newVal, "messageString:", socketStore.messageString); + formatAppLog("log", "at pages/Chat/Chat.vue:1142", "isThinking 变化:", oldVal, "→", newVal, "messageString:", socketStore.messageString); if (!oldVal && newVal) { - formatAppLog("log", "at pages/Chat/Chat.vue:1156", "AI开始回复(跨设备同步),锁定输入框"); + formatAppLog("log", "at pages/Chat/Chat.vue:1145", "AI开始回复(跨设备同步),锁定输入框"); isThinking.value = true; if (!streamingMessageId.value) { streamingMessageId.value = "streaming-" + Date.now(); @@ -6294,7 +6366,7 @@ This will fail in production.`); return; } if (oldVal && !newVal) { - formatAppLog("log", "at pages/Chat/Chat.vue:1172", "AI回复结束(正常/中断),解锁并刷新消息列表"); + formatAppLog("log", "at pages/Chat/Chat.vue:1161", "AI回复结束(正常/中断),解锁并刷新消息列表"); if (streamingMessageId.value) { allmessages.value = allmessages.value.filter((m) => m._id !== streamingMessageId.value); streamingMessageId.value = null; @@ -6310,14 +6382,16 @@ This will fail in production.`); if (reason === "pc offline") { isThinking.value = false; socketStore.authFailReason = ""; - vue.nextTick(() => { - uni.showModal({ - title: "提示", - content: "PC端不在线,不可聊天", - showCancel: false, - confirmText: "知道了" - }); + uni.showToast({ + title: "PC端不在线,请先登录", + icon: "none", + duration: 500 }); + setTimeout(() => { + uni.reLaunch({ + url: "/pages/Login/Login" + }); + }, 500); } }); vue.watch(() => socketStore.messageString, (newContent) => { @@ -6346,15 +6420,15 @@ This will fail in production.`); UserData.value = await getUserInfo(userToken.value); UserId.value = UserData.value._id; UserAvatar.value = UserData.value.avatar || ""; - formatAppLog("log", "at pages/Chat/Chat.vue:1236", "用户信息已加载:", UserId.value, UserAvatar.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1227", "用户信息已加载:", UserId.value, UserAvatar.value); } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:1238", "获取用户信息失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:1229", "获取用户信息失败:", error); } }; const takeUserConversations = async () => { try { userToken.value = getToken(); - formatAppLog("log", "at pages/Chat/Chat.vue:1246", "token:", userToken.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1237", "token:", userToken.value); UserConversations.value = await getUserConversations(userToken.value) || []; const savedSessionId = getCurrentSessionId(); if (savedSessionId && UserConversations.value.some((c) => c._id === savedSessionId)) { @@ -6364,7 +6438,7 @@ This will fail in production.`); } else { currentSessionId.value = ""; } - formatAppLog("log", "at pages/Chat/Chat.vue:1258", "保存会话id:", currentSessionId.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1249", "保存会话id:", currentSessionId.value); uni.setStorageSync("currentSessionId", currentSessionId.value); } catch (error) { uni.showToast({ @@ -6376,17 +6450,17 @@ This will fail in production.`); const FriendInfoList = vue.ref([]); const takeFriendList = async () => { try { - formatAppLog("log", "at pages/Chat/Chat.vue:1273", "开始获取好友列表"); + formatAppLog("log", "at pages/Chat/Chat.vue:1264", "开始获取好友列表"); const friendList = await getChatFriend(UserId.value); - formatAppLog("log", "at pages/Chat/Chat.vue:1276", "friendList:", friendList); + formatAppLog("log", "at pages/Chat/Chat.vue:1267", "friendList:", friendList); if (friendList && friendList.length) { FriendInfoList.value = await takeUserAvatar(friendList); } else { FriendInfoList.value = []; - formatAppLog("log", "at pages/Chat/Chat.vue:1281", "好友列表为空"); + formatAppLog("log", "at pages/Chat/Chat.vue:1272", "好友列表为空"); } } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:1284", "获取好友列表失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:1275", "获取好友列表失败:", error); FriendInfoList.value = []; } finally { UserConversations.value = FriendInfoList.value; @@ -6413,17 +6487,17 @@ This will fail in production.`); }; }); } catch (err) { - formatAppLog("error", "at pages/Chat/Chat.vue:1314", "获取好友头像失败", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1305", "获取好友头像失败", err); return friendList; } }; const GroupList = vue.ref([]); const takeGroupList = async () => { try { - formatAppLog("log", "at pages/Chat/Chat.vue:1324", "开始获取群聊列表"); + formatAppLog("log", "at pages/Chat/Chat.vue:1315", "开始获取群聊列表"); GroupList.value = await getGroup(UserId.value); } catch (error) { - formatAppLog("error", "at pages/Chat/Chat.vue:1329", "获取群聊列表失败:", error); + formatAppLog("error", "at pages/Chat/Chat.vue:1320", "获取群聊列表失败:", error); GroupList.value = []; } finally { UserConversations.value = GroupList.value; @@ -6435,22 +6509,22 @@ This will fail in production.`); return []; try { const memberIds = memberList.map((item) => item.groupContactId); - formatAppLog("log", "at pages/Chat/Chat.vue:1343", "请求头像的ID列表:", memberIds); + formatAppLog("log", "at pages/Chat/Chat.vue:1334", "请求头像的ID列表:", memberIds); const memberAvatarList = await getUserAvatar(userToken.value, memberIds); - formatAppLog("log", "at pages/Chat/Chat.vue:1345", "头像接口返回数据:", memberAvatarList); + formatAppLog("log", "at pages/Chat/Chat.vue:1336", "头像接口返回数据:", memberAvatarList); const userMap = new Map(memberAvatarList.map((user) => [user.user_id, user]) || []); - formatAppLog("log", "at pages/Chat/Chat.vue:1348", "userMap的keys:", Array.from(userMap.keys())); + formatAppLog("log", "at pages/Chat/Chat.vue:1339", "userMap的keys:", Array.from(userMap.keys())); return memberList.map((member) => { const memberId = member.groupContactId; const userInfo = userMap.get(memberId); - formatAppLog("log", "at pages/Chat/Chat.vue:1353", `查找 ${memberId} 的头像:`, userInfo); + formatAppLog("log", "at pages/Chat/Chat.vue:1344", `查找 ${memberId} 的头像:`, userInfo); return { ...member, avatar: (userInfo == null ? void 0 : userInfo.avatar) || null }; }); } catch (err) { - formatAppLog("error", "at pages/Chat/Chat.vue:1360", "获取群成员头像失败", err); + formatAppLog("error", "at pages/Chat/Chat.vue:1351", "获取群成员头像失败", err); return memberList; } }; @@ -6497,12 +6571,12 @@ This will fail in production.`); const takeGroupMessages = async () => { try { allmessages.value = await getGroupMessages(currentSessionId.value) || []; - formatAppLog("log", "at pages/Chat/Chat.vue:1424", "群聊消息:", allmessages.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1415", "群聊消息:", allmessages.value); const memberList = await getGroupMemberList(currentSessionId.value); - formatAppLog("log", "at pages/Chat/Chat.vue:1427", "获取到的群成员列表:", memberList); + formatAppLog("log", "at pages/Chat/Chat.vue:1418", "获取到的群成员列表:", memberList); if (memberList && memberList.length) { groupMemberList.value = await takeGroupMemberAvatar(memberList); - formatAppLog("log", "at pages/Chat/Chat.vue:1430", "群成员列表(带头像):", groupMemberList.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1421", "群成员列表(带头像):", groupMemberList.value); } else { groupMemberList.value = []; } @@ -6526,9 +6600,9 @@ This will fail in production.`); } }; vue.watch(() => friendSocketStore.MessageReceived, (newId) => { - formatAppLog("log", "at pages/Chat/Chat.vue:1477", "收到了好友消息"); + formatAppLog("log", "at pages/Chat/Chat.vue:1468", "收到了好友消息"); if (newId) { - formatAppLog("log", "at pages/Chat/Chat.vue:1479", "ChatType:", ChatType.value); + formatAppLog("log", "at pages/Chat/Chat.vue:1470", "ChatType:", ChatType.value); switch (ChatType.value) { case 0: takeConversationMessages(); @@ -6543,7 +6617,7 @@ This will fail in production.`); friendSocketStore.MessageReceived = false; break; default: - formatAppLog("log", "at pages/Chat/Chat.vue:1495", "default 分支"); + formatAppLog("log", "at pages/Chat/Chat.vue:1486", "default 分支"); friendSocketStore.MessageReceived = false; break; } @@ -6622,7 +6696,7 @@ This will fail in production.`); onUnload(() => { socketStore.disconnect(); }); - const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, wyxdWorkspaceId, wyxdFilePath, wyxdFileName, wyxdUserToken, hasWyxdFile, convertMarkdownTable, renderTable, escapeLoneUnderscores, pareseMarkdown, sanitizeContent, previewImage, openFile, formatFileSize, parseFileInfo, selectNormalChat, showNewChatModal, closeNewChatModal, isChatSidebar, handleChatSidebar, goWorkSpace, goWyxdViewer, goCloudDatabase, logOut, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isSelfSent, isUploading, isLoadingMessages, uploadedFiles, streamingMessageId, showMessageModal, detailLinks, handleChatContentClick, extractLinks, extractFileNameFromUrl, showMessageDetail, closeMessageDetail, downloadToast, get downloadToastTimer() { + const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, wyxdWorkspaceId, wyxdFilePath, wyxdFileName, wyxdUserToken, hasWyxdFile, convertMarkdownTable, renderTable, escapeLoneUnderscores, pareseMarkdown, sanitizeContent, previewImage, openFile: openFile$1, formatFileSize, parseFileInfo, selectNormalChat, showNewChatModal, closeNewChatModal, isChatSidebar, handleChatSidebar, goWorkSpace, goWyxdViewer, goCloudDatabase, logOut, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isSelfSent, isUploading, isLoadingMessages, uploadedFiles, streamingMessageId, showMessageModal, detailLinks, handleChatContentClick, extractLinks, extractFileNameFromUrl, showMessageDetail, closeMessageDetail, downloadToast, get downloadToastTimer() { return downloadToastTimer; }, set downloadToastTimer(v) { downloadToastTimer = v; @@ -6680,6 +6754,10 @@ This will fail in production.`); return chooseFile; }, get socketManager() { return socketManager; + }, get openFileNative() { + return openFile; + }, get downloadAndOpen() { + return downloadAndOpen$1; } }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; @@ -7423,7 +7501,7 @@ This will fail in production.`); await doUploadWorkspaceFiles(files); }, fail: (err) => { - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:176", "选择文件失败:", err); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:177", "选择文件失败:", err); } }); }; @@ -7460,7 +7538,7 @@ This will fail in production.`); initCurrentFolderList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:229", "上传文件失败:", error); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:230", "上传文件失败:", error); uni.showToast({ title: typeof error === "string" ? error : "上传失败,请重试", icon: "error" @@ -7500,7 +7578,7 @@ This will fail in production.`); closeNewFolderModal(); initCurrentFolderList(); } catch (error) { - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:275", "创建文件夹失败:", error); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:276", "创建文件夹失败:", error); uni.showToast({ title: "创建失败,请重试", icon: "error" @@ -7511,8 +7589,9 @@ This will fail in production.`); if (isSelectFolder.value) return; const isWyxd = folder.name && folder.name.toLowerCase().endsWith(".wyxd"); - const itemList = isWyxd ? ["下载", "AI修改", "删除", "WYXD查看器"] : ["下载", "删除"]; + const itemList = isWyxd ? ["下载", "删除", "WYXD查看器", "AI修改"] : ["下载", "删除"]; uni.showActionSheet({ + title: folder.name, itemList, success: (res) => { if (isWyxd) { @@ -7521,14 +7600,14 @@ This will fail in production.`); handleDownload(folder); break; case 1: - handleAiModify(folder); - break; - case 2: handleDelete(folder); break; - case 3: + case 2: openWyxdViewer(folder); break; + case 3: + handleAiModify(folder); + break; } } else { switch (res.tapIndex) { @@ -7570,7 +7649,7 @@ This will fail in production.`); initCurrentFolderList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:352", "重命名失败:", error); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:354", "重命名失败:", error); uni.showToast({ title: typeof error === "string" ? error : "重命名失败,请重试", icon: "error" @@ -7615,8 +7694,8 @@ This will fail in production.`); uni.hideLoading(); if (downloadRes.statusCode === 200) { const tempPath = downloadRes.tempFilePath; - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:409", "// 下载成功,文件下载路径为:", tempPath); - openFile(tempPath); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:411", "// 下载成功,文件下载路径为:", tempPath); + openFile$1(tempPath); } else { uni.showToast({ title: "下载失败", @@ -7626,7 +7705,7 @@ This will fail in production.`); }, fail: (err) => { uni.hideLoading(); - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:420", "下载文件失败:", err); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:422", "下载文件失败:", err); uni.showToast({ title: "下载失败,请重试", icon: "error" @@ -7635,52 +7714,24 @@ This will fail in production.`); }); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:429", "获取下载链接失败:", error); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:431", "获取下载链接失败:", error); uni.showToast({ title: "获取下载链接失败,请重试", icon: "error" }); } }; - const openFile = (filePath) => { - uni.openDocument({ - filePath, - success: () => uni.showToast({ - title: "打开成功", - icon: "success" - }), - fail: (err) => { - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:446", "打开文件失败:", err); - uni.showToast({ - title: "无法打开此文件", - icon: "error" - }); - } - }); - }; - const openFileWithMenu = (filePath) => { - uni.openDocument({ - filePath, - showMenu: true, - success: () => uni.showToast({ - title: "打开成功", - icon: "success" - }), - fail: (err) => { - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:465", "打开文件失败:", err); - uni.showToast({ - title: "无法打开此文件", - icon: "error" - }); - } + const openFile$1 = (filePath) => { + openFile(filePath, () => { + uni.showToast({ title: "无法打开此文件", icon: "error" }); }); }; const openWyxdViewer = (folder) => { const filePath = folder.path.startsWith("./") ? folder.path.slice(2) : folder.path; - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:477", "解析文件路径:", filePath); - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:478", "folder", folder); - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:479", "encode", encodeURIComponent(filePath)); - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:480", "encode", encodeURIComponent(folder.name)); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:449", "解析文件路径:", filePath); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:450", "folder", folder); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:451", "encode", encodeURIComponent(filePath)); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:452", "encode", encodeURIComponent(folder.name)); uni.navigateTo({ url: "/pages/WYXD/WYXD?workspaceId=" + encodeURIComponent(workspaceId.value) + "&filePath=" + encodeURIComponent(filePath) + "&fileName=" + encodeURIComponent(folder.name) + "&userToken=" + encodeURIComponent(UserToken.value) }); @@ -7699,7 +7750,7 @@ This will fail in production.`); if (res.confirm) { try { const filePath = `./${folder.path}`; - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:510", "删除的是:", filePath); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:482", "删除的是:", filePath); await daleteWorkspace(UserToken.value, workspaceId.value, filePath); uni.showToast({ title: "删除成功", @@ -7707,7 +7758,7 @@ This will fail in production.`); }); initCurrentFolderList(); } catch (error) { - formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:518", "删除失败:", error); + formatAppLog("error", "at pages/WorkSpace/WorkSpace.vue:490", "删除失败:", error); uni.showToast({ title: "删除失败,请重试", icon: "error" @@ -7775,7 +7826,7 @@ This will fail in production.`); const currentFolderList = vue.ref([]); const getCurrentFolderList = () => { var _a, _b; - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:599", "当前路径为:", JSON.stringify(folderStack.value)); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:571", "当前路径为:", JSON.stringify(folderStack.value)); const currentPath = folderStack.value.length > 0 ? folderStack.value[folderStack.value.length - 1].path : "."; if (currentPath === ".") { return ((_a = allFoldersData.value) == null ? void 0 : _a.children) || []; @@ -7799,7 +7850,7 @@ This will fail in production.`); const initCurrentFolderList = async () => { workspaceId.value = getWorkspaceId(); UserToken.value = getToken(); - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:626", "getWorkspaceId:", workspaceId.value); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:598", "getWorkspaceId:", workspaceId.value); allFoldersData.value = await getWorkspaceList(UserToken.value, workspaceId.value); currentFolderList.value = getCurrentFolderList(); }; @@ -7846,7 +7897,7 @@ This will fail in production.`); uni.navigateBack({ delta: 1, fail() { - formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:686", "返回失败,进入兜底跳转"); + formatAppLog("log", "at pages/WorkSpace/WorkSpace.vue:658", "返回失败,进入兜底跳转"); uni.reLaunch({ url: "/pages/Chat/Chat" }); @@ -7857,7 +7908,7 @@ This will fail in production.`); vue.onMounted(() => { initCurrentFolderList(); }); - const __returned__ = { UserToken, workspaceId, navbarBeforeTitle, navbarTitle, isSelectFolder, selectFileList, handleSelectFolder, selectFolder, showNewFolder, isNFNFocused, newFolderName, closeNewFolderModal, newWorkspaceFolder, handleUploadFile, doUploadWorkspaceFiles, currentFolderPath, folderPathPreview, confirmCreateFolder, handleLongPress, handleRename, handleDownload, openFile, openFileWithMenu, openWyxdViewer, handleAiModify, handleDelete, isMenuOpen, handleMenu, searchKeyword, isSearchFocus, handleSearchFocus, getFileIcon, allFoldersData, folderStack, currentFolderList, getCurrentFolderList, initCurrentFolderList, handleFolderClick, handleSelectAll, handleBackOrCheck, onMounted: vue.onMounted, ref: vue.ref, computed: vue.computed, get getWorkspaceId() { + const __returned__ = { UserToken, workspaceId, navbarBeforeTitle, navbarTitle, isSelectFolder, selectFileList, handleSelectFolder, selectFolder, showNewFolder, isNFNFocused, newFolderName, closeNewFolderModal, newWorkspaceFolder, handleUploadFile, doUploadWorkspaceFiles, currentFolderPath, folderPathPreview, confirmCreateFolder, handleLongPress, handleRename, handleDownload, openFile: openFile$1, openWyxdViewer, handleAiModify, handleDelete, isMenuOpen, handleMenu, searchKeyword, isSearchFocus, handleSearchFocus, getFileIcon, allFoldersData, folderStack, currentFolderList, getCurrentFolderList, initCurrentFolderList, handleFolderClick, handleSelectAll, handleBackOrCheck, onMounted: vue.onMounted, ref: vue.ref, computed: vue.computed, get getWorkspaceId() { return getWorkspaceId; }, get getToken() { return getToken; @@ -7877,6 +7928,8 @@ This will fail in production.`); return workspaceUploadFileByURL; }, get updateWorkspaceFileName() { return updateWorkspaceFileName; + }, get openFileNative() { + return openFile; } }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; @@ -10077,7 +10130,7 @@ This will fail in production.`); personalFiles.value = personalData || []; } } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:689", "获取文件列表失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:690", "获取文件列表失败:", error); rawPersonalFileData.value = []; personalFiles.value = []; } @@ -10086,11 +10139,11 @@ This will fail in production.`); try { teamId = teamId == null ? "" : String(teamId); const teamData = await getCloudFileList(userToken.value, "team", "/", teamId); - formatAppLog("log", "at pages/CloudDatabase/CloudDatabase.vue:700", "团队云端文件:", JSON.stringify(teamData)); + formatAppLog("log", "at pages/CloudDatabase/CloudDatabase.vue:701", "团队云端文件:", JSON.stringify(teamData)); rawTeamFileData.value = teamData || []; teamFiles.value = teamData || []; } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:704", "获取团队文件列表失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:705", "获取团队文件列表失败:", error); rawTeamFileData.value = []; teamFiles.value = []; } @@ -10177,7 +10230,7 @@ This will fail in production.`); uni.hideLoading(); if (downloadRes.statusCode === 200) { const tempPath = downloadRes.tempFilePath; - openFile(tempPath); + openFile$1(tempPath); } else { uni.showToast({ title: "下载失败", @@ -10195,29 +10248,21 @@ This will fail in production.`); }); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:821", "下载失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:822", "下载失败:", error); uni.showToast({ title: "下载失败,请重试", icon: "error" }); } }; - const openFile = (filePath) => { - uni.openDocument({ - filePath, - success: () => uni.showToast({ - title: "打开成功", - icon: "success" - }), - fail: (err) => { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:838", "打开文件失败:", err); - openFileWithMenu(filePath); - } + const openFile$1 = (filePath) => { + openFile(filePath, () => { + openFileWithMenu(filePath); }); }; const openFileWithMenu = (filePath) => { plus.runtime.openFile(filePath, {}, (e2) => { - formatAppLog("log", "at pages/CloudDatabase/CloudDatabase.vue:850", "文件打开成功"); + formatAppLog("log", "at pages/CloudDatabase/CloudDatabase.vue:842", "文件打开成功"); }); }; const handleRename = (file) => { @@ -10259,7 +10304,7 @@ This will fail in production.`); refreshCurrentFileList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:916", "deleteCloudFile 失败,尝试 daleteWorkspace:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:908", "deleteCloudFile 失败,尝试 daleteWorkspace:", error); try { const filePath = file.path || "/" + file.name; if (workspaceId.value) { @@ -10271,7 +10316,7 @@ This will fail in production.`); }); refreshCurrentFileList(); } catch (err2) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:928", "删除失败:", err2); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:920", "删除失败:", err2); uni.showToast({ title: "删除失败,请重试", icon: "error" @@ -10321,7 +10366,7 @@ This will fail in production.`); closeNewFolderModal(); refreshCurrentFileList(); } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:985", "创建文件夹失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:977", "创建文件夹失败:", error); uni.showToast({ title: "创建失败,请重试", icon: "error" @@ -10364,7 +10409,7 @@ This will fail in production.`); doUploadFiles(tempFiles); }, fail: (err) => { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1035", "选择文件失败:", err); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1027", "选择文件失败:", err); } }); }; @@ -10385,7 +10430,7 @@ This will fail in production.`); refreshCurrentFileList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1061", "上传文件失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1053", "上传文件失败:", error); uni.showToast({ title: "上传失败,请重试", icon: "error" @@ -10405,7 +10450,7 @@ This will fail in production.`); const list = await getCloudDbList(token); allDatabases.value = list || []; } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1087", "获取数据库列表失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1079", "获取数据库列表失败:", error); allDatabases.value = []; } finally { isDbLoading.value = false; @@ -10435,7 +10480,7 @@ This will fail in production.`); await fetchDbList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1118", "创建数据库失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1110", "创建数据库失败:", error); uni.showToast({ title: "创建失败,请重试", icon: "error" }); } }; @@ -10460,7 +10505,7 @@ This will fail in production.`); uploadDbFilePath.value = file.path; }, fail: (err) => { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1147", "选择文件失败:", err); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1139", "选择文件失败:", err); uni.showToast({ title: "选择文件失败", icon: "none" }); } }); @@ -10487,7 +10532,7 @@ This will fail in production.`); await fetchDbList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1175", "上传数据库失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1167", "上传数据库失败:", error); uni.showToast({ title: "上传失败,请重试", icon: "error" }); } }; @@ -10506,7 +10551,7 @@ This will fail in production.`); await fetchDbList(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1195", "删除数据库失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1187", "删除数据库失败:", error); uni.showToast({ title: "删除失败,请重试", icon: "error" }); } } @@ -10564,12 +10609,12 @@ This will fail in production.`); const groups = await getTeamList(token); teamGroups.value = groups || []; } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1264", "获取团队列表失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1256", "获取团队列表失败:", error); teamGroups.value = []; } }; const selectTeam = async (teamId) => { - formatAppLog("log", "at pages/CloudDatabase/CloudDatabase.vue:1270", "团队id为", teamId); + formatAppLog("log", "at pages/CloudDatabase/CloudDatabase.vue:1262", "团队id为", teamId); currentTeamId.value = teamId; try { const token = getToken(); @@ -10588,7 +10633,7 @@ This will fail in production.`); }; }); } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1287", "获取团队成员失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1279", "获取团队成员失败:", error); currentTeamMembers.value = []; } currentFolderPath.value = []; @@ -10620,7 +10665,7 @@ This will fail in production.`); }; }); } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1321", "获取团队成员失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1313", "获取团队成员失败:", error); uni.showToast({ title: "获取团队信息失败", icon: "none" }); return; } @@ -10682,7 +10727,7 @@ This will fail in production.`); currentTeamId.value = currentTeamId.value; } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1393", "修改团队信息失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1385", "修改团队信息失败:", error); uni.showToast({ title: "修改失败,请重试", icon: "error" }); } }; @@ -10703,7 +10748,7 @@ This will fail in production.`); await refreshTeamMembers(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1418", "调整成员身份失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1410", "调整成员身份失败:", error); uni.showToast({ title: "操作失败,请重试", icon: "error" }); } } @@ -10727,7 +10772,7 @@ This will fail in production.`); await refreshTeamMembers(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1444", "移除团队成员失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1436", "移除团队成员失败:", error); uni.showToast({ title: "移除失败,请重试", icon: "error" }); } } @@ -10767,7 +10812,7 @@ This will fail in production.`); if (searchResultList.value.length === 0) { } } catch (error) { - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1486", "搜索用户失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1478", "搜索用户失败:", error); searchResultList.value = []; searched.value = true; } @@ -10790,7 +10835,7 @@ This will fail in production.`); await refreshTeamMembers(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1512", "添加团队成员失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1504", "添加团队成员失败:", error); uni.showToast({ title: "添加失败,请重试", icon: "error" }); } } @@ -10821,7 +10866,7 @@ This will fail in production.`); closeTeamManage(); } catch (error) { uni.hideLoading(); - formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1546", "删除团队失败:", error); + formatAppLog("error", "at pages/CloudDatabase/CloudDatabase.vue:1538", "删除团队失败:", error); uni.showToast({ title: "删除失败,请重试", icon: "error" }); } } @@ -10833,7 +10878,7 @@ This will fail in production.`); await fetchTeamList(); await fetchDbList(); }); - const __returned__ = { userToken, userId, workspaceId, currentCategory, switchCategory, navbarTitle, isMenuOpen, isSelectFolder, selectFileList, handleMenu, handleSelectFolder, parentFolderName, handleBackOrUp, rawPersonalFileData, rawTeamFileData, personalFiles, teamFiles, currentFolderPath, isFolder, getFileExtension, getFileIcon, formatFileSize, currentFolderDisplayPath, personalFileCount, findFolderByPath, loadCurrentFiles, fetchFileList, fetchTeamFileList, handleFileClick, handleFileLongPress, handleDownload, openFile, openFileWithMenu, handleRename, handleDeleteFile, refreshCurrentFileList, showNewFolder, newFolderName, openNewFolderModal, closeNewFolderModal, confirmCreateFolder, showUploadPathInput, uploadPath, handleUploadFile, closeUploadPathInput, confirmUploadPath, chooseAndUploadFile, doUploadFiles, allDatabases, isDbLoading, personalDatabases, teamDatabases, showNewDb, newDbName, fetchDbList, openNewDbModal, closeNewDbModal, confirmCreateDb, showUploadDb, uploadDbFileName, uploadDbFilePath, openUploadDbModal, closeUploadDbModal, handlePickDbFile, confirmUploadDb, handleDeleteDb, handleDbClick, formatDbTime, getAccessLevelLabel, showTeamManage, teamGroups, currentTeamId, currentTeamMembers, inviteKeyword, currentTeamDescription, currentTeamType, currentUserRoleInTeam, isTeamAdmin, fetchTeamList, selectTeam, openTeamManage, closeTeamManage, showEditTeam, editTeamName, editTeamDesc, editTeamType, openEditTeamModal, closeEditTeamModal, confirmEditTeam, toggleMemberRole, removeTeamMemberHandler, refreshTeamMembers, searchResultList, searched, searchTeamMember, addTeamMemberHandler, handleDeleteTeam, onMounted: vue.onMounted, ref: vue.ref, computed: vue.computed, get getToken() { + const __returned__ = { userToken, userId, workspaceId, currentCategory, switchCategory, navbarTitle, isMenuOpen, isSelectFolder, selectFileList, handleMenu, handleSelectFolder, parentFolderName, handleBackOrUp, rawPersonalFileData, rawTeamFileData, personalFiles, teamFiles, currentFolderPath, isFolder, getFileExtension, getFileIcon, formatFileSize, currentFolderDisplayPath, personalFileCount, findFolderByPath, loadCurrentFiles, fetchFileList, fetchTeamFileList, handleFileClick, handleFileLongPress, handleDownload, openFile: openFile$1, openFileWithMenu, handleRename, handleDeleteFile, refreshCurrentFileList, showNewFolder, newFolderName, openNewFolderModal, closeNewFolderModal, confirmCreateFolder, showUploadPathInput, uploadPath, handleUploadFile, closeUploadPathInput, confirmUploadPath, chooseAndUploadFile, doUploadFiles, allDatabases, isDbLoading, personalDatabases, teamDatabases, showNewDb, newDbName, fetchDbList, openNewDbModal, closeNewDbModal, confirmCreateDb, showUploadDb, uploadDbFileName, uploadDbFilePath, openUploadDbModal, closeUploadDbModal, handlePickDbFile, confirmUploadDb, handleDeleteDb, handleDbClick, formatDbTime, getAccessLevelLabel, showTeamManage, teamGroups, currentTeamId, currentTeamMembers, inviteKeyword, currentTeamDescription, currentTeamType, currentUserRoleInTeam, isTeamAdmin, fetchTeamList, selectTeam, openTeamManage, closeTeamManage, showEditTeam, editTeamName, editTeamDesc, editTeamType, openEditTeamModal, closeEditTeamModal, confirmEditTeam, toggleMemberRole, removeTeamMemberHandler, refreshTeamMembers, searchResultList, searched, searchTeamMember, addTeamMemberHandler, handleDeleteTeam, onMounted: vue.onMounted, ref: vue.ref, computed: vue.computed, get getToken() { return getToken; }, get chooseFile() { return chooseFile; @@ -10877,6 +10922,8 @@ This will fail in production.`); return uploadCloudDbFile; }, get deleteCloudDb() { return deleteCloudDb; + }, get openFileNative() { + return openFile; } }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; @@ -12903,7 +12950,7 @@ This will fail in production.`); if (friendSocketStore.isConnected) return; if (!userToken.value || !UserId.value) { - formatAppLog("warn", "at pages/text/text.vue:334", "Token或UserId未准备好"); + formatAppLog("warn", "at pages/text/text.vue:335", "Token或UserId未准备好"); return; } friendSocketStore.connect({ @@ -12986,7 +13033,7 @@ This will fail in production.`); ); return html; } catch (e2) { - formatAppLog("error", "at pages/text/text.vue:455", "解析失败", e2); + formatAppLog("error", "at pages/text/text.vue:456", "解析失败", e2); return content; } }; @@ -13006,16 +13053,8 @@ This will fail in production.`); urls: [url] }); }; - const openFile = (url) => { - uni.downloadFile({ - url, - success: (res) => { - uni.openDocument({ - filePath: res.tempFilePath, - showMenu: true - }); - } - }); + const openFile$1 = (url) => { + downloadAndOpen(url); }; const formatFileSize = (size) => { if (!size) @@ -13045,7 +13084,7 @@ This will fail in production.`); files }; } catch (e2) { - formatAppLog("error", "at pages/text/text.vue:532", "解析文件信息失败:", e2); + formatAppLog("error", "at pages/text/text.vue:525", "解析文件信息失败:", e2); return { textContent: content, files: [] @@ -13082,7 +13121,7 @@ This will fail in production.`); } takeUserConversations(); } catch (error) { - formatAppLog("error", "at pages/text/text.vue:577", "新建普通会话失败:", error); + formatAppLog("error", "at pages/text/text.vue:570", "新建普通会话失败:", error); uni.showToast({ title: "创建会话失败,请重试", icon: "none" @@ -13120,7 +13159,7 @@ This will fail in production.`); }; const previewFileArray = vue.ref([]); const uploadPhoto = () => { - formatAppLog("log", "at pages/text/text.vue:626", "点击了拍照上传"); + formatAppLog("log", "at pages/text/text.vue:619", "点击了拍照上传"); uni.chooseImage({ count: 1, sourceType: ["camera", "album"], @@ -13143,7 +13182,7 @@ This will fail in production.`); }); }, fail: (err) => { - formatAppLog("error", "at pages/text/text.vue:644", "选择图片失败", err); + formatAppLog("error", "at pages/text/text.vue:637", "选择图片失败", err); } }); }; @@ -13152,12 +13191,12 @@ This will fail in production.`); }; const fileList = vue.ref([]); const uploadFile = () => { - formatAppLog("log", "at pages/text/text.vue:655", "点击了上传文件"); + formatAppLog("log", "at pages/text/text.vue:648", "点击了上传文件"); chooseFile({ count: 5, type: "all", success: (res) => { - formatAppLog("log", "at pages/text/text.vue:660", "成功了"); + formatAppLog("log", "at pages/text/text.vue:653", "成功了"); fileList.value = res.tempFiles; previewFileArray.value.push(...res.tempFiles); uni.showToast({ @@ -13166,7 +13205,7 @@ This will fail in production.`); }); }, fail: (err) => { - formatAppLog("error", "at pages/text/text.vue:671", "选择失败:", err); + formatAppLog("error", "at pages/text/text.vue:664", "选择失败:", err); uni.showToast({ title: "选择失败", icon: "error" @@ -13366,7 +13405,7 @@ This will fail in production.`); previewFileArray.value = []; } catch (err) { uni.hideLoading(); - formatAppLog("error", "at pages/text/text.vue:895", "文件上传失败:", err); + formatAppLog("error", "at pages/text/text.vue:888", "文件上传失败:", err); uni.showToast({ title: "文件上传失败,请重试", icon: "error" @@ -13500,15 +13539,15 @@ This will fail in production.`); } }; const stopConversation = async () => { - formatAppLog("log", "at pages/text/text.vue:1064", "中断对话 - 当前会话ID:", currentSessionId.value); + formatAppLog("log", "at pages/text/text.vue:1057", "中断对话 - 当前会话ID:", currentSessionId.value); try { await socketStore.send({ type: "stop", conversation_id: currentSessionId.value }); - formatAppLog("log", "at pages/text/text.vue:1070", "中断指令已发送成功"); + formatAppLog("log", "at pages/text/text.vue:1063", "中断指令已发送成功"); } catch (err) { - formatAppLog("error", "at pages/text/text.vue:1072", "中断指令发送失败:", err); + formatAppLog("error", "at pages/text/text.vue:1065", "中断指令发送失败:", err); } if (streamingMessageId.value) { allmessages.value = allmessages.value.filter((m) => m._id !== streamingMessageId.value); @@ -13526,9 +13565,9 @@ This will fail in production.`); }); }; vue.watch(() => socketStore.isThinking, (newVal, oldVal) => { - formatAppLog("log", "at pages/text/text.vue:1096", "isThinking 变化:", oldVal, "→", newVal, "messageString:", socketStore.messageString); + formatAppLog("log", "at pages/text/text.vue:1089", "isThinking 变化:", oldVal, "→", newVal, "messageString:", socketStore.messageString); if (!oldVal && newVal) { - formatAppLog("log", "at pages/text/text.vue:1099", "AI开始回复(跨设备同步),锁定输入框"); + formatAppLog("log", "at pages/text/text.vue:1092", "AI开始回复(跨设备同步),锁定输入框"); isThinking.value = true; if (!streamingMessageId.value) { streamingMessageId.value = "streaming-" + Date.now(); @@ -13542,7 +13581,7 @@ This will fail in production.`); return; } if (oldVal && !newVal) { - formatAppLog("log", "at pages/text/text.vue:1115", "AI回复结束(正常/中断),解锁并刷新消息列表"); + formatAppLog("log", "at pages/text/text.vue:1108", "AI回复结束(正常/中断),解锁并刷新消息列表"); if (streamingMessageId.value) { allmessages.value = allmessages.value.filter((m) => m._id !== streamingMessageId.value); streamingMessageId.value = null; @@ -13558,14 +13597,16 @@ This will fail in production.`); if (reason === "pc offline") { isThinking.value = false; socketStore.authFailReason = ""; - vue.nextTick(() => { - uni.showModal({ - title: "提示", - content: "PC端不在线,不可聊天", - showCancel: false, - confirmText: "知道了" - }); + uni.showToast({ + title: "PC端不在线", + icon: "none", + duration: 1500 }); + setTimeout(() => { + uni.reLaunch({ + url: "/pages/Login/Login" + }); + }, 1500); } }); vue.watch(() => socketStore.messageString, (newContent) => { @@ -13594,15 +13635,15 @@ This will fail in production.`); UserData.value = await getUserInfo(userToken.value); UserId.value = UserData.value._id; UserAvatar.value = UserData.value.avatar || ""; - formatAppLog("log", "at pages/text/text.vue:1179", "用户信息已加载:", UserId.value, UserAvatar.value); + formatAppLog("log", "at pages/text/text.vue:1174", "用户信息已加载:", UserId.value, UserAvatar.value); } catch (error) { - formatAppLog("error", "at pages/text/text.vue:1181", "获取用户信息失败:", error); + formatAppLog("error", "at pages/text/text.vue:1176", "获取用户信息失败:", error); } }; const takeUserConversations = async () => { try { userToken.value = getToken(); - formatAppLog("log", "at pages/text/text.vue:1189", "token:", userToken.value); + formatAppLog("log", "at pages/text/text.vue:1184", "token:", userToken.value); UserConversations.value = await getUserConversations(userToken.value) || []; const savedSessionId = getCurrentSessionId(); if (savedSessionId && UserConversations.value.some((c) => c._id === savedSessionId)) { @@ -13612,7 +13653,7 @@ This will fail in production.`); } else { currentSessionId.value = ""; } - formatAppLog("log", "at pages/text/text.vue:1201", "保存会话id:", currentSessionId.value); + formatAppLog("log", "at pages/text/text.vue:1196", "保存会话id:", currentSessionId.value); uni.setStorageSync("currentSessionId", currentSessionId.value); } catch (error) { uni.showToast({ @@ -13624,17 +13665,17 @@ This will fail in production.`); const FriendInfoList = vue.ref([]); const takeFriendList = async () => { try { - formatAppLog("log", "at pages/text/text.vue:1216", "开始获取好友列表"); + formatAppLog("log", "at pages/text/text.vue:1211", "开始获取好友列表"); const friendList = await getChatFriend(UserId.value); - formatAppLog("log", "at pages/text/text.vue:1219", "friendList:", friendList); + formatAppLog("log", "at pages/text/text.vue:1214", "friendList:", friendList); if (friendList && friendList.length) { FriendInfoList.value = await takeUserAvatar(friendList); } else { FriendInfoList.value = []; - formatAppLog("log", "at pages/text/text.vue:1224", "好友列表为空"); + formatAppLog("log", "at pages/text/text.vue:1219", "好友列表为空"); } } catch (error) { - formatAppLog("error", "at pages/text/text.vue:1227", "获取好友列表失败:", error); + formatAppLog("error", "at pages/text/text.vue:1222", "获取好友列表失败:", error); FriendInfoList.value = []; } finally { UserConversations.value = FriendInfoList.value; @@ -13661,17 +13702,17 @@ This will fail in production.`); }; }); } catch (err) { - formatAppLog("error", "at pages/text/text.vue:1257", "获取好友头像失败", err); + formatAppLog("error", "at pages/text/text.vue:1252", "获取好友头像失败", err); return friendList; } }; const GroupList = vue.ref([]); const takeGroupList = async () => { try { - formatAppLog("log", "at pages/text/text.vue:1267", "开始获取群聊列表"); + formatAppLog("log", "at pages/text/text.vue:1262", "开始获取群聊列表"); GroupList.value = await getGroup(UserId.value); } catch (error) { - formatAppLog("error", "at pages/text/text.vue:1272", "获取群聊列表失败:", error); + formatAppLog("error", "at pages/text/text.vue:1267", "获取群聊列表失败:", error); GroupList.value = []; } finally { UserConversations.value = GroupList.value; @@ -13683,22 +13724,22 @@ This will fail in production.`); return []; try { const memberIds = memberList.map((item) => item.groupContactId); - formatAppLog("log", "at pages/text/text.vue:1286", "请求头像的ID列表:", memberIds); + formatAppLog("log", "at pages/text/text.vue:1281", "请求头像的ID列表:", memberIds); const memberAvatarList = await getUserAvatar(userToken.value, memberIds); - formatAppLog("log", "at pages/text/text.vue:1288", "头像接口返回数据:", memberAvatarList); + formatAppLog("log", "at pages/text/text.vue:1283", "头像接口返回数据:", memberAvatarList); const userMap = new Map(memberAvatarList.map((user) => [user.user_id, user]) || []); - formatAppLog("log", "at pages/text/text.vue:1291", "userMap的keys:", Array.from(userMap.keys())); + formatAppLog("log", "at pages/text/text.vue:1286", "userMap的keys:", Array.from(userMap.keys())); return memberList.map((member) => { const memberId = member.groupContactId; const userInfo = userMap.get(memberId); - formatAppLog("log", "at pages/text/text.vue:1296", `查找 ${memberId} 的头像:`, userInfo); + formatAppLog("log", "at pages/text/text.vue:1291", `查找 ${memberId} 的头像:`, userInfo); return { ...member, avatar: (userInfo == null ? void 0 : userInfo.avatar) || null }; }); } catch (err) { - formatAppLog("error", "at pages/text/text.vue:1303", "获取群成员头像失败", err); + formatAppLog("error", "at pages/text/text.vue:1298", "获取群成员头像失败", err); return memberList; } }; @@ -13741,12 +13782,12 @@ This will fail in production.`); const takeGroupMessages = async () => { try { allmessages.value = await getGroupMessages(currentSessionId.value) || []; - formatAppLog("log", "at pages/text/text.vue:1363", "群聊消息:", allmessages.value); + formatAppLog("log", "at pages/text/text.vue:1358", "群聊消息:", allmessages.value); const memberList = await getGroupMemberList(currentSessionId.value); - formatAppLog("log", "at pages/text/text.vue:1366", "获取到的群成员列表:", memberList); + formatAppLog("log", "at pages/text/text.vue:1361", "获取到的群成员列表:", memberList); if (memberList && memberList.length) { groupMemberList.value = await takeGroupMemberAvatar(memberList); - formatAppLog("log", "at pages/text/text.vue:1369", "群成员列表(带头像):", groupMemberList.value); + formatAppLog("log", "at pages/text/text.vue:1364", "群成员列表(带头像):", groupMemberList.value); } else { groupMemberList.value = []; } @@ -13768,9 +13809,9 @@ This will fail in production.`); } }; vue.watch(() => friendSocketStore.MessageReceived, (newId) => { - formatAppLog("log", "at pages/text/text.vue:1414", "收到了好友消息"); + formatAppLog("log", "at pages/text/text.vue:1409", "收到了好友消息"); if (newId) { - formatAppLog("log", "at pages/text/text.vue:1416", "ChatType:", ChatType.value); + formatAppLog("log", "at pages/text/text.vue:1411", "ChatType:", ChatType.value); switch (ChatType.value) { case 0: takeConversationMessages(); @@ -13785,7 +13826,7 @@ This will fail in production.`); friendSocketStore.MessageReceived = false; break; default: - formatAppLog("log", "at pages/text/text.vue:1432", "default 分支"); + formatAppLog("log", "at pages/text/text.vue:1427", "default 分支"); friendSocketStore.MessageReceived = false; break; } @@ -13847,7 +13888,7 @@ This will fail in production.`); onUnload(() => { socketStore.disconnect(); }); - const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, convertMarkdownTable, renderTable, escapeLoneUnderscores, pareseMarkdown, sanitizeContent, previewImage, openFile, formatFileSize, parseFileInfo, selectNormalChat, showNewChatModal, closeNewChatModal, isChatSidebar, handleChatSidebar, goWorkSpace, goCloudDatabase, logOut, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isSelfSent, isUploading, uploadedFiles, streamingMessageId, showMessageModal, detailLinks, handleChatContentClick, extractLinks, extractFileNameFromUrl, showMessageDetail, closeMessageDetail, downloadToast, get downloadToastTimer() { + const __returned__ = { friendSocketStore, handleFriendConnect, socketStore, ChatType, convertMarkdownTable, renderTable, escapeLoneUnderscores, pareseMarkdown, sanitizeContent, previewImage, openFile: openFile$1, formatFileSize, parseFileInfo, selectNormalChat, showNewChatModal, closeNewChatModal, isChatSidebar, handleChatSidebar, goWorkSpace, goCloudDatabase, logOut, previewFileArray, uploadPhoto, deleteImage, fileList, uploadFile, handleConnect, isThinking, isSelfSent, isUploading, uploadedFiles, streamingMessageId, showMessageModal, detailLinks, handleChatContentClick, extractLinks, extractFileNameFromUrl, showMessageDetail, closeMessageDetail, downloadToast, get downloadToastTimer() { return downloadToastTimer; }, set downloadToastTimer(v) { downloadToastTimer = v; @@ -13903,6 +13944,8 @@ This will fail in production.`); return chooseFile; }, get socketManager() { return socketManager; + }, get openFileNative() { + return openFile; } }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; diff --git a/unpackage/dist/dev/app-plus/manifest.json b/unpackage/dist/dev/app-plus/manifest.json index bb75db3..dc0a2bb 100644 --- a/unpackage/dist/dev/app-plus/manifest.json +++ b/unpackage/dist/dev/app-plus/manifest.json @@ -5,7 +5,7 @@ "iPad" ], "id": "__UNI__923FD9E", - "name": "test1", + "name": "宇恒一号", "version": { "name": "1.1.1", "code": 2 diff --git a/utils/fileOpener.js b/utils/fileOpener.js new file mode 100644 index 0000000..ce56409 --- /dev/null +++ b/utils/fileOpener.js @@ -0,0 +1,124 @@ +/** + * 文件打开工具 - 强制弹出应用选择器 + * + * uni.openDocument 的 showMenu 和 plus.runtime.openFile 在真机上 + * 都可能直接跳转默认应用。用 Android 原生 Intent.createChooser + * 强制弹出"选择应用"对话框。 + * + * Android 7.0+ 会阻止 file:// URI 暴露给其他应用,需要禁用此限制。 + */ + +/** + * 根据文件扩展名获取 MIME 类型 + */ +function getMimeType(filePath) { + const ext = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase() + const mimeMap = { + 'pdf': 'application/pdf', + 'doc': 'application/msword', + 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xls': 'application/vnd.ms-excel', + 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'ppt': 'application/vnd.ms-powerpoint', + 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'txt': 'text/plain', + 'html': 'text/html', + 'htm': 'text/html', + 'xml': 'text/xml', + 'json': 'application/json', + 'csv': 'text/csv', + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'png': 'image/png', + 'gif': 'image/gif', + 'bmp': 'image/bmp', + 'webp': 'image/webp', + 'mp4': 'video/mp4', + 'mp3': 'audio/mpeg', + 'wav': 'audio/wav', + 'zip': 'application/zip', + 'rar': 'application/x-rar-compressed', + '7z': 'application/x-7z-compressed', + 'apk': 'application/vnd.android.package-archive' + } + return mimeMap[ext] || '*/*' +} + +/** + * 打开文件,弹出应用选择器 + * @param {string} filePath 本地文件路径 + * @param {Function} onFail 打开失败时的回调 + */ +export function openFile(filePath, onFail) { + // #ifdef APP-PLUS + try { + const main = plus.android.runtimeMainActivity() + const Intent = plus.android.importClass('android.content.Intent') + const Uri = plus.android.importClass('android.net.Uri') + const File = plus.android.importClass('java.io.File') + + // Android 7.0+ 默认禁止 file:// URI,禁用此限制 + if (plus.os.sdkInt >= 24) { + const StrictMode = plus.android.importClass('android.os.StrictMode') + StrictMode.disableDeathOnFileUriExposure() + } + + const file = new File(filePath) + if (!file.exists()) { + throw new Error('文件不存在: ' + filePath) + } + + const uri = Uri.fromFile(file) + const mimeType = getMimeType(filePath) + + const intent = new Intent(Intent.ACTION_VIEW) + intent.setDataAndType(uri, mimeType) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + // 核心:createChooser 每次必弹选择器,无视已设置的默认应用 + const chooser = Intent.createChooser(intent, '选择应用打开') + main.startActivity(chooser) + + console.log('openFile success - chooser shown') + } catch (e) { + console.error('openFile native failed, fallback:', e) + uni.openDocument({ + filePath: filePath, + showMenu: true, + fail: typeof onFail === 'function' ? onFail : () => {} + }) + } + // #endif + + // #ifndef APP-PLUS + uni.openDocument({ + filePath: filePath, + showMenu: true, + fail: typeof onFail === 'function' ? onFail : () => {} + }) + // #endif +} + +/** + * 下载文件并打开(弹出应用选择器) + * @param {string} url 远程文件 URL + * @param {Function} onFail 失败回调 + */ +export function downloadAndOpen(url, onFail) { + uni.downloadFile({ + url: url, + success: (res) => { + if (res.statusCode === 200) { + openFile(res.tempFilePath, onFail) + } else { + console.error('下载失败, statusCode:', res.statusCode) + if (typeof onFail === 'function') onFail() + } + }, + fail: (err) => { + console.error('downloadFile fail:', err) + if (typeof onFail === 'function') onFail() + } + }) +}