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