城市合伙人端的修改(后台)
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
Form,
|
||||
Image,
|
||||
Input,
|
||||
InputNumber,
|
||||
Modal,
|
||||
Select,
|
||||
Space,
|
||||
@@ -57,8 +58,7 @@ type CityOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
code: string;
|
||||
partnerId?: string | null;
|
||||
partner?: { id: string; companyName: string };
|
||||
partnerBindings?: Array<{ partnerAccountId: string; partnerCompanyName?: string }>;
|
||||
};
|
||||
|
||||
export default function StoresPage() {
|
||||
@@ -87,12 +87,12 @@ export default function StoresPage() {
|
||||
const [cities, setCities] = useState<CityOption[]>([]);
|
||||
const [optionsLoading, setOptionsLoading] = useState(false);
|
||||
|
||||
const selectedPartnerId = Form.useWatch('partnerId', createForm);
|
||||
const selectedPartnerId = Form.useWatch('partnerAccountId', createForm);
|
||||
const selectedRegionCodes = Form.useWatch('regionCodes', createForm);
|
||||
const selectedCityId = Form.useWatch('cityId', createForm);
|
||||
|
||||
function bindRegionSelection(codes: string[], partnerId?: string) {
|
||||
const binding = resolveRegionBinding(codes, cities, partnerId ?? selectedPartnerId);
|
||||
function bindRegionSelection(codes: string[], partnerAccountId?: string) {
|
||||
const binding = resolveRegionBinding(codes, cities, partnerAccountId ?? selectedPartnerId);
|
||||
if (!binding) {
|
||||
createForm.setFieldsValue({ regionCodes: codes, cityId: undefined });
|
||||
return;
|
||||
@@ -114,7 +114,7 @@ export default function StoresPage() {
|
||||
if (binding.cityId && binding.matchedCity) {
|
||||
return `已匹配开城城市:${binding.matchedCity.name}(区划 ${binding.cityCode},区县 ${binding.region.districtCode})`;
|
||||
}
|
||||
return `区划 ${binding.cityCode} 暂未开城,请先在「开城 → 开城城市」添加`;
|
||||
return `区划 ${binding.cityCode} 暂未开城,请先在「开城 → 城市」添加`;
|
||||
}, [selectedRegionCodes, cities, selectedPartnerId]);
|
||||
|
||||
async function loadOptions() {
|
||||
@@ -127,8 +127,8 @@ export default function StoresPage() {
|
||||
]);
|
||||
setPartners(p.items);
|
||||
setCities(c.items);
|
||||
if (!p.items.length) message.warning('暂无开城合伙人,请先在「开城 → 开城合伙人」中创建');
|
||||
if (!c.items.length) message.warning('暂无开城城市,请先在「开城 → 开城城市」中创建');
|
||||
if (!p.items.length) message.warning('暂无开城合伙人,请先在「开城 → 城市」详情中创建合伙人');
|
||||
if (!c.items.length) message.warning('暂无开城城市,请先在「开城 → 城市」中创建');
|
||||
} catch (e) {
|
||||
message.error(e instanceof Error ? e.message : '加载合伙人/城市失败');
|
||||
} finally {
|
||||
@@ -147,6 +147,7 @@ export default function StoresPage() {
|
||||
void loadOptions();
|
||||
createForm.setFieldsValue({
|
||||
envPhotoUrls: ['', '', ''],
|
||||
settlementRate: 60,
|
||||
});
|
||||
setCreateStep(0);
|
||||
setCreateError('');
|
||||
@@ -162,7 +163,7 @@ export default function StoresPage() {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await createForm.validateFields(['partnerId', 'regionCodes', 'cityId', 'name', 'phone', 'address']);
|
||||
await createForm.validateFields(['partnerAccountId', 'regionCodes', 'cityId', 'name', 'phone', 'address']);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
@@ -184,7 +185,7 @@ export default function StoresPage() {
|
||||
await request('/admin/stores', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
partnerId: values.partnerId,
|
||||
partnerAccountId: values.partnerAccountId,
|
||||
cityId: values.cityId,
|
||||
province: values.province,
|
||||
city: values.city,
|
||||
@@ -199,6 +200,7 @@ export default function StoresPage() {
|
||||
bankAccountName: values.bankAccountName.trim(),
|
||||
bankAccountNo: values.bankAccountNo.replace(/\s/g, ''),
|
||||
bankBranch: values.bankBranch.trim(),
|
||||
settlementRate: Number(values.settlementRate ?? 60) / 100,
|
||||
}),
|
||||
});
|
||||
message.success('门店已创建');
|
||||
@@ -208,7 +210,7 @@ export default function StoresPage() {
|
||||
if (e && typeof e === 'object' && 'errorFields' in e) {
|
||||
const fields = e as { errorFields?: Array<{ name: string[] }> };
|
||||
const first = fields.errorFields?.[0]?.name?.[0];
|
||||
if (first === 'partnerId' || first === 'cityId' || first === 'regionCodes' || first === 'name' || first === 'phone') {
|
||||
if (first === 'partnerAccountId' || first === 'cityId' || first === 'regionCodes' || first === 'name' || first === 'phone') {
|
||||
setCreateStep(0);
|
||||
}
|
||||
return;
|
||||
@@ -239,7 +241,15 @@ export default function StoresPage() {
|
||||
<Button type="link" size="small" onClick={async () => {
|
||||
const d = await request<Record<string, unknown>>(`/admin/stores/${row.id}`);
|
||||
setDetail(d);
|
||||
editForm.setFieldsValue({ name: d.name, phone: d.phone, intro: d.intro, coverUrl: d.coverUrl, address: d.address, district: d.district });
|
||||
editForm.setFieldsValue({
|
||||
name: d.name,
|
||||
phone: d.phone,
|
||||
intro: d.intro,
|
||||
coverUrl: d.coverUrl,
|
||||
address: d.address,
|
||||
district: d.district,
|
||||
settlementRate: d.settlementRate != null ? Number(d.settlementRate) * 100 : 60,
|
||||
});
|
||||
setDrawerOpen(true);
|
||||
}}>详情</Button>
|
||||
),
|
||||
@@ -279,7 +289,11 @@ export default function StoresPage() {
|
||||
}} />
|
||||
<Button type="primary" onClick={async () => {
|
||||
const v = await editForm.validateFields();
|
||||
await request(`/admin/stores/${detail.id}`, { method: 'PUT', body: JSON.stringify(v) });
|
||||
const payload = {
|
||||
...v,
|
||||
settlementRate: v.settlementRate != null ? Number(v.settlementRate) / 100 : undefined,
|
||||
};
|
||||
await request(`/admin/stores/${detail.id}`, { method: 'PUT', body: JSON.stringify(payload) });
|
||||
message.success('已保存');
|
||||
setDetail({ ...detail, ...v });
|
||||
void reload();
|
||||
@@ -291,6 +305,9 @@ export default function StoresPage() {
|
||||
<Descriptions column={1} bordered size="small" style={{ marginBottom: 16 }}>
|
||||
<Descriptions.Item label="ID">{String(detail.id)}</Descriptions.Item>
|
||||
<Descriptions.Item label="地址">{String(detail.province)}{String(detail.cityName)}{String(detail.district)}{String(detail.address)}</Descriptions.Item>
|
||||
<Descriptions.Item label="核销结算比例">
|
||||
{detail.settlementRate != null ? `${Math.round(Number(detail.settlementRate) * 100)}%` : '60%'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="核销数">{String(detail.redeemCount ?? 0)}</Descriptions.Item>
|
||||
<Descriptions.Item label="操作">
|
||||
<Button type="link" size="small" style={{ padding: 0 }} onClick={() => navigate(`/logs/stores?storeId=${detail.id}`)}>
|
||||
@@ -312,6 +329,9 @@ export default function StoresPage() {
|
||||
<Form.Item name="intro" label="介绍"><Input.TextArea rows={4} /></Form.Item>
|
||||
<Form.Item name="district" label="区县"><Input /></Form.Item>
|
||||
<Form.Item name="address" label="详细地址"><Input /></Form.Item>
|
||||
<Form.Item name="settlementRate" label="核销结算比例 %" initialValue={60} rules={[{ required: true }]}>
|
||||
<InputNumber min={0} max={100} precision={2} style={{ width: '100%' }} addonAfter="%" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</>
|
||||
)}
|
||||
@@ -339,16 +359,16 @@ export default function StoresPage() {
|
||||
)}
|
||||
<Form form={createForm} layout="vertical" preserve>
|
||||
<div style={{ display: createStep === 0 ? 'block' : 'none' }}>
|
||||
<Form.Item name="partnerId" label="开城合伙人" rules={[{ required: true, message: '请选择开城合伙人' }]}>
|
||||
<Form.Item name="partnerAccountId" label="开城合伙人" rules={[{ required: true, message: '请选择开城合伙人' }]}>
|
||||
<Select
|
||||
showSearch
|
||||
loading={optionsLoading}
|
||||
optionFilterProp="label"
|
||||
placeholder={optionsLoading ? '加载中…' : '请选择开城合伙人'}
|
||||
options={partners.map((p) => ({ value: p.id, label: p.companyName }))}
|
||||
onChange={(partnerId) => {
|
||||
onChange={(partnerAccountId) => {
|
||||
const codes = createForm.getFieldValue('regionCodes') as string[] | undefined;
|
||||
if (codes?.length === 3) bindRegionSelection(codes, partnerId);
|
||||
if (codes?.length === 3) bindRegionSelection(codes, partnerAccountId);
|
||||
else createForm.setFieldValue('cityId', undefined);
|
||||
}}
|
||||
/>
|
||||
@@ -418,6 +438,9 @@ export default function StoresPage() {
|
||||
<Form.Item name="bankBranch" label="开户支行" rules={[{ required: true, message: '请填写开户支行' }]}>
|
||||
<Input placeholder="例如:中国工商银行洛阳分行" />
|
||||
</Form.Item>
|
||||
<Form.Item name="settlementRate" label="核销结算比例 %" initialValue={60} rules={[{ required: true, message: '请填写结算比例' }]}>
|
||||
<InputNumber min={0} max={100} precision={2} style={{ width: '100%' }} addonAfter="%" />
|
||||
</Form.Item>
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
|
||||
Reference in New Issue
Block a user