Bläddra i källkod

后台新增首页数据统计

xiaoshushu 3 år sedan
förälder
incheckning
3728504533

+ 18 - 4
smart-admin/src/main/java/com/huijy/web/controller/monitor/ServerController.java

@@ -1,5 +1,7 @@
 package com.huijy.web.controller.monitor;
 
+import com.huijy.management.service.IContentService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -14,14 +16,26 @@ import com.huijy.framework.web.domain.Server;
  */
 @RestController
 @RequestMapping("/monitor/server")
-public class ServerController
-{
+public class ServerController {
+
+    @Autowired
+    private IContentService contentService;
+
     @PreAuthorize("@ss.hasPermi('monitor:server:list')")
     @GetMapping()
-    public AjaxResult getInfo() throws Exception
-    {
+    public AjaxResult getInfo() throws Exception {
         Server server = new Server();
         server.copyTo();
         return AjaxResult.success(server);
     }
+
+    /**
+     * 后台UI首页数据统计
+     *
+     * @return
+     */
+    @GetMapping(value = "/home")
+    public AjaxResult home() {
+        return AjaxResult.success(contentService.home());
+    }
 }

+ 6 - 0
smart-system/src/main/java/com/huijy/management/mapper/ContentMapper.java

@@ -1,6 +1,8 @@
 package com.huijy.management.mapper;
 
 import java.util.List;
+import java.util.Map;
+
 import com.huijy.management.domain.Content;
 
 /**
@@ -65,4 +67,8 @@ public interface ContentMapper
      * @return
      */
     public Integer updateBrowseNumById(Long contentId);
+
+    public List<Map<String, Object>> home();
+
+
 }

+ 4 - 0
smart-system/src/main/java/com/huijy/management/service/IContentService.java

@@ -1,6 +1,8 @@
 package com.huijy.management.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.huijy.management.domain.Content;
 
 /**
@@ -62,4 +64,6 @@ public interface IContentService
     Integer updateAudit(Long contentId,String auditFlag,String auditMsg,Long adminId);
 
     Integer updateRelease(Long contentId,String releaseFlag,Long adminId);
+
+    public List<Map<String, Object>> home();
 }

+ 6 - 0
smart-system/src/main/java/com/huijy/management/service/impl/ContentServiceImpl.java

@@ -2,6 +2,7 @@ package com.huijy.management.service.impl;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 import com.huijy.common.exception.ServiceException;
 import com.huijy.common.utils.DateUtils;
@@ -155,4 +156,9 @@ public class ContentServiceImpl implements IContentService
         }
         return   updateContent(content);
     }
+
+    @Override
+    public List<Map<String, Object>> home() {
+        return contentMapper.home();
+    }
 }

+ 29 - 0
smart-system/src/main/resources/mapper/management/ContentMapper.xml

@@ -137,4 +137,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <update id="updateBrowseNumById" parameterType="Long">
         update t_content t set t.browse_num = t.browse_num+1 where t.content_id = #{contentId}
     </update>
+
+    <!--后台UI首页数据统计-->
+    <select id="home" resultType="java.util.Map">
+    SELECT a.date,ifnull(b.count,0) as wx,ifnull(c.count,0) as member,
+    (SELECT COUNT(*) FROM t_content WHERE service_info=1 )AS content1,
+    (SELECT COUNT(*) FROM t_content WHERE service_info=2 )AS content2,
+    (SELECT COUNT(*) FROM t_content WHERE service_info=3 )AS content3,
+    (SELECT COUNT(*) FROM t_content WHERE service_info=4 )AS content4,
+    (SELECT COUNT(*) FROM wx_user)AS wxs,
+    (SELECT COUNT(*) FROM t_member)AS members
+    FROM (
+    SELECT curdate()AS date
+    union all
+    SELECT date_sub(curdate(), interval 1 day) AS date
+    union all
+    SELECT date_sub(curdate(), interval 2 day) AS date
+    union all
+    SELECT date_sub(curdate(), interval 3 day) AS date
+    union all
+    SELECT date_sub(curdate(), interval 4 day) AS date
+    union all
+    SELECT date_sub(curdate(), interval 5 day) AS date
+    union all
+    SELECT date_sub(curdate(), interval 6 day) AS date) a
+    LEFT JOIN (SELECT date(u.create_time) AS datetime, count(*) AS count FROM wx_user u GROUP BY date(u.create_time)) b ON a.date = b.datetime
+    LEFT JOIN (SELECT date(u.register_time) AS datetime, count(*) AS count FROM t_member u GROUP BY date(u.register_time)) c ON a.date = c.datetime
+    ORDER BY a.date ASC
+    </select>
+
 </mapper>

+ 7 - 0
smart-ui/src/api/monitor/server.js

@@ -6,4 +6,11 @@ export function getServer() {
     url: '/monitor/server',
     method: 'get'
   })
+}
+// 后台UI首页数据统计
+export function home() {
+  return request({
+    url: '/monitor/server/home',
+    method: 'get'
+  })
 }

BIN
smart-ui/src/assets/images/app.jpg


BIN
smart-ui/src/assets/images/pc.jpg


+ 99 - 61
smart-ui/src/views/dashboard/LineChart.vue

@@ -1,11 +1,11 @@
 <template>
-  <div :class="className" :style="{height:height,width:width}" />
+  <div :class="className" :style="{ height: height, width: width }" />
 </template>
 
 <script>
-import echarts from 'echarts'
-require('echarts/theme/macarons') // echarts theme
-import resize from './mixins/resize'
+import echarts from 'echarts';
+require('echarts/theme/macarons'); // echarts theme
+import resize from './mixins/resize';
 
 export default {
   mixins: [resize],
@@ -20,61 +20,88 @@ export default {
     },
     height: {
       type: String,
-      default: '350px'
+      default: '300px'
     },
     autoResize: {
       type: Boolean,
       default: true
     },
     chartData: {
-      type: Object,
+      type: Array,
       required: true
     }
   },
   data() {
     return {
       chart: null
-    }
+    };
   },
   watch: {
     chartData: {
       deep: true,
       handler(val) {
-        this.setOptions(val)
+        this.setOptions(val);
       }
     }
   },
   mounted() {
     this.$nextTick(() => {
-      this.initChart()
-    })
+      this.initChart();
+    });
   },
   beforeDestroy() {
     if (!this.chart) {
-      return
+      return;
     }
-    this.chart.dispose()
-    this.chart = null
+    this.chart.dispose();
+    this.chart = null;
   },
   methods: {
     initChart() {
-      this.chart = echarts.init(this.$el, 'macarons')
-      this.setOptions(this.chartData)
+      this.chart = echarts.init(this.$el, 'macarons');
+      this.setOptions(this.chartData);
     },
-    setOptions({ expectedData, actualData } = {}) {
+    setOptions(chartData) {
+      let xAxis = [];
+      let data1 = [];
+      let data2 = [];
+      if (chartData) {
+        chartData.forEach((item, index) => {
+          if (index - chartData.length == -1) {
+            xAxis.push('今天');
+          } else {
+            xAxis.push(item.date.substring(5, 10));
+          }
+          data1.push({ value: item.wx, name: item.date });
+          data2.push({ value: item.member, name: item.date });
+        });
+      }
       this.chart.setOption({
+        title: {
+          text: '近7天注册人数',
+          padding: 3
+        },
+        legend: {
+          icon: 'roundRect',
+          data: ['微信公众号', '小程序'],
+          textStyle: {
+            fontSize: 15
+          }
+        },
         xAxis: {
-          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+          type: 'category',
+          data: xAxis,
           boundaryGap: false,
-          axisTick: {
-            show: false
+          axisLabel: {
+            margin: 16,
+            fontSize: 15
           }
         },
         grid: {
           left: 10,
-          right: 10,
-          bottom: 20,
-          top: 30,
+          right: 20,
+          bottom: 0,
+          top: 75,
           containLabel: true
         },
         tooltip: {
@@ -85,51 +112,62 @@ export default {
           padding: [5, 10]
         },
         yAxis: {
-          axisTick: {
-            show: false
+          type: 'value',
+          minInterval: 1,
+          axisLabel: {
+            fontSize: 15
           }
         },
-        legend: {
-          data: ['expected', 'actual']
-        },
-        series: [{
-          name: 'expected', itemStyle: {
-            normal: {
-              color: '#FF005A',
-              lineStyle: {
+        series: [
+          {
+            name: '微信公众号',
+            itemStyle: {
+              normal: {
                 color: '#FF005A',
-                width: 2
+                lineStyle: {
+                  color: '#FF005A',
+                  width: 3
+                },
+                areaStyle: {
+                  color: '#FF5722'
+                }
               }
-            }
+            },
+            smooth: true,
+            type: 'line',
+            data: data1,
+            markPoint: {
+              data: [{ type: 'max', name: '最大值' }, { type: 'min', name: '最小值' }]
+            },
+            animationDuration: 2800,
+            animationEasing: 'cubicInOut'
           },
-          smooth: true,
-          type: 'line',
-          data: expectedData,
-          animationDuration: 2800,
-          animationEasing: 'cubicInOut'
-        },
-        {
-          name: 'actual',
-          smooth: true,
-          type: 'line',
-          itemStyle: {
-            normal: {
-              color: '#3888fa',
-              lineStyle: {
-                color: '#3888fa',
-                width: 2
-              },
-              areaStyle: {
-                color: '#f3f8ff'
+          {
+            name: '小程序',
+            itemStyle: {
+              normal: {
+                color: '#5f79ca',
+                lineStyle: {
+                  color: '#5f79ca',
+                  width: 3
+                },
+                areaStyle: {
+                  color: '#8da2e4'
+                }
               }
-            }
-          },
-          data: actualData,
-          animationDuration: 2800,
-          animationEasing: 'quadraticOut'
-        }]
-      })
+            },
+            smooth: true,
+            type: 'line',
+            data: data2,
+            markPoint: {
+              data: [{ type: 'max', name: '最大值' }, { type: 'min', name: '最小值' }]
+            },
+            animationDuration: 2800,
+            animationEasing: 'cubicInOut'
+          }
+        ]
+      });
     }
   }
-}
+};
 </script>

+ 52 - 102
smart-ui/src/views/dashboard/PanelGroup.vue

@@ -1,84 +1,77 @@
 <template>
   <el-row :gutter="40" class="panel-group">
     <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('newVisitis')">
-        <div class="card-panel-icon-wrapper icon-people">
-          <svg-icon icon-class="peoples" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            访客
+      <router-link :to="'/exam/user'">
+        <div class="card-panel">
+          <div class="card-panel-icon-wrapper icon-people"><svg-icon icon-class="star" class-name="card-panel-icon" style="color: red;" /></div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">党政服务</div>
+            <count-to :start-val="0" :end-val="cdata.content1" class="card-panel-num" />
           </div>
-          <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
         </div>
-      </div>
+      </router-link>
     </el-col>
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('messages')">
-        <div class="card-panel-icon-wrapper icon-message">
-          <svg-icon icon-class="message" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            消息
+    <router-link :to="'/exam/subject'">
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <div class="card-panel">
+          <div class="card-panel-icon-wrapper icon-message"><svg-icon icon-class="international" class-name="card-panel-icon" style="color: #36a3f7;" /></div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">景区介绍</div>
+            <count-to :start-val="0" :end-val="cdata.content2" class="card-panel-num" />
           </div>
-          <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
-        </div>
-      </div>
-    </el-col>
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('purchases')">
-        <div class="card-panel-icon-wrapper icon-money">
-          <svg-icon icon-class="money" class-name="card-panel-icon" />
         </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            金额
+      </el-col>
+    </router-link>
+    <router-link :to="'/exam/test'">
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <div class="card-panel">
+          <div class="card-panel-icon-wrapper icon-money"><svg-icon icon-class="skill" class-name="card-panel-icon" style="color: #607D8B;" /></div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">旅游攻略</div>
+            <count-to :start-val="0" :end-val="cdata.content3" class="card-panel-num" />
           </div>
-          <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
         </div>
-      </div>
-    </el-col>
-    <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
-      <div class="card-panel" @click="handleSetLineChartData('shoppings')">
-        <div class="card-panel-icon-wrapper icon-shopping">
-          <svg-icon icon-class="shopping" class-name="card-panel-icon" />
-        </div>
-        <div class="card-panel-description">
-          <div class="card-panel-text">
-            订单
+      </el-col>
+    </router-link>
+    <router-link :to="'/exam/notice'">
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <div class="card-panel">
+          <div class="card-panel-icon-wrapper icon-shopping"><svg-icon icon-class="form" class-name="card-panel-icon" style="color: #40c9c6;" /></div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">热门活动</div>
+            <count-to :start-val="0" :end-val="cdata.content4" class="card-panel-num" />
           </div>
-          <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
         </div>
-      </div>
-    </el-col>
+      </el-col>
+    </router-link>
   </el-row>
 </template>
 
 <script>
-import CountTo from 'vue-count-to'
+import CountTo from 'vue-count-to';
 
 export default {
   components: {
     CountTo
   },
+  props: {
+    cdata: {
+      type: Object,
+      required: true
+    }
+  },
   methods: {
     handleSetLineChartData(type) {
-      this.$emit('handleSetLineChartData', type)
+      this.$emit('handleSetLineChartData', type);
     }
   }
-}
+};
 </script>
 
 <style lang="scss" scoped>
 .panel-group {
-  margin-top: 18px;
-
-  .card-panel-col {
-    margin-bottom: 32px;
-  }
-
   .card-panel {
+    border-radius: 5px;
     height: 108px;
     cursor: pointer;
     font-size: 12px;
@@ -86,91 +79,48 @@ export default {
     overflow: hidden;
     color: #666;
     background: #fff;
-    box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
-    border-color: rgba(0, 0, 0, .05);
-
-    &:hover {
-      .card-panel-icon-wrapper {
-        color: #fff;
-      }
-
-      .icon-people {
-        background: #40c9c6;
-      }
-
-      .icon-message {
-        background: #36a3f7;
-      }
-
-      .icon-money {
-        background: #f4516c;
-      }
-
-      .icon-shopping {
-        background: #34bfa3
-      }
-    }
-
-    .icon-people {
-      color: #40c9c6;
-    }
-
-    .icon-message {
-      color: #36a3f7;
-    }
-
-    .icon-money {
-      color: #f4516c;
-    }
-
-    .icon-shopping {
-      color: #34bfa3
-    }
-
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
+    border-color: rgba(0, 0, 0, 0.05);
     .card-panel-icon-wrapper {
       float: left;
       margin: 14px 0 0 14px;
       padding: 16px;
       transition: all 0.38s ease-out;
-      border-radius: 6px;
+      border-radius: 8px;
+      //background-color: aliceblue;
     }
-
     .card-panel-icon {
       float: left;
-      font-size: 48px;
+      font-size: 57px;
     }
-
     .card-panel-description {
       float: right;
       font-weight: bold;
       margin: 26px;
       margin-left: 0px;
-
+      text-align: center;
       .card-panel-text {
         line-height: 18px;
         color: rgba(0, 0, 0, 0.45);
         font-size: 16px;
         margin-bottom: 12px;
       }
-
       .card-panel-num {
-        font-size: 20px;
+        font-size: 22px;
       }
     }
   }
 }
 
-@media (max-width:550px) {
+@media (max-width: 550px) {
   .card-panel-description {
     display: none;
   }
-
   .card-panel-icon-wrapper {
     float: none !important;
     width: 100%;
     height: 100%;
     margin: 0 !important;
-
     .svg-icon {
       display: block;
       margin: 14px auto !important;

+ 91 - 27
smart-ui/src/views/index.vue

@@ -1,43 +1,107 @@
 <template>
-  <div class="app-container">
-    
+  <div class="dashboard-editor-container" v-loading="loading">
+    <!--天气-->
+    <iframe
+      allowtransparency="true"
+      frameborder="0"
+      width="565"
+      height="98"
+      scrolling="no"
+      src="//tianqi.2345.com/plugin/widget/index.htm?s=1&z=1&t=1&v=0&d=3&bd=0&k=000000&f=&ltf=009944&htf=cc0000&q=0&e=0&a=1&c=54511&w=565&h=98&align=center"
+    ></iframe>
+    <!--天气end-->
+    <panel-group :cdata="data[0]" />
+    <el-row>
+      <div class="chart-wrapper"><line-chart :chart-data="data" /></div>
+    </el-row>
+    <el-row :gutter="32">
+      <el-col :span="8">
+        <div class="chart-wrapper">
+          <a class="pop" href="https://xdmly.qiyiiot.com/pc/" target="_blank" title="点击跳转到大屏数据展示">
+            <div class="lab">大屏数据展示</div>
+            <img :src="pc" />
+          </a>
+        </div>
+      </el-col>
+      <el-col :span="8">
+        <div class="chart-wrapper">
+          <a class="pop" href="https://mp.weixin.qq.com/" target="_blank" title="点击跳转到微信公众号后台">
+            <div class="lab">微信公众号({{ data[0].wxs }}人关注过)</div>
+            <img :src="app" />
+          </a>
+        </div>
+      </el-col>
+      <el-col :span="8">
+        <div class="chart-wrapper">
+          <a class="pop" href="https://mp.weixin.qq.com/" target="_blank" title="点击跳转到小程序后台">
+            <div class="lab">小程序({{ data[0].members }}人使用过)</div>
+            <img :src="app" />
+          </a>
+        </div>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
 <script>
-// import { getServer } from "@/api/monitor/server";
-
+import PanelGroup from './dashboard/PanelGroup';
+import LineChart from './dashboard/LineChart';
+import { home } from '@/api/monitor/server';
+import app from '@/assets/images/app.jpg';
+import pc from '@/assets/images/pc.jpg';
 export default {
-  name: "Server",
+  name: 'Index',
+  components: {
+    PanelGroup,
+    LineChart
+  },
   data() {
     return {
-      // 加载层信息
-      loading: [],
-      // 服务器信息
-      server: []
+      loading: true,
+      data: [{}],
+      app: app,
+      pc: pc
     };
   },
   created() {
-    // this.getList();
-    // this.openLoading();
+    home().then(res => {
+      this.data = res.data;
+      this.loading = false;
+    });
   },
   methods: {
-    /** 查询服务器信息 */
-    getList() {
-      getServer().then(response => {
-        this.server = response.data;
-        this.loading.close();
-      });
-    },
-    // 打开加载层
-    openLoading() {
-      this.loading = this.$loading({
-        lock: true,
-        text: "拼命读取中",
-        spinner: "el-icon-loading",
-        background: "rgba(0, 0, 0, 0.7)"
-      });
+    handleSetLineChartData(type) {
+      this.lineChartData = lineChartData[type];
     }
   }
 };
-</script>
+</script>
+
+<style lang="scss">
+.dashboard-editor-container {
+  padding: 0px 22px 20px 22px;
+  .chart-wrapper {
+    background: #fff;
+    padding: 16px;
+    margin-top: 25px;
+    border-radius: 7px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
+    text-align: center;
+    overflow: hidden;
+    .pop {
+      cursor: pointer;
+      .lab {
+        font-weight: bold;
+        font-size: 17px;
+        padding-bottom: 15px;
+        color: #0d90d0;
+      }
+      img {
+        margin: 0 auto;
+        height: 200px;
+        border-radius: 5px;
+      }
+    }
+  }
+}
+</style>