@jari-ace/element-plus-component 0.3.1 → 0.3.3

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 (148) hide show
  1. package/dist/components/autoComplete/JaAutoComplete.vue.d.ts +956 -1179
  2. package/dist/components/autoComplete/JaAutoComplete.vue.d.ts.map +1 -1
  3. package/dist/components/button/JaButton.vue.d.ts +114 -450
  4. package/dist/components/button/JaButton.vue.d.ts.map +1 -1
  5. package/dist/components/checkbox/JaCheckbox.vue.d.ts +228 -150
  6. package/dist/components/checkbox/JaCheckbox.vue.d.ts.map +1 -1
  7. package/dist/components/checkboxGroup/JaCheckboxGroup.vue.d.ts +215 -137
  8. package/dist/components/checkboxGroup/JaCheckboxGroup.vue.d.ts.map +1 -1
  9. package/dist/components/dropdownButton/JaDropdownButton.vue.d.ts +700 -1596
  10. package/dist/components/dropdownButton/JaDropdownButton.vue.d.ts.map +1 -1
  11. package/dist/components/form/JaForm.vue.d.ts +1 -1
  12. package/dist/components/formItem/JaFormItem.vue.d.ts +83 -293
  13. package/dist/components/formItem/JaFormItem.vue.d.ts.map +1 -1
  14. package/dist/components/input/JaInput.vue.d.ts +244 -609
  15. package/dist/components/input/JaInput.vue.d.ts.map +1 -1
  16. package/dist/components/inputI18n/I18nBundleEditor.vue.d.ts +1 -1
  17. package/dist/components/inputI18n/I18nBundleEditor.vue.d.ts.map +1 -1
  18. package/dist/components/inputI18n/I18nBundleEditor.vue.js +1 -1
  19. package/dist/components/inputI18n/I18nBundleEditor.vue.js.map +1 -1
  20. package/dist/components/inputI18n/InputI18n.vue.d.ts.map +1 -1
  21. package/dist/components/inputI18n/InputI18n.vue.js +14 -5
  22. package/dist/components/inputI18n/InputI18n.vue.js.map +1 -1
  23. package/dist/components/inputNumber/JaInputNumber.vue.d.ts +117 -471
  24. package/dist/components/inputNumber/JaInputNumber.vue.d.ts.map +1 -1
  25. package/dist/components/inputNumber/JaInputNumber.vue.js +4 -1
  26. package/dist/components/inputNumber/JaInputNumber.vue.js.map +1 -1
  27. package/dist/components/properyPicker/PropertyPicker.vue.d.ts.map +1 -1
  28. package/dist/components/properyPicker/PropertyPicker.vue.js +4 -8
  29. package/dist/components/properyPicker/PropertyPicker.vue.js.map +1 -1
  30. package/dist/components/radioGroup/JaRadioGroup.vue.d.ts +96 -287
  31. package/dist/components/radioGroup/JaRadioGroup.vue.d.ts.map +1 -1
  32. package/dist/components/rolePicker/RoleCategorySelector.vue.d.ts +14 -0
  33. package/dist/components/rolePicker/RoleCategorySelector.vue.d.ts.map +1 -0
  34. package/dist/components/rolePicker/RoleCategorySelector.vue.js +410 -0
  35. package/dist/components/rolePicker/RoleCategorySelector.vue.js.map +1 -0
  36. package/dist/components/rolePicker/RoleEditor.vue.d.ts +1 -0
  37. package/dist/components/rolePicker/RoleEditor.vue.d.ts.map +1 -1
  38. package/dist/components/rolePicker/RoleEditor.vue.js +64 -31
  39. package/dist/components/rolePicker/RoleEditor.vue.js.map +1 -1
  40. package/dist/components/rolePicker/baseRolePicker.vue.d.ts.map +1 -1
  41. package/dist/components/rolePicker/baseRolePicker.vue.js +7 -9
  42. package/dist/components/rolePicker/baseRolePicker.vue.js.map +1 -1
  43. package/dist/components/rolePicker/index.d.ts +2 -0
  44. package/dist/components/rolePicker/index.d.ts.map +1 -1
  45. package/dist/components/rolePicker/index.js +2 -0
  46. package/dist/components/rolePicker/index.js.map +1 -1
  47. package/dist/components/scrollbar/Scrollbar.vue.d.ts +110 -378
  48. package/dist/components/scrollbar/Scrollbar.vue.d.ts.map +1 -1
  49. package/dist/components/switch/JaSwitch.vue.d.ts +96 -431
  50. package/dist/components/switch/JaSwitch.vue.d.ts.map +1 -1
  51. package/dist/components/upload/JaUploader.vue.d.ts +50 -6
  52. package/dist/components/upload/JaUploader.vue.d.ts.map +1 -1
  53. package/dist/components/upload/index.d.ts +141 -3
  54. package/dist/components/upload/index.d.ts.map +1 -1
  55. package/dist/components/upload/index.js +4 -1
  56. package/dist/components/upload/index.js.map +1 -1
  57. package/dist/components/upload/types.d.ts +3 -0
  58. package/dist/components/upload/types.d.ts.map +1 -0
  59. package/dist/components/upload/types.js +2 -0
  60. package/dist/components/upload/types.js.map +1 -0
  61. package/dist/components/upload/uploader.vue.d.ts +26 -3
  62. package/dist/components/upload/uploader.vue.d.ts.map +1 -1
  63. package/dist/components/upload/uploader.vue.js +28 -11
  64. package/dist/components/upload/uploader.vue.js.map +1 -1
  65. package/dist/components/userGroupTree/src/userGroupTree.vue.d.ts +1808 -0
  66. package/dist/components/userGroupTree/src/userGroupTree.vue.d.ts.map +1 -0
  67. package/dist/components/userGroupTree/src/userGroupTree.vue.js +23 -14
  68. package/dist/components/userGroupTree/src/userGroupTree.vue.js.map +1 -1
  69. package/dist/components/userSelectDialog/src/userSelectDialog.vue.d.ts.map +1 -1
  70. package/dist/components/userSelectDialog/src/userSelectDialog.vue.js +2 -0
  71. package/dist/components/userSelectDialog/src/userSelectDialog.vue.js.map +1 -1
  72. package/dist/hooks/useAppInstances.d.ts +17 -4
  73. package/dist/hooks/useAppInstances.d.ts.map +1 -1
  74. package/dist/hooks/useAppInstances.js +109 -24
  75. package/dist/hooks/useAppInstances.js.map +1 -1
  76. package/dist/hooks/useClassificationLevels.d.ts.map +1 -1
  77. package/dist/hooks/useClassificationLevels.js +30 -7
  78. package/dist/hooks/useClassificationLevels.js.map +1 -1
  79. package/dist/hooks/useConstraintProviders.d.ts +5 -0
  80. package/dist/hooks/useConstraintProviders.d.ts.map +1 -0
  81. package/dist/hooks/useConstraintProviders.js +31 -0
  82. package/dist/hooks/useConstraintProviders.js.map +1 -0
  83. package/dist/hooks/useEntities.d.ts +9 -0
  84. package/dist/hooks/useEntities.d.ts.map +1 -0
  85. package/dist/hooks/useEntities.js +40 -0
  86. package/dist/hooks/useEntities.js.map +1 -0
  87. package/dist/hooks/useEntityPropDataTypes.d.ts +5 -0
  88. package/dist/hooks/useEntityPropDataTypes.d.ts.map +1 -0
  89. package/dist/hooks/useEntityPropDataTypes.js +31 -0
  90. package/dist/hooks/useEntityPropDataTypes.js.map +1 -0
  91. package/dist/hooks/useFileConfigurations.d.ts +6 -0
  92. package/dist/hooks/useFileConfigurations.d.ts.map +1 -0
  93. package/dist/hooks/useFileConfigurations.js +37 -0
  94. package/dist/hooks/useFileConfigurations.js.map +1 -0
  95. package/dist/hooks/useGroups.d.ts +7 -0
  96. package/dist/hooks/useGroups.d.ts.map +1 -0
  97. package/dist/hooks/useGroups.js +75 -0
  98. package/dist/hooks/useGroups.js.map +1 -0
  99. package/dist/hooks/useNumberTemplates.d.ts +6 -0
  100. package/dist/hooks/useNumberTemplates.d.ts.map +1 -0
  101. package/dist/hooks/useNumberTemplates.js +37 -0
  102. package/dist/hooks/useNumberTemplates.js.map +1 -0
  103. package/dist/hooks/useProperties.d.ts +9 -0
  104. package/dist/hooks/useProperties.d.ts.map +1 -0
  105. package/dist/hooks/useProperties.js +40 -0
  106. package/dist/hooks/useProperties.js.map +1 -0
  107. package/dist/hooks/useRoleCategories.d.ts +6 -0
  108. package/dist/hooks/useRoleCategories.d.ts.map +1 -0
  109. package/dist/hooks/useRoleCategories.js +37 -0
  110. package/dist/hooks/useRoleCategories.js.map +1 -0
  111. package/dist/hooks/useRoles.d.ts +6 -0
  112. package/dist/hooks/useRoles.d.ts.map +1 -0
  113. package/dist/hooks/useRoles.js +38 -0
  114. package/dist/hooks/useRoles.js.map +1 -0
  115. package/dist/index.d.ts +9 -0
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +9 -0
  118. package/dist/index.js.map +1 -1
  119. package/lib/index.css +1 -1
  120. package/lib/index.js +9385 -8876
  121. package/lib/index.umd.cjs +34 -34
  122. package/package.json +7 -7
  123. package/packages/components/input/JaInput.vue +1 -1
  124. package/packages/components/inputI18n/I18nBundleEditor.vue +2 -2
  125. package/packages/components/inputI18n/InputI18n.vue +33 -25
  126. package/packages/components/inputNumber/JaInputNumber.vue +6 -5
  127. package/packages/components/properyPicker/PropertyPicker.vue +4 -8
  128. package/packages/components/rolePicker/RoleCategorySelector.vue +154 -0
  129. package/packages/components/rolePicker/RoleEditor.vue +16 -7
  130. package/packages/components/rolePicker/baseRolePicker.vue +6 -13
  131. package/packages/components/rolePicker/index.ts +3 -0
  132. package/packages/components/upload/index.ts +4 -1
  133. package/packages/components/upload/types.ts +4 -0
  134. package/packages/components/upload/uploader.vue +456 -381
  135. package/packages/components/userGroupTree/src/userGroupTree.vue +54 -17
  136. package/packages/components/userSelectDialog/src/userSelectDialog.vue +1 -1
  137. package/packages/hooks/useAppInstances.ts +121 -25
  138. package/packages/hooks/useClassificationLevels.ts +31 -7
  139. package/packages/hooks/useConstraintProviders.ts +36 -0
  140. package/packages/hooks/useEntities.ts +44 -0
  141. package/packages/hooks/useEntityPropDataTypes.ts +37 -0
  142. package/packages/hooks/useFileConfigurations.ts +41 -0
  143. package/packages/hooks/useGroups.ts +81 -0
  144. package/packages/hooks/useNumberTemplates.ts +43 -0
  145. package/packages/hooks/useProperties.ts +44 -0
  146. package/packages/hooks/useRoleCategories.ts +42 -0
  147. package/packages/hooks/useRoles.ts +44 -0
  148. package/packages/index.ts +9 -0
