@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.
Files changed (274) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/README.md +5 -0
  3. package/auto-imports.d.ts +12 -0
  4. package/components.d.ts +45 -0
  5. package/dist.zip +0 -0
  6. package/index.html +13 -0
  7. package/package.json +100 -0
  8. package/presets/eslint/.eslintrc-auto-import.json +462 -0
  9. package/presets/plugins/html.ts +14 -0
  10. package/presets/shared/env.ts +46 -0
  11. package/presets/shared/resolvers.ts +29 -0
  12. package/presets/tov.ts +132 -0
  13. package/presets/types/auto-imports.d.ts +806 -0
  14. package/presets/types/components.d.ts +164 -0
  15. package/presets/types/env.d.ts +17 -0
  16. package/public/favicon.svg +1 -0
  17. package/public/icons.svg +24 -0
  18. package/public/testfile/README.md +5 -0
  19. package/public/testfile/useFileContextMenu.js +74 -0
  20. package/public/testfile//345/217/221/347/245/250.pdf +0 -0
  21. package/public/testfile//346/216/245/346/224/266/345/207/275.docx +0 -0
  22. package/public/testfile//350/247/204/346/240/274/345/236/213/345/217/2671.txt +263 -0
  23. package/public/testfile//350/247/206/351/242/2211.mp4 +0 -0
  24. package/public/testfile//351/237/263/351/242/2211.mp3 +0 -0
  25. package/src/App.vue +8 -0
  26. package/src/api/admin/admin-2fa.js +18 -0
  27. package/src/api/admin/admin-download-log.js +37 -0
  28. package/src/api/admin/admin-login-log.js +9 -0
  29. package/src/api/admin/admin-permission.js +9 -0
  30. package/src/api/admin/admin-setting.js +121 -0
  31. package/src/api/admin/admin-share.js +20 -0
  32. package/src/api/admin/admin-short-link.js +49 -0
  33. package/src/api/admin/admin-sso.js +38 -0
  34. package/src/api/admin/admin-storage.js +189 -0
  35. package/src/api/admin/admin-user.js +61 -0
  36. package/src/api/home/common.js +9 -0
  37. package/src/api/home/file-operator.js +89 -0
  38. package/src/api/home/home.js +87 -0
  39. package/src/api/home/install.js +18 -0
  40. package/src/api/home/login.js +9 -0
  41. package/src/api/home/only-office.js +10 -0
  42. package/src/api/home/share.js +115 -0
  43. package/src/api/home/user.js +74 -0
  44. package/src/api/tools/tools-115.js +17 -0
  45. package/src/api/tools/tools-gd.js +13 -0
  46. package/src/api/tools/tools-s3.js +25 -0
  47. package/src/api/tools/tools-sharepoint.js +19 -0
  48. package/src/assets/hero.png +0 -0
  49. package/src/assets/icons/401.svg +1 -0
  50. package/src/assets/icons/403.svg +45 -0
  51. package/src/assets/icons/404.svg +1 -0
  52. package/src/assets/icons/500.svg +1 -0
  53. package/src/assets/icons/admin-login.svg +1 -0
  54. package/src/assets/icons/document.svg +1 -0
  55. package/src/assets/icons/empty.svg +145 -0
  56. package/src/assets/icons/file-type-apk.svg +1 -0
  57. package/src/assets/icons/file-type-archive.svg +1 -0
  58. package/src/assets/icons/file-type-audio.svg +1 -0
  59. package/src/assets/icons/file-type-back.svg +1 -0
  60. package/src/assets/icons/file-type-css.svg +1 -0
  61. package/src/assets/icons/file-type-deb.svg +1 -0
  62. package/src/assets/icons/file-type-dll.svg +1 -0
  63. package/src/assets/icons/file-type-doc.svg +1 -0
  64. package/src/assets/icons/file-type-document.svg +1 -0
  65. package/src/assets/icons/file-type-docx.svg +1 -0
  66. package/src/assets/icons/file-type-exe.svg +1 -0
  67. package/src/assets/icons/file-type-expression.svg +1 -0
  68. package/src/assets/icons/file-type-file.svg +1 -0
  69. package/src/assets/icons/file-type-folder.svg +1 -0
  70. package/src/assets/icons/file-type-html.svg +1 -0
  71. package/src/assets/icons/file-type-image.svg +1 -0
  72. package/src/assets/icons/file-type-java.svg +1 -0
  73. package/src/assets/icons/file-type-js.svg +1 -0
  74. package/src/assets/icons/file-type-less.svg +1 -0
  75. package/src/assets/icons/file-type-md.svg +1 -0
  76. package/src/assets/icons/file-type-office.svg +1 -0
  77. package/src/assets/icons/file-type-pdf.svg +1 -0
  78. package/src/assets/icons/file-type-php.svg +1 -0
  79. package/src/assets/icons/file-type-ppt.svg +1 -0
  80. package/src/assets/icons/file-type-pptx.svg +1 -0
  81. package/src/assets/icons/file-type-py.svg +1 -0
  82. package/src/assets/icons/file-type-rb.svg +1 -0
  83. package/src/assets/icons/file-type-root.svg +1 -0
  84. package/src/assets/icons/file-type-rpm.svg +1 -0
  85. package/src/assets/icons/file-type-rust.svg +1 -0
  86. package/src/assets/icons/file-type-script.svg +1 -0
  87. package/src/assets/icons/file-type-text.svg +1 -0
  88. package/src/assets/icons/file-type-three3d.svg +5 -0
  89. package/src/assets/icons/file-type-vbs.svg +1 -0
  90. package/src/assets/icons/file-type-video.svg +1 -0
  91. package/src/assets/icons/file-type-xls.svg +1 -0
  92. package/src/assets/icons/file-type-xlsx.svg +1 -0
  93. package/src/assets/icons/file-type-xml.svg +1 -0
  94. package/src/assets/icons/file-type-yaml.svg +1 -0
  95. package/src/assets/icons/file-upload.svg +1 -0
  96. package/src/assets/icons/github.svg +1 -0
  97. package/src/assets/icons/install-step.svg +40 -0
  98. package/src/assets/icons/reset-password.svg +1 -0
  99. package/src/assets/icons/storage-aliyun.svg +1 -0
  100. package/src/assets/icons/storage-baidu.svg +1 -0
  101. package/src/assets/icons/storage-doge-cloud.svg +207 -0
  102. package/src/assets/icons/storage-ftp.svg +13 -0
  103. package/src/assets/icons/storage-google-drive.svg +8 -0
  104. package/src/assets/icons/storage-huawei.svg +1 -0
  105. package/src/assets/icons/storage-local.svg +11 -0
  106. package/src/assets/icons/storage-minio.svg +1 -0
  107. package/src/assets/icons/storage-onedrive-china.svg +18 -0
  108. package/src/assets/icons/storage-onedrive.svg +4 -0
  109. package/src/assets/icons/storage-open115.svg +23 -0
  110. package/src/assets/icons/storage-qiniu.svg +1 -0
  111. package/src/assets/icons/storage-s3.svg +5 -0
  112. package/src/assets/icons/storage-sftp.svg +13 -0
  113. package/src/assets/icons/storage-sharepoint-china.svg +23 -0
  114. package/src/assets/icons/storage-sharepoint.svg +1 -0
  115. package/src/assets/icons/storage-tencent.svg +9 -0
  116. package/src/assets/icons/storage-ufile.svg +14 -0
  117. package/src/assets/icons/storage-upyun.svg +1 -0
  118. package/src/assets/icons/storage-webdav.svg +1 -0
  119. package/src/assets/icons/upload.svg +50 -0
  120. package/src/assets/icons/zfile-basic.svg +17 -0
  121. package/src/assets/icons/zfile-horizontal.svg +16 -0
  122. package/src/assets/icons/zfile.svg +1 -0
  123. package/src/assets/vite.svg +1 -0
  124. package/src/assets/vue.svg +1 -0
  125. package/src/components/HelloWorld.vue +319 -0
  126. package/src/components/common/QrCodePreview.vue +118 -0
  127. package/src/components/common/dialog/ZDialog.vue +171 -0
  128. package/src/components/common/dialog/types.ts +19 -0
  129. package/src/components/common/dialog/useDialog.ts +18 -0
  130. package/src/components/common/dialog/useDialogWithForm.ts +21 -0
  131. package/src/components/copy.vue +133 -0
  132. package/src/components/file/preview/AudioPlayer.vue +333 -0
  133. package/src/components/file/preview/CopyCode.vue +47 -0
  134. package/src/components/file/preview/FileGallery.vue +199 -0
  135. package/src/components/file/preview/ImageViewer.vue +432 -0
  136. package/src/components/file/preview/KkFileViewer.vue +86 -0
  137. package/src/components/file/preview/KkFileViewerDialog.vue +42 -0
  138. package/src/components/file/preview/MarkdownViewer.vue +102 -0
  139. package/src/components/file/preview/MarkdownViewerAsyncLoading.vue +17 -0
  140. package/src/components/file/preview/MarkdownViewerDialogAsyncLoading.vue +12 -0
  141. package/src/components/file/preview/OfficeViewer.vue +76 -0
  142. package/src/components/file/preview/OfficeViewerDialog.vue +55 -0
  143. package/src/components/file/preview/PdfViewer.vue +157 -0
  144. package/src/components/file/preview/PdfViewerDialog.vue +41 -0
  145. package/src/components/file/preview/TextViewer.vue +232 -0
  146. package/src/components/file/preview/TextViewerAsyncLoading.vue +22 -0
  147. package/src/components/file/preview/TextViewerDialog.vue +53 -0
  148. package/src/components/file/preview/Three3dPreview.vue +114 -0
  149. package/src/components/file/preview/Three3dPreviewDialog.vue +50 -0
  150. package/src/components/file/preview/VideoPlayer.vue +341 -0
  151. package/src/components/file/preview/VideoPlayerAsyncLoading.vue +45 -0
  152. package/src/components/file/preview/VideoPlayerDialog.vue +51 -0
  153. package/src/components/file/selectFolder/SelectFolder.vue +208 -0
  154. package/src/components/file/selectFolder/index.ts +50 -0
  155. package/src/components/file/selectFolder/types.ts +5 -0
  156. package/src/components/fileReview/AudioPlayer-copy.vue +333 -0
  157. package/src/components/fileReview/PdfViewer-copy.vue +157 -0
  158. package/src/components/fileReview/TextViewer-copy.vue +44 -0
  159. package/src/components/fileReview/VideoPlayer-copy.vue +341 -0
  160. package/src/components/messageBox/confirm/confirm.vue +137 -0
  161. package/src/components/messageBox/confirm/index.ts +27 -0
  162. package/src/components/messageBox/confirm/types.ts +15 -0
  163. package/src/components/messageBox/messageBox.ts +9 -0
  164. package/src/components/messageBox/prompt/index.ts +27 -0
  165. package/src/components/messageBox/prompt/prompt.vue +178 -0
  166. package/src/components/messageBox/prompt/types.ts +24 -0
  167. package/src/components/vue-codemirror/editor.vue +212 -0
  168. package/src/components/vue-codemirror/encodings.ts +27 -0
  169. package/src/components/vue-codemirror/index.vue +380 -0
  170. package/src/components/vue-codemirror/lang-code/cpp/index.ts +3 -0
  171. package/src/components/vue-codemirror/lang-code/css/index.ts +2 -0
  172. package/src/components/vue-codemirror/lang-code/dockerfile/index.ts +5 -0
  173. package/src/components/vue-codemirror/lang-code/erlang/index.ts +6 -0
  174. package/src/components/vue-codemirror/lang-code/go/index.ts +5 -0
  175. package/src/components/vue-codemirror/lang-code/html/index.ts +3 -0
  176. package/src/components/vue-codemirror/lang-code/java/index.ts +3 -0
  177. package/src/components/vue-codemirror/lang-code/javascript/index.ts +3 -0
  178. package/src/components/vue-codemirror/lang-code/json/index.ts +3 -0
  179. package/src/components/vue-codemirror/lang-code/jsx/index.ts +3 -0
  180. package/src/components/vue-codemirror/lang-code/lua/index.ts +6 -0
  181. package/src/components/vue-codemirror/lang-code/markdown/index.ts +2 -0
  182. package/src/components/vue-codemirror/lang-code/mysql/index.ts +3 -0
  183. package/src/components/vue-codemirror/lang-code/nginx/index.ts +6 -0
  184. package/src/components/vue-codemirror/lang-code/perl/index.ts +5 -0
  185. package/src/components/vue-codemirror/lang-code/pgsql/index.ts +2 -0
  186. package/src/components/vue-codemirror/lang-code/php/index.ts +3 -0
  187. package/src/components/vue-codemirror/lang-code/powershell/index.ts +3 -0
  188. package/src/components/vue-codemirror/lang-code/python/index.ts +2 -0
  189. package/src/components/vue-codemirror/lang-code/r/index.ts +5 -0
  190. package/src/components/vue-codemirror/lang-code/ruby/index.ts +5 -0
  191. package/src/components/vue-codemirror/lang-code/rust/index.ts +2 -0
  192. package/src/components/vue-codemirror/lang-code/shell/index.ts +5 -0
  193. package/src/components/vue-codemirror/lang-code/sql/index.ts +3 -0
  194. package/src/components/vue-codemirror/lang-code/stylus/index.ts +3 -0
  195. package/src/components/vue-codemirror/lang-code/swift/index.ts +4 -0
  196. package/src/components/vue-codemirror/lang-code/toml/index.ts +3 -0
  197. package/src/components/vue-codemirror/lang-code/tsx/index.ts +2 -0
  198. package/src/components/vue-codemirror/lang-code/typescript/index.ts +2 -0
  199. package/src/components/vue-codemirror/lang-code/vb/index.ts +3 -0
  200. package/src/components/vue-codemirror/lang-code/vbscript/index.ts +3 -0
  201. package/src/components/vue-codemirror/lang-code/xml/index.ts +2 -0
  202. package/src/components/vue-codemirror/lang-code/yaml/index.ts +3 -0
  203. package/src/components/vue-codemirror/languages.ts +8 -0
  204. package/src/components/vue-codemirror/themes.ts +5 -0
  205. package/src/components/vue-codemirror/toolbar.vue +183 -0
  206. package/src/components/vue-codemirror/types.ts +12 -0
  207. package/src/components.d.ts +49 -0
  208. package/src/composables/admin/layout/admin-layout.js +53 -0
  209. package/src/composables/admin/link/useLinkSetting.js +16 -0
  210. package/src/composables/admin/sso/baseSsoConfig.js +54 -0
  211. package/src/composables/admin/sso/useSsoConfig.js +176 -0
  212. package/src/composables/admin/storage/storage-copy.js +89 -0
  213. package/src/composables/admin/storage/storage-filter.js +64 -0
  214. package/src/composables/admin/storage/storage-list.js +202 -0
  215. package/src/composables/admin/storage/storage-password.js +101 -0
  216. package/src/composables/admin/storage/storage-readme.js +102 -0
  217. package/src/composables/admin/storage/utils/open115-util.js +61 -0
  218. package/src/composables/admin/useAdminSetting.js +60 -0
  219. package/src/composables/admin/useClientInfo.js +20 -0
  220. package/src/composables/admin/user/user-copy.js +79 -0
  221. package/src/composables/file/useBatchOperatorResult.js +19 -0
  222. package/src/composables/file/useFileContextMenu.js +74 -0
  223. package/src/composables/file/useFileData.js +243 -0
  224. package/src/composables/file/useFileLink.js +175 -0
  225. package/src/composables/file/useFileLoading.js +41 -0
  226. package/src/composables/file/useFileLongPressEvent.js +71 -0
  227. package/src/composables/file/useFileOperator.js +347 -0
  228. package/src/composables/file/useFilePreview.js +99 -0
  229. package/src/composables/file/useFilePwd.js +138 -0
  230. package/src/composables/file/useFileSelect.js +105 -0
  231. package/src/composables/file/useFileShare.js +39 -0
  232. package/src/composables/file/useFileUpload.js +1045 -0
  233. package/src/composables/file/useKkFileViewDialog.js +24 -0
  234. package/src/composables/file/useOfficeViewerDialog.js +20 -0
  235. package/src/composables/file/usePdfViewerDialog.js +22 -0
  236. package/src/composables/file/useShareActions.js +94 -0
  237. package/src/composables/file/useShareTableOperator.js +84 -0
  238. package/src/composables/file/useTableOperator.js +211 -0
  239. package/src/composables/file/useTextViewerDialog.js +22 -0
  240. package/src/composables/file/useThree3dPreviewDialog.js +23 -0
  241. package/src/composables/file/useVideoPlayerDialog.js +19 -0
  242. package/src/composables/header/useHeaderBreadcrumb.js +111 -0
  243. package/src/composables/header/useHeaderStorageList.js +150 -0
  244. package/src/composables/header/useSetting.js +58 -0
  245. package/src/composables/share/useShareData.js +178 -0
  246. package/src/composables/useDarks.ts +4 -0
  247. package/src/composables/useRouterData.js +41 -0
  248. package/src/constant/index.js +193 -0
  249. package/src/http/index.js +153 -0
  250. package/src/http/request.js +31 -0
  251. package/src/main.ts +23 -0
  252. package/src/stores/file-data.ts +108 -0
  253. package/src/stores/global-config.ts +115 -0
  254. package/src/stores/storage-config.ts +123 -0
  255. package/src/style.css +296 -0
  256. package/src/styles/admin.scss +91 -0
  257. package/src/styles/code-editor-variables.scss +52 -0
  258. package/src/styles/element-plus.scss +22 -0
  259. package/src/styles/error-page.css +26 -0
  260. package/src/styles/main.css +142 -0
  261. package/src/styles/tailwind/index.scss +33 -0
  262. package/src/utils/index.ts +7 -0
  263. package/src/utils/models/base.ts +34 -0
  264. package/src/utils/models/file.ts +95 -0
  265. package/src/utils/models/path.ts +117 -0
  266. package/src/utils/models/qrcode.ts +21 -0
  267. package/src/utils/models/time.ts +132 -0
  268. package/src/utils/models/util.ts +42 -0
  269. package/src/utils/models/window.ts +14 -0
  270. package/stats.html +4950 -0
  271. package/tsconfig.app.json +16 -0
  272. package/tsconfig.json +7 -0
  273. package/tsconfig.node.json +26 -0
  274. package/vite.config.ts +57 -0
