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):
form, error = JsonParser(
Argument('duration', type=list, help='参数错误')
).parse(request.body)
if error is None:
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()} data = {x.id: {'name': x.name, 'count': 0} for x in App.objects.all()}
for req in DeployRequest.objects.filter(created_at__gt=human_date()): for req in DeployRequest.objects.filter(created_at__gt=s_date, created_at__lt=e_date):
data[req.deploy.app_id]['count'] += 1 data[req.deploy.app_id]['count'] += 1
data = sorted(data.values(), key=lambda x: x['count'], reverse=True)[:5] data = sorted(data.values(), key=lambda x: x['count'], reverse=True)[:5]
return json_response(data) return json_response(data)
return json_response(error=error)
def get_deploy(request): def get_deploy(request):

View File

@ -3,30 +3,64 @@
* 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() {
http.get('/api/home/request/')
.then(res => this.setState({res}))
.finally(() => this.setState({loading: false}))
}
render() {
const {res, loading} = this.state;
return ( return (
<Card loading={loading} title="发布申请Top5"> <Card loading={loading} title="发布申请Top5" extra={(
<div style={{display: 'flex', alignItems: 'center'}}>
<span className={range === 'day' ? styles.spanButtonActive : styles.spanButton}
onClick={() => handleClick('day')}>今日</span>
<span className={range === 'week' ? styles.spanButtonActive : styles.spanButton}
onClick={() => handleClick('week')}>本周</span>
<span className={range === 'month' ? styles.spanButtonActive : styles.spanButton}
onClick={() => handleClick('month')}>本月</span>
<DatePicker.RangePicker value={duration} onChange={handleClick}/>
</div>
)}>
<Chart height={300} data={res} padding={[10, 0, 30, 35]} forceFit> <Chart height={300} data={res} padding={[10, 0, 30, 35]} forceFit>
<Axis name="name"/> <Axis name="name"/>
<Axis name="count" title/> <Axis name="count" title/>
@ -35,5 +69,4 @@ export default class RequestTop extends React.Component {
</Chart> </Chart>
</Card> </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;
}