cloud-web-corejs 1.1.0-dev.27 → 1.1.0-dev.29

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 (171) hide show
  1. package/package.json +4 -11
  2. package/src/components/table/index.js +3 -0
  3. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +18 -1
  4. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +33 -20
  5. package/src/components/xform/form-render/container-item/data-table-mixin.js +16 -8
  6. package/src/components/xform/form-render/container-item/list-h5-item.vue +92 -309
  7. package/src/components/xform/mixins/scriptHttp.js +1 -1
  8. package/src/components/xform/utils/util.js +20 -0
  9. package/src/views/demo/bizTab/bill/billConfig.js +41 -0
  10. package/src/views/demo/bizTab/bill/detail.vue +436 -0
  11. package/src/views/demo/bizTab/bill/list.vue +288 -0
  12. package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
  13. package/src/views/demo/bizTab/simple/billApi.js +123 -0
  14. package/src/views/demo/bizTab/simple/detail.vue +407 -0
  15. package/src/views/demo/bizTab/simple/list.vue +217 -0
  16. package/src/views/demo/bizTab/standalone/index.vue +121 -0
  17. package/src/views/demo/bizTab/wf/billConfig.js +44 -0
  18. package/src/views/demo/bizTab/wf/detail.vue +661 -0
  19. package/src/views/demo/bizTab/wf/list.vue +242 -0
  20. package/src/app-bootstrap.js +0 -523
  21. package/src/boot-assets.legacy.js +0 -7
  22. package/src/boot-assets.next.js +0 -7
  23. package/src/core-resources/css/h5.scss +0 -548
  24. package/src/core-resources/css/iconfont.css +0 -1447
  25. package/src/core-resources/font/iconfont.ttf +0 -0
  26. package/src/core-resources/font/iconfont.woff +0 -0
  27. package/src/core-resources/font/iconfont.woff2 +0 -0
  28. package/src/core-resources/images/default-header.png +0 -0
  29. package/src/core-resources/images/ico-default_wenjian.svg +0 -1
  30. package/src/core-resources/images/ico-excel.svg +0 -1
  31. package/src/core-resources/images/ico-ftl.svg +0 -7
  32. package/src/core-resources/images/ico-html.svg +0 -1
  33. package/src/core-resources/images/ico-java.svg +0 -1
  34. package/src/core-resources/images/ico-music.svg +0 -1
  35. package/src/core-resources/images/ico-pdf.svg +0 -1
  36. package/src/core-resources/images/ico-photo.svg +0 -1
  37. package/src/core-resources/images/ico-ppt.svg +0 -1
  38. package/src/core-resources/images/ico-psd.svg +0 -1
  39. package/src/core-resources/images/ico-service.png +0 -0
  40. package/src/core-resources/images/ico-txt.svg +0 -1
  41. package/src/core-resources/images/ico-video.svg +0 -1
  42. package/src/core-resources/images/ico-vue.svg +0 -8
  43. package/src/core-resources/images/ico-wenjianjia.svg +0 -1
  44. package/src/core-resources/images/ico-wrod.svg +0 -1
  45. package/src/core-resources/images/ico-xml.svg +0 -1
  46. package/src/core-resources/images/ico-yasuobao.svg +0 -1
  47. package/src/core-resources/images/icon-error.png +0 -0
  48. package/src/core-resources/images/icon-tips.png +0 -0
  49. package/src/core-resources/images/nodata.png +0 -0
  50. package/src/core-resources/images/nodata2.png +0 -0
  51. package/src/core-resources/js/base/common.js +0 -110
  52. package/src/icons/index.js +0 -9
  53. package/src/icons/svg/404.svg +0 -1
  54. package/src/icons/svg/alert.svg +0 -1
  55. package/src/icons/svg/bug.svg +0 -1
  56. package/src/icons/svg/button.svg +0 -1
  57. package/src/icons/svg/card.svg +0 -1
  58. package/src/icons/svg/cascader-field.svg +0 -1
  59. package/src/icons/svg/census.svg +0 -1
  60. package/src/icons/svg/chart.svg +0 -1
  61. package/src/icons/svg/checkbox-field.svg +0 -1
  62. package/src/icons/svg/clipboard.svg +0 -1
  63. package/src/icons/svg/color-field.svg +0 -1
  64. package/src/icons/svg/component.svg +0 -1
  65. package/src/icons/svg/custom-component.svg +0 -1
  66. package/src/icons/svg/dashboard.svg +0 -1
  67. package/src/icons/svg/data-table.svg +0 -1
  68. package/src/icons/svg/date-field.svg +0 -1
  69. package/src/icons/svg/date-range-field.svg +0 -1
  70. package/src/icons/svg/descriptions.svg +0 -1
  71. package/src/icons/svg/divider.svg +0 -1
  72. package/src/icons/svg/document.svg +0 -1
  73. package/src/icons/svg/documentation.svg +0 -1
  74. package/src/icons/svg/drag.svg +0 -1
  75. package/src/icons/svg/echart-category.svg +0 -1
  76. package/src/icons/svg/echart-pie.svg +0 -1
  77. package/src/icons/svg/echart.svg +0 -1
  78. package/src/icons/svg/edit.svg +0 -1
  79. package/src/icons/svg/education.svg +0 -1
  80. package/src/icons/svg/email.svg +0 -1
  81. package/src/icons/svg/example.svg +0 -1
  82. package/src/icons/svg/excel.svg +0 -1
  83. package/src/icons/svg/exit-fullscreen.svg +0 -1
  84. package/src/icons/svg/eye-open.svg +0 -1
  85. package/src/icons/svg/eye.svg +0 -1
  86. package/src/icons/svg/file-upload-field.svg +0 -1
  87. package/src/icons/svg/form.svg +0 -1
  88. package/src/icons/svg/fullscreen.svg +0 -1
  89. package/src/icons/svg/github.svg +0 -1
  90. package/src/icons/svg/grid.svg +0 -1
  91. package/src/icons/svg/guide.svg +0 -1
  92. package/src/icons/svg/html-text.svg +0 -1
  93. package/src/icons/svg/ico-more.svg +0 -1
  94. package/src/icons/svg/ico-wenjianjia.svg +0 -1
  95. package/src/icons/svg/icon.svg +0 -1
  96. package/src/icons/svg/input-batch.svg +0 -1
  97. package/src/icons/svg/international.svg +0 -1
  98. package/src/icons/svg/language.svg +0 -1
  99. package/src/icons/svg/link.svg +0 -1
  100. package/src/icons/svg/list-export.svg +0 -1
  101. package/src/icons/svg/list.svg +0 -1
  102. package/src/icons/svg/lock.svg +0 -1
  103. package/src/icons/svg/message.svg +0 -1
  104. package/src/icons/svg/money.svg +0 -1
  105. package/src/icons/svg/nested.svg +0 -1
  106. package/src/icons/svg/news-list.svg +0 -1
  107. package/src/icons/svg/node-tree.svg +0 -1
  108. package/src/icons/svg/number-field.svg +0 -1
  109. package/src/icons/svg/password.svg +0 -1
  110. package/src/icons/svg/pdf.svg +0 -1
  111. package/src/icons/svg/people.svg +0 -1
  112. package/src/icons/svg/peoples.svg +0 -1
  113. package/src/icons/svg/picture-upload-field.svg +0 -1
  114. package/src/icons/svg/qq.svg +0 -1
  115. package/src/icons/svg/query.svg +0 -1
  116. package/src/icons/svg/radio-field.svg +0 -1
  117. package/src/icons/svg/rate-field.svg +0 -1
  118. package/src/icons/svg/redo.svg +0 -1
  119. package/src/icons/svg/rich-editor-field.svg +0 -1
  120. package/src/icons/svg/search.svg +0 -1
  121. package/src/icons/svg/searchbox.svg +0 -1
  122. package/src/icons/svg/section.svg +0 -1
  123. package/src/icons/svg/select-field.svg +0 -1
  124. package/src/icons/svg/shopping.svg +0 -1
  125. package/src/icons/svg/size.svg +0 -1
  126. package/src/icons/svg/skill.svg +0 -1
  127. package/src/icons/svg/slider-field.svg +0 -1
  128. package/src/icons/svg/slot-component.svg +0 -1
  129. package/src/icons/svg/slot-field.svg +0 -1
  130. package/src/icons/svg/star.svg +0 -1
  131. package/src/icons/svg/static-text.svg +0 -1
  132. package/src/icons/svg/status.svg +0 -1
  133. package/src/icons/svg/sub-form.svg +0 -1
  134. package/src/icons/svg/switch-field.svg +0 -1
  135. package/src/icons/svg/tab.svg +0 -1
  136. package/src/icons/svg/table.svg +0 -1
  137. package/src/icons/svg/text-field.svg +0 -1
  138. package/src/icons/svg/text.svg +0 -1
  139. package/src/icons/svg/textarea-field.svg +0 -1
  140. package/src/icons/svg/theme.svg +0 -1
  141. package/src/icons/svg/time-field.svg +0 -1
  142. package/src/icons/svg/time-range-field.svg +0 -1
  143. package/src/icons/svg/tips-text.svg +0 -1
  144. package/src/icons/svg/title-head.svg +0 -1
  145. package/src/icons/svg/tree-pane.svg +0 -1
  146. package/src/icons/svg/tree-table.svg +0 -1
  147. package/src/icons/svg/tree.svg +0 -1
  148. package/src/icons/svg/undo.svg +0 -1
  149. package/src/icons/svg/uploadbox.svg +0 -1
  150. package/src/icons/svg/user.svg +0 -1
  151. package/src/icons/svg/vf-box.svg +0 -1
  152. package/src/icons/svg/vf-dialog.svg +0 -1
  153. package/src/icons/svg/vf-drawer.svg +0 -1
  154. package/src/icons/svg/vue-sfc.svg +0 -1
  155. package/src/icons/svg/wechat.svg +0 -1
  156. package/src/icons/svg/zip.svg +0 -1
  157. package/src/index.next.js +0 -5
  158. package/src/styles/btn.scss +0 -104
  159. package/src/styles/element-ui.scss +0 -155
  160. package/src/styles/element-variables.scss +0 -31
  161. package/src/styles/global.scss +0 -115
  162. package/src/styles/index.scss +0 -200
  163. package/src/styles/menu-icons.scss +0 -75
  164. package/src/styles/mixin.scss +0 -72
  165. package/src/styles/nprogress.scss +0 -14
  166. package/src/styles/sidebar.scss +0 -281
  167. package/src/styles/split-handle.scss +0 -52
  168. package/src/styles/theme-variables.scss +0 -7
  169. package/src/styles/transition.scss +0 -48
  170. package/src/styles/utilities.scss +0 -137
  171. package/src/styles/variables.scss +0 -44
