| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484 | import { Card, Input, Radio, Select, Space, Spin, Tag, TimePicker, Tooltip, message } from "antd";import React, { useCallback, useEffect, useState } from "react";import { ColumnHeightOutlined, ColumnWidthOutlined, EyeInvisibleOutlined, EyeOutlined, RedoOutlined } from "@ant-design/icons";import useEcharts from '@/Hook/useEcharts'import { useModel } from 'umi'import { ListHourProps, ListType } from '@/services/adMonitor/adMonitor'import '../../adMonitor/adMonitorList/table.less'import moment from "moment";import TableData from "@/pages/launchSystemNew/components/TableData";import RuleAccountLog from "@/components/EarlyWarning/ruleAccountLog";import { LineField } from "@/pages/adMonitor/adMonitorList/config";import FilterQuery from "@/pages/adMonitor/adMonitorList/components/FilterQuery";import Details from "./Details";import { columnsMonitor } from "./tableMonitorConfig";import { qiliangpaihanghour } from "./config";import { syncBatchApi } from "@/services/launchAdq/adqv3";import { useAjax } from "@/Hook/useAjax";interface newListType extends ListType {    totalTimeUnit: 'total' | 'minute' | 'hour' | 'day',    planTimeUnit: 'minute' | 'hour' | 'day'}/** * 今日起量监控 * @param props  * @returns  */function Monitor(props: { onChange: () => void }) {    const { onChange } = props    const { getCostTrendV3List, getCostTopV3List, getListForHourV3, getAdqAccountList } = useModel('useAdMonitor.useMonitor')    const { getPicherList } = useModel('useOperating.useWxGroupList')    // 变量开始    const [queryForm, setQueryForm] = useState<newListType>({ totalTimeUnit: 'day', planTimeUnit: 'hour', sysUserId: JSON.parse(sessionStorage.getItem('SYSUSERID') || '[]'), pageNum: 1, pageSize: 20 }) // 搜索变量//startTime: moment().format('YYYY-MM-DD'), endTime: moment().format('YYYY-MM-DD'),    const { BarMonitor, LineMonitor } = useEcharts()    const [barDis, setBarDis] = useState<any[]>([])    const [lineDis, setLineDis] = useState<any[]>([])    const [lineTitle, setLineTitle] = useState<string>('广告总消耗趋势')    const [px, setPx] = useState<boolean>(false)//设置顶部图形的排列方式    const [visible, setVisible] = useState<boolean>(false) // 详情弹窗控制    const [aId, setAId] = useState<any>()    const [showEacharts, setShowEacharts] = useState<boolean>(true)    const [queryForHour, setQueryForHour] = useState<ListHourProps>({ pageNum: 1, pageSize: 20 })    const [filterQuery, setFilterQuery] = useState<any>({})    const [logVisible, setLogVisible] = useState<boolean>(false)    const [adgroupId, setAdgroupId] = useState<string>('')    const [adgroupName, setAdgroupName] = useState<string>('')    const [accountIdRule, setAccountIdRule] = useState<string>('')    const [trendColumns, setTrendColumns] = useState<string[]>(['cost'])    const { totalTimeUnit, planTimeUnit, adgroup, accountId, sysUserId, groupAccountIds } = queryForm    const configName = '起量广告排行明细3.0'    const { getGroupList, groupListInit } = useModel('useLaunchAdq.useAdAuthorize')    const syncBatch = useAjax((params) => syncBatchApi(params))    useEffect(() => {        groupListInit()    }, [])    useEffect(() => {        getList()    }, [queryForHour, filterQuery, queryForm?.sysUserId, queryForm?.accountId, queryForm?.adgroup, queryForm?.groupAccountIds])    const getList = () => {        let message = localStorage.getItem(`myAdMonitorConfig1.0.1_${configName}`)        if (message) {            message = JSON.parse(message)        }        let isAccountId = true        let isAdgroupId = true        let isAdgroupName = true        let columns: string[] = []        if (message && Array.isArray(message)) {            message.forEach((item: { serverIndex: any; dataIndex: string; }) => {                if (!['event'].includes(item.dataIndex)) {                    if (item.dataIndex === 'account_id') {                        isAccountId = false                    } else if (item.dataIndex === 'adgroup_id') {                        isAdgroupId = false                    } else if (item.dataIndex === 'adgroup_name') {                        isAdgroupName = false                    }                    columns.push(item?.serverIndex || 'adgroup_data.' + item.dataIndex)                }            })        } else {            qiliangpaihanghour.forEach((item: any) => {                item?.data?.forEach((d: { default: any, serverIndex: string, dataIndex: string }) => {                    if (d.default && !['event'].includes(d.dataIndex)) {                        if (d.dataIndex === 'account_id') {                            isAccountId = false                        } else if (d.dataIndex === 'adgroup_id') {                            isAdgroupId = false                        } else if (item.dataIndex === 'adgroup_name') {                            isAdgroupName = false                        }                        columns.push(d?.serverIndex || 'adgroup_data.' + d.dataIndex)                    }                })            })        }        if (isAccountId) {            columns.push('adgroup_data.account_id')        }        if (isAdgroupId) {            columns.push('adgroup_data.adgroup_id')        }        if (isAdgroupName) {            columns.push('adgroup_data.adgroup_name')        }        let params = { ...queryForHour, ...filterQuery }        if (queryForm?.sysUserId) {            params.sysUserIds = queryForm?.sysUserId        }        if (queryForm?.accountId && queryForm?.accountId?.length > 0) {            params.accountIdStr = queryForm?.accountId.toString()        }        if (queryForm?.adgroup) {            params.adgroupIdStr = queryForm?.adgroup        }        if (queryForm?.groupAccountIds) {            params.groupAccountIds = queryForm?.groupAccountIds        }        params.columns = columns        getListForHourV3.run(params)    }    // 获取投手    useEffect(() => {        !getPicherList.data && getPicherList.run()    }, [])    // 获取广告账号    useEffect(() => {        !getAdqAccountList.data && getAdqAccountList.run()    }, [])    // // 获取排行数据,柱图    useEffect(() => {        getPlanCostList()    }, [totalTimeUnit, accountId, sysUserId, groupAccountIds])    // 获取今日计划总消耗图谱,折线    useEffect(() => {        getTootalCostList()    }, [planTimeUnit, adgroup, accountId, sysUserId, groupAccountIds, trendColumns])    /** 获取折线图 */    const getTootalCostList = useCallback(async () => {        let { totalTimeUnit, planTimeUnit, pageNum, pageSize, adgroup, sysUserId, accountId, ...newQueryForm } = queryForm        let params = adgroup ? { ...newQueryForm, adgroupIdStr: adgroup } : newQueryForm        let res = await getCostTrendV3List.run({ ...params, timeUnit: planTimeUnit, sysUserIds: sysUserId, accountIdStr: accountId?.join(), trendColumns })        let data = trendColumns.map((field) => {            let value: any = {}            res?.data?.forEach((item: any, index: number) => {                if (index === 0) value.legendName = LineField[field];                value[item?.trend_unit] = item?.[field]            });            return value        })        setLineDis(() => data)        setLineTitle(() => `广告总${LineField[trendColumns[0]]}趋势`)    }, [queryForm, lineDis, trendColumns])    /** 获取柱状图 */    const getPlanCostList = useCallback(async () => {        let { totalTimeUnit, planTimeUnit, pageNum, pageSize, sysUserId, accountId, ...newQueryForm } = queryForm        let { adgroup, ...planQueryFrom } = newQueryForm        let res = await getCostTopV3List.run({ ...planQueryFrom, timeUnit: totalTimeUnit, sysUserIds: sysUserId, accountId: accountId?.join(), topN: 10 })        let data = res?.data?.map((item: { adgroupId: number, cost: number, adgroupName: string, accountId: number }) => {            return { name: item.adgroupId.toString(), value: item.cost, adName: item.adgroupName, accountId: item.accountId }        })        data = data?.sort((a: any, b: any) => {            var value1 = a['value'];            var value2 = b['value'];            return value2 - value1;        })        setBarDis(() => data)    }, [queryForm, barDis])    // 详情    const details = (data: any) => {        setAId(data)        setVisible(true)    }    // 计划详情    const planDetail = (data: any) => {        sessionStorage.setItem('ADIDORNAME', JSON.stringify(data))        onChange && onChange()    }    //全部接口刷新    const refresh = () => {        getCostTrendV3List.refresh()        getCostTopV3List.refresh()        getListForHourV3.refresh()    }    // 接口自动刷新10分钟一次    useEffect(() => {        let time = setInterval(() => {            refresh()        }, 1000 * 60 * 10)        return () => {            clearInterval(time)        }    }, [])    //图形排列样式改变重新获取数据刷新图形    const set = useCallback((b) => {        setPx(b)        getCostTrendV3List.refresh()        getCostTopV3List.refresh()    }, [getCostTopV3List, getCostTrendV3List, trendColumns])    // 处理折线图数据    const timePickerHandle = async (values: any, formatString: [string, string]) => {        let res = await getCostTrendV3List.data        let data = trendColumns.map((field) => {            let value: any = {}            res?.data?.forEach((item: any, index: number) => {                if (index === 0) value.legendName = LineField[field];                value[item?.trend_unit] = item?.[field]            });            return value        })        if (values) {            let date = moment().format('YYYY-MM-DD')            let strTime = formatString[0]            let endTime = formatString[1]            let dateTimeStr = `${date} ${strTime}:00`            let dateTimeEnd = `${date} ${endTime}:00`            let newData: any[] = data.map(item => {                let { legendName, ...otherData } = item                let newItem: any = { legendName }                for (const key in otherData) {                    if (Object.prototype.hasOwnProperty.call(otherData, key)) {                        const value = otherData[key];                        if (moment(dateTimeStr) <= moment(key) && moment(key) <= moment(dateTimeEnd)) {                            newItem[key] = value                        }                    }                }                return newItem            })            setLineDis(() => newData)        } else {            setLineDis(() => data)        }    }    const log = (value: any) => {        setAccountIdRule(value.account_id)        setAdgroupId(value.adgroup_id)        setAdgroupName(value.adgroup_name)        setLogVisible(true)    }    const sync = (data: any) => {        const hide = message.loading(`${data?.adgroup_name}广告同步中`, 0, () => {            message.success('修改成功');        });        let accountAdgroupMaps = [data.account_id + ',' + data.adgroup_id]        syncBatch.run({ accountAdgroupMaps }).then(res => {            hide()            getListForHourV3.refresh()            message.success('同步完成!')        }).catch(() => hide())    }    return <Space direction='vertical' style={{ width: '100%' }} className="monitor">        <Card hoverable bodyStyle={{ padding: '12px 16px' }}>            <div style={{ display: 'flex', justifyContent: 'space-between' }}>                <Space>                    <Select                        showSearch                        value={queryForm.sysUserId}                        style={{ minWidth: 180, maxWidth: 250 }}                        mode='multiple'                        maxTagCount={1}                        allowClear                        placeholder="请选择投手"                        disabled={queryForm?.adgroup || queryForm?.accountId?.length > 0}                        onChange={(value: number[]) => {                            setQueryForm({ ...queryForm, sysUserId: value, pageNum: 1 })                            sessionStorage.setItem('SYSUSERID', value ? JSON.stringify(value) : '')                        }}                        filterOption={(input, option) =>                            (option?.children as any).toLowerCase().indexOf(input.toLowerCase()) >= 0                        }                    >                        {getPicherList?.data?.map((item: { nickname: string, userId: number }, index: number) =>                            <Select.Option                                value={item.userId}                                key={item.userId + '' + index}                            >                                {item.nickname}                            </Select.Option>                        )}                    </Select>                    <Select                        showSearch                        mode='multiple'                        maxTagCount={1}                        value={queryForm.accountId}                        style={{ minWidth: 220, maxWidth: 250 }}                        allowClear                        placeholder="请选择广告账号"                        onChange={(value: number[]) => {                            setQueryForm({ ...queryForm, 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>                    <Input                        value={queryForm?.accountId?.toString()}                        placeholder="输入广告账号"                        onChange={(e) => {                            setQueryForm({ ...queryForm, accountId: e.target.value ? e.target.value?.split(/[,,\s\n]+/) : undefined })                        }}                        allowClear                    />                    <Input                        value={queryForm.adgroup}                        placeholder="广告ID"                        onChange={(e) => {                            setQueryForm({ ...queryForm, adgroup: e.target.value })                        }}                        allowClear                    />                    <Select                        showSearch                        mode='multiple'                        maxTagCount={1}                        value={queryForm.groupAccountIds}                        style={{ minWidth: 150 }}                        allowClear                        placeholder="请选择账号分组"                        onChange={(value: number[]) => {                            setQueryForm({ ...queryForm, groupAccountIds: value, pageNum: 1 })                        }}                    >                        {getGroupList?.data?.map((item: { groupId: number, groupName: number }) => <Select.Option                            value={item.groupId}                            key={item.groupId}                        >                            {item.groupName}                        </Select.Option>)}                    </Select>                </Space>                <Space>                    <Tag onClick={() => setShowEacharts(!showEacharts)}>{showEacharts ? <><EyeInvisibleOutlined /> 隐藏</> : <><EyeOutlined /> 显示</>}</Tag>                    <Tag color="#2db7f5" onClick={refresh}><RedoOutlined />   刷新</Tag>                </Space>            </div>        </Card>        {showEacharts && <Card hoverable bodyStyle={{ padding: '12px 16px' }}>            <span style={{ position: 'absolute', top: 10, zIndex: 10 }}>                {px ?                    <Tooltip title='左右排列'><Tag color='#f50' onClick={() => { set(false) }}><ColumnWidthOutlined /><span style={{ fontSize: 10 }}>左右排列</span></Tag></Tooltip>                    :                    <Tooltip title='上下排列'><Tag color='#f50' onClick={() => { set(true) }} ><ColumnHeightOutlined /><span style={{ fontSize: 10 }}>上下排列</span></Tag></Tooltip>                }            </span>            <div className={!px ? 'charts' : 'charts charts100'}>                <div>                    <div className="selectTime">                        <Space>                            <span style={{ fontSize: 10, color: '#999' }}>刷新时间:{getCostTopV3List?.data?.reqTime}</span>                            <Radio.Group value={queryForm.totalTimeUnit} buttonStyle="solid" size='small' onChange={(e) => { setQueryForm({ ...queryForm, totalTimeUnit: e.target.value }) }}>                                <Radio.Button value="total">总</Radio.Button>                                <Radio.Button value="day">天</Radio.Button>                                <Radio.Button value="hour">小时</Radio.Button>                                <Radio.Button value="minute">5min</Radio.Button>                            </Radio.Group>                        </Space>                    </div>                    {getCostTopV3List?.loading ? <Spin /> : <BarMonitor style={{ width: '100%', height: '100%' }} data={barDis} xName="今日消耗" yName="广告名称" onChange={(value: string, accountId) => { console.log(value, accountId); setQueryForm({ ...queryForm, adgroup: value }) }} planID={queryForm?.adgroup} />}                </div>                <div>                    <div className="selectTime">                        <Space>                            <span style={{ fontSize: 10, color: '#999' }}>刷新时间:{getCostTrendV3List?.data?.reqTime}</span>                            <Radio.Group value={queryForm.planTimeUnit} buttonStyle="solid" size='small' onChange={(e) => { setQueryForm({ ...queryForm, planTimeUnit: e.target.value }) }}>                                <Radio.Button value="hour">小时</Radio.Button>                                <Radio.Button value="minute">5min</Radio.Button>                            </Radio.Group>                            {queryForm.planTimeUnit === 'minute' && <TimePicker.RangePicker                                size="small"                                format='HH:mm'                                minuteStep={5}                                onChange={timePickerHandle}                            />}                            <Select                                showSearch                                mode='multiple'                                maxTagCount={1}                                value={trendColumns}                                style={{ minWidth: 130 }}                                allowClear                                placeholder="请选择图表字段"                                onChange={(value: string[]) => {                                    setTrendColumns(value?.length ? value : ['cost'])                                }}                                size="small"                            >                                {Object.keys(LineField).map((key) => <Select.Option value={key} key={key}>                                    {LineField[key]}                                </Select.Option>)}                            </Select>                        </Space>                    </div>                    {getCostTrendV3List?.loading ? <Spin /> : <LineMonitor style={{ width: '100%', height: '100%' }} series smooth data={lineDis} title={trendColumns?.length > 1 ? undefined : lineTitle} />}                </div>            </div>        </Card>}        <div className={'MYtable'}>            <TableData                refreshData={getList}                bodyStyle={{ padding: '12px 16px' }}                gutter={[0, 12]}                columns={columnsMonitor(planDetail, details, (value) => { setQueryForm({ ...queryForm, adgroup: value }); }, log, sync)}                dataSource={getListForHourV3?.data?.data?.records}                loading={getListForHourV3?.loading}                ajax={getListForHourV3}                leftChild={                    <Space>                        <FilterQuery onChange={(data) => {                            setFilterQuery(data)                        }} />                    </Space>                }                myKey={'adgroup_id'}                fixed={{ left: 0, right: 2 }}                total={getListForHourV3?.data?.data?.total}                onChange={(props: any) => {                    let { sortData, pagination } = props                    let { current, pageSize } = pagination                    let newQueryForm = JSON.parse(JSON.stringify(queryForHour))                    newQueryForm.pageNum = current                    newQueryForm.pageSize = pageSize                    if (sortData && JSON.stringify('sortData') !== '{}') {                        let { field, order } = sortData   // descend 降序 大到小  ascend 升序 小到大                        if (order) {                            newQueryForm.sortColumn = field                            newQueryForm.sortAsc = order === 'ascend'                        } else {                            Object.keys(newQueryForm).forEach(key => {                                if (key === 'sortColumn' || key === 'sortAsc') {                                    delete newQueryForm[key]                                }                            })                        }                    } else {                        Object.keys(newQueryForm).forEach(key => {                            if (key === 'sortField' || key === 'sort') {                                delete newQueryForm[key]                            }                        })                    }                    setQueryForHour({ ...newQueryForm })                }}                page={queryForHour.pageNum}                pageSize={queryForHour.pageSize}                scroll={{ y: 750 }}                config={qiliangpaihanghour}                configName={configName}            />        </div>        {visible && <Details visible={visible} onClose={() => { setVisible(false) }} data={aId} />}        {logVisible && <RuleAccountLog accountId={accountIdRule} adgroupName={adgroupName} adgroupId={adgroupId} visible={logVisible} onClose={() => setLogVisible(false)} />}    </Space>}export default React.memo(Monitor)
 |