@@ -1,26 +1,26 @@
1
1
  <script setup lang="ts">
2
2
  import {
3
- createAxiosWithoutCache,
4
- type FileInfo, Jari,
5
- useFilesApi,
6
- useLoginUser,
7
- type ClassificationLevel, type UploadInitParams, useLoading
3
+ createAxiosWithoutCache,
4
+ type FileInfo, Jari,
5
+ useFilesApi,
6
+ useLoginUser,
7
+ type ClassificationLevel, type UploadInitParams, useLoading
8
8
  } from "@jari-ace/app-bolts";
9
- import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
10
- import { ArrowDown, Download, Upload } from "@element-plus/icons-vue";
9
+ import {nextTick, onMounted, onUnmounted, ref, watch} from "vue";
10
+ import {ArrowDown, Download, Upload} from "@element-plus/icons-vue";
11
11
  import {
12
- useSystemClassificationLevelMap,
13
- useSystemClassificationLevels
12
+ useSystemClassificationLevelMap,
13
+ useSystemClassificationLevels
14
14
  } from "../../hooks/useClassificationLevels";
15
15
  import Ace = Jari.Ace;
16
- import { ElMessageBox } from "element-plus";
16
+ import {ElMessageBox} from "element-plus";
17
17
  import "@uppy/core/css/style.min.css";