@@ -0,0 +1,95 @@
1
+ import { constant } from '~/constant/index.js'
2
+ export const fileSizeFormat = (bytes: number): string => {
3
+ if (bytes === 0) return '-';
4
+ if (bytes === -1) return '未知';
5
+ const k = 1024;
6
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
7
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
8
+ return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
9
+ }
10
+
11
+ export const fileSizeFilter = (row: { type: string, size?: number }, column: any, bytes: number): string => {
12
+ if (row.type === "BACK") return '';
13
+ if (row.type === "ROOT") return '-';
14
+ if (row.type === "FOLDER" && !row.size) return '-';
15
+ if (bytes === 0) return '0 B';
16
+ if (bytes === -1) return '未知';
17
+ const k = 1024;
18
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
19
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
20
+ return fileSizeFormat(bytes);
21
+ }
22
+
23
+ export const getFileIconName = (file: { type: string, name: string }): string => {
24
+ let iconName: string;
25
+ if (file.type === 'BACK' || file.type === 'FOLDER' || file.type === 'ROOT') {
26
+ return file.type.toLowerCase();
27
+ } else {
28
+ const fileSuffix = getFileSuffix(file.name);
29
+ const fileType = getFileType(file.name);
30
+
31
+ if (constant.iconFileType.indexOf(fileSuffix) !== -1) {
32
+ iconName = fileSuffix;
33
+ } else if (fileType) {
34
+ iconName = fileType;
35
+ } else {
36
+ iconName = 'file';
37
+ }
38
+ }
39
+ return iconName;
40
+ }
41
+
42
+ export const getFileSuffix = (name: string): string => {
43
+ const lastIndex = name.lastIndexOf('.');
44
+ if (lastIndex === -1) {
45
+ return 'other';
46
+ }
47
+ return name.substring(lastIndex + 1).toLowerCase();
48
+ }
49
+
50
+ export const getFileName = (name: string): string => {
51
+ const lastIndex = name.lastIndexOf('/');
52
+ if (lastIndex === -1) {
53
+ return name;
54
+ }
55
+ return name.substring(lastIndex + 1);
56
+ }
57
+
58
+ export const getFileNameIgnoreExt = (name: string): string => {
59
+ const lastIndex = name.lastIndexOf('.');
60
+ if (lastIndex === -1) {
61
+ return '';
62
+ }
63
+ return name.substring(0, lastIndex);
64
+ }
65
+
66
+ export const getFileType = (name: string): string | undefined => {
67
+ let fileType: string | undefined;
68
+ for (const key in constant.fileTypeMap) {
69
+ const suffix = getFileSuffix(name);
70
+ if (constant.fileTypeMap[key].indexOf(suffix) !== -1) {
71
+ fileType = key;
72
+ break;
73
+ }
74
+ }
75
+ return fileType;
76
+ }
77
+
78
+
79
+ /**
80
+ * 将 File 对象转换为 Base64 字符串
81
+ * @param {File} file - 用户选择的文件对象
82
+ * @returns {Promise<string>} - 返回一个 Promise,成功时解析为 Base64 格式的 data URL
83
+ */
84
+ export function fileToBase64(file) {
85
+ return new Promise((resolve, reject) => {
86
+ const reader = new FileReader();
87
+ reader.readAsDataURL(file);
88
+ reader.onload = () => {
89
+ resolve(reader.result);
90
+ };
91
+ reader.onerror = (error) => {
92
+ reject(error);
93
+ };
94
+ });
95
+ }
@@ -0,0 +1,117 @@
1
+ import { strIsEmpty } from "~/utils";
2
+
3
+ export const concatPath = (...paths: (string | null | undefined)[]): string => {
4
+ let result: string | null = null;
5
+ for (let path of paths) {
6
+ if (!path) {
7
+ continue;
8
+ }
9
+ if (result === null) {
10
+ result = path;
11
+ continue;
12
+ }
13
+ result = result + '/' + path;
14
+ }
15
+ if (result === null) {
16
+ return '';
17
+ }
18
+ return removeDuplicateSeparator(result);
19
+ }
20
+
21
+ export const concatPathAndEncodeAll = (...paths: (string | null | undefined)[]): string => {
22
+ return encodeAllIgnoreSlashes(concatPath(...paths));
23
+ }
24
+
25
+ export const removeDuplicateSeparator = (path: string): string => {
26
+ let result = '';
27
+
28
+ if (path.indexOf("http://") === 0) {
29
+ result = "http://";
30
+ } else if (path.indexOf("https://") === 0) {
31
+ result = "https://";
32
+ }
33
+
34
+ for (let i = result.length; i < path.length - 1; i++) {
35
+ let current = path.charAt(i);
36
+ let next = path.charAt(i + 1);
37
+ if (!(current === '/' && next === '/')) {
38
+ result += current;
39
+ }
40
+ }
41
+ result += path.charAt(path.length - 1);
42
+ return result;
43
+ }
44
+
45
+ export const encodeAllIgnoreSlashes = (str: string): string => {
46
+ if (strIsEmpty(str)) {
47
+ return '';
48
+ }
49
+
50
+ let result = '';
51
+ let prevIndex = -1;
52
+
53
+ for (let i = 0; i < str.length; i++) {
54
+ const c = str.charAt(i);
55
+ if (c === '/') {
56
+ if (prevIndex < i) {
57
+ let subStr = str.substring(prevIndex + 1, i);
58
+ result += encodeURIComponent(subStr);
59
+ prevIndex = i;
60
+ }
61
+ result += c;
62
+ }
63
+
64
+ if (i === str.length - 1 && prevIndex < i) {
65
+ let subStr = str.substring(prevIndex + 1, i + 1);
66
+ result += encodeURIComponent(subStr);
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+
72
+ export function buildKkFileViewUrl(file: any, kkFileViewUrl: string) {
73
+ const originalFileName = file.name;
74
+ const fileUrl = file.url;
75
+
76
+ if (!kkFileViewUrl || !fileUrl || !originalFileName) {
77
+ console.error("构建 kkFileView URL 失败:缺少必要参数。");
78
+ return null;
79
+ }
80
+
81
+ // 1. 构造安全文件名
82
+ const lastDotIndex = originalFileName.lastIndexOf('.');
83
+ const extension = (lastDotIndex !== -1) ? originalFileName.substring(lastDotIndex) : '';
84
+ let safeBaseName;
85
+ if (typeof window.crypto?.randomUUID === 'function') {
86
+ safeBaseName = window.crypto.randomUUID();
87
+ } else {
88
+ safeBaseName = Date.now().toString(36) + Math.random().toString(36).substring(2);
89
+ }
90
+ const safeFileName = `${safeBaseName}${extension}`;
91
+
92
+ // 2. 拼接 fullfilename 参数
93
+ const separator = fileUrl.includes('?') ? '&' : '?';
94
+ const urlToEncode = `${fileUrl}${separator}fullfilename=${safeFileName}`;
95
+
96
+ // 3. Base64 编码
97
+ const encoder = new TextEncoder();
98
+ const utf8Bytes = encoder.encode(urlToEncode);
99
+ const byteString = String.fromCharCode(...utf8Bytes);
100
+ const base64Url = btoa(byteString);
101
+
102
+ // 4. URL 编码
103
+ const finalEncodedUrl = encodeURIComponent(base64Url);
104
+
105
+ // 5. 返回最终 URL
106
+ return `${kkFileViewUrl}/onlinePreview?url=${finalEncodedUrl}`;
107
+ }
108
+
109
+ // 构建分享基础路径 /share/{shareKey}
110
+ export const buildShareBasePath = (shareKey: string): string => {
111
+ if (!shareKey) return '/share';
112
+ try {
113
+ return `/share/${encodeURIComponent(shareKey)}`;
114
+ } catch (e) {
115
+ return `/share/${shareKey}`;
116
+ }
117
+ }
@@ -0,0 +1,21 @@
1
+ import { encodeData } from 'beautify-qrcode';
2
+
3
+ export const generateQRCode = (options: Object, rendererFunc: Function) => {
4
+ const qrcode = encodeData(options);
5
+ return svgToDataUri(rendererFunc(qrcode));
6
+ }
7
+
8
+ const svgToDataUri = (svgText: string) => {
9
+ let xmlElement = document.createElement("xml")
10
+ xmlElement.innerHTML = svgText;
11
+
12
+ // 增加 svg 底色, 防止复制后是透明.
13
+ let rectElement = document.createElement("rect")
14
+ rectElement.setAttribute('width', '100%');
15
+ rectElement.setAttribute('height', '100%');
16
+ rectElement.style.fill = '#ffffff';
17
+
18
+ xmlElement.children[0].prepend(rectElement);
19
+
20
+ return 'data:image/svg+xml;utf8,' + encodeURIComponent(xmlElement.innerHTML);
21
+ }
@@ -0,0 +1,132 @@
1
+ import { reactive } from "vue";
2
+
3
+ type TimeUnit = 's' | 'm' | 'h' | 'd' | 'w' | 'M' | 'y' | 'forever';
4
+
5
+ interface TimeItem {
6
+ value: number;
7
+ unit: TimeUnit;
8
+ }
9
+
10
+ export const getUnitMax = (unit: TimeUnit): number => {
11
+ switch (unit) {
12
+ case 's':
13
+ return 59;
14
+ case 'm':
15
+ return 59;
16
+ case 'h':
17
+ return 23;
18
+ case 'd':
19
+ return 31;
20
+ case 'w':
21
+ return 52;
22
+ case 'M':
23
+ return 12;
24
+ case 'y':
25
+ return 100;
26
+ case 'forever':
27
+ return 99999999;
28
+ default:
29
+ return 0;
30
+ }
31
+ }
32
+
33
+ export const generateSeconds = (item: TimeItem): number => {
34
+ if (!item) return 0;
35
+ if (!item.value) return 0;
36
+ if (!item.unit) return 0;
37
+ if (item.unit === 'forever') return -1;
38
+ const value = parseInt(item.value.toString());
39
+ switch (item.unit) {
40
+ case "s":
41
+ return value;
42
+ case "m":
43
+ return value * 60;
44
+ case "h":
45
+ return value * 60 * 60;
46
+ case "d":
47
+ return value * 60 * 60 * 24;
48
+ case "w":
49
+ return value * 60 * 60 * 24 * 7;
50
+ case "M":
51
+ return value * 60 * 60 * 24 * 30;
52
+ case "y":
53
+ return value * 60 * 60 * 24 * 365;
54
+ default:
55
+ return 0;
56
+ }
57
+ }
58
+
59
+ interface Shortcut {
60
+ text: string;
61
+ value: () => [Date, Date];
62
+ }
63
+
64
+ export const shortcuts: Shortcut[] = [
65
+ {
66
+ text: '前一周',
67
+ value: () => {
68
+ const end = new Date();
69
+ const start = new Date();
70
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
71
+ return [start, end];
72
+ },
73
+ },
74
+ {
75
+ text: '前一月',
76
+ value: () => {
77
+ const end = new Date();
78
+ const start = new Date();
79
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
80
+ return [start, end];
81
+ },
82
+ },
83
+ {
84
+ text: '前三月',
85
+ value: () => {
86
+ const end = new Date();
87
+ const start = new Date();
88
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
89
+ return [start, end];
90
+ },
91
+ },
92
+ {
93
+ text: '前六月',
94
+ value: () => {
95
+ const end = new Date();
96
+ const start = new Date();
97
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 180);
98
+ return [start, end];
99
+ },
100
+ },
101
+ {
102
+ text: '前一年',
103
+ value: () => {
104
+ const end = new Date();
105
+ const start = new Date();
106
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
107
+ return [start, end];
108
+ },
109
+ },
110
+ ];
111
+
112
+ const pad2 = (n: number) => (n < 10 ? '0' + n : '' + n);
113
+
114
+ export const formatLocalDateTime = (date: Date) => {
115
+ if (!date) return null;
116
+ const d = new Date(date);
117
+ const yyyy = d.getFullYear();
118
+ const MM = pad2(d.getMonth() + 1);
119
+ const dd = pad2(d.getDate());
120
+ const HH = pad2(d.getHours());
121
+ const mm = pad2(d.getMinutes());
122
+ const ss = pad2(d.getSeconds());
123
+ return `${yyyy}-${MM}-${dd} ${HH}:${mm}:${ss}`;
124
+ };
125
+
126
+ // 禁用过去的日期
127
+ export const disablePastDates = (time: Date) => {
128
+ return time.getTime() < Date.now();
129
+ };
130
+
131
+ export const defaultTime = reactive([new Date(0, 0, 0, 0, 0, 0), new Date(0, 0, 0, 23, 59, 59)]);
132
+ export const dateValueFormat = 'YYYY-MM-DD HH:mm:ss';
@@ -0,0 +1,42 @@
1
+ export const openPage = (url: string) => {
2
+ window.open(url);
3
+ }
4
+
5
+ type EllipsisPosition = "start" | "middle" | "end";
6
+
7
+ export const formatEllipsis = (
8
+ value: string,
9
+ maxLength: number,
10
+ position: EllipsisPosition = "end"
11
+ ) => {
12
+ if (typeof value !== "string") {
13
+ value = value == null ? "" : String(value);
14
+ }
15
+
16
+ const input = value;
17
+ if (maxLength <= 0) {
18
+ return "";
19
+ }
20
+ if (input.length <= maxLength) {
21
+ return input;
22
+ }
23
+
24
+ if (maxLength === 1) {
25
+ return "…";
26
+ }
27
+
28
+ const visibleCount = maxLength - 1;
29
+
30
+ if (position === "start") {
31
+ return `…${input.slice(-visibleCount)}`;
32
+ }
33
+
34
+ if (position === "middle") {
35
+ const prefixLength = Math.ceil(visibleCount / 2);
36
+ const suffixLength = Math.floor(visibleCount / 2);
37
+ const suffix = suffixLength > 0 ? input.slice(-suffixLength) : "";
38
+ return `${input.slice(0, prefixLength)}…${suffix}`;
39
+ }
40
+
41
+ return `${input.slice(0, visibleCount)}…`;
42
+ }
@@ -0,0 +1,14 @@
1
+ import { computed } from 'vue'
2
+ import { useWindowSize } from '@vueuse/core'
3
+ // 当前页面宽高
4
+ export const { width: currentPageWidth, height: currentPageHeight } = useWindowSize()
5
+
6
+ // 是否为移动端
7
+ export const isMobile = computed(() => {
8
+ return currentPageWidth.value < 768;
9
+ });
10
+
11
+ // 是否为非移动端
12
+ export const isNotMobile = computed(() => {
13
+ return currentPageWidth.value >= 768;
14
+ });