| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <template>
- <!-- 地区选择 -->
- <uv-picker
- ref="pickerRef"
- :columns="columns"
- keyName="name"
- @confirm="areaConfirm"
- @change="areaChange"
- >
- </uv-picker>
- </template>
- <script setup name="RegionSelection">
- import { computed, onMounted, ref, watch } from "vue";
- import { cnareaTreeLbs } from "@/api/index";
- const emit = defineEmits(["confirm"]);
- const props = defineProps({
- // 地区选择器层级, 默认3级
- // 1级 省
- // 2级 市
- // 3级 区县
- hierarchy: {
- type: Number,
- default: () => 3,
- },
- });
- const pickerRef = ref(null);
- const columnIndexs = ref([0, 0, 0]);
- const provinceList = ref([]);
- const municipalityNames = ["北京", "天津", "上海", "重庆"];
- const isMunicipality = (name) => municipalityNames.includes(String(name || ""));
- const getCnareaTreeLbs = () => {
- cnareaTreeLbs().then((res) => {
- if (res.code == 200) {
- provinceList.value = res.data?.children || [];
- initColumns();
- }
- });
- };
- const safeHierarchy = computed(() => {
- const n = Number(props.hierarchy);
- if (!Number.isFinite(n)) return 3;
- return Math.min(3, Math.max(1, n));
- });
- const selectedProvince = computed(() => {
- const provinces = provinceList.value || [];
- const pIndex = columnIndexs.value[0] || 0;
- return provinces[pIndex] || null;
- });
- const selectedCityList = computed(() => {
- return selectedProvince.value?.children || [];
- });
- const selectedMunicipalityCity = computed(() => {
- if (!selectedProvince.value) return null;
- if (!isMunicipality(selectedProvince.value.name)) return null;
- const cities = selectedCityList.value || [];
- if (cities.length !== 1) return null;
- return cities[0] || null;
- });
- const secondColumnList = computed(() => {
- if (!selectedProvince.value) return [];
- if (safeHierarchy.value === 1) return [];
- if (safeHierarchy.value === 2 && selectedMunicipalityCity.value) {
- return selectedMunicipalityCity.value.children || [];
- }
- return selectedCityList.value || [];
- });
- const thirdColumnList = computed(() => {
- if (safeHierarchy.value !== 3) return [];
- const p = selectedProvince.value;
- if (!p) return [];
- const cities = selectedCityList.value || [];
- const cIndex = columnIndexs.value[1] || 0;
- return cities[cIndex]?.children || [];
- });
- const initColumns = () => {
- const pIndex = 0;
- const cIndex = 0;
- columnIndexs.value = [pIndex, cIndex, 0];
- if (pickerRef.value?.setIndexs) {
- pickerRef.value.setIndexs(
- columnIndexs.value.slice(0, safeHierarchy.value),
- true
- );
- }
- };
- const columns = computed(() => {
- const provinces = provinceList.value || [];
- if (safeHierarchy.value === 1) return [provinces];
- if (safeHierarchy.value === 2) return [provinces, secondColumnList.value];
- return [provinces, selectedCityList.value || [], thirdColumnList.value];
- });
- // 地区选择器改变事件
- const areaChange = (e) => {
- const { columnIndex, index, indexs } = e || {};
- if (safeHierarchy.value === 1) return;
- if (columnIndex === 0) {
- const next = [index || 0, 0, 0];
- columnIndexs.value = next;
- pickerRef.value?.setIndexs?.(next.slice(0, safeHierarchy.value), true);
- return;
- }
- if (columnIndex === 1) {
- if (safeHierarchy.value === 2) {
- const next = [
- (indexs && indexs[0]) || columnIndexs.value[0] || 0,
- index || 0,
- 0,
- ];
- columnIndexs.value = next;
- pickerRef.value?.setIndexs?.(next.slice(0, safeHierarchy.value), true);
- return;
- }
- const next = [
- (indexs && indexs[0]) || columnIndexs.value[0] || 0,
- index || 0,
- 0,
- ];
- columnIndexs.value = next;
- pickerRef.value?.setIndexs?.(next.slice(0, safeHierarchy.value), true);
- }
- };
- // 地区选择器确认事件
- const areaConfirm = (e) => {
- let obj = {
- provinceName: undefined,
- provinceCode: undefined,
- cityName: undefined,
- cityCode: undefined,
- areaName: undefined,
- areaCode: undefined,
- };
- const values = e?.value || [];
- if (values.length > 0) {
- obj.provinceName = values[0]?.name;
- obj.provinceCode = values[0]?.id;
- if (safeHierarchy.value === 2) {
- if (isMunicipality(values[0]?.name) && selectedMunicipalityCity.value) {
- obj.cityName = selectedMunicipalityCity.value.name;
- obj.cityCode = selectedMunicipalityCity.value.id;
- obj.areaName = values[1]?.name;
- obj.areaCode = values[1]?.id;
- } else {
- obj.cityName = values[1]?.name;
- obj.cityCode = values[1]?.id;
- }
- } else if (safeHierarchy.value >= 3) {
- obj.cityName = values[1]?.name;
- obj.cityCode = values[1]?.id;
- obj.areaName = values[2]?.name;
- obj.areaCode = values[2]?.id;
- }
- }
- emit("confirm", obj);
- };
- const open = () => {
- // initColumns();
- pickerRef.value?.open?.();
- };
- onMounted(() => {
- getCnareaTreeLbs();
- });
- watch(
- () => props.hierarchy,
- () => {
- initColumns();
- }
- );
- defineExpose({
- open,
- });
- </script>
- <style>
- </style>
|