前测模板选填添加收起功能
This commit is contained in:
+256
-244
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
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 { PlusOutlined, EditOutlined, FileTextOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
|
||||||
import { getPreTestList, createPreTest, getArea, getPreTestDetail, updatePreTest, deletePreTest } from '../api';
|
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 [modalMode, setModalMode] = useState<'create' | 'edit' | 'detail'>('create');
|
||||||
const [currentRecord, setCurrentRecord] = useState<PreTestRecord | null>(null);
|
const [currentRecord, setCurrentRecord] = useState<PreTestRecord | null>(null);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const [expandOptional, setExpandOptional] = useState(false);
|
||||||
const [submitLoading, setSubmitLoading] = useState(false);
|
const [submitLoading, setSubmitLoading] = useState(false);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(10);
|
const [pageSize, setPageSize] = useState(10);
|
||||||
@@ -692,7 +693,7 @@ const PreTest: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={<Space>{modalMode === 'create' ? '新增前测模板' : modalMode === 'edit' ? '编辑前测模板' : '前测模板详情'}</Space>}
|
title={<Space>{modalMode === 'create' ? '新增前测模板(选填项如填写需准确填写)' : modalMode === 'edit' ? '编辑前测模板(选填项如填写需准确填写)' : '前测模板详情'}</Space>}
|
||||||
open={modalOpen}
|
open={modalOpen}
|
||||||
onCancel={handleCloseModal}
|
onCancel={handleCloseModal}
|
||||||
onOk={handleSubmit}
|
onOk={handleSubmit}
|
||||||
@@ -743,257 +744,268 @@ const PreTest: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
{platform !== 'LOCAL' && (
|
<Collapse
|
||||||
<Form.Item
|
defaultActiveKey={[]}
|
||||||
name="external_action"
|
activeKey={expandOptional ? ['optional'] : []}
|
||||||
label="转化目标"
|
onChange={() => setExpandOptional(!expandOptional)}
|
||||||
>
|
|
||||||
<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="受众地区"
|
|
||||||
>
|
>
|
||||||
<Cascader
|
<Collapse.Panel header="选填项" key="optional">
|
||||||
multiple
|
{platform !== 'LOCAL' && (
|
||||||
placeholder="请选择受众地区(可多选)"
|
<Form.Item
|
||||||
style={{ borderRadius: 8, minHeight: 40 }}
|
name="external_action"
|
||||||
options={areaOptions}
|
label="转化目标"
|
||||||
maxTagCount="responsive"
|
>
|
||||||
/>
|
<Select
|
||||||
</Form.Item>
|
placeholder="请选择转化目标"
|
||||||
<div style={{ display: 'flex', gap: 16 }}>
|
style={{ borderRadius: 8, height: 40 }}
|
||||||
<Form.Item
|
options={PRETEST_FIELDS.filter(field => {
|
||||||
style={{ flex: 1 }}
|
if (platform === 'AD') {
|
||||||
name="cus_name"
|
return field.name.startsWith('AD_');
|
||||||
label="客户主体名称"
|
} else if (platform === 'QIANCHUAN') {
|
||||||
>
|
return field.name.startsWith('QC_');
|
||||||
<Input
|
} else if (platform === 'LOCAL') {
|
||||||
placeholder="请输入客户主体名称"
|
return field.name.startsWith('LOCAL_');
|
||||||
style={{ borderRadius: 8, height: 40 }}
|
}
|
||||||
/>
|
return true;
|
||||||
</Form.Item>
|
}).map(field => ({
|
||||||
<Form.Item
|
value: field.name,
|
||||||
style={{ flex: 1 }}
|
label: (
|
||||||
name="pricing_type"
|
<span>
|
||||||
label="出价类型"
|
{field.label}
|
||||||
>
|
{field.description && (
|
||||||
<Select
|
<Typography.Text style={{ color: '#94a3b8', fontSize: 12, marginLeft: 4 }}>
|
||||||
placeholder="请选择出价类型"
|
({field.description})
|
||||||
style={{ borderRadius: 8, height: 40 }}
|
</Typography.Text>
|
||||||
options={[
|
)}
|
||||||
{ value: 'OCPC', label: 'OCPC' },
|
</span>
|
||||||
{ value: 'CPA', label: 'CPA' },
|
),
|
||||||
{ value: 'OCPM', label: 'OCPM' },
|
}))}
|
||||||
]}
|
/>
|
||||||
/>
|
</Form.Item>
|
||||||
</Form.Item>
|
)}
|
||||||
</div>
|
|
||||||
{platform == 'AD' && (
|
<div style={{ display: 'flex', gap: 16 }}>
|
||||||
<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
|
<Form.Item
|
||||||
style={{ flex: 1 }}
|
name="audience_region"
|
||||||
name="cost_cap"
|
label="受众地区"
|
||||||
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
|
<Select
|
||||||
placeholder="是否最优成本出价"
|
placeholder="请选择默认模板"
|
||||||
style={{ borderRadius: 8, height: 40 }}
|
style={{ borderRadius: 8, height: 40 }}
|
||||||
options={[
|
options={[
|
||||||
{ value: true, label: '开启' },
|
{ value: true, label: '是' },
|
||||||
{ value: false, label: '关闭' },
|
{ value: false, label: '否' },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Collapse.Panel>
|
||||||
<Form.Item
|
</Collapse>
|
||||||
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>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user