yumi-admin/apps/src/views/operate/components/system-region-select.vue
2026-05-25 21:59:19 +08:00

115 lines
2.4 KiB
Vue

<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { regionConfigTable } from '#/api/legacy/system';
import { Select } from 'antdv-next';
const props = withDefaults(
defineProps<{
clearable?: boolean;
disabled?: boolean;
filterable?: boolean;
multiple?: boolean;
placeholder?: string;
sysOrigin: string;
value?: any;
valueField?: 'id' | 'regionCode';
}>(),
{
clearable: false,
disabled: false,
filterable: true,
multiple: false,
placeholder: '请选择',
value: '',
valueField: 'id',
},
);
const emit = defineEmits<{
change: [any, Record<string, any> | null];
'update:value': [any];
}>();
const loading = ref(false);
const list = ref<Array<Record<string, any>>>([]);
const selectValue = ref<any>(props.value);
const regionOptions = computed(() =>
list.value.map((item) => ({
label: item.regionName || '-',
value:
props.valueField === 'regionCode'
? (item.regionCode || item.code || item.id)
: (item.id as any),
})),
);
watch(
() => props.value,
(value) => {
selectValue.value = value;
},
{ immediate: true },
);
watch(
() => props.sysOrigin,
async (value) => {
if (!value) {
list.value = [];
return;
}
loading.value = true;
try {
list.value = await regionConfigTable({ sysOrigin: value });
} finally {
loading.value = false;
}
},
{ immediate: true },
);
function emitChange(value: any) {
emit('update:value', value);
const item = list.value.find((current) => {
const currentValue =
props.valueField === 'regionCode'
? current.regionCode || current.code || current.id
: current.id;
return String(currentValue) === String(value);
}) || null;
emit('change', value, item);
}
function handleChange(value: any) {
selectValue.value = value;
emitChange(value);
}
function clearValue() {
const value = props.multiple ? [] : '';
selectValue.value = value;
emitChange(value);
}
defineExpose({
clearValue,
});
</script>
<template>
<Select option-label-prop="label"
:value="selectValue"
:allow-clear="clearable"
:disabled="disabled"
:loading="loading"
:mode="multiple ? 'multiple' : undefined"
:options="regionOptions"
:placeholder="placeholder"
:show-search="filterable"
style="width: 100%"
@change="handleChange"
/>
</template>