فهرست منبع

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

zhouj1203@hotmail.com 1 سال پیش
والد
کامیت
b7cfdf6e7a
46فایلهای تغییر یافته به همراه5421 افزوده شده و 1021 حذف شده
  1. 6 4
      TEAMModelBI/ClientApp/src/view/areaServe/setthird.vue
  2. 4 4
      TEAMModelBI/ClientApp/src/view/areamanage/statistics.vue
  3. 60 4
      TEAMModelBI/ClientApp/src/view/product/details.vue
  4. 28 8
      TEAMModelBI/ClientApp/src/view/product/index.vue
  5. 10 3
      TEAMModelBI/Controllers/Census/SchoolController.cs
  6. 0 1
      TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs
  7. 28 22
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs
  8. 4 0
      TEAMModelOS.SDK/Models/Cosmos/OpenEntity/OStudent.cs
  9. 655 102
      TEAMModelOS.SDK/Models/Cosmos/School/ScoreCalc.cs
  10. 16 3
      TEAMModelOS.SDK/Models/Cosmos/Student/OverallEducation.cs
  11. 105 3
      TEAMModelOS.SDK/Models/Service/LessonService.cs
  12. 12 1
      TEAMModelOS.SDK/Models/Service/SchoolService.cs
  13. 1 0
      TEAMModelOS/ClientApp/package.json
  14. 61 0
      TEAMModelOS/ClientApp/src/common/BaseDashSelect.vue
  15. 56 0
      TEAMModelOS/ClientApp/src/common/BaseDashTab.vue
  16. 11 0
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  17. 1 1
      TEAMModelOS/ClientApp/src/common/BaseSelectTch.vue
  18. 8 5
      TEAMModelOS/ClientApp/src/components/dashboard/student/BaseCircle.vue
  19. 137 0
      TEAMModelOS/ClientApp/src/components/dashboard/student/BaseStuRankList.vue
  20. 281 0
      TEAMModelOS/ClientApp/src/components/dashboard/studentAll/BaseLineBar.vue
  21. 1 0
      TEAMModelOS/ClientApp/src/components/dashboard/studentAll/BaseScoreBar.vue
  22. 281 0
      TEAMModelOS/ClientApp/src/components/dashboard/studentAll/BaseStudyLineBar.vue
  23. 6 3
      TEAMModelOS/ClientApp/src/components/student-web/WrongQusetion/WrongQues.vue
  24. 5 0
      TEAMModelOS/ClientApp/src/router/routes.js
  25. 27 31
      TEAMModelOS/ClientApp/src/view/dashboard/fiveEdu/FiveEdu.less
  26. 389 276
      TEAMModelOS/ClientApp/src/view/dashboard/fiveEdu/FiveEdu.vue
  27. 0 2
      TEAMModelOS/ClientApp/src/view/dashboard/moral/MoralDash.vue
  28. 0 258
      TEAMModelOS/ClientApp/src/view/dashboard/study/BaseExamLine.vue
  29. 281 0
      TEAMModelOS/ClientApp/src/view/dashboard/study/BaseExamLineBar.vue
  30. 145 0
      TEAMModelOS/ClientApp/src/view/dashboard/study/BaseLevelBar.vue
  31. 99 54
      TEAMModelOS/ClientApp/src/view/dashboard/study/BaseRadar.vue
  32. 281 0
      TEAMModelOS/ClientApp/src/view/dashboard/study/BaseStudyLineBar.vue
  33. 5 6
      TEAMModelOS/ClientApp/src/view/dashboard/study/BaseSubLine.vue
  34. 9 1
      TEAMModelOS/ClientApp/src/view/dashboard/study/StudyDash.less
  35. 62 77
      TEAMModelOS/ClientApp/src/view/dashboard/study/StudyDash.vue
  36. 185 0
      TEAMModelOS/ClientApp/src/view/iot/schooliot.vue
  37. 34 4
      TEAMModelOS/ClientApp/src/view/mycourse/record/Record.vue
  38. 1 0
      TEAMModelOS/ClientApp/src/view/student-web/AppNew.vue
  39. 1 1
      TEAMModelOS/Controllers/Both/CourseBaseController.cs
  40. 1868 85
      TEAMModelOS/Controllers/Both/ScoreCalcController.cs
  41. 2 0
      TEAMModelOS/Controllers/OpenApi/Business/BizCustomizeController.cs
  42. 79 52
      TEAMModelOS/Controllers/System/BlobController.cs
  43. 168 2
      TEAMModelOS/Controllers/XTest/TestController.cs
  44. 4 4
      TEAMModelOS/TEAMModelOS.csproj
  45. 3 3
      TEAMModelOS/appsettings.Development.json
  46. 1 1
      TEAMModelOS/appsettings.json

+ 6 - 4
TEAMModelBI/ClientApp/src/view/areaServe/setthird.vue

@@ -136,7 +136,7 @@
             <p class="set-basics-title">
             <p class="set-basics-title">
             <div class="set-basics-title-name">关联用户</div>
             <div class="set-basics-title-name">关联用户</div>
             <div class="set-basics-save">
             <div class="set-basics-save">
-              <el-button type="primary" size="small" @click="addschoolRelevancy=true" v-if="PowerShow">
+              <el-button type="primary" size="small" @click="addschoolAdmin=true" v-if="PowerShow">
                 <svg class="addrelevancy-icon" aria-hidden="true">
                 <svg class="addrelevancy-icon" aria-hidden="true">
                   <use xlink:href="#icon-guanlianrenyuan"></use>
                   <use xlink:href="#icon-guanlianrenyuan"></use>
                 </svg>
                 </svg>
@@ -221,7 +221,7 @@
     <!--添加关联学校弹窗end-->
     <!--添加关联学校弹窗end-->
     <!--添加关联用户弹窗-->
     <!--添加关联用户弹窗-->
     <div class="adduser-relevancy">
     <div class="adduser-relevancy">
-      <el-dialog v-model="addschoolRelevancy" title="搜索用户列表" width="25%">
+      <el-dialog v-model="addschoolAdmin" title="搜索用户列表" width="25%">
         <div>
         <div>
           <el-input v-model="searchUser" placeholder="搜索 手机号码" class="input-with-select" size="small" clearable>
           <el-input v-model="searchUser" placeholder="搜索 手机号码" class="input-with-select" size="small" clearable>
             <template #prepend>
             <template #prepend>
@@ -250,7 +250,7 @@
         </el-table>
         </el-table>
         <template #footer>
         <template #footer>
           <span class="dialog-footer">
           <span class="dialog-footer">
-            <el-button @click="addschoolRelevancy = false">取消</el-button>
+            <el-button @click="addschoolAdmin = false">取消</el-button>
             <el-button type="primary" @click="notarizebox=true">关联选中用户</el-button>
             <el-button type="primary" @click="notarizebox=true">关联选中用户</el-button>
           </span>
           </span>
         </template>
         </template>
@@ -326,6 +326,7 @@ export default {
     let original = ref([])
     let original = ref([])
     let timer = ref('')
     let timer = ref('')
     let addschoolRelevancy = ref(false)
     let addschoolRelevancy = ref(false)
+    let addschoolAdmin=ref(false)
     let checkedSchool = ref([])
     let checkedSchool = ref([])
     let checkedUser = ref([])
     let checkedUser = ref([])
     let removeArr = ref([])
     let removeArr = ref([])
@@ -682,7 +683,8 @@ export default {
       correlationRole,
       correlationRole,
       removeUser,
       removeUser,
       removeUserarr,
       removeUserarr,
-      removeUserList
+      removeUserList,
+      addschoolAdmin
     }
     }
   },
   },
 }
 }

+ 4 - 4
TEAMModelBI/ClientApp/src/view/areamanage/statistics.vue

@@ -75,7 +75,7 @@
               <div class="area-item" v-for="(item,index) in areaLists" :key="item.id">
               <div class="area-item" v-for="(item,index) in areaLists" :key="item.id">
                 <div class="area-item-list">
                 <div class="area-item-list">
                   <p class="area-item-name">{{item.name}}</p>
                   <p class="area-item-name">{{item.name}}</p>
-                  <p class="area-item-school"><span class="area-item-school-title">学区学校数:</span><span class="area-item-school-content">{{item.scCnt}}</span></p>
+                  <p class="area-item-school"><span class="area-item-school-title">学区学校数:</span><span class="area-item-school-content">{{item.schoolCount}}</span></p>
                   <!-- <p class="area-item-school"><span class="area-item-school-title">学区教师数:</span><span class="area-item-school-content">{{item.tchCnt}}</span></p>
                   <!-- <p class="area-item-school"><span class="area-item-school-title">学区教师数:</span><span class="area-item-school-content">{{item.tchCnt}}</span></p>
             <p class="area-item-school"><span class="area-item-school-title">学区学生数:</span><span class="area-item-school-content">{{item.stuCnt}}</span></p> -->
             <p class="area-item-school"><span class="area-item-school-title">学区学生数:</span><span class="area-item-school-content">{{item.stuCnt}}</span></p> -->
                 </div>
                 </div>
@@ -1547,9 +1547,9 @@ export default {
     }
     }
     //获取全区的学区列表
     //获取全区的学区列表
     function getAllList () {
     function getAllList () {
-      proxy.$api.getAreaList({}).then((res) => {
+      proxy.$api.getCapacity({}).then((res) => {
         console.log(res, 'LIST')
         console.log(res, 'LIST')
-        res.state === 200 ? (areaLists.value = res.areaInfos, searchOriginal.value = res.areaInfos) : ''
+        res.state === 200 ? (areaLists.value = res.areas, searchOriginal.value = res.areas) : ''
       }).catch((error) => {
       }).catch((error) => {
         ElMessage.error('学区列表API异常')
         ElMessage.error('学区列表API异常')
       })
       })
@@ -1761,7 +1761,7 @@ export default {
         CounselorList.value = res.saless
         CounselorList.value = res.saless
         aspectsLoading.value.counselorData = false
         aspectsLoading.value.counselorData = false
         // //基本
         // //基本
-        aspectsData.value[0].num = res.schoolInfos.length
+        aspectsData.value[0].num = res.schCnt
         aspectsData.value[1].num = res.areaScStats.tch
         aspectsData.value[1].num = res.areaScStats.tch
         aspectsData.value[2].num = res.areaScStats.stu
         aspectsData.value[2].num = res.areaScStats.stu
         console.log(res.areaScStats.lessStats.all,res.areaScStats.actStats.all,'某个学区的')
         console.log(res.areaScStats.lessStats.all,res.areaScStats.actStats.all,'某个学区的')

+ 60 - 4
TEAMModelBI/ClientApp/src/view/product/details.vue

@@ -262,11 +262,11 @@
               <el-table-column prop="lessonRecord" label="课堂总数" align="center" />
               <el-table-column prop="lessonRecord" label="课堂总数" align="center" />
               <el-table-column prop="lessonLengMin" label="课堂时间(分钟)" align="center" />
               <el-table-column prop="lessonLengMin" label="课堂时间(分钟)" align="center" />
               <el-table-column prop="tGreen" label="T指数" align="center" />
               <el-table-column prop="tGreen" label="T指数" align="center" />
-              <el-table-column label="" align="center">
+              <!-- <el-table-column label="" align="center">
                 <template #default="scope">
                 <template #default="scope">
                   <el-button type="primary" plain @click="detailsSchool(scope.row)">查看</el-button>
                   <el-button type="primary" plain @click="detailsSchool(scope.row)">查看</el-button>
                 </template>
                 </template>
-              </el-table-column>
+              </el-table-column> -->
             </el-table>
             </el-table>
           </div>
           </div>
         </el-tab-pane>
         </el-tab-pane>
@@ -876,6 +876,7 @@ function init (againvalue) {
   if(propsbox.pattern && propsbox.pattern.state ==="area"){
   if(propsbox.pattern && propsbox.pattern.state ==="area"){
      let areaidValue=propsbox.detailsData.school[0].areaId
      let areaidValue=propsbox.detailsData.school[0].areaId
      let patternData=propsbox.pattern.data
      let patternData=propsbox.pattern.data
+     console.log(patternData,'88899784')
      let areainSchool=patternData.filter((item)=>{
      let areainSchool=patternData.filter((item)=>{
       return  item.school.areaId === areaidValue
       return  item.school.areaId === areaidValue
      })
      })
@@ -883,10 +884,65 @@ function init (againvalue) {
      areainSchool.forEach((item)=>{
      areainSchool.forEach((item)=>{
       item.name =item.school.name
       item.name =item.school.name
      })
      })
+     let trimData=[]
+     areainSchool.forEach((itemS)=>{
+       let schoolName=itemS.name
+       console.log(schoolName,'名字')
+       let results=trimData.findIndex((itemA)=>{return itemA.name === schoolName})
+       console.log(results,'results')
+       if(results === -1){
+        //数组不存在 直接添加学校
+        trimData.push(itemS)
+       }else{
+        console.log(results,'进入第二部分')
+        //数组存在学校 数据累加
+        trimData[results].deviceAuth += itemS.deviceAuth;
+        trimData[results].deviceCnt +=itemS.deviceCnt
+        trimData[results].deviceNoAuth +=itemS.deviceNoAuth
+        trimData[results].interact +=itemS.interact
+        trimData[results].item +=itemS.item
+        trimData[results].lTypeCoop +=itemS.lTypeCoop
+        trimData[results].lTypeDif +=itemS.lTypeDif
+        trimData[results].lTypeIact +=itemS.lTypeIact
+        trimData[results].lTypeMis +=itemS.lTypeMis
+        trimData[results].lTypeNone +=itemS.lTypeNone
+        trimData[results].lTypeTst +=itemS.lTypeTst
+        trimData[results].lessonCnt +=itemS.lessonCnt
+        trimData[results].lessonCntDevice +=itemS.lessonCntDevice
+        trimData[results].lessonCntId +=itemS.lessonCntId
+        trimData[results].lessonCntIdDevice +=itemS.lessonCntIdDevice
+        trimData[results].lessonLengMin +=itemS.lessonLengMin
+        trimData[results].lessonRecord +=itemS.lessonRecord
+        trimData[results].mission +=itemS.mission
+        trimData[results].missionFin +=itemS.missionFin
+        trimData[results].stuLessonLengMin +=itemS.stuLessonLengMin
+        trimData[results].stuShow +=itemS.stuShow
+        trimData[results].tGreen +=itemS.tGreen
+        trimData[results].tmidCnt +=itemS.tmidCnt
+        trimData[results].toolType='HiTeach'
+        trimData[results].date=itemS.date
+        trimData[results].year=itemS.year
+        trimData[results].month=itemS.month
+        trimData[results].day=itemS.day >0 ? itemS.day:1
+        trimData[results].useDeviceIrs +=itemS.useDeviceIrs
+        trimData[results].useHaboard +=itemS.useHaboard
+        trimData[results].useHita +=itemS.useHita
+        trimData[results].useIES +=itemS.useIES
+        trimData[results].useIES5Resource +=itemS.useIES5Resource
+        trimData[results].useWebIrs +=itemS.useWebIrs
+        trimData[results].deviceAuthList = trimData[results].deviceAuthList.concat(itemS.deviceAuthList);
+        trimData[results].deviceList=trimData[results].deviceList.concat(itemS.deviceList)
+        trimData[results].deviceNoAuthList=trimData[results].deviceNoAuthList.concat(itemS.deviceNoAuthList)
+        trimData[results].tmidList= trimData[results].tmidList.concat(itemS.tmidList)
+       }
+     })
+     //处理学校数量
      basicaList.value.forEach((item)=>{
      basicaList.value.forEach((item)=>{
-      item.key === 'schoolnum' ? item.value=areainSchool.length:''
+      item.key === 'schoolnum' ? item.value=trimData.length:''
      })
      })
-     tableData.value=areainSchool
+     //console.log(areainSchool.length,'学校数量')
+     console.log(trimData,'清理过后的')
+     tableData.value=trimData
   }
   }
 }
 }
 function detailsSchool(value){
 function detailsSchool(value){

+ 28 - 8
TEAMModelBI/ClientApp/src/view/product/index.vue

@@ -169,7 +169,7 @@
     <div class="data-tables">
     <div class="data-tables">
       <el-auto-resizer>
       <el-auto-resizer>
         <template #default="{ height, width }">
         <template #default="{ height, width }">
-          <el-table-v2 :columns="columns" :data="filterdata" :width="width" :height="height" :sort-by="sortState" @column-sort="onSort" fixed />
+          <el-table-v2 v-model:sort-state="sortState" :columns="columns" :data="filterdata" :width="width" :height="height" @column-sort="onSort" fixed />
         </template>
         </template>
       </el-auto-resizer>
       </el-auto-resizer>
     </div>
     </div>
@@ -303,6 +303,7 @@ let columns = ref([
     title: "教室数",//显示在单元格表头的文本
     title: "教室数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "tmidCnt",
     key: "tmidCnt",
@@ -310,6 +311,7 @@ let columns = ref([
     title: "教师数",//显示在单元格表头的文本
     title: "教师数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "stuShow",
     key: "stuShow",
@@ -317,6 +319,7 @@ let columns = ref([
     title: "学生人数",//显示在单元格表头的文本
     title: "学生人数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "lessonRecord",
     key: "lessonRecord",
@@ -324,6 +327,7 @@ let columns = ref([
     title: "课堂总数",//显示在单元格表头的文本
     title: "课堂总数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "lessonLengMin",
     key: "lessonLengMin",
@@ -331,6 +335,7 @@ let columns = ref([
     title: "课堂总时数",//显示在单元格表头的文本
     title: "课堂总时数",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "tGreen",
     key: "tGreen",
@@ -338,6 +343,7 @@ let columns = ref([
     title: "T绿灯",//显示在单元格表头的文本
     title: "T绿灯",//显示在单元格表头的文本
     width: 100,//当前列的宽度,必须设置
     width: 100,//当前列的宽度,必须设置
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "date",
     key: "date",
@@ -345,6 +351,7 @@ let columns = ref([
     title: "时间",
     title: "时间",
     width: 100,
     width: 100,
     headerClass: 'general',
     headerClass: 'general',
+    sortable:true
   },
   },
   {
   {
     key: "handle",
     key: "handle",
@@ -391,13 +398,21 @@ columns.value[0].headerCellRenderer = (props = HeaderCellSlotProps) => {
       )
       )
     }
     }
 const sortState = ref({
 const sortState = ref({
-  key: 'name',
-  order: TableV2SortOrder.ASC,
+  'deviceCnt':TableV2SortOrder.ASC,
+  'tmidCnt': TableV2SortOrder.ASC,
+  'stuShow': TableV2SortOrder.ASC,
+  'lessonRecord':TableV2SortOrder.ASC,
+  'lessonLengMin':TableV2SortOrder.ASC,
+  'tGreen':TableV2SortOrder.ASC,
+  'date':TableV2SortOrder.ASC,
 })
 })
-const onSort = (sortBy) => {
-  console.log(sortBy)
-  filterdata.value = filterdata.value.reverse()
-  sortState.value = sortBy
+const onSort = ({key,order}) => {
+  console.log(key,order)
+  sortState.value[key] = order
+  let field=key;let modes=order;let allData=filterdata.value
+  modes === 'desc' ? allData.sort((a,b)=> b[field]-a[field]): allData.sort((a,b)=> a[field]-b[field])
+  filterdata.value=allData
+  console.log(allData)
 }
 }
 const searchColumns = [
 const searchColumns = [
   {
   {
@@ -770,6 +785,8 @@ function serachToresult (startTime, endTime, product, schools, unit) {
           items.id === areIds ? item.name=items.name:''
           items.id === areIds ? item.name=items.name:''
         })
         })
         }
         }
+        //去重schollId
+        item.schoolId=[...new Set(item.schoolId)]
        })
        })
       //someDataMerge(res.data)
       //someDataMerge(res.data)
       // console.log(nameText,'名字')
       // console.log(nameText,'名字')
@@ -1265,7 +1282,10 @@ function someDataMerge(arr){
     acc.deviceAuthList = acc.deviceAuthList.concat(cur.deviceAuthList);
     acc.deviceAuthList = acc.deviceAuthList.concat(cur.deviceAuthList);
     acc.deviceList=acc.deviceList.concat(cur.deviceList)
     acc.deviceList=acc.deviceList.concat(cur.deviceList)
     acc.deviceNoAuthList=acc.deviceNoAuthList.concat(cur.deviceNoAuthList)
     acc.deviceNoAuthList=acc.deviceNoAuthList.concat(cur.deviceNoAuthList)
-    acc.school.push(cur.school)
+    //存在就不添加
+    let schoolResult=acc.school.findIndex(item=>item.name ===cur.school.name && item.name !==null)
+    console.log(schoolResult,'反馈的值')
+    schoolResult === -1 ? acc.school.push(cur.school):''
     acc.schoolId.push(cur.schoolId)
     acc.schoolId.push(cur.schoolId)
     acc.tmidList=acc.tmidList.concat(cur.tmidList)
     acc.tmidList=acc.tmidList.concat(cur.tmidList)
     // 返回累加器对象
     // 返回累加器对象

+ 10 - 3
TEAMModelBI/Controllers/Census/SchoolController.cs

@@ -1016,6 +1016,11 @@ namespace TEAMModelBI.Controllers.Census
                 lastYear.Add(item);
                 lastYear.Add(item);
                 }
                 }
             }
             }
+            //本學區虛擬學校數取得
+            string schcntSql = $"SELECT VALUE COUNT(c.id) FROM c WHERE c.areaId='{areaId}'";
+            int sbCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School", "Base", schcntSql);
+            int vrCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School", "VirtualBase", schcntSql);
+            int schCnt = sbCnt + vrCnt;
 
 
             StatsInfo statsInfo = null;
             StatsInfo statsInfo = null;
             statsInfo = SchoolStatsWay.GetAreaStats(cosmosClient, _option, statsInfos, scIds, area);
             statsInfo = SchoolStatsWay.GetAreaStats(cosmosClient, _option, statsInfos, scIds, area);
@@ -1200,7 +1205,7 @@ namespace TEAMModelBI.Controllers.Census
                 }
                 }
             }
             }
 
 
-            return Ok(new { state = RespondCode.Ok, areaScStats, schoolInfos, weekLess, assists = assits.Where((w, i) => assits.FindIndex(s => s.id.Equals(w.id)) == i).ToList(), saless = saless.Where((w, i) => saless.FindIndex(f => f.id.Equals(w.id)) == i).ToList(), useSize, typeStics = typeStics.ToList() });
+            return Ok(new { state = RespondCode.Ok, areaScStats, schCnt, schoolInfos, weekLess, assists = assits.Where((w, i) => assits.FindIndex(s => s.id.Equals(w.id)) == i).ToList(), saless = saless.Where((w, i) => saless.FindIndex(f => f.id.Equals(w.id)) == i).ToList(), useSize, typeStics = typeStics.ToList() });
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -1239,7 +1244,8 @@ namespace TEAMModelBI.Controllers.Census
                 easyInfos.Add(item);
                 easyInfos.Add(item);
             }
             }
 
 
-            int scCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "Normal", "Base", sql);
+            int scCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School", "Base", sql);
+            int vrCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School", "VirtualBase", sql);
             int scWeekCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "Normal", "Base", $"{sql} where c.createTime >= {weekS} and c.createTime <= {weekE}");
             int scWeekCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "Normal", "Base", $"{sql} where c.createTime >= {weekS} and c.createTime <= {weekE}");
             int scMonthCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "Normal", "Base", $"{sql} where c.createTime >= {mthS} and c.createTime <= {mthE}");
             int scMonthCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "Normal", "Base", $"{sql} where c.createTime >= {mthS} and c.createTime <= {mthE}");
             List<string> scId = new();
             List<string> scId = new();
@@ -1258,7 +1264,7 @@ namespace TEAMModelBI.Controllers.Census
             if (statsInfo != null)
             if (statsInfo != null)
             {
             {
                 allScStats.areaCnt = easyInfos.Count;
                 allScStats.areaCnt = easyInfos.Count;
-                allScStats.sc = statsInfos.Count;
+                //allScStats.sc = statsInfos.Count;
                 allScStats.weekSc = scWeekCnt;
                 allScStats.weekSc = scWeekCnt;
                 allScStats.monthSc = scMonthCnt;
                 allScStats.monthSc = scMonthCnt;
                 allScStats.tch = statsInfo.tch;
                 allScStats.tch = statsInfo.tch;
@@ -1315,6 +1321,7 @@ namespace TEAMModelBI.Controllers.Census
                     allScStats.srStats.finish = statsInfo.study.finish;
                     allScStats.srStats.finish = statsInfo.study.finish;
                 }
                 }
             }
             }
+            allScStats.sc = scCnt + vrCnt; //學校數
 
 
             return Ok(new { state = RespondCode.Ok, allScStats, areaGroup });
             return Ok(new { state = RespondCode.Ok, allScStats, areaGroup });
         }
         }

+ 0 - 1
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -1478,7 +1478,6 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                     //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} blob刷新完成!", GroupNames.醍摩豆服務運維群組);
                                     //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} blob刷新完成!", GroupNames.醍摩豆服務運維群組);
                                     await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobname}" }, _serviceBus, _configuration, _azureRedis);
                                     await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobname}" }, _serviceBus, _configuration, _azureRedis);
                                     msgs.Add(update);
                                     msgs.Add(update);
