123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- import { Checkbox, DatePicker, Form, Input, message, Modal, notification, Radio, Select, Space, TimePicker, Tooltip } from "antd"
- import React, { useEffect, useState } from "react"
- import TimeInSelect from "../../components/timeInSelect"
- import moment from "moment"
- import { getTimeSeriesList } from "./const";
- import { editAdqAdgroupsDataApi } from "@/services/launchAdq/adq";
- import { useAjax } from "@/Hook/useAjax";
- import { BidStrategyEnum, GoalRoasEnum } from "@/services/launchAdq/enum";
- import { QuestionCircleOutlined } from "@ant-design/icons";
- import { RangePickerProps } from "antd/lib/date-picker";
- const { RangePicker } = DatePicker;
- let DatePickers: any = DatePicker
- interface Props {
- title: string,
- visible?: boolean,
- onChange?: () => void,
- onClose?: () => void,
- selectedRows: any[]
- }
- /**
- * 修改广告
- * @returns
- */
- const UpdateAd: React.FC<Props> = ({ title = '修改广告', visible, onChange, onClose, selectedRows }) => {
- /***************************/
- const [form] = Form.useForm();
- let dateType = Form.useWatch('dateType', form)
- let field = Form.useWatch('field', form)
- const [state, setState] = useState<any>({ isShowTime: [] })
- const [isBidSType, setIsBidSType] = useState<boolean>(true)
- const [timeSeriesType, setTimeSeriesType] = useState<'allDayLong' | 'timeInterValS'>('allDayLong')
- const editAdqAdgroupsData = useAjax((params) => editAdqAdgroupsDataApi(params))
- /***************************/
- useEffect(() => {
- setIsBidSType(selectedRows.every((item: { smartBidType: string }) => item.smartBidType === 'SMART_BID_TYPE_CUSTOM'))
- }, [selectedRows])
- const handleOk = () => {
- form.validateFields().then(values => {
- console.log(values);
- let newValues = JSON.parse(JSON.stringify(values))
- let field = newValues.field
- let adgroupsUpdateDatetimeDTO = {} // 排期
- let adgroupsUpdateBidAmountDTO = {} // 出价
- let deepConversionSpec = {} // ROI
- let data = {}
- if (timeSeriesType === 'allDayLong') {
- newValues.timeSeries = getTimeSeriesList()
- }
- if (title === '批量修改深度优化') {
- deepConversionSpec['deepConversionType'] = newValues.deepConversionType
- deepConversionSpec['deepConversionWorthSpec'] = {
- expectedRoi: newValues.deepBidAmount,
- goal: newValues.goal
- }
- } else {
- field?.forEach((key: string) => {
- switch (key) {
- case 'dateType':
- if (newValues.dateType === '2') {
- adgroupsUpdateDatetimeDTO['beginDate'] = moment(newValues.date).format('YYYY-MM-DD')
- adgroupsUpdateDatetimeDTO['endDate'] = ''
- } else {
- adgroupsUpdateDatetimeDTO['beginDate'] = moment(newValues.date[0]).format('YYYY-MM-DD')
- adgroupsUpdateDatetimeDTO['endDate'] = moment(newValues.date[1]).format('YYYY-MM-DD')
- }
- break
- case 'timeType':
- // if (timeSeriesType === 'timeInterValS') {
- // if (newValues.firstDayBeginTime && moment(newValues.firstDayBeginTime).format('HH:mm:ss') !== '00:00:00') {
- // message.error('1111')
- // return
- // }
- // }
- if (newValues.timeSeries) {
- adgroupsUpdateDatetimeDTO['timeSeries'] = newValues.timeSeries.join('')
- }
- if (newValues.firstDayBeginTime) {
- adgroupsUpdateDatetimeDTO['firstDayBeginTime'] = moment(newValues.firstDayBeginTime).format('HH:mm:ss')
- }
- break
- case 'bidSType':
- adgroupsUpdateBidAmountDTO['bidStrategy'] = newValues.bidStrategy
- adgroupsUpdateBidAmountDTO['bidAmount'] = newValues.bidAmount
- break
- case 'dailyBudget':
- data['dailyBudget'] = newValues.dailyBudget
- break
- case 'adgroupName':
- data['adgroupName'] = newValues.adgroupName
- break
- }
- })
- }
-
- editAdqAdgroupsData.run({ adgroupIds: selectedRows.map((item: { adgroupId: number }) => item.adgroupId), adgroupsUpdateDatetimeDTO, adgroupsUpdateBidAmountDTO, deepConversionSpec, ...data }).then(res => {
- if (res) {
- message.success(`修改操作完成.结果请在操作记录查询!`)//成功: ${res.success},失败: ${res.fail}
- if (res?.fail) {
- notification.error({
- message: `修改失败`,
- description: `成功: ${res.success},修改失败${res.fail}条,失败的请到任务列表查看`,
- duration: 0
- });
- }
- onChange?.()
- }
- })
- })
- }
- /** 禁止选择以前时间 */
- const disabledDate: RangePickerProps['disabledDate'] = current => {
- // Can not select days before today and today
- return current && current < moment().startOf('day');
- };
- return <Modal
- title={title}
- visible={visible}
- onOk={handleOk}
- width={800}
- onCancel={() => onClose && onClose()}
- confirmLoading={editAdqAdgroupsData.loading}
- >
- <Form
- form={form}
- labelCol={{ span: 4 }}
- className='ad_form_style'
- colon={false}
- initialValues={{
- dateType: '2',
- date: moment().startOf('day'),
- timeSeries: getTimeSeriesList(),
- firstDayBeginTime: moment('2023-02-24 00:00:00'),
- bidStrategy: 'BID_STRATEGY_TARGET_COST',
- optimizationMode: 'DEEP_CONVERSION_TARGET',
- deepConversionType: 'DEEP_CONVERSION_WORTH',
- goal: 'GOAL_1DAY_PURCHASE_ROAS'
- }}
- >
- {title === '批量修改' ? <>
- <Form.Item label={<strong>选择修改字段</strong>} name='field' rules={[{ required: true, message: '选择修改字段' }]}>
- <Checkbox.Group>
- <Checkbox value="dateType">投放日期</Checkbox>
- <Checkbox value="timeType">投放时段</Checkbox>
- <Checkbox value="bidSType" disabled={!isBidSType}>
- <Space size={5}>
- 出价
- {!isBidSType && <Tooltip title="选择的广告包含自动出价类型,不支持修改出价">
- <QuestionCircleOutlined />
- </Tooltip>}
- </Space>
- </Checkbox>
- <Checkbox value="dailyBudget">广告预算</Checkbox>
- <Checkbox value="adgroupName">广告名称</Checkbox>
- </Checkbox.Group>
- </Form.Item>
- {field?.includes('dateType') && <>
- <Form.Item label={<strong>投放日期</strong>} name='dateType'>
- <Radio.Group onChange={(e) => {
- if (e.target.value === "1") {
- form.setFieldsValue({ date: [moment().startOf('day'), moment().startOf('day').add(1, 'M')] })
- }
- if (e.target.value === "2") {
- form.setFieldsValue({ date: moment().startOf('day') })
- }
- }}>
- <Radio.Button value="1">选择开始与结束日期</Radio.Button>
- <Radio.Button value="2">长期投放</Radio.Button>
- </Radio.Group>
- </Form.Item>
- {/* 投放日期的不同展示不同的日期选择 */}
- {dateType === '1' ? <Form.Item name='date' rules={[{ required: true, message: '请选择日期' }]}>
- <RangePicker style={{ marginLeft: 125 }} disabledDate={disabledDate}></RangePicker>
- </Form.Item> : <Form.Item name='date' style={{ marginLeft: 125 }} rules={[{ required: true, message: '请选择日期' }]}>
- <DatePickers disabledDate={disabledDate} />
- </Form.Item>}
- </>}
- {field?.includes('timeType') && <>
- <Form.Item label={<strong>投放时段</strong>} style={{ marginBottom: 0 }}>
- <Space direction='vertical' style={{ width: '100%' }}>
- <Radio.Group
- name='timeSeriesType'
- value={timeSeriesType}
- onChange={(value) => {
- setTimeSeriesType(value.target.value)
- if (value.target.value === 'timeInterValS') {
- setState({ isShowTime: ['1'] })
- }
- }}>
- <Radio.Button value={'allDayLong'}>全天投放</Radio.Button>
- <Radio.Button value={'timeInterValS'}>指定多个时段</Radio.Button>
- </Radio.Group>
- {timeSeriesType === 'timeInterValS' && <Form.Item name='timeSeries' noStyle rules={[{ required: true, message: '请选择时段' }]}>
- <TimeInSelect />
- </Form.Item>}
- </Space>
- </Form.Item>
- <Form.Item label={<strong></strong>}>
- <Space>
- <Checkbox.Group options={[{ label: '指定首日开始投放时间', value: '1' }]} disabled={timeSeriesType === 'timeInterValS'} value={state.isShowTime} onChange={(checkedValue) => { setState({ ...state, isShowTime: checkedValue }) }} />
- {state?.isShowTime?.length > 0 && <Form.Item name='firstDayBeginTime' noStyle rules={[{ required: true, message: '请选择时间' }]}>
- <TimePicker />
- </Form.Item>}
- </Space>
- </Form.Item>
- </>}
- {field?.includes('bidSType') && <>
- <Form.Item label={<strong>出价策略</strong>} name='bidStrategy' rules={[{ required: true, message: '请选择出价策略' }]}>
- <Radio.Group>
- {Object.keys(BidStrategyEnum).map(key => {
- return <Radio.Button value={key} key={key} disabled={key === 'BID_STRATEGY_PRIORITY_CAP_COST'}>{BidStrategyEnum[key]}</Radio.Button>
- })}
- </Radio.Group>
- </Form.Item>
- <Form.Item label={<strong>出价</strong>} name='bidAmount' rules={[{ required: true, message: '请输入价格' }]}>
- <Input placeholder={`输入价格 元`} style={{ width: 300 }} />
- </Form.Item>
- </>}
- {field?.includes('dailyBudget') && <>
- <Form.Item label={<strong>广告预算</strong>} name='dailyBudget' rules={[
- { required: true, message: '请输入广告预算' },
- {
- required: true, message: `大于0,并且填写数字`, validator(rule, value, callback) {
- let regPos = /^[0-9]+.?[0-9]*/; //判断是否是数字。
- if (!regPos.test(value)) {
- return Promise.reject()
- }
- if (value >= 0) {
- return Promise.resolve()
- } else {
- return Promise.reject()
- }
- },
- },
- ]}>
- <Input placeholder={`输入价格 元`} style={{ width: 300 }} />
- </Form.Item>
- </>}
- {field?.includes('adgroupName') && <>
- <Form.Item label={<strong>广告名称</strong>} name='adgroupName' rules={[{ required: true, message: '请输入广告名称' }]}>
- <Input placeholder={`请输入广告名称`} style={{ width: 300 }} />
- </Form.Item>
- </>}
- </> : <>
- <Form.Item label={<strong>深度优化方式</strong>} name='optimizationMode' rules={[{ required: true, message: '请选择深度优化方式' }]}>
- <Radio.Group disabled>
- <Radio.Button value="DEEP_CONVERSION_TARGET">深度目标优化</Radio.Button>
- </Radio.Group>
- </Form.Item>
- <Form.Item label={<strong>深度优化类型</strong>} name='deepConversionType' rules={[{ required: true, message: '请选择深度优化类型' }]}>
- <Radio.Group disabled onChange={() => {
- form.setFieldsValue({
- goal: undefined,
- deepBidAmount: undefined
- })
- }}>
- <Radio.Button value="DEEP_CONVERSION_WORTH">优化 ROI</Radio.Button>
- </Radio.Group>
- </Form.Item>
- <Form.Item label={<strong>深度优化目标</strong>} name='goal' rules={[{ required: true, message: '请选择深度优化目标' }]}>
- <Select style={{ width: 380 }} placeholder='请选择'>
- {Object.keys(GoalRoasEnum).filter(key => ['GOAL_1DAY_PURCHASE_ROAS']?.includes(key)).map(key => <Select.Option value={key} key={key}>{GoalRoasEnum[key]}</Select.Option>)}
- </Select>
- </Form.Item>
- <Form.Item label={<strong>期望ROI</strong>} name='deepBidAmount' rules={[{ required: true, message: '请输入期望ROI' }]}>
- <Input style={{ width: 380 }} placeholder={`期望ROI目标范围0.001~1000,输入0.05,表示ROI目标为5%`} />
- </Form.Item>
- </>}
- </Form>
- </Modal>
- }
- export default React.memo(UpdateAd)
|