|
@@ -316,7 +316,7 @@
|
|
|
width="700px"
|
|
width="700px"
|
|
|
:close-on-click-modal="false"
|
|
:close-on-click-modal="false"
|
|
|
>
|
|
>
|
|
|
- <RegionCascader v-model="selectedSupplyAreaCodes" :multiple="true" :options="supplyAreaOptions" />
|
|
|
|
|
|
|
+ <RegionCascader v-model="selectedSupplyAreaCodes" :multiple="true" :options="supplyAreaOptions" :show-district="false" />
|
|
|
|
|
|
|
|
<template #footer>
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|
|
<div class="dialog-footer">
|
|
@@ -778,7 +778,7 @@ const authorizationPagination = ref({
|
|
|
// 供货区域对话框相关
|
|
// 供货区域对话框相关
|
|
|
const supplyAreaDialogVisible = ref(false);
|
|
const supplyAreaDialogVisible = ref(false);
|
|
|
const supplyAreaSubmitLoading = ref(false);
|
|
const supplyAreaSubmitLoading = ref(false);
|
|
|
-const selectedSupplyAreaCodes = ref<string[]>([]); // 选中的供货区域(区县ID数组)
|
|
|
|
|
|
|
+const selectedSupplyAreaCodes = ref<string[]>([]); // 选中的供货区域(省/市ID数组)
|
|
|
const savedAreaData = ref<any[]>([]); // 已保存的供货区域数据
|
|
const savedAreaData = ref<any[]>([]); // 已保存的供货区域数据
|
|
|
|
|
|
|
|
// 供货区域选择器数据源(从接口获取)
|
|
// 供货区域选择器数据源(从接口获取)
|
|
@@ -1958,89 +1958,54 @@ const handleEditSupplyArea = async () => {
|
|
|
selectedSupplyAreaCodes.value = buildSupplyAreaCodesFromSavedData(savedAreaData.value);
|
|
selectedSupplyAreaCodes.value = buildSupplyAreaCodesFromSavedData(savedAreaData.value);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 根据已保存的省/市数据生成 RegionCascader 需要的区县编码列表 */
|
|
|
|
|
|
|
+/** 根据已保存的省/市数据生成 RegionCascader 需要的省/市ID列表 */
|
|
|
const buildSupplyAreaCodesFromSavedData = (areaData: any[]) => {
|
|
const buildSupplyAreaCodesFromSavedData = (areaData: any[]) => {
|
|
|
const codes = new Set<string>();
|
|
const codes = new Set<string>();
|
|
|
if (!areaData || areaData.length === 0) return [];
|
|
if (!areaData || areaData.length === 0) return [];
|
|
|
|
|
|
|
|
- const provinces: any[] = supplyAreaOptions.value || [];
|
|
|
|
|
-
|
|
|
|
|
- const collectDistrictIdsUnderNode = (node: any) => {
|
|
|
|
|
- const result: string[] = [];
|
|
|
|
|
- const dfs = (n: any) => {
|
|
|
|
|
- if (!n) return;
|
|
|
|
|
- if (!n.children || n.children.length === 0) {
|
|
|
|
|
- if (n.value) result.push(String(n.value));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- n.children.forEach((c: any) => dfs(c));
|
|
|
|
|
- };
|
|
|
|
|
- dfs(node);
|
|
|
|
|
- return result;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const findNodeById = (id: string) => {
|
|
|
|
|
- for (const p of provinces) {
|
|
|
|
|
- if (String(p.value) === id) return p;
|
|
|
|
|
- for (const c of p.children || []) {
|
|
|
|
|
- if (String(c.value) === id) return c;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return null;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
areaData.forEach((area: any) => {
|
|
areaData.forEach((area: any) => {
|
|
|
const level = String(area.level);
|
|
const level = String(area.level);
|
|
|
- const areaId = String(area.areaId ?? area.areaCode ?? '');
|
|
|
|
|
|
|
+ const areaId = String(area.areaId ?? area.id ?? '');
|
|
|
if (!areaId) return;
|
|
if (!areaId) return;
|
|
|
-
|
|
|
|
|
- // 已保存的供货区域通常只包含省(1)/市(2),回显时要勾选其下所有区县
|
|
|
|
|
if (level === '1' || level === '2') {
|
|
if (level === '1' || level === '2') {
|
|
|
- const node = findNodeById(areaId);
|
|
|
|
|
- if (node) {
|
|
|
|
|
- collectDistrictIdsUnderNode(node).forEach((d) => codes.add(d));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ codes.add(areaId);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
return Array.from(codes);
|
|
return Array.from(codes);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 根据区县编码在 regionOptions 中找到对应的省/市节点 */
|
|
|
|
|
-const findProvinceCityByDistrictCode = (districtCode: string, provinces: any[]) => {
|
|
|
|
|
- for (const province of provinces) {
|
|
|
|
|
- const cities = province?.children || [];
|
|
|
|
|
- for (const city of cities) {
|
|
|
|
|
- const districts = city?.children || [];
|
|
|
|
|
- const hit = districts.find((d: any) => d.value === districtCode);
|
|
|
|
|
- if (hit) {
|
|
|
|
|
- return { province, city };
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return null;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-/** 根据区县编码提取供货区域(省/市)展示字符串 */
|
|
|
|
|
-const extractRegionDataFromDistrictCodes = (districtCodes: string[]) => {
|
|
|
|
|
|
|
+/** 根据省/市ID提取供货区域(省/市)展示字符串 */
|
|
|
|
|
+const extractRegionDataFromSelectedProvinceCityIds = (selectedIds: string[]) => {
|
|
|
const provinces: any[] = supplyAreaOptions.value || [];
|
|
const provinces: any[] = supplyAreaOptions.value || [];
|
|
|
const provinceNames: string[] = [];
|
|
const provinceNames: string[] = [];
|
|
|
const cityNames: string[] = [];
|
|
const cityNames: string[] = [];
|
|
|
const addedProvinces = new Set<string>();
|
|
const addedProvinces = new Set<string>();
|
|
|
const addedCities = new Set<string>();
|
|
const addedCities = new Set<string>();
|
|
|
|
|
|
|
|
- districtCodes.forEach(code => {
|
|
|
|
|
- const path = findProvinceCityByDistrictCode(code, provinces);
|
|
|
|
|
- if (!path) return;
|
|
|
|
|
|
|
+ selectedIds.forEach((id) => {
|
|
|
|
|
+ for (const province of provinces) {
|
|
|
|
|
+ if (String(province.value) === String(id)) {
|
|
|
|
|
+ if (!addedProvinces.has(String(province.value))) {
|
|
|
|
|
+ provinceNames.push(province.label);
|
|
|
|
|
+ addedProvinces.add(String(province.value));
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const { province, city } = path;
|
|
|
|
|
- if (province && !addedProvinces.has(province.value)) {
|
|
|
|
|
- provinceNames.push(province.label);
|
|
|
|
|
- addedProvinces.add(province.value);
|
|
|
|
|
- }
|
|
|
|
|
- if (city && !addedCities.has(city.value)) {
|
|
|
|
|
- cityNames.push(city.label);
|
|
|
|
|
- addedCities.add(city.value);
|
|
|
|
|
|
|
+ const cities = province?.children || [];
|
|
|
|
|
+ const hitCity = cities.find((c: any) => String(c.value) === String(id));
|
|
|
|
|
+ if (hitCity) {
|
|
|
|
|
+ if (!addedProvinces.has(String(province.value))) {
|
|
|
|
|
+ provinceNames.push(province.label);
|
|
|
|
|
+ addedProvinces.add(String(province.value));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!addedCities.has(String(hitCity.value))) {
|
|
|
|
|
+ cityNames.push(hitCity.label);
|
|
|
|
|
+ addedCities.add(String(hitCity.value));
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -2051,37 +2016,57 @@ const extractRegionDataFromDistrictCodes = (districtCodes: string[]) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/** 构建 areaList 数组(提交给后端:省(1)/市(2)) */
|
|
/** 构建 areaList 数组(提交给后端:省(1)/市(2)) */
|
|
|
-const buildAreaListFromDistrictCodes = (districtCodes: string[]) => {
|
|
|
|
|
|
|
+const buildAreaListFromSelectedProvinceCityIds = (selectedIds: string[]) => {
|
|
|
const provinces: any[] = supplyAreaOptions.value || [];
|
|
const provinces: any[] = supplyAreaOptions.value || [];
|
|
|
const areaList: any[] = [];
|
|
const areaList: any[] = [];
|
|
|
const addedProvinces = new Set<string>();
|
|
const addedProvinces = new Set<string>();
|
|
|
const addedCities = new Set<string>();
|
|
const addedCities = new Set<string>();
|
|
|
|
|
|
|
|
- districtCodes.forEach(code => {
|
|
|
|
|
- const path = findProvinceCityByDistrictCode(code, provinces);
|
|
|
|
|
- if (!path) return;
|
|
|
|
|
- const { province, city } = path;
|
|
|
|
|
-
|
|
|
|
|
- if (province && !addedProvinces.has(province.value)) {
|
|
|
|
|
- areaList.push({
|
|
|
|
|
- areaId: Number(province.value),
|
|
|
|
|
- areaCode: province.areaCode || province.value,
|
|
|
|
|
- areaName: province.label,
|
|
|
|
|
- level: 1,
|
|
|
|
|
- parentId: 0
|
|
|
|
|
- });
|
|
|
|
|
- addedProvinces.add(province.value);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ selectedIds.forEach((id) => {
|
|
|
|
|
+ for (const province of provinces) {
|
|
|
|
|
+ // 省
|
|
|
|
|
+ if (String(province.value) === String(id)) {
|
|
|
|
|
+ if (!addedProvinces.has(String(province.value))) {
|
|
|
|
|
+ areaList.push({
|
|
|
|
|
+ areaId: Number(province.value),
|
|
|
|
|
+ areaCode: province.areaCode || province.value,
|
|
|
|
|
+ areaName: province.label,
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ parentId: 0
|
|
|
|
|
+ });
|
|
|
|
|
+ addedProvinces.add(String(province.value));
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (province && city && !addedCities.has(city.value)) {
|
|
|
|
|
- areaList.push({
|
|
|
|
|
- areaId: Number(city.value),
|
|
|
|
|
- areaCode: city.areaCode || city.value,
|
|
|
|
|
- areaName: city.label,
|
|
|
|
|
- level: 2,
|
|
|
|
|
- parentId: Number(province.value)
|
|
|
|
|
- });
|
|
|
|
|
- addedCities.add(city.value);
|
|
|
|
|
|
|
+ // 市
|
|
|
|
|
+ const cities = province?.children || [];
|
|
|
|
|
+ const hitCity = cities.find((c: any) => String(c.value) === String(id));
|
|
|
|
|
+ if (hitCity) {
|
|
|
|
|
+ // city 已选时确保 parent province 也存在(即使组件没回传,也兜底)
|
|
|
|
|
+ if (!addedProvinces.has(String(province.value))) {
|
|
|
|
|
+ areaList.push({
|
|
|
|
|
+ areaId: Number(province.value),
|
|
|
|
|
+ areaCode: province.areaCode || province.value,
|
|
|
|
|
+ areaName: province.label,
|
|
|
|
|
+ level: 1,
|
|
|
|
|
+ parentId: 0
|
|
|
|
|
+ });
|
|
|
|
|
+ addedProvinces.add(String(province.value));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!addedCities.has(String(hitCity.value))) {
|
|
|
|
|
+ areaList.push({
|
|
|
|
|
+ areaId: Number(hitCity.value),
|
|
|
|
|
+ areaCode: hitCity.areaCode || hitCity.value,
|
|
|
|
|
+ areaName: hitCity.label,
|
|
|
|
|
+ level: 2,
|
|
|
|
|
+ parentId: Number(province.value)
|
|
|
|
|
+ });
|
|
|
|
|
+ addedCities.add(String(hitCity.value));
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -2104,30 +2089,51 @@ const handleSupplyAreaSubmit = async () => {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- console.log('提交前的选中区县编码:', selectedSupplyAreaCodes.value);
|
|
|
|
|
|
|
+ console.log('提交前的选中省/市ID:', selectedSupplyAreaCodes.value);
|
|
|
|
|
|
|
|
// 构建 areaList 数组
|
|
// 构建 areaList 数组
|
|
|
- const areaList = buildAreaListFromDistrictCodes(selectedSupplyAreaCodes.value);
|
|
|
|
|
|
|
+ const areaList = buildAreaListFromSelectedProvinceCityIds(selectedSupplyAreaCodes.value);
|
|
|
console.log('构建的 areaList:', areaList);
|
|
console.log('构建的 areaList:', areaList);
|
|
|
|
|
|
|
|
|
|
+ // 前端兜底去重:避免后端按“追加插入”导致重复省/市
|
|
|
|
|
+ // 只提交“新增的”省/市(已存在的省/市不重复提交)
|
|
|
|
|
+ const existedKeys = new Set<string>();
|
|
|
|
|
+ (savedAreaData.value || []).forEach((a: any) => {
|
|
|
|
|
+ const level = String(a.level);
|
|
|
|
|
+ const areaId = String(a.areaId ?? a.id ?? '');
|
|
|
|
|
+ if (!areaId) return;
|
|
|
|
|
+ if (level === '1' || level === '2') {
|
|
|
|
|
+ existedKeys.add(`${level}-${areaId}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const areaListToSubmit = (areaList || []).filter((a: any) => {
|
|
|
|
|
+ const level = String(a.level);
|
|
|
|
|
+ const areaId = String(a.areaId ?? '');
|
|
|
|
|
+ if (!areaId) return false;
|
|
|
|
|
+ return !existedKeys.has(`${level}-${areaId}`);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
// 从选中的编码中提取区域信息(用于显示)
|
|
// 从选中的编码中提取区域信息(用于显示)
|
|
|
- const regionData = extractRegionDataFromDistrictCodes(selectedSupplyAreaCodes.value);
|
|
|
|
|
|
|
+ const regionData = extractRegionDataFromSelectedProvinceCityIds(selectedSupplyAreaCodes.value);
|
|
|
console.log('提取的区域数据:', regionData);
|
|
console.log('提取的区域数据:', regionData);
|
|
|
|
|
|
|
|
// 构建提交数据
|
|
// 构建提交数据
|
|
|
const submitData: any = {
|
|
const submitData: any = {
|
|
|
supplierId: id,
|
|
supplierId: id,
|
|
|
supplyNo: detailData.value.supplierNo,
|
|
supplyNo: detailData.value.supplierNo,
|
|
|
- areaList: areaList
|
|
|
|
|
|
|
+ areaList: areaListToSubmit
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
- // 只在编辑模式下添加 supplyStatus
|
|
|
|
|
- if (isEditMode.value) {
|
|
|
|
|
- submitData.supplyStatus = "4";
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
console.log('提交的数据:', submitData);
|
|
console.log('提交的数据:', submitData);
|
|
|
|
|
|
|
|
|
|
+ if (!submitData.areaList || submitData.areaList.length === 0) {
|
|
|
|
|
+ ElMessage.success('保存成功');
|
|
|
|
|
+ supplyAreaDialogVisible.value = false;
|
|
|
|
|
+ await getSupplyAreaList();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
await addArea(submitData);
|
|
await addArea(submitData);
|
|
|
|
|
|
|
|
// 更新本地数据
|
|
// 更新本地数据
|
|
@@ -2148,7 +2154,6 @@ const handleSupplyAreaSubmit = async () => {
|
|
|
...detailData.value, // 当前页面的数据
|
|
...detailData.value, // 当前页面的数据
|
|
|
supplierType: String(detailData.value.supplierType),
|
|
supplierType: String(detailData.value.supplierType),
|
|
|
cooperateLevel: String(detailData.value.cooperateLevel),
|
|
cooperateLevel: String(detailData.value.cooperateLevel),
|
|
|
- supplyStatus: "4"
|
|
|
|
|
};
|
|
};
|
|
|
} else {
|
|
} else {
|
|
|
// 临时表没有记录,使用当前数据
|
|
// 临时表没有记录,使用当前数据
|
|
@@ -2156,7 +2161,6 @@ const handleSupplyAreaSubmit = async () => {
|
|
|
...detailData.value,
|
|
...detailData.value,
|
|
|
supplierType: String(detailData.value.supplierType),
|
|
supplierType: String(detailData.value.supplierType),
|
|
|
cooperateLevel: String(detailData.value.cooperateLevel),
|
|
cooperateLevel: String(detailData.value.cooperateLevel),
|
|
|
- supplyStatus: "4"
|
|
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2180,11 +2184,8 @@ const handleSupplyAreaSubmit = async () => {
|
|
|
|
|
|
|
|
ElMessage.success('保存成功');
|
|
ElMessage.success('保存成功');
|
|
|
supplyAreaDialogVisible.value = false;
|
|
supplyAreaDialogVisible.value = false;
|
|
|
-
|
|
|
|
|
- // add状态下保存后需要重新查询回显,edit状态不需要
|
|
|
|
|
- if (isAddMode.value) {
|
|
|
|
|
- await getSupplyAreaList();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
|
|
+ await getSupplyAreaList();
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
console.error('保存供货区域失败:', e);
|
|
console.error('保存供货区域失败:', e);
|
|
|
ElMessage.error('保存失败');
|
|
ElMessage.error('保存失败');
|