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

4 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>