cloud-web-corejs 1.0.280 → 1.1.0-dev.10

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 (193) hide show
  1. package/package.json +6 -2
  2. package/src/components/VabUpload/image-viewer.vue +442 -442
  3. package/src/components/VabUpload/index.vue +45 -3
  4. package/src/components/VabUpload/mixins.js +174 -34
  5. package/src/components/VabUpload/previewGroup.js +128 -0
  6. package/src/components/VabUpload/view.vue +248 -209
  7. package/src/components/baseTabs/mixins.js +181 -181
  8. package/src/components/bizTab/BizBillActions.vue +129 -0
  9. package/src/components/bizTab/BizTabListPage.vue +391 -0
  10. package/src/components/bizTab/README.md +378 -0
  11. package/src/components/bizTab/billTableUtil.js +48 -0
  12. package/src/components/bizTab/billValidators.js +136 -0
  13. package/src/components/bizTab/bizBillDetailMixin.js +705 -0
  14. package/src/components/bizTab/index.js +24 -0
  15. package/src/components/excelExport/exportFieldDialog.vue +23 -12
  16. package/src/components/excelExport/exportItemConfigUtil.js +30 -0
  17. package/src/components/excelExport/mixins.js +3 -3
  18. package/src/components/excelImport/index.vue +156 -156
  19. package/src/components/jsonImport/index.vue +1 -1
  20. package/src/components/langImport/index.vue +1 -1
  21. package/src/components/mobile/statusTag/mixins.js +1 -61
  22. package/src/components/mobile/wf/addTaskUserdialog.vue +23 -3
  23. package/src/components/mobile/wf/content.vue +1705 -1556
  24. package/src/components/mobile/wf/deleteTaskUserDialog.vue +22 -3
  25. package/src/components/mobile/wf/mixins/wfModifyDialogMixin.js +8 -6
  26. package/src/components/mobile/wf/selectUserDialog.vue +122 -0
  27. package/src/components/mobile/wf/setCandidateDialog.vue +25 -4
  28. package/src/components/mobile/wf/urgingDialog.vue +26 -3
  29. package/src/components/mobile/wf/wfModifyDialog.vue +4 -0
  30. package/src/components/obsUpload/index.vue +1 -1
  31. package/src/components/table/config.js +78 -78
  32. package/src/components/table/index.js +1276 -1276
  33. package/src/components/table/plugins/cell-area/index.js +1055 -0
  34. package/src/components/table/plugins/cell-area/index.scss +77 -0
  35. package/src/components/table/plugins/cell-area/util.js +224 -0
  36. package/src/components/table/tableForm.vue +330 -330
  37. package/src/components/table/tableFormMixin.js +318 -318
  38. package/src/components/table/vxeFilter/index.js +163 -163
  39. package/src/components/table/vxeFilter/mixin.js +316 -316
  40. package/src/components/wf/content.vue +1188 -1188
  41. package/src/components/wf/wf.js +40 -20
  42. package/src/components/wf/wfActionDropdown.vue +1 -1
  43. package/src/components/wf/wfActionItems.js +1 -1
  44. package/src/components/xform/docs/2026-08 xform H5 P0 /345/256/236/347/216/260/350/247/204/346/240/274.md" +528 -0
  45. package/src/components/xform/docs/2026-08 xform H5 P1 /345/256/236/347/216/260/350/247/204/346/240/274.md" +412 -0
  46. package/src/components/xform/docs/2026-08 xform H5 P2 /345/256/236/347/216/260/350/247/204/346/240/274.md" +287 -0
  47. package/src/components/xform/docs/2026-08 xform /347/247/273/345/212/250/347/253/257/345/270/203/345/261/200/345/257/271/351/275/220 bill_setting /346/226/271/346/241/210.md" +400 -0
  48. package/src/components/xform/form-designer/designer.js +51 -52
  49. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +269 -269
  50. package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +18 -2
  51. package/src/components/xform/form-designer/form-widget/container-widget/detail-temp-widget.vue +132 -0
  52. package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +250 -250
  53. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +23 -2
  54. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +30 -1
  55. package/src/components/xform/form-designer/form-widget/dialog/fileReferenceDialog.vue +319 -320
  56. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +365 -365
  57. package/src/components/xform/form-designer/form-widget/dialog/importDialog.vue +185 -185
  58. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +554 -555
  59. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +409 -409
  60. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +150 -132
  61. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +114 -114
  62. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +154 -154
  63. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +47 -1
  64. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +178 -178
  65. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +77 -77
  66. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +6 -0
  67. package/src/components/xform/form-designer/form-widget/field-widget/select-widget.vue +139 -139
  68. package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +1 -1
  69. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +106 -106
  70. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +134 -134
  71. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +3 -2
  72. package/src/components/xform/form-designer/indexMixin.js +35 -1
  73. package/src/components/xform/form-designer/setting-panel/form-setting.vue +39 -39
  74. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +10 -10
  75. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/exportItemColumns-dialog.vue +438 -432
  76. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +2103 -2103
  77. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-temp-edito.vue +90 -0
  78. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +82 -82
  79. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +833 -846
  80. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +8 -8
  81. package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +137 -137
  82. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
  83. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +43 -43
  84. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +43 -43
  85. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +96 -96
  86. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +51 -0
  87. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +42 -42
  88. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +43 -43
  89. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +158 -158
  90. package/src/components/xform/form-designer/setting-panel/property-editor/h5Span-editor.vue +51 -0
  91. package/src/components/xform/form-designer/setting-panel/property-editor/itemStyle-editor.vue +39 -0
  92. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +188 -188
  93. package/src/components/xform/form-designer/setting-panel/property-editor/styleTempClass-editor.vue +51 -0
  94. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +347 -347
  95. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +12 -0
  96. package/src/components/xform/form-designer/toolbar-panel/index.vue +884 -874
  97. package/src/components/xform/form-designer/toolbar-panel/indexMixin.js +14 -0
  98. package/src/components/xform/form-designer/widget-panel/index.vue +11 -7
  99. package/src/components/xform/form-designer/widget-panel/indexMixin.js +30 -6
  100. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +112 -4
  101. package/src/components/xform/form-render/container-item/data-table-mixin.js +151 -93
  102. package/src/components/xform/form-render/container-item/detail-h5-item.vue +204 -34
  103. package/src/components/xform/form-render/container-item/detail-temp-item.vue +110 -0
  104. package/src/components/xform/form-render/container-item/h5-card-pane-item.vue +160 -140
  105. package/src/components/xform/form-render/container-item/list-h5-item.vue +1913 -1699
  106. package/src/components/xform/form-render/index.vue +153 -147
  107. package/src/components/xform/form-render/indexMixin.js +35 -3
  108. package/src/components/xform/lang/en-US.js +14 -0
  109. package/src/components/xform/lang/zh-CN.js +17 -0
  110. package/src/components/xform/mixins/defaultHandle.js +707 -707
  111. package/src/components/xform/styles/h5.scss +2238 -0
  112. package/src/components/xform/utils/textMaskUtil.js +182 -179
  113. package/src/components/xform/utils/treeTableUtil.js +1292 -1265
  114. package/src/components/xform/utils/util.js +56 -11
  115. package/src/directive/append-to-body/index.js +48 -0
  116. package/src/index.js +13 -4
  117. package/src/layout/components/Sidebar/default.vue +1655 -1655
  118. package/src/layout/components/extractedCode/viewDialog.vue +7 -7
  119. package/src/router/index.js +48 -27
  120. package/src/router/modules/customer.js +71 -14
  121. package/src/store/modules/permission.js +17 -18
  122. package/src/utils/assetUrl.js +19 -0
  123. package/src/utils/pdfUtil.js +429 -429
  124. package/src/utils/resolveViewComponent.js +142 -16
  125. package/src/utils/vab.js +1283 -1279
  126. package/src/views/bd/project/branch/bd_branch/edit.vue +145 -0
  127. package/src/views/bd/project/branch/bd_branch/list.vue +72 -0
  128. package/src/views/bd/project/branch/bd_branch/menuKindDialog.vue +106 -0
  129. package/src/views/bd/project/branch/bd_branch/mixins/edit.js +189 -0
  130. package/src/views/bd/project/branch/bd_branch/mixins/list.js +124 -0
  131. package/src/views/bd/project/branch/bd_branch/mixins/menuKindDialog.js +85 -0
  132. package/src/views/bd/project/branch/form_script/list.vue +31 -0
  133. package/src/views/bd/project/branch/form_template/list.vue +30 -0
  134. package/src/views/bd/project/branch/menu_kind/list.vue +31 -0
  135. package/src/views/bd/project/common/form_script/list.vue +16 -0
  136. package/src/views/bd/project/common/form_template/list.vue +15 -0
  137. package/src/views/bd/project/common/menu_kind/list.vue +15 -0
  138. package/src/views/bd/project/core/branchContext.js +100 -0
  139. package/src/views/bd/project/core/branchPage.js +78 -0
  140. package/src/views/bd/project/core/branchPageWrap.vue +225 -0
  141. package/src/views/bd/project/core/branchScope.js +44 -0
  142. package/src/views/bd/project/core/branchSearchPage.js +285 -0
  143. package/src/views/bd/project/core/branchSelect.vue +85 -0
  144. package/src/views/bd/project/core/branchTreeBar.vue +81 -0
  145. package/src/views/bd/project/core/httpBranchPatch.js +58 -0
  146. package/src/views/bd/project/datatable/menu_kind/list.vue +15 -0
  147. package/src/views/bd/project/datatable/table_model/list.vue +15 -0
  148. package/src/views/bd/setting/bd_company_env/dialog.vue +174 -174
  149. package/src/views/bd/setting/form_template/edit.vue +378 -356
  150. package/src/views/bd/setting/form_template/formDesignerDialog.vue +6 -0
  151. package/src/views/bd/setting/form_template/formTemplateType.js +43 -0
  152. package/src/views/bd/setting/form_template/list.vue +304 -303
  153. package/src/views/bd/setting/form_template/mixins/edit.js +344 -280
  154. package/src/views/bd/setting/form_template/mixins/list.js +748 -721
  155. package/src/views/bd/setting/table_model/edit.vue +1066 -1066
  156. package/src/views/bd/setting/table_model/mixins/edit.js +1455 -1455
  157. package/src/views/bd/setting/table_model/mixins/zdDialog.js +148 -148
  158. package/src/views/demo/bizTab/bill/billConfig.js +41 -0
  159. package/src/views/demo/bizTab/bill/detail.vue +436 -0
  160. package/src/views/demo/bizTab/bill/list.vue +288 -0
  161. package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
  162. package/src/views/demo/bizTab/simple/billApi.js +123 -0
  163. package/src/views/demo/bizTab/simple/detail.vue +407 -0
  164. package/src/views/demo/bizTab/simple/list.vue +217 -0
  165. package/src/views/demo/bizTab/standalone/index.vue +121 -0
  166. package/src/views/demo/bizTab/wf/billConfig.js +44 -0
  167. package/src/views/demo/bizTab/wf/detail.vue +661 -0
  168. package/src/views/demo/bizTab/wf/list.vue +242 -0
  169. package/src/views/support/form-dialog-demo/demoPickerDialog.vue +72 -0
  170. package/src/views/support/form-dialog-demo/index.vue +537 -0
  171. package/src/views/user/file_view_ins/list.vue +970 -970
  172. package/src/views/user/form/vform/designer.vue +823 -821
  173. package/src/views/user/home/default.vue +1117 -1117
  174. package/src/views/user/home/default2.vue +1 -1
  175. package/src/views/user/home/index.vue +103 -101
  176. package/src/views/user/home/wjl/content.vue +1569 -0
  177. package/src/views/user/notify_message/dialog.vue +139 -137
  178. package/src/views/user/outLink/cc_form_view.vue +188 -0
  179. package/src/views/user/outLink/form_view.vue +202 -202
  180. package/src/views/user/outLink/index.vue +110 -110
  181. package/src/views/user/outLink/view.vue +3 -3
  182. package/src/views/user/role/edit.vue +632 -632
  183. package/src/views/user/role/list.vue +260 -260
  184. package/src/views/user/wf/iframe/index.vue +51 -51
  185. package/src/views/user/wf/iframe/index2.vue +64 -64
  186. package/src/views/user/wf/wf_manage/list.vue +1112 -1116
  187. package/src/views/user/wf/wf_manage/list2.vue +871 -875
  188. package/src/views/user/wf/wf_manage/wfContentDialog.vue +134 -131
  189. package/src/views/user/wf/wf_obj_config/importItemDialog.vue +1 -1
  190. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-menu-widget.vue +0 -106
  191. package/src/components/xform/form-designer/form-widget/field-widget/tableexportbuttonwidget.vue +0 -99
  192. package/src/components/xform/form-render/container-item/list-h5-item2.vue +0 -1340
  193. package/src/utils/wf.js +0 -766