18
18
  import "@uppy/dashboard/css/style.min.css";
19
19
  import "@uppy/audio/css/style.min.css";
20
20
  import "@uppy/screen-capture/css/style.min.css";
21
21
  import "@uppy/webcam/css/style.min.css";
22
22
  import "@uppy/image-editor/css/style.min.css";
23
- import Uppy from "@uppy/core";
23
+ import Uppy, {type Meta, type UppyFile} from "@uppy/core";
24
24
  import Tus from "@uppy/tus";
25
25
  import Webcam from "@uppy/webcam";
26
26
  import ScreenCapture from "@uppy/screen-capture";
@@ -32,44 +32,45 @@ import prettyBytes from "pretty-bytes";
32
32
  import PdfViewerModal from "./pdf-viewer/PdfViewerModal.vue";
33
33
 
34
34
  import {
35
- ElTable,
36
- ElTableColumn,
37
- ElButton,
38
- ElDropdown,
39
- ElDropdownItem,
40
- ElDropdownMenu,
41
- ElIcon,
42
- ElTag
35
+ ElTable,
36
+ ElTableColumn,
37
+ ElButton,
38
+ ElDropdown,
39
+ ElDropdownItem,
40
+ ElDropdownMenu,
41
+ ElIcon,
42
+ ElTag
43
43
  } from "element-plus";
44
+ import type {AceFile} from "./types";
44
45
 
45
46
  const props = defineProps<{
46
- /**
47
- * 应用名
48
- */
49
- serviceName: string,
50
- /**
51
- * 附件配置key
52
- */
53
- configKey: string,
54
- /**
55
- * 附件令牌
56
- */
57
- attachToken?: string,
58
- /**
59
- * 数据密集
60
- */
61
- classificationLevel?: number,
62
- /**
63
- * 文件列表高度
64
- */
65
- height?: string | number,
66
- /**
67
- * 文件列表最大高度
68
- */
69
- maxHeight?: string | number
47
+ /**
48
+ * 应用名
49
+ */
50
+ serviceName: string,
51
+ /**
52
+ * 附件配置key
53
+ */
54
+ configKey: string,
55
+ /**
56
+ * 附件令牌
57
+ */
58
+ attachToken?: string,
59
+ /**
60
+ * 数据密集
61
+ */
62
+ classificationLevel?: number,
63
+ /**
64
+ * 文件列表高度
65
+ */
66
+ height?: string | number,
67
+ /**
68
+ * 文件列表最大高度
69
+ */
70
+ maxHeight?: string | number
70
71
  }>();
71
72
  const attachId = defineModel<string>({
72
- required: false
73
+ required: false
73
74
  });
74
75
  const axios = createAxiosWithoutCache();
75
76
  const loading = useLoading(axios);
@@ -87,429 +88,503 @@ const uploadingProgress = ref(100);
87
88
  const pdfViewerVisible = ref(false);
88
89
  const pdfSrc = ref("");
89
90
  const previewableFileExts = [".doc", ".docx", ".xls", ".xlsx", ".wps", ".et",
90
- ".csv", ".txt", ".rtf", ".odt", "ods", ".mht", ".ppt", ".pptx", ".odp", ".pdf", "xps", "."];
91
- const emits = defineEmits(['change']);
91
+ ".csv", ".txt", ".rtf", ".odt", ".ods", ".mht", ".ppt", ".pptx", ".odp", ".pdf", ".xps", "."];
92
+ const emits = defineEmits<{
93
+ /**
94
+ * 附件ID变更事件
95
+ */
96
+ change: [attachId: string],
97
+ /**
98
+ * 添加单个文件事件
99
+ */
100
+ fileAdded: [AceFile],
101
+ /**
102
+ * 添加多个文件事件
103
+ */
104
+ filesAdded: [AceFile[]],
105
+ /**
106
+ * 删除单个文件事件
107
+ */
108
+ fileRemoved: [AceFile],
109
+ /**
110
+ * 开始上传事件
111
+ */
112
+ upload: [uploadID: string, files: AceFile[]],
113
+ /**
114
+ * 全体进度事件
115
+ */
116
+ progress: [progress: number],
117
+ /**
118
+ * 单文件进度事件
119
+ */
120
+ uploadProgress: [file: AceFile],
121
+ /**
122
+ * 文件上传暂停事件
123
+ */
124
+ uploadPause: [file: AceFile, isPaused: boolean],
125
+ /**
126
+ * 文件上传成功事件
127
+ */
128
+ uploadSuccess: [file: AceFile],
129
+ /**
130
+ * 全部上传完成事件
131
+ */
132
+ complete: [successful: AceFile[], failed: AceFile[]],
133
+ /**
134
+ * 全体上传失败事件
135
+ */
136
+ error: [error: Error]
137
+ /**
138
+ * 单个文件上传失败事件
139
+ */
140
+ uploadError: [file: AceFile, error: Error]
141
+
142
+
143
+ }>();
92
144
  let uppy: Uppy | undefined;
93
145
  curAttachToken.value = props.attachToken;
94
146
 
