ny
22 小时以前 282fbc6488f4e8ceb5fda759f963ee88fbf7b999
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<script lang="ts" setup>
import { computed, reactive, toRefs, unref, watch } from 'vue';
 
import { useAttrs } from '@jnpf/hooks';
import { uniqueByField } from '@jnpf/utils';
 
import { globalShareState } from '@vben-core/shared/global-state';
 
import { useDebounceFn } from '@vueuse/core';
import { AutoComplete, Form } from 'ant-design-vue';
 
import { autoCompleteProps } from './props';
 
interface State {
  innerValue: any;
  options: any[];
}
 
defineOptions({ inheritAttrs: false, name: 'JnpfAutoComplete' });
 
const props = defineProps(autoCompleteProps);
const emit = defineEmits(['update:value', 'change']);
const attrs: any = useAttrs({ excludeDefaultKeys: false });
const formItemContext = Form.useInjectFormItemContext();
const state = reactive<State>({
  innerValue: undefined,
  options: [],
});
const { innerValue, options } = toRefs(state);
const { getDataInterfaceDataSelect } = globalShareState.getApi();
 
const getBindValue = computed(() => ({
  ...unref(attrs),
  allowClear: props.allowClear,
  disabled: props.disabled,
  placeholder: props.placeholder,
}));
 
watch(
  () => unref(props.value),
  (val) => {
    setValue(val);
  },
  { immediate: true },
);
 
function setValue(value) {
  innerValue.value = value;
}
function onChange(val) {
  emit('update:value', val);
  emit('change', val);
  formItemContext.onFieldChange();
}
function onFocus() {
  onSearch(state.innerValue);
}
function onSearch(searchText: string) {
  if (!props.interfaceId) return (state.options = []);
  const paramList = getParamList();
  paramList.forEach((res) => {
    if (res.relationField === '@keyword') res.defaultValue = searchText;
  });
  const query = {
    interfaceId: props.interfaceId,
    pageSize: 50,
    paramList,
    relationField: props.relationField,
  };
  getDataInterfaceDataSelect(query)
    .then((res) => {
      if (!res.data.list) return (state.options = []);
      let list = res.data.list.map((o) => ({ ...o, value: o[props.relationField] }));
      // 根据对象的某个属性值去重
      if (list.length > 0) list = uniqueByField(list, props.relationField);
      state.options = props.total ? list.splice(0, props.total) : list;
    })
    .catch(() => {
      state.options = [];
    });
}
const debounceOnSearch = useDebounceFn(onSearch, 200);
function getParamList() {
  const templateJson: any[] = props.templateJson;
  if (!props.formData) return templateJson;
  for (const element of templateJson) {
    if (element.relationField && element.sourceType == 1) {
      if (element.relationField.includes('-')) {
        const tableVModel = element.relationField.split('-')[0];
        const childVModel = element.relationField.split('-')[1];
        element.defaultValue =
          (props.formData[tableVModel] &&
            props.formData[tableVModel][props.rowIndex as unknown as number] &&
            props.formData[tableVModel][props.rowIndex as unknown as number][childVModel]) ||
          '';
      } else {
        element.defaultValue = props.formData[element.relationField] || '';
      }
    }
  }
  return templateJson;
}
</script>
 
<template>
  <AutoComplete v-bind="getBindValue" v-model:value="innerValue" :options="options" @change="onChange" @focus="onFocus" @search="debounceOnSearch">
    <template v-for="item in Object.keys($slots)" #[item]="data">
      <slot :name="item" v-bind="data || {}"></slot>
    </template>
  </AutoComplete>
</template>