@@ -67,25 +67,19 @@
67
67
  </div>
68
68
  <div class="h5-list-box">
69
69
  <div
70
- v-for="(row, rowIndex) in visibleRows"
70
+ v-for="(row, rowIndex) in fieldModel"
71
71
  :key="rowIndex"
72
72
  class="item"
73
- @click="onRowClick(row)"
74
- :class="[
75
- { checked: checkItemIds.includes(row.id) },
76
- itemCardClass,
77
- getRowCompareClass(row),
78
- ]"
73
+ @click="itemCheck(row)"
74
+ :class="{ checked: checkItemIds.includes(row.id) }"
79
75
  >
80
- <!-- 右上角查看角标(对齐 bill_setting 的 .pro-item .t::after)。
81
- 与 itemStyle 解绑:点整行进详情是明细行的统一行为,
82
- 这个角标是它的视觉提示,不该藏在选项后面。
83
- 查询选择场景点行是勾选、不进详情,故不显示。 -->
84
- <i class="h5-item-arrow" v-if="!widget.options.isQueryTable"></i>
85
- <!-- 明细行不放删除按钮:点击整行进详情即可。
86
- 要恢复的话,除了放回这个 div,还得给它补流程判断
87
- (有流程且当前节点不可编辑时要藏掉),它不是 widget,
88
- 拿不到 hiddenByWf / widgetShowRule 那两套。 -->
76
+ <div
77
+ v-if="!widget.options.isQueryTable"
78
+ class="del-btn"
79
+ @click.stop="deleteRow(row, rowIndex)"
80
+ >
81
+ <i class="el-icon-delete"></i>
82
+ </div>
89
83
  <template v-if="vxeOption.columns.length > 0">
