|
|
@@ -1,47 +1,61 @@
|
|
|
<template>
|
|
|
- <el-dialog :close-on-click-modal="false"
|
|
|
- :visible.sync="addressView"
|
|
|
- append-to-body
|
|
|
- class="modal"
|
|
|
- title="选择城市" width="950px">
|
|
|
+ <el-dialog
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :visible.sync="addressView"
|
|
|
+ append-to-body
|
|
|
+ class="modal"
|
|
|
+ title="选择城市"
|
|
|
+ width="950px"
|
|
|
+ >
|
|
|
<el-row :gutter="24" type="flex">
|
|
|
<el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" class="item">
|
|
|
<div class="check-btn">
|
|
|
- <el-checkbox v-model="iSselect" @change="allCheckbox">全选</el-checkbox>
|
|
|
+ <el-checkbox :value="iSselect" @change="onSelectAll">全选</el-checkbox>
|
|
|
<div class="empty" @click="empty">清空</div>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
- <el-row :gutter="24" :loading="loading" >
|
|
|
- <el-col :xl="6" :lg="6" :md="6" :sm="8" :xs="6" class="item" v-for="(item,index) in cityList" :key="index">
|
|
|
- <div @mouseenter="enter(index)" @mouseleave="leave()" v-if="item.level==1">
|
|
|
- <el-checkbox
|
|
|
- v-model="item.checked"
|
|
|
- :label="item.cityName"
|
|
|
- :disabled="item.disabled"
|
|
|
- @change="checkedClick(index)"
|
|
|
- :class="{ 'disabled-checkbox': item.disabled }"
|
|
|
- >{{item.cityName}}</el-checkbox>
|
|
|
- <div class="city" v-show="activeCity===index">
|
|
|
+
|
|
|
+ <el-row :gutter="24" v-loading="loading">
|
|
|
+ <el-col
|
|
|
+ :xl="6" :lg="6" :md="6" :sm="8" :xs="6"
|
|
|
+ class="item"
|
|
|
+ v-for="(item, index) in cityList"
|
|
|
+ :key="'p-' + item.cityId"
|
|
|
+ >
|
|
|
+ <div class="province-wrap" v-if="item.level == 1">
|
|
|
+ <div class="province-row">
|
|
|
+ <el-checkbox
|
|
|
+ :value="item.checked"
|
|
|
+ :indeterminate="item.indeterminate"
|
|
|
+ :disabled="item.disabled"
|
|
|
+ @change="(val) => onProvinceChange(index, val)"
|
|
|
+ :class="{ 'disabled-checkbox': item.disabled }"
|
|
|
+ >{{ item.cityName }}</el-checkbox>
|
|
|
+ <span
|
|
|
+ v-if="item.children && item.children.length"
|
|
|
+ class="expand-btn"
|
|
|
+ @click.stop="toggleExpand(index)"
|
|
|
+ >{{ activeCity === index ? '收起' : '展开' }}</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="city-panel" v-show="activeCity === index">
|
|
|
<div class="checkBox">
|
|
|
- <div class="arrow"></div>
|
|
|
- <div>
|
|
|
- <el-checkbox
|
|
|
- v-model="subitem.checked"
|
|
|
- :label="subitem.cityName"
|
|
|
- :disabled="subitem.disabled"
|
|
|
- @change="primary(index,subindex)"
|
|
|
- class="itemn"
|
|
|
- v-for="(subitem,subindex) in item.children"
|
|
|
- :key="subindex"
|
|
|
- :class="{ 'disabled-checkbox': subitem.disabled }"
|
|
|
- >{{subitem.cityName}}</el-checkbox>
|
|
|
- </div>
|
|
|
+ <el-checkbox
|
|
|
+ v-for="(subitem, subindex) in item.children"
|
|
|
+ :key="'c-' + subitem.cityId"
|
|
|
+ class="itemn"
|
|
|
+ :value="subitem.checked"
|
|
|
+ :disabled="subitem.disabled"
|
|
|
+ @change="(val) => onCityChange(index, subindex, val)"
|
|
|
+ :class="{ 'disabled-checkbox': subitem.disabled }"
|
|
|
+ >{{ subitem.cityName }}</el-checkbox>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
+
|
|
|
<div slot="footer">
|
|
|
<el-button @click="close">取消</el-button>
|
|
|
<el-button type="primary" @click="confirm">确定</el-button>
|
|
|
@@ -50,7 +64,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import {getAllList} from "@/api/hisStore/city";
|
|
|
+import { getAllList } from '@/api/hisStore/city'
|
|
|
|
|
|
export default {
|
|
|
name: 'CityZm',
|
|
|
@@ -74,397 +88,356 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- enter(index) {
|
|
|
- this.activeCity = index;
|
|
|
- },
|
|
|
- leave() {
|
|
|
- this.activeCity = null;
|
|
|
+ /** 点击展开/收起市级列表(不用 hover,即时响应) */
|
|
|
+ toggleExpand(index) {
|
|
|
+ this.activeCity = this.activeCity === index ? -1 : index
|
|
|
},
|
|
|
+
|
|
|
getCityList() {
|
|
|
- this.loading = true;
|
|
|
+ this.loading = true
|
|
|
+ this.activeCity = -1
|
|
|
+ this.iSselect = false
|
|
|
getAllList().then(res => {
|
|
|
- this.loading = false;
|
|
|
- console.log(res.data)
|
|
|
- var data = res.data;
|
|
|
- this.cityList = data.filter(item => item.level === 1)
|
|
|
-
|
|
|
- this.cityList.forEach((item, index, arr) => {
|
|
|
- // 加载市的数据
|
|
|
- var subData = data.filter(subitem => subitem.parentId === item.cityId && subitem.level === 2)
|
|
|
- console.log(subData)
|
|
|
- item.children = subData;
|
|
|
-
|
|
|
- // 加载县的数据到每个市下
|
|
|
- item.children.forEach((city, cityIndex) => {
|
|
|
- var countyData = data.filter(county => county.parentId === city.cityId && county.level === 3);
|
|
|
- if (countyData && countyData.length > 0) {
|
|
|
- city.children = countyData;
|
|
|
- }
|
|
|
- });
|
|
|
+ this.loading = false
|
|
|
+ const data = res.data || []
|
|
|
+ const provinces = data.filter(item => item.level === 1)
|
|
|
+
|
|
|
+ provinces.forEach(province => {
|
|
|
+ const cities = data.filter(
|
|
|
+ sub => sub.parentId === province.cityId && sub.level === 2
|
|
|
+ )
|
|
|
+ cities.forEach(city => {
|
|
|
+ const counties = data.filter(
|
|
|
+ county => county.parentId === city.cityId && county.level === 3
|
|
|
+ )
|
|
|
+ this.$set(city, 'children', counties)
|
|
|
+ this.$set(city, 'checked', false)
|
|
|
+ this.$set(city, 'disabled', false)
|
|
|
+ counties.forEach(county => {
|
|
|
+ this.$set(county, 'checked', false)
|
|
|
+ this.$set(county, 'disabled', false)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.$set(province, 'children', cities)
|
|
|
+ this.$set(province, 'checked', false)
|
|
|
+ this.$set(province, 'indeterminate', false)
|
|
|
+ this.$set(province, 'disabled', false)
|
|
|
+ this.$set(province, 'count', 0)
|
|
|
+ this.markSelectedCities(province)
|
|
|
+ })
|
|
|
|
|
|
- // 标记已选择的城市
|
|
|
- this.markSelectedCities(item);
|
|
|
- });
|
|
|
+ this.cityList = provinces
|
|
|
})
|
|
|
},
|
|
|
- // 标记已选择的城市为禁用状态
|
|
|
+
|
|
|
+ /** 已选城市禁用(外部传入 selectedCities) */
|
|
|
markSelectedCities(province) {
|
|
|
- let that = this;
|
|
|
- if (!that.selectedCities || that.selectedCities.length === 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (!this.selectedCities || this.selectedCities.length === 0) return
|
|
|
|
|
|
- // 检查是否选择了整个省(children为空数组或不存在)
|
|
|
- let selectedProvince = that.selectedCities.find(city => {
|
|
|
+ const selectedProvince = this.selectedCities.find(city => {
|
|
|
if (city.cityId === province.cityId) {
|
|
|
- // 如果没有children属性,或者children是空数组,说明选择了整个省
|
|
|
- return !city.children || city.children.length === 0;
|
|
|
+ return !city.children || city.children.length === 0
|
|
|
}
|
|
|
- return false;
|
|
|
- });
|
|
|
+ return false
|
|
|
+ })
|
|
|
|
|
|
if (selectedProvince) {
|
|
|
- // 整个省已选择,禁用省和所有市
|
|
|
- that.$set(province, 'disabled', true);
|
|
|
- if (province.children && province.children.length > 0) {
|
|
|
- province.children.forEach((city, cityIndex) => {
|
|
|
- that.$set(province.children[cityIndex], 'disabled', true);
|
|
|
- // 如果市下有县,也禁用所有县
|
|
|
- if (city.children && city.children.length > 0) {
|
|
|
- city.children.forEach((county, countyIndex) => {
|
|
|
- that.$set(province.children[cityIndex].children[countyIndex], 'disabled', true);
|
|
|
- });
|
|
|
+ this.$set(province, 'disabled', true)
|
|
|
+ ;(province.children || []).forEach((city, cityIndex) => {
|
|
|
+ this.$set(province.children[cityIndex], 'disabled', true)
|
|
|
+ ;(city.children || []).forEach((county, countyIndex) => {
|
|
|
+ this.$set(province.children[cityIndex].children[countyIndex], 'disabled', true)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const selectedCityMap = new Map()
|
|
|
+ this.selectedCities.forEach(selectedCity => {
|
|
|
+ if (selectedCity.cityId === province.cityId && selectedCity.children && selectedCity.children.length > 0) {
|
|
|
+ selectedCity.children.forEach(child => {
|
|
|
+ if (!selectedCityMap.has(child.cityId)) {
|
|
|
+ selectedCityMap.set(child.cityId, new Set())
|
|
|
}
|
|
|
- });
|
|
|
+ if (child.children && child.children.length > 0) {
|
|
|
+ child.children.forEach(county => {
|
|
|
+ selectedCityMap.get(child.cityId).add(county.cityId)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
- } else {
|
|
|
- // 检查是否有部分市被选择
|
|
|
- let selectedCityMap = new Map(); // 存储已选择的市及其县信息
|
|
|
- that.selectedCities.forEach(selectedCity => {
|
|
|
- if (selectedCity.cityId === province.cityId && selectedCity.children && selectedCity.children.length > 0) {
|
|
|
- // 该省下有选择的市
|
|
|
- selectedCity.children.forEach(child => {
|
|
|
- if (!selectedCityMap.has(child.cityId)) {
|
|
|
- selectedCityMap.set(child.cityId, new Set());
|
|
|
- }
|
|
|
- // 如果市下有选择的县,记录县的ID
|
|
|
- if (child.children && child.children.length > 0) {
|
|
|
- child.children.forEach(county => {
|
|
|
- selectedCityMap.get(child.cityId).add(county.cityId);
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (selectedCityMap.size > 0) {
|
|
|
- // 检查该省下所有市是否都被选择
|
|
|
- let allCitiesSelected = true;
|
|
|
- if (province.children && province.children.length > 0) {
|
|
|
- province.children.forEach(city => {
|
|
|
- if (!selectedCityMap.has(city.cityId)) {
|
|
|
- allCitiesSelected = false;
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
- allCitiesSelected = false;
|
|
|
- }
|
|
|
+ })
|
|
|
|
|
|
- // 如果所有市都被选择,禁用整个省
|
|
|
- if (allCitiesSelected) {
|
|
|
- that.$set(province, 'disabled', true);
|
|
|
- }
|
|
|
+ if (selectedCityMap.size === 0) return
|
|
|
|
|
|
- // 标记已选择的市为禁用,并检查市下的县
|
|
|
- if (province.children && province.children.length > 0) {
|
|
|
- province.children.forEach((city, cityIndex) => {
|
|
|
- if (selectedCityMap.has(city.cityId)) {
|
|
|
- // 该市已被选择
|
|
|
- let selectedCountyIds = selectedCityMap.get(city.cityId);
|
|
|
-
|
|
|
- // 检查是否选择了整个市(没有选择具体的县,或者县列表为空)
|
|
|
- let citySelectedData = null;
|
|
|
- that.selectedCities.forEach(selectedCity => {
|
|
|
- if (selectedCity.cityId === province.cityId && selectedCity.children) {
|
|
|
- let foundCity = selectedCity.children.find(c => c.cityId === city.cityId);
|
|
|
- if (foundCity && (!foundCity.children || foundCity.children.length === 0)) {
|
|
|
- citySelectedData = foundCity;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (citySelectedData) {
|
|
|
- // 选择了整个市,禁用该市和所有县
|
|
|
- that.$set(province.children[cityIndex], 'disabled', true);
|
|
|
- if (city.children && city.children.length > 0) {
|
|
|
- city.children.forEach((county, countyIndex) => {
|
|
|
- that.$set(province.children[cityIndex].children[countyIndex], 'disabled', true);
|
|
|
- });
|
|
|
- }
|
|
|
- } else if (city.children && city.children.length > 0 && selectedCountyIds.size > 0) {
|
|
|
- // 检查该市下所有县是否都被选择
|
|
|
- let allCountiesSelected = true;
|
|
|
- city.children.forEach(county => {
|
|
|
- if (!selectedCountyIds.has(county.cityId)) {
|
|
|
- allCountiesSelected = false;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 如果所有县都被选择,禁用该市
|
|
|
- if (allCountiesSelected) {
|
|
|
- that.$set(province.children[cityIndex], 'disabled', true);
|
|
|
- }
|
|
|
-
|
|
|
- // 标记已选择的县为禁用
|
|
|
- city.children.forEach((county, countyIndex) => {
|
|
|
- if (selectedCountyIds.has(county.cityId)) {
|
|
|
- that.$set(province.children[cityIndex].children[countyIndex], 'disabled', true);
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 选择了整个市(没有县的数据或没有选择县),禁用该市
|
|
|
- that.$set(province.children[cityIndex], 'disabled', true);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
+ const allCitiesSelected =
|
|
|
+ province.children &&
|
|
|
+ province.children.length > 0 &&
|
|
|
+ province.children.every(city => selectedCityMap.has(city.cityId))
|
|
|
+
|
|
|
+ if (allCitiesSelected) {
|
|
|
+ this.$set(province, 'disabled', true)
|
|
|
}
|
|
|
- },
|
|
|
- /**
|
|
|
- * 全选或者反选
|
|
|
- * @param checked
|
|
|
- */
|
|
|
- allCheckbox: function () {
|
|
|
- let that = this, checked = this.iSselect;
|
|
|
- that.cityList.forEach(function (item, key) {
|
|
|
- // 跳过已禁用的省
|
|
|
- if (item.disabled) {
|
|
|
- return;
|
|
|
+
|
|
|
+ ;(province.children || []).forEach((city, cityIndex) => {
|
|
|
+ if (!selectedCityMap.has(city.cityId)) return
|
|
|
+
|
|
|
+ let citySelectedWhole = false
|
|
|
+ this.selectedCities.forEach(selectedCity => {
|
|
|
+ if (selectedCity.cityId === province.cityId && selectedCity.children) {
|
|
|
+ const foundCity = selectedCity.children.find(c => c.cityId === city.cityId)
|
|
|
+ if (foundCity && (!foundCity.children || foundCity.children.length === 0)) {
|
|
|
+ citySelectedWhole = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const selectedCountyIds = selectedCityMap.get(city.cityId)
|
|
|
+ if (citySelectedWhole || !city.children || city.children.length === 0 || selectedCountyIds.size === 0) {
|
|
|
+ this.$set(province.children[cityIndex], 'disabled', true)
|
|
|
+ ;(city.children || []).forEach((_, countyIndex) => {
|
|
|
+ this.$set(province.children[cityIndex].children[countyIndex], 'disabled', true)
|
|
|
+ })
|
|
|
+ return
|
|
|
}
|
|
|
- that.$set(that.cityList[key], 'checked', checked);
|
|
|
- if (checked) {
|
|
|
- // 只计算未禁用的市的数量
|
|
|
- let enabledCount = that.cityList[key].children.filter(city => !city.disabled).length;
|
|
|
- that.$set(that.cityList[key], 'count', enabledCount);
|
|
|
- } else {
|
|
|
- that.$set(that.cityList[key], 'count', 0);
|
|
|
+
|
|
|
+ const allCountiesSelected = city.children.every(county => selectedCountyIds.has(county.cityId))
|
|
|
+ if (allCountiesSelected) {
|
|
|
+ this.$set(province.children[cityIndex], 'disabled', true)
|
|
|
}
|
|
|
- that.cityList[key].children.forEach(function (val, k) {
|
|
|
- // 跳过已禁用的市
|
|
|
- if (!val.disabled) {
|
|
|
- that.$set(that.cityList[key].children[k], 'checked', checked);
|
|
|
+ city.children.forEach((county, countyIndex) => {
|
|
|
+ if (selectedCountyIds.has(county.cityId)) {
|
|
|
+ this.$set(province.children[cityIndex].children[countyIndex], 'disabled', true)
|
|
|
}
|
|
|
})
|
|
|
- });
|
|
|
+ })
|
|
|
},
|
|
|
- // 清空;
|
|
|
- empty() {
|
|
|
- let that = this;
|
|
|
- that.cityList.forEach(function (item, key) {
|
|
|
- // 跳过已禁用的省
|
|
|
- if (item.disabled) {
|
|
|
- return;
|
|
|
- }
|
|
|
- that.$set(that.cityList[key], 'checked', false);
|
|
|
- that.cityList[key].children.forEach(function (val, k) {
|
|
|
- // 跳过已禁用的市
|
|
|
- if (!val.disabled) {
|
|
|
- that.$set(that.cityList[key].children[k], 'checked', false);
|
|
|
- }
|
|
|
- });
|
|
|
- that.$set(that.cityList[key], 'count', 0);
|
|
|
- });
|
|
|
- this.iSselect = false;
|
|
|
+
|
|
|
+ /** 根据市级勾选情况,回写省的 checked / indeterminate */
|
|
|
+ syncProvinceState(index) {
|
|
|
+ const province = this.cityList[index]
|
|
|
+ if (!province) return
|
|
|
+ const enabledCities = (province.children || []).filter(c => !c.disabled)
|
|
|
+ const checkedCount = enabledCities.filter(c => c.checked === true).length
|
|
|
+ const total = enabledCities.length
|
|
|
+
|
|
|
+ this.$set(province, 'count', checkedCount)
|
|
|
+ if (total === 0) {
|
|
|
+ this.$set(province, 'checked', false)
|
|
|
+ this.$set(province, 'indeterminate', false)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 全选:省勾选;部分:半选;全不选:不勾选
|
|
|
+ this.$set(province, 'checked', checkedCount === total)
|
|
|
+ this.$set(province, 'indeterminate', checkedCount > 0 && checkedCount < total)
|
|
|
+ if (checkedCount === 0) {
|
|
|
+ this.iSselect = false
|
|
|
+ }
|
|
|
+ this.syncSelectAllFlag()
|
|
|
+ },
|
|
|
+
|
|
|
+ syncSelectAllFlag() {
|
|
|
+ const enabledProvinces = this.cityList.filter(p => !p.disabled)
|
|
|
+ this.iSselect =
|
|
|
+ enabledProvinces.length > 0 &&
|
|
|
+ enabledProvinces.every(p => p.checked === true && !p.indeterminate)
|
|
|
},
|
|
|
+
|
|
|
/**
|
|
|
- * 点击省
|
|
|
- * @param index
|
|
|
+ * 省勾选变化:
|
|
|
+ * - true => 联动选中所有未禁用市
|
|
|
+ * - false => 联动取消所有未禁用市
|
|
|
*/
|
|
|
- checkedClick: function (index) {
|
|
|
- let that = this;
|
|
|
- // 如果省被禁用,不允许操作
|
|
|
- if (that.cityList[index].disabled) {
|
|
|
- return;
|
|
|
+ onProvinceChange(index, val) {
|
|
|
+ const province = this.cityList[index]
|
|
|
+ if (!province || province.disabled) return
|
|
|
+
|
|
|
+ const checked = val === true
|
|
|
+ this.$set(province, 'checked', checked)
|
|
|
+ this.$set(province, 'indeterminate', false)
|
|
|
+
|
|
|
+ ;(province.children || []).forEach((city, key) => {
|
|
|
+ if (!city.disabled) {
|
|
|
+ this.$set(province.children[key], 'checked', checked)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const enabledCount = (province.children || []).filter(c => !c.disabled).length
|
|
|
+ this.$set(province, 'count', checked ? enabledCount : 0)
|
|
|
+ if (!checked) {
|
|
|
+ this.iSselect = false
|
|
|
}
|
|
|
- if (that.cityList[index].checked) {
|
|
|
- // 只选择未禁用的市
|
|
|
- let enabledCount = 0;
|
|
|
- that.cityList[index].children.forEach(function (item, key) {
|
|
|
- if (!item.disabled) {
|
|
|
- that.$set(that.cityList[index].children[key], 'checked', true);
|
|
|
- enabledCount++;
|
|
|
- }
|
|
|
- });
|
|
|
- that.$set(that.cityList[index], 'count', enabledCount);
|
|
|
- } else {
|
|
|
- that.$set(that.cityList[index], 'count', 0);
|
|
|
- that.$set(that.cityList[index], 'checked', false);
|
|
|
- that.cityList[index].children.forEach(function (item, key) {
|
|
|
- // 只取消未禁用的市的选中状态
|
|
|
- if (!item.disabled) {
|
|
|
- that.$set(that.cityList[index].children[key], 'checked', false);
|
|
|
- }
|
|
|
- });
|
|
|
- that.iSselect = false;
|
|
|
+ this.syncSelectAllFlag()
|
|
|
+ // 勾选省时自动展开,方便确认;取消时不强制收起
|
|
|
+ if (checked) {
|
|
|
+ this.activeCity = index
|
|
|
}
|
|
|
+ this.$forceUpdate()
|
|
|
},
|
|
|
+
|
|
|
/**
|
|
|
- * 点击市区
|
|
|
- * @param index
|
|
|
- * @param ind
|
|
|
+ * 市勾选变化:只改当前市,再回写省状态(不会全选其它市)
|
|
|
*/
|
|
|
- primary: function (index, ind) {
|
|
|
- // 如果市被禁用,不允许操作
|
|
|
- if (this.cityList[index].children[ind].disabled) {
|
|
|
- return;
|
|
|
- }
|
|
|
- let checked = false, count = 0;
|
|
|
- this.cityList[index].children.forEach(function (item, key) {
|
|
|
- console.log("item:" + item.checked)
|
|
|
- if (item.checked) {
|
|
|
- checked = true;
|
|
|
- count++;
|
|
|
- }
|
|
|
- });
|
|
|
- this.$set(this.cityList[index], 'count', count);
|
|
|
- this.$set(this.cityList[index], 'checked', checked);
|
|
|
+ onCityChange(index, subindex, val) {
|
|
|
+ const province = this.cityList[index]
|
|
|
+ if (!province || !province.children || !province.children[subindex]) return
|
|
|
+ const city = province.children[subindex]
|
|
|
+ if (city.disabled) return
|
|
|
+
|
|
|
+ this.$set(province.children[subindex], 'checked', val === true)
|
|
|
+ this.syncProvinceState(index)
|
|
|
+ this.$forceUpdate()
|
|
|
},
|
|
|
- // 确定;
|
|
|
- confirm() {
|
|
|
- let that = this;
|
|
|
- // 被选中的省市;
|
|
|
- let selectList = [];
|
|
|
- that.cityList.forEach(function (item, key) {
|
|
|
- // 跳过已禁用的省
|
|
|
- if (item.disabled) {
|
|
|
- return;
|
|
|
- }
|
|
|
- let data = {};
|
|
|
- if (item.checked) {
|
|
|
- data = {
|
|
|
- name: item.cityName,
|
|
|
- cityId: item.cityId,
|
|
|
- children: []
|
|
|
- };
|
|
|
|
|
|
- }
|
|
|
- that.cityList[key].children.forEach(function (i, k) {
|
|
|
- // 只添加未禁用且选中的市
|
|
|
- if (i.checked && !i.disabled) {
|
|
|
- let cityData = {
|
|
|
- cityId: i.cityId
|
|
|
- };
|
|
|
-
|
|
|
- // 如果市下有县,检查是否有选中的县
|
|
|
- if (i.children && i.children.length > 0) {
|
|
|
- let selectedCounties = [];
|
|
|
- i.children.forEach(function (county, countyIndex) {
|
|
|
- if (county.checked && !county.disabled) {
|
|
|
- selectedCounties.push({
|
|
|
- cityId: county.cityId
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 如果有选中的县,添加到市的children中
|
|
|
+ /** 顶部全选 */
|
|
|
+ onSelectAll(val) {
|
|
|
+ const checked = val === true
|
|
|
+ this.iSselect = checked
|
|
|
+ this.cityList.forEach((province, key) => {
|
|
|
+ if (province.disabled) return
|
|
|
+ this.$set(this.cityList[key], 'checked', checked)
|
|
|
+ this.$set(this.cityList[key], 'indeterminate', false)
|
|
|
+ ;(province.children || []).forEach((city, k) => {
|
|
|
+ if (!city.disabled) {
|
|
|
+ this.$set(this.cityList[key].children[k], 'checked', checked)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const enabledCount = (province.children || []).filter(c => !c.disabled).length
|
|
|
+ this.$set(this.cityList[key], 'count', checked ? enabledCount : 0)
|
|
|
+ })
|
|
|
+ this.$forceUpdate()
|
|
|
+ },
|
|
|
+
|
|
|
+ empty() {
|
|
|
+ this.cityList.forEach((province, key) => {
|
|
|
+ if (province.disabled) return
|
|
|
+ this.$set(this.cityList[key], 'checked', false)
|
|
|
+ this.$set(this.cityList[key], 'indeterminate', false)
|
|
|
+ this.$set(this.cityList[key], 'count', 0)
|
|
|
+ ;(province.children || []).forEach((city, k) => {
|
|
|
+ if (!city.disabled) {
|
|
|
+ this.$set(this.cityList[key].children[k], 'checked', false)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.iSselect = false
|
|
|
+ this.$forceUpdate()
|
|
|
+ },
|
|
|
+
|
|
|
+ confirm() {
|
|
|
+ const selectList = []
|
|
|
+ this.cityList.forEach(province => {
|
|
|
+ if (province.disabled) return
|
|
|
+
|
|
|
+ const selectedCities = []
|
|
|
+ ;(province.children || []).forEach(city => {
|
|
|
+ if (city.checked === true && !city.disabled) {
|
|
|
+ const cityData = { cityId: city.cityId }
|
|
|
+ if (city.children && city.children.length > 0) {
|
|
|
+ const selectedCounties = city.children
|
|
|
+ .filter(county => county.checked === true && !county.disabled)
|
|
|
+ .map(county => ({ cityId: county.cityId }))
|
|
|
if (selectedCounties.length > 0) {
|
|
|
- cityData.children = selectedCounties;
|
|
|
+ cityData.children = selectedCounties
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- data.children.push(cityData);
|
|
|
+ selectedCities.push(cityData)
|
|
|
}
|
|
|
- });
|
|
|
- if (data.cityId !== undefined) {
|
|
|
- selectList.push(data);
|
|
|
+ })
|
|
|
+
|
|
|
+ const enabledCities = (province.children || []).filter(c => !c.disabled)
|
|
|
+ const allSelected =
|
|
|
+ province.checked === true &&
|
|
|
+ !province.indeterminate &&
|
|
|
+ selectedCities.length === enabledCities.length
|
|
|
+
|
|
|
+ if (allSelected || selectedCities.length > 0) {
|
|
|
+ selectList.push({
|
|
|
+ name: province.cityName,
|
|
|
+ cityId: province.cityId,
|
|
|
+ // 整省全选:children 空数组;否则带上手选市
|
|
|
+ children: allSelected ? [] : selectedCities
|
|
|
+ })
|
|
|
}
|
|
|
- });
|
|
|
- console.log(selectList);
|
|
|
+ })
|
|
|
+
|
|
|
if (selectList.length === 0) {
|
|
|
return this.$message({
|
|
|
message: '至少选择一个省份或者城市',
|
|
|
type: 'error'
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.$emit('selectCity', selectList, this.type);
|
|
|
- that.addressView = false;
|
|
|
- this.cityList = []
|
|
|
+ })
|
|
|
}
|
|
|
+
|
|
|
+ this.$emit('selectCity', selectList, this.type)
|
|
|
+ this.addressView = false
|
|
|
+ this.cityList = []
|
|
|
+ this.activeCity = -1
|
|
|
+ this.iSselect = false
|
|
|
},
|
|
|
+
|
|
|
close() {
|
|
|
- this.addressView = false;
|
|
|
- this.cityList = [];
|
|
|
- // 重置选中状态
|
|
|
- this.iSselect = false;
|
|
|
+ this.addressView = false
|
|
|
+ this.cityList = []
|
|
|
+ this.activeCity = -1
|
|
|
+ this.iSselect = false
|
|
|
}
|
|
|
- },
|
|
|
- mounted() {
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-
|
|
|
.modal .item {
|
|
|
position: relative;
|
|
|
- margin-bottom: 20px;
|
|
|
+ margin-bottom: 16px;
|
|
|
}
|
|
|
|
|
|
-.modal .item .city {
|
|
|
- position: absolute;
|
|
|
- z-index: 9;
|
|
|
- top: 17px;
|
|
|
- width: 100%;
|
|
|
- padding-top: 18px;
|
|
|
+.province-wrap {
|
|
|
+ position: relative;
|
|
|
}
|
|
|
|
|
|
-.modal .item .city .checkBox {
|
|
|
- width: 97%;
|
|
|
- padding: 10px;
|
|
|
- border: 1px solid #eee;
|
|
|
- background-color: #fff;
|
|
|
- max-height: 100px;
|
|
|
- overflow-x: hidden;
|
|
|
- overflow-y: auto;
|
|
|
+.province-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
}
|
|
|
|
|
|
-.modal .item .city .checkBox .arrow {
|
|
|
- position: absolute;
|
|
|
- top: 3px;
|
|
|
- width: 0;
|
|
|
- height: 0;
|
|
|
- border: 8px solid transparent;
|
|
|
- border-bottom-color: #ddd;
|
|
|
+.expand-btn {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #409eff;
|
|
|
+ cursor: pointer;
|
|
|
+ user-select: none;
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
|
|
|
-.modal .item .city .checkBox .arrow:before {
|
|
|
- position: absolute;
|
|
|
- bottom: -8px;
|
|
|
- right: -7px;
|
|
|
- content: "";
|
|
|
- width: 0;
|
|
|
- height: 0;
|
|
|
- border: 7px solid transparent;
|
|
|
- border-bottom-color: #fff;
|
|
|
+.expand-btn:hover {
|
|
|
+ text-decoration: underline;
|
|
|
}
|
|
|
|
|
|
-.modal .item .city .checkBox .itemn {
|
|
|
- margin-bottom: 10px;
|
|
|
+.city-panel {
|
|
|
+ position: relative;
|
|
|
+ z-index: 9;
|
|
|
+ margin-top: 6px;
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
|
|
|
-.radio {
|
|
|
- padding: 5px 0;
|
|
|
- font-size: 14px !important;
|
|
|
+.city-panel .checkBox {
|
|
|
+ width: 100%;
|
|
|
+ padding: 10px;
|
|
|
+ border: 1px solid #eee;
|
|
|
+ background-color: #fff;
|
|
|
+ max-height: 140px;
|
|
|
+ overflow-x: hidden;
|
|
|
+ overflow-y: auto;
|
|
|
+ box-sizing: border-box;
|
|
|
}
|
|
|
|
|
|
-.red {
|
|
|
- color: #ff0000;
|
|
|
+.city-panel .checkBox .itemn {
|
|
|
+ margin: 0 12px 8px 0;
|
|
|
}
|
|
|
|
|
|
.empty {
|
|
|
cursor: pointer;
|
|
|
- margin-left: 10px
|
|
|
+ margin-left: 10px;
|
|
|
}
|
|
|
|
|
|
.check-btn {
|
|
|
@@ -474,7 +447,6 @@ export default {
|
|
|
justify-content: flex-end;
|
|
|
}
|
|
|
|
|
|
-/* 禁用状态的复选框样式 */
|
|
|
.disabled-checkbox {
|
|
|
opacity: 0.5;
|
|
|
cursor: not-allowed !important;
|