import React, { useState, useEffect } from 'react'; 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'; interface PreTestRecord { id: string; authorizationId: string; templateName: string; selectedFields: string[]; status: string; createdAt: string; } interface PreTestField { id: string; name: string; label: string; description?: string; } const PRETEST_FIELDS: PreTestField[] = [ { id: 'AD_APP_ACTIVATE', name: 'AD_APP_ACTIVATE', label: '应用-激活', description: '应用激活行为' }, { id: 'AD_APP_AUTH', name: 'AD_APP_AUTH', label: '应用-授信', description: '应用授信行为' }, { id: 'AD_APP_BOOK', name: 'AD_APP_BOOK', label: '应用-预约表单', description: '应用预约表单' }, { id: 'AD_APP_BUY', name: 'AD_APP_BUY', label: '应用-APP内付费', description: 'APP内付费行为' }, { id: 'AD_APP_CLICKS', name: 'AD_APP_CLICKS', label: '应用-点击量', description: '应用点击量' }, { id: 'AD_APP_DETAIL', name: 'AD_APP_DETAIL', label: '应用-APP内详情页到站UV', description: 'APP内详情页到站UV' }, { id: 'AD_APP_DOWNLOADED', name: 'AD_APP_DOWNLOADED', label: '应用-下载完成', description: '应用下载完成' }, { id: 'AD_APP_INSTALLED', name: 'AD_APP_INSTALLED', label: '应用-安装完成', description: '应用安装完成' }, { id: 'AD_APP_KEY_BEHAVIOR', name: 'AD_APP_KEY_BEHAVIOR', label: '应用-关键行为', description: '应用关键行为' }, { id: 'AD_APP_ORDER', name: 'AD_APP_ORDER', label: '应用-APP内下单', description: 'APP内下单行为' }, { id: 'AD_APP_PAY', name: 'AD_APP_PAY', label: '应用-付费', description: '应用付费行为' }, { id: 'AD_APP_PRE_AUTH', name: 'AD_APP_PRE_AUTH', label: '应用-预授信', description: '应用预授信行为' }, { id: 'AD_APP_PRE_DOWNLOAD', name: 'AD_APP_PRE_DOWNLOAD', label: '应用-预约下载', description: '应用预约下载' }, { id: 'AD_APP_PUSH_ORDER', name: 'AD_APP_PUSH_ORDER', label: '应用-首次发单(乘客)', description: '首次发单行为' }, { id: 'AD_APP_REGISTER', name: 'AD_APP_REGISTER', label: '应用-注册', description: '应用注册行为' }, { id: 'AD_APP_SHOW', name: 'AD_APP_SHOW', label: '应用-展示量', description: '应用展示量' }, { id: 'AD_APP_SUBMIT', name: 'AD_APP_SUBMIT', label: '应用-提交认证', description: '应用提交认证' }, { id: 'AD_APP_VIEW', name: 'AD_APP_VIEW', label: '应用-APP内访问', description: 'APP内访问行为' }, { id: 'AD_CLUE_AUTH', name: 'AD_CLUE_AUTH', label: '销售线索收集-授信', description: '销售线索授信' }, { id: 'AD_CLUE_BUTTON', name: 'AD_CLUE_BUTTON', label: '销售线索收集-按钮跳转', description: '按钮跳转' }, { id: 'AD_CLUE_CLICKS', name: 'AD_CLUE_CLICKS', label: '销售线索收集-点击量', description: '点击量' }, { id: 'AD_CLUE_CONFIRM', name: 'AD_CLUE_CONFIRM', label: '销售线索收集-回访-信息确认', description: '回访信息确认' }, { id: 'AD_CLUE_CONSULT', name: 'AD_CLUE_CONSULT', label: '销售线索收集-有效咨询', description: '有效咨询' }, { id: 'AD_CLUE_CONSULT_MSG', name: 'AD_CLUE_CONSULT_MSG', label: '销售线索收集-留资咨询', description: '留资咨询' }, { id: 'AD_CLUE_COUPON', name: 'AD_CLUE_COUPON', label: '销售线索收集-卡券领取', description: '卡券领取' }, { id: 'AD_CLUE_CUSTOMER', name: 'AD_CLUE_CUSTOMER', label: '销售线索收集-有效获客', description: '有效获客' }, { id: 'AD_CLUE_CVT', name: 'AD_CLUE_CVT', label: '销售线索收集-多转化', description: '多转化' }, { id: 'AD_CLUE_DONE', name: 'AD_CLUE_DONE', label: '销售线索收集-完件', description: '完件' }, { id: 'AD_CLUE_FORM', name: 'AD_CLUE_FORM', label: '销售线索收集-表单提交', description: '表单提交' }, { id: 'AD_CLUE_FRIENDS', name: 'AD_CLUE_FRIENDS', label: '销售线索收集-回访-加为好友', description: '回访加为好友' }, { id: 'AD_CLUE_INSURANCE', name: 'AD_CLUE_INSURANCE', label: '销售线索收集-保险支付', description: '保险支付' }, { id: 'AD_CLUE_INTENTION', name: 'AD_CLUE_INTENTION', label: '销售线索收集-存在意向', description: '存在意向' }, { id: 'AD_CLUE_INTENTION_FORM', name: 'AD_CLUE_INTENTION_FORM', label: '销售线索收集-意向表单', description: '意向表单' }, { id: 'AD_CLUE_INTENTION_TEL', name: 'AD_CLUE_INTENTION_TEL', label: '销售线索收集-意向话单', description: '意向话单' }, { id: 'AD_CLUE_MESSAGE', name: 'AD_CLUE_MESSAGE', label: '销售线索收集-私信消息', description: '私信消息' }, { id: 'AD_CLUE_MONEY', name: 'AD_CLUE_MONEY', label: '销售线索收集-放款', description: '放款' }, { id: 'AD_CLUE_MSG', name: 'AD_CLUE_MSG', label: '销售线索收集-私信留资', description: '私信留资' }, { id: 'AD_CLUE_PAGE', name: 'AD_CLUE_PAGE', label: '销售线索收集-访问目标页面', description: '访问目标页面' }, { id: 'AD_CLUE_PAY', name: 'AD_CLUE_PAY', label: '销售线索收集-付费', description: '付费' }, { id: 'AD_CLUE_PRE_AUTH', name: 'AD_CLUE_PRE_AUTH', label: '销售线索收集-预授信', description: '预授信' }, { id: 'AD_CLUE_PROTENTIAL_DEAL', name: 'AD_CLUE_PROTENTIAL_DEAL', label: '销售线索收集-回访-高潜成交', description: '回访高潜成交' }, { id: 'AD_CLUE_PUSH_ORDER', name: 'AD_CLUE_PUSH_ORDER', label: '销售线索收集-首次发单(乘客)', description: '首次发单' }, { id: 'AD_CLUE_REGISTER', name: 'AD_CLUE_REGISTER', label: '销售线索收集-注册', description: '注册' }, { id: 'AD_CLUE_SHOW', name: 'AD_CLUE_SHOW', label: '销售线索收集-展示量', description: '展示量' }, { id: 'AD_CLUE_SUBMIT', name: 'AD_CLUE_SUBMIT', label: '销售线索收集-提交认证', description: '提交认证' }, { id: 'AD_CLUE_TEL', name: 'AD_CLUE_TEL', label: '销售线索收集-智能电话确认接通', description: '智能电话确认接通' }, { id: 'AD_CLUE_TEL_CALL', name: 'AD_CLUE_TEL_CALL', label: '销售线索收集-电话接通', description: '电话接通' }, { id: 'AD_CLUE_WX_ADD', name: 'AD_CLUE_WX_ADD', label: '销售线索收集-微信-添加企业微信', description: '添加企业微信' }, { id: 'AD_CLUE_WX_COPY', name: 'AD_CLUE_WX_COPY', label: '销售线索收集-微信复制', description: '微信复制' }, { id: 'AD_CLUE_WX_MSG', name: 'AD_CLUE_WX_MSG', label: '销售线索收集-微信-用户首次消息', description: '用户首次消息' }, { id: 'AD_ECP_APP_BUY', name: 'AD_ECP_APP_BUY', label: '电商-app内下单', description: '电商app内下单' }, { id: 'AD_ECP_APP_DETAIL', name: 'AD_ECP_APP_DETAIL', label: '电商-app内详情页到站uv', description: '电商app内详情页到站uv' }, { id: 'AD_ECP_APP_VIEW', name: 'AD_ECP_APP_VIEW', label: '电商-app内访问', description: '电商app内访问' }, { id: 'AD_ECP_BUTTON', name: 'AD_ECP_BUTTON', label: '电商-按钮跳转', description: '电商按钮跳转' }, { id: 'AD_ECP_INTEREST', name: 'AD_ECP_INTEREST', label: '电商-引流电商种草', description: '引流电商种草' }, { id: 'AD_ECP_SHOP', name: 'AD_ECP_SHOP', label: '电商-调起店铺', description: '调起店铺' }, { id: 'AD_ECP_SHOP_STAY', name: 'AD_ECP_SHOP_STAY', label: '电商-店铺停留', description: '店铺停留' }, { id: 'AD_MINIAPP_ACTIVATE', name: 'AD_MINIAPP_ACTIVATE', label: '快应用-激活', description: '快应用激活' }, { id: 'AD_MINIAPP_KEY_BEHAVIOR', name: 'AD_MINIAPP_KEY_BEHAVIOR', label: '快应用-关键行为', description: '快应用关键行为' }, { id: 'AD_MINIAPP_PAY', name: 'AD_MINIAPP_PAY', label: '快应用-付费', description: '快应用付费' }, { id: 'AD_MINIAPP_REGISTER', name: 'AD_MINIAPP_REGISTER', label: '快应用-注册', description: '快应用注册' }, { id: 'AD_NATIVE_ACTIVATE', name: 'AD_NATIVE_ACTIVATE', label: '原声互动-激活', description: '原声互动激活' }, { id: 'AD_NATIVE_CLICKS', name: 'AD_NATIVE_CLICKS', label: '原声互动-组件点击', description: '组件点击' }, { id: 'AD_NATIVE_FANS_GROUP', name: 'AD_NATIVE_FANS_GROUP', label: '原声互动-粉丝入群', description: '粉丝入群' }, { id: 'AD_NATIVE_FOLLOW', name: 'AD_NATIVE_FOLLOW', label: '原声互动-帐号关注', description: '帐号关注' }, { id: 'AD_NATIVE_INTERACTIVE', name: 'AD_NATIVE_INTERACTIVE', label: '原声互动-互动', description: '互动' }, { id: 'AD_NATIVE_LIVE', name: 'AD_NATIVE_LIVE', label: '原声互动-预约直播', description: '预约直播' }, { id: 'AD_NATIVE_LIVE_DONATE', name: 'AD_NATIVE_LIVE_DONATE', label: '原声互动-直播间营销捐赠', description: '直播间营销捐赠' }, { id: 'AD_NATIVE_LIVE_PAY', name: 'AD_NATIVE_LIVE_PAY', label: '原声互动-直播间打赏', description: '直播间打赏' }, { id: 'AD_NATIVE_LIVE_STAY', name: 'AD_NATIVE_LIVE_STAY', label: '原声互动-直播间停留', description: '直播间停留' }, { id: 'AD_NATIVE_LIVE_VIEW', name: 'AD_NATIVE_LIVE_VIEW', label: '原声互动-直播间观看', description: '直播间观看' }, { id: 'AD_NATIVE_PAY', name: 'AD_NATIVE_PAY', label: '原声互动-付费', description: '原声互动付费' }, { id: 'AD_PRODUCT_ACTIVATE', name: 'AD_PRODUCT_ACTIVATE', label: '商品-激活', description: '商品激活' }, { id: 'AD_PRODUCT_APP_BUY', name: 'AD_PRODUCT_APP_BUY', label: '商品-app内下单', description: '商品app内下单' }, { id: 'AD_PRODUCT_APP_DETAIL', name: 'AD_PRODUCT_APP_DETAIL', label: '商品-app内详情页到站uv', description: '商品app内详情页到站uv' }, { id: 'AD_PRODUCT_APP_PAY', name: 'AD_PRODUCT_APP_PAY', label: '商品-app内付费', description: '商品app内付费' }, { id: 'AD_PRODUCT_APP_VIEW', name: 'AD_PRODUCT_APP_VIEW', label: '商品-app内访问', description: '商品app内访问' }, { id: 'AD_PRODUCT_FORM', name: 'AD_PRODUCT_FORM', label: '商品-表单提交', description: '商品表单提交' }, { id: 'AD_PRODUCT_KEY_BEHAVIOR', name: 'AD_PRODUCT_KEY_BEHAVIOR', label: '商品-关键行为', description: '商品关键行为' }, { id: 'AD_PRODUCT_PAY', name: 'AD_PRODUCT_PAY', label: '商品-付费', description: '商品付费' }, { id: 'AD_TINYAPP_ACTIVATE', name: 'AD_TINYAPP_ACTIVATE', label: '小程序-激活', description: '小程序激活' }, { id: 'AD_TINYAPP_KEY_BEHAVIOR', name: 'AD_TINYAPP_KEY_BEHAVIOR', label: '小程序-关键行为', description: '小程序关键行为' }, { id: 'AD_TINYAPP_PAY', name: 'AD_TINYAPP_PAY', label: '小程序-付费', description: '小程序付费' }, { id: 'QC_LIVE_BUY', name: 'QC_LIVE_BUY', label: '直播投放-直播间下单', description: '直播间下单' }, { id: 'QC_LIVE_CHECK', name: 'QC_LIVE_CHECK', label: '直播投放-直播间结算', description: '直播间结算' }, { id: 'QC_LIVE_COMMENTS', name: 'QC_LIVE_COMMENTS', label: '直播投放-直播间评论', description: '直播间评论' }, { id: 'QC_LIVE_DEAL', name: 'QC_LIVE_DEAL', label: '直播投放-直播间成交', description: '直播间成交' }, { id: 'QC_LIVE_ENTRY', name: 'QC_LIVE_ENTRY', label: '直播投放-进入直播间', description: '进入直播间' }, { id: 'QC_LIVE_FANS', name: 'QC_LIVE_FANS', label: '直播投放-直播间粉丝提升', description: '直播间粉丝提升' }, { id: 'QC_LIVE_HIT', name: 'QC_LIVE_HIT', label: '直播投放-直播加热', description: '直播加热' }, { id: 'QC_LIVE_PRODUCT_CLICKS', name: 'QC_LIVE_PRODUCT_CLICKS', label: '直播投放-直播间商品点击', description: '直播间商品点击' }, { id: 'QC_LIVE_ROI_CHECK', name: 'QC_LIVE_ROI_CHECK', label: '直播投放-结算roi', description: '结算roi' }, { id: 'QC_LIVE_ROI_DEAL', name: 'QC_LIVE_ROI_DEAL', label: '直播投放-支付roi-直播间成交', description: '支付roi直播间成交' }, { id: 'QC_LIVE_ROI_QC', name: 'QC_LIVE_ROI_QC', label: '直播投放-支付roi-千川直接+间接订单', description: '支付roi千川订单' }, { id: 'QC_PRODUCT_BUY', name: 'QC_PRODUCT_BUY', label: '商品投放-商品购买', description: '商品购买' }, { id: 'QC_PRODUCT_COMMENTS', name: 'QC_PRODUCT_COMMENTS', label: '商品投放-点赞评论', description: '点赞评论' }, { id: 'QC_PRODUCT_FANS', name: 'QC_PRODUCT_FANS', label: '商品投放-粉丝提升', description: '粉丝提升' }, { id: 'QC_PRODUCT_INTEREST', name: 'QC_PRODUCT_INTEREST', label: '商品投放-人群种草', description: '人群种草' }, { id: 'QC_PRODUCT_QC', name: 'QC_PRODUCT_QC', label: '商品投放-千川直接+间接订单', description: '千川订单' }, { id: 'QC_PRODUCT_ROI', name: 'QC_PRODUCT_ROI', label: '商品投放-商品支付roi', description: '商品支付roi' }, ]; const formatDateTime = (dateStr: string) => { if (!dateStr) return ''; const date = new Date(dateStr); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }; const PreTest: React.FC = () => { const { message } = App.useApp(); const [records, setRecords] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); const [modalOpen, setModalOpen] = useState(false); const [modalMode, setModalMode] = useState<'create' | 'edit' | 'detail'>('create'); const [currentRecord, setCurrentRecord] = useState(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); const [platform, setPlatform] = useState('AD'); const [searchPlatform, setSearchPlatform] = useState(undefined); const [areaOptions, setAreaOptions] = useState([]); const [cityCodeMap, setCityCodeMap] = useState>({}); const [provinceCityMap, setProvinceCityMap] = useState>({}); useEffect(() => { loadRecords(); }, [currentPage, pageSize]); useEffect(() => { loadProvinceOptions(); }, []); const loadRecords = async (params?: { page?: number; pageSize?: number; platform?: string }) => { setLoading(true); try { const page = params?.page ?? currentPage; const size = params?.pageSize ?? pageSize; const platform = params?.platform ?? searchPlatform; const res = await getPreTestList({ page, pageSize: size, platform }); setRecords(res.data || []); setTotal(res.pagination?.total || 0); setCurrentPage(res.pagination?.page || 1); setPageSize(res.pagination?.pageSize || 10); } catch (error) { message.error('获取前测列表失败'); } finally { setLoading(false); } }; const loadProvinceOptions = async () => { try { const cachedData = localStorage.getItem('preTestAreaData'); if (cachedData) { const parsed = JSON.parse(cachedData); setAreaOptions(parsed.areaOptions); setCityCodeMap(parsed.cityCodeMap); setProvinceCityMap(parsed.provinceCityMap); return; } const res = await getArea({ level: 'ONE_LEVEL' }); const provinces = res.data || []; const map: Record = {}; const provinceCity: Record = {}; const provinceOptions = await Promise.all( provinces.map(async (province: any) => { let cities: any[] = []; try { const cityRes = await getArea({ level: 'TWO_LEVEL', parent_code: province.code }); cities = (cityRes.data || []).map((city: any) => ({ value: city.code, label: city.name, isLeaf: true, })); const cityCodes = cities.map((city: any) => city.value); provinceCity[province.code] = cityCodes; cities.forEach((city: any) => { map[city.value] = city.label; }); } catch (error) { console.error(`获取省份 ${province.name} 的城市失败`, error); provinceCity[province.code] = []; } return { value: province.code, label: province.name, isLeaf: false, children: cities, }; }) ); const cacheData = { areaOptions: provinceOptions, cityCodeMap: map, provinceCityMap: provinceCity }; localStorage.setItem('preTestAreaData', JSON.stringify(cacheData)); setAreaOptions(provinceOptions); setCityCodeMap(map); setProvinceCityMap(provinceCity); } catch (error) { message.error('获取省份信息失败'); } }; const loadCityOptions = async (selectedOptions: any) => { const targetOption = selectedOptions[selectedOptions.length - 1]; targetOption.loading = true; try { const res = await getArea({ level: 'TWO_LEVEL', parent_code: targetOption.value }); targetOption.children = (res.data || []).map((item: any) => ({ value: item.code, label: item.name, isLeaf: true, })); targetOption.loading = false; setAreaOptions([...areaOptions]); } catch (error) { message.error('获取城市信息失败'); targetOption.loading = false; setAreaOptions([...areaOptions]); } }; const tableData = records.map((item, index) => ({ ...item, index: (currentPage - 1) * pageSize + index + 1, key: item.id, })); const columns = [ { title: '前测模板编号', dataIndex: 'id', key: 'id', width: 120, render: (text: string) => {text}, }, { title: '模板名称', dataIndex: 'name', key: 'name', ellipsis: true, render: (text: string) => ( {text} ), }, { title: '平台', dataIndex: 'platform', key: 'platform', render: (text: string) => ( {text === 'AD' ? 'AD' : text === 'QIANCHUAN' ? '千川' : '本地推'} ), }, { title: '转化目标', dataIndex: 'externalAction', key: 'externalAction', ellipsis: true, width: 200, render: (text: string) => { if (!text) return -; const field = PRETEST_FIELDS.find(f => f.name === text.trim()); return ( {field ? field.label : text} ); }, }, { title: '目标转化成本', dataIndex: 'cpaBid', key: 'cpaBid', width: 120, render: (text: number) => ( {text !== undefined ? text : '-'} ), }, { title: '受众性别', dataIndex: 'audienceGender', key: 'audienceGender', width: 90, render: (text: string) => ( {text === 'ALL' ? '不限' : text === 'MALE' ? '男' : text === 'FEMALE' ? '女' : text || '-'} ), }, { title: '受众年龄', dataIndex: 'audienceAge', key: 'audienceAge', width: 90, render: (text: string[]) => ( {Array.isArray(text) ? text.join(', ') : text || '-'} ), }, { title: '受众地区', dataIndex: 'audienceRegion', key: 'audienceRegion', ellipsis: true, width: 300, render: (text: string[]) => { if (!Array.isArray(text) || text.length === 0) { return -; } const cityNames = text.map(code => cityCodeMap[String(code)] || String(code)); return ( ) }, }, { title: '网络类型', dataIndex: 'audienceNetwork', key: 'audienceNetwork', width: 90, render: (text: string[]) => ( {Array.isArray(text) ? text.join(', ') : text || '-'} ), }, { title: '客户主体名称', dataIndex: 'cusName', key: 'cusName', ellipsis: true, width: 120, render: (text: string) => ( {text || '-'} ), }, { title: '出价类型', dataIndex: 'pricingType', key: 'pricingType', width: 90, render: (text: string) => ( {text || '-'} ), }, { title: '目标点击成本', dataIndex: 'cpcBid', key: 'cpcBid', width: 120, render: (text: number) => ( {text !== undefined ? text : '-'} ), }, { title: '预算金额', dataIndex: 'budget', key: 'budget', width: 100, render: (text: number) => ( {text !== undefined ? text : '-'} ), }, { title: '默认模板', dataIndex: 'isDefault', key: 'isDefault', width: 90, render: (text: boolean) => ( {text ? '是' : '否'} ), }, { title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', width: 160, render: (text: string) => {formatDateTime(text)}, }, { title: '操作', dataIndex: 'operation', fixed: 'right' as const, key: 'operation', render: (_: any, record: PreTestRecord) => ( ), }, ]; const handleOpenModal = () => { form.resetFields(); setPlatform('AD'); setModalMode('create'); setCurrentRecord(null); setModalOpen(true); }; const fillFormWithDetail = async (data: any) => { setCurrentRecord(data); setPlatform(data.platform || 'AD'); const regionCodes = data.audienceRegion || []; const regionPaths: string[][] = []; for (const code of regionCodes) { const cityCode = String(code); if (cityCode.length >= 6) { const provinceCode = cityCode.slice(0, 2); loadCityOptions(provinceCode); regionPaths.push([provinceCode, cityCode]); } } form.setFieldsValue({ name: data.name, note: data.note, platform: data.platform, external_action: data.externalAction, cpa_bid: data.cpaBid, audience_gender: data.audienceGender, audience_age: data.audienceAge || [], audience_region: regionPaths, audience_network: data.audienceNetwork || [], cus_name: data.cusName, pricing_type: data.pricingType, cost_cap: data.costCap !== undefined ? data.costCap : false, target_cost: data.targetCost !== undefined ? data.targetCost : false, nobid: data.nobid !== undefined ? data.nobid : false, cpc_bid: data.cpcBid, budget: data.budget, is_default: data.isDefault !== undefined ? data.isDefault : false, }); }; const handleDetail = async (record: PreTestRecord) => { try { const res = await getPreTestDetail(record.id); const data = res.data; setModalMode('detail'); fillFormWithDetail(data); setModalOpen(true); } catch (error) { message.error('获取详情失败'); } }; const handleEdit = async (record: PreTestRecord) => { try { const res = await getPreTestDetail(record.id); const data = res.data; setModalMode('edit'); fillFormWithDetail(data); setModalOpen(true); } catch (error) { message.error('获取详情失败'); } }; const handleDelete = (record: PreTestRecord) => { Modal.confirm({ title: '确认删除', content: '确定要删除该前测模板吗?', okText: '确定', cancelText: '取消', onOk: async () => { try { await deletePreTest(record.id); message.success('删除成功'); loadRecords(); } catch (error) { message.error('删除失败'); } }, }); }; const handleCloseModal = () => { setModalOpen(false); form.resetFields(); setPlatform('AD'); }; const handleSubmit = async () => { try { const values = await form.validateFields(); setSubmitLoading(true); const regionCodes: string[] = []; (values.audience_region || []).forEach((path: string[]) => { if (path.length === 1) { const provinceCode = path[0]; const cities = provinceCityMap[provinceCode] || []; regionCodes.push(...cities); } else if (path.length >= 2) { regionCodes.push(path[path.length - 1]); } }); const params = { name: values.name, note: values.note, platform: values.platform, external_action: values.external_action, cpa_bid: values.cpa_bid || 0, audience_gender: values.audience_gender, audience_age: values.audience_age || [], audience_region: regionCodes, audience_network: values.audience_network || [], cus_name: values.cus_name, pricing_type: values.pricing_type, cost_cap: values.cost_cap || false, target_cost: values.target_cost || false, nobid: values.nobid || false, cpc_bid: values.cpc_bid || 0, budget: values.budget || 0, is_default: values.is_default || false, }; let result; if (modalMode === 'edit' && currentRecord) { result = await updatePreTest(currentRecord.id, params); message.success('前测模板更新成功'); } else { result = await createPreTest(params); message.success('前测模板创建成功'); } setModalOpen(false); form.resetFields(); loadRecords(); } catch (error: any) { if (error?.message) { message.error(error.message); } else if (error?.response?.data?.message) { message.error(error.response.data.message); } else { message.error(modalMode === 'edit' ? '更新失败,请重试' : '创建失败,请重试'); } } finally { setSubmitLoading(false); } }; const handlePageChange = (page: number, size: number) => { setCurrentPage(page); setPageSize(size); }; return (
素材前测模板
{ 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: ( {field.label} {field.description && ( ({field.description}) )} ), }))} /> )}
parseFloat(e.target.value) || undefined} >
)}
parseFloat(e.target.value) || undefined} > parseFloat(e.target.value) || undefined} >