|
@@ -1,24 +1,44 @@
|
|
import React, { useEffect, useState, useRef } from 'react';
|
|
import React, { useEffect, useState, useRef } from 'react';
|
|
import { connect } from 'dva';
|
|
import { connect } from 'dva';
|
|
-import { Form, Table, DatePicker, Input, Button } from 'antd';
|
|
|
|
|
|
+import { Form, Table, DatePicker, Input, Button, Empty, Card, Affix } from 'antd';
|
|
import styles from './report.less';
|
|
import styles from './report.less';
|
|
import UserRptModal from './UserRptModal';
|
|
import UserRptModal from './UserRptModal';
|
|
import DepCompareModal from './DepCompareModal';
|
|
import DepCompareModal from './DepCompareModal';
|
|
import moment from 'moment';
|
|
import moment from 'moment';
|
|
import { downloadFile, getToken } from '@/utils/utils.js';
|
|
import { downloadFile, getToken } from '@/utils/utils.js';
|
|
|
|
+import * as echarts from 'echarts';
|
|
|
|
+import { CloseOutlined } from '@ant-design/icons';
|
|
|
|
|
|
const { RangePicker } = DatePicker;
|
|
const { RangePicker } = DatePicker;
|
|
|
|
+const initData = [
|
|
|
|
+ // 上个月第一天
|
|
|
|
+ moment()
|
|
|
|
+ .subtract(1, 'month')
|
|
|
|
+ .startOf('month'),
|
|
|
|
+ // 上个月最后一天
|
|
|
|
+ moment()
|
|
|
|
+ .subtract(1, 'month')
|
|
|
|
+ .endOf('month'),
|
|
|
|
+];
|
|
|
|
|
|
function Department(props) {
|
|
function Department(props) {
|
|
const { dispatch, loading, dep } = props;
|
|
const { dispatch, loading, dep } = props;
|
|
const [form] = Form.useForm();
|
|
const [form] = Form.useForm();
|
|
const [visible, setVisible] = useState(false);
|
|
const [visible, setVisible] = useState(false);
|
|
const [modalFilter, setModalFilter] = useState({});
|
|
const [modalFilter, setModalFilter] = useState({});
|
|
|
|
+ const [current, setCurrent] = useState(null);
|
|
|
|
+ const chartRef = useRef(null);
|
|
const columns = [
|
|
const columns = [
|
|
{
|
|
{
|
|
title: '部门名称',
|
|
title: '部门名称',
|
|
// render: record => <a onClick={() => showUserModal(record)}>{record.dep_name}</a>,
|
|
// render: record => <a onClick={() => showUserModal(record)}>{record.dep_name}</a>,
|
|
- render: record => <a onClick={() => showDepCompare(record)}>{record.dep_name}</a>,
|
|
|
|
|
|
+ render: record => <a onClick={() => setCurrent(record)}>{record.dep_name}</a>,
|
|
|
|
+ width: '32%',
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ title: '有效利用率',
|
|
|
|
+ dataIndex: 'usage_percent',
|
|
|
|
+ render: percent => (percent * 100).toFixed(2) + '%',
|
|
},
|
|
},
|
|
{
|
|
{
|
|
title: '执行项目人日',
|
|
title: '执行项目人日',
|
|
@@ -53,9 +73,9 @@ function Department(props) {
|
|
dataIndex: 'total_cnt',
|
|
dataIndex: 'total_cnt',
|
|
},
|
|
},
|
|
{
|
|
{
|
|
- title: '有效利用率',
|
|
|
|
- dataIndex: 'usage_percent',
|
|
|
|
- render: percent => (percent * 100).toFixed(2) + '%',
|
|
|
|
|
|
+ title: '操作',
|
|
|
|
+ width: 80,
|
|
|
|
+ render: item => <a onClick={() => showDepCompare(item)}>详情</a>,
|
|
},
|
|
},
|
|
// {
|
|
// {
|
|
// title: '付费工时数',
|
|
// title: '付费工时数',
|
|
@@ -92,7 +112,7 @@ function Department(props) {
|
|
const renderSearch = () => {
|
|
const renderSearch = () => {
|
|
return (
|
|
return (
|
|
<Form layout="inline" form={form}>
|
|
<Form layout="inline" form={form}>
|
|
- <Form.Item label="时间" name="time" initialValue={[moment().startOf('years'), moment()]}>
|
|
|
|
|
|
+ <Form.Item label="时间" name="time" initialValue={initData}>
|
|
<RangePicker placeholder="选择时间" allowClear={false} />
|
|
<RangePicker placeholder="选择时间" allowClear={false} />
|
|
</Form.Item>
|
|
</Form.Item>
|
|
<Form.Item>
|
|
<Form.Item>
|
|
@@ -124,13 +144,51 @@ function Department(props) {
|
|
});
|
|
});
|
|
setVisible(true);
|
|
setVisible(true);
|
|
};
|
|
};
|
|
|
|
+ const renderChart = item => {
|
|
|
|
+ let data = [
|
|
|
|
+ { value: item.type_project_cnt, name: '执行项目人日' },
|
|
|
|
+ { value: item.type_sale_cnt, name: '售前支持' },
|
|
|
|
+ { value: item.type_market_cnt, name: '市场品牌' },
|
|
|
|
+ { value: item.type_normal_cnt, name: '日常' },
|
|
|
|
+ { value: item.type_standardize_cnt, name: '标准化' },
|
|
|
|
+ { value: item.type_rd_cnt, name: '研发' },
|
|
|
|
+ ];
|
|
|
|
+ // 过滤为0的值
|
|
|
|
+ data = data.filter(item => item.value);
|
|
|
|
+ chartRef.current.setOption({
|
|
|
|
+ tooltip: {
|
|
|
|
+ trigger: 'item',
|
|
|
|
+ },
|
|
|
|
+ series: [
|
|
|
|
+ {
|
|
|
|
+ type: 'pie',
|
|
|
|
+ radius: '70%',
|
|
|
|
+ data: data,
|
|
|
|
+ emphasis: {
|
|
|
|
+ itemStyle: {
|
|
|
|
+ shadowBlur: 10,
|
|
|
|
+ shadowOffsetX: 0,
|
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.5)',
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ });
|
|
|
|
+ };
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
// dispatch({
|
|
// dispatch({
|
|
// type: 'report/queryUserReport',
|
|
// type: 'report/queryUserReport',
|
|
// });
|
|
// });
|
|
handleSearch();
|
|
handleSearch();
|
|
|
|
+ chartRef.current = echarts.init(document.getElementById('chart'));
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ if (current) {
|
|
|
|
+ renderChart(current);
|
|
|
|
+ }
|
|
|
|
+ }, [current]);
|
|
|
|
+
|
|
return (
|
|
return (
|
|
<div>
|
|
<div>
|
|
<div className={styles.topPart}>
|
|
<div className={styles.topPart}>
|
|
@@ -139,15 +197,27 @@ function Department(props) {
|
|
导出
|
|
导出
|
|
</Button>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
- <Table
|
|
|
|
- loading={loading}
|
|
|
|
- rowKey="dep_id"
|
|
|
|
- style={{ marginTop: 20 }}
|
|
|
|
- columns={columns}
|
|
|
|
- dataSource={dep.list}
|
|
|
|
- pagination={false}
|
|
|
|
- onExpand={onExpand}
|
|
|
|
- />
|
|
|
|
|
|
+ <div style={{ marginTop: 20, display: 'flex' }}>
|
|
|
|
+ <Table
|
|
|
|
+ loading={loading}
|
|
|
|
+ rowKey="dep_id"
|
|
|
|
+ style={{ width: '100%' }}
|
|
|
|
+ columns={columns}
|
|
|
|
+ dataSource={dep.list}
|
|
|
|
+ pagination={false}
|
|
|
|
+ onExpand={onExpand}
|
|
|
|
+ />
|
|
|
|
+ <Affix offsetTop={20}>
|
|
|
|
+ <Card
|
|
|
|
+ extra={<CloseOutlined onClick={() => setCurrent(null)} />}
|
|
|
|
+ title={current?.dep_name}
|
|
|
|
+ style={{ display: current ? 'block' : 'none', marginLeft: 20 }}
|
|
|
|
+ >
|
|
|
|
+ <div id="chart" style={{ width: 400, height: 340 }}></div>
|
|
|
|
+ </Card>
|
|
|
|
+ </Affix>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
{/* <UserRptModal filter={modalFilter} visible={visible} onCancel={() => setVisible(false)} /> */}
|
|
{/* <UserRptModal filter={modalFilter} visible={visible} onCancel={() => setVisible(false)} /> */}
|
|
<DepCompareModal filter={modalFilter} visible={visible} onCancel={() => setVisible(false)} />
|
|
<DepCompareModal filter={modalFilter} visible={visible} onCancel={() => setVisible(false)} />
|
|
</div>
|
|
</div>
|