push
This commit is contained in:
366
lib/component/form/input/input-cityV2.vue
Normal file
366
lib/component/form/input/input-cityV2.vue
Normal file
@@ -0,0 +1,366 @@
|
||||
<!-- @format -->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-input
|
||||
placeholder="请选择"
|
||||
readonly="readonly"
|
||||
style="cursor: pointer"
|
||||
v-model:value="choiceCityName"
|
||||
@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[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 { cloneDeep, isArray, isEqual, isObject } from 'lodash-es';
|
||||
import { defineComponent, ref, watch, computed, onMounted } from 'vue';
|
||||
import { http } from '/nerv-lib/util/http';
|
||||
export default defineComponent({
|
||||
name: 'NsInputCityV2',
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
defaultValue: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
api: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
fieldMap: {
|
||||
type: Object || Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
formModel: {
|
||||
type: Object || Array,
|
||||
},
|
||||
isSeparate: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['change'],
|
||||
setup(props, { emit }) {
|
||||
// console.log(props);
|
||||
const visible = ref(false);
|
||||
const hasload = ref(false);
|
||||
let choiceCity = ref<any[]>([]);
|
||||
let choiceCityName = ref('');
|
||||
let province = ref([]); //省
|
||||
let city = ref([]); //市
|
||||
let area = ref([]); //区
|
||||
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;
|
||||
initData(regionLevel.value);
|
||||
};
|
||||
|
||||
const choiceItem = (e: any) => {
|
||||
let currObject = [
|
||||
{ name: 0, code: 3, enmpitIndex: [1, 2, 4, 5] },
|
||||
{ name: 1, code: 4, enmpitIndex: [2, 5] },
|
||||
{ name: 2, code: 5, enmpitIndex: [] },
|
||||
];
|
||||
let enmpitIndex = [[1, 2, 4, 5], [2, 5], []][regionLevel.value - 1];
|
||||
let cureleve: { name: number; code: number; enmpitIndex: any[] } =
|
||||
currObject[regionLevel.value - 1];
|
||||
const update = () => {
|
||||
let copecity = cloneDeep(choiceCity.value);
|
||||
Object.keys(cureleve).forEach((el: string) => {
|
||||
let index = cureleve[el];
|
||||
let value = e[el];
|
||||
copecity[index] = value;
|
||||
});
|
||||
enmpitIndex.forEach((el) => {
|
||||
copecity[el] = null;
|
||||
});
|
||||
choiceCity.value = [...copecity];
|
||||
};
|
||||
switch (regionLevel.value) {
|
||||
case 1:
|
||||
update();
|
||||
regionLevel.value = 2;
|
||||
initData(2, e.code);
|
||||
break;
|
||||
case 2:
|
||||
update();
|
||||
regionLevel.value = 3;
|
||||
initData(3, e.code);
|
||||
break;
|
||||
case 3:
|
||||
update();
|
||||
closeCard();
|
||||
break;
|
||||
}
|
||||
};
|
||||
const initData = (regionLevel: Number, code?: Number) => {
|
||||
let parentcode = '';
|
||||
switch (regionLevel) {
|
||||
case 1:
|
||||
province.value = [];
|
||||
data.value[2] = [];
|
||||
data.value[3] = [];
|
||||
break;
|
||||
case 2:
|
||||
parentcode = choiceCity.value[3];
|
||||
city.value = [];
|
||||
data.value[3] = [];
|
||||
break;
|
||||
case 3:
|
||||
parentcode = choiceCity.value[4];
|
||||
area.value = [];
|
||||
break;
|
||||
}
|
||||
async function getDate() {
|
||||
try {
|
||||
let body: Recordable = {};
|
||||
body['regionLevel'] = regionLevel;
|
||||
if (parentcode || regionLevel == 1) {
|
||||
body.parentCode = parentcode;
|
||||
const res = await http.get(props.api || '/api/pension/pension/objs/BaseArea', body);
|
||||
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();
|
||||
};
|
||||
const updateValue = (newv) => {
|
||||
let leve = 0;
|
||||
let code = '';
|
||||
let cityMap = newv;
|
||||
newv.forEach((el, i) => {
|
||||
if (el) {
|
||||
leve = i;
|
||||
}
|
||||
});
|
||||
if (!props.isSeparate) {
|
||||
regionLevel.value = leve > 0 ? leve : 1;
|
||||
} else {
|
||||
regionLevel.value = leve > 2 ? leve - 2 : 1;
|
||||
}
|
||||
regionLevel.value == 1 ? '' : (code = cityMap[leve - 1]);
|
||||
if (!props.isSeparate) {
|
||||
newv.forEach((el, i) => {
|
||||
if (i === 0) {
|
||||
let cityNameList = el.split('/');
|
||||
cityNameList.forEach((item, index) => {
|
||||
cityMap[index] = item;
|
||||
});
|
||||
} else {
|
||||
cityMap[i + 3] = el;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cityMap = newv;
|
||||
}
|
||||
choiceCity.value = cityMap;
|
||||
initData(regionLevel.value, code);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initData(regionLevel.value);
|
||||
if (isArray(props.value) && props.value.length) {
|
||||
updateValue(props.value);
|
||||
}
|
||||
if (props.defaultValue.length) {
|
||||
updateValue(props.defaultValue);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => choiceCity.value,
|
||||
(newv, oldv) => {
|
||||
if (newv) {
|
||||
let list = [];
|
||||
newv.forEach((el, i) => {
|
||||
if (el && i < 3) {
|
||||
list.push(el);
|
||||
}
|
||||
});
|
||||
choiceCityName.value = list.join('/');
|
||||
if (!props.isSeparate) {
|
||||
emit('change', [choiceCityName, ...newv.slice(1)]);
|
||||
} else {
|
||||
emit('change', newv);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(newv, oldv) => {
|
||||
if (!isEqual(newv, oldv) && !isEqual(newv, choiceCity.value)) {
|
||||
updateValue(newv);
|
||||
}
|
||||
if (props.value?.length > 5 && props.value[4]) {
|
||||
regionLevel.value = 3;
|
||||
initData(regionLevel.value);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.formModel,
|
||||
(newv, oldv) => {
|
||||
if (newv && !props.value.length && props.fieldMap.length && !hasload.value) {
|
||||
let cityMap = [];
|
||||
let leve = 0;
|
||||
let code = '';
|
||||
props.fieldMap.forEach((el, i) => {
|
||||
cityMap[i] = newv[el];
|
||||
if (newv[el]) {
|
||||
leve = i;
|
||||
}
|
||||
});
|
||||
if (!props.isSeparate) {
|
||||
regionLevel.value = leve > 0 ? leve : 1;
|
||||
} else {
|
||||
regionLevel.value = leve > 2 ? leve - 2 : 1;
|
||||
}
|
||||
regionLevel.value == 1 ? '' : (code = cityMap[leve - 1]);
|
||||
// choiceCity.value = cityMap;
|
||||
updateValue(cityMap, code);
|
||||
hasload.value = true;
|
||||
}
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => visible.value,
|
||||
(val) => {
|
||||
val
|
||||
? document.body.addEventListener('click', closeCard)
|
||||
: document.body.removeEventListener('click', closeCard);
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
choiceCity,
|
||||
showCard,
|
||||
closeCard,
|
||||
regionLevel,
|
||||
check,
|
||||
choiceItem,
|
||||
visible,
|
||||
province,
|
||||
city,
|
||||
area,
|
||||
data,
|
||||
choiceCityName,
|
||||
};
|
||||
},
|
||||
});
|
||||
</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>
|
||||
Reference in New Issue
Block a user