sa2kit 1.6.3 → 1.6.6

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 (119) hide show
  1. package/dist/audioDetection/index.js.map +1 -1
  2. package/dist/audioDetection/index.mjs.map +1 -1
  3. package/dist/auth/index.d.mts +26 -1
  4. package/dist/auth/index.d.ts +26 -1
  5. package/dist/auth/index.js +51 -23
  6. package/dist/auth/index.js.map +1 -1
  7. package/dist/auth/index.mjs +34 -3
  8. package/dist/auth/index.mjs.map +1 -1
  9. package/dist/auth/middleware/index.js +3 -3
  10. package/dist/auth/middleware/index.mjs +2 -2
  11. package/dist/auth/routes/index.js +14 -14
  12. package/dist/auth/routes/index.mjs +2 -2
  13. package/dist/auth/services/index.d.mts +1 -0
  14. package/dist/auth/services/index.d.ts +1 -0
  15. package/dist/auth/services/index.js +7 -7
  16. package/dist/auth/services/index.mjs +1 -1
  17. package/dist/calendar/index.d.mts +1197 -0
  18. package/dist/calendar/index.d.ts +1197 -0
  19. package/dist/calendar/index.js +5376 -0
  20. package/dist/calendar/index.js.map +1 -0
  21. package/dist/calendar/index.mjs +5311 -0
  22. package/dist/calendar/index.mjs.map +1 -0
  23. package/dist/calendar/routes/index.d.mts +118 -0
  24. package/dist/calendar/routes/index.d.ts +118 -0
  25. package/dist/calendar/routes/index.js +335 -0
  26. package/dist/calendar/routes/index.js.map +1 -0
  27. package/dist/calendar/routes/index.mjs +327 -0
  28. package/dist/calendar/routes/index.mjs.map +1 -0
  29. package/dist/calendar/server.d.mts +1184 -0
  30. package/dist/calendar/server.d.ts +1184 -0
  31. package/dist/calendar/server.js +219 -0
  32. package/dist/calendar/server.js.map +1 -0
  33. package/dist/calendar/server.mjs +165 -0
  34. package/dist/calendar/server.mjs.map +1 -0
  35. package/dist/{chunk-EBP7AE6F.js → chunk-2ODO4HEI.js} +48 -20
  36. package/dist/chunk-2ODO4HEI.js.map +1 -0
  37. package/dist/{chunk-RCNNVNLT.mjs → chunk-3BGPZN4X.mjs} +8 -3
  38. package/dist/chunk-3BGPZN4X.mjs.map +1 -0
  39. package/dist/{chunk-FV3FNHQY.js → chunk-6W5BMXJG.js} +4 -4
  40. package/dist/{chunk-FV3FNHQY.js.map → chunk-6W5BMXJG.js.map} +1 -1
  41. package/dist/chunk-6WXOA4BE.mjs +302 -0
  42. package/dist/chunk-6WXOA4BE.mjs.map +1 -0
  43. package/dist/{chunk-NMF4ANIC.js → chunk-7Z5LLJ3A.js} +8 -2
  44. package/dist/chunk-7Z5LLJ3A.js.map +1 -0
  45. package/dist/chunk-AXP7KROR.js +314 -0
  46. package/dist/chunk-AXP7KROR.js.map +1 -0
  47. package/dist/{chunk-42IJ7HEI.js → chunk-CD77U7LZ.js} +5 -5
  48. package/dist/{chunk-42IJ7HEI.js.map → chunk-CD77U7LZ.js.map} +1 -1
  49. package/dist/{chunk-6BL3AZGD.js → chunk-DUHZ7VZP.js} +2 -2
  50. package/dist/chunk-DUHZ7VZP.js.map +1 -0
  51. package/dist/{chunk-6VHWOPRR.mjs → chunk-ESRCX5TQ.mjs} +3 -3
  52. package/dist/{chunk-6VHWOPRR.mjs.map → chunk-ESRCX5TQ.mjs.map} +1 -1
  53. package/dist/{chunk-QKXKXAAV.js → chunk-G4AMEDO5.js} +2 -2
  54. package/dist/{chunk-QKXKXAAV.js.map → chunk-G4AMEDO5.js.map} +1 -1
  55. package/dist/chunk-GAC4J5GX.js +228 -0
  56. package/dist/chunk-GAC4J5GX.js.map +1 -0
  57. package/dist/chunk-IEA55H3G.js +106 -0
  58. package/dist/chunk-IEA55H3G.js.map +1 -0
  59. package/dist/{chunk-U2L6V7KD.mjs → chunk-OCR5DS4C.mjs} +2 -2
  60. package/dist/chunk-OCR5DS4C.mjs.map +1 -0
  61. package/dist/{chunk-IBLB7ARJ.mjs → chunk-QAT2RWAO.mjs} +3 -3
  62. package/dist/{chunk-IBLB7ARJ.mjs.map → chunk-QAT2RWAO.mjs.map} +1 -1
  63. package/dist/chunk-R2F4BXUU.mjs +100 -0
  64. package/dist/chunk-R2F4BXUU.mjs.map +1 -0
  65. package/dist/chunk-T6TE7GTY.mjs +218 -0
  66. package/dist/chunk-T6TE7GTY.mjs.map +1 -0
  67. package/dist/{chunk-MBG4DBGP.mjs → chunk-ZCLAF3XN.mjs} +47 -19
  68. package/dist/chunk-ZCLAF3XN.mjs.map +1 -0
  69. package/dist/{chunk-6LEA37ZM.mjs → chunk-ZYXF3L6T.mjs} +2 -2
  70. package/dist/{chunk-6LEA37ZM.mjs.map → chunk-ZYXF3L6T.mjs.map} +1 -1
  71. package/dist/imageCrop/index.js.map +1 -1
  72. package/dist/imageCrop/index.mjs.map +1 -1
  73. package/dist/{index-DtLpANUB.d.mts → index-DSel44Ke.d.mts} +24 -1
  74. package/dist/{index-DtLpANUB.d.ts → index-DSel44Ke.d.ts} +24 -1
  75. package/dist/index.d.mts +426 -3
  76. package/dist/index.d.ts +426 -3
  77. package/dist/index.js +2116 -65
  78. package/dist/index.js.map +1 -1
  79. package/dist/index.mjs +1949 -33
  80. package/dist/index.mjs.map +1 -1
  81. package/dist/mmd/index.d.mts +78 -1
  82. package/dist/mmd/index.d.ts +78 -1
  83. package/dist/mmd/index.js +397 -50
  84. package/dist/mmd/index.js.map +1 -1
  85. package/dist/mmd/index.mjs +399 -53
  86. package/dist/mmd/index.mjs.map +1 -1
  87. package/dist/music/index.d.mts +54 -5
  88. package/dist/music/index.d.ts +54 -5
  89. package/dist/music/index.js +35 -435
  90. package/dist/music/index.js.map +1 -1
  91. package/dist/music/index.mjs +2 -424
  92. package/dist/music/index.mjs.map +1 -1
  93. package/dist/music/server/index.d.mts +1 -1
  94. package/dist/music/server/index.d.ts +1 -1
  95. package/dist/music/server/index.js +14 -6
  96. package/dist/music/server/index.mjs +1 -1
  97. package/dist/testYourself/admin/index.js +3 -3
  98. package/dist/testYourself/admin/index.mjs +1 -1
  99. package/dist/testYourself/index.js +7 -7
  100. package/dist/testYourself/index.js.map +1 -1
  101. package/dist/testYourself/index.mjs +2 -2
  102. package/dist/testYourself/index.mjs.map +1 -1
  103. package/dist/universalFile/index.d.mts +125 -7
  104. package/dist/universalFile/index.d.ts +125 -7
  105. package/dist/universalFile/index.js +1253 -30
  106. package/dist/universalFile/index.js.map +1 -1
  107. package/dist/universalFile/index.mjs +1244 -23
  108. package/dist/universalFile/index.mjs.map +1 -1
  109. package/dist/utils/index.d.mts +5 -1
  110. package/dist/utils/index.d.ts +5 -1
  111. package/dist/utils/index.js +13 -9
  112. package/dist/utils/index.mjs +1 -1
  113. package/package.json +18 -3
  114. package/dist/chunk-6BL3AZGD.js.map +0 -1
  115. package/dist/chunk-EBP7AE6F.js.map +0 -1
  116. package/dist/chunk-MBG4DBGP.mjs.map +0 -1
  117. package/dist/chunk-NMF4ANIC.js.map +0 -1
  118. package/dist/chunk-RCNNVNLT.mjs.map +0 -1
  119. package/dist/chunk-U2L6V7KD.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  export { CDNProviderError, FileProcessingError, FileServiceError, FileUploadError, StorageProviderError } from '../chunk-CIVO4R6N.mjs';
2
2
  import '../chunk-BJTO5JO5.mjs';
3
- import React, { useState, useRef, useCallback } from 'react';
3
+ import React2, { useState, useRef, useCallback, useEffect } from 'react';
4
4
  import { Upload, AlertCircle, CheckCircle2, Loader2, X, Image, Film, Music, FileText } from 'lucide-react';
5
5
 
6
6
  // src/universalFile/constants.ts
