5 Revize a3bca0ef80 ... a719b369fe

Autor SHA1 Zpráva Datum
  shylock a719b369fe fix(compiler): 首页数据对接接口,展示动态数据和echarts图表 před 1 měsícem
  lizhiqi de3a575200 Merge branch 'master' of lizhiqi/yongxu-web into master před 2 měsíci
  lizhiqi 0c94666061 Merge branch 'master' of lizhiqi/yongxu-web into master před 2 měsíci
  lizhiqi c2467d865b Merge branch 'master' of lizhiqi/yongxu-web into master před 6 měsíci
  lizhiqi 382ef9ec93 Merge branch 'master' of lizhiqi/yongxu-web into master před 7 měsíci

+ 5 - 7
src/components/EchartsCommon/barChart.tsx

@@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react';
 import * as echarts from 'echarts';
 
 interface propsData {
-  xData: string[];
+  seriesData: string[];
   yData: string[];
   color: string;
   width: string;
@@ -11,11 +11,10 @@ interface propsData {
 
 const LineChart: React.FC<propsData> = (props) => {
   const chartRef: any = useRef();
-  const { xData, yData, color, width, height } = props;
+  const { yData, seriesData, color, width, height } = props;
 
   // 初始化
   useEffect(() => {
-    console.log(xData, yData);
     const chart = echarts.init(chartRef.current);
     const options = {
       legend: {
@@ -39,7 +38,6 @@ const LineChart: React.FC<propsData> = (props) => {
         axisTick: {
           show: false,
         },
-
         axisLabel: {
           //  改变x轴字体颜色和大小
           textStyle: {
@@ -50,7 +48,7 @@ const LineChart: React.FC<propsData> = (props) => {
       },
       yAxis: {
         type: 'category',
-        data: ['响水', '滨海', '滨海', '东海', '徐州', '响水'],
+        data: yData,
         splitLine: {
           show: false,
         },
@@ -74,7 +72,7 @@ const LineChart: React.FC<propsData> = (props) => {
         {
           type: 'bar',
           name: '产出',
-          barWidth: 15,
+          barWidth: 22,
           itemStyle: {
             normal: {
               label: {
@@ -91,7 +89,7 @@ const LineChart: React.FC<propsData> = (props) => {
               barBorderRadius: 15,
             },
           },
-          data: [19, 29, 39, 81, 29, 39],
+          data: seriesData,
         },
       ],
     };

+ 4 - 4
src/components/EchartsCommon/lineChart.tsx

@@ -15,7 +15,6 @@ const LineChart: React.FC<propsData> = (props) => {
 
   // 初始化
   useEffect(() => {
-    console.log(xData, yData);
     const chart = echarts.init(chartRef.current);
     const options = {
       legend: {
@@ -34,7 +33,7 @@ const LineChart: React.FC<propsData> = (props) => {
       xAxis: [
         {
           type: 'category',
-          data: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
+          data: xData,
           axisLine: {
             lineStyle: {
               color: '#ddd',
@@ -44,6 +43,7 @@ const LineChart: React.FC<propsData> = (props) => {
             show: false,
           },
           axisLabel: {
+            rotate: 45,
             interval: 0,
             textStyle: {
               color: '#333',
@@ -76,9 +76,9 @@ const LineChart: React.FC<propsData> = (props) => {
       ],
       series: [
         {
-          name: 'S',
+          name: '',
           type: 'line',
-          data: [13, 10, 3, 12, 15, 30, 7],
+          data: yData,
           symbolSize: 6,
           symbol: 'circle',
           smooth: true,

+ 1 - 0
src/pages/Welcome.less

@@ -47,6 +47,7 @@
   }
   .dataItemValue {
     margin-top: 20px;
+    margin-right: 5px;
     font-weight: bold;
     font-size: 30px;
   }

+ 155 - 29
src/pages/Welcome.tsx

@@ -1,8 +1,13 @@
 import { PageContainer } from '@ant-design/pro-components';
-import { Button, Card, Col, DatePicker, Form, Row, Space } from 'antd';
+import { Button, Card, Col, DatePicker, Form, Row, Space, Spin } from 'antd';
 import React, { useEffect, useRef, useState } from 'react';
 import styles from './Welcome.less';
-import { getStatisticData } from '@/services/statistic';
+import {
+  getAppUserData,
+  getDailyActiveData,
+  getNewUserData,
+  getStatisticData,
+} from '@/services/statistic';
 import { ReloadOutlined, SearchOutlined } from '@ant-design/icons';
 import moment from 'moment/moment';
 import * as echarts from 'echarts';
@@ -23,16 +28,42 @@ const Welcome: React.FC = () => {
   const [form] = Form.useForm();
   const [data, setData] = useState<any>(null);
   const [searchData, setSearchData] = useState<object | null>({});
+  const [userData, setUserData] = useState<any>(null);
+  const [appUserData, setAppUserData] = useState<any>(null);
+  const [dailyActiveData, setDailyActiveData] = useState<any>(null);
+  const [deviceTypeData, setDeviceType] = useState<any>(null);
   const chartRef: any = useRef();
 
   // 获取数据
-  const getList = () => {
+  const getDeviceData = () => {
     const params = {
       ...searchData,
     };
     getStatisticData(params).then((res) => {
       if (res && res.code === 0) {
         setData(res.data);
+        // 设备类型统计数据
+        if (
+          res.data &&
+          res.data.ffx &&
+          res.data.wuheng &&
+          res.data.xfcs &&
+          res.data.xfjh &&
+          res.data.xfjs
+        ) {
+          const deviceName = ['分风箱', '五恒一体机', '新风除湿', '新风净化', '新风加湿'];
+          const deviceTypeValue = [
+            res.data.ffx,
+            res.data.wuheng,
+            res.data.xfcs,
+            res.data.xfjh,
+            res.data.xfjs,
+          ];
+          setDeviceType({ deviceName, deviceTypeValue });
+        } else {
+          setDeviceType(null);
+        }
+        // 渲染环形图
         const chart = echarts.init(chartRef.current);
         const region = JSON.parse(res.data.region);
         const newData = Object.entries(region).map(([name, value]) => ({ value, name }));
@@ -98,13 +129,56 @@ const Welcome: React.FC = () => {
     });
   };
 
+  // 新增用户数统计
+  const getUserData = () => {
+    getNewUserData().then((res) => {
+      if (res && res.code === 0) {
+        setUserData(res.data);
+      }
+    });
+  };
+
+  // app使用次数统计
+  const getAppCount = () => {
+    getAppUserData().then((res) => {
+      if (res && res.code === 0) {
+        setAppUserData(res.data);
+      }
+    });
+  };
+
+  // 获取日活用户统计数据
+  const getDailyActiveUser = () => {
+    getDailyActiveData().then((res) => {
+      if (res && res.code === 0) {
+        const list = res.data || [];
+        if (list && list.length > 0) {
+          // 把x轴的数据和y轴的数据进行匹配
+          const xData = list.map(
+            (el: { date: string }) => moment(el.date).format('MM-DD') || '暂无',
+          );
+          const yData = list.map((el: { dau: number }) => el.dau);
+          setDailyActiveData({ xData, yData });
+        } else {
+          setDailyActiveData(null);
+        }
+      }
+    });
+  };
+
   // 初始化
   useEffect(() => {
-    getList();
+    getDeviceData();
+    // 用户数据
+    getUserData();
+    // app使用次数统计
+    getAppCount();
+    // 获取日活用户统计
+    getDailyActiveUser();
   }, []);
 
   useEffect(() => {
-    getList();
+    getDeviceData();
   }, [searchData]);
 
   //  搜索
@@ -125,12 +199,12 @@ const Welcome: React.FC = () => {
   };
 
   // 千分号格式化
-  // const formatNumber = (num: any) => {
-  //   if (num === null || num === undefined || isNaN(num)) return '';
-  //   return parseFloat(num).toLocaleString(undefined, {
-  //     maximumFractionDigits: 20,
-  //   });
-  // };
+  const formatNumber = (num: any) => {
+    if (num === null || num === undefined || isNaN(num)) return '';
+    return parseFloat(num).toLocaleString(undefined, {
+      maximumFractionDigits: 20,
+    });
+  };
 
   return (
     <PageContainer>
@@ -163,7 +237,7 @@ const Welcome: React.FC = () => {
               <Card className={styles.dataItem} bordered={false}>
                 <div className={styles.dataTitle}>设备总数</div>
                 <div className={styles.dataValue}>
-                  <span className={styles.dataNum}>{data?.total}</span>
+                  <span className={styles.dataNum}>{data?.total || 0}</span>
                   <span style={{ color: 'gray' }}>台</span>
                 </div>
               </Card>
@@ -172,7 +246,7 @@ const Welcome: React.FC = () => {
               <Card className={styles.dataItem} bordered={false}>
                 <div className={styles.dataTitle}>总在线数</div>
                 <div className={styles.dataValue}>
-                  <span className={styles.dataNum}>{data?.online}</span>
+                  <span className={styles.dataNum}>{data?.online || 0}</span>
                   <span style={{ color: 'gray' }}>台</span>
                 </div>
               </Card>
@@ -181,7 +255,7 @@ const Welcome: React.FC = () => {
               <Card className={styles.dataItem} bordered={false}>
                 <div className={styles.dataTitle}>五恒在线数</div>
                 <div className={styles.dataValue}>
-                  <span className={styles.dataNum}>{data?.wuheng_online}</span>
+                  <span className={styles.dataNum}>{data?.wuheng_online || 0}</span>
                   <span style={{ color: 'gray' }}>台</span>
                 </div>
               </Card>
@@ -190,7 +264,7 @@ const Welcome: React.FC = () => {
               <Card className={styles.dataItem} bordered={false}>
                 <div className={styles.dataTitle}>激活五恒数</div>
                 <div className={styles.dataValue}>
-                  <span className={styles.dataNum}>{data?.wuheng}</span>
+                  <span className={styles.dataNum}>{data?.wuheng || 0}</span>
                   <span style={{ color: 'gray' }}>台</span>
                 </div>
               </Card>
@@ -199,7 +273,7 @@ const Welcome: React.FC = () => {
               <Card className={styles.dataItem} bordered={false}>
                 <div className={styles.dataTitle}>分风箱在线数</div>
                 <div className={styles.dataValue}>
-                  <span className={styles.dataNum}>{data?.ffx_online}</span>
+                  <span className={styles.dataNum}>{data?.ffx_online || 0}</span>
                   <span style={{ color: 'gray' }}>台</span>
                 </div>
               </Card>
@@ -212,12 +286,19 @@ const Welcome: React.FC = () => {
         <Col span={16}>
           <div>
             <Row gutter={[20, 20]}>
-              <Col span={6}>
+              <Col flex="1">
                 <Card hoverable>
                   <div className={styles.userDataItem}>
                     <div>
                       <div className={styles.dataItemTitle}>用户数</div>
-                      <div className={styles.dataItemValue}>222</div>
+                      <div>
+                        <span className={styles.dataItemValue}>
+                          {userData?.total && userData?.total.length > 3
+                            ? formatNumber(userData?.total)
+                            : userData?.total || 0}
+                        </span>
+                        <span style={{ color: 'gray' }}>人</span>
+                      </div>
                     </div>
                     <div className={styles.dataItemIcon}>
                       <img src={userIcon} alt="用户icon" />
@@ -225,12 +306,15 @@ const Welcome: React.FC = () => {
                   </div>
                 </Card>
               </Col>
-              <Col span={6}>
+              <Col flex="1">
                 <Card hoverable>
                   <div className={styles.userDataItem}>
                     <div>
-                      <div className={styles.dataItemTitle}>今日新增</div>
-                      <div className={styles.dataItemValue}>222</div>
+                      <div className={styles.dataItemTitle}>今日新增用户数</div>
+                      <div>
+                        <span className={styles.dataItemValue}>{userData?.tnu || 0}</span>
+                        <span style={{ color: 'gray' }}>人</span>
+                      </div>
                     </div>
                     <div className={styles.dataItemIcon}>
                       <img src={todayIcon} alt="今日新增icon" />
@@ -238,12 +322,15 @@ const Welcome: React.FC = () => {
                   </div>
                 </Card>
               </Col>
-              <Col span={6}>
+              <Col flex="1">
                 <Card hoverable>
                   <div className={styles.userDataItem}>
                     <div>
-                      <div className={styles.dataItemTitle}>本月新增</div>
-                      <div className={styles.dataItemValue}>222</div>
+                      <div className={styles.dataItemTitle}>本月新增用户数</div>
+                      <div>
+                        <span className={styles.dataItemValue}>{userData?.mnu || 0}</span>
+                        <span style={{ color: 'gray' }}>人</span>
+                      </div>
                     </div>
                     <div className={styles.dataItemIcon}>
                       <img src={monthIcon} alt="本月新增icon" />
@@ -251,12 +338,31 @@ const Welcome: React.FC = () => {
                   </div>
                 </Card>
               </Col>
-              <Col span={6}>
+              <Col flex="1">
+                <Card hoverable>
+                  <div className={styles.userDataItem}>
+                    <div>
+                      <div className={styles.dataItemTitle}>今日App使用次数</div>
+                      <div>
+                        <span className={styles.dataItemValue}>{appUserData?.total || 0}</span>
+                        <span style={{ color: 'gray' }}>次</span>
+                      </div>
+                    </div>
+                    <div className={styles.dataItemIcon}>
+                      <img src={appIcon} alt="App统计次数icon" />
+                    </div>
+                  </div>
+                </Card>
+              </Col>
+              <Col flex="1">
                 <Card hoverable>
                   <div className={styles.userDataItem}>
                     <div>
-                      <div className={styles.dataItemTitle}>App统计次数</div>
-                      <div className={styles.dataItemValue}>222</div>
+                      <div className={styles.dataItemTitle}>本月日均使用APP次数</div>
+                      <div>
+                        <span className={styles.dataItemValue}>{appUserData?.month_avg || 0}</span>
+                        <span style={{ color: 'gray' }}>次</span>
+                      </div>
                     </div>
                     <div className={styles.dataItemIcon}>
                       <img src={appIcon} alt="App统计次数icon" />
@@ -269,13 +375,33 @@ const Welcome: React.FC = () => {
               <Col span={12}>
                 <Card hoverable>
                   <div style={{ marginBottom: '20px', fontWeight: 'bold' }}>日活用户统计</div>
-                  <LineChart color="#1890ff" height="450px" width="700px" xData={[]} yData={[]} />
+                  {dailyActiveData && dailyActiveData.xData && dailyActiveData.yData ? (
+                    <LineChart
+                      color="#1890ff"
+                      height="450px"
+                      width="700px"
+                      xData={dailyActiveData?.xData}
+                      yData={dailyActiveData?.yData}
+                    />
+                  ) : (
+                    <Spin />
+                  )}
                 </Card>
               </Col>
               <Col span={12}>
                 <Card hoverable>
                   <div style={{ marginBottom: '20px', fontWeight: 'bold' }}>设备类型统计</div>
-                  <BarChart color="#1890ff" height="450px" width="700px" xData={[]} yData={[]} />
+                  {deviceTypeData && deviceTypeData.deviceName && deviceTypeData.deviceTypeValue ? (
+                    <BarChart
+                      color="#1890ff"
+                      height="450px"
+                      width="700px"
+                      seriesData={deviceTypeData?.deviceTypeValue}
+                      yData={deviceTypeData?.deviceName}
+                    />
+                  ) : (
+                    <Spin />
+                  )}
                 </Card>
               </Col>
             </Row>

+ 21 - 0
src/services/statistic.ts

@@ -7,3 +7,24 @@ import { stringify } from 'qs';
 export async function getStatisticData(params: any) {
   return request(`/web/v1/statistic/dev_online?${stringify(params)}`);
 }
+
+/**
+ * 获取用户数据
+ */
+export async function getNewUserData() {
+  return request(`/web/v1/statistic/new_user_statistic`);
+}
+
+/**
+ * 获取App使用次数数据
+ */
+export async function getAppUserData() {
+  return request(`/web/v1/statistic/app_user_count`);
+}
+
+/**
+ * 获取日活跃用户数据
+ */
+export async function getDailyActiveData() {
+  return request(`/web/v1/statistic/daily_active_users`);
+}