You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
10 KiB
400 lines
10 KiB
7 months ago
|
<!-- @format -->
|
||
|
|
||
|
<template>
|
||
|
<div>
|
||
|
<div v-show="false">{{ getDetail }}</div>
|
||
|
|
||
|
<a-input
|
||
|
placeholder="请选择"
|
||
|
readonly="readonly"
|
||
|
style="cursor: pointer"
|
||
|
v-model:value="choiceCity"
|
||
|
@click.stop="showCard">
|
||
|
<template #suffix> <ns-icon name="drow" size="12" @click.stop="showCard" /></template>
|
||
|
</a-input>
|
||
|
<div v-show="visible" class="selectCard">
|
||
|
<header class="card_header">
|
||
|
<div :style="{ background: regionLevel === 1 ? '#fff' : '' }" @click.stop="check(1)"
|
||
|
>省</div
|
||
|
>
|
||
|
<div :style="{ background: regionLevel === 2 ? '#fff' : '' }" @click.stop="check(2)"
|
||
|
>市</div
|
||
|
>
|
||
|
<div :style="{ background: regionLevel === 3 ? '#fff' : '' }" @click.stop="check(3)"
|
||
|
>区</div
|
||
|
>
|
||
|
</header>
|
||
|
<ul>
|
||
|
<li
|
||
|
:class="choiceCity.split('/')[regionLevel - 1] === item.name ? 'isChoice' : ''"
|
||
|
@click.stop="choiceItem(item)"
|
||
|
v-for="item in data[regionLevel]"
|
||
|
:key="item.code"
|
||
|
>{{ item.name }}</li
|
||
|
>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script lang="ts">
|
||
|
import { defineComponent, ref, watch, computed } from 'vue';
|
||
|
import { http } from '/nerv-lib/util/http';
|
||
|
export default defineComponent({
|
||
|
name: 'NsInputCity',
|
||
|
props: {
|
||
|
value: {},
|
||
|
defaultHomeAddress: {
|
||
|
type: String,
|
||
|
default: '',
|
||
|
},
|
||
|
defaultProvinceCode: {
|
||
|
type: String,
|
||
|
default: '',
|
||
|
},
|
||
|
defaultCityCode: {
|
||
|
type: String,
|
||
|
default: '',
|
||
|
},
|
||
|
defaultAreaCode: {
|
||
|
type: String,
|
||
|
default: '',
|
||
|
},
|
||
|
api: {
|
||
|
type: String,
|
||
|
default: '',
|
||
|
},
|
||
|
isSeparate: {
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
},
|
||
|
emits: ['change'],
|
||
|
setup(props, context) {
|
||
|
const visible = ref(false);
|
||
|
let choiceCity = ref('');
|
||
|
let province = ref([]); //省
|
||
|
let city = ref([]); //市
|
||
|
let area = ref([]); //区
|
||
|
let provinceCode = ref('');
|
||
|
let cityCode = ref('');
|
||
|
let areaCode = ref('');
|
||
|
let addre = props.defaultHomeAddress.split('/');
|
||
|
if (props.defaultHomeAddress) {
|
||
|
context.emit('change', [
|
||
|
addre[0],
|
||
|
addre[1],
|
||
|
addre[2],
|
||
|
props.defaultProvinceCode,
|
||
|
props.defaultCityCode,
|
||
|
props.defaultAreaCode,
|
||
|
props.defaultHomeAddress,
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
choiceCity.value = props.defaultHomeAddress || '';
|
||
|
// province.value = addRe[0] || '';
|
||
|
// city.value = addRe[1] || '';
|
||
|
// area.value = addRe[2] || '';
|
||
|
provinceCode.value = props.defaultProvinceCode || '';
|
||
|
cityCode.value = props.defaultCityCode || '';
|
||
|
areaCode.value = props.defaultAreaCode || '';
|
||
|
|
||
|
const data = ref([]);
|
||
|
data.value[1] = province.value;
|
||
|
const regionLevel = ref(1);
|
||
|
const showCard = () => {
|
||
|
visible.value = true;
|
||
|
};
|
||
|
const closeCard = () => {
|
||
|
visible.value = false;
|
||
|
};
|
||
|
const check = (e) => {
|
||
|
regionLevel.value = e;
|
||
|
};
|
||
|
const initData = (regionLevel: Number, code?: Number) => {
|
||
|
switch (regionLevel) {
|
||
|
case 1:
|
||
|
province.value = [];
|
||
|
|
||
|
break;
|
||
|
case 2:
|
||
|
city.value = [];
|
||
|
data.value[3] = [];
|
||
|
break;
|
||
|
case 3:
|
||
|
area.value = [];
|
||
|
break;
|
||
|
}
|
||
|
async function getDate() {
|
||
|
try {
|
||
|
let date = {};
|
||
|
date.regionLevel = regionLevel;
|
||
|
code ? (date.parentCode = code) : '';
|
||
|
const res = await http.get(props.api || '/api/pension/pension/objs/BaseArea', date);
|
||
|
if (res.success) {
|
||
|
switch (regionLevel) {
|
||
|
case 1:
|
||
|
province.value = res.data;
|
||
|
break;
|
||
|
case 2:
|
||
|
city.value = res.data;
|
||
|
break;
|
||
|
case 3:
|
||
|
area.value = res.data;
|
||
|
break;
|
||
|
}
|
||
|
data.value[regionLevel] = res.data;
|
||
|
}
|
||
|
} catch (err) {
|
||
|
console.log(err);
|
||
|
}
|
||
|
}
|
||
|
getDate();
|
||
|
};
|
||
|
|
||
|
watch(
|
||
|
() => [
|
||
|
props.defaultHomeAddress,
|
||
|
props.defaultProvinceCode,
|
||
|
props.defaultCityCode,
|
||
|
props.defaultAreaCode,
|
||
|
],
|
||
|
([defaultHomeAddress, defaultProvinceCode, defaultCityCode, defaultAreaCode]) => {
|
||
|
if (defaultHomeAddress) {
|
||
|
choiceCity.value = defaultHomeAddress;
|
||
|
}
|
||
|
if (defaultProvinceCode) {
|
||
|
regionLevel.value = 1;
|
||
|
provinceCode.value = defaultProvinceCode;
|
||
|
regionLevel.value = 2;
|
||
|
initData(regionLevel.value, provinceCode.value);
|
||
|
}
|
||
|
if (defaultCityCode) {
|
||
|
regionLevel.value = 2;
|
||
|
cityCode.value = defaultCityCode;
|
||
|
initData(regionLevel.value, provinceCode.value);
|
||
|
regionLevel.value = 3;
|
||
|
initData(regionLevel.value, cityCode.value);
|
||
|
}
|
||
|
if (defaultAreaCode) {
|
||
|
areaCode.value = defaultAreaCode;
|
||
|
regionLevel.value = 3;
|
||
|
initData(regionLevel.value, cityCode.value);
|
||
|
}
|
||
|
},
|
||
|
);
|
||
|
const getDetail = computed(() => {
|
||
|
const { value } = props;
|
||
|
if (!value) {
|
||
|
regionLevel.value = 1;
|
||
|
choiceCity.value = '';
|
||
|
provinceCode.value = '';
|
||
|
cityCode.value = '';
|
||
|
areaCode.value = '';
|
||
|
//test.value = [];
|
||
|
} else {
|
||
|
}
|
||
|
// choiceCity.value = value;
|
||
|
return value;
|
||
|
});
|
||
|
watch(
|
||
|
() => props.value,
|
||
|
(value) => {
|
||
|
if (!value) {
|
||
|
data.value[2] = [];
|
||
|
data.value[3] = [];
|
||
|
}
|
||
|
},
|
||
|
{ deep: true },
|
||
|
);
|
||
|
|
||
|
return {
|
||
|
getDetail,
|
||
|
choiceCity,
|
||
|
showCard,
|
||
|
closeCard,
|
||
|
regionLevel,
|
||
|
check,
|
||
|
visible,
|
||
|
initData,
|
||
|
province,
|
||
|
city,
|
||
|
area,
|
||
|
provinceCode,
|
||
|
cityCode,
|
||
|
areaCode,
|
||
|
data,
|
||
|
};
|
||
|
},
|
||
|
watch: {
|
||
|
visible(val) {
|
||
|
val
|
||
|
? document.body.addEventListener('click', this.closeCard)
|
||
|
: document.body.removeEventListener('click', this.closeCard);
|
||
|
},
|
||
|
choiceCity(val) {
|
||
|
let info = { label: '', provinceCode: '', cityCode: '', areaCode: '' };
|
||
|
let addressArr = this.defaultHomeAddress.split('/');
|
||
|
info.provinceCode = this.provinceCode;
|
||
|
info.cityCode = this.cityCode;
|
||
|
info.areaCode = this.areaCode;
|
||
|
if (this.isSeparate) {
|
||
|
info.label = val.split('/');
|
||
|
this.$emit('change', [
|
||
|
info.label[0],
|
||
|
info.label[1],
|
||
|
info.label[2],
|
||
|
info.provinceCode,
|
||
|
info.cityCode,
|
||
|
info.areaCode,
|
||
|
val,
|
||
|
]);
|
||
|
} else {
|
||
|
info.label = val;
|
||
|
this.$emit('change', [info.label, info.provinceCode, info.cityCode, info.areaCode, val]);
|
||
|
}
|
||
|
},
|
||
|
// regionLevel(val) {
|
||
|
// switch (val) {
|
||
|
// case 1:
|
||
|
// this.data = this.province;
|
||
|
// break;
|
||
|
// case 2:
|
||
|
// this.data = this.city;
|
||
|
// // this.area = [];
|
||
|
// break;
|
||
|
// case 3:
|
||
|
// this.data = this.area;
|
||
|
// break;
|
||
|
// }
|
||
|
// },
|
||
|
},
|
||
|
created() {
|
||
|
this.initData(this.regionLevel);
|
||
|
},
|
||
|
methods: {
|
||
|
// initData(regionLevel: Number, code?: Number) {
|
||
|
// const that = this;
|
||
|
// switch (regionLevel) {
|
||
|
// case 1:
|
||
|
// that.province = [];
|
||
|
// break;
|
||
|
// case 2:
|
||
|
// that.city = [];
|
||
|
// break;
|
||
|
// case 3:
|
||
|
// that.area = [];
|
||
|
// break;
|
||
|
// }
|
||
|
// async function getDate() {
|
||
|
// try {
|
||
|
// let date = {};
|
||
|
// date.regionLevel = regionLevel;
|
||
|
// code ? (date.parentCode = code) : '';
|
||
|
// const res = await http.get('/api/pension/pension/objs/BaseArea', date);
|
||
|
// if (res.success) {
|
||
|
// switch (that.regionLevel) {
|
||
|
// case 1:
|
||
|
// that.province = res.data;
|
||
|
// break;
|
||
|
// case 2:
|
||
|
// that.city = res.data;
|
||
|
// break;
|
||
|
// case 3:
|
||
|
// that.area = res.data;
|
||
|
// break;
|
||
|
// }
|
||
|
// that.data = res.data;
|
||
|
// }
|
||
|
// } catch (err) {
|
||
|
// console.log(err);
|
||
|
// }
|
||
|
// }
|
||
|
// getDate();
|
||
|
// },
|
||
|
choiceItem(e: any) {
|
||
|
switch (this.regionLevel) {
|
||
|
case 1:
|
||
|
this.choiceCity = e.name;
|
||
|
this.provinceCode = e.code;
|
||
|
this.cityCode = '';
|
||
|
this.areaCode = '';
|
||
|
this.initData(2, e.code);
|
||
|
this.regionLevel = 2;
|
||
|
break;
|
||
|
case 2:
|
||
|
this.choiceCity = this.choiceCity.split('/')[0] + `/${e.name}`;
|
||
|
this.cityCode = e.code;
|
||
|
this.areaCode = '';
|
||
|
this.initData(3, e.code);
|
||
|
this.regionLevel = 3;
|
||
|
break;
|
||
|
case 3:
|
||
|
this.choiceCity =
|
||
|
this.choiceCity.split('/')[0] + '/' + this.choiceCity.split('/')[1] + `/${e.name}`;
|
||
|
this.areaCode = e.code;
|
||
|
this.closeCard();
|
||
|
break;
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
});
|
||
|
</script>
|
||
|
<style lang="less" scoped>
|
||
|
.selectCard {
|
||
|
position: absolute;
|
||
|
z-index: 4;
|
||
|
width: 300px;
|
||
|
height: 180px;
|
||
|
transform: translateY(5px);
|
||
|
box-shadow: 0 2px 8px rgb(0 0 0 / 15%);
|
||
|
animation: move-down 0.5s;
|
||
|
background: #fff;
|
||
|
border: 1px solid #ccc;
|
||
|
.card_header {
|
||
|
width: 100%;
|
||
|
height: 26px;
|
||
|
background: rgb(238, 238, 238);
|
||
|
display: flex;
|
||
|
justify-content: space-between;
|
||
|
border-bottom: 1px solid #ccc;
|
||
|
div {
|
||
|
text-align: center;
|
||
|
width: 34%;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
}
|
||
|
ul {
|
||
|
width: 100%;
|
||
|
height: 150px;
|
||
|
overflow: auto;
|
||
|
list-style: none;
|
||
|
padding: 10px;
|
||
|
li {
|
||
|
line-height: 30px;
|
||
|
cursor: pointer;
|
||
|
padding-left: 10px;
|
||
|
&:hover {
|
||
|
background-color: rgba(3, 141, 218, 0.1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
.isChoice {
|
||
|
color: rgb(3, 141, 218);
|
||
|
}
|
||
|
@keyframes move-down {
|
||
|
0% {
|
||
|
transform: scale(0);
|
||
|
height: 0px;
|
||
|
opacity: 0;
|
||
|
}
|
||
|
100% {
|
||
|
transform: scale(1);
|
||
|
height: 180px;
|
||
|
opacity: 1;
|
||
|
}
|
||
|
}
|
||
|
</style>
|