A 发布申请TOP5图表支持选择时间范围统计

pull/161/head
vapao 2020-07-29 20:58:28 +08:00
parent 9dd1ee8ae6
commit 6c91f6f5f2
3 changed files with 94 additions and 34 deletions

View File

@ -8,7 +8,8 @@ from apps.schedule.models import Task
from apps.monitor.models import Detection from apps.monitor.models import Detection
from apps.alarm.models import Alarm from apps.alarm.models import Alarm
from apps.deploy.models import Deploy, DeployRequest from apps.deploy.models import Deploy, DeployRequest
from libs.utils import json_response, human_date from libs.utils import json_response, human_date, parse_time
from libs.parser import JsonParser, Argument
from datetime import datetime, timedelta from datetime import datetime, timedelta
import json import json
@ -35,11 +36,18 @@ def get_alarm(request):
def get_request(request): def get_request(request):
data = {x.id: {'name': x.name, 'count': 0} for x in App.objects.all()} form, error = JsonParser(
for req in DeployRequest.objects.filter(created_at__gt=human_date()): Argument('duration', type=list, help='参数错误')
data[req.deploy.app_id]['count'] += 1 ).parse(request.body)
data = sorted(data.values(), key=lambda x: x['count'], reverse=True)[:5] if error is None:
return json_response(data) s_date = form.duration[0]
e_date = (parse_time(form.duration[1]) + timedelta(days=1)).strftime('%Y-%m-%d')
data = {x.id: {'name': x.name, 'count': 0} for x in App.objects.all()}
for req in DeployRequest.objects.filter(created_at__gt=s_date, created_at__lt=e_date):
data[req.deploy.app_id]['count'] += 1
data = sorted(data.values(), key=lambda x: x['count'], reverse=True)[:5]
return json_response(data)
return json_response(error=error)
def get_deploy(request): def get_deploy(request):

View File

@ -3,37 +3,70 @@
* Copyright (c) <spug.dev@gmail.com> * Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License. * Released under the AGPL-3.0 License.
*/ */
import React from 'react'; import React, { useState, useEffect } from 'react';
import { Card } from 'antd'; import { Card, DatePicker } from 'antd';
import { Chart, Geom, Axis, Tooltip } from 'bizcharts'; import { Chart, Geom, Axis, Tooltip } from 'bizcharts';
import styles from './index.module.css';
import moment from 'moment';
import { http } from 'libs'; import { http } from 'libs';
export default class RequestTop extends React.Component {
constructor(props) { export default function () {
super(props); const [loading, setLoading] = useState(false);
this.state = { const [duration, setDuration] = useState([moment(), moment()]);
loading: true, const [range, setRange] = useState('day');
res: [] const [res, setRes] = useState([])
};
useEffect(() => {
setLoading(true);
const strDuration = duration.map(x => x.format('YYYY-MM-DD'))
http.post('/api/home/request/', {duration: strDuration})
.then(res => setRes(res))
.finally(() => setLoading(false))
}, [duration])
function handleClick(val) {
let duration = [];
switch (val) {
case 'day':
setRange('day');
duration = [moment(), moment()];
break;
case 'week':
setRange('week');
duration = [moment().weekday(0), moment().weekday(6)];
break;
case 'month':
setRange('month');
const s_date = moment().startOf('month')
const e_date = moment().endOf('month')
duration = [s_date, e_date];
break;
default:
setRange('custom')
duration = val
}
setDuration(duration)
} }
componentDidMount() { return (
http.get('/api/home/request/') <Card loading={loading} title="发布申请Top5" extra={(
.then(res => this.setState({res})) <div style={{display: 'flex', alignItems: 'center'}}>
.finally(() => this.setState({loading: false})) <span className={range === 'day' ? styles.spanButtonActive : styles.spanButton}
} onClick={() => handleClick('day')}>今日</span>
<span className={range === 'week' ? styles.spanButtonActive : styles.spanButton}
render() { onClick={() => handleClick('week')}>本周</span>
const {res, loading} = this.state; <span className={range === 'month' ? styles.spanButtonActive : styles.spanButton}
return ( onClick={() => handleClick('month')}>本月</span>
<Card loading={loading} title="发布申请Top5"> <DatePicker.RangePicker value={duration} onChange={handleClick}/>
<Chart height={300} data={res} padding={[10, 0, 30, 35]} forceFit> </div>
<Axis name="name"/> )}>
<Axis name="count" title/> <Chart height={300} data={res} padding={[10, 0, 30, 35]} forceFit>
<Tooltip/> <Axis name="name"/>
<Geom type="interval" position="name*count"/> <Axis name="count" title/>
</Chart> <Tooltip/>
</Card> <Geom type="interval" position="name*count"/>
) </Chart>
} </Card>
)
} }

View File

@ -0,0 +1,19 @@
:global(.ant-card-extra) {
padding: 12px 0;
}
.spanButton {
cursor: pointer;
margin-right: 24px;
color: rgba(0, 0, 0, .65);
}
.spanButtonActive {
cursor: pointer;
margin-right: 24px;
color: #1890ff;
}
.spanButton:hover {
color: #1890ff;
}