Преглед на файлове

Merge remote-tracking branch 'origin/master'

zhoupeng преди 2 години
родител
ревизия
ece3dcd3b5

+ 8 - 0
chuanyi-admin/src/api/dashboard.js

@@ -16,6 +16,14 @@ export function getCustomerUserNum() {
   })
 }
 
+/** 查询客户端在线用户数量 */
+export function getOnlineUser(loginType) {
+  return request({
+    url: '/user/getOnlineUser?loginType=' + loginType,
+    method: 'get'
+  })
+}
+
 /** 查询角色数量 */
 export function getRoleNum() {
   return request({

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
chuanyi-admin/src/icons/svg/user-manger.svg


+ 1 - 0
chuanyi-admin/src/icons/svg/user-online.svg

@@ -0,0 +1 @@
+<svg t="1680592211773" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21929" width="64" height="64"><path d="M697.856 322.56A185.856 185.856 0 1 0 386.048 460.8a279.552 279.552 0 0 0-191.488 256 35.328 35.328 0 1 0 71.168 0c0-110.592 102.4-200.192 235.52-204.8h25.6a229.888 229.888 0 0 1 124.416 34.816l8.192 5.632a198.656 198.656 0 0 1 99.328 165.376 35.328 35.328 0 0 0 71.168 0 269.312 269.312 0 0 0-134.144-231.424h-2.56a227.328 227.328 0 0 0-51.2-27.648 184.832 184.832 0 0 0 55.808-136.192zM512 226.304A96.256 96.256 0 1 1 415.744 322.56 96.256 96.256 0 0 1 512 226.304z" fill="#438CFF" p-id="21930"></path><path d="M884.224 16.384H824.32a38.4 38.4 0 0 0 0 76.8h59.904a64 64 0 0 1 64 63.488v581.12a64 64 0 0 1-64 63.488H139.776a64 64 0 0 1-64-63.488V156.672a64 64 0 0 1 64-63.488h488.448a38.4 38.4 0 0 0 0-76.8H139.776A140.8 140.8 0 0 0 0 156.672v581.12a140.8 140.8 0 0 0 140.8 140.288h332.8v51.2H303.616a38.4 38.4 0 0 0 0 76.8h417.792a38.4 38.4 0 1 0 0-76.8h-171.008v-51.2h333.824A140.8 140.8 0 0 0 1024 737.792V156.672A140.8 140.8 0 0 0 884.224 16.384z" fill="#438CFF" p-id="21931"></path></svg>

+ 1 - 0
chuanyi-admin/src/icons/svg/user-role.svg

@@ -0,0 +1 @@
+<svg t="1680592022584" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14645" width="64" height="64"><path d="M492.5 384H318.1c-10.8 0-19.5-8.7-19.5-19.5v-3.7c0-10.8 8.7-19.5 19.5-19.5h174.4c10.8 0 19.5 8.7 19.5 19.5v3.7c0 10.8-8.7 19.5-19.5 19.5zM492.5 512H318.1c-10.8 0-19.5-8.7-19.5-19.5v-3.7c0-10.8 8.7-19.5 19.5-19.5h174.4c10.8 0 19.5 8.7 19.5 19.5v3.7c0 10.8-8.7 19.5-19.5 19.5zM492.5 640H318.1c-10.8 0-19.5-8.7-19.5-19.5v-3.7c0-10.8 8.7-19.5 19.5-19.5h174.4c10.8 0 19.5 8.7 19.5 19.5v3.7c0 10.8-8.7 19.5-19.5 19.5z" fill="#A9D8FF" p-id="14646"></path><path d="M704 429m-83 0a83 83 0 1 0 166 0 83 83 0 1 0-166 0Z" fill="#298DF7" p-id="14647"></path><path d="M806.1 677.9H601.9c-26 0-47.2-21.2-47.2-47.2 0-47 38.5-85.5 85.5-85.5h127.6c47 0 85.5 38.5 85.5 85.5 0 26-21.2 47.2-47.2 47.2z" fill="#298DF7" p-id="14648"></path><path d="M704 256c11.9 0 21.3-9.4 21.3-21.3v-21.3c0-46.9-38.4-85.3-85.3-85.3H256c-46.9 0-85.3 38.4-85.3 85.3v597.3c0 46.9 38.4 85.3 85.3 85.3h384c46.9 0 85.3-38.4 85.3-85.3v-21.3c0-11.9-9.4-21.3-21.3-21.3s-21.3 9.4-21.3 21.3v21.3c0 23.5-19.2 42.7-42.7 42.7H256c-23.5 0-42.7-19.2-42.7-42.7V213.3c0-23.5 19.2-42.7 42.7-42.7h384c23.5 0 42.7 19.2 42.7 42.7v21.3c0 12 9.4 21.4 21.3 21.4z" fill="#3C99FE" p-id="14649"></path><path d="M704 213.3c-11.9 0-21.3 9.4-21.3 21.3s9.4 21.3 21.3 21.3 21.3-9.4 21.3-21.3-9.4-21.3-21.3-21.3z" fill="#3C99FE" p-id="14650"></path></svg>

+ 1 - 0
chuanyi-admin/src/icons/svg/user-t.svg

@@ -0,0 +1 @@
+<svg t="1680591971888" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12617" width="64" height="64"><path d="M481.1 190c30.3 0 58.8 11.8 80.3 33.3 21.4 21.4 33.3 50 33.3 80.3v15c0 30.3-11.8 58.8-33.3 80.3-21.4 21.4-50 33.3-80.3 33.3-30.3 0-58.8-11.8-80.3-33.3-21.4-21.4-33.3-50-33.3-80.3v-15c0-30.3 11.8-58.8 33.3-80.3 21.5-21.5 50-33.3 80.3-33.3m0-60c-95.8 0-173.5 77.7-173.5 173.5v15c0 95.8 77.7 173.5 173.5 173.5s173.5-77.7 173.5-173.5v-15C654.7 207.6 577 130 481.1 130z" fill="#3FA9F5" p-id="12618"></path><path d="M515.2 516.3c48.3 0 93.8 18.8 127.9 53 34.2 34.2 53 79.6 53 127.9 0 40.1-32.6 72.7-72.7 72.7H338.8c-40.1 0-72.7-32.6-72.7-72.7 0-48.3 18.8-93.8 53-127.9 34.2-34.2 79.6-53 127.9-53h68.2m0-60h-68.1c-133.1 0-240.9 107.9-240.9 240.9 0 73.3 59.4 132.7 132.7 132.7h284.7c73.3 0 132.7-59.4 132.7-132.7-0.2-133-108-240.9-241.1-240.9z" fill="#3FA9F5" p-id="12619"></path></svg>

+ 1 - 0
chuanyi-admin/src/icons/svg/user-table.svg

@@ -0,0 +1 @@
+<svg t="1680592180287" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20709" width="64" height="64"><path d="M939.008 913.408H105.472V90.112c0-11.264-9.216-20.48-20.48-20.48s-20.48 9.216-20.48 20.48v843.776c0 11.264 9.216 20.48 20.48 20.48h854.016c11.264 0 20.48-9.216 20.48-20.48s-9.216-20.48-20.48-20.48z" fill="#1296DB" p-id="20710"></path><path d="M203.776 863.232h71.68c22.528 0 40.96-18.432 40.96-40.96v-230.4c0-22.528-18.432-40.96-40.96-40.96h-71.68c-22.528 0-40.96 18.432-40.96 40.96v230.4c0 22.528 18.432 40.96 40.96 40.96z m71.68-40.96v20.48-20.48z m-71.68-230.4h71.68v230.4h-71.68v-230.4z m199.68 271.36h71.68c22.528 0 40.96-18.432 40.96-40.96V355.328c0-22.528-18.432-40.96-40.96-40.96h-71.68c-22.528 0-40.96 18.432-40.96 40.96v466.944c0 22.528 18.432 40.96 40.96 40.96z m71.68-40.96v20.48-20.48z m-71.68-466.944h71.68v466.944h-71.68V355.328zM604.16 863.232h71.68c22.528 0 40.96-18.432 40.96-40.96v-384c0-22.528-18.432-40.96-40.96-40.96h-71.68c-22.528 0-40.96 18.432-40.96 40.96v384c0 22.528 18.432 40.96 40.96 40.96z m0-424.96h71.68v384h-71.68v-384z m199.68 424.96h71.68c22.528 0 40.96-18.432 40.96-40.96V133.12c0-22.528-18.432-40.96-40.96-40.96h-71.68c-22.528 0-40.96 18.432-40.96 40.96v689.152c0 22.528 18.432 40.96 40.96 40.96z m0-730.112h71.68v689.152h-71.68V133.12z" fill="#1296DB" p-id="20711"></path></svg>

+ 187 - 54
chuanyi-admin/src/views/dashboard/index.vue

@@ -1,86 +1,132 @@
 <template>
   <div class="sy-content">
-    <div class="statistics">
-      <div v-for="(item, index) in statData" :key="index" class="stat-item">
-        <span class="stat-top">{{ item.title }}</span>
-        <span class="stat-bottom">{{ item.num }}</span>
-      </div>
-    </div>
+<!--    <div class="statistics">-->
+<!--      <div v-for="(item, index) in statData" :key="index" class="stat-item">-->
+<!--        <span class="stat-top">{{ item.title }}</span>-->
+<!--        <span class="stat-bottom">{{ item.num }}</span>-->
+<!--      </div>-->
+<!--    </div>-->
+    <el-row :gutter="40" class="panel-group">
+      <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
+        <div class="card-panel">
+          <div class="card-panel-icon-wrapper icon-people">
+            <svg-icon icon-class="user-manger" class-name="card-panel-icon" />
+          </div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">管理端用户数量</div>
+            <count-to :start-val="startVal" :end-val="statistics.managerUserNum" :duration="countDuration" class="card-panel-num" />
+          </div>
+        </div>
+      </el-col>
+      <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="user-t" class-name="card-panel-icon" />
+          </div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">客户端用户数量</div>
+            <count-to :start-val="startVal" :end-val="statistics.clientUserNum" :duration="countDuration" class="card-panel-num" />
+          </div>
+        </div>
+      </el-col>
+      <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="user-role" class-name="card-panel-icon" />
+          </div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">角色数量</div>
+            <count-to :start-val="startVal" :end-val="statistics.roleNum" :duration="countDuration" class="card-panel-num" />
+          </div>
+        </div>
+      </el-col>
+      <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="user-table" class-name="card-panel-icon" />
+          </div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">报表数量</div>
+            <count-to :start-val="startVal" :end-val="statistics.reportNum" :duration="countDuration" class="card-panel-num" />
+          </div>
+        </div>
+      </el-col>
+      <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="user-online" class-name="card-panel-icon" />
+          </div>
+          <div class="card-panel-description">
+            <div class="card-panel-text">客户端在线用户数</div>
+            <count-to :start-val="startVal" :end-val="statistics.onlineClientUserNum" :duration="countDuration" class="card-panel-num" />
+          </div>
+        </div>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
 <script>
 import { mapGetters } from 'vuex'
+import CountTo from 'vue-count-to'
 import {
   getManagerUserNum,
   getCustomerUserNum,
   getRoleNum,
-  getReportFormrNum
+  getReportFormrNum, getOnlineUser
 } from '@/api/dashboard'
 
 export default {
   name: 'Dashboard',
+  components: {
+    CountTo
+  },
   data() {
     return {
-      statData: []
+      statData: [],
+      countDuration: 1000,
+      startVal: 0,
+      statistics: {
+        roleNum: 0,
+        managerUserNum: 0,
+        clientUserNum: 0,
+        onlineClientUserNum: 0,
+        reportNum: 0
+      }
     }
   },
   computed: {
     ...mapGetters(['roles'])
   },
   created() {
-    this.statistics()
+    this.statisticsNum()
   },
   methods: {
-    statistics() {
-      const p1 = new Promise((resolve, reject) => {
-        getManagerUserNum().then((res) => {
-          if (res.code === 200) {
-            resolve(res.data)
-          }
-        })
+    statisticsNum() {
+      getManagerUserNum().then((res) => {
+        if (res.code === 200) {
+          this.statistics.managerUserNum = res.data
+        }
       })
-      const p2 = new Promise((resolve, reject) => {
-        getCustomerUserNum().then((res) => {
-          if (res.code === 200) {
-            resolve(res.data)
-          }
-        })
+      getCustomerUserNum().then((res) => {
+        if (res.code === 200) {
+          this.statistics.clientUserNum = res.data
+        }
       })
-      const p3 = new Promise((resolve, reject) => {
-        getRoleNum().then((res) => {
-          if (res.code === 200) {
-            resolve(res.data)
-          }
-        })
+      getRoleNum().then((res) => {
+        if (res.code === 200) {
+          this.statistics.roleNum = res.data
+        }
       })
-      const p4 = new Promise((resolve, reject) => {
-        getReportFormrNum().then((res) => {
-          if (res.code === 200) {
-            resolve(res.data)
-          }
-        })
+      getReportFormrNum().then((res) => {
+        if (res.code === 200) {
+          this.statistics.reportNum = res.data
+        }
       })
-      Promise.all([p1, p2, p3, p4]).then((res) => {
-        const [a, b, c, d] = res
-        this.statData = [
-          {
-            title: '管理端用户数量',
-            num: a
-          },
-          {
-            title: '客户端用户数量',
-            num: b
-          },
-          {
-            title: '角色数量',
-            num: c
-          },
-          {
-            title: '报表数量',
-            num: d
-          }
-        ]
+      getOnlineUser('front').then((res) => {
+        if (res.code === 200) {
+          this.statistics.onlineClientUserNum = res.data
+        }
       })
     }
   }
@@ -93,6 +139,7 @@ export default {
   justify-content: space-between;
   margin: 30px auto;
   width: 50%;
+  flex-wrap: wrap;
   .stat-item {
     display: flex;
     flex-direction: column;
@@ -107,4 +154,90 @@ export default {
     }
   }
 }
+.panel-group {
+  margin-top: 18px;
+
+  .card-panel-col {
+    margin-bottom: 32px;
+  }
+
+  .card-panel {
+    height: 108px;
+    //cursor: pointer;
+    font-size: 12px;
+    position: relative;
+    overflow: hidden;
+    color: #666;
+    background: #fff;
+    box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
+    border-color: rgba(0, 0, 0, .05);
+
+    .icon-people {
+      color: #40c9c6;
+    }
+
+    .icon-message {
+      color: #36a3f7;
+    }
+
+    .icon-money {
+      color: #f4516c;
+    }
+
+    .icon-shopping {
+      color: #34bfa3
+    }
+
+    .card-panel-icon-wrapper {
+      float: left;
+      margin: 14px 0 0 14px;
+      padding: 16px;
+      transition: all 0.38s ease-out;
+      border-radius: 6px;
+    }
+
+    .card-panel-icon {
+      float: left;
+      font-size: 48px;
+    }
+
+    .card-panel-description {
+      float: right;
+      font-weight: bold;
+      margin: 26px;
+      margin-left: 0px;
+
+      .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;
+        float: right;
+      }
+    }
+  }
+}
+
+@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;
+      float: none !important;
+    }
+  }
+}
 </style>

+ 15 - 4
chuanyi_client2/src/views/my_report/index.vue

@@ -1239,14 +1239,14 @@ export default {
           this.chooseMyReport = res.data
           this.btnType = 'show'
         }
-        this.setLuckysheetStatus(luckyData, true)
+        this.setLuckysheetStatus(luckyData, true, type)
       }).catch((e) => {
         loading.close()
         showAlertWin(this, e)
       })
     },
     /** 设置工作表状态 */
-    setLuckysheetStatus(luckyData, isReadOnly) {
+    setLuckysheetStatus(luckyData, isReadOnly, type) {
       let _this = this
       luckysheet.destroy()
       let option = luckyData.option
@@ -1290,6 +1290,8 @@ export default {
       // 钩子函数
       option.hook = {
         workbookCreateAfter() {
+          let charts = luckyData.charts
+          let tables = luckyData.tables
           option.data.forEach((data, i) => {
             if (data.chart && data.chart.length > 0) {
               data.chart.forEach((chart, j) => {
@@ -1299,8 +1301,17 @@ export default {
               })
             }
           })
-          _this.drawAutoReportData(luckyData.tables)
-          luckysheet.setRangeShow("BH1");
+          if (type == '') {
+            for (let i in charts) {
+              _this.insertEChartInfo(charts[i])
+            }
+            for (let i in tables) {
+              _this.insertTableInfo(tables[i])
+            }
+            _this.drawBaseInfo()
+          }
+          _this.drawAutoReportData(tables)
+          luckysheet.setRangeShow('BH1')
         }
       }
       luckysheet.create(option)

Някои файлове не бяха показани, защото твърде много файлове са промени