• 罗成兵's avatar
    1 · 6d01face
    罗成兵 authored
    6d01face
allAreaCascader.vue 7.15 KB
<template>
    <div>
        <a-cascader v-model="areaCode"
                    ref="cascader"
                    :style="{width:width}"
                    change-on-select
                    :disabled="disabled"
                    :options="options"
                    :fieldNames="fieldNames"
                    :load-data="loadAreaData"
                    @change="areaChange"
                    placeholder="请选择">
        </a-cascader>
    </div>
</template>
<!--

全国地区级联选择控件,包括回显数据

-->
<script>
export default {
    name: "allAreaCascader",
    props: ["disabled", "value", "width"],
    created() {
        this.loadAreaData([{areaCode: 0}]);
    },
    mounted() {
        this.handleAreaCode(this.value);
    },
    data() {
        return {
            areaCode: undefined,
            options: [],
            fieldNames: {
                label: 'areaName',
                value: 'areaCode',
                children: 'children'
            },
            areaData: {},
            optionsObj: {},
            number3: 0,
            number4: 0,
        };
    },
    watch: {
        //子组件中直接使用prop1
        value(newValue, oldValue) {
            this.handleAreaCode(newValue);
            //this.$emit( 'propChange',  newValue )
        }
    },
    methods: {
        handleAreaCode(areaCode) {
            if (this.$api.utils.isBlank(areaCode)) {
                this.areaCode = [];
                return;
            }
            let level = 1;
            if (areaCode.length == 2) {
                this.areaCode = [areaCode];
                return;
            }
            let provinceCode = areaCode.substring(0, 2);
            let cityCodeFull = areaCode.substring(0, 4) + "00000000";
            let countyCode, townshipCode, villageCode;
            let countyCodeFull, townshipCodeFull;
            level = 2;
            if (areaCode.substring(2, 4) != '00') {
                level = 3
                countyCode = areaCode.substring(0, 6);
                countyCodeFull = areaCode.substring(0, 6) + "000000";
                if (areaCode.substring(4, 6) != '00') {
                    level = 4;
                    townshipCode = areaCode.substring(0, 9);
                    townshipCodeFull = areaCode.substring(0, 9) + "000";
                    if (areaCode.substring(6, 9) != '000') {
                        level = 5;
                        villageCode = areaCode.substring(0, 12);
                    }
                }
            }
            let areaCodeList = [provinceCode, cityCodeFull, countyCodeFull, townshipCodeFull, villageCode];
            if (level > 1) {
                this.$api.common.fetchAreaByCode(provinceCode).then(({data = []}) => {
                    this.handleData(data, 2, cityCodeFull);
                    if (level > 2) {
                        this.$api.common.fetchAreaByCode(cityCodeFull).then(({data = []}) => {
                            this.handleData(data, 3, cityCodeFull);
                            if (level > 3) {
                                this.$api.common.fetchAreaByCode(countyCodeFull).then(({data = []}) => {
                                    this.handleData(data, 4, countyCodeFull);
                                    if (level > 4) {
                                        this.$api.common.fetchAreaByCode(townshipCodeFull).then(({data = []}) => {
                                            this.handleData(data, 5, townshipCodeFull);
                                            this.areaCode = areaCodeList;
                                            this.isEndHandle(provinceCode)
                                        });
                                    } else {
                                        this.isEndHandle(provinceCode)
                                        this.areaCode = areaCodeList;
                                    }
                                })
                            } else {
                                this.areaCode = areaCodeList;
                                this.isEndHandle(provinceCode)
                            }
                        })
                    } else {
                        this.areaCode = areaCodeList;
                        this.isEndHandle(provinceCode)
                    }
                })
            } else {
                this.areaCode = areaCodeList;
                this.isEndHandle(provinceCode)
            }
        },
        isEndHandle(provinceCode) {
            this.options.forEach(x => {
                if (x.areaCode == provinceCode) {
                    x.children = this.optionsObj;
                }
            })
        },
        handleData(data, level, areaCode) {
            if (this.$api.utils.isBlank(data)) {
                return;
            }
            data.forEach(item => {
                item['isLeaf'] = item.areaLevel >= 5;
            });
            if (level == 2) {
                this.optionsObj = data;
            }
            if (level == 3) {
                let number3 = 0;
                this.optionsObj.forEach(x => {
                    if (x.areaCode == areaCode) {
                        x.children = data;
                        this.number3 = number3;
                    }
                    number3++;
                })
            }
            if (level == 4) {
                let number4 = 0;
                this.optionsObj[this.number3].children.forEach(x => {
                    if (x.areaCode == areaCode) {
                        x.children = data;
                        this.number4 = number4;
                    }
                    number4++;
                })
            }
            if (level == 5) {
                this.optionsObj[this.number3].children[this.number4].children.forEach(x => {
                    if (x.areaCode == areaCode) {
                        x.children = data;
                    }
                })
            }
        },
        loadAreaData(selectedOptions) {
            const targetOption = selectedOptions[selectedOptions.length - 1];
            targetOption.loading = true;
            this.$api.common.fetchAreaByCode(targetOption.areaCode).then(({data = []}) => {
                targetOption.loading = false;
                if (this.$api.utils.isBlank(data)) {
                    return;
                }
                data.forEach(item => {
                    item['isLeaf'] = item.areaLevel >= 5;
                })
                if (targetOption.areaCode == 0) {
                    this.options = [...data];
                } else {
                    targetOption.children = [...data]
                    this.options = [...this.options]
                }
            })
        },
        setValue(areaCode) {
            this.handleAreaCode(areaCode);
        },
        getValue() {
            return this.areaCode;
        },
        areaChange(areaCode) {
            if (areaCode.length == 0) {
                this.$emit("input", "");
                return;
            }
            this.$emit("input", areaCode[areaCode.length - 1])
        },
        focus() {
            let input = this.$refs["cascader"];
            input.focus();
        }
    }
}
</script>

<style scoped>

</style>