@chenghongyu/xpt-file-viewer 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/extensions.json +3 -0
- package/README.md +5 -0
- package/auto-imports.d.ts +12 -0
- package/components.d.ts +45 -0
- package/dist.zip +0 -0
- package/index.html +13 -0
- package/package.json +100 -0
- package/presets/eslint/.eslintrc-auto-import.json +462 -0
- package/presets/plugins/html.ts +14 -0
- package/presets/shared/env.ts +46 -0
- package/presets/shared/resolvers.ts +29 -0
- package/presets/tov.ts +132 -0
- package/presets/types/auto-imports.d.ts +806 -0
- package/presets/types/components.d.ts +164 -0
- package/presets/types/env.d.ts +17 -0
- package/public/favicon.svg +1 -0
- package/public/icons.svg +24 -0
- package/public/testfile/README.md +5 -0
- package/public/testfile/useFileContextMenu.js +74 -0
- package/public/testfile//345/217/221/347/245/250.pdf +0 -0
- package/public/testfile//346/216/245/346/224/266/345/207/275.docx +0 -0
- package/public/testfile//350/247/204/346/240/274/345/236/213/345/217/2671.txt +263 -0
- package/public/testfile//350/247/206/351/242/2211.mp4 +0 -0
- package/public/testfile//351/237/263/351/242/2211.mp3 +0 -0
- package/src/App.vue +8 -0
- package/src/api/admin/admin-2fa.js +18 -0
- package/src/api/admin/admin-download-log.js +37 -0
- package/src/api/admin/admin-login-log.js +9 -0
- package/src/api/admin/admin-permission.js +9 -0
- package/src/api/admin/admin-setting.js +121 -0
- package/src/api/admin/admin-share.js +20 -0
- package/src/api/admin/admin-short-link.js +49 -0
- package/src/api/admin/admin-sso.js +38 -0
- package/src/api/admin/admin-storage.js +189 -0
- package/src/api/admin/admin-user.js +61 -0
- package/src/api/home/common.js +9 -0
- package/src/api/home/file-operator.js +89 -0
- package/src/api/home/home.js +87 -0
- package/src/api/home/install.js +18 -0
- package/src/api/home/login.js +9 -0
- package/src/api/home/only-office.js +10 -0
- package/src/api/home/share.js +115 -0
- package/src/api/home/user.js +74 -0
- package/src/api/tools/tools-115.js +17 -0
- package/src/api/tools/tools-gd.js +13 -0
- package/src/api/tools/tools-s3.js +25 -0
- package/src/api/tools/tools-sharepoint.js +19 -0
- package/src/assets/hero.png +0 -0
- package/src/assets/icons/401.svg +1 -0
- package/src/assets/icons/403.svg +45 -0
- package/src/assets/icons/404.svg +1 -0
- package/src/assets/icons/500.svg +1 -0
- package/src/assets/icons/admin-login.svg +1 -0
- package/src/assets/icons/document.svg +1 -0
- package/src/assets/icons/empty.svg +145 -0
- package/src/assets/icons/file-type-apk.svg +1 -0
- package/src/assets/icons/file-type-archive.svg +1 -0
- package/src/assets/icons/file-type-audio.svg +1 -0
- package/src/assets/icons/file-type-back.svg +1 -0
- package/src/assets/icons/file-type-css.svg +1 -0
- package/src/assets/icons/file-type-deb.svg +1 -0
- package/src/assets/icons/file-type-dll.svg +1 -0
- package/src/assets/icons/file-type-doc.svg +1 -0
- package/src/assets/icons/file-type-document.svg +1 -0
- package/src/assets/icons/file-type-docx.svg +1 -0
- package/src/assets/icons/file-type-exe.svg +1 -0
- package/src/assets/icons/file-type-expression.svg +1 -0
- package/src/assets/icons/file-type-file.svg +1 -0
- package/src/assets/icons/file-type-folder.svg +1 -0
- package/src/assets/icons/file-type-html.svg +1 -0
- package/src/assets/icons/file-type-image.svg +1 -0
- package/src/assets/icons/file-type-java.svg +1 -0
- package/src/assets/icons/file-type-js.svg +1 -0
- package/src/assets/icons/file-type-less.svg +1 -0
- package/src/assets/icons/file-type-md.svg +1 -0
- package/src/assets/icons/file-type-office.svg +1 -0
- package/src/assets/icons/file-type-pdf.svg +1 -0
- package/src/assets/icons/file-type-php.svg +1 -0
- package/src/assets/icons/file-type-ppt.svg +1 -0
- package/src/assets/icons/file-type-pptx.svg +1 -0
- package/src/assets/icons/file-type-py.svg +1 -0
- package/src/assets/icons/file-type-rb.svg +1 -0
- package/src/assets/icons/file-type-root.svg +1 -0
- package/src/assets/icons/file-type-rpm.svg +1 -0
- package/src/assets/icons/file-type-rust.svg +1 -0
- package/src/assets/icons/file-type-script.svg +1 -0
- package/src/assets/icons/file-type-text.svg +1 -0
- package/src/assets/icons/file-type-three3d.svg +5 -0
- package/src/assets/icons/file-type-vbs.svg +1 -0
- package/src/assets/icons/file-type-video.svg +1 -0
- package/src/assets/icons/file-type-xls.svg +1 -0
- package/src/assets/icons/file-type-xlsx.svg +1 -0
- package/src/assets/icons/file-type-xml.svg +1 -0
- package/src/assets/icons/file-type-yaml.svg +1 -0
- package/src/assets/icons/file-upload.svg +1 -0
- package/src/assets/icons/github.svg +1 -0
- package/src/assets/icons/install-step.svg +40 -0
- package/src/assets/icons/reset-password.svg +1 -0
- package/src/assets/icons/storage-aliyun.svg +1 -0
- package/src/assets/icons/storage-baidu.svg +1 -0
- package/src/assets/icons/storage-doge-cloud.svg +207 -0
- package/src/assets/icons/storage-ftp.svg +13 -0
- package/src/assets/icons/storage-google-drive.svg +8 -0
- package/src/assets/icons/storage-huawei.svg +1 -0
- package/src/assets/icons/storage-local.svg +11 -0
- package/src/assets/icons/storage-minio.svg +1 -0
- package/src/assets/icons/storage-onedrive-china.svg +18 -0
- package/src/assets/icons/storage-onedrive.svg +4 -0
- package/src/assets/icons/storage-open115.svg +23 -0
- package/src/assets/icons/storage-qiniu.svg +1 -0
- package/src/assets/icons/storage-s3.svg +5 -0
- package/src/assets/icons/storage-sftp.svg +13 -0
- package/src/assets/icons/storage-sharepoint-china.svg +23 -0
- package/src/assets/icons/storage-sharepoint.svg +1 -0
- package/src/assets/icons/storage-tencent.svg +9 -0
- package/src/assets/icons/storage-ufile.svg +14 -0
- package/src/assets/icons/storage-upyun.svg +1 -0
- package/src/assets/icons/storage-webdav.svg +1 -0
- package/src/assets/icons/upload.svg +50 -0
- package/src/assets/icons/zfile-basic.svg +17 -0
- package/src/assets/icons/zfile-horizontal.svg +16 -0
- package/src/assets/icons/zfile.svg +1 -0
- package/src/assets/vite.svg +1 -0
- package/src/assets/vue.svg +1 -0
- package/src/components/HelloWorld.vue +319 -0
- package/src/components/common/QrCodePreview.vue +118 -0
- package/src/components/common/dialog/ZDialog.vue +171 -0
- package/src/components/common/dialog/types.ts +19 -0
- package/src/components/common/dialog/useDialog.ts +18 -0
- package/src/components/common/dialog/useDialogWithForm.ts +21 -0
- package/src/components/copy.vue +133 -0
- package/src/components/file/preview/AudioPlayer.vue +333 -0
- package/src/components/file/preview/CopyCode.vue +47 -0
- package/src/components/file/preview/FileGallery.vue +199 -0
- package/src/components/file/preview/ImageViewer.vue +432 -0
- package/src/components/file/preview/KkFileViewer.vue +86 -0
- package/src/components/file/preview/KkFileViewerDialog.vue +42 -0
- package/src/components/file/preview/MarkdownViewer.vue +102 -0
- package/src/components/file/preview/MarkdownViewerAsyncLoading.vue +17 -0
- package/src/components/file/preview/MarkdownViewerDialogAsyncLoading.vue +12 -0
- package/src/components/file/preview/OfficeViewer.vue +76 -0
- package/src/components/file/preview/OfficeViewerDialog.vue +55 -0
- package/src/components/file/preview/PdfViewer.vue +157 -0
- package/src/components/file/preview/PdfViewerDialog.vue +41 -0
- package/src/components/file/preview/TextViewer.vue +232 -0
- package/src/components/file/preview/TextViewerAsyncLoading.vue +22 -0
- package/src/components/file/preview/TextViewerDialog.vue +53 -0
- package/src/components/file/preview/Three3dPreview.vue +114 -0
- package/src/components/file/preview/Three3dPreviewDialog.vue +50 -0
- package/src/components/file/preview/VideoPlayer.vue +341 -0
- package/src/components/file/preview/VideoPlayerAsyncLoading.vue +45 -0
- package/src/components/file/preview/VideoPlayerDialog.vue +51 -0
- package/src/components/file/selectFolder/SelectFolder.vue +208 -0
- package/src/components/file/selectFolder/index.ts +50 -0
- package/src/components/file/selectFolder/types.ts +5 -0
- package/src/components/fileReview/AudioPlayer-copy.vue +333 -0
- package/src/components/fileReview/PdfViewer-copy.vue +157 -0
- package/src/components/fileReview/TextViewer-copy.vue +44 -0
- package/src/components/fileReview/VideoPlayer-copy.vue +341 -0
- package/src/components/messageBox/confirm/confirm.vue +137 -0
- package/src/components/messageBox/confirm/index.ts +27 -0
- package/src/components/messageBox/confirm/types.ts +15 -0
- package/src/components/messageBox/messageBox.ts +9 -0
- package/src/components/messageBox/prompt/index.ts +27 -0
- package/src/components/messageBox/prompt/prompt.vue +178 -0
- package/src/components/messageBox/prompt/types.ts +24 -0
- package/src/components/vue-codemirror/editor.vue +212 -0
- package/src/components/vue-codemirror/encodings.ts +27 -0
- package/src/components/vue-codemirror/index.vue +380 -0
- package/src/components/vue-codemirror/lang-code/cpp/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/css/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/dockerfile/index.ts +5 -0
- package/src/components/vue-codemirror/lang-code/erlang/index.ts +6 -0
- package/src/components/vue-codemirror/lang-code/go/index.ts +5 -0
- package/src/components/vue-codemirror/lang-code/html/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/java/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/javascript/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/json/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/jsx/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/lua/index.ts +6 -0
- package/src/components/vue-codemirror/lang-code/markdown/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/mysql/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/nginx/index.ts +6 -0
- package/src/components/vue-codemirror/lang-code/perl/index.ts +5 -0
- package/src/components/vue-codemirror/lang-code/pgsql/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/php/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/powershell/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/python/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/r/index.ts +5 -0
- package/src/components/vue-codemirror/lang-code/ruby/index.ts +5 -0
- package/src/components/vue-codemirror/lang-code/rust/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/shell/index.ts +5 -0
- package/src/components/vue-codemirror/lang-code/sql/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/stylus/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/swift/index.ts +4 -0
- package/src/components/vue-codemirror/lang-code/toml/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/tsx/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/typescript/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/vb/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/vbscript/index.ts +3 -0
- package/src/components/vue-codemirror/lang-code/xml/index.ts +2 -0
- package/src/components/vue-codemirror/lang-code/yaml/index.ts +3 -0
- package/src/components/vue-codemirror/languages.ts +8 -0
- package/src/components/vue-codemirror/themes.ts +5 -0
- package/src/components/vue-codemirror/toolbar.vue +183 -0
- package/src/components/vue-codemirror/types.ts +12 -0
- package/src/components.d.ts +49 -0
- package/src/composables/admin/layout/admin-layout.js +53 -0
- package/src/composables/admin/link/useLinkSetting.js +16 -0
- package/src/composables/admin/sso/baseSsoConfig.js +54 -0
- package/src/composables/admin/sso/useSsoConfig.js +176 -0
- package/src/composables/admin/storage/storage-copy.js +89 -0
- package/src/composables/admin/storage/storage-filter.js +64 -0
- package/src/composables/admin/storage/storage-list.js +202 -0
- package/src/composables/admin/storage/storage-password.js +101 -0
- package/src/composables/admin/storage/storage-readme.js +102 -0
- package/src/composables/admin/storage/utils/open115-util.js +61 -0
- package/src/composables/admin/useAdminSetting.js +60 -0
- package/src/composables/admin/useClientInfo.js +20 -0
- package/src/composables/admin/user/user-copy.js +79 -0
- package/src/composables/file/useBatchOperatorResult.js +19 -0
- package/src/composables/file/useFileContextMenu.js +74 -0
- package/src/composables/file/useFileData.js +243 -0
- package/src/composables/file/useFileLink.js +175 -0
- package/src/composables/file/useFileLoading.js +41 -0
- package/src/composables/file/useFileLongPressEvent.js +71 -0
- package/src/composables/file/useFileOperator.js +347 -0
- package/src/composables/file/useFilePreview.js +99 -0
- package/src/composables/file/useFilePwd.js +138 -0
- package/src/composables/file/useFileSelect.js +105 -0
- package/src/composables/file/useFileShare.js +39 -0
- package/src/composables/file/useFileUpload.js +1045 -0
- package/src/composables/file/useKkFileViewDialog.js +24 -0
- package/src/composables/file/useOfficeViewerDialog.js +20 -0
- package/src/composables/file/usePdfViewerDialog.js +22 -0
- package/src/composables/file/useShareActions.js +94 -0
- package/src/composables/file/useShareTableOperator.js +84 -0
- package/src/composables/file/useTableOperator.js +211 -0
- package/src/composables/file/useTextViewerDialog.js +22 -0
- package/src/composables/file/useThree3dPreviewDialog.js +23 -0
- package/src/composables/file/useVideoPlayerDialog.js +19 -0
- package/src/composables/header/useHeaderBreadcrumb.js +111 -0
- package/src/composables/header/useHeaderStorageList.js +150 -0
- package/src/composables/header/useSetting.js +58 -0
- package/src/composables/share/useShareData.js +178 -0
- package/src/composables/useDarks.ts +4 -0
- package/src/composables/useRouterData.js +41 -0
- package/src/constant/index.js +193 -0
- package/src/http/index.js +153 -0
- package/src/http/request.js +31 -0
- package/src/main.ts +23 -0
- package/src/stores/file-data.ts +108 -0
- package/src/stores/global-config.ts +115 -0
- package/src/stores/storage-config.ts +123 -0
- package/src/style.css +296 -0
- package/src/styles/admin.scss +91 -0
- package/src/styles/code-editor-variables.scss +52 -0
- package/src/styles/element-plus.scss +22 -0
- package/src/styles/error-page.css +26 -0
- package/src/styles/main.css +142 -0
- package/src/styles/tailwind/index.scss +33 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/models/base.ts +34 -0
- package/src/utils/models/file.ts +95 -0
- package/src/utils/models/path.ts +117 -0
- package/src/utils/models/qrcode.ts +21 -0
- package/src/utils/models/time.ts +132 -0
- package/src/utils/models/util.ts +42 -0
- package/src/utils/models/window.ts +14 -0
- package/stats.html +4950 -0
- package/tsconfig.app.json +16 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +26 -0
- package/vite.config.ts +57 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
const visible = ref(false);
|
|
3
|
+
const operatorResultList = ref([]);
|
|
4
|
+
export default function useBatchOperatorResult() {
|
|
5
|
+
|
|
6
|
+
const open = (list) => {
|
|
7
|
+
if (list && list.length > 0) {
|
|
8
|
+
operatorResultList.value = list;
|
|
9
|
+
visible.value = true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
open,
|
|
15
|
+
visible,
|
|
16
|
+
operatorResultList
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
import "v-contextmenu/dist/themes/default.css";
|
|
3
|
+
|
|
4
|
+
import useFileSelect from "~/composables/file/useFileSelect";
|
|
5
|
+
const { selectRows, clearSelection, toggleRowSelection } = useFileSelect();
|
|
6
|
+
|
|
7
|
+
import useRouterData from "~/composables/useRouterData";
|
|
8
|
+
let { storageKey, routeRef } = useRouterData();
|
|
9
|
+
|
|
10
|
+
import useFileDataStore from "~/stores/file-data";
|
|
11
|
+
let fileDataStore = useFileDataStore();
|
|
12
|
+
|
|
13
|
+
const contextMenuTargetFile = ref(false);
|
|
14
|
+
const contextMenuTargetBlank = ref(false);
|
|
15
|
+
|
|
16
|
+
let contextmenuRef;
|
|
17
|
+
|
|
18
|
+
export default function useFileContextMenu() {
|
|
19
|
+
|
|
20
|
+
const showFileMenu = (row, column, event) => {
|
|
21
|
+
// 在文件页需要存储源 key;在分享页(/share/:shareKey)允许无 storageKey
|
|
22
|
+
const inShare = !!routeRef.value.params?.shareKey;
|
|
23
|
+
if (!inShare && !storageKey.value) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 如果右键的不是空白区域,则不显示菜单
|
|
28
|
+
if (row instanceof Event) {
|
|
29
|
+
event = row;
|
|
30
|
+
let parentDom = document.querySelector(".zfile-index-body");
|
|
31
|
+
let ignoreDom = document.querySelector(".el-dialog");
|
|
32
|
+
if (!parentDom.contains(event.target) || ignoreDom?.contains(event.target)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
contextMenuTargetBlank.value = true;
|
|
36
|
+
} else {
|
|
37
|
+
if (row.type === 'BACK') {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
fileDataStore.updateCurrentRightClickRow(row);
|
|
41
|
+
|
|
42
|
+
if (!selectRows.value.includes(row)) {
|
|
43
|
+
clearSelection();
|
|
44
|
+
toggleRowSelection(row, true);
|
|
45
|
+
}
|
|
46
|
+
contextMenuTargetFile.value = true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
event.stopPropagation();
|
|
51
|
+
|
|
52
|
+
contextmenuRef.show({
|
|
53
|
+
top: event.clientY,
|
|
54
|
+
left: event.clientX
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
window.onclick = () => {
|
|
58
|
+
contextmenuRef.hide();
|
|
59
|
+
contextMenuTargetBlank.value = false;
|
|
60
|
+
contextMenuTargetFile.value = false;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
contextmenuRef.$el.hidden = false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const initContextMenu = (ref) => {
|
|
67
|
+
contextmenuRef = ref.value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
initContextMenu, showFileMenu, contextMenuTargetFile, contextMenuTargetBlank
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { useTitle } from "@vueuse/core";
|
|
2
|
+
import { reactive, watch, computed, onMounted, onUnmounted, nextTick } from "vue";
|
|
3
|
+
import {ElMessage} from "element-plus";
|
|
4
|
+
import MessageBox from "~/components/messageBox/messageBox";
|
|
5
|
+
import { concatPathAndEncodeAll } from "~/utils";
|
|
6
|
+
|
|
7
|
+
import useFileContextMenu from "~/composables/file/useFileContextMenu";
|
|
8
|
+
const { contextMenuTargetFile, contextMenuTargetBlank } = useFileContextMenu();
|
|
9
|
+
|
|
10
|
+
import path from "path-browserify";
|
|
11
|
+
|
|
12
|
+
import {loadFileListReq, loadStorageConfigReq} from "~/api/home/home";
|
|
13
|
+
|
|
14
|
+
import useRouterData from "~/composables/useRouterData";
|
|
15
|
+
let { routerRef, fullpath, storageKey, currentPath } = useRouterData()
|
|
16
|
+
|
|
17
|
+
import useFilePwd from "~/composables/file/useFilePwd";
|
|
18
|
+
let { getPathPwd, putPathPwd, popPassword } = useFilePwd();
|
|
19
|
+
|
|
20
|
+
import useHeaderStorageList from "~/composables/header/useHeaderStorageList";
|
|
21
|
+
const { storageListAsFileList } = useHeaderStorageList();
|
|
22
|
+
|
|
23
|
+
import useFileLoading from "~/composables/file/useFileLoading";
|
|
24
|
+
const { loading, firstLoading, basicLoading, skeletonLoading } = useFileLoading();
|
|
25
|
+
|
|
26
|
+
import useFileDataStore from "~/stores/file-data";
|
|
27
|
+
let fileDataStore = useFileDataStore();
|
|
28
|
+
|
|
29
|
+
import useStorageConfigStore from "~/stores/storage-config";
|
|
30
|
+
let storageConfigStore = useStorageConfigStore();
|
|
31
|
+
|
|
32
|
+
const title = useTitle(storageConfigStore.globalConfig.siteName);
|
|
33
|
+
|
|
34
|
+
import useGlobalConfigStore from "~/stores/global-config";
|
|
35
|
+
let globalConfigStore = useGlobalConfigStore();
|
|
36
|
+
|
|
37
|
+
// 引入文件预览组件
|
|
38
|
+
import useFilePreview from '~/composables/file/useFilePreview';
|
|
39
|
+
const { openAudio, openImage, openOffice, openPdf, openText, openVideo, open3d, openKkFileView } = useFilePreview();
|
|
40
|
+
|
|
41
|
+
// 文件操作相关
|
|
42
|
+
import useFileOperator from '~/composables/file/useFileOperator';
|
|
43
|
+
|
|
44
|
+
// ------------- loading start ------------
|
|
45
|
+
|
|
46
|
+
let skeletonData = reactive([]);
|
|
47
|
+
if (skeletonData.length === 0) {
|
|
48
|
+
// 动态配置骨架屏行数
|
|
49
|
+
for (let i = 0; i < globalConfigStore.zfileConfig.skeleton.size; i++) {
|
|
50
|
+
skeletonData.push({})
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// ------------- loading end ------------
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
// 文件列表查询条件
|
|
57
|
+
let searchParam = reactive({
|
|
58
|
+
path: '',
|
|
59
|
+
orderBy: '',
|
|
60
|
+
orderDirection: ''
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
import useFileSelect from "~/composables/file/useFileSelect";
|
|
64
|
+
let { selectRows, clearSelection } = useFileSelect();
|
|
65
|
+
|
|
66
|
+
export default function useFileData() {
|
|
67
|
+
|
|
68
|
+
// 排序并重新加载数据
|
|
69
|
+
const sortChangeMethod = ({prop, order}) => {
|
|
70
|
+
searchParam.orderBy = prop;
|
|
71
|
+
searchParam.orderDirection = order === "descending" ? "desc" : "asc";
|
|
72
|
+
loadFile();
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 加载数据
|
|
77
|
+
* @param initParam
|
|
78
|
+
* path: 指定加载的路径, 如果不指定则使用路由路径
|
|
79
|
+
* password: 指定加载的密码, 如果不指定则获取 path 对应的密码,如果 path 为空,则获取当前路由路径
|
|
80
|
+
* rememberPassword: 是否记住密码, 如果不指定则不记住密码
|
|
81
|
+
*/
|
|
82
|
+
const loadFile = (initParam) => {
|
|
83
|
+
// 未指定 storageKey 时, 不执行任何操作.
|
|
84
|
+
if (!storageKey.value) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
loading.value = true;
|
|
88
|
+
|
|
89
|
+
let loadPath = initParam?.path || currentPath.value;
|
|
90
|
+
|
|
91
|
+
let param = initParam || {};
|
|
92
|
+
param.storageKey = storageKey.value;
|
|
93
|
+
param.path = loadPath;
|
|
94
|
+
param.password = param.password || getPathPwd(loadPath, param.init);
|
|
95
|
+
param.orderBy = searchParam.orderBy || storageConfigStore.globalConfig.defaultSortField;
|
|
96
|
+
param.orderDirection = searchParam.orderDirection || storageConfigStore.globalConfig.defaultSortOrder;
|
|
97
|
+
|
|
98
|
+
let requestStorageId = storageKey.value;
|
|
99
|
+
loadFileListReq(param).then((response) => {
|
|
100
|
+
// 将加载成功的密码存储起来.
|
|
101
|
+
let passwordPattern = response.data.passwordPattern;
|
|
102
|
+
putPathPwd(passwordPattern, param.password, initParam?.rememberPassword);
|
|
103
|
+
|
|
104
|
+
// 如果请求的 storageKey 和当前的 storageKey 不一致
|
|
105
|
+
// 则表示再加载数据期间,修改了 storageKey, 为了防止数据错乱, 取消本次渲染.
|
|
106
|
+
if (requestStorageId !== storageKey.value) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let fileList = response.data.files;
|
|
111
|
+
|
|
112
|
+
// 如果不是根路径, 则构建 back 上级路径的数据.
|
|
113
|
+
if (loadPath !== '' && loadPath !== '/') {
|
|
114
|
+
let parentPathName = path.basename(path.resolve(currentPath.value, "../"));
|
|
115
|
+
fileList.unshift({
|
|
116
|
+
name: parentPathName ? parentPathName : '/',
|
|
117
|
+
path: path.resolve(loadPath, '../'),
|
|
118
|
+
type: 'BACK'
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
fileDataStore.updateFileList(fileList);
|
|
123
|
+
loading.value = false;
|
|
124
|
+
firstLoading.value = true;
|
|
125
|
+
selectRows.value = [];
|
|
126
|
+
|
|
127
|
+
// 修改标题
|
|
128
|
+
if (fullpath.value) {
|
|
129
|
+
title.value = storageConfigStore.globalConfig.siteName + ' | ' + fullpath.value[fullpath.value.length - 1];
|
|
130
|
+
} else {
|
|
131
|
+
title.value = storageConfigStore.globalConfig.siteName + ' | 首页';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
loadFileConfig(param);
|
|
135
|
+
}).catch((error) => {
|
|
136
|
+
const onConfirm = (password, rememberPassword) => {
|
|
137
|
+
loadFile({password, rememberPassword});
|
|
138
|
+
};
|
|
139
|
+
const onCancel = () => {
|
|
140
|
+
if ((loadPath === '/' || loadPath === '') && storageConfigStore.globalConfig.rootShowStorage === true) {
|
|
141
|
+
fileDataStore.updateFileList(storageListAsFileList.value);
|
|
142
|
+
routerRef.value.push("/");
|
|
143
|
+
title.value = storageConfigStore.globalConfig.siteName + ' | 首页';
|
|
144
|
+
loading.value = false;
|
|
145
|
+
} else {
|
|
146
|
+
let parentPath = path.resolve(loadPath, '../');
|
|
147
|
+
routerRef.value.push("/" + storageKey.value + parentPath);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
let data = error.response.data;
|
|
151
|
+
// 如果需要密码或密码错误进行提示, 并弹出输入密码的框.
|
|
152
|
+
if (data.code === constant.responseCode.INVALID_PASSWORD) {
|
|
153
|
+
ElMessage.warning('密码错误,请重新输入!');
|
|
154
|
+
popPassword(onConfirm, onCancel);
|
|
155
|
+
} else if (data.code === constant.responseCode.REQUIRED_PASSWORD) {
|
|
156
|
+
popPassword(onConfirm, onCancel);
|
|
157
|
+
} else {
|
|
158
|
+
ElMessage.error(data.msg);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 加载存储器设置
|
|
164
|
+
const loadFileConfig = (loadFileParam) => {
|
|
165
|
+
|
|
166
|
+
let param = {
|
|
167
|
+
storageKey: storageKey.value,
|
|
168
|
+
path: currentPath.value,
|
|
169
|
+
password: loadFileParam.password
|
|
170
|
+
}
|
|
171
|
+
loadStorageConfigReq(param).then((res) => {
|
|
172
|
+
storageConfigStore.updateFolderConfig(res.data);
|
|
173
|
+
|
|
174
|
+
// 如果切换了存储器 ID, 则
|
|
175
|
+
if (storageKey.value !== fileDataStore.oldStorageKey) {
|
|
176
|
+
fileDataStore.updateOldStorageKey(storageKey.value);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
// 点击文件时,判断是文件夹则进入文件夹,是文件则进行预览
|
|
184
|
+
const openRow = (row, fromContextmenu) => {
|
|
185
|
+
if (!row.name) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 当右键菜单打开时, 点击文件时, 不进行任何操作. 应该关闭右键菜单.
|
|
190
|
+
if (!fromContextmenu && (contextMenuTargetFile.value === true || contextMenuTargetBlank.value === true)) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
fileDataStore.updateCurrentClickRow(row);
|
|
195
|
+
// 如果是文件且格式支持预览, 则进行预览, 格式不支持预览, 则直接进行下载 (ftp 模式不支持预览, 全部是下载)
|
|
196
|
+
if (row.type === 'FILE') {
|
|
197
|
+
const { batchDownloadFile } = useFileOperator();
|
|
198
|
+
|
|
199
|
+
// 获取文件类型
|
|
200
|
+
let fileType = row.fileType;
|
|
201
|
+
if (storageConfigStore.folderConfig.permission.preview) {
|
|
202
|
+
switch (fileType) {
|
|
203
|
+
case 'video': openVideo(); break;
|
|
204
|
+
case 'image': openImage(row); break;
|
|
205
|
+
case 'text': openText(); break;
|
|
206
|
+
case 'audio': openAudio(row); break;
|
|
207
|
+
case 'office': openOffice(row); break;
|
|
208
|
+
case 'pdf': openPdf(row); break;
|
|
209
|
+
case 'three3d': open3d(row); break;
|
|
210
|
+
case 'kkfileview': openKkFileView(row); break;
|
|
211
|
+
default: batchDownloadFile(row);
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
batchDownloadFile(row);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// clearSelection();
|
|
218
|
+
} else {
|
|
219
|
+
if (row.type === 'ROOT') {
|
|
220
|
+
routerRef.value.push(row.path);
|
|
221
|
+
storageConfigStore.folderConfig.readmeText = '';
|
|
222
|
+
} else if (row.type === 'BACK') {
|
|
223
|
+
let fullPath = concatPathAndEncodeAll("/", storageKey.value, row.path);
|
|
224
|
+
routerRef.value.push(fullPath);
|
|
225
|
+
storageConfigStore.folderConfig.readmeText = '';
|
|
226
|
+
} else {
|
|
227
|
+
let fullPath = concatPathAndEncodeAll("/", storageKey.value, row.path, row.name);
|
|
228
|
+
routerRef.value.push(fullPath);
|
|
229
|
+
storageConfigStore.folderConfig.readmeText = '';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
// ------------- folder password handled by useFilePwd ------------
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
loadFile, openRow, searchParam, sortChangeMethod,
|
|
239
|
+
skeletonLoading, skeletonData, basicLoading, loading,
|
|
240
|
+
loadFileConfig
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { ref, reactive, computed } from 'vue'
|
|
2
|
+
import { concatPath, fileSizeFormat, generateQRCode } from "~/utils";
|
|
3
|
+
import { batchGeneratePathLinkReq, batchGenerateShortLinkReq } from "~/api/home/home";
|
|
4
|
+
|
|
5
|
+
import { toClipboard } from '@soerenmartius/vue3-clipboard'
|
|
6
|
+
import { rendererRect, rendererRound,
|
|
7
|
+
rendererDSJ, rendererLine, rendererFuncB } from 'beautify-qrcode';
|
|
8
|
+
|
|
9
|
+
const generateLinkLoading = ref(false);
|
|
10
|
+
const generateLinkDialogVisible = ref(false);
|
|
11
|
+
const generateLinkFormData = reactive({
|
|
12
|
+
expireTime: null,
|
|
13
|
+
});
|
|
14
|
+
const currentLinkDialogType = ref(''); // 当前链接弹窗类型, 可以为 shortLink 或 pathLink
|
|
15
|
+
|
|
16
|
+
import useRouterData from "~/composables/useRouterData";
|
|
17
|
+
let { storageKey } = useRouterData()
|
|
18
|
+
|
|
19
|
+
const dataList = ref([]);
|
|
20
|
+
let data = computed(() => {
|
|
21
|
+
return dataList.value.length > 0 ? dataList.value[0] : null;
|
|
22
|
+
});
|
|
23
|
+
let generateLinkResultDialogVisible = ref(false);
|
|
24
|
+
let generateLinkResultLoading = ref(false);
|
|
25
|
+
|
|
26
|
+
const linkDialogVisible = computed(() => {
|
|
27
|
+
return generateLinkDialogVisible.value && generateLinkResultDialogVisible.value;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export default function useFileLink() {
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* 打开生成链接弹窗
|
|
34
|
+
*/
|
|
35
|
+
const openGenerateLinkDialog = (type) => {
|
|
36
|
+
currentLinkDialogType.value = type;
|
|
37
|
+
if (type === 'pathLink') {
|
|
38
|
+
openGenerateLinkResultDialog();
|
|
39
|
+
} else {
|
|
40
|
+
generateLinkDialogVisible.value = true;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 关闭生成链接弹窗
|
|
46
|
+
*/
|
|
47
|
+
const closeGenerateLinkDialog = () => {
|
|
48
|
+
generateLinkDialogVisible.value = false;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 提交生成链接表单
|
|
53
|
+
*/
|
|
54
|
+
const submitGenerateLinkForm = () => {
|
|
55
|
+
closeGenerateLinkDialog();
|
|
56
|
+
openGenerateLinkResultDialog();
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 打开直链生成结果弹窗
|
|
63
|
+
*/
|
|
64
|
+
const openGenerateLinkResultDialog = () => {
|
|
65
|
+
generateLinkResultDialogVisible.value = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 复制直链
|
|
70
|
+
*/
|
|
71
|
+
let copyText = (text) => {
|
|
72
|
+
toClipboard(text).then(() => {
|
|
73
|
+
ElMessage.success('复制成功');
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 生成直链
|
|
79
|
+
*
|
|
80
|
+
* @param files 要生成的直链列表
|
|
81
|
+
*/
|
|
82
|
+
const generateALlLink = async (files) => {
|
|
83
|
+
generateLinkResultLoading.value = true;
|
|
84
|
+
|
|
85
|
+
let pathLinkList = [], shortLinkList = [];
|
|
86
|
+
if (currentLinkDialogType.value === 'pathLink' || currentLinkDialogType.value === 'all') {
|
|
87
|
+
pathLinkList = await batchGetFilePathLink(files);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (currentLinkDialogType.value === 'shortLink' || currentLinkDialogType.value === 'all') {
|
|
91
|
+
shortLinkList = await batchGetShortLink(files)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
files.forEach((file, index) => {
|
|
95
|
+
let item = {
|
|
96
|
+
name: file.name,
|
|
97
|
+
size: fileSizeFormat(file.size),
|
|
98
|
+
time: file.time,
|
|
99
|
+
pathLink: pathLinkList[index],
|
|
100
|
+
shortLink: shortLinkList[index]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (files.length === 1) {
|
|
104
|
+
// 生成二维码
|
|
105
|
+
const qrcodeOptions = {
|
|
106
|
+
text: currentLinkDialogType.value === 'pathLink' ? pathLinkList[index] : shortLinkList[index],
|
|
107
|
+
correctLevel: 2,
|
|
108
|
+
isSpace: false
|
|
109
|
+
}
|
|
110
|
+
item.qrcode = {
|
|
111
|
+
a1: generateQRCode(qrcodeOptions, rendererRect),
|
|
112
|
+
a2: generateQRCode(qrcodeOptions, rendererRound),
|
|
113
|
+
sp1: generateQRCode(qrcodeOptions, rendererDSJ),
|
|
114
|
+
aa1: generateQRCode(qrcodeOptions, rendererLine),
|
|
115
|
+
ab2: generateQRCode(qrcodeOptions, rendererFuncB)
|
|
116
|
+
}
|
|
117
|
+
item.currentImg = item.qrcode.a1;
|
|
118
|
+
}
|
|
119
|
+
dataList.value.push(item);
|
|
120
|
+
})
|
|
121
|
+
generateLinkResultLoading.value = false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const batchGetFilePathLink = async (files) => {
|
|
125
|
+
let pathLinkList = [];
|
|
126
|
+
let param = {
|
|
127
|
+
storageKey: storageKey.value,
|
|
128
|
+
paths: [],
|
|
129
|
+
expireTime: 0
|
|
130
|
+
}
|
|
131
|
+
files.forEach((file) => {
|
|
132
|
+
let pathAndName = concatPath(file.path, file.name);
|
|
133
|
+
param.paths.push(pathAndName);
|
|
134
|
+
})
|
|
135
|
+
let res = await batchGeneratePathLinkReq(param);
|
|
136
|
+
res.data.forEach((item) => {
|
|
137
|
+
pathLinkList.push(item.address);
|
|
138
|
+
})
|
|
139
|
+
return pathLinkList;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const batchGetShortLink = async (files) => {
|
|
143
|
+
let shortLinkList = [];
|
|
144
|
+
let param = {
|
|
145
|
+
storageKey: storageKey.value,
|
|
146
|
+
paths: [],
|
|
147
|
+
expireTime: generateLinkFormData.expireTime
|
|
148
|
+
}
|
|
149
|
+
files.forEach((file) => {
|
|
150
|
+
let pathAndName = concatPath(file.path, file.name);
|
|
151
|
+
param.paths.push(pathAndName);
|
|
152
|
+
})
|
|
153
|
+
let res = await batchGenerateShortLinkReq(param);
|
|
154
|
+
res.data.forEach((item) => {
|
|
155
|
+
shortLinkList.push(item.address);
|
|
156
|
+
})
|
|
157
|
+
return shortLinkList;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
currentLinkDialogType,
|
|
162
|
+
generateLinkDialogVisible,
|
|
163
|
+
openGenerateLinkDialog,
|
|
164
|
+
closeGenerateLinkDialog,
|
|
165
|
+
generateLinkFormData,
|
|
166
|
+
generateLinkLoading,
|
|
167
|
+
submitGenerateLinkForm,
|
|
168
|
+
|
|
169
|
+
linkDialogVisible,
|
|
170
|
+
generateLinkResultDialogVisible, generateLinkResultLoading, openGenerateLinkResultDialog, copyText, data, dataList, generateALlLink,
|
|
171
|
+
batchGetFilePathLink
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ref, computed } from "vue";
|
|
2
|
+
const loading = ref(false);
|
|
3
|
+
const firstLoading = ref(false);
|
|
4
|
+
|
|
5
|
+
import useGlobalConfigStore from "~/stores/global-config";
|
|
6
|
+
let globalConfigStore = useGlobalConfigStore();
|
|
7
|
+
|
|
8
|
+
// 是否启用骨架屏 loading
|
|
9
|
+
let skeletonLoading = computed(() => {
|
|
10
|
+
let skeletonEnable = globalConfigStore.zfileConfig.skeleton.enable;
|
|
11
|
+
let skeletonShow = globalConfigStore.zfileConfig.skeleton.show;
|
|
12
|
+
|
|
13
|
+
// 如果启用了骨架屏
|
|
14
|
+
if (skeletonEnable) {
|
|
15
|
+
// 如果骨架屏模式为是 '始终加载'
|
|
16
|
+
if (skeletonShow === 'always') {
|
|
17
|
+
return loading.value;
|
|
18
|
+
} else { // 如果骨架屏模式为是仅 '首次加载'
|
|
19
|
+
// 已经首次加载后, 则不使用骨架屏
|
|
20
|
+
return firstLoading.value ? false : loading.value;
|
|
21
|
+
}
|
|
22
|
+
} else { // 如果未启用骨架屏, 则直接返回 false
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// 是否显示普通 loading
|
|
28
|
+
let basicLoading = computed(() => {
|
|
29
|
+
return skeletonLoading.value ? false : loading.value;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export default function useFileLoading() {
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
loading,
|
|
36
|
+
firstLoading,
|
|
37
|
+
skeletonLoading,
|
|
38
|
+
basicLoading
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { onLongPress } from '@vueuse/core'
|
|
2
|
+
|
|
3
|
+
import uaBrowser from 'ua-browser'
|
|
4
|
+
const browserInfo = uaBrowser();
|
|
5
|
+
|
|
6
|
+
import useFileDataStore from "~/stores/file-data";
|
|
7
|
+
let fileDataStore = useFileDataStore();
|
|
8
|
+
|
|
9
|
+
import useFileContextMenu from "~/composables/file/useFileContextMenu";
|
|
10
|
+
const { showFileMenu } = useFileContextMenu();
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 绑定元素长按事件
|
|
14
|
+
* @param elementRef 可长按区域元素引用
|
|
15
|
+
* @param parseRowFunc 解析长按数据行的方法
|
|
16
|
+
*/
|
|
17
|
+
const bindElementLongPressEvent = (elementRef, parseRowFunc) => {
|
|
18
|
+
function onLongPressCallbackHook(e) {
|
|
19
|
+
const row = parseRowFunc(e, elementRef);
|
|
20
|
+
if (row) {
|
|
21
|
+
showFileMenu(row, null, e)
|
|
22
|
+
} else {
|
|
23
|
+
showFileMenu(e)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onLongPress(
|
|
28
|
+
elementRef,
|
|
29
|
+
onLongPressCallbackHook,
|
|
30
|
+
{
|
|
31
|
+
modifiers: {
|
|
32
|
+
prevent: true,
|
|
33
|
+
stop: true,
|
|
34
|
+
capture: true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 解析 el-table 下长按行数据
|
|
42
|
+
* @param e 长按事件对象
|
|
43
|
+
* @param elementRef 可长按区域元素引用
|
|
44
|
+
*/
|
|
45
|
+
const parseElTableRowFunc = (e, elementRef) => {
|
|
46
|
+
const target = e.target;
|
|
47
|
+
const ListTable = elementRef.value.querySelector('#ListTable')
|
|
48
|
+
let row = null;
|
|
49
|
+
if (ListTable.contains(target)) {
|
|
50
|
+
let rowEle = target.closest('.el-table__row')
|
|
51
|
+
if (rowEle) {
|
|
52
|
+
let children = Array.from(rowEle.parentNode.children);
|
|
53
|
+
let index = children.indexOf(rowEle);
|
|
54
|
+
row = fileDataStore.fileList[index];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return row;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default function useFileLongPressEvent(elRef) {
|
|
61
|
+
|
|
62
|
+
onMounted(() => {
|
|
63
|
+
// Safari 浏览器在移动端长按事件 (因为不支持 contextmenu 事件)
|
|
64
|
+
const isIOS = browserInfo.os === 'iOS';
|
|
65
|
+
const isIPAD = browserInfo.os === 'MacOS' && browserInfo.device === 'Tablet';
|
|
66
|
+
if (isIOS || isIPAD) {
|
|
67
|
+
bindElementLongPressEvent(elRef, parseElTableRowFunc);
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
}
|