前测模板选填添加收起功能
This commit is contained in:
+256
-244
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Table, Tag, Button, Typography, Space, Modal, Form, Input, Select, Cascader, App, Pagination } from 'antd';
|
||||
import { Table, Tag, Button, Typography, Space, Modal, Form, Input, Select, Cascader, App, Pagination, Collapse } from 'antd';
|
||||
import { PlusOutlined, EditOutlined, FileTextOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
|
||||
import { getPreTestList, createPreTest, getArea, getPreTestDetail, updatePreTest, deletePreTest } from '../api';
|
||||
|
||||
@@ -143,6 +143,7 @@ const PreTest: React.FC = () => {
|
||||
const [modalMode, setModalMode] = useState<'create' | 'edit' | 'detail'>('create');
|
||||
const [currentRecord, setCurrentRecord] = useState<PreTestRecord | null>(null);
|
||||
const [form] = Form.useForm();
|
||||
const [expandOptional, setExpandOptional] = useState(false);
|
||||
const [submitLoading, setSubmitLoading] = useState(false);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
@@ -692,7 +693,7 @@ const PreTest: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
title={<Space>{modalMode === 'create' ? '新增前测模板' : modalMode === 'edit' ? '编辑前测模板' : '前测模板详情'}</Space>}
|
||||
title={<Space>{modalMode === 'create' ? '新增前测模板(选填项如填写需准确填写)' : modalMode === 'edit' ? '编辑前测模板(选填项如填写需准确填写)' : '前测模板详情'}</Space>}
|
||||
open={modalOpen}
|
||||
onCancel={handleCloseModal}
|
||||
onOk={handleSubmit}
|
||||
@@ -743,257 +744,268 @@ const PreTest: React.FC = () => {
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
{platform !== 'LOCAL' && (
|
||||
<Form.Item
|
||||
name="external_action"
|
||||
label="转化目标"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择转化目标"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={PRETEST_FIELDS.filter(field => {
|
||||
if (platform === 'AD') {
|
||||
return field.name.startsWith('AD_');
|
||||
} else if (platform === 'QIANCHUAN') {
|
||||
return field.name.startsWith('QC_');
|
||||
} else if (platform === 'LOCAL') {
|
||||
return field.name.startsWith('LOCAL_');
|
||||
}
|
||||
return true;
|
||||
}).map(field => ({
|
||||
value: field.name,
|
||||
label: (
|
||||
<span>
|
||||
{field.label}
|
||||
{field.description && (
|
||||
<Typography.Text style={{ color: '#94a3b8', fontSize: 12, marginLeft: 4 }}>
|
||||
({field.description})
|
||||
</Typography.Text>
|
||||
)}
|
||||
</span>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cpa_bid"
|
||||
label="目标转化成本"
|
||||
rules={[
|
||||
{ type: 'number', min: 1, max: 10000, message: '取值范围: 1-10000' },
|
||||
]}
|
||||
getValueFromEvent={(e) => parseFloat(e.target.value) || undefined}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="取值范围: 1-10000,精确到小数点后2位"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
min={1}
|
||||
max={10000}
|
||||
step={0.01}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="audience_gender"
|
||||
label="受众性别"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择受众性别"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: 'ALL', label: '不限' },
|
||||
{ value: 'MALE', label: '男' },
|
||||
{ value: 'FEMALE', label: '女' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="audience_age"
|
||||
label="受众年龄"
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="请选择受众年龄(可多选)"
|
||||
style={{ borderRadius: 8, minHeight: 40 }}
|
||||
maxTagCount="responsive"
|
||||
options={[
|
||||
{ value: 'ALL', label: '不限' },
|
||||
{ value: '18-23', label: '18-23岁' },
|
||||
{ value: '24-30', label: '24-30岁' },
|
||||
{ value: '31-40', label: '31-40岁' },
|
||||
{ value: '41-49', label: '41-49岁' },
|
||||
{ value: '50', label: '50岁以上' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="audience_network"
|
||||
label="网络类型"
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="请选择网络类型(可多选)"
|
||||
style={{ borderRadius: 8, minHeight: 40 }}
|
||||
maxTagCount="responsive"
|
||||
options={[
|
||||
{ value: 'ALL', label: '不限' },
|
||||
{ value: '5G', label: '5G' },
|
||||
{ value: '4G', label: '4G' },
|
||||
{ value: '3G', label: '3G' },
|
||||
{ value: '2G', label: '2G' },
|
||||
{ value: 'WIFI', label: 'wifi' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
<Form.Item
|
||||
name="audience_region"
|
||||
label="受众地区"
|
||||
<Collapse
|
||||
defaultActiveKey={[]}
|
||||
activeKey={expandOptional ? ['optional'] : []}
|
||||
onChange={() => setExpandOptional(!expandOptional)}
|
||||
>
|
||||
<Cascader
|
||||
multiple
|
||||
placeholder="请选择受众地区(可多选)"
|
||||
style={{ borderRadius: 8, minHeight: 40 }}
|
||||
options={areaOptions}
|
||||
maxTagCount="responsive"
|
||||
/>
|
||||
</Form.Item>
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cus_name"
|
||||
label="客户主体名称"
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入客户主体名称"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="pricing_type"
|
||||
label="出价类型"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择出价类型"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: 'OCPC', label: 'OCPC' },
|
||||
{ value: 'CPA', label: 'CPA' },
|
||||
{ value: 'OCPM', label: 'OCPM' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
{platform == 'AD' && (
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Collapse.Panel header="选填项" key="optional">
|
||||
{platform !== 'LOCAL' && (
|
||||
<Form.Item
|
||||
name="external_action"
|
||||
label="转化目标"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择转化目标"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={PRETEST_FIELDS.filter(field => {
|
||||
if (platform === 'AD') {
|
||||
return field.name.startsWith('AD_');
|
||||
} else if (platform === 'QIANCHUAN') {
|
||||
return field.name.startsWith('QC_');
|
||||
} else if (platform === 'LOCAL') {
|
||||
return field.name.startsWith('LOCAL_');
|
||||
}
|
||||
return true;
|
||||
}).map(field => ({
|
||||
value: field.name,
|
||||
label: (
|
||||
<span>
|
||||
{field.label}
|
||||
{field.description && (
|
||||
<Typography.Text style={{ color: '#94a3b8', fontSize: 12, marginLeft: 4 }}>
|
||||
({field.description})
|
||||
</Typography.Text>
|
||||
)}
|
||||
</span>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cpa_bid"
|
||||
label="目标转化成本"
|
||||
rules={[
|
||||
{ type: 'number', min: 1, max: 10000, message: '取值范围: 1-10000' },
|
||||
]}
|
||||
getValueFromEvent={(e) => parseFloat(e.target.value) || undefined}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="取值范围: 1-10000,精确到小数点后2位"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
min={1}
|
||||
max={10000}
|
||||
step={0.01}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="audience_gender"
|
||||
label="受众性别"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择受众性别"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: 'ALL', label: '不限' },
|
||||
{ value: 'MALE', label: '男' },
|
||||
{ value: 'FEMALE', label: '女' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="audience_age"
|
||||
label="受众年龄"
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="请选择受众年龄(可多选)"
|
||||
style={{ borderRadius: 8, minHeight: 40 }}
|
||||
maxTagCount="responsive"
|
||||
options={[
|
||||
{ value: 'ALL', label: '不限' },
|
||||
{ value: '18-23', label: '18-23岁' },
|
||||
{ value: '24-30', label: '24-30岁' },
|
||||
{ value: '31-40', label: '31-40岁' },
|
||||
{ value: '41-49', label: '41-49岁' },
|
||||
{ value: '50', label: '50岁以上' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="audience_network"
|
||||
label="网络类型"
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="请选择网络类型(可多选)"
|
||||
style={{ borderRadius: 8, minHeight: 40 }}
|
||||
maxTagCount="responsive"
|
||||
options={[
|
||||
{ value: 'ALL', label: '不限' },
|
||||
{ value: '5G', label: '5G' },
|
||||
{ value: '4G', label: '4G' },
|
||||
{ value: '3G', label: '3G' },
|
||||
{ value: '2G', label: '2G' },
|
||||
{ value: 'WIFI', label: 'wifi' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cost_cap"
|
||||
label="是否最优成本出价"
|
||||
name="audience_region"
|
||||
label="受众地区"
|
||||
>
|
||||
<Cascader
|
||||
multiple
|
||||
placeholder="请选择受众地区(可多选)"
|
||||
style={{ borderRadius: 8, minHeight: 40 }}
|
||||
options={areaOptions}
|
||||
maxTagCount="responsive"
|
||||
/>
|
||||
</Form.Item>
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cus_name"
|
||||
label="客户主体名称"
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入客户主体名称"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="pricing_type"
|
||||
label="出价类型"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择出价类型"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: 'OCPC', label: 'OCPC' },
|
||||
{ value: 'CPA', label: 'CPA' },
|
||||
{ value: 'OCPM', label: 'OCPM' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
{platform == 'AD' && (
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cost_cap"
|
||||
label="是否最优成本出价"
|
||||
initialValue={false}
|
||||
>
|
||||
<Select
|
||||
placeholder="是否最优成本出价"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '开启' },
|
||||
{ value: false, label: '关闭' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="target_cost"
|
||||
label="是否稳定成本出价"
|
||||
initialValue={false}
|
||||
>
|
||||
<Select
|
||||
placeholder="是否稳定成本出价"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '开启' },
|
||||
{ value: false, label: '关闭' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="nobid"
|
||||
label="是否最大转化出价"
|
||||
initialValue={false}
|
||||
>
|
||||
<Select
|
||||
placeholder="是否最大转化出价"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '开启' },
|
||||
{ value: false, label: '关闭' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cpc_bid"
|
||||
label="目标点击成本"
|
||||
getValueFromEvent={(e) => parseFloat(e.target.value) || undefined}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="请输入目标点击成本"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="budget"
|
||||
label="预算金额"
|
||||
getValueFromEvent={(e) => parseFloat(e.target.value) || undefined}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="请输入预算金额"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<Form.Item
|
||||
name="note"
|
||||
label="备注"
|
||||
>
|
||||
<Input.TextArea
|
||||
placeholder="请输入备注"
|
||||
rows={2}
|
||||
style={{ borderRadius: 8 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="is_default"
|
||||
label="默认模板"
|
||||
initialValue={false}
|
||||
>
|
||||
<Select
|
||||
placeholder="是否最优成本出价"
|
||||
placeholder="请选择默认模板"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '开启' },
|
||||
{ value: false, label: '关闭' },
|
||||
{ value: true, label: '是' },
|
||||
{ value: false, label: '否' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="target_cost"
|
||||
label="是否稳定成本出价"
|
||||
>
|
||||
<Select
|
||||
placeholder="是否稳定成本出价"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '开启' },
|
||||
{ value: false, label: '关闭' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="nobid"
|
||||
label="是否最大转化出价"
|
||||
>
|
||||
<Select
|
||||
placeholder="是否最大转化出价"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '开启' },
|
||||
{ value: false, label: '关闭' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ display: 'flex', gap: 16 }}>
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="cpc_bid"
|
||||
label="目标点击成本"
|
||||
getValueFromEvent={(e) => parseFloat(e.target.value) || undefined}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="请输入目标点击成本"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
style={{ flex: 1 }}
|
||||
name="budget"
|
||||
label="预算金额"
|
||||
getValueFromEvent={(e) => parseFloat(e.target.value) || undefined}
|
||||
>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder="请输入预算金额"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<Form.Item
|
||||
name="note"
|
||||
label="备注"
|
||||
>
|
||||
<Input.TextArea
|
||||
placeholder="请输入备注"
|
||||
rows={2}
|
||||
style={{ borderRadius: 8 }}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="is_default"
|
||||
label="默认模板"
|
||||
initialValue={false}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择默认模板"
|
||||
style={{ borderRadius: 8, height: 40 }}
|
||||
options={[
|
||||
{ value: true, label: '是' },
|
||||
{ value: false, label: '否' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Collapse.Panel>
|
||||
</Collapse>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user