@@ -14,13 +14,21 @@
14
14
  >
15
15
  <div class="upload-box" style="margin-left:-20px;margin-right:-20px;">
16
16
  <div class="upload-b_left" @click="choosePasteArea" :class="{on:pasteAreaStatus}"
17
- v-show="option.hidePasteArea!==true">
17
+ v-show="option.hidePasteArea!==true"
18
+ @dragenter="handlePasteAreaDragEnter"
19
+ @dragover="handlePasteAreaDragOver"
20
+ @dragleave="handlePasteAreaDragLeave"
21
+ @drop="handlePasteAreaDrop">
18
22
  <div class="t"><i
19
- class="el-icon-warning-outline"></i>{{ $t2('选择此处,可粘贴文件', 'components.VabUpload.tip') }}(Ctrl+V)
23
+ class="el-icon-warning-outline"></i>{{ $t2('选择此处,可粘贴文件', 'components.VabUpload.tip') }}(Ctrl+V){{ $t1(',或将文件拖拽到此处') }}
24
+ </div>
25
+ <div class="drag-mask" v-show="pasteAreaDragging">
26
+ <i class="el-icon-upload"></i>
27
+ <p>{{ $t1('松开鼠标,添加文件') }}</p>
20
28
  </div>
21
29
  <ul class="el-upload-list el-upload-list--picture">
