|
|
@@ -98,7 +98,6 @@ interface UtPickerAreaProps {
|
|
|
title?: string;
|
|
|
maxLevel?: number;
|
|
|
selectCodeMax?: string;
|
|
|
- selectedCodes?: string[];
|
|
|
}
|
|
|
|
|
|
const props = withDefaults(defineProps<UtPickerAreaProps>(), {
|
|
|
@@ -107,14 +106,12 @@ const props = withDefaults(defineProps<UtPickerAreaProps>(), {
|
|
|
title: '选择区域',
|
|
|
maxLevel: 3,
|
|
|
selectCodeMax: '',
|
|
|
- selectedCodes: () => [] as string[],
|
|
|
});
|
|
|
|
|
|
const emits = defineEmits<{
|
|
|
(e: 'update:modelValue', value: string): void;
|
|
|
(e: 'update:show', value: boolean): void;
|
|
|
(e: 'confirm', payload: ConfirmPayload): void;
|
|
|
- (e: 'update:selectedCodes', value: string[]): void;
|
|
|
}>();
|
|
|
|
|
|
const uToastRef = ref<{ show: (opts: any) => void } | null>(null);
|
|
|
@@ -178,21 +175,34 @@ const canonical6 = (code: MaybeStringNumber): string => {
|
|
|
}
|
|
|
return s;
|
|
|
};
|
|
|
+// 从根开始拆分一条完整链路:只保留真实存在的层级
|
|
|
+// 规则:
|
|
|
+// - 先归一到 6 位区域基码 base6(省/市/区),再按 省(2) / 市(4) / 区(6) 拆分
|
|
|
+// - 若原始码长度 > 6(如 9/12 位),再追加完整码作为最后一级
|
|
|
+// 这样不会生成诸如 9 位的“虚拟层级”,避免回显时名称缺失
|
|
|
const chainFromRoot = (code: MaybeStringNumber): string[] => {
|
|
|
- const s = normalize6(code);
|
|
|
- if (!s || s === '000000') return [];
|
|
|
+ const raw = normalize6(code);
|
|
|
+ if (!raw || raw === '000000') return [];
|
|
|
+
|
|
|
const list: string[] = [];
|
|
|
- // 省/市/区:统一输出为“最少6位”,少于补0,多余去掉末尾00(canonical6 内处理)
|
|
|
- for (let i = 2; i <= Math.min(6, s.length); i += 2) {
|
|
|
- list.push(canonical6(s.slice(0, i)));
|
|
|
+
|
|
|
+ // 6 位区域基码(省/市/区)
|
|
|
+ const base6 = canonical6(raw).slice(0, 6);
|
|
|
+ if (base6 && base6 !== '000000') {
|
|
|
+ const prov = base6.slice(0, 2).padEnd(6, '0');
|
|
|
+ const city = base6.slice(0, 4).padEnd(6, '0');
|
|
|
+ const dist = base6;
|
|
|
+
|
|
|
+ [prov, city, dist].forEach((c) => {
|
|
|
+ if (c && c !== '000000' && !list.includes(c)) list.push(c);
|
|
|
+ });
|
|
|
}
|
|
|
- // 扩展层级:9/12 位,保持真实长度;其 6 位基底已按 canonical6 规范化
|
|
|
- if (s.length > 6) {
|
|
|
- const base6 = canonical6(s).slice(0, 6);
|
|
|
- for (let j = 9; j <= s.length; j += 3) {
|
|
|
- list.push(base6 + s.slice(6, j));
|
|
|
- }
|
|
|
+
|
|
|
+ // 扩展层级:保留原始完整码(9/12 位等),作为区县之后的细分层级
|
|
|
+ if (raw.length > 6 && !list.includes(raw)) {
|
|
|
+ list.push(raw);
|
|
|
}
|
|
|
+
|
|
|
return list;
|
|
|
};
|
|
|
|
|
|
@@ -217,7 +227,7 @@ const pendingMap = ref<Record<string, Promise<AreaItem[]> | undefined>>({});
|
|
|
const nameMap = ref<Record<string, string>>({ '000000': '全国' });
|
|
|
|
|
|
// 选中链路(不包含 baseRoot),例如 baseRoot=省,选中市/区... 这里存 [市, 区, ...]
|
|
|
-const selectedCodes = ref<string[]>(props?.selectedCodes || []);
|
|
|
+const selectedCodes = ref<string[]>([]);
|
|
|
const currentValue = ref<string>(''); // 当前选中最终 code
|
|
|
|
|
|
// 计算列:每列的父节点仅为“下一列的父节点”,避免最后一级再多出一列
|
|
|
@@ -258,15 +268,32 @@ const getChildren = async (parentCode: string): Promise<AreaItem[]> => {
|
|
|
});
|
|
|
if (res?.code === 200) {
|
|
|
const rows: AreaItem[] = (res.rows || []).map((x: any) => ({
|
|
|
- // 不再截断为 6 位,保留完整 code
|
|
|
- adcdCode: nameKey(x.adcdCode),
|
|
|
+ // 保留服务端返回的完整编码(6 位省级,12 位市/区/街道/村委会)
|
|
|
+ adcdCode: String(x.adcdCode ?? ''),
|
|
|
adcdName: x.adcdName,
|
|
|
}));
|
|
|
childrenMap.value[key] = rows; // 写入结果缓存
|
|
|
rows.forEach((r) => {
|
|
|
- // 名称缓存:精确键必存;仅当长度<=6时,才缓存到最少6位标准键,避免覆盖区县名称
|
|
|
- nameMap.value[r.adcdCode] = r.adcdName;
|
|
|
- nameMap.value[nameKey(r.adcdCode)] = r.adcdName;
|
|
|
+ const codeStr = String(r.adcdCode ?? '');
|
|
|
+ if (!codeStr) return;
|
|
|
+
|
|
|
+ // 精确键:始终缓存,保证 9/12 位街道、村委会可以直接取到名称
|
|
|
+ nameMap.value[codeStr] = r.adcdName;
|
|
|
+
|
|
|
+ // 若是 6 位(省/市/区),补一份到归一化 6 位 key(一般相同)
|
|
|
+ if (codeStr.length <= 6) {
|
|
|
+ const k6 = nameKey(codeStr);
|
|
|
+ if (!nameMap.value[k6]) nameMap.value[k6] = r.adcdName;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 若是 12 位且末尾 6 位全为 0,视为“市/区等 6 位层级”的 12 位表示
|
|
|
+ // 额外为其 6 位基码建立名称映射,方便用 6 位链路回显
|
|
|
+ if (codeStr.length === 12 && codeStr.endsWith('000000')) {
|
|
|
+ const base6 = codeStr.slice(0, 6);
|
|
|
+ if (!nameMap.value[base6]) nameMap.value[base6] = r.adcdName;
|
|
|
+ const k6 = nameKey(base6);
|
|
|
+ if (!nameMap.value[k6]) nameMap.value[k6] = r.adcdName;
|
|
|
+ }
|
|
|
});
|
|
|
delete pendingMap.value[key]; // 清除进行中缓存
|
|
|
return rows;
|
|
|
@@ -480,7 +507,6 @@ const confirmPick = (): void => {
|
|
|
fullNames: nameList.join(''),
|
|
|
fullName // 新增:完整地址名称
|
|
|
});
|
|
|
- emits('update:selectedCodes', codeList);
|
|
|
close();
|
|
|
};
|
|
|
|