import { defineStore } from 'pinia' import store from '@/store' import { ref } from 'vue' import * as AreaApi from '@/api/system/area' export interface AreaNode { id: number name: string children?: AreaNode[] } export const useAreaStore = defineStore('area', () => { const areaTree = ref([]) const cascaderOptions = computed(() => { const guangdong = areaTree.value.find((province) => province.name === '广东省') const guangzhou = guangdong?.children?.find((city) => city.name === '广州市') return [{ id: 0, name: '全国', children: areaTree }, ...(guangzhou ? [guangzhou] : [])] }) async function loadAreaTree() { if (areaTree.value.length > 0) { return } const res = await AreaApi.getAreaTree() if (res.code === 0) { areaTree.value = res.data || [] } return areaTree.value } const areaIdx = computed(() => { const nodeMap = new Map() const ancestorsMap = new Map() const stack: { node: AreaNode; parents: AreaNode[] }[] = [] for (let i = areaTree.value.length - 1; i >= 0; i--) { stack.push({ node: areaTree.value[i], parents: [] }) } while (stack.length > 0) { const { node, parents } = stack.pop()! nodeMap.set(node.id, node) ancestorsMap.set(node.id, parents) if (node.children?.length) { const newParents = [...parents, node] for (let i = node.children.length - 1; i >= 0; i--) { stack.push({ node: node.children[i], parents: newParents }) } } } return [nodeMap, ancestorsMap] }) const areaNodeMap = computed(() => areaIdx.value[0]) const areaAncestorsMap = computed(() => areaIdx.value[1]) function getDistrictName(districtId: number): string { if (areaNodeMap.value == null) { return '' } return areaNodeMap.value.get(districtId)?.name || `${districtId}` } function getDistrictFullName(districtId: number): string { if (areaNodeMap.value == null || areaAncestorsMap.value == null) { return '' } const ancestors = areaAncestorsMap.value.get(districtId) || [] const node = areaNodeMap.value.get(districtId) const parts = [...ancestors.map((a) => a.name)] if (node) parts.push(node.name) return parts.join('') || `${districtId}` } const streetCache = ref>({}) // 获取街道同时缓存 async function getStreetsByDistrict(districtId: number) { if (streetCache.value[districtId]) { return streetCache.value[districtId] } const res = await AreaApi.getAreaTreeById(districtId) if (res.code === 0) { streetCache.value[districtId] = res.data || [] } return streetCache.value[districtId] || [] } function getStreetName(streetId: number, districtId?: number): string { if (!districtId) return '' const streets = streetCache.value[districtId] if (!streets) return '' const found = streets.find((s) => s.id === streetId) return found?.name || '' } return { areaTree, cascaderOptions, areaIdx, areaNodeMap, areaAncestorsMap, streetCache, loadAreaTree, getStreetsByDistrict, getDistrictFullName, getStreetName, } }) export const useAreaStoreWithOut = () => { return useAreaStore(store) }