-
                                     DoLessonStudentRecord(_dingDing, _snowflakeId, lessonRecord, scope, client, school, tmdid, teacher, _serviceBus, _azureStorage, _configuration, lessonBase);
                                     DoLessonStudentRecord(_dingDing, _snowflakeId, lessonRecord, scope, client, school, tmdid, teacher, _serviceBus, _azureStorage, _configuration, lessonBase);
 
 
                                 }
                                 }

+ 28 - 22
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs

@@ -163,31 +163,37 @@ namespace TEAMModelOS.SDK.DI
                 return (new CosmosDBResult<T> { list = list, ru = RU, continuationToken = continuationToken });
                 return (new CosmosDBResult<T> { list = list, ru = RU, continuationToken = continuationToken });
             }
             }
 
 
-            await foreach (var item in container.GetItemQueryStreamIterator(queryText: sql, continuationToken: continuationToken, 
-                requestOptions: new QueryRequestOptions { MaxItemCount = pageSize, PartitionKey = new PartitionKey(partitionkey) }) )
-            {
-                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+            try {
+                await foreach (var item in container.GetItemQueryStreamIterator(queryText: sql, continuationToken: continuationToken,
+                 requestOptions: new QueryRequestOptions { MaxItemCount = pageSize, PartitionKey = new PartitionKey(partitionkey) }))
                 {
                 {
-                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray()) {
-                        list.Add(obj.ToObject<T>());
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            list.Add(obj.ToObject<T>());
+                        }
+                    }
+                    if (sql.Contains(" distinct ", StringComparison.OrdinalIgnoreCase)
+                        || (sql.Contains("order ", StringComparison.OrdinalIgnoreCase)
+                        && !sql.Contains(".order ", StringComparison.OrdinalIgnoreCase)))
+                    {
+                        continuationToken = null;
+                    }
+                    else
+                    {
+                        continuationToken = item.GetContinuationToken();
+                    }
+                    RU = item.RU();
+                    if (pageSize.HasValue && pageSize.Value >= 0 && list.Count >= pageSize)
+                    {
+                        break;
                     }
                     }
                 }
                 }
-                if (sql.Contains(" distinct ", StringComparison.OrdinalIgnoreCase)
-                    || (sql.Contains("order ", StringComparison.OrdinalIgnoreCase) 
-                    && !sql.Contains(".order ", StringComparison.OrdinalIgnoreCase)))
-                {
-                    continuationToken = null;
-                }
-                else
-                {
-                    continuationToken = item.GetContinuationToken();
-                }
-                RU = item.RU();
-                if (pageSize.HasValue && pageSize.Value >= 0 && list.Count >= pageSize)
-                {
-                    break;
-                }
+            }
+            catch (Exception ex) { 
+                Console.WriteLine(ex.ToString());
             }
             }
             //记录日志,RU开销大于400(开发测试),1000(正式)
             //记录日志,RU开销大于400(开发测试),1000(正式)
             return (new CosmosDBResult<T> { list = list, ru = RU, continuationToken = continuationToken }); ;
             return (new CosmosDBResult<T> { list = list, ru = RU, continuationToken = continuationToken }); ;

+ 4 - 0
TEAMModelOS.SDK/Models/Cosmos/OpenEntity/OStudent.cs

@@ -94,6 +94,10 @@ namespace TEAMModelOS.SDK.Models.Cosmos.OpenEntity
     /// </summary>
     /// </summary>
     public class OAnswer
     public class OAnswer
     {
     {
+        /// <summary>
+        /// 推送时间戳
+        /// </summary>
+        public long time { get; set;}
         /// <summary>
         /// <summary>
         /// 答题id
         /// 答题id
         /// </summary>
         /// </summary>

+ 655 - 102
TEAMModelOS.SDK/Models/Cosmos/School/ScoreCalc.cs

@@ -1,4 +1,5 @@
-using System;
+using DocumentFormat.OpenXml.Spreadsheet;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
@@ -15,8 +16,9 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         {
         {
             pk = "ScoreCalc";
             pk = "ScoreCalc";
             members = new List<ScoreCalcMember>();
             members = new List<ScoreCalcMember>();
-            scores = new List<double>();
-            scoresOrg = new List<double>();
+            //scores = new List<double>();
+            //scoresOrg = new List<double>();
+            editScores = new List<double>();
         }
         }
         /// <summary>
         /// <summary>
         /// 名稱
         /// 名稱
@@ -41,11 +43,15 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各成員成績總覽
         /// 各成員成績總覽
         /// </summary>
         /// </summary>
-        public List<double> scores { get; set; }
+        //public List<double> scores { get; set; }
         /// <summary>
         /// <summary>
         /// 各成員成績總覽最初系統計算結果
         /// 各成員成績總覽最初系統計算結果
         /// </summary>
         /// </summary>
-        public List<double> scoresOrg { get; set; }
+        //public List<double> scoresOrg { get; set; }
+        /// <summary>
+        /// 各學生最後成績的加減分
+        /// </summary>
+        public List<double> editScores { get; set; }
         /// <summary>
         /// <summary>
         /// 總覽分項權重類型 count:加權 | percentage:百分比
         /// 總覽分項權重類型 count:加權 | percentage:百分比
         /// </summary>
         /// </summary>
@@ -58,62 +64,62 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
     {
     {
         public ScoreCalcActivityBase()
         public ScoreCalcActivityBase()
         {
         {
-            pk = "ScoreCalc";
+            pk = "ScoreCalcAct";
             itemRates = new List<double>();
             itemRates = new List<double>();
-            itemScores = new List<double>();
-            itemScoresOrg = new List<double>();
-            stuScores = new List<double>();
-            stuActScores = new List<List<double>>();
-            stuActScoresOrg = new List<List<double>>();
+            //itemScores = new List<double>();
+            //itemScoresOrg = new List<double>();
+            //stuScores = new List<double>();            
         }
         }
         /// <summary>
         /// <summary>
         /// 成績計算ID
         /// 成績計算ID
         /// </summary>
         /// </summary>
         public string scorecalcId { get; set; }
         public string scorecalcId { get; set; }
         /// <summary>
         /// <summary>
-        /// 類型 exam:評量 | homework:作業 | lessonrecord:課堂紀錄
+        /// 活動名稱
         /// </summary>
         /// </summary>
-        public string type { get; set; }
+        public string name { get; set; }
         /// <summary>
         /// <summary>
-        /// 各活動權重
+        /// 類型 exam:評量 | homework:作業 | lessonrecord:課堂紀錄
         /// </summary>
         /// </summary>
-        public List<double> itemRates { get; set; }
+        public string type { get; set; }
         /// <summary>
         /// <summary>
-        /// 各活動權重類型 count:加權 | percentage:百分比
+        /// 總加權數
         /// </summary>
         /// </summary>
-        public string itemRateType { get; set; }
+        public double rate { get; set; }
         /// <summary>
         /// <summary>
-        /// 各活動分數最終結果
+        /// 個學生最後成績的加減分
         /// </summary>
         /// </summary>
-        public List<double> itemScores { get; set; }
+        public List<double> editScores { get; set; }
         /// <summary>
         /// <summary>
-        /// 各活動分數最初系統計算結果
+        /// 各活動權重
         /// </summary>
         /// </summary>
-        public List<double> itemScoresOrg { get; set; }
+        public List<double> itemRates { get; set; }
         /// <summary>
         /// <summary>
-        /// 最終成績
+        /// 各活動權重類型 count:加權 | percentage:百分比
         /// </summary>
         /// </summary>
-        public double score { get; set; }
+        //public string itemRateType { get; set; }
         /// <summary>
         /// <summary>
-        /// 最終成績系統計算結果
+        /// 各活動分數最終結果 - 一門課全部學生的平均 - 編輯後
         /// </summary>
         /// </summary>
-        public double scoreOrg { get; set; }
+        //public List<double> itemScores { get; set; }
         /// <summary>
         /// <summary>
-        /// 總加權數
+        /// 各活動分數最初系統計算結果 - 一門課全部學生的平均 - 原始
         /// </summary>
         /// </summary>
-        public double rate { get; set; }
+        //public List<double> itemScoresOrg { get; set; }
         /// <summary>
         /// <summary>
-        /// 各學生所有活動結算成績
+        /// 最終成績 - 一個項目總平均 - 編輯後
         /// </summary>
         /// </summary>
-        public List<double> stuScores { get; set; }
+        //public double score { get; set; }
         /// <summary>
         /// <summary>
-        /// 各活動所屬學生成績
+        /// 最終成績系統計算結果 - 一個項目總平均 - 原始
         /// </summary>
         /// </summary>
-        public List<List<double>> stuActScores { get; set; }
+        //public double scoreOrg { get; set; }
+
         /// <summary>
         /// <summary>
-        /// 各活動所屬學生成績最初系統計算結果
+        /// 各學生所有活動結算成績 - 此項目所有學生的計算後分數
         /// </summary>
         /// </summary>
-        public List<List<double>> stuActScoresOrg { get; set; }
+        //public List<double> stuScores { get; set; }
+
     }
     }
     /// <summary>
     /// <summary>
     /// 成績計算總覽分項-評量、作業
     /// 成績計算總覽分項-評量、作業
@@ -123,35 +129,62 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         public ScoreCalcActivity()
         public ScoreCalcActivity()
         {
         {
             items = new List<ScoreCalcActivityItems>();
             items = new List<ScoreCalcActivityItems>();
+            stuActScores = new List<List<double>>();
+            stuActScoresOrg = new List<List<double>>();
         }
         }
         /// <summary>
         /// <summary>
         /// 被選取的活動列表
         /// 被選取的活動列表
         /// </summary>
         /// </summary>
         public List<ScoreCalcActivityItems> items { get; set; }
         public List<ScoreCalcActivityItems> items { get; set; }
+        /// <summary>
+        /// 各活動所屬學生成績
+        /// </summary>
+        public List<List<double>> stuActScores { get; set; }
+        /// <summary>
+        /// 各活動所屬學生成績最初系統計算結果
+        /// </summary>
+        public List<List<double>> stuActScoresOrg { get; set; }
     }
     }
     /// <summary>
     /// <summary>
     /// 成績計算總覽分項-課堂紀錄
     /// 成績計算總覽分項-課堂紀錄
     /// </summary>
     /// </summary>
-    public class ScoreCalcLsRecord : CosmosEntity
+    public class ScoreCalcLsRecord : ScoreCalcActivityBase
     {
     {
         public ScoreCalcLsRecord()
         public ScoreCalcLsRecord()
         {
         {
             items = new List<ScoreCalcActivityItems>();
             items = new List<ScoreCalcActivityItems>();
 
 
-            stuActAttendOrgVals = new List<List<string>>();
+            stuActAttendOrgVals = new List<List<double>>();
             stuActAttendScores = new List<List<double>>();
             stuActAttendScores = new List<List<double>>();
-            stuAttendScores = new List<double>();
-            stuActPointOrgVals = new List<List<int>>();
+            //stuAttendScores = new List<double>();
+            stuActPointOrgVals = new List<List<double>>();
             stuActPointScores = new List<List<double>>();
             stuActPointScores = new List<List<double>>();
-            stuPointScores = new List<double>();
-            stuActItactOrgVals = new List<List<int>>();
+            //stuPointScores = new List<double>();
+            stuActItactOrgVals = new List<List<double>>();
             stuActItactScores = new List<List<double>>();
             stuActItactScores = new List<List<double>>();
-            stuItactScores = new List<double>();
+            //stuItactScores = new List<double>();
         }
         }
         /// <summary>
         /// <summary>
+        /// 出席加權數
+        /// </summary>
+        public double attendRate { get; set; }
+        /// <summary>
+        /// 記分板加權數
+        /// </summary>
+        public double pointRate { get; set; }
+        /// <summary>
+        /// 互動加權數
+        /// </summary>
+        public double itactRate { get; set; }
+        /// <summary>
+        /// 總加權數
+        /// </summary>
+        /// <summary>
         /// 被選取的課堂紀錄列表
         /// 被選取的課堂紀錄列表
         /// </summary>
         /// </summary>
         public List<ScoreCalcActivityItems> items { get; set; }
         public List<ScoreCalcActivityItems> items { get; set; }
+
+        #region ==========出席==========
         /// <summary>
         /// <summary>
         /// 課堂紀錄出席 採用的公式ID (依照items順序 第一個課堂紀錄公式 第二個...)
         /// 課堂紀錄出席 採用的公式ID (依照items順序 第一個課堂紀錄公式 第二個...)
         /// </summary>
         /// </summary>
@@ -159,7 +192,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各學生各課堂紀錄出席 系統原值
         /// 各學生各課堂紀錄出席 系統原值
         /// </summary>
         /// </summary>
-        public List<List<string>> stuActAttendOrgVals { get; set; }
+        public List<List<double>> stuActAttendOrgVals { get; set; }
         /// <summary>
         /// <summary>
         /// 各學生各課堂紀錄出席 分數
         /// 各學生各課堂紀錄出席 分數
         /// </summary>
         /// </summary>
@@ -167,7 +200,10 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各學生所有課堂紀錄出席 分數
         /// 各學生所有課堂紀錄出席 分數
         /// </summary>
         /// </summary>
-        public List<double> stuAttendScores { get; set; }
+        //public List<double> stuAttendScores { get; set; }
+        #endregion
+
+        #region ==========記分板==========
         /// <summary>
         /// <summary>
         /// 課堂紀錄記分板 採用的公式ID
         /// 課堂紀錄記分板 採用的公式ID
         /// </summary>
         /// </summary>
@@ -175,7 +211,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各學生各課堂紀錄記分板 系統原值
         /// 各學生各課堂紀錄記分板 系統原值
         /// </summary>
         /// </summary>
-        public List<List<int>> stuActPointOrgVals { get; set; }
+        public List<List<double>> stuActPointOrgVals { get; set; }
         /// <summary>
         /// <summary>
         /// 各學生各課堂紀錄記分板 分數
         /// 各學生各課堂紀錄記分板 分數
         /// </summary>
         /// </summary>
@@ -183,7 +219,10 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各學生所有課堂紀錄記分板 分數
         /// 各學生所有課堂紀錄記分板 分數
         /// </summary>
         /// </summary>
-        public List<double> stuPointScores { get; set; }
+        //public List<double> stuPointScores { get; set; }
+        #endregion
+
+        #region ==========互動==========
         /// <summary>
         /// <summary>
         /// 課堂紀錄互動 採用的公式ID
         /// 課堂紀錄互動 採用的公式ID
         /// </summary>
         /// </summary>
@@ -191,7 +230,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各學生各課堂紀錄互動 系統原值
         /// 各學生各課堂紀錄互動 系統原值
         /// </summary>
         /// </summary>
-        public List<List<int>> stuActItactOrgVals { get; set; }
+        public List<List<double>> stuActItactOrgVals { get; set; }
         /// <summary>
         /// <summary>
         /// 各學生各課堂紀錄互動 分數
         /// 各學生各課堂紀錄互動 分數
         /// </summary>
         /// </summary>
@@ -199,19 +238,9 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 各學生所有課堂紀錄互動 分數
         /// 各學生所有課堂紀錄互動 分數
         /// </summary>
         /// </summary>
-        public List<double> stuItactScores { get; set; }
-        /// <summary>
-        /// 出席加權數
-        /// </summary>
-        public double attendRate { get; set; }
-        /// <summary>
-        /// 記分板加權數
-        /// </summary>
-        public double pointRate { get; set; }
-        /// <summary>
-        /// 互動加權數
-        /// </summary>
-        public double itactRate { get; set; }
+        //public List<double> stuItactScores { get; set; }
+        #endregion
+
     }
     }
 
 
     public class ScoreCalcMember
     public class ScoreCalcMember
@@ -243,12 +272,12 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 發布對象 學校(school)/個人(private)
         /// 發布對象 學校(school)/個人(private)
         /// </summary>
         /// </summary>
-        public string scope { get; set; }
+        //public string scope { get; set; }
         /// <summary>
         /// <summary>
         /// (評量專有)擁有者 學校(school)/個人(teacher)
         /// (評量專有)擁有者 學校(school)/個人(teacher)
         /// </summary>
         /// </summary>
-        public string owner { get; set; }
-        
+        //public string owner { get; set; }
+
         /// <summary>
         /// <summary>
         /// 活動名稱
         /// 活動名稱
         /// </summary>
         /// </summary>
@@ -256,15 +285,15 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// <summary>
         /// 活動進度 pending 待发布 | going 已发布 | finish 已结束
         /// 活動進度 pending 待发布 | going 已发布 | finish 已结束
         /// </summary>
         /// </summary>
-        public string progress { get; set; }
+        //public string progress { get; set; }
         /// <summary>
         /// <summary>
         /// 活動評分狀態(評量專用) 0未评分,1已评分
         /// 活動評分狀態(評量專用) 0未评分,1已评分
         /// </summary>
         /// </summary>
-        public int sStatus { get; set; } = 0;
+        //public int sStatus { get; set; } = 0;
         /// <summary>
         /// <summary>
         /// 評測類型(評量專用) 0:線上評量 | 1:課中評量 | 2.卷卡合一
         /// 評測類型(評量專用) 0:線上評量 | 1:課中評量 | 2.卷卡合一
         /// </summary>
         /// </summary>
-        public string source { get; set; }
+        //public string source { get; set; }
         /// <summary>
         /// <summary>
         /// 創建時間 (milliseconds 13位數)
         /// 創建時間 (milliseconds 13位數)
         /// </summary>
         /// </summary>
@@ -275,94 +304,618 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         public bool use { get; set; }
         public bool use { get; set; }
     }
     }
     /// <summary>
     /// <summary>
-    /// 課堂紀錄
+    /// 老師成績計算公式 code:"ScoreCalcFunc-{TMID}"
+    /// </summary>
+    public class ScoreCalcFunc : CosmosEntity
+    {
+        public ScoreCalcFunc()
+        {
+            pk = "ScoreCalcActFormula";
+            keyvals = new List<ScoreCalcFuncTemplateKeyval>();
+        }
+
+        public string name { get; set; }
+        public string scorecalcActId { get; set; }
+        /// <summary>
+        /// 類型 exam:評量 | homework:作業 | lessonrecord:課堂紀錄
+        /// </summary>
+        public string type { get; set; }
+        /// <summary>
+        /// 種類 attend:出席 | point:得分版 | interaction:互動
+        /// </summary>
+        public string method { get; set; }
+        /// <summary>
+        /// 模板 simpleAttend: 簡單出席計算法 | attendRate:出席率計算法 | custom:自訂
+        /// </summary>
+        public string template { get; set; }
+        /// <summary>
+        /// 公式鍵值定義
+        /// </summary>
+        public List<ScoreCalcFuncTemplateKeyval> keyvals { get; set; }
+        /// <summary>
+        /// 公式內容
+        /// </summary>
+        public string content { get; set; }
+    }
+    public class ScoreCalcFuncTemplateKeyval
+    {
+        public string key { get; set; }
+        public string val { get; set; }
+        //public string type { get; set; }
+        //public string describe { get; set; }
+    }
+    /// <summary>
+    /// 評量活動取系統資料
     /// </summary>
     /// </summary>
-    public class ScoreCalcLsRecordItems
+    public class ExamItem
     {
     {
         /// <summary>
         /// <summary>
-        /// 課堂紀錄ID
+        /// 評量id
+        /// </summary>
+        public string examId { get; set; }
+        /// <summary>
+        /// 評量名稱
+        /// </summary>
+        public string name { get; set; }
+        /// <summary>
+        /// 評量學生Id列表
+        /// </summary>
+        public List<string> studentIds { get; set; }
+        /// <summary>
+        /// 評量分數列表
+        /// </summary>
+        public List<double> sum { get; set; }
+    }
+    /// <summary>
+    /// 取作業活動Id
+    /// </summary>
+    public class HomeworkItem
+    {
+        /// <summary>
+        /// 作業id
         /// </summary>
         /// </summary>
         public string id { get; set; }
         public string id { get; set; }
         /// <summary>
         /// <summary>
-        /// 課堂紀錄分區鍵
+        /// 作業名稱
+        /// </summary>
+        public string name { get; set; }
+        /// <summary>
+        /// 作業代碼 包含學生座號
         /// </summary>
         /// </summary>
         public string code { get; set; }
         public string code { get; set; }
         /// <summary>
         /// <summary>
-        /// 課堂紀錄名稱
+        /// 分數
         /// </summary>
         /// </summary>
-        public string name { get; set; }
+        public double score { get; set; }
         /// <summary>
         /// <summary>
-        /// 學校ID
+        /// pk
+        /// </summary>
+        public string pk { get; set; }
+        /// <summary>
+        /// school id
         /// </summary>
         /// </summary>
         public string school { get; set; }
         public string school { get; set; }
+    }
+
+    #region (四)更新成績統計首頁表資料用
+    /// <summary>
+    /// 更新成績統計首頁表資料 參數
+    /// </summary>
+    public class UpdateSscoreCalcRq
+    {
+        public UpdateSscoreCalcRq()
+        {
+            ScoreCalcAct = new List<ScoreCalcAct>();
+            editScores = new List<double>();
+        }
         /// <summary>
         /// <summary>
-        /// 上課時長(分)
+        /// 成績統計id
         /// </summary>
         /// </summary>
-        public double duration { get; set; } = 0;
+        public string id { get; set; }
         /// <summary>
         /// <summary>
-        /// 總計分
+        /// teammodelId
         /// </summary>
         /// </summary>
-        public double totalPoint { get; set; } = 0;
+        public string teammodelId { get; set; }
+
         /// <summary>
         /// <summary>
-        /// 學生總數(出席人數)
+        /// 成績統計名稱
         /// </summary>
         /// </summary>
-        public int mCount { get; set; } = 0;
+        public string name { get; set; }
         /// <summary>
         /// <summary>
-        /// 作品總數
+        /// 成績統計名稱
         /// </summary>
         /// </summary>
-        public int collateCount { get; set; } = 0;
+        public List<ScoreCalcAct> ScoreCalcAct { get; set; }
+
+        /// <summary>
+        /// 成績統計的加減分
+        /// </summary>
+        public List<double> editScores { get; set; }
+    }
+    /// <summary>
+    /// 更新成績統計首頁表資料 參數ScoreCalcAct
+    /// </summary>
+    public class ScoreCalcAct
+    {
+        public ScoreCalcAct()
+        {
+            editScores = new List<double>();
+        }
         /// <summary>
         /// <summary>
-        /// 學生互動總數
+        /// 項目id
         /// </summary>
         /// </summary>
-        public int clientInteractionCount { get; set; } = 0;
+        public string id { get; set; }
         /// <summary>
         /// <summary>
-        /// 測驗得分率
+        /// 項目類別
         /// </summary>
         /// </summary>
-        public double examPointRate { get; set; } = 0;
+        public string type { get; set; }
         /// <summary>
         /// <summary>
-        /// 是否使用(是否被勾選) true:使用
+        /// 出席比重
+        /// </summary>
+        public double attendRate { get; set; }
+        /// <summary>
+        /// 記分比重
+        /// </summary>
+        public double pointRate { get; set; }
+        /// <summary>
+        /// 互動比重
+        /// </summary>
+        public double itactRate { get; set; }
+        /// <summary>
+        /// 總比重
+        /// </summary>
+        public double rate { get; set; }
+        /// <summary>
+        /// 項目成績的加減分
+        /// </summary>
+        public List<double> editScores { get; set; }
+    }
+
+    #endregion
+
+    // 取物件Id用
+    public class ItemId
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        public string id { get; set; }
+    }
+
+    #region (六)更新公式設定(一次可以處理多個公式)資料用
+    /// <summary>
+    /// 更新公式資料 參數
+    /// </summary>
+    public class UpdateFormulaRq
+    {
+        public UpdateFormulaRq()
+        {
+            scoreCalcFunc = new List<ScoreCalcFuncRq>();
+        }
+        /// <summary>
+        /// 項目id
+        /// </summary>
+        public string scoreCalcActId { get; set; }
+        /// <summary>
+        /// teammodelId
+        /// </summary>
+        public string teammodelId { get; set; }
+        /// <summary>
+        /// 種類 attend:出席 | point:得分版 | interaction:互動
+        /// </summary>
+        public string method { get; set; }
+        /// <summary>
+        /// 公式資料列表
+        /// </summary>        
+        public List<ScoreCalcFuncRq> scoreCalcFunc { get; set; }
+    }
+
+    /// <summary>
+    /// 更新公式資料用的 細項參數
+    /// </summary>
+    public class ScoreCalcFuncRq: ScoreCalcFunc
+    {
+        /// <summary>
+        /// 是否為使用中的公式
         /// </summary>
         /// </summary>
         public bool use { get; set; }
         public bool use { get; set; }
     }
     }
+
+    #endregion
+
+    #region (九)更新項目及子項目資料
     /// <summary>
     /// <summary>
-    /// 老師成績計算公式 code:"ScoreCalcFunc-{TMID}"
+    /// Request 參數
     /// </summary>
     /// </summary>
