blob: bfdd9ad7a4ee631c2c9e29cf7393b6a2af7531af [file]
<!--
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<template>
<el-row :gutter="10" :span="24">
<template v-if="!detail">
<el-col :span="span">
<!-- style="width:calc(100% - 6px);" -->
<el-select v-model="province" clearable placeholder="请选择" class="w-206">
<el-option label="全国" value="" v-if="showAll"></el-option>
<el-option v-for="item in Provinces" :key="item.provCode" :label="item.provName" :value="item.provCode">
</el-option>
</el-select>
</el-col>
<el-col :span="span">
<!-- style="width:calc(100% - 6px);" -->
<el-select v-model="city" clearable placeholder="请选择" class="w-206">
<el-option v-for="item in Cities" :key="item.cityCode" :label="item.cityName" :value="item.cityCode">
</el-option>
</el-select>
</el-col>
<el-col :span="span">
<!-- style="width:calc(100% - 6px);" -->
<el-select v-model="country" clearable placeholder="请选择" class="w-206">
<el-option v-for="item in Countries" :key="item.regiCode" :label="item.regiName" :value="item.regiCode">
</el-option>
</el-select>
</el-col>
</template>
<span v-else>{{currentProvince}} {{currentCity}}{{currentCountry}}</span>
<slot></slot>
</el-row>
</template>
<script>
export default {
name: 'AddrSelect',
props: {
// v-model 绑定
value: {
type: String,
required: true,
default: ''
},
// 传输值的分隔符
symbol: {
type: String,
default: '@'
},
// 是否展示“全国”选项,表单搜索情况下需要
showAll: {
type: Boolean,
default: true
},
span: {
type: Number,
default: 8
},
detail: {
type: Boolean
}
},
data () {
return {
setValueing: false, // 是否正在一串异步设置选择值过程中,在此期间,不能更新相关的值,只能清空对应的表单
province: '',
city: '',
country: '',
Provinces: [],
Cities: [],
Countries: []
}
},
computed: {
addr () {
return this.value ? this.value.replace(/null/g, '').split(this.symbol) : []
},
currentProvince () {
return this.getAddress(this.Provinces, this.province, 'provCode', 'provName')
},
currentCity () {
return this.getAddress(this.Cities, this.city, 'cityCode', 'cityName')
},
currentCountry () {
return this.getAddress(this.Countries, this.country, 'regiCode', 'regiName')
}
},
watch: {
province (v) {
this.Cities = []
this.Countries = []
if (this.setValueing) {
return
}
this.city = ''
this.country = ''
v && this.getCities(v)
this.emitValue()
},
city (v) {
this.Countries = []
if (this.setValueing) {
return
}
this.country = ''
v && this.getCountries(v)
this.emitValue()
},
country () {
this.emitValue()
},
value (v) {
console.log(v, 'v')
if (v && v.indexOf(this.symbol) === -1) {
this.$message.warning('未识别的地址格式,请重新选择')
return
}
if (!v) {
this.clear()
}
this.setAddr()
}
},
methods: {
getAddress (array, val, key, target) {
let result = ''
for (let index = 0; index < array.length; index++) {
const element = array[index][key]
if (element === val) {
result = array[index][target]
break
}
}
return result
},
emitValue () {
this.$emit('input', [this.province, this.city, this.country].join(this.symbol))
this.$emit('selected', {
province: this.province,
city: this.city,
country: this.country
})
},
setAddr () {
if (this.setValueing) {
return
}
this.setValueing = true
this.getProvincesIfNeeded()
.then(() => {
this.province = this.addr[0] || ''
if (this.province) {
return Promise.resolve(true)
} else {
return Promise.reject(false)
}
})
.then(this.getCitiesIfNeeded)
.then(() => {
this.city = this.addr[1] || ''
if (this.city) {
return Promise.resolve(true)
} else {
return Promise.reject(false)
}
})
.then(this.getCountriesIfNeeded)
.then(() => {
this.country = this.addr[2] || ''
})
.catch(err => {
console.log(err)
})
.finally(() => {
this.setValueing = false
})
},
clear () {
this.province = ''
this.city = ''
this.country = ''
},
getProvincesIfNeeded () {
return new Promise((resolve, reject) => {
if (this.Provinces.length) {
resolve(true)
}
this.getProvinces().then(res => {
if (this.Provinces.length) {
resolve(true)
} else {
reject(false)
}
}).catch(() => {
reject(false)
})
})
},
getCitiesIfNeeded () {
return new Promise((resolve, reject) => {
if (this.Cities.length) {
resolve(true)
}
this.getCities(this.province).then(res => {
if (this.Cities.length) {
resolve(true)
} else {
reject(false)
}
}).catch(() => {
reject(false)
})
})
},
getCountriesIfNeeded () {
return new Promise((resolve, reject) => {
if (this.Countries.length) {
resolve(true)
}
this.getCountries(this.city).then(res => {
if (this.Countries.length) {
resolve(true)
} else {
reject(false)
}
}).catch(() => {
reject(false)
})
})
},
getProvinces () {
return this.$http.get('/basic/province').then(res => {
res = res.data
if (res.code === 200) {
this.Provinces = res.data || []
} else {
this.$message.error(res.msg)
}
}).catch(err => {
this.$message.error('网络错误,请重试!')
})
},
getCities (key) {
return this.$http.get('/basic/city', {
params: {
key
}
}).then(res => {
res = res.data
if (res.code === 200) {
this.Cities = res.data || []
} else {
this.Cities = []
this.$message.error(res.msg)
}
}).catch(err => {
this.Cities = []
this.$message.error('网络错误,请重试!')
})
},
getCountries (key) {
return this.$http.get('/basic/region', {
params: {
key
}
}).then(res => {
res = res.data
if (res.code === 200) {
this.Countries = res.data || []
} else {
this.Countries = []
this.$message.error(res.msg)
}
}).catch(err => {
this.Countries = []
this.$message.error('网络错误,请重试!')
})
},
findKeybyName (name, type) {
if (type === 'province') {
return this.Provinces.find(p => {
return p.provName === name
}).provId
} else if (type === 'city') {
return this.Cities.find(p => {
return p.cityName === name
}).cityId
} else {
return this.Countries.find(p => {
return p.regiName === name
}).regiId
}
}
},
created () {
this.setAddr()
},
mounted () {
}
}
</script>
<style scoped lang='scss'>
</style>