This commit is contained in:
2026-07-21 13:20:06 +08:00
parent 76df2b9cd2
commit e50d1b8fda
21 changed files with 714 additions and 129 deletions

View File

@@ -65,6 +65,24 @@
{{ row.status === 1 ? '启用' : '停用' }}
</el-tag>
</template>
<template #country-form>
<el-select
v-model="form.countryCode"
clearable
filterable
:disabled="isParentRegionLocked"
placeholder="请选择国家"
style="width: 100%"
@change="handleCountryChange"
>
<el-option
v-for="item in countryOptions"
:key="item.id"
:label="item.title"
:value="item.id"
/>
</el-select>
</template>
<template #menu="{ row, index }">
<el-button
type="primary"
@@ -87,11 +105,12 @@
</template>
<template #regionCode-form>
<el-cascader
:key="regionCascaderKey"
v-model="form.regionCode"
:props="regionProps"
clearable
filterable
:disabled="isParentRegionLocked"
:disabled="isRegionDisabled"
style="width: 100%"
@change="handleRegionChange"
/>
@@ -133,6 +152,8 @@ import { getToken } from '@/utils/auth';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
const DEFAULT_COUNTRY_CODE = '+86';
export default {
data() {
const validateCode = (rule, value, callback) => {
@@ -183,6 +204,8 @@ export default {
excelBox: false,
excelForm: {},
portOptions: [],
countryOptions: [],
regionCascaderKey: 0,
regionNodeMap: {},
regionNameMap: {},
regionProps: {
@@ -206,6 +229,7 @@ export default {
dialogWidth: 980,
tip: false,
searchShow: true,
searchLabelWidth: 120,
searchMenuSpan: 6,
border: true,
index: true,
@@ -279,6 +303,15 @@ export default {
slot: true,
disabled: true,
},
{
label: '国家',
prop: 'country',
search: true,
formslot: true,
span: 12,
minWidth: 100,
rules: [{ required: true, message: '请选择国家', trigger: 'change' }],
},
{
label: '城市',
prop: 'regionCode',
@@ -287,14 +320,6 @@ export default {
span: 12,
rules: [{ required: true, message: '请选择所属城市', trigger: 'change' }],
},
{
label: '国家',
prop: 'country',
search: true,
addDisplay: false,
editDisplay: false,
minWidth: 100,
},
{
label: '城市',
prop: 'city',
@@ -309,6 +334,7 @@ export default {
type: 'number',
precision: 6,
minWidth: 130,
overHidden: false,
rules: [{ validator: validateLongitude, trigger: 'blur' }],
},
{
@@ -317,6 +343,7 @@ export default {
type: 'number',
precision: 6,
minWidth: 130,
overHidden: false,
rules: [{ validator: validateLatitude, trigger: 'blur' }],
},
{
@@ -324,6 +351,8 @@ export default {
prop: 'dataSource',
type: 'select',
search: true,
minWidth: 120,
overHidden: false,
dicData: [
{ label: '全部', value: '' },
{ label: '初始化导入', value: '初始化导入' },
@@ -338,6 +367,8 @@ export default {
search: true,
slot: true,
dataType: 'number',
minWidth: 110,
overHidden: false,
dicData: [
{ label: '全部', value: '' },
{ label: '启用', value: 1 },
@@ -423,11 +454,16 @@ export default {
},
isAdmin() {
const authority = this.userInfo && this.userInfo.authority;
return Array.isArray(authority) ? authority.includes('admin') : String(authority || '').includes('admin');
return Array.isArray(authority)
? authority.includes('admin')
: String(authority || '').includes('admin');
},
isParentRegionLocked() {
return this.form.category === '码头' && !!this.form.parentId;
},
isRegionDisabled() {
return this.isParentRegionLocked || !this.form.countryCode;
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
@@ -437,6 +473,7 @@ export default {
},
},
created() {
this.loadCountryOptions();
this.loadPortOptions();
},
methods: {
@@ -454,7 +491,11 @@ export default {
}
},
loadRegionNode(node, resolve) {
const parentCode = node.level === 0 ? '00' : node.value;
const parentCode = node.level === 0 ? this.form.countryCode : node.value;
if (!parentCode) {
resolve([]);
return;
}
getLazyTree(parentCode).then(res => {
const regionList = res.data.data || [];
const nodes = regionList.map(region => {
@@ -469,6 +510,15 @@ export default {
resolve(nodes);
});
},
loadCountryOptions() {
return getLazyTree('0').then(res => {
this.countryOptions = res.data.data || [];
this.countryOptions.forEach(country => {
this.regionNodeMap[country.id] = country;
this.regionNameMap[country.title] = country.id;
});
});
},
loadPortOptions() {
getPortSelect().then(res => {
this.portOptions = res.data.data;
@@ -485,6 +535,19 @@ export default {
}
this.handleCodeChange(this.form.code);
},
handleCountryChange(value) {
const country = this.countryOptions.find(item => item.id === value);
this.form.country = country ? country.title : '';
this.form.regionCode = [];
this.form.city = '';
this.regionCascaderKey += 1;
},
syncCountryName(countryCode) {
const country = this.countryOptions.find(item => item.id === countryCode);
if (country) {
this.form.country = country.title;
}
},
handleParentChange(value) {
const parent = this.portOptions.find(item => item.id === value);
if (!parent) return;
@@ -499,43 +562,68 @@ export default {
}
this.form.country = parent.country;
this.form.city = parent.city;
this.resolveRegionCode(parent.country, parent.city).then(regionCode => {
this.form.regionCode = regionCode;
});
this.resolveCountryCode(parent.country)
.then(countryCode => {
this.form.countryCode = countryCode;
this.syncCountryName(countryCode);
this.regionCascaderKey += 1;
return this.resolveRegionCode(parent.country, parent.city);
})
.then(regionCode => {
this.form.regionCode = regionCode;
});
},
handleRegionChange(value) {
const regionCode = Array.isArray(value) ? value : [];
const provinceCode = regionCode[0];
const cityCode = regionCode[1];
const province = this.regionNodeMap[provinceCode];
const city = this.regionNodeMap[cityCode];
this.form.country = province ? province.title : '';
this.form.city = city ? city.title : '';
},
resolveCountryCode(country) {
if (!country) {
return Promise.resolve('');
}
const countryOption = this.countryOptions.find(
item => item.title === country || item.id === country
);
if (countryOption) {
return Promise.resolve(countryOption.id);
}
return this.loadCountryOptions().then(() => {
const option = this.countryOptions.find(
item => item.title === country || item.id === country
);
return option ? option.id : DEFAULT_COUNTRY_CODE;
});
},
resolveRegionCode(country, city) {
if (!country || !city) {
return Promise.resolve([]);
}
const provinceCode = this.regionNameMap[country];
if (provinceCode) {
const cityCode = this.regionNameMap[city];
if (cityCode) {
return Promise.resolve([provinceCode, cityCode]);
}
return this.loadRegionList(provinceCode).then(cityList => {
const cityNode = cityList.find(item => item.title === city);
return cityNode ? [provinceCode, cityNode.id] : [provinceCode];
});
const countryCode = this.form.countryCode || this.regionNameMap[country];
if (!countryCode) {
return Promise.resolve([]);
}
return this.loadRegionList('00').then(provinceList => {
const province = provinceList.find(item => item.title === country);
if (!province) {
return [];
return this.loadRegionList(countryCode).then(provinceList => {
const province = provinceList.find(item => item.title === country || item.title === city);
if (province) {
return this.loadRegionList(province.id).then(cityList => {
const cityNode = cityList.find(item => item.title === city);
return cityNode ? [province.id, cityNode.id] : [province.id];
});
}
return this.loadRegionList(province.id).then(cityList => {
const cityNode = cityList.find(item => item.title === city);
return cityNode ? [province.id, cityNode.id] : [province.id];
});
return provinceList.reduce((promise, item) => {
return promise.then(result => {
if (result.length > 0) {
return result;
}
return this.loadRegionList(item.id).then(cityList => {
const cityNode = cityList.find(child => child.title === city);
return cityNode ? [item.id, cityNode.id] : [];
});
});
}, Promise.resolve([]));
});
},
loadRegionList(parentCode) {
@@ -682,18 +770,32 @@ export default {
if (['edit', 'view'].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
this.resolveRegionCode(this.form.country, this.form.city).then(regionCode => {
this.form.regionCode = regionCode;
this.handleCategoryChange(this.form.category);
done();
});
this.resolveCountryCode(this.form.country)
.then(countryCode => {
this.form.countryCode = countryCode;
this.syncCountryName(countryCode);
this.regionCascaderKey += 1;
return this.resolveRegionCode(this.form.country, this.form.city);
})
.then(regionCode => {
this.form.regionCode = regionCode;
this.handleCategoryChange(this.form.category);
done();
});
});
return;
} else {
this.resolveRegionCode(this.form.country, this.form.city).then(regionCode => {
this.form.regionCode = regionCode;
done();
});
this.resolveCountryCode(this.form.country)
.then(countryCode => {
this.form.countryCode = countryCode;
this.syncCountryName(countryCode);
this.regionCascaderKey += 1;
return this.resolveRegionCode(this.form.country, this.form.city);
})
.then(regionCode => {
this.form.regionCode = regionCode;
done();
});
return;
}
},