城市合伙人端开店城市屁默认郑州

This commit is contained in:
2026-07-10 13:14:46 +08:00
parent 363717e441
commit 1761f7b3bf
4 changed files with 82 additions and 11 deletions
@@ -1,7 +1,12 @@
import { createPortal } from 'react-dom';
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { codeToText } from 'element-china-area-data';
import { CHINA_REGION_OPTIONS, formatRegionLabel, parseRegionCodes } from '../lib/china-region';
import {
CHINA_REGION_OPTIONS,
DEFAULT_REGION_CODES,
formatRegionLabel,
parseRegionCodes,
} from '../lib/china-region';
type RegionNode = {
value: string;
@@ -40,10 +45,26 @@ function lockBodyScroll(lock: boolean) {
}
}
function buildInitialDraft(value: string[]): { draft: string[]; step: number } {
if (value.length === 3) {
return { draft: [...value], step: 2 };
}
if (value.length > 0) {
const draft = [...value];
for (let i = value.length; i < DEFAULT_REGION_CODES.length; i += 1) {
draft.push(DEFAULT_REGION_CODES[i]);
}
return { draft, step: Math.min(value.length, 2) };
}
return { draft: [...DEFAULT_REGION_CODES], step: 1 };
}
export default function ChinaRegionPicker({ value = [], onChange, disabled }: ChinaRegionPickerProps) {
const [open, setOpen] = useState(false);
const [draft, setDraft] = useState<string[]>(value);
const [step, setStep] = useState(0);
const listRef = useRef<HTMLDivElement>(null);
const activeItemRef = useRef<HTMLButtonElement | null>(null);
const options = CHINA_REGION_OPTIONS as RegionNode[];
const parsed = parseRegionCodes(value);
@@ -69,11 +90,23 @@ export default function ChinaRegionPicker({ value = [], onChange, disabled }: Ch
return () => lockBodyScroll(false);
}, [open]);
useEffect(() => {
if (!open) return;
const timer = window.setTimeout(() => {
const container = listRef.current;
const activeEl = activeItemRef.current;
if (!container || !activeEl) return;
const offset = activeEl.offsetTop - container.clientHeight / 2 + activeEl.clientHeight / 2;
container.scrollTo({ top: Math.max(0, offset), behavior: 'smooth' });
}, 0);
return () => window.clearTimeout(timer);
}, [open, step, activeCode, listItems]);
function openPicker() {
if (disabled) return;
const next = value.length === 3 ? [...value] : [];
const { draft: next, step: initialStep } = buildInitialDraft(value);
setDraft(next);
setStep(next.length >= 3 ? 2 : next.length);
setStep(initialStep);
setOpen(true);
}
@@ -147,13 +180,14 @@ export default function ChinaRegionPicker({ value = [], onChange, disabled }: Ch
</p>
)}
<div className="partner-region-list" role="listbox">
<div className="partner-region-list" role="listbox" ref={listRef}>
{listItems.map((item) => (
<button
key={item.value}
type="button"
role="option"
aria-selected={activeCode === item.value}
ref={activeCode === item.value ? (el) => { activeItemRef.current = el; } : undefined}
className={`partner-region-item${activeCode === item.value ? ' partner-region-item--active' : ''}`}
onClick={() => selectItem(item.value)}
>
+14
View File
@@ -36,6 +36,20 @@ export function formatRegionLabel(region: ParsedChinaRegion): string {
return `${region.province} / ${region.city} / ${region.district}`;
}
/** 合伙人录店默认省市区 adcode:河南省 / 郑州市 / 金水区 */
export const DEFAULT_REGION_CODES = ['41', '4101', '410105'] as const;
export function getDefaultPartnerRegionForm() {
const regionCodes = [...DEFAULT_REGION_CODES];
const parsed = parseRegionCodes(regionCodes);
return {
regionCodes,
province: parsed?.province ?? '河南省',
city: parsed?.city ?? '郑州市',
district: parsed?.district ?? '金水区',
};
}
export function matchOpenCityId(cities: OpenCityRef[], districtCode: string): string | undefined {
const cityCode = districtCodeToCityCode(districtCode);
return (
+4 -5
View File
@@ -27,12 +27,11 @@ export function storeDraftKey(accountId?: string): string {
return accountId ? `${STORE_DRAFT_KEY}_${accountId}` : STORE_DRAFT_KEY;
}
import { getDefaultPartnerRegionForm } from './china-region';
export const defaultStoreForm = (): StoreDraftForm => ({
regionCodes: [],
...getDefaultPartnerRegionForm(),
cityId: '',
province: '',
city: '',
district: '',
name: '',
phone: '',
address: '',
@@ -54,7 +53,7 @@ export function normalizeStringArray(raw: unknown, length: number): string[] {
function normalizeForm(raw: Record<string, unknown>): StoreDraftForm {
const base = defaultStoreForm();
const regionCodes = Array.isArray(raw.regionCodes)
const regionCodes = Array.isArray(raw.regionCodes) && raw.regionCodes.length >= 3
? raw.regionCodes.map((code) => String(code))
: base.regionCodes;
return {
@@ -168,6 +168,30 @@ export default function StoreCreatePage() {
useEffect(() => {
if (!cities.length || form.regionCodes.length < 3 || form.cityId) return;
const binding = resolveRegionBinding(form.regionCodes, cities);
if (!binding) return;
patchForm({
cityId: binding.cityId ?? '',
province: binding.region.province,
city: binding.region.city,
district: binding.region.district,
});
}, [cities, form.regionCodes, form.cityId]);
const regionBindingHint = useMemo(() => {
if (!form.regionCodes.length) return null;