fix(admin): city-scoped district pick and clearer overlap errors
CI / verify (pull_request) Has been cancelled

Region partners only select districts under the chosen city; overlap errors name the occupying partner.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-22 18:14:54 +08:00
parent 85f2c156b0
commit 8c4419e04e
9 changed files with 338 additions and 140 deletions
+12 -1
View File
@@ -63,10 +63,21 @@ describe('validatePartnerCityBinding', () => {
it('rejects overlapping district codes', () => {
const result = validatePartnerCityBinding(
[{ id: '1', partnerAccountId: '10', scopeType: 'DISTRICT', districtCodes: ['410105'] }],
[
{
id: '1',
partnerAccountId: '10',
scopeType: 'DISTRICT',
districtCodes: ['410105'],
companyName: '甲公司',
},
],
{ partnerAccountId: '11', scopeType: 'DISTRICT', districtCodes: ['410105'] },
);
expect(result.ok).toBe(false);
expect(result.message).toContain('区域重合');
expect(result.message).toContain('甲公司');
expect(result.occupiedCodes).toEqual(['410105']);
});
it('allows valid district binding', () => {
+16 -6
View File
@@ -7,6 +7,8 @@ export interface PartnerCityBindingInput {
scopeType: CityPartnerScopeType;
districtCodes?: string[] | null;
bindingStatus?: CityPartnerStatus;
/** 仅用于重合报错文案 */
companyName?: string | null;
}
export interface PartnerCityResolveRef {
@@ -20,6 +22,7 @@ export interface PartnerCityResolveRef {
export interface PartnerCityValidationResult {
ok: boolean;
message?: string;
occupiedCodes?: string[];
}
function normalizeDistrictCodes(codes?: string[] | null): string[] {
@@ -98,18 +101,25 @@ export function validatePartnerCityBinding(
return { ok: false, message: '区域合伙人须至少选择一个区县' };
}
const occupied = new Set<string>();
const occupiedBy = new Map<string, string>();
for (const row of others) {
if (row.scopeType !== 'DISTRICT') continue;
const owner = row.companyName?.trim() || '其他区域合伙人';
for (const code of normalizeDistrictCodes(row.districtCodes)) {
occupied.add(code);
if (!occupiedBy.has(code)) occupiedBy.set(code, owner);
}
}
for (const code of districts) {
if (occupied.has(code)) {
return { ok: false, message: `区县 ${code} 已被其他区域合伙人占用` };
}
const overlaps = districts.filter((code) => occupiedBy.has(code));
if (overlaps.length) {
const detail = overlaps
.map((code) => `${code}${occupiedBy.get(code)}`)
.join('、');
return {
ok: false,
message: `区域重合:以下区县已被占用,请改选其他区县 — ${detail}`,
occupiedCodes: overlaps,
};
}
return { ok: true };