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

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 (159) 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 +44 -2
  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 +247 -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/mobile/statusTag/mixins.js +1 -61
  19. package/src/components/mobile/wf/content.vue +1662 -1556
  20. package/src/components/mobile/wf/mixins/wfModifyDialogMixin.js +8 -6
  21. package/src/components/table/config.js +78 -78
  22. package/src/components/table/index.js +1276 -1276
  23. package/src/components/table/plugins/cell-area/index.js +1055 -0
  24. package/src/components/table/plugins/cell-area/index.scss +77 -0
  25. package/src/components/table/plugins/cell-area/util.js +224 -0
  26. package/src/components/table/tableForm.vue +330 -330
  27. package/src/components/table/tableFormMixin.js +318 -318
  28. package/src/components/table/vxeFilter/index.js +163 -163
  29. package/src/components/table/vxeFilter/mixin.js +316 -316
  30. package/src/components/wf/content.vue +1188 -1188
  31. package/src/components/wf/wf.js +40 -20
  32. package/src/components/wf/wfActionDropdown.vue +1 -1
  33. package/src/components/wf/wfActionItems.js +1 -1
  34. 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
  35. 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
  36. 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
  37. 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
  38. package/src/components/xform/form-designer/designer.js +15 -0
  39. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +269 -269
  40. package/src/components/xform/form-designer/form-widget/container-widget/detail-temp-widget.vue +132 -0
  41. package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +250 -250
  42. package/src/components/xform/form-designer/form-widget/dialog/fileReferenceDialog.vue +319 -320
  43. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +365 -365
  44. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +554 -555
  45. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +409 -409
  46. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +150 -132
  47. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +114 -114
  48. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +154 -154
  49. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +47 -1
  50. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +178 -178
  51. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +77 -77
  52. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +6 -0
  53. package/src/components/xform/form-designer/form-widget/field-widget/select-widget.vue +139 -139
  54. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +106 -106
  55. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +134 -134
  56. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +1 -0
  57. package/src/components/xform/form-designer/setting-panel/form-setting.vue +39 -39
  58. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +10 -10
  59. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/exportItemColumns-dialog.vue +438 -432
  60. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +2103 -2103
  61. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-temp-edito.vue +90 -0
  62. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +82 -82
  63. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +19 -5
  64. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +8 -8
  65. package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +137 -137
  66. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
  67. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +43 -43
  68. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +43 -43
  69. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +96 -96
  70. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +51 -0
  71. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +42 -42
  72. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +43 -43
  73. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +158 -158
  74. package/src/components/xform/form-designer/setting-panel/property-editor/h5Span-editor.vue +51 -0
  75. package/src/components/xform/form-designer/setting-panel/property-editor/itemStyle-editor.vue +39 -0
  76. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +188 -188
  77. package/src/components/xform/form-designer/setting-panel/property-editor/styleTempClass-editor.vue +51 -0
  78. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +347 -347
  79. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +4 -0
  80. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +59 -3
  81. package/src/components/xform/form-render/container-item/data-table-mixin.js +151 -93
  82. package/src/components/xform/form-render/container-item/detail-h5-item.vue +183 -32
  83. package/src/components/xform/form-render/container-item/detail-temp-item.vue +110 -0
  84. package/src/components/xform/form-render/container-item/h5-card-pane-item.vue +160 -140
  85. package/src/components/xform/form-render/container-item/list-h5-item.vue +1688 -1700
  86. package/src/components/xform/form-render/index.vue +153 -147
  87. package/src/components/xform/form-render/indexMixin.js +12 -0
  88. package/src/components/xform/lang/en-US.js +10 -0
  89. package/src/components/xform/lang/zh-CN.js +12 -0
  90. package/src/components/xform/mixins/defaultHandle.js +707 -707
  91. package/src/components/xform/styles/h5.scss +1992 -0
  92. package/src/components/xform/utils/textMaskUtil.js +182 -179
  93. package/src/components/xform/utils/treeTableUtil.js +1292 -1265
  94. package/src/components/xform/utils/util.js +56 -11
  95. package/src/index.js +9 -4
  96. package/src/layout/components/extractedCode/viewDialog.vue +7 -7
  97. package/src/router/index.js +21 -0
  98. package/src/router/modules/customer.js +71 -14
  99. package/src/store/modules/permission.js +17 -18
  100. package/src/utils/pdfUtil.js +429 -429
  101. package/src/utils/resolveViewComponent.js +142 -16
  102. package/src/views/bd/project/branch/bd_branch/edit.vue +145 -0
  103. package/src/views/bd/project/branch/bd_branch/list.vue +72 -0
  104. package/src/views/bd/project/branch/bd_branch/menuKindDialog.vue +106 -0
  105. package/src/views/bd/project/branch/bd_branch/mixins/edit.js +189 -0
  106. package/src/views/bd/project/branch/bd_branch/mixins/list.js +124 -0
  107. package/src/views/bd/project/branch/bd_branch/mixins/menuKindDialog.js +85 -0
  108. package/src/views/bd/project/branch/form_script/list.vue +31 -0
  109. package/src/views/bd/project/branch/form_template/list.vue +30 -0
  110. package/src/views/bd/project/branch/menu_kind/list.vue +31 -0
  111. package/src/views/bd/project/common/form_script/list.vue +16 -0
  112. package/src/views/bd/project/common/form_template/list.vue +15 -0
  113. package/src/views/bd/project/common/menu_kind/list.vue +15 -0
  114. package/src/views/bd/project/core/branchContext.js +100 -0
  115. package/src/views/bd/project/core/branchPage.js +78 -0
  116. package/src/views/bd/project/core/branchPageWrap.vue +225 -0
  117. package/src/views/bd/project/core/branchScope.js +44 -0
  118. package/src/views/bd/project/core/branchSearchPage.js +285 -0
  119. package/src/views/bd/project/core/branchSelect.vue +85 -0
  120. package/src/views/bd/project/core/branchTreeBar.vue +81 -0
  121. package/src/views/bd/project/core/httpBranchPatch.js +58 -0
  122. package/src/views/bd/project/datatable/menu_kind/list.vue +15 -0
  123. package/src/views/bd/project/datatable/table_model/list.vue +15 -0
  124. package/src/views/bd/setting/bd_company_env/dialog.vue +174 -174
  125. package/src/views/bd/setting/table_model/edit.vue +1066 -1066
  126. package/src/views/bd/setting/table_model/mixins/edit.js +1455 -1455
  127. package/src/views/bd/setting/table_model/mixins/zdDialog.js +148 -148
  128. package/src/views/demo/bizTab/bill/billConfig.js +41 -0
  129. package/src/views/demo/bizTab/bill/detail.vue +436 -0
  130. package/src/views/demo/bizTab/bill/list.vue +288 -0
  131. package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
  132. package/src/views/demo/bizTab/simple/billApi.js +123 -0
  133. package/src/views/demo/bizTab/simple/detail.vue +407 -0
  134. package/src/views/demo/bizTab/simple/list.vue +217 -0
  135. package/src/views/demo/bizTab/standalone/index.vue +121 -0
  136. package/src/views/demo/bizTab/wf/billConfig.js +44 -0
  137. package/src/views/demo/bizTab/wf/detail.vue +661 -0
  138. package/src/views/demo/bizTab/wf/list.vue +242 -0
  139. package/src/views/support/form-dialog-demo/demoPickerDialog.vue +72 -0
  140. package/src/views/support/form-dialog-demo/index.vue +537 -0
  141. package/src/views/user/file_view_ins/list.vue +3 -3
  142. package/src/views/user/home/index.vue +8 -6
  143. package/src/views/user/home/wjl/content.vue +1569 -0
  144. package/src/views/user/notify_message/dialog.vue +7 -5
  145. package/src/views/user/outLink/cc_form_view.vue +188 -0
  146. package/src/views/user/outLink/form_view.vue +2 -2
  147. package/src/views/user/outLink/index.vue +4 -4
  148. package/src/views/user/outLink/view.vue +3 -3
  149. package/src/views/user/role/edit.vue +632 -632
  150. package/src/views/user/role/list.vue +260 -260
  151. package/src/views/user/wf/iframe/index.vue +3 -3
  152. package/src/views/user/wf/iframe/index2.vue +3 -3
  153. package/src/views/user/wf/wf_manage/list.vue +1112 -1116
  154. package/src/views/user/wf/wf_manage/list2.vue +9 -13
  155. package/src/views/user/wf/wf_manage/wfContentDialog.vue +8 -5
  156. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-menu-widget.vue +0 -106
  157. package/src/components/xform/form-designer/form-widget/field-widget/tableexportbuttonwidget.vue +0 -99
  158. package/src/components/xform/form-render/container-item/list-h5-item2.vue +0 -1340
  159. package/src/utils/wf.js +0 -766