90
84
  <div class="t1" v-if="widget.options.isQueryTable">
91
85
  <template
@@ -111,12 +105,7 @@
111
105
  <template
112
106
  v-else-if="column.slots && column.slots.default == 'widget'"
113
107
  >
114
- <!-- 临时只读:只出选中文本;关掉 H5_TEMP_READ_ONLY 后仍走下面的控件 -->
115
- <template v-if="getReadMode()">
116
- {{ getColumnDisplayText(column, row, rowIndex) }}
117
- </template>
118
108
  <component
119
- v-else
120
109
  :is="getColumnWidgetName(column.params.widget)"
121
110
  :field="column.params.widget"
122
111
  :form-model="globalModel.formModel"
@@ -190,14 +179,6 @@
190
179
  <!-- <div class="status">未审核</div>-->
191
180
  </template>
192
181
  </div>
193
- <!-- 明细卡片的主标题,对齐 bill_setting 的 .pro-item .t(render.vue:105):
194
- 只出主字段的值、前面一个圆点、右上角是「查看」角标。
195
- 上面那个 .t1 是查询选择列表专用的(出「标题:值」若干对),两者互斥。
196
- 主字段就是 isMainFiled 标的那一列(columns() 里取第一个可见列),
197
- 查询选择模式一直用它当标题行,这里把同一口径用到明细卡片上。 -->
198
- <div class="t1 h5-item-title" v-else-if="!!mainTitleColumn">
199
- <b>{{ getColumnDisplayText(mainTitleColumn, row, rowIndex) }}</b>
200
- </div>
201
182
  <div class="t2">
202
183
  <template
203
184
  v-if="
@@ -205,19 +186,13 @@
205
186
  "
206
187
  >
207
188
  <template v-for="(column, columnIndex) in vxeOption.columns">
208
- <!-- 主字段已经当标题了,不再在字段区重复一遍(查询选择模式本来
209
- 就是这个口径,这里两种模式统一)。没有主标题时(mainTitleColumn
210
- 为空,如只有一列)照常全出。 -->
211
189
  <template
212
190
  v-if="
213
- (!column.isMainFiled || !mainTitleColumn) &&
191
+ (!widget.options.isQueryTable || !column.isMainFiled) &&
214
192
  column.showForRow
215
193
  "
216
194
  >
217
- <!-- m2 = 半行(一行两个)。类名沿用 style.scss:14095 早就留好的
218
- `.t2 > dl.m2{width:50%}`(那条规则一直没人往 dl 上打过类)。
219
- 由列的「H5列宽」选项控制,见 isHalfColumn。 -->
220
- <dl :key="columnIndex" :class="{ m2: isHalfColumn(column) }">
195
+ <dl :key="columnIndex">
221
196
  <div>
222
197
  <dt>{{ column.title }}:</dt>
223
198
  <dd>
@@ -235,11 +210,6 @@
235
210
  }}
236
211
  </template>
237
212
 
238
- <!-- 临时只读:行上只出选中文本。控件/操作链接不能删,
239
- 关掉 H5_TEMP_READ_ONLY 后仍要能编辑。 -->
240
- <template v-else-if="getReadMode()">
241
- {{ getColumnDisplayText(column, row, rowIndex) }}
242
- </template>
243
213
  <template
244
214
  v-else-if="
245
215
  column.slots && column.slots.default == 'widget'
@@ -276,7 +246,7 @@
276
246
  <a
277
247
  href="javascript:void(0);"
278
248
  class="a-link"
279
- @click="deleteRow(row, rowIndex)"
249
+ @click.stop="deleteRow(row, rowIndex)"
280
250
  >
