| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- <template>
- <el-cascader
- v-model="selectedValue"
- :options="options"
- :props="cascaderProps"
- :placeholder="placeholder"
- :disabled="disabled"
- :style="{ width: width }"
- filterable
- clearable
- collapse-tags
- collapse-tags-tooltip
- separator="/"
- @change="handleChange"
- @clear="handleClear"
- />
- </template>
- <script lang="ts" setup>
- import { ref, watch, computed, onMounted, nextTick } from 'vue'
- import { treePosition } from '@/api/system/position'
- const props = defineProps<{
- modelValue: any
- disabled?: boolean
- width?: string
- placeholder?: string
- }>()
- const emits = defineEmits(['update:modelValue', 'change'])
- const options = ref<any[]>([])
- const loading = ref(false)
- const selectedValue = ref<any[]>([])
- const dataLoaded = ref(false)
- const placeholder = computed(() => props.placeholder || '请选择安装位置')
- const cascaderProps = {
- value: 'code',
- label: 'name',
- children: 'children',
- expandTrigger: 'hover' as const
- }
- const loadData = async () => {
- if (dataLoaded.value) return
- loading.value = true
- try {
- const response = await treePosition()
- options.value = response.data || []
- dataLoaded.value = true
-
- // 等待DOM更新后再设置选中值
- await nextTick()
- await nextTick()
-
- if (props.modelValue) {
- updateSelectedValue(props.modelValue)
- }
- } catch (error) {
- console.error('获取位置列表失败:', error)
- } finally {
- loading.value = false
- }
- }
- const updateSelectedValue = (value: any) => {
- if (value && typeof value === 'object') {
- const obj = value as any
- selectedValue.value = [obj.terminlCode, obj.regionalCode, obj.channelCode].filter(Boolean)
- } else {
- selectedValue.value = []
- }
- }
- const findNodeByCode = (nodes: any[], code: string): any | null => {
- for (const node of nodes) {
- if (node.code === code) {
- return node
- }
- if (node.children && node.children.length > 0) {
- const found = findNodeByCode(node.children, code)
- if (found) return found
- }
- }
- return null
- }
- const handleChange = (value: any) => {
- console.log(value,"value")
- if (!value || value.length === 0) {
- selectedValue.value = []
- emits('update:modelValue', null)
- emits('change', null)
- return
- }
-
- const terminal = findNodeByCode(options.value, value[0])
- const region = value[1] ? findNodeByCode(options.value, value[1]) || (terminal?.children?.find((c: any) => c.code === value[1])) : null
- const channel = value[2] ? (region?.children?.find((c: any) => c.code === value[2])) : null
-
- const result = {
- terminlCode: value[0] || '',
- terminlName: terminal?.name || '',
- regionalCode: value[1] || '',
- regionalName: region?.name || '',
- channelCode: value[2] || '',
- channelName: channel?.name || ''
- }
-
- emits('update:modelValue', result)
- emits('change', result)
- }
- const handleClear = () => {
- selectedValue.value = []
- emits('update:modelValue', null)
- emits('change', null)
- }
- watch(() => props.modelValue, async (newValue) => {
- if (newValue) {
- if (!dataLoaded.value) {
- await loadData()
- } else {
- await nextTick()
- updateSelectedValue(newValue)
- }
- }
- }, { deep: true, immediate: true })
- watch(() => options.value, (newOptions) => {
- if (newOptions.length > 0 && props.modelValue) {
- nextTick(() => {
- updateSelectedValue(props.modelValue)
- })
- }
- }, { immediate: false })
- onMounted(() => {
- loadData()
- })
- </script>
- <style scoped>
- </style>
|