|  | @@ -0,0 +1,159 @@
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <el-cascader
 | 
	
		
			
				|  |  | +    ref="cascader"
 | 
	
		
			
				|  |  | +    v-model="selectedValues"
 | 
	
		
			
				|  |  | +    :options="options"
 | 
	
		
			
				|  |  | +    :props="cascaderProps"
 | 
	
		
			
				|  |  | +    :placeholder="placeholder"
 | 
	
		
			
				|  |  | +    :clearable="clearable"
 | 
	
		
			
				|  |  | +    :disabled="disabled"
 | 
	
		
			
				|  |  | +    :size="size"
 | 
	
		
			
				|  |  | +    @change="handleChange"
 | 
	
		
			
				|  |  | +    @expand-change="handleExpandChange"
 | 
	
		
			
				|  |  | +    filterable
 | 
	
		
			
				|  |  | +  />
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script>
 | 
	
		
			
				|  |  | +import { getLazyTree } from '@/api/base/region'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default {
 | 
	
		
			
				|  |  | +  name: 'RegionCascader',
 | 
	
		
			
				|  |  | +  props: {
 | 
	
		
			
				|  |  | +    value: {
 | 
	
		
			
				|  |  | +      type: [String, Array],
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    placeholder: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: '请选择省/市/区'
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    clearable: {
 | 
	
		
			
				|  |  | +      type: Boolean,
 | 
	
		
			
				|  |  | +      default: true
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    disabled: {
 | 
	
		
			
				|  |  | +      type: Boolean,
 | 
	
		
			
				|  |  | +      default: false
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    size: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: 'small'
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  data() {
 | 
	
		
			
				|  |  | +    return {
 | 
	
		
			
				|  |  | +      options: [],
 | 
	
		
			
				|  |  | +      selectedValues: [],
 | 
	
		
			
				|  |  | +      cascaderProps: {
 | 
	
		
			
				|  |  | +        value: 'value',
 | 
	
		
			
				|  |  | +        label: 'title',
 | 
	
		
			
				|  |  | +        children: 'children',
 | 
	
		
			
				|  |  | +        lazy: true,
 | 
	
		
			
				|  |  | +        lazyLoad: this.lazyLoad,
 | 
	
		
			
				|  |  | +        checkStrictly: false
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  watch: {
 | 
	
		
			
				|  |  | +    value: {
 | 
	
		
			
				|  |  | +      handler(newVal) {
 | 
	
		
			
				|  |  | +        if (newVal && typeof newVal === 'string') {
 | 
	
		
			
				|  |  | +          this.selectedValues = []
 | 
	
		
			
				|  |  | +        } else if (Array.isArray(newVal)) {
 | 
	
		
			
				|  |  | +          this.selectedValues = [...newVal]
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          this.selectedValues = []
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      immediate: true
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  async mounted() {
 | 
	
		
			
				|  |  | +    await this.loadProvinces()
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  methods: {
 | 
	
		
			
				|  |  | +    async loadProvinces() {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const res = await getLazyTree('00')
 | 
	
		
			
				|  |  | +        if (res.data.success) {
 | 
	
		
			
				|  |  | +          this.options = res.data.data.map(item => ({
 | 
	
		
			
				|  |  | +            ...item,
 | 
	
		
			
				|  |  | +            leaf: false
 | 
	
		
			
				|  |  | +          }))
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } catch (error) {
 | 
	
		
			
				|  |  | +        console.error('加载省级数据失败:', error)
 | 
	
		
			
				|  |  | +        this.$message.error('加载省级数据失败')
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    async lazyLoad(node, resolve) {
 | 
	
		
			
				|  |  | +      const { level, value } = node
 | 
	
		
			
				|  |  | +      
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        // 如果是第三级(区级),直接返回空数组,不再加载子级
 | 
	
		
			
				|  |  | +        if (level >= 3) {
 | 
	
		
			
				|  |  | +          resolve([])
 | 
	
		
			
				|  |  | +          return
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const res = await getLazyTree(value)
 | 
	
		
			
				|  |  | +        if (res.data.success) {
 | 
	
		
			
				|  |  | +          const children = res.data.data.map(item => ({
 | 
	
		
			
				|  |  | +            ...item,
 | 
	
		
			
				|  |  | +            leaf: level >= 2 // 市级的子级(区级)设为叶子节点
 | 
	
		
			
				|  |  | +          }))
 | 
	
		
			
				|  |  | +          resolve(children)
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          resolve([])
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } catch (error) {
 | 
	
		
			
				|  |  | +        console.error('加载子级数据失败:', error)
 | 
	
		
			
				|  |  | +        resolve([])
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 选择改变事件
 | 
	
		
			
				|  |  | +     * @param {Array} values - 选中的值数组
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleChange(values) {
 | 
	
		
			
				|  |  | +      this.selectedValues = values || []
 | 
	
		
			
				|  |  | +      
 | 
	
		
			
				|  |  | +      // 获取选中的节点信息
 | 
	
		
			
				|  |  | +    //   const selectedNodes = this.$refs.cascader?.getCheckedNodes() || []
 | 
	
		
			
				|  |  | +      const selectedNodes = this.$refs.cascader ? this.$refs.cascader.getCheckedNodes() : []
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      let regionName = ''
 | 
	
		
			
				|  |  | +      let regionCode = ''
 | 
	
		
			
				|  |  | +      
 | 
	
		
			
				|  |  | +      if (values && values.length > 0) {
 | 
	
		
			
				|  |  | +        // 获取选中的节点信息
 | 
	
		
			
				|  |  | +        const selectedNodes = this.$refs.cascader.getCheckedNodes()
 | 
	
		
			
				|  |  | +        if (selectedNodes.length > 0) {
 | 
	
		
			
				|  |  | +          const node = selectedNodes[0]
 | 
	
		
			
				|  |  | +          regionName = node.pathLabels.join(' ')
 | 
	
		
			
				|  |  | +          regionCode = values[values.length - 1]
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 直接返回regionName作为组件的值,这样avue-crud可以正确验证
 | 
	
		
			
				|  |  | +      this.$emit('input', regionName)
 | 
	
		
			
				|  |  | +      this.$emit('change', {
 | 
	
		
			
				|  |  | +        values,
 | 
	
		
			
				|  |  | +        regionName,
 | 
	
		
			
				|  |  | +        regionCode
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 展开改变事件
 | 
	
		
			
				|  |  | +     * @param {Array} activeValues - 当前展开的值
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleExpandChange(activeValues) {
 | 
	
		
			
				|  |  | +      this.$emit('expand-change', activeValues)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</script>
 |