cloud-web-corejs 1.0.54-dev.797 → 1.0.54-dev.799
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.
- package/package.json +3 -1
- package/src/components/baseTabs/mixins.js +11 -12
- package/src/components/bizTab/BizBillActions.vue +129 -0
- package/src/components/bizTab/BizTabListPage.vue +391 -0
- package/src/components/bizTab/README.md +378 -0
- package/src/components/bizTab/billTableUtil.js +48 -0
- package/src/components/bizTab/billValidators.js +136 -0
- package/src/components/bizTab/bizBillDetailMixin.js +687 -0
- package/src/components/bizTab/index.js +24 -0
- package/src/components/excelExport/exportFieldDialog.vue +373 -367
- package/src/components/excelExport/exportType.js +49 -0
- package/src/components/excelExport/mixins.js +1153 -1141
- package/src/components/vb-tabs/x-tabs.vue +167 -143
- package/src/components/wf/wfUtil.js +327 -292
- package/src/components/xform/form-designer/designer.js +56 -8
- package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +59 -5
- package/src/components/xform/form-designer/form-widget/field-widget/baseAttachment-widget.vue +60 -8
- package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +8 -2
- package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +120 -92
- package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +63 -94
- package/src/components/xform/form-designer/index.vue +0 -1
- package/src/components/xform/form-designer/setting-panel/dataSource-setting.vue +397 -397
- package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +602 -602
- package/src/components/xform/form-designer/setting-panel/form-setting.vue +13 -13
- package/src/components/xform/form-designer/setting-panel/option-items-setting.vue +585 -585
- package/src/components/xform/form-designer/setting-panel/property-editor/a-link-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/a-text-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/alignType-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/censusClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/colorClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/commonAttributeEnabled-editor.vue +3 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +1154 -1154
- package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-editor.vue +96 -80
- package/src/components/xform/form-designer/setting-panel/property-editor/container-detail-plain/detail-plain-editor.vue +75 -75
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/colHeight-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-height-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-offset-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-pull-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-push-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-span-editor.vue +4 -4
- package/src/components/xform/form-designer/setting-panel/property-editor/container-h5-card/h5-card-editor.vue +124 -124
- package/src/components/xform/form-designer/setting-panel/property-editor/container-panel/height-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-panel/width-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tab-customClass-editor.vue +119 -119
- package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tabClass-editor.vue +45 -45
- package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +344 -344
- package/src/components/xform/form-designer/setting-panel/property-editor/container-table-cell/cellHeight-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-table-cell/cellWidth-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-tree/tree-customClass-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/container-tree-pane/tree-pane-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/cancelButtonLabel-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/okButtonLabel-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/title-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/width-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/containerClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/customClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/defaultValue-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/descriptionsItems-editor.vue +4 -4
- package/src/components/xform/form-designer/setting-panel/property-editor/downloadButtonFlag-editor.vue +3 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/dsName-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/echartHeight-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/endPlaceholder-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-accessUrl/accessUrl-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaDataType-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaMinLevel-editor.vue +50 -50
- package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaName-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-autocomplete/autocomplete-vabSearchName-editor.vue +7 -7
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/addTableData-event-editor.vue +84 -84
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/button-type-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindEvent-editor.vue +97 -97
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/form-host-event-editor.vue +188 -188
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
- package/src/components/xform/form-designer/setting-panel/property-editor/field-common/keyName-editor.vue +74 -67
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-dateLimit-editor.vue +4 -4
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-format-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-type-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-valueFormat-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultTime-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-format-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-type-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-valueFormat-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-divider/contentPosition-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-dropdown-menu/dropdown-menu-editor.vue +59 -59
- package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-bar-editor.vue +11 -11
- package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-category-editor.vue +10 -10
- package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-pie-editor.vue +12 -12
- package/src/components/xform/form-designer/setting-panel/property-editor/field-file-upload/file-upload-fileTypes-editor.vue +44 -44
- package/src/components/xform/form-designer/setting-panel/property-editor/field-html-text/htmlContent-editor.vue +29 -29
- package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import-button-editor.vue +6 -6
- package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +3 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/field-number/controlsPosition-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-picture-upload/picture-upload-fileTypes-editor.vue +44 -44
- package/src/components/xform/form-designer/setting-panel/property-editor/field-print-button/print-button-editor.vue +115 -115
- package/src/components/xform/form-designer/setting-panel/property-editor/field-print-button/print-detail-button-editor.vue +115 -115
- package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/highThreshold-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/lowThreshold-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/rate-defaultValue-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/rate-max-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-script/script-editor.vue +4 -4
- package/src/components/xform/form-designer/setting-panel/property-editor/field-script-input/script-input-editor.vue +4 -4
- package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/fontSize-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/textContent-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-status/field-status-editor.vue +3 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/activeText-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/inactiveText-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/switchWidth-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-button-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +74 -71
- package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/table-export-button-editor.vue +3 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-format-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-timeLimit-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-format-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-vabSearch/vabSearchField-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/field-vabSearch/vabSearchName-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload/field-vabUpload-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload2/field-vabUpload2-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-vue-page/vue-page-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/fileMaxSize-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/fileTypesSelect.vue +176 -176
- package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +2 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/formatType-editor.vue +2 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/formula-editor.vue +972 -972
- package/src/components/xform/form-designer/setting-panel/property-editor/iconClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/label-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/labelAlign-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/labelColor-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/labelIconPosition-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/labelWidth-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/limit-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/max-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/maxLength-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/min-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/minLength-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/multipleLimit-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +178 -178
- package/src/components/xform/form-designer/setting-panel/property-editor/oplog-editor.vue +3 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/placeholder-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/precision-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/project-tag-editor.vue +6 -6
- package/src/components/xform/form-designer/setting-panel/property-editor/requiredHint-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/rows-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/space-editor-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/startPlaceholder-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/step-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/styleTableClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/styleTitClass-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/tempStorage-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/type-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/uploadTip-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/uploadURL-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/urlValueEnabled-editor.vue +91 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/validation-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/validationHint-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/widgetWidth-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/propertyRegister.js +1 -0
- package/src/components/xform/form-designer/widget-panel/index.vue +3 -1
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +55 -13
- package/src/components/xform/form-render/container-item/data-table-mixin copy.js +5910 -0
- package/src/components/xform/form-render/container-item/data-table-mixin.js +59 -13
- package/src/components/xform/form-render/container-item/detail-item.vue +52 -11
- package/src/components/xform/form-render/container-item/tab-item.vue +6 -2
- package/src/components/xform/form-render/indexMixin.js +56 -16
- package/src/components/xform/lang/zh-CN.js +2 -1
- package/src/components/xform/utils/attachmentValueUtil.js +239 -0
- package/src/components/xform/utils/util.js +27 -0
- package/src/mixins/wf/index.js +40 -38
- package/src/router/modules/customer.js +50 -0
- package/src/store/config/index.js +46 -0
- package/src/utils/scrollUtil.js +25 -0
- package/src/views/demo/bizTab/bill/billConfig.js +41 -0
- package/src/views/demo/bizTab/bill/detail.vue +436 -0
- package/src/views/demo/bizTab/bill/list.vue +288 -0
- package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
- package/src/views/demo/bizTab/simple/billApi.js +123 -0
- package/src/views/demo/bizTab/simple/detail.vue +407 -0
- package/src/views/demo/bizTab/simple/list.vue +217 -0
- package/src/views/demo/bizTab/standalone/index.vue +121 -0
- package/src/views/demo/bizTab/wf/billConfig.js +44 -0
- package/src/views/demo/bizTab/wf/detail.vue +661 -0
- package/src/views/demo/bizTab/wf/list.vue +242 -0
- package/src/views/user/outLink/cc_form_view.vue +185 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloud-web-corejs",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.54-dev.
|
|
4
|
+
"version": "1.0.54-dev.799",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vue-cli-service serve",
|
|
7
7
|
"dev:micro": "vue-cli-service serve --port 17527",
|
|
@@ -172,8 +172,10 @@
|
|
|
172
172
|
"src/components/langTag",
|
|
173
173
|
"src/components/formDialog",
|
|
174
174
|
"src/components/formDrawer",
|
|
175
|
+
"src/components/bizTab",
|
|
175
176
|
"src/api",
|
|
176
177
|
"src/views/bd",
|
|
178
|
+
"src/views/demo",
|
|
177
179
|
"src/views/support",
|
|
178
180
|
"src/views/user",
|
|
179
181
|
"src/views/mobile/user",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { scrollIntoScrollParent } from '@base/utils/scrollUtil';
|
|
2
|
+
|
|
1
3
|
let baseTabsMixin, baseTabPaneMixin;
|
|
2
4
|
|
|
3
5
|
baseTabsMixin = {
|
|
@@ -76,17 +78,10 @@ baseTabsMixin = {
|
|
|
76
78
|
this.$emit('input', name);
|
|
77
79
|
this.$emit('on-click', name);
|
|
78
80
|
let target = this.getTabs()[index].$el;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
83
|
-
if (scrollContainer) {
|
|
84
|
-
let containerRect = scrollContainer.getBoundingClientRect();
|
|
85
|
-
let targetRect = target.getBoundingClientRect();
|
|
86
|
-
scrollContainer.scrollTop += targetRect.top - containerRect.top;
|
|
87
|
-
} else {
|
|
88
|
-
target.scrollIntoView();
|
|
89
|
-
}
|
|
81
|
+
//滚动体是 .d-cont 还是它外面那层(.d-header + div{flex:1;overflow-y:auto})由布局决定,
|
|
82
|
+
//原来写死 .d-cont,在 .d-cont 没有确定高度(height:inherit 拿到 auto)的页面上
|
|
83
|
+
//scrollTop 赋值是空操作,点导航没反应——统一交给 scrollIntoScrollParent 找真正的滚动体。
|
|
84
|
+
scrollIntoScrollParent(target);
|
|
90
85
|
}
|
|
91
86
|
},
|
|
92
87
|
watch: {
|
|
@@ -127,7 +122,11 @@ baseTabPaneMixin = {
|
|
|
127
122
|
}
|
|
128
123
|
},
|
|
129
124
|
beforeDestroy() {
|
|
130
|
-
|
|
125
|
+
//getParent() 只认 baseTabs 父级/祖父级,拿不到就是没被 baseTabs 包着(如设计期画布、
|
|
126
|
+
//或中间隔了 draggable),此时没有 navList 可维护,直接跳过——原来这里直接取 .navList 会崩。
|
|
127
|
+
let parentPanel = this.getParent();
|
|
128
|
+
if (!parentPanel) return;
|
|
129
|
+
let navList = parentPanel.navList;
|
|
131
130
|
if (navList.length <= 1) {
|
|
132
131
|
this.updateNav();
|
|
133
132
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="fr">
|
|
3
|
+
<!-- 按钮顺序(.fr 里 DOM 次序即从左到右):
|
|
4
|
+
翻单 → 提交流程 → 业务按钮(默认插槽) → 重置 → 保存
|
|
5
|
+
#before 是留给"要排在翻单之前"的特例,一般不用。
|
|
6
|
+
另外 wfUtil 的「修改单据」按钮是 append 到本容器最前面的,会落在最左侧。 -->
|
|
7
|
+
<slot name="before"></slot>
|
|
8
|
+
<!-- ① 上一单 / 下一单:列表侧 openDetail 传了 navRows 才出现 -->
|
|
9
|
+
<template v-if="showBillNav">
|
|
10
|
+
<!-- 用默认按钮而不是 primary+plain:element 对 primary+plain 的禁用态是淡蓝
|
|
11
|
+
(#8cc5ff/#ecf5ff),在头部一排蓝按钮里看不出不可点;默认按钮的禁用态本来就是灰的 -->
|
|
12
|
+
<el-button
|
|
13
|
+
class="button-sty"
|
|
14
|
+
icon="el-icon-arrow-left"
|
|
15
|
+
:disabled="!detail.canPrevBill || busy"
|
|
16
|
+
@click="detail.gotoPrevBill()"
|
|
17
|
+
>{{ $t1("上一单") }}</el-button
|
|
18
|
+
>
|
|
19
|
+
<el-button
|
|
20
|
+
class="button-sty"
|
|
21
|
+
:disabled="!detail.canNextBill || busy"
|
|
22
|
+
@click="detail.gotoNextBill()"
|
|
23
|
+
>{{ $t1("下一单") }}<i class="el-icon-arrow-right el-icon--right"
|
|
24
|
+
/></el-button>
|
|
25
|
+
</template>
|
|
26
|
+
<!-- ② 提交流程。新增页是「保存并提交流程」,已存过的单据是「提交流程」,两者互斥 -->
|
|
27
|
+
<el-button
|
|
28
|
+
v-if="detail.showSaveSubmitBtn"
|
|
29
|
+
type="success"
|
|
30
|
+
class="button-sty"
|
|
31
|
+
icon="el-icon-video-play"
|
|
32
|
+
:disabled="busy"
|
|
33
|
+
:loading="detail.billSaving"
|
|
34
|
+
@click="detail.saveAndSubmitHandle()"
|
|
35
|
+
>{{ detail.saveSubmitButtonName }}</el-button
|
|
36
|
+
>
|
|
37
|
+
<el-button
|
|
38
|
+
v-if="detail.showWfStartBtn"
|
|
39
|
+
type="success"
|
|
40
|
+
class="button-sty"
|
|
41
|
+
icon="el-icon-video-play"
|
|
42
|
+
:disabled="busy"
|
|
43
|
+
@click="detail.startWfHandle()"
|
|
44
|
+
>{{ detail.submitButtonName }}</el-button
|
|
45
|
+
>
|
|
46
|
+
<!-- ③ 业务按钮(作废/复制/打印这类各单据自己的动作) -->
|
|
47
|
+
<slot></slot>
|
|
48
|
+
<!-- ④⑤ 重置、保存。每个按钮都显式写 :disabled:el-button 没传 disabled 时会继承外层
|
|
49
|
+
el-form 的 disabled(element-ui button.vue buttonDisabled),显式传就切断这条继承 -->
|
|
50
|
+
<el-button
|
|
51
|
+
v-if="canEdit"
|
|
52
|
+
type="primary"
|
|
53
|
+
plain
|
|
54
|
+
class="button-sty"
|
|
55
|
+
icon="el-icon-refresh-right"
|
|
56
|
+
:disabled="busy"
|
|
57
|
+
@click="detail.reloadDetail()"
|
|
58
|
+
>{{ $t1("重置") }}</el-button
|
|
59
|
+
>
|
|
60
|
+
<el-button
|
|
61
|
+
v-if="canEdit"
|
|
62
|
+
type="primary"
|
|
63
|
+
class="button-sty"
|
|
64
|
+
icon="el-icon-check"
|
|
65
|
+
:disabled="busy"
|
|
66
|
+
:loading="detail.billSaving"
|
|
67
|
+
@click="detail.saveHandle()"
|
|
68
|
+
>{{ $t1("保存") }}</el-button
|
|
69
|
+
>
|
|
70
|
+
</div>
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<script>
|
|
74
|
+
/**
|
|
75
|
+
* 单据详情头部按钮区,统一「上一单/下一单 / 提交流程 / 保存 / 重置」的显隐、顺序与文案。
|
|
76
|
+
* 从左到右固定为:翻单 → 提交流程 → 业务按钮(默认插槽) → 重置 → 保存。
|
|
77
|
+
* 按钮名走后台 wf_diy_attribute 的 param18(wfButtonName.js),后台没配才用默认文案。
|
|
78
|
+
*
|
|
79
|
+
* 用法(detail 传详情组件自身,模板里用 Vue 内置的 _self):
|
|
80
|
+
* <div class="d-header clearfix">
|
|
81
|
+
* <div class="fl">标题</div>
|
|
82
|
+
* <biz-bill-actions :detail="_self" />
|
|
83
|
+
* </div>
|
|
84
|
+
*
|
|
85
|
+
* 注意:根节点是 .d-header 里的 .fr,别再往外包一层,否则布局会散,
|
|
86
|
+
* 而且 wfUtil 的「修改单据」按钮就是往 .el-form .d-header > .fr 里塞的。
|
|
87
|
+
*/
|
|
88
|
+
export default {
|
|
89
|
+
name: "BizBillActions",
|
|
90
|
+
props: {
|
|
91
|
+
// 详情组件实例(混入了 bizBillDetailMixin)
|
|
92
|
+
detail: {
|
|
93
|
+
type: Object,
|
|
94
|
+
required: true,
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* 覆盖「是否可编辑」(显示重置/保存)。
|
|
98
|
+
* 不传 = 自动判断:流程没启动、或流程当前节点允许改单据。
|
|
99
|
+
* 故意不声明 type:Boolean 型 prop 不传时 Vue 会塞 false,三态就没法表达。
|
|
100
|
+
*/
|
|
101
|
+
editable: {
|
|
102
|
+
default: undefined,
|
|
103
|
+
},
|
|
104
|
+
// 是否显示上一单/下一单。不传 = 有翻单快照就显示
|
|
105
|
+
billNav: {
|
|
106
|
+
default: undefined,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
computed: {
|
|
110
|
+
// 与字段禁用同源:都取详情的 canEditBill(),不会出现「字段能改却没有保存按钮」
|
|
111
|
+
canEdit() {
|
|
112
|
+
if (this.editable !== undefined && this.editable !== null) {
|
|
113
|
+
return !!this.editable;
|
|
114
|
+
}
|
|
115
|
+
return !this.detail.billDisabled;
|
|
116
|
+
},
|
|
117
|
+
showBillNav() {
|
|
118
|
+
if (this.billNav !== undefined && this.billNav !== null) {
|
|
119
|
+
return !!this.billNav;
|
|
120
|
+
}
|
|
121
|
+
return !!this.detail.billNavState;
|
|
122
|
+
},
|
|
123
|
+
// 保存中、或「已入库待提交流程」期间:一律禁用,避免并发写同一张单
|
|
124
|
+
busy() {
|
|
125
|
+
return !!(this.detail.billSaving || this.detail.billSubmitting);
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
</script>
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div id="containt">
|
|
3
|
+
<x-tabs
|
|
4
|
+
ref="xTabs"
|
|
5
|
+
v-model="activeName"
|
|
6
|
+
class="tab-box"
|
|
7
|
+
:tabNameEnable="true"
|
|
8
|
+
:beforeRemove="handleBeforeRemove"
|
|
9
|
+
@removeTab="handleTabRemoved"
|
|
10
|
+
@tabClick="handleTabClick"
|
|
11
|
+
>
|
|
12
|
+
<!-- 列表页签的 name 必须是 "second":x-tabs.doRemoveTab 关掉首个页签时会硬回退到 "second" -->
|
|
13
|
+
<el-tab-pane :label="listLabel" :name="LIST_TAB_NAME">
|
|
14
|
+
<div class="grid-height">
|
|
15
|
+
<slot name="list"></slot>
|
|
16
|
+
</div>
|
|
17
|
+
</el-tab-pane>
|
|
18
|
+
<template #editTab="{ tab }">
|
|
19
|
+
<el-tab-pane
|
|
20
|
+
:key="tab.tabName"
|
|
21
|
+
:label="getTabLabel(tab)"
|
|
22
|
+
:name="tab.tabName"
|
|
23
|
+
:closable="true"
|
|
24
|
+
>
|
|
25
|
+
<!-- showContent 由宿主控制:置 false 再置 true = 详情整体重挂载(重新取数) -->
|
|
26
|
+
<div v-if="tab.showContent" class="biz-tab-detail">
|
|
27
|
+
<slot name="detail" :tab="tab"></slot>
|
|
28
|
+
</div>
|
|
29
|
+
</el-tab-pane>
|
|
30
|
+
</template>
|
|
31
|
+
</x-tabs>
|
|
32
|
+
<!-- 页签之外的内容(各类选择弹框等),与 std 手写列表页把 dialog 放在 el-tabs 外的习惯一致 -->
|
|
33
|
+
<slot></slot>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script>
|
|
38
|
+
/**
|
|
39
|
+
* 单据「列表 + 多详情页签」宿主壳。
|
|
40
|
+
*
|
|
41
|
+
* 只管页签,不认识任何业务表单:详情内容整个由 #detail 插槽提供。
|
|
42
|
+
* 详情组件通过 inject("bizTabHost") 拿到本组件实例,配合 bizBillDetailMixin 完成
|
|
43
|
+
* 「新增页签 → 保存升编辑态 → 提交流程 → 关页签回列表刷新」这条链路。
|
|
44
|
+
*
|
|
45
|
+
* 用法见 src/components/bizTab/README.md 与 src/views/demo/bizTab/。
|
|
46
|
+
*/
|
|
47
|
+
// 列表页签固定名:x-tabs.doRemoveTab 关掉第一个动态页签时会硬回退到 "second"
|
|
48
|
+
const LIST_TAB_NAME = "second";
|
|
49
|
+
|
|
50
|
+
export default {
|
|
51
|
+
name: "BizTabListPage",
|
|
52
|
+
props: {
|
|
53
|
+
// 当前页签名,可选 v-model;不绑也能用(内部自持)
|
|
54
|
+
value: String,
|
|
55
|
+
// 列表页签标题
|
|
56
|
+
listLabel: {
|
|
57
|
+
type: String,
|
|
58
|
+
default: () => "列表",
|
|
59
|
+
},
|
|
60
|
+
// 页签标题取详情数据的哪个字段(如单号 sn、名称 name)
|
|
61
|
+
titleField: {
|
|
62
|
+
type: String,
|
|
63
|
+
default: () => "name",
|
|
64
|
+
},
|
|
65
|
+
// 新增页签的初始标题;保存成功后自动换成 titleField 的值
|
|
66
|
+
addTitle: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: () => "新增",
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* 流程动作完成后的页签行为。
|
|
72
|
+
* "refreshCurrent" 刷新当前页签(默认,能看到最新流程信息)
|
|
73
|
+
* "closeToList" 关掉当前页签 → 回列表 → 刷新列表
|
|
74
|
+
* 传字符串 = 所有动作统一;传对象 = 按动作分别配置,未列出的走 default:
|
|
75
|
+
* { submit: "closeToList", agree: "closeToList", default: "refreshCurrent" }
|
|
76
|
+
* 动作类型:submit 提交(启动流程) / agree 通过 / reject 驳回 /
|
|
77
|
+
* interrupt 中断撤回 / transfer 转办 / talk 沟通
|
|
78
|
+
*/
|
|
79
|
+
behavior: {
|
|
80
|
+
type: [String, Object],
|
|
81
|
+
default: () => "refreshCurrent",
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* 关闭页签前置钩子 beforeTabClose(tab, detail) => Boolean | Promise,返回 false / reject 中止关闭。
|
|
85
|
+
* 不传则用内置判断:详情实现了 isBillDirty() 就问它,否则「未保存过的新增页签」才确认。
|
|
86
|
+
*/
|
|
87
|
+
beforeTabClose: Function,
|
|
88
|
+
// 是否启用上面那套内置关闭确认(自己传了 beforeTabClose 时本项无效)
|
|
89
|
+
confirmOnClose: {
|
|
90
|
+
type: Boolean,
|
|
91
|
+
default: () => true,
|
|
92
|
+
},
|
|
93
|
+
// 激活列表页签时(含关掉详情页签自动回到列表)是否自动刷新列表
|
|
94
|
+
refreshOnActivateList: {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
default: () => true,
|
|
97
|
+
},
|
|
98
|
+
// 页签数量上限。x-tabs 内部超过 30 会顶掉第一个,这里提前拦下来给提示
|
|
99
|
+
maxTabs: {
|
|
100
|
+
type: Number,
|
|
101
|
+
default: () => 10,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
data() {
|
|
105
|
+
return {
|
|
106
|
+
LIST_TAB_NAME,
|
|
107
|
+
activeName: LIST_TAB_NAME,
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
provide() {
|
|
111
|
+
return {
|
|
112
|
+
bizTabHost: this,
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
created() {
|
|
116
|
+
// 详情组件实例登记表(key = tabName)。故意不放 data:这里只做查表,
|
|
117
|
+
// 进了响应式反而会让详情实例被递归 observe。
|
|
118
|
+
this.detailRefs = {};
|
|
119
|
+
if (this.value) this.activeName = this.value;
|
|
120
|
+
},
|
|
121
|
+
watch: {
|
|
122
|
+
value(val) {
|
|
123
|
+
if (val && val !== this.activeName) this.activeName = val;
|
|
124
|
+
},
|
|
125
|
+
activeName(val) {
|
|
126
|
+
this.$emit("input", val);
|
|
127
|
+
this.$emit("tab-change", val);
|
|
128
|
+
if (val !== LIST_TAB_NAME) return;
|
|
129
|
+
// 回到列表就刷新:手动关页签、程序化关页签、手动点列表页签三条路径都在这里收口,
|
|
130
|
+
// 免得列表停留在陈旧数据上(低代码 list.vue 的 watch activeName 是同一意图)。
|
|
131
|
+
if (this._skipListRefresh) {
|
|
132
|
+
this._skipListRefresh = false;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (this.refreshOnActivateList) this.refreshList();
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
methods: {
|
|
139
|
+
// ===== 对外:打开页签 =====
|
|
140
|
+
/**
|
|
141
|
+
* 打开「新增」页签。
|
|
142
|
+
* 关键点:合成一个唯一 id 当页签标识,同时把 dataId 显式置 null——
|
|
143
|
+
* 否则 x-tabs 默认拿 row.id 当 dataId,详情会拿着这个假 id 去 getOne。
|
|
144
|
+
*/
|
|
145
|
+
openAdd(param, option) {
|
|
146
|
+
if (!this.checkTabLimit()) return null;
|
|
147
|
+
let key
|
|
148
|
+
= "add_" + Date.now() + "_" + Math.random().toString(36).slice(2, 6);
|
|
149
|
+
let row = { id: key };
|
|
150
|
+
row[this.titleField] = this.buildAddTitle();
|
|
151
|
+
this.$refs.xTabs.openEditTab(row, param || null, {
|
|
152
|
+
tabParam: {
|
|
153
|
+
tabName: key,
|
|
154
|
+
tabLabelField: this.titleField,
|
|
155
|
+
isAdd: true,
|
|
156
|
+
dataId: null,
|
|
157
|
+
// 翻单快照:新增也带上(navIndex=-1),保存后把新单插到序列首位
|
|
158
|
+
navRows: (option && option.navRows) || null,
|
|
159
|
+
navIndex: -1,
|
|
160
|
+
...((option && option.tabParam) || {}),
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
return key;
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* 打开「详情/编辑」页签。同一单据已开则复用并激活,不重复开。
|
|
167
|
+
* option.navRows / option.navIndex 传了就能用「上一单/下一单」翻单,
|
|
168
|
+
* 一般直接把列表的 fullData 和当前行下标丢进来。
|
|
169
|
+
*/
|
|
170
|
+
openDetail(row, param, option) {
|
|
171
|
+
let dataId = row ? row.id : null;
|
|
172
|
+
if (dataId == null || dataId === "") return this.openAdd(param, option);
|
|
173
|
+
if (!this.hasTab(dataId) && !this.checkTabLimit()) return null;
|
|
174
|
+
let key = String(dataId);
|
|
175
|
+
// 这单已经开着、而且里面有没保存的修改:只激活,不重新取数。
|
|
176
|
+
// openEditTab 的复用分支会 showContent 置 false 再置 true(等于重挂载),
|
|
177
|
+
// 从列表再点一次就把用户改了半天的内容无声冲掉了。
|
|
178
|
+
if (this.hasTab(key) && this.isDetailDirty(this.getTab(key))) {
|
|
179
|
+
this.activeName = key;
|
|
180
|
+
return key;
|
|
181
|
+
}
|
|
182
|
+
this.$refs.xTabs.openEditTab(row, param || null, {
|
|
183
|
+
tabParam: {
|
|
184
|
+
tabName: key,
|
|
185
|
+
tabLabelField: this.titleField,
|
|
186
|
+
isAdd: false,
|
|
187
|
+
dataId: dataId,
|
|
188
|
+
navRows: (option && option.navRows) || null,
|
|
189
|
+
navIndex: (option && option.navIndex != null) ? option.navIndex : -1,
|
|
190
|
+
...((option && option.tabParam) || {}),
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
return key;
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
// ===== 对外:供详情组件(bizBillDetailMixin)回调 =====
|
|
197
|
+
/**
|
|
198
|
+
* 新增保存成功后「只升级页签元数据」:转编辑态 + 换标题,不重渲染详情内容。
|
|
199
|
+
*
|
|
200
|
+
* 元数据升级与内容刷新必须分开做:
|
|
201
|
+
* - 升级了 dataId,后续再保存走更新,不会重复入库(提交失败/取消后重点依赖这条);
|
|
202
|
+
* - 不在这里重渲染,把那唯一一次刷新留给流程结束后的分支,详情最多刷一次、不闪。
|
|
203
|
+
*/
|
|
204
|
+
promoteTab(tab, info) {
|
|
205
|
+
if (!tab) return;
|
|
206
|
+
let dataId = info ? info.dataId : null;
|
|
207
|
+
if (dataId != null && dataId !== "") {
|
|
208
|
+
let isAdd = tab.isAdd;
|
|
209
|
+
tab.dataId = dataId;
|
|
210
|
+
tab.isAdd = false;
|
|
211
|
+
if (tab.data) this.$set(tab.data, "id", dataId);
|
|
212
|
+
// 新增保存:把新单插到翻单序列首位(新数组,不改列表的 fullData 引用)
|
|
213
|
+
if (isAdd && Array.isArray(tab.navRows)) {
|
|
214
|
+
tab.navRows = [tab.data, ...tab.navRows];
|
|
215
|
+
tab.navIndex = 0;
|
|
216
|
+
}
|
|
217
|
+
// 页签 key(tabName) 仍是当初的合成 id:换掉会连带 el-tab-pane 重建、详情被迫重挂载,
|
|
218
|
+
// 正好破坏「保存后不刷详情」的设计。重复打开的去重靠 tab.data.id,它已是真单号。
|
|
219
|
+
}
|
|
220
|
+
this.syncTabTitle(tab, info ? info.title : null);
|
|
221
|
+
},
|
|
222
|
+
// 同步页签标题;空值保持原标题,不回退成单号
|
|
223
|
+
syncTabTitle(tab, title) {
|
|
224
|
+
if (!tab || !tab.data) return;
|
|
225
|
+
if (title == null || title === "") return;
|
|
226
|
+
this.$set(tab.data, this.titleField, title);
|
|
227
|
+
},
|
|
228
|
+
// 重挂载详情内容(重新取数)。页签已被关掉时自动跳过。
|
|
229
|
+
refreshTab(tab) {
|
|
230
|
+
if (!tab || !this.isLiveTab(tab)) return;
|
|
231
|
+
tab.showContent = false;
|
|
232
|
+
setTimeout(() => {
|
|
233
|
+
if (this.isLiveTab(tab)) tab.showContent = true;
|
|
234
|
+
}, 200);
|
|
235
|
+
},
|
|
236
|
+
// 关页签 → 回列表 → 刷新列表。顺序不能反:doRemoveTab 会自己抢 activeName。
|
|
237
|
+
closeTabToList(tab) {
|
|
238
|
+
this.backToList();
|
|
239
|
+
if (tab) this.$refs.xTabs.doRemoveTab(tab.tabName);
|
|
240
|
+
},
|
|
241
|
+
// 程序化关页签,跳过关闭确认
|
|
242
|
+
closeTab(tab) {
|
|
243
|
+
if (tab) this.$refs.xTabs.doRemoveTab(tab.tabName);
|
|
244
|
+
},
|
|
245
|
+
// 切到列表页签;刷新由 activeName 的 watcher 统一收口,refresh === false 可跳过这次刷新
|
|
246
|
+
backToList(refresh) {
|
|
247
|
+
if (refresh === false) this._skipListRefresh = true;
|
|
248
|
+
if (this.activeName === LIST_TAB_NAME) {
|
|
249
|
+
this._skipListRefresh = false;
|
|
250
|
+
if (refresh !== false && this.refreshOnActivateList) this.refreshList();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.activeName = LIST_TAB_NAME;
|
|
254
|
+
},
|
|
255
|
+
refreshList() {
|
|
256
|
+
this.$emit("refresh-list");
|
|
257
|
+
},
|
|
258
|
+
/**
|
|
259
|
+
* 取某个动作完成后的页签行为。详情组件用它决定「刷新本页」还是「关页签回列表」。
|
|
260
|
+
*/
|
|
261
|
+
getBehavior(kind) {
|
|
262
|
+
let behavior = this.behavior;
|
|
263
|
+
if (typeof behavior === "string") return behavior;
|
|
264
|
+
if (behavior && typeof behavior === "object") {
|
|
265
|
+
return behavior[kind] || behavior.default || "refreshCurrent";
|
|
266
|
+
}
|
|
267
|
+
return "refreshCurrent";
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// ===== 对外:上一单 / 下一单 =====
|
|
271
|
+
/**
|
|
272
|
+
* 能不能翻到相邻单据(同步判断:不是新增页签、有快照、没到边界)。
|
|
273
|
+
* 返回目标行下标,不能翻返回 -1。
|
|
274
|
+
*/
|
|
275
|
+
canNavigate(tab, step) {
|
|
276
|
+
if (!tab || tab.isAdd) return -1;
|
|
277
|
+
let rows = tab.navRows;
|
|
278
|
+
if (!Array.isArray(rows) || !rows.length) return -1;
|
|
279
|
+
let idx = (tab.navIndex == null ? -1 : tab.navIndex) + step;
|
|
280
|
+
if (idx < 0 || idx >= rows.length) return -1;
|
|
281
|
+
let row = rows[idx];
|
|
282
|
+
if (!row || row.id == null || row.id === "") return -1;
|
|
283
|
+
return idx;
|
|
284
|
+
},
|
|
285
|
+
/**
|
|
286
|
+
* 把某个页签翻到相邻单据。step = -1 上一单 / +1 下一单,到边界不循环。
|
|
287
|
+
* 页签标题取 tab.data[titleField],所以整行换掉即可;详情靠重挂载按新 dataId 取数。
|
|
288
|
+
* 翻单会丢掉未保存的修改,所以先过一遍脏数据确认(与关页签同一判据)。
|
|
289
|
+
* @returns {Promise<Boolean>} 是否真的翻了
|
|
290
|
+
*/
|
|
291
|
+
navigateTab(tab, step) {
|
|
292
|
+
let idx = this.canNavigate(tab, step);
|
|
293
|
+
if (idx < 0) return Promise.resolve(false);
|
|
294
|
+
return this.confirmLeaveDetail(tab).then((pass) => {
|
|
295
|
+
if (!pass) return false;
|
|
296
|
+
// 确认期间可能已经被关掉或翻走了,重新校一次
|
|
297
|
+
let target = this.canNavigate(tab, step);
|
|
298
|
+
if (target < 0 || !this.isLiveTab(tab)) return false;
|
|
299
|
+
tab.navIndex = target;
|
|
300
|
+
tab.data = tab.navRows[target];
|
|
301
|
+
tab.dataId = tab.data.id; // 详情不 watch dataId,靠下面的重挂载按新单号取数
|
|
302
|
+
this.refreshTab(tab);
|
|
303
|
+
return true;
|
|
304
|
+
});
|
|
305
|
+
},
|
|
306
|
+
// 详情有没有未保存的修改(详情实现了 isBillDirty 才判得出来)
|
|
307
|
+
isDetailDirty(tab) {
|
|
308
|
+
let detail = this.getDetail(tab);
|
|
309
|
+
return !!(
|
|
310
|
+
detail
|
|
311
|
+
&& typeof detail.isBillDirty === "function"
|
|
312
|
+
&& detail.isBillDirty()
|
|
313
|
+
);
|
|
314
|
+
},
|
|
315
|
+
// 要离开/重载当前详情(翻单等)前的确认;不脏直接放行
|
|
316
|
+
confirmLeaveDetail(tab) {
|
|
317
|
+
if (!this.isDetailDirty(tab)) return Promise.resolve(true);
|
|
318
|
+
return this.$baseConfirm(
|
|
319
|
+
this.$t1("单据已修改尚未保存,确定放弃修改吗?")
|
|
320
|
+
).then(
|
|
321
|
+
() => true,
|
|
322
|
+
() => false
|
|
323
|
+
);
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
// ===== 内部 =====
|
|
327
|
+
// 详情实例登记:refreshTab 会销毁重建详情,所以登记/注销都由详情自己在生命周期里做
|
|
328
|
+
registerDetail(tab, vm) {
|
|
329
|
+
if (tab && tab.tabName) this.detailRefs[tab.tabName] = vm;
|
|
330
|
+
},
|
|
331
|
+
unregisterDetail(tab, vm) {
|
|
332
|
+
if (!tab || !tab.tabName) return;
|
|
333
|
+
if (this.detailRefs[tab.tabName] === vm) delete this.detailRefs[tab.tabName];
|
|
334
|
+
},
|
|
335
|
+
getDetail(tab) {
|
|
336
|
+
return tab && tab.tabName ? this.detailRefs[tab.tabName] || null : null;
|
|
337
|
+
},
|
|
338
|
+
getTabs() {
|
|
339
|
+
return this.$refs.xTabs ? this.$refs.xTabs.tabs : [];
|
|
340
|
+
},
|
|
341
|
+
getTab(tabName) {
|
|
342
|
+
return this.getTabs().find((tab) => tab.tabName === tabName) || null;
|
|
343
|
+
},
|
|
344
|
+
isLiveTab(tab) {
|
|
345
|
+
return this.getTabs().indexOf(tab) >= 0;
|
|
346
|
+
},
|
|
347
|
+
hasTab(dataId) {
|
|
348
|
+
return this.getTabs().some((tab) => tab.tabName === String(dataId));
|
|
349
|
+
},
|
|
350
|
+
getTabLabel(tab) {
|
|
351
|
+
let label = tab.data ? tab.data[this.titleField] : null;
|
|
352
|
+
return label == null || label === "" ? this.addTitle : label;
|
|
353
|
+
},
|
|
354
|
+
// 多个新增页签标题一样会分不清,第二个起加序号:新增 / 新增2 / 新增3
|
|
355
|
+
buildAddTitle() {
|
|
356
|
+
let count = this.getTabs().filter((tab) => tab.isAdd).length;
|
|
357
|
+
return count > 0 ? this.addTitle + (count + 1) : this.addTitle;
|
|
358
|
+
},
|
|
359
|
+
checkTabLimit() {
|
|
360
|
+
if (this.getTabs().length < this.maxTabs) return true;
|
|
361
|
+
this.$message.warning(
|
|
362
|
+
this.$t1
|
|
363
|
+
? this.$t1(`最多同时打开 ${this.maxTabs} 个页签,请先关闭部分页签`)
|
|
364
|
+
: `最多同时打开 ${this.maxTabs} 个页签,请先关闭部分页签`
|
|
365
|
+
);
|
|
366
|
+
return false;
|
|
367
|
+
},
|
|
368
|
+
handleBeforeRemove(targetName, tab) {
|
|
369
|
+
let detail = this.getDetail(tab);
|
|
370
|
+
if (this.beforeTabClose) return this.beforeTabClose(tab, detail);
|
|
371
|
+
if (!this.confirmOnClose) return true;
|
|
372
|
+
// 详情自己会判脏就听它的,否则退回「新增还没存过」这一条
|
|
373
|
+
if (detail && typeof detail.isBillDirty === "function") {
|
|
374
|
+
if (!detail.isBillDirty()) return true;
|
|
375
|
+
return this.$baseConfirm(this.$t1("单据已修改尚未保存,确定关闭吗?"));
|
|
376
|
+
}
|
|
377
|
+
if (!tab || !tab.isAdd) return true;
|
|
378
|
+
return this.$baseConfirm(this.$t1("新增内容尚未保存,确定关闭吗?"));
|
|
379
|
+
},
|
|
380
|
+
handleTabRemoved(targetName) {
|
|
381
|
+
let detail = this.detailRefs[targetName];
|
|
382
|
+
if (detail) delete this.detailRefs[targetName];
|
|
383
|
+
this.$emit("tab-removed", targetName);
|
|
384
|
+
},
|
|
385
|
+
// x-tabs 转发的是 el-tabs 的 tab-click 载荷(页签组件实例,不是名字),原样往上抛
|
|
386
|
+
handleTabClick(tab) {
|
|
387
|
+
this.$emit("tab-click", tab);
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
</script>
|