Commit e6353bc8599d3372d2e5df0dd998ff9fc906fa37

Authored by ww
1 parent a27a5e41

perf: visual board implement map component data source bind

  1 +<script lang="ts">
  2 + export type OptionsItem = { label: string; value: string; disabled?: boolean };
  3 + export interface OnChangeHookParams {
  4 + options: Ref<OptionsItem[]>;
  5 + }
  6 +</script>
  7 +
1 <script lang="ts" setup> 8 <script lang="ts" setup>
2 - import { ref, watchEffect, computed, unref, watch } from 'vue'; 9 + import { ref, watchEffect, computed, unref, watch, Ref } from 'vue';
3 import { Select } from 'ant-design-vue'; 10 import { Select } from 'ant-design-vue';
4 import { isFunction } from '/@/utils/is'; 11 import { isFunction } from '/@/utils/is';
5 import { useRuleFormItem } from '/@/hooks/component/useFormItem'; 12 import { useRuleFormItem } from '/@/hooks/component/useFormItem';
@@ -8,8 +15,6 @@ @@ -8,8 +15,6 @@
8 import { LoadingOutlined } from '@ant-design/icons-vue'; 15 import { LoadingOutlined } from '@ant-design/icons-vue';
9 import { useI18n } from '/@/hooks/web/useI18n'; 16 import { useI18n } from '/@/hooks/web/useI18n';
10 17
11 - type OptionsItem = { label: string; value: string; disabled?: boolean };  
12 -  
13 const emit = defineEmits(['options-change', 'change']); 18 const emit = defineEmits(['options-change', 'change']);
14 const props = withDefaults( 19 const props = withDefaults(
15 defineProps<{ 20 defineProps<{
@@ -22,12 +27,16 @@ @@ -22,12 +27,16 @@
22 labelField?: string; 27 labelField?: string;
23 valueField?: string; 28 valueField?: string;
24 immediate?: boolean; 29 immediate?: boolean;
  30 + queryEmptyDataAgin?: boolean;
  31 + onChangeHook?: ({ options }: OnChangeHookParams) => void;
  32 + dropdownVisibleChangeHook?: ({ options }: OnChangeHookParams) => void;
25 }>(), 33 }>(),
26 { 34 {
27 resultField: '', 35 resultField: '',
28 labelField: 'label', 36 labelField: 'label',
29 valueField: 'value', 37 valueField: 'value',
30 immediate: true, 38 immediate: true,
  39 + queryEmptyDataAgin: true,
31 } 40 }
32 ); 41 );
33 const options = ref<OptionsItem[]>([]); 42 const options = ref<OptionsItem[]>([]);
@@ -42,7 +51,6 @@ @@ -42,7 +51,6 @@
42 51
43 const getOptions = computed(() => { 52 const getOptions = computed(() => {
44 const { labelField, valueField = 'value', numberToString } = props; 53 const { labelField, valueField = 'value', numberToString } = props;
45 -  
46 return unref(options).reduce((prev, next: Recordable) => { 54 return unref(options).reduce((prev, next: Recordable) => {
47 if (next) { 55 if (next) {
48 const value = next[valueField]; 56 const value = next[valueField];
@@ -92,24 +100,34 @@ @@ -92,24 +100,34 @@
92 } 100 }
93 101
94 async function handleFetch() { 102 async function handleFetch() {
95 - if (!props.immediate && unref(isFirstLoad)) { 103 + const { immediate, dropdownVisibleChangeHook } = props;
  104 + if (!immediate && unref(isFirstLoad)) {
96 await fetch(); 105 await fetch();
97 isFirstLoad.value = false; 106 isFirstLoad.value = false;
98 } 107 }
  108 + if (dropdownVisibleChangeHook && isFunction(dropdownVisibleChangeHook)) {
  109 + dropdownVisibleChangeHook({ options });
  110 + }
99 } 111 }
100 112
101 function emitChange() { 113 function emitChange() {
102 emit('options-change', unref(getOptions)); 114 emit('options-change', unref(getOptions));
103 } 115 }
104 116
105 - function handleChange(_, ...args) { 117 + function handleChange(value: string, ...args) {
106 emitData.value = args; 118 emitData.value = args;
107 - if (!_) handleSearch(); 119 + if (!value && props.queryEmptyDataAgin) handleSearch();
  120 + const { onChangeHook } = props;
  121 + if (!onChangeHook && !isFunction(onChangeHook)) return;
  122 + onChangeHook({ options });
108 } 123 }
109 124
110 async function handleSearch(params?: string) { 125 async function handleSearch(params?: string) {
111 - const searchApi = props.searchApi;  
112 - if (!searchApi || !isFunction(searchApi)) return; 126 + let { searchApi, api } = props;
  127 + if (!searchApi || !isFunction(searchApi)) {
  128 + if (!api || !isFunction(api)) return;
  129 + searchApi = api;
  130 + }
113 options.value = []; 131 options.value = [];
114 try { 132 try {
115 loading.value = true; 133 loading.value = true;
@@ -135,6 +153,7 @@ @@ -135,6 +153,7 @@
135 <Select 153 <Select
136 @dropdownVisibleChange="handleFetch" 154 @dropdownVisibleChange="handleFetch"
137 v-bind="attrs" 155 v-bind="attrs"
  156 + show-search
138 @change="handleChange" 157 @change="handleChange"
139 :options="getOptions" 158 :options="getOptions"
140 @search="handleSearch" 159 @search="handleSearch"
@@ -2,6 +2,8 @@ import { getAllDeviceByOrg, getDeviceAttributes, getGatewaySlaveDevice } from '/ @@ -2,6 +2,8 @@ import { getAllDeviceByOrg, getDeviceAttributes, getGatewaySlaveDevice } from '/
2 import { getOrganizationList } from '/@/api/system/system'; 2 import { getOrganizationList } from '/@/api/system/system';
3 import { FormSchema } from '/@/components/Form'; 3 import { FormSchema } from '/@/components/Form';
4 import { copyTransFun } from '/@/utils/fnUtils'; 4 import { copyTransFun } from '/@/utils/fnUtils';
  5 +import { OnChangeHookParams } from '/@/components/Form/src/components/ApiSearchSelect.vue';
  6 +import { unref } from 'vue';
5 7
6 export enum BasicConfigField { 8 export enum BasicConfigField {
7 NAME = 'name', 9 NAME = 'name',
@@ -366,84 +368,68 @@ export const mapFormSchema: FormSchema[] = [ @@ -366,84 +368,68 @@ export const mapFormSchema: FormSchema[] = [
366 }, 368 },
367 { 369 {
368 field: DataSourceField.LONGITUDE_ATTRIBUTE, 370 field: DataSourceField.LONGITUDE_ATTRIBUTE,
369 - component: 'ApiSelect', 371 + component: 'ApiSearchSelect',
370 label: '经度属性', 372 label: '经度属性',
371 colProps: { span: 8 }, 373 colProps: { span: 8 },
372 rules: [{ required: true, message: '属性为必填项' }], 374 rules: [{ required: true, message: '属性为必填项' }],
373 - componentProps({ formModel, formActionType }) {  
374 - const { updateSchema, setFieldsValue } = formActionType; 375 + componentProps({ formModel }) {
375 const organizationId = formModel[DataSourceField.ORIGINATION_ID]; 376 const organizationId = formModel[DataSourceField.ORIGINATION_ID];
376 const isGatewayDevice = formModel[DataSourceField.IS_GATEWAY_DEVICE]; 377 const isGatewayDevice = formModel[DataSourceField.IS_GATEWAY_DEVICE];
377 const deviceId = formModel[DataSourceField.DEVICE_ID]; 378 const deviceId = formModel[DataSourceField.DEVICE_ID];
378 const slaveDeviceId = formModel[DataSourceField.SLAVE_DEVICE_ID]; 379 const slaveDeviceId = formModel[DataSourceField.SLAVE_DEVICE_ID];
379 -  
380 - let attrs: Record<'label' | 'value', string>[] = [];  
381 return { 380 return {
382 api: async () => { 381 api: async () => {
383 if (organizationId && deviceId) { 382 if (organizationId && deviceId) {
384 try { 383 try {
385 if (isGatewayDevice && slaveDeviceId) { 384 if (isGatewayDevice && slaveDeviceId) {
386 - return (attrs = await getDeviceAttribute(slaveDeviceId)); 385 + return await getDeviceAttribute(slaveDeviceId);
387 } 386 }
388 if (!isGatewayDevice) { 387 if (!isGatewayDevice) {
389 - return (attrs = await getDeviceAttribute(deviceId)); 388 + return await getDeviceAttribute(deviceId);
390 } 389 }
391 } catch (error) {} 390 } catch (error) {}
392 } 391 }
393 return []; 392 return [];
394 }, 393 },
395 placeholder: '请选择经度属性', 394 placeholder: '请选择经度属性',
396 - getPopupContainer: () => document.body,  
397 - onChange: (value: string) => {  
398 - if (!value) return;  
399 - setFieldsValue({ [DataSourceField.LATITUDE_ATTRIBUTE]: null });  
400 - updateSchema({  
401 - field: DataSourceField.LATITUDE_ATTRIBUTE,  
402 - componentProps: {  
403 - options: attrs.filter((item) => item.value !== value),  
404 - },  
405 - }); 395 + dropdownVisibleChangeHook: ({ options }: OnChangeHookParams) => {
  396 + options.value = unref(options).filter(
  397 + (item) => item.value !== formModel[DataSourceField.LATITUDE_ATTRIBUTE]
  398 + );
406 }, 399 },
  400 + getPopupContainer: () => document.body,
407 }; 401 };
408 }, 402 },
409 }, 403 },
410 { 404 {
411 field: DataSourceField.LATITUDE_ATTRIBUTE, 405 field: DataSourceField.LATITUDE_ATTRIBUTE,
412 - component: 'ApiSelect', 406 + component: 'ApiSearchSelect',
413 label: '纬度属性', 407 label: '纬度属性',
414 colProps: { span: 8 }, 408 colProps: { span: 8 },
415 rules: [{ required: true, message: '属性为必填项' }], 409 rules: [{ required: true, message: '属性为必填项' }],
416 - componentProps({ formModel, formActionType }) {  
417 - const { updateSchema, setFieldsValue } = formActionType; 410 + componentProps({ formModel }) {
418 const organizationId = formModel[DataSourceField.ORIGINATION_ID]; 411 const organizationId = formModel[DataSourceField.ORIGINATION_ID];
419 const isGatewayDevice = formModel[DataSourceField.IS_GATEWAY_DEVICE]; 412 const isGatewayDevice = formModel[DataSourceField.IS_GATEWAY_DEVICE];
420 const deviceId = formModel[DataSourceField.DEVICE_ID]; 413 const deviceId = formModel[DataSourceField.DEVICE_ID];
421 const slaveDeviceId = formModel[DataSourceField.SLAVE_DEVICE_ID]; 414 const slaveDeviceId = formModel[DataSourceField.SLAVE_DEVICE_ID];
422 - let attrs: Record<'label' | 'value', string>[] = [];  
423 -  
424 return { 415 return {
425 api: async () => { 416 api: async () => {
426 if (organizationId && deviceId) { 417 if (organizationId && deviceId) {
427 try { 418 try {
428 if (isGatewayDevice && slaveDeviceId) { 419 if (isGatewayDevice && slaveDeviceId) {
429 - return (attrs = await getDeviceAttribute(slaveDeviceId)); 420 + return getDeviceAttribute(slaveDeviceId);
430 } 421 }
431 if (!isGatewayDevice) { 422 if (!isGatewayDevice) {
432 - return (attrs = await getDeviceAttribute(deviceId)); 423 + return await getDeviceAttribute(deviceId);
433 } 424 }
434 } catch (error) {} 425 } catch (error) {}
435 } 426 }
436 return []; 427 return [];
437 }, 428 },
438 - onChange: (value: string) => {  
439 - if (!value) return;  
440 - setFieldsValue({ [DataSourceField.LONGITUDE_ATTRIBUTE]: null });  
441 - updateSchema({  
442 - field: DataSourceField.LATITUDE_ATTRIBUTE,  
443 - componentProps: {  
444 - options: attrs.filter((item) => item.value !== value),  
445 - },  
446 - }); 429 + dropdownVisibleChangeHook: ({ options }: OnChangeHookParams) => {
  430 + options.value = unref(options).filter(
  431 + (item) => item.value !== formModel[DataSourceField.LONGITUDE_ATTRIBUTE]
  432 + );
447 }, 433 },
448 placeholder: '请选择纬度属性', 434 placeholder: '请选择纬度属性',
449 getPopupContainer: () => document.body, 435 getPopupContainer: () => document.body,