@@ -793,10 +793,10 @@ var FileUploader = ({
793
793
  const [completedFiles, setCompletedFiles] = useState([]);
794
794
  const fileInputRef = useRef(null);
795
795
  const getFileIcon = (mimeType) => {
796
- if (mimeType.startsWith("image/")) return /* @__PURE__ */ React.createElement(Image, { className: "w-5 h-5" });
797
- if (mimeType.startsWith("video/")) return /* @__PURE__ */ React.createElement(Film, { className: "w-5 h-5" });
798
- if (mimeType.startsWith("audio/")) return /* @__PURE__ */ React.createElement(Music, { className: "w-5 h-5" });
799
- return /* @__PURE__ */ React.createElement(FileText, { className: "w-5 h-5" });
796
+ if (mimeType.startsWith("image/")) return /* @__PURE__ */ React2.createElement(Image, { className: "w-5 h-5" });
797
+ if (mimeType.startsWith("video/")) return /* @__PURE__ */ React2.createElement(Film, { className: "w-5 h-5" });
798
+ if (mimeType.startsWith("audio/")) return /* @__PURE__ */ React2.createElement(Music, { className: "w-5 h-5" });
799
+ return /* @__PURE__ */ React2.createElement(FileText, { className: "w-5 h-5" });
800
800
  };
801
801
  const validateFile2 = (file) => {
802
802
  if (file.size > maxFileSize * 1024 * 1024) {
@@ -955,7 +955,7 @@ var FileUploader = ({
955
955
  p-6 text-center
956
956
  ${mode === "compact" ? "p-4" : mode === "detailed" ? "p-8" : "p-6"}
957
957
  `;
958
- return /* @__PURE__ */ React.createElement("div", { className: "w-full space-y-4" }, /* @__PURE__ */ React.createElement(
958
+ return /* @__PURE__ */ React2.createElement("div", { className: "w-full space-y-4" }, /* @__PURE__ */ React2.createElement(
959
959
  "div",
960
960
  {
961
961
  className: containerClasses,
@@ -964,13 +964,13 @@ var FileUploader = ({
964
964
  onDrop: handleDrop,
965
965
  onClick: handleClick
966
966
  },
967
- /* @__PURE__ */ React.createElement("div", { className: uploadAreaClasses }, /* @__PURE__ */ React.createElement(
967
+ /* @__PURE__ */ React2.createElement("div", { className: uploadAreaClasses }, /* @__PURE__ */ React2.createElement(
968
968
  Upload,
969
969
  {
970
970
  className: `mx-auto mb-4 text-gray-400 ${mode === "compact" ? "w-8 h-8 mb-2" : "w-12 h-12"}`
971
971
  }
972
- ), mode === "compact" ? /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400" }, "\u70B9\u51FB\u4E0A\u4F20\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-semibold text-gray-700 dark:text-gray-300 mb-2" }, "\u4E0A\u4F20\u6587\u4EF6"), /* @__PURE__ */ React.createElement("p", { className: "text-gray-600 dark:text-gray-400 mb-2" }, "\u70B9\u51FB\u9009\u62E9\u6587\u4EF6\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC"), mode === "detailed" && /* @__PURE__ */ React.createElement("div", { className: "text-sm text-gray-500 space-y-1" }, acceptedTypes.length > 0 && /* @__PURE__ */ React.createElement("p", null, "\u652F\u6301\u683C\u5F0F: ", acceptedTypes.join(", ")), /* @__PURE__ */ React.createElement("p", null, "\u6700\u5927\u5927\u5C0F: ", maxFileSize, "MB | \u6700\u591A\u6587\u4EF6: ", maxFiles, "\u4E2A")))),
973
- /* @__PURE__ */ React.createElement(
972
+ ), mode === "compact" ? /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400" }, "\u70B9\u51FB\u4E0A\u4F20\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC") : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("h3", { className: "text-lg font-semibold text-gray-700 dark:text-gray-300 mb-2" }, "\u4E0A\u4F20\u6587\u4EF6"), /* @__PURE__ */ React2.createElement("p", { className: "text-gray-600 dark:text-gray-400 mb-2" }, "\u70B9\u51FB\u9009\u62E9\u6587\u4EF6\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC"), mode === "detailed" && /* @__PURE__ */ React2.createElement("div", { className: "text-sm text-gray-500 space-y-1" }, acceptedTypes.length > 0 && /* @__PURE__ */ React2.createElement("p", null, "\u652F\u6301\u683C\u5F0F: ", acceptedTypes.join(", ")), /* @__PURE__ */ React2.createElement("p", null, "\u6700\u5927\u5927\u5C0F: ", maxFileSize, "MB | \u6700\u591A\u6587\u4EF6: ", maxFiles, "\u4E2A")))),
973
+ /* @__PURE__ */ React2.createElement(
974
974
  "input",
975
975
  {
976
976
  ref: fileInputRef,
@@ -982,21 +982,21 @@ var FileUploader = ({
982
982
  disabled
983
983
  }
984
984
  )
985
- ), uploadingFiles.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u4E0A\u4F20\u4E2D (", uploadingFiles.length, ")"), uploadingFiles.map((uploadingFile) => /* @__PURE__ */ React.createElement(
985
+ ), uploadingFiles.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u4E0A\u4F20\u4E2D (", uploadingFiles.length, ")"), uploadingFiles.map((uploadingFile) => /* @__PURE__ */ React2.createElement(
986
986
  "div",
987
987
  {
988
988
  key: uploadingFile.id,
989
989
  className: "flex items-center space-x-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg"
990
990
  },
991
- /* @__PURE__ */ React.createElement("div", { className: "flex-shrink-0" }, uploadingFile.progress.status === "failed" ? /* @__PURE__ */ React.createElement(AlertCircle, { className: "w-5 h-5 text-red-500" }) : uploadingFile.progress.status === "completed" ? /* @__PURE__ */ React.createElement(CheckCircle2, { className: "w-5 h-5 text-green-500" }) : /* @__PURE__ */ React.createElement(Loader2, { className: "w-5 h-5 text-blue-500 animate-spin" })),
992
- /* @__PURE__ */ React.createElement("div", { className: "flex-grow min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between mb-1" }, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate" }, uploadingFile.file.name), /* @__PURE__ */ React.createElement("span", { className: "text-xs text-gray-500" }, formatFileSize2(uploadingFile.file.size))), uploadingFile.error ? /* @__PURE__ */ React.createElement("p", { className: "text-xs text-red-500" }, uploadingFile.error) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 mb-1" }, /* @__PURE__ */ React.createElement(
991
+ /* @__PURE__ */ React2.createElement("div", { className: "flex-shrink-0" }, uploadingFile.progress.status === "failed" ? /* @__PURE__ */ React2.createElement(AlertCircle, { className: "w-5 h-5 text-red-500" }) : uploadingFile.progress.status === "completed" ? /* @__PURE__ */ React2.createElement(CheckCircle2, { className: "w-5 h-5 text-green-500" }) : /* @__PURE__ */ React2.createElement(Loader2, { className: "w-5 h-5 text-blue-500 animate-spin" })),
992
+ /* @__PURE__ */ React2.createElement("div", { className: "flex-grow min-w-0" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mb-1" }, /* @__PURE__ */ React2.createElement("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate" }, uploadingFile.file.name), /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-gray-500" }, formatFileSize2(uploadingFile.file.size))), uploadingFile.error ? /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-red-500" }, uploadingFile.error) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { className: "w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 mb-1" }, /* @__PURE__ */ React2.createElement(
993
993
  "div",
994
994
  {
995
995
  className: "bg-blue-500 h-2 rounded-full transition-all duration-300",
996
996
  style: { width: `${uploadingFile.progress.progress}%` }
997
997
  }
998
- )), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-gray-500" }, formatProgress(uploadingFile.progress)))),
999
- /* @__PURE__ */ React.createElement(
998
+ )), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-gray-500" }, formatProgress(uploadingFile.progress)))),
999
+ /* @__PURE__ */ React2.createElement(
1000
1000
  "button",
1001
1001
  {
1002
1002
  onClick: (e) => {
@@ -1005,17 +1005,17 @@ var FileUploader = ({
1005
1005
  },
1006
1006
  className: "flex-shrink-0 p-1 text-gray-400 hover:text-red-500 transition-colors"
1007
1007
  },
1008
- /* @__PURE__ */ React.createElement(X, { className: "w-4 h-4" })
1008
+ /* @__PURE__ */ React2.createElement(X, { className: "w-4 h-4" })
1009
1009
  )
1010
- ))), completedFiles.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u5DF2\u5B8C\u6210 (", completedFiles.length, ")"), completedFiles.map((file) => /* @__PURE__ */ React.createElement(
1010
+ ))), completedFiles.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u5DF2\u5B8C\u6210 (", completedFiles.length, ")"), completedFiles.map((file) => /* @__PURE__ */ React2.createElement(
1011
1011
  "div",
1012
1012
  {
1013
1013
  key: file.id,
1014
1014
  className: "flex items-center space-x-3 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg"
1015
1015
  },
1016
- /* @__PURE__ */ React.createElement("div", { className: "flex-shrink-0" }, getFileIcon(file.mimeType)),
1017
- /* @__PURE__ */ React.createElement("div", { className: "flex-grow min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between mb-1" }, /* @__PURE__ */ React.createElement("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate" }, file.originalName), /* @__PURE__ */ React.createElement("span", { className: "text-xs text-gray-500" }, formatFileSize2(file.size))), /* @__PURE__ */ React.createElement("p", { className: "text-xs text-green-600 dark:text-green-400" }, "\u4E0A\u4F20\u6210\u529F \u2022 ", new Date(file.uploadTime).toLocaleTimeString())),
1018
- /* @__PURE__ */ React.createElement(
1016
+ /* @__PURE__ */ React2.createElement("div", { className: "flex-shrink-0" }, getFileIcon(file.mimeType)),
1017
+ /* @__PURE__ */ React2.createElement("div", { className: "flex-grow min-w-0" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mb-1" }, /* @__PURE__ */ React2.createElement("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate" }, file.originalName), /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-gray-500" }, formatFileSize2(file.size))), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-green-600 dark:text-green-400" }, "\u4E0A\u4F20\u6210\u529F \u2022 ", new Date(file.uploadTime).toLocaleTimeString())),
1018
+ /* @__PURE__ */ React2.createElement(
1019
1019
  "button",
1020
1020
  {
1021
1021
  onClick: (e) => {
@@ -1024,17 +1024,1238 @@ var FileUploader = ({
1024
1024
  },
1025
1025
  className: "flex-shrink-0 p-1 text-gray-400 hover:text-red-500 transition-colors"
1026
1026
  },
1027
- /* @__PURE__ */ React.createElement(X, { className: "w-4 h-4" })
1027
+ /* @__PURE__ */ React2.createElement(X, { className: "w-4 h-4" })
1028
1028
  )
1029
- ))), mode === "detailed" && (completedFiles.length > 0 || uploadingFiles.length > 0) && /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center text-sm text-gray-500 pt-2 border-t border-gray-200 dark:border-gray-700" }, /* @__PURE__ */ React.createElement("span", null, "\u603B\u8BA1: ", completedFiles.length + uploadingFiles.length, " \u6587\u4EF6"), /* @__PURE__ */ React.createElement("span", null, "\u5927\u5C0F:", " ", formatFileSize2(
1029
+ ))), mode === "detailed" && (completedFiles.length > 0 || uploadingFiles.length > 0) && /* @__PURE__ */ React2.createElement("div", { className: "flex justify-between items-center text-sm text-gray-500 pt-2 border-t border-gray-200 dark:border-gray-700" }, /* @__PURE__ */ React2.createElement("span", null, "\u603B\u8BA1: ", completedFiles.length + uploadingFiles.length, " \u6587\u4EF6"), /* @__PURE__ */ React2.createElement("span", null, "\u5927\u5C0F:", " ", formatFileSize2(
1030
1030
  [
1031
1031
  ...completedFiles.map((f) => f.size),
1032
1032
  ...uploadingFiles.map((f) => f.file.size)
1033
1033
  ].reduce((total, size) => total + size, 0)
1034
1034
  ))));
1035
1035
  };
1036
- var FileUploader_default = FileUploader;
1036
+ var MIME_TYPE_CATEGORIES = {
1037
+ "image": ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
1038
+ "video": ["video/mp4", "video/avi", "video/mov", "video/webm"],
1039
+ "audio": ["audio/mp3", "audio/wav", "audio/ogg", "audio/aac"],
1040
+ "document": ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
1041
+ "archive": ["application/zip", "application/x-rar-compressed", "application/x-7z-compressed"]
1042
+ };
1043
+ var UniversalFileManager = ({
1044
+ moduleId,
1045
+ businessId,
1046
+ mode = "grid",
1047
+ allowUpload = true,
1048
+ allowDownload = true,
1049
+ allowDelete = false,
1050
+ allowBatch = true,
1051
+ showPreview = true,
1052
+ showSearch = true,
1053
+ showFilters = true,
1054
+ pageSize = 20,
1055
+ customActions = [],
1056
+ onFileSelect,
1057
+ onUploadComplete
1058
+ }) => {
1059
+ const [state, setState] = useState({
1060
+ files: [],
1061
+ selectedFiles: /* @__PURE__ */ new Set(),
1062
+ loading: false,
1063
+ uploading: false,
1064
+ error: null,
1065
+ searchQuery: "",
1066
+ filters: {
1067
+ mimeType: "",
1068
+ dateRange: { start: null, end: null },
1069
+ sizeRange: { min: 0, max: Number.MAX_SAFE_INTEGER }
1070
+ },
1071
+ sortBy: "uploadTime",
1072
+ sortOrder: "desc",
1073
+ pagination: {
1074
+ page: 1,
1075
+ pageSize,
1076
+ total: 0,
1077
+ totalPages: 0
1078
+ },
1079
+ previewFile: null,
1080
+ showUploadModal: false
1081
+ });
1082
+ const loadFiles = useCallback(async () => {
1083
+ setState((prev) => ({ ...prev, loading: true, error: null }));
1084
+ try {
1085
+ const queryOptions = {
1086
+ moduleId,
1087
+ businessId,
1088
+ page: state.pagination.page,
1089
+ pageSize: state.pagination.pageSize,
1090
+ sortBy: state.sortBy,
1091
+ sortOrder: state.sortOrder
1092
+ };
1093
+ if (state.searchQuery) {
1094
+ }
1095
+ if (state.filters.mimeType) {
1096
+ queryOptions.mimeType = state.filters.mimeType;
1097
+ }
1098
+ if (state.filters.dateRange.start) {
1099
+ queryOptions.startTime = state.filters.dateRange.start;
1100
+ }
1101
+ if (state.filters.dateRange.end) {
1102
+ queryOptions.endTime = state.filters.dateRange.end;
1103
+ }
1104
+ const mockResult = {
1105
+ items: [],
1106
+ total: 0,
1107
+ page: queryOptions.page || 1,
1108
+ pageSize: queryOptions.pageSize || 20,
1109
+ totalPages: 0,
1110
+ hasNext: false,
1111
+ hasPrev: false
1112
+ };
1113
+ setState((prev) => ({
1114
+ ...prev,
1115
+ files: mockResult.items,
1116
+ pagination: {
1117
+ page: mockResult.page,
1118
+ pageSize: mockResult.pageSize,
1119
+ total: mockResult.total,
1120
+ totalPages: mockResult.totalPages
1121
+ },
1122
+ loading: false
1123
+ }));
1124
+ } catch (error) {
1125
+ console.error("\u52A0\u8F7D\u6587\u4EF6\u5217\u8868\u5931\u8D25:", error);
1126
+ setState((prev) => ({
1127
+ ...prev,
1128
+ loading: false,
1129
+ error: error instanceof Error ? error.message : "\u52A0\u8F7D\u6587\u4EF6\u5217\u8868\u5931\u8D25"
1130
+ }));
1131
+ }
1132
+ }, [moduleId, businessId, state.searchQuery, state.filters, state.sortBy, state.sortOrder, state.pagination.page, state.pagination.pageSize]);
1133
+ useEffect(() => {
1134
+ loadFiles();
1135
+ }, [loadFiles]);
1136
+ const handleFileSelect = useCallback((fileId, selected) => {
1137
+ setState((prev) => {
1138
+ const newSelectedFiles = new Set(prev.selectedFiles);
1139
+ if (selected) {
1140
+ newSelectedFiles.add(fileId);
1141
+ } else {
1142
+ newSelectedFiles.delete(fileId);
1143
+ }
1144
+ const selectedFileList = prev.files.filter((file) => newSelectedFiles.has(file.id));
1145
+ if (onFileSelect) {
1146
+ onFileSelect(selectedFileList);
1147
+ }
1148
+ return {
1149
+ ...prev,
1150
+ selectedFiles: newSelectedFiles
1151
+ };
1152
+ });
1153
+ }, [onFileSelect, state.files]);
1154
+ const handleSelectAll = useCallback((selected) => {
1155
+ setState((prev) => {
1156
+ const newSelectedFiles = selected ? new Set(prev.files.map((file) => file.id)) : /* @__PURE__ */ new Set();
1157
+ const selectedFileList = selected ? prev.files : [];
1158
+ if (onFileSelect) {
1159
+ onFileSelect(selectedFileList);
1160
+ }
1161
+ return {
1162
+ ...prev,
1163
+ selectedFiles: newSelectedFiles
1164
+ };
1165
+ });
1166
+ }, [onFileSelect, state.files]);
1167
+ const handleDeleteFiles = useCallback(async (fileIds) => {
1168
+ if (!window.confirm(`\u786E\u5B9A\u8981\u5220\u9664\u9009\u4E2D\u7684 ${fileIds.length} \u4E2A\u6587\u4EF6\u5417\uFF1F`)) {
1169
+ return;
1170
+ }
1171
+ setState((prev) => ({ ...prev, loading: true }));
1172
+ try {
1173
+ console.log("\u5220\u9664\u6587\u4EF6:", fileIds);
1174
+ await loadFiles();
1175
+ setState((prev) => ({
1176
+ ...prev,
1177
+ selectedFiles: /* @__PURE__ */ new Set(),
1178
+ loading: false
1179
+ }));
1180
+ } catch (error) {
1181
+ console.error("\u5220\u9664\u6587\u4EF6\u5931\u8D25:", error);
1182
+ setState((prev) => ({
1183
+ ...prev,
1184
+ loading: false,
1185
+ error: error instanceof Error ? error.message : "\u5220\u9664\u6587\u4EF6\u5931\u8D25"
1186
+ }));
1187
+ }
1188
+ }, [loadFiles]);
1189
+ const handleDownloadFile = useCallback(async (file) => {
1190
+ try {
1191
+ console.log("\u4E0B\u8F7D\u6587\u4EF6:", file.originalName);
1192
+ } catch (error) {
1193
+ console.error("\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25:", error);
1194
+ setState((prev) => ({
1195
+ ...prev,
1196
+ error: error instanceof Error ? error.message : "\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25"
1197
+ }));
1198
+ }
1199
+ }, []);
1200
+ const handlePreviewFile = useCallback((file) => {
1201
+ setState((prev) => ({
1202
+ ...prev,
1203
+ previewFile: file
1204
+ }));
1205
+ }, []);
1206
+ const handleClosePreview = useCallback(() => {
1207
+ setState((prev) => ({
1208
+ ...prev,
1209
+ previewFile: null
1210
+ }));
1211
+ }, []);
1212
+ const handleSearch = useCallback((query) => {
1213
+ setState((prev) => ({
1214
+ ...prev,
1215
+ searchQuery: query,
1216
+ pagination: { ...prev.pagination, page: 1 }
1217
+ }));
1218
+ }, []);
1219
+ const handleFilterChange = useCallback((filterType, value) => {
1220
+ setState((prev) => ({
1221
+ ...prev,
1222
+ filters: {
1223
+ ...prev.filters,
1224
+ [filterType]: value
1225
+ },
1226
+ pagination: { ...prev.pagination, page: 1 }
1227
+ }));
1228
+ }, []);
1229
+ useCallback((field) => {
1230
+ setState((prev) => ({
1231
+ ...prev,
1232
+ sortBy: field,
1233
+ sortOrder: prev.sortBy === field && prev.sortOrder === "asc" ? "desc" : "asc",
1234
+ pagination: { ...prev.pagination, page: 1 }
1235
+ }));
1236
+ }, []);
1237
+ const handlePageChange = useCallback((page) => {
1238
+ setState((prev) => ({
1239
+ ...prev,
1240
+ pagination: { ...prev.pagination, page }
1241
+ }));
1242
+ }, []);
1243
+ const formatFileSize2 = useCallback((bytes) => {
1244
+ if (bytes === 0) return "0 B";
1245
+ const k = 1024;
1246
+ const sizes = ["B", "KB", "MB", "GB", "TB"];
1247
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1248
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
1249
+ }, []);
1250
+ const getFileTypeIcon = useCallback((mimeType) => {
1251
+ if (mimeType.startsWith("image/")) return "\u{1F5BC}\uFE0F";
1252
+ if (mimeType.startsWith("video/")) return "\u{1F3AC}";
1253
+ if (mimeType.startsWith("audio/")) return "\u{1F3B5}";
1254
+ if (mimeType.includes("pdf")) return "\u{1F4C4}";
1255
+ if (mimeType.includes("word")) return "\u{1F4DD}";
1256
+ if (mimeType.includes("excel")) return "\u{1F4CA}";
1257
+ if (mimeType.includes("powerpoint")) return "\u{1F4CA}";
1258
+ if (mimeType.includes("zip") || mimeType.includes("rar")) return "\u{1F4E6}";
1259
+ return "\u{1F4C1}";
1260
+ }, []);
1261
+ const getFileTypeLabel = useCallback((mimeType) => {
1262
+ for (const [category, types] of Object.entries(MIME_TYPE_CATEGORIES)) {
1263
+ if (types.some((type) => mimeType.includes(type))) {
1264
+ return category;
1265
+ }
1266
+ }
1267
+ return "other";
1268
+ }, []);
1269
+ const isPreviewable = useCallback((file) => {
1270
+ return file.mimeType.startsWith("image/") || file.mimeType.startsWith("video/") || file.mimeType.startsWith("audio/") || file.mimeType.includes("pdf");
1271
+ }, []);
1272
+ const renderFileItem = useCallback((file) => {
1273
+ const isSelected = state.selectedFiles.has(file.id);
1274
+ const typeIcon = getFileTypeIcon(file.mimeType);
1275
+ const typeLabel = getFileTypeLabel(file.mimeType);
1276
+ return /* @__PURE__ */ React2.createElement(
1277
+ "div",
1278
+ {
1279
+ key: file.id,
1280
+ className: `relative border rounded-lg p-4 cursor-pointer transition-all duration-200 hover:shadow-md ${isSelected ? "border-blue-500 bg-blue-50" : "border-gray-200 hover:border-gray-300"}`,
1281
+ onClick: () => handleFileSelect(file.id, !isSelected)
1282
+ },
1283
+ allowBatch && /* @__PURE__ */ React2.createElement("div", { className: "absolute top-2 left-2" }, /* @__PURE__ */ React2.createElement(
1284
+ "input",
1285
+ {
1286
+ type: "checkbox",
1287
+ checked: isSelected,
1288
+ onChange: (e) => {
1289
+ e.stopPropagation();
1290
+ handleFileSelect(file.id, e.target.checked);
1291
+ },
1292
+ className: "w-4 h-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
1293
+ }
1294
+ )),
1295
+ /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col items-center space-y-2" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl" }, typeIcon), /* @__PURE__ */ React2.createElement("div", { className: "text-center w-full" }, /* @__PURE__ */ React2.createElement("h3", { className: "font-medium text-sm text-gray-900 truncate", title: file.originalName }, file.originalName), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-gray-500 mt-1" }, formatFileSize2(file.size)), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-blue-600 capitalize" }, typeLabel), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-gray-400" }, new Date(file.uploadTime).toLocaleDateString()))),
1296
+ /* @__PURE__ */ React2.createElement("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity" }, /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-1" }, showPreview && isPreviewable(file) && /* @__PURE__ */ React2.createElement(
1297
+ "button",
1298
+ {
1299
+ onClick: (e) => {
1300
+ e.stopPropagation();
1301
+ handlePreviewFile(file);
1302
+ },
1303
+ className: "p-1 text-gray-600 hover:text-blue-600 hover:bg-white rounded",
1304
+ title: "\u9884\u89C8"
1305
+ },
1306
+ "\u{1F441}\uFE0F"
1307
+ ), allowDownload && /* @__PURE__ */ React2.createElement(
1308
+ "button",
1309
+ {
1310
+ onClick: (e) => {
1311
+ e.stopPropagation();
1312
+ handleDownloadFile(file);
1313
+ },
1314
+ className: "p-1 text-gray-600 hover:text-green-600 hover:bg-white rounded",
1315
+ title: "\u4E0B\u8F7D"
1316
+ },
1317
+ "\u2B07\uFE0F"
1318
+ ), allowDelete && /* @__PURE__ */ React2.createElement(
1319
+ "button",
1320
+ {
1321
+ onClick: (e) => {
1322
+ e.stopPropagation();
1323
+ handleDeleteFiles([file.id]);
1324
+ },
1325
+ className: "p-1 text-gray-600 hover:text-red-600 hover:bg-white rounded",
1326
+ title: "\u5220\u9664"
1327
+ },
1328
+ "\u{1F5D1}\uFE0F"
1329
+ )))
1330
+ );
1331
+ }, [
1332
+ state.selectedFiles,
1333
+ allowBatch,
1334
+ allowDownload,
1335
+ allowDelete,
1336
+ showPreview,
1337
+ handleFileSelect,
1338
+ handlePreviewFile,
1339
+ handleDownloadFile,
1340
+ handleDeleteFiles,
1341
+ getFileTypeIcon,
1342
+ getFileTypeLabel,
1343
+ formatFileSize2,
1344
+ isPreviewable
1345
+ ]);
1346
+ const renderSearchBar = () => {
1347
+ if (!showSearch) return null;
1348
+ return /* @__PURE__ */ React2.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement(
1349
+ "input",
1350
+ {
1351
+ type: "text",
1352
+ placeholder: "\u641C\u7D22\u6587\u4EF6\u540D...",
1353
+ value: state.searchQuery,
1354
+ onChange: (e) => handleSearch(e.target.value),
1355
+ className: "w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
1356
+ }
1357
+ ), /* @__PURE__ */ React2.createElement("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" }, /* @__PURE__ */ React2.createElement("span", { className: "text-gray-400" }, "\u{1F50D}"))));
1358
+ };
1359
+ const renderFilters = () => {
1360
+ if (!showFilters) return null;
1361
+ return /* @__PURE__ */ React2.createElement("div", { className: "mb-6 p-4 bg-gray-50 rounded-lg" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-medium text-gray-700 mb-3" }, "\u7B5B\u9009\u5668"), /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-xs font-medium text-gray-700 mb-1" }, "\u6587\u4EF6\u7C7B\u578B"), /* @__PURE__ */ React2.createElement(
1362
+ "select",
1363
+ {
1364
+ value: state.filters.mimeType,
1365
+ onChange: (e) => handleFilterChange("mimeType", e.target.value),
1366
+ className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
1367
+ },
1368
+ /* @__PURE__ */ React2.createElement("option", { value: "" }, "\u5168\u90E8"),
1369
+ /* @__PURE__ */ React2.createElement("option", { value: "image/" }, "\u56FE\u7247"),
1370
+ /* @__PURE__ */ React2.createElement("option", { value: "video/" }, "\u89C6\u9891"),
1371
+ /* @__PURE__ */ React2.createElement("option", { value: "audio/" }, "\u97F3\u9891"),
1372
+ /* @__PURE__ */ React2.createElement("option", { value: "application/pdf" }, "PDF"),
1373
+ /* @__PURE__ */ React2.createElement("option", { value: "application/" }, "\u6587\u6863")
1374
+ )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-xs font-medium text-gray-700 mb-1" }, "\u4E0A\u4F20\u65F6\u95F4"), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
1375
+ "input",
1376
+ {
1377
+ type: "date",
1378
+ value: state.filters.dateRange.start?.toISOString().split("T")[0] || "",
1379
+ onChange: (e) => handleFilterChange("dateRange", {
1380
+ ...state.filters.dateRange,
1381
+ start: e.target.value ? new Date(e.target.value) : null
1382
+ }),
1383
+ className: "flex-1 px-2 py-1 text-xs border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
1384
+ }
1385
+ ), /* @__PURE__ */ React2.createElement(
1386
+ "input",
1387
+ {
1388
+ type: "date",
1389
+ value: state.filters.dateRange.end?.toISOString().split("T")[0] || "",
1390
+ onChange: (e) => handleFilterChange("dateRange", {
1391
+ ...state.filters.dateRange,
1392
+ end: e.target.value ? new Date(e.target.value) : null
1393
+ }),
1394
+ className: "flex-1 px-2 py-1 text-xs border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
1395
+ }
1396
+ ))), /* @__PURE__ */ React2.createElement("div", { className: "flex items-end" }, /* @__PURE__ */ React2.createElement(
1397
+ "button",
1398
+ {
1399
+ onClick: () => setState((prev) => ({
1400
+ ...prev,
1401
+ filters: {
1402
+ mimeType: "",
1403
+ dateRange: { start: null, end: null },
1404
+ sizeRange: { min: 0, max: Number.MAX_SAFE_INTEGER }
1405
+ }
1406
+ })),
1407
+ className: "px-3 py-2 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50"
1408
+ },
1409
+ "\u6E05\u9664\u7B5B\u9009"
1410
+ ))));
1411
+ };
1412
+ const renderToolbar = () => {
1413
+ const selectedCount = state.selectedFiles.size;
1414
+ const hasSelection = selectedCount > 0;
1415
+ return /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mb-6" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-4" }, allowBatch && state.files.length > 0 && /* @__PURE__ */ React2.createElement("label", { className: "flex items-center space-x-2" }, /* @__PURE__ */ React2.createElement(
1416
+ "input",
1417
+ {
1418
+ type: "checkbox",
1419
+ checked: selectedCount === state.files.length && state.files.length > 0,
1420
+ onChange: (e) => handleSelectAll(e.target.checked),
1421
+ className: "w-4 h-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
1422
+ }
1423
+ ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-gray-700" }, "\u5168\u9009 (", selectedCount, "/", state.files.length, ")")), hasSelection && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2" }, allowDelete && /* @__PURE__ */ React2.createElement(
1424
+ "button",
1425
+ {
1426
+ onClick: () => handleDeleteFiles(Array.from(state.selectedFiles)),
1427
+ className: "px-3 py-1 text-sm text-red-600 border border-red-300 rounded hover:bg-red-50"
1428
+ },
1429
+ "\u5220\u9664\u9009\u4E2D (",
1430
+ selectedCount,
1431
+ ")"
1432
+ ), customActions.map((action) => {
1433
+ const selectedFileList = state.files.filter((file) => state.selectedFiles.has(file.id));
1434
+ const isDisabled = action.disabled?.(selectedFileList) || false;
1435
+ return /* @__PURE__ */ React2.createElement(
1436
+ "button",
1437
+ {
1438
+ key: action.key,
1439
+ onClick: () => action.onClick(selectedFileList),
1440
+ disabled: isDisabled,
1441
+ className: `px-3 py-1 text-sm border rounded ${isDisabled ? "text-gray-400 border-gray-200 cursor-not-allowed" : "text-blue-600 border-blue-300 hover:bg-blue-50"}`
1442
+ },
1443
+ action.icon && /* @__PURE__ */ React2.createElement("span", { className: "mr-1" }, action.icon),
1444
+ action.label
1445
+ );
1446
+ }))), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-4" }, /* @__PURE__ */ React2.createElement(
1447
+ "select",
1448
+ {
1449
+ value: `${state.sortBy}-${state.sortOrder}`,
1450
+ onChange: (e) => {
1451
+ const [sortBy, sortOrder] = e.target.value.split("-");
1452
+ setState((prev) => ({ ...prev, sortBy, sortOrder }));
1453
+ },
1454
+ className: "px-3 py-1 text-sm border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
1455
+ },
1456
+ /* @__PURE__ */ React2.createElement("option", { value: "uploadTime-desc" }, "\u6700\u65B0\u4E0A\u4F20"),
1457
+ /* @__PURE__ */ React2.createElement("option", { value: "uploadTime-asc" }, "\u6700\u65E9\u4E0A\u4F20"),
1458
+ /* @__PURE__ */ React2.createElement("option", { value: "originalName-asc" }, "\u6587\u4EF6\u540D A-Z"),
1459
+ /* @__PURE__ */ React2.createElement("option", { value: "originalName-desc" }, "\u6587\u4EF6\u540D Z-A"),
1460
+ /* @__PURE__ */ React2.createElement("option", { value: "size-desc" }, "\u6587\u4EF6\u5927\u5C0F \u5927-\u5C0F"),
1461
+ /* @__PURE__ */ React2.createElement("option", { value: "size-asc" }, "\u6587\u4EF6\u5927\u5C0F \u5C0F-\u5927")
1462
+ ), allowUpload && /* @__PURE__ */ React2.createElement(
1463
+ "button",
1464
+ {
1465
+ onClick: () => setState((prev) => ({ ...prev, showUploadModal: true })),
1466
+ className: "px-4 py-2 text-sm text-white bg-blue-600 rounded hover:bg-blue-700 focus:ring-2 focus:ring-blue-500"
1467
+ },
1468
+ "\u2B06\uFE0F \u4E0A\u4F20\u6587\u4EF6"
1469
+ )));
1470
+ };
1471
+ const renderPagination = () => {
1472
+ if (state.pagination.totalPages <= 1) return null;
1473
+ const { page, totalPages } = state.pagination;
1474
+ const pages = [];
1475
+ const startPage = Math.max(1, page - 2);
1476
+ const endPage = Math.min(totalPages, page + 2);
1477
+ for (let i = startPage; i <= endPage; i++) {
1478
+ pages.push(i);
1479
+ }
1480
+ return /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mt-6" }, /* @__PURE__ */ React2.createElement("div", { className: "text-sm text-gray-700" }, "\u663E\u793A\u7B2C ", (page - 1) * state.pagination.pageSize + 1, " - ", Math.min(page * state.pagination.pageSize, state.pagination.total), " \u9879\uFF0C \u5171 ", state.pagination.total, " \u9879"), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2" }, /* @__PURE__ */ React2.createElement(
1481
+ "button",
1482
+ {
1483
+ onClick: () => handlePageChange(page - 1),
1484
+ disabled: page <= 1,
1485
+ className: "px-3 py-1 text-sm border rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50"
1486
+ },
1487
+ "\u4E0A\u4E00\u9875"
1488
+ ), pages.map((pageNum) => /* @__PURE__ */ React2.createElement(
1489
+ "button",
1490
+ {
1491
+ key: pageNum,
1492
+ onClick: () => handlePageChange(pageNum),
1493
+ className: `px-3 py-1 text-sm border rounded ${pageNum === page ? "bg-blue-600 text-white border-blue-600" : "hover:bg-gray-50"}`
1494
+ },
1495
+ pageNum
1496
+ )), /* @__PURE__ */ React2.createElement(
1497
+ "button",
1498
+ {
1499
+ onClick: () => handlePageChange(page + 1),
1500
+ disabled: page >= totalPages,
1501
+ className: "px-3 py-1 text-sm border rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50"
1502
+ },
1503
+ "\u4E0B\u4E00\u9875"
1504
+ )));
1505
+ };
1506
+ return /* @__PURE__ */ React2.createElement("div", { className: "w-full" }, state.error && /* @__PURE__ */ React2.createElement("div", { className: "mb-4 p-4 bg-red-50 border border-red-200 rounded-lg" }, /* @__PURE__ */ React2.createElement("p", { className: "text-red-800" }, state.error), /* @__PURE__ */ React2.createElement(
1507
+ "button",
1508
+ {
1509
+ onClick: () => setState((prev) => ({ ...prev, error: null })),
1510
+ className: "mt-2 text-red-600 hover:text-red-800"
1511
+ },
1512
+ "\u5173\u95ED"
1513
+ )), renderSearchBar(), renderFilters(), renderToolbar(), /* @__PURE__ */ React2.createElement("div", { className: "min-h-96" }, state.loading ? /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-center h-32" }, /* @__PURE__ */ React2.createElement("div", { className: "text-gray-500" }, /* @__PURE__ */ React2.createElement("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-2" }), /* @__PURE__ */ React2.createElement("p", null, "\u52A0\u8F7D\u4E2D..."))) : state.files.length === 0 ? /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-center h-32" }, /* @__PURE__ */ React2.createElement("div", { className: "text-center text-gray-500" }, /* @__PURE__ */ React2.createElement("p", { className: "text-4xl mb-2" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement("p", null, "\u6682\u65E0\u6587\u4EF6"), allowUpload && /* @__PURE__ */ React2.createElement(
1514
+ "button",
1515
+ {
1516
+ onClick: () => setState((prev) => ({ ...prev, showUploadModal: true })),
1517
+ className: "mt-2 text-blue-600 hover:text-blue-800"
1518
+ },
1519
+ "\u70B9\u51FB\u4E0A\u4F20\u7B2C\u4E00\u4E2A\u6587\u4EF6"
1520
+ ))) : /* @__PURE__ */ React2.createElement("div", { className: `grid gap-4 ${mode === "grid" ? "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6" : "grid-cols-1"}` }, state.files.map(renderFileItem))), renderPagination(), state.previewFile && showPreview && /* @__PURE__ */ React2.createElement(
1521
+ FilePreviewModal,
1522
+ {
1523
+ file: state.previewFile,
1524
+ onClose: handleClosePreview
1525
+ }
1526
+ ), state.showUploadModal && allowUpload && /* @__PURE__ */ React2.createElement(
1527
+ UploadModal,
1528
+ {
1529
+ moduleId,
1530
+ businessId,
1531
+ onClose: () => setState((prev) => ({ ...prev, showUploadModal: false })),
1532
+ onUploadComplete: (files) => {
1533
+ setState((prev) => ({ ...prev, showUploadModal: false }));
1534
+ if (onUploadComplete) {
1535
+ onUploadComplete(files);
1536
+ }
1537
+ loadFiles();
1538
+ }
1539
+ }
1540
+ ));
1541
+ };
1542
+ var FilePreviewModal = ({ file, onClose }) => {
1543
+ const renderPreviewContent = () => {
1544
+ if (file.mimeType.startsWith("image/")) {
1545
+ return /* @__PURE__ */ React2.createElement(
1546
+ "img",
1547
+ {
1548
+ src: file.cdnUrl || `/api/files/${file.id}/download`,
1549
+ alt: file.originalName,
1550
+ className: "max-w-full max-h-full object-contain"
1551
+ }
1552
+ );
1553
+ }
1554
+ if (file.mimeType.startsWith("video/")) {
1555
+ return /* @__PURE__ */ React2.createElement(
1556
+ "video",
1557
+ {
1558
+ src: file.cdnUrl || `/api/files/${file.id}/download`,
1559
+ controls: true,
1560
+ className: "max-w-full max-h-full"
1561
+ },
1562
+ "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u89C6\u9891\u64AD\u653E"
1563
+ );
1564
+ }
1565
+ if (file.mimeType.startsWith("audio/")) {
1566
+ return /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col items-center space-y-4" }, /* @__PURE__ */ React2.createElement("div", { className: "text-6xl" }, "\u{1F3B5}"), /* @__PURE__ */ React2.createElement(
1567
+ "audio",
1568
+ {
1569
+ src: file.cdnUrl || `/api/files/${file.id}/download`,
1570
+ controls: true,
1571
+ className: "w-full max-w-md"
1572
+ },
1573
+ "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u97F3\u9891\u64AD\u653E"
1574
+ ));
1575
+ }
1576
+ if (file.mimeType.includes("pdf")) {
1577
+ return /* @__PURE__ */ React2.createElement(
1578
+ "iframe",
1579
+ {
1580
+ src: `${file.cdnUrl || `/api/files/${file.id}/download`}#toolbar=0`,
1581
+ className: "w-full h-full min-h-96",
1582
+ title: file.originalName
1583
+ }
1584
+ );
1585
+ }
1586
+ return /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col items-center justify-center h-64 text-gray-500" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl mb-4" }, "\u{1F4C4}"), /* @__PURE__ */ React2.createElement("p", null, "\u6B64\u6587\u4EF6\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u9884\u89C8"), /* @__PURE__ */ React2.createElement(
1587
+ "a",
1588
+ {
1589
+ href: file.cdnUrl || `/api/files/${file.id}/download`,
1590
+ download: file.originalName,
1591
+ className: "mt-4 px-4 py-2 text-blue-600 border border-blue-300 rounded hover:bg-blue-50"
1592
+ },
1593
+ "\u4E0B\u8F7D\u6587\u4EF6"
1594
+ ));
1595
+ };
1596
+ return /* @__PURE__ */ React2.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-white rounded-lg max-w-4xl max-h-[90vh] overflow-hidden flex flex-col" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-4 border-b" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-lg font-medium truncate", title: file.originalName }, file.originalName), /* @__PURE__ */ React2.createElement(
1597
+ "button",
1598
+ {
1599
+ onClick: onClose,
1600
+ className: "p-2 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100"
1601
+ },
1602
+ "\u2715"
1603
+ )), /* @__PURE__ */ React2.createElement("div", { className: "flex-1 p-4 overflow-auto flex items-center justify-center" }, renderPreviewContent()), /* @__PURE__ */ React2.createElement("div", { className: "p-4 border-t bg-gray-50 text-sm text-gray-600" }, /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u6587\u4EF6\u5927\u5C0F\uFF1A"), (file.size / 1024 / 1024).toFixed(2), " MB"), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u4E0A\u4F20\u65F6\u95F4\uFF1A"), new Date(file.uploadTime).toLocaleString()), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u6587\u4EF6\u7C7B\u578B\uFF1A"), file.mimeType), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u8BBF\u95EE\u6B21\u6570\uFF1A"), file.accessCount)))));
1604
+ };
1605
+ var UploadModal = ({
1606
+ moduleId,
1607
+ businessId,
1608
+ onClose,
1609
+ onUploadComplete
1610
+ }) => {
1611
+ return /* @__PURE__ */ React2.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-white rounded-lg max-w-2xl w-full max-h-[80vh] overflow-hidden" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-4 border-b" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-lg font-medium" }, "\u4E0A\u4F20\u6587\u4EF6"), /* @__PURE__ */ React2.createElement(
1612
+ "button",
1613
+ {
1614
+ onClick: onClose,
1615
+ className: "p-2 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100"
1616
+ },
1617
+ "\u2715"
1618
+ )), /* @__PURE__ */ React2.createElement("div", { className: "p-6" }, /* @__PURE__ */ React2.createElement("p", { className: "text-gray-600 mb-4" }, "\u8FD9\u91CC\u5C06\u96C6\u6210UniversalFileUploader\u7EC4\u4EF6"), /* @__PURE__ */ React2.createElement("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-8 text-center text-gray-500" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl mb-4" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement("p", null, "\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u5904\u6216\u70B9\u51FB\u9009\u62E9\u6587\u4EF6"), /* @__PURE__ */ React2.createElement(
1619
+ "input",
1620
+ {
1621
+ type: "file",
1622
+ multiple: true,
1623
+ className: "hidden",
1624
+ onChange: (e) => {
1625
+ console.log("\u9009\u62E9\u6587\u4EF6:", e.target.files);
1626
+ onUploadComplete([]);
1627
+ }
1628
+ }
1629
+ )))));
1630
+ };
1631
+ var FolderManager = ({
1632
+ currentFolderId,
1633
+ folderTree,
1634
+ showFileCount = true,
1635
+ showSize = true,
1636
+ allowCreate = true,
1637
+ allowRename = true,
1638
+ allowDelete = true,
1639
+ allowDrag = false,
1640
+ onFolderSelect,
1641
+ onFolderCreate,
1642
+ onFolderRename,
1643
+ onFolderDelete,
1644
+ onFileMove
1645
+ }) => {
1646
+ const [state, setState] = useState({
1647
+ expandedFolders: new Set(currentFolderId ? [currentFolderId] : []),
1648
+ editingFolder: null,
1649
+ editingName: "",
1650
+ creatingFolder: null,
1651
+ newFolderName: "",
1652
+ dragOverFolder: null,
1653
+ contextMenu: null
1654
+ });
1655
+ const toggleFolder = useCallback((folderId) => {
1656
+ setState((prev) => {
1657
+ const newExpanded = new Set(prev.expandedFolders);
1658
+ if (newExpanded.has(folderId)) {
1659
+ newExpanded.delete(folderId);
1660
+ } else {
1661
+ newExpanded.add(folderId);
1662
+ }
1663
+ return { ...prev, expandedFolders: newExpanded };
1664
+ });
1665
+ }, []);
1666
+ const selectFolder = useCallback((folderId) => {
1667
+ if (onFolderSelect) {
1668
+ onFolderSelect(folderId);
1669
+ }
1670
+ }, [onFolderSelect]);
1671
+ const startCreateFolder = useCallback((parentId) => {
1672
+ setState((prev) => ({
1673
+ ...prev,
1674
+ creatingFolder: parentId || null,
1675
+ newFolderName: "\u65B0\u5EFA\u6587\u4EF6\u5939",
1676
+ contextMenu: null
1677
+ }));
1678
+ }, []);
1679
+ const confirmCreateFolder = useCallback(async () => {
1680
+ if (!state.newFolderName.trim() || !onFolderCreate) return;
1681
+ try {
1682
+ await onFolderCreate(state.creatingFolder || void 0, state.newFolderName.trim());
1683
+ setState((prev) => ({
1684
+ ...prev,
1685
+ creatingFolder: null,
1686
+ newFolderName: ""
1687
+ }));
1688
+ } catch (error) {
1689
+ console.error("\u521B\u5EFA\u6587\u4EF6\u5939\u5931\u8D25:", error);
1690
+ }
1691
+ }, [state.creatingFolder, state.newFolderName, onFolderCreate]);
1692
+ const cancelCreateFolder = useCallback(() => {
1693
+ setState((prev) => ({
1694
+ ...prev,
1695
+ creatingFolder: null,
1696
+ newFolderName: ""
1697
+ }));
1698
+ }, []);
1699
+ const startRenameFolder = useCallback((folderId, currentName) => {
1700
+ setState((prev) => ({
1701
+ ...prev,
1702
+ editingFolder: folderId,
1703
+ editingName: currentName,
1704
+ contextMenu: null
1705
+ }));
1706
+ }, []);
1707
+ const confirmRenameFolder = useCallback(async () => {
1708
+ if (!state.editingFolder || !state.editingName.trim() || !onFolderRename) return;
1709
+ try {
1710
+ await onFolderRename(state.editingFolder, state.editingName.trim());
1711
+ setState((prev) => ({
1712
+ ...prev,
1713
+ editingFolder: null,
1714
+ editingName: ""
1715
+ }));
1716
+ } catch (error) {
1717
+ console.error("\u91CD\u547D\u540D\u6587\u4EF6\u5939\u5931\u8D25:", error);
1718
+ }
1719
+ }, [state.editingFolder, state.editingName, onFolderRename]);
1720
+ const cancelRenameFolder = useCallback(() => {
1721
+ setState((prev) => ({
1722
+ ...prev,
1723
+ editingFolder: null,
1724
+ editingName: ""
1725
+ }));
1726
+ }, []);
1727
+ const deleteFolder = useCallback(async (folderId, folderName) => {
1728
+ if (!window.confirm(`\u786E\u5B9A\u8981\u5220\u9664\u6587\u4EF6\u5939"${folderName}"\u5417\uFF1F\u6B64\u64CD\u4F5C\u5C06\u5220\u9664\u6587\u4EF6\u5939\u5185\u7684\u6240\u6709\u6587\u4EF6\u3002`)) {
1729
+ return;
1730
+ }
1731
+ if (!onFolderDelete) return;
1732
+ try {
1733
+ await onFolderDelete(folderId);
1734
+ setState((prev) => ({ ...prev, contextMenu: null }));
1735
+ } catch (error) {
1736
+ console.error("\u5220\u9664\u6587\u4EF6\u5939\u5931\u8D25:", error);
1737
+ }
1738
+ }, [onFolderDelete]);
1739
+ const handleContextMenu = useCallback((e, folderId) => {
1740
+ e.preventDefault();
1741
+ setState((prev) => ({
1742
+ ...prev,
1743
+ contextMenu: {
1744
+ folderId,
1745
+ x: e.clientX,
1746
+ y: e.clientY
1747
+ }
1748
+ }));
1749
+ }, []);
1750
+ const closeContextMenu = useCallback(() => {
1751
+ setState((prev) => ({ ...prev, contextMenu: null }));
1752
+ }, []);
1753
+ const handleDragOver = useCallback((e, folderId) => {
1754
+ if (!allowDrag) return;
1755
+ e.preventDefault();
1756
+ setState((prev) => ({ ...prev, dragOverFolder: folderId }));
1757
+ }, [allowDrag]);
1758
+ const handleDragLeave = useCallback(() => {
1759
+ setState((prev) => ({ ...prev, dragOverFolder: null }));
1760
+ }, []);
1761
+ const handleDrop = useCallback(async (e, folderId) => {
1762
+ if (!allowDrag || !onFileMove) return;
1763
+ e.preventDefault();
1764
+ setState((prev) => ({ ...prev, dragOverFolder: null }));
1765
+ try {
1766
+ const fileIds = JSON.parse(e.dataTransfer.getData("application/json"));
1767
+ await onFileMove(fileIds, folderId);
1768
+ } catch (error) {
1769
+ console.error("\u79FB\u52A8\u6587\u4EF6\u5931\u8D25:", error);
1770
+ }
1771
+ }, [allowDrag, onFileMove]);
1772
+ const formatSize = useCallback((bytes) => {
1773
+ if (bytes === 0) return "0 B";
1774
+ const k = 1024;
1775
+ const sizes = ["B", "KB", "MB", "GB", "TB"];
1776
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1777
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
1778
+ }, []);
1779
+ const renderFolderNode = useCallback((folder, level = 0) => {
1780
+ const isExpanded = state.expandedFolders.has(folder.id);
1781
+ const isSelected = currentFolderId === folder.id;
1782
+ const isEditing = state.editingFolder === folder.id;
1783
+ const isDragOver = state.dragOverFolder === folder.id;
1784
+ return /* @__PURE__ */ React2.createElement("div", { key: folder.id, className: "select-none" }, /* @__PURE__ */ React2.createElement(
1785
+ "div",
1786
+ {
1787
+ className: `flex items-center py-1 px-2 rounded-md cursor-pointer transition-colors ${isSelected ? "bg-blue-100 text-blue-800" : isDragOver ? "bg-green-100" : "hover:bg-gray-100"}`,
1788
+ style: { paddingLeft: `${level * 16 + 8}px` },
1789
+ onClick: () => selectFolder(folder.id),
1790
+ onContextMenu: (e) => handleContextMenu(e, folder.id),
1791
+ onDragOver: allowDrag ? (e) => handleDragOver(e, folder.id) : void 0,
1792
+ onDragLeave: allowDrag ? handleDragLeave : void 0,
1793
+ onDrop: allowDrag ? (e) => handleDrop(e, folder.id) : void 0
1794
+ },
1795
+ folder.children.length > 0 && /* @__PURE__ */ React2.createElement(
1796
+ "button",
1797
+ {
1798
+ onClick: (e) => {
1799
+ e.stopPropagation();
1800
+ toggleFolder(folder.id);
1801
+ },
1802
+ className: "mr-1 p-1 hover:bg-gray-200 rounded"
1803
+ },
1804
+ /* @__PURE__ */ React2.createElement("span", { className: `text-xs transition-transform ${isExpanded ? "rotate-90" : ""}` }, "\u25B6")
1805
+ ),
1806
+ /* @__PURE__ */ React2.createElement("span", { className: "mr-2 text-yellow-600" }, isExpanded ? "\u{1F4C2}" : "\u{1F4C1}"),
1807
+ /* @__PURE__ */ React2.createElement("div", { className: "flex-1 flex items-center justify-between" }, isEditing ? /* @__PURE__ */ React2.createElement(
1808
+ "input",
1809
+ {
1810
+ type: "text",
1811
+ value: state.editingName,
1812
+ onChange: (e) => setState((prev) => ({ ...prev, editingName: e.target.value })),
1813
+ onBlur: confirmRenameFolder,
1814
+ onKeyDown: (e) => {
1815
+ if (e.key === "Enter") {
1816
+ confirmRenameFolder();
1817
+ } else if (e.key === "Escape") {
1818
+ cancelRenameFolder();
1819
+ }
1820
+ },
1821
+ onClick: (e) => e.stopPropagation(),
1822
+ className: "flex-1 px-1 py-0 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-blue-500",
1823
+ autoFocus: true
1824
+ }
1825
+ ) : /* @__PURE__ */ React2.createElement("span", { className: "text-sm truncate" }, folder.name), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2 text-xs text-gray-500 ml-2" }, showFileCount && /* @__PURE__ */ React2.createElement("span", null, folder.fileCount, " \u9879"), showSize && folder.totalSize > 0 && /* @__PURE__ */ React2.createElement("span", null, formatSize(folder.totalSize))))
1826
+ ), state.creatingFolder === folder.id && /* @__PURE__ */ React2.createElement(
1827
+ "div",
1828
+ {
1829
+ className: "flex items-center py-1 px-2 ml-4",
1830
+ style: { paddingLeft: `${(level + 1) * 16 + 8}px` }
1831
+ },
1832
+ /* @__PURE__ */ React2.createElement("span", { className: "mr-2 text-yellow-600" }, "\u{1F4C1}"),
1833
+ /* @__PURE__ */ React2.createElement(
1834
+ "input",
1835
+ {
1836
+ type: "text",
1837
+ value: state.newFolderName,
1838
+ onChange: (e) => setState((prev) => ({ ...prev, newFolderName: e.target.value })),
1839
+ onBlur: confirmCreateFolder,
1840
+ onKeyDown: (e) => {
1841
+ if (e.key === "Enter") {
1842
+ confirmCreateFolder();
1843
+ } else if (e.key === "Escape") {
1844
+ cancelCreateFolder();
1845
+ }
1846
+ },
1847
+ className: "flex-1 px-1 py-0 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-blue-500",
1848
+ autoFocus: true
1849
+ }
1850
+ )
1851
+ ), isExpanded && folder.children.map(
1852
+ (child) => renderFolderNode(child, level + 1)
1853
+ ));
1854
+ }, [
1855
+ state.expandedFolders,
1856
+ state.editingFolder,
1857
+ state.editingName,
1858
+ state.creatingFolder,
1859
+ state.newFolderName,
1860
+ state.dragOverFolder,
1861
+ currentFolderId,
1862
+ allowDrag,
1863
+ showFileCount,
1864
+ showSize,
1865
+ selectFolder,
1866
+ toggleFolder,
1867
+ handleContextMenu,
1868
+ handleDragOver,
1869
+ handleDragLeave,
1870
+ handleDrop,
1871
+ confirmRenameFolder,
1872
+ cancelRenameFolder,
1873
+ confirmCreateFolder,
1874
+ cancelCreateFolder,
1875
+ formatSize
1876
+ ]);
1877
+ const renderContextMenu = () => {
1878
+ if (!state.contextMenu) return null;
1879
+ const folder = findFolderById(folderTree, state.contextMenu.folderId);
1880
+ if (!folder) return null;
1881
+ return /* @__PURE__ */ React2.createElement(
1882
+ "div",
1883
+ {
1884
+ className: "fixed bg-white border border-gray-200 rounded-md shadow-lg z-50 py-1",
1885
+ style: {
1886
+ left: state.contextMenu.x,
1887
+ top: state.contextMenu.y
1888
+ },
1889
+ onClick: closeContextMenu
1890
+ },
1891
+ allowCreate && /* @__PURE__ */ React2.createElement(
1892
+ "button",
1893
+ {
1894
+ onClick: () => startCreateFolder(folder.id),
1895
+ className: "w-full px-4 py-2 text-left text-sm hover:bg-gray-100 flex items-center"
1896
+ },
1897
+ /* @__PURE__ */ React2.createElement("span", { className: "mr-2" }, "\u{1F4C1}"),
1898
+ "\u65B0\u5EFA\u5B50\u6587\u4EF6\u5939"
1899
+ ),
1900
+ allowRename && /* @__PURE__ */ React2.createElement(
1901
+ "button",
1902
+ {
1903
+ onClick: () => startRenameFolder(folder.id, folder.name),
1904
+ className: "w-full px-4 py-2 text-left text-sm hover:bg-gray-100 flex items-center"
1905
+ },
1906
+ /* @__PURE__ */ React2.createElement("span", { className: "mr-2" }, "\u270F\uFE0F"),
1907
+ "\u91CD\u547D\u540D"
1908
+ ),
1909
+ allowDelete && /* @__PURE__ */ React2.createElement(
1910
+ "button",
1911
+ {
1912
+ onClick: () => deleteFolder(folder.id, folder.name),
1913
+ className: "w-full px-4 py-2 text-left text-sm hover:bg-gray-100 text-red-600 flex items-center"
1914
+ },
1915
+ /* @__PURE__ */ React2.createElement("span", { className: "mr-2" }, "\u{1F5D1}\uFE0F"),
1916
+ "\u5220\u9664\u6587\u4EF6\u5939"
1917
+ )
1918
+ );
1919
+ };
1920
+ const findFolderById = (folders, id) => {
1921
+ for (const folder of folders) {
1922
+ if (folder.id === id) return folder;
1923
+ const found = findFolderById(folder.children, id);
1924
+ if (found) return found;
1925
+ }
1926
+ return null;
1927
+ };
1928
+ React2.useEffect(() => {
1929
+ if (!state.contextMenu) return;
1930
+ const handleClickOutside = () => {
1931
+ closeContextMenu();
1932
+ };
1933
+ document.addEventListener("click", handleClickOutside);
1934
+ return () => document.removeEventListener("click", handleClickOutside);
1935
+ }, [state.contextMenu, closeContextMenu]);
1936
+ return /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-2 border-b bg-gray-50" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-medium text-gray-700" }, "\u6587\u4EF6\u5939"), allowCreate && /* @__PURE__ */ React2.createElement(
1937
+ "button",
1938
+ {
1939
+ onClick: () => startCreateFolder(),
1940
+ className: "px-2 py-1 text-xs text-blue-600 border border-blue-300 rounded hover:bg-blue-50",
1941
+ title: "\u65B0\u5EFA\u6587\u4EF6\u5939"
1942
+ },
1943
+ "\u2795"
1944
+ )), /* @__PURE__ */ React2.createElement("div", { className: "p-2 max-h-96 overflow-y-auto" }, folderTree.length === 0 ? /* @__PURE__ */ React2.createElement("div", { className: "text-center text-gray-500 py-8" }, /* @__PURE__ */ React2.createElement("div", { className: "text-2xl mb-2" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement("p", { className: "text-sm" }, "\u6682\u65E0\u6587\u4EF6\u5939"), allowCreate && /* @__PURE__ */ React2.createElement(
1945
+ "button",
1946
+ {
1947
+ onClick: () => startCreateFolder(),
1948
+ className: "mt-2 text-blue-600 hover:text-blue-800 text-sm"
1949
+ },
1950
+ "\u521B\u5EFA\u7B2C\u4E00\u4E2A\u6587\u4EF6\u5939"
1951
+ )) : /* @__PURE__ */ React2.createElement("div", { className: "space-y-1" }, folderTree.map((folder) => renderFolderNode(folder))), state.creatingFolder === null && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center py-1 px-2" }, /* @__PURE__ */ React2.createElement("span", { className: "mr-2 text-yellow-600" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement(
1952
+ "input",
1953
+ {
1954
+ type: "text",
1955
+ value: state.newFolderName,
1956
+ onChange: (e) => setState((prev) => ({ ...prev, newFolderName: e.target.value })),
1957
+ onBlur: confirmCreateFolder,
1958
+ onKeyDown: (e) => {
1959
+ if (e.key === "Enter") {
1960
+ confirmCreateFolder();
1961
+ } else if (e.key === "Escape") {
1962
+ cancelCreateFolder();
1963
+ }
1964
+ },
1965
+ className: "flex-1 px-1 py-0 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-blue-500",
1966
+ autoFocus: true
1967
+ }
1968
+ ))), renderContextMenu());
1969
+ };
1970
+ var FolderManager_default = FolderManager;
1971
+ var FileShareModal = ({
1972
+ files,
1973
+ onClose,
1974
+ onShareSuccess
1975
+ }) => {
1976
+ const [shareOptions, setShareOptions] = useState({
1977
+ expireType: "7days",
1978
+ requirePassword: false,
1979
+ password: "",
1980
+ permission: "view",
1981
+ downloadLimit: void 0
1982
+ });
1983
+ const [loading, setLoading] = useState(false);
1984
+ const [shareInfo, setShareInfo] = useState(null);
1985
+ const [error, setError] = useState(null);
1986
+ const generatePassword = useCallback(() => {
1987
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1988
+ let password = "";
1989
+ for (let i = 0; i < 6; i++) {
1990
+ password += chars.charAt(Math.floor(Math.random() * chars.length));
1991
+ }
1992
+ setShareOptions((prev) => ({ ...prev, password }));
1993
+ }, []);
1994
+ const getExpiresAt = useCallback(() => {
1995
+ const now = /* @__PURE__ */ new Date();
1996
+ switch (shareOptions.expireType) {
1997
+ case "never":
1998
+ return void 0;
1999
+ case "1hour":
2000
+ return new Date(now.getTime() + 60 * 60 * 1e3);
2001
+ case "1day":
2002
+ return new Date(now.getTime() + 24 * 60 * 60 * 1e3);
2003
+ case "7days":
2004
+ return new Date(now.getTime() + 7 * 24 * 60 * 60 * 1e3);
2005
+ case "30days":
2006
+ return new Date(now.getTime() + 30 * 24 * 60 * 60 * 1e3);
2007
+ case "custom":
2008
+ return shareOptions.customExpireTime;
2009
+ default:
2010
+ return void 0;
2011
+ }
2012
+ }, [shareOptions.expireType, shareOptions.customExpireTime]);
2013
+ const handleCreateShare = useCallback(async () => {
2014
+ setLoading(true);
2015
+ setError(null);
2016
+ try {
2017
+ const expiresAt = getExpiresAt();
2018
+ const mockShareInfo = {
2019
+ shareUrl: `${window.location.origin}/share/${generateShareCode()}`,
2020
+ password: shareOptions.requirePassword ? shareOptions.password : void 0,
2021
+ expiresAt,
2022
+ permission: shareOptions.permission,
2023
+ shareCode: generateShareCode()
2024
+ };
2025
+ setShareInfo(mockShareInfo);
2026
+ if (onShareSuccess) {
2027
+ onShareSuccess(mockShareInfo);
2028
+ }
2029
+ } catch (error2) {
2030
+ console.error("\u521B\u5EFA\u5206\u4EAB\u5931\u8D25:", error2);
2031
+ setError(error2 instanceof Error ? error2.message : "\u521B\u5EFA\u5206\u4EAB\u5931\u8D25");
2032
+ } finally {
2033
+ setLoading(false);
2034
+ }
2035
+ }, [files, shareOptions, getExpiresAt, onShareSuccess]);
2036
+ const generateShareCode = useCallback(() => {
2037
+ return Math.random().toString(36).substring(2, 10).toUpperCase();
2038
+ }, []);
2039
+ const copyToClipboard = useCallback(async (text) => {
2040
+ try {
2041
+ await navigator.clipboard.writeText(text);
2042
+ console.log("\u590D\u5236\u6210\u529F");
2043
+ } catch (error2) {
2044
+ console.error("\u590D\u5236\u5931\u8D25:", error2);
2045
+ const textArea = document.createElement("textarea");
2046
+ textArea.value = text;
2047
+ document.body.appendChild(textArea);
2048
+ textArea.select();
2049
+ document.execCommand("copy");
2050
+ document.body.removeChild(textArea);
2051
+ }
2052
+ }, []);
2053
+ const formatFileList = useCallback(() => {
2054
+ if (files.length === 0) return "0 \u4E2A\u6587\u4EF6";
2055
+ if (files.length === 1 && files[0]) {
2056
+ return files[0].originalName;
2057
+ }
2058
+ return `${files.length} \u4E2A\u6587\u4EF6`;
2059
+ }, [files]);
2060
+ const renderShareSettings = () => {
2061
+ if (shareInfo) return null;
2062
+ return /* @__PURE__ */ React2.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-gray-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("h3", { className: "font-medium text-gray-900 mb-2" }, "\u8981\u5206\u4EAB\u7684\u6587\u4EF6"), /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, files.map((file) => /* @__PURE__ */ React2.createElement("div", { key: file.id, className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React2.createElement("span", { className: "text-gray-700 truncate" }, file.originalName), /* @__PURE__ */ React2.createElement("span", { className: "text-gray-500 text-xs" }, (file.size / 1024 / 1024).toFixed(2), " MB"))))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u8FC7\u671F\u65F6\u95F4"), /* @__PURE__ */ React2.createElement(
2063
+ "select",
2064
+ {
2065
+ value: shareOptions.expireType,
2066
+ onChange: (e) => setShareOptions((prev) => ({
2067
+ ...prev,
2068
+ expireType: e.target.value
2069
+ })),
2070
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
2071
+ },
2072
+ /* @__PURE__ */ React2.createElement("option", { value: "never" }, "\u6C38\u4E0D\u8FC7\u671F"),
2073
+ /* @__PURE__ */ React2.createElement("option", { value: "1hour" }, "1\u5C0F\u65F6\u540E"),
2074
+ /* @__PURE__ */ React2.createElement("option", { value: "1day" }, "1\u5929\u540E"),
2075
+ /* @__PURE__ */ React2.createElement("option", { value: "7days" }, "7\u5929\u540E"),
2076
+ /* @__PURE__ */ React2.createElement("option", { value: "30days" }, "30\u5929\u540E"),
2077
+ /* @__PURE__ */ React2.createElement("option", { value: "custom" }, "\u81EA\u5B9A\u4E49\u65F6\u95F4")
2078
+ ), shareOptions.expireType === "custom" && /* @__PURE__ */ React2.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React2.createElement(
2079
+ "input",
2080
+ {
2081
+ type: "datetime-local",
2082
+ value: shareOptions.customExpireTime?.toISOString().slice(0, 16) || "",
2083
+ onChange: (e) => setShareOptions((prev) => ({
2084
+ ...prev,
2085
+ customExpireTime: e.target.value ? new Date(e.target.value) : void 0
2086
+ })),
2087
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500",
2088
+ min: (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
2089
+ }
2090
+ ))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u8BBF\u95EE\u6743\u9650"), /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("label", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(
2091
+ "input",
2092
+ {
2093
+ type: "radio",
2094
+ name: "permission",
2095
+ value: "view",
2096
+ checked: shareOptions.permission === "view",
2097
+ onChange: (e) => setShareOptions((prev) => ({
2098
+ ...prev,
2099
+ permission: e.target.value
2100
+ })),
2101
+ className: "mr-2"
2102
+ }
2103
+ ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm" }, "\u4EC5\u9884\u89C8\uFF08\u4E0D\u5141\u8BB8\u4E0B\u8F7D\uFF09")), /* @__PURE__ */ React2.createElement("label", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(
2104
+ "input",
2105
+ {
2106
+ type: "radio",
2107
+ name: "permission",
2108
+ value: "download",
2109
+ checked: shareOptions.permission === "download",
2110
+ onChange: (e) => setShareOptions((prev) => ({
2111
+ ...prev,
2112
+ permission: e.target.value
2113
+ })),
2114
+ className: "mr-2"
2115
+ }
2116
+ ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm" }, "\u5141\u8BB8\u4E0B\u8F7D")))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "flex items-center mb-2" }, /* @__PURE__ */ React2.createElement(
2117
+ "input",
2118
+ {
2119
+ type: "checkbox",
2120
+ checked: shareOptions.requirePassword,
2121
+ onChange: (e) => setShareOptions((prev) => ({
2122
+ ...prev,
2123
+ requirePassword: e.target.checked,
2124
+ password: e.target.checked ? prev.password : ""
2125
+ })),
2126
+ className: "mr-2"
2127
+ }
2128
+ ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm font-medium text-gray-700" }, "\u8BBE\u7F6E\u8BBF\u95EE\u5BC6\u7801")), shareOptions.requirePassword && /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
2129
+ "input",
2130
+ {
2131
+ type: "text",
2132
+ value: shareOptions.password,
2133
+ onChange: (e) => setShareOptions((prev) => ({
2134
+ ...prev,
2135
+ password: e.target.value
2136
+ })),
2137
+ placeholder: "\u8F93\u5165\u8BBF\u95EE\u5BC6\u7801",
2138
+ className: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500",
2139
+ maxLength: 20
2140
+ }
2141
+ ), /* @__PURE__ */ React2.createElement(
2142
+ "button",
2143
+ {
2144
+ type: "button",
2145
+ onClick: generatePassword,
2146
+ className: "px-3 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
2147
+ },
2148
+ "\u968F\u673A\u751F\u6210"
2149
+ ))), shareOptions.permission === "download" && /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u4E0B\u8F7D\u6B21\u6570\u9650\u5236"), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2" }, /* @__PURE__ */ React2.createElement(
2150
+ "input",
2151
+ {
2152
+ type: "checkbox",
2153
+ checked: shareOptions.downloadLimit !== void 0,
2154
+ onChange: (e) => setShareOptions((prev) => ({
2155
+ ...prev,
2156
+ downloadLimit: e.target.checked ? 10 : void 0
2157
+ })),
2158
+ className: "mr-2"
2159
+ }
2160
+ ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-gray-700" }, "\u9650\u5236\u4E0B\u8F7D\u6B21\u6570"), shareOptions.downloadLimit !== void 0 && /* @__PURE__ */ React2.createElement(
2161
+ "input",
2162
+ {
2163
+ type: "number",
2164
+ value: shareOptions.downloadLimit,
2165
+ onChange: (e) => setShareOptions((prev) => ({
2166
+ ...prev,
2167
+ downloadLimit: parseInt(e.target.value) || 1
2168
+ })),
2169
+ min: 1,
2170
+ max: 1e3,
2171
+ className: "w-20 px-2 py-1 text-sm border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
2172
+ }
2173
+ ))));
2174
+ };
2175
+ const renderShareResult = () => {
2176
+ if (!shareInfo) return null;
2177
+ return /* @__PURE__ */ React2.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React2.createElement("div", { className: "text-center" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl mb-4" }, "\u2705"), /* @__PURE__ */ React2.createElement("h3", { className: "text-lg font-medium text-gray-900 mb-2" }, "\u5206\u4EAB\u94FE\u63A5\u5DF2\u521B\u5EFA"), /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-gray-600" }, formatFileList(), " \u5DF2\u6210\u529F\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5")), /* @__PURE__ */ React2.createElement("div", { className: "bg-gray-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u5206\u4EAB\u94FE\u63A5"), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
2178
+ "input",
2179
+ {
2180
+ type: "text",
2181
+ value: shareInfo.shareUrl,
2182
+ readOnly: true,
2183
+ className: "flex-1 px-3 py-2 text-sm bg-white border border-gray-300 rounded-md"
2184
+ }
2185
+ ), /* @__PURE__ */ React2.createElement(
2186
+ "button",
2187
+ {
2188
+ onClick: () => copyToClipboard(shareInfo.shareUrl),
2189
+ className: "px-3 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
2190
+ },
2191
+ "\u590D\u5236\u94FE\u63A5"
2192
+ ))), shareInfo.password && /* @__PURE__ */ React2.createElement("div", { className: "bg-yellow-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u8BBF\u95EE\u5BC6\u7801"), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
2193
+ "input",
2194
+ {
2195
+ type: "text",
2196
+ value: shareInfo.password,
2197
+ readOnly: true,
2198
+ className: "flex-1 px-3 py-2 text-sm bg-white border border-gray-300 rounded-md"
2199
+ }
2200
+ ), /* @__PURE__ */ React2.createElement(
2201
+ "button",
2202
+ {
2203
+ onClick: () => copyToClipboard(shareInfo.password),
2204
+ className: "px-3 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
2205
+ },
2206
+ "\u590D\u5236\u5BC6\u7801"
2207
+ )), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-yellow-800 mt-2" }, "\u26A0\uFE0F \u8BF7\u59A5\u5584\u4FDD\u7BA1\u8BBF\u95EE\u5BC6\u7801\uFF0C\u8BBF\u95EE\u8005\u9700\u8981\u6B64\u5BC6\u7801\u624D\u80FD\u67E5\u770B\u6587\u4EF6")), /* @__PURE__ */ React2.createElement("div", { className: "bg-blue-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("h4", { className: "text-sm font-medium text-blue-900 mb-2" }, "\u5206\u4EAB\u4FE1\u606F"), /* @__PURE__ */ React2.createElement("div", { className: "space-y-1 text-sm text-blue-800" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u6743\u9650\uFF1A"), shareInfo.permission === "view" ? "\u4EC5\u9884\u89C8" : "\u5141\u8BB8\u4E0B\u8F7D"), shareInfo.expiresAt && /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u8FC7\u671F\u65F6\u95F4\uFF1A"), shareInfo.expiresAt.toLocaleString()), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u5206\u4EAB\u4EE3\u7801\uFF1A"), shareInfo.shareCode))), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
2208
+ "button",
2209
+ {
2210
+ onClick: () => {
2211
+ const shareText = [
2212
+ `\u6587\u4EF6\u5206\u4EAB\uFF1A${formatFileList()}`,
2213
+ `\u94FE\u63A5\uFF1A${shareInfo.shareUrl}`,
2214
+ shareInfo.password ? `\u5BC6\u7801\uFF1A${shareInfo.password}` : "",
2215
+ shareInfo.expiresAt ? `\u8FC7\u671F\u65F6\u95F4\uFF1A${shareInfo.expiresAt.toLocaleString()}` : "\u6C38\u4E0D\u8FC7\u671F"
2216
+ ].filter(Boolean).join("\n");
2217
+ copyToClipboard(shareText);
2218
+ },
2219
+ className: "flex-1 px-4 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
2220
+ },
2221
+ "\u{1F4CB} \u590D\u5236\u5B8C\u6574\u4FE1\u606F"
2222
+ ), /* @__PURE__ */ React2.createElement(
2223
+ "button",
2224
+ {
2225
+ onClick: () => {
2226
+ console.log("\u5176\u4ED6\u5206\u4EAB\u65B9\u5F0F");
2227
+ },
2228
+ className: "px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50"
2229
+ },
2230
+ "\u{1F517} \u5176\u4ED6\u5206\u4EAB\u65B9\u5F0F"
2231
+ )));
2232
+ };
2233
+ return /* @__PURE__ */ React2.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-white rounded-lg max-w-md w-full max-h-[90vh] overflow-hidden" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-4 border-b" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-lg font-medium" }, shareInfo ? "\u5206\u4EAB\u6210\u529F" : "\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5"), /* @__PURE__ */ React2.createElement(
2234
+ "button",
2235
+ {
2236
+ onClick: onClose,
2237
+ className: "p-2 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100"
2238
+ },
2239
+ "\u2715"
2240
+ )), /* @__PURE__ */ React2.createElement("div", { className: "p-6 max-h-[calc(90vh-120px)] overflow-y-auto" }, error && /* @__PURE__ */ React2.createElement("div", { className: "mb-4 p-4 bg-red-50 border border-red-200 rounded-lg" }, /* @__PURE__ */ React2.createElement("p", { className: "text-red-800 text-sm" }, error)), renderShareSettings(), renderShareResult()), !shareInfo && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-end space-x-2 p-4 border-t bg-gray-50" }, /* @__PURE__ */ React2.createElement(
2241
+ "button",
2242
+ {
2243
+ onClick: onClose,
2244
+ className: "px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50"
2245
+ },
2246
+ "\u53D6\u6D88"
2247
+ ), /* @__PURE__ */ React2.createElement(
2248
+ "button",
2249
+ {
2250
+ onClick: handleCreateShare,
2251
+ disabled: loading || shareOptions.requirePassword && !shareOptions.password,
2252
+ className: "px-4 py-2 text-sm text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
2253
+ },
2254
+ loading ? /* @__PURE__ */ React2.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2" }), "\u521B\u5EFA\u4E2D...") : "\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5"
2255
+ ))));
2256
+ };
2257
+ var FileShareModal_default = FileShareModal;
1037
2258
 
