Browse Source

新增两个总结页面

samhoo 6 years ago
parent
commit
6b9cdf32c0

File diff suppressed because it is too large
+ 726 - 88
uas-office-web/wxuasapproval/package-lock.json


+ 2 - 0
uas-office-web/wxuasapproval/package.json

@@ -4,8 +4,10 @@
   "private": true,
   "private": true,
   "homepage": ".",
   "homepage": ".",
   "dependencies": {
   "dependencies": {
+    "@antv/data-set": "^0.11.1",
     "antd-mobile": "^2.3.1",
     "antd-mobile": "^2.3.1",
     "babel-polyfill": "^6.26.0",
     "babel-polyfill": "^6.26.0",
+    "bizcharts": "^3.5.7",
     "js-cookie": "^2.2.1",
     "js-cookie": "^2.2.1",
     "moment": "^2.22.2",
     "moment": "^2.22.2",
     "react": "^16.5.2",
     "react": "^16.5.2",

+ 0 - 1
uas-office-web/wxuasapproval/public/index.html

@@ -19,7 +19,6 @@
       work correctly both with client-side routing and a non-root public URL.
       work correctly both with client-side routing and a non-root public URL.
       Learn how to configure a non-root public URL by running `npm run build`.
       Learn how to configure a non-root public URL by running `npm run build`.
     -->
     -->
-
     <script type="text/javascript">
     <script type="text/javascript">
       function GetQueryString (name) {
       function GetQueryString (name) {
         let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
         let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')

+ 5 - 0
uas-office-web/wxuasapproval/src/configs/router.config.js

@@ -11,6 +11,8 @@ import Approval from '../pages/approval/Approval'
 import BindResult from '../pages/bindPhone/BindResult'
 import BindResult from '../pages/bindPhone/BindResult'
 import RedirectPage from '../pages/RedirectPage'
 import RedirectPage from '../pages/RedirectPage'
 import ApprovalHome from '../pages/approval/ApprovalHome'
 import ApprovalHome from '../pages/approval/ApprovalHome'
+import UseStatus from '../pages/useStatus/UseStatus'
+import WorkSummary from '../pages/workSummary/WorkSummary'
 
 
 export class Routes extends React.Component {
 export class Routes extends React.Component {
 
 
@@ -29,6 +31,9 @@ export class Routes extends React.Component {
           <Route path='/redirect/:paramsStr?' component={RedirectPage}/>
           <Route path='/redirect/:paramsStr?' component={RedirectPage}/>
           <Route path='/bindPhone/:openId?' component={BindPhone}/>
           <Route path='/bindPhone/:openId?' component={BindPhone}/>
           <Route path='/bindResult/:result' component={BindResult}/>
           <Route path='/bindResult/:result' component={BindResult}/>
+
+          <Route path='/usestatus/:instanceId' component={UseStatus}/>
+          <Route path='/worksummary' component={WorkSummary}/>
           {/*<Redirect path='/' to={{pathname: '/bindPhone'}}/>*/}
           {/*<Redirect path='/' to={{pathname: '/bindPhone'}}/>*/}
 
 
           {/*404页面*/}
           {/*404页面*/}

+ 1 - 0
uas-office-web/wxuasapproval/src/pages/approval/Approval.jsx

@@ -559,6 +559,7 @@ export default class Approval extends Component {
       // 'Cookie': 'JSESSIONID=' + mSessionId,
       // 'Cookie': 'JSESSIONID=' + mSessionId,
       // "Content-Type": "application/json; charset=UTF-8"
       // "Content-Type": "application/json; charset=UTF-8"
     }).then((response) => {
     }).then((response) => {
+      console.log('response',response)
       try {
       try {
         let result = response
         let result = response
         let infoObject = result.info
         let infoObject = result.info

+ 202 - 0
uas-office-web/wxuasapproval/src/pages/useStatus/UseStatus.jsx

@@ -0,0 +1,202 @@
+import React, { Component } from 'react';
+import {
+    Chart,
+    Geom,
+    Axis,
+    Tooltip,
+    Coord,
+    Label
+} from "bizcharts";
+import { message, Spin } from 'antd'
+import DataSet from "@antv/data-set";
+import './useStatus.css';
+import { fetchPost, fetchGet } from '../../utils/fetchRequest';
+import {
+    isObjEmpty
+} from '@/utils/common'
+
+let DEPART, USERCOUNT,dataLength;
+let DURATIONLIST = [];
+let DAILYCOUNT = [];
+let columnWidth = 300;
+let mBaseUrl =  window.location.origin+'/office';
+
+
+export default class Basic extends Component {
+    constructor() {
+        super()
+
+        this.state = { 
+            loading: true    //更改
+        }
+    }
+
+    componentWillMount() {
+        document.title = '部门成员使用情况'
+        let instanceId = this.props.match.params.instanceId;
+        if (!isObjEmpty(instanceId)) {
+            try {
+                this.getData(instanceId);
+            } catch (e) {
+                this.setState({
+                    loading: false,
+                })
+                message.error('参数获取失败')
+            }
+        } else {
+            this.setState({
+                loading: false,
+            })
+            message.error('参数获取失败')
+        }
+
+    }
+
+    getData = (instanceId) => {
+        fetchPost(mBaseUrl+'/api/analysis/getAnalysisByWeek', {
+            'instanceid': instanceId,
+        }, {
+            // 'Cookie': 'JSESSIONID=' + mSessionId,
+            // "Content-Type": "application/json; charset=UTF-8"
+        }).then((response) => {
+            if(response.success){
+                let dataSource = response.data[0];
+                DEPART = dataSource.DEPART;
+                USERCOUNT = dataSource.USERCOUNT;
+                DURATIONLIST = dataSource.DURATIONLIST;
+                DAILYCOUNT = dataSource.DAILYCOUNT;
+                dataLength = DURATIONLIST.length;
+                if(dataLength>0){
+                    columnWidth = dataLength*55;
+                }else{
+                    columnWidth = 300
+                }
+                this.setState({
+                    loading: false
+                })
+            }
+        }).catch(error => {
+            console.log(error)
+        })
+    }
+    handleClick = e => {
+        if (e.data) {
+            let emcode = e.data.point.EMCODE;
+            let instanceId = this.props.match.params.instanceId;
+            emcode = encodeURIComponent(emcode);
+            instanceId = encodeURIComponent(instanceId);
+            this.props.history.push('/worksummary?emcode=' + emcode + '&instanceId=' + instanceId)
+        } else {
+            return false;
+        }
+
+
+    }
+    render() {
+        const { loading } = this.state;
+        const cols = {
+            EMCOUNT: {
+                min: 0
+            },
+            DATE_TIME: {
+                range: [0, 1]
+            }
+        };
+        const ds = new DataSet();
+        const dv = ds.createView().source(DURATIONLIST);
+        dv.source(DURATIONLIST).transform({
+            type: "sort",
+            callback(a, b) {
+                // 排序依据,和原生js的排序callback一致
+                return a.DURATION - b.DURATION;
+            }
+        });
+
+        return (
+            <div className="useStatusRoot">
+                <Spin size="large"
+                    style={{ display: loading ? 'flex' : 'none' }}
+                    tip='数据请求中...'>
+                </Spin>
+                <div style={{ display: loading ? 'none' : 'flex' }} className='content'>
+                    <div className='branch'>{DEPART}</div>
+                    <div className='lineCharts'>
+                        <div className='useNum'>使用人数{USERCOUNT}人</div>
+                        <Chart padding={['12%','10%','12%','auto']} height={300} data={DAILYCOUNT} scale={cols} forceFit>
+                            <Axis
+                                name="DATE_TIME"
+                                label={{
+                                    offset: 12,
+                                    textStyle: {
+                                        fontSize: '16',
+                                        fill: '#959595'
+                                    }
+                                }} />
+                            <Axis
+                                name="EMCOUNT"
+                                position="right"
+                                label={{
+                                    offset: 10,
+                                    textStyle: {
+                                        fontSize: '16',
+                                        fill: '#959595'
+                                    }
+                                }}
+                            />
+                            <Tooltip
+                                crosshairs={{
+                                    type: "y"
+                                }}
+                            />
+                            <Geom type="line" position="DATE_TIME*EMCOUNT" size={2} />
+                            <Geom
+                                type="point"
+                                position="DATE_TIME*EMCOUNT"
+                                size={4}
+                                shape={"circle"}
+                                style={{
+                                    stroke: "#fff",
+                                    lineWidth: 1
+                                }}
+                            />
+                        </Chart>
+                    </div>
+                    <div className='columnCharts'>
+                        <div className='useTime'>成员使用时间(分钟)</div>
+                        <Chart
+                            onPlotClick={this.handleClick}
+                            padding={['auto','12%','auto','auto']}
+                            height={columnWidth}
+                            data={dv}
+                            forceFit
+                        >
+                            <Coord transpose />
+                            <Axis
+                                name="EMNAME"
+                                label={{
+                                    offset: 10,
+                                    textStyle: {
+                                        fontSize: '16',
+                                        fill: '#000'
+                                    }
+                                }}
+                            />
+                            <Axis name="DURATION" label={null} />
+                            <Tooltip />
+                            <Geom type="interval" position="EMNAME*DURATION" >
+                                <Label
+                                    offset={5}
+                                    content="DURATION"
+                                    textStyle={{
+                                        fill: '#000', // 文本的颜色
+                                        fontSize: '16', // 文本大小
+                                    }} />
+                            </Geom>
+                        </Chart>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+

+ 42 - 0
uas-office-web/wxuasapproval/src/pages/useStatus/useStatus.css

@@ -0,0 +1,42 @@
+
+.useStatusRoot{
+    width: 100%;
+    height: 100%;
+    background: #f5f5f5 !important;
+    display: flex;
+    flex-direction: column;
+    font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
+}
+.useStatusRoot .content {
+    width: 100%;
+    flex: 1;
+    flex-direction: column;
+    overflow-y: scroll;
+    overflow-x: hidden;
+}
+.useStatusRoot .content .branch{
+    padding:4%;
+    padding-bottom: 1%;
+    color:#000;
+    font-size:17px;
+    font-weight:bold;
+    background:#fff;
+}
+.useStatusRoot .content .lineCharts{
+    background:#fff;
+}
+.useStatusRoot .content .columnCharts{
+    background:#fff;
+    margin:3% 0 0 0;
+}
+.useStatusRoot .content .lineCharts .useNum{
+    font-size:21px;
+    padding-left:4%;
+    color:#000;
+    font-weight:bold;
+}
+.useStatusRoot .content .columnCharts .useTime{
+    margin:0 !important;
+    padding:4%;
+    font-size:16px;
+}

+ 170 - 0
uas-office-web/wxuasapproval/src/pages/workSummary/WorkSummary.jsx

@@ -0,0 +1,170 @@
+import React, { Component } from 'react';
+import {
+    Chart,
+    Geom,
+    Axis,
+    Tooltip,
+    Coord,
+    Label
+} from "bizcharts";
+import DataSet from "@antv/data-set";
+import './workSummary.css';
+import { Avatar, message, Spin } from 'antd';
+import { List } from 'antd-mobile';
+import { fetchPost, fetchGet } from '../../utils/fetchRequest'
+import {
+    isObjNull, strContain, isObjEmpty, isEmptyObject, getStrValue,
+} from '@/utils/common'
+const Item = List.Item;
+
+let EMCODE, EMNAME, RANGETIME, DURATION, ADDCOUNT, COMMITCOUNT, AUDITCOUNT, dataLength;
+let MODELLIST = [];
+let columnWidth = 300;
+let mBaseUrl =  window.location.origin+'/office';
+
+export default class Basic extends Component {
+    constructor() {
+        super()
+
+        this.state = {
+            loading: true   //更改
+        }
+    }
+    componentWillMount() {
+        let messobj = this.getUrlData();
+        if (!isObjEmpty(messobj)) {
+            try {
+                let emCode = decodeURIComponent(messobj.emcode);
+                let instanceId = decodeURIComponent(messobj.instanceId);
+                this.getData(emCode, instanceId);
+            } catch (e) {
+                this.setState({
+                    loading: false,
+                })
+                message.error('参数获取失败')
+            }
+        } else {
+            this.setState({
+                loading: false,
+            })
+            message.error('参数获取失败')
+        }
+    }
+
+    getUrlData() {
+        let url = window.location.search;  //url中?之后的部分
+        url = url.substring(1);    //去掉?
+        let dataObj = {};
+        if (url.indexOf('&') > -1) {
+            url = url.split('&');
+            for (let i = 0; i < url.length; i++) {
+                let arr = url[i].split('=');
+                dataObj[arr[0]] = arr[1];
+            }
+        } else {
+            url = url.split('=');
+            dataObj[url[0]] = url[1];
+        }
+        return dataObj;
+    }
+
+    getData = (emCode, instanceId) => {
+        fetchPost(mBaseUrl+'/api/analysis/getAnalysisByPerson', {
+            'emCode': emCode,
+            'instanceid': instanceId
+        }, {
+            // 'Cookie': 'JSESSIONID=' + mSessionId,
+            // "Content-Type": "application/json; charset=UTF-8"
+        }).then((response) => {
+            if (response.success) {
+                let dataSource = response.data;
+                EMCODE = dataSource.EMCODE;
+                EMNAME = dataSource.EMNAME;
+                RANGETIME = dataSource.RANGETIME;
+                DURATION = dataSource.DURATION;
+                ADDCOUNT = dataSource.ADDCOUNT;
+                COMMITCOUNT = dataSource.COMMITCOUNT;
+                AUDITCOUNT = dataSource.AUDITCOUNT;
+                MODELLIST = dataSource.MODELLIST;
+                dataLength = MODELLIST.length;
+                if (dataLength > 0) {
+                    columnWidth = dataLength * 55;
+                } else {
+                    columnWidth = 300
+                }
+                this.setState({
+                    loading: false
+                })
+            }
+        }).catch(error => {
+            console.log(error)
+        })
+    }
+
+    render() {
+        const { loading } = this.state;
+        const ds = new DataSet();
+        const dv = ds.createView().source(MODELLIST);
+        dv.source(MODELLIST).transform({
+            type: "sort",
+            callback(a, b) {
+                // 排序依据,和原生js的排序callback一致
+                return a.DURATION - b.DURATION;
+            }
+        });
+
+        return (
+            <div className=" workSummaryRoot">
+                <Spin size="large"
+                    style={{ display: loading ? 'flex' : 'none' }}
+                    tip='数据请求中...'>
+                </Spin>
+                <div style={{ display: loading ? 'none' : 'flex' }} className='content'>
+                    <div className='selfMess'>
+                        <Avatar size={42} src={require('@/images/default_header.png')} />
+                        <div className='self'>
+                            <p className='name'>{EMNAME}</p>
+                            <p className='summary'>一周小结 {RANGETIME}</p>
+                        </div>
+                    </div>
+                    <div className='workSummary'>
+                        <p className='workTitle'>工作小结</p>
+                        <List className="my-list">
+                            <Item extra={DURATION + ' 分钟'}>累计在线时长:</Item>
+                            <Item extra={ADDCOUNT + ' 项'}>累计新增单据:</Item>
+                            <Item extra={COMMITCOUNT + ' 项'}>累计提交单据:</Item>
+                            <Item extra={AUDITCOUNT + ' 项'}>累计处理审批:</Item>
+                        </List>
+                    </div>
+                    <div className='columnCharts'>
+                        <div className='useTime'>各模块使用情况(分钟)</div>
+                        <Chart padding={['auto', '12%', 'auto', 'auto']} height={columnWidth} data={dv} forceFit>
+                            <Coord transpose />
+                            <Axis
+                                name="MODELNAME"
+                                label={{
+                                    textStyle: {
+                                        textAlign: 'end', // 文本对齐方向,可取值为: start center end
+                                        fill: '#000',
+                                        fontSize: '16'
+                                    }
+                                }}
+                            />
+                            <Axis name="DURATION" label={null} />
+                            <Tooltip />
+                            <Geom type="interval" position="MODELNAME*DURATION" >
+                                <Label label={{
+                                    textStyle: {
+                                        fill: '#000',
+                                        fontSize: '16'
+                                    }
+                                }} offset={5} content="DURATION" />
+                            </Geom>
+                        </Chart>
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+

+ 62 - 0
uas-office-web/wxuasapproval/src/pages/workSummary/workSummary.css

@@ -0,0 +1,62 @@
+.workSummaryRoot {
+    width: 100%;
+    height: 100%;
+    background: #f5f5f5 !important;
+    display:-webkit-flex;
+    display: flex;
+    font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
+}
+.workSummaryRoot .content {
+    width: 100%;
+    flex: 1;
+    overflow-y: scroll;
+    overflow-x: hidden;
+    display:-webkit-flex;
+    display: flex;
+    -webkit-flex-direction: column;
+    flex-direction: column;
+}
+.content::-webkit-scrollbar {
+    display: none;
+}
+.workSummaryRoot .content .selfMess{
+    width: 100%;
+    padding: 10px;
+    display: flex;
+    align-items: center;
+    background:#fff;
+}
+.workSummaryRoot .content .selfMess .self{
+    width:100%;
+}
+.workSummaryRoot .content .selfMess .self .name{
+    font-size:16px;
+    margin:0;
+    margin-left:5%;
+    color:#000;
+}
+.workSummaryRoot .content .selfMess .self .summary{
+    margin-left:5%;
+    font-size:16px;
+    color:#333333;
+}
+.workSummaryRoot .content .workSummary {
+    margin:3% 0 0 0;
+}
+.workSummaryRoot .content .workSummary .workTitle{
+    margin:0 !important;
+    padding:2%;
+    padding-left:5%;
+    color: rgba(0, 0, 0, 0.65);
+    font-size:16px;
+    background:#fff;
+}
+.workSummaryRoot .content .columnCharts{
+    margin:3% 0 0 0;
+    background:#fff;
+}
+.workSummaryRoot .content .columnCharts .useTime{
+    margin:0 !important;
+    padding:4% 4% 0 4%;
+    font-size: 16px;
+}

Some files were not shown because too many files changed in this diff