-    public class ScoreCalcFunc : CosmosEntity
+    public class UpdateScoreCalcActRqBase
     {
     {
-        public ScoreCalcFunc()
+        /// <summary>
+        /// 活動id
+        /// </summary>
+        public string scoreCalcActId { get; set; }
+        /// <summary>
+        /// 活動名稱
+        /// </summary>
+        public string name { get; set; }
+        /// <summary>
+        /// 活動加權數
+        /// </summary>
+        public double rate { get; set; }
+    }
+    
+    public class UpdateActivityActRq : UpdateScoreCalcActRqBase
+    {
+        public UpdateActivityActRq()
         {
         {
-            pk = "ScoreCalc";
-            keyvals = new List<ScoreCalcFuncTemplateKeyval>();
+            items = new List<SubActActivity>();
         }
         }
+        /// <summary>
+        /// 活動子項目資料列表
+        /// </summary>
+        public List<SubActActivity> items { get; set; }
+    }
+   
+    public class UpdateLsRecordActRq : UpdateScoreCalcActRqBase
+    {
+        public UpdateLsRecordActRq()
+        {
+            items = new List<SubActLsRecord>();
+        }             
+        /// <summary>
+        /// 子項目資料列表
+        /// </summary>
+        public List<SubActLsRecord> items { get; set; }
+    }
+    #endregion
+
+    #region(十三)匯出原始成績資料
+    /// <summary>
+    /// 原始成績Base
+    /// </summary>
+    public class ExportOrgDataBase
+    {       
+        /// <summary>
+        /// 名稱
+        /// </summary>
+        public string name { get; set; }
+    }
+    /// <summary>
+    /// 活動成績大項
+    /// </summary>
+    public class ExportOrgActivityData : ExportOrgDataBase
+    {
+        public ExportOrgActivityData()
+        {
+            data = new List<ActivityScores>();
+        }
+        /// <summary>
+        /// 活動子項目資料列表
+        /// </summary>
+        public List<ActivityScores> data { get; set; }
+    }
+    /// <summary>
+    /// 課堂成績大項
+    /// </summary>
+    public class ExportOrgLsRecordData  : ExportOrgDataBase
+    {
+        public ExportOrgLsRecordData()
+        {
+            data = new List<LessonScores>();
+        }
+        /// <summary>
+        /// 課程原始分數資料
+        /// </summary>
+        public List<LessonScores> data { get; set; }
+    }
+
+    /// <summary>
+    /// 課堂分數欄位
+    /// </summary>
+    public class LessonScores
+    {
+        /// <summary>
+        /// 學生id
+        /// </summary>
         public string id { get; set; }
         public string id { get; set; }
+        /// <summary>
+        /// 名稱
+        /// </summary>
+        public string name { get; set; }
+        /// <summary>
+        /// 座號
+        /// </summary>
+        public string no { get; set; }
+        /// <summary>
+        /// 出席
+        /// </summary>
+        public double attend { get; set; }
+        /// <summary>
+        /// 記分板
+        /// </summary>
+        public double point { get; set; }
+        /// <summary>
+        ///互動
+        /// </summary>
+        public double interaction { get; set; }
+    }
+    /// <summary>
+    /// 活動分數欄位
+    /// </summary>
+    public class ActivityScores
+    {
+        /// <summary>
+        /// 學生id
+        /// </summary>
+        public string id { get; set; }
+        /// <summary>
+        /// 名稱
+        /// </summary>
+        public string name { get; set; }
+        /// <summary>
+        /// 座號
+        /// </summary>
+        public string no { get; set; }
+        /// <summary>
+        /// 分數
+        /// </summary>
+        public double score { get; set; }
+    }
+    #endregion
+
+    #region (十二)登錄指定子項目成績資料用
+
+    /// <summary>
+    /// 更新成績 參數
+    /// </summary>
+    public class UpdateScoreBase
+    {
+        /// <summary>
+        /// 活動項目id
+        /// </summary>
+        public string scoreCalcActId { get; set; }
+        /// <summary>
+        /// teammodelId
+        /// </summary>
+        public string teammodelId { get; set; }
+        /// <summary>
+        /// 子項目id
+        /// </summary>
+        public string id { get; set; }
+    }
+    /// <summary>
+    /// 更新課堂子項目成績 參數
+    /// </summary>
+    public class UpdateScoreLessonRq: UpdateScoreBase
+    {
+        public UpdateScoreLessonRq()
+        {
+            stuActAttendScores = new List<double>();
+            stuActPointScores = new List<double>();
+            stuActItactScores = new List<double>();
+        }
+        /// <summary>
+        /// 出席分數
+        /// </summary>
+        public List<double> stuActAttendScores { get; set; }
+        /// <summary>
+        /// 記分板分數
+        /// </summary>
+        public List<double> stuActPointScores { get; set; }
+        /// <summary>
+        /// 互動分數
+        /// </summary>
+        public List<double> stuActItactScores { get; set; }
+    }
+
+    /// <summary>
+    /// 更新活動子項目成績 參數
+    /// </summary>
+    public class UpdateScoreActivityRq : UpdateScoreBase
+    {
+        public UpdateScoreActivityRq()
+        {
+            scores = new List<double>();
+        }
+        /// <summary>
+        /// 分數
+        /// </summary>
+        public List<double> scores { get; set; }
+    }
+
+    #endregion
+
+
+    #region API回傳資料用
+
+    #region (二)查詢成績統計首頁表資料用
+    /// <summary>
+    /// 查詢總表-活動資料的Base
+    /// </summary>
+    public class ScoreCalcActDtoBase
+    {
+        public ScoreCalcActDtoBase()
+        {
+            editScores = new List<double>();
+        }
+        /// <summary>
+        /// 活動id
+        /// </summary>
+        public string id { get; set; }
+        /// <summary>
+        /// 活動名稱
+        /// </summary>
         public string name { get; set; }
         public string name { get; set; }
         /// <summary>
         /// <summary>
         /// 類型 exam:評量 | homework:作業 | lessonrecord:課堂紀錄
         /// 類型 exam:評量 | homework:作業 | lessonrecord:課堂紀錄
         /// </summary>
         /// </summary>
         public string type { get; set; }
         public string type { get; set; }
         /// <summary>
         /// <summary>
-        /// 種類 attend:出席 | point:得分版 | interaction:互動
+        /// 活動加權數
         /// </summary>
         /// </summary>
-        public string method { get; set; }
+        public double rate { get; set; }
         /// <summary>
         /// <summary>
-        /// 模板 simpleAttend: 簡單出席計算法 | attendRate:出席率計算法 | custom:自訂
+        /// 個學生最後成績的加減分
         /// </summary>
         /// </summary>
-        public string template { get; set; }
+        public List<double> editScores { get; set; }
+    }
+    /// <summary>
+    /// 查詢總表-活動資料的詳細列表資料
+    /// </summary>
+    public class ScoreCalcActivityActDto : ScoreCalcActDtoBase
+    {
+        public ScoreCalcActivityActDto()
+        {
+            items = new List<SubActActivity>();
+        }
         /// <summary>
         /// <summary>
-        /// 公式鍵值定義
+        /// 活動子項目資料列表
         /// </summary>
         /// </summary>
-        public List<ScoreCalcFuncTemplateKeyval> keyvals { get; set; }
+        public List<SubActActivity> items { get; set; }
+    }
+    /// <summary>
+    /// 查詢總表-活動資料課堂紀錄的詳細列表資料
+    /// </summary>
+    public class ScoreCalcLsRecordActDto : ScoreCalcActDtoBase
+    {
+        public ScoreCalcLsRecordActDto()
+        {
+            items = new List<SubActLsRecord>();
+            attendStates = new List<AttendStatesCalc>();
+        }
         /// <summary>
         /// <summary>
-        /// 公式內容
+        /// 出席占比重
         /// </summary>
         /// </summary>
-        public string content { get; set; }
+        public double attendRate { get; set; }
+        /// <summary>
+        /// 記分板占比重
+        /// </summary>
+        public double pointRate { get; set; }
+        /// <summary>
+        /// 互動占比重
+        /// </summary>
+        public double itactRate { get; set; }
+        /// <summary>
+        /// 出席公式
+        /// </summary>
+        public string stuAttendFunctionId { get; set; }
+        /// <summary>
+        /// 記分公式
+        /// </summary>
+        public string stuPointFunctionId { get; set; }
+        /// <summary>
+        /// 互動公式
+        /// </summary>
+        public string stuItactFunctionId { get; set; }
+        /// <summary>
+        /// 出席狀態統計資料
+        /// </summary>
+        public List<AttendStatesCalc> attendStates { get; set; }
+        /// <summary>
+        /// 子項目資料列表
+        /// </summary>
+        public List<SubActLsRecord> items { get; set; }
+    }
+    /// <summary>
+    /// 統計出席狀態
+    /// Uncall,0(未點名)
+    /// Attended,1(出席)
+    /// Absent,2(缺席)
+    /// DayOff,3(請假)
+    /// Absent_Sick,4(病假)
+    /// Absent_Personal,5(事假)
+    /// Absent_Official,6(公假)
+    /// </summary>
+    public class AttendStatesCalc
+    {
+        /// <summary>
+        /// 病假次數
+        /// </summary>
+        public int Absent_Sick { get; set; }
+        /// <summary>
+        /// 缺席次數
+        /// </summary>
+        public int Absent { get; set; }
+        /// <summary>
+        /// 事假次數
+        /// </summary>
+        public int Absent_Personal { get; set; }
+        /// <summary>
+        /// 公假次數
+        /// </summary>
+        public int Absent_Official { get; set; }
     }
     }
+    /// <summary>
+    /// 子項目欄位的Base
+    /// </summary>
+    public class SubActBase
+    {
+        /// <summary>
+        /// 子項目id
+        /// </summary>
+        public string id { get; set; }
+        /// <summary>
+        /// 子項目名稱
+        /// </summary>
+        public string name { get; set; }
+        /// <summary>
+        /// 子項目加權數
+        /// </summary>
+        public double rate { get; set; }
+        /// <summary>
+        /// 是否為勾選的項目
+        /// </summary>
+        public bool use { get; set; }
 
 
-    public class ScoreCalcFuncTemplateKeyval
+    }
+    /// <summary>
+    /// 活動子項目欄位
+    /// </summary>
+    public class SubActActivity : SubActBase
     {
     {
-        public string key { get; set; }
-        public string val { get; set; }
-        public string type { get; set; }
-        public string describe { get; set; }
+        public SubActActivity()
+        {
+            scores = new List<double>();
+        }
+        public List<double> scores { get; set; }
     }
     }
+    /// <summary>
+    /// 課堂紀錄子項目欄位
+    /// </summary>
+    public class SubActLsRecord : SubActBase
+    {
+        public SubActLsRecord()
+        {
+            stuActAttendScores = new List<double>();
+            stuActPointScores = new List<double>();
+            stuActItactScores = new List<double>();
+        }
+        /// <summary>
+        /// 出席分數
+        /// </summary>
+        public List<double> stuActAttendScores { get; set; }
+        /// <summary>
+        /// 記分板分數
+        /// </summary>
+        public List<double> stuActPointScores { get; set; }
+        /// <summary>
+        /// 互動分數
+        /// </summary>
+        public List<double> stuActItactScores { get; set; }
+    }
+    /// <summary>
+    /// 成績統計列表用資料
+    /// </summary>
+    public class Calc
+    {
+        /// <summary>
+        /// 成績統計id
+        /// </summary>
+        public string id { get; set; }
+        /// <summary>
+        /// 成績統計名稱
+        /// </summary>
+        public string name { get; set; }
+    }
+    #endregion
+
+    #endregion
 }
 }

+ 16 - 3
TEAMModelOS.SDK/Models/Cosmos/Student/OverallEducation.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
 
 
 namespace TEAMModelOS.SDK.Models
 namespace TEAMModelOS.SDK.Models
 {
 {
@@ -11,8 +12,8 @@ namespace TEAMModelOS.SDK.Models
     /// </summary>
     /// </summary>
     public class OverallEducation : CosmosEntity
     public class OverallEducation : CosmosEntity
     {
     {
-        // code = "hbcn-studentId"
-        // id="2021-semesterId"
+        // code = "OverallEducation-hbcn"
+        // id="2021-semesterId-studentId"
         /// <summary>
         /// <summary>
         /// 
         /// 
         /// </summary>
         /// </summary>
@@ -70,6 +71,10 @@ namespace TEAMModelOS.SDK.Models
         /// 劳动 
         /// 劳动 
         /// </summary>
         /// </summary>
         public List<EducationScore> labour { get; set; } = new List<EducationScore>();
         public List<EducationScore> labour { get; set; } = new List<EducationScore>();
+        /// <summary>
+        /// 学生课堂积分
+        /// </summary>
+        public List<StudentLessonRecord> lessonScore { get; set; } = new List<StudentLessonRecord>();
 
 
     }
     }
     public class EducationScore {
     public class EducationScore {
@@ -131,7 +136,11 @@ namespace TEAMModelOS.SDK.Models
         /// <summary>
         /// <summary>
         /// 项目分数
         /// 项目分数
         /// </summary>
         /// </summary>
-        public double score { get; set; }//
+        public double score { get; set; }
+        /// <summary>
+        ///细项配分满分
+        /// </summary>
+        public double totalScore { get; set; } = 100;
         /// <summary>
         /// <summary>
         /// 评分等级
         /// 评分等级
         /// </summary>
         /// </summary>
@@ -140,6 +149,10 @@ namespace TEAMModelOS.SDK.Models
         /// 细项考核时间
         /// 细项考核时间
         /// </summary>
         /// </summary>
         public long time { get; set; }
         public long time { get; set; }
+        /// <summary>
+        /// 细项类型,用于评测(评测的科目),艺术(音乐,美术,舞蹈等)具体分类
+        /// </summary>
+        public string type { get; set; }
     }
     }
 
 
 
 

+ 105 - 3
TEAMModelOS.SDK/Models/Service/LessonService.cs

@@ -1,7 +1,10 @@
 using Azure.Core;
 using Azure.Core;
 using Azure.Cosmos;
 using Azure.Cosmos;
 using Azure.Messaging.ServiceBus;
 using Azure.Messaging.ServiceBus;
+using DocumentFormat.OpenXml.Drawing.Charts;
+using DocumentFormat.OpenXml.VariantTypes;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
+using MathNet.Numerics.Distributions;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Hosting;
 using OpenXmlPowerTools;
 using OpenXmlPowerTools;
@@ -16,6 +19,7 @@ using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
 using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
 using TEAMModelOS.SDK.Services;
 using TEAMModelOS.SDK.Services;
 
 
 namespace TEAMModelOS.SDK.Models.Service
 namespace TEAMModelOS.SDK.Models.Service
@@ -171,18 +175,26 @@ namespace TEAMModelOS.SDK.Models.Service
             try
             try
             {
             {
                 int year = DateTimeOffset.UtcNow.Year;
                 int year = DateTimeOffset.UtcNow.Year;
+                string hs = lessonBase?.report?.clientSummaryList.ToJsonString();
                 var clientSummaryList = lessonBase?.report?.clientSummaryList?.Where(x => x.groupTaskCompleteCount != 0 || x.groupScore != 0 || x.score != 0 || x.tnteractScore != 0 || x.taskCompleteCount != 0);
                 var clientSummaryList = lessonBase?.report?.clientSummaryList?.Where(x => x.groupTaskCompleteCount != 0 || x.groupScore != 0 || x.score != 0 || x.tnteractScore != 0 || x.taskCompleteCount != 0);
                 IEnumerable<LessonStudent> students = new List<LessonStudent>();
                 IEnumerable<LessonStudent> students = new List<LessonStudent>();
                 if (clientSummaryList.Any())
                 if (clientSummaryList.Any())
                 {
                 {
-                    students = lessonBase.student.Where(x => clientSummaryList.Select(x => x.seatID).Contains(x.seatID));
+                    var ids = clientSummaryList.Select(x => x.seatID);
+                    students = lessonBase.student.Where(x => ids.Contains(x.seatID));
                 }
                 }
+                List<Student> studentsBase = new List<Student>();
                 var stuids = students.Where(x => x.type == 2);
                 var stuids = students.Where(x => x.type == 2);
                 if (stuids.Any())
                 if (stuids.Any())
                 {
                 {
                     stuids.ToList().ForEach(x => {
                     stuids.ToList().ForEach(x => {
                         x.school = string.IsNullOrWhiteSpace(x.school) ? school : x.school;
                         x.school = string.IsNullOrWhiteSpace(x.school) ? school : x.school;
                     });
                     });
+                  var result= await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>($"select value c from c where c.id in ({string.Join(",",stuids.Select(d=>$"'{d.id}'"))})", $"Base-{school}");
+                    if (result.list.Any()) { 
+                        studentsBase = result.list;
+                    
+                    }
                 }
                 }
                 var groups = stuids.Where(z => !string.IsNullOrWhiteSpace(z.school)).GroupBy(x => x.school).Select(y => new { code = y.Key, list = y.ToList() });
                 var groups = stuids.Where(z => !string.IsNullOrWhiteSpace(z.school)).GroupBy(x => x.school).Select(y => new { code = y.Key, list = y.ToList() });
                 List<StudentScoreRecord> lessonStudentRecords = new List<StudentScoreRecord>();
                 List<StudentScoreRecord> lessonStudentRecords = new List<StudentScoreRecord>();
@@ -205,8 +217,17 @@ namespace TEAMModelOS.SDK.Models.Service
                         lessonStudentRecords.Add(item);
                         lessonStudentRecords.Add(item);
                     }
                     }
                 }
                 }
-                List<Task<ItemResponse<StudentScoreRecord>>> records = new List<Task<ItemResponse<StudentScoreRecord>>>();
-                stuids.ToList().ForEach(x => {
+                School schoolBase = null;
+                Period period = null;
+                (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) dataSemester = new(null,-1, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow) ;
+                if (!string.IsNullOrWhiteSpace(school)) {
+                     schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
+                     period = schoolBase.period.Find(x => x.id.Equals($"{lessonRecord.periodId}"));
+                     dataSemester= SchoolService.GetSemester(period);
+                }
+                List <Task<ItemResponse<StudentScoreRecord>>> records = new List<Task<ItemResponse<StudentScoreRecord>>>();
+                List<Task<ItemResponse<OverallEducation>>> overallEducations   = new List<Task<ItemResponse<OverallEducation>>>();
+                stuids.ToList().ForEach(async x => {
                     var record = lessonStudentRecords.Find(l => l.stuid.Equals(x.id) && l.code.Equals($"StudentScoreRecord") && l.school.Equals(x.school));
                     var record = lessonStudentRecords.Find(l => l.stuid.Equals(x.id) && l.code.Equals($"StudentScoreRecord") && l.school.Equals(x.school));
                     ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
                     ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
                     if (record != null)
                     if (record != null)
@@ -281,6 +302,82 @@ namespace TEAMModelOS.SDK.Models.Service
                     record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
                     record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
                     record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
                     record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
                     record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
                     record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
+                    if (dataSemester.currSemester != null  && (clientSummaryList.groupScore>0  || clientSummaryList.score > 0 || clientSummaryList.tnteractScore > 0)) {
+                        string oid = $"{dataSemester.studyYear}-{dataSemester.currSemester.id}-{record.stuid}"; 
+                        string ocode = $"OverallEducation-{school}";
+                        var student= studentsBase.Find(stu => stu.id.Equals(x.id));
+                        Azure.Response response = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReadItemStreamAsync(oid, new PartitionKey(ocode));
+                        OverallEducation overallEducation = null;
+                        if (response.Status != 200) {
+                            overallEducation = new OverallEducation
+                            {
+                                id =oid,
+                                code = $"OverallEducation-{school}",
+                                pk = "OverallEducation",
+                                ttl = -1,
+                                name = x.name,
+                                classId = student?.classId,
+                                schoolCode = $"{school}",
+                                semesterId = dataSemester.currSemester.id,
+                                year = dataSemester.studyYear,
+                                periodId = $"{period.id}",
+                                stuYear = student.year,
+                                studentId = x.id,
+                                lessonScore= new List<StudentLessonRecord> { new StudentLessonRecord
+                             {
+                                 gscore = clientSummaryList.groupScore,
+                                 pscore = clientSummaryList.score,
+                                 tscore = clientSummaryList.tnteractScore,
+                                 tmdid = teacher.id,
+                                 school = school,
+                                 scope = lessonRecord.scope,
+                                 lessonId = lessonRecord.id,
+                                 courseId = lessonRecord.courseId,
+                                 periodId = lessonRecord.periodId,
+                                 subjectId = lessonRecord.subjectId,
+                                 time= lessonRecord.startTime
+                             }}
+                            };
+                        }
+                        else {
+                            overallEducation=JsonDocument.Parse(response.Content).RootElement.ToObject<OverallEducation>();
+                            var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(lessonRecord.id));
+                            if (hasrecord != null)
+                            {
+                                hasrecord.gscore = clientSummaryList.groupScore;
+                                hasrecord.pscore = clientSummaryList.score;
+                                hasrecord.tscore = clientSummaryList.tnteractScore;
+                                hasrecord.tmdid = teacher.id;
+                                hasrecord.school = school;
+                                hasrecord.scope = lessonRecord.scope;
+                                hasrecord.lessonId = lessonRecord.id;
+                                hasrecord.courseId = lessonRecord.courseId;
+                                hasrecord.periodId = lessonRecord.periodId;
+                                hasrecord.subjectId = lessonRecord.subjectId;
+                                hasrecord.time = lessonRecord.startTime;
+                            }
+                            else
+                            {
+                                overallEducation.lessonScore.Add(
+                                     new StudentLessonRecord
+                                     {
+                                         gscore = clientSummaryList.groupScore,
+                                         pscore = clientSummaryList.score,
+                                         tscore = clientSummaryList.tnteractScore,
+                                         tmdid = teacher.id,
+                                         school = school,
+                                         scope = lessonRecord.scope,
+                                         lessonId = lessonRecord.id,
+                                         courseId = lessonRecord.courseId,
+                                         periodId = lessonRecord.periodId,
+                                         subjectId = lessonRecord.subjectId,
+                                         time = lessonRecord.startTime
+                                     }
+                                 );
+                            }
+                        }
+                        overallEducations.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(overallEducation, partitionKey: new PartitionKey(overallEducation.code)));
+                    }
                     records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
                     records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
                 });
                 });
                 tmdids.ToList().ForEach(x => {
                 tmdids.ToList().ForEach(x => {
@@ -361,11 +458,16 @@ namespace TEAMModelOS.SDK.Models.Service
                     record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
                     record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
                     record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
                     record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
                     records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
                     records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
+                    
                 });
                 });
                 if (records.Any())
                 if (records.Any())
                 {
                 {
                     await Task.WhenAll(records);
                     await Task.WhenAll(records);
                 }
                 }