@@ -0,0 +1,78 @@
1
+ import branchScope from "./branchScope";
2
+ import { BRANCH_FLAG } from "./branchContext";
3
+ import branchPageWrap from "./branchPageWrap.vue";
4
+
5
+ /**
6
+ * 分支工程页面通用逻辑:
7
+ * 1. 进入先选分支,选中后再渲染被复用的原组件
8
+ * 2. 选中后分支锁定,不可再改
9
+ * 3. 「打开新分支」以独立标签再开一页(需菜单 meta.repeatOpen)
10
+ */
11
+ let modules = {};
12
+ modules = {
13
+ components: { branchPageWrap },
14
+ mixins: [branchScope(BRANCH_FLAG.BRANCH)],
15
+ data() {
16
+ return {
17
+ branchCode: "",
18
+ branchName: "",
19
+ // 组件创建时记下原始菜单名,避免 route.meta.title 被改写后叠加多个分支名
20
+ baseTabTitle: "",
21
+ };
22
+ },
23
+ computed: {
24
+ branchLabel() {
25
+ if (!this.branchCode) {
26
+ return "";
27
+ }
28
+ if (this.branchName) {
29
+ return `${this.branchName}(${this.branchCode})`;
30
+ }
31
+ return this.branchCode;
32
+ },
33
+ },
34
+ created() {
35
+ this.baseTabTitle = this.resolveBaseTabTitle();
36
+ },
37
+ methods: {
38
+ resolveBaseTabTitle() {
39
+ let matched = this.$route.matched || [];
40
+ let last = matched[matched.length - 1] || {};
41
+ // 优先用路由记录上的原始 menuName,勿用可能已被污染的 meta.title
42
+ return (
43
+ last.menuName ||
44
+ this.$route.menuName ||
45
+ last.meta?.originTitle ||
46
+ this.$route.meta?.originTitle ||
47
+ last.meta?.title ||
48
+ this.$route.meta?.title ||
49
+ ""
50
+ );
51
+ },
52
+ onBranchChange(branch) {
53
+ if (!branch || !branch.branchCode) {
54
+ return;
55
+ }
56
+ this.branchCode = branch.branchCode;
57
+ this.branchName = branch.branchName || "";
58
+ this.updateTabTitle();
59
+ },
60
+ updateTabTitle() {
61
+ let base = this.baseTabTitle || this.resolveBaseTabTitle();
62
+ let suffix = this.branchName || this.branchCode;
63
+ // 菜单名形如「表单模板-分支」,选中分支后把末尾的「分支」换成分支名
64
+ let title = suffix
65
+ ? `${base.replace(/[--—]?\s*分支$/, "")}-${suffix}`
66
+ : base;
67
+ this.$store.dispatch("tagsView/updateVisitedView2", {
68
+ view: this.$route,
69
+ title,
70
+ });
71
+ },
72
+ openNewBranch() {
73
+ // 带 repeatOpen 的菜单:附带唯一 _rk,新开独立标签回到选分支态
74
+ this.$openView({ path: this.$route.path }, this.$route);
75
+ },
76
+ },
77
+ };
78
+ export default modules;
@@ -0,0 +1,225 @@
1
+ <template>
2
+ <div class="bd-branch-page" :class="{ 'has-branch': !!branchCode }">
3
+ <!-- 已选分支:内容区顶部工具条,不可改;提供打开新分支 -->
4
+ <div class="branch-bar" v-if="branchCode && showBar">
5
+ <span class="branch-locked">
6
+ <span class="label">{{ $t1("分支") }}:</span>
7
+ <span class="value">{{ branchLabel || branchCode }}</span>
8
+ </span>
9
+ <el-button
10
+ v-if="showOpenNew"
11
+ size="mini"
12
+ type="primary"
13
+ plain
14
+ icon="el-icon-plus"
15
+ @click="$emit('open-new')"
16
+ >
17
+ {{ $t1("打开新分支") }}
18
+ </el-button>
19
+ </div>
20
+ <div class="branch-body" ref="branchBody" v-if="branchCode">
21
+ <slot></slot>
22
+ </div>
23
+ <!-- 未选:先选分支再进入具体页面 -->
24
+ <div class="branch-empty" v-else>
25
+ <i class="el-icon-office-building"></i>
26
+ <p class="tip">{{ $t1("请先选择分支") }}</p>
27
+ <branchSelect
28
+ :value="branchCode"
29
+ @input="$emit('update:branchCode', $event)"
30
+ @change="$emit('branch-change', $event)"
31
+ ></branchSelect>
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <script>
37
+ import branchSelect from "./branchSelect.vue";
38
+
39
+ const BADGE_CLASS = "bd-branch-detail-badge";
40
+
41
+ export default {
42
+ name: "bdBranchPageWrap",
43
+ components: { branchSelect },
44
+ props: {
45
+ branchCode: String,
46
+ branchLabel: String,
47
+ // 页面自己在查询条件里展示/切换分支时,顶部工具条就是多余的
48
+ showBar: {
49
+ type: Boolean,
50
+ default: true,
51
+ },
52
+ showOpenNew: {
53
+ type: Boolean,
54
+ default: true,
55
+ },
56
+ },
57
+ watch: {
58
+ branchCode() {
59
+ this.scheduleInjectBadge();
60
+ },
61
+ branchLabel() {
62
+ this.scheduleInjectBadge();
63
+ },
64
+ },
65
+ mounted() {
66
+ this.scheduleInjectBadge();
67
+ },
68
+ beforeDestroy() {
69
+ this.clearInjectTimer();
70
+ this.clearBodyObserver();
71
+ },
72
+ methods: {
73
+ clearInjectTimer() {
74
+ if (this._injectTimer) {
75
+ clearTimeout(this._injectTimer);
76
+ this._injectTimer = null;
77
+ }
78
+ },
79
+ clearBodyObserver() {
80
+ if (this._bodyObserver) {
81
+ this._bodyObserver.disconnect();
82
+ this._bodyObserver = null;
83
+ }
84
+ },
85
+ scheduleInjectBadge() {
86
+ this.clearInjectTimer();
87
+ this._injectTimer = setTimeout(() => {
88
+ this.ensureBodyObserver();
89
+ this.injectDetailBadges();
90
+ }, 50);
91
+ },
92
+ ensureBodyObserver() {
93
+ let body = this.$refs.branchBody;
94
+ if (!body || this._bodyObserver) {
95
+ return;
96
+ }
97
+ // 详情页通过 x-tabs 异步挂载,监听后补上分支名
98
+ this._bodyObserver = new MutationObserver(() => {
99
+ if (this._injecting) {
100
+ return;
101
+ }
102
+ this.scheduleInjectBadge();
103
+ });
104
+ this._bodyObserver.observe(body, { childList: true, subtree: true });
105
+ },
106
+ injectDetailBadges() {
107
+ let body = this.$refs.branchBody;
108
+ if (!body || !this.branchCode || this._injecting) {
109
+ return;
110
+ }
111
+ this._injecting = true;
112
+ try {
113
+ let text = this.$t1("分支") + ":" + (this.branchLabel || this.branchCode);
114
+ let headers = body.querySelectorAll(".detail-wrap .d-header .fl");
115
+ headers.forEach((el) => {
116
+ let badge = el.querySelector("." + BADGE_CLASS);
117
+ if (!badge) {
118
+ badge = document.createElement("span");
119
+ badge.className = BADGE_CLASS;
120
+ badge.textContent = text;
121
+ el.appendChild(badge);
122
+ return;
123
+ }
124
+ // 相同文案不要再写,否则会反复触发 MutationObserver 卡死页面
125
+ if (badge.textContent !== text) {
126
+ badge.textContent = text;
127
+ }
128
+ });
129
+ } finally {
130
+ this._injecting = false;
131
+ }
132
+ },
133
+ },
134
+ };</script>
135
+
136
+ <style lang="scss" scoped>
137
+ .bd-branch-page {
138
+ position: relative;
139
+ height: 100%;
140
+
141
+ &.has-branch {
142
+ display: flex;
143
+ flex-direction: column;
144
+ }
145
+
146
+ .branch-bar {
147
+ flex: none;
148
+ display: flex;
149
+ align-items: center;
150
+ gap: 12px;
151
+ margin: 0 10px 8px;
152
+ padding: 8px 12px;
153
+ background: #fff;
154
+ border-radius: 2px;
155
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
156
+
157
+ .branch-locked {
158
+ display: inline-flex;
159
+ align-items: center;
160
+ color: #606266;
161
+ font-size: 13px;
162
+
163
+ .label {
164
+ margin-right: 6px;
165
+ color: #909399;
166
+ }
167
+
168
+ .value {
169
+ max-width: 320px;
170
+ overflow: hidden;
171
+ text-overflow: ellipsis;
172
+ white-space: nowrap;
173
+ font-weight: 500;
174
+ color: #303133;
175
+ }
176
+ }
177
+ }
178
+
179
+ .branch-body {
180
+ flex: 1;
181
+ min-height: 0;
182
+ overflow: hidden;
183
+ }
184
+
185
+ .branch-empty {
186
+ height: 100%;
187
+ display: flex;
188
+ flex-direction: column;
189
+ align-items: center;
190
+ justify-content: center;
191
+ color: #909399;
192
+ background-color: #fff;
193
+ border-radius: 2px;
194
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
195
+ margin: 0 10px;
196
+
197
+ i {
198
+ font-size: 48px;
199
+ margin-bottom: 12px;
200
+ color: #c0c4cc;
201
+ }
202
+
203
+ .tip {
204
+ margin: 0 0 16px;
205
+ font-size: 14px;
206
+ }
207
+ }
208
+ }
209
+ </style>
210
+
211
+ <style lang="scss">
212
+ /* 注入到原详情页标题栏,不能用 scoped */
213
+ .bd-branch-detail-badge {
214
+ display: inline-block;
215
+ margin-left: 12px;
216
+ padding: 2px 8px;
217
+ font-size: 14px;
218
+ font-weight: 600;
219
+ line-height: 20px;
220
+ color: #ff731c;
221
+ background: #fff3ea;
222
+ border-radius: 2px;
223
+ vertical-align: middle;
224
+ }
225
+ </style>
@@ -0,0 +1,44 @@
1
+ import { SCOPE_KEY, setFallbackScope } from "./branchContext";
2
+ import { installBranchHttp } from "./httpBranchPatch";
3
+
4
+ /**
5
+ * 壳组件 mixin:在实例上挂分支作用域标记。
6
+ *
7
+ * created 早于子组件的 created,保证被复用的原组件发出的第一个请求就带上分支参数;
8
+ * 请求补丁也在这里安装,无需改动 main.js。
9
+ *
10
+ * @param {number} branchFlag 分支标识:0通用工程 1分支工程 99数据表分类
11
+ */
12
+ export default function branchScope(branchFlag) {
13
+ return {
14
+ created() {
15
+ installBranchHttp();
16
+ this[SCOPE_KEY] = {
17
+ branchFlag,
18
+ branchCode: this.branchCode || null,
19
+ branchName: this.branchName || null,
20
+ };
21
+ setFallbackScope(this[SCOPE_KEY]);
22
+ },
23
+ mounted() {
24
+ setFallbackScope(this[SCOPE_KEY]);
25
+ },
26
+ activated() {
27
+ setFallbackScope(this[SCOPE_KEY]);
28
+ },
29
+ deactivated() {
30
+ setFallbackScope(null);
31
+ },
32
+ beforeDestroy() {
33
+ setFallbackScope(null);
34
+ },
35
+ watch: {
36
+ branchCode(val) {
37
+ this[SCOPE_KEY].branchCode = val || null;
38
+ },
39
+ branchName(val) {
40
+ this[SCOPE_KEY].branchName = val || null;
41
+ },
42
+ },
43
+ };
44
+ }
@@ -0,0 +1,285 @@
1
+ import branchScope from "./branchScope";
2
+ import { BRANCH_FLAG, needInject } from "./branchContext";
3
+
4
+ const BRANCH_FIELD = "branchCode";
5
+
6
+ /** 只读接口:分支未就绪时直接返回空结果,避免表格一直转圈 */
7
+ const READ_SUFFIXES = [
8
+ "/getAllList",
9
+ "/getChildren",
10
+ "/listPage",
11
+ "/listOtherPage",
12
+ "/listPageWf",
13
+ ];
14
+
15
+ function isReadUrl(url) {
16
+ if (!url) {
17
+ return false;
18
+ }
19
+ let path = url;
20
+ let qIndex = path.indexOf("?");
21
+ if (qIndex >= 0) {
22
+ path = path.substring(0, qIndex);
23
+ }
24
+ return READ_SUFFIXES.some((item) => path.endsWith(item));
25
+ }
26
+
27
+ /**
28
+ * 分支工程页面(分支收敛到查询条件)通用逻辑:
29
+ * 1. 不做进入前的分支门禁,也不提供「打开新分支」,分支就是查询条件里的第一个下拉框
30
+ * 2. 没选到有效分支时整页不可操作:不查询、不保存、不导入导出
31
+ * 3. 切换分支即清空其余查询条件并重新查询;分支不做记忆,每次进来都要重新选
32
+ * 4. 页面用 extends 复用 bd/setting 下的原组件,这里全部改在实例级的 $vxeTableUtil /
33
+ * $http / $jsonImport / $jsonExport 上做,不必重写原组件的任何方法
34
+ */
35
+ let modules = {};
36
+ modules = {
37
+ mixins: [branchScope(BRANCH_FLAG.BRANCH)],
38
+ props: {
39
+ // 由外层前置选择页带进来的分支,组件挂载时就已经确定
40
+ initBranchCode: String,
41
+ },
42
+ data() {
43
+ return {
44
+ branchCode: this.initBranchCode || "",
45
+ branchName: "",
46
+ branches: [],
47
+ branchesLoaded: false,
48
+ };
49
+ },
50
+ computed: {
51
+ /** 后台匹配得到分支才算就绪;分支列表未回来前,先按已选分支放行 */
52
+ branchReady() {
53
+ if (!this.branchCode) {
54
+ return false;
55
+ }
56
+ if (!this.branchesLoaded) {
57
+ return true;
58
+ }
59
+ return this.branches.some((item) => item.branchCode === this.branchCode);
60
+ },
61
+ },
62
+ created() {
63
+ this.patchVxeTableUtil();
64
+ this.patchBranchGuard();
65
+ },
66
+ watch: {
67
+ "formData.branchCode"(val) {
68
+ this.applyBranch(val);
69
+ },
70
+ },
71
+ methods: {
72
+ /** 实例级覆盖 $vxeTableUtil.initVxeTable,给原页面的查询条件补一列分支 */
73
+ patchVxeTableUtil() {
74
+ let origin = this.$vxeTableUtil;
75
+ if (!origin || this._branchVxePatched) {
76
+ return;
77
+ }
78
+ this._branchVxePatched = true;
79
+ let that = this;
80
+ // $vxeTableUtil 上都是无 this 依赖的普通函数,原型继承 + 覆盖单个方法即可
81
+ this.$vxeTableUtil = Object.assign(Object.create(origin), {
82
+ initVxeTable(option) {
83
+ that.injectBranchSearchColumn(option);
84
+ return origin.initVxeTable(option);
85
+ },
86
+ });
87
+ },
88
+ /** 分支未就绪时拦掉本页所有分支相关请求与导入导出 */
89
+ patchBranchGuard() {
90
+ if (this._branchGuardPatched) {
91
+ return;
92
+ }
93
+ this._branchGuardPatched = true;
94
+ let that = this;
95
+
96
+ // $commonHttp 内部转调 this.$http,表格查询/树懒加载/行保存都会走到这里
97
+ let originHttp = this.$http;
98
+ let wrapped = function (option) {
99
+ if (option && needInject(option.url) && !that.branchReady) {
100
+ return that.refuseBranchRequest(option);
101
+ }
102
+ return originHttp.apply(this, arguments);
103
+ };
104
+ Object.assign(wrapped, originHttp);
105
+ wrapped.prototype = originHttp.prototype;
106
+ this.$http = wrapped;
107
+
108
+ let originImport = this.$jsonImport;
109
+ if (typeof originImport === "function") {
110
+ this.$jsonImport = function () {
111
+ if (!that.checkBranchReady()) {
112
+ return;
113
+ }
114
+ return originImport.apply(this, arguments);
115
+ };
116
+ }
117
+ let originExport = this.$jsonExport;
118
+ if (typeof originExport === "function") {
119
+ this.$jsonExport = function () {
120
+ if (!that.checkBranchReady()) {
121
+ return;
122
+ }
123
+ return originExport.apply(this, arguments);
124
+ };
125
+ }
126
+ },
127
+ refuseBranchRequest(option) {
128
+ if (isReadUrl(option.url)) {
129
+ let res = { type: "success", objx: { records: [], total: 0 } };
130
+ if (option.callback) {
131
+ option.callback(res);
132
+ }
133
+ if (option.success) {
134
+ option.success(res);
135
+ }
136
+ return Promise.resolve(res);
137
+ }
138
+ this.warnBranchRequired();
139
+ if (option.error) {
140
+ option.error(null);
141
+ }
142
+ return Promise.resolve(null);
143
+ },
144
+ checkBranchReady() {
145
+ if (this.branchReady) {
146
+ return true;
147
+ }
148
+ this.warnBranchRequired();
149
+ return false;
150
+ },
151
+ warnBranchRequired() {
152
+ // 同一批操作只提示一次,避免树表并发请求刷屏
153
+ if (this._branchWarning) {
154
+ return;
155
+ }
156
+ this._branchWarning = true;
157
+ setTimeout(() => {
158
+ this._branchWarning = false;
159
+ }, 1000);
160
+ this.$message({
161
+ type: "warning",
162
+ message: this.$t1("请先选择分支"),
163
+ });
164
+ },
165
+ injectBranchSearchColumn(option) {
166
+ if (!option) {
167
+ return;
168
+ }
169
+ this._branchTableRef = option.tableRef || this._branchTableRef;
170
+ let columns = option.searchColumns || [];
171
+ if (columns.some((item) => item.field === BRANCH_FIELD)) {
172
+ return;
173
+ }
174
+ option.searchColumns = [this.buildBranchSearchColumn(), ...columns];
175
+ },
176
+ buildBranchSearchColumn() {
177
+ return {
178
+ title: this.$t1("分支"),
179
+ field: BRANCH_FIELD,
180
+ type: "select",
181
+ common: true,
182
+ // fixed 让「查询条件设置」的保存结果无法把它挪位置或收进高级筛选
183
+ fixed: true,
184
+ // 分支不允许清空,页面必须始终处在某个分支下
185
+ clearable: false,
186
+ itemOption: [],
187
+ // 不做记忆,只回填前置页刚选的分支
188
+ defaultValue: this.branchCode || null,
189
+ syncHandle: () => {
190
+ return this.loadBranches();
191
+ },
192
+ };
193
+ },
194
+ loadBranches() {
195
+ return new Promise((resolve) => {
196
+ this.$http({
197
+ url: USER_PREFIX + "/bd_branch/listPage",
198
+ method: "post",
199
+ data: {
200
+ enabled: true,
201
+ current: 1,
202
+ size: 500,
203
+ },
204
+ success: (res) => {
205
+ let records = res?.objx?.records || [];
206
+ this.branches = records;
207
+ this.branchesLoaded = true;
208
+ this.dropInvalidBranch();
209
+ this.syncBranchName();
210
+ resolve(
211
+ records.map((item) => {
212
+ return {
213
+ label: item.branchName + "(" + item.branchCode + ")",
214
+ value: item.branchCode,
215
+ };
216
+ })
217
+ );
218
+ },
219
+ error: () => {
220
+ this.branchesLoaded = true;
221
+ resolve([]);
222
+ },
223
+ });
224
+ });
225
+ },
226
+ /** 已选分支后台查不到(停用/删除)时清掉,页面回到不可操作状态 */
227
+ dropInvalidBranch() {
228
+ if (!this.branchCode || this.branchReady) {
229
+ return;
230
+ }
231
+ this.branchCode = "";
232
+ if (this.formData) {
233
+ this.$set(this.formData, BRANCH_FIELD, null);
234
+ }
235
+ this.$message({
236
+ type: "warning",
237
+ message: this.$t1("原分支已不可用,请重新选择分支"),
238
+ });
239
+ // 清掉可能已经查回来的旧分支数据
240
+ this.reloadBranchTable();
241
+ },
242
+ syncBranchName() {
243
+ let current = this.branches.find(
244
+ (item) => item.branchCode === this.branchCode
245
+ );
246
+ this.branchName = current ? current.branchName || "" : "";
247
+ },
248
+ applyBranch(val) {
249
+ let branchCode = val || "";
250
+ // 值没变就不要再触发一次查询
251
+ if (branchCode === this.branchCode) {
252
+ return;
253
+ }
254
+ this.branchCode = branchCode;
255
+ this.syncBranchName();
256
+ // 换分支等于换了一套数据,其余查询条件全部清空
257
+ this.formData = { [BRANCH_FIELD]: branchCode || null };
258
+ this.reloadBranchTable();
259
+ // 通知外层同步标签页名等分支信息
260
+ this.$emit("branch-change", {
261
+ branchCode: this.branchCode,
262
+ branchName: this.branchName,
263
+ });
264
+ },
265
+ reloadBranchTable() {
266
+ let grid = this.$refs[this._branchTableRef || "table-m1"];
267
+ if (grid) {
268
+ grid.commitProxy("reload");
269
+ }
270
+ },
271
+ searchEvent() {
272
+ if (!this.checkBranchReady()) {
273
+ return;
274
+ }
275
+ this.reloadBranchTable();
276
+ },
277
+ /** 重置查询条件时保留已选分支 */
278
+ resetEvent() {
279
+ let branchCode = this.formData ? this.formData.branchCode : "";
280
+ this.formData = { [BRANCH_FIELD]: branchCode || null };
281
+ this.reloadBranchTable();
282
+ },
283
+ },
284
+ };
285
+ export default modules;
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <div class="bd-branch-select">
3
+ <span class="label">{{ $t1("分支") }}:</span>
4
+ <el-select
5
+ :value="value"
6
+ size="small"
7
+ filterable
8
+ :placeholder="$t1('请选择分支')"
9
+ @change="handleChange"
10
+ >
11
+ <el-option
12
+ v-for="item in branches"
13
+ :key="item.branchCode"
14
+ :label="item.branchName + '(' + item.branchCode + ')'"
15
+ :value="item.branchCode"
16
+ ></el-option>
17
+ </el-select>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ name: "bdBranchSelect",
24
+ props: {
25
+ value: String,
26
+ },
27
+ data() {
28
+ return {
29
+ branches: [],
30
+ };
31
+ },
32
+ mounted() {
33
+ this.initData();
34
+ },
35
+ methods: {
36
+ initData() {
37
+ this.$http({
38
+ url: USER_PREFIX + "/bd_branch/listPage",
39
+ method: "post",
40
+ data: {
41
+ enabled: true,
42
+ current: 1,
43
+ size: 500,
44
+ },
45
+ success: (res) => {
46
+ this.branches = res?.objx?.records || [];
47
+ },
48
+ });
49
+ },
50
+ // 分支不做记忆,每次进页面都要重新选
51
+ handleChange(val) {
52
+ let branchCode = val || "";
53
+ this.$emit("input", branchCode);
54
+ this.$emit(
55
+ "change",
56
+ this.branches.find((item) => item.branchCode === branchCode) || null
57
+ );
58
+ },
59
+ },
60
+ };
61
+ </script>
62
+
63
+ <style lang="scss" scoped>
64
+ .bd-branch-select {
65
+ display: inline-flex;
66
+ align-items: center;
67
+
68
+ .label {
69
+ margin-right: 6px;
70
+ color: #666;
71
+ white-space: nowrap;
72
+ }
73
+
74
+ /* 覆盖全局 .el-select{display:block} / .el-input{width:148px},避免框体和内层宽度不一致 */
75
+ ::v-deep .el-select {
76
+ display: inline-block;
77
+ width: 180px;
78
+
79
+ .el-input,
80
+ .el-input__inner {
81
+ width: 100% !important;
82
+ }
83
+ }
84
+ }
85
+ </style>