From 3e001ce66f6f572c692d620c4365a816ea1acd24 Mon Sep 17 00:00:00 2001 From: Lrd <13001933075@sina.cn> Date: Thu, 9 Jul 2026 13:48:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=90=8E=E7=AB=AF=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- video-gen-admin/src/api/index.ts | 11 + .../src/pages/AdminMaterialList.tsx | 78 ++--- .../src/pages/AdminPreTestTemplates.tsx | 325 ++++++++++++++---- 3 files changed, 315 insertions(+), 99 deletions(-) diff --git a/video-gen-admin/src/api/index.ts b/video-gen-admin/src/api/index.ts index 981ea553..2a5885b8 100644 --- a/video-gen-admin/src/api/index.ts +++ b/video-gen-admin/src/api/index.ts @@ -1020,6 +1020,17 @@ export async function getPreTestTemplateList(params: PreTestTemplateListParams): return api.get(`/material-admin/pre-test-template-list?${query.toString()}`); } +export interface GetAreaParams { + level?: string; + parent_code?: string; +} +export async function getArea(params?: GetAreaParams): Promise { + const query = new URLSearchParams(); + if (params?.level) query.set('level', params.level); + if (params?.parent_code) query.set('parent_code', params.parent_code); + return api.get(`/pre-test-template/getArea?${query.toString()}`); +} + // ── Private Portrait Admin ──────────────────────────────── export async function adminGetPrivatePortraitProjects(params: { userId?: string; libraryType?: string; keyword?: string; status?: string; page?: number; pageSize?: number } = {}): Promise { const query = new URLSearchParams(); diff --git a/video-gen-admin/src/pages/AdminMaterialList.tsx b/video-gen-admin/src/pages/AdminMaterialList.tsx index af1bfecc..408a0097 100644 --- a/video-gen-admin/src/pages/AdminMaterialList.tsx +++ b/video-gen-admin/src/pages/AdminMaterialList.tsx @@ -46,37 +46,35 @@ const AdminMaterialList: React.FC = () => { key: 'advertiserId', }, { - title: '备注', - dataIndex: 'note', - key: 'note', - width: 200, - render: (text: string) => ( - - ), + title: '素材ID', + dataIndex: 'materialId', + key: 'materialId', + width: 180, }, { - title: '授权ID', - dataIndex: 'oauthId', - key: 'oauthId', - }, - { - title: '预测试结果', - dataIndex: 'preResult', - key: 'preResult', - width: 120, - render: (text: string) => , + title: '上传ID', + dataIndex: 'uploadId', + key: 'uploadId', + render: (v: string) => { + if (!v) return '-'; + const short = v.length > 12 ? `${v.slice(0, 6)}...${v.slice(-4)}` : v; + return ( + + {short} + + ); + }, }, { title: '预测试模板ID', dataIndex: 'preTestTemplateId', key: 'preTestTemplateId', }, + { + title: '授权ID', + dataIndex: 'oauthId', + key: 'oauthId', + }, { title: '目标标ID', dataIndex: 'targetId', @@ -98,24 +96,26 @@ const AdminMaterialList: React.FC = () => { key: 'userId', }, { - title: '素材ID', - dataIndex: 'materialId', - key: 'materialId', - width: 180, + title: '备注', + dataIndex: 'note', + key: 'note', + width: 200, + render: (text: string) => ( + + ), }, { - title: '上传ID', - dataIndex: 'uploadId', - key: 'uploadId', - render: (v: string) => { - if (!v) return '-'; - const short = v.length > 12 ? `${v.slice(0, 6)}...${v.slice(-4)}` : v; - return ( - - {short} - - ); - }, + title: '预测试结果', + dataIndex: 'preResult', + key: 'preResult', + width: 120, + render: (text: string) => , }, { title: '资源类型', diff --git a/video-gen-admin/src/pages/AdminPreTestTemplates.tsx b/video-gen-admin/src/pages/AdminPreTestTemplates.tsx index d0ec8e7e..2776d9c3 100644 --- a/video-gen-admin/src/pages/AdminPreTestTemplates.tsx +++ b/video-gen-admin/src/pages/AdminPreTestTemplates.tsx @@ -1,8 +1,119 @@ import React, { useEffect, useState } from 'react'; -import { Button, Input, Table, Pagination, Tag, Typography, DatePicker } from 'antd'; +import { Button, Input, Table, Pagination, Tag, Typography, DatePicker, message, Tooltip } from 'antd'; import { FileTextOutlined } from '@ant-design/icons'; -import { getPreTestTemplateList } from '../api'; +import { getPreTestTemplateList, getArea } from '../api'; import dayjs from 'dayjs'; + +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); @@ -24,6 +135,48 @@ const AdminPreTestTemplates: React.FC = () => { const [searchId, setSearchId] = useState(''); const [searchPhone, setSearchPhone] = useState(''); const [searchCreatedAt, setSearchCreatedAt] = useState<[dayjs.Dayjs, dayjs.Dayjs] | undefined>(); + const [cityCodeMap, setCityCodeMap] = useState>({}); + + useEffect(() => { + loadProvinceOptions(); + }, []); + + const loadProvinceOptions = async () => { + try { + const cachedData = localStorage.getItem('preTestAreaData'); + if (cachedData) { + const parsed = JSON.parse(cachedData); + setCityCodeMap(parsed.cityCodeMap); + return; + } + + const res = await getArea({ level: 'ONE_LEVEL' }); + const provinces = res.data || []; + const map: Record = {}; + 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 || []; + cities.forEach((city: any) => { + map[city.code] = city.name; + }); + } catch (error) { + console.error(`获取省份 ${province.name} 的城市失败`, error); + } + }) + ); + + const cacheData = { cityCodeMap: map }; + localStorage.setItem('preTestAreaData', JSON.stringify(cacheData)); + setCityCodeMap(map); + } catch (error) { + console.error('加载区域数据失败:', error); + message.error('加载区域数据失败'); + } + }; + const columns = [ { title: '序号', @@ -36,12 +189,53 @@ const AdminPreTestTemplates: React.FC = () => { title: 'ID', dataIndex: 'id', key: 'id', + width: 120, + render: (v: string) => { + if (!v) return '-'; + const short = v.length > 12 ? `${v.slice(0, 6)}...${v.slice(-4)}` : v; + return ( + + {short} + + ); + }, + }, + // { + // title: '手机号', + // dataIndex: 'phone', + // key: 'phone', + // width: 150, + // }, + { + title: '投放平台', + dataIndex: 'platform', + key: 'platform', + width: 100, + render: (text: string) => ( + + {text === 'AD' ? 'AD' : text === 'QIANCHUAN' ? '千川' : '本地推'} + + ), }, { - title: '手机号', - dataIndex: 'phone', - key: 'phone', - width: 150, + 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: 100, }, { title: '受众年龄', @@ -65,42 +259,68 @@ const AdminPreTestTemplates: React.FC = () => { title: '受众区域', dataIndex: 'audienceRegion', key: 'audienceRegion', - width: 100, + ellipsis: true, + width: 300, + render: (text: string) => { + const arr = JSON.parse(text); + if (!Array.isArray(arr) || arr.length === 0) { + return -; + } + const cityNames = arr.map(code => { + const paddedCode = String(code).padEnd(6, '0'); + return cityCodeMap[paddedCode] || paddedCode; + }); + return ( + + ) + }, }, { - title: '预算', - dataIndex: 'budget', - key: 'budget', - width: 100, - }, - { - title: '成本上限', - dataIndex: 'costCap', - key: 'costCap', - width: 100, - }, - { - title: 'CPA预算', - dataIndex: 'cpaBid', - key: 'cpaBid', - width: 100, - }, - { - title: 'CPC预算', - dataIndex: 'cpcBid', - key: 'cpcBid', - width: 100, - }, - { - title: '客户名称', + title: '客户主体名称', dataIndex: 'cusName', key: 'cusName', width: 150, }, { - title: '外部操作', - dataIndex: 'externalAction', - key: 'externalAction', + title: '计费方式', + dataIndex: 'pricingType', + key: 'pricingType', + width: 100, + }, + { + title: '是否最优成本出价', + dataIndex: 'costCap', + key: 'costCap', + width: 100, + }, + { + title: '是否稳定成本出价', + dataIndex: 'targetCost', + key: 'targetCost', + width: 100, + }, + { + title: '是否最大转化出价', + dataIndex: 'nobid', + key: 'nobid', + width: 100, + }, + { + title: '目标点击成本', + dataIndex: 'cpcBid', + key: 'cpcBid', + width: 100, + }, + { + title: '预算金额', + dataIndex: 'budget', + key: 'budget', width: 100, }, { @@ -109,41 +329,26 @@ const AdminPreTestTemplates: React.FC = () => { key: 'name', width: 150, }, - { - title: '名称', - dataIndex: 'nobid', - key: 'nobid', - width: 150, - }, { title: '备注', dataIndex: 'note', key: 'note', width: 150, }, - { - title: '平台', - dataIndex: 'platform', - key: 'platform', - width: 100, - }, - { - title: '定价类型', - dataIndex: 'pricingType', - key: 'pricingType', - width: 100, - }, - { - title: '目标成本', - dataIndex: 'targetCost', - key: 'targetCost', - width: 100, - }, { title: '用户ID', dataIndex: 'userId', key: 'userId', - width: 100, + width: 110, + render: (v: string) => { + if (!v) return '-'; + const short = v.length > 12 ? `${v.slice(0, 6)}...${v.slice(-4)}` : v; + return ( + + {short} + + ); + }, }, { title: '用户手机号',