+                if (overallEducations.Any())
+                {
+                    await Task.WhenAll(overallEducations);
+                }
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {

+ 12 - 1
TEAMModelOS.SDK/Models/Service/SchoolService.cs

@@ -283,9 +283,20 @@ namespace TEAMModelOS.SDK
         /// </summary>
         /// </summary>
         /// <param name="semesterList"></param>
         /// <param name="semesterList"></param>
         /// <returns></returns>
         /// <returns></returns>
-        public static (Semester currSemester,  int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) GetSemester(  Period period, string time =null) {
+        public static (Semester currSemester,  int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) GetSemester(  Period period, long timestamp = 0,  string time =null) {
             //string time = "2023/05-11";
             //string time = "2023/05-11";
             DateTimeOffset date = default;
             DateTimeOffset date = default;
+            if (timestamp > 1000000000) {
+                //毫秒级
+                if (timestamp > 1000000000000)
+                {
+                    date = DateTimeOffset.FromUnixTimeMilliseconds(timestamp);
+                }
+                //秒级
+                else {
+                    date = DateTimeOffset.FromUnixTimeSeconds(timestamp);
+                }
+            }
             if (!(!string.IsNullOrWhiteSpace(time) && DateTimeOffset.TryParse(time, out date)))
             if (!(!string.IsNullOrWhiteSpace(time) && DateTimeOffset.TryParse(time, out date)))
             {
             {
                 //date = DateTimeOffset.FromUnixTimeSeconds(1672506061);
                 //date = DateTimeOffset.FromUnixTimeSeconds(1672506061);

+ 1 - 0
TEAMModelOS/ClientApp/package.json

@@ -22,6 +22,7 @@
     "@vue/eslint-config-standard": "^4.0.0",
     "@vue/eslint-config-standard": "^4.0.0",
     "animate.css": "^3.7.2",
     "animate.css": "^3.7.2",
     "apexcharts": "^3.26.1",
     "apexcharts": "^3.26.1",
+    "autofit.js": "^2.0.5",
     "axios": "^0.21.4",
     "axios": "^0.21.4",
     "core-js": "^3.1.2",
     "core-js": "^3.1.2",
     "d3": "^5.9.2",
     "d3": "^5.9.2",

+ 61 - 0
TEAMModelOS/ClientApp/src/common/BaseDashSelect.vue

@@ -0,0 +1,61 @@
+<template>
+  <div class="base-dash-select">
+    <Select v-model="curOption" @on-change="onChange">
+      <Option v-for="(item, index) in options" :value="index">{{
+        item
+      }}</Option>
+    </Select>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    options: {
+      type: Array,
+      default: () => ["前 20 名", "后 20 名",'倒数 20 名'],
+    },
+  },
+  data() {
+    return {
+      curOption: 0,
+    };
+  },
+  methods: {
+    onChange(index) {
+      // this.activeTabIndex = index
+    },
+  },
+};
+</script>
+
+<style lang="less">
+.base-dash-select {
+  display: flex;
+  margin-left: auto;
+  margin-right: 5px;
+
+  .ivu-select-single,
+  .ivu-select-selection {
+    background-color: #1e335b !important;
+    border-color: #5263af !important;
+    height: 28px;
+    border-radius: 0;
+    border-width: 2px;
+    transform: skewX(-5deg);
+  }
+
+  .ivu-select-selected-value {
+    font-size: 13px !important;
+    color: #c9cbe3;
+    line-height: 26px !important;
+  }
+
+  .ivu-select-arrow{
+    top: 56%;
+    right: 4px;
+    color: #c9cbe3;
+  }
+
+}
+</style>

+ 56 - 0
TEAMModelOS/ClientApp/src/common/BaseDashTab.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="base-dash-tab">
+    <div :class="['item',activeTabIndex === tabIndex ? 'active' : '']" v-for="(tab,tabIndex) in tabs" :key="tabIndex" @click="onTabClick(tabIndex)">
+      <span>{{ tab }}</span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+    props:{
+        tabs:{
+            type:Array,
+            default:() => []
+        }
+    },
+    data(){
+        return {
+            activeTabIndex:0
+        }
+    },
+    methods:{
+        onTabClick(index){
+            this.activeTabIndex = index
+            this.$emit('tab-change',index)
+        }
+    }
+}
+</script>
+
+<style lang="less">
+.base-dash-tab {
+  display: flex;
+  margin-left: auto;
+  margin-right: 5px;
+  .item {
+    font-size: 12px;
+    display: inline-block;
+    padding: 2px 6px;
+    border: 2px solid #2e6099;
+    transform: skewX(-20deg);
+    margin-right: -2px;
+    cursor: pointer;
+  } 
+
+  .active{
+    background-color: #4e6cad;
+    color: #fff;
+  }
+
+  .pre .ivu-icon {
+    transform: rotate(180deg);
+    transform-origin: center;
+  }
+}
+</style>

+ 11 - 0
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -404,6 +404,17 @@ export default {
           child: [],
           child: [],
           isShow: this.IES5Menu
           isShow: this.IES5Menu
         },
         },
+        // {
+        //   icon: 'iconfont icon-data-count',
+        //   name: 'iot数据看板',
+        //   router: '/schooliot',
+        //   tag: '',
+        //   role: 'admin',
+        //   permission: 'dashboard-read',
+        //   menuName: 'TeacherDashboard',
+        //   child: [],
+        //   isShow: this.IES5Menu
+        // },
         // 学校管理
         // 学校管理
         {
         {
           icon: 'iconfont icon-school',
           icon: 'iconfont icon-school',

+ 1 - 1
TEAMModelOS/ClientApp/src/common/BaseSelectTch.vue

@@ -2,7 +2,7 @@
   <div class="base-tch-select">
   <div class="base-tch-select">
     <Select v-model="selectTch" filterable clearable :multiple="isMultiple" :max-tag-count="2" @on-change="onSelectChange" :placeholder="$t('jyzx.application.teacherName')">
     <Select v-model="selectTch" filterable clearable :multiple="isMultiple" :max-tag-count="2" @on-change="onSelectChange" :placeholder="$t('jyzx.application.teacherName')">
       <Option v-for="(item,index) in teacherList" :value="item.id" :label="item.name" :key="index">
       <Option v-for="(item,index) in teacherList" :value="item.id" :label="item.name" :key="index">
-        <span style="margin-right: 10px;">{{item.name}}</span>
+        <span style="margin-right: 10px;">{{item.name}}<span v-if="item.iname">({{item.iname}})</span></span>
         <span class="tch-group-tag" v-for="(group,groupIndex) in item.groups" :key="groupIndex">{{ group.name }}</span>
         <span class="tch-group-tag" v-for="(group,groupIndex) in item.groups" :key="groupIndex">{{ group.name }}</span>
       </Option>
       </Option>
     </Select>
     </Select>

+ 8 - 5
TEAMModelOS/ClientApp/src/components/dashboard/student/BaseCircle.vue

@@ -28,6 +28,7 @@ export default {
   },
   },
   methods: {
   methods: {
     doRender() {
     doRender() {
+      if(!document.getElementById(this.circleId)) return
       let myChart = this.$echarts.init(document.getElementById(this.circleId))
       let myChart = this.$echarts.init(document.getElementById(this.circleId))
       let option = {
       let option = {
         title: [
         title: [
@@ -37,8 +38,9 @@ export default {
             top: '50%',
             top: '50%',
             textStyle: {
             textStyle: {
               color: '#FFFFFF',
               color: '#FFFFFF',
-              fontSize: 16,
+              fontSize: 14,
               fontWeight: '100',
               fontWeight: '100',
+              fontFamily: 'Hm'
             },
             },
           },
           },
           {
           {
@@ -47,8 +49,8 @@ export default {
             bottom: '10%',
             bottom: '10%',
             textStyle: {
             textStyle: {
               color: '#FFFFFF',
               color: '#FFFFFF',
-              fontSize: 16,
-              fontWeight: 'bold',
+              fontSize: 14,
+              fontFamily: 'Hm'
             },
             },
           },
           },
           {
           {
@@ -56,9 +58,10 @@ export default {
             x: 'center',
             x: 'center',
             top: '30%',
             top: '30%',
             textStyle: {
             textStyle: {
-              fontSize: '32',
+              fontSize: '30',
               color: '#FFFFFF',
               color: '#FFFFFF',
-              foontWeight: '600',
+              fontWeight: '100',
+              fontFamily: 'Hm'
             },
             },
           },
           },
         ],
         ],

+ 137 - 0
TEAMModelOS/ClientApp/src/components/dashboard/student/BaseStuRankList.vue

@@ -0,0 +1,137 @@
+<template>
+  <div class="stu-rank-container">
+    <div class="rank-item" v-for="(stu, stuIndex) in stuList">
+      <div class="left">
+        <div class="rank-count rank-number">
+            <span v-if="stuIndex > 2">{{ stuIndex + 1 }}</span>
+            <span v-if="stuIndex === 0">
+                <img src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/1.6409822.png" alt="" width="30">
+            </span>
+            <span v-if="stuIndex === 1">
+                <img src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/2.f827b4b.png" alt="" width="30">
+            </span>
+            <span v-if="stuIndex === 2">
+                <img src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/3.566d5a4.png" alt="" width="30">
+            </span>
+      </div>
+      <div class="user-avatar">
+        <span class="byte-avatar byte-avatar--circle">
+          <img
+            src="https://p3-passport.byteimg.com/img/user-avatar/5a998b33d01c58c913fbfee8d3e4a040~180x180.awebp" @click="goStudent"
+          />
+        </span>
+      </div>
+      <div class="user-info">
+        <div class="username">{{ stu.name }}</div>
+      </div>
+      </div>
+      <div class="mid">
+        <span>{{ stu.className }}</span>
+      </div>
+      <div class="right">
+        <span>{{ stu.score }} 分</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      stuList: [
+        {
+          name: "张三",
+          avatar: "",
+          className: "1班",
+          score: 98,
+        },
+        {
+          name: "张三2",
+          avatar: "",
+          className: "1班",
+          score: 96,
+        },
+        {
+          name: "张三3",
+          avatar: "",
+          className: "1班",
+          score: 84,
+        },
+        {
+          name: "张三4",
+          avatar: "",
+          className: "1班",
+          score: 82,
+        },
+        {
+          name: "张三2",
+          avatar: "",
+          className: "1班",
+          score: 96,
+        },
+        {
+          name: "张三3",
+          avatar: "",
+          className: "1班",
+          score: 84,
+        },
+        {
+          name: "张三4",
+          avatar: "",
+          className: "1班",
+          score: 82,
+        },
+      ],
+    };
+  },
+  methods:{
+    goStudent(){
+      this.$emit('stu-click')
+    }
+  }
+};
+</script>
+
+<style lang="less">
+.stu-rank-container {
+  width: 100%;
+  max-height: 300px;
+  overflow: auto;
+
+  &::-webkit-scrollbar-thumb {
+    background: transparent;
+    border-radius: 5px;
+}
+
+  .rank-item {
+    padding: 5px 12px;
+    padding-right: 30px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    &:nth-child(odd){
+        background-color: #07427f52;
+    }
+
+    .left{
+        display: flex;
+        align-items: center;
+        width: 50%;
+
+        .rank-number{
+            width: 40px;
+            text-align: center;
+        }
+    }
+  }
+
+  .byte-avatar img{
+    width: 32px;
+    height: 32px;
+    display: inline-block;
+    border-radius: 50%;
+    margin: 0 10px 0 20px;
+  }
+}
+</style>

+ 281 - 0
TEAMModelOS/ClientApp/src/components/dashboard/studentAll/BaseLineBar.vue

@@ -0,0 +1,281 @@
+<template>
+  <div id="BaseLineBar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    };
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById("BaseLineBar"));
+      var option = {
+        tooltip: {
+          trigger: "item",
+          axisPointer: {
+            // 坐标轴指示器,坐标轴触发有效
+            type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
+          },
+        },
+        grid: {
+          left: "2%",
+          right: "8%",
+          bottom: "10%",
+          top: "10%",
+          containLabel: true,
+        },
+        dataZoom: [
+          {
+            show: true,
+            height: 10,
+            start: 1,
+            end: 100,
+            xAxisIndex: [0],
+            bottom: 10,
+            handleIcon:
+              "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleSize: "110%",
+            handleStyle: {
+              color: "#5B3AAE",
+            },
+            textStyle: {
+              color: "rgba(204,187,225,0.5)",
+            },
+            fillerColor: "rgba(67,55,160,0.4)",
+            borderColor: "rgba(204,187,225,0.5)",
+          },
+          {
+            type: "inside",
+            show: true,
+            height: 15,
+            start: 1,
+            end: 35,
+          },
+        ],
+        legend: {
+          data: ["评测一", "评测二", "评测三"],
+          left: "center",
+          top: "0%",
+          textStyle: {
+            color: "#ccc",
+            fontFamily: "Hm",
+          },
+          itemWidth: 15,
+          itemHeight: 10,
+          itemGap: 25,
+        },
+        xAxis: {
+          type: "category",
+          data: [
+            "2022级1班",
+            "2022级2班",
+            "2022级3班",
+            "2022级4班",
+            "2022级5班",
+            "2022级6班",
+            "2022级7班",
+            "2022级8班",
+          ],
+          axisLine: {
+            lineStyle: {
+              color: "#fff",
+            },
+          },
+          axisLabel: {
+            textStyle: {
+              color: "#ccc",
+              fontFamily: "Hm",
+            },
+          },
+        },
+
+        yAxis: [
+          {
+            name: "得分率",
+            nameTextStyle: {
+              fontSize: 12,
+              fontFamily: "Hm",
+              color: "#ccc",
+            },
+            type: "value",
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisLabel: {
+              textStyle: {
+                color: "#ccc",
+                fontFamily: "Hm",
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+          },
+        ],
+        series: [
+          {
+            name: "评测一",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 52,
+                  lineStyle: {
+                    color: "#4bdfff",
+                  },
+
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#29acff",
+                  },
+                  {
+                    offset: 1,
+                    color: "#4bdfff",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 40, 84, 30, 95, 40, 40, 40, 70],
+          },
+          {
+            name: "评测二",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 64,
+                  lineStyle: {
+                    color: "#3d93f2",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#3d93f2",
+                  },
+                  {
+                    offset: 1,
+                    color: "#5dc1fd",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 50, 50, 50, 50, 40, 40, 50, 80],
+          },
+          {
+            name: "评测三",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 38,
+                  lineStyle: {
+                    color: "#01c871",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#01c871",
+                  },
+                  {
+                    offset: 1,
+                    color: "#55f49c",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 60, 70, 70, 62, 40, 30, 60, 78],
+          },
+        ],
+      };
+      myChart.clear();
+      myChart.setOption(option);
+      window.addEventListener("resize", function () {
+        myChart.resize();
+      });
+    },
+  },
+  mounted() {
+    this.doRender();
+  },
+};
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 1 - 0
TEAMModelOS/ClientApp/src/components/dashboard/studentAll/BaseScoreBar.vue

@@ -391,6 +391,7 @@ export default {
               color: '#fff',
               color: '#fff',
               fontSize: 12,
               fontSize: 12,
               fontStyle: 'bold',
               fontStyle: 'bold',
+              fontFamily:'Hm',
               align: 'center',
               align: 'center',
             },
             },
 
 

+ 281 - 0
TEAMModelOS/ClientApp/src/components/dashboard/studentAll/BaseStudyLineBar.vue

@@ -0,0 +1,281 @@
+<template>
+  <div id="BaseStudyLineBar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    };
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById("BaseStudyLineBar"));
+      var option = {
+        tooltip: {
+          trigger: "item",
+          axisPointer: {
+            // 坐标轴指示器,坐标轴触发有效
+            type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
+          },
+        },
+        grid: {
+          left: "2%",
+          right: "8%",
+          bottom: "10%",
+          top: "10%",
+          containLabel: true,
+        },
+        dataZoom: [
+          {
+            show: true,
+            height: 10,
+            start: 1,
+            end: 100,
+            xAxisIndex: [0],
+            bottom: 10,
+            handleIcon:
+              "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleSize: "110%",
+            handleStyle: {
+              color: "#5B3AAE",
+            },
+            textStyle: {
+              color: "rgba(204,187,225,0.5)",
+            },
+            fillerColor: "rgba(67,55,160,0.4)",
+            borderColor: "rgba(204,187,225,0.5)",
+          },
+          {
+            type: "inside",
+            show: true,
+            height: 15,
+            start: 1,
+            end: 35,
+          },
+        ],
+        legend: {
+          data: ["互动指数", "合作指数", "素养指数"],
+          left: "center",
+          top: "0%",
+          textStyle: {
+            color: "#ccc",
+            fontFamily: "Hm",
+          },
+          itemWidth: 15,
+          itemHeight: 10,
+          itemGap: 25,
+        },
+        xAxis: {
+          type: "category",
+          data: [
+            "2022级1班",
+            "2022级2班",
+            "2022级3班",
+            "2022级4班",
+            "2022级5班",
+            "2022级6班",
+            "2022级7班",
+            "2022级8班",
+          ],
+          axisLine: {
+            lineStyle: {
+              color: "#fff",
+            },
+          },
+          axisLabel: {
+            textStyle: {
+              color: "#ccc",
+              fontFamily: "Hm",
+            },
+          },
+        },
+
+        yAxis: [
+          {
+            name: "",
+            nameTextStyle: {
+              fontSize: 12,
+              fontFamily: "Hm",
+              color: "#ccc",
+            },
+            type: "value",
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisLabel: {
+              textStyle: {
+                color: "#ccc",
+                fontFamily: "Hm",
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+          },
+        ],
+        series: [
+          {
+            name: "互动指数",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 52,
+                  lineStyle: {
+                    color: "#4bdfff",
+                  },
+
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#29acff",
+                  },
+                  {
+                    offset: 1,
+                    color: "#4bdfff",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 40, 84, 30, 95, 40, 40, 40, 70],
+          },
+          {
+            name: "合作指数",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 64,
+                  lineStyle: {
+                    color: "#3d93f2",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#3d93f2",
+                  },
+                  {
+                    offset: 1,
+                    color: "#5dc1fd",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 50, 50, 50, 50, 40, 40, 50, 80],
+          },
+          {
+            name: "素养指数",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 38,
+                  lineStyle: {
+                    color: "#01c871",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#01c871",
+                  },
+                  {
+                    offset: 1,
+                    color: "#55f49c",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 60, 70, 70, 62, 40, 30, 60, 78],
+          },
+        ],
+      };
+      myChart.clear();
+      myChart.setOption(option);
+      window.addEventListener("resize", function () {
+        myChart.resize();
+      });
+    },
+  },
+  mounted() {
+    this.doRender();
+  },
+};
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 6 - 3
TEAMModelOS/ClientApp/src/components/student-web/WrongQusetion/WrongQues.vue

@@ -22,7 +22,8 @@
             </div>
             </div>
             <div>
             <div>
                 <p class="count-text">{{ $t("studentWeb.wrongQues.summary5") }}</p>
                 <p class="count-text">{{ $t("studentWeb.wrongQues.summary5") }}</p>
-                <p class="count-text-foot">
+                <p class="count-text-foot count-num count-num-4" v-if="lastTime.day < 0">{{ '今日' }}</p>
+                <p class="count-text-foot" v-else>
                     <span class="count-num count-num-4">{{ lastTime.day }}</span>
                     <span class="count-num count-num-4">{{ lastTime.day }}</span>
                     {{ $t("studentWeb.wrongQues.day1") }}
                     {{ $t("studentWeb.wrongQues.day1") }}
                     <span>({{ lastTime.time }})</span>
                     <span>({{ lastTime.time }})</span>
