|
@@ -0,0 +1,235 @@
|
|
|
+import { Button, Progress, Select, Space, Statistic, Table, Tag } from "antd"
|
|
|
+import React, { useEffect, useState } from "react"
|
|
|
+import style from './index.less'
|
|
|
+import Draggable from "react-draggable"
|
|
|
+import { CloseCircleOutlined, SearchOutlined, SyncOutlined } from "@ant-design/icons"
|
|
|
+import { allPlanProps, getAdqAccountListApi, getAllPlanListApi } from "@/services/adMonitor/adMonitor"
|
|
|
+import { useAjax } from "@/Hook/useAjax"
|
|
|
+import { ColumnsType } from "antd/lib/table"
|
|
|
+import { GGStateData } from "@/pages/adMonitor/adMonitorList/data"
|
|
|
+import { GUANGGAOZHUANGTAI } from "@/pages/adMonitor/adMonitorList/enum"
|
|
|
+import SearchSelect from "./searchSelect"
|
|
|
+import moment from "moment"
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ userId: string
|
|
|
+ onChange?: (adidList?: number[]) => void
|
|
|
+}
|
|
|
+/**
|
|
|
+ * 开启监控过滤
|
|
|
+ * @returns
|
|
|
+ */
|
|
|
+const AdIdSearch: React.FC<Props> = ({ userId, onChange }) => {
|
|
|
+
|
|
|
+ /***************************/
|
|
|
+ const [show, setShow] = useState<boolean>(false)
|
|
|
+ const [editSelectedRow, setEditSelectedRow] = useState<any[]>([])
|
|
|
+ const [queryFrom, setQueryForm] = useState<allPlanProps>({ pageNum: 1, pageSize: 20, createStartTime: moment().subtract(3, 'days').format('YYYY-MM-DD'), createEndTime: moment().format('YYYY-MM-DD') })
|
|
|
+
|
|
|
+ const getAllPlanList = useAjax((params) => getAllPlanListApi(params))
|
|
|
+ // 获取广告账号列表
|
|
|
+ const getAdqAccountList = useAjax(() => getAdqAccountListApi(), { formatResult: true })
|
|
|
+ /***************************/
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (show) {
|
|
|
+ getAllPlanList.run({ sysUserId: [userId], ...queryFrom })
|
|
|
+ }
|
|
|
+ }, [userId, show, queryFrom])
|
|
|
+
|
|
|
+ const open = () => {
|
|
|
+ setShow(true)
|
|
|
+ getAdqAccountList.run()
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleOk = () => {
|
|
|
+ onChange?.(editSelectedRow)
|
|
|
+ }
|
|
|
+
|
|
|
+ return <>
|
|
|
+ <Button onClick={() => open()}>开启监控过滤</Button>
|
|
|
+ {show && <Draggable>
|
|
|
+ <div className={`floating-window MYtable ${style.searchModal}`}>
|
|
|
+ <div className={style.close} onClick={() => setShow(false)}><CloseCircleOutlined /></div>
|
|
|
+ <Space>
|
|
|
+ <Select
|
|
|
+ showSearch
|
|
|
+ mode='multiple'
|
|
|
+ maxTagCount={1}
|
|
|
+ value={queryFrom.accountId}
|
|
|
+ style={{ minWidth: 140, maxWidth: 250 }}
|
|
|
+ allowClear
|
|
|
+ placeholder="请选择广告账号"
|
|
|
+ onChange={(value: number[]) => {
|
|
|
+ setQueryForm({ ...queryFrom, accountId: value, pageNum: 1 })
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {getAdqAccountList?.data?.data?.map((item: { id: number, accountId: number }) => <Select.Option
|
|
|
+ value={item.accountId}
|
|
|
+ key={item.id}
|
|
|
+ >
|
|
|
+ {item.accountId}
|
|
|
+ </Select.Option>)}
|
|
|
+ </Select>
|
|
|
+ <Select style={{ width: 140 }} placeholder="请选择广告状态" value={queryFrom.adStatus} onChange={(value: number) => {
|
|
|
+ setQueryForm({ ...queryFrom, pageNum: 1, adStatus: value })
|
|
|
+ }} allowClear>
|
|
|
+ {Object.keys(GUANGGAOZHUANGTAI).map(key => {
|
|
|
+ return <Select.Option value={key} key={key}>{GUANGGAOZHUANGTAI[key]}</Select.Option>
|
|
|
+ })}
|
|
|
+ </Select>
|
|
|
+ <SearchSelect queryFrom={queryFrom} setQueryForm={setQueryForm} />
|
|
|
+ <Button type="link" icon={<SyncOutlined />} style={{ padding: 0 }} onClick={() => getAllPlanList?.refresh()}>刷新</Button>
|
|
|
+ </Space>
|
|
|
+ <Table
|
|
|
+ size="small"
|
|
|
+ loading={getAllPlanList.loading}
|
|
|
+ dataSource={getAllPlanList?.data?.records}
|
|
|
+ columns={columns}
|
|
|
+ rowKey={'id'}
|
|
|
+ scroll={{ x: 300, y: 200 }}
|
|
|
+ pagination={{
|
|
|
+ total: getAllPlanList?.data?.total,
|
|
|
+ showTotal: (total) => <Tag color="cyan">总共{total}数据</Tag>,
|
|
|
+ current: getAllPlanList?.data?.current || 1,
|
|
|
+ pageSize: getAllPlanList?.data?.size || 20,
|
|
|
+ }}
|
|
|
+ rowSelection={{
|
|
|
+ selectedRowKeys: editSelectedRow,
|
|
|
+ onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
|
|
|
+ console.log(selectedRowKeys, selectedRows)
|
|
|
+ setEditSelectedRow(selectedRowKeys)
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ onChange={(pagination, filters, sortData: any) => {
|
|
|
+ let { current, pageSize } = pagination
|
|
|
+ let newQueryForm = JSON.parse(JSON.stringify(queryFrom))
|
|
|
+ newQueryForm.pageNum = current
|
|
|
+ newQueryForm.pageSize = pageSize
|
|
|
+ if (sortData && JSON.stringify('sortData') !== '{}') {
|
|
|
+ let { field, order } = sortData // descend 降序 大到小 ascend 升序 小到大
|
|
|
+ if (order) {
|
|
|
+ newQueryForm.sortField = field
|
|
|
+ newQueryForm.sort = order === 'ascend' ? 'ASC' : 'DESC'
|
|
|
+ } else {
|
|
|
+ Object.keys(newQueryForm).forEach(key => {
|
|
|
+ if (key === 'sortField' || key === 'sort') {
|
|
|
+ delete newQueryForm[key]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Object.keys(newQueryForm).forEach(key => {
|
|
|
+ if (key === 'sortField' || key === 'sort') {
|
|
|
+ delete newQueryForm[key]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ setQueryForm({ ...newQueryForm })
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ {editSelectedRow?.length > 0 && <div className={style.bts}>
|
|
|
+ <Button icon={<SearchOutlined />} type="primary" onClick={() => handleOk()} />
|
|
|
+ </div>}
|
|
|
+ </div>
|
|
|
+ </Draggable>}
|
|
|
+ </>
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const columns: ColumnsType<any> = [
|
|
|
+ {
|
|
|
+ title: '广告ID',
|
|
|
+ dataIndex: 'adgroupId',
|
|
|
+ key: 'adgroupId',
|
|
|
+ align: 'center',
|
|
|
+ width: 90,
|
|
|
+ fixed: 'left',
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '广告状态',
|
|
|
+ dataIndex: 'adStatus',
|
|
|
+ key: 'adStatus',
|
|
|
+ align: 'center',
|
|
|
+ width: 90,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (a: any) => {
|
|
|
+ return GGStateData[a] || '--'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '广告总消耗',
|
|
|
+ dataIndex: 'cost',
|
|
|
+ key: 'cost',
|
|
|
+ align: 'center',
|
|
|
+ width: 100,
|
|
|
+ ellipsis: true,
|
|
|
+ sorter: true,
|
|
|
+ render: (a: any) => {
|
|
|
+ return <div style={{ height: 26, position: 'relative' }}>
|
|
|
+ <Progress
|
|
|
+ strokeColor={{
|
|
|
+ from: '#10c1e9',
|
|
|
+ to: '#6892d0',
|
|
|
+ }}
|
|
|
+ status="active"
|
|
|
+ showInfo={false}
|
|
|
+ percent={a ? a / 3000 * 100 : 0}
|
|
|
+ />
|
|
|
+ <span style={{ position: 'absolute', left: 0, top: 2, bottom: 0, right: 0 }}><Statistic value={a || 0} valueStyle={a >= 30000 ? { color: '#000', fontWeight: 500 } : { fontWeight: 500 }} /></span>
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '曝光量',
|
|
|
+ dataIndex: 'viewCount',
|
|
|
+ key: 'viewCount',
|
|
|
+ align: 'center',
|
|
|
+ width: 75,
|
|
|
+ sorter: true,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (a: number) => {
|
|
|
+ return <span style={a <= 8 ? { color: '#0f990f', fontWeight: 600 } : a >= 100 ? { color: 'red', fontWeight: 600 } : {}}> {a || '--'}</span >
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '下单量',
|
|
|
+ dataIndex: 'orderCount',
|
|
|
+ key: 'orderCount',
|
|
|
+ align: 'center',
|
|
|
+ width: 75,
|
|
|
+ sorter: true,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (a: any) => {
|
|
|
+ return <Statistic value={a || 0} />
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '千次曝光成本',
|
|
|
+ dataIndex: 'thousandDisplayPrice',
|
|
|
+ key: 'thousandDisplayPrice',
|
|
|
+ align: 'center',
|
|
|
+ width: 95,
|
|
|
+ // sorter: true,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (a: any) => {
|
|
|
+ return <Statistic value={a ? a?.toFixed(2) : 0} />
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '点击量',
|
|
|
+ dataIndex: 'clickCount',
|
|
|
+ key: 'clickCount',
|
|
|
+ align: 'center',
|
|
|
+ width: 70,
|
|
|
+ sorter: true,
|
|
|
+ ellipsis: true,
|
|
|
+ render: (a: number) => {
|
|
|
+ return <span style={a <= 8 ? { color: '#0f990f', fontWeight: 600 } : a >= 100 ? { color: 'red', fontWeight: 600 } : {}}> {a || '--'}</span >
|
|
|
+ },
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+export default React.memo(AdIdSearch)
|