95
147
  onMounted(async () => {
96
- user.value = useLoginUser();
97
- const cl = Math.max(props.classificationLevel ?? 50, user.value?.classifiedLevel ?? 50);
98
- classificationLevels.value = await useSystemClassificationLevels();
99
- classificationLevelMap.value = await useSystemClassificationLevelMap();
100
- allowedClassificationLevels.value = classificationLevels.value.filter(l => l.value >= cl);
101
- if (props.attachToken) {
102
- await initLoad();
103
- } else {
104
- await initNew();
105
- }
148
+ user.value = useLoginUser();
149
+ const cl = Math.max(props.classificationLevel ?? 50, user.value?.classifiedLevel ?? 50);
150
+ classificationLevels.value = await useSystemClassificationLevels();
151
+ classificationLevelMap.value = await useSystemClassificationLevelMap();
152
+ allowedClassificationLevels.value = classificationLevels.value.filter(l => l.value >= cl);
153
+ if (props.attachToken) {
154
+ await initLoad();
155
+ } else {
156
+ await initNew();
157
+ }
106
158
  });
107
159
 
108
160
  onUnmounted(() => {
109
- if (uppy) uppy.destroy();
110
- uppy = undefined;
161
+ if (uppy) uppy.destroy();
162
+ uppy = undefined;
111
163
  });
112
164
 
113
165
  async function loadFileInfos() {
114
- if (!curAttachToken.value) {
115
- files.value = [];
116
- }
117
- files.value = await api.getFileList(curAttachToken.value!);
166
+ if (!curAttachToken.value) {
167
+ files.value = [];
168
+ }
169
+ files.value = await api.getFileList(curAttachToken.value!);
118
170
  }
119
171
 