@@ -171,13 +172,15 @@ export default {
                     if(type) {
                     if(type) {
                         if(res.data.length) {
                         if(res.data.length) {
                             let nowTime = new Date().getTime()
                             let nowTime = new Date().getTime()
+                            let startTime = new Date(new Date().toLocaleDateString()).getTime()
+                            let endTime = new Date(new Date().toLocaleDateString()).getTime() + 24*60*60*1000 - 1
                             this.lastTime = {
                             this.lastTime = {
                                 time: res.data[0].last_rev_time ? this.dateFormat(res.data[0].last_rev_time) : '-',
                                 time: res.data[0].last_rev_time ? this.dateFormat(res.data[0].last_rev_time) : '-',
-                                day: Math.floor((nowTime - res.data[0].last_rev_time) / (1000*60*60*24))
+                                day: res.data[0].last_rev_time > startTime && res.data[0].last_rev_time < endTime ? -1 : Math.floor((nowTime - res.data[0].last_rev_time) / (1000*60*60*24))
                             }
                             }
                             this.nextTime = {
                             this.nextTime = {
                                 time: res.data[0].nxt_rev_time ? this.dateFormat(res.data[0].nxt_rev_time) : '-',
                                 time: res.data[0].nxt_rev_time ? this.dateFormat(res.data[0].nxt_rev_time) : '-',
-                                day: Math.floor((res.data[0].nxt_rev_time - nowTime) / (1000*60*60*24))
+                                day: res.data[0].nxt_rev_time > startTime && res.data[0].nxt_rev_time < endTime ? -1 : Math.floor((res.data[0].nxt_rev_time - startTime) / (1000*60*60*24))
                             }
                             }
                             this.topicTotal = res.data[0].total_qs
                             this.topicTotal = res.data[0].total_qs
                             this.wellDone = res.data[0].well_done_qs
                             this.wellDone = res.data[0].well_done_qs

+ 5 - 0
TEAMModelOS/ClientApp/src/router/routes.js

@@ -1128,6 +1128,11 @@ export const routes = [{
     //         middleware: ['login', 'ability:admin,dashboard-read'],
     //         middleware: ['login', 'ability:admin,dashboard-read'],
     //     }
     //     }
     // },
     // },
+    {
+        name: 'schooliot',
+        path: '/schooliot',
+        component: () => import('@/view/iot/schooliot.vue'),
+    },
     {
     {
         name: 'moralDashboard',
         name: 'moralDashboard',
         path: '/moralDashboard',
         path: '/moralDashboard',

+ 27 - 31
TEAMModelOS/ClientApp/src/view/dashboard/fiveEdu/FiveEdu.less

@@ -64,30 +64,30 @@
         .ivu-cascader {
         .ivu-cascader {
             margin: 0 10px;
             margin: 0 10px;
         }
         }
-    }
 
 
-    .ivu-select,
-    .ivu-input,
-    .ivu-select-placeholder {
-        color: @mainColor  !important;
-    }
+        .ivu-select,
+        .ivu-input,
+        .ivu-select-placeholder {
+            color: @mainColor  !important;
+        }
 
 
-    .ivu-select-selection,
-    .ivu-input {
-        background-color: #5389ee38 !important;
-        border-color: @mainColor;
-        height: 36px;
-        border-radius: 0;
-        margin-right: 10px;
-        margin-bottom: 5px;
-        border-width: 2px;
-        transform: skewX(-10deg);
-    }
+        .ivu-select-selection,
+        .ivu-input {
+            background-color: #5389ee38 !important;
+            border-color: @mainColor;
+            height: 36px;
+            border-radius: 0;
+            margin-right: 10px;
+            margin-bottom: 5px;
+            border-width: 2px;
+            transform: skewX(-10deg);
+        }
 
 
-    .ivu-input {
-        width: 150px;
-        color: rgb(206, 201, 201) !important;
-        font-weight: bold;
+        .ivu-input {
+            width: 150px;
+            color: rgb(206, 201, 201) !important;
+            font-weight: bold;
+        }
     }
     }
 
 
     .ivu-cascader .ivu-cascader-menu-item {
     .ivu-cascader .ivu-cascader-menu-item {
@@ -118,7 +118,9 @@
     }
     }
 
 
     .ivu-select-selected-value {
     .ivu-select-selected-value {
-        font-size: 18px;
+        font-size: 14px;
+        line-height: 32px;
+        color: #cec9c9;
     }
     }
 
 
     .ivu-select-input {
     .ivu-select-input {
@@ -182,8 +184,6 @@
             width: 100%;
             width: 100%;
             display: flex;
             display: flex;
             padding: 10px;
             padding: 10px;
-            font-size: 16px;
-            font-weight: bold;
             align-items: center;
             align-items: center;
 
 
 
 
@@ -249,16 +249,12 @@
                     justify-content: center;
                     justify-content: center;
 
 
                     .num {
                     .num {
-                        font-size: 46px;
+                        font-size: 36px;
                         font-weight: bold;
                         font-weight: bold;
-                        font-family: staticFont;
                         color: #1dd86b;
                         color: #1dd86b;
                     }
                     }
-
-
                     .label {
                     .label {
-                        font-weight: bold;
-                        color: #a1a5a5;
+                        color: #cccccc;
                     }
                     }
                 }
                 }
             }
             }
@@ -501,7 +497,7 @@
                             justify-content: space-between;
                             justify-content: space-between;
 
 
                             .dv-border-box-13 {
                             .dv-border-box-13 {
-                                width: 50%;
+                                width: 100%;
                             }
                             }
                         }
                         }
 
 

+ 389 - 276
TEAMModelOS/ClientApp/src/view/dashboard/fiveEdu/FiveEdu.vue

@@ -1,16 +1,45 @@
 <template>
 <template>
   <div id="FiveEduIndex" ref="appRef">
   <div id="FiveEduIndex" ref="appRef">
     <div class="bg">
     <div class="bg">
-      <dv-loading v-if="loading">{{ $t('researchCenter.dashboard.loading') }}</dv-loading>
+      <dv-loading v-if="loading">{{
+        $t("researchCenter.dashboard.loading")
+      }}</dv-loading>
       <div v-else-if="isAll" class="host-body all-student">
       <div v-else-if="isAll" class="host-body all-student">
         <div class="tools">
         <div class="tools">
-          <Cascader :data="targetData" v-model="targetValue" change-on-select :clearable="false" @on-change="onTargetChange" />
-          <span class="time-text">{{ dateYear }} <span style="display: inline-block; margin: 0 5px;color: #0fa2fe;">{{ dateDay }}</span> </span>
-          <span class="icon iconfont icon-tuichuquanping" style="font-size: 22px;" :title="$t('researchCenter.dashboard.quit')" @click="goBack"></span>
+          <Select
+            v-model="semesterValue"
+            @on-change="onSemesterChange"
+            style="width: 160px"
+          >
+            <Option v-for="(item, index) in semesterData" :value="index">{{
+              item
+            }}</Option>
+          </Select>
+          <Cascader
+            :data="targetData"
+            v-model="targetValue"
+            change-on-select
+            :clearable="false"
+            @on-change="onTargetChange"
+          />
+          <span
+            class="icon iconfont icon-tuichuquanping"
+            style="font-size: 22px"
+            :title="$t('researchCenter.dashboard.quit')"
+            @click="goBack"
+          ></span>
         </div>
         </div>
         <div class="school-info">
         <div class="school-info">
-          <div class="dash-menus" style="display:flex;">
-            <div :class="['menu-item', activeMenuId === menu.id ? 'menu-item-active' : '']" v-for="(menu,menuIndex) in menus" :key="menuIndex" @click="onMenuClick(menu)">
+          <div class="dash-menus" style="display: flex">
+            <div
+              :class="[
+                'menu-item',
+                activeMenuId === menu.id ? 'menu-item-active' : '',
+              ]"
+              v-for="(menu, menuIndex) in menus"
+              :key="menuIndex"
+              @click="onMenuClick(menu)"
+            >
               <span>{{ menu.name }}</span>
               <span>{{ menu.name }}</span>
             </div>
             </div>
           </div>
           </div>
@@ -21,9 +50,17 @@
             <dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" />
             <dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" />
             <div class="title">
             <div class="title">
               <span class="dash-title-text">学生五育大数据看板</span>
               <span class="dash-title-text">学生五育大数据看板</span>
-              <dv-decoration-6 class="dv-dec-6" :reverse="true" :color="['#50e3c2', '#67a1e5']" />
+              <dv-decoration-6
+                class="dv-dec-6"
+                :reverse="true"
+                :color="['#50e3c2', '#67a1e5']"
+              />
             </div>
             </div>
-            <dv-decoration-8 class="dv-dec-8" :reverse="true" :color="['#568aea', '#000000']" />
+            <dv-decoration-8
+              class="dv-dec-8"
+              :reverse="true"
+              :color="['#568aea', '#000000']"
+            />
           </div>
           </div>
           <dv-decoration-10 class="dv-dec-10-s" />
           <dv-decoration-10 class="dv-dec-10-s" />
         </div>
         </div>
@@ -36,10 +73,19 @@
                 <div class="dashboard-block">
                 <div class="dashboard-block">
                   <div class="block-content">
                   <div class="block-content">
                     <div class="static-wrap">
                     <div class="static-wrap">
-                      <div class="item" v-for="(item,index) in staticArr">
-                        <span class="num" :style="{color:item.color}">
-                          <countTo :startVal='0' :endVal='item.val' :duration='1000' class="count-num"></countTo>
-                          <span v-show="index > 3" style="font-size: 30px;margin-left:-10px">%</span>
+                      <div class="item" v-for="(item, index) in staticArr">
+                        <span class="num" :style="{ color: item.color }">
+                          <countTo
+                            :startVal="0"
+                            :endVal="item.val"
+                            :duration="1000"
+                            class="count-num"
+                          ></countTo>
+                          <span
+                            v-show="index > 3"
+                            style="font-size: 30px; margin-left: -10px"
+                            >%</span
+                          >
                         </span>
                         </span>
                         <span class="label">{{ item.label }}</span>
                         <span class="label">{{ item.label }}</span>
                       </div>
                       </div>
@@ -54,23 +100,23 @@
                 <dv-border-box-13>
                 <dv-border-box-13>
                   <div class="dashboard-block">
                   <div class="dashboard-block">
                     <div class="block-title">
                     <div class="block-title">
-                      <span>近三次评测统计图</span>
-                      <dv-decoration-1 style="width:150px;height:20px;" />
+                      <span>班级综合排名</span>
+                      <dv-decoration-1 style="width: 80px; height: 20px" />
                     </div>
                     </div>
-                    <div class="block-content">
-                      <!-- <BaseWordCloud></BaseWordCloud> -->
-                      <BaseExamLine></BaseExamLine>
+                    <div class="block-content" style="padding-top: 0">
+                      <dv-scroll-board :config="classRankConfig" />
                     </div>
                     </div>
                   </div>
                   </div>
                 </dv-border-box-13>
                 </dv-border-box-13>
                 <dv-border-box-13>
                 <dv-border-box-13>
                   <div class="dashboard-block">
                   <div class="dashboard-block">
                     <div class="block-title">
                     <div class="block-title">
-                      <span>智育稳定度统计分布</span>
-                      <dv-decoration-1 style="width:150px;height:20px;" />
+                      <span>个人综合排名</span>
+                      <dv-decoration-1 style="width: 80px; height: 20px" />
+                      <BaseDashSelect></BaseDashSelect>
                     </div>
                     </div>
                     <div class="block-content">
                     <div class="block-content">
-                      <BaseScoreBar></BaseScoreBar>
+                      <BaseStuRankList @stu-click="goStudent"></BaseStuRankList>
                     </div>
                     </div>
                   </div>
                   </div>
                 </dv-border-box-13>
                 </dv-border-box-13>
@@ -79,22 +125,12 @@
                 <div class="bottom">
                 <div class="bottom">
                   <dv-border-box-13>
                   <dv-border-box-13>
                     <div class="dashboard-block">
                     <div class="dashboard-block">
-
                       <div class="block-title">
                       <div class="block-title">
                         <span>学生德育风采</span>
                         <span>学生德育风采</span>
-                        <dv-decoration-1 style="width:150px;height:20px;" />
+                        <dv-decoration-1 style="width: 80px; height: 20px" />
                       </div>
                       </div>
                       <div class="block-content">
                       <div class="block-content">
                         <BaseCarousel></BaseCarousel>
                         <BaseCarousel></BaseCarousel>
-                        <!-- <div class="honor-avatar">
-                          <div class="honor-item" v-for="(item,index) in stuTopArr" :key="index">
-                            <img class="img-avatar" @click="goStudent()" src="https://paas-admin.xydqq.cn/img/avatar.647bbbfe.png" alt="" width="80">
-                            <img class="img-crown" src="@/assets/dashboard/student/icon_crown.png" alt="" v-show="index === 0">
-                            <img class="img-crown" src="@/assets/dashboard/student/icon_crown2.png" alt="" v-show="index === 1">
-                            <img class="img-crown" src="@/assets/dashboard/student/icon_crown3.png" alt="" v-show="index === 2">
-                            <span>学生姓名{{ index + 1 }}</span>
-                          </div>
-                        </div> -->
                       </div>
                       </div>
                     </div>
                     </div>
                   </dv-border-box-13>
                   </dv-border-box-13>
@@ -103,38 +139,16 @@
                   <dv-border-box-13>
                   <dv-border-box-13>
                     <div class="dashboard-block">
                     <div class="dashboard-block">
                       <div class="block-title">
                       <div class="block-title">
-                        <span>班级综合排名</span>
-                        <dv-decoration-1 style="width:150px;height:20px;" />
-                        <BasePaging></BasePaging>
+                        <span>学生学习表现统计图</span>
+                        <dv-decoration-1 style="width: 80px; height: 20px" />
+                        <BaseDashTab
+                          :tabs="['评测活动表现', '课堂学习表现']"
+                          @tab-change="onLineBarTabChange"
+                        ></BaseDashTab>
                       </div>
                       </div>
                       <div class="block-content">
                       <div class="block-content">
-                        <dv-scroll-board :config="classRankConfig" />
-                      </div>
-                    </div>
-                  </dv-border-box-13>
-                  <dv-border-box-13>
-                    <div class="dashboard-block">
-                      <div class="block-title">
-                        <span>个人综合排名</span>
-                        <dv-decoration-1 style="width:150px;height:20px;" v-if="!inClassView" />
-                        <BasePaging></BasePaging>
-                      </div>
-                      <div class="block-content">
-                        <div class="stu-search-wrap" v-if="inClassView">
-                          <Select filterable v-model="curStuIndex" style="width:200px" @on-change="onStuSelect">
-                            <Option v-for="(item,index) in stuList" :value="index" :key="item.id">{{ item.name }}({{ item.id }})</Option>
-                          </Select>
-                        </div>
-                        <!-- <dv-scroll-board :config="gradeRankConfig" /> -->
-                        <div class="honor-avatar" v-if="homeData">
-                          <div class="honor-item" v-for="(item,index) in stuTopArr" :key="index">
-                            <img class="img-avatar" @click="goStudent(item)" :src="item.picture || require('../stu_avatar.png')" alt="" width="68">
-                            <img class="img-crown" src="@/assets/dashboard/student/icon_crown.png" alt="" v-show="index === 0">
-                            <img class="img-crown" src="@/assets/dashboard/student/icon_crown2.png" alt="" v-show="index === 1">
-                            <img class="img-crown" src="@/assets/dashboard/student/icon_crown3.png" alt="" v-show="index === 2">
-                            <span>{{ item.name }}</span>
-                          </div>
-                        </div>
+                        <BaseLineBar v-if="lineBarType === 'exam'"></BaseLineBar>
+                        <BaseStudyLineBar v-else></BaseStudyLineBar>
                       </div>
                       </div>
                     </div>
                     </div>
                   </dv-border-box-13>
                   </dv-border-box-13>
@@ -149,11 +163,37 @@
                 <div class="dashboard-block">
                 <div class="dashboard-block">
                   <div class="block-title">
                   <div class="block-title">
                     <span>体育优秀达标数据</span>
                     <span>体育优秀达标数据</span>
-                    <dv-decoration-1 style="width:150px;height:20px;" />
+                    <dv-decoration-1 style="width: 80px; height: 20px" />
                   </div>
                   </div>
                   <div class="block-content" v-if="homeData">
                   <div class="block-content" v-if="homeData">
-                    <BaseCircle circleId="sportGoodCircle" chatName="优秀率" :percent="homeData.sports_count ? +((homeData.sports_count90 / homeData.sports_count) * 100).toFixed(1) : 0" :subTitle="homeData.sports_count90 + '人'"></BaseCircle>
-                    <BaseCircle circleId="sportNormalCircle" chatName="达标率" :percent="homeData.sports_count ? +((homeData.sports_count60 / homeData.sports_count) * 100).toFixed(1): 0" :subTitle="homeData.sports_count60 + '人'"></BaseCircle>
+                    <BaseCircle
+                      circleId="sportGoodCircle"
+                      chatName="优秀率"
+                      :percent="
+                        homeData.sports_count
+                          ? +(
+                              (homeData.sports_count90 /
+                                homeData.sports_count) *
+                              100
+                            ).toFixed(1)
+                          : 0
+                      "
+                      :subTitle="homeData.sports_count90 + '人'"
+                    ></BaseCircle>
+                    <BaseCircle
+                      circleId="sportNormalCircle"
+                      chatName="达标率"
+                      :percent="
+                        homeData.sports_count
+                          ? +(
+                              (homeData.sports_count60 /
+                                homeData.sports_count) *
+                              100
+                            ).toFixed(1)
+                          : 0
+                      "
+                      :subTitle="homeData.sports_count60 + '人'"
+                    ></BaseCircle>
                   </div>
                   </div>
                 </div>
                 </div>
               </dv-border-box-13>
               </dv-border-box-13>
@@ -163,11 +203,22 @@
                 <div class="dashboard-block">
                 <div class="dashboard-block">
                   <div class="block-title">
                   <div class="block-title">
                     <span>艺术优秀达标数据</span>
                     <span>艺术优秀达标数据</span>
-                    <dv-decoration-1 style="width:150px;height:20px;" />
+                    <dv-decoration-1 style="width: 80px; height: 20px" />
+                    <BaseDashTab :tabs="['音乐', '美术']"></BaseDashTab>
                   </div>
                   </div>
                   <div class="block-content">
                   <div class="block-content">
-                    <BaseCircle circleId="artGoodCircle" chatName="优秀率" :percent="42" subTitle="66人"></BaseCircle>
-                    <BaseCircle circleId="artNormalCircle" chatName="达标率" :percent="83" subTitle="1284人"></BaseCircle>
+                    <BaseCircle
+                      circleId="artGoodCircle"
+                      chatName="优秀率"
+                      :percent="42"
+                      subTitle="66人"
+                    ></BaseCircle>
+                    <BaseCircle
+                      circleId="artNormalCircle"
+                      chatName="达标率"
+                      :percent="83"
+                      subTitle="1284人"
+                    ></BaseCircle>
                   </div>
                   </div>
                 </div>
                 </div>
               </dv-border-box-13>
               </dv-border-box-13>
@@ -177,11 +228,21 @@
                 <div class="dashboard-block">
                 <div class="dashboard-block">
                   <div class="block-title">
                   <div class="block-title">
                     <span>劳动实践常用任务</span>
                     <span>劳动实践常用任务</span>
-                    <dv-decoration-1 style="width:150px;height:20px;" />
+                    <dv-decoration-1 style="width: 80px; height: 20px" />
                   </div>
                   </div>
                   <div class="block-content">
                   <div class="block-content">
-                    <BaseCircle circleId="workGoodCircle" chatName="优秀率" :percent="87" subTitle="207人"></BaseCircle>
-                    <BaseCircle circleId="workNormalCircle" chatName="达标率" :percent="92" subTitle="1666人"></BaseCircle>
+                    <BaseCircle
+                      circleId="workGoodCircle"
+                      chatName="优秀率"
+                      :percent="87"
+                      subTitle="207人"
+                    ></BaseCircle>
+                    <BaseCircle
+                      circleId="workNormalCircle"
+                      chatName="达标率"
+                      :percent="92"
+                      subTitle="1666人"
+                    ></BaseCircle>
                     <!-- <BaseProgressBar></BaseProgressBar> -->
                     <!-- <BaseProgressBar></BaseProgressBar> -->
                     <!-- <BaseScoreBar></BaseScoreBar> -->
                     <!-- <BaseScoreBar></BaseScoreBar> -->
                   </div>
                   </div>
@@ -193,79 +254,89 @@
 
 
         <StudyDash v-else-if="activeMenuId === 'study'"></StudyDash>
         <StudyDash v-else-if="activeMenuId === 'study'"></StudyDash>
         <MoralDash v-else-if="activeMenuId === 'moral'"></MoralDash>
         <MoralDash v-else-if="activeMenuId === 'moral'"></MoralDash>
-        <!-- <ArtDash v-else-if="activeMenuId === 'art'"></ArtDash> -->
-        <!-- <div class="sport-box" style="width:100%;height:90vh;padding-top:25px;" v-show="activeMenuId === 'sport'">
-          <iframe src="https://ydztshow.cdwalker.com/app-health-100/smart-course" width="100%" height="100%" frameborder="0"></iframe>
-        </div> -->
       </div>
       </div>
-
     </div>
     </div>
     <Modal v-model="noAuthModal" footer-hide :transfer="false">
     <Modal v-model="noAuthModal" footer-hide :transfer="false">
       <!-- <p style="color: #5b60a5;text-align:center;font-weight: bold;font-size:18px;margin">温馨提示</p> -->
       <!-- <p style="color: #5b60a5;text-align:center;font-weight: bold;font-size:18px;margin">温馨提示</p> -->
-      <p style=" color: #fff;font-weight: bold;margin:20px;font-size:18px">您当前所在学校尚未购买【{{ noAuthName }}】大数据模块,无法查看,详请联系学校管理员</p>
+      <p style="color: #fff; font-weight: bold; margin: 20px; font-size: 18px">
+        您当前所在学校尚未购买【{{
+          noAuthName
+        }}】大数据模块,无法查看,详请联系学校管理员
+      </p>
     </Modal>
     </Modal>
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
-import countTo from 'vue-count-to'
-import BaseRateLine from '@/components/dashboard/studentAll/BaseRateLine'
-import BaseWordCloud from '@/components/dashboard/studentAll/BaseWordCloud'
-import BaseScoreBar from '@/components/dashboard/studentAll/BaseScoreBar'
-import BaseGenderPie from '@/components/dashboard/studentAll/BaseGenderPie'
-import BaseArtCircle from '@/components/dashboard/student/BaseArtCircle'
-import BaseMusicCircle from '@/components/dashboard/student/BaseMusicCircle'
-import BaseCircle from '@/components/dashboard/student/BaseCircle'
-import StudentDetails from '../Student'
-import BaseProgressBar from '@/components/dashboard/student/BaseProgressBar'
-import StudyDash from '../study/StudyDash'
-import BaseExamLine from '../study/BaseExamLine'
-import MoralDash from '../moral/MoralDash'
-import ArtDash from '../Art.vue'
-import BaseCarousel from '../moral/BaseCarousel'
+import autofit from "autofit.js";
+import countTo from "vue-count-to";
+import BaseLineBar from "@/components/dashboard/studentAll/BaseLineBar";
+import BaseStudyLineBar from "@/components/dashboard/studentAll/BaseStudyLineBar";
+import BaseRateLine from "@/components/dashboard/studentAll/BaseRateLine";
+import BaseWordCloud from "@/components/dashboard/studentAll/BaseWordCloud";
+import BaseScoreBar from "@/components/dashboard/studentAll/BaseScoreBar";
+import BaseGenderPie from "@/components/dashboard/studentAll/BaseGenderPie";
+import BaseArtCircle from "@/components/dashboard/student/BaseArtCircle";
+import BaseMusicCircle from "@/components/dashboard/student/BaseMusicCircle";
+import BaseStuRankList from "@/components/dashboard/student/BaseStuRankList";
+import BaseCircle from "@/components/dashboard/student/BaseCircle";
+import StudentDetails from "../Student";
+import BaseProgressBar from "@/components/dashboard/student/BaseProgressBar";
+import StudyDash from "../study/StudyDash";
+import MoralDash from "../moral/MoralDash";
+import ArtDash from "../Art.vue";
+import BaseCarousel from "../moral/BaseCarousel";
 export default {
 export default {
   data() {
   data() {
     return {
     return {
-      noAuthName: '劳动教育',
+      lineBarType:'exam',
+      noAuthName: "劳动教育",
       noAuthModal: false,
       noAuthModal: false,
       curStuIndex: -1,
       curStuIndex: -1,
       stuList: [],
       stuList: [],
       stuTopArr: new Array(8),
       stuTopArr: new Array(8),
       targetValue: [],
       targetValue: [],
       targetData: [],
       targetData: [],
+      semesterData: [
+        "2023年上学期",
+        "2023年下学期",
+        "2022年上学期",
+        "2022年下学期",
+      ],
+      semesterValue: 0,
       homeData: null,
       homeData: null,
       menus: [
       menus: [
         {
         {
-          id: 'all',
-          name: '总览',
+          id: "all",
+          name: "总览",
         },
         },
         {
         {
-          id: 'moral',
-          name: '德'
+          id: "moral",
+          name: "德",
         },
         },
         {
         {
-          id: 'study',
-          name: '智'
+          id: "study",
+          name: "智",
         },
         },
         {
         {
-          id: 'sport',
-          name: '体'
+          id: "sport",
+          name: "体",
         },
         },
         {
         {
-          id: 'art',
-          name: '艺'
+          id: "art",
+          name: "艺",
         },
         },
         {
         {
-          id: 'work',
-          name: '劳'
-        }
+          id: "work",
+          name: "劳",
+        },
       ],
       ],
-      activeMenuId: 'all',
+      activeMenuId: "all",
       isFull: false,
       isFull: false,
       isAll: true,
       isAll: true,
       activeClassIndex: -1,
       activeClassIndex: -1,
       activeGradeIndex: 0,
       activeGradeIndex: 0,
-      activeMenu: 'music',
+      activeMenu: "music",
       timing: null,
       timing: null,
       loading: true,
       loading: true,
       dateDay: null,
       dateDay: null,
@@ -275,46 +346,52 @@ export default {
       selectClassIds: [],
       selectClassIds: [],
       staticArr: [
       staticArr: [
         {
         {
-          label: '学生总数',
-          color: '#7ec4ff',
-          val: 0
+          label: "学生总数",
+          color: "#7ec4ff",
+          val: 0,
         },
         },
         {
         {
-          label: '年级数',
-          color: '#7ec4ff',
-          val: 0
-        }, {
-          label: '班级数',
-          color: '#7ec4ff',
-          val: 0
+          label: "年级数",
+          color: "#7ec4ff",
+          val: 0,
         },
         },
         {
         {
-          label: '活动数',
-          color: '#7ec4ff',
-          val: 0
+          label: "班级数",
+          color: "#7ec4ff",
+          val: 0,
         },
         },
         {
         {
-          label: '优秀率',
-          color: '#20d99d',
-          val: 0
+          label: "活动数",
+          color: "#7ec4ff",
+          val: 0,
         },
         },
         {
         {
-          label: '及格率',
-          color: '#ff8e2e',
-          val: 0
-        }
+          label: "优秀率",
+          color: "#20d99d",
+          val: 0,
+        },
+        {
+          label: "及格率",
+          color: "#ff8e2e",
+          val: 0,
+        },
       ],
       ],
-      classes: ['1班', '2班', '3班', '4班', '5班', '6班'],
-      grades: ['五年级', '六年级'],
+      classes: ["1班", "2班", "3班", "4班", "5班", "6班"],
+      grades: ["五年级", "六年级"],
       gradeRankConfig: {
       gradeRankConfig: {
-        header: ['<span style="color:#32c5e9;font-weight: bold;">年级</span>', '<span style="color:#32c5e9;font-weight: bold;">最高分</span>', '<span style="color:#32c5e9;font-weight: bold;">最低分</span>', '<span style="color:#32c5e9;font-weight: bold;">综合平均分</span>'],
+        header: [
+          '<span style="color:#32c5e9;font-weight: bold;">年级</span>',
+          '<span style="color:#32c5e9;font-weight: bold;">最高分</span>',
+          '<span style="color:#32c5e9;font-weight: bold;">最低分</span>',
+          '<span style="color:#32c5e9;font-weight: bold;">综合平均分</span>',
+        ],
         data: [
         data: [
-          ['大一年级', '84.3 分', '52.1 分', '74.3 分'],
-          ['大二年级', '82.6 分', '54.3 分', '72.3 分'],
-          ['大三年级', '76.0 分', '43.8 分', '68.1 分'],
-          ['大四年级', '74.1 分', '40.2 分', '61.8 分'],
+          ["大一年级", "84.3 分", "52.1 分", "74.3 分"],
+          ["大二年级", "82.6 分", "54.3 分", "72.3 分"],
+          ["大三年级", "76.0 分", "43.8 分", "68.1 分"],
+          ["大四年级", "74.1 分", "40.2 分", "61.8 分"],
         ],
         ],
-        align: ['center'],
+        align: ["center"],
         rowNum: 5,
         rowNum: 5,
         headerHeight: 50,
         headerHeight: 50,
         headerBGC: "transparent", //表头
         headerBGC: "transparent", //表头
@@ -322,58 +399,68 @@ export default {
         evenRowBGC: "transparent", //偶数行
         evenRowBGC: "transparent", //偶数行
       },
       },
       classRankConfig: {
       classRankConfig: {
-        header: ['<span style="color:#32c5e9;font-weight: bold;">班级</span>', '<span style="color:#32c5e9;font-weight: bold;">最高分</span>', '<span style="color:#32c5e9;font-weight: bold;">最低分</span>', '<span style="color:#32c5e9;font-weight: bold;">综合平均分</span>'],
+        header: [
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">班级</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">最高分</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">最低分</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">平均分</span>',
+        ],
         data: [
         data: [
-          ['大一年级1班', '84.3 分', '65.7 分', '74.8 分'],
-          ['大一年级2班', '82.6 分', '64.3 分', '72.3 分'],
-          ['大一年级3班', '76.0 分', '60.9 分', '69.9 分'],
-          ['大一年级4班', '74.1 分', '52.6 分', '65.3 分'],
-          ['大一年级5班', '65.8 分', '48.7 分', '56.8 分'],
+          ["1班", "84.3", "65.7", "74.8"],
+          ["2班", "82.6", "64.3", "72.3"],
+          ["3班", "76.0", "60.9", "69.9"],
+          ["4班", "74.1", "52.6", "65.3"],
+          ["5班", "65.8", "48.7", "56.8"],
+          ["6班", "76.0", "60.9", "69.9"],
+          ["7班", "74.1", "52.6", "65.3"],
+          ["8班", "65.8", "48.7", "56.8"],
         ],
         ],
-        align: ['center'],
-        rowNum: 5,
-        headerHeight: 50,
+        align: ["center", "center", "center", "center"],
+        rowNum: 6,
+        headerHeight: 40,
         headerBGC: "transparent", //表头
         headerBGC: "transparent", //表头
         oddRowBGC: "transparent", //奇数行
         oddRowBGC: "transparent", //奇数行
-        evenRowBGC: "transparent", //偶数行
+        evenRowBGC: "#07427f52",
       },
       },
       sportConfig: {
       sportConfig: {
         data: [
         data: [
           {
           {
-            name: '篮球',
-            value: 55
+            name: "篮球",
+            value: 55,
           },
           },
           {
           {
-            name: '足球',
-            value: 120
+            name: "足球",
+            value: 120,
           },
           },
           {
           {
-            name: '排球',
-            value: 71
+            name: "排球",
+            value: 71,
           },
           },
           {
           {
-            name: '羽毛球',
-            value: 66
+            name: "羽毛球",
+            value: 66,
           },
           },
           {
           {
-            name: '网球',
-            value: 80
+            name: "网球",
+            value: 80,
           },
           },
         ],
         ],
         img: [
         img: [
-          require('@/assets/dashboard/student/sport2.png'),
-          require('@/assets/dashboard/student/sport5.png'),
-          require('@/assets/dashboard/student/sport3.png'),
-          require('@/assets/dashboard/student/sport4.png'),
-          require('@/assets/dashboard/student/sport1.png'),
+          require("@/assets/dashboard/student/sport2.png"),
+          require("@/assets/dashboard/student/sport5.png"),
+          require("@/assets/dashboard/student/sport3.png"),
+          require("@/assets/dashboard/student/sport4.png"),
+          require("@/assets/dashboard/student/sport1.png"),
         ],
         ],
         imgSideLength: 20,
         imgSideLength: 20,
-        showValue: true
-      }
-    }
+        showValue: true,
+      },
+    };
   },
   },
   components: {
   components: {
-    BaseExamLine,
+    BaseStudyLineBar,
+    BaseStuRankList,
+    BaseLineBar,
     StudyDash,
     StudyDash,
     ArtDash,
     ArtDash,
     MoralDash,
     MoralDash,
@@ -387,109 +474,124 @@ export default {
     BaseMusicCircle,
     BaseMusicCircle,
     BaseCircle,
     BaseCircle,
     BaseProgressBar,
     BaseProgressBar,
-    BaseCarousel
+    BaseCarousel,
   },
   },
   mounted() {
   mounted() {
+    autofit.init({
+      designHeight: 980,
+      designWidth: 1920,
+      renderDom: "#FiveEduIndex",
+      resize: true,
+    });
     if (!this.isFull) {
     if (!this.isFull) {
       setTimeout(() => {
       setTimeout(() => {
-        this.$tools.fullScreen(document.getElementById('FiveEduIndex'))
-        this.isFull = true
-      }, 100)
+        this.$tools.fullScreen(document.getElementById("FiveEduIndex"));
+        this.isFull = true;
+      }, 100);
     }
     }
-    this.timeFn()
+    this.timeFn();
     // this.cancelLoading()
     // this.cancelLoading()
   },
   },
   beforeDestroy() {
   beforeDestroy() {
-    clearInterval(this.timing)
+    clearInterval(this.timing);
   },
   },
   created() {
   created() {
     if (!this.isTestView) {
     if (!this.isTestView) {
-      this.activeMenuId = 'study'
+      this.activeMenuId = "study";
     }
     }
-    this.curPeriod = this.$store.state.user.curPeriod
-    this.findTargets()
-
+    this.curPeriod = this.$store.state.user.curPeriod;
+    this.findTargets();
   },
   },
   methods: {
   methods: {
+    onLineBarTabChange(val){
+      this.lineBarType = val === 0 ? 'exam' : 'study'
+    },
     findHomeData(target) {
     findHomeData(target) {
-      let curSemester = this.$tools.getCurSemester()
+      let curSemester = this.$tools.getCurSemester();
       let params = {
       let params = {
-        "school": this.$store.state.userInfo.schoolCode,
-        "periodId": this.curPeriod.id,
-        "semesterId": curSemester.id,
-        "year": 2021,
-        "grades": [Number(target[0])]
-      }
+        school: this.$store.state.userInfo.schoolCode,
+        periodId: this.curPeriod.id,
+        semesterId: curSemester.id,
+        year: 2021,
+        grades: [Number(target[0])],
+      };
       if (target.length > 1) {
       if (target.length > 1) {
-        params.classIds = [target[1]]
+        params.classIds = [target[1]];
       }
       }
-      this.$api.dashboard.findFiveEduData(params).then(res => {
-        this.homeData = res
-        this.staticArr[0].val = res.studentCount
-        this.staticArr[1].val = res.gradeCount
-        this.staticArr[2].val = res.classCount
-        this.staticArr[3].val = res.activityCount
-        this.staticArr[4].val = +(res.rate90 * 100).toFixed(2)
-        this.staticArr[5].val = +(res.rate60 * 100).toFixed(2)
-        this.stuTopArr = res.ranking.length ? res.ranking.slice(0, 8) : this.stuList.slice(0, 8)
+      this.$api.dashboard.findFiveEduData(params).then((res) => {
+        this.homeData = res;
+        this.staticArr[0].val = res.studentCount;
+        this.staticArr[1].val = res.gradeCount;
+        this.staticArr[2].val = res.classCount;
+        this.staticArr[3].val = res.activityCount;
+        this.staticArr[4].val = +(res.rate90 * 100).toFixed(2);
+        this.staticArr[5].val = +(res.rate60 * 100).toFixed(2);
+        this.stuTopArr = res.ranking.length
+          ? res.ranking.slice(0, 8)
+          : this.stuList.slice(0, 8);
         if (res.classDatas.length) {
         if (res.classDatas.length) {
-          this.classRankConfig.data = res.classDatas.map(i => {
-            return [i.className, i.best.toFixed(2) + '分', i.last.toFixed(2) + '分', i.avg.toFixed(2) + '分']
-          })
+          this.classRankConfig.data = res.classDatas.map((i) => {
+            return [
+              i.className,
+              i.best.toFixed(2) + "分",
+              i.last.toFixed(2) + "分",
+              i.avg.toFixed(2) + "分",
+            ];
+          });
         }
         }
-        this.cancelLoading()
-      })
+        this.cancelLoading();
+      });
     },
     },
     onStuSelect(val) {
     onStuSelect(val) {
-      this.goStudent(this.stuList[val])
+      this.goStudent(this.stuList[val]);
     },
     },
     onMenuClick(menu) {
     onMenuClick(menu) {
       switch (menu.id) {
       switch (menu.id) {
-        case 'all':
+        case "all":
           if (this.isTestView) {
           if (this.isTestView) {
-            this.activeMenuId = menu.id
+            this.activeMenuId = menu.id;
           } else {
           } else {
-            this.noAuthModal = true
-            this.noAuthName = '大数据总览看板'
+            this.noAuthModal = true;
+            this.noAuthName = "大数据总览看板";
           }
           }
           break;
           break;
-        case 'moral':
+        case "moral":
           // if (this.isTestView) {
           // if (this.isTestView) {
           //   this.activeMenuId = menu.id
           //   this.activeMenuId = menu.id
           // } else {
           // } else {
           //   this.noAuthModal = true
           //   this.noAuthModal = true
           //   this.noAuthName = '德育看板'
           //   this.noAuthName = '德育看板'
           // }
           // }
-          this.noAuthModal = true
-          this.noAuthName = '德育看板'
+          this.noAuthModal = true;
+          this.noAuthName = "德育看板";
           break;
           break;
-        case 'study':
-          this.activeMenuId = menu.id
+        case "study":
+          this.activeMenuId = menu.id;
           break;
           break;
-        case 'sport':
+        case "sport":
           if (this.isTestView) {
           if (this.isTestView) {
             // window.open('https://ydztshow.cdwalker.com/app-health-100/smart-course')
             // window.open('https://ydztshow.cdwalker.com/app-health-100/smart-course')
-            this.activeMenuId = menu.id
-            this.$router.push('/sportDashboard')
+            this.activeMenuId = menu.id;
+            this.$router.push("/sportDashboard");
           } else {
           } else {
-            this.noAuthModal = true
-            this.noAuthName = '体育看板'
+            this.noAuthModal = true;
+            this.noAuthName = "体育看板";
           }
           }
           break;
           break;
-        case 'art':
+        case "art":
           // this.$tools.exitFullscreen()
           // this.$tools.exitFullscreen()
           if (this.hasArtAuth) {
           if (this.hasArtAuth) {
-            this.$router.push('/artDashboard')
-            this.activeMenuId = menu.id
+            this.$router.push("/artDashboard");
+            this.activeMenuId = menu.id;
           } else {
           } else {
-            this.noAuthModal = true
-            this.noAuthName = '艺术测评'
+            this.noAuthModal = true;
+            this.noAuthName = "艺术测评";
           }
           }
 
 
           break;
           break;
-        case 'work':
-          this.noAuthModal = true
-          this.noAuthName = '劳动教育看板'
+        case "work":
+          this.noAuthModal = true;
+          this.noAuthName = "劳动教育看板";
           break;
           break;
         default:
         default:
           break;
           break;
@@ -500,105 +602,117 @@ export default {
       let params = {
       let params = {
         schoolId: this.$store.state.userInfo.schoolCode,
         schoolId: this.$store.state.userInfo.schoolCode,
         periodId: this.curPeriod.id,
         periodId: this.curPeriod.id,
-        opt: 'manage',
-        type: ['class']
-      }
+        opt: "manage",
+        type: ["class"],
+      };
       this.$api.common.getActivityTarget(params).then(
       this.$api.common.getActivityTarget(params).then(
-        res => {
-          let grades = this.curPeriod.grades
+        (res) => {
+          let grades = this.curPeriod.grades;
           this.targetData = grades.map((i, index) => {
           this.targetData = grades.map((i, index) => {
             return {
             return {
               label: i,
               label: i,
-              value: index + 1 + ''
-            }
-          })
-          let curYear = new Date().getFullYear()
+              value: index + 1 + "",
+            };
+          });
+          let curYear = new Date().getFullYear();
           this.targetData.forEach((grade, gradeIndex) => {
           this.targetData.forEach((grade, gradeIndex) => {
-            grade.children = res.groupLists.filter(i => i.year == curYear - gradeIndex).map(classItem => {
-              return {
-                label: classItem.name,
-                value: classItem.id
-              }
-            })
-          })
-          this.targetValue = ['1']
-          this.findHomeData(this.targetValue)
+            grade.children = res.groupLists
+              .filter((i) => i.year == curYear - gradeIndex)
+              .map((classItem) => {
+                return {
+                  label: classItem.name,
+                  value: classItem.id,
+                };
+              });
+          });
+          this.targetValue = ["1"];
+          this.findHomeData(this.targetValue);
         },
         },
-        err => {
-          this.$Messag.error('查询发布对象失败')
+        (err) => {
+          this.$Messag.error("查询发布对象失败");
         }
         }
-      )
+      );
     },
     },
+    onSemesterChange(val) {},
     /* 切换对象 */
     /* 切换对象 */
     onTargetChange(val) {
     onTargetChange(val) {
-      this.curStuIndex = -1
+      this.curStuIndex = -1;
       // 选中年级
       // 选中年级
       if (val.length === 1) {
       if (val.length === 1) {
-        this.inClassView = false
-        this.selectClassIds = this.targetData[+val[0] - 1].children.map(i => i.value)
-        this.findHomeData(val)
+        this.inClassView = false;
+        this.selectClassIds = this.targetData[+val[0] - 1].children.map(
+          (i) => i.value
+        );
+        this.findHomeData(val);
       } else {
       } else {
         // 选中某个班级
         // 选中某个班级
-        this.inClassView = true
-        this.selectClassIds = [val[val.length - 1]]
-        this.$api.common.getGroupListByIds({
-          schoolId: this.$store.state.userInfo.schoolCode,
-          ids: this.selectClassIds
-        }).then(res => {
-          this.stuList = res.members
-        })
-        this.findHomeData(val)
+        this.inClassView = true;
+        this.selectClassIds = [val[val.length - 1]];
+        this.$api.common
+          .getGroupListByIds({
+            schoolId: this.$store.state.userInfo.schoolCode,
+            ids: this.selectClassIds,
+          })
+          .then((res) => {
+            this.stuList = res.members;
+          });
+        this.findHomeData(val);
       }
       }
-
     },
     },
 
 
     goStudent(stuInfo) {
     goStudent(stuInfo) {
-      sessionStorage.setItem('dash_stu_info', JSON.stringify(stuInfo))
-      this.$tools.exitFullscreen()
-      this.$router.push('/stuDetails')
+      sessionStorage.setItem("dash_stu_info", JSON.stringify(stuInfo));
+      this.$tools.exitFullscreen();
+      this.$router.push("/stuDetails");
     },
     },
     goBack() {
     goBack() {
-      this.$tools.exitFullscreen()
-      this.$router.push('/home/homePage')
+      this.$tools.exitFullscreen();
+      this.$router.push("/home/homePage");
     },
     },
     timeFn() {
     timeFn() {
       this.timing = setInterval(() => {
       this.timing = setInterval(() => {
-        this.dateDay = this.$tools.formatTime(new Date(), 'hh:mm:ss')
-        this.dateYear = this.$tools.formatTime(new Date(), 'yyyy-MM-dd')
-      }, 1000)
+        this.dateDay = this.$tools.formatTime(new Date(), "hh:mm:ss");
+        this.dateYear = this.$tools.formatTime(new Date(), "yyyy-MM-dd");
+      }, 1000);
     },
     },
     cancelLoading() {
     cancelLoading() {
       setTimeout(() => {
       setTimeout(() => {
-        this.loading = false
-      }, 1000)
+        this.loading = false;
+      }, 1000);
     },
     },
   },
   },
   computed: {
   computed: {
     schoolInfo() {
     schoolInfo() {
-      let store_user = this.$store.state.user
-      let semesterRange = this.$tools.getSemesterTimeRange()
+      let store_user = this.$store.state.user;
+      let semesterRange = this.$tools.getSemesterTimeRange();
       return {
       return {
         schoolName: store_user.schoolProfile.school_base.name,
         schoolName: store_user.schoolProfile.school_base.name,
         schoolLogo: store_user.schoolProfile.school_base.picture,
         schoolLogo: store_user.schoolProfile.school_base.picture,
         periodName: store_user.curPeriod.name,
         periodName: store_user.curPeriod.name,
-        curSemester: semesterRange.name
-      }
+        curSemester: semesterRange.name,
+      };
     },
     },
     /* 判断是否为测试站 */
     /* 判断是否为测试站 */
     isTestSite() {
     isTestSite() {
-      return window.location.host.includes('test.teammodel')
+      return window.location.host.includes("test.teammodel");
     },
     },
     /* 醍摩豆学校和研发学校才开放查阅的DEMO页面 */
     /* 醍摩豆学校和研发学校才开放查阅的DEMO页面 */
     isTestView() {
     isTestView() {
-      return ['habook', 'ydzt', 'cdydzt', 'hbcn'].includes(this.$store.state.userInfo.schoolCode)
+      return ["habook", "ydzt", "cdydzt", "hbcn"].includes(
+        this.$store.state.userInfo.schoolCode
+      );
     },
     },
     /* 判断是否购买艺术评测 */
     /* 判断是否购买艺术评测 */
     hasArtAuth() {
     hasArtAuth() {
-      let schoolProfile = JSON.parse(decodeURIComponent(localStorage.school_profile || '{}', "utf-8"))
-      return schoolProfile.schoolShows?.find(item => item.status === 1 && item.type === 'art')
-    }
-  }
-}
+      let schoolProfile = JSON.parse(
+        decodeURIComponent(localStorage.school_profile || "{}", "utf-8")
+      );
+      return schoolProfile.schoolShows?.find(
+        (item) => item.status === 1 && item.type === "art"
+      );
+    },
+  },
+};
 </script>
 </script>
 
 
 <style lang="less">
 <style lang="less">
@@ -610,4 +724,3 @@ export default {
   background-color: #2fa0efe0;
   background-color: #2fa0efe0;
 }
 }
 </style>
 </style>
-

+ 0 - 2
TEAMModelOS/ClientApp/src/view/dashboard/moral/MoralDash.vue

@@ -139,7 +139,6 @@ import BaseScoreBar from './BaseScoreBar'
 import BaseScorePie from './BaseScorePie'
 import BaseScorePie from './BaseScorePie'
 import BaseScoreLine from './BaseScoreLine'
 import BaseScoreLine from './BaseScoreLine'
 import BaseCarousel from './BaseCarousel'
 import BaseCarousel from './BaseCarousel'
-import BaseExamLine from './BaseExamLine'
 import BaseSubLine from './BaseSubLine'
 import BaseSubLine from './BaseSubLine'
 import BaseStudyRadar from './BaseRadar'
 import BaseStudyRadar from './BaseRadar'
 import BaseWordCloud from '@/components/dashboard/studentAll/BaseWordCloud'
 import BaseWordCloud from '@/components/dashboard/studentAll/BaseWordCloud'
@@ -148,7 +147,6 @@ export default {
     countTo,
     countTo,
     BaseCircle,
     BaseCircle,
     BaseCarousel,
     BaseCarousel,
-    BaseExamLine,
     BaseScorePie,
     BaseScorePie,
     BaseScoreLine,
     BaseScoreLine,
     BaseScoreBar,
     BaseScoreBar,

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 258
TEAMModelOS/ClientApp/src/view/dashboard/study/BaseExamLine.vue


+ 281 - 0
TEAMModelOS/ClientApp/src/view/dashboard/study/BaseExamLineBar.vue

@@ -0,0 +1,281 @@
+<template>
+  <div id="BaseLineBar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    };
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById("BaseLineBar"));
+      var option = {
+        tooltip: {
+          trigger: "item",
+          axisPointer: {
+            // 坐标轴指示器,坐标轴触发有效
+            type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
+          },
+        },
+        grid: {
+          left: "2%",
+          right: "8%",
+          bottom: "10%",
+          top: "10%",
+          containLabel: true,
+        },
+        dataZoom: [
+          {
+            show: true,
+            height: 10,
+            start: 1,
+            end: 100,
+            xAxisIndex: [0],
+            bottom: 10,
+            handleIcon:
+              "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleSize: "110%",
+            handleStyle: {
+              color: "#5B3AAE",
+            },
+            textStyle: {
+              color: "rgba(204,187,225,0.5)",
+            },
+            fillerColor: "rgba(67,55,160,0.4)",
+            borderColor: "rgba(204,187,225,0.5)",
+          },
+          {
+            type: "inside",
+            show: true,
+            height: 15,
+            start: 1,
+            end: 35,
+          },
+        ],
+        legend: {
+          data: ["评测一", "评测二", "评测三"],
+          left: "center",
+          top: "0%",
+          textStyle: {
+            color: "#ccc",
+            fontFamily: "Hm",
+          },
+          itemWidth: 15,
+          itemHeight: 10,
+          itemGap: 25,
+        },
+        xAxis: {
+          type: "category",
+          data: [
+            "2022级1班",
+            "2022级2班",
+            "2022级3班",
+            "2022级4班",
+            "2022级5班",
+            "2022级6班",
+            "2022级7班",
+            "2022级8班",
+          ],
+          axisLine: {
+            lineStyle: {
+              color: "#fff",
+            },
+          },
+          axisLabel: {
+            textStyle: {
+              color: "#ccc",
+              fontFamily: "Hm",
+            },
+          },
+        },
+
+        yAxis: [
+          {
+            name: "得分率",
+            nameTextStyle: {
+              fontSize: 12,
+              fontFamily: "Hm",
+              color: "#ccc",
+            },
+            type: "value",
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisLabel: {
+              textStyle: {
+                color: "#ccc",
+                fontFamily: "Hm",
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+          },
+        ],
+        series: [
+          {
+            name: "评测一",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 52,
+                  lineStyle: {
+                    color: "#4bdfff",
+                  },
+
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#29acff",
+                  },
+                  {
+                    offset: 1,
+                    color: "#4bdfff",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 40, 84, 30, 95, 40, 40, 40, 70],
+          },
+          {
+            name: "评测二",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 64,
+                  lineStyle: {
+                    color: "#3d93f2",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#3d93f2",
+                  },
+                  {
+                    offset: 1,
+                    color: "#5dc1fd",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 50, 50, 50, 50, 40, 40, 50, 80],
+          },
+          {
+            name: "评测三",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 38,
+                  lineStyle: {
+                    color: "#01c871",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#01c871",
+                  },
+                  {
+                    offset: 1,
+                    color: "#55f49c",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 60, 70, 70, 62, 40, 30, 60, 78],
+          },
+        ],
+      };
+      myChart.clear();
+      myChart.setOption(option);
+      window.addEventListener("resize", function () {
+        myChart.resize();
+      });
+    },
+  },
+  mounted() {
+    this.doRender();
+  },
+};
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 145 - 0
TEAMModelOS/ClientApp/src/view/dashboard/study/BaseLevelBar.vue

@@ -0,0 +1,145 @@
+<template>
+  <div id="BaseLevelBar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    };
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById("BaseLevelBar"));
+      // 指定图表的配置项和数据
+      var data1 = [20, 30, 20, 30, 20, 30, 20, 30, 20, 30];
+      var data2 = [9, 30, 9, 60, 70, 20, 59, 20, 49, 20];
+      var data3 = [20, 30, 20, 30, 20, 30, 20, 30, 20, 30];
+      var data4 = [20, 30, 20, 30, 20, 30, 20, 30, 20, 30];
+      var datacity = [
+        "2022级1班",
+        "2022级2班",
+        "2022级3班",
+        "2022级4班",
+        "2022级5班",
+        "2022级6班",
+        "2022级7班",
+        "2022级8班",
+      ];
+      var option = {
+        color: ["#20afe3", "#33cbff", "#66f8ff", "#bcf5f5"],
+        tooltip: {
+          trigger: "axis",
+        },
+        legend: {
+          data: ["A", "B", "C", "D"],
+          itemWidth: 15,
+          itemHeight: 10,
+          itemGap: 25,
+          textStyle: {
+            fontSize: 12,
+            color: "#ccc",
+            fontFamily: "Hm",
+          },
+        },
+        grid: {
+          //图表的位置
+          top: "20%",
+          left: "3%",
+          right: "4%",
+          bottom: "3%",
+          containLabel: true,
+        },
+        yAxis: [
+          {
+            name: "人数",
+            nameTextStyle: {
+              fontSize: 12,
+              fontFamily: "Hm",
+              color: "#ccc",
+            },
+            type: "value",
+            splitLine: {
+              show: false,
+            },
+            axisLine: {
+              lineStyle: {
+                color: "#fff",
+              },
+            },
+            axisLabel: {
+              textStyle: {
+                color: "#ccc",
+                fontFamily: "Hm",
+              },
+            },
+          },
+        ],
+        xAxis: [
+          {
+            axisLine: {
+              lineStyle: {
+                color: "#fff",
+              },
+            },
+            axisLabel: {
+              textStyle: {
+                color: "#ccc",
+                fontFamily: "Hm",
+              },
+            },
+            data: datacity,
+          },
+        ],
+        series: [
+          {
+            name: "A",
+            type: "bar",
+            stack: "1",
+            barWidth: "20px",
+            data: data1,
+          },
+          {
+            name: "B",
+            type: "bar",
+            barWidth: "20px",
+            stack: "1",
+            data: data2,
+          },
+          {
+            name: "C",
+            type: "bar",
+            stack: "1",
+            barWidth: "20px",
+            data: data3,
+          },
+          {
+            name: "D",
+            type: "bar",
+            stack: "1",
+            barWidth: "20px",
+            data: data4,
+          },
+        ],
+      };
+      myChart.clear();
+      myChart.setOption(option);
+      window.addEventListener("resize", function () {
+        myChart.resize();
+      });
+    },
+  },
+  mounted() {
+    this.doRender();
+  },
+};
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 99 - 54
TEAMModelOS/ClientApp/src/view/dashboard/study/BaseRadar.vue

@@ -6,40 +6,56 @@ export default {
   data() {
   data() {
     return {
     return {
       option: null,
       option: null,
-    }
+    };
   },
   },
   methods: {
   methods: {
     doRender() {
     doRender() {
-      let myChart = this.$echarts.init(document.getElementById('studyRadar'))
-      var dataname = ['记忆', '理解', '应用', '创造', '评价', '分析']
-      var datamax = [20, 20, 20, 20, 20, 20]
-      var datavaule = [10, 16, 20, 15, 12, 18]
+      let myChart = this.$echarts.init(document.getElementById("studyRadar"));
+      var dataname = ["合作", "互动", "评测", "素养"];
+      var datamax = [100, 100, 100, 100];
+      var datavaule = [70, 96, 80, 85];
+      var datavaule2 = [60, 66, 70, 65];
 
 
-      var indicator = []
+      var indicator = [];
       for (var i = 0; i < dataname.length; i++) {
       for (var i = 0; i < dataname.length; i++) {
         indicator.push({
         indicator.push({
           name: dataname[i],
           name: dataname[i],
           max: datamax[i],
           max: datamax[i],
-        })
+        });
       }
       }
       let option = {
       let option = {
         tooltip: {
         tooltip: {
-          show: false,
           trigger: "item",
           trigger: "item",
         },
         },
+        legend: {
+          left:'10',
+          bottom:'0',
+          itemWidth: 15,
+          itemHeight: 10,
+          itemGap: 25,
+          textStyle: {
+            fontSize: 12,
+            fontFamily:'Hm',
+            color: "#ccc",
+          },
+          data: ["全校", "一年级"],
+        },
         radar: {
         radar: {
           center: ["50%", "50%"],
           center: ["50%", "50%"],
-          radius: "90%",
-          startAngle: 240,
+          radius: "80%",
+          startAngle: 90,
           splitNumber: 5,
           splitNumber: 5,
           splitArea: {
           splitArea: {
             areaStyle: {
             areaStyle: {
               color: [
               color: [
-                'rgba(0,96,208, 0.1)', 'rgba(0,96,208, 0.2)',
-                'rgba(0,96,208, 0.4)', 'rgba(0,96,208, 0.6)',
-                'rgba(0,96,208, 0.8)', 'rgba(0,96,208, 1)'
-              ].reverse()
-            }
+                "rgba(0,96,208, 0.1)",
+                "rgba(0,96,208, 0.2)",
+                "rgba(0,96,208, 0.4)",
+                "rgba(0,96,208, 0.6)",
+                "rgba(0,96,208, 0.8)",
+                "rgba(0,96,208, 1)",
+              ].reverse(),
+            },
           },
           },
           axisLabel: {
           axisLabel: {
             show: false,
             show: false,
@@ -47,59 +63,88 @@ export default {
           axisLine: {
           axisLine: {
             show: true,
             show: true,
             lineStyle: {
             lineStyle: {
-              color: "transparent"
-            }
+              color: "transparent",
+            },
           },
           },
           splitLine: {
           splitLine: {
             show: true,
             show: true,
             lineStyle: {
             lineStyle: {
-              color: "transparent"
-            }
+              color: "transparent",
+            },
           },
           },
           name: {
           name: {
             textStyle: {
             textStyle: {
-              color: '#fff',
-              fontSize: '12',
-              padding: 10
-            }
+              color: "#fff",
+              fontSize: "12",
+              fontFamily: "Hm",
+            },
           },
           },
-          indicator: indicator
+          indicator: indicator,
         },
         },
 
 
-        series: [{
-          type: "radar",
-          symbol: "circle",
-          symbolSize: 7,
-          areaStyle: {
-            normal: {
-              color: 'rgba(170, 216, 255, 0.2)',
-            }
-          },
+        series: [
+          {
+            type: "radar",
+            symbol: "circle",
+            symbolSize: 7,
+            areaStyle: {
+              normal: {
+                color: "rgba(170, 216, 255, 0.2)",
+              },
+            },
 
 
-          itemStyle: {
-            color: '#84E1FF',
-            borderColor: '#00A7FE',
-            borderWidth: 1,
+            itemStyle: {
+              color: "#84E1FF",
+              borderColor: "#00A7FE",
+              borderWidth: 1,
+            },
+            lineStyle: {
+              normal: {
+                color: "#00A7FE",
+                width: 2,
+              },
+            },
+            data: [{
+              value:datavaule,
+              name:'全校'
+            }],
           },
           },
-          lineStyle: {
-            normal: {
-              color: "#00A7FE",
-              width: 2
-            }
+          {
+            type: "radar",
+            symbol: "circle",
+            symbolSize: 7,
+            areaStyle: {
+              normal: {
+                color: "rgba(90,216,166,0.8)",
+              },
+            },
+            itemStyle: {
+              color: "rgba(90,216,166,0.8)",
+              borderColor: "rgba(90,216,166,0.8)",
+              borderWidth: 1,
+            },
+            lineStyle: {
+              normal: {
+                color: "rgba(90,216,166,0.8)",
+                width: 2,
+              },
+            },
+            data: [{
+              value:datavaule2,
+              name:'一年级'
+            }],
           },
           },
-          data: [datavaule]
-        }]
+        ],
       };
       };
-      myChart.clear()
-      myChart.setOption(option)
-      window.addEventListener('resize', function () {
-        myChart.resize()
-      })
-
-    }
+      myChart.clear();
+      myChart.setOption(option);
+      window.addEventListener("resize", function () {
+        myChart.resize();
+      });
+    },
   },
   },
   mounted() {
   mounted() {
-    this.doRender()
+    this.doRender();
   },
   },
   //   watch: {
   //   watch: {
   //     '$store.state.dashboard.artDashboard': {
   //     '$store.state.dashboard.artDashboard': {
@@ -110,7 +155,7 @@ export default {
   //       }
   //       }
   //     }
   //     }
   //   }
   //   }
-}
+};
 </script>
 </script>
 
 
 <style>
 <style>
@@ -120,4 +165,4 @@ export default {
   margin: 0 auto;
   margin: 0 auto;
   display: block;
   display: block;
 }
 }
-</style>
+</style>

+ 281 - 0
TEAMModelOS/ClientApp/src/view/dashboard/study/BaseStudyLineBar.vue

@@ -0,0 +1,281 @@
+<template>
+  <div id="BaseStudyLineBar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    };
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById("BaseStudyLineBar"));
+      var option = {
+        tooltip: {
+          trigger: "item",
+          axisPointer: {
+            // 坐标轴指示器,坐标轴触发有效
+            type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
+          },
+        },
+        grid: {
+          left: "2%",
+          right: "8%",
+          bottom: "10%",
+          top: "10%",
+          containLabel: true,
+        },
+        dataZoom: [
+          {
+            show: true,
+            height: 10,
+            start: 1,
+            end: 100,
+            xAxisIndex: [0],
+            bottom: 10,
+            handleIcon:
+              "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleSize: "110%",
+            handleStyle: {
+              color: "#5B3AAE",
+            },
+            textStyle: {
+              color: "rgba(204,187,225,0.5)",
+            },
+            fillerColor: "rgba(67,55,160,0.4)",
+            borderColor: "rgba(204,187,225,0.5)",
+          },
+          {
+            type: "inside",
+            show: true,
+            height: 15,
+            start: 1,
+            end: 35,
+          },
+        ],
+        legend: {
+          data: ["互动指数", "合作指数", "素养指数"],
+          left: "center",
+          top: "0%",
+          textStyle: {
+            color: "#ccc",
+            fontFamily: "Hm",
+          },
+          itemWidth: 15,
+          itemHeight: 10,
+          itemGap: 25,
+        },
+        xAxis: {
+          type: "category",
+          data: [
+            "2022级1班",
+            "2022级2班",
+            "2022级3班",
+            "2022级4班",
+            "2022级5班",
+            "2022级6班",
+            "2022级7班",
+            "2022级8班",
+          ],
+          axisLine: {
+            lineStyle: {
+              color: "#fff",
+            },
+          },
+          axisLabel: {
+            textStyle: {
+              color: "#ccc",
+              fontFamily: "Hm",
+            },
+          },
+        },
+
+        yAxis: [
+          {
+            name: "",
+            nameTextStyle: {
+              fontSize: 12,
+              fontFamily: "Hm",
+              color: "#ccc",
+            },
+            type: "value",
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisLabel: {
+              textStyle: {
+                color: "#ccc",
+                fontFamily: "Hm",
+              },
+            },
+            axisLine: {
+              lineStyle: {
+                color: "#cdd5e2",
+              },
+            },
+          },
+        ],
+        series: [
+          {
+            name: "互动指数",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 52,
+                  lineStyle: {
+                    color: "#4bdfff",
+                  },
+
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#29acff",
+                  },
+                  {
+                    offset: 1,
+                    color: "#4bdfff",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 40, 84, 30, 95, 40, 40, 40, 70],
+          },
+          {
+            name: "合作指数",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 64,
+                  lineStyle: {
+                    color: "#3d93f2",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#3d93f2",
+                  },
+                  {
+                    offset: 1,
+                    color: "#5dc1fd",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 50, 50, 50, 50, 40, 40, 50, 80],
+          },
+          {
+            name: "素养指数",
+            type: "bar",
+            barWidth: "12px",
+            markLine: {
+              silent: true,
+              symblo: "none",
+              label: {
+                position: "end",
+              },
+              data: [
+                {
+                  name: "年级",
+                  yAxis: 38,
+                  lineStyle: {
+                    color: "#01c871",
+                  },
+                  label: {
+                    position: "end",
+                    formatter: "{b} {c}%",
+                    textStyle: {
+                      fontFamily: "Hm",
+                    },
+                  },
+                },
+              ],
+            },
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "#01c871",
+                  },
+                  {
+                    offset: 1,
+                    color: "#55f49c",
+                  },
+                ]),
+                // barBorderRadius: 6,
+              },
+            },
+            data: [40, 60, 70, 70, 62, 40, 30, 60, 78],
+          },
+        ],
+      };
+      myChart.clear();
+      myChart.setOption(option);
+      window.addEventListener("resize", function () {
+        myChart.resize();
+      });
+    },
+  },
+  mounted() {
+    this.doRender();
+  },
+};
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 5 - 6
TEAMModelOS/ClientApp/src/view/dashboard/study/BaseSubLine.vue