281
251
  <el-tooltip
282
252
  :enterable="false"
@@ -326,9 +296,12 @@
326
296
  </template>
327
297
  </template>
328
298
  </div>
329
- <!-- 明细行不摆操作按钮区:点整行进详情。查询选择场景(isQueryTable)
330
- 仍保留行按钮,那边点行是勾选、按钮另有用途。 -->
331
- <div class="btns" v-if="widget.options.isQueryTable">
299
+ <div class="btns">
300
+ <!-- <div class="checkbox_fl">
301
+ <el-checkbox></el-checkbox>
302
+ </div> -->
303
+ <!-- <a class="btn"><i class="el-icon-delete"/><span>删除</span></a>
304
+ <a class="btn"><i class="el-icon-edit"/><span>查看</span></a>-->
332
305
  <template
333
306
  v-if="!!widget.lineButtons && widget.lineButtons.length > 0"
334
307
  >
@@ -397,27 +370,6 @@
397
370
  <p>产地:广东佛山</p>
398
371
  </div>-->
399
372
  </div>
400
- <!-- 折叠尾行:详情里挂的明细列表默认只出 H5_LIST_COLLAPSE_SIZE 条,
401
- 「更多(N)」展开全部、「收起」折回去,同一行来回切。
402
- 显示条件用 collapseTogglable 而不是 collapsedRest —— 展开后 collapsedRest
403
- 是 0,用它当条件的话「收起」会连同尾行一起消失,就折不回去了。
404
- 摆在 .h5-list-box 里当最后一个子元素,跟着它的内边距与卡片对齐。
405
- 样式见 styles/h5.scss 块 I4。 -->
406
- <div
407
- class="h5-list-more"
408
- v-if="collapseTogglable"
409
- @click="toggleAllRows"
410
- >
411
- <template v-if="showAllRows">
412
- <span>{{ $t1("收起") }}</span>
413
- <i class="el-icon-arrow-up"></i>
414
- </template>
415
- <template v-else>
416
- <span>{{ $t1("更多") }}</span>
417
- <span class="h5-list-more-count">({{ collapsedRest }})</span>
418
- <i class="el-icon-arrow-down"></i>
419
- </template>
420
- </div>
421
373
  </div>
422
374
  <div class="vxe-grid" v-if="widget.options.isQueryTable">
423
375
  <div class="vxe-grid&#45;&#45;pager-wrapper">
@@ -482,7 +434,6 @@
482
434
  top="0px"
483
435
  v-el-drag-dialog
484
436
  v-el-dialog-center
485
- :append-to-body ="true"
486
437
  :destroy-on-close="true"
487
438
  >
488
439
  <div class="cont" style="height: calc(100vh - 73px)">
@@ -604,10 +555,7 @@
604
555
  <template
605
556
  v-if="!widget.options.isQueryTable || !column.isMainFiled"
606
557
  >
607
- <!-- 与列表卡片同口径:列配了 H5列宽=半行 时打 m2。
608
- 弹框 append-to-body,样式挂在 .el-dialog.h5view-dialog,
609
- 见 styles/h5.scss。 -->
610
- <dl :key="columnIndex" :class="{ m2: isHalfColumn(column) }">
558
+ <dl>
611
559
  <div>
612
560
  <dt>{{ column.title }}:</dt>
613
561
  <dd>
@@ -713,9 +661,63 @@
713
661
  </template>
714
662
  </template>
715
663
  </div>
716
- <!-- 明细详情弹框里不摆行操作按钮区:行按钮(lineButtons)属于列表行的
717
- 操作,详情里用不上;容器本身带 border-top 和 padding,即使按钮被
718
- wf 联动隐藏了也会留下一条空白横条。关闭走右上角的 X。 -->
664
+ <div class="btns">
665
+ <template
666
+ v-if="!!widget.lineButtons && widget.lineButtons.length > 0"
667
+ >
668
+ <template v-for="(subWidget, swIdx) in widget.lineButtons">
669
+ <template v-if="'container' === subWidget.category">
670
+ <component
671
+ :is="subWidget.type + '-item'"
672
+ :widget="subWidget"
673
+ :key="swIdx"
674
+ :parent-list="widget.lineButtons"
675
+ :index-of-parent-list="swIdx"
676
+ :parent-widget="widget"
677
+ :subFormRowIndex="rowIndex"
678
+ :tableParam="{
679
+ rowIndex: rowIndex,
680
+ row: row,
681
+ items: fieldModel,
682
+ }"
683
+ >
684
+ <!-- 递归传递插槽!!! -->
685
+ <template
686
+ v-for="slot in Object.keys($scopedSlots)"
687
+ v-slot:[slot]="scope"
688
+ >
689
+ <slot :name="slot" v-bind="scope" />
690
+ </template>
691
+ </component>
692
+ </template>
693
+ <template v-else>
694
+ <component
695
+ :is="subWidget.type + '-widget'"
696
+ :field="subWidget"
697
+ :designer="null"
698
+ :key="swIdx"
699
+ :parent-list="widget.lineButtons"
700
+ :index-of-parent-list="swIdx"
701
+ :parent-widget="widget"
702
+ :subFormRowIndex="rowIndex"
703
+ :tableParam="{
704
+ rowIndex: rowIndex,
705
+ row: row,
706
+ items: fieldModel,
707
+ }"
708
+ >
709
+ <!-- 递归传递插槽!!! -->
710
+ <template
711
+ v-for="slot in Object.keys($scopedSlots)"
712
+ v-slot:[slot]="scope"
713
+ >
714
+ <slot :name="slot" v-bind="scope" />
715
+ </template>
716
+ </component>
717
+ </template>
718
+ </template>
719
+ </template>
720
+ </div>
719
721
  </template>
