<template>
|
<div class="area-select">
|
<el-button v-if="!disabled" class="mb-10" type="primary" @click="openDialog"
|
>选择</el-button
|
>
|
<div class="tag-list">
|
<el-tag
|
v-for="item in value"
|
:key="item.city"
|
type="primary"
|
:closable="!disabled"
|
@close="onTagClose(item)"
|
>{{ item.province }}-{{ item.city }}</el-tag
|
>
|
</div>
|
<el-dialog
|
title="选择地区"
|
:visible.sync="dialogVisible"
|
append-to-body
|
:close-on-click-modal="false"
|
>
|
<div
|
v-for="item in districtList"
|
:key="item.code"
|
class="mb-10 p-10 border-dashed border-[#eee]"
|
>
|
<el-bus-checkbox
|
v-model="item.selected"
|
has-select-all
|
:from-dict="false"
|
:options="item.children"
|
:props="{ label: 'name', value: 'code', selectAllLabel: item.name }"
|
></el-bus-checkbox>
|
</div>
|
<div slot="footer" class="flex items-center justify-between">
|
<el-checkbox v-model="allChecked" @change="onCheckedChange"
|
>全选</el-checkbox
|
>
|
<div>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="onConfirm">确定</el-button>
|
</div>
|
</div>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import cloneDeep from 'lodash.clonedeep'
|
export default {
|
props: {
|
value: {
|
type: Array,
|
default: () => [],
|
},
|
disabled: {
|
type: Boolean,
|
default: false,
|
},
|
},
|
data() {
|
return {
|
list: [],
|
districtList: [],
|
dialogVisible: false,
|
allChecked: false,
|
}
|
},
|
mounted() {
|
this.getDistrictList()
|
},
|
methods: {
|
async getDistrictList() {
|
if (this.districtList.length === 0) {
|
const { code, data } = await this.$services.base.getAreaJson()
|
if (code === 0) {
|
const list = JSON.parse(data)
|
this.deleteRegion(list)
|
this.districtList = list
|
}
|
}
|
},
|
deleteRegion(list) {
|
list.forEach((province) => {
|
if (Array.isArray(province.children)) {
|
province.children.forEach((city) => {
|
city.parentName = province.name
|
if ('children' in city) {
|
delete city.children
|
}
|
})
|
}
|
})
|
},
|
getAreaStatus() {
|
return new Promise((resolve) => {
|
if (this.districtList.length > 0) {
|
resolve()
|
} else {
|
const timer = setInterval(() => {
|
if (this.districtList.length > 0) {
|
resolve()
|
clearTimeout(timer)
|
}
|
}, 100)
|
}
|
})
|
},
|
async openDialog() {
|
await this.getAreaStatus()
|
this.setSelectedCity()
|
this.dialogVisible = true
|
},
|
onCheckedChange(e) {
|
if (e) {
|
this.districtList.forEach((province) => {
|
if (Array.isArray(province.children)) {
|
province.selected = province.children.map((i) => i.code)
|
}
|
})
|
} else {
|
this.districtList.forEach((province) => {
|
province.selected = []
|
})
|
}
|
},
|
// 根据当前value选中弹出框中的城市
|
setSelectedCity() {
|
this.districtList.forEach((province) => {
|
const selectedCity = this.value
|
.filter((i) => i.province === province.code)
|
.map((i) => i.city)
|
province.selected = selectedCity
|
})
|
this.districtList = cloneDeep(this.districtList)
|
},
|
onConfirm() {
|
const value = this.districtList.reduce((total, current) => {
|
if (Array.isArray(current.selected) && current.selected.length > 0) {
|
total = total.concat(
|
current.selected.reduce((t, c) => {
|
t.push({ province: current.code, city: c })
|
return t
|
}, [])
|
)
|
}
|
return total
|
}, [])
|
this.$emit('input', value)
|
this.dialogVisible = false
|
},
|
onTagClose(item) {
|
const value = this.value.filter(
|
(i) => i.province !== item.province || i.city !== item.city
|
)
|
this.$emit('input', value)
|
},
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.area-select {
|
width: 100%;
|
.tag-list {
|
.el-tag {
|
margin-right: 6px;
|
margin-bottom: 6px;
|
}
|
}
|
}
|
</style>
|