@@ -54,9 +54,9 @@ export default {
             },
             },
             axisLabel: {
             axisLabel: {
               show: true,
               show: true,
-              // interval: '0',//X轴坐标全显示
               textStyle: {
               textStyle: {
-                color: "#fff"
+                color: "#ccc",
+                fontFamily:'Hm'
               }
               }
             }
             }
           }
           }
@@ -70,7 +70,8 @@ export default {
             axisLabel: {
             axisLabel: {
               show: true,
               show: true,
               textStyle: {
               textStyle: {
-                color: "#fff"
+                color: "#ccc",
+                fontFamily:'Hm'
               }
               }
             }
             }
           }
           }
@@ -79,15 +80,13 @@ export default {
           {
           {
             name: name,
             name: name,
             type: 'bar',
             type: 'bar',
-            barMaxWidth: 20,
+            barMaxWidth: 18,
             barMinWidth: 10,
             barMinWidth: 10,
             minWidth: 5,
             minWidth: 5,
             xAxisIndex: 0,
             xAxisIndex: 0,
             yAxisIndex: 0,
             yAxisIndex: 0,
             itemStyle: {
             itemStyle: {
-              barBorderRadius: 20,
               normal: {
               normal: {
-                barBorderRadius: 10,
                 color: function (params) {
                 color: function (params) {
                   var colors = []
                   var colors = []
                   var maxIndex = 1;
                   var maxIndex = 1;

+ 9 - 1
TEAMModelOS/ClientApp/src/view/dashboard/study/StudyDash.less

@@ -1,6 +1,14 @@
 .study-dash-container {
 .study-dash-container {
     .right-box-top {
     .right-box-top {
-        height: 64% !important;
+        height: 60% !important;
+        }
+
+        .right-box-bottom {
+            height: 35% !important;
+        }
+
+        .left-bottom-left {
+            width: 50% !important;
     }
     }
 
 
     .top {
     .top {

+ 62 - 77
TEAMModelOS/ClientApp/src/view/dashboard/study/StudyDash.vue

@@ -24,105 +24,83 @@
           <dv-border-box-13>
           <dv-border-box-13>
             <div class="dashboard-block">
             <div class="dashboard-block">
               <div class="block-title">
               <div class="block-title">
-                <span>近三次评测统计图</span>
+                <span>班级排行</span>
                 <dv-decoration-1 style="width:150px;height:20px;" />
                 <dv-decoration-1 style="width:150px;height:20px;" />
               </div>
               </div>
               <div class="block-content">
               <div class="block-content">
-                <BaseExamLine></BaseExamLine>
+                 <dv-scroll-board :config="classRankConfig" />
               </div>
               </div>
             </div>
             </div>
           </dv-border-box-13>
           </dv-border-box-13>
           <dv-border-box-13>
           <dv-border-box-13>
             <div class="dashboard-block">
             <div class="dashboard-block">
               <div class="block-title">
               <div class="block-title">
-                <span>学习稳定度统计分布</span>
+                <span>课堂学习表现</span>
                 <dv-decoration-1 style="width:150px;height:20px;" />
                 <dv-decoration-1 style="width:150px;height:20px;" />
               </div>
               </div>
               <div class="block-content">
               <div class="block-content">
-                <BaseScoreBar></BaseScoreBar>
+                <BaseStudyLineBar></BaseStudyLineBar>
               </div>
               </div>
             </div>
             </div>
           </dv-border-box-13>
           </dv-border-box-13>
         </div>
         </div>
-        <div class="left-bottom-right">
-          <div class="top">
-            <dv-border-box-13>
-              <div class="dashboard-block">
-                <div class="block-title">
-                  <span>班级排名</span>
-                  <dv-decoration-1 style="width:150px;height:20px;" />
-                  <BasePaging></BasePaging>
-                </div>
-                <div class="block-content">
-                  <dv-scroll-board :config="classRankConfig" />
-                </div>
+        <div class="left-bottom-left">
+          <dv-border-box-13>
+            <div class="dashboard-block">
+              <div class="block-title">
+                <span>各班等级分布</span>
+                <dv-decoration-1 style="width:150px;height:20px;" />
               </div>
               </div>
-            </dv-border-box-13>
-            <dv-border-box-13>
-              <div class="dashboard-block">
-                <div class="block-title">
-                  <span>学生排名</span>
-                  <dv-decoration-1 style="width:150px;height:20px;" />
-                  <BasePaging></BasePaging>
-                </div>
-                <div class="block-content">
-                  <div class="rank-wrap">
-                    <div class="stu-rank-item" v-for="(rankStu,rankStuIndex) in stuTopArr" :key="rankStuIndex">
-                      <dv-border-box-7>
-                        <img class="img-crown" src="@/assets/dashboard/student/icon_crown.png" alt="" v-if="rankStuIndex === 0">
-                        <img class="img-crown" src="@/assets/dashboard/student/icon_crown2.png" alt="" v-else-if="rankStuIndex === 1">
-                        <img class="img-crown" src="@/assets/dashboard/student/icon_crown3.png" alt="" v-else-if="rankStuIndex === 2">
-                        <span class="rank-index" v-else>{{ rankStuIndex + 1 }}</span>
-                        </span>
-                        <img class="img-avatar" @click="goStudent()" src="https://paas-admin.xydqq.cn/img/avatar.647bbbfe.png" alt="" width="50">
-                        <div class="stu-info">
-                          <p class="name">学生姓名{{ rankStuIndex + 1 }}</p>
-                          <p class="id">{{ 140015511001 + rankStuIndex }}</p>
-                        </div>
-                        <span class="rank-score">
-                          <span>{{ (87.63 - 5.2 * rankStuIndex).toFixed(2) }}</span>
-                          <span style="font-size:12px;display:inline-block;color:#ccc">平均分</span>
-                        </span>
-                      </dv-border-box-7>
-                    </div>
-                  </div>
-                </div>
+              <div class="block-content">
+                <BaseLevelBar></BaseLevelBar>
               </div>
               </div>
-            </dv-border-box-13>
-          </div>
+            </div>
+          </dv-border-box-13>
+          <dv-border-box-13>
+            <div class="dashboard-block">
+              <div class="block-title">
+                <span>评测活动表现</span>
+                <dv-decoration-1 style="width:150px;height:20px;" />
+              </div>
+              <div class="block-content">
+                <BaseExamLineBar></BaseExamLineBar>
+              </div>
+            </div>
+          </dv-border-box-13>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
     <!-- 右侧 -->
     <!-- 右侧 -->
     <div class="right-box">
     <div class="right-box">
-      <div class="right-box-top">
+      <div class="right-box-bottom">
         <dv-border-box-13>
         <dv-border-box-13>
           <div class="dashboard-block">
           <div class="dashboard-block">
             <div class="block-title">
             <div class="block-title">
-              <span>各科表现排行</span>
+              <span>学生表现</span>
               <dv-decoration-1 style="width:150px;height:20px;" />
               <dv-decoration-1 style="width:150px;height:20px;" />
             </div>
             </div>
-            <div class="block-content" style="display:flex;flex-direction:column;">
-              <BaseSubLine></BaseSubLine>
-              <br>
-              <dv-scroll-ranking-board :config="stuRankConfig" style="width:90%;margin-left:5%" />
+            <div class="block-content">
+              <BaseStudyRadar></BaseStudyRadar>
             </div>
             </div>
           </div>
           </div>
         </dv-border-box-13>
         </dv-border-box-13>
       </div>
       </div>
-      <div class="right-box-bottom">
+      <div class="right-box-top">
         <dv-border-box-13>
         <dv-border-box-13>
           <div class="dashboard-block">
           <div class="dashboard-block">
             <div class="block-title">
             <div class="block-title">
-              <span>认知层次分布</span>
+              <span>各科评测表现</span>
               <dv-decoration-1 style="width:150px;height:20px;" />
               <dv-decoration-1 style="width:150px;height:20px;" />
             </div>
             </div>
-            <div class="block-content">
-              <BaseStudyRadar></BaseStudyRadar>
+            <div class="block-content" style="display:flex;flex-direction:column;">
+              <BaseSubLine></BaseSubLine>
+              <br>
+              <dv-scroll-ranking-board :config="stuRankConfig" style="width:90%;margin-left:5%" />
             </div>
             </div>
           </div>
           </div>
         </dv-border-box-13>
         </dv-border-box-13>
       </div>
       </div>
+      
     </div>
     </div>
   </div>
   </div>
 </template>
 </template>
@@ -131,15 +109,19 @@
 import countTo from 'vue-count-to'
 import countTo from 'vue-count-to'
 import BaseCircle from '@/components/dashboard/student/BaseCircle'
 import BaseCircle from '@/components/dashboard/student/BaseCircle'
 import BaseScoreBar from '@/components/dashboard/studentAll/BaseScoreBar'
 import BaseScoreBar from '@/components/dashboard/studentAll/BaseScoreBar'
-import BaseExamLine from './BaseExamLine'
+import BaseExamLineBar from './BaseExamLineBar'
+import BaseStudyLineBar from './BaseStudyLineBar'
 import BaseSubLine from './BaseSubLine'
 import BaseSubLine from './BaseSubLine'
 import BaseStudyRadar from './BaseRadar'
 import BaseStudyRadar from './BaseRadar'
+import BaseLevelBar from './BaseLevelBar'
 export default {
 export default {
   components: {
   components: {
     countTo,
     countTo,
     BaseCircle,
     BaseCircle,
-    BaseExamLine,
     BaseScoreBar,
     BaseScoreBar,
+    BaseLevelBar,
+    BaseExamLineBar,
+    BaseStudyLineBar,
     BaseSubLine,
     BaseSubLine,
     BaseStudyRadar
     BaseStudyRadar
   },
   },
@@ -178,27 +160,30 @@ export default {
       ],
       ],
       stuTopArr: new Array(7),
       stuTopArr: new Array(7),
       classRankConfig: {
       classRankConfig: {
-        header: ['<span style="color:#32c5e9;font-weight: bold;">班级</span>', '<span style="color:#32c5e9;font-weight: bold;">最高分</span>', '<span style="color:#32c5e9;font-weight: bold;">最低分</span>', '<span style="color:#32c5e9;font-weight: bold;">综合平均分</span>'],
+        header: [
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">班级</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">互动</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">合作</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">素养</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">评测</span>',
+          '<span style="color:#7ec4ff;font-weight: 200;font-size:12px">综合</span>',
+        ],
         data: [
         data: [
-          ['大一年级1班', '84.3 分', '84.3 分', '84.3 分'],
-          ['大一年级2班', '82.6 分', '84.3 分', '84.3 分'],
-          ['大一年级3班', '76.0 分', '84.3 分', '84.3 分'],
-          ['大一年级4班', '74.1 分', '84.3 分', '84.3 分'],
-          ['大一年级5班', '65.8 分', '84.3 分', '84.3 分'],
-          ['大一年级6班', '64.3 分', '84.3 分', '84.3 分'],
-          ['大一年级7班', '84.3 分', '84.3 分', '84.3 分'],
-          ['大一年级8班', '82.6 分', '84.3 分', '84.3 分'],
-          ['大一年级9班', '76.0 分', '84.3 分', '84.3 分'],
-          ['大一年级10班', '74.1 分', '84.3 分', '84.3 分'],
-          ['大一年级11班', '65.8 分', '84.3 分', '84.3 分'],
-          ['大一年级12班', '64.3 分', '84.3 分', '84.3 分'],
+          ["1班", "84.3", "65.7", "74.8","74.8","A"],
+          ["2班", "82.6", "64.3", "72.3","74.8","A"],
+          ["3班", "76.0", "60.9", "69.9","74.8","A"],
+          ["4班", "74.1", "52.6", "65.3","74.8","B"],
+          ["5班", "65.8", "48.7", "56.8","74.8","B"],
+          ["6班", "76.0", "60.9", "69.9","74.8","C"],
+          ["7班", "74.1", "52.6", "65.3","74.8","C"],
+          ["8班", "65.8", "48.7", "56.8","74.8","C"],
         ],
         ],
-        align: ['center'],
-        rowNum: 12,
-        headerHeight: 30,
+        align: ["center","center","center","center","center","center"],
+        rowNum: 6,
+        headerHeight: 40,
         headerBGC: "transparent", //表头
         headerBGC: "transparent", //表头
         oddRowBGC: "transparent", //奇数行
         oddRowBGC: "transparent", //奇数行
-        evenRowBGC: "transparent", //偶数行
+        evenRowBGC: "#07427f52",
       },
       },
       stuRankConfig: {
       stuRankConfig: {
         data: [
         data: [

+ 185 - 0
TEAMModelOS/ClientApp/src/view/iot/schooliot.vue

@@ -0,0 +1,185 @@
+<template>
+<div class="schooliotbox">
+    <div class="containerbox">
+        <!--header-->
+            <!--title-->
+            <div class="container-title">
+                <dv-decoration-10 class="dv-dec-10" />
+                <div class="title-center">
+                    <dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" />
+                    <div class="title-text">
+                        <span class="title-textbox">iot数据看板</span>
+                        <dv-decoration-6 class="dv-dec-6" :reverse="true" :color="['#50e3c2', '#67a1e5']" />
+                    </div>
+                    <dv-decoration-8 class="dv-dec-8" :reverse="true" :color="['#568aea', '#000000']" />
+                </div>
+                <dv-decoration-10 class="dv-dec-10-s" />
+            </div>
+             <!--title end -->
+             <!--school name-->
+             <div class="school-name">
+                <img :src="schoolInfo.schoolLogo">
+                <span class="schoolbox-name">{{ schoolInfo.schoolName }}</span>
+                <span class="schoolbox-period">{{ schoolInfo.periodName }}</span>
+                <span class="schoolbox-semester">{{ schoolInfo.curSemester }}</span>
+             </div>
+             <!--school name  end-->
+             <!--time-->
+             <div class="timebox">
+                <span class="timebox-text">{{ times.year }} <span style="display: inline-block; margin: 0 5px;color: #0fa2fe;">{{ times.day }}</span> </span>
+             </div>
+             <!--time end-->
+        <!--header end-->
+    </div>
+</div>
+</template>
+<script>
+export default {
+   name:'schooliot',
+   data(){
+    return{
+        times:{
+            year:null,
+            month:null,
+            week:null,
+            day:null
+        }
+    }
+   },
+   mounted(){
+    this.timeFn()
+   },
+   created(){
+    
+   },
+   computed: {
+    schoolInfo() {
+      let store_user = this.$store.state.user
+      let semesterRange = this.$tools.getSemesterTimeRange()
+      return {
+        schoolName: store_user.schoolProfile.school_base.name,
+        schoolLogo: store_user.schoolProfile.school_base.picture,
+        periodName: store_user.curPeriod.name,
+        curSemester: semesterRange.name_with_year
+      }
+    }
+  },
+   methods:{
+    timeFn() {
+      this.timing = setInterval(() => {
+        this.times.day = this.$tools.formatTime(new Date(), 'hh:mm:ss')
+        this.times.year = this.$tools.formatTime(new Date(), 'yyyy-MM-dd')
+        this.times.week = this.weekday[new Date().getDay()]
+      }, 1000)
+    },
+   }
+}
+</script>
+<style scoped>
+.schooliotbox{
+    color: #d3d6dd;
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    position: relative;
+}
+.containerbox{
+    width:100%;
+    height:100%;
+    padding: 16px 16px 0 16px;
+    background-image:url('../../assets/image/pageBg.png');
+    background-size: cover;
+    background-position: center center;
+}
+.container-title,.title-center{
+    display: flex;
+    flex-wrap: nowrap;
+}
+.title-text{
+    position: relative;
+    width: 500px;
+    text-align: center;
+    background-size: cover;
+    background-repeat: no-repeat;
+}
+.title-textbox{
+    font-size: 28px;
+    font-weight: bold;
+    position: absolute;
+    letter-spacing: 3px;
+    display: inline-block;
+    background-image: linear-gradient(#00b5ef, #7393a6);
+    -webkit-background-clip: text;
+    background-clip: text;
+    font-family: auto;
+    color: transparent;
+    bottom: 15px;
+    left: 50%;
+    transform: translate(-50%);
+    width: 80%;
+}
+.schooliotbox .dv-dec-10{
+    width:33.3%;
+    height:5px;
+    display: flex;
+}
+.schooliotbox .dv-dec-10-s{
+    transform: rotateY(180deg);
+    width:33.3%;
+    height:5px;
+    display: flex;
+}
+.schooliotbox .dv-dec-8{
+    width: 200px;
+    height: 50px;
+    display: flex;
+}
+.schooliotbox .title-center .dv-dec-6{
+    position: absolute;
+    bottom:0;
+    left:50%;
+    width:250px;
+    height:8px;
+    transform: translate(-50%);
+}
+.school-name{
+    position: absolute;
+    left: 30px;
+    top: 40px;
+    font-size: 20px;
+    font-weight: bold;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+}
+.school-name img{
+    border-radius: 50%;
+    width: 25px;
+}
+.schoolbox-name{
+    margin: 0 10px;
+}
+.schoolbox-period,.schoolbox-semester{
+    font-size: 12px;
+    background-color: #2d2d2d;
+    display: inline-block;
+    padding: 2px 10px;
+    border-radius: 4px;
+    margin-right: 5px;
+}
+.timebox{
+    position: absolute;
+    right: 30px;
+    top: 30px;
+    font-size: 26px;
+    font-weight: bold;
+    cursor: pointer;
+}
+.timebox-text{
+    font-size: 30px;
+    margin-right: 20px;
+    font-weight: 200;
+    color: #9f9f9f;
+    font-family: 'staticFont';
+}
+</style>

+ 34 - 4
TEAMModelOS/ClientApp/src/view/mycourse/record/Record.vue

@@ -474,24 +474,25 @@ export default {
         params.expire = true
         params.expire = true
       }
       }
       this.$api.lessonRecord.getLessonList(params).then(
       this.$api.lessonRecord.getLessonList(params).then(
-        res => {
+        async res => {
           if (res.lessonRecords) {
           if (res.lessonRecords) {
             res.lessonRecords.forEach(item => {
             res.lessonRecords.forEach(item => {
               item.show = item.show ? item.show : []
               item.show = item.show ? item.show : []
               item.isShare = item.show.includes('student')
               item.isShare = item.show.includes('student')
             })
             })
-            this.recordList = res.lessonRecords
+            let reList = res.lessonRecords
             let sasInfo = {}
             let sasInfo = {}
             let blobInfo = this.rcdParams.scope === 'school' ? this.$store.state.user.schoolProfile : this.$store.state.user.userProfile
             let blobInfo = this.rcdParams.scope === 'school' ? this.$store.state.user.schoolProfile : this.$store.state.user.userProfile
             sasInfo.sas = '?' + blobInfo.blob_sas
             sasInfo.sas = '?' + blobInfo.blob_sas
             sasInfo.name = this.rcdParams.scope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
             sasInfo.name = this.rcdParams.scope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
             sasInfo.url = blobInfo.blob_uri.slice(0, blobInfo.blob_uri.lastIndexOf(sasInfo.name) - 1)
             sasInfo.url = blobInfo.blob_uri.slice(0, blobInfo.blob_uri.lastIndexOf(sasInfo.name) - 1)
-            this.recordList.forEach(item => {
+            reList.forEach(item => {
               item.sokrateImg = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Sokrates/SokratesResults/event.png${sasInfo.sas}`
               item.sokrateImg = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Sokrates/SokratesResults/event.png${sasInfo.sas}`
               item.eNote = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Note.pdf${sasInfo.sas}`
               item.eNote = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Note.pdf${sasInfo.sas}`
               item.video = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Record/CourseRecord.mp4${sasInfo.sas}`
               item.video = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Record/CourseRecord.mp4${sasInfo.sas}`
-              item.poster = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Record/CoverImage.jpg${sasInfo.sas}`
+              // item.poster = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Record/CoverImage.jpg${sasInfo.sas}`
             })
             })
+            this.recordList = await this.getCoverImg(reList)
             this.recordList.sort((a, b) => {
             this.recordList.sort((a, b) => {
               return a.startTime - b.startTime > 0 ? -1 : 1
               return a.startTime - b.startTime > 0 ? -1 : 1
             })
             })
@@ -502,6 +503,35 @@ export default {
         }
         }
       )
       )
     },
     },
+    getCoverImg(lists) {
+        return new Promise(async (resolve, reject) => {
+            let promiseArr = []
+            let sasInfo = {}
+            let blobInfo = this.rcdParams.scope === 'school' ? this.$store.state.user.schoolProfile : this.$store.state.user.userProfile
+            sasInfo.sas = '?' + blobInfo.blob_sas
+            sasInfo.name = this.rcdParams.scope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
+            sasInfo.url = blobInfo.blob_uri.slice(0, blobInfo.blob_uri.lastIndexOf(sasInfo.name) - 1)
+            lists.forEach((item, index) => {
+                promiseArr.push(new Promise(async (r, j) => {
+                    let imageCover = ''
+                    try {
+                        let url = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/IES/TimeLine.json${sasInfo.sas}`
+                        let res = JSON.parse(await this.$tools.getFile(url))
+                        let pgids = res.PgIdList || []
+                        imageCover = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Memo/${pgids[0]}.jpg${sasInfo.sas}`
+                    } catch (e) {
+                    }
+                    item.poster = imageCover
+                    r(item)
+                }))
+            })
+            Promise.all(promiseArr).then(res => {
+                resolve(res)
+            }).catch(err => {
+                reject(err)
+            })
+        })
+    },
   },
   },
   watch: {
   watch: {
     rcdParams: {
     rcdParams: {

+ 1 - 0
TEAMModelOS/ClientApp/src/view/student-web/AppNew.vue

@@ -519,6 +519,7 @@ export default {
             this.$store.commit("setNowCourse", undefined)
             this.$store.commit("setNowCourse", undefined)
             this.$store.commit("setAllCourse", [])
             this.$store.commit("setAllCourse", [])
             this.$store.commit("setOnlySystem", false)
             this.$store.commit("setOnlySystem", false)
+            this.$store.commit("setisScale", false)
             localStorage.removeItem('Item')
             localStorage.removeItem('Item')
             localStorage.removeItem('subjectNow')
             localStorage.removeItem('subjectNow')
             localStorage.removeItem('examInfo')
             localStorage.removeItem('examInfo')

+ 1 - 1
TEAMModelOS/Controllers/Both/CourseBaseController.cs

@@ -708,7 +708,7 @@ namespace TEAMModelOS.Controllers.Both
                                     continue;
                                     continue;
                                 }
                                 }
                                 //获取当前学年,当前学期,当前导入时间的日期,以及下学期开学时间
                                 //获取当前学年,当前学期,当前导入时间的日期,以及下学期开学时间
-                                (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) info = SchoolService.GetSemester(period, item.stime);
+                                (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) info = SchoolService.GetSemester(period,time: item.stime);
                                 if (info.currSemester != null)
                                 if (info.currSemester != null)
                                 {
                                 {
                                     //5.2检查课程结束日期格式是否正确
                                     //5.2检查课程结束日期格式是否正确

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1868 - 85
TEAMModelOS/Controllers/Both/ScoreCalcController.cs


+ 2 - 0
TEAMModelOS/Controllers/OpenApi/Business/BizCustomizeController.cs

@@ -485,10 +485,12 @@ namespace TEAMModelOS.Controllers
                         temp.score = oAnswer.score;
                         temp.score = oAnswer.score;
                         //智音数据来源
                         //智音数据来源
                         temp.source = 1;
                         temp.source = 1;
+
                         studentArtResult.zyanswer.questionId = oAnswer.questionId;
                         studentArtResult.zyanswer.questionId = oAnswer.questionId;
                         studentArtResult.zyanswer.thirdAnswerId = oAnswer.thirdAnswerId;
                         studentArtResult.zyanswer.thirdAnswerId = oAnswer.thirdAnswerId;
                         studentArtResult.zyanswer.score = oAnswer.score;
                         studentArtResult.zyanswer.score = oAnswer.score;
                         studentArtResult.zyanswer.detail = oAnswer.detail;
                         studentArtResult.zyanswer.detail = oAnswer.detail;
+                        studentArtResult.zyanswer.time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                         await cosmosClient.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StudentArtResult>(studentArtResult, studentArtResult.id, new PartitionKey(studentArtResult.code));
                         await cosmosClient.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StudentArtResult>(studentArtResult, studentArtResult.id, new PartitionKey(studentArtResult.code));
                         return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Ok, msg = "成功", data = oAnswer } });
                         return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Ok, msg = "成功", data = oAnswer } });
                     }
                     }

+ 79 - 52
TEAMModelOS/Controllers/System/BlobController.cs

@@ -34,6 +34,8 @@ using TEAMModelOS.SDK.Services;
 using DocumentFormat.OpenXml.Wordprocessing;
 using DocumentFormat.OpenXml.Wordprocessing;
 using OpenXmlPowerTools;
 using OpenXmlPowerTools;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Specialized;
+using DocumentFormat.OpenXml.Drawing.Wordprocessing;
 
 
 namespace TEAMModelOS.Controllers
 namespace TEAMModelOS.Controllers
 {
 {
@@ -853,62 +855,83 @@ namespace TEAMModelOS.Controllers
         [AuthToken(Roles = "teacher,admin")]
         [AuthToken(Roles = "teacher,admin")]
         [HttpPost("delete-unlink")]
         [HttpPost("delete-unlink")]
         public async Task<IActionResult> DeleteUnlink(JsonElement json) {
         public async Task<IActionResult> DeleteUnlink(JsonElement json) {
-            var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
-            int status = 0;
-            if (!json.TryGetProperty("scope", out JsonElement scope))
-            {
-                return Ok(new { status, msg = "参数错误" });
-            }
-            string containerName = scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase) ? school : userid;
-            bool exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:ScanResult:{scope}:{containerName}");
-            if (exists)
-            {
-                var result = await _azureRedis.GetRedisClient(8).StringGetAsync($"Blob:ScanResult:{scope}:{containerName}");
-                if (result.HasValue)
+            try {
+                var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
+                int status = 0;
+                if (!json.TryGetProperty("scope", out JsonElement scope))
                 {
                 {
-                    List<UnLink> unLinksData = result.ToString().ToObject<List<UnLink>>();
-                    if (unLinksData.IsNotEmpty())
+                    return Ok(new { status, msg = "参数错误" });
+                }
+                string containerName = scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase) ? school : userid;
+                bool exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:ScanResult:{scope}:{containerName}");
+                if (exists)
+                {
+                    var result = await _azureRedis.GetRedisClient(8).StringGetAsync($"Blob:ScanResult:{scope}:{containerName}");
+                    if (result.HasValue)
                     {
                     {
-                        List<Task<Azure.Response<bool>>> list = new List<Task<Response<bool>>>();
-                        unLinksData.ForEach(unLink =>
-                       {
-                           foreach (var item in unLink.blobs.Select(z => z.Key))
-                           {
-                               var ps = item.Split("/");
-                               if (ps.Length > 2)
-                               {
-                                   //list.Add(_azureStorage.GetBlobContainerClient(containerName.ToString()).DeleteBlobIfExistsAsync(item));
-                               }
-                               else if (ps.Length == 2 && ps[1].Contains('.'))
-                               {
-
-                                   //list.Add(_azureStorage.GetBlobContainerClient(containerName.ToString()).DeleteBlobIfExistsAsync(item));
-                               }
-                           }
-                       });
-                        if (list.Count > 0)
+                        List<UnLink> unLinksData = result.ToString().ToObject<List<UnLink>>();
+                        if (unLinksData.IsNotEmpty())
                         {
                         {
-                            if (list.Count <= 256)
+                            var uri = _azureStorage.GetBlobContainerClient(containerName).Uri;
+                            BlobBatchClient blobBatch = _azureStorage.GetBlobContainerClient(containerName).GetBlobBatchClient();
+                            foreach (var unLink in unLinksData)
                             {
                             {
-                                await Task.WhenAll(list);
-                            }
-                            else
-                            {
-                                int pages = (list.Count + 255) / 256; //256是批量操作最大值,pages = (total + max -1) / max;
-                                for (int i = 0; i < pages; i++)
+
+                                var urls =  unLink.blobs.Select(z => z.Key).Select(z =>  new Uri(Path.Combine(uri.ToString(), z)));
+
+                                int len = 100;
+                                if (urls.Count() > 0)
                                 {
                                 {
-                                    List<Task<Azure.Response<bool>>> lists = list.Skip((i) * 256).Take(256).ToList();
-                                    await Task.WhenAll(lists);
+                                    if (urls.Count() <= len)
+                                    {
+                                        try
+                                        {
+                                            await blobBatch.DeleteBlobsAsync(urls);
+                                        }
+                                        catch (Exception ex) { }
+                                    }
+                                    else
+                                    {
+                                        int pages = (urls.Count() + len) / len; //256是批量操作最大值,pages = (total + max -1) / max;
+                                        for (int i = 0; i < pages; i++)
+                                        {
+                                            List<Uri> lists = urls.Skip((i) * len).Take(len).ToList();
+                                            try
+                                            {
+                                                await blobBatch.DeleteBlobsAsync(lists);
+                                            }
+                                            catch (Exception ex) { }
+                                        }
+                                    }
                                 }
                                 }
                             }
                             }
-                        }
-                        //为节省服务器开销, 限制只能一天清理一次
+                            //为节省服务器开销, 限制只能一天清理一次
 #if DEBUG
 #if DEBUG
-                        _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", new List<UnLink>().ToJsonString(), expiry: new TimeSpan(0, 0, 30));
+                            _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", new List<UnLink>().ToJsonString(), expiry: new TimeSpan(0, 0, 30));
 #else
 #else
-             _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", new List<UnLink>().ToJsonString(), expiry: new TimeSpan(24, 0, 0));
+                        _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", new List<UnLink>().ToJsonString(), expiry: new TimeSpan(24, 0, 0));
 #endif
 #endif
-                        return Ok(new { status = 3, msg = "清理成功!" });
+                            HashSet<string> root = null;
+                            if (_option.Location.Contains("Test", StringComparison.OrdinalIgnoreCase) || _option.Location.Contains("Dep", StringComparison.OrdinalIgnoreCase))
+                            {
+                                root = unLinksData.Select(x => x.prefix).ToHashSet();
+                            }
+                            else
+                            {
+                                root = unLinksData.Where(z => z.size > 0).Select(x => x.prefix).ToHashSet();
+                            }
+                            if (root != null)
+                            {
+                                root.ToList().ForEach(async x => {
+                                    await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = x, name = $"{containerName}" }, _serviceBus, _configuration, _azureRedis);
+                                });
+                            }
+                            return Ok(new { status = 3, msg = "清理成功!" });
+                        }
+                        else
+                        {
+                            return Ok(new { status = 2, msg = "最近清理过,暂无清理项!" });
+                        }
                     }
                     }
                     else
                     else
                     {
                     {
@@ -917,13 +940,13 @@ namespace TEAMModelOS.Controllers
                 }
                 }
                 else
                 else
                 {
                 {
-                    return Ok(new { status = 2, msg = "最近清理过,暂无清理项!" });
+                    return Ok(new { status = 4, msg = "请重新检查清理项!" });
                 }
                 }
+            } catch (Exception ex ) {
+              await  _dingDing.SendBotMsg($"{_option.Location},{DeleteUnlink}\n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
             }
             }
-            else {
-                return Ok(new { status=4, msg = "请重新检查清理项!" });
-            }
-            
+            return Ok(new { status = 4, msg = "请重新检查清理项!" });
+
         }
         }
         [ProducesDefaultResponseType]
         [ProducesDefaultResponseType]
         [Authorize(Roles = "IES")]
         [Authorize(Roles = "IES")]
@@ -1009,6 +1032,10 @@ namespace TEAMModelOS.Controllers
                                     long? size = unlink.Select(z => z.Value).Sum();
                                     long? size = unlink.Select(z => z.Value).Sum();
                                     unLinks.Add(new UnLink { prefix = prefix, blobs = unlink, size = size });
                                     unLinks.Add(new UnLink { prefix = prefix, blobs = unlink, size = size });
                                 }
                                 }
+                                else {
+                                    long? size = blobs.Select(z => z.Value).Sum();
+                                    unLinks.Add(new UnLink { prefix = prefix, blobs = blobs, size = size });
+                                }
                             }
                             }
                             break;
                             break;
                         }
                         }
@@ -1328,7 +1355,7 @@ namespace TEAMModelOS.Controllers
              _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", unLinks.ToJsonString(), expiry: new TimeSpan(24, 0, 0));
              _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", unLinks.ToJsonString(), expiry: new TimeSpan(24, 0, 0));
 #endif
 #endif
 
 
-            return Ok(new { status = 1, totalCount, totalSize, summary, /*unLinks*/ });
+            return Ok(new { status = 1, totalCount, totalSize, summary, unLinks });
         }
         }
     }
     }
 }
 }

+ 168 - 2
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -4,6 +4,7 @@ using Azure.Cosmos;
 using Azure.Messaging.ServiceBus;
 using Azure.Messaging.ServiceBus;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs.Models;
 using Azure.Storage.Blobs.Models;
+using Azure.Storage.Blobs.Specialized;
 using DinkToPdf;
 using DinkToPdf;
 using DinkToPdf.Contracts;
 using DinkToPdf.Contracts;
 using DocumentFormat.OpenXml.Drawing.Wordprocessing;
 using DocumentFormat.OpenXml.Drawing.Wordprocessing;
@@ -48,9 +49,11 @@ using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
 using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Services;
 using TEAMModelOS.SDK.Services;
+using Top.Api;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.SchoolService;
 using static TEAMModelOS.SDK.SchoolService;
 
 
@@ -86,8 +89,171 @@ namespace TEAMModelOS.Controllers
             _coreAPIHttpService = coreAPIHttpService;
             _coreAPIHttpService = coreAPIHttpService;
             _searcher = searcher;
             _searcher = searcher;
         }
         }
-
-       
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("transform-lessonrecord-overalleducation")]
+        public async Task<IActionResult> TransformLessonrecordOveralleducation(JsonElement json) {
+            //string msg = json.ToString();
+            //var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
+            //var messageChange = new ServiceBusMessage(msg);
+            //messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
+            //await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
+            string sql = "select value c from  c  where  c.pk='StudentScoreRecord' and c.userType='student' and c.school<>null  and c.school<>'' ";
+            List<StudentScoreRecord> studentScores = new List<StudentScoreRecord>();
+            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<StudentScoreRecord>(sql)) {
+                studentScores.Add(item);
+            }
+            var group = studentScores.GroupBy(z => z.school);
+            string schoolSql = $"select value c from c where c.id in ({string.Join(",",group.Select(x=>$"'{x.Key}'"))})";
+            var resultScool= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<School>(schoolSql,"Base");
+            foreach(var item in group)
+            {
+                var list = item.ToList();
+                var stuids = list.Select(z => z.stuid);
+                string studentSql = $"select value c from c where c.id in ({string.Join(",", stuids.Select(x => $"'{x}'"))})";
+                var resultStuden = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>(studentSql, $"Base-{item.Key}");
+               
+                foreach (var sturecord in list) {
+                    HashSet<OverallEducation> overallEducations = new HashSet<OverallEducation>();
+                    var studentBase = resultStuden.list.Find(x => x.id.Equals(sturecord.stuid, StringComparison.OrdinalIgnoreCase));
+                    var schoolBase = resultScool.list.Find(x => x.id.Equals(sturecord.school, StringComparison.OrdinalIgnoreCase));
+                    if (studentBase == null) {
+                        continue;
+                    }
+                    var  period = schoolBase.period.Find(x => x.id.Equals($"{studentBase.periodId}"));
+                    foreach (var record in sturecord.lessonRecords) {
+                        if (record.time > 1000000000000) {
+                            (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) dataSemester = SchoolService.GetSemester(period, record.time);
+                            string oid = $"{dataSemester.studyYear}-{dataSemester.currSemester.id}-{sturecord.stuid}";
+                            string ocode = $"OverallEducation-{sturecord.school}";
+                            OverallEducation overallEducation =  overallEducations.Where(o => o.id.Equals(oid, StringComparison.OrdinalIgnoreCase) && o.code.Equals(ocode, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
+                            if (overallEducation != null)
+                            {
+                                var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(record.lessonId));
+                                if (hasrecord != null)
+                                {
+                                    hasrecord.gscore = record.gscore;
+                                    hasrecord.pscore = record.pscore;
+                                    hasrecord.tscore = record.tscore;
+                                    hasrecord.tmdid = record.tmdid;
+                                    hasrecord.school = record.school;
+                                    hasrecord.scope = record.scope;
+                                    hasrecord.lessonId = record.lessonId;
+                                    hasrecord.courseId = record.courseId;
+                                    hasrecord.periodId = record.periodId;
+                                    hasrecord.subjectId = record.subjectId;
+                                    hasrecord.time = record.time;
+                                }
+                                else
+                                {
+                                    overallEducation.lessonScore.Add(
+                                         new StudentLessonRecord
+                                         {
+                                             gscore = record.gscore,
+                                             pscore = record.pscore,
+                                             tscore = record.tscore,
+                                             tmdid = record.tmdid,
+                                             school = record.school,
+                                             scope = record.scope,
+                                             lessonId = record.lessonId,
+                                             courseId = record.courseId,
+                                             periodId = record.periodId,
+                                             subjectId = record.subjectId,
+                                             time = record.time
+                                         }
+                                     );
+                                }
+                            }
+                            else {
+                                Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).ReadItemStreamAsync(oid, new PartitionKey(ocode));
+                                if (response.Status != 200)
+                                {
+                                    overallEducation = new OverallEducation
+                                    {
+                                        id = oid,
+                                        code = $"OverallEducation-{sturecord.school}",
+                                        pk = "OverallEducation",
+                                        ttl = -1,
+                                        name = studentBase.name,
+                                        classId = studentBase?.classId,
+                                        schoolCode = $"{sturecord.school}",
+                                        semesterId = dataSemester.currSemester.id,
+                                        year = dataSemester.studyYear,
+                                        periodId = $"{period.id}",
+                                        stuYear = studentBase.year,
+                                        studentId = studentBase.id,
+                                        lessonScore = new List<StudentLessonRecord>
+                                    {
+                                        new StudentLessonRecord
+                                        {
+                                            gscore = record.gscore,
+                                            pscore = record.pscore,
+                                            tscore = record.tscore,
+                                            tmdid = record.tmdid,
+                                            school = record.school,
+                                            scope = record.scope,
+                                            lessonId = record.lessonId,
+                                            courseId = record.courseId,
+                                            periodId = record.periodId,
+                                            subjectId = record.subjectId,
+                                            time= record.time
+                                         }
+                                    }
+                                    };
+                                }
+                                else
+                                {
+                                    overallEducation = JsonDocument.Parse(response.Content).RootElement.ToObject<OverallEducation>();
+                                    var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(record.lessonId));
+                                    if (hasrecord != null)
+                                    {
+                                        hasrecord.gscore = record.gscore;
+                                        hasrecord.pscore = record.pscore;
+                                        hasrecord.tscore = record.tscore;
+                                        hasrecord.tmdid = record.tmdid;
+                                        hasrecord.school = record.school;
+                                        hasrecord.scope = record.scope;
+                                        hasrecord.lessonId = record.lessonId;
+                                        hasrecord.courseId = record.courseId;
+                                        hasrecord.periodId = record.periodId;
+                                        hasrecord.subjectId = record.subjectId;
+                                        hasrecord.time = record.time;
+                                    }
+                                    else
+                                    {
+                                        overallEducation.lessonScore.Add(
+                                             new StudentLessonRecord
+                                             {
+                                                 gscore = record.gscore,
+                                                 pscore = record.pscore,
+                                                 tscore = record.tscore,
+                                                 tmdid = record.tmdid,
+                                                 school = record.school,
+                                                 scope = record.scope,
+                                                 lessonId = record.lessonId,
+                                                 courseId = record.courseId,
+                                                 periodId = record.periodId,
+                                                 subjectId = record.subjectId,
+                                                 time = record.time
+                                             }
+                                         );
+                                    }
+                                }
+                                overallEducations.Add(overallEducation);
+                            }
+                        }
+                    }
+                    foreach (var overallEducation in overallEducations) {
+                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(overallEducation, partitionKey: new PartitionKey(overallEducation.code));
+                    }
+                }
+            }
+            return Ok();
+        }
 
 
         /// <summary>
         /// <summary>
         /// 
         /// 