1038
- export { ALL_SUPPORTED_MIME_TYPES, API_BASE_PATH, API_ENDPOINTS, AUDIO_EXTENSIONS, AUDIO_MIME_TYPES, DEFAULT_CHUNK_SIZE, DEFAULT_MAX_AUDIO_SIZE, DEFAULT_MAX_DOCUMENT_SIZE, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_IMAGE_SIZE, DEFAULT_MAX_VIDEO_SIZE, DEFAULT_PAGE_SIZE, DEFAULT_REQUEST_TIMEOUT, DEFAULT_UPLOAD_TIMEOUT, DOCUMENT_EXTENSIONS, DOCUMENT_MIME_TYPES, FileUploader_default as DefaultFileUploader, ERROR_CODES, FileUploader, IMAGE_EXTENSIONS, IMAGE_MIME_TYPES, UNIVERSAL_FILE_NAME, UNIVERSAL_FILE_VERSION, UniversalFileClient, VIDEO_EXTENSIONS, VIDEO_MIME_TYPES, buildQueryString, calculateProgress, calculateRemainingTime, calculateSpeed, createFileClient, createFileError, formatErrorMessage, formatFileSize, generateStoragePath, generateUniqueFileName, getFileCategory, getFileExtension, getMimeTypeFromFileName, isAudioFile, isDocumentFile, isImageFile, isMimeTypeSupported, isVideoFile, parseFileSize, parseQueryString, parseStoragePath, readFileAsArrayBuffer, readFileAsBase64, readFileAsText, sanitizeFileName, universalFileClient, validateFile, validateFileName, validateFileSize, validateFileType };
2259
+ export { ALL_SUPPORTED_MIME_TYPES, API_BASE_PATH, API_ENDPOINTS, AUDIO_EXTENSIONS, AUDIO_MIME_TYPES, DEFAULT_CHUNK_SIZE, DEFAULT_MAX_AUDIO_SIZE, DEFAULT_MAX_DOCUMENT_SIZE, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_IMAGE_SIZE, DEFAULT_MAX_VIDEO_SIZE, DEFAULT_PAGE_SIZE, DEFAULT_REQUEST_TIMEOUT, DEFAULT_UPLOAD_TIMEOUT, DOCUMENT_EXTENSIONS, DOCUMENT_MIME_TYPES, ERROR_CODES, FileShareModal_default as FileShareModal, FileUploader, FolderManager_default as FolderManager, IMAGE_EXTENSIONS, IMAGE_MIME_TYPES, UNIVERSAL_FILE_NAME, UNIVERSAL_FILE_VERSION, UniversalFileClient, UniversalFileManager, VIDEO_EXTENSIONS, VIDEO_MIME_TYPES, buildQueryString, calculateProgress, calculateRemainingTime, calculateSpeed, createFileClient, createFileError, formatErrorMessage, formatFileSize, generateStoragePath, generateUniqueFileName, getFileCategory, getFileExtension, getMimeTypeFromFileName, isAudioFile, isDocumentFile, isImageFile, isMimeTypeSupported, isVideoFile, parseFileSize, parseQueryString, parseStoragePath, readFileAsArrayBuffer, readFileAsBase64, readFileAsText, sanitizeFileName, universalFileClient, validateFile, validateFileName, validateFileSize, validateFileType };
1039
2260
  //# sourceMappingURL=index.mjs.map
1040
2261
  //# sourceMappingURL=index.mjs.map