|
@@ -25,15 +25,13 @@ interface newListType extends ListType {
|
|
|
function Monitor(props: { onChange: () => void }) {
|
|
|
const { onChange } = props
|
|
|
const { getPlanList, getTotalCost, getPlanCost, getPlanDetailList, getMinuteList, getAdqAccountList } = useModel('useAdMonitor.useMonitor')
|
|
|
- const { state } = useModel('useOperating.useWxGroupList')
|
|
|
+ const { getPicherList } = useModel('useOperating.useWxGroupList')
|
|
|
// 变量开始
|
|
|
const [queryForm, setQueryForm] = useState<newListType>({ totalTimeUnit: 'day', planTimeUnit: 'hour', 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 [datas, setDatas] = useState<any[]>([]) // 所有数据
|
|
|
- const [pichers, setPichers] = useState<any[]>([]) // 投手数据
|
|
|
const [mode, setMode] = useState<string>('total') // 总/明细
|
|
|
const [px, setPx] = useState<boolean>(false)//设置顶部图形的排列方式
|
|
|
const [planDetailList, setPlanDetailList] = useState<any[]>([])
|
|
@@ -41,68 +39,41 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
const [visible, setVisible] = useState<boolean>(false) // 详情弹窗控制
|
|
|
const [aId, setAId] = useState<any>()
|
|
|
const [downLoadLoading, setDownLoadLoading] = useState<boolean>(false)
|
|
|
+ const [hour, setHour] = useState<any>()
|
|
|
+ const [clickAccountId, setClickAccountId] = useState<number[]>([])
|
|
|
const { totalTimeUnit, planTimeUnit, adgroup, accountId, sysUserId, pageNum, pageSize, campaign, sortField, sort } = queryForm
|
|
|
-
|
|
|
// 变量结束
|
|
|
+
|
|
|
+ // 获取投手
|
|
|
useEffect(() => {
|
|
|
- if (state?.allOfMember?.length > 0) {//组长数据存在使用组长数据
|
|
|
- setDatas(state?.allOfMember)
|
|
|
- } else if (state?.myallOfUser?.length > 0) {//否则个人
|
|
|
- setDatas(state?.myallOfUser)
|
|
|
- }
|
|
|
- }, [state])
|
|
|
+ getPicherList.run()
|
|
|
+ }, [])
|
|
|
// 获取广告账号
|
|
|
useEffect(() => {
|
|
|
getAdqAccountList.run()
|
|
|
}, [])
|
|
|
- // 处理投手
|
|
|
- useEffect(() => {
|
|
|
- if (datas.length > 0) {
|
|
|
- let new_pichers = datas?.map((item: { key: { nickname: string, userId: number } }) => ({ nickName: item?.key?.nickname, userId: item?.key?.userId }))
|
|
|
- if (JSON.stringify(pichers) !== JSON.stringify(new_pichers)) {//避免重复设置触发条件多次请求接口
|
|
|
- setPichers(new_pichers)
|
|
|
- }
|
|
|
- }
|
|
|
- }, [datas, pichers])
|
|
|
// // 获取排行数据,柱图
|
|
|
useEffect(() => {
|
|
|
- if (pichers.length > 0) {
|
|
|
- getPlanCostList()
|
|
|
- }
|
|
|
- }, [totalTimeUnit, accountId, sysUserId, pichers])
|
|
|
- // 获取起量计划列表 底部table
|
|
|
- useEffect(() => {
|
|
|
- if (pichers.length > 0) {
|
|
|
- if (mode === 'total') {
|
|
|
- getList()
|
|
|
- } else if (mode === 'detail') {
|
|
|
- if (adgroup) {
|
|
|
- getDetailList(adgroup)
|
|
|
- }
|
|
|
- } else if (mode === 'minute') {
|
|
|
- if (adgroup) {
|
|
|
- getMinuList(adgroup)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }, [accountId, sysUserId, pageNum, pageSize, campaign, pichers, adgroup, sortField, sort, mode])
|
|
|
+ getPlanCostList()
|
|
|
+ }, [totalTimeUnit, accountId, sysUserId])
|
|
|
// 获取今日计划总消耗图谱,折线
|
|
|
useEffect(() => {
|
|
|
- if (pichers.length > 0) {
|
|
|
- getTootalCostList()
|
|
|
+ getTootalCostList()
|
|
|
+ }, [planTimeUnit, adgroup, accountId, sysUserId])
|
|
|
+ // 获取起量计划列表 底部table
|
|
|
+ useEffect(() => {
|
|
|
+ if (mode === 'total') {
|
|
|
+ getList()
|
|
|
}
|
|
|
- }, [planTimeUnit, adgroup, accountId, sysUserId, pichers])
|
|
|
+ }, [accountId, sysUserId, pageNum, pageSize, campaign, adgroup, sortField, sort, mode, hour])
|
|
|
+
|
|
|
// 获取起量明细表 点击
|
|
|
useEffect(() => {
|
|
|
- // if (adgroup) {
|
|
|
- // getDetailList(adgroup)
|
|
|
- // } else {
|
|
|
- // setMode('total')//切到总表
|
|
|
- // }
|
|
|
if (!adgroup) {
|
|
|
setMode('total')//切到总表
|
|
|
}
|
|
|
}, [adgroup])
|
|
|
+
|
|
|
/** 获取折线图 */
|
|
|
const getTootalCostList = useCallback(async () => {
|
|
|
let { totalTimeUnit, planTimeUnit, pageNum, pageSize, adgroup, sysUserId, accountId, ...newQueryForm } = queryForm
|
|
@@ -115,7 +86,7 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
})
|
|
|
setLineDis(() => data)
|
|
|
setLineTitle(() => res?.data?.adName ? res?.data?.adName + '_消耗趋势' : '广告总消耗趋势')
|
|
|
- }, [queryForm, lineDis, pichers])
|
|
|
+ }, [queryForm, lineDis])
|
|
|
|
|
|
/** 获取柱状图 */
|
|
|
const getPlanCostList = useCallback(async () => {
|
|
@@ -123,8 +94,8 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
let { adgroup, ...planQueryFrom } = newQueryForm
|
|
|
let newPitcherIds = sysUserId?.join()
|
|
|
let res = await getPlanCost.run({ ...planQueryFrom, timeUnit: totalTimeUnit, sysUserId: newPitcherIds, accountId: accountId?.join() })
|
|
|
- let data = res?.data?.planCostDtoList?.map((item: { adId: number, cost: number, adName: string }) => {
|
|
|
- return { name: item.adId.toString(), value: item.cost, adName: item.adName }
|
|
|
+ let data = res?.data?.planCostDtoList?.map((item: { adId: number, cost: number, adName: string, accountId: number }) => {
|
|
|
+ return { name: item.adId.toString(), value: item.cost, adName: item.adName, accountId: item.accountId }
|
|
|
})
|
|
|
data = data?.sort((a: any, b: any) => {
|
|
|
var value1 = a['value'];
|
|
@@ -132,26 +103,27 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
return value2 - value1;
|
|
|
})
|
|
|
setBarDis(() => data)
|
|
|
- }, [queryForm, barDis, pichers])
|
|
|
+ }, [queryForm, barDis])
|
|
|
|
|
|
// 气量Table总表
|
|
|
const getList = useCallback(() => {
|
|
|
let { totalTimeUnit, planTimeUnit, timeUnit, sysUserId, accountId, ...newQueryForm } = queryForm
|
|
|
- getPlanList.run({ ...newQueryForm, sysUserId, accountId: accountId?.join() })
|
|
|
- }, [queryForm, pichers])
|
|
|
+ getPlanList.run({ ...newQueryForm, sysUserId, accountId, hour })
|
|
|
+ }, [queryForm, hour])
|
|
|
|
|
|
|
|
|
// 起量明细表 点击
|
|
|
- const getDetailList = useCallback((adgroup: any) => {
|
|
|
+ const getDetailList = useCallback((adgroup: any, clickAccountId: any[]) => {
|
|
|
+ setClickAccountId(clickAccountId)
|
|
|
let { totalTimeUnit, planTimeUnit, timeUnit, pageNum, pageSize, adgroup: aa, sysUserId, accountId, ...newQueryForm } = queryForm
|
|
|
if (adgroup) {
|
|
|
setMode('detail')//切到明细
|
|
|
- getPlanDetailList.run({ ...newQueryForm, adgroupId: adgroup, sysUserId, accountId: accountId?.join() }).then((res: any) => {
|
|
|
+ getPlanDetailList.run({ ...newQueryForm, adgroupId: adgroup, sysUserId, accountId: accountId ? accountId : clickAccountId }).then((res: any) => {
|
|
|
setPlanDetailList(res?.data ? [...res?.data] : [])
|
|
|
setQueryForm({ ...queryForm, adgroup })
|
|
|
})
|
|
|
}
|
|
|
- }, [queryForm, getPlanList, pichers, planDetailList])
|
|
|
+ }, [queryForm, getPlanList, planDetailList])
|
|
|
|
|
|
// 详情
|
|
|
const details = (data: any) => {
|
|
@@ -160,16 +132,17 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
}
|
|
|
|
|
|
// 起量5min表
|
|
|
- const getMinuList = useCallback((adgroup: any) => {
|
|
|
+ const getMinuList = useCallback((adgroup: any, clickAccountId: any[]) => {
|
|
|
+ setClickAccountId(clickAccountId)
|
|
|
let { totalTimeUnit, planTimeUnit, timeUnit, pageNum, pageSize, adgroup: aa, sysUserId, accountId, ...newQueryForm } = queryForm
|
|
|
if (adgroup) {
|
|
|
setMode('minute')
|
|
|
- getMinuteList.run({ ...newQueryForm, adgroupId: adgroup, sysUserId, accountId: accountId?.join() }).then((res: any) => {
|
|
|
+ getMinuteList.run({ ...newQueryForm, adgroupId: adgroup, sysUserId, accountId: accountId ? accountId : clickAccountId }).then((res: any) => {
|
|
|
setMinuteList(res?.data ? [...res?.data] : [])
|
|
|
setQueryForm({ ...queryForm, adgroup })
|
|
|
})
|
|
|
}
|
|
|
- }, [queryForm, getPlanList, pichers, minuteList, adgroup])
|
|
|
+ }, [queryForm, getPlanList, minuteList, adgroup])
|
|
|
|
|
|
// 计划详情
|
|
|
const planDetail = (data: any) => {
|
|
@@ -185,6 +158,7 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
getPlanDetailList.refresh()
|
|
|
getMinuteList.refresh()
|
|
|
}
|
|
|
+
|
|
|
// 接口自动刷新10分钟一次
|
|
|
useEffect(() => {
|
|
|
let time = setInterval(() => {
|
|
@@ -193,7 +167,8 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
return () => {
|
|
|
clearInterval(time)
|
|
|
}
|
|
|
- }, [pichers])
|
|
|
+ }, [])
|
|
|
+
|
|
|
//图形排列样式改变重新获取数据刷新图形
|
|
|
const set = useCallback((b) => {
|
|
|
setPx(b)
|
|
@@ -203,7 +178,6 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
|
|
|
// 下载
|
|
|
const downLoadExcel = useCallback(() => {
|
|
|
- // downLoadUpAdApi, downLoadDetailApi, downLoadDetailMinuteApi
|
|
|
let ajax: any = null
|
|
|
let params: any = {}
|
|
|
let { totalTimeUnit, planTimeUnit, timeUnit, sysUserId, accountId, adgroup, pageNum, pageSize, ...newQueryForm } = queryForm
|
|
@@ -228,7 +202,7 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
downloadFile1(res, 'octet-stream', formatDate(new Date()) + ".xlsx")
|
|
|
}).catch(() => setDownLoadLoading(false))
|
|
|
}
|
|
|
- }, [queryForm, mode, pichers, downLoadLoading])
|
|
|
+ }, [queryForm, mode, downLoadLoading])
|
|
|
|
|
|
// 处理折线图数据
|
|
|
const timePickerHandle = async (values: any, formatString: [string, string]) => {
|
|
@@ -259,6 +233,17 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const disabledTime = () => {
|
|
|
+ let h = moment().format('H')
|
|
|
+ let H: number[] = []
|
|
|
+ for (let index = Number(h) + 1; index < 23; index++) {
|
|
|
+ H.push(index)
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ disabledHours: () => H
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return <Space direction='vertical' style={{ width: '100%' }} className="monitor">
|
|
|
<Card hoverable >
|
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
@@ -271,17 +256,19 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
maxTagCount={1}
|
|
|
disabled={queryForm?.accountId?.length > 0}
|
|
|
allowClear placeholder="请选择投手"
|
|
|
- onChange={(value: string) => { setQueryForm({ ...queryForm, sysUserId: value, pageNum: 1 }) }}
|
|
|
+ onChange={(value: number[]) => {
|
|
|
+ setQueryForm({ ...queryForm, sysUserId: value, pageNum: 1 })
|
|
|
+ }}
|
|
|
filterOption={(input, option) =>
|
|
|
(option?.children as any).toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
|
}
|
|
|
>
|
|
|
- {pichers?.map((item: { nickName: string, userId: number }, index: number) =>
|
|
|
+ {getPicherList?.data?.map((item: { nickname: string, userId: number }, index: number) =>
|
|
|
<Select.Option
|
|
|
value={item.userId}
|
|
|
key={item.userId + '' + index}
|
|
|
>
|
|
|
- {item.nickName}
|
|
|
+ {item.nickname}
|
|
|
</Select.Option>
|
|
|
)}
|
|
|
</Select>
|
|
@@ -296,31 +283,42 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
filterOption={(input, option) =>
|
|
|
(option?.children as any).toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
|
}
|
|
|
- onChange={(value: string) => {
|
|
|
+ onChange={(value: number[]) => {
|
|
|
setQueryForm({ ...queryForm, accountId: value, pageNum: 1 })
|
|
|
}}
|
|
|
>
|
|
|
- {getAdqAccountList?.data?.data?.map((item: { id: number, accountId: number, wechatAccountName: string }) => <Select.Option
|
|
|
+ {getAdqAccountList?.data?.data?.map((item: { id: number, accountId: number }) => <Select.Option
|
|
|
value={item.accountId}
|
|
|
key={item.id}
|
|
|
>
|
|
|
- {item.accountId + "_" + item.wechatAccountName}
|
|
|
+ {item.accountId}
|
|
|
</Select.Option>)}
|
|
|
</Select>
|
|
|
- <Input value={queryForm.campaign} placeholder="计划ID" onChange={(e) => {
|
|
|
- let value = e.target.value
|
|
|
- if (!isNaN(Number(value))) {
|
|
|
- setQueryForm({ ...queryForm, campaign: value })
|
|
|
- }
|
|
|
- }}
|
|
|
- allowClear />
|
|
|
- <Input value={queryForm.adgroup} placeholder="广告ID" onChange={(e) => {
|
|
|
- let value = e.target.value
|
|
|
- if (!isNaN(Number(value))) {
|
|
|
- setQueryForm({ ...queryForm, adgroup: e.target.value })
|
|
|
- }
|
|
|
- }
|
|
|
- } allowClear />
|
|
|
+ <Input
|
|
|
+ value={queryForm.campaign}
|
|
|
+ placeholder="计划ID"
|
|
|
+ onChange={(e) => {
|
|
|
+ let value = e.target.value
|
|
|
+ if (!isNaN(Number(value))) {
|
|
|
+ setQueryForm({ ...queryForm, campaign: value })
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ allowClear
|
|
|
+ />
|
|
|
+ <Input
|
|
|
+ value={queryForm.adgroup}
|
|
|
+ placeholder="广告ID"
|
|
|
+ onChange={(e) => {
|
|
|
+ let value = e.target.value
|
|
|
+ if (!isNaN(Number(value))) {
|
|
|
+ setQueryForm({ ...queryForm, adgroup: e.target.value })
|
|
|
+ }
|
|
|
+ if (!value) {
|
|
|
+ setClickAccountId([])
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ allowClear
|
|
|
+ />
|
|
|
</Space>
|
|
|
<Space>
|
|
|
<Tag color="#2db7f5" onClick={refresh}><RedoOutlined /> 刷新</Tag>
|
|
@@ -347,7 +345,7 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
</Radio.Group>
|
|
|
</Space>
|
|
|
</div>
|
|
|
- {getPlanCost?.loading ? <Spin /> : <BarMonitor style={{ width: '100%', height: '100%' }} data={barDis} xName="今日消耗" yName="广告名称" onChange={(value?: string) => { setQueryForm({ ...queryForm, adgroup: value }); setMode('detail') }} planID={queryForm?.adgroup} />}
|
|
|
+ {getPlanCost?.loading ? <Spin /> : <BarMonitor style={{ width: '100%', height: '100%' }} data={barDis} xName="今日消耗" yName="广告名称" onChange={(value: string, accountId) => { getDetailList(value, accountId) }} planID={queryForm?.adgroup} />}
|
|
|
</div>
|
|
|
<div>
|
|
|
<div className="selectTime">
|
|
@@ -379,12 +377,23 @@ function Monitor(props: { onChange: () => void }) {
|
|
|
<Space>
|
|
|
<Radio.Group onChange={(e: RadioChangeEvent) => {
|
|
|
let value = e.target.value
|
|
|
- setMode(value)
|
|
|
+ switch (value) {
|
|
|
+ case 'total':
|
|
|
+ setMode(value)
|
|
|
+ break;
|
|
|
+ case 'detail':
|
|
|
+ getDetailList(queryForm.adgroup, clickAccountId)
|
|
|
+ break
|
|
|
+ case 'minute':
|
|
|
+ getMinuList(queryForm.adgroup, clickAccountId)
|
|
|
+ break
|
|
|
+ }
|
|
|
}} value={mode} size='small'>
|
|
|
<Radio.Button value="total">总</Radio.Button>
|
|
|
<Radio.Button value="detail" disabled={!adgroup}>小时</Radio.Button>
|
|
|
<Radio.Button value="minute" disabled={!adgroup}>5min</Radio.Button>
|
|
|
</Radio.Group>
|
|
|
+ {mode === 'total' && <TimePicker disabledTime={disabledTime} size='small' style={{ width: 110 }} onChange={(e) => { setHour(e ? moment(e).format('H') : null) }} format="HH" />}
|
|
|
<Button size="small" icon={<CloudDownloadOutlined />} loading={downLoadLoading} onClick={downLoadExcel}>{mode === 'total' ? '总表' : mode === 'detail' ? '小时表' : '5min表'}下载</Button>
|
|
|
</Space>
|
|
|
}
|