22
30
  <div class="nodata" v-if="pasteList.length == 0">
23
- <img src="~@/resources/images/nodata2.png"/>
31
+ <img :src="$assetUrl(require('@/resources/images/nodata2.png'))" />
24
32
  </div>
25
33
  <li v-for="(pasteFile,index) in pasteList" :key="index" class="el-upload-list__item is-success">
26
34
  <div>
@@ -239,4 +247,38 @@ export default {
239
247
  .showPasteArea {
240
248
  margin-left:291px
241
249
  }
250
+
251
+ /* 左侧粘贴区支持拖拽文件,拖拽时铺一层提示遮罩(pointer-events:none 保证拖拽事件仍落到容器上) */
252
+ .upload-b_left {
253
+ position: relative;
254
+
255
+ .drag-mask {
256
+ position: absolute;
257
+ top: 0;
258
+ left: 0;
259
+ right: 0;
260
+ bottom: 0;
261
+ z-index: 2;
262
+ display: flex;
263
+ flex-direction: column;
264
+ align-items: center;
265
+ justify-content: center;
266
+ margin: 4px;
267
+ border: dashed 2px $--color-primary;
268
+ border-radius: 9px;
269
+ background: rgba(255, 255, 255, 0.88);
270
+ color: $--color-primary;
271
+ pointer-events: none;
272
+
273
+ i {
274
+ font-size: 46px;
275
+ margin-bottom: 8px;
276
+ }
277
+
278
+ p {
279
+ margin: 0;
280
+ font-size: 12px;
281
+ }
282
+ }
283
+ }
242
284
  </style>
@@ -3,6 +3,11 @@ let tmixins, tViewMixins, pmixins;
3
3
  import axios from "axios";
4
4
  import SparkMD5 from "spark-md5";
5
5
  import settingConfig from "@/settings.js";
6
+ import {
7
+ registerPreviewInstance,
8
+ unregisterPreviewInstance,
9
+ collectPreviewList,
10
+ } from "./previewGroup.js";
6
11
 
7
12
  let imFun = {
8
13
  axios,
@@ -109,6 +114,8 @@ tmixins = {
109
114
  showPrivateProfileDialog: false,
110
115
  pasteList: [],
111
116
  pasteAreaStatus: false,
117
+ pasteAreaDragging: false,
118
+ pasteAreaDragDepth: 0,
112
119
  option: {},
113
120
  editFileIndex: -1,
114
121
  showFileNameDialog: false,
@@ -375,6 +382,8 @@ tmixins = {
375
382
  this.clearFileInfo();
376
383
  this.initPickUploadMode();
377
384
  this.pasteAreaStatus = false;
385
+ this.pasteAreaDragging = false;
386
+ this.pasteAreaDragDepth = 0;
378
387
  this.dialogFormVisible = true;
379
388
  /*document.removeEventListener('paste', this.pasteEvent);
380
389
  document.addEventListener('paste', this.pasteEvent);*/
@@ -1207,27 +1216,93 @@ tmixins = {
1207
1216
  if (!(e.clipboardData && e.clipboardData.items)) {
1208
1217
  return;
1209
1218
  }
1210
- let files = Array.from(e.clipboardData.files);
1219
+ this.appendPasteFiles(Array.from(e.clipboardData.files));
1220
+ },
1221
+ /* 追加原始文件到左侧待确认列表(粘贴、拖拽共用) */
1222
+ appendPasteFiles(files) {
1223
+ if (!files || !files.length) {
1224
+ return;
1225
+ }
1211
1226
  let getFileSuffix = this.$commonFileUtil.getFileSuffix;
1212
- if (files.length) {
1213
- let fileList = files.map((rawFile) => {
1214
- let name = rawFile.name;
1215
- let index = name.lastIndexOf(".");
1216
- let fileSuffix = getFileSuffix(name);
1217
- let fileName =
1218
- index >= 0 ? name.substring(0, index).toString() : name.toString();
1219
- let file = {
1220
- name: rawFile.name,
1221
- size: rawFile.size,
1222
- raw: rawFile,
1223
- showUrl: URL.createObjectURL(rawFile),
1224
- fileName: fileName,
1225
- fileSuffix: fileSuffix,
1226
- };
1227
- return file;
1227
+ let fileList = files.map((rawFile) => {
1228
+ let name = rawFile.name;
1229
+ let index = name.lastIndexOf(".");
1230
+ let fileSuffix = getFileSuffix(name);
1231
+ let fileName =
1232
+ index >= 0 ? name.substring(0, index).toString() : name.toString();
1233
+ let file = {
1234
+ name: rawFile.name,
1235
+ size: rawFile.size,
1236
+ raw: rawFile,
1237
+ showUrl: URL.createObjectURL(rawFile),
1238
+ fileName: fileName,
1239
+ fileSuffix: fileSuffix,
1240
+ };
1241
+ return file;
1242
+ });
1243
+ this.pasteList.push(...fileList);
1244
+ },
1245
+ isFileDragEvent(e) {
1246
+ let dataTransfer = e.dataTransfer;
1247
+ if (!dataTransfer || !dataTransfer.types) return false;
1248
+ return Array.prototype.indexOf.call(dataTransfer.types, "Files") >= 0;
1249
+ },
1250
+ handlePasteAreaDragEnter(e) {
1251
+ if (!this.isFileDragEvent(e)) return;
1252
+ e.preventDefault();
1253
+ e.stopPropagation();
1254
+ this.pasteAreaDragDepth++;
1255
+ this.pasteAreaDragging = true;
1256
+ },
1257
+ handlePasteAreaDragOver(e) {
1258
+ if (!this.isFileDragEvent(e)) return;
1259
+ e.preventDefault();
1260
+ e.stopPropagation();
1261
+ e.dataTransfer.dropEffect = "copy";
1262
+ this.pasteAreaDragging = true;
1263
+ },
1264
+ handlePasteAreaDragLeave(e) {
1265
+ if (!this.isFileDragEvent(e)) return;
1266
+ e.preventDefault();
1267
+ e.stopPropagation();
1268
+ this.pasteAreaDragDepth--;
1269
+ if (this.pasteAreaDragDepth <= 0) {
1270
+ this.pasteAreaDragDepth = 0;
1271
+ this.pasteAreaDragging = false;
1272
+ }
1273
+ },
1274
+ handlePasteAreaDrop(e) {
1275
+ this.pasteAreaDragDepth = 0;
1276
+ this.pasteAreaDragging = false;
1277
+ if (!this.isFileDragEvent(e)) return;
1278
+ e.preventDefault();
1279
+ e.stopPropagation();
1280
+ /* 拖入即视为选中该区域,与粘贴保持一致 */
1281
+ this.pasteAreaStatus = true;
1282
+ let dataTransfer = e.dataTransfer;
1283
+ let items = dataTransfer.items ? Array.from(dataTransfer.items) : [];
1284
+ let hasDirectory = false;
1285
+ let files = Array.from(dataTransfer.files || []).filter(
1286
+ (rawFile, index) => {
1287
+ let item = items[index];
1288
+ let getAsEntry = item && item.webkitGetAsEntry;
1289
+ let entry = getAsEntry ? item.webkitGetAsEntry() : null;
1290
+ if (entry && entry.isDirectory) {
1291
+ hasDirectory = true;
1292
+ return false;
1293
+ }
1294
+ return true;
1295
+ }
1296
+ );
1297
+ if (hasDirectory) {
1298
+ this.$message({
1299
+ message: this.$t1("不支持上传文件夹,已自动忽略"),
1300
+ type: "warning",
1301
+ showClose: true,
1302
+ duration: 3000,
1228
1303
  });
1229
- this.pasteList.push(...fileList);
1230
1304
  }
1305
+ this.appendPasteFiles(files);
1231
1306
  },
1232
1307
  deletePasteFile(index) {
1233
1308
  this.pasteList.splice(index, 1);
@@ -1372,12 +1447,18 @@ tViewMixins = {
1372
1447
  attachments: [],
1373
1448
  pictureList: [],
1374
1449
  pictureDtoList: [],
1450
+ // 传给预览弹框的图片列表:可能跨字段汇总了整个表单的图片,见 previewGroup.js
1451
+ previewList: [],
1375
1452
  showPropertiesDialog: false,
1376
1453
  editAttachment: null,
1377
1454
  showViewer: false,
1378
1455
  chooseIndex: 0,
1379
1456
  fileServerInfo: {},
1380
1457
  model: null,
1458
+ // H5 非图片文件预览弹框,见 openFilePreviewDialog
1459
+ showFilePreviewDialog: false,
1460
+ previewFileUrl: null,
1461
+ previewFileName: null,
1381
1462
  };
1382
1463
  },
1383
1464
  computed: {
@@ -1442,6 +1523,12 @@ tViewMixins = {
1442
1523
  this.initFileServerInfo();
1443
1524
  this.initFile();
1444
1525
  },
1526
+ mounted() {
1527
+ registerPreviewInstance(this);
1528
+ },
1529
+ beforeDestroy() {
1530
+ unregisterPreviewInstance(this);
1531
+ },
1445
1532
  methods: {
1446
1533
  pasteEvent(e) {
1447
1534
  e.stopPropagation();
@@ -1657,23 +1744,41 @@ tViewMixins = {
1657
1744
  .concat(this.pictureDtoList.slice(0, pictureIndex));
1658
1745
  return res;
1659
1746
  },
1660
- openImagePreView(index) {
1661
- // this.chooseIndex = index;
1662
- let pictureIndex = -1;
1663
- this.attachments.find((item, i) => {
1664
- let typeStr = Object.prototype.toString.call(item);
1665
- if (typeStr == "[object Object]") {
1666
- if (this.$commonFileUtil.isPictureFile(item.url)) {
1667
- pictureIndex++;
1668
- }
1669
- } else {
1670
- if (this.$commonFileUtil.isPictureFile(item)) {
1671
- pictureIndex++;
1672
- }
1747
+ isPictureAttachment(attachment) {
1748
+ if (!attachment) return false;
1749
+ let typeStr = Object.prototype.toString.call(attachment);
1750
+ if (typeStr == "[object Object]") {
1751
+ return this.$commonFileUtil.isPictureFile(attachment.url);
1752
+ }
1753
+ return this.$commonFileUtil.isPictureFile(attachment);
1754
+ },
1755
+ /**
1756
+ * 本字段当前的图片列表。现算而不用 pictureDtoList:后者靠 attachments 的引用监听维护,
1757
+ * 删除(splice)、父组件直接改 file 数组都不会触发,拿到的可能是旧列表。
1758
+ * previewGroup.js 汇总整表图片时也会调用它。
1759
+ */
1760
+ getPreviewPictureList() {
1761
+ let list = [];
1762
+ (this.attachments || []).forEach((item) => {
1763
+ if (this.isPictureAttachment(item)) {
1764
+ list.push(item);
1673
1765
  }
1674
- return index == i;
1675
1766
  });
1676
- this.chooseIndex = pictureIndex;
1767
+ return list;
1768
+ },
1769
+ openImagePreView(index) {
1770
+ let pictures = this.getPreviewPictureList();
1771
+ // 点中的图片在本字段图片里的下标 = 它前面有几张图片
1772
+ let pictureIndex = 0;
1773
+ for (let i = 0; i < index; i++) {
1774
+ if (this.isPictureAttachment(this.attachments[i])) {
1775
+ pictureIndex++;
1776
+ }
1777
+ }
1778
+ // 上一张 / 下一张要能翻遍整个表单,列表拼的是同组所有字段的图片
1779
+ let { list, offset } = collectPreviewList(this, pictures);
1780
+ this.previewList = list;
1781
+ this.chooseIndex = offset + pictureIndex;
1677
1782
  this.showViewer = true;
1678
1783
  },
1679
1784
  openPropertiesDialog(attachment) {
@@ -1682,6 +1787,8 @@ tViewMixins = {
1682
1787
  },
1683
1788
  closeViewer() {
1684
1789
  this.showViewer = false;
1790
+ // 列表里可能持有别的字段的附件对象,关掉就释放
1791
+ this.previewList = [];
1685
1792
  },
1686
1793
  hasPreview(attachment) {
1687
1794
  let fileServerPreviewEnabled = this.getFileServerPreviewEnabled();
@@ -1712,9 +1819,42 @@ tViewMixins = {
1712
1819
  fileServerPreviewEnabled &&
1713
1820
  this.$commonFileUtil.isPreviewFile(url)
1714
1821
  ) {
1715
- this.$openFilePreview(url);
1822
+ /* 非图片文件:PC 走 $openFilePreview —— 它拿到预览地址后是 openInNewTab
1823
+ (见 utils/vab.js),在 H5 上等于跳出应用、返回全靠浏览器后退,体验断裂。
1824
+ H5 改成本组件内的全屏弹框套 iframe。开关由宿主传 h5Preview(xform 的
1825
+ vabUpload-widget 按 formConfig.layoutType === 'H5' 给),不传则维持原样。 */
1826
+ if (this.$attrs.h5Preview === true || this.$attrs.h5Preview === "true") {
1827
+ this.openFilePreviewDialog(url, this.getAttachmentName(attachment));
1828
+ } else {
1829
+ this.$openFilePreview(url);
1830
+ }
1716
1831
  }
1717
1832
  },
1833
+ /**
1834
+ * H5 的非图片文件预览:取预览地址后用弹框里的 iframe 承载。
1835
+ * 取址接口与 $openFilePreview 完全一致,只是不跳新标签页。
1836
+ */
1837
+ openFilePreviewDialog(url, name) {
1838
+ let fileSuffix = this.$commonFileUtil.getFileSuffix(url);
1839
+ if (!this.$commonFileUtil.isPreviewFile(url)) {
1840
+ return;
1841
+ }
1842
+ this.$http({
1843
+ url: USER_PREFIX + "/sf_common/getFilePreviewUrl",
1844
+ method: "post",
1845
+ data: {
1846
+ url: url,
1847
+ },
1848
+ isLoading: true,
1849
+ success: (res) => {
1850
+ if (!res.objx) return;
1851
+ this.previewFileUrl = res.objx;
1852
+ // 名字取不到就退回后缀,别让标题栏空着
1853
+ this.previewFileName = name || fileSuffix || "";
1854
+ this.showFilePreviewDialog = true;
1855
+ },
1856
+ });
1857
+ },
1718
1858
  getAttachmentName(attachment) {
1719
1859
  let name = null;
1720
1860
  let typeStr = Object.prototype.toString.call(attachment);
@@ -0,0 +1,128 @@
1
+ /**
2
+ * 附件图片预览分组
3
+ *
4
+ * 单个附件字段(baseUpload)只持有自己的图片,预览弹框的「上一张 / 下一张」原先也只能在
5
+ * 本字段内翻页。这里维护一份已挂载 baseUpload 实例的登记表:打开预览时把同一表单范围内
6
+ * 的所有图片按 DOM 顺序拼成一个列表交给 el-image-viewer,翻页于是能跨字段覆盖整个表单。
7
+ *
8
+ * 分组范围 = 从自身向上找到的第一个「边界元素」(见 SCOPE_SELECTOR)。弹框 / 抽屉 / 表单
9
+ * 都算边界,保证背景页面的图片不会串进弹框的预览里,明细表编辑行里的附件也只跟同一行翻页。
10
+ *
11
+ * 组件上可用 preview-group 覆盖:
12
+ * preview-group="xxx" 给同一字符串的实例强制同组(可跨边界)
13
+ * :preview-group="false" 退回只翻本字段(旧行为)
14
+ */
15
+
16
+ // 已挂载的 baseUpload 实例。组件 mounted 时登记、beforeDestroy 时注销
17
+ const instances = new Set();
18
+
19
+ // 分组边界:弹框、抽屉、表单
20
+ const SCOPE_SELECTOR = ".el-dialog,.el-drawer,.el-form,form";
21
+
22
+ export function registerPreviewInstance(vm) {
23
+ instances.add(vm);
24
+ }
25
+
26
+ export function unregisterPreviewInstance(vm) {
27
+ instances.delete(vm);
28
+ }
29
+
30
+ // 模板里写 preview-group 与 previewGroup 落到 $attrs 的 key 不同,两个都认
31
+ function readGroupAttr(vm) {
32
+ let attrs = (vm && vm.$attrs) || {};
33
+ return attrs.previewGroup !== undefined
34
+ ? attrs.previewGroup
35
+ : attrs["preview-group"];
36
+ }
37
+
38
+ function isGroupEnabled(vm) {
39
+ let value = readGroupAttr(vm);
40
+ return value !== false && value !== "false";
41
+ }
42
+
43
+ function getScope(vm) {
44
+ let group = readGroupAttr(vm);
45
+ // 显式指定的分组名优先,此时不再看 DOM 位置
46
+ if (typeof group === "string") {
47
+ let name = group.trim();
48
+ if (name && name !== "true" && name !== "false") return name;
49
+ }
50
+ let el = vm.$el;
51
+ while (el && el.nodeType === 1) {
52
+ if (el.matches && el.matches(SCOPE_SELECTOR)) {
53
+ return el;
54
+ }
55
+ el = el.parentElement;
56
+ }
57
+ return (vm.$el && vm.$el.ownerDocument.body) || null;
58
+ }
59
+
60
+ /**
61
+ * 隐藏的实例不参与分组:看不见的图片(未激活的页签、折叠面板)混进来翻页只会莫名其妙。
62
+ * 不用 getClientRects / offsetParent 判定——jsdom 没有排版,那两个恒为空。
63
+ */
64
+ function isHidden(el) {
65
+ if (!el || el.nodeType !== 1 || el.isConnected === false) return true;
66
+ let view = el.ownerDocument && el.ownerDocument.defaultView;
67
+ if (!view || !view.getComputedStyle) return false;
68
+ let node = el;
69
+ while (node && node.nodeType === 1) {
70
+ let style = view.getComputedStyle(node);
71
+ if (style && (style.display === "none" || style.visibility === "hidden")) {
72
+ return true;
73
+ }
74
+ node = node.parentElement;
75
+ }
76
+ return false;
77
+ }
78
+
79
+ function compareDomOrder(a, b) {
80
+ if (a === b) return 0;
81
+ let relation = a.compareDocumentPosition(b);
82
+ // 2 = DOCUMENT_POSITION_PRECEDING, 4 = DOCUMENT_POSITION_FOLLOWING
83
+ if (relation & 4) return -1;
84
+ if (relation & 2) return 1;
85
+ return 0;
86
+ }
87
+
88
+ function getPictures(vm) {
89
+ if (typeof vm.getPreviewPictureList !== "function") return [];
90
+ return vm.getPreviewPictureList() || [];
91
+ }
92
+
93
+ /**
94
+ * 汇总 vm 所在分组的图片列表
95
+ * @param {Object} vm 触发预览的 baseUpload 实例
96
+ * @param {Array} ownList vm 自己的图片列表(调用方已算好,避免重复计算)
97
+ * @returns {{list: Array, offset: Number}} 拼接后的列表与 vm 自己的图片在其中的起始下标
98
+ */
99
+ export function collectPreviewList(vm, ownList) {
100
+ let own = ownList || [];
101
+ if (!isGroupEnabled(vm)) {
102
+ return { list: own, offset: 0 };
103
+ }
104
+ let scope = getScope(vm);
105
+ let members = [];
106
+ instances.forEach((item) => {
107
+ if (item === vm || !item.$el) return;
108
+ if (!isGroupEnabled(item)) return;
109
+ if (getScope(item) !== scope) return;
110
+ if (isHidden(item.$el)) return;
111
+ members.push(item);
112
+ });
113
+ members.push(vm);
114
+ members.sort((a, b) => compareDomOrder(a.$el, b.$el));
115
+
116
+ let list = [];
117
+ let offset = 0;
118
+ members.forEach((item) => {
119
+ let pictures = item === vm ? own : getPictures(item);
120
+ if (item === vm) {
121
+ offset = list.length;
122
+ }
123
+ if (pictures.length) {
124
+ list = list.concat(pictures);
125
+ }
126
+ });
127
+ return { list, offset };
128
+ }