bl-common-vue3 3.8.127 → 3.8.129

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bl-common-vue3",
3
- "version": "3.8.127",
3
+ "version": "3.8.129",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "description": "bailing vue3 common components lib",
@@ -0,0 +1,402 @@
1
+ <template>
2
+ <bl-modal
3
+ :title="title"
4
+ :visible="visible"
5
+ :width="width"
6
+ :destroyOnClose="true"
7
+ :bodyStyle="modalBodyStyle"
8
+ centered
9
+ @cancel="close"
10
+ @ok="save"
11
+ :confirmLoading="saving"
12
+ >
13
+ <div class="village-config-setting">
14
+ <div class="village-config-setting__tree">
15
+ <div class="village-config-setting__tree-content">
16
+ <VillageTree
17
+ v-bind="villageTreeProps"
18
+ @getCurrent="getCurrentSelect"
19
+ @request="handleTreeRequest"
20
+ />
21
+ </div>
22
+ </div>
23
+ <div class="village-config-setting__content">
24
+ <a-spin :spinning="loading">
25
+ <slot
26
+ :formData="formData"
27
+ :villageId="villageId"
28
+ :loading="loading"
29
+ :saving="saving"
30
+ :isCommonConfig="isCommonConfig"
31
+ :reload="loadConfig"
32
+ :save="save"
33
+ :request="request"
34
+ />
35
+ </a-spin>
36
+ </div>
37
+ </div>
38
+ </bl-modal>
39
+ </template>
40
+
41
+ <script>
42
+ import { computed, defineComponent, reactive, toRefs, watch } from "vue";
43
+ import { message, Spin } from "ant-design-vue";
44
+ import { cloneDeep } from "lodash";
45
+ import BlModal from "../BlModal/index.vue";
46
+ import VillageTree from "../VillageTree/index.vue";
47
+ import { t } from "../../locale";
48
+
49
+ const DEFAULT_MODAL_BODY_STYLE = {
50
+ padding: 0,
51
+ height: "46vh",
52
+ };
53
+
54
+ const cloneData = (data = {}) => {
55
+ if (!data || typeof data !== "object") {
56
+ return {};
57
+ }
58
+ return cloneDeep(data);
59
+ };
60
+
61
+ export default defineComponent({
62
+ name: "VillageConfigSetting",
63
+ components: {
64
+ BlModal,
65
+ VillageTree,
66
+ "a-spin": Spin,
67
+ },
68
+ props: {
69
+ visible: {
70
+ type: Boolean,
71
+ default: false,
72
+ },
73
+ // 配置分类。为空时保持 /apartment/config 的旧逐字段存储方式。
74
+ configKey: {
75
+ type: String,
76
+ default: "",
77
+ },
78
+ // 配置接口。默认值兼容现有公寓参数接口,其他模块可传入自己的接口。
79
+ api: {
80
+ type: Object,
81
+ default: () => ({
82
+ server: "/village",
83
+ get: "/apartment/config",
84
+ save: "/apartment/config",
85
+ }),
86
+ },
87
+ // 接口未返回整份配置时使用的前端默认值。
88
+ defaultFormData: {
89
+ type: Object,
90
+ default: () => ({}),
91
+ },
92
+ villageId: {
93
+ type: [Number, String],
94
+ default: 0,
95
+ },
96
+ roomTypeList: {
97
+ type: Array,
98
+ default: () => [],
99
+ },
100
+ display: {
101
+ type: Number,
102
+ default: 1,
103
+ },
104
+ treeProps: {
105
+ type: Object,
106
+ default: () => ({}),
107
+ },
108
+ title: {
109
+ type: String,
110
+ default: "",
111
+ },
112
+ width: {
113
+ type: [Number, String],
114
+ default: 800,
115
+ },
116
+ bodyStyle: {
117
+ type: Object,
118
+ default: () => ({}),
119
+ },
120
+ normalizeFormData: {
121
+ type: Function,
122
+ default: (data) => data,
123
+ },
124
+ formatSubmitData: {
125
+ type: Function,
126
+ default: (data) => data,
127
+ },
128
+ },
129
+ emits: ["cancel", "success", "loaded", "error", "request", "village-change"],
130
+ setup(props, { emit }) {
131
+ const state = reactive({
132
+ formData: cloneData(props.defaultFormData),
133
+ villageId: props.villageId || "common",
134
+ loading: false,
135
+ saving: false,
136
+ });
137
+
138
+ const modalBodyStyle = computed(() => ({
139
+ ...DEFAULT_MODAL_BODY_STYLE,
140
+ ...props.bodyStyle,
141
+ }));
142
+
143
+ const villageTreeProps = computed(() => ({
144
+ roomType: props.roomTypeList,
145
+ display: props.display,
146
+ showCompany: true,
147
+ isdisabledNumber: 1,
148
+ onlyVillage: true,
149
+ prependTreeNodes: [{
150
+ id: "common",
151
+ key: "common-config",
152
+ title: t("VillageConfigSetting.index.000001-0"),
153
+ childType: "commonConfig",
154
+ isLeaf: true,
155
+ }],
156
+ defaultSelectedKey: props.villageId ? "" : "common-config",
157
+ refreshParams: props.villageId ? {
158
+ villageId: props.villageId,
159
+ selected: { villageId: props.villageId },
160
+ } : undefined,
161
+ ...props.treeProps,
162
+ }));
163
+
164
+ const isCommonConfig = computed(() => state.villageId === "common");
165
+
166
+ const apiConfig = computed(() => ({
167
+ server: "/village",
168
+ get: "/apartment/config",
169
+ save: "/apartment/config",
170
+ ...props.api,
171
+ }));
172
+
173
+ const request = ({ method, server, url, extra = {} }) => {
174
+ return new Promise((resolve, reject) => {
175
+ emit("request", {
176
+ params: { method, server, url, extra },
177
+ success: resolve,
178
+ fail: reject,
179
+ });
180
+ });
181
+ };
182
+
183
+ const setFormData = (data = {}) => {
184
+ if (!data || typeof data !== "object" || !Object.keys(data).length) {
185
+ state.formData = cloneData(props.defaultFormData);
186
+ return;
187
+ }
188
+ const normalizedData = props.normalizeFormData(data) || {};
189
+ state.formData = normalizedData && typeof normalizedData === "object"
190
+ ? {
191
+ ...cloneData(props.defaultFormData),
192
+ ...cloneData(normalizedData),
193
+ }
194
+ : cloneData(props.defaultFormData);
195
+ };
196
+
197
+ const loadConfig = async () => {
198
+ if (!state.villageId) {
199
+ return;
200
+ }
201
+
202
+ state.loading = true;
203
+ try {
204
+ const extra = {
205
+ village_id: state.villageId,
206
+ };
207
+ if (props.configKey) {
208
+ extra.configKey = props.configKey;
209
+ }
210
+ const res = await request({
211
+ method: "get",
212
+ server: apiConfig.value.server,
213
+ url: apiConfig.value.get,
214
+ extra,
215
+ });
216
+ setFormData(res?.list || {});
217
+ emit("loaded", cloneData(state.formData));
218
+ } catch (error) {
219
+ emit("error", error);
220
+ } finally {
221
+ state.loading = false;
222
+ }
223
+ };
224
+
225
+ const changeVillage = async (villageId) => {
226
+ if (!villageId) {
227
+ return;
228
+ }
229
+ state.villageId = villageId;
230
+ emit("village-change", {
231
+ villageId,
232
+ });
233
+ if (props.visible) {
234
+ await loadConfig();
235
+ }
236
+ };
237
+
238
+ const getCurrentSelect = async (info) => {
239
+ const current = info?.current || {};
240
+ if (current.childType === "commonConfig") {
241
+ await changeVillage("common");
242
+ return;
243
+ }
244
+ if (current.childType !== "village") {
245
+ return;
246
+ }
247
+ await changeVillage(current.id);
248
+ };
249
+
250
+ watch(
251
+ () => props.villageId,
252
+ (villageId) => {
253
+ if (villageId) {
254
+ changeVillage(villageId);
255
+ }
256
+ },
257
+ { immediate: true },
258
+ );
259
+
260
+ watch(
261
+ () => props.visible,
262
+ (visible) => {
263
+ if (visible) {
264
+ if (props.villageId) {
265
+ state.villageId = props.villageId;
266
+ } else if (!state.villageId) {
267
+ state.villageId = "common";
268
+ }
269
+ if (state.villageId) {
270
+ loadConfig();
271
+ }
272
+ }
273
+ },
274
+ );
275
+
276
+ const handleTreeRequest = ({ params, success, fail }) => {
277
+ request(params)
278
+ .then((res) => {
279
+ if (typeof success === "function") {
280
+ success(res);
281
+ }
282
+ })
283
+ .catch((error) => {
284
+ if (typeof fail === "function") {
285
+ fail(error);
286
+ }
287
+ });
288
+ };
289
+
290
+ const close = () => {
291
+ state.villageId = "";
292
+ state.loading = false;
293
+ state.saving = false;
294
+ setFormData();
295
+ emit("cancel");
296
+ };
297
+
298
+ const save = async () => {
299
+ if (!state.villageId || state.saving) {
300
+ return;
301
+ }
302
+
303
+ state.saving = true;
304
+ try {
305
+ const params = {
306
+ village_id: state.villageId,
307
+ param: props.formatSubmitData(cloneData(state.formData)),
308
+ };
309
+ if (props.configKey) {
310
+ params.configKey = props.configKey;
311
+ }
312
+ const res = await request({
313
+ method: "put",
314
+ server: apiConfig.value.server,
315
+ url: apiConfig.value.save,
316
+ extra: params,
317
+ });
318
+ message.success(res?.msg || t("common.action.success"));
319
+ emit("success", {
320
+ villageId: state.villageId,
321
+ formData: cloneData(state.formData),
322
+ response: res,
323
+ });
324
+ close();
325
+ } catch (error) {
326
+ emit("error", error);
327
+ } finally {
328
+ state.saving = false;
329
+ }
330
+ };
331
+
332
+ return {
333
+ ...toRefs(state),
334
+ modalBodyStyle,
335
+ villageTreeProps,
336
+ isCommonConfig,
337
+ request,
338
+ loadConfig,
339
+ getCurrentSelect,
340
+ handleTreeRequest,
341
+ close,
342
+ save,
343
+ t,
344
+ };
345
+ },
346
+ });
347
+ </script>
348
+
349
+ <style scoped lang="less">
350
+ .village-config-setting {
351
+ box-sizing: border-box;
352
+ display: flex;
353
+ height: 100%;
354
+ padding: 10px;
355
+ gap: 10px;
356
+ background: #f0f2f5;
357
+
358
+ &__tree,
359
+ &__content {
360
+ min-width: 0;
361
+ height: 100%;
362
+ padding: 10px;
363
+ background: #fff;
364
+ }
365
+
366
+ &__tree {
367
+ display: flex;
368
+ flex-direction: column;
369
+ width: 260px;
370
+ flex: 0 0 260px;
371
+ }
372
+
373
+ &__tree-content {
374
+ min-height: 0;
375
+ flex: 1;
376
+ }
377
+
378
+ &__content {
379
+ flex: 1;
380
+ overflow-y: auto;
381
+ }
382
+ }
383
+
384
+ @media (max-width: 767px) {
385
+ .village-config-setting {
386
+ flex-direction: column;
387
+ overflow-y: auto;
388
+
389
+ &__tree {
390
+ width: 100%;
391
+ height: 180px;
392
+ flex-basis: 180px;
393
+ }
394
+
395
+ &__content {
396
+ height: auto;
397
+ min-height: 260px;
398
+ overflow-y: visible;
399
+ }
400
+ }
401
+ }
402
+ </style>
@@ -167,6 +167,21 @@ export default defineComponent({
167
167
  buildLevelCanSelectFirst:{
168
168
  type:Boolean,
169
169
  default:false
170
+ },
171
+ // 配置树仅允许选择项目节点和自定义配置节点。
172
+ onlyVillage: {
173
+ type: Boolean,
174
+ default: false,
175
+ },
176
+ // 在项目树前追加的自定义节点。
177
+ prependTreeNodes: {
178
+ type: Array,
179
+ default: () => [],
180
+ },
181
+ // 初始化时默认选中的节点 key。
182
+ defaultSelectedKey: {
183
+ type: String,
184
+ default: "",
170
185
  }
171
186
  },
172
187
  components: {
@@ -200,6 +215,9 @@ export default defineComponent({
200
215
  /** 点击选中当前项 */
201
216
  const onTreeSelect = (value, e) => {
202
217
  const current = e.node.dataRef;
218
+ if (props.onlyVillage && !["village", "commonConfig"].includes(current.childType)) {
219
+ return;
220
+ }
203
221
  let levelList =['department','buildLevel']
204
222
  if (props.showCompany) {
205
223
  levelList = ['buildLevel']
@@ -494,6 +512,9 @@ export default defineComponent({
494
512
  listItem.title = listItem.name;
495
513
  listItem.level = level;
496
514
  listItem.slotIcon = `${listItem.childType}Icon`;
515
+ if (props.onlyVillage) {
516
+ listItem.disabled = true;
517
+ }
497
518
  listItem.children = [];
498
519
  if (listItem.subcat && listItem.subcat.length) {
499
520
  listItem.children = getDeptTreeList(
@@ -512,7 +533,7 @@ export default defineComponent({
512
533
  );
513
534
  listItem.children = [...listItem.children, ...villageList];
514
535
  }else{
515
- if (props.showCompany) {
536
+ if (props.showCompany && !props.onlyVillage) {
516
537
  listItem.noVillage = 1
517
538
  setSelected(listItem);
518
539
  }
@@ -592,7 +613,7 @@ export default defineComponent({
592
613
  slotIcon: "buildIcon",
593
614
  isLeaf: false,
594
615
  });
595
- if (!(props.showCompany && villageList.length > 1)) {
616
+ if (totalVillageCount === 1) {
596
617
  state.expandedKeys.push(`${village.key}_buildLevel_${build.id}`);
597
618
  }
598
619
  }
@@ -642,7 +663,7 @@ export default defineComponent({
642
663
  } else {
643
664
  if (props.showCompany) {
644
665
  parentData.noVillage = 0
645
- if (!props.setFirst){
666
+ if (!props.setFirst && !props.onlyVillage){
646
667
  setSelected(parentData);
647
668
  }
648
669
  }else{
@@ -694,12 +715,20 @@ export default defineComponent({
694
715
  const totalVillageCount = res.list
695
716
  ? getVillageCount(res.list)
696
717
  : res.villageList?.length || 0;
697
- state.treeList = res.list
718
+ const villageTree = res.list
698
719
  ? getDeptTreeList(res.list, 1, totalVillageCount)
699
720
  : getVillageTreeList(res.villageList, 1, {}, totalVillageCount);
721
+ state.treeList = [...props.prependTreeNodes, ...villageTree];
700
722
  state.loadingTree = false;
701
- state.treeList[0].disabled = props.isdisabledNumber ? true : false
702
- if (props.setFirst&&state.treeList.length&&state.treeList[0].children){
723
+ if (state.treeList[0] && !props.prependTreeNodes.length) {
724
+ state.treeList[0].disabled = props.isdisabledNumber ? true : false;
725
+ }
726
+ const defaultSelectedNode = props.defaultSelectedKey
727
+ ? state.treeList.find((item) => item.key === props.defaultSelectedKey)
728
+ : undefined;
729
+ if (defaultSelectedNode) {
730
+ setSelected(defaultSelectedNode);
731
+ } else if (props.setFirst&&state.treeList.length&&state.treeList[0].children){
703
732
  setSelected(state.treeList[0].children[0])
704
733
  }
705
734
  let buildList = getBuildCount(state.treeList, []);
@@ -844,7 +873,7 @@ export default defineComponent({
844
873
  slotIcon: "buildIcon",
845
874
  isLeaf: false,
846
875
  });
847
- if (buildId == build.id && !(state.expandedKeys || []).includes(`${v.key}_buildLevel_${build.id}`)) {
876
+ if (buildId == build.id && state.expandedKeys.includes(v.key) && !state.expandedKeys.includes(`${v.key}_buildLevel_${build.id}`)) {
848
877
  state.expandedKeys.push(`${v.key}_buildLevel_${build.id}`)
849
878
  }
850
879
  }
@@ -13,6 +13,7 @@ export { default as SelectProperty } from "./SelectProperty/index.vue";
13
13
  export { default as ChooseHousingResources } from "./ChooseHousingResources/index.vue";
14
14
  export { default as CheckedHousingResources } from "./CheckedHousingResources/index.vue";
15
15
  export { default as VillageTree } from "./VillageTree/index.vue"; //该组件只能用于侧边栏筛选,或者无编辑(不用回显的情况,有导入的情况就没有对应的key导致回显失败)
16
+ export { default as VillageConfigSetting } from "./VillageConfigSetting/index.vue";
16
17
  export { default as UserDetail } from "./UserDetail/index.vue";
17
18
  export { default as BlIcon } from "./BLIcon/index.js";
18
19
  export { default as ViewEnergyList } from "./ViewEnergyList/index.vue";
@@ -536,5 +536,6 @@
536
536
  "PreviewFile.printModal.success": "發送成功",
537
537
  "PreviewFile.download": "文件下載",
538
538
  "PreviewFile.print": "列印文件",
539
- "PreviewFile.defaultTitle": "預覽文件"
539
+ "PreviewFile.defaultTitle": "預覽文件",
540
+ "VillageConfigSetting.index.000001-0": "公共配置"
540
541
  }
@@ -536,5 +536,6 @@
536
536
  "PreviewFile.printModal.success": "Sent",
537
537
  "PreviewFile.download": "Download File",
538
538
  "PreviewFile.print": "Print File",
539
- "PreviewFile.defaultTitle": "Preview File"
539
+ "PreviewFile.defaultTitle": "Preview File",
540
+ "VillageConfigSetting.index.000001-0": "Public configuration"
540
541
  }
@@ -536,5 +536,6 @@
536
536
  "PreviewFile.printModal.success": "送信しました",
537
537
  "PreviewFile.download": "ファイルダウンロード",
538
538
  "PreviewFile.print": "ファイル印刷",
539
- "PreviewFile.defaultTitle": "ファイルをプレビュー"
539
+ "PreviewFile.defaultTitle": "ファイルをプレビュー",
540
+ "VillageConfigSetting.index.000001-0": "共通設定"
540
541
  }
@@ -536,5 +536,6 @@
536
536
  "PreviewFile.printModal.success": "發送成功",
537
537
  "PreviewFile.download": "文件下載",
538
538
  "PreviewFile.print": "列印文件",
539
- "PreviewFile.defaultTitle": "預覽文件"
539
+ "PreviewFile.defaultTitle": "預覽文件",
540
+ "VillageConfigSetting.index.000001-0": "公共配置"
540
541
  }
@@ -536,5 +536,6 @@
536
536
  "PreviewFile.printModal.success": "发送成功",
537
537
  "PreviewFile.download": "文档下载",
538
538
  "PreviewFile.print": "文档打印",
539
- "PreviewFile.defaultTitle": "预览文档"
539
+ "PreviewFile.defaultTitle": "预览文档",
540
+ "VillageConfigSetting.index.000001-0": "公共配置"
540
541
  }