+ 4 - 4
TEAMModelOS/TEAMModelOS.csproj

@@ -69,11 +69,11 @@
     <SpaRoot>ClientApp\</SpaRoot>
     <SpaRoot>ClientApp\</SpaRoot>
     <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
     <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
     <UserSecretsId>078b5d89-7d90-4f6a-88fc-7d96025990a8</UserSecretsId>
     <UserSecretsId>078b5d89-7d90-4f6a-88fc-7d96025990a8</UserSecretsId>
-    <Version>5.2306.14</Version>
-    <AssemblyVersion>5.2306.14.1</AssemblyVersion>
-    <FileVersion>5.2306.14.1</FileVersion>
+    <Version>5.2306.20</Version>
+    <AssemblyVersion>5.2306.20.1</AssemblyVersion>
+    <FileVersion>5.2306.20.1</FileVersion>
     <Description>TEAMModelOS(IES5)</Description>
     <Description>TEAMModelOS(IES5)</Description>
-    <PackageReleaseNotes>IES版本说明版本切换标记5.2306.14.1</PackageReleaseNotes>
+    <PackageReleaseNotes>IES版本说明版本切换标记5.2306.20.1</PackageReleaseNotes>
     <PackageId>TEAMModelOS</PackageId>
     <PackageId>TEAMModelOS</PackageId>
     <Authors>teammodel</Authors>
     <Authors>teammodel</Authors>
     <Company>醍摩豆(成都)信息技术有限公司</Company>
     <Company>醍摩豆(成都)信息技术有限公司</Company>

