feat(cps): 活动表单支持编辑 + 列表加编辑按钮

- ActivityFormModal 改 create+edit 双模式(回填字段, 编辑走 PATCH, 加状态切换)
- 活动列表操作列加「编辑」

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 22:13:36 +08:00
parent b1923c3133
commit cef5ea0140
+54 -18
View File
@@ -556,6 +556,7 @@ function ActivitiesTab() {
);
const canManage = canDo(['operator']);
const [createOpen, setCreateOpen] = useState(false);
const [editing, setEditing] = useState<CpsActivity | null>(null);
const delActivity = async (a: CpsActivity) => {
try {
@@ -613,17 +614,20 @@ function ActivitiesTab() {
title: '操作',
key: 'op',
fixed: 'right' as const,
width: 80,
width: 120,
render: (_: unknown, a: CpsActivity) => (
<Popconfirm
title="删除这个活动?"
description="已生成的链接仍可用;淘宝活动删除后其落地页改用默认图。"
okText="删除"
okButtonProps={{ danger: true }}
onConfirm={() => delActivity(a)}
>
<a style={{ color: '#cf1322' }}></a>
</Popconfirm>
<Space>
<a onClick={() => setEditing(a)}></a>
<Popconfirm
title="删除这个活动?"
description="已生成的链接仍可用;淘宝活动删除后其落地页改用默认图。"
okText="删除"
okButtonProps={{ danger: true }}
onConfirm={() => delActivity(a)}
>
<a style={{ color: '#cf1322' }}></a>
</Popconfirm>
</Space>
),
},
] as ColumnsType<CpsActivity>)
@@ -652,9 +656,10 @@ function ActivitiesTab() {
showTotal: (t) => `${t} 个活动`,
onChange,
}}
scroll={{ x: 1160 }}
scroll={{ x: 1200 }}
/>
<ActivityFormModal open={createOpen} onClose={() => setCreateOpen(false)} onDone={reload} />
<ActivityFormModal open={createOpen} activity={null} onClose={() => setCreateOpen(false)} onDone={reload} />
<ActivityFormModal open={!!editing} activity={editing} onClose={() => setEditing(null)} onDone={reload} />
</div>
);
}
@@ -734,22 +739,38 @@ function ImagePicker({ value, onChange }: { value?: string | null; onChange?: (v
function ActivityFormModal({
open,
activity,
onClose,
onDone,
}: {
open: boolean;
activity: CpsActivity | null;
onClose: () => void;
onDone: () => void;
}) {
const [form] = Form.useForm();
const isEdit = !!activity;
const platform = (Form.useWatch('platform', form) as string | undefined) || 'meituan';
useEffect(() => {
if (open) {
form.resetFields();
form.setFieldsValue({ platform: 'meituan' });
if (activity) {
form.setFieldsValue({
name: activity.name,
platform: activity.platform,
act_id: activity.act_id,
product_view_sign: activity.product_view_sign,
payload: activity.payload,
image_url: activity.image_url,
remark: activity.remark,
status: activity.status,
});
} else {
form.resetFields();
form.setFieldsValue({ platform: 'meituan' });
}
}
}, [open, form]);
}, [open, activity, form]);
const submit = async () => {
const v = await form.validateFields();
@@ -763,8 +784,13 @@ function ActivityFormModal({
return;
}
try {
await api.post('/admin/api/cps/activities', v);
message.success('已新建活动');
if (isEdit && activity) {
await api.patch(`/admin/api/cps/activities/${activity.id}`, v);
message.success('已更新活动');
} else {
await api.post('/admin/api/cps/activities', v);
message.success('已新建活动');
}
onClose();
onDone();
} catch (e) {
@@ -773,7 +799,7 @@ function ActivityFormModal({
};
return (
<Modal title="新建活动" open={open} onOk={submit} onCancel={onClose} destroyOnHidden>
<Modal title={isEdit ? '编辑活动' : '新建活动'} open={open} onOk={submit} onCancel={onClose} destroyOnHidden>
<Form form={form} layout="vertical" initialValues={{ platform: 'meituan' }}>
<Form.Item name="name" label="活动名" rules={[{ required: true }]}>
<Input placeholder="如:点我领取大额红包" />
@@ -823,6 +849,16 @@ function ActivityFormModal({
<Form.Item name="remark" label="备注">
<Input.TextArea rows={2} maxLength={256} />
</Form.Item>
{isEdit && (
<Form.Item name="status" label="状态">
<Select
options={[
{ value: 'active', label: '启用(active)' },
{ value: 'archived', label: '归档(archived)' },
]}
/>
</Form.Item>
)}
</Form>
</Modal>
);