123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- import { useAjax } from "@/Hook/useAjax"
- import { delBatchApi, modifyAdTimeBatchApi, modifyAmountBatchApi, modifyDailyBudgetBatchApi, updateBatchAdgroupInfoApi } from "@/services/launchAdq/adqv3"
- import { Button, Card, DatePicker, Form, Input, InputNumber, Modal, Radio, Select, Space, Table, message } from "antd"
- import React, { useEffect, useState } from "react"
- import '../../tencentAdPutIn/index.less'
- import { RangePickerProps } from "antd/lib/date-picker"
- import moment from "moment"
- import style from '../../tencentAdPutIn/create/index.less'
- import TimeInSelect from "@/pages/launchSystemNew/components/timeInSelect"
- import { getTimeSeriesList } from "@/pages/launchSystemNew/adq/ad/const"
- import { txtLength } from "@/utils/utils"
- import InputName from "@/components/InputName"
- import New1Radio from "../../components/New1Radio"
- import { SelectTimeList } from "../../tencentAdPutIn/const"
- interface Props {
- type: '修改出价' | '修改名称' | '修改日限额' | '修改投放时间' | '删除' | '深度优化ROI' | '修改投放首日开始时间'
- updateData: any[],
- visible?: boolean,
- onClose?: () => void
- onChange?: () => void
- }
- const UpdateAd3: React.FC<Props> = ({ visible, type, onClose, onChange, updateData }) => {
- /****************************************/
- const [form] = Form.useForm();
- const timeSeriesType = Form.useWatch('timeSeriesType', form)
- const updateType = Form.useWatch('updateType', form)
- const [failIdList, setFailIdList] = useState<{ adgroupId: number, code: number, message: string, messageCn: string }[]>([])
- const [failVisible, setFailVisible] = useState<boolean>(false)
- const modifyAmountBatch = useAjax((params) => modifyAmountBatchApi(params)) // 出价
- const modifyAdTimeBatch = useAjax((params) => modifyAdTimeBatchApi(params)) // 时间
- const updateBatchAdgroupInfo = useAjax((params) => updateBatchAdgroupInfoApi(params)) // 名称
- const modifyDailyBudgetBatch = useAjax((params) => modifyDailyBudgetBatchApi(params)) // 日限额
- const delBatch = useAjax((params) => delBatchApi(params)) // 删除
- /****************************************/
- useEffect(() => {
- if (type === '删除') {
- form.setFieldsValue({ delAd: updateData.map(item => item.adgroupName) })
- } else if (type === '深度优化ROI') {
- form.setFieldsValue({ deepConversionSpec: updateData?.[0]?.deepConversionSpec })
- }
- }, [type, updateData])
- const handleOk = (values: any) => {
- console.log(values)
- let accountAdgroupMaps = [...new Set(updateData?.map(item => item.accountId + ',' + item.adgroupId))]
- switch (type) {
- case '修改出价':
- let paramsCj: any = {}
- if (values?.updateType === 'percent') {
- paramsCj.bidAmountPercent = values?.bidAmountPercent / 100
- } else {
- paramsCj.bidAmount = values?.bidAmount
- }
- modifyAmountBatch.run({ accountAdgroupMaps, ...paramsCj }).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`修改操作完成!`)
- onChange?.()
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- })
- break
- case '修改名称':
- case '深度优化ROI':
- case '修改投放首日开始时间':
- let params2: any = {}
- if (type === '深度优化ROI') {
- params2 = JSON.parse(JSON.stringify(values))
- if (params2.updateType === 'percent') {
- delete params2?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoi
- params2.deepConversionSpec.deepConversionWorthSpec.expectedRoiPercent = params2?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoiPercent / 100
- } else {
- delete params2?.deepConversionSpec?.deepConversionWorthSpec?.expectedRoiPercent
- }
- delete params2.updateType
- } else {
- params2 = values
- }
- updateBatchAdgroupInfo.run({ accountAdgroupMaps, ...params2 }).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`修改操作完成!`)
- onChange?.()
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- })
- break
- case '修改投放时间':
- let params = { accountAdgroupMaps, ...values }
- params.beginDate = moment(params.date[0]).format('YYYY-MM-DD')
- params.endDate = moment(params.date[1]).format('YYYY-MM-DD')
- if (params.timeSeriesType === '0') {
- // params.timeSeries = Array(336).fill(1).join('');
- } else {
- params.timeSeries = params.timeSeries.join('');
- }
- delete params.timeSeriesType
- delete params.date
- modifyAdTimeBatch.run(params).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`修改操作完成!`)
- onChange?.()
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- })
- break
- case '修改日限额':
- modifyDailyBudgetBatch.run({ accountAdgroupMaps, ...values }).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`修改操作完成!`)
- onChange?.()
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- })
- break
- case '删除':
- delBatch.run({ accountAdgroupMaps }).then(res => {
- if (res?.failIdList?.length === 0) {
- message.success(`删除广告操作完成!`)
- onChange?.()
- } else {
- setFailIdList(res?.list || [])
- setFailVisible(true)
- }
- })
- break
- }
- }
- /** 禁止选择以前时间 */
- const disabledDate: RangePickerProps['disabledDate'] = current => {
- // Can not select days before today and today
- return current && current < moment().startOf('day');
- };
- return <>
- <Modal
- title={<strong>{type}</strong>}
- open={visible}
- footer={null}
- onCancel={onClose}
- bodyStyle={{ padding: '0 0 40px', position: 'relative', borderRadius: '0 0 8px 8px' }}
- className='modalResetCss'
- width={type === '修改投放时间' ? 900 : type === '深度优化ROI' ? 800 : 600}
- >
- <Form
- form={form}
- name="updateAd3.0"
- labelAlign='left'
- labelCol={{ span: ['修改投放首日开始时间', '修改出价'].includes(type) ? 6 : 4 }}
- colon={false}
- style={{ backgroundColor: '#f1f4fc', maxHeight: 600, overflow: 'hidden', overflowY: 'auto', padding: '10px 10px 10px', borderRadius: '0 0 8px 8px' }}
- scrollToFirstError
- onFinishFailed={({ errorFields }) => {
- message.error(errorFields?.[0]?.errors?.[0])
- }}
- onFinish={handleOk}
- initialValues={{ timeSeriesType: '0', timeSeries: getTimeSeriesList(), updateType: 'fixed' }}
- >
- <Card
- title={<strong style={{ fontSize: 14 }}>{type === '删除' ? '确认删除?' : '修改设置'}</strong>}
- className="cardResetCss"
- >
- {type === '修改出价' ? <>
- <Form.Item
- label={<strong>出价修改方式</strong>}
- name='updateType'
- rules={[
- { required: true, message: '请选择出价修改方式' }
- ]}
- >
- <Radio.Group buttonStyle="solid">
- <Radio.Button value="fixed">固定值</Radio.Button>
- <Radio.Button value="percent">百分比上下浮动修改</Radio.Button>
- </Radio.Group>
- </Form.Item>
- {updateType === 'fixed' ? <Form.Item
- label={<strong>出价</strong>}
- name='bidAmount'
- rules={[
- { required: true, message: '请输入' }
- ]}
- >
- <InputNumber min={0} style={{ width: '100%' }} placeholder="请输入价格 元" />
- </Form.Item> : <Form.Item
- label={<strong>浮动比</strong>}
- name='bidAmountPercent'
- rules={[
- { required: true, message: '请输入' }
- ]}
- >
- <InputNumber placeholder="出价,原有基础上下调百分比" style={{ width: '100%' }} addonAfter="%" />
- </Form.Item>}
- </> : type === '修改名称' ? <Form.Item
- label={<strong>广告名称</strong>}
- name='adgroupName'
- // tooltip="下标、日期时分秒、广告账户创建时默认自带"
- rules={[
- { required: true, message: '请输入广告名称!' },
- {
- required: true, message: '广告名称不能包含特殊字符:< > & ‘ ” / 以及TAB、换行、回车键,请修改', validator(_, value) {
- let reg = /[&‘’“”/\n\t\f]/ig
- if (value && reg.test(value)) {
- return Promise.reject()
- }
- return Promise.resolve()
- }
- },
- {
- required: true, message: '请确保广告名称长度不超过60个字(1个汉字等于2个字符)', validator(_, value) {
- if (value && txtLength(value) > 50) {
- return Promise.reject()
- }
- return Promise.resolve()
- }
- }
- ]}
- >
- <InputName placeholder='广告名称' style={{ width: 420 }} length={50} />
- </Form.Item> : type === '修改日限额' ? <Form.Item
- label={<strong>日限额</strong>}
- name='bidAmount'
- rules={[
- { required: true, message: '请输入' }
- ]}
- >
- <InputNumber min={0} style={{ width: '100%' }} placeholder="请输入日限额 元" />
- </Form.Item> : type === '修改投放时间' ? <>
- <Form.Item label={<strong>投放日期</strong>} name='date' rules={[{ required: true, message: '请选择投放日期' }]}>
- <DatePicker.RangePicker disabledDate={disabledDate} />
- </Form.Item>
- <Form.Item label={<strong>投放时间</strong>}>
- <Card bordered className="cardResetCss newCss" bodyStyle={{ padding: 0 }}>
- <div className={style.newSpace}>
- <div className={style.newSpace_top}>
- <div className={style.newSpace_title} style={{ width: 78 }}>选择时段</div>
- <Form.Item name='timeSeriesType' style={{ marginBottom: 0 }}>
- <Radio.Group>
- <Radio value="0">全天</Radio>
- <Radio value="2">指定多个时段</Radio>
- </Radio.Group>
- </Form.Item>
- </div>
- {timeSeriesType === '2' && <div className={style.newSpace_bottom} style={{ marginLeft: 65 }}>
- <Form.Item name='timeSeries' noStyle rules={[{ required: true, message: '请选择时段' }]}>
- <TimeInSelect />
- </Form.Item>
- </div>}
- </div>
- </Card>
- </Form.Item>
- </> : type === '删除' ? <Form.Item label={<strong>广告名称</strong>} name='delAd' rules={[{ required: true, message: '请选择广告' }]}>
- <Input.TextArea disabled />
- </Form.Item> : type === '深度优化ROI' ? <>
- <Form.Item label={<strong>深度优化类型</strong>} name={['deepConversionSpec', 'deepConversionType']} rules={[{ required: true, message: '请选择深度优化类型' }]}>
- <New1Radio data={[{ label: '优化ROI', value: 'DEEP_CONVERSION_WORTH', disabled: true }]} />
- </Form.Item>
- <Form.Item label={<strong>深度优化目标</strong>} name={['deepConversionSpec', 'deepConversionWorthSpec', 'goal']} rules={[{ required: true, message: '请选择深度优化目标' }]}>
- <Select style={{ width: 480 }} placeholder='请选择'>
- <Select.Option value={'GOAL_1DAY_PURCHASE_ROAS'}>首日付费ROI</Select.Option>
- </Select>
- </Form.Item>
- <Form.Item
- label={<strong>期望ROI修改方式</strong>}
- name='updateType'
- rules={[
- { required: true, message: '请选择期望ROI修改方式' }
- ]}
- >
- <Radio.Group buttonStyle="solid">
- <Radio.Button value="fixed">固定值</Radio.Button>
- <Radio.Button value="percent">百分比上下浮动修改</Radio.Button>
- </Radio.Group>
- </Form.Item>
- {updateType === 'fixed' ? <Form.Item
- label={<strong>期望ROI</strong>}
- name={['deepConversionSpec', 'deepConversionWorthSpec', 'expectedRoi']}
- rules={[
- { required: true, message: '请输入期望ROI' },
- { type: 'number', min: 0.001, max: 1000, message: '范围0.001~1000' },
- {
- validator: (_: any, value: string) => {
- if (!value || /^\d+(\.\d{0,3})?$/.test(value)) {
- return Promise.resolve();
- }
- return Promise.reject(new Error('请输入最多三位小数'));
- }
- }
- ]}
- >
- <InputNumber style={{ width: 480 }} placeholder={`期望ROI目标范围0.001~1000,输入0.05,表示ROI目标为5%`} />
- </Form.Item> : <Form.Item
- label={<strong>期望ROI浮动比</strong>}
- name={['deepConversionSpec', 'deepConversionWorthSpec', 'expectedRoiPercent']}
- rules={[{ required: true, message: '请输入期望ROI浮动比' }]}
- >
- <InputNumber style={{ width: 480 }} placeholder="期望ROI,原有基础上下调百分比" addonAfter="%" />
- </Form.Item>}
- </> : type === '修改投放首日开始时间' ? <Form.Item name='firstDayBeginTime' label={<strong>首日开始时间</strong>} rules={[{ required: true, message: '请选择首日开始时间' }]}>
- <Select
- style={{ width: 180 }}
- allowClear
- placeholder='请选择首日开始时间'
- options={SelectTimeList}
- />
- </Form.Item> : null}
- </Card>
- <Form.Item className="submit_pull">
- <Space>
- <Button onClick={onClose}>取消</Button>
- <Button type="primary" htmlType="submit" className="modalResetCss" loading={modifyAmountBatch.loading || modifyAdTimeBatch.loading || updateBatchAdgroupInfo.loading || modifyDailyBudgetBatch.loading || delBatch.loading}>
- 确定
- </Button>
- </Space>
- </Form.Item>
- </Form>
- </Modal>
- {failVisible && <Modal
- title={<strong>报错信息</strong>}
- open={failVisible}
- className='modalResetCss'
- width={650}
- onCancel={() => { setFailVisible(false); setFailIdList([]) }}
- footer={null}
- >
- <Table
- size="small"
- bordered
- rowKey={'adgroupId'}
- columns={[{
- title: '广告ID',
- dataIndex: 'adgroupId',
- key: 'adgroupId',
- width: 110,
- render: (value) => <span style={{ fontSize: 12 }}>{value}</span>,
- }, {
- title: 'code',
- dataIndex: 'code',
- key: 'code',
- width: 70,
- align: 'center',
- render: (value) => <span style={{ fontSize: 12 }}>{value}</span>,
- }, {
- title: '错误信息',
- dataIndex: 'messageCn',
- key: 'messageCn',
- render: (value) => <span style={{ fontSize: 12 }}>{value}</span>,
- }]}
- dataSource={failIdList}
- />
- </Modal>}
- </>
- }
- export default React.memo(UpdateAd3)
|