120
172
  function createUppyInstance() {
121
- if (uppy) {
122
- uppy.destroy();
123
- }
124
- const cfg = uploadInitParams.value!.fileConfig;
125
- uppy = new Uppy({
126
- autoProceed: true,
127
- locale: zhCN
128
- }).on("progress", progress => {
129
- if (progress == 100) {
130
- loadFileInfos();
131
- }
132
- uploadingProgress.value = progress;
133
- });
134
- uppy.use(Tus, {
135
- endpoint: new URL("/ace-file-service/uploads", location.origin).toString(),
136
- withCredentials: true,
137
- retryDelays: undefined,
138
- chunkSize: !uploadInitParams.value?.chunkSize || uploadInitParams.value?.chunkSize
139
- == 0 ? Infinity : uploadInitParams.value?.chunkSize,
140
- parallelUploads: 1,
141
- headers: {
142
- aceAttachId: attachId.value!,
143
- aceNewForm: isNewForm.value ? "yes" : "no"
144
- },
145
- metadata: {
146
- attachId: attachId.value!,
147
- configKey: props.configKey,
148
- appServiceName: props.serviceName,
149
- classifiedLevel: selectedFileClassificationLevel.value.toString()
150
- },
151
- metadataForPartialUploads: {
152
- attachId: attachId.value!,
153
- configKey: props.configKey,
154
- appServiceName: props.serviceName,
155
- classifiedLevel: selectedFileClassificationLevel.value.toString()
173
+ if (uppy) {
174
+ uppy.destroy();
156
175
  }
157
- });
158
- if (cfg.enableWebcam) {
159
- uppy.use(Webcam, {
160
- // Webcam 的相关配置
161
- modes: cfg.allowedWebcamModes?.map(m => {
162
- switch (m) {
163
- case "VIDEO_AUDIO":
164
- return "video-audio";
165
- case "VIDEO_ONLY":
166
- return "video-only";
167
- case "PICTURE":
168
- return "picture";
176
+ const cfg = uploadInitParams.value!.fileConfig;
177
+ uppy = new Uppy({
178
+ autoProceed: true,
179
+ locale: zhCN
180
+ }).on("progress", progress => {
181
+ if (progress == 100) {
182
+ loadFileInfos();
169
183
  }
170
- }),
171
- mirror: false
184
+ uploadingProgress.value = progress;
172
185
  });
173
- }
174
- if (cfg.enableAudio) {
175
- uppy.use(Audio);
176
- }
177
- if (cfg.enableScreenCapture) {
178
- uppy.use(ScreenCapture);
179
- }
180
- let selectionType: "files" | "folders" | "both" | undefined;
181
- if (cfg.disableFileUpload) {
182
- if (cfg.disableDirUpload) {
183
- selectionType = undefined;
184
- } else {
185
- selectionType = "folders";
186
+ uppy.use(Tus, {
187
+ endpoint: new URL("/ace-file-service/uploads", location.origin).toString(),
188
+ withCredentials: true,
189
+ retryDelays: undefined,
190
+ chunkSize: !uploadInitParams.value?.chunkSize || uploadInitParams.value?.chunkSize
191
+ == 0 ? Infinity : uploadInitParams.value?.chunkSize,
192
+ parallelUploads: 1,
193
+ headers: {
194
+ aceAttachId: attachId.value!,
195
+ aceNewForm: isNewForm.value ? "yes" : "no"
196
+ },
197
+ metadata: {
198
+ attachId: attachId.value!,
199
+ configKey: props.configKey,
200
+ appServiceName: props.serviceName,
201
+ classifiedLevel: selectedFileClassificationLevel.value.toString()
202
+ },
203
+ metadataForPartialUploads: {
204
+ attachId: attachId.value!,
205
+ configKey: props.configKey,
206
+ appServiceName: props.serviceName,
207
+ classifiedLevel: selectedFileClassificationLevel.value.toString()
208
+ }
209
+ });
210
+ if (cfg.enableWebcam) {
211
+ uppy.use(Webcam, {
212
+ // Webcam 的相关配置
213
+ modes: cfg.allowedWebcamModes?.map(m => {
214
+ switch (m) {
215
+ case "VIDEO_AUDIO":
216
+ return "video-audio";
217
+ case "VIDEO_ONLY":
218
+ return "video-only";
219
+ case "PICTURE":
220
+ return "picture";
221
+ }
222
+ }),
223
+ mirror: false
224
+ });
225
+ }
226
+ if (cfg.enableAudio) {
227
+ uppy.use(Audio);
186
228
  }
187
- } else {
188
- if (cfg.disableDirUpload) {
189
- selectionType = "files";
229
+ if (cfg.enableScreenCapture) {
230
+ uppy.use(ScreenCapture);
231
+ }
232
+ let selectionType: "files" | "folders" | "both" | undefined;
233
+ if (cfg.disableFileUpload) {
234
+ if (cfg.disableDirUpload) {
235
+ selectionType = undefined;
236
+ } else {
237
+ selectionType = "folders";
238
+ }
190
239
  } else {
191
- selectionType = "both";
240
+ if (cfg.disableDirUpload) {
241
+ selectionType = "files";
242
+ } else {
243
+ selectionType = "both";
244
+ }
192
245
  }
193
- }
194
- uppy.use(Dashboard, {
195
- inline: false,
196
- note: cfg.uploadNote,
197
- proudlyDisplayPoweredByUppy: false,
198
- fileManagerSelectionType: selectionType,
199
- singleFileFullScreen: false,
200
- disableLocalFiles: cfg.disableFileUpload ?? false,
201
- closeAfterFinish: true,
202
- closeModalOnClickOutside: true
203
- }).use(ImageEditor);
246
+ uppy.use(Dashboard, {
247
+ inline: false,
248
+ note: cfg.uploadNote,
249
+ proudlyDisplayPoweredByUppy: false,
250
+ fileManagerSelectionType: selectionType,
251
+ singleFileFullScreen: false,
252
+ disableLocalFiles: cfg.disableFileUpload ?? false,
253
+ closeAfterFinish: true,
254
+ closeModalOnClickOutside: true
255
+ }).use(ImageEditor);
256
+
257
+ uppy.on('file-added', file => {
258
+ emits('fileAdded', file)
259
+ }).on('files-added', files => {
260
+ emits('filesAdded', files)
261
+ }).on('file-removed', file => {
262
+ emits('fileRemoved', file)
263
+ }).on('upload', (uploadID, files) => {
264
+ emits('upload', uploadID, files);
265
+ }).on('progress', progress => {
266
+ emits('progress', progress)
267
+ }).on('upload-progress', file=> {
268
+ emits('uploadProgress', file)
269
+ }).on('upload-pause', (file, isPaused)=>{
270
+ emits("uploadPause", file, isPaused)
271
+ }).on('upload-success', file => {
272
+ emits('uploadSuccess', file)
273
+ }).on('complete', (result)=> {
274
+ emits('complete', result.successful, result.failed)
275
+ }).on('error', (error)=> {
276
+ emits('error', error)
277
+ }).on('upload-error', (file,error)=> {
278
+ emits('uploadError', file, error)
279
+ })
204
280
  }
205
281
 
206
282
  async function onUploadBtnClick() {
207
- const cfg = uploadInitParams.value?.fileConfig;
208
- if (cfg) {
209
- uppy?.setMeta({
210
- attachId: attachId.value!,
211
- configKey: props.configKey,
212
- appServiceName: props.serviceName,
213
- classifiedLevel: selectedFileClassificationLevel.value.toString()
214
- });
215
- const dashboard = uppy?.getPlugin("Dashboard") as any;
216
- if (dashboard) {
217
- dashboard.setOptions({
218
- note: (
219
- cfg.uploadNote ? cfg.uploadNote : ""
220
- )
221
- + `(正在上传${classificationLevelMap.value?.get(selectedFileClassificationLevel.value)}文件)`
222
- });
283
+ const cfg = uploadInitParams.value?.fileConfig;
284
+ if (cfg) {
285
+ uppy?.setMeta({
286
+ attachId: attachId.value!,
287
+ configKey: props.configKey,
288
+ appServiceName: props.serviceName,
289
+ classifiedLevel: selectedFileClassificationLevel.value.toString()
290
+ });
291
+ const dashboard = uppy?.getPlugin("Dashboard") as any;
292
+ if (dashboard) {
293
+ dashboard.setOptions({
294
+ note: (
295
+ cfg.uploadNote ? cfg.uploadNote : ""
296
+ )
297
+ + `(正在上传${classificationLevelMap.value?.get(selectedFileClassificationLevel.value)}文件)`
298
+ });
299
+ }
300
+ dashboard?.openModal();
301
+ } else {
302
+ ElMessageBox.alert("无法找到附件配置" + props.configKey, "错误");
223
303
  }
224
- dashboard?.openModal();
225
- } else {
226
- ElMessageBox.alert("无法找到附件配置" + props.configKey, "错误");
227
- }
228
304
  }
229
305
 
230
306
  function handleClassificationLevelSelCmd(level: number) {
231
- selectedFileClassificationLevel.value = level;
232
- uppy?.setMeta({
233
- attachId: attachId.value!,
234
- configKey: props.configKey,
235
- appServiceName: props.serviceName,
236
- classifiedLevel: selectedFileClassificationLevel.value.toString()
237
- });
238
- const dashboard = uppy?.getPlugin("Dashboard") as any;
239
- if (dashboard) {
240
- const cfg = uploadInitParams.value?.fileConfig;
241
- if (cfg) {
242
- dashboard.setOptions({
243
- note: (
244
- cfg.uploadNote ? cfg.uploadNote : ""
245
- )
246
- + `(正在上传${classificationLevelMap.value?.get(selectedFileClassificationLevel.value)}文件)`
247
- });
307
+ selectedFileClassificationLevel.value = level;
308
+ uppy?.setMeta({
309
+ attachId: attachId.value!,
310
+ configKey: props.configKey,
311
+ appServiceName: props.serviceName,
312
+ classifiedLevel: selectedFileClassificationLevel.value.toString()
313
+ });
314
+ const dashboard = uppy?.getPlugin("Dashboard") as any;
315
+ if (dashboard) {
316
+ const cfg = uploadInitParams.value?.fileConfig;
317
+ if (cfg) {
318
+ dashboard.setOptions({
319
+ note: (
320
+ cfg.uploadNote ? cfg.uploadNote : ""
321
+ )
322
+ + `(正在上传${classificationLevelMap.value?.get(selectedFileClassificationLevel.value)}文件)`
323
+ });
324
+ }
325
+ dashboard?.openModal();
248
326
  }
249
- dashboard?.openModal();
250
- }
251
327
  }
252
328
 
253
329
  async function initLoad() {
254
- uploadInitParams.value = await api.initLoad(props.serviceName, props.configKey, props.attachToken!);
255
- files.value = uploadInitParams.value.files;
256
- attachId.value = uploadInitParams.value?.attachId;
257
- curAttachToken.value = uploadInitParams.value?.attachId;
258
- isNewForm.value = false;
259
- await nextTick();
260
- createUppyInstance();
330
+ uploadInitParams.value = await api.initLoad(props.serviceName, props.configKey, props.attachToken!);
331
+ files.value = uploadInitParams.value.files;
332
+ attachId.value = uploadInitParams.value?.attachId;
333
+ curAttachToken.value = uploadInitParams.value?.attachId;
334
+ isNewForm.value = false;
335
+ await nextTick();
336
+ createUppyInstance();
261
337
  }
262
338
 
263
339
  async function initNew() {
264
- uploadInitParams.value = await api.initNew(props.serviceName, props.configKey);
265
- files.value = uploadInitParams.value.files;
266
- attachId.value = uploadInitParams.value?.attachId;
267
- curAttachToken.value = uploadInitParams.value?.attachToken;
268
- isNewForm.value = true;
269
- emits('change', attachId.value);
270
- await nextTick();
271
- createUppyInstance();
340
+ uploadInitParams.value = await api.initNew(props.serviceName, props.configKey);
341
+ files.value = uploadInitParams.value.files;
342
+ attachId.value = uploadInitParams.value?.attachId;
343
+ curAttachToken.value = uploadInitParams.value?.attachToken;
344
+ isNewForm.value = true;
345
+ emits('change', attachId.value);
346
+ await nextTick();
347
+ createUppyInstance();
272
348
  }
273
349
 
274
350
  async function delUploadedFile(file: FileInfo) {
275
- await api.deleteFile(file.token || file.id);
276
- files.value = files.value.filter(f => f.id !== file.id);
351
+ await api.deleteFile(file.token || file.id);
352
+ files.value = files.value.filter(f => f.id !== file.id);
277
353
  }
278
354
 
279
- function previewFile(fileToken:string) {
280
- pdfSrc.value = new URL("uploads/preview/" + fileToken, location.origin).toString()
281
- pdfViewerVisible.value = true;
355
+ function previewFile(fileToken: string) {
356
+ pdfSrc.value = new URL("uploads/preview/" + fileToken, location.origin).toString()
357
+ pdfViewerVisible.value = true;
282
358
  }
283
359
 
284
360
  function downloadFile(fileToken: string) {
285
- api.downloadFile(fileToken);
361
+ api.downloadFile(fileToken);
286
362
  }
287
363
 
288
364
  function viewUppyDashboard() {
289
- const dashboard = uppy?.getPlugin("Dashboard") as any;
290
- if (dashboard) {
291
- dashboard.openModal();
292
- }
365
+ const dashboard = uppy?.getPlugin("Dashboard") as any;
366
+ if (dashboard) {
367
+ dashboard.openModal();
368
+ }
293
369
  }
294
370
 
295
371
  function downloadAll() {
296
- if (!curAttachToken.value) {
297
- return;
298
- }
299
- api.downloadZipFile(curAttachToken.value);
372
+ if (!curAttachToken.value) {
373
+ return;
374
+ }
375
+ api.downloadZipFile(curAttachToken.value);
300
376
  }
301
377
 
302
378
  function checkAllowUpload() {
303
- const cfg = uploadInitParams.value?.fileConfig;
304
- if (cfg) {
305
- let hasRole = true;
306
- if (cfg.uploadAuthCode) {
307
- const login = useLoginUser();
308
- if (login) {
309
- hasRole = login.hasRole(cfg.uploadAuthCode);
310
- }
311
- return !cfg.disallowUpload && hasRole;
379
+ const cfg = uploadInitParams.value?.fileConfig;
380
+ if (cfg) {
381
+ let hasRole = true;
382
+ if (cfg.uploadAuthCode) {
383
+ const login = useLoginUser();
384
+ if (login) {
385
+ hasRole = login.hasRole(cfg.uploadAuthCode);
386
+ }
387
+ return !cfg.disallowUpload && hasRole;
388
+ }
389
+ return !cfg.disallowUpload;
312
390
  }
313
- return !cfg.disallowUpload;
314
- }
315
- console.log('file cfg is null')
316
- return false;
391
+ console.log('file cfg is null')
392
+ return false;
317
393
  }
318
394
 
319
395
  function checkAllowDownload() {
320
- const cfg = uploadInitParams.value?.fileConfig;
321
- if (cfg) {
322
- let hasRole = true;
323
- if (cfg.downloadAuthCode) {
324
- const login = useLoginUser();
325
- if (login) {
326
- hasRole = login.hasRole(cfg.downloadAuthCode);
327
- }
328
- return !cfg.disallowDownload && hasRole;
396
+ const cfg = uploadInitParams.value?.fileConfig;
397
+ if (cfg) {
398
+ let hasRole = true;
399
+ if (cfg.downloadAuthCode) {
400
+ const login = useLoginUser();
401
+ if (login) {
402
+ hasRole = login.hasRole(cfg.downloadAuthCode);
403
+ }
404
+ return !cfg.disallowDownload && hasRole;
405
+ }
406
+ return !cfg.disallowDownload;
329
407
  }
330
- return !cfg.disallowDownload;
331
- }
332
- return false;
408
+ return false;
333
409
  }
334
410
 
335
411
  function checkAllowDelete() {
336
- const cfg = uploadInitParams.value?.fileConfig;
337
- if (cfg) {
338
- let hasRole = true;
339
- if (cfg.deleteAuthCode) {
340
- const login = useLoginUser();
341
- if (login) {
342
- hasRole = login.hasRole(cfg.deleteAuthCode);
343
- }
344
- return !cfg.disallowDelete && hasRole;
412
+ const cfg = uploadInitParams.value?.fileConfig;
413
+ if (cfg) {
414
+ let hasRole = true;
415
+ if (cfg.deleteAuthCode) {
416
+ const login = useLoginUser();
417
+ if (login) {
418
+ hasRole = login.hasRole(cfg.deleteAuthCode);
419
+ }
420
+ return !cfg.disallowDelete && hasRole;
421
+ }
422
+ return !cfg.disallowDelete;
345
423
  }
346
- return !cfg.disallowDelete;
347
- }
348
- return false;
424
+ return false;
349
425
  }
350
426
 
351
427
  function checkAllowPreview(file: FileInfo) {
352
- const cfg = uploadInitParams.value?.fileConfig;
353
- if (cfg) {
354
- if (cfg.disablePreview) {
355
- return false;
356
- }
357
- if (!previewableFileExts.some(ext => file.fileName.endsWith(ext))) {
358
- return false;
428
+ const cfg = uploadInitParams.value?.fileConfig;
429
+ if (cfg) {
430
+ if (cfg.disablePreview) {
431
+ return false;
432
+ }
433
+ if (!previewableFileExts.some(ext => file.fileName.endsWith(ext))) {
434
+ return false;
435
+ }
436
+ return true;
359
437
  }
360
- return true;
361
- }
362
- return false;
438
+ return false;
363
439
  }
364
440
 
365
441
  watch(() => props.attachToken, () => {
366
- if (props.attachToken) {
367
- initLoad();
368
- } else {
369
- initNew();
370
- }
442
+ if (props.attachToken) {
443
+ initLoad();
444
+ } else {
445
+ initNew();
446
+ }
371
447
  });
372
448
 
373
-
374
449
  </script>
375
450
 
376
451
  <template>
377
- <div class="ja-uploader">
378
- <div class="ja-uploader-tools">
379
- <el-button plain type="success" :icon="Upload" @click="onUploadBtnClick"
380
- :loading="loading" :disabled="loading" size="small"
381
- v-if="allowedClassificationLevels.length <= 1 && checkAllowUpload()">
382
- 上传{{ uploadInitParams?.fileConfig.enableClassifiedLevel ? "(非密)" : "" }}
383
- </el-button>
384
- <el-button plain :icon="Download" @click="downloadAll" v-if="checkAllowDownload()"
385
- :loading="loading" :disabled="loading || files?.length === 0" size="small">全部下载
386
- </el-button>
387
- <el-dropdown v-if="allowedClassificationLevels.length > 1 && checkAllowUpload()"
388
- @command="handleClassificationLevelSelCmd" size="small">
389
- <el-button type="success" size="small">
390
- 上传
391
- <el-icon class="el-icon--right">
392
- <arrow-down />
393
- </el-icon>
394
- </el-button>
395
- <template #dropdown>
396
- <el-dropdown-menu>
397
- <el-dropdown-item v-for="cl in allowedClassificationLevels"
398
- :key="cl.value"
399
- :command="cl.value">{{ cl.label }}
400
- </el-dropdown-item>
401
- </el-dropdown-menu>
402
- </template>
403
- </el-dropdown>
404
- <div class="container" @click="viewUppyDashboard"
405
- v-if="uploadingProgress < 100 && uploadingProgress > 0">
406
- <p>
407
- <span class="loader-shimmer">正在上传,已完成{{ uploadingProgress }}%...</span>
408
- </p>
409
- </div>
452
+ <div class="ja-uploader">
453
+ <div class="ja-uploader-tools">
454
+ <el-button plain type="success" :icon="Upload" @click="onUploadBtnClick"
455
+ :loading="loading" :disabled="loading" size="small"
456
+ v-if="allowedClassificationLevels.length <= 1 && checkAllowUpload()">
457
+ 上传{{ uploadInitParams?.fileConfig.enableClassifiedLevel ? "(非密)" : "" }}
458
+ </el-button>
459
+ <el-button plain :icon="Download" @click="downloadAll" v-if="checkAllowDownload()"
460
+ :loading="loading" :disabled="loading || files?.length === 0" size="small">
461
+ 全部下载
462
+ </el-button>
463
+ <el-dropdown v-if="allowedClassificationLevels.length > 1 && checkAllowUpload()"
464
+ @command="handleClassificationLevelSelCmd" size="small">
465
+ <el-button type="success" size="small">
466
+ 上传
467
+ <el-icon class="el-icon--right">
468
+ <arrow-down/>
469
+ </el-icon>
470
+ </el-button>
471
+ <template #dropdown>
472
+ <el-dropdown-menu>
473
+ <el-dropdown-item v-for="cl in allowedClassificationLevels"
474
+ :key="cl.value"
475
+ :command="cl.value">{{ cl.label }}
476
+ </el-dropdown-item>
477
+ </el-dropdown-menu>
478
+ </template>
479
+ </el-dropdown>
480
+ <div class="container" @click="viewUppyDashboard"
481
+ v-if="uploadingProgress < 100 && uploadingProgress > 0">
482
+ <p>
483
+ <span class="loader-shimmer">正在上传,已完成{{ uploadingProgress }}%...</span>
484
+ </p>
485
+ </div>
486
+ </div>
487
+ <el-table :data="files" :show-header="true" style="width: 100%" empty-text="暂无文件"
488
+ :height="props.height" :max-height="props.maxHeight">
489
+ <el-table-column prop="fileName"/>
490
+ <el-table-column prop="fileSize" width="100">
491
+ <template #default="scope">
492
+ {{ prettyBytes(scope.row.fileSize) }}
493
+ </template>
494
+ </el-table-column>
495
+ <el-table-column prop="classifiedLevel" width="60">
496
+ <template #default="scope">
497
+ <el-tag
498
+ :type="scope.row.classifiedLevel < 50? ( scope.row.classifiedLevel < 30 ? 'danger' : 'warning'): 'info'">
499
+ {{ classificationLevelMap?.get(scope.row.classifiedLevel) }}
500
+ </el-tag>
501
+ </template>
502
+ </el-table-column>
503
+ <el-table-column align="right" width="150" fixed="right">
504
+ <template #default="scope">
505
+ <el-button link type="warning" @click="previewFile(scope.row.token)"
506
+ v-if="checkAllowPreview(scope.row)">预览
507
+ </el-button>
508
+ <el-button link type="primary" @click="downloadFile(scope.row.token)"
509
+ v-if="checkAllowDownload()">下载
510
+ </el-button>
511
+ <el-button link type="danger" @click="delUploadedFile(scope.row)"
512
+ v-if="checkAllowDelete()">删除
513
+ </el-button>
514
+ </template>
515
+ </el-table-column>
516
+ </el-table>
410
517
  </div>
411
- <el-table :data="files" :show-header="true" style="width: 100%" empty-text="暂无文件"
412
- :height="props.height" :max-height="props.maxHeight">
413
- <el-table-column prop="fileName" />
414
- <el-table-column prop="fileSize" width="100">
415
- <template #default="scope">
416
- {{ prettyBytes(scope.row.fileSize) }}
417
- </template>
418
- </el-table-column>
419
- <el-table-column prop="classifiedLevel" width="60">
420
- <template #default="scope">
421
- <el-tag
422
- :type="scope.row.classifiedLevel < 50? ( scope.row.classifiedLevel < 30 ? 'danger' : 'warning'): 'info'">
423
- {{ classificationLevelMap?.get(scope.row.classifiedLevel) }}
424
- </el-tag>
425
- </template>
426
- </el-table-column>
427
- <el-table-column align="right" width="150" fixed="right">
428
- <template #default="scope">
429
- <el-button link type="warning" @click="previewFile(scope.row.token)"
430
- v-if="checkAllowPreview(scope.row)">预览</el-button>
431
- <el-button link type="primary" @click="downloadFile(scope.row.token)"
432
- v-if="checkAllowDownload()">下载
433
- </el-button>
434
- <el-button link type="danger" @click="delUploadedFile(scope.row)"
435
- v-if="checkAllowDelete()">删除
436
- </el-button>
437
- </template>
438
- </el-table-column>
439
- </el-table>
440
- </div>
441
- <pdf-viewer-modal :src="pdfSrc" v-model="pdfViewerVisible"></pdf-viewer-modal>
518
+ <pdf-viewer-modal :src="pdfSrc" v-model="pdfViewerVisible"></pdf-viewer-modal>
442
519
  </template>
443
520
 
444
- <style>
521
+ <style lang="scss" scoped>
445
522
  .uppy-Dashboard--modal {
446
- z-index: 9999 !important;
523
+ z-index: 9999 !important;
447
524
  }
448
525
 
449
526
  .uppy-Root {
450
- z-index: 9999;
527
+ z-index: 9999;
451
528
  }
452
- </style>
453
-
454
- <style lang="scss" scoped>
455
529
 
456
530
  .ja-uploader {
457
- width: 100%;
458
- display: flex;
459
- flex-direction: column;
460
- gap: 4px;
461
-
462
- &-tools {
531
+ width: 100%;
463
532
  display: flex;
464
- }
465
- }
533
+ flex-direction: column;
534
+ gap: 4px;
466
535
 
467
- .container {
468
- padding: 0 0 0 8px;
469
- cursor: pointer;
470
- }
536
+ &-tools {
537
+ display: flex;
538
+ }
471
539
 
472
- .loader-shimmer {
473
- display: inline-block;
474
- margin-left: 8px;
475
- padding: 0 12px;
476
- background-color: #e0f5f0;
477
- color: #888;
478
- border-radius: 4px;
479
- font-size: 0.9em;
480
- font-weight: 500;
481
- position: relative;
482
- overflow: hidden; /* 隐藏闪光效果的溢出 */
483
- vertical-align: middle;
484
- }
540
+ .container {
541
+ padding: 0 0 0 8px;
542
+ cursor: pointer;
543
+ }
485
544
 
486
- .loader-shimmer::after {
487
- content: '';
488
- position: absolute;
489
- top: 0;
490
- left: -100%; /* 从左侧外部开始 */
491
- width: 50%; /* 闪光宽度 */
492
- height: 100%;
493
-
494
- /* 闪光效果:透明 -> 亮白色 -> 透明 */
495
- background: linear-gradient(
496
- 90deg,
497
- transparent,
498
- rgba(255, 255, 255, 0.8),
499
- transparent
500
- );
501
-
502
- /* 动画: 1.5秒, 缓入缓出, 无限循环 */
503
- animation: shimmer 1.5s ease-in-out infinite;
504
- }
545
+ .loader-shimmer {
546
+ display: inline-block;
547
+ margin-left: 8px;
548
+ padding: 0 12px;
549
+ background-color: #e0f5f0;
550
+ color: #888;
551
+ border-radius: 4px;
552
+ font-size: 0.9em;
553
+ font-weight: 500;
554
+ position: relative;
555
+ overflow: hidden; /* 隐藏闪光效果的溢出 */
556
+ vertical-align: middle;
557
+ }
558
+
559
+ .loader-shimmer::after {
560
+ content: '';
561
+ position: absolute;
562
+ top: 0;
563
+ left: -100%; /* 从左侧外部开始 */
564
+ width: 50%; /* 闪光宽度 */
565
+ height: 100%;
566
+
567
+ /* 闪光效果:透明 -> 亮白色 -> 透明 */
568
+ background: linear-gradient(
569
+ 90deg,
570
+ transparent,
571
+ rgba(255, 255, 255, 0.8),
572
+ transparent
573
+ );
574
+
575
+ /* 动画: 1.5秒, 缓入缓出, 无限循环 */
576
+ animation: shimmer 1.5s ease-in-out infinite;
577
+ }
505
578
 
506
- @keyframes shimmer {
507
- 0% {
508
- left: -100%;
509
- }
510
- 100% {
511
- left: 150%; /* 移动到右侧外部 */
512
- }
579
+ @keyframes shimmer {
580
+ 0% {
581
+ left: -100%;
582
+ }
583
+ 100% {
584
+ left: 150%; /* 移动到右侧外部 */
585
+ }
586
+ }
513
587
  }
514
588
 
589
+
515
590
  </style>