Ver Fonte

Merge branch 'develop' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop

CrazyIter_Bin há 2 anos atrás
pai
commit
1024b653c9

+ 6 - 1
TEAMModelBI/ClientApp/src/api/index.js

@@ -434,7 +434,7 @@ export default {
     },
     //课例数据占比
     proportionData(data) {
-        return post('schoolcheck/get-schooldate', data)
+        return post('/schoolcheck/get-schooldate', data)
     },
     //获取试卷资源
     getExaminations(data) {
@@ -530,6 +530,11 @@ export default {
         return post('/bizuser/rel-biz', data)
     },
 
+    /*产品使用分析*/
+    getUseproduct(data) {
+        return post('/prodanalysis/get-iotstics', data)
+    },
+    /*产品使用分析end*/
 
     //获取地址location
     getlocation(key, location) {

+ 6 - 8
TEAMModelBI/ClientApp/src/components/echarts/Xline.vue

@@ -15,7 +15,7 @@ export default {
       default: '100%',
     },
     lineData: {
-      type: Array,
+      type: Object,
       default: () => { },
     },
     title: {
@@ -57,14 +57,12 @@ class InitChart {
     this.state.chart && this.destory()
     this.state.chart = echarts.init(this.myEcharts.value)
     this.state.chart.setOption({
-      title: datas.title ? datas.title : {},
-      backgroundColor: datas.backgroundColor ? datas.backgroundColor : '',
+      tooltip: datas.tooltip ? datas.tooltip : '',
+      legend: datas.legend ? datas.legend : '',
       grid: datas.grid ? datas.grid : '',
-      // legend: datas.legend ? datas.legend : {},
-      xAxis: datas.xAxis ? datas.xAxis : {},
-      yAxis: datas.yAxis ? datas.yAxis : {},
-      dataZoom: datas.dataZoom ? datas.dataZoom : '',
-      series: datas.series ? datas.series : [],
+      xAxis: datas.xAxis ? datas.xAxis : '',
+      yAxis: datas.yAxis ? datas.yAxis : '',
+      series: datas.series ? datas.series : '',
     })
     window.addEventListener('resize', () => {
       this.state.chart.resize()

+ 2 - 1
TEAMModelBI/ClientApp/src/until/http.js

@@ -21,7 +21,8 @@ axios.interceptors.request.use(
             config.url.indexOf('bizconfig') != -1 ||
             config.url.indexOf('paper') != -1 ||
             config.url.indexOf('notice') != -1 ||
-            config.url.indexOf('bizuser') != -1
+            config.url.indexOf('bizuser') != -1 ||
+            config.url.indexOf('prodanalysis') != -1
         ) {
             config.headers = {
                 'Content-Type': 'application/json',

+ 4 - 4
TEAMModelBI/ClientApp/src/view/index/operateLog.vue

@@ -246,7 +246,7 @@ export default {
         cellRenderer: (data) =>
         (
           <>
-            <el-button type="primary" onClick={details.bind(data.rowData)}>查看</el-button>
+            <el-button type="primary" onClick={details.bind(this, data)}>查看</el-button>
           </>
         ),
       }
@@ -350,9 +350,9 @@ export default {
       searchKey.value = ''
     }
     //日子详情
-    function details (item) {
-      console.log(item, '数据')
-      logdataDetails.value = item
+    function details (item, data) {
+      console.log(item.rowData, '数据')
+      logdataDetails.value = item.rowData
       logdetails.value = true
     }
     function debounce (fn, wait) {

+ 289 - 250
TEAMModelBI/ClientApp/src/view/product/details.vue

@@ -39,30 +39,9 @@
             </div>
           </div>
         </div>
-        <div class="lessons-box">
-          <div class="lessons-item" v-for="(items,indexs) in lessonsList" :key="indexs">
-            <div class="lessons-img-title">
-              <div class="lessons-img">
-                <svg class="lessonsicon" aria-hidden="true">
-                  <use :xlink:href="items.icon"></use>
-                </svg>
-              </div>
-              <div class="lesson-title">{{items.title}}</div>
-            </div>
-            <div class="inquirybox"><span>{{items.content}}</span></div>
-            <div class="less-value">{{items.value}}</div>
-            <div class="result-box">
-              <svg class="lessRicon" aria-hidden="true" v-show="items.state ===true">
-                <use xlink:href="#icon-zhengque2"></use>
-              </svg>
-              <svg class="lessRicon" aria-hidden="true" v-show="items.state ===false">
-                <use xlink:href="#icon-cuowu"></use>
-              </svg>
-            </div>
-          </div>
-        </div>
-        <div class="inuse-box">
+        <div class="apparatusAndpower">
           <div class="inuse-left">
+            <p class="inuse-title">课中互动</p>
             <div class="inuse-item" v-for="(item,index) in inuseList" :key="index">
               <div class="item-img">
                 <svg class="inuseicon" aria-hidden="true">
@@ -75,9 +54,44 @@
               </div>
             </div>
           </div>
+          <div class="apparatus-box">
+            <p class="apparatus-title">设备与授权</p>
+            <div class="apparatus-item" v-for="(item,index) in powerList.facility" :key="index">
+              <div class="item-num">{{item.value}}</div>
+              <span class="item-title">{{item.name}}</span>
+            </div>
+          </div>
+          <div class="power-box">
+            <p class="apparatus-title">课堂与授权</p>
+            <div class="power-item" v-for="(item,index) in powerList.class" :key="index">
+              <div class="item-num">{{item.value}}</div>
+              <span class="item-title">{{item.name}}</span>
+            </div>
+          </div>
+        </div>
+        <div class="minxinbox">
+          <div class="lessons-box">
+            <div class="lessons-item" v-for="(items,indexs) in lessonsList" :key="indexs">
+              <div class="lessons-img-title">
+                <div class="lessons-img">
+                  <svg class="lessonsicon" aria-hidden="true">
+                    <use :xlink:href="items.icon"></use>
+                  </svg>
+                </div>
+                <div class="lesson-title">{{items.title}}</div>
+              </div>
+              <div class="inquirybox"><span>{{items.content}}</span></div>
+              <div class="less-value">{{indexs+1 === lessonsList.length ? items.value:items.value+'/堂课'}}</div>
+              <div class="result-box">
+                <svg class="lessRicon" aria-hidden="true">
+                  <use :xlink:href="items.value !==0 ? '#icon-zhengque2':'#icon-cuowu'"></use>
+                </svg>
+              </div>
+            </div>
+          </div>
           <div class="inuse-right">
             <div class="inuse-total">
-              <p>450<span>/堂课</span></p>
+              <p>{{echartData.total}}<span>/堂课</span></p>
               <div class="class-title">多形态课堂总量</div>
             </div>
             <div class="echartsX">
@@ -88,7 +102,7 @@
                 <p>{{itemA.name}}</p>
                 <div class="valuebox">
                   <span>{{itemA.value}}</span>
-                  <span :class="itemA.textClass">{{itemA.percent}}</span>
+                  <span :class="itemA.textClass">{{itemA.percent}}%</span>
                 </div>
                 <div :class="itemA.class"></div>
               </div>
@@ -208,7 +222,7 @@
                       <p>{{itemA.name}}</p>
                       <div class="valuebox">
                         <span>{{itemA.value}}</span>
-                        <span :class="itemA.textClass">{{itemA.percent}}</span>
+                        <!-- <span :class="itemA.textClass">{{itemA.percent}}</span> -->
                       </div>
                       <div :class="itemA.class"></div>
                     </div>
@@ -245,6 +259,11 @@
 <script setup>
 import { ref, getCurrentInstance, defineEmits, computed, onMounted } from 'vue'
 import Xlines from '@/components/echarts/Xline.vue'
+import * as echarts from 'echarts'
+let props = defineProps({
+  detailsData: Object
+})
+console.log(props.detailsData, '子组件')
 let value1 = ref('')
 let value = ref()
 let $myemit = defineEmits(['myback'])
@@ -620,6 +639,19 @@ let basicaList = ref([
   { title: '课堂总时数', icon: '#icon--shijian ', value: '648 min' },
   { title: '授权类型', icon: '#icon-guanfangshouquan', value: '已授权' },
 ])
+let powerList = ref({
+  facility: [
+    { name: '设备数量', value: 0, },
+    { name: '无授权设备', value: 0, },
+    { name: '授权设备', value: 0, }
+  ],
+  class: [
+    { name: '928授权', value: 0 },
+    { name: 'ID授权', value: 0 },
+    { name: '设备授权', value: 0 },
+    { name: '综合授权', value: 0 },
+  ]
+})
 let itemWidth = ref((100 / basicaList.value.length).toFixed(2))
 //处理默认呈现还是学区呈现
 onMounted(() => {
@@ -627,17 +659,17 @@ onMounted(() => {
 })
 console.log(basicaList.value, '@@@@')
 let lessonsList = ref([
-  { icon: '#icon--caozuorizhi', title: 'IES课程', content: '是否使用IES课程', state: true, value: '100/堂课' },
-  { icon: '#icon--caozuorizhi', title: 'webIrs', content: '是否使用webIrs', state: true, value: '100/堂课' },
-  { icon: '#icon--caozuorizhi', title: 'IRS', content: '是否使用IRS', state: true, value: '100/堂课' },
-  { icon: '#icon--caozuorizhi', title: 'HiTA', content: '是否使用HiTA', state: false, value: '0/堂课' },
-  { icon: '#icon--caozuorizhi', title: 'HaBoard', content: '是否使用HaBoard', state: false, value: '0/堂课' },
-  { icon: '#icon--caozuorizhi', title: 'IES5资源', content: '是否使用IES5资源', state: true, value: '50/堂课' },
+  { icon: '#icon--caozuorizhi', title: 'IES课程', content: '是否使用IES课程', state: true, value: 0 },
+  { icon: '#icon--caozuorizhi', title: 'webIrs', content: '是否使用webIrs', state: true, value: 0 },
+  { icon: '#icon--caozuorizhi', title: 'IRS', content: '是否使用IRS', state: true, value: 0 },
+  { icon: '#icon--caozuorizhi', title: 'HiTA', content: '是否使用HiTA', state: false, value: 0 },
+  { icon: '#icon--caozuorizhi', title: 'HaBoard', content: '是否使用HaBoard', state: false, value: 0 },
+  { icon: '#icon--caozuorizhi', title: 'IES5资源', content: '是否使用IES5资源', state: true, value: 0 },
   { icon: '#icon--caozuorizhi', title: 'T指数', content: '课程T指数', state: true, value: 0 },
 ])
 let inuseList = ref([
   { title: '任务数', value: 15, icon: '#icon-renwu', percent: '41.2%', class: 'task', textClass: 'task-text' },
-  { title: '作品完成总数', value: 10, icon: '#icon-yiwancheng-', percent: '30%', class: 'accomplish', textClass: 'accomplish-text' },
+  { title: '作品数', value: 10, icon: '#icon-yiwancheng-', percent: '30%', class: 'accomplish', textClass: 'accomplish-text' },
   { title: '题目数', value: 22, icon: '#icon-ic_mianxing_jiakaotimu_1', percent: '10%', class: 'topic', textClass: 'topic-text' },
   { title: '互动次数', value: 58, icon: '#icon-hudongshequ', percent: '5%', class: 'interaction', textClass: 'interaction-text' },
 ])
@@ -651,234 +683,188 @@ let classType = ref([
 let echartData = ref({
   total: 0,
   xlines: {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        show: true,
+        status: 'shadow',
+        z: -1,
+        shadowStyle: {
+          color: 'rgba(81, 138, 252, 0.1)',
+        },
+        type: 'shadow'
+      }
+    },
     grid: {
-      bottom: '0%',
+      bottom: '10%',
       left: '5%',
       right: '5%',
-      top: '0%',
+      top: '10%',
       containLabel: true,
     },
     xAxis: {
-      type: 'value', // 坐标轴类型,   'value' 数值轴,适用于连续数据
-      // 坐标轴刻度
+      position: 'bottom',
+      type: 'category',
+      axisLine: {
+        show: true,
+        lineStyle: {
+          color: '#ECF1F6'
+        }
+      },
       axisTick: {
-        show: false // 是否显示坐标轴刻度 默认显示
+        show: false,
       },
-      // 坐标轴轴线
-      axisLine: { // 是否显示坐标轴轴线 默认显示
-        show: false // 是否显示坐标轴轴线 默认显示
+      axisLabel: {
+        show: true,
+        rotate: 0,
+        fontSize: 12,
+        color: 'rgba(0, 0, 0, 1)'
       },
-      // 坐标轴在图表区域中的分隔线
       splitLine: {
-        show: false // 是否显示分隔线。默认数值轴显示
+        show: true,
+        lineStyle: {
+          color: 'rgba(193, 207, 220, 1)',
+          width: 0,
+          type: 'dashed'
+        }
       },
-      // 坐标轴刻度标签
-      axisLabel: {
-        show: false // 是否显示刻度标签 默认显示
-      }
+      boundaryGap: true, // 坐标轴两边是否留白
+      data: ['合作型态', '互动型态', '任务型态', '差异化型态', '测验型态']
     },
     yAxis: [
-      // 左侧Y轴
       {
-        // 坐标轴类型,  'category' 类目轴,适用于离散的类目数据
-        // 为该类型时必须通过 data 设置类目数据
-        type: 'category',
-        // 坐标轴刻度
-        axisTick: {
-          show: false // 是否显示坐标轴刻度 默认显示
-        },
-        // 坐标轴轴线
-        axisLine: { // 是否显示坐标轴轴线 默认显示
-          show: false, // 是否显示坐标轴轴线 默认显示
-          lineStyle: { // 坐标轴线线的颜色
-            color: '#cdd3ee'
-          }
+        type: 'value',
+        position: 'left',
+        minInterval: 0,
+        // maxInterval: 5,
+        axisLine: {
+          show: false,
         },
-        // 坐标轴在图表区域中的分隔线
-        splitLine: {
-          show: false // 是否显示分隔线。默认数值轴显示
+        axisTick: {
+          show: false,
         },
-        // 坐标轴刻度标签
         axisLabel: {
-          show: false, // 是否显示刻度标签 默认显示
-          fontSize: 16, // 文字的字体大小
-          color: '#333', // 刻度标签文字的颜色
-          // 使用字符串模板,模板变量为刻度默认标签 {value}
-          formatter: '{value}'
-        },
-      }
-    ],
-    series: [
-      {
-        type: 'bar', // 系列类型
-        name: '任务数', // 系列名称, 用于tooltip的显示, legend 的图例筛选
-        // 数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加
-        stack: '总量',
-        barMaxWidth: 30, // 柱条的最大宽度,不设时自适应
-        // 图形上的文本标签
-        label: {
           show: true,
-          position: 'inside',
-          formatter: function (params) {
-            if (params.value > 0) {
-              var res = params.value + '%';
-              return res;
-            } else {
-              return '';
-            }
-          },
-          // formatter: '{c}%',
-          textStyle: {
-            fontSize: 16,
-            fontWeight: 'bolder',
-            color: '#fff',
-          }
+          rotate: 0,
+          fontSize: 12,
+          color: 'rgba(0, 0, 0, 1)',
         },
-        // 图形样式
-        itemStyle: {
-          //   borderWidth: 5,
-          //   borderColor: "#baeee3",
-          color: '#58D4AF',
-        },
-        data: [41.2], // 系列中的数据内容数组
-      },
-      {
-        type: 'bar', // 系列类型
-        name: '作品完成数', // 系列名称, 用于tooltip的显示, legend 的图例筛选
-        // 数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加
-        stack: '总量',
-        barMaxWidth: 30, // 柱条的最大宽度,不设时自适应
-        // 图形上的文本标签
-        label: {
+        splitLine: {
           show: true,
-          position: 'inside',
-          formatter: function (params) {
-            if (params.value > 0) {
-              var res = params.value + '%';
-              return res;
-            } else {
-              return '';
-            }
-          },
-          // formatter: '{c}%',
-          textStyle: {
-            fontSize: 16,
-            fontWeight: 'bolder',
-            color: '#fff',
+          lineStyle: {
+            color: 'rgba(193, 207, 220, 1)',
+            width: 1,
+            type: 'solid'
           }
         },
-        // 图形样式
-        itemStyle: {
-          // color: '#eb6776',
-          colro: '#03241B',
-        },
-        data: [30] // 系列中的数据内容数组
-      },
+      }
+    ],
+    series: [
       {
-        type: 'bar', // 系列类型
-        name: '题目数', // 系列名称, 用于tooltip的显示, legend 的图例筛选
-        // 数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加
-        stack: '总量',
-        barMaxWidth: 30, // 柱条的最大宽度,不设时自适应
-        // 图形上的文本标签
-        label: {
-          show: true,
-          position: 'inside',
-          formatter: function (params) {
-            if (params.value > 0) {
-              var res = params.value + '%';
-              return res;
-            } else {
-              return '';
-            }
-          },
-          // formatter: '{c}%',
-          textStyle: {
-            fontSize: 16,
-            fontWeight: 'bolder',
-            color: '#fff',
-          }
-        },
-        // 图形样式
+        type: 'bar',
+        data: [],
         itemStyle: {
-          color: '#62D0F3',
-        },
-        data: [10] // 系列中的数据内容数组
-      },
-      {
-        type: 'bar', // 系列类型
-        name: '互动数', // 系列名称, 用于tooltip的显示, legend 的图例筛选
-        // 数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加
-        stack: '总量',
-        barMaxWidth: 30, // 柱条的最大宽度,不设时自适应
-        // 图形上的文本标签
-        label: {
-          show: true,
-          position: 'inside',
-          formatter: function (params) {
-            if (params.value > 0) {
-              var res = params.value + '%';
-              return res;
-            } else {
-              return '';
+          normal: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+              offset: 0,
+              color: "rgba(124, 135, 254, 1)"
+            },
+            {
+              offset: 1,
+              color: "rgba(81, 138, 252, 1)"
             }
-          },
-          // formatter: '{c}%',
-          textStyle: {
-            fontSize: 16,
-            fontWeight: 'bolder',
-            color: '#fff',
+            ])
           }
         },
-        // 图形样式
-        itemStyle: {
-          color: '#fd79a8',
-        },
-        data: [5] // 系列中的数据内容数组
-      },
-      {
-        type: 'bar', // 系列类型
-        name: '互动数', // 系列名称, 用于tooltip的显示, legend 的图例筛选
-        // 数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加
-        stack: '总量',
-        barMaxWidth: 30, // 柱条的最大宽度,不设时自适应
-        // 图形上的文本标签
         label: {
-          show: true,
-          position: 'inside',
-          formatter: function (params) {
-            if (params.value > 0) {
-              var res = params.value + '%';
-              return res;
-            } else {
-              return '';
+          normal: {
+            show: true,
+            position: "top",
+            textStyle: {
+              color: "rgba(63, 149, 218, 1)",
+              fontSize: 18,
+              fontFamily: 'DIN',
+              fontWeight: 'bold'
             }
-          },
-          // formatter: '{c}%',
-          textStyle: {
-            fontSize: 16,
-            fontWeight: 'bolder',
-            color: '#fff',
           }
         },
-        // 图形样式
-        itemStyle: {
-          color: '#c3bef0',
-        },
-        data: [10] // 系列中的数据内容数组
-      },
+        barMaxWidth: '20%',
+      }
     ]
   }
 })
 function init () {
-  let totalsArr = []
-  inuseList.value.forEach((item) => { totalsArr.push(item.value) })
-  console.log(totalsArr)
-  let totalNum = totalsArr.reduce(function (prev, cur) {
-    return prev + cur;
-  })
-  echartData.value.total = totalNum
+  // let totalsArr = []
+  // inuseList.value.forEach((item) => { totalsArr.push(item.value) })
+  // console.log(totalsArr)
+  // let totalNum = totalsArr.reduce(function (prev, cur) {
+  //   return prev + cur;
+  // })
   console.log(totalNum, '总数')
+
+  //处理header基础信息
+  let { schoolId, stuShow, lessonLengMin, lessonRecord, stuLessonLengMin } = props.detailsData
+  console.log(schoolId, stuShow, '!!!!!')
+  basicaList.value[0].value = schoolId
+  basicaList.value[1].value = 0
+  basicaList.value[2].value = 0
+  basicaList.value[3].value = 0
+  basicaList.value[4].value = stuShow
+  basicaList.value[5].value = stuLessonLengMin
+  basicaList.value[6].value = lessonRecord
+  basicaList.value[7].value = lessonLengMin
+
+  //处理课中使用数据
+  let { useIES, useWebIrs, useDeviceIrs, useHita, useHaboard, useIES5Resource, tGreen } = props.detailsData
+  lessonsList.value[0].value = useIES
+  lessonsList.value[1].value = useWebIrs
+  lessonsList.value[2].value = useDeviceIrs
+  lessonsList.value[3].value = useHita
+  lessonsList.value[4].value = useHaboard
+  lessonsList.value[5].value = useIES5Resource
+  lessonsList.value[6].value = tGreen
+
+  //授权占比
+  let { deviceCnt, deviceNoAuth, deviceAuth, lessonCnt928, lessonCntId, lessonCntDevice, lessonCntIdDevice } = props.detailsData
+  powerList.value.facility[0].value = deviceCnt
+  powerList.value.facility[1].value = deviceNoAuth
+  powerList.value.facility[2].value = deviceAuth
+
+  powerList.value.class[0].value = lessonCnt928
+  powerList.value.class[1].value = lessonCntId
+  powerList.value.class[2].value = lessonCntDevice
+  powerList.value.class[3].value = lessonCntIdDevice
+  //处理任务数、作品完成、题目等。。。。
+  let { mission, missionFin, item, interact } = props.detailsData
+  inuseList.value[0].value = mission
+  inuseList.value[1].value = missionFin
+  inuseList.value[2].value = item
+  inuseList.value[3].value = interact
+
+  //处理多形态课堂
+  let { lTypeCoop, lTypeIact, lTypeMis, lTypeTst, lTypeDif } = props.detailsData
+  let totalNum = [lTypeCoop, lTypeIact, lTypeMis, lTypeTst, lTypeDif].reduce((prev, cur) => { return prev + cur }, 0)
+  echartData.value.total = totalNum
+  console.log(totalNum)
+  classType.value[0].value = lTypeCoop
+  classType.value[0].percent = lTypeCoop === 0 ? 0 : (lTypeCoop / totalNum).toFixed(2) * 100
+  classType.value[1].value = lTypeIact
+  classType.value[1].percent = lTypeIact === 0 ? 0 : (lTypeIact / totalNum).toFixed(2) * 100
+  classType.value[2].value = lTypeMis
+  classType.value[2].percent = lTypeMis === 0 ? 0 : (lTypeMis / totalNum).toFixed(2) * 100
+  classType.value[3].value = lTypeTst
+  classType.value[3].percent = lTypeTst === 0 ? 0 : (lTypeTst / totalNum).toFixed(2) * 100
+  classType.value[4].value = lTypeDif
+  classType.value[4].percent = lTypeDif === 0 ? 0 : (lTypeDif / totalNum).toFixed(2) * 100
+
+  //echarts占比
+  echartData.value.xlines.series[0].data = [15, 20, 30, 45, 60]
+  // echartData.value.xlines.series[1].data = [classType.value[1].percent]
+  // echartData.value.xlines.series[2].data = [classType.value[2].percent]
+  // echartData.value.xlines.series[3].data = [classType.value[3].percent]
+  // echartData.value.xlines.series[4].data = [classType.value[4].percent]
+
+  // console.log(echartData.value.xlines.series[0].data, echartData.value.xlines.series[1].data)
 }
 function backbtn () {
   $myemit('myback', 'default')
@@ -948,6 +934,66 @@ init()
   /* height: 30vh; */
   display: flex;
   flex-wrap: nowrap;
+  justify-content: space-between;
+}
+.apparatusAndpower {
+  width: 100%;
+  display: flex;
+  flex-wrap: nowrap;
+  line-height: 60px;
+  /* justify-content: space-between; */
+}
+.apparatus-box,
+.power-box {
+  width: 32%;
+  box-shadow: 0 2px 5px #e9e9e9;
+  background: #fff;
+  margin: 0.5%;
+  border-radius: 5px;
+  display: flex;
+  justify-content: space-between;
+  /* align-items: center; */
+  flex-wrap: wrap;
+}
+.apparatus-item {
+  width: 30%;
+  margin: 0% 1%;
+  box-shadow: 0 2px 5px #e9e9e9;
+  background: #fff;
+  border-radius: 5px;
+  margin: 1%;
+}
+.power-item {
+  width: 23%;
+  margin: 0% 1%;
+  box-shadow: 0 2px 5px #e9e9e9;
+  background: #fff;
+  border-radius: 5px;
+  margin: 1%;
+}
+.apparatus-title {
+  font-size: 16px;
+  margin-bottom: 5px;
+  border-bottom: 1px dashed #e9e9e9;
+  line-height: 40px;
+  width: 100%;
+  background: #dfe6e9;
+  color: #fff;
+  font-weight: bold;
+}
+.inuse-title {
+  width: 100%;
+  background: #dfe6e9;
+  margin-bottom: 5px;
+  line-height: 40px;
+  border-bottom: 1px dashed #e9e9e9;
+  font-size: 16px;
+  font-weight: bold;
+  color: #fff;
+}
+.item-num {
+  font-size: 20px;
+  font-weight: bold;
 }
 .basicadata-item {
   display: flex;
@@ -959,7 +1005,7 @@ init()
   border-radius: 5px;
   box-shadow: 0 2px 5px #e9e9e9;
   background: #fff;
-  margin: 0.5% 1% 1% 1%;
+  margin: 0.5%;
 }
 .item-title-images {
   width: 100%;
@@ -978,8 +1024,12 @@ init()
   font-weight: bold;
   color: #303a5d;
 }
+.minxinbox {
+  width: 100%;
+  display: flex;
+}
 .lessons-box {
-  width: 98%;
+  width: 50%;
   height: 50vh;
   border-radius: 5px;
   background: #fff;
@@ -1048,49 +1098,38 @@ init()
   vertical-align: -0.5em;
   fill: currentColor;
 }
-.inuse-box {
-  width: 98%;
-  height: 25vh;
-  margin: 1%;
-  /* border-radius: 5px;
-  background: #fff;
-  box-shadow: 0 2px 5px #e9e9e9;
-  margin: 0.5% 1%;
-  overflow: hidden;
-  overflow-y: auto; */
-  display: flex;
-}
 .inuse-left {
-  width: 49%;
-  margin-left: 0%;
-  border-radius: 5px;
-  background: #fff;
+  width: 35%;
   box-shadow: 0 2px 5px #e9e9e9;
-  margin: 0.5% 0%;
+  background: #fff;
+  margin: 0.5%;
+  border-radius: 5px;
   display: flex;
-  justify-content: center;
+  justify-content: space-around;
   align-items: center;
+  flex-wrap: wrap;
 }
 .inuse-right {
-  width: 50%;
+  width: 49.5%;
   margin-left: 0%;
   border-radius: 5px;
   background: #fff;
   box-shadow: 0 2px 5px #e9e9e9;
   margin: 0.5% 0%;
-  margin-left: 1%;
+  /* margin-left: 1%; */
   position: relative;
 }
 .inuse-item {
   width: 22%;
   display: flex;
-  line-height: 40px;
+  height: 120px;
+  /* line-height: 40px; */
   justify-content: center;
   align-items: center;
   border-radius: 5px;
   /* box-shadow: 0 2px 5px #e9e9e9; */
   border: 1px solid #e9e9e9;
-  margin-left: 1.5%;
+  margin: 1%;
 }
 .inuseicon {
   width: 3em;
@@ -1129,7 +1168,7 @@ init()
 }
 .echartsX {
   width: 100%;
-  height: 45%;
+  height: 75%;
   margin-top: 6%;
   overflow: hidden;
 }

+ 39 - 33
TEAMModelBI/ClientApp/src/view/product/index.vue

@@ -129,7 +129,7 @@
           </div>
         </div>
         <div class="middlebox-right">
-          <div class="middlebox-right-title">共有<span class="middlebox-right-num">45</span>条数据</div>
+          <div class="middlebox-right-title">共有<span class="middlebox-right-num">{{filterdata.length}}</span>条数据</div>
           <div class="exportbtn">
             <el-button type="success" plain @click="exportstate=true">导出数据到Execl</el-button>
             <!-- <el-button type="success" plain disabled>导出数据到Execl</el-button> -->
@@ -140,13 +140,13 @@
     <div class="data-tables">
       <el-auto-resizer>
         <template #default="{ height, width }">
-          <el-table-v2 :columns="columns" :data="data" :width="width" :height="height" fixed />
+          <el-table-v2 :columns="columns" :data="filterdata" :width="width" :height="height" fixed />
         </template>
       </el-auto-resizer>
     </div>
   </div>
   <div v-else-if="showState==='details'">
-    <Details @myback="changStateshow"></Details>
+    <Details @myback="changStateshow" :detailsData="detailsData"></Details>
   </div>
   <div class="dialog-filter" v-if="exportstate">
     <el-dialog v-model="exportstate" title="筛选导出" width="35%">
@@ -195,25 +195,27 @@
 <script setup>
 import option_cn from '@/static/regions/region_cn.json'
 import { ref, getCurrentInstance, watch } from 'vue'
+import { ElMessage, TableV2SortOrder } from 'element-plus'
 import Details from './details.vue'
+let { proxy } = getCurrentInstance()
 let drawer = ref(false)
 let direction = ref('ttb')
 let activeNames = ref(['1'])
 let showState = ref('default')
 let findValue = ref()
 let columns = ref([
+  // {
+  //   key: "id",
+  //   dataKey: "id",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
+  //   title: "编号",//显示在单元格表头的文本
+  //   width: 100,//当前列的宽度,必须设置
+  //   fixed: false,//是否固定列
+  //   headerClass: 'header-class',
+  // },
   {
-    key: "id",
-    dataKey: "id",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
-    title: "编号",//显示在单元格表头的文本
-    width: 100,//当前列的宽度,必须设置
-    fixed: false,//是否固定列
-    headerClass: 'header-class',
-  },
-  {
-    key: "name",
-    dataKey: "name",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
-    title: "名称",//显示在单元格表头的文本
+    key: "schoolId",
+    dataKey: "schoolId",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
+    title: "简码",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
   },
@@ -232,36 +234,36 @@ let columns = ref([
     headerClass: 'general',
   },
   {
-    key: "studennum",
-    dataKey: "studennum",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
+    key: "stuShow",
+    dataKey: "stuShow",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
     title: "学生人数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
   },
   {
-    key: "classtotal",
-    dataKey: "classtotal",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
+    key: "lessonRecord",
+    dataKey: "lessonRecord",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
     title: "课堂总数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
   },
   {
-    key: "studentime",
-    dataKey: "studentime",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
+    key: "lessonLengMin",
+    dataKey: "lessonLengMin",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
     title: "课堂总时数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
   },
   {
-    key: "tnum",
-    dataKey: "tnum",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
+    key: "tGreen",
+    dataKey: "tGreen",//需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
     title: "T指数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
   },
   {
-    key: "time",
-    dataKey: "time",
+    key: "date",
+    dataKey: "date",
     title: "时间",
     width: 100,
     headerClass: 'general',
@@ -280,15 +282,7 @@ let columns = ref([
     )
   },
 ])
-let data = ref([
-  { id: 1, name: '1111', classnum: '33091', teachnum: 123, studennum: 80, classtotal: 7, studentime: '120Min', tnum: 75, type: '1', time: '2023-03-01' },
-  { id: 2, name: '2222', classnum: '33092', teachnum: 123, studennum: 55, classtotal: 8, studentime: '110Min', tnum: 45, type: '2', time: '2023-03-02' },
-  { id: 3, name: '3333', classnum: '33093', teachnum: 123, studennum: 130, classtotal: 9, studentime: '60Min', tnum: 55, type: '0', time: '2023-03-03' },
-  { id: 4, name: '4444', classnum: '33094', teachnum: 123, studennum: 70, classtotal: 7, studentime: '50Min', tnum: 85, type: '1', time: '2023-03-04' },
-  { id: 5, name: '5555', classnum: '33095', teachnum: 123, studennum: 66, classtotal: 8, studentime: '130Min', tnum: 80, type: '2', time: '2023-03-05' },
-  { id: 6, name: '666', classnum: '33096', teachnum: 123, studennum: 50, classtotal: 9, studentime: '140Min', tnum: 95, type: '2', time: '2023-03-07' },
-  { id: 7, name: '77777', classnum: '33097', teachnum: 123, studennum: 32, classtotal: 6, studentime: '120Min', tnum: 65, type: '0', time: '2023-03-08' },
-])
+let filterdata = ref([])
 let productData = ref({
   dataType: '结果类型',
   datainfo: [
@@ -394,9 +388,11 @@ let exportStandard = ref([
   { title: 'T指标数', value: 0, key: 'Tnum', option: [{ name: '无绿灯', value: '0' }, { name: '单绿灯', value: '1' }, { name: '双绿灯', value: '2' }] },
   { title: '授权类型', value: 0, key: 'powertype', option: [{ name: '全部', value: 'all' }, { name: '试用', value: 'test' }, { name: '已授权', value: 'power' }] },
 ])
+let detailsData = ref()
 function changeState (value) {
   console.log(value)
   showState.value = 'details'
+  detailsData.value = value.rowData
 }
 function changStateshow (value) {
   console.log(value, '状态改变')
@@ -405,6 +401,16 @@ function changStateshow (value) {
 function selectBlur (e) {
   dataForm.value.newData = e.target.value;
 }
+function init () {
+  let data = { "dateFrom": "2023-04-12", "dateTo": "2023-04-19", "prod": "HiTeach", "schoolIds": ["tbslgb", "habook"], "dateUnit": "Day" }
+  proxy.$api.getUseproduct(data).then((res) => {
+    console.log(res, 'backPromise')
+    res.state === 200 ? filterdata.value = res.data : ''
+  }).catch((err) => {
+    ElMessage.error('API异常,数据获取失败')
+  })
+}
+init()
 watch(activeNames, (newdata) => {
   if (newdata.length === 0) {
     changeHight.value = 80