<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>
|