720
722
 
721
723
  <!-- <div class="t1">
@@ -730,16 +732,6 @@
730
732
  </div>
731
733
  </div>
732
734
  </div>
733
- <span slot="footer" class="dialog-footer">
734
- <el-button
735
- type="primary"
736
- plain
737
- class="button-sty"
738
- icon="el-icon-close"
739
- @click="showRowDetailDialog = false"
740
- >{{ $t1("关闭") }}</el-button
741
- >
742
- </span>
743
735
  </el-dialog>
744
736
  </container-item-wrapper>
745
737
  </template>
@@ -776,11 +768,6 @@ const baseRefUtil = {
776
768
  };
777
769
 
778
770
  const defaultPageSize = 2;
779
-
780
- /* H5 详情里挂的明细列表,折叠态露出的行数。
781
- 写死而不做成表单选项:与 detail-h5-item 的 H5_BOTTOM_MAX_BUTTONS 同理 ——
782
- 做成 options 后,已保存的表单会锁住旧值,改原型默认值不生效,反成绊脚石。 */
783
- const H5_LIST_COLLAPSE_SIZE = 5;
784
771
  export default {
785
772
  name: "list-h5-item",
786
773
  components: {
@@ -812,7 +799,6 @@ export default {
812
799
  "globalModel",
813
800
  "getFormConfig",
814
801
  "getGlobalDsv",
815
- "getReadMode",
816
802
  ],
817
803
  data: function () {
818
804
  let that = this;
@@ -856,29 +842,17 @@ export default {
856
842
  keyword: null,
857
843
 
858
844
  checkItemIds: [],
859
- /* 「更多」是否点过。折叠只在详情里挂的明细列表上生效,见 collapsible */
860
- showAllRows: false,
861
845
  };
862
846
  },
863
847
  watch: {
864
848
  fieldModel(val) {
865
849
  this.formModel[this.fieldKeyName] = val || [];
866
- /* 换了一整批数据(setValue / 重新取数)就退回折叠态。
867
- push 追加行不会触发这里,那条路径由 addTableData 自己展开。 */
868
- this.showAllRows = false;
869
850
  },
870
851
  },
871
852
  computed: {
872
853
  formConfig: function () {
873
854
  return this.getFormConfig();
874
855
  },
875
- /**
876
- * 明细行卡片样式开关。只判 === 'card':老表单该 option 为 null/undefined
877
- * (upgradeWidgetConfig 补的是 null,运行时读不到这个键),必须退回朴素列表。
878
- */
879
- itemCardClass: function () {
880
- return this.widget.options.itemStyle === "card" ? "h5-item-card" : "";
881
- },
882
856
  paginationLayout: function () {
883
857
  return this.widget.options.smallPagination
884
858
  ? "prev, pager, next"
@@ -896,60 +870,6 @@ export default {
896
870
  : !!this.widget.options.buttonsColumnFixed &&
897
871
  this.widget.options.buttonsColumnFixed;
898
872
  },
899
- /**
900
- * 明细卡片主标题所用的列(对齐 bill_setting 的 mainFieldName)。
901
- *
902
- * 主字段就是 columns() 里标了 isMainFiled 的那一列 —— 第一个既有 prop
903
- * 又 showForRow 的列,不是另配的选项。查询选择列表一直拿它当标题行,
904
- * 这里把同一口径用到明细卡片上。
905
- *
906
- * 返回值同时决定字段区要不要把主字段排除掉(模板里那个 v-if)。
907
- */
908
- mainTitleColumn() {
909
- let visible = (this.vxeOption.columns || []).filter(
910
- (column) => column.showForRow
911
- );
912
- let main = visible.find((column) => column.isMainFiled) || null;
913
- if (!main) return null;
914
- // 查询选择模式的标题行是另一个 .t1,与可见列数无关,一直排除主字段,保持原口径
915
- if (this.widget.options.isQueryTable) return main;
916
- // 明细卡片:只有一列时不抽标题 —— 抽走字段区就空了,不如照常当字段出
917
- return visible.length < 2 ? null : main;
918
- },
919
- /**
920
- * 是否走折叠(默认只出 H5_LIST_COLLAPSE_SIZE 条 + 「更多」尾行)。
921
- * 两个条件缺一不可,见 isInDetailH5 与下面这条:
922
- * 查询选择列表(isQueryTable)是整屏选数据用的、自己带分页器,再截断会跟分页打架。
923
- */
924
- collapsible() {
925
- return !this.widget.options.isQueryTable && this.isInDetailH5();
926
- },
927
- /**
928
- * 尾行(「更多 / 收起」)要不要出:够不着折叠线就不出,够着了就一直在 ——
929
- * 展开态也要留着,那是「收起」的入口。
930
- */
931
- collapseTogglable() {
932
- let total = (this.fieldModel || []).length;
933
- return this.collapsible && total > H5_LIST_COLLAPSE_SIZE;
934
- },
935
- /* 折起来没露出的行数,即「更多」后面括号里那个数 */
936
- collapsedRest() {
937
- if (!this.collapsible || this.showAllRows) return 0;
938
- let total = (this.fieldModel || []).length;
939
- return total > H5_LIST_COLLAPSE_SIZE ? total - H5_LIST_COLLAPSE_SIZE : 0;
940
- },
941
- /**
942
- * 真正渲染的行。
943
- * ★ 只能从头切:rowIndex 在模板里同时当 subFormRowIndex / formItemProp 的下标
944
- * (行内控件靠它定位 formModel 里的那一行)和 deleteRow 的下标,从头切时它与
945
- * fieldModel 的下标恒等,不必再做一层映射。
946
- * 传给格式化函数的 items 仍是整份 fieldModel(模板里没改),那是数据不是视图。
947
- */
948
- visibleRows() {
949
- let rows = this.fieldModel || [];
950
- if (this.collapsedRest <= 0) return rows;
951
- return rows.slice(0, H5_LIST_COLLAPSE_SIZE);
952
- },
953
873
  columns() {
954
874
  let tableColumns = this.widget.options.tableColumns;
955
875
  let newColumns = [];
@@ -985,8 +905,7 @@ export default {
985
905
  fixed: !!t.fixed && t.fixed,
986
906
  field: t.prop,
987
907
  title: t.label,
988
- // 原来这里还有一个 `witdh: t.width` —— 键名拼错(w-i-t-d-h)、全库无人读取,
989
- // 且 H5 卡片是 dl/dt/dd 排版本来就不吃列宽。列配置里的「列宽」已一并去掉。
908
+ witdh: t.width,
990
909
  sortable: t.sortable,
991
910
  align: t.align ? t.align : "center",
992
911
  formatter: this.formatterValue,
@@ -1077,37 +996,6 @@ export default {
1077
996
  this.unregisterFromRefList();
1078
997
  },
1079
998
  methods: {
1080
- /**
1081
- * 是否挂在 H5 详情容器里 —— 折叠只对这种场景生效:list-h5 也能当整屏列表用,
1082
- * 整屏的不该只出 5 条。
1083
- *
1084
- * 沿父链找 detail-h5-item,中间隔着 transition-group / 卡片容器都无所谓;
1085
- * 遇到弹框/抽屉容器就停 —— 弹框里那份是独立的一屏,不算详情里挂的明细。
1086
- * 结果缓存在非响应式实例属性上:父链在实例生命周期内不变,而 collapsible
1087
- * 是渲染期求值的 computed,不能每次都走一遍链。
1088
- */
1089
- isInDetailH5() {
1090
- if (this._inDetailH5 === undefined) {
1091
- this._inDetailH5 = false;
1092
- let vm = this.$parent;
1093
- while (vm) {
1094
- let name = vm.$options.name;
1095
- if (name === "vf-dialog-item" || name === "vf-drawer-item") break;
1096
- if (name === "detail-h5-item") {
1097
- this._inDetailH5 = true;
1098
- break;
1099
- }
1100
- vm = vm.$parent;
1101
- }
1102
- }
1103
- return this._inDetailH5;
1104
- },
1105
- /* 尾行的开关:「更多」展开全部、「收起」折回前 H5_LIST_COLLAPSE_SIZE 条。
1106
- 折回时不动任何数据,只切视图 —— 行下标始终是 fieldModel 的下标(见 visibleRows)。
1107
- 重新取数时 watch 会自动退回折叠态。 */
1108
- toggleAllRows() {
1109
- this.showAllRows = !this.showAllRows;
1110
- },
1111
999
  openAdvancedSearchDialog() {
1112
1000
  /*let formData = this.formModel;
1113
1001
  let advancedFormData = {};
@@ -1650,9 +1538,6 @@ export default {
1650
1538
  return newData;
1651
1539
  },
1652
1540
  addTableData(rows, field) {
1653
- if (this.getReadMode && this.getReadMode()) {
1654
- return;
1655
- }
1656
1541
  let formDataModel = this.formModel;
1657
1542
  let tableRows = this.fieldModel;
1658
1543
  let fullData = this.fieldModel;
@@ -1681,42 +1566,36 @@ export default {
1681
1566
  let newData = this.createNewTableData();
1682
1567
  tableRows.push(newData);
1683
1568
  }
1684
- /* 追加的行落在末尾,折叠态下会被藏住 —— 加完就展开。
1685
- 这里是 push 改数组,watch fieldModel 不触发,必须自己来。 */
1686
- this.showAllRows = true;
1687
1569
  // this.formModel[this.fieldKeyName] = this.$baseLodash(this.fieldModel)
1688
1570
  // this.fieldModel = tableRows
1689
1571
  // $grid.loadData(tableRows);
1690
1572
  },
1691
1573
  getColumnWidgetConfig(row) {
1692
1574
  let formRef = this.getFormRef();
1575
+ let formatS = row.formatS;
1693
1576
  let columnSelectedWidget = null;
1694
1577
  let columnEditFields = null;
1578
+
1695
1579
  let type = this.columnFormatMap[row.formatS];
1696
1580
 
1697
1581
  if (type) {
1698
- // 格式化配置写在 row.widget(含 optionItems);老数据才落在 columnOption。
1699
- // 不能每次从字段模板重建,否则下拉选项丢失,行上只能看到 value。
1700
- if (row.widget && row.widget.type) {
1701
- columnSelectedWidget = this.$baseLodash.cloneDeep(row.widget);
1582
+ columnSelectedWidget = this.$baseLodash.cloneDeep(
1583
+ formRef.getFieldWidgetByType(type)
1584
+ );
1585
+ let tmpId = generateId();
1586
+ let idVal = row.prop ? row.prop : type + tmpId;
1587
+ columnSelectedWidget.id = idVal;
1588
+ columnSelectedWidget.options.name = idVal;
1589
+ if (row.columnOption && Object.keys(row.columnOption).length) {
1590
+ row.columnOption.required = row.required || false;
1591
+ columnSelectedWidget.options = row.columnOption;
1702
1592
  } else {
1703
- columnSelectedWidget = this.$baseLodash.cloneDeep(
1704
- formRef.getFieldWidgetByType(type)
1705
- );
1706
- let tmpId = generateId();
1707
- let idVal = row.prop ? row.prop : type + tmpId;
1708
- columnSelectedWidget.id = idVal;
1709
- if (row.columnOption && Object.keys(row.columnOption).length) {
1710
- columnSelectedWidget.options = row.columnOption;
1711
- }
1712
- }
1713
- if (!columnSelectedWidget.options) {
1714
- columnSelectedWidget.options = {};
1593
+ columnSelectedWidget.options.required = row.required || false;
1594
+ row.columnOption = columnSelectedWidget.options;
1715
1595
  }
1716
1596
  columnSelectedWidget.options.name = row.prop;
1717
1597
  columnSelectedWidget.options.label = row.label;
1718
1598
  columnSelectedWidget.options.labelHidden = true;
1719
- columnSelectedWidget.options.required = row.required || false;
1720
1599
  }
1721
1600
  return { columnSelectedWidget, columnEditFields };
1722
1601
  },
@@ -1797,102 +1676,6 @@ export default {
1797
1676
  option.prefix = option.prefix || serverName;
1798
1677
  this.$excelExport({ targetRef: tableRef, ...option });
1799
1678
  },
1800
- /**
1801
- * 行级对比标记,复用 indexMixin 的 getCompareRowClass(data-table 也在用,
1802
- * 见 data-table-mixin.js 的 rowClassName)。返回
1803
- * xform-compare-row-new / xform-compare-row-changed / ""。
1804
- * 未参与对比的子表由 getCompareRowClass 内部的 isCompareSubTable 拦掉,
1805
- * 不会满屏高亮,这里无需重复判断。
1806
- */
1807
- getRowCompareClass(row) {
1808
- let formRef = this.getFormRef();
1809
- if (!formRef || !formRef.isCompare || !formRef.getCompareRowClass)
1810
- return "";
1811
- return formRef.getCompareRowClass(this.fieldKeyName, row);
1812
- },
1813
- /**
1814
- * 该列在 H5 明细卡片里是否占半行(一行两个)。
1815
- *
1816
- * 取列的「H5列宽」选项(table-column-dialog 的「编辑更多属性」里配),
1817
- * 运行期从 columnConfig 上读 —— createColumns 把整个设计器列对象原样挂在
1818
- * `col.params.columnConfig` 上(data-table-mixin.js:1762)。
1819
- * 只认 'half':没配过的老列读到 undefined,按整行处理;不能写成 !== 'full'。
1820
- */
1821
- isHalfColumn(column) {
1822
- return column?.params?.columnConfig?.h5Span === "half";
1823
- },
1824
- /**
1825
- * 明细行的显示文本。
1826
- *
1827
- * H5 只读:行上不渲染下拉框,只出选中项文本。
1828
- * 有选项的列必须自己把 value 换成 label,formatterValue 不做选项映射。
1829
- */
1830
- getColumnDisplayText(column, row, rowIndex) {
1831
- let value = row[column.field];
1832
- let columnWidget = column.params ? column.params.widget : null;
1833
- if (columnWidget) {
1834
- let mapped = this.getWidgetOptionLabel(columnWidget, value);
1835
- if (mapped != null && mapped !== "") {
1836
- return mapped;
1837
- }
1838
- }
1839
- return column.formatter({
1840
- cellValue: value,
1841
- column: column,
1842
- rowIndex: rowIndex,
1843
- row: row,
1844
- items: this.fieldModel,
1845
- });
1846
- },
1847
- getOptionItemValueKey(widget) {
1848
- let options = (widget && widget.options) || {};
1849
- if (options.commonAttributeEnabled) {
1850
- return options.valueKey || "sn";
1851
- }
1852
- return options.valueKey || "value";
1853
- },
1854
- getOptionItemLabelKey(widget) {
1855
- let options = (widget && widget.options) || {};
1856
- if (options.commonAttributeEnabled) {
1857
- return options.labelKey || "value";
1858
- }
1859
- return options.labelKey || "label";
1860
- },
1861
- getWidgetOptionLabel(fieldWidget, fieldModel) {
1862
- if (fieldModel === null || fieldModel === undefined || fieldModel === "") {
1863
- return fieldModel;
1864
- }
1865
- let options = (fieldWidget && fieldWidget.options) || {};
1866
- let optionList = options.optionItems || options.statusParam;
1867
- if (!Array.isArray(optionList) || !optionList.length) {
1868
- return null;
1869
- }
1870
- let labelField = this.getOptionItemLabelKey(fieldWidget);
1871
- let valueField = this.getOptionItemValueKey(fieldWidget);
1872
- let values = Array.isArray(fieldModel) ? fieldModel : [fieldModel];
1873
- let labels = values.map((val) => {
1874
- let item = optionList.find(
1875
- (o) => o[valueField] === val || String(o[valueField]) === String(val)
1876
- );
1877
- if (!item) return null;
1878
- let label = item[labelField];
1879
- return this.$t1 ? this.$t1(label) : label;
1880
- });
1881
- let hit = labels.filter((x) => x != null && x !== "");
1882
- return hit.length ? hit.join(",") : null;
1883
- },
1884
- /**
1885
- * 行点击:
1886
- * - 查询选择场景(isQueryTable):点行是勾选,保持原行为;
1887
- * - 明细行:点整行打开明细详情(行上不再摆删除/操作按钮)。
1888
- */
1889
- onRowClick(row) {
1890
- if (this.widget.options.isQueryTable) {
1891
- this.itemCheck(row);
1892
- return
1893
- }
1894
- this.openRowDetailDialog(row);
1895
- },
1896
1679
  itemCheck(row) {
1897
1680
  let dataTableConfig = this.dataTableConfig;
1898
1681
  if (dataTableConfig) {
@@ -124,7 +124,7 @@ modules = {
124
124
 
125
125
  let url = `/${searviceName}/bd_api/${formCode}/${scriptCode}`;
126
126
  return this.getHttpTarget().$http({
127
- // aes: true,
127
+ aes: true,
128
128
  url: url,
129
129
  method: `post`,
130
130
  // loadingTarget: this.getLoadingTarget(),
@@ -19,6 +19,26 @@ export function isNotNull(value) {
19
19
  return value !== null && value !== undefined;
20
20
  }
21
21
 
22
+ /**
23
+ * 数据返回类型是否为「分页集合数据」。
24
+ * 设计器 option 存的是字符串 "2",部分存量模板可能是数字 2。
25
+ */
26
+ export function isPagedCollectionReturnType(accessReturnType) {
27
+ return String(accessReturnType) === "2";
28
+ }
29
+
30
+ /**
31
+ * 数据表格是否应展示并启用分页。
32
+ * 分页集合数据必须走分页(请求带 current/size,响应按 records/total 解析),
33
+ * 与「是否显示分页」是否勾选无关。
34
+ */
35
+ export function shouldShowDataTablePagination(options = {}) {
36
+ return (
37
+ !!options.showPagination ||
38
+ isPagedCollectionReturnType(options.accessReturnType)
39
+ );
40
+ }
41
+
22
42
  const ATTACHMENT_WIDGET_TYPES = ["vabUpload", "baseAttachment", "vabUpload2"];
23
43
 
24
44
  const PROJECT_TAG_WIDGET_TYPES = [
@@ -0,0 +1,41 @@
1
+ import prefixConfig from "@/prefixConfig.js";
2
+
3
+ /**
4
+ * demo B 接的是真实单据:PMD 的「产品变更申请」,走通用 bd_api(getPage / getOne / getList / saveUpdate)。
5
+ * 换成你自己的单据只改这里:表单编码、表名、流程编码、页签标题字段。
6
+ *
7
+ * 请求写法逐条对齐 stdxx 的真实页面 `views/pmd/product/product_change/{list,edit,productItemDialog}.vue`,
8
+ * 那边跑得通这边就跑得通(连 getOne/saveUpdate 不带 formVersion 都是照它来的)。
9
+ *
10
+ * ⚠️ 前置条件(跑不起来先核对这几条):
11
+ * 1. 表单模板 item_change(列表)/ item_change_edit(详情),且配了脚本
12
+ * getPage / getOne / getList / saveUpdate / findItemPage;
13
+ * 2. 表 pcp_item_change / pcp_item_change_item 存在;
14
+ * 3. 流程 product_change_edit 存在,且至少有一个允许改单据(toModify)的节点,
15
+ * 否则「通过自动保存」这条验不到。
16
+ * 真实页面还会写第三张表 pcp_product_properties_change(产品参数),demo 不带它——
17
+ * saveUpdate 只写 data 里出现的表,不传即不动,所以参数不会被清空。
18
+ * 不吃这些前置条件的版本看 ../simple/(前端 mock,不打后台)。
19
+ *
20
+ * ⚠️ 保存是整表提交:saveUpdate 的 data 里带哪几张表,后台就按哪几张表落库。
21
+ * 所以 detail.vue 把子表 pcp_item_change_item 一起读出来、原样带回,
22
+ * 不然拿真实单据试保存会把子表冲掉。你自己的单据有子表时照此办理。
23
+ */
24
+ export const BILL = {
25
+ prefix: prefixConfig.PMD_PREFIX,
26
+ listFormCode: "item_change", // 列表分页用的表单编码
27
+ formCode: "item_change_edit", // 详情取数/保存用的表单编码
28
+ taBm: "pcp_item_change", // 主表表名
29
+ itemTaBm: "pcp_item_change_item", // 子表表名
30
+ wfCode: "div_form_item_change_edit", // 流程编码
31
+ titleField: "sn", // 页签标题字段(变更单号)
32
+ type: 0, // 业务过滤条件:0 产品变更 / 1 零件变更
33
+ };
34
+
35
+ export const STATUS_MAP = {
36
+ 0: { label: "未审核", cls: "list-tag warning" },
37
+ 1: { label: "审核中", cls: "list-tag" },
38
+ 2: { label: "已审核", cls: "list-tag success" },
39
+ };
40
+
41
+ export default BILL;