+ 3 - 3
TEAMModelOS/appsettings.Development.json

@@ -18,10 +18,10 @@
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4",
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4",
     "HttpTrigger": "https://teammodelosfunction-test.chinacloudsites.cn/api/",
     "HttpTrigger": "https://teammodelosfunction-test.chinacloudsites.cn/api/",
     //"HttpTrigger": "http://localhost:7071/api/"
     //"HttpTrigger": "http://localhost:7071/api/"
-    "Version": "5.2306.14.1"
+    "Version": "5.2306.20.1"
   },
   },
   "Azure": {
   "Azure": {
-    // 测试站数据库
+     //测试站数据库
     "Storage": {
     "Storage": {
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
     },
     },
@@ -39,7 +39,7 @@
     },
     },
     "SignalR": {
     "SignalR": {
       "ConnectionString": "Endpoint=https://channel.service.signalr.net;AccessKey=KrblW06tuA4a/GyqRPDU0ynFFmAWxbAvyJihHclSXbQ=;Version=1.0;"
       "ConnectionString": "Endpoint=https://channel.service.signalr.net;AccessKey=KrblW06tuA4a/GyqRPDU0ynFFmAWxbAvyJihHclSXbQ=;Version=1.0;"
-    },
+    }
     // 正式站数据库
     // 正式站数据库
     //"Storage": {
     //"Storage": {
     //  "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelos;AccountKey=Dl04mfZ9hE9cdPVO1UtqTUQYN/kz/dD/p1nGvSq4tUu/4WhiKcNRVdY9tbe8620nPXo/RaXxs+1F9sVrWRo0bg==;EndpointSuffix=core.chinacloudapi.cn"
     //  "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelos;AccountKey=Dl04mfZ9hE9cdPVO1UtqTUQYN/kz/dD/p1nGvSq4tUu/4WhiKcNRVdY9tbe8620nPXo/RaXxs+1F9sVrWRo0bg==;EndpointSuffix=core.chinacloudapi.cn"

+ 1 - 1
TEAMModelOS/appsettings.json

@@ -18,7 +18,7 @@
     "Exp": 86400,
     "Exp": 86400,
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4",
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4",
     "HttpTrigger": "https://teammodelosfunction.chinacloudsites.cn/api/",
     "HttpTrigger": "https://teammodelosfunction.chinacloudsites.cn/api/",
-    "Version": "5.2306.14.1"
+    "Version": "5.2306.20.1"
   },
   },
   "Azure": {
   "Azure": {
     "Storage": {
     "Storage": {