|
@@ -0,0 +1,170 @@
|
|
|
+import { useAjax } from "@/Hook/useAjax"
|
|
|
+import { CheckOutlined, QuestionCircleOutlined, SyncOutlined } from "@ant-design/icons"
|
|
|
+import { Button, message, Modal, Radio, Space, Table, Tooltip } from "antd"
|
|
|
+import React, { useEffect, useState } from "react"
|
|
|
+import style from '../GoodsModal/index.less'
|
|
|
+import columns from './tableConfig'
|
|
|
+import { getAudiencesListApi } from "@/services/adqV3/global"
|
|
|
+
|
|
|
+/**
|
|
|
+ * 优量汇流量包
|
|
|
+ * @returns
|
|
|
+ */
|
|
|
+interface Props {
|
|
|
+ visible?: boolean,
|
|
|
+ onClose?: () => void,
|
|
|
+ onChange?: (data: PULLIN.AccountCreateLogsProps[]) => void,
|
|
|
+ data: PULLIN.AccountCreateLogsProps[]
|
|
|
+}
|
|
|
+const Audience: React.FC<Props> = (props) => {
|
|
|
+
|
|
|
+ /************************/
|
|
|
+ const { visible, onClose, data: data1, onChange } = props
|
|
|
+ const [tableData, setTableData] = useState<any[]>([])//table数据
|
|
|
+ const [selectAdz, setSelectAdz] = useState<number>(1) // 选择广告主
|
|
|
+ const [data, setData] = useState<PULLIN.AccountCreateLogsProps[]>(data1)
|
|
|
+ const [positionPackageType, setPositionPackageType] = useState<'customAudience' | 'excludedCustomAudience'>('customAudience')
|
|
|
+
|
|
|
+ const getAudiencesList = useAjax((params) => getAudiencesListApi(params))
|
|
|
+ /************************/
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data?.length > 0) {
|
|
|
+ getList(data[selectAdz - 1].accountId)
|
|
|
+ } else {
|
|
|
+ setTableData([])
|
|
|
+ }
|
|
|
+ }, [selectAdz])
|
|
|
+
|
|
|
+ // 获取人群包
|
|
|
+ const getList = (accountId: number) => {
|
|
|
+ getAudiencesList.run({ adAccountId: accountId }).then(res => {
|
|
|
+ setTableData(res || [])
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleOk = () => {
|
|
|
+ onChange?.(data)
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 设置选中广告主 */
|
|
|
+ const handleSelectAdz = (value: number) => {
|
|
|
+ if (value === selectAdz) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ setSelectAdz(value)
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 表格选折 */
|
|
|
+ const onChangeTable = (selectedRowKeys: React.Key[]) => {
|
|
|
+ const newData = JSON.parse(JSON.stringify(data))
|
|
|
+ newData[selectAdz - 1][positionPackageType] = selectedRowKeys
|
|
|
+ setData([...newData])
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清空已选
|
|
|
+ const clearGoods = () => {
|
|
|
+ const newData = JSON.parse(JSON.stringify(data))
|
|
|
+ newData[selectAdz - 1][positionPackageType] = []
|
|
|
+ setData([...newData])
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 一键设置 */
|
|
|
+ const setOnekey = () => {
|
|
|
+ const newData: PULLIN.AccountCreateLogsProps[] = JSON.parse(JSON.stringify(data))
|
|
|
+ const hide = message.loading(`正在设置...`, 0, () => {
|
|
|
+ message.success('设置成功');
|
|
|
+ });
|
|
|
+ const audienceIds: string[] = data[selectAdz - 1][positionPackageType] || []
|
|
|
+ const fileterData = newData.filter(item => item.accountId !== data[selectAdz - 1].accountId)
|
|
|
+ const ajax = fileterData.map(item => getAudiencesListApi({ adAccountId: item.accountId }))
|
|
|
+ Promise.all(ajax).then(res => {
|
|
|
+ fileterData.forEach((item, index) => {
|
|
|
+ const dataAudienceIds = res[index]?.data?.map((i: { audienceId: any }) => i.audienceId) || []
|
|
|
+ const newDataIndex = newData.findIndex(d => d.accountId === item.accountId)
|
|
|
+ if (newDataIndex !== -1) {
|
|
|
+ newData[newDataIndex][positionPackageType] = audienceIds.filter(a => dataAudienceIds.includes(a))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setData([...newData])
|
|
|
+ hide()
|
|
|
+ message.success('设置成功');
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return <Modal
|
|
|
+ title={<strong>选择自定义人群包</strong>}
|
|
|
+ open={visible}
|
|
|
+ onCancel={() => { onClose && onClose() }}
|
|
|
+ onOk={handleOk}
|
|
|
+ width={900}
|
|
|
+ className={`${style.SelectPackage} modalResetCss`}
|
|
|
+ bodyStyle={{ padding: '0 10px 0 10px' }}
|
|
|
+ >
|
|
|
+ <div className={style.content}>
|
|
|
+ <div className={style.left}>
|
|
|
+ <h4 className={style.title}>媒体账户</h4>
|
|
|
+ <div className={style.accountIdList}>
|
|
|
+ {data?.map((item, index) => {
|
|
|
+ const positionPackage = data[index]?.[positionPackageType] || []
|
|
|
+ return <div key={index} onClick={() => { handleSelectAdz(index + 1) }} className={`${style.accItem} ${selectAdz === index + 1 && style.select} `}>
|
|
|
+ {item?.accountId}
|
|
|
+ {positionPackage?.length > 0 && <CheckOutlined style={{ color: '#1890ff' }} />}
|
|
|
+ </div>
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className={style.right}>
|
|
|
+ <Space style={{ marginBottom: 10 }} align="center">
|
|
|
+ <Radio.Group value={positionPackageType} onChange={(e) => setPositionPackageType(e.target.value)} buttonStyle="solid">
|
|
|
+ <Radio.Button value="customAudience">定向用户群 {(data[selectAdz - 1]?.['customAudience'] || [])?.length > 0 && <CheckOutlined />}</Radio.Button>
|
|
|
+ <Radio.Button value="excludedCustomAudience">排除用户群 {(data[selectAdz - 1]?.['excludedCustomAudience'] || [])?.length > 0 && <CheckOutlined />}</Radio.Button>
|
|
|
+ </Radio.Group>
|
|
|
+ <Button icon={<SyncOutlined />} type='link' style={{ padding: 0 }} loading={getAudiencesList?.loading} onClick={() => { getList(data[selectAdz - 1].accountId) }}>刷新</Button>
|
|
|
+ {data?.length > 1 && <Button style={{ padding: 0 }} disabled={!data[selectAdz - 1][positionPackageType]?.length} onClick={() => setOnekey()} type="link" loading={getAudiencesList.loading}>
|
|
|
+ <Space>
|
|
|
+ <span>一键设置{positionPackageType === 'customAudience' ? '定向用户群' : '排除用户群'}</span>
|
|
|
+ <Tooltip color="#FFF" overlayInnerStyle={{ color: '#000' }} title="设置其它账号有相同ID的人群包为那个账号的人群包(注意需要用户人群包ID相同,否则不设置)">
|
|
|
+ <QuestionCircleOutlined />
|
|
|
+ </Tooltip>
|
|
|
+ </Space>
|
|
|
+ </Button>}
|
|
|
+ {(data[selectAdz - 1]?.[positionPackageType] || [])?.length > 0 && <Button style={{ padding: 0 }} type='link' danger onClick={() => { clearGoods() }}>清空{positionPackageType === 'customAudience' ? '定向用户群' : '排除用户群'}</Button>}
|
|
|
+ </Space>
|
|
|
+ <Table
|
|
|
+ columns={columns()}
|
|
|
+ dataSource={tableData}
|
|
|
+ size="small"
|
|
|
+ loading={getAudiencesList?.loading}
|
|
|
+ scroll={{ y: 400 }}
|
|
|
+ rowKey={'audienceId'}
|
|
|
+ rowSelection={{
|
|
|
+ selectedRowKeys: data[selectAdz - 1]?.[positionPackageType],
|
|
|
+ getCheckboxProps: (record: any) => {
|
|
|
+ return {
|
|
|
+ disabled: !['PENDING', 'PROCESSING', 'SUCCESS'].includes(record.status) ||
|
|
|
+ data?.[selectAdz - 1]?.[positionPackageType === 'excludedCustomAudience' ? 'customAudience' : 'excludedCustomAudience']?.includes(record.audienceId)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onChange: onChangeTable
|
|
|
+ }}
|
|
|
+ onRow={(record) => ({
|
|
|
+ onClick: () => {
|
|
|
+ let newDatas = JSON.parse(JSON.stringify(data))
|
|
|
+ let oldData = newDatas[selectAdz - 1]?.[positionPackageType] || []
|
|
|
+ const selected = oldData?.some((item: any) => item === record.audienceId);
|
|
|
+ const newSelectedRows = selected
|
|
|
+ ? oldData?.filter((item: any) => item !== record.audienceId)
|
|
|
+ : [...oldData, record.audienceId];
|
|
|
+ newDatas[selectAdz - 1][positionPackageType] = newSelectedRows;
|
|
|
+ setData([...newDatas])
|
|
|
+ },
|
|
|
+ })}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+}
|
|
|
+
|
|
|
+export default React.memo(Audience)
|