CrazyIter_Bin 2 年之前
父节点
当前提交
b489653b59
共有 100 个文件被更改,包括 7106 次插入3089 次删除
  1. 73 73
      TEAMModelBI/ClientApp/src/components/echarts/doublePie.vue
  2. 26 18
      TEAMModelBI/ClientApp/src/router/index.js
  3. 64 8
      TEAMModelBI/ClientApp/src/view/areamanage/statistics.vue
  4. 19 11
      TEAMModelBI/ClientApp/src/view/common/aside.vue
  5. 2 2
      TEAMModelBI/ClientApp/src/view/participation/index.vue
  6. 4 10
      TEAMModelBI/ClientApp/src/view/participation/setAbility.vue
  7. 4 4
      TEAMModelBI/ClientApp/src/view/schoolServe/analyseSchool.vue
  8. 114 8
      TEAMModelBI/ClientApp/src/view/schoolServe/school.vue
  9. 24 17
      TEAMModelBI/ClientApp/src/view/systemConfig/apimanage.vue
  10. 110 8
      TEAMModelBI/ClientApp/src/view/systemConfig/correlation.vue
  11. 2 2
      TEAMModelBI/ClientApp/src/view/systemConfig/index.vue
  12. 2 1
      TEAMModelBI/ClientApp/src/view/teachermanage/manage.vue
  13. 2 13
      TEAMModelBI/Controllers/BIBlob/AnalyseFileController.cs
  14. 2 34
      TEAMModelBI/Controllers/BICommon/JointlyController.cs
  15. 1 3
      TEAMModelBI/Controllers/BIHome/HomeStatisController.cs
  16. 10 117
      TEAMModelBI/Controllers/BIHome/OnLineController.cs
  17. 6 9
      TEAMModelBI/Controllers/BINormal/AbilityMgmtController.cs
  18. 9 11
      TEAMModelBI/Controllers/BINormal/AbilityTaskMgmtController.cs
  19. 0 638
      TEAMModelBI/Controllers/BINormal/AppCompanyController.cs
  20. 3 4
      TEAMModelBI/Controllers/BINormal/AreaRelevantController.cs
  21. 4 11
      TEAMModelBI/Controllers/BINormal/BatchAreaController.cs
  22. 0 3
      TEAMModelBI/Controllers/BINormal/BusinessConfigController.cs
  23. 29 43
      TEAMModelBI/Controllers/BISchool/BatchSchoolController.cs
  24. 2 6
      TEAMModelBI/Controllers/BISchool/RoomController.cs
  25. 22 61
      TEAMModelBI/Controllers/BISchool/SchoolController.cs
  26. 5 4
      TEAMModelBI/Controllers/BIStudent/StudentController.cs
  27. 0 2
      TEAMModelBI/Controllers/BITable/BIOpenApiController.cs
  28. 27 27
      TEAMModelBI/Controllers/BITable/DDStructController.cs
  29. 3 3
      TEAMModelBI/Controllers/BITable/OperateLogController.cs
  30. 23 116
      TEAMModelBI/Controllers/BITable/TableDingDingInfoController.cs
  31. 4 2
      TEAMModelBI/Controllers/BITeacher/TeacherController.cs
  32. 17 19
      TEAMModelBI/Controllers/BITest/TestController.cs
  33. 38 30
      TEAMModelBI/Controllers/Census/ActivitySticsController.cs
  34. 24 32
      TEAMModelBI/Controllers/Census/BlobLogController.cs
  35. 17 13
      TEAMModelBI/Controllers/Census/ItemSticsController.cs
  36. 7 1
      TEAMModelBI/Controllers/Census/LessonSticsController.cs
  37. 12 7
      TEAMModelBI/Controllers/Census/PaperController.cs
  38. 17 18
      TEAMModelBI/Controllers/Census/ProductStatisController.cs
  39. 4 0
      TEAMModelBI/Controllers/Census/SchoolController.cs
  40. 1 82
      TEAMModelBI/Controllers/LoginController.cs
  41. 1 0
      TEAMModelBI/Controllers/ManySiteCut/SystemConfigController.cs
  42. 1 41
      TEAMModelBI/Controllers/RepairApi/TeacherREPController.cs
  43. 41 0
      TEAMModelBI/Tool/CommonFind.cs
  44. 19 0
      TEAMModelBI/appsettings.Development.json
  45. 3 3
      TEAMModelOS.FunctionV4/TEAMModelOS.FunctionV4.csproj
  46. 284 11
      TEAMModelOS.FunctionV4/TimeTrigger/IESTimerTrigger.cs
  47. 22 0
      TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeID.cs
  48. 27 0
      TEAMModelOS.SDK/Helper/Common/TaskAll/BatchTask.cs
  49. 5 1
      TEAMModelOS.SDK/Helper/Network/IP2Region/IPSearcher.cs
  50. 1 1
      TEAMModelOS.SDK/Models/Cosmos/BI/BICommon/MonthStartEnd.cs
  51. 5 0
      TEAMModelOS.SDK/Models/Cosmos/BI/StaticValue.cs
  52. 15 0
      TEAMModelOS.SDK/Models/Cosmos/Common/GroupList.cs
  53. 9 4
      TEAMModelOS.SDK/Models/Cosmos/School/Class.cs
  54. 3 3
      TEAMModelOS.SDK/Models/Cosmos/Student/Student.cs
  55. 155 22
      TEAMModelOS.SDK/Models/Service/GroupListService.cs
  56. 0 3
      TEAMModelOS.SDK/Models/Service/LoginService.cs
  57. 81 125
      TEAMModelOS/ClientApp/public/lang/en-US.js
  58. 33 2
      TEAMModelOS/ClientApp/public/lang/zh-CN.js
  59. 38 6
      TEAMModelOS/ClientApp/public/lang/zh-TW.js
  60. 0 43
      TEAMModelOS/ClientApp/src/api/courseMgmt.js
  61. 1 1
      TEAMModelOS/ClientApp/src/api/login.js
  62. 二进制
      TEAMModelOS/ClientApp/src/assets/image/cus-import-cn.png
  63. 二进制
      TEAMModelOS/ClientApp/src/assets/image/cus-import-en.png
  64. 二进制
      TEAMModelOS/ClientApp/src/assets/image/cus-import-tw.png
  65. 4 4
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  66. 419 418
      TEAMModelOS/ClientApp/src/common/BaseNotification.vue
  67. 274 276
      TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue
  68. 210 178
      TEAMModelOS/ClientApp/src/common/BaseUpload.vue
  69. 2 2
      TEAMModelOS/ClientApp/src/components/coursemgt/StudentList.vue
  70. 2 16
      TEAMModelOS/ClientApp/src/components/dashboard/art/BaseStuLineBar.vue
  71. 449 0
      TEAMModelOS/ClientApp/src/components/dashboard/art/BaseYdztRadar.vue
  72. 445 0
      TEAMModelOS/ClientApp/src/components/dashboard/art/BaseYdztRadarMusic.vue
  73. 57 4
      TEAMModelOS/ClientApp/src/components/dashboard/art/LeftCenter.vue
  74. 65 11
      TEAMModelOS/ClientApp/src/components/dashboard/art/RightTop.vue
  75. 410 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseList.less
  76. 1184 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView.vue
  77. 136 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/ActivityView.less
  78. 380 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/ActivityView.vue
  79. 77 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/SchoolReport.less
  80. 317 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/SchoolReport.vue
  81. 162 0
      TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseiView.less
  82. 226 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.less
  83. 5 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.vue
  84. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContent.vue
  85. 0 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/LessonTestReport.less
  86. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  87. 0 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperTest.less
  88. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.vue
  89. 0 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperView-style.less
  90. 0 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperView.less
  91. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue
  92. 0 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/SubjectMould.vue
  93. 184 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.less
  94. 295 326
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue
  95. 36 36
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventView.vue
  96. 210 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventiView.less
  97. 36 36
      TEAMModelOS/ClientApp/src/components/student-web/EventView/ExamView.vue
  98. 36 36
      TEAMModelOS/ClientApp/src/components/student-web/EventView/HomeworkView.vue
  99. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseView/ActivityView.vue
  100. 0 0
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeViewnnnnew.less

+ 73 - 73
TEAMModelBI/ClientApp/src/components/echarts/doublePie.vue

@@ -1,89 +1,89 @@
 <!--基础折线图-->
 <template>
-    <div ref="myEcharts" :style="{ height, width }"></div>
+  <div ref="myEcharts" :style="{ height, width }"></div>
 </template>
 <script>
 import { ref, onMounted, nextTick, watch, getCurrentInstance } from 'vue'
 import * as echarts from 'echarts'
 export default {
-    name: 'baseBar',
-    props: {
-        width: {
-            type: String,
-            default: '100%',
-        },
-        height: {
-            type: String,
-            default: '100%',
-        },
-        doublePieData: {
-            type: Object,
-            default: () => {},
-        },
-        title: {
-            type: String,
-            default: '',
-        },
+  name: 'baseBar',
+  props: {
+    width: {
+      type: String,
+      default: '100%',
     },
-    setup(props) {
-        const myEcharts = ref(null)
-        let { proxy } = getCurrentInstance()
-        const chart = new InitChart(props, myEcharts)
-        onMounted(() => {
-            chart.init(props.doublePieData, proxy)
-        })
-        watch(
-            props,
-            (nweProps) => {
-                nextTick(() => {
-                    nweProps ? chart.init(props.doublePieData, proxy) : ''
-                })
-            },
-            { immediate: true, deep: true }
-        )
-        return {
-            myEcharts,
-        }
+    height: {
+      type: String,
+      default: '100%',
+    },
+    doublePieData: {
+      type: Object,
+      default: () => { },
+    },
+    title: {
+      type: String,
+      default: '',
     },
+  },
+  setup (props) {
+    const myEcharts = ref(null)
+    let { proxy } = getCurrentInstance()
+    const chart = new InitChart(props, myEcharts)
+    onMounted(() => {
+      chart.init(props.doublePieData, proxy)
+    })
+    watch(
+      props,
+      (nweProps) => {
+        nextTick(() => {
+          nweProps ? chart.init(props.doublePieData, proxy) : ''
+        })
+      },
+      { immediate: true, deep: true }
+    )
+    return {
+      myEcharts,
+    }
+  },
 }
 class InitChart {
-    constructor(props, myEcharts) {
-        this.props = props
-        this.myEcharts = myEcharts
-        this.state = {
-            chart: null,
-        }
-    }
-    init(datas, proxy) {
-        // var color = ['#55E6C1 ', '#25CCF7', '#F97F51', '#ff7675', '#5352ed', '#D6A2E8']
-        // var data = [
-        //     { value: 9, name: '已完成' },
-        //     { value: 33, name: '进行中' },
-        //     { value: 82, name: '未完成' },
-        // ]
-        console.log(datas, 'double调用')
-        this.state.chart && this.destory()
-        this.state.chart = echarts.init(this.myEcharts.value)
-        this.state.chart.setOption({
-            color: datas.color ? datas.color : '',
-            tooltip: {
-                trigger: 'item',
-                formatter: '{a} <br/>{b}: {c} ({d}%)',
-            },
-            legend: datas.legend ? datas.legend : {},
-            series: datas.series ? datas.series : [],
-        })
-        window.addEventListener('resize', () => {
-            this.state.chart.resize()
-        })
+  constructor(props, myEcharts) {
+    this.props = props
+    this.myEcharts = myEcharts
+    this.state = {
+      chart: null,
     }
+  }
+  init (datas, proxy) {
+    // var color = ['#55E6C1 ', '#25CCF7', '#F97F51', '#ff7675', '#5352ed', '#D6A2E8']
+    // var data = [
+    //     { value: 9, name: '已完成' },
+    //     { value: 33, name: '进行中' },
+    //     { value: 82, name: '未完成' },
+    // ]
+    console.log(datas, 'double调用')
+    this.state.chart && this.destory()
+    this.state.chart = echarts.init(this.myEcharts.value)
+    this.state.chart.setOption({
+      color: datas.color ? datas.color : '',
+      tooltip: datas.tooltip ? datas.tooltip : {
+        trigger: 'item',
+        formatter: '{a} <br/>{b}: {c} ({d}%)',
+      },
+      legend: datas.legend ? datas.legend : {},
+      series: datas.series ? datas.series : [],
+    })
+    window.addEventListener('resize', () => {
+      this.state.chart.resize()
+    })
+  }
 
-    destory() {
-        this.state.chart.dispose()
-        window.removeEventListener('resize', () => {
-            console.log('事件移除')
-        })
-    }
+  destory () {
+    this.state.chart.dispose()
+    window.removeEventListener('resize', () => {
+      console.log('事件移除')
+    })
+  }
 }
 </script>
 <style lang="less"></style>

+ 26 - 18
TEAMModelBI/ClientApp/src/router/index.js

@@ -109,6 +109,14 @@ const routes = [{
                 isShow: true,
                 component: () => require.ensure([], (require) => require(`@/view/index/operateLog.vue`))
             },
+            {
+                name: "apistatistics",
+                path: "apistatistics",
+                permission: "batcharea-read|batcharea-upd|batchschool-read|batchschool-upd",
+                roles: ['admin'],
+                isShow: true,
+                component: () => require.ensure([], (require) => require(`@/view/systemConfig/apimanage.vue`))
+            },
             //单个学校数据统计
             {
                 name: "analyse",
@@ -171,25 +179,25 @@ const routes = [{
         component: () => require.ensure([], (require) => require(`@/view/404.vue`))
     },
     //第三方登录页
-    {
-        path: "/login-thirdparty",
-        name: "login-thirdparty",
-        component: () => require.ensure([], (require) => require(`@/view/thirdparty/login.vue`))
-    },
+    // {
+    //     path: "/login-thirdparty",
+    //     name: "login-thirdparty",
+    //     component: () => require.ensure([], (require) => require(`@/view/thirdparty/login.vue`))
+    // },
     //第三方首页
-    {
-        path: "/thirdpartys",
-        name: "thirdpartys",
-        component: () => require.ensure([], (require) => require(`@/view/thirdparty/index.vue`)),
-        // children: [{
-        //     name: "index",
-        //     path: "index",
-        //     permission: "",
-        //     roles: [],
-        //     isShow: true,
-        //     component: () => require.ensure([], (require) => require(`@/view/thirdparty/index.vue`))
-        // }]
-    },
+    // {
+    //     path: "/thirdpartys",
+    //     name: "thirdpartys",
+    //     component: () => require.ensure([], (require) => require(`@/view/thirdparty/index.vue`)),
+    //     // children: [{
+    //     //     name: "index",
+    //     //     path: "index",
+    //     //     permission: "",
+    //     //     roles: [],
+    //     //     isShow: true,
+    //     //     component: () => require.ensure([], (require) => require(`@/view/thirdparty/index.vue`))
+    //     // }]
+    // },
 ];
 const router = createRouter({
     history: createWebHashHistory(),

+ 64 - 8
TEAMModelBI/ClientApp/src/view/areamanage/statistics.vue

@@ -70,8 +70,8 @@
           <div class="area-item-list">
             <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.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.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> -->
           </div>
           <div class="item-detailsbtn" @click="getSchoolDistrict(item)">
             <span>详情 ></span>
@@ -222,6 +222,9 @@
             <el-table-column prop="id" label="简码" align="center" />
             <el-table-column prop="size" label="空间" align="center" />
             <el-table-column align="center">
+              <template #header>
+                <el-input v-model="areaSearchValue" size="small" placeholder="搜索学校名称/简码" />
+              </template>
               <template #default="scope">
                 <el-button type="primary" size="small" @click="detailsclick(scope.row)">详情</el-button>
               </template>
@@ -246,6 +249,7 @@ import { useRouter } from 'vue-router'
 import { useStore } from 'vuex'
 import * as echarts from 'echarts'
 import 'echarts-liquidfill'
+import { Sort } from '@element-plus/icons'
 export default {
   components: {
     CommonPie,
@@ -339,6 +343,9 @@ export default {
     let schooltableData = ref([])
     //某个学区顾问列表
     let CounselorList = ref([])
+    let areaSearchValue = ref()
+    let timer = ref('')
+    let originalSchool = ref([])
     //总区域echarts需要数据
     let totalArea = ref({
       //单独的饼图
@@ -1199,10 +1206,15 @@ export default {
           { value: 0, name: '进行中' },
           { value: 0, name: '未完成' },
         ],
+        tooltip: {
+          trigger: 'item',
+          formatter: "{a} <br/>{b}人数 : {c} 人({d}%)"
+        },
         legend: {
           orient: 'vertical',
           right: '5%',
           top: '15%',
+          bottom: '15%',
           itemWidth: 15,
           itemHeight: 15,
           textStyle: {
@@ -1446,6 +1458,7 @@ export default {
       }).catch((error) => {
         ElMessage.error('学区列表API异常')
       })
+      loadingTotal.value.areaList = false
     }
     //获取全区的评量、投票、问卷、作业
     function getclassification (val) {
@@ -1572,6 +1585,9 @@ export default {
             activityData.value.oneself[5].num = res.allLess
             // activityData.value.oneself[7].num = parseInt(res.examAreaCount) + parseInt(res.homeworkAreaCount) + parseInt(res.voteAreaCount) + parseInt(res.surveyAreaCount)
             //header数量
+            nowArea.value.schoolCount = res.scCnt
+            nowArea.value.studentCount = res.stuCnt
+            nowArea.value.teacherCount = res.tchCnt
             let teachNums = 0
             for (let i in res.schools) {
               teachNums += res.schools[i].teacherCount
@@ -1668,7 +1684,7 @@ export default {
           areaData.value.versions.series[0].data[2].value = majorV.length
           aspectsLoading.value.basics = false
         }
-        res.state === 200 ? (schooltableData.value = res.areaSchool, aspectsLoading.value.schoolList = false) : ''
+        res.state === 200 ? (schooltableData.value = res.areaSchool, originalSchool.value = res.areaSchool, aspectsLoading.value.schoolList = false) : ''
       }).catch((error) => {
         ElMessage.error('学区内学校列表获取异常')
       })
@@ -1690,11 +1706,21 @@ export default {
             let result = (proxy.$common.convertSize(res.useSize) / res.areaSize).toFixed(2)
             employInfo.push(result)
             areaData.value.size.series[0].data = employInfo
-            let namedata = ['文档', '图片', '其他', '视频', '缩略图', '教材', '音频', ' HiTeach上传的数据']
+            let namedata = [
+              { label: '文档', value: 'doc' },
+              { label: '图片', value: 'image' },
+              { label: '其他', value: 'other' },
+              { label: '视频', value: 'video' },
+              { label: '缩略图', value: 'thum' },
+              { label: '教材', value: 'res' },
+              { label: '音频', value: 'audio' },
+              { label: 'HiTeach上传的数据', value: 'records' },
+            ]
             for (let i in namedata) {
-              let names = namedata[i]
+              let names = namedata[i].label
+              let values = namedata[i].value
               for (let n in res.typeCount) {
-                i === n ? (res.typeCount[n].name = names) : ''
+                res.typeCount[n].key === values ? (res.typeCount[n].name = names) : ''
               }
             }
             areaData.value.sizeProportion.series[0].data = res.typeCount
@@ -1725,6 +1751,10 @@ export default {
               lastWeek.push({ name: names, value: item.weekCnt })
               nowMonths.push({ name: names, value: item.monthCnt })
             })
+            console.log(totalData, lastWeek, nowMonths, '查看数据')
+            totalData = (totalData.sort((a, b) => { return a.value - b.value })).slice(0, 5)
+            lastWeek = (lastWeek.sort((a, b) => { return a.value - b.value })).slice(0, 5)
+            nowMonths = (nowMonths.sort((a, b) => { return a.value - b.value })).slice(0, 5)
             areaData.value.class.series[0].data = totalData
             areaData.value.lastweek.series[0].data = lastWeek
             areaData.value.monthsContrast.series[0].data = nowMonths
@@ -1769,11 +1799,32 @@ export default {
       console.log(store.state, '9999999')
       router.push({ path: 'campus', query: { pattern: 'details' } })
     }
+    function debounce (fn, wait) {
+      if (timer.value !== null) {
+        clearTimeout(timer.value)
+      }
+      timer.value = setTimeout(fn, wait)
+    }
+    function personnelSearch () {
+      let arr = schooltableData.value
+      let newArr = arr.filter((item) => {
+        // return (item.name && item.name.includes(filterText.value)) || (item.mobile && item.mobile.includes(filterText.value)) || (item.mobile && item.mobile.tmdId.includes(filterText.value))
+        return item.name.includes(areaSearchValue.value) || item.id.includes(areaSearchValue.value)
+      })
+      schooltableData.value = newArr
+    }
     getAll()
     // getoption()
     watch(showPattern, (newValue, oldValue) => {
       newValue === 'all' ? backIndex() : ''
     })
+    watch(areaSearchValue, (newdata) => {
+      if (newdata.trim().length !== 0) {
+        debounce(personnelSearch, 500)
+      } else {
+        schooltableData.value = originalSchool.value
+      }
+    })
     return {
       aspectsData,
       showPattern,
@@ -1801,7 +1852,11 @@ export default {
       detailsclick,
       getclassification,
       versionsInfo,
-      getAllList
+      getAllList,
+      areaSearchValue,
+      timer,
+      personnelSearch,
+      originalSchool
     }
   },
 }
@@ -2215,7 +2270,8 @@ export default {
 .area-item-name {
   font-size: 16px;
   font-weight: 600;
-  margin-bottom: 10px;
+  margin-bottom: 20px;
+  margin-top: 10px;
 }
 .area-item-school-title,
 .area-item-school-content {

+ 19 - 11
TEAMModelBI/ClientApp/src/view/common/aside.vue

@@ -109,6 +109,14 @@ export default {
             isShow: true,
             sort: 4,
           },
+          {
+            name: 'API统计',
+            router: '/home/apistatistics',
+            icon: '#icon-shuju',
+            permission: [],
+            isShow: true,
+            sort: 5,
+          },
         ],
       },
       {
@@ -118,7 +126,7 @@ export default {
         icon: '#icon-zisunchaquyufenbu',
         permission: ['batcharea-read', 'batcharea-upd'],
         isShow: true,
-        sort: 5,
+        sort: 6,
         child: [
           {
             name: '学区管理',
@@ -126,7 +134,7 @@ export default {
             icon: '#icon-quyuguanli',
             permission: ['orgusers-read', 'orgusers-upd'],
             isShow: true,
-            sort: 6,
+            sort: 7,
           },
           {
             name: '学校管理',
@@ -134,7 +142,7 @@ export default {
             icon: '#icon-pingtai_xuexiaoguanli',
             permission: ['orgusers-read', 'orgusers-upd'],
             isShow: true,
-            sort: 7,
+            sort: 8,
           },
           {
             name: '微能力管理',
@@ -142,7 +150,7 @@ export default {
             icon: '#icon-peizhiguanli',
             permission: ['orgusers-read', 'orgusers-upd'],
             isShow: true,
-            sort: 8,
+            sort: 9,
           },
           {
             name: '第三方管理',
@@ -150,7 +158,7 @@ export default {
             icon: '#icon-collaboration-system',
             permission: [],
             isShow: true,
-            sort: 9,
+            sort: 10,
           },
         ],
       },
@@ -213,7 +221,7 @@ export default {
         role: ['admin', 'assist'],
         isShow: true,
         permission: '',
-        sort: 9,
+        sort: 11,
         child: [
           {
             name: '学区情况',
@@ -221,7 +229,7 @@ export default {
             icon: '#icon-xiangmufanwei',
             permission: [],
             isShow: true,
-            sort: 10,
+            sort: 12,
           },
           {
             name: '学校情况',
@@ -229,7 +237,7 @@ export default {
             icon: '#icon-xuexiao2',
             permission: [],
             isShow: true,
-            sort: 11,
+            sort: 13,
           },
         ],
       },
@@ -240,7 +248,7 @@ export default {
         role: ['admin', 'assist', 'leader'],
         isShow: true,
         permission: '',
-        sort: 12,
+        sort: 14,
         child: [
           {
             name: '学校管理',
@@ -248,7 +256,7 @@ export default {
             icon: '#icon-xuexiao3',
             permission: [],
             isShow: true,
-            sort: 13,
+            sort: 15,
           },
           {
             name: '微能力点管理',
@@ -256,7 +264,7 @@ export default {
             icon: '#icon-tiaozheng1',
             permission: [],
             isShow: true,
-            sort: 14,
+            sort: 16,
           },
         ],
       },

+ 2 - 2
TEAMModelBI/ClientApp/src/view/participation/index.vue

@@ -348,7 +348,7 @@ export default {
           res.schoolAssists[i].serviceData = []
           if (res.schoolAssists[i].assists) {
             res.schoolAssists[i].assisName = ''
-            res.schoolAssists[i].location = res.schoolAssists[i].province + res.schoolAssists[i].city + res.schoolAssists[i].dist
+            res.schoolAssists[i].location = res.schoolAssists[i].dist !== null ? res.schoolAssists[i].province + res.schoolAssists[i].city + res.schoolAssists[i].dist : res.schoolAssists[i].province + res.schoolAssists[i].city
             let datas = res.schoolAssists[i].assists
             for (let y in datas) {
               res.schoolAssists[i].assisName = res.schoolAssists[i].assisName + datas[y].tmdName + ','
@@ -906,7 +906,7 @@ export default {
   margin-bottom: 30px;
 }
 .scalebox {
-  width: 60%;
+  width: 75%;
   margin-left: 20%;
 }
 .scalebox-content {

+ 4 - 10
TEAMModelBI/ClientApp/src/view/participation/setAbility.vue

@@ -33,14 +33,9 @@
                   </div>
                 </template>
                 <div class="information-box">
-                  <p class="source">{{ $t(`abilityManages.source`) }}:<span class="source-title">{{ item.name
-                            }}</span></p>
-                  <p class="source">{{ $t(`abilityManages.area`) }}:<span class="source-title">{{
-                                    item.provName
-                            }}{{ item.cityName }}</span></p>
-                  <p class="source">{{ $t(`abilityManages.affiliation`) }}:<span class="source-title">{{
-                                    item.institution
-                            }}</span></p>
+                  <p class="source">{{ $t(`abilityManages.source`) }}:<span class="source-title">{{ item.name}}</span></p>
+                  <p class="source">{{ $t(`abilityManages.area`) }}:<span class="source-title">{{item.provName}}{{ item.cityName }}</span></p>
+                  <p class="source">{{ $t(`abilityManages.affiliation`) }}:<span class="source-title">{{item.institution}}</span></p>
                 </div>
               </el-card>
             </div>
@@ -57,8 +52,7 @@
           <el-table-column prop="institution" :label="$t(`abilityManages.listTables.affiliation`)" align="center" />
           <el-table-column :label="$t(`abilityManages.listTables.operate`)" align="center" v-if="PowerShow">
             <template #default="scope">
-              <el-button size="mini" @click="pitch(scope.row)">{{ $t(`abilityManages.listTables.redact`)
-                            }}
+              <el-button size="mini" @click="pitch(scope.row)">{{ $t(`abilityManages.listTables.redact`)}}
               </el-button>
             </template>
           </el-table-column>

+ 4 - 4
TEAMModelBI/ClientApp/src/view/schoolServe/analyseSchool.vue

@@ -39,8 +39,8 @@
               <p class="compare">
                 <span class="compare-title" v-if="items.type==='month'">同上周对比:</span>
                 <span class="compare-title" v-else-if="items.type==='semester'">同上学期对比:</span>
-                <span class="compare-icon red" v-if="items.compare <0">↓<span>{{items.compare}}%</span></span>
-                <span class="compare-icon greens" v-if="items.compare >=0">↑<span>{{items.compare}}%</span></span>
+                <span class="compare-icon greens" v-if="items.compare <0">↓<span>{{items.compare}}%</span></span>
+                <span class="compare-icon red" v-if="items.compare >=0">↑<span>{{items.compare}}%</span></span>
               </p>
             </div>
           </div>
@@ -52,8 +52,8 @@
               <p :class="[items.type ==='month' ? 'alonebox-content':'total-alonebox-content']">{{items.num}}</p>
               <p class="compare">
                 <span class="compare-title">同去年对比:</span>
-                <span class="compare-icon red" v-if="items.compare <0">↓<span>{{items.compare}}%</span></span>
-                <span class="compare-icon green " v-if="items.compare >=0">↑<span>{{items.compare}}%</span></span>
+                <span class="compare-icon green" v-if="items.compare <0">↓<span>{{items.compare}}%</span></span>
+                <span class="compare-icon red " v-if="items.compare >=0">↑<span>{{items.compare}}%</span></span>
               </p>
             </div>
           </div>

+ 114 - 8
TEAMModelBI/ClientApp/src/view/schoolServe/school.vue

@@ -44,7 +44,7 @@
           删除勾选学校
         </el-button>
       </div>
-      <div class="schoolNums"><span>学校数量:</span><span>{{tableData.length}}</span></div>
+      <div class="schoolNums"><span>学校数量:</span><span>{{tablesccnt}}</span></div>
       <div class="createschools">
         <el-button size="small" @click="createdSchoolbtn" type="primary">
           <svg class="created-icon" aria-hidden="true">
@@ -55,7 +55,7 @@
       </div>
     </div>
     <div class="school-list">
-      <el-table :data="tableData" style="width: 100%" height="75vh" v-loading="loading" element-loading-text="加载中..." @selection-change="selectChange">
+      <el-table :data="tableData" :ref="tablesInfo" id="tablescroll" style="width: 100%" height="75vh" v-loading="loading" element-loading-text="加载中..." @selection-change="selectChange">
         <el-table-column type="selection" width="55" />
         <el-table-column prop="index" :label="$t(`schoolManages.tables.serialnum`)" type="index" sortable align="center" />
         <el-table-column :label="$t(`schoolManages.tables.badge`)" width="150" align="center">
@@ -230,13 +230,17 @@
               <el-form-item label="所属学区:" class="school-form-area">
                 <div v-if="PowerShow">
                   <el-select v-model="areaSelect.Selectvalue" :placeholder="$t(`schoolManages.basicSet.region`)">
-                    <el-option v-for="item in areaSelect.data" :key="item.name" :label="item.name" :value="item.id">
+                    <el-option v-for="item in areaSelect.data" :key="item.name" :label="item.name" :value="item.id" :disabled="item.cutArea">
+                      <div class="areaname">{{item.name}}</div>
+                      <div class="stepicon" v-show="item.cutArea"><span>已同步省平台</span></div>
                     </el-option>
                   </el-select>
                 </div>
                 <div v-else-if="!PowerShow">
                   <el-select v-model="areaSelect.Selectvalue" :placeholder="$t(`schoolManages.basicSet.region`)" disabled>
                     <el-option v-for="item in areaSelect.data" :key="item.name" :label="item.name" :value="item.id">
+                      <div class="areaname">{{item.name}}</div>
+                      <div class="stepicon" v-show="item.cutArea"><span>已同步省平台</span></div>
                     </el-option>
                   </el-select>
                 </div>
@@ -285,7 +289,7 @@
   <!--编辑学校页面end-->
 </template>
 <script>
-import { reactive, ref, getCurrentInstance, toRef } from 'vue'
+import { reactive, ref, getCurrentInstance, toRef, onMounted, watch } from 'vue'
 import option from '@/static/region.json'
 import { useStore } from 'vuex'
 import { ElMessage, ElLoading, ElMessageBox } from 'element-plus'
@@ -310,6 +314,10 @@ export default {
     const routerInfo = useRouter()
     //为了让表单呈现 暂时的数据,
     let tableData = ref([])
+    let tablesInfo = ref()
+    let tablesccnt = ref(0)
+    let timer = ref()
+    let tableNexttoken = ref()
     const form = reactive({
       name: '',
       region: '',
@@ -335,6 +343,7 @@ export default {
     const value2 = ref(true)
     //为了让表单呈现 暂时的数据,
     let loading = ref(true)
+    let scrollHeight = ref()
     let uploadHeader = ref({})
     let nowPitchdata = ref({
       address: '',
@@ -405,6 +414,22 @@ export default {
     let deleteSchoolArr = ref([])
     provinceOptions.value.optionInfo = optionsData
     console.log(store.state.point)
+    onMounted(() => {
+      //监听表格滚动事件
+      // let table = mutipleTable.value._value.layout.table.refs.bodyWrapper;
+      let table = document.getElementById('tablescroll')
+      console.log(table, '查看是否获取到')
+      table.addEventListener("scroll", (res) => { loadmore(res) }, true);
+    })
+    const loadmore = (res) => {
+      console.log(res, '8888888')
+      if (res.target.scrollTop && ((res.target.scrollHeight - 20) <= (res.target.scrollTop + res.target.clientHeight))) {
+        console.log('gaodu')
+        scrollHeight.value = (res.target.scrollHeight - 20) - (res.target.scrollTop + res.target.clientHeight)
+        console.log(scrollHeight.value, '值')
+        // datascroll()
+      }
+    }
     //所有学校列表
     function getAllschool () {
       proxy.$api.getSchooldata({}).then((res) => {
@@ -414,7 +439,7 @@ export default {
           res.schoolAssists[i].serviceData = []
           if (res.schoolAssists[i].assists) {
             res.schoolAssists[i].assisName = ''
-            res.schoolAssists[i].location = res.schoolAssists[i].province + res.schoolAssists[i].city + res.schoolAssists[i].dist
+            res.schoolAssists[i].location = res.schoolAssists[i].dist !== null ? res.schoolAssists[i].province + res.schoolAssists[i].city + res.schoolAssists[i].dist : res.schoolAssists[i].province + res.schoolAssists[i].city
             let datas = res.schoolAssists[i].assists
             for (let y in datas) {
               res.schoolAssists[i].assisName = res.schoolAssists[i].assisName + datas[y].tmdName + ','
@@ -429,7 +454,7 @@ export default {
           }
         }
         console.log(res)
-        res.state == 200 ? (tableData.value = [], originalData.value = [], tableData.value.push(...res.schoolAssists), (originalData.value = res.schoolAssists), (loading.value = false)) : ''
+        res.state == 200 ? (tableData.value = [], originalData.value = [], tableData.value.push(...res.schoolAssists), (originalData.value = res.schoolAssists), (loading.value = false), tableNexttoken.value = res.continuationToken, tablesccnt.value = res.scCnt) : ''
       })
     }
     //点击学校列表,详情
@@ -769,6 +794,55 @@ export default {
       deleteSchoolArr.value = value
       console.log(deleteSchoolArr.value[0])
     }
+    function datascroll () {
+      console.log('触发了')
+      loading.value = true
+      let data = { contToken: tableNexttoken.value }
+      if (tableNexttoken.value === null) {
+        ElMessage.success('已经到最底了')
+        loading.value = false
+        return
+      }
+      proxy.$api.getSchooldata(data).then((res) => {
+        console.log(res, '查询到下一页数据了')
+        if (res.state === 200) {
+          for (let i in res.schoolAssists) {
+            res.schoolAssists[i].serviceData = []
+            if (res.schoolAssists[i].assists) {
+              res.schoolAssists[i].assisName = ''
+              res.schoolAssists[i].location = res.schoolAssists[i].dist !== null ? res.schoolAssists[i].province + res.schoolAssists[i].city + res.schoolAssists[i].dist : res.schoolAssists[i].province + res.schoolAssists[i].city
+              let datas = res.schoolAssists[i].assists
+              for (let y in datas) {
+                res.schoolAssists[i].assisName = res.schoolAssists[i].assisName + datas[y].tmdName + ','
+              }
+            }
+            if (res.schoolAssists[i].service.length > 0) {
+              res.schoolAssists[i].service.forEach((x) => {
+                for (let m in patternIcon.value) {
+                  patternIcon.value[m].key === x ? res.schoolAssists[i].serviceData.push(patternIcon.value[m]) : ''
+                }
+              })
+            }
+          }
+        }
+        tableData.value.push(...res.schoolAssists)
+        tableNexttoken.value = res.continuationToken
+      }).catch((error) => {
+        ElMessage.error('API异常,获取更多学校数据失败')
+      })
+      loading.value = false
+    }
+    function debounce (fn, wait) {
+      if (timer.value !== null) {
+        clearTimeout(timer.value)
+      }
+      timer.value = setTimeout(fn, wait)
+    }
+    watch(scrollHeight, (newdata) => {
+      if (scrollHeight.value < 0) {
+        debounce(datascroll, 500)
+      }
+    })
     getAllschool()
     getAllassists()
     return {
@@ -818,7 +892,14 @@ export default {
       siteList,
       selectChange,
       deleteSchoolArr,
-      batchRemoveSchool
+      batchRemoveSchool,
+      datascroll,
+      scrollHeight,
+      loadmore,
+      tableNexttoken,
+      tablesInfo,
+      debounce,
+      tablesccnt
     }
   },
 }
@@ -1101,6 +1182,31 @@ export default {
   top: -1px;
   left: -4px;
 }
+.areaname,
+.stepicon {
+  display: inline-block;
+  vertical-align: top;
+}
+.stepicon {
+  float: right;
+  border: 1px solid #ccc;
+  font-size: 12px;
+}
+.stepicon {
+  float: right;
+  height: 22px;
+  line-height: 20px;
+  margin: 2px 4px 2px 0;
+  padding: 0 8px;
+  border: 1px solid #e8eaec;
+  border-radius: 3px;
+  background: #fffbe6;
+  font-size: 12px;
+  vertical-align: middle;
+  opacity: 1;
+  overflow: hidden;
+  border-color: #ffe58f;
+}
 </style>
 <style>
 .schoolboxea .el-cascader {
@@ -1218,7 +1324,7 @@ export default {
 }
 .upload-demo-redact .el-image {
   width: 100%;
-  height: 125px;
+  height: 110px;
 }
 @media screen and (max-width: 1920px) {
   .school-formbox .school-form-badge {

+ 24 - 17
TEAMModelBI/ClientApp/src/view/systemConfig/apimanage.vue

@@ -2,7 +2,7 @@
   <div class="apibox">
     <div class="apibox-top">
       <div class="apibox-top-title">
-        <!-- <p>API访问情况</p> -->
+        <p>当日API访问情况</p>
       </div>
       <div class="apibox-top-left">
         <div class="toptitle">
@@ -13,20 +13,9 @@
           </div>
           <div class="toptitle-text">当日访问量</div>
         </div>
-        <CommonApiBar :barData="countBar" width="30vw" height="26vh" @clicktime="clicktimes"></CommonApiBar>
+        <CommonApiBar :barData="countBar" width="30vw" height="29vh" @clicktime="clicktimes"></CommonApiBar>
       </div>
       <div class="apibox-top-center">
-        <div class="toptitle">
-          <div class="toptitle-icon">
-            <el-icon size="16" color="#e17055">
-              <Medal />
-            </el-icon>
-          </div>
-          <div class="toptitle-text">API访问排行</div>
-        </div>
-        <CommonApiBar :barData="rankBar" width="30vw" height="26vh"></CommonApiBar>
-      </div>
-      <div class="apibox-top-right">
         <div class="toptitle">
           <div class="toptitle-icon">
             <el-icon size="16" color="#00cec9">
@@ -39,9 +28,20 @@
           暂无当前时间或选择时间数据
         </div>
         <div v-else>
-          <CommonApiBar :barData="minuteBar" width="30vw" height="26vh"></CommonApiBar>
+          <CommonApiBar :barData="minuteBar" width="30vw" height="29vh"></CommonApiBar>
         </div>
       </div>
+      <div class="apibox-top-right">
+        <div class="toptitle">
+          <div class="toptitle-icon">
+            <el-icon size="16" color="#e17055">
+              <Medal />
+            </el-icon>
+          </div>
+          <div class="toptitle-text">API访问排行</div>
+        </div>
+        <CommonApiBar :barData="rankBar" width="30vw" height="29vh"></CommonApiBar>
+      </div>
     </div>
     <div class="apibox-list">
       <div class="apibox-list-header">
@@ -53,7 +53,7 @@
         </div>
       </div>
       <div class="apibox-list-content">
-        <el-table :data="tableData" style="width: 100%" height="420" v-loading="loadingShow.table" element-loading-text="数据加载中...">
+        <el-table :data="tableData" style="width: 100%" height="420" v-loading="loadingShow.table" element-loading-text="数据加载中..." empty-text="暂无数据">
           <el-table-column prop="api" label="api路径" />
           <el-table-column prop="hostName" label="主机名称" />
           <el-table-column prop="count" label="访问次数" sortable />
@@ -260,7 +260,7 @@ export default ({
       },
       grid: {
         left: '1%',
-        right: '5%',
+        right: '1%',
         bottom: '5%',
         containLabel: true,
       },
@@ -450,6 +450,10 @@ export default ({
         var rankDatas = [];
         let ranx = []; let rankdata = []
         if (res.state === 200) {
+          if (res.days.length === 0) {
+            ElMessage.info('暂无API相关统计数据')
+            return
+          }
           //处理时间
           for (let i in hourData) {
             let nums = parseInt(i) + 1
@@ -634,7 +638,7 @@ export default ({
 .apibox-top-right,
 .apibox-top-center {
   width: 33%;
-  height: 28vh;
+  height: 29vh;
   border-right: 1px solid #ccc;
   position: relative;
 }
@@ -688,4 +692,7 @@ export default ({
   line-height: 20px;
   margin-top: 2px;
 }
+.apibox-top-right {
+  border-right: 0px;
+}
 </style>

+ 110 - 8
TEAMModelBI/ClientApp/src/view/systemConfig/correlation.vue

@@ -35,13 +35,16 @@
     <div class="school-list">
       <div class="school-list-header">
         <div class="correlationbox-titles">学校列表:</div>
+        <div class="correlationbox-search">
+          <el-input v-model="schoolSearch" placeholder="输入学校名称/简码 搜索" :prefix-icon="Search" size="small" clearable />
+        </div>
         <div class="correlationbox-btn">
           <el-button type="primary" size="small" v-if="multipleSchool.length >0 && PowerShow" @click="multipleCorrelation">关联选中学校</el-button>
           <el-button type="primary" size="small" v-else-if="multipleSchool.length ===0 && PowerShow" disabled>关联选中学校</el-button>
         </div>
       </div>
       <div class="listbox">
-        <el-table :data="tableData" style="width: 100%" height="40vh" size="small" @selection-change="checkSchool">
+        <el-table :data="tableData" id="schoolList" style="width: 100%" height="45vh" size="small" @selection-change="checkSchool" empty-text='暂无相关搜索数据'>
           <el-table-column type="selection" v-if="PowerShow" />
           <el-table-column :label="$t(`personnelManagement.personnelTable.headportrait`)" align="center">
             <template #default="scope">
@@ -63,8 +66,9 @@
   </div>
 </template>
 <script>
-import { ref, getCurrentInstance, watch } from 'vue'
+import { ref, getCurrentInstance, watch, onMounted } from 'vue'
 import { ElMessage, ElLoading, ElMessageBox } from 'element-plus'
+import { Search } from '@element-plus/icons'
 export default {
   props: {
     userdata: {
@@ -72,6 +76,9 @@ export default {
       default: () => { },
     },
   },
+  components: {
+    Search
+  },
   setup (props) {
     let { proxy } = getCurrentInstance()
     let PowerShow = proxy.$access.identifyPosition(JSON.parse(localStorage.getItem('id_token')))
@@ -79,9 +86,34 @@ export default {
     let tableData = ref([])
     let nowUsers = ref()
     let multipleSchool = ref([])
-    function getSchoolList () {
+    let schoolSearch = ref('')
+    let original = ref([])
+    let timer = ref('')
+    let nextpageToken = ref('')
+    let scrollHeight = ref('init')
+    onMounted(() => {
+      //监听表格滚动事件
+      // let table = mutipleTable.value._value.layout.table.refs.bodyWrapper;
+      let table = document.getElementById('schoolList')
+      console.log(table, '查看是否获取到')
+      table.addEventListener("scroll", (res) => { loadmore(res) }, true);
+    })
+    const loadmore = (res) => {
+      // console.log(res, res.target.scrollHeight, res.target.scrollTop + res.target.clientHeight, '实际高度')
+      if (res.target.scrollTop && ((res.target.scrollHeight - 10) <= (res.target.scrollTop + res.target.clientHeight))) {
+        scrollHeight.value = (res.target.scrollHeight - 10) - (res.target.scrollTop + res.target.clientHeight)
+        console.log(scrollHeight.value, '值')
+      }
+    }
+    function getSchoolList (value) {
+      console.log(value, '触发下一页')
+      if (nextpageToken.value == null) {
+        ElMessage.success('已经到最底了')
+        return
+      }
+      let data = value ? { contToken: value } : {}
       proxy.$api
-        .getSchooldata({})
+        .getSchooldata(data)
         .then((res) => {
           console.log(res, '学校的返回列表')
           // res.state === 200 ? (tableData.value = res.schoolAssists) : ''
@@ -95,7 +127,15 @@ export default {
                 }
               }
             }
-            tableData.value = res.schoolAssists
+            nextpageToken.value = res.continuationToken
+            if (!value) {
+              tableData.value = res.schoolAssists;
+              original.value = res.schoolAssists;
+            } else {
+              tableData.value.push(...res.schoolAssists)
+              original.value = tableData.value
+              scrollHeight.value = 'init'
+            }
             processingSchool()
           }
         })
@@ -202,6 +242,41 @@ export default {
       }
       tableData.value = allSchool
     }
+    function debounce (fn, wait) {
+      if (timer.value !== null) {
+        clearTimeout(timer.value)
+      }
+      timer.value = setTimeout(fn, wait)
+    }
+    function personnelSearch () {
+      let names = schoolSearch.value
+      let reg = new RegExp("[\\u4E00-\\u9FFF]+", "g")
+      let data = reg.test(names) ? { name: names } : { scId: names }
+      proxy.$api.getSchooldata(data).then((res) => {
+        if (res.state === 200) {
+          for (let i in res.schoolAssists) {
+            if (res.schoolAssists[i].assists) {
+              res.schoolAssists[i].assisName = ''
+              let datas = res.schoolAssists[i].assists
+              for (let y in datas) {
+                res.schoolAssists[i].assisName = res.schoolAssists[i].assisName + datas[y].tmdName + ','
+              }
+            }
+          }
+          tableData.value = res.schoolAssists
+          processingSchool()
+        }
+      }).catch((error) => {
+        ElMessage.error('搜索学校失败,API异常')
+      })
+    }
+    function loadData () {
+
+    }
+    watch(scrollHeight, (newdata, olddata) => {
+      console.log(newdata, olddata, '监听的数据')
+      olddata === 'init' && newdata <= 0 ? getSchoolList(nextpageToken.value) : ''
+    })
     watch(
       props,
       (newuser) => {
@@ -210,8 +285,32 @@ export default {
       },
       { immediate: true, deep: true }
     )
+    watch(schoolSearch, (newdata) => {
+      if (newdata.trim().length !== 0) {
+        debounce(personnelSearch, 500)
+      } else {
+        tableData.value = original.value
+      }
+    })
     getSchoolList()
-    return { tableData, tableDatas, correlation, removeSchool, nowUsers, getSchoolList, checkSchool, multipleSchool, multipleCorrelation, processingSchool, PowerShow }
+    return {
+      tableData,
+      tableDatas,
+      correlation,
+      removeSchool,
+      nowUsers,
+      getSchoolList,
+      checkSchool,
+      multipleSchool,
+      multipleCorrelation,
+      processingSchool,
+      PowerShow,
+      schoolSearch,
+      timer,
+      personnelSearch,
+      scrollHeight,
+      loadData
+    }
   },
 }
 </script>
@@ -277,13 +376,16 @@ export default {
   justify-content: space-between;
 }
 .correlationbox-titles {
-  width: 50%;
+  width: 20%;
   font-size: 14px;
   color: #b2bec3;
   text-align: left;
 }
+.correlationbox-search {
+  width: 45%;
+}
 .correlationbox-btn {
-  width: 50%;
+  width: 30%;
   text-align: right;
 }
 </style>

+ 2 - 2
TEAMModelBI/ClientApp/src/view/systemConfig/index.vue

@@ -31,9 +31,9 @@
         <el-tab-pane label="系统管理者" name="admin">
           <SetAdmin></SetAdmin>
         </el-tab-pane>
-        <el-tab-pane label="API管理" name="api">
+        <!-- <el-tab-pane label="API管理" name="api">
           <ApiManage></ApiManage>
-        </el-tab-pane>
+        </el-tab-pane> -->
       </el-tabs>
     </div>
   </div>

+ 2 - 1
TEAMModelBI/ClientApp/src/view/teachermanage/manage.vue

@@ -90,7 +90,7 @@
     </el-table>
   </div>
   <div class="personnel-drawer">
-    <el-drawer v-model="drawer" title="用户相关信息配置" :direction="direction" :modal="false" :before-close="closeDrawer()">
+    <el-drawer v-model="drawer" title="用户相关信息配置" :direction="direction" :modal="true" :before-close="closeDrawer()">
       <el-tabs v-model="activeName" class="demo-tabs">
         <el-tab-pane label="权限/身份" name="first">
           <Operates ref="roaming" :userdata="nowUser" @changeShow="changeState"></Operates>
@@ -815,6 +815,7 @@ export default {
 }
 .personnel-drawer .el-drawer.rtl {
   top: 6%;
+  height: 94vh;
 }
 .personnel-drawer .el-drawer__header {
   line-height: 20px;

+ 2 - 13
TEAMModelBI/Controllers/BIBlob/AnalyseFileController.cs

@@ -68,9 +68,6 @@ namespace TEAMModelBI.Controllers.BIBlob
                     {
                         var response = blobCilent.GetBlobClient($"{blobItem.Name}").DownloadTo(meomoryStream);
                         //var response = await blob.GetBlobClient($"{blobItem.Name}").DownloadToAsync(meomoryStream);
-                        //var temps = meomoryStream.ToString();
-                        //var temp1 = Encoding.UTF8.GetString(meomoryStream.ToArray());
-                        //var temp = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToObject<RecCnt>();
 
                         RecCnt recCnt = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToString().ToObject<RecCnt>();
 
@@ -112,9 +109,6 @@ namespace TEAMModelBI.Controllers.BIBlob
                         {
                             var response = blobCilent.GetBlobClient($"{blobItem.Name}").DownloadTo(meomoryStream);
                             //var response = await blob.GetBlobClient($"{blobItem.Name}").DownloadToAsync(meomoryStream);
-                            //var temps = meomoryStream.ToString();
-                            //var temp1 = Encoding.UTF8.GetString(meomoryStream.ToArray());
-                            //var temp = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToObject<RecCnt>();
 
                             RecCnt recCnt = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToString().ToObject<RecCnt>();
                             savenDayApis.AddRange(recCnt.apiCnt);
@@ -155,9 +149,6 @@ namespace TEAMModelBI.Controllers.BIBlob
                         {
                             var response = blobCilent.GetBlobClient($"{blobItem.Name}").DownloadTo(meomoryStream);
                             //var response = await blob.GetBlobClient($"{blobItem.Name}").DownloadToAsync(meomoryStream);
-                            //var temps = meomoryStream.ToString();
-                            //var temp1 = Encoding.UTF8.GetString(meomoryStream.ToArray());
-                            //var temp = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToObject<RecCnt>();
 
                             RecCnt recCnt = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToString().ToObject<RecCnt>();
                             thirtyDayApi.AddRange(recCnt.apiCnt);
@@ -176,6 +167,7 @@ namespace TEAMModelBI.Controllers.BIBlob
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-visitjson")]
         public async Task<IActionResult> GetVisitJson(JsonElement jsonElement) 
         {
@@ -233,10 +225,6 @@ namespace TEAMModelBI.Controllers.BIBlob
                         var response = blob.GetBlobClient($"{blobItem.Name}").DownloadTo(meomoryStream);
                         //var response = await blob.GetBlobClient($"{blobItem.Name}").DownloadToAsync(meomoryStream);
 
-                        var temps = meomoryStream.ToString();
-                        var temp1 = Encoding.UTF8.GetString(meomoryStream.ToArray());
-                        var temp = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToObject<RecCnt>();
-
                         RecCnt recCnt = Encoding.UTF8.GetString(meomoryStream.ToArray()).ToString().ToObject<RecCnt>();
                         recCnts.Add(recCnt);
                     }
@@ -250,6 +238,7 @@ namespace TEAMModelBI.Controllers.BIBlob
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-loginfos")]
         public async Task<IActionResult> GetOSLog(JsonElement jsonElement) 
         {

+ 2 - 34
TEAMModelBI/Controllers/BICommon/JointlyController.cs

@@ -19,7 +19,7 @@ namespace TEAMModelBI.Controllers.BICommon
         private readonly AzureStorageFactory _azureStorage;
         private readonly DingDing _dingDing;
         private readonly Option _option;
-        public readonly List<string> _containers = new List<string> { "Teacher", "School", "Student", "Normal", "Common" };
+        public readonly List<string> _containers = new() { "Teacher", "School", "Student", "Normal", "Common" };
 
         public JointlyController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option)
         {
@@ -42,7 +42,7 @@ namespace TEAMModelBI.Controllers.BICommon
             if (!jsonEmelent.TryGetProperty("type", out JsonElement type)) return BadRequest();
             jsonEmelent.TryGetProperty("code", out JsonElement code);
             var cosmosClient = _azureCosmos.GetCosmosClient();
-            List<object> objs = new List<object>();
+            List<object> objs = new();
             List<int> types = type.ToObject<List<int>>();
 
             if (types.Count > 0)
@@ -80,38 +80,6 @@ namespace TEAMModelBI.Controllers.BICommon
                 }
             }
 
-            //if (type.GetInt32() != 0) 
-            //{
-            //    await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", _containers[type.GetInt32()]).GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.id='{id}'", requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
-            //    {
-            //        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())
-            //            {
-            //                objs.Add(obj.ToObject<object>());
-            //            }
-            //        }
-            //    }
-            //}
-            //else
-            //{
-            //    foreach (var contaoner in _containers)
-            //    {
-            //        await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", contaoner).GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.id='{id}'", requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
-            //        {
-            //            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())
-            //                {
-            //                    objs.Add(obj.ToObject<object>());
-            //                }
-            //            }
-            //        }
-            //    }
-            //}
-
             return Ok(new { state = 200, infos = objs });
         }
 

+ 1 - 3
TEAMModelBI/Controllers/BIHome/HomeStatisController.cs

@@ -230,8 +230,6 @@ namespace TEAMModelBI.Controllers.BIHome
                     {
                         citySchool.cityCode = itemStandrd.cityCode;
                         citySchool.cityName = itemStandrd.cityName;
-
-                        //string sqlTxt = $"select count(c.id) totals from c where c.standard='{itemStandrd.standard}'";
                         string sqlTxt = $"select value(count(c.id)) from c where c.areaId='{itemStandrd.areaId}' and c.standard='{itemStandrd.standard}'";
                         citySchool.schoolCount += await CommonFind.GetSqlValueCount(cosmosClient, "School", sqlTxt,  "Base");
 
@@ -439,6 +437,7 @@ namespace TEAMModelBI.Controllers.BIHome
         /// 统计学校和教师空间类型   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-datatypestics")]
         public async Task<IActionResult> GetDataTypeStics(JsonElement jsonElement) 
         {
@@ -524,7 +523,6 @@ namespace TEAMModelBI.Controllers.BIHome
 
                         useSize += blobsize;
                         typeStics1 = typeStics1.Concat(schoolStics).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value));  //lamebda表达式
-                        //typeStics1 = (from e in typeStics1.Concat(schoolStics) group e by e.Key into g select new { Name = g.Key, Count = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.Name, item => item.Count);
                         continue;
 
                     }

+ 10 - 117
TEAMModelBI/Controllers/BIHome/OnLineController.cs

@@ -41,6 +41,7 @@ namespace TEAMModelBI.Controllers.BIHome
         /// 总数统计   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-count")]
         public async Task<IActionResult> GetCount(JsonElement jsonElement) 
         {
@@ -113,24 +114,6 @@ namespace TEAMModelBI.Controllers.BIHome
             }
             apiCnt = recCnts.Select(x => x.apiCnt.Select(s => s.count).Sum()).Sum();
 
-            //List<RecOnLine> recStuOnLines = new();
-            //await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Student").GetItemQueryIterator<RecOnLine>(queryText: "select c.id,c.name,c.code,c.loginInfos from c where c.pk='Base' and array_length(c.loginInfos) > 0 ", requestOptions:new QueryRequestOptions() { }))
-            //{
-            //    recStuOnLines.Add(item);
-            //}
-
-            //List<RecOnLine> recTecOnLines = new();
-            //await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecOnLine>(queryText: "select c.id,c.name,c.code,c.loginInfos from c where array_length(c.loginInfos) > 0 ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
-            //{
-            //    recTecOnLines.Add(item);
-            //}
-
-            ////onStuCnt = (from rs in recStuOnLines from l in rs.loginInfos where l.expire >= hour1 select rs).ToList().Count();  //linq查询 学生在线人数
-            //onStuCnt = recStuOnLines.Select(rss => new RecOnLine { id = rss.id,code=rss.code, name =rss.name,loginInfos = new List<Teacher.LoginInfo> { rss.loginInfos.Find(f => f.expire >= hour1) } }).Where(w => w.loginInfos.FirstOrDefault() != null).ToList().Count();  //lambda 表达式查询   教师查询人数
-
-            ////onTchCnt = (from rs in recTecOnLines from l in rs.loginInfos where l.expire >= hour1 select rs).ToList().Count();  //linq查询  教师查询人数
-            //onTchCnt = recTecOnLines.Select(rss => new RecOnLine { id = rss.id,code=rss.code, name =rss.name,loginInfos = new List<Teacher.LoginInfo> { rss.loginInfos.Find(f => f.expire >= hour1) } }).Where(w => w.loginInfos.FirstOrDefault() != null).ToList().Count();  //lambda 表达式查询    教师查询人数
-
             return Ok(new { state = 200, areaCnt, scCnt, tchCnt, stuCnt, todayScCnt, todayTchCnt, todayStuCnt, onStuCnt, onTchCnt, apiCnt });
         }
 
@@ -138,6 +121,7 @@ namespace TEAMModelBI.Controllers.BIHome
         /// 在线人数趋势图   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-trend")]
         public async Task<IActionResult> GetTrend(JsonElement jsonElement) 
         {
@@ -189,8 +173,6 @@ namespace TEAMModelBI.Controllers.BIHome
                     foreach (var item in hourLoginsTch)
                     {
                         await redisClinet.SortedSetIncrementAsync($"Login:IES:teacher:{dateDay}", $"{item.Hour}", item.Teacher);//存一天24小时
-                        //var utcTo = new DateTimeOffset(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, item.Hour, 0, 0)).Hour;
-                        //var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {item.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
                         tchDays.Add(item.Hour, item.Teacher);
                         if (allDays.ContainsKey(item.Hour))
                             allDays[item.Hour] = (allDays[item.Hour] + item.Teacher);
@@ -207,8 +189,6 @@ namespace TEAMModelBI.Controllers.BIHome
                 {
                     int val = (int)item.Score;
                     int key = (int)item.Element;
-                    //var utcTo = new DateTimeOffset(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, key, 0, 0)).Hour;
-                    //var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {key}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
                     stuDays.Add(key, val);
                     if (allDays.ContainsKey(key))
                         allDays[key] = (allDays[key] + val);
@@ -227,8 +207,6 @@ namespace TEAMModelBI.Controllers.BIHome
                     foreach (var item in hourLoginsStu)
                     {
                         await redisClinet.SortedSetIncrementAsync($"Login:IES:student:{dateDay}", $"{item.Hour}", item.Student);//存一天24小时
-                        //var utcTo = new DateTimeOffset(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, item.Hour, 0, 0)).Hour;
-                        //var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {item.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
                         stuDays.Add(item.Hour, item.Student);
                         if (allDays.ContainsKey(item.Hour))
                             allDays[item.Hour] = (allDays[item.Hour] + item.Student);
@@ -245,8 +223,6 @@ namespace TEAMModelBI.Controllers.BIHome
                 {
                     int val = (int)item.Score;
                     int key = (int)item.Element;
-                    //var utcTo = new DateTimeOffset(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, key, 00, 00)).Hour;
-                    //var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {key}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
                     tmdDays.Add(key, val);
                     if (allDays.ContainsKey(key))
                         allDays[key] = (allDays[key] + val);
@@ -266,7 +242,6 @@ namespace TEAMModelBI.Controllers.BIHome
                     {
                         await redisClinet.SortedSetIncrementAsync($"Login:IES:tmduser:{dateDay}", $"{item.Hour}", item.TmdUser);//存一天24小时
                         var utcTo = new DateTimeOffset(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, item.Hour, 00, 00)).Hour;
-                        //var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {item.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
                         tmdDays.Add(utcTo, item.TmdUser);
                         if (allDays.ContainsKey(utcTo))
                             allDays[utcTo] = (allDays[utcTo] + item.TmdUser);
@@ -283,6 +258,7 @@ namespace TEAMModelBI.Controllers.BIHome
         /// 课例趋势图   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-lessontrend")]
         public async Task<IActionResult> GetLessonTrend(JsonElement jsonElement)
         {
@@ -369,7 +345,12 @@ namespace TEAMModelBI.Controllers.BIHome
 
                 for (int i = 1; i <= month; i++)
                 {
-                    DateTimeOffset timeDay = new DateTime(year, i, day, 0, 0, 0);
+                    DateTimeOffset timeDay = DateTimeOffset.UtcNow;
+                    if (i == 2)
+                    {
+                        int tempDay = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? tempDay = 29 : tempDay = 28;
+                        timeDay = new DateTime(year, i, tempDay, 0, 0, 0);
+                    }
                     var (monthS, monthE) = TimeHelper.GetStartOrEnd(timeDay, "month");   //本月开始/结束时间
 
                     var openLesn = allLess.Where(item => item.startTime >= monthS && item.startTime <= monthE && item.upload == 0).ToList();
@@ -399,64 +380,13 @@ namespace TEAMModelBI.Controllers.BIHome
                 months = new { sdOpenLesn = yrOpenLesn.ToList(), sdUpdLesn = yrUpdLesn.ToList() },
                 years = new { sdOpenLesn = allOpenLesn.ToList(), sdUpdLesn = allUpdLesn.ToList() }
             }) ;
-
-            //string lesnSql = $"select c.id,c.name,c.code,c.school,c.scope,c.startTime  from c where c.pk='LessonRecord' and c.startTime >={daySt} and c.startTime <= {dayEt}";
-            ////今天课例
-            //sameDayLesn = await CommonFind.GetObject<RecLesn>(cosmosClient, new List<string>() { "School", "Teacher" }, lesnSql);
-
-            ////await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecLesn>(queryText: lesnSql, requestOptions: new QueryRequestOptions() { }))
-            ////{
-            ////    sameDayLesn.Add(item);
-            ////}
-            ////await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecLesn>(queryText: lesnSql, requestOptions: new QueryRequestOptions() { }))
-            ////{
-            ////    sameDayLesn.Add(item);
-            ////}
-            ////昨天课例
-            //string yesterDayLesnSql = $"select c.id,c.name,c.code,c.school,c.scope,c.startTime  from c where c.pk='LessonRecord' and c.startTime >={lastDayS} and c.startTime <= {lastdayE}";
-            //yesterDayLesn = await CommonFind.GetObject<RecLesn>(cosmosClient, new List<string>() { "School", "Teacher" }, yesterDayLesnSql);
-            ////await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecLesn>(queryText: yesterDayLesnSql, requestOptions: new QueryRequestOptions() { }))
-            ////{
-            ////    yesterDayLesn.Add(item);
-            ////}
-
-            ////await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecLesn>(queryText: yesterDayLesnSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("LessonRecord") }))
-            ////{
-            ////    yesterDayLesn.Add(item);
-            ////}
-
-            //for (int i = 0; i < 24; i++)
-            //{
-            //    if (hour >= i)
-            //    {
-            //        DateTimeOffset timeHour = new DateTime(year, month, day, i, 0, 0);
-            //        var (hourS, hourE) = TimeHelper.GetStartOrEnd(timeHour, type: "hour");
-
-            //        var openLesn = sameDayLesn.Where(item => item.startTime >= hourS && item.startTime <= hourE && item.upload == 0);
-            //        sdOpenLesn.Add(i, openLesn.Count());
-
-            //        var UpdLesn = sameDayLesn.Where(item => item.startTime >= hourS && item.startTime <= hourE && item.upload == 1);
-            //        sdUpdLesn.Add(i, openLesn.Count());
-
-            //    }
-
-            //    DateTimeOffset yesterday = new DateTime(lestDate.Year, lestDate.Month, lestDate.Day, i, 0, 0);
-            //    var (yHourS, yHourE) = TimeHelper.GetStartOrEnd(yesterday, type: "hour");
-
-            //    var yOpenLesn = yesterDayLesn.Where(item => item.startTime >= yHourS && item.startTime <= yHourE && item.upload == 0).ToList();
-            //    ydOpenLesn.Add(i, yOpenLesn.Count);
-
-            //    var yUpdLesn = yesterDayLesn.Where(item => item.startTime >= yHourS && item.startTime <= yHourE && item.upload == 1).ToList();
-            //    ydUpdLesn.Add(i, yUpdLesn.Count);
-            //}
-
-            //return Ok(new { state = 200, sdOpenLesn = sdOpenLesn.ToList(), sdUpdLesn = sdUpdLesn.ToList(), ydOpenLesn = ydOpenLesn.ToList(), ydUpdLesn = ydUpdLesn.ToList() });
         }
 
         /// <summary>
         /// 版本数量占比   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-edition")]
         public async Task<IActionResult> GetEdition(JsonElement jsonElement) 
         {
@@ -506,43 +436,6 @@ namespace TEAMModelBI.Controllers.BIHome
             return Ok(new { state = 200, beCnt, seCnt, peCnt, scEdCnt });
         }
 
-        /// <summary>
-        /// 开课
-        /// </summary>
-        /// <param name="jsonElement"></param>
-        /// <returns></returns>
-        public async Task<IActionResult> GetTmdCount(JsonElement jsonElement) 
-        {
-            if(jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return BadRequest();
-            var cosmosClient = _azureCosmos.GetCosmosClient();
-            var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin");
-            var blobClient = _azureStorage.GetBlobContainerClient($"0-public");
-            jsonElement.TryGetProperty("site", out JsonElement site);
-            if ($"{site}".Equals(BIConst.Global))
-            {
-                cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-                table = _azureStorage.GetCloudTableClient(BIConst.Global).GetTableReference("IESLogin");
-                blobClient = _azureStorage.GetBlobContainerClient($"0-public", BIConst.Global);
-            }           
-
-
-            List<string> schools = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
-
-
-
-
-            return Ok(new { state = 200 });
-        }
-
-
-        public record YearLesson 
-        {
-            public long year { get; set; }
-            public List<int> upload { get; set; }
-            public List<string> id { get; set; }
-        }
-
-
         /// <summary>
         /// 记录学校版本信息
         /// </summary>

+ 6 - 9
TEAMModelBI/Controllers/BINormal/AbilityMgmtController.cs

@@ -44,7 +44,7 @@ namespace TEAMModelBI.Controllers.BINormal
         }
 
         /// <summary>
-        /// 依据区级的标准编号获取标准的编号集合   //后端有
+        /// 依据区级的标准编号获取标准的编号集合   //已对接
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
@@ -60,7 +60,7 @@ namespace TEAMModelBI.Controllers.BINormal
                 if ($"{site}".Equals(BIConst.Global))
                     cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
 
-                List<Ability> abilities = new List<Ability>();
+                List<Ability> abilities = new();
                 string sqltxt = "select value(c) from c";
                 await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: sqltxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{standard}") }))
                 {
@@ -71,7 +71,7 @@ namespace TEAMModelBI.Controllers.BINormal
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"BI,{_option.Location} /biabilitymgmt/get-abilitysbystandard  \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"BI,{_option.Location} /biabilitymgmt/get-abilitys  \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
                 return BadRequest();
             }
         }
@@ -136,7 +136,7 @@ namespace TEAMModelBI.Controllers.BINormal
                     tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
                     blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
                 }
-                List<AbilityTask> syllabus = new List<AbilityTask>();
+                List<AbilityTask> syllabus = new();
                 string sql = $"select value(c) from c where c.abilityId='{id}'";
                 var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Ability-{standard}"));
                 await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{standard}") }))
@@ -151,7 +151,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 if (response.Status == 200)
                 {
                     //保存操作记录
-                    //await _azureStorage.SaveBILog("abilityTask-del", $"{_tmdName}【{_tmdId}】删除册别,删除ID:{id}", _dingDing, httpContext: HttpContext);
                     await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "abilityTask-del", $"{_tmdName}【{_tmdId}】删除册别,删除ID:{id}", _dingDing, httpContext: HttpContext);
 
                     return Ok(new { state = 200 });
@@ -179,7 +178,7 @@ namespace TEAMModelBI.Controllers.BINormal
             {
                 var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
 
-                StringBuilder stringBuilder = new StringBuilder($"{_tmdName}【{_tmdId}】");
+                StringBuilder stringBuilder = new($"{_tmdName}【{_tmdId}】");
 
                 //Ability ability = recordAbility.ability;
                 ability.pk = "Ability";
@@ -208,7 +207,7 @@ namespace TEAMModelBI.Controllers.BINormal
                 {
                     ability.comid = Guid.NewGuid().ToString();
 
-                    StringBuilder sqltxt = new StringBuilder("select value(c) from c  where c.status = 1 ");
+                    StringBuilder sqltxt = new("select value(c) from c  where c.status = 1 ");
                     if (!string.IsNullOrEmpty(ability.dimension))
                     {
                         sqltxt.Append($" and c.dimension = '{ability.dimension}' and c.name = '{ability.name}'  and c.no = '{ability.no}' ");
@@ -251,7 +250,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog(tempType?.ToString(), stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, tempType?.ToString(), stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
 
                 return Ok(new { state = 200, Ability = tempAbility });
@@ -297,7 +295,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("ability-update", $"{_tmdName}【{_tmdId}】设置是否必修状态。标准:{currencys[0].standard}", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "ability-update", $"{_tmdName}【{_tmdId}】设置是否必修状态。标准:{currencys[0].standard}", _dingDing, httpContext: HttpContext);
 
                 return Ok(new { state = 200, currencys });

+ 9 - 11
TEAMModelBI/Controllers/BINormal/AbilityTaskMgmtController.cs

@@ -63,8 +63,8 @@ namespace TEAMModelBI.Controllers.BINormal
                 if ($"{site}".Equals(BIConst.Global))
                     cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
                 Ability ability = null;
-                List<AbilityTaskTreeNode> abilityTaskTreeNodes = new List<AbilityTaskTreeNode>();//原始数据未排序
-                List<AbilityTaskTreeNode> redtAbilityTaskTreeNodes = new List<AbilityTaskTreeNode>();//排序后的数据
+                List<AbilityTaskTreeNode> abilityTaskTreeNodes = new();//原始数据未排序
+                List<AbilityTaskTreeNode> redtAbilityTaskTreeNodes = new();//排序后的数据
 
                 int rnodeCount = 0;
                 try
@@ -84,7 +84,7 @@ namespace TEAMModelBI.Controllers.BINormal
                         list.ForEach(x => { if (x.IsNotEmpty()) { rnodeCount += 1; } });
                     }
                     List<AbilityTaskTree> trees = AbilityService.ListToTree(item.children);
-                    AbilityTaskTreeNode abilityTaskTreeNode = new AbilityTaskTreeNode() { id = item.id, scope = item.scope, trees = trees, abilityId = item.abilityId, auth = item.auth, codeval = ability.school };
+                    AbilityTaskTreeNode abilityTaskTreeNode = new() { id = item.id, scope = item.scope, trees = trees, abilityId = item.abilityId, auth = item.auth, codeval = ability.school };
                     abilityTaskTreeNodes.Add(abilityTaskTreeNode);
                 }
 
@@ -139,7 +139,7 @@ namespace TEAMModelBI.Controllers.BINormal
                     blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
                 }
 
-                StringBuilder msgBuilder = new StringBuilder($"{_tmdName}【{_tmdId}】");
+                StringBuilder msgBuilder = new($"{_tmdName}【{_tmdId}】");
                 string type = null;
                 long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 foreach (var abilityTaskTree in recordAbilityTask.abilityTask)
@@ -161,9 +161,9 @@ namespace TEAMModelBI.Controllers.BINormal
                             {
                                 abilityTaskTree.trees.ForEach(x => x.id = abilityTaskTree.id);
                             }
-                            List<Tnode> nodes = new List<Tnode>();
+                            List<Tnode> nodes = new();
                             AbilityService.TreeToList(abilityTaskTree.trees, nodes, now);
-                            abilityTask = new AbilityTask();
+                            abilityTask = new();
                             abilityTask.id = abilityTaskTree.id;
                             abilityTask.children = nodes;
                             abilityTask.code = $"AbilityTask-{recordAbilityTask.standard}";
@@ -183,7 +183,7 @@ namespace TEAMModelBI.Controllers.BINormal
                             {
                                 abilityTaskTree.trees.ForEach(x => x.id = abilityTaskTree.id);
                             }
-                            List<Tnode> nodes = new List<Tnode>();
+                            List<Tnode> nodes = new();
                             AbilityService.TreeToList(abilityTaskTree.trees, nodes, now);
                             abilityTask.children = nodes;
                             abilityTaskTree.auth = abilityTask.auth;
@@ -200,9 +200,9 @@ namespace TEAMModelBI.Controllers.BINormal
                         {
                             abilityTaskTree.trees.ForEach(x => x.id = abilityTaskTree.id);
                         }
-                        List<Tnode> nodes = new List<Tnode>();
+                        List<Tnode> nodes = new();
                         AbilityService.TreeToList(abilityTaskTree.trees, nodes, now);
-                        AbilityTask abilityTask = new AbilityTask
+                        AbilityTask abilityTask = new()
                         {
                             id = id,
                             code = $"AbilityTask-{recordAbilityTask.standard}",
@@ -222,7 +222,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog(type, msgBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, type, msgBuilder?.ToString(), _dingDing, httpContext: HttpContext);
 
                 return Ok(new { state = 200, recordAbilityTask });
@@ -265,7 +264,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 string msg = $"{_tmdName}【{_tmdId}】删除册别,删除状态:{response.Status},删除ID:{id}";
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("abilitytask-del", msg, _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "abilitytask-del", msg, _dingDing, httpContext: HttpContext);
                 if (response.Status == 204)
                     return Ok(new { state = 200 });

+ 0 - 638
TEAMModelBI/Controllers/BINormal/AppCompanyController.cs

@@ -1,638 +0,0 @@
-using Azure.Cosmos;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Options;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Threading.Tasks;
-using TEAMModelBI.Filter;
-using TEAMModelBI.Models.Extension;
-using TEAMModelBI.Tool.Extension;
-using TEAMModelOS.Models;
-using TEAMModelOS.SDK.Context.BI;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.SDK.Extension;
-using TEAMModelOS.SDK.Models.Cosmos.BI;
-using TEAMModelOS.SDK.Models.Service;
-
-namespace TEAMModelBI.Controllers.BINormal
-{
-    [Route("appcompany")]
-    [ApiController]
-    public class AppCompanyController : ControllerBase
-    {
-        public readonly AzureCosmosFactory _azureCosmos;
-        public readonly AzureStorageFactory _azureStorage;
-        public readonly DingDing _dingDing;
-        public readonly Option _option;
-        private readonly IConfiguration _configuration;
-        private readonly NotificationService _notificationService;
-
-        public AppCompanyController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService)
-        {
-            _azureCosmos = azureCosmos;
-            _azureStorage = azureStorage;
-            _dingDing = dingDing;
-            _option = option?.Value;
-            _configuration = configuration;
-            _notificationService = notificationService;
-        }
-
-        /// <summary>
-        /// 查询应用信息
-        /// </summary>
-        /// <param name="jsonElement"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [HttpPost("get-info")]
-        public async Task<IActionResult> GetInfo(JsonElement jsonElement)
-        {
-            jsonElement.TryGetProperty("appId", out JsonElement appId);
-            jsonElement.TryGetProperty("eid", out JsonElement eid);
-            jsonElement.TryGetProperty("audit", out JsonElement audit);
-            jsonElement.TryGetProperty("site", out JsonElement site);
-
-            var cosmosClient = _azureCosmos.GetCosmosClient();
-            if ($"{site}".Equals(BIConst.Global))
-                cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            StringBuilder sqlTxt = new($"select c.id,c.pk,c.code,c.name,c.descr,c.picture,c.jwtKey,c.status,c.audit,c.refuseDesc,c.gateways,c.apis,c.webhookDomain,c.webHooks,c.schools from c where c.pk='App'");
-            if (!string.IsNullOrEmpty($"{appId}"))
-            {
-                sqlTxt.Append($" and id='{appId}'");
-            }
-            if (!string.IsNullOrEmpty($"{audit}"))
-            {
-                sqlTxt.Append($" and audit='{audit}'");
-            }
-
-            List<ReadCompany> appCompanys = new();
-            await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Normal").GetItemQueryStreamIterator(queryText: sqlTxt.ToString(), requestOptions: string.IsNullOrEmpty($"{eid}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"App-{eid}") }))
-            {
-                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())
-                    {
-                        ReadCompany readCompany = new()
-                        {
-                            id = obj.GetProperty("id").GetString(),
-                            pk = obj.GetProperty("pk").GetString(),
-                            code = obj.GetProperty("code").GetString(),
-                            name = obj.GetProperty("name").GetString(),
-                            descr = obj.GetProperty("descr").GetString(),
-                            picture = obj.GetProperty("picture").GetString(),
-                            jwtKey = obj.GetProperty("jwtKey").GetString(),
-                            status = obj.GetProperty("status").GetInt32(),
-                            audit = obj.GetProperty("audit").GetInt32(),
-                            refuseDesc = obj.GetProperty("refuseDesc").GetString(),
-                            gateways = obj.GetProperty("gateways").GetString(),
-                            apis = obj.GetProperty("apis").ToObject<List<AppApiState>>(),
-                            webhookDomain = obj.GetProperty("webhookDomain").GetString(),
-                            webHooks = obj.GetProperty("webHooks").ToObject<List<WebHookState>>(),
-                            schools = obj.GetProperty("schools").ToObject<List<ApplySchool>>()
-                        };
-
-                        appCompanys.Add(readCompany);
-                    }
-                }
-            }
-
-            return Ok(new { state = 200, appCompanys });
-        }
-
-        /// <summary>
-        /// 新增或者修改应用
-        /// </summary>
-        /// <param name="appCompany"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [AuthToken(Roles = "admin,rdc,company")]
-        [HttpPost("set-info")]
-        public async Task<IActionResult> SetAppInfo(AppCompany appCompany, [FromHeader] string site)
-        {
-            try
-            {
-                var (loginId, loginName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
-                var cosmosClient = _azureCosmos.GetCosmosClient();
-                var tableClient = _azureStorage.GetCloudTableClient();
-                var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
-                if ($"{site}".Equals(BIConst.Global))
-                {
-                    cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-                    tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
-                    blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
-                }
-                StringBuilder stringBuilder = new($"{loginName}【{loginId}】");
-                string type = "";
-                //新建
-                if (string.IsNullOrEmpty($"{appCompany.id}"))
-                {
-                    appCompany.id = GenerateRandom.StrRandom(8, large: true, small: true);
-                    appCompany.code = $"App-{appCompany.code}";
-                    appCompany.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-                    appCompany.status = -1;
-                    appCompany.audit = -1;
-                    appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").CreateItemAsync<AppCompany>(appCompany, new PartitionKey(appCompany.code));
-                    stringBuilder.Append($"新增应用,应用ID:{appCompany.id},应用名称:{appCompany.name}");
-                    type = "appCompany-add";
-                }
-                //修改
-                else
-                {
-                    var response = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReadItemStreamAsync(appCompany.id, new PartitionKey(appCompany.code));
-                    if (response.Status == 200)
-                    {
-                        appCompany.pk = "App";
-                        appCompany.ttl = -1;
-                        appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReplaceItemAsync<AppCompany>(appCompany, appCompany.id, new PartitionKey(appCompany.code));
-                        stringBuilder.Append($"修改应用,应用ID:{appCompany.id},应用名称:{appCompany.name}");
-                        type = "appCompany-update";
-                    }
-                    else return Ok(new { state = 404, msg = "未找到该id相关的企业应用信息" });
-                }
-
-                //保存操作记录
-                //await _azureStorage.SaveBILog(type, stringBuilder.ToString(), _dingDing, httpContext: HttpContext);
-                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, type, stringBuilder.ToString(), _dingDing, httpContext: HttpContext);
-                return Ok(new { state = 200, appCompany });
-            }
-            catch (Exception e)
-            {
-                await _dingDing.SendBotMsg($"BI,{_option.Location} , /appcompany/set-info   \n {e.Message}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
-                return BadRequest();
-            }
-        }
-
-        /// <summary>
-        /// 查询未审核的信息
-        /// </summary>
-        /// <param name="jsonElement"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [HttpPost("get-noaudit")]
-        public async Task<IActionResult> GetNoAudit(JsonElement jsonElement) 
-        {
-            if(!jsonElement.TryGetProperty("operate", out JsonElement operate)) return BadRequest();
-            jsonElement.TryGetProperty("site", out JsonElement site);
-            var cosmosClient = _azureCosmos.GetCosmosClient();
-            var tableClient = _azureStorage.GetCloudTableClient();
-            var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
-            if ($"{site}".Equals(BIConst.Global))
-            {
-                cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-                tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
-                blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
-            }
-            StringBuilder sqlTxt = new();
-
-            switch (operate.GetString())
-            {
-                case "api":
-                    sqlTxt.Append($"SELECT c.id, c.code,c.name,c.pk,c.audit,ARRAY(SELECT VALUE a FROM a in c.apis where a.status = -1) as operate FROM c where c.pk='App' and c.audit=1");
-                    break;
-                case "school":
-                    sqlTxt.Append($"SELECT c.id, c.code,c.name,c.pk,c.audit,ARRAY(SELECT VALUE a FROM a in c.schools where a.status = -1) as operate FROM c where c.pk='App' and c.audit=1");
-                    break;
-                default:
-                    sqlTxt.Append($"select c.id,c.code,c.name,c.pk,c.audit from c where c.audit=-1 and c.pk='App'");
-                    break;
-            }
-
-            List<NoAudit> noAudits = new();
-
-            await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Normal").GetItemQueryStreamIterator(queryText: sqlTxt.ToString(), requestOptions: new QueryRequestOptions() { })) 
-            {
-                var json = await JsonDocument.ParseAsync(item.ContentStream);
-                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt16() > 0) 
-                {
-                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray()) 
-                    {
-                        NoAudit noAudit = new();
-                        noAudit.id = obj.GetProperty("id").GetString();
-                        noAudit.code = obj.GetProperty("code").GetString();
-                        noAudit.pk = obj.GetProperty("pk").GetString();
-                        noAudit.name = obj.GetProperty("name").GetString();
-                        if (!string.IsNullOrEmpty($"{operate}"))
-                        {
-                            noAudit.operate = obj.GetProperty("operate").ToObject<List<object>>();
-                        }
-                        noAudit.audit = obj.GetProperty("audit").GetInt32();
-
-                        noAudits.Add(noAudit);
-                    }
-                }            
-            }
-
-            return Ok(new { state = 200, noAudits });
-        }
-
-        /// <summary>
-        /// 审核应用是否通过
-        /// </summary>
-        /// <param name="jsonElement"></param>
-        /// <returns></returns>
-        [AuthToken(Roles = "admin,rdc")]
-        [HttpPost("get-apply")]
-        public async Task<IActionResult> SetAuditApp(JsonElement jsonElement)
-        {
-            try
-            {
-                var (loginId, loginName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
-                if (!jsonElement.TryGetProperty("appIds", out JsonElement appIds)) return BadRequest();
-                if (!jsonElement.TryGetProperty("isAudit", out JsonElement isAudit)) return BadRequest();
-                jsonElement.TryGetProperty("refuseDesc", out JsonElement refuseDesc);
-                jsonElement.TryGetProperty("site", out JsonElement site);
-                var cosmosClient = _azureCosmos.GetCosmosClient();
-                var tableClient = _azureStorage.GetCloudTableClient();
-                var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
-                if ($"{site}".Equals(BIConst.Global)) 
-                {
-                    cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-                    tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
-                    blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
-                }
-                StringBuilder strMsg = new($"{loginName}【{loginId}】");
-                List<AppIdOrCode> idOrCode = appIds.ToObject<List<AppIdOrCode>>();
-                List<AppIdOrCode> haveIds = new();
-                if (idOrCode.Count > 0)
-                {
-                    foreach (var idCode in idOrCode)
-                    {
-                        AppCompany appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReadItemAsync<AppCompany>(idCode.id, new PartitionKey(idCode.code));
-                        strMsg.Append($"审核应用{appCompany.name}【{appCompany.id}】,审核状态:");
-                        //var response = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReadItemStreamAsync(idCode.id, new PartitionKey(idCode.code));
-                        if (bool.Parse($"{isAudit}") == true)
-                        {
-                            appCompany.audit = 1;
-                            appCompany.jwtKey = JwtAuth.CreateApplyJwtKeyBI(_option.HostName, _option.JwtSecretKey, appCompany);
-                            strMsg.Append("通过。");
-                        }
-                        else
-                        {
-                            appCompany.audit = 0;
-                            appCompany.refuseDesc = $"{refuseDesc}";
-                            strMsg.Append("拒绝通过。");
-                        }
-                        try
-                        {
-                            
-                            await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReplaceItemAsync<AppCompany>(appCompany, appCompany.id, new PartitionKey(idCode.code));
-                        }
-                        catch
-                        {
-                            haveIds.Add(idCode);
-                            strMsg.Append($"异常:id:{idCode.id},code:{idCode.code};");
-                        }
-                    }
-                }
-                else return Ok(new { state = 404, msg = "appIds参数错误" });
-
-                //保存操作记录
-                //await _azureStorage.SaveBILog("appCompany-update", strMsg.ToString(), _dingDing, httpContext: HttpContext);
-                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "appCompany-update", strMsg.ToString(), _dingDing, httpContext: HttpContext);
-
-                if (haveIds.Count > 0)
-                    return Ok(new { state = 201, msg = "部分应用审核失败!", haveIds });
-                else return Ok(new { state = 200 });
-            }
-            catch (Exception e)
-            {
-                await _dingDing.SendBotMsg($"BI,{_option.Location} , /appcompany/get-applyapi   \n {e.Message}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
-                return BadRequest();
-            }
-        }
-
-        /// <summary>
-        /// 应用申请Api接口信息
-        /// 审核应用api接口信息
-        /// </summary>
-        /// <param name="jsonElement"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [AuthToken(Roles = "admin,rdc,company")]
-        [HttpPost("set-applyapi")]
-        public async Task<IActionResult> SetApplyApi(JsonElement jsonElement)
-        {
-            try
-            {
-                var (loginId, loginName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
-                if (!jsonElement.TryGetProperty("applyApis", out JsonElement jsApplyApis)) return BadRequest();
-                if (!jsonElement.TryGetProperty("operate", out JsonElement operate)) return BadRequest();
-                jsonElement.TryGetProperty("site", out JsonElement site);
-
-                StringBuilder strMsg = new($"{loginName}【{loginId}】");
-                var cosmosClient = _azureCosmos.GetCosmosClient();
-                var tableClient = _azureStorage.GetCloudTableClient();
-                var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
-                if ($"{site}".Equals(BIConst.Global))
-                {
-                    cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-                    tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
-                    blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
-                }
-                string bizcode = "";  //消息名称
-                List<string> sendWhom = new();//消息分发给谁   待完善
-                List<ApplyApi> applyApis = jsApplyApis.ToObject<List<ApplyApi>>();
-                List<ApplyApi> haveApi = new();  //存在api接口
-                Dictionary<string,string> noAudit = new();
-
-                foreach (var tempApp in applyApis)
-                {
-                    AppCompany appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReadItemAsync<AppCompany>($"{tempApp.appId}", new PartitionKey($"{tempApp.appCode}"));
-
-                    if (appCompany != null || appCompany.audit != -1 || appCompany.audit != 0)
-                    {
-                        switch (operate.GetString())
-                        {
-                            case "apply":
-                                strMsg.Append($"申请:{appCompany.name}【{appCompany.id}】应用的Api:");
-                                if (!jsonElement.TryGetProperty("applyDesc", out JsonElement applyDesc)) return BadRequest();
-                                tempApp.apiIds.ForEach(x =>
-                                {
-                                    var strt = appCompany.apis.Find(y => y.no.Equals($"{x}"));
-                                    if (strt == null)
-                                    {
-                                        appCompany.apis.Add(new AppApiState() { no = $"{x}", applyDesc = $"{applyDesc}", status = -1 });
-                                        strMsg.Append($"{x},");
-                                    }
-                                    else haveApi.Add(tempApp);
-                                });
-                                sendWhom.Add(appCompany.id);
-                                bizcode = "applyapi";
-                                if (haveApi.Count > 0) strMsg.Append($"已有存在的api:{haveApi.ToJsonString()}。");
-                                break;
-                            case "audit":
-                                if (!jsonElement.TryGetProperty("isAudit", out JsonElement isAudit)) return BadRequest();
-                                string refuseDesc = "";
-                                if (bool.Parse($"{isAudit}") == false)
-                                {
-                                    if (!jsonElement.TryGetProperty("refuseDesc", out JsonElement jsonRefuseDesc)) return BadRequest();
-                                    refuseDesc = jsonRefuseDesc.GetString();
-                                }
-
-                                strMsg.Append($"审核{appCompany.name}【{appCompany.id}】应用的Api:");
-                                tempApp.apiIds.ForEach(x =>
-                                {
-                                    var temp = appCompany.apis.Find(n => n.no == x);
-                                    if (temp != null)
-                                    {
-                                        AppApiState appApiState = appCompany.apis.Single(a => a.no == x);
-                                        if (bool.Parse($"{isAudit}") == true)
-                                        {
-                                            appApiState.status = 1;
-                                            appApiState.refuseDesc = null;
-                                            appCompany.jwtKey = JwtAuth.CreateApplyJwtKeyBI(_option.HostName, _option.JwtSecretKey, appCompany);
-                                            strMsg.Append($"{appApiState.no}通过,");
-                                        }
-                                        else
-                                        {
-                                            appApiState.status = 0;
-                                            appApiState.refuseDesc = $"{refuseDesc}";
-                                            strMsg.Append($"{appApiState.no}失败,");
-                                        }
-                                    }
-                                    else haveApi.Add(tempApp);
-                                });
-
-                                if (haveApi.Count > 0) strMsg.Append($"该应用没有申请相关API接口:{haveApi.ToJsonString()}。");
-                                sendWhom.Add(appCompany.id);
-                                bizcode = "auditapi";
-
-                                break;
-                            default:
-                                return Ok(new { state = 400, msg = "operate参数错误" });
-                        }
-                        appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReplaceItemAsync<AppCompany>(appCompany, appCompany.id, new PartitionKey(appCompany.code));
-                    }
-                    else noAudit.Add($"{appCompany.id}", $"{appCompany.name}");
-                }
-
-                //发送消息
-                var location = _option.Location;
-                Notification notification = new()
-                {
-                    hubName = bizcode,
-                    type = "msg",
-                    from = $"BI:{_option.Location}:private",
-                    to = sendWhom,
-                    label = $"{bizcode}-appCompany",
-                    body = new { location = location, biz = bizcode, appid = sendWhom, appName = sendWhom, status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
-                };
-
-                var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
-                var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
-                var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
-                await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //站内发送消息
-
-                //保存操作记录
-                //await _azureStorage.SaveBILog("appCompany-update", strMsg.ToString(), _dingDing, httpContext: HttpContext);
-                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "appCompany-update", strMsg.ToString(), _dingDing, httpContext: HttpContext);
-                if (haveApi.Count > 0 || noAudit.Count > 0)
-                    return Ok(new { state = 201, msg = "部分成功", haveApi, noAudit });
-                else return Ok(new { state = 200 });
-            }
-            catch (Exception e)
-            {
-                await _dingDing.SendBotMsg($"BI,{_option.Location} , /appcompany/get-applyapi   \n {e.Message}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
-                return BadRequest();
-            }
-        }
-
-        /// <summary>
-        /// 应用申请学校
-        /// 应用审核申请的学校
-        /// </summary>
-        /// <param name="jsonElement"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [AuthToken(Roles = "admin,rdc,company")]
-        [HttpPost("set-applyschool")]
-        public async Task<IActionResult> SetAuditSchool(JsonElement jsonElement)
-        {
-            try
-            {
-                var (loginId, loginName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
-                if (!jsonElement.TryGetProperty("appId", out JsonElement appId)) return BadRequest();
-                if (!jsonElement.TryGetProperty("appCode", out JsonElement appCode)) return BadRequest();
-                if (!jsonElement.TryGetProperty("schooCode", out JsonElement schooCode)) return BadRequest();
-                if (!jsonElement.TryGetProperty("operate", out JsonElement operate)) return BadRequest();
-                jsonElement.TryGetProperty("site", out JsonElement site);
-
-                var cosmosClient = _azureCosmos.GetCosmosClient();
-                var tableClient = _azureStorage.GetCloudTableClient();
-                var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
-                if ($"{site}".Equals(BIConst.Global)) 
-                {
-                    cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-                    tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
-                    blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
-                }
-                StringBuilder strMsg = new($"{loginName}【{loginId}】操作:");
-                List<string> haveSchool = new();
-                List<string> sendWhom = new();//消息分发给谁   待完善
-                string bizcode = "";  //消息名称
-
-                AppCompany appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReadItemAsync<AppCompany>($"{appId}", new PartitionKey($"{appCode}"));
-                if (appCompany.audit == -1 || appCompany.audit == 0) 
-                {
-                    return Ok(new { state = 401, msg = "应用未审核请先审核应用程序" });
-                }
-
-                if (appCompany != null)
-                {
-                    switch (operate.GetString())
-                    {
-                        case "apply":
-                            var aSchool = appCompany.schools.Find(x => x.id.Equals($"{schooCode}"));
-                            if (!jsonElement.TryGetProperty("name", out JsonElement name)) return BadRequest();
-                            if (aSchool == null)
-                            {
-                                jsonElement.TryGetProperty("picture", out JsonElement picture);
-                                strMsg.Append($"应用{appCompany.name}【{appCompany.id}】申请学校{name}【{schooCode}】,申请成功。");
-                                appCompany.schools.Add(new ApplySchool() { id = $"{schooCode}", name = $"{name}", picture = $"{picture}" });
-                            }
-                            else
-                            {
-                                haveSchool.Add(schooCode.GetString());
-                                strMsg.Append($"应用{appCompany.name}【{appCompany.id}】申请的学校{name}【{schooCode}】已存在。");
-                            }
-                            sendWhom = new List<string> { "1528783103", "1636016499" };
-                            bizcode = "applyschool";
-
-                            break;
-                        case "audit":
-                            if (!jsonElement.TryGetProperty("isAudit", out JsonElement isAudit)) return BadRequest();
-                            string refuseDesc = "";
-                            if (bool.Parse($"{isAudit}") == false)
-                            {
-                                if (!jsonElement.TryGetProperty("refuseDesc", out JsonElement jsonRefuseDesc)) return BadRequest();
-                                refuseDesc = jsonRefuseDesc.GetString();
-                            }
-
-                            var applySchool = appCompany.schools.Find(x => x.id.Equals($"{schooCode}"));
-                            strMsg.Append($"审核应用{appCompany.name}【{appCompany.id}】状态:");
-                            if (applySchool != null)
-                            {
-                                if (bool.Parse($"{isAudit}") == true)
-                                {
-                                    applySchool.status = 1;
-                                    applySchool.refuseDesc = null;
-                                    appCompany.jwtKey = JwtAuth.CreateApplyJwtKeyBI(_option.HostName, _option.JwtSecretKey, appCompany);
-                                    strMsg.Append($"审核成功。");
-                                }
-                                else
-                                {
-                                    applySchool.status = 0;
-                                    applySchool.refuseDesc = $"{refuseDesc}";
-                                    strMsg.Append($"审核失败。");
-                                }
-                            }
-                            else
-                            {
-                                haveSchool.Add(schooCode.GetString());
-                                strMsg.Append($"已审核状态!");
-                            }
-                            sendWhom = new List<string> { "1528783103", "1636016499" };
-                            bizcode = "auditschool";
-
-                            break;
-                        default:
-                            return Ok(new { state = 400, msg = "operate参数错误" });
-                    }
-
-                    appCompany = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReplaceItemAsync<AppCompany>(appCompany, appCompany.id, new PartitionKey(appCompany.code));
-                }
-                else return Ok(new { state = 404, msg = "未找到该应用" });
-
-                //发送消息
-                var location = _option.Location;
-                Notification notification = new()
-                {
-                    hubName = bizcode,
-                    type = "msg",
-                    from = $"BI:{_option.Location}:private",
-                    to = sendWhom,
-                    label = $"{bizcode}-appCompany",
-                    body = new { location = location, biz = bizcode, appid = appCompany.id, appName = appCompany.name, status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
-                };
-
-                var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
-                var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
-                var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
-                await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //站内发送消息
-
-                //保存操作记录
-                //await _azureStorage.SaveBILog("appCompany-update", strMsg.ToString(), _dingDing, httpContext: HttpContext);
-                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "appCompany-update", strMsg.ToString(), _dingDing, httpContext: HttpContext);
-                if (haveSchool.Count > 0) return Ok(new { state = 201, msg = "已存在学校,无须申请!", haveSchool });
-                else return Ok(new { state = 200 });
-            }
-            catch (Exception e)
-            {
-                await _dingDing.SendBotMsg($"BI,{_option.Location} , /appcompany/set-auditschool   \n {e.Message}\n{e.StackTrace}\n{e.StackTrace} \n ", GroupNames.成都开发測試群組);
-                return BadRequest();
-            }
-        }
-
-        /// <summary>
-        /// 应用申请和审核api信息
-        /// </summary>
-        public record ApplyApi
-        {
-            public string appId { get; set; }
-            public string appCode { get; set; }
-            public List<string> apiIds { get; set; }
-        }
-
-        /// <summary>
-        /// 审核应用
-        /// </summary>
-        public record AppIdOrCode
-        {
-            public string id { get; set; }
-            public string code { get; set; }
-        }
-
-        /// <summary>
-        /// 未审核应用
-        /// </summary>
-        public record NoAudit 
-        { 
-            public string id { get; set; }
-            public string code { get; set; }
-
-            public string pk { get; set; }
-
-            public string name { get;set; }
-            public List<object> operate { get; set; }
-            public int audit { get; set; }
-        }
-
-        /// <summary>
-        /// 显示应用
-        /// </summary>
-        public record ReadCompany
-        {
-            public string id { get; set; }
-            public string pk { get; set; }
-            public string code { get; set; }
-            public string name { get; set; }
-            public string descr { get; set; }
-            public string picture { get; set; }
-            public string jwtKey { get; set; }
-            public int status { get; set; }
-            public int audit { get; set; }
-            public string refuseDesc { get; set; }
-            public string gateways { get; set; }
-            public List<AppApiState> apis { get; set; }
-            public string webhookDomain { get; set; }
-            public List<WebHookState> webHooks { get; set; }
-            public List<ApplySchool> schools { get; set; }
-        }
-
-    }
-}

+ 3 - 4
TEAMModelBI/Controllers/BINormal/AreaRelevantController.cs

@@ -41,6 +41,8 @@ namespace TEAMModelBI.Controllers.BINormal
             _azureStorage = azureStorage;
             _dingDing = dingDing;
             _option = option?.Value;
+            _configuration = configuration;
+            _coreAPIHttpService = coreAPIHttpService;
         }
 
         /// <summary>
@@ -72,7 +74,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 if (isManyArea)
                 {
                     sqltxt = $"SELECT c.id,c.name,c.schoolCode,c.province,c.city,c.dist,c.picture,c.period,c.areaId,c.standard,c.manyAreas FROM c join m in c.manyAreas WHERE c.areaId ='{_areaId}' or m.areaId='{_areaId}'";
-                    //sqltxt = $"SELECT c.id,c.name,c.schoolCode,c.province,c.city,c.dist,c.picture,c.period FROM c join m in c.manyAreas where m.areaId='{_areaId}' or c.areaId='{_areaId}'";
                 }
 
                 await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: sqltxt, requestOptions:new QueryRequestOptions() { PartitionKey = new PartitionKey("Base")})) 
@@ -133,7 +134,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 jsonElement.TryGetProperty("isDefault", out JsonElement isDefault);
                 jsonElement.TryGetProperty("site", out JsonElement site);
 
-
                 var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 var tableClient = _azureStorage.GetCloudTableClient();
@@ -198,7 +198,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 School school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(tempSchool, tempSchool.id, new PartitionKey("Base"));
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("school-update", $"{_tmdName}【{_tmdId}】已操作学校({schoolId})移除该区域", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-update", $"{_tmdName}【{_tmdId}】已操作学校(ID:{schoolId})移除已区域(ID:{areaId})", _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200, school });
             }
@@ -393,6 +392,7 @@ namespace TEAMModelBI.Controllers.BINormal
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-assists")]
         public async Task<IActionResult> GetAssists(JsonElement jsonElement)
         {
@@ -457,7 +457,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 else { noIds.Add(item); }
             }
 
-
             return Ok(new { state = 200, areaAssists, noIds });
 
         }

+ 4 - 11
TEAMModelBI/Controllers/BINormal/BatchAreaController.cs

@@ -153,7 +153,6 @@ namespace TEAMModelBI.Controllers.BINormal
                     };
                 }
 
-
                 return Ok(new { state = 200, areas, continuationToken });
             }
             catch (Exception ex)
@@ -194,7 +193,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 //操作记录实体
                 var tempStandard = !string.IsNullOrEmpty($"{oldStandard}") && !string.IsNullOrEmpty($"{_oldId}") ? $"{oldStandard}" : "standard2";
 
-                //var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin");
                 var cosmosClient = _azureCosmos.GetCosmosClient();//数据库连接
                 var tableClient = _azureStorage.GetCloudTableClient();
                 var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
@@ -215,8 +213,6 @@ namespace TEAMModelBI.Controllers.BINormal
                     cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
                     tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
                     blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", name: BIConst.Global);
-                    //serBusClient = _serviceBus.GetServiceBusClient(BIConst.Global);  //暂未确定使用默认
-                    //activeTask = _configuration.GetValue<string>("GlobalAzure:ServiceBus:ActiveTask");   //暂未确定使用默认
                 }
 
                 var table = tableClient.GetTableReference("IESLogin");
@@ -619,8 +615,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 jsonElement.TryGetProperty("newName", out JsonElement newName);
                 jsonElement.TryGetProperty("site", out JsonElement site);
 
-
-
                 var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
                 //操作记录实体
                 string blobOrTable = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
@@ -749,7 +743,6 @@ namespace TEAMModelBI.Controllers.BINormal
                         //abilityTasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{_oldStandard}")));
                         await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{_oldStandard}"));
                     }
-
                 }
                 catch
                 {
@@ -818,7 +811,7 @@ namespace TEAMModelBI.Controllers.BINormal
                 string partitionCode = "DelBeforeCopyAbility-mark";
 
                 //执行复制操作
-                BatchCopyFile batchCopyFile = new BatchCopyFile();
+                BatchCopyFile batchCopyFile = new();
                 batchCopyFile.blobCntr = "teammodelos";
                 batchCopyFile.oldFileName = $"{_newStandard}";
                 batchCopyFile.newFileName = $"{_oldStandard}";
@@ -839,7 +832,7 @@ namespace TEAMModelBI.Controllers.BINormal
                 }
 
                 //发送消息实体
-                Notification notification = new Notification
+                Notification notification = new()
                 {
                     hubName = "hita",
                     type = "msg",
@@ -857,7 +850,6 @@ namespace TEAMModelBI.Controllers.BINormal
                 await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //发送站内发送消息
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("area-cut", $"{_tmdName}【{_tmdId}】已操作【{_oldStandard}】切换至{_newStandard}微能力点,复制标准:{_newStandard}", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "area-cut", $"{_tmdName}【{_tmdId}】已操作【{_oldStandard}】切换至{_newStandard}微能力点,复制标准:{_newStandard}", _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200 });
             }
@@ -873,6 +865,7 @@ namespace TEAMModelBI.Controllers.BINormal
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("del-area")]
         public async Task<IActionResult> DelArea(JsonElement jsonElement)
         {
@@ -968,7 +961,7 @@ namespace TEAMModelBI.Controllers.BINormal
 
                     List<object> fileobj = new();
                     //先删除原有的文件
-                    List<Task<Response<bool>>> DelList = new List<Task<Response<bool>>>();
+                    List<Task<Response<bool>>> DelList = new();
                     await foreach (BlobItem blobItem in blobClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, $"yxpt/{area.standard}/"))
                     {
                         fileobj.Add(blobItem.Name);

+ 0 - 3
TEAMModelBI/Controllers/BINormal/BusinessConfigController.cs

@@ -119,7 +119,6 @@ namespace TEAMModelBI.Controllers.BINormal
                     bizConfig = await cosmosClient.GetContainer("TEAMModelOS", "Normal").ReplaceItemAsync<BizConfig>(bizConfig, bizConfig.id, new PartitionKey("BizConfig"));
                     strMsg.Append($"{bizConfig.name}【{bizConfig.id}】修改企业基础信息。");
                     type = "bizconfig-update";
-
                 }
             }
 
@@ -128,7 +127,6 @@ namespace TEAMModelBI.Controllers.BINormal
             return Ok(new { state = RespondCode.Ok, bizConfig });
         }
 
-
         /// <summary>
         /// 获取企业信息列表   //已对接
         /// </summary>
@@ -325,7 +323,6 @@ namespace TEAMModelBI.Controllers.BINormal
             return Ok(new { state = RespondCode.Ok , openSchools });
         }
 
-
         public record OpenSchool
         {
             public string id { get; set; }

+ 29 - 43
TEAMModelBI/Controllers/BISchool/BatchSchoolController.cs

@@ -67,7 +67,7 @@ namespace TEAMModelBI.Controllers.BISchool
         public async Task<IActionResult> GetAuthorityBIList(JsonElement jsonElement)
         {
             jsonElement.TryGetProperty("site", out JsonElement site);
-            Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", "authority-bi" } };
+            Dictionary<string, object> dic = new() { { "PartitionKey", "authority-bi" } };
             var table = _azureStorage.GetCloudTableClient().GetTableReference("SchoolSetting");
             if ($"{site}".Equals(BIConst.Global))
                 table = _azureStorage.GetCloudTableClient(BIConst.Global).GetTableReference("SchoolSetting");
@@ -93,7 +93,7 @@ namespace TEAMModelBI.Controllers.BISchool
                 List<BISchool> schools = new();
                 List<BISchool> userScs = new();
                 List<BISchool> cutArea = new();
-                StringBuilder stringBuilder = new StringBuilder($"{_tmdName}【{_tmdId}】使用批量创校功能:");
+                StringBuilder stringBuilder = new($"{_tmdName}【{_tmdId}】使用批量创校功能:");
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 var tableClient = _azureStorage.GetCloudTableClient();
                 var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
@@ -205,7 +205,7 @@ namespace TEAMModelBI.Controllers.BISchool
                                             //教师存在,在该教师信息中添加要管理的学校信息
                                             teacher.schools.Add(new Teacher.TeacherSchool { areaId = string.IsNullOrEmpty(bischool.areaId) ? "" : bischool.areaId, schoolId = createSchoolInfo.id, name = bischool.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
                                             //await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, coreUser.id, new PartitionKey("Base"));
-                                            SchoolTeacher schoolTeacher = new SchoolTeacher
+                                            SchoolTeacher schoolTeacher = new()
                                             {
                                                 id = coreUser.id,
                                                 code = $"Teacher-{createSchoolInfo.id}",
@@ -271,7 +271,6 @@ namespace TEAMModelBI.Controllers.BISchool
                 else return Ok(new { state = 1, message = "创校信息为空" });
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("school-batchAdd", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-batchAdd", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 if (schools.Count == foundSchools.biSchools.Count || userScs.Count == foundSchools.biSchools.Count)
                     return Ok(new { state = RespondCode.CreateFailed, message = "已有部分学校批量创建成功;学校已经重复/学校信息有误!请检查学校信息!", schools, userScs });
@@ -302,20 +301,22 @@ namespace TEAMModelBI.Controllers.BISchool
             try
             {
                 jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
-                jsonElement.TryGetProperty("schoolCode", out JsonElement _schoolCode);
+                jsonElement.TryGetProperty("scId", out JsonElement scId);
+                jsonElement.TryGetProperty("name", out JsonElement name);
                 jsonElement.TryGetProperty("site", out JsonElement site);
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 if ($"{site}".Equals(BIConst.Global))
                     cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
+                int scCnt = 0;
 
-                int? pageSize = null;      //默认不指定返回大小        
+                int? pageSize = 10;      //默认不指定返回大小        
                 string continuationToken = string.Empty;     //返给前端分页token           
                 string pageToken = default;//接受前端的分页Tolen
                 bool iscontinuation = false;//是否需要进行分页查询,默认不分页
                 List<AssistSchool> schoolAssists = new(); //返回学校列表集合
                 List<string> schoolIds = new();
                 StringBuilder stringBuilder = new("select c.id,c.code,c.schoolCode,c.name,c.region,c.province,c.city,c.dist,c.size,c.address,c.picture,c.type,c.scale,c.areaId,c.standard from c");
-
+                scCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", "select value(count(c.id)) from c", "Base");
                 if (jsonElement.TryGetProperty("pageSize", out JsonElement jsonPageSize))
                 {
                     if (!jsonPageSize.ValueKind.Equals(JsonValueKind.Undefined) && !jsonPageSize.ValueKind.Equals(JsonValueKind.Null) && jsonPageSize.TryGetInt32(out int tempPageSize))
@@ -350,9 +351,14 @@ namespace TEAMModelBI.Controllers.BISchool
                 }
                 else
                 {
-                    if (!string.IsNullOrEmpty($"{_schoolCode}"))
+                    if (!string.IsNullOrEmpty($"{scId}") && string.IsNullOrEmpty($"{name}"))
                     {
-                        stringBuilder.Append($" where c.id='{_schoolCode}'");
+                        stringBuilder.Append($" where c.id='{scId}'");
+                    }
+
+                    if (string.IsNullOrEmpty($"{scId}") && !string.IsNullOrEmpty($"{name}"))
+                    {
+                        stringBuilder.Append($" where Contains(c.name,'{name}')");
                     }
 
                     await foreach (var itemSchool in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: stringBuilder.ToString(), continuationToken: pageToken, requestOptions: new QueryRequestOptions() { MaxItemCount = pageSize, PartitionKey = new PartitionKey("Base") }))
@@ -396,7 +402,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     school.lessonCount = await CommonFind.GetSqlValueCount(cosmosClient, "School", $"select value(count(c.id)) from c ", $"LessonRecord-{school.id}");
                 });
 
-                return Ok(new { state = 200, continuationToken, schoolAssists, });
+                return Ok(new { state = 200, scCnt, continuationToken, schoolAssists, });
             }
             catch (Exception ex)
             {
@@ -454,7 +460,7 @@ namespace TEAMModelBI.Controllers.BISchool
                 jsonElement.TryGetProperty("site", out JsonElement site);
                 string schoolId = (jsonElement.TryGetProperty("schoolId", out JsonElement _schoolId)) ? _schoolId.GetString() : string.Empty;
 
-                Dictionary<string, List<Dictionary<string, string>>> haveSchoolManger = new Dictionary<string, List<Dictionary<string, string>>>();
+                Dictionary<string, List<Dictionary<string, string>>> haveSchoolManger = new();
 
                 string managerWhereOption = (!string.IsNullOrWhiteSpace(schoolId)) ? $" AND c.code = 'Teacher-{schoolId}'" : string.Empty;
                 //查询学校的顾问
@@ -470,7 +476,7 @@ namespace TEAMModelBI.Controllers.BISchool
                         string id = obj.GetProperty("id").GetString(); //管理员ID
                         string name = obj.GetProperty("name").GetString(); //管理员姓名
                         string tempSchoolId = obj.GetProperty("schoolId").GetString(); //学校ID
-                        Dictionary<string, string> managerDic = new Dictionary<string, string>();
+                        Dictionary<string, string> managerDic = new();
                         managerDic.Add("id", id);
                         managerDic.Add("name", name);
                         if (haveSchoolManger.ContainsKey(tempSchoolId))
@@ -568,7 +574,7 @@ namespace TEAMModelBI.Controllers.BISchool
 
                 List<string> assistId = _assistId.ToObject<List<string>>();
                 //List<string> periodS = period.ToObject<List<string>>();
-                Dictionary<string, List<Dictionary<string, string>>> haveSchoolManger = new Dictionary<string, List<Dictionary<string, string>>>();
+                Dictionary<string, List<Dictionary<string, string>>> haveSchoolManger = new();
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 var tableClient = _azureStorage.GetCloudTableClient();
                 var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
@@ -583,7 +589,7 @@ namespace TEAMModelBI.Controllers.BISchool
                 School tempShool = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{_schoolId}", new PartitionKey("Base"));
                 if (tempShool != null)
                 {
-                    List<Period> periods = new List<Period>();
+                    List<Period> periods = new();
                     string campusId = Guid.NewGuid().ToString();
                     //periodS.ForEach(x =>
                     //{
@@ -604,7 +610,7 @@ namespace TEAMModelBI.Controllers.BISchool
 
                     //修改学校教师关联的信息
                     string sql = $"SELECT distinct value(c) FROM c join A1 in c.schools where A1.schoolId='{tempShool.id}'";
-                    List<Teacher> teachers = new List<Teacher>();
+                    List<Teacher> teachers = new();
                     await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
                     {
                         teachers.Add(item);
@@ -625,7 +631,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     {
                         //修改学校顾问
                         string sqlTxt = $"SELECT value(c) From c WHERE ARRAY_CONTAINS(c.roles,'assist',true)";
-                        List<SchoolTeacher> schoolTeachers = new List<SchoolTeacher>();
+                        List<SchoolTeacher> schoolTeachers = new();
                         await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<SchoolTeacher>(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{tempShool.id}") }))
                         {
                             if (!assistId.Contains(item.id))
@@ -674,7 +680,7 @@ namespace TEAMModelBI.Controllers.BISchool
                                     }
                                     else
                                     {
-                                        SchoolTeacher addSchoolTeacher = new SchoolTeacher
+                                        SchoolTeacher addSchoolTeacher = new()
                                         {
                                             id = itemTeacher,
                                             code = $"Teacher-{tempShool.id}",
@@ -692,7 +698,7 @@ namespace TEAMModelBI.Controllers.BISchool
                                 }
                                 else
                                 {
-                                    Teacher.TeacherSchool teacherSchool = new Teacher.TeacherSchool
+                                    Teacher.TeacherSchool teacherSchool = new()
                                     {
                                         schoolId = tempShool.id,
                                         name = tempShool.name,
@@ -706,7 +712,7 @@ namespace TEAMModelBI.Controllers.BISchool
                                     await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(tempTeacher, tempTeacher.id, new PartitionKey($"Base"));
 
                                     //不存在则在原来的基础上添加顾问角色
-                                    SchoolTeacher addSchoolTeacher = new SchoolTeacher
+                                    SchoolTeacher addSchoolTeacher = new()
                                     {
                                         id = itemTeacher,
                                         code = $"Teacher-{tempShool.id}",
@@ -727,7 +733,6 @@ namespace TEAMModelBI.Controllers.BISchool
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("school-update", $"{_tmdName}【{_tmdId}】修改学校功能,修改的学校:{_schoolId},{_type},{picture},{size},{string.Join("|", assistId.ToArray())}", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-update", $"{_tmdName}【{_tmdId}】修改学校功能,修改的学校:{_schoolId},{_type},{picture},{size},{string.Join("|", assistId.ToArray())}", _dingDing, httpContext: HttpContext);
 
                 return Ok(new { state = 200 });
@@ -817,26 +822,6 @@ namespace TEAMModelBI.Controllers.BISchool
 
                 schoolAssist.assists = await CommonFind.FindSchoolRoles(cosmosClient, itemSchool.id, "assist");
 
-                //List<Assist> assists = new List<Assist>();
-                ////查询学校的顾问
-                //string managerSql = $"SELECT DISTINCT REPLACE(c.code, 'Teacher-', '') AS schoolId, c.id, c.name FROM c WHERE ARRAY_CONTAINS(c.roles, 'assist', true) AND c.pk = 'Teacher' AND c.status = 'join' AND c.code = 'Teacher-{itemSchool.id}'";
-                //var cosmosClent = _azureCosmos.GetCosmosClient();
-                //await foreach (var item in cosmosClent.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: managerSql, requestOptions: new QueryRequestOptions() { }))
-                //{
-                //    using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                //    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                //    {
-                //        Assist assist = new Assist
-                //        {
-                //            tmdId = obj.GetProperty("id").GetString(),
-                //            tmdName = obj.GetProperty("name").GetString()
-                //        };
-
-                //        assists.Add(assist);
-                //    }
-                //}
-                //schoolAssist.assists = assists;
-
                 schoolAssists.Add(schoolAssist);
             }
 
@@ -845,6 +830,7 @@ namespace TEAMModelBI.Controllers.BISchool
 
 
         #region   预设学校基础信息 多语言
+
         /// <summary>
         /// 预设学校基础信息 多语言
         /// </summary>
@@ -855,8 +841,8 @@ namespace TEAMModelBI.Controllers.BISchool
         public List<Period> PresetSchoolPeriod(List<string> period, string Language, string campusId)
         {
             var builder = $"{_environment.ContentRootPath}/JsonFile/Preset/LangSchoolConfig.json";
-            StreamReader streamReader = new StreamReader(new FileStream(builder, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8);
-            StringBuilder stringBuilder = new StringBuilder();
+            StreamReader streamReader = new(new FileStream(builder, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8);
+            StringBuilder stringBuilder = new();
             string text;
             while ((text = streamReader.ReadLine()) != null)
             {
@@ -875,7 +861,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("zh-CN"));
             }
 
-            List<Period> periods = new List<Period>();
+            List<Period> periods = new();
             period.ForEach(x =>
             {
                 periods.Add(new Period

+ 2 - 6
TEAMModelBI/Controllers/BISchool/RoomController.cs

@@ -57,7 +57,7 @@ namespace TEAMModelBI.Controllers.BISchool
                 jsonElement.TryGetProperty("site", out JsonElement site);
                 var s = string.IsNullOrEmpty($"{serial}") ? null : $"{serial}";
 
-                Room room = new Room();
+                Room room = new();
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 var tableClient = _azureStorage.GetCloudTableClient();
                 var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
@@ -77,18 +77,14 @@ namespace TEAMModelBI.Controllers.BISchool
 
                     room = await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(roomInfo, $"{roomId}", new PartitionKey($"{roomCode}"));
 
-                    StringBuilder stringBudeler = new StringBuilder($"{_tmdName}【{_tmdId}】将{roomInfo.id}教师和{serial}产品");
+                    StringBuilder stringBudeler = new($"{_tmdName}【{_tmdId}】将{roomInfo.id}教师和{serial}产品");
                     if (!string.IsNullOrEmpty($"{serial}")) { stringBudeler.Append($"绑定。"); } else { stringBudeler.Append($"解绑。"); }
 
                     //保存操作记录
-                    //await _azureStorage.SaveBILog("room-update", $"{_tmdName}【{_tmdId}】将{roomInfo.id}教师和{serial}产品绑定", _dingDing, httpContext: HttpContext);
                     await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "room-update", $"{_tmdName}【{_tmdId}】将{roomInfo.id}教师和{serial}产品绑定", _dingDing, httpContext: HttpContext);
                 }
                 else
-                {
                     return Ok(new { state = 401, msg = "未找到教室" });
-                }
-
                 return Ok(new { state = 200, room });
             }
             catch (Exception ex)

+ 22 - 61
TEAMModelBI/Controllers/BISchool/SchoolController.cs

@@ -121,8 +121,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     {
                         foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                         {
-                            //List<string> temp0 = obj.GetProperty("period").ToObject<List<Period>>().Select(x=>x.name).ToList();
-                            NotAreaSchool notAreaSchool = new NotAreaSchool()
+                            NotAreaSchool notAreaSchool = new()
                             {
                                 id = obj.GetProperty("id").GetString(),
                                 name = obj.GetProperty("name").GetString(),
@@ -151,7 +150,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     }
                 }
 
-                List<NotAreaSchool> notAreaSchools = new List<NotAreaSchool>();
+                List<NotAreaSchool> notAreaSchools = new();
                 tempNotAreaSchools.ForEach(nas =>
                 {
                     if (nas.areas == null)
@@ -270,7 +269,6 @@ namespace TEAMModelBI.Controllers.BISchool
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("school-update", $"{_tmdName}【{_tmdId}】操作学校加入区域功能,加入的区域:{standard},学校ID:{string.Join("|", schoolCodes.ToArray())}", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-update", msg.ToString(), _dingDing, httpContext: HttpContext);
 
                 return Ok(new { state = 200 });
@@ -303,9 +301,7 @@ namespace TEAMModelBI.Controllers.BISchool
                 string sqlTxt = $"select c.id,c.code,c.schoolCode,c.name,c.region,c.province,c.city,c.dist,c.size,c.address,c.picture,c.type,c.scale,c.areaId,c.standard,c.period from c where c.id='{schoolId}'";
                 await foreach (var itemSchool in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<AssistSchool>(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
                 {
-                    //schoolAssists.Add(itemSchool);
                     schoolAssists = itemSchool;
-                    //school = itemSchool;
                 }
 
                 if (schoolAssists.id != null)
@@ -366,13 +362,12 @@ namespace TEAMModelBI.Controllers.BISchool
                     blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
                 }
                 string _auth = HttpContext.GetXAuth("AuthToken");
-                //var (tmdId, tmdName) = HttpJwtAnalysis.JwtXAuth(_auth, _option);
                 var (tmdId, tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(_auth, _option);
                 var response = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school.id, new PartitionKey($"Base"));
                 if (response.Status == 200)
                 {
                     string sql = $"SELECT distinct value(c) FROM c join A1 in c.schools where A1.schoolId='{school.id}'";
-                    List<Teacher> teachers = new List<Teacher>();
+                    List<Teacher> teachers = new();
                     await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Teacher>(sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
                     {
                         teachers.Add(item);
@@ -391,43 +386,11 @@ namespace TEAMModelBI.Controllers.BISchool
                     schoolInfo = await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<School>(school, school.id, new PartitionKey($"Base"));
 
                     //保存操作记录
-                    //await _azureStorage.SaveBILog("school-update", $"{tmdName}【{tmdId}】修改学校信息,学校和ID:{school.name}【{school.id}】", _dingDing, httpContext: HttpContext);
                     await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-update", $"{tmdName}【{tmdId}】修改学校信息,学校和ID:{school.name}【{school.id}】", _dingDing, httpContext: HttpContext);
                 }
                 else return Ok(new { state = 400, message = "请求错误!" });
 
                 return Ok(new { state = 200, schoolInfo });
-
-                //School tempShool = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(replaceSchool.school.id, new PartitionKey("Base"));
-                //if (tempShool != null)
-                //{
-                //    List<Teacher> teachers = new List<Teacher>();
-                //    string sqltxt = $"select distinct value(c) from c join a1 in c.schools where a1.schoolId='{replaceSchool.school.id}'";
-                //    await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sqltxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
-                //    {
-                //        teachers.Add(item);
-                //    }
-
-                //    foreach (var item in teachers)
-                //    {
-                //        Teacher.TeacherSchool teacherSchool = item.schools.Find(x => x.schoolId.Equals(replaceSchool.school.id));
-                //        if (teacherSchool != null)
-                //        {
-                //            teacherSchool.name = replaceSchool.school.name;
-                //            teacherSchool.picture = replaceSchool.school.picture;
-                //            teacherSchool.areaId = replaceSchool.school.areaId;
-                //        }
-                //        await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(item, item.id, new PartitionKey("Base"));
-                //    }
-
-                //    schoolInfo = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(replaceSchool.school, replaceSchool.school.id, new PartitionKey("Base"));
-
-                //    //保存操作记录
-                //    await _azureStorage.SaveBILog("school-update", $"{replaceSchool.tmdName}【{replaceSchool.tmdId}】修改学校信息,学校和ID:{replaceSchool.school.name}【{replaceSchool.school.id}】", _dingDing, httpContext: HttpContext);
-
-                //    return Ok(new { state = 200, schoolInfo });
-                //}
-                //else return Ok(new { state = 400, message = "请求错误!" });
             }
             catch (Exception ex)
             {
@@ -441,6 +404,7 @@ namespace TEAMModelBI.Controllers.BISchool
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-assistspace")]
         public async Task<IActionResult> GetAssistSchoolSpace(JsonElement jsonElement)
         {
@@ -662,6 +626,7 @@ namespace TEAMModelBI.Controllers.BISchool
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-scmanage")]
         public async Task<IActionResult> GetSchoolManage(JsonElement jsonElement)
         {
@@ -789,7 +754,6 @@ namespace TEAMModelBI.Controllers.BISchool
                 await _dingDing.SendBotMsg($"BI,{_option.Location}  /batchschool/set-schoolme \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
                 return BadRequest();
             }
-
         }
 
         /// <summary>
@@ -956,7 +920,6 @@ namespace TEAMModelBI.Controllers.BISchool
                 //}
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("set-del", msg.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "set-del", msg.ToString(), _dingDing, httpContext: HttpContext);
                 if (delSchoolRels.Count > 0)
                     return Ok(new { state = 201, delSchoolRels });
@@ -975,6 +938,7 @@ namespace TEAMModelBI.Controllers.BISchool
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-schoolcnt")]
         public async Task<IActionResult> GetSchoolCnt(JsonElement jsonElement)
         {
@@ -1038,8 +1002,6 @@ namespace TEAMModelBI.Controllers.BISchool
 
                 string currencySql = "select value(count(c.id)) from c";
 
-                //schoolInfo.lessonCount = await CommonFind.GetSqlValueCount(cosmosClient, "School", currencySql,  $"LessonRecord-{schoolInfo.id}");
-
                 tecCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", currencySql, $"Teacher-{schoolInfo.id}"); // 教师数量
                 classCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", currencySql, $"Class-{schoolInfo.id}"); //班级
                 stuCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Student", currencySql, $"Base-{schoolInfo.id}"); //学生
@@ -1086,6 +1048,7 @@ namespace TEAMModelBI.Controllers.BISchool
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-analyse")]
         public async Task<IActionResult> GetAnalyse(JsonElement jsonElement)
         {
@@ -1122,11 +1085,11 @@ namespace TEAMModelBI.Controllers.BISchool
             int lessLastYearCnt = 0; //去年的课例
             int lessYearCnt = 0; //今年的课例
 
-            int allInterCnt = 0;   //所有互动
-            int lastDayInterCnt = 0;   // 昨天课例互动
-            int interCnt = 0;   // 今天课例互动
-            int lastYearInterCnt = 0;   // 去年课例互动
-            int yearInterCnt = 0;   // 今年课例互动
+            double allInterCnt = 0;   //所有互动
+            double lastDayInterCnt = 0;   // 昨天课例互动
+            double interCnt = 0;   // 今天课例互动
+            double lastYearInterCnt = 0;   // 去年课例互动
+            double yearInterCnt = 0;   // 今年课例互动
 
             int allActCnt = 0;    //所有活动
             int lastActCnt = 0;    //昨天活动
@@ -1141,7 +1104,7 @@ namespace TEAMModelBI.Controllers.BISchool
             lessAllCant = await CommonFind.GetSqlValueCount(cosmosClient, "School", commSql, $"LessonRecord-{schoolId}");
 
             string lessCode = $"LessonRecord-{schoolId}";
-            string lessLastdaySql = $"{commSql} where c.startTime >= {lastDays} and c.startTime <= {lastDays} ";
+            string lessLastdaySql = $"{commSql} where c.startTime >= {lastDays} and c.startTime <= {lastDaye} ";
             lessLastdayCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", lessLastdaySql, lessCode);
 
             string lessDaySql = $"{commSql} where c.startTime >= {days} and c.startTime <= {daye} ";
@@ -1155,19 +1118,19 @@ namespace TEAMModelBI.Controllers.BISchool
 
             //课例互动
             string strInterSql = $"select value(sum(c.clientInteractionAverge)) from c";
-            allInterCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", strInterSql, lessCode);
+            allInterCnt = await CommonFind.GetSqlValueDoubleCounnt(cosmosClient, "School", strInterSql, lessCode);
 
             string lastdayInterSql = $"{strInterSql} where c.startTime >= { lastDays} and c.startTime <= {lastDays} ";
-            lastDayInterCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", lastdayInterSql, lessCode);
+            lastDayInterCnt = await CommonFind.GetSqlValueDoubleCounnt(cosmosClient, "School", lastdayInterSql, lessCode);
 
             string dayInterSql = $"{strInterSql} where c.startTime >= { days} and c.startTime <= {daye} ";
-            interCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", dayInterSql, lessCode);
+            interCnt = await CommonFind.GetSqlValueDoubleCounnt(cosmosClient, "School", dayInterSql, lessCode);
 
             string lastYarInterSql = $"{strInterSql} where c.startTime >= { lastYears} and c.startTime <= {lastYeare} ";
-            lastYearInterCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", lastYarInterSql, lessCode);
+            lastYearInterCnt = await CommonFind.GetSqlValueDoubleCounnt(cosmosClient, "School", lastYarInterSql, lessCode);
 
             string yearInterSql = $"{strInterSql} where c.startTime >= { years} and c.startTime <= {yeare} ";
-            yearInterCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", yearInterSql, lessCode);
+            yearInterCnt = await CommonFind.GetSqlValueDoubleCounnt(cosmosClient, "School", yearInterSql, lessCode);
 
             //活动
             allActCnt = await ActivityWay.GetCnt(cosmosClient, condSql: $"and c.school='{schoolId}'");
@@ -1192,6 +1155,7 @@ namespace TEAMModelBI.Controllers.BISchool
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-schooldate")]
         public async Task<IActionResult> GetSchoolDate(JsonElement jsonElement)
         {
@@ -1426,7 +1390,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     yearCnt.lessCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", selessSql);
 
                     string interactSql = $"select value(sum(c.clientInteractionAverge)) from c where c.pk='LessonRecord' and {scSql} and c.startTime >= { item.start} and c.startTime <= {item.end}";
-                    yearCnt.interCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", interactSql);
+                    yearCnt.interCnt = await CommonFind.GetSqlValueDoubleCounnt(cosmosClient, "School", interactSql);
 
                     string mthActSql = $"and {scSql} and c.createTime >= {item.start} and c.createTime <= {item.end}";
                     yearCnt.actCnt = await ActivityWay.GetCnt(cosmosClient, condSql: mthActSql);
@@ -1685,14 +1649,13 @@ namespace TEAMModelBI.Controllers.BISchool
             var productAn = products.GroupBy(g => g).Select(s => new { key = s.Key, cnt = s.ToList().Count }).ToList();
 
             return Ok(new { state = RespondCode.Ok, allCnt, adCnt, scInfos, productAn });
-            // var productAn = products.GroupBy(x => x).Select(y => new { key = y.Key, count = y.ToList().Count }).ToList();
-
         }
 
         /// <summary>
         /// 通过学校Id查询详情   数据管理工具——查询工具
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetSchool(JsonElement jsonElement)
         {
@@ -1803,7 +1766,6 @@ namespace TEAMModelBI.Controllers.BISchool
                             catalog.Add(key, val);
                         }
                         useSpaceInfo = useSpaceInfo.Concat(catalog).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value));  //lamebda表达式
-                        //useSpaceInfo = (from e in useSpaceInfo.Concat(catalog) group e by e.Key into g select new { Name = g.Key, value = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.Name, item => item.value);  //linq 方式合并
                     }
                     else
                     {
@@ -1817,7 +1779,6 @@ namespace TEAMModelBI.Controllers.BISchool
                         }
                         useSize += size.Item1.Value;
                         useSpaceInfo = useSpaceInfo.Concat(size.Item2).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value));   //lamebda表达式
-                        //useSpaceInfo = (from e in useSpaceInfo.Concat(size.Item2) group e by e.Key into g select new { Name = g.Key, value = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.Name, item => item.value);   //linq 方式合并
                     }
                 }
             }
@@ -1889,6 +1850,7 @@ namespace TEAMModelBI.Controllers.BISchool
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-shift")]
         public async Task<IActionResult> GetShift(JsonElement jsonElement)
         {
@@ -1946,7 +1908,6 @@ namespace TEAMModelBI.Controllers.BISchool
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("schoolTeacher-add", $"{_tmdName}【{_tmdId}】移交顾问给{newSchoolTeacher.name}【{newSchoolTeacher.id}】", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "schoolTeacher-add", $"{_tmdName}【{_tmdId}】移交顾问给{newSchoolTeacher.name}【{newSchoolTeacher.id}】", _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200 });
             }

+ 5 - 4
TEAMModelBI/Controllers/BIStudent/StudentController.cs

@@ -46,7 +46,7 @@ namespace TEAMModelBI.Controllers.BIStudent
             var cosmosClient = _azureCosmos.GetCosmosClient();
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            List<object> objs = new List<object>();
+            List<object> objs = new();
             await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.id='{studentId}'", requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
             {
                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
@@ -67,6 +67,7 @@ namespace TEAMModelBI.Controllers.BIStudent
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-classIds")]
         public async Task<IActionResult> CorrectActivityClassIds(JsonElement jsonElement)
         {
@@ -80,7 +81,7 @@ namespace TEAMModelBI.Controllers.BIStudent
 
                 //string sqlTxt = "SELECT select c.id,c.code,c.classIds FROM c  where c.pk='Activity' and c.classIds <> []";
                 string sqlTxt = "select c.id,c.code,c.classIds from c where c.school='cswznb' and c.classIds <> []";
-                List<CorrectStu> correctStus = new List<CorrectStu>();
+                List<CorrectStu> correctStus = new();
                 await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
@@ -93,10 +94,10 @@ namespace TEAMModelBI.Controllers.BIStudent
 
                         //List<string> newList = templist.Distinct().ToList(); //Equals实现去重  
                         //List<string> newLis1 = templist.Where((x, i) => templist.FindIndex(z => z == x) == i).ToList(); //Lambda表达式去重 
-                        HashSet<string> hashSet = new HashSet<string>(templist);//哈希自动去重
+                        HashSet<string> hashSet = new(templist);//哈希自动去重
                         if (hashSet.Count != templist.Count)
                         {
-                            CorrectStu correctList = new CorrectStu() { id = $"{tempTd}", code = $"{code}", classIds = hashSet.ToList() };
+                            CorrectStu correctList = new() { id = $"{tempTd}", code = $"{code}", classIds = hashSet.ToList() };
                             correctStus.Add(correctList);
                         }
                     }

+ 0 - 2
TEAMModelBI/Controllers/BITable/BIOpenApiController.cs

@@ -135,7 +135,6 @@ namespace TEAMModelBI.Controllers.BITable
                     else return Ok(new { state = 404, msg = "未找到该id相关的Api信息" });
                 }
                 //保存操作记录
-                //await _azureStorage.SaveBILog(type, strMsg.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, type, strMsg.ToString(), _dingDing, httpContext: HttpContext);
                 
                 return Ok(new { state = 200, openApi });
@@ -147,7 +146,6 @@ namespace TEAMModelBI.Controllers.BITable
             }
         }
 
-
         public record ReadApi
         {
             public string id { get; set; }

+ 27 - 27
TEAMModelBI/Controllers/BITable/DDStructController.cs

@@ -64,8 +64,8 @@ namespace TEAMModelBI.Controllers.BITable
                 string appSecret = _configuration["DingDingAuth:appSecret"];
 
                 //获取access_token
-                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-                OapiGettokenRequest request = new OapiGettokenRequest();
+                DefaultDingTalkClient client = new("https://oapi.dingtalk.com/gettoken");
+                OapiGettokenRequest request = new();
                 request.Appkey = appKey;
                 request.Appsecret = appSecret;
                 request.SetHttpMethod("Get");
@@ -95,7 +95,7 @@ namespace TEAMModelBI.Controllers.BITable
 
                         //获取一级部门用户列表
                         IDingTalkClient userListClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
-                        OapiUserListidRequest reqUserList1 = new OapiUserListidRequest() { DeptId = deptList.DeptId };
+                        OapiUserListidRequest reqUserList1 = new() { DeptId = deptList.DeptId };
                         OapiUserListidResponse rspUserList1 = userListClient1.Execute(reqUserList1, access_token);
                         if (rspUserList1.Result != null)
                         {
@@ -104,26 +104,26 @@ namespace TEAMModelBI.Controllers.BITable
 
                         //获取用户详细信息
                         IDingTalkClient v2UserListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
-                        OapiV2UserGetRequest reqv2UserList = new OapiV2UserGetRequest();
+                        OapiV2UserGetRequest reqv2UserList = new();
                         OapiV2UserGetResponse rspv2UserList = v2UserListClient.Execute(reqv2UserList, access_token);
 
                         //获取二级部门列表
-                        OapiV2DepartmentListsubRequest reqlistsub = new OapiV2DepartmentListsubRequest() { DeptId = deptList.DeptId, Language = "zh_CN" };
+                        OapiV2DepartmentListsubRequest reqlistsub = new() { DeptId = deptList.DeptId, Language = "zh_CN" };
                         OapiV2DepartmentListsubResponse rsplistsub = v2ListsubClient1.Execute(reqlistsub, access_token);
 
-                        List<DeptBaseResponseDomain> deptBaseResponseDomainList = new List<DeptBaseResponseDomain>();
+                        List<DeptBaseResponseDomain> deptBaseResponseDomainList = new();
                         if (rsplistsub.Result != null)
                         {
                             foreach (var deptlist2 in rsplistsub.Result)
                             {
                                 //添加二级部门
-                                DeptBaseResponseDomain deptBaseResponseDomain2 = new DeptBaseResponseDomain();
+                                DeptBaseResponseDomain deptBaseResponseDomain2 = new();
                                 deptBaseResponseDomain2.deptId = deptlist2.DeptId;
                                 deptBaseResponseDomain2.Name = deptlist2.Name;
                                 deptBaseResponseDomain2.ParentId = deptlist2.ParentId;
 
                                 //获取三级部门用户列表
-                                OapiUserListidRequest reqUserList2 = new OapiUserListidRequest() { DeptId = deptlist2.DeptId };
+                                OapiUserListidRequest reqUserList2 = new() { DeptId = deptlist2.DeptId };
                                 OapiUserListidResponse rspUserList2 = userListClient1.Execute(reqUserList2, access_token);
                                 if (rspUserList2.Result != null)
                                 {
@@ -131,23 +131,23 @@ namespace TEAMModelBI.Controllers.BITable
                                     deptBaseResponseDomain2.ddUserList = rspUserList2.Result.UseridList;
                                 }
                                 //获取三级部门列表
-                                OapiV2DepartmentListsubRequest reqlistsub3 = new OapiV2DepartmentListsubRequest() { DeptId = deptlist2.DeptId, Language = "zh_CN" };
+                                OapiV2DepartmentListsubRequest reqlistsub3 = new() { DeptId = deptlist2.DeptId, Language = "zh_CN" };
                                 OapiV2DepartmentListsubResponse rsplistsub3 = v2ListsubClient1.Execute(reqlistsub3, access_token);
 
-                                List<DeptBaseResponseDomain> deptBaseResponseDomain3List = new List<DeptBaseResponseDomain>();
+                                List<DeptBaseResponseDomain> deptBaseResponseDomain3List = new();
 
                                 if (rsplistsub3.Result != null)
                                 {
                                     foreach (var dept3List in rsplistsub3.Result)
                                     {
                                         //添加三级部门
-                                        DeptBaseResponseDomain deptBaseResponseDomain3 = new DeptBaseResponseDomain();
+                                        DeptBaseResponseDomain deptBaseResponseDomain3 = new();
                                         deptBaseResponseDomain3.deptId = dept3List.DeptId;
                                         deptBaseResponseDomain3.Name = dept3List.Name;
                                         deptBaseResponseDomain3.ParentId = dept3List.ParentId;
 
                                         //获取部门用户列表
-                                        OapiUserListidRequest reqUserList3 = new OapiUserListidRequest() { DeptId = dept3List.DeptId };
+                                        OapiUserListidRequest reqUserList3 = new() { DeptId = dept3List.DeptId };
                                         OapiUserListidResponse rspUserList3 = userListClient1.Execute(reqUserList3, access_token);
                                         if (rspUserList3.Result != null)
                                         {
@@ -156,23 +156,23 @@ namespace TEAMModelBI.Controllers.BITable
                                         }
 
                                         //获取部门列表  四级目录
-                                        OapiV2DepartmentListsubRequest reqlistsub4 = new OapiV2DepartmentListsubRequest() { DeptId = dept3List.DeptId, Language = "zh_CN" };
+                                        OapiV2DepartmentListsubRequest reqlistsub4 = new() { DeptId = dept3List.DeptId, Language = "zh_CN" };
                                         OapiV2DepartmentListsubResponse rsplistsu4 = v2ListsubClient1.Execute(reqlistsub4, access_token);
 
-                                        List<DeptBaseResponseDomain> deptBaseResponseDomain4List = new List<DeptBaseResponseDomain>();
+                                        List<DeptBaseResponseDomain> deptBaseResponseDomain4List = new();
                                         if (rsplistsu4.Result != null)
                                         {
 
                                             foreach (var dept4List in rsplistsu4.Result)
                                             {
-                                                DeptBaseResponseDomain deptBaseResponseDomain4 = new DeptBaseResponseDomain();
+                                                DeptBaseResponseDomain deptBaseResponseDomain4 = new();
                                                 deptBaseResponseDomain4.deptId = dept4List.DeptId;
                                                 deptBaseResponseDomain4.Name = dept4List.Name;
                                                 deptBaseResponseDomain4.ParentId = dept4List.ParentId;
                                                 deptBaseResponseDomain4List.Add(deptBaseResponseDomain4);
 
                                                 //获取四级部门用户列表
-                                                OapiUserListidRequest reqUserList4 = new OapiUserListidRequest() { DeptId = dept4List.DeptId };
+                                                OapiUserListidRequest reqUserList4 = new() { DeptId = dept4List.DeptId };
                                                 OapiUserListidResponse rspUserList4 = userListClient1.Execute(reqUserList4, access_token);
                                                 if (rspUserList4.Result != null)
                                                 {
@@ -340,7 +340,7 @@ namespace TEAMModelBI.Controllers.BITable
                     {
                         foreach (var tempDept in rspDeptLis2.Result)
                         {
-                            OapiV2UserListRequest reqUserList2 = new OapiV2UserListRequest();
+                            OapiV2UserListRequest reqUserList2 = new();
                             reqUserList2.DeptId = long.Parse($"{tempDept.DeptId}");
                             reqUserList2.Cursor = 0L;
                             reqUserList2.Size = 50L;
@@ -356,7 +356,7 @@ namespace TEAMModelBI.Controllers.BITable
                                     var tempInfo = dDAndTmdInfos.Find(x => x.unionid.Equals(itemUser2.Unionid));
                                     if (string.IsNullOrEmpty($"{tempInfo}"))
                                     {
-                                        DDUserInfoAndTMD dDAndTmdInfo2 = new DDUserInfoAndTMD();
+                                        DDUserInfoAndTMD dDAndTmdInfo2 = new();
                                         dDAndTmdInfo2.unionid = itemUser2.Unionid;
                                         dDAndTmdInfo2.userid = itemUser2.Userid;
                                         dDAndTmdInfo2.title = itemUser2.Title;
@@ -451,8 +451,8 @@ namespace TEAMModelBI.Controllers.BITable
 
 
                 //获取access_token
-                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-                OapiGettokenRequest request = new OapiGettokenRequest();
+                DefaultDingTalkClient client = new("https://oapi.dingtalk.com/gettoken");
+                OapiGettokenRequest request = new();
                 request.Appkey = appKey;
                 request.Appsecret = appSecret;
                 request.SetHttpMethod("Get");
@@ -466,7 +466,7 @@ namespace TEAMModelBI.Controllers.BITable
                 string access_token = response.AccessToken;
                 IDingTalkClient userInfoClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
 
-                Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", "authority-bi" } };
+                Dictionary<string, object> dic = new() { { "PartitionKey", "authority-bi" } };
                 var table = _azureStorage.GetCloudTableClient().GetTableReference("SchoolSetting");
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 if ($"{site}".Equals(BIConst.Global)) 
@@ -484,14 +484,14 @@ namespace TEAMModelBI.Controllers.BITable
                     List<string> str_userids = str_userids1.Where((x, i) => str_userids1.FindIndex(z => z == x) == i).ToList();//Lambda表达式去重 
                     foreach (var tempid in str_userids)
                     {
-                        OapiV2UserGetRequest reqUserInfo = new OapiV2UserGetRequest() { Userid = $"{tempid}", Language = "zh_CN" };                        
+                        OapiV2UserGetRequest reqUserInfo = new() { Userid = $"{tempid}", Language = "zh_CN" };                        
                         OapiV2UserGetResponse rspUserInfo = userInfoClient.Execute(reqUserInfo, access_token);
                         if (rspUserInfo.Result != null)
                         {
-                            List<string> roles = new List<string>();//角色列表
-                            List<string> power = new List<string>();//权限列表
+                            List<string> roles = new();//角色列表
+                            List<string> power = new();//权限列表
 
-                            DDUserInfoAndTMD dDUserInfoAndTMD = new DDUserInfoAndTMD();
+                            DDUserInfoAndTMD dDUserInfoAndTMD = new();
                             dDUserInfoAndTMD.unionid = rspUserInfo.Result.Unionid;
                             dDUserInfoAndTMD.title = rspUserInfo.Result.Title;
                             dDUserInfoAndTMD.userid = rspUserInfo.Result.Userid;
@@ -577,7 +577,7 @@ namespace TEAMModelBI.Controllers.BITable
 
             //获取企业内部应用的accessToken
             IDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-            OapiGettokenRequest request = new OapiGettokenRequest();
+            OapiGettokenRequest request = new();
             request.Appkey = str_appKey;
             request.Appsecret = str_appSecret;
             request.SetHttpMethod("GET");
@@ -587,7 +587,7 @@ namespace TEAMModelBI.Controllers.BITable
                 return Ok(new { state = 0, message = "请检查配置" });
             }
             IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/org/union/branch/get");
-            OapiOrgUnionBranchGetRequest req = new OapiOrgUnionBranchGetRequest();
+            OapiOrgUnionBranchGetRequest req = new();
             OapiOrgUnionBranchGetResponse rsp = client.Execute(req, tokenResponse.AccessToken);
 
             return Ok(new { Result = rsp.Result, Body = rsp.Body, RequestId = rsp.RequestId, SubErrCode = rsp.SubErrCode, Success = rsp.Success });

+ 3 - 3
TEAMModelBI/Controllers/BITable/OperateLogController.cs

@@ -40,6 +40,7 @@ namespace TEAMModelBI.Controllers.BITable
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-record")]
         public async Task<IActionResult> GetOperateLogRecord(JsonElement jsonElement)
         {
@@ -110,8 +111,8 @@ namespace TEAMModelBI.Controllers.BITable
 
                 var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
                 //var temp = await _azureStorage.Delete<OperateLog>(partitionKey: "OperateLog-BI", rowKey: $"{startDate}");  //删除单个
-                StringBuilder operateStr = new StringBuilder($"{_tmdName}【{_tmdId}】账户删除操作记录,");
-                StringBuilder tableStrWhere = new StringBuilder();
+                StringBuilder operateStr = new($"{_tmdName}【{_tmdId}】账户删除操作记录,");
+                StringBuilder tableStrWhere = new();
                 if (!string.IsNullOrEmpty($"{rowKey}"))
                 {
                     tableStrWhere.Append($"RowKey {QueryComparisons.Equal} '{rowKey}'");
@@ -134,7 +135,6 @@ namespace TEAMModelBI.Controllers.BITable
                 var temp = await table.DeleteStringWhere<BIOptLog>(rowKey: tableStrWhere.ToString());
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("operatelog-del", operateStr?.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "operatelog-del", operateStr?.ToString(), _dingDing, httpContext: HttpContext);
 
                 if (temp.Count > 0)

+ 23 - 116
TEAMModelBI/Controllers/BITable/TableDingDingInfoController.cs

@@ -91,7 +91,7 @@ namespace TEAMModelBI.Controllers.BITable
 
                 //获取access_token
                 IDingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-                OapiGettokenRequest tokenRequest = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+                OapiGettokenRequest tokenRequest = new() { Appkey = appKey, Appsecret = appSecret };
                 tokenRequest.SetHttpMethod("Get");
                 OapiGettokenResponse tokenRespone = tokenClient.Execute(tokenRequest);
                 if (tokenRespone.IsError)
@@ -104,7 +104,7 @@ namespace TEAMModelBI.Controllers.BITable
                 //获取部门接口
                 IDingTalkClient deptListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
                 //一级部门
-                OapiV2DepartmentListsubRequest reqDeptList1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
+                OapiV2DepartmentListsubRequest reqDeptList1 = new() { DeptId = 1L, Language = "zh_CN" };
                 OapiV2DepartmentListsubResponse rspDeptList1 = deptListClient.Execute(reqDeptList1, access_token);
 
                 List<DingDingUserInfo> ddUserInfos = new();
@@ -119,7 +119,7 @@ namespace TEAMModelBI.Controllers.BITable
                         if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(dingDingUserInfos1);
 
                         //获取二级部门
-                        OapiV2DepartmentListsubRequest reqDeptList2 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
+                        OapiV2DepartmentListsubRequest reqDeptList2 = new() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
                         OapiV2DepartmentListsubResponse rspDeptList2 = deptListClient.Execute(reqDeptList2, access_token);
                         if (rspDeptList2.Result != null)
                         {
@@ -131,7 +131,7 @@ namespace TEAMModelBI.Controllers.BITable
                                 if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(dingDingUserInfos2);
 
                                 //获取三级部门
-                                OapiV2DepartmentListsubRequest reqDeptList3 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
+                                OapiV2DepartmentListsubRequest reqDeptList3 = new() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
                                 OapiV2DepartmentListsubResponse rspDeptList3 = deptListClient.Execute(reqDeptList3, access_token);
                                 if (rspDeptList3.Result != null)
                                 {
@@ -143,7 +143,7 @@ namespace TEAMModelBI.Controllers.BITable
                                         if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(dingDingUserInfos3);
 
                                         //获取四级部门
-                                        OapiV2DepartmentListsubRequest reqDeptList4 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
+                                        OapiV2DepartmentListsubRequest reqDeptList4 = new() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
                                         OapiV2DepartmentListsubResponse rspDeptList4 = deptListClient.Execute(reqDeptList4, access_token);
                                         if (rspDeptList4.Result != null)
                                         {
@@ -155,7 +155,7 @@ namespace TEAMModelBI.Controllers.BITable
                                                 if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(dingDingUserInfos4);
 
                                                 //获取五级部门
-                                                OapiV2DepartmentListsubRequest reqDeptList5 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
+                                                OapiV2DepartmentListsubRequest reqDeptList5 = new() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
                                                 OapiV2DepartmentListsubResponse rspDeptList5 = deptListClient.Execute(reqDeptList5, access_token);
                                                 if (rspDeptList5.Result != null)
                                                 {
@@ -178,7 +178,6 @@ namespace TEAMModelBI.Controllers.BITable
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构更新至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构更新至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
                 var tempddUserInfos = ddUserInfos.GroupBy(c => c.userId).Select(c => c.First()).ToList();//去重
                 //List<DingDingUserInfo> TempdingDingUserInfos = await _azureStorage.SaveOrUpdateAll(dingDingUserInfos);  //只是保存至Table
@@ -401,7 +400,6 @@ namespace TEAMModelBI.Controllers.BITable
                 ddUserInfo = await table.UpdateAll<DingDingUserInfo>(ddUserInfo);
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("tabledd-update", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200, ddUserInfo, roles, permissions });
             }
@@ -439,7 +437,7 @@ namespace TEAMModelBI.Controllers.BITable
                 var table = tableClient.GetTableReference("BIDDUserInfo");
                 //string divide = _configuration["CustomParam:SiteScope"];
                 string divide = _option.Location;
-                Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" } };
+                Dictionary<string, object> dic = new() { { "PartitionKey", $"{divide}" } };
 
                 List<DingDingUserInfo> tempUserInfos = await table.FindListByDict<DingDingUserInfo>(dic);
 
@@ -459,65 +457,6 @@ namespace TEAMModelBI.Controllers.BITable
                 userInfo.Where((x, i) => userInfo.FindIndex(z => z.RowKey.Equals(x.RowKey)) == i);//Lambda表达式去重
                 //userInfo.GroupBy(p => p).Select(p => p.Key).ToList();//去重复
 
-                //List<DingDingUserInfo> ddUserInfo = new();
-                //List<DingDingUserInfo> tempUser = new();
-
-                //tempUser = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "deptId", $"{deptId}" } });
-                //if (tempUser.Count == 0)
-                //{
-                //    tempUser = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{deptId}" } });
-                //}
-
-                //foreach (var itemUser in tempUser)
-                //{
-                //    var tempUser1 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{deptId}" } });
-                //    foreach (var itemUser1 in tempUser1)
-                //    {
-                //        if (!long.Parse($"{deptId}").Equals(itemUser1.pid))
-                //        {
-                //            var tempUser2 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{itemUser1.pid}" } });
-                //            foreach (var itemUser2 in tempUser2)
-                //            {
-                //                if (!itemUser1.pid.Equals(itemUser2.pid))
-                //                {
-                //                    var tempUser3 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{itemUser2.pid}" } });
-                //                    foreach (var itemUser3 in tempUser3)
-                //                    {
-                //                        if (!itemUser2.pid.Equals(itemUser3.pid))
-                //                        {
-                //                            var tempUser4 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{itemUser3.pid}" } });
-                //                            foreach (var itemUser4 in tempUser4)
-                //                            {
-                //                                if (!itemUser3.pid.Equals(itemUser4.pid)) { }
-                //                                if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser4.RowKey)) == null)
-                //                                {
-                //                                    ddUserInfo.Add(itemUser4);
-                //                                }
-                //                            }
-                //                        }
-                //                        if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser3.RowKey)) == null)
-                //                        {
-                //                            ddUserInfo.Add(itemUser3);
-                //                        }
-                //                    }
-                //                }
-                //                if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser2.RowKey)) == null)
-                //                {
-                //                    ddUserInfo.Add(itemUser2);
-                //                }
-                //            }
-                //        }
-                //        if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser1.RowKey)) == null)
-                //        {
-                //            ddUserInfo.Add(itemUser1);
-                //        }
-                //    }
-                //    if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser.RowKey)) == null)
-                //    {
-                //        ddUserInfo.Add(itemUser);
-                //    }
-                //}
-
                 List<DDUserInfo> ddUserInfos = new();
                 foreach (var item in userInfo)
                 {
@@ -552,7 +491,7 @@ namespace TEAMModelBI.Controllers.BITable
 
                     if (!string.IsNullOrEmpty(item.schoolIds))
                     {
-                        List<string> tempSchoolIds = new List<string>(item.schoolIds.Split("|"));
+                        List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
                         tempUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
                     }
                     ddUserInfos.Add(tempUserInfo);
@@ -607,7 +546,7 @@ namespace TEAMModelBI.Controllers.BITable
                 //string divide = _configuration["CustomParam:SiteScope"];
                 string divide = _option.Location;
 
-                Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" }, { "mobile", $"{mobile}" } };
+                Dictionary<string, object> dic = new() { { "PartitionKey", $"{divide}" }, { "mobile", $"{mobile}" } };
                 List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
 
                 if (ddUserInfoList.Count > 0)
@@ -678,7 +617,7 @@ namespace TEAMModelBI.Controllers.BITable
 
                         if (!string.IsNullOrEmpty(respUser.schoolIds))
                         {
-                            List<string> tempSchoolIds = new List<string>(respUser.schoolIds.Split("|"));
+                            List<string> tempSchoolIds = new(respUser.schoolIds.Split("|"));
                             dDUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
                         }
                         ddUserInfos.Add(dDUserInfo);
@@ -711,7 +650,6 @@ namespace TEAMModelBI.Controllers.BITable
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("tabledd-update",msg.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200, ddUserInfos });
             }
@@ -820,7 +758,6 @@ namespace TEAMModelBI.Controllers.BITable
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200, roles });
 
@@ -865,7 +802,7 @@ namespace TEAMModelBI.Controllers.BITable
 
                 //获取access_token
                 IDingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-                OapiGettokenRequest tokenRequest = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+                OapiGettokenRequest tokenRequest = new() { Appkey = appKey, Appsecret = appSecret };
                 tokenRequest.SetHttpMethod("Get");
                 OapiGettokenResponse tokenRespone = tokenClient.Execute(tokenRequest);
                 if (tokenRespone.IsError)
@@ -878,7 +815,7 @@ namespace TEAMModelBI.Controllers.BITable
                 //获取部门接口
                 IDingTalkClient deptListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
                 //一级部门
-                OapiV2DepartmentListsubRequest reqDeptList1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
+                OapiV2DepartmentListsubRequest reqDeptList1 = new() { DeptId = 1L, Language = "zh_CN" };
                 OapiV2DepartmentListsubResponse rspDeptList1 = deptListClient.Execute(reqDeptList1, access_token);
 
                 List<DingDingUserInfo> ddUserInfos = new();
@@ -893,7 +830,7 @@ namespace TEAMModelBI.Controllers.BITable
                         if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(dingDingUserInfos1);
 
                         //获取二级部门
-                        OapiV2DepartmentListsubRequest reqDeptList2 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
+                        OapiV2DepartmentListsubRequest reqDeptList2 = new() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
                         OapiV2DepartmentListsubResponse rspDeptList2 = deptListClient.Execute(reqDeptList2, access_token);
                         if (rspDeptList2.Result != null)
                         {
@@ -905,7 +842,7 @@ namespace TEAMModelBI.Controllers.BITable
                                 if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(dingDingUserInfos2);
 
                                 //获取三级部门
-                                OapiV2DepartmentListsubRequest reqDeptList3 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
+                                OapiV2DepartmentListsubRequest reqDeptList3 = new() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
                                 OapiV2DepartmentListsubResponse rspDeptList3 = deptListClient.Execute(reqDeptList3, access_token);
                                 if (rspDeptList3.Result != null)
                                 {
@@ -917,7 +854,7 @@ namespace TEAMModelBI.Controllers.BITable
                                         if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(dingDingUserInfos3);
 
                                         //获取四级部门
-                                        OapiV2DepartmentListsubRequest reqDeptList4 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
+                                        OapiV2DepartmentListsubRequest reqDeptList4 = new() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
                                         OapiV2DepartmentListsubResponse rspDeptList4 = deptListClient.Execute(reqDeptList4, access_token);
                                         if (rspDeptList4.Result != null)
                                         {
@@ -929,7 +866,7 @@ namespace TEAMModelBI.Controllers.BITable
                                                 if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(dingDingUserInfos4);
 
                                                 //获取五级部门
-                                                OapiV2DepartmentListsubRequest reqDeptList5 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
+                                                OapiV2DepartmentListsubRequest reqDeptList5 = new() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
                                                 OapiV2DepartmentListsubResponse rspDeptList5 = deptListClient.Execute(reqDeptList5, access_token);
                                                 if (rspDeptList5.Result != null)
                                                 {
@@ -952,8 +889,7 @@ namespace TEAMModelBI.Controllers.BITable
                 }
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构更新至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
-                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构更新至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
+                await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构初始化至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
                 var tempddUserInfos = ddUserInfos.GroupBy(c => c.userId).Select(c => c.First()).ToList();//去重
                 //List<DingDingUserInfo> TempdingDingUserInfos = await _azureStorage.SaveOrUpdateAll(dingDingUserInfos);  //只是保存至Table
                 //查询数据的数据 并和钉钉查询的数据对比,找出不同的数据,并删除  待后期测试
@@ -1037,28 +973,6 @@ namespace TEAMModelBI.Controllers.BITable
                     picture = coreUser.picture;
                 }else return Ok(new { state = 1, message = "该手机号未找到醍摩豆账户" });
 
-                //HttpClient httpClient = _http.CreateClient();
-                //string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
-                //List<string> mobiles = new List<string>() { $"{mobile}" };
-                //HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(url, mobiles);
-                //if (responseMessage.StatusCode == HttpStatusCode.OK)
-                //{
-                //    string temp = responseMessage.Content.ReadAsStringAsync().Result;
-                //    List<JsonElement> json_id = temp.ToObject<List<JsonElement>>();
-                //    if (json_id.Count > 0)
-                //    {
-                //        foreach (var item in json_id)
-                //        {
-                //            tmdId = item.GetProperty("id").ToString();
-                //            tmdName = item.GetProperty("name").ToString();
-                //            tmdMobile = item.GetProperty("mobile").ToString();
-                //            mail = item.GetProperty("mail").ToString();
-                //            picture = item.GetProperty("picture").ToString();
-                //        }
-                //    }
-                //    else return Ok(new { state = 1, message = "该手机号未找到醍摩豆账户" });
-                //}
-
                 tempddUsers = await table.QueryWhereString<DingDingUserInfo>(tableSql.ToString());
 
                 if (tempddUsers.Count > 0)
@@ -1081,7 +995,6 @@ namespace TEAMModelBI.Controllers.BITable
                 if (ddUsers.Count > 0) ddUsers = await table.SaveOrUpdateAll(ddUsers);
 
                 //保存操作记录
-                //await _azureStorage.SaveBILog("tabledd-update", $"{_tmdName}【{_tmdId}】操作:绑定钉钉账户[{rowKey}]和醍摩豆账户[{tmdId}]", _dingDing, httpContext: HttpContext);
                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】操作:绑定钉钉账户[{rowKey}]和醍摩豆账户[{tmdId}]", _dingDing, httpContext: HttpContext);
                 return Ok(new { state = 200, ddUsers });
             }
@@ -1097,6 +1010,7 @@ namespace TEAMModelBI.Controllers.BITable
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("set-apiphoneadmin")]
         public async Task<IActionResult> SetPhoneAdmin(JsonElement jsonElement) 
         {
@@ -1151,7 +1065,6 @@ namespace TEAMModelBI.Controllers.BITable
             }
 
             //保存操作记录
-            //await _azureStorage.SaveBILog("tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
             await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
             return Ok(new { state = 200, roles });
         }
@@ -1231,7 +1144,7 @@ namespace TEAMModelBI.Controllers.BITable
 
                 //获取access_token
                 IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-                OapiGettokenRequest request = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+                OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
                 request.SetHttpMethod("Get");
                 OapiGettokenResponse response = client.Execute(request);
                 if (response.IsError)
@@ -1243,15 +1156,15 @@ namespace TEAMModelBI.Controllers.BITable
                 string access_token = response.AccessToken;
 
                 IDingTalkClient InductionClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querypreentry");
-                OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new OapiSmartworkHrmEmployeeQuerypreentryRequest() { Offset = 0L, Size = 50 };
+                OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new() { Offset = 0L, Size = 50 };
                 reqInduction.SetHttpMethod("GET");
                 OapiSmartworkHrmEmployeeQuerypreentryResponse rspInduction = InductionClient.Execute(reqInduction, access_token);
                 if (rspInduction.Result.DataList != null)
                 {
-                    List<DingDingUserInfo> ddUserInfos = new List<DingDingUserInfo>();
+                    List<DingDingUserInfo> ddUserInfos = new();
                     foreach (var itemId in rspInduction.Result.DataList)
                     {
-                        DingDingUserInfo ddUserInfo = new DingDingUserInfo();
+                        DingDingUserInfo ddUserInfo = new();
                         ddUserInfo.PartitionKey = divide;
                         ddUserInfo.RowKey = itemId;
                         ddUserInfos.Add(ddUserInfo);
@@ -1260,12 +1173,9 @@ namespace TEAMModelBI.Controllers.BITable
                     List<DingDingUserInfo> tempddUserInfos = await table.SaveAll(ddUserInfos);
 
                     //保存操作记录
-                    //await _azureStorage.SaveBILog("tabledd-add", $"{_tmdName}【{_tmdId}】添加待入职员工至table数据表中", _dingDing, httpContext: HttpContext);
                     await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-add", $"{_tmdName}【{_tmdId}】添加待入职员工至table数据表中", _dingDing, httpContext: HttpContext);
                     if (ddUserInfos.Count == tempddUserInfos.Count)
-                    {
                         return Ok(new { state = 200, UserInfo = tempddUserInfos });
-                    }
                     else
                     {
                         var diffArr = tempddUserInfos.Where(c => !ddUserInfos.Contains(c)).ToList();
@@ -1273,9 +1183,7 @@ namespace TEAMModelBI.Controllers.BITable
                     }
                 }
                 else
-                {
                     return Ok(new { state = 400, rspInduction.SubErrCode, rspInduction.SubErrMsg });
-                }
             }
             catch (Exception ex)
             {
@@ -1326,7 +1234,7 @@ namespace TEAMModelBI.Controllers.BITable
                 string access_token = response.AccessToken;
 
                 IDingTalkClient quitStaffClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querydimission");
-                OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new OapiSmartworkHrmEmployeeQuerydimissionRequest() { Offset = 0L, Size = 50L };
+                OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new() { Offset = 0L, Size = 50L };
                 OapiSmartworkHrmEmployeeQuerydimissionResponse rspDimission = quitStaffClient.Execute(reqDimission, access_token);
                 if (rspDimission.Result != null)
                 {
@@ -1337,7 +1245,6 @@ namespace TEAMModelBI.Controllers.BITable
                     }
 
                     //保存操作记录
-                    //await _azureStorage.SaveBILog("tabledd-del", $"{_tmdName}【{_tmdId}】从table数据表中删除离职员工", _dingDing, httpContext: HttpContext);
                     await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-del", $"{_tmdName}【{_tmdId}】从table数据表中删除离职员工", _dingDing, httpContext: HttpContext);
                     return Ok(new { state = 200 });
                 }

+ 4 - 2
TEAMModelBI/Controllers/BITeacher/TeacherController.cs

@@ -35,6 +35,7 @@ namespace TEAMModelBI.Controllers.BITeacher
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-teachers")]
         public async Task<IActionResult> GetTeachers(JsonElement jsonElement) 
         {
@@ -45,7 +46,7 @@ namespace TEAMModelBI.Controllers.BITeacher
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
             
-            List<SchoolTeacher> teachers = new List<SchoolTeacher>();
+            List<SchoolTeacher> teachers = new();
             string sqlTxt = "";
             if (!string.IsNullOrEmpty($"{tmdId}")) 
             {
@@ -81,6 +82,7 @@ namespace TEAMModelBI.Controllers.BITeacher
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetInfo(JsonElement jsonElement) 
         {
@@ -91,7 +93,7 @@ namespace TEAMModelBI.Controllers.BITeacher
             var cosmosClient = _azureCosmos.GetCosmosClient();
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            List<object> objs = new List<object>();
+            List<object> objs = new();
 
             await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.id='{teacherId}'", requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
             {

+ 17 - 19
TEAMModelBI/Controllers/BITest/TestController.cs

@@ -94,7 +94,7 @@ namespace TEAMModelBI.Controllers.BITest
             if (!jsonElement.TryGetProperty("oldStandard", out JsonElement _oldStandard)) return BadRequest();
             var cosmosClient = _azureCosmos.GetCosmosClient();
 
-            List<string> abilityIds = new List<string>();  //册别的ID集合
+            List<string> abilityIds = new();  //册别的ID集合
 
             //查询册别信息
             await foreach (var tempAbility in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{_oldStandard}") }))
@@ -107,7 +107,7 @@ namespace TEAMModelBI.Controllers.BITest
                 var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityIds, $"Ability-{_oldStandard}");
             }
 
-            List<string> abilityTaskIds = new List<string>();  //章节ID集合
+            List<string> abilityTaskIds = new();  //章节ID集合
 
             await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{_oldStandard}") }))
             {
@@ -201,7 +201,7 @@ namespace TEAMModelBI.Controllers.BITest
             jsonElement.TryGetProperty("endDate", out JsonElement endDate);
             jsonElement.TryGetProperty("platform", out JsonElement platform);
 
-            List<string> strlist = new List<string>();
+            List<string> strlist = new();
             if (!string.IsNullOrEmpty($"{single}"))
                 strlist.Add($"RowKey {QueryComparisons.Equal} {single}");
             if (!string.IsNullOrEmpty($"{startDate}"))
@@ -270,7 +270,7 @@ namespace TEAMModelBI.Controllers.BITest
 
             //获取access_token
             IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-            OapiGettokenRequest request = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+            OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
             request.SetHttpMethod("Get");
             OapiGettokenResponse response = client.Execute(request);
             if (response.IsError)
@@ -282,7 +282,7 @@ namespace TEAMModelBI.Controllers.BITest
             string access_token = response.AccessToken;
             
             IDingTalkClient quitStaffClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querydimission");
-            OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new OapiSmartworkHrmEmployeeQuerydimissionRequest() { Offset = 0L, Size = 50L };
+            OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new() { Offset = 0L, Size = 50L };
             OapiSmartworkHrmEmployeeQuerydimissionResponse rspDimission = quitStaffClient.Execute(reqDimission, access_token);
 
             if (rspDimission.SubErrCode == "60011")
@@ -314,7 +314,7 @@ namespace TEAMModelBI.Controllers.BITest
 
             //获取access_token
             IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-            OapiGettokenRequest request = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+            OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
             request.SetHttpMethod("Get");
             OapiGettokenResponse response = client.Execute(request);
             if (response.IsError)
@@ -326,7 +326,7 @@ namespace TEAMModelBI.Controllers.BITest
             string access_token = response.AccessToken;
 
             IDingTalkClient InductionClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querypreentry");
-            OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new OapiSmartworkHrmEmployeeQuerypreentryRequest() { Offset = 0L, Size = 50 };
+            OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new() { Offset = 0L, Size = 50 };
             reqInduction.SetHttpMethod("GET");
             OapiSmartworkHrmEmployeeQuerypreentryResponse rspInduction = InductionClient.Execute(reqInduction, access_token);
             if (rspInduction.Result.DataList != null)
@@ -334,7 +334,7 @@ namespace TEAMModelBI.Controllers.BITest
                 foreach (var itemId in rspInduction.Result.DataList)
                 {
                     IDingTalkClient client3 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
-                    OapiV2UserGetRequest v2GetRequest = new OapiV2UserGetRequest()
+                    OapiV2UserGetRequest v2GetRequest = new()
                     {
                         Userid = itemId,
                         Language = "zh_CN"
@@ -365,7 +365,7 @@ namespace TEAMModelBI.Controllers.BITest
 
             //获取access_token
             IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
-            OapiGettokenRequest request = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+            OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
             request.SetHttpMethod("Get");
             OapiGettokenResponse response = client.Execute(request);
             if (response.IsError)
@@ -390,7 +390,7 @@ namespace TEAMModelBI.Controllers.BITest
             //} while (vars);
 
             IDingTalkClient jobclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob");
-            OapiSmartworkHrmEmployeeQueryonjobRequest jobreq = new OapiSmartworkHrmEmployeeQueryonjobRequest { StatusList = "2,3,-1", Offset = 1, Size = 50 };   //2:试用期 3:正式 5:待离职 -1:无状态
+            OapiSmartworkHrmEmployeeQueryonjobRequest jobreq = new() { StatusList = "2,3,-1", Offset = 1, Size = 50 };   //2:试用期 3:正式 5:待离职 -1:无状态
             OapiSmartworkHrmEmployeeQueryonjobResponse jobrsp = jobclient.Execute(jobreq, access_token);
             if (jobrsp.SubErrCode == "60011")
             {
@@ -422,7 +422,7 @@ namespace TEAMModelBI.Controllers.BITest
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 List<AssistSchool> schoolAssists = new();
                 //StringBuilder stringBuilder = new StringBuilder("select value(c) from c");
-                StringBuilder stringBuilder = new StringBuilder("select c.id,c.code,c.schoolCode,c.name,c.region,c.province,c.city,c.dist,c.size,c.address,c.picture,c.type,c.scale,c.areaId,c.standard from c");
+                StringBuilder stringBuilder = new("select c.id,c.code,c.schoolCode,c.name,c.region,c.province,c.city,c.dist,c.size,c.address,c.picture,c.type,c.scale,c.areaId,c.standard from c");
 
                 if (!string.IsNullOrEmpty($"{_schoolCode}"))
                 {
@@ -745,8 +745,8 @@ namespace TEAMModelBI.Controllers.BITest
         public async Task<IActionResult> GetYearMonth()
         {
             var cosmosClient = _azureCosmos.GetCosmosClient();
-            Dictionary<int, long> tempYear = new Dictionary<int, long>();
-            List<TempSchool> tempSchools = new List<TempSchool>();
+            Dictionary<int, long> tempYear = new();
+            List<TempSchool> tempSchools = new();
             for (int i = 1; i < 13; i++)
             {
                 var start = 00022222330;
@@ -758,7 +758,7 @@ namespace TEAMModelBI.Controllers.BITest
                     {
                         foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                         {
-                            TempSchool tempSchool = new TempSchool();
+                            TempSchool tempSchool = new();
                             tempSchool.id = obj.GetProperty("id").GetString();
                             tempSchool.ts = obj.GetProperty("_ts").GetInt64();
                             tempSchool.name = obj.GetProperty("name").GetString();
@@ -906,11 +906,11 @@ namespace TEAMModelBI.Controllers.BITest
         public async Task<IActionResult> GetRepeat(JsonElement jsonElement) 
         {
             jsonElement.TryGetProperty("datetime", out JsonElement _datetime);
-            Dictionary<string, string> prodict = new Dictionary<string, string>() { { "YMPCVCIM", "学情分析模组" }, { "IPDYZYLC", "智慧学校管理服务" }, { "3CLYJ6NP", "AClass ONE智慧学伴" }, { "IPALJ6NY", "数据储存服务空间" },{ "VABAJ6NV", "卷卡合一阅卷系统" } };
+            Dictionary<string, string> prodict = new() { { "YMPCVCIM", "学情分析模组" }, { "IPDYZYLC", "智慧学校管理服务" }, { "3CLYJ6NP", "AClass ONE智慧学伴" }, { "IPALJ6NY", "数据储存服务空间" },{ "VABAJ6NV", "卷卡合一阅卷系统" } };
             var ste = prodict["IPDYZYLC"];
 
-            List<string> str_str = new List<string>() { "12", "20", "13", "13", "14", "16" };
-            List<strend> strends = new List<strend> { new strend { id = 1, name = "12", age = 20 }, new strend { id = 1, name = "13", age = 20 }, new strend { id = 2, name = "22", age = 22 }, new strend { id = 3, name = "23", age = 23 } };
+            List<string> str_str = new() { "12", "20", "13", "13", "14", "16" };
+            List<strend> strends = new() { new strend { id = 1, name = "12", age = 20 }, new strend { id = 1, name = "13", age = 20 }, new strend { id = 2, name = "22", age = 22 }, new strend { id = 3, name = "23", age = 23 } };
             //str_str.Distinct().ToList();
             strends.Where((x, i) => strends.FindIndex(z => z.id.Equals(x.id)) == i).ToList();
             List<strend> str_strend1 = strends.Where((x, i) => strends.FindIndex(z => z.id.Equals(x.id)) == i).ToList();
@@ -1258,8 +1258,6 @@ namespace TEAMModelBI.Controllers.BITest
 
             var temps= await _azureRedis.GetRedisClient(dbnum: 0, name: "Global").SortedSetIncrementAsync($"Login:IES:Test", $"1", 1);//一天24小时  小时为单位
 
-
-
             var cosmosDefaulat = _azureCosmos.GetCosmosClient(); //默认数据库
             List<School> schools = new();
             await foreach (var item in cosmosDefaulat.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<School>(queryText: "select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))

+ 38 - 30
TEAMModelBI/Controllers/Census/ActivitySticsController.cs

@@ -46,6 +46,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 统计所有的评量活动,问卷调查,投票活动,作业   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-allactivity")]
         public async Task<IActionResult> GetAllActivity(JsonElement jsonElement)
         {
@@ -438,6 +439,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 所有区的统计接口 学区情况   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-all")]
         public async Task<IActionResult> GetAll(JsonElement jsonElement)
         {
@@ -533,6 +535,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-areasanls")]
         public async Task<IActionResult> GetAreasAnls(JsonElement jsonElement)
         {
@@ -549,27 +552,28 @@ namespace TEAMModelBI.Controllers.Census
 
             foreach (var area in areaInfos)
             {
-                string scSql = $"select value(c.id) from c where c.areaId='{area.id}'";
-                List<string> scIds = await CommonFind.GetValueSingle(cosmosClient, "School", scSql,"Base");
+                //string scSql = $"select value(c.id) from c where c.areaId='{area.id}'";
+                //List<string> scIds = await CommonFind.GetValueSingle(cosmosClient, "School", scSql,"Base");
                 //allSize += recSchools.Select(s => s.size).Sum();
-                area.scCnt = scIds.Count;
-                int tTchCnt = 0;
-                int tStuCnt = 0;
-                if (scIds.Count > 0)
-                {
-                    scSql = BICommonWay.ManyScSql("REPLACE(c.code, 'Teacher-', '')", scIds);
-
-                    //查教师
-                    string tchSql = $"select value(count(c.id)) from c where c.pk='Teacher' and {scSql}";
-                    tTchCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", tchSql);
-
-                    scSql = BICommonWay.ManyScSql("REPLACE(c.code, 'Base-', '')", scIds);
-                    //查学生
-                    string stuSql = $"select value(count(c.id)) from c where c.pk='Base' and {scSql}";
-                    tStuCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Student", stuSql);
-                }
-                area.tchCnt = tTchCnt;
-                area.stuCnt = tStuCnt;
+                area.scCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", $"select value(count(c.id)) from c where c.areaId='{area.id}'", "Base");
+                //area.scCnt = scIds.Count;
+                //int tTchCnt = 0;
+                //int tStuCnt = 0;
+                //if (scIds.Count > 0)
+                //{
+                //    scSql = BICommonWay.ManyScSql("REPLACE(c.code, 'Teacher-', '')", scIds);
+
+                //    //查教师
+                //    string tchSql = $"select value(count(c.id)) from c where c.pk='Teacher' and {scSql}";
+                //    tTchCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", tchSql);
+
+                //    scSql = BICommonWay.ManyScSql("REPLACE(c.code, 'Base-', '')", scIds);
+                //    //查学生
+                //    string stuSql = $"select value(count(c.id)) from c where c.pk='Base' and {scSql}";
+                //    tStuCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Student", stuSql);
+                ////}
+                //area.tchCnt = tTchCnt;
+                //area.stuCnt = tStuCnt;
             }
 
             return Ok(new { state = RespondCode.Ok, areaInfos });
@@ -580,6 +584,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-allanls")]
         public async Task<IActionResult> GetAllAnls(JsonElement jsonElement) 
         {
@@ -719,7 +724,7 @@ namespace TEAMModelBI.Controllers.Census
 
             List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
 
-            List<ActivityCount> activityCounts = new List<ActivityCount>();
+            List<ActivityCount> activityCounts = new();
             foreach (var itemId in schoolIds)
             {
                 School school = new();
@@ -729,7 +734,7 @@ namespace TEAMModelBI.Controllers.Census
                     using var json = await JsonDocument.ParseAsync(response.ContentStream);
                     school = json.ToObject<School>();
                 }
-                ActivityCount activityCount = new ActivityCount() { id = itemId, name = school.name != null ? school.name : itemId };
+                ActivityCount activityCount = new() { id = itemId, name = school.name != null ? school.name : itemId };
                 foreach (var type in StaticValue.activityTypes)
                 {
                     string activitySql = $"SELECT value(count(c.id)) FROM c WHERE c.pk='{type}' AND c.school='{itemId}'";
@@ -749,6 +754,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-termactivity")]
         public async Task<IActionResult> GetTermActivity(JsonElement jsonElement)
         {
@@ -763,7 +769,7 @@ namespace TEAMModelBI.Controllers.Census
             if (!string.IsNullOrEmpty($"{tmdId}"))
             {
                 List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
-                List<ActivityCount> activityCounts = new List<ActivityCount>();
+                List<ActivityCount> activityCounts = new();
                 foreach (var schoolId in schoolIds)
                 {
                     School school = new();
@@ -773,7 +779,7 @@ namespace TEAMModelBI.Controllers.Census
                         using var json = await JsonDocument.ParseAsync(response.ContentStream);
                         school = json.ToObject<School>();
                     }
-                    ActivityCount activityCount = new ActivityCount() { id = schoolId, name = school.name != null ? school.name : schoolId };
+                    ActivityCount activityCount = new() { id = schoolId, name = school.name != null ? school.name : schoolId };
 
                     foreach (var type in StaticValue.activityTypes)
                     {
@@ -795,7 +801,7 @@ namespace TEAMModelBI.Controllers.Census
                     string querySql = $"SELECT value(COUNT(c.id)) FROM c where c.pk='{type}' and c.createTime >= {start} and c.createTime <= {end}";
                     long totals = await CommonFind.GetSqlValueCount(cosmosClient, "Common", querySql);
 
-                    KeyValuePair<string, object> valuePair = new KeyValuePair<string, object>(type, totals);
+                    KeyValuePair<string, object> valuePair = new(type, totals);
                     typeCount.Add(valuePair);
                 }
 
@@ -808,6 +814,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-area")]
         public async Task<IActionResult> GetAreaActovoty(JsonElement jsonElement)
         {
@@ -832,7 +839,7 @@ namespace TEAMModelBI.Controllers.Census
             foreach (var school in schools)
             {
 
-                ActivityCount tempCount = new ActivityCount() { id = school.id, name = school.name != null ? school.name : school.id };
+                ActivityCount tempCount = new() { id = school.id, name = school.name != null ? school.name : school.id };
                 foreach (var type in StaticValue.activityTypes)
                 {
                     StringBuilder sqlTxt = new($"select value(COUNT(c.id)) from c where c.pk='{type}' and c.school='{school.id}' ");
@@ -867,6 +874,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetInfo(JsonElement jsonElement)
         {
@@ -879,8 +887,8 @@ namespace TEAMModelBI.Controllers.Census
             var cosmosClient = _azureCosmos.GetCosmosClient();
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            List<object> infos = new List<object>();
-            StringBuilder sqlTxt = new StringBuilder($"select * from c where c.id='{id}'");
+            List<object> infos = new();
+            StringBuilder sqlTxt = new($"select * from c where c.id='{id}'");
             if (!string.IsNullOrEmpty($"{activity}"))
             {
                 sqlTxt.Append($" and c.pk='{activity}'");
@@ -920,8 +928,8 @@ namespace TEAMModelBI.Controllers.Census
             public string standard { get; set; }
             public string standardName { get; set; }
             public int scCnt { get; set; } = 0;
-            public int tchCnt { get; set; } = 0;
-            public int stuCnt { get; set; } = 0;
+            //public int tchCnt { get; set; } = 0;
+            //public int stuCnt { get; set; } = 0;
         }
 
 

+ 24 - 32
TEAMModelBI/Controllers/Census/BlobLogController.cs

@@ -13,6 +13,8 @@ using TEAMModelOS.Models;
 using TEAMModelOS.SDK.Context.BI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models.Cosmos.BI;
+using TEAMModelOS.SDK.Models.Service.BI;
 
 namespace TEAMModelBI.Controllers.Census
 {
@@ -51,35 +53,30 @@ namespace TEAMModelBI.Controllers.Census
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
             StringBuilder sqlSize = new($"select value(sum(c.size)) from c ");
             long useSize = 0;  //使用大小
-            List<RecBlobFile> blobFiles = new();
+            Dictionary<string, int> typeCnt = new();
 
+            List<string> schoolIds = new();
             if (!string.IsNullOrEmpty($"{areaId}"))
             {
                 string sqlTxt = $"select c.id from c where c.areaId='{areaId}'";
                 sqlSize.Append($" where c.areaId = '{areaId}'");
-
-                List<string> schools = await CommonFind.FindSchoolIds(cosmosClient, sqlTxt.ToString(), "Base");
-                foreach (var id in schools)
+                schoolIds = await CommonFind.FindSchoolIds(cosmosClient, sqlTxt.ToString(), "Base");
+                foreach (var item in StaticValue.fileType)
                 {
-                    await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecBlobFile>(queryText: "SELECT c.id,c.code,c.name,c.size,c.type FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Bloblog-{id}") }))
-                    {
-                        blobFiles.Add(item);
-                    }
-
-                    List<string> tecId = await CommonFind.FindRolesId(cosmosClient, schools);
-                    List<RecBlobFile> tecBlob = await GetBlobTeache(cosmosClient, tecId);
-                    if (tecBlob.Count > 0) 
+                    int fileCnt = 0;
+                    if (schoolIds.Count > 0)
                     {
-                        blobFiles.Concat(tecBlob);
-                    }
-
-                    await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecBlobFile>(queryText: $"SELECT c.id,c.code,c.name,c.size,c.type FROM c where c.pk='Bloblog'", requestOptions: new QueryRequestOptions() { }))
-                    {
-                        blobFiles.Add(item);
+                        string inScStr = BICommonWay.ManyScSql(" REPLACE(c.code, 'Bloblog-', '')", schoolIds);
+                        string typeSql = $"select value(count(c.id)) from c where c.pk='Bloblog' and {inScStr} and c.type='{item}'";
+                        fileCnt = await CommonFind.GetSqlValueCount(cosmosClient, new List<string>() { "School", "Teacher" }, typeSql);
                     }
+                    typeCnt.Add(item, fileCnt);
+                }
 
+                foreach (var scId in schoolIds)
+                {
                     long blobsize = 0;
-                    RedisValue value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{id}");
+                    RedisValue value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{scId}");
                     if (!value.IsNullOrEmpty)
                     {
                         JsonElement record = value.ToString().ToObject<JsonElement>();
@@ -92,19 +89,15 @@ namespace TEAMModelBI.Controllers.Census
             }
             else
             {
-                await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecBlobFile>(queryText: "SELECT c.id,c.code,c.name,c.size,c.type FROM c where c.pk='Bloblog'", requestOptions: new QueryRequestOptions() { }))
+                foreach (var item in StaticValue.fileType)
                 {
-                    blobFiles.Add(item);
-                }
+                    string typeSql = $"select value(count(c.id)) from c where c.pk='Bloblog' and c.type='{item}'";
+                    int fileCnt = await CommonFind.GetSqlValueCount(cosmosClient, new List<string>() { "School", "Teacher" }, typeSql);
 
-                await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecBlobFile>(queryText: "SELECT c.id,c.code,c.name,c.size,c.type FROM c where c.pk='Bloblog'", requestOptions: new QueryRequestOptions() { }))
-                {
-                    blobFiles.Add(item);
+                    typeCnt.Add(item, fileCnt);
                 }
-
-                List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c", "Base");
-
-                foreach (var id in schoolIds) 
+                schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c", "Base");
+                foreach (var id in schoolIds)
                 {
                     long blobsize = 0;
                     RedisValue value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{id}");
@@ -119,11 +112,9 @@ namespace TEAMModelBI.Controllers.Census
                 }
             }
 
-            var typeCount = blobFiles.GroupBy(m => new { m.type }).Select(y => new { key = y.Key.type, value = y.Count() }).ToList();
             var areaSize = await CommonFind.GetSqlValueCount(cosmosClient, "School", sqlSize.ToString(), "Base");
 
-            return Ok(new { state = 200, areaSize, useSize, recCount= blobFiles.Count, typeCount });
-
+            return Ok(new { state = 200, areaSize, useSize, typeCount = typeCnt.ToList() });
         }
 
         /// <summary>
@@ -132,6 +123,7 @@ namespace TEAMModelBI.Controllers.Census
         /// <param name="cosmosClient"></param>
         /// <param name="teacherIds"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         public async static Task<List<RecBlobFile>> GetBlobTeache(CosmosClient cosmosClient, List<string> teacherIds)
         {
             List<RecBlobFile> blobFiles = new();

+ 17 - 13
TEAMModelBI/Controllers/Census/ItemSticsController.cs

@@ -38,6 +38,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-totals")]
         public async Task<IActionResult> GetTotals(JsonElement jsonElement)
         {
@@ -61,7 +62,7 @@ namespace TEAMModelBI.Controllers.Census
                         school = json.ToObject<School>();
                     }
 
-                    ItemTatols itempTatols = new ItemTatols() { id = scid, name = school.name != null ? school.name : scid };
+                    ItemTatols itempTatols = new() { id = scid, name = school.name != null ? school.name : scid };
 
                     string sqlTxt = $"select value(COUNT(c.id)) from c where c.code='Item-{scid}'";
                     long totals = await CommonFind.GetSqlValueCount(cosmosClient, new List<string>() { "School", "Teacher" }, sqlTxt.ToString());
@@ -83,6 +84,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 试题类型统计
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-type")]
         public async Task<IActionResult> GetTypeCount(JsonElement jsonElement) 
         {
@@ -95,8 +97,8 @@ namespace TEAMModelBI.Controllers.Census
             var cosmosClient = _azureCosmos.GetCosmosClient();
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            List<string> itemType = new List<string> { "single", "multiple", "judge", "complete", "subjective", "connector", "correct", "compose" };
-            List<object> typeCount = new List<object>();
+            List<string> itemType = new() { "single", "multiple", "judge", "complete", "subjective", "connector", "correct", "compose" };
+            List<object> typeCount = new();
 
             if (!string.IsNullOrEmpty($"{tmdId}"))
             {
@@ -112,7 +114,7 @@ namespace TEAMModelBI.Controllers.Census
                         school = json.ToObject<School>();
                     }
 
-                    Census tempCensus = new Census() { id = schoolId, name = school.name != null ? school.name : schoolId };
+                    Census tempCensus = new() { id = schoolId, name = school.name != null ? school.name : schoolId };
 
                     foreach (var type in itemType)
                     {
@@ -151,6 +153,7 @@ namespace TEAMModelBI.Controllers.Census
         ///  依据难度统计
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-level")]
         public async Task<IActionResult> GetLevelCount(JsonElement jsonElement)
         {
@@ -162,11 +165,11 @@ namespace TEAMModelBI.Controllers.Census
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
             var (start, end) = TimeHelper.GetTermStartOrEnd(DateTime.Now);
 
-            List<object> levelCount = new List<object>();
+            List<object> levelCount = new();
 
             if (!string.IsNullOrEmpty($"{tmdId}"))
             {
-                List<string> schoolIds = new List<string>();
+                List<string> schoolIds = new();
                 schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
 
                 foreach (var schoolId in schoolIds)
@@ -180,7 +183,7 @@ namespace TEAMModelBI.Controllers.Census
                         school = json.ToObject<School>();
                     }
 
-                    Census tempCensus = new Census() { id = schoolId, name = school.name != null ? school.name : schoolId };
+                    Census tempCensus = new() { id = schoolId, name = school.name != null ? school.name : schoolId };
 
                     for (int i = 1; i < 6; i++)
                     {
@@ -230,11 +233,11 @@ namespace TEAMModelBI.Controllers.Census
             var cosmosClient = _azureCosmos.GetCosmosClient();
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            List<object> layerCount = new List<object>();
+            List<object> layerCount = new();
 
             if (!string.IsNullOrEmpty($"{tmdId}"))
             {
-                List<string> schoolIds = new List<string>();
+                List<string> schoolIds = new();
                 schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
 
                 foreach (var schoolId in schoolIds)
@@ -247,7 +250,7 @@ namespace TEAMModelBI.Controllers.Census
                         school = json.ToObject<School>();
                     }
 
-                    Census tempCensus = new Census() { id = schoolId, name = school.name != null ? school.name : schoolId };
+                    Census tempCensus = new() { id = schoolId, name = school.name != null ? school.name : schoolId };
 
                     for (int i = 1; i <= 6; i++)
                     {
@@ -268,7 +271,7 @@ namespace TEAMModelBI.Controllers.Census
             {
                 for (int i = 1; i <= 6; i++)
                 {
-                    StringBuilder sqlTxt = new StringBuilder($"select value(COUNT(c.id)) from c where c.pk='Item' and c.field={i}");
+                    StringBuilder sqlTxt = new($"select value(COUNT(c.id)) from c where c.pk='Item' and c.field={i}");
                     if (bool.Parse($"{term}") == true)
                     {
                         sqlTxt.Append($" and c.createTime >= {start} and c.createTime <= {end}");
@@ -287,6 +290,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetInfo(JsonElement jsonElement) 
         {
@@ -297,7 +301,7 @@ namespace TEAMModelBI.Controllers.Census
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
 
-            List<object> objItems = new List<object>();
+            List<object> objItems = new();
             string sqlTxt = $"select * from c where c.id='{itemId}' and c.pk='Item'";
 
             if (!string.IsNullOrEmpty($"{isPersonal}"))
@@ -319,7 +323,7 @@ namespace TEAMModelBI.Controllers.Census
             }
             else 
             {
-                List<string> tableName = new List<string> { "School", "Teacher" };
+                List<string> tableName = new() { "School", "Teacher" };
                 foreach (string key in tableName) 
                 {
                     await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", key).GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { }))

+ 7 - 1
TEAMModelBI/Controllers/Census/LessonSticsController.cs

@@ -206,6 +206,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 统计所有区级的课例和活动   //已对接
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-allarea")]
         public async Task<IActionResult> GetAllArea(JsonElement jsonElement)
         {
@@ -248,12 +249,12 @@ namespace TEAMModelBI.Controllers.Census
             return Ok(new { state = 200, areaInfos });
         }
 
-
         /// <summary>
         /// 查询课例数量
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-count")]
         public async Task<IActionResult> GetCount(JsonElement jsonElement)
         {
@@ -366,6 +367,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 统计所有的课例数据
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-diccount")]
         public async Task<IActionResult> GetDicCount(JsonElement jsonElement)
         {
@@ -600,6 +602,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetInfo(JsonElement jsonElement) 
         {
@@ -628,6 +631,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-less")]
         public async Task<IActionResult> GetLess(JsonElement jsonElement)
         {
@@ -672,6 +676,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("set-bilessonstats")]
         public async Task<IActionResult> SetBILeesonStats(JsonElement jsonElement)
         {
@@ -880,6 +885,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-alllesson")]
         public async Task<IActionResult> GetAllLessonRecords(JsonElement jsonElement)
         {

+ 12 - 7
TEAMModelBI/Controllers/Census/PaperController.cs

@@ -42,6 +42,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-count")]
         public async Task<IActionResult> GetCount(JsonElement jsonElement)
         {
@@ -56,10 +57,10 @@ namespace TEAMModelBI.Controllers.Census
 
             if (!string.IsNullOrEmpty($"{tmdId}"))
             {
-                List<string> schoolIds = new List<string>();
+                List<string> schoolIds = new();
                 schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
 
-                List<SchoolPaper> schoolPapers = new List<SchoolPaper>();
+                List<SchoolPaper> schoolPapers = new();
                 string time = "";
                 bool bos = bool.Parse($"{term}");
                 if (bos == true)
@@ -112,6 +113,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 查询所有的试题数量
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-total")]
         public async Task<IActionResult> GetTotal(JsonElement jsonElement)
         {
@@ -139,8 +141,8 @@ namespace TEAMModelBI.Controllers.Census
             var cosmosClient = _azureCosmos.GetCosmosClient();
             if ($"{site}".Equals(BIConst.Global))
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
-            List<string> schoolIds = new List<string>();
-            List<SchoolPaper> schoolPapers = new List<SchoolPaper>();
+            List<string> schoolIds = new();
+            List<SchoolPaper> schoolPapers = new();
 
             schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
 
@@ -154,7 +156,7 @@ namespace TEAMModelBI.Controllers.Census
                     school = json.ToObject<School>();
                 }
 
-                SchoolPaper schoolPaper = new SchoolPaper() { id = schoolId , name = school != null ? school.name : schoolId };
+                SchoolPaper schoolPaper = new() { id = schoolId , name = school != null ? school.name : schoolId };
 
                 schoolPaper.totals = await CommonFind.GetSqlValueCount(cosmosClient, "School", $"select value(COUNT(c.id)) from c where c.code='Paper-{schoolId}'");
 
@@ -169,6 +171,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-yerar")]
         public async Task<IActionResult> GetNewYear(JsonElement jsonElement) 
         {
@@ -228,6 +231,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-termpaper")]
         public async Task<IActionResult> GetTermPaper(JsonElement jsonElement) 
         {
@@ -256,7 +260,7 @@ namespace TEAMModelBI.Controllers.Census
                         school = json.ToObject<School>();
                     }
 
-                    SchoolPaper schoolPaper = new SchoolPaper() { id = schoolId, name = school != null ? school.name : schoolId };
+                    SchoolPaper schoolPaper = new() { id = schoolId, name = school != null ? school.name : schoolId };
 
                     string sqlTxt = $"select value(count(c.id)) from c where c.createTime >={start} and c.createTime <={end}";
 
@@ -294,6 +298,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetInfo(JsonElement jsonElement) 
         {
@@ -326,7 +331,7 @@ namespace TEAMModelBI.Controllers.Census
             }
             else
             {
-                List<string> tableName = new List<string> { "School", "Teacher" };
+                List<string> tableName = new(){ "School", "Teacher" };
                 foreach (var temp in tableName)
                 {
                     await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", temp).GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { }))

+ 17 - 18
TEAMModelBI/Controllers/Census/ProductStatisController.cs

@@ -169,6 +169,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-school")]
         public async Task<IActionResult> GetSchoolSum(JsonElement jsonElement)
         {
@@ -179,15 +180,15 @@ namespace TEAMModelBI.Controllers.Census
             if ($"{site}".Equals(BIConst.Global))
                 clientContainer = _azureCosmos.GetCosmosClient(name: BIConst.Global);
 
-            List<SchoolProductSerial> serials = new List<SchoolProductSerial>(); //软体
-            List<SchoolProductService> services = new List<SchoolProductService>(); //服务
-            List<SchoolProductHard> hards = new List<SchoolProductHard>(); //硬体
+            List<SchoolProductSerial> serials = new(); //软体
+            List<SchoolProductService> services = new(); //服务
+            List<SchoolProductHard> hards = new(); //硬体
 
-            SchoolProductSum productSum = new SchoolProductSum(); //产品状态
-            List<SchoolProductSumProdInfo> prodinfo = new List<SchoolProductSumProdInfo>(); //学校的产品信息
-            List<SchoolProductSumData> serialRecord = new List<SchoolProductSumData>(); //软体购买记录
-            List<SchoolProductSumDataService> serviceRecord = new List<SchoolProductSumDataService>(); //服务购买记录
-            List<SchoolProductSumDataHard> hardRecord = new List<SchoolProductSumDataHard>(); //硬体购买记录
+            SchoolProductSum productSum = new(); //产品状态
+            List<SchoolProductSumProdInfo> prodinfo = new(); //学校的产品信息
+            List<SchoolProductSumData> serialRecord = new(); //软体购买记录
+            List<SchoolProductSumDataService> serviceRecord = new(); //服务购买记录
+            List<SchoolProductSumDataHard> hardRecord = new(); //硬体购买记录
 
 
             //取产品的数量
@@ -242,7 +243,7 @@ namespace TEAMModelBI.Controllers.Census
             }
 
             //学校教室
-            List<Room> rooms = new List<Room>();
+            List<Room> rooms = new();
             await foreach (var item in clientContainer.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Room>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Room-{schoolCode}") }))
             {
                 rooms.Add(item);
@@ -256,6 +257,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-assistschool")]
         public async Task<IActionResult> GetAssistSchoolId(JsonElement jsonElement)
         {
@@ -266,7 +268,7 @@ namespace TEAMModelBI.Controllers.Census
                 cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
 
             List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
-            List<SchoolProduct> schoolProducts = new List<SchoolProduct>();
+            List<SchoolProduct> schoolProducts = new();
             foreach (var scid in schoolIds)
             {
                 School school = new();
@@ -278,7 +280,7 @@ namespace TEAMModelBI.Controllers.Census
                     school = json.ToObject<School>();
                 }
 
-                SchoolProduct sProduct = new SchoolProduct() { id = scid, name = school != null ? school.name : scid };
+                SchoolProduct sProduct = new() { id = scid, name = school != null ? school.name : scid };
 
                 List<ProductStatis> productStatis = new();
 
@@ -320,7 +322,7 @@ namespace TEAMModelBI.Controllers.Census
                             }
                             else
                             {
-                                ProductStatis tempProd = new ProductStatis()
+                                ProductStatis tempProd = new()
                                 {
                                     prodCode = serial.prodCode,
                                     prodName = _serials[serial.prodCode],
@@ -342,7 +344,7 @@ namespace TEAMModelBI.Controllers.Census
                             }
                             else
                             {
-                                ProductStatis tempProd = new ProductStatis()
+                                ProductStatis tempProd = new()
                                 {
                                     prodCode = ser.prodCode,
                                     prodName = _services[ser.prodCode],
@@ -366,6 +368,7 @@ namespace TEAMModelBI.Controllers.Census
         /// 所有模组统计
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-moduleanalys")]
         public async Task<IActionResult> GetModuleAnalys(JsonElement jsonElement)
         {
@@ -486,6 +489,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-adviserschool")]
         public async Task<IActionResult> GetAdviserSchool(JsonElement jsonElement) 
         {
@@ -578,8 +582,6 @@ namespace TEAMModelBI.Controllers.Census
             public long yearSeri { get; set; }
         }
 
-
-
         public record SchoolProduct 
         {
             public string id { get; set; }
@@ -589,7 +591,6 @@ namespace TEAMModelBI.Controllers.Census
             public List<ProductStatis> product { get; set; }
         }
 
-
         public record ProductStatis 
         {
             public string prodCode { get; set; }
@@ -599,8 +600,6 @@ namespace TEAMModelBI.Controllers.Census
             //public string dataType { get; set; }
 
             public long Count { get; set; }
-
-
         }
          
     }

+ 4 - 0
TEAMModelBI/Controllers/Census/SchoolController.cs

@@ -42,6 +42,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-all")]
         public async Task<IActionResult> GetAll(JsonElement jsonElement)
         {
@@ -136,6 +137,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-assist")]
         public async Task<IActionResult> GetAssistStatis(JsonElement jsonElement)
         {
@@ -235,6 +237,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-idstatis")]
         public async Task<IActionResult> GetIdStatis(JsonElement jsonElement)
         {
@@ -350,6 +353,7 @@ namespace TEAMModelBI.Controllers.Census
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-info")]
         public async Task<IActionResult> GetSchool(JsonElement jsonElement)
         {

+ 1 - 82
TEAMModelBI/Controllers/LoginController.cs

@@ -199,7 +199,6 @@ namespace TEAMModelBI.Controllers
                             strMsg.Append($"{item.tmdName}【{item.tmdId}】醍摩豆账号和{item.name}【{item.userId}】钉钉账户绑定成功");
 
                             //保存操作记录
-                            //await _azureStorage.SaveBILog("tabledd-update", strMsg?.ToString(), _dingDing, httpContext: HttpContext, twebsite: Website, tid: item.tmdId, tname: item.tmdName);
                             await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", strMsg?.ToString(), _dingDing, httpContext: HttpContext, twebsite: Website, tid: item.tmdId, tname: item.tmdName);
 
                             saveInfo.Add(item);                            
@@ -262,28 +261,6 @@ namespace TEAMModelBI.Controllers
                         }
                         else return Ok(new { state = 404, msg = "依据钉钉手机号未找到醍摩豆账号!" });
 
-                        //HttpClient httpClient = _http.CreateClient();
-                        //string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
-
-                        //List<string> mobiles = new() { $"{ ddUserInfo.mobile}" };
-                        //HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(url, mobiles);
-                        //if (responseMessage.StatusCode == HttpStatusCode.OK)
-                        //{
-                        //    string temp = responseMessage.Content.ReadAsStringAsync().Result;
-                        //    List<JsonElement> json_id = temp.ToObject<List<JsonElement>>();
-                        //    if (json_id.Count > 0)
-                        //    {
-                        //        foreach (var tmd in json_id)
-                        //        {
-                        //            ddUserInfo.tmdId = tmd.GetProperty("id").ToString();
-                        //            ddUserInfo.tmdName = tmd.GetProperty("name").ToString();
-                        //            ddUserInfo.tmdMobile = tmd.GetProperty("mobile").ToString();
-                        //            ddUserInfo.picture = tmd.GetProperty("picture").ToString();
-                        //            ddUserInfo.mail = tmd.GetProperty("mail").ToString();
-                        //        }
-                        //    }
-                        //    else return Ok(new { state = 404, msg = "依据钉钉手机号未找到醍摩豆账号!" });
-                        //}
                     }
                     else return Ok(new { state = 404, msg = "钉钉手机号为空" });
 
@@ -296,7 +273,6 @@ namespace TEAMModelBI.Controllers
                     ddUserInfo = await table.Save<DingDingUserInfo>(ddUserInfo);
 
                     //保存操作记录
-                    //await _azureStorage.SaveBILog("tabledd-update", $"{ddUserInfo.tmdName}【{ddUserInfo.tmdId}】醍摩豆账号和{ddUserInfo.name}【{ddUserInfo.RowKey}】钉钉账户绑定成功", _dingDing, httpContext: HttpContext, tid: ddUserInfo.tmdId, tname: ddUserInfo.tmdName, twebsite: Website);
                     await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{ddUserInfo.tmdName}【{ddUserInfo.tmdId}】醍摩豆账号和{ddUserInfo.name}【{ddUserInfo.RowKey}】钉钉账户绑定成功", _dingDing, httpContext: HttpContext, tid: ddUserInfo.tmdId, tname: ddUserInfo.tmdName, twebsite: Website);
 
                     roles = !string.IsNullOrEmpty($"{ddUserInfo.roles}") ? new List<string>(ddUserInfo.roles.Split(",")) : new List<string>();
@@ -394,26 +370,6 @@ namespace TEAMModelBI.Controllers
                         }
                         else return Ok(new { state = 404, msg = "手机号未找到醍摩豆账户" });
 
-                        //string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
-                        //List<string> mobiles = new() { $"{mobile}" };
-                        //HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(url, mobiles);
-                        //if (responseMessage.StatusCode == HttpStatusCode.OK)
-                        //{
-                        //    var temp = await responseMessage.Content.ReadAsStringAsync();
-                        //    if (temp.Length > 0)
-                        //    {
-                        //        List<JsonElement> itemjson = temp.ToObject<List<JsonElement>>();
-                        //        foreach (var item in itemjson)
-                        //        {
-                        //            itemUser.tmdId = item.GetProperty("id").ToString();
-                        //            itemUser.tmdName = item.GetProperty("name").ToString();
-                        //            itemUser.tmdMobile = item.GetProperty("mobile").ToString();
-                        //            itemUser.picture = item.GetProperty("picture").ToString();
-                        //            itemUser.mail = item.GetProperty("mail").ToString();
-                        //        }
-                        //    }
-                        //}
-                        //else return Ok(new { state = 404, msg = "手机号未找到醍摩豆账户" });
                     }
 
                     if (string.IsNullOrEmpty($"{mobile}") && string.IsNullOrEmpty($"{idtoken}"))
@@ -425,7 +381,6 @@ namespace TEAMModelBI.Controllers
                         roles = roles.Where(w => !string.IsNullOrEmpty(w)).ToList();
 
                         //保存操作记录
-                        //await _azureStorage.SaveBILog("tabledd-update", $"{itemUser.tmdName}【{itemUser.tmdId}】醍摩豆账号和{itemUser.name}【{itemUser.userId}】钉钉账户绑定成功", _dingDing, tid: itemUser.tmdId, tname: itemUser.name, twebsite: Website, httpContext: HttpContext);
                         await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{itemUser.tmdName}【{itemUser.tmdId}】醍摩豆账号和{itemUser.name}【{itemUser.userId}】钉钉账户绑定成功", _dingDing, tid: itemUser.tmdId, tname: itemUser.name, twebsite: Website, httpContext: HttpContext);
 
                         id_token = JwtAuth.CreateAuthTokenBI(_option.HostName, itemUser.tmdId?.ToString(), itemUser.tmdName?.ToString(), itemUser.picture?.ToString(), _option.JwtSecretKey, scope: "assist", webSite: Website, isex: false, itemUser.userId?.ToString(), itemUser.name?.ToString(), itemUser.avatar?.ToString(), roles: roles?.ToArray(), permissions: permissions?.ToArray(), expire: 3);
@@ -517,43 +472,6 @@ namespace TEAMModelBI.Controllers
                             await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{coreUser.name}【{coreUser.id}】醍摩豆账号和{itemUser.name}【{itemUser.userId}】钉钉账户绑定成功", _dingDing, tid: itemUser.tmdId, tname: itemUser.name, twebsite: Website, httpContext: HttpContext);
                         }
                         else return Ok(new { state = 400, message = "该手机没有注册醍摩豆账号信息" });
-
-                        //HttpClient httpClient = _http.CreateClient();
-                        //string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
-                        //HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(url, moile);
-
-                        //if (responseMessage.StatusCode == HttpStatusCode.OK)
-                        //{
-                        //    var temp = await responseMessage.Content.ReadAsStringAsync();
-                        //    if (temp.Length > 0)
-                        //    {
-                        //        List<JsonElement> itemjson = temp.ToObject<List<JsonElement>>();
-                        //        string tmdId = null;
-                        //        string tmdName = null;
-                        //        foreach (var item in itemjson)
-                        //        {
-                        //            tmdId = item.GetProperty("id").ToString();
-                        //            tmdName = item.GetProperty("name").ToString();
-                        //            itemUser.tmdId = tmdId?.ToString();
-                        //            itemUser.tmdName = tmdName?.ToString();
-                        //            itemUser.tmdMobile = item.GetProperty("mobile").ToString();
-                        //            itemUser.picture = item.GetProperty("picture").ToString();
-                        //            itemUser.mail = item.GetProperty("mail").ToString();
-                        //            roles = !string.IsNullOrEmpty($"{itemUser.roles}") ? new List<string>(itemUser.roles.Split(",")) : new List<string>();
-                        //            permissions = !string.IsNullOrEmpty($"{itemUser.permissions}") ? new List<string>(itemUser.permissions.Split(",")) : new List<string>();
-
-                        //            ddUserInfos.Add(itemUser);
-                        //        }
-
-                        //        ddUserInfos = await table.UpdateAll<DingDingUserInfo>(ddUserInfos);
-
-                        //        //保存操作记录
-                        //        //await _azureStorage.SaveBILog("tabledd-update", $"{tmdName}【{tmdId}】醍摩豆账号和{itemUser.name}【{itemUser.userId}】钉钉账户绑定成功", _dingDing, tid: itemUser.tmdId, tname: itemUser.name, twebsite: Website, httpContext: HttpContext);
-                        //        await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{tmdName}【{tmdId}】醍摩豆账号和{itemUser.name}【{itemUser.userId}】钉钉账户绑定成功", _dingDing, tid: itemUser.tmdId, tname: itemUser.name, twebsite: Website, httpContext: HttpContext);
-                        //    }
-                        //    else return Ok(new { state = 400, message = "该手机没有注册醍摩豆账号信息" });
-                        //}
-                        //else return Ok(new { state = responseMessage.StatusCode });
                     }
                     //自己写的
                     id_token = JwtAuth.CreateAuthTokenBI(_option.HostName, itemUser.tmdId?.ToString(), itemUser.tmdName?.ToString(), itemUser.picture?.ToString(), _option.JwtSecretKey, scope: "assist", webSite: Website, isex: false, itemUser.userId?.ToString(), itemUser.name?.ToString(), itemUser.avatar?.ToString(), roles: roles?.ToArray(), permissions: permissions?.ToArray(), expire: 3);
@@ -647,6 +565,7 @@ namespace TEAMModelBI.Controllers
         /// </summary>
         /// <param name="jsonElement"></param>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("set-bizuser")]
         public async Task<IActionResult> SetBizUserLogin(JsonElement jsonElement)
         {

+ 1 - 0
TEAMModelBI/Controllers/ManySiteCut/SystemConfigController.cs

@@ -43,6 +43,7 @@ namespace TEAMModelBI.Controllers.ManySiteCut
         /// 获取应用配置文件
         /// </summary>
         /// <returns></returns>
+        [ProducesDefaultResponseType]
         [HttpPost("get-config")]
         public async Task<IActionResult> GetConfigJson() 
         {

+ 1 - 41
TEAMModelBI/Controllers/RepairApi/TeacherREPController.cs

@@ -20,47 +20,7 @@ namespace TEAMModelBI.Controllers.RepairApi
 
         }
 
-        List<string> schools = new()
-        {
-            "dghznx",
-            "cxhhlx",
-            "xjaxx",
-            "zjqxx",
-            "xnygxx",
-            "lxxcfx",
-            "gxjrxx",
-            "cdgxsx",
-            "yzxx",
-            "kjyxx",
-            "wjylxx",
-            "dsgjxx",
-            "ydzt",
-            "xndbxx",
-            "sqtszx",
-            "cdxczx",
-            "ghsyzx",
-            "lqsx",
-            "cdxxps",
-            "xcfx",
-            "xyqxx",
-            "xncbyy",
-            "cdlqjk",
-            "lqdmxx",
-            "lqyx",
-            "pclxxx",
-            "cdfzx",
-            "xnblxx",
-            "ghsx",
-            "khdycz",
-            "khbmxx",
-            "khdecz",
-            "khzx",
-            "khhbzx",
-            "gxxcxx",
-            "khhtxx",
-            "khdxxx",
-            "khsyxx"
-        };
+        List<string> schools = new() { "dghznx", "cxhhlx", "xjaxx", "zjqxx", "xnygxx", "lxxcfx", "gxjrxx", "cdgxsx", "yzxx", "kjyxx", "wjylxx", "dsgjxx", "ydzt", "xndbxx", "sqtszx", "cdxczx", "ghsyzx", "lqsx", "cdxxps", "xcfx", "xyqxx", "xncbyy", "cdlqjk", "lqdmxx", "lqyx", "pclxxx", "cdfzx", "xnblxx", "ghsx", "khdycz", "khbmxx", "khdecz", "khzx", "khhbzx", "gxxcxx", "khhtxx", "khdxxx", "khsyxx" };
 
         /// <summary>
         /// 修改教师学校信息

+ 41 - 0
TEAMModelBI/Tool/CommonFind.cs

@@ -219,6 +219,47 @@ namespace TEAMModelBI.Tool
             return totals;
         }
 
+        /// <summary>
+        /// 单个容器数据统计  double
+        /// </summary>
+        /// <param name="cosmosClient"></param>
+        /// <param name="container"></param>
+        /// <param name="SqlTxt"></param>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        public static async Task<double> GetSqlValueDoubleCounnt(CosmosClient cosmosClient, string container, string SqlTxt, string code = null)
+        {
+            double totals = 0;
+            await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<double>(queryText: SqlTxt, requestOptions: string.IsNullOrEmpty(code) ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey(code) }))
+            {
+                totals = item;
+            }
+
+            return totals;
+        }
+
+        /// <summary>
+        /// 多个容器数据统计  double
+        /// </summary>
+        /// <param name="cosmosClient"></param>
+        /// <param name="container"></param>
+        /// <param name="SqlTxt"></param>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        public static async Task<double> GetSqlValueDoubleCounnt(CosmosClient cosmosClient, List<string> containers, string SqlTxt, string code = null)
+        {
+            double totals = 0;
+            foreach (var container in containers)
+            {
+                await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<double>(queryText: SqlTxt, requestOptions: string.IsNullOrEmpty(code) ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey(code) }))
+                {
+                    totals += item;
+                }
+            }
+
+            return totals;
+        }
+
         /// <summary>
         /// 通过SQL 语句返回实体信息
         /// </summary>

+ 19 - 0
TEAMModelBI/appsettings.Development.json

@@ -38,6 +38,25 @@
       "ActiveTask": "dep-active-task",
       "ItemCondQueue": "dep-itemcond"
     }
+
+    ////正式站
+    //"Storage": {
+    //  "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
+    //},
+    //"LogStorage": {
+    //  "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodellog;AccountKey=lxVDrgs+6rKtmASL3k1WrarrEd5Rk42wS1Mu5+sqQlPya1JLSlFDtnZUvMPeHHe7zlESfn/1NY7CZdGviy2UCw==;EndpointSuffix=core.chinacloudapi.cn"
+    //},
+    //"Cosmos": {
+    //  "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
+    //},
+    //"Redis": {
+    //  "ConnectionString": "52.130.252.100:6379,password=habook,ssl=false,abortConnect=False,writeBuffer=10240"
+    //},
+    //"ServiceBus": {
+    //  "ConnectionString": "Endpoint=sb://teammodelos.servicebus.chinacloudapi.cn/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=Sy4h4EQ8zP+7w/lOLi1X3tGord/7ShFHimHs1vC50Dc=",
+    //  "ActiveTask": "dep-active-task",
+    //  "ItemCondQueue": "dep-itemcond"
+    //}
   },
   //国际站连接字符串  暂时是本地
   "GlobalAzure": {

+ 3 - 3
TEAMModelOS.FunctionV4/TEAMModelOS.FunctionV4.csproj

@@ -5,9 +5,9 @@
 		<OutputType>Exe</OutputType>
 		<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
 		<SignAssembly>true</SignAssembly>
-		<Version>5.2207.20</Version>
-		<AssemblyVersion>5.2207.20.1</AssemblyVersion>
-		<FileVersion>5.2207.20.1</FileVersion>
+		<Version>5.2207.27</Version>
+		<AssemblyVersion>5.2207.27.1</AssemblyVersion>
+		<FileVersion>5.2207.27.1</FileVersion>
 		<PackageId>TEAMModelOS.FunctionV4</PackageId>
 		<Authors>teammodel</Authors>
 		<Company>醍摩豆(成都)信息技术有限公司</Company>

+ 284 - 11
TEAMModelOS.FunctionV4/TimeTrigger/IESTimerTrigger.cs

@@ -13,10 +13,12 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Net;
+using System.Net.Http;
 using System.Reflection;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
+using System.Web;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
@@ -30,27 +32,37 @@ namespace TEAMModelOS.FunctionV4.TimeTrigger
 {
     public class IESTimerTrigger
     {
+        /// <summary>
+        /// 文档。https://docs.microsoft.com/zh-cn/azure/azure-functions/functions-bindings-timer?tabs=in-process&pivots=programming-language-csharp
+        /// Timer 在线测试  https://ncrontab.swimburger.net/
+        /// </summary>
         private readonly AzureCosmosFactory _azureCosmos;
         private readonly DingDing _dingDing;
         private readonly AzureStorageFactory _azureStorage;
         private readonly AzureRedisFactory _azureRedis;
         private readonly IConverter _converter;
-        public IESTimerTrigger(IConverter converter, AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis)
+        private readonly SnowflakeId _snowflakeId;
+        private readonly HttpClient _httpClient;
+        public IESTimerTrigger(HttpClient httpClient,SnowflakeId snowflakeId,IConverter converter, AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis)
         {
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _azureStorage = azureStorage;
             _azureRedis = azureRedis;
             _converter = converter;
-        } /// <summary>
-          /// </summary>
-          /// <param name="req"></param>
-          /// <param name="log"></param>
-          /// <returns></returns>
+            _snowflakeId=snowflakeId;
+            _httpClient = httpClient;
+        }
+        /// <summary>
+        /// 防火墙日志记录文件
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
         [Function("FireWallFileLog")]
         //https://docs.azure.cn/zh-cn/azure-functions/functions-bindings-timer?tabs=in-process&pivots=programming-language-csharp
         //0 1 * * * * 一天中每小时的第 1 分钟
-        //0 */1 * * * *  每五分钟一次
+        //0 */10 * * * *  每五分钟一次
         public async Task FireWallFileLog([TimerTrigger("0 1 * * * *")] TimerInfo myTimer, ILogger log)
         {
             try
@@ -61,18 +73,41 @@ namespace TEAMModelOS.FunctionV4.TimeTrigger
                 var m = datetime.Month >= 10 ? $"{datetime.Month}" : $"0{datetime.Month}";
                 var d = datetime.Day >= 10 ? $"{datetime.Day}" : $"0{datetime.Day}";
                 var h = datetime.Hour >= 10 ? $"{datetime.Hour}" : $"0{datetime.Hour}";
+#if DEBUG
+                if (location.Equals("China-Dep"))
+#else
                 if (location.Equals("China"))
+#endif
+
                 {
                     string path = $"resourceId=/SUBSCRIPTIONS/73B7F9EF-D8B7-4444-9E8D-D80B43BF3CD4/RESOURCEGROUPS/TEAMMODELCHENGDU/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/OSFIREWARE/y={y}/m={m}/d={d}/h={h}/m=00/PT1H.json";
                     var retn = await BILogAnalyseService.GetPathAnalyse(_azureStorage, path, "LogStorage");
                     if (retn.recCnts.IsNotEmpty())
                     {
                         
-                        var topApi = retn.recCnts.SelectMany(x => x.apiCnt).OrderByDescending(o => o.count).Take(5).Select(x => new { x.api, x.ip, x.count });
-                        var topIp = retn.recCnts.SelectMany(x => x.ipCnt).OrderByDescending(o => o.count).Take(5).Select(x => new { x.api, x.ip, x.count });
+                         
                         //https://teammodelos.blob.core.chinacloudapi.cn/0-public/pie-borderRadius.html
-                       
-                        await _dingDing.SendBotMarkdown("防火墙日志记录", $"#### 防火墙日志记录\n> 记录时间:{datetime.AddHours(8).ToString("yyyy-MM-dd HH")}\n> ![screenshot]()\n> ###### 发布时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} [地址]({retn.saveUrls.First()}) \n", GroupNames.醍摩豆服務運維群組);
+                        string publishUrl = $"https://teammodelos.blob.core.chinacloudapi.cn/0-public/api-count.html?url={HttpUtility.UrlEncode(retn.saveUrls.First(),Encoding.UTF8)}&time={HttpUtility.UrlEncode(datetime.AddHours(8).ToString("yyyy年MM月dd日 HH时"),Encoding.UTF8)}";
+                        string ulrs = $"https://teammodelos.blob.core.chinacloudapi.cn/0-public/api-count.html?url={retn.saveUrls.First()}&time={datetime.AddHours(8).ToString("yyyy年MM月dd日 HH时")}";
+                        string ulr = $"http://cdhabook.teammodel.cn:8805/screen/screenshot-png?width=1920&height=980&url={HttpUtility.UrlEncode(ulrs,Encoding.UTF8)}&delay=5000";
+                        string image = "";
+                        try
+                        {
+                            string strs = await _httpClient.GetStringAsync(ulr);
+                            if (!string.IsNullOrWhiteSpace(strs)) {
+                                JsonElement json = strs.ToObject<JsonElement>();
+                                json.TryGetProperty("url", out JsonElement base64);
+                                using (MemoryStream ms = new MemoryStream(Convert.FromBase64String($"{base64}"))) {
+                                    image = await _azureStorage.GetBlobContainerClient("0-public").UploadFileByContainer( ms, $"visitCnt/{y}{m}{d}", $"{y}{m}{d}{h}.png",false);
+                                }
+                                   
+                            }
+                        }
+                        catch (Exception ex) { 
+                          
+                        }
+                        await _dingDing.SendBotMarkdown("防火墙日志记录", $"#### 防火墙日志记录\n> 记录时间:{datetime.AddHours(8).ToString("yyyy-MM-dd HH")}\n> ![screenshot]({image})\n> ###### 发布时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}" +
+                            $" [发布地址]({publishUrl}) \n", GroupNames.成都开发測試群組);
                     }
                 }
                 else if (location.Contains("Global"))
@@ -84,7 +119,245 @@ namespace TEAMModelOS.FunctionV4.TimeTrigger
             {
                // await _dingDing.SendBotMsg($"FireWallFileLog 防火墙日志记录: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}\n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
             }
+        }
+
+
+        /// <summary>
+        /// 清理HiTeach教研类型的课例文件上传在Blob空间的文件。 0  */10  22-23 * * *
+        /// 该代码执行之后 需要删除或者取消Timer任务。
+        /// </summary>
+        /// <param name="myTimer"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
+        [Function("CleanUnusedLessonRecord")]
+        //5分钟一次
+        public async Task CleanUnusedLessonRecord([TimerTrigger("0 */10 15-23 * * *")] TimerInfo myTimer, ILogger log) {
+            string location = Environment.GetEnvironmentVariable("Option:Location");
+            try {
+                if (location.Equals("China") || location.Equals("Global"))
+                {
+                    bool lockKey = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"LessonRecord:Unused:Lock:{location}");
+                    //bool keyLock = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"LessonRecord:Unused:Lock:Lock");
+                    //if (keyLock) { 
+                    //    return; 
+                    //}
+                    //key不存在的时候 。
+                    if (!lockKey)
+                    {
+                        var schoolKeys = new List<IdCodeCount>();
+                        var teacherKeys = new List<IdCodeCount>();
+                        string sqlT = "select   c.id,c.name, 'Teacher' as code  from c where c.code='Base'";
+                        string sqlS = "select   c.id,c.name, 'School' as code  from c where c.code='Base'";
+                        await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).
+                            GetItemQueryIterator<IdCodeCount>(queryText: sqlT, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
+                        {
+                            teacherKeys.Add(item);
+                        }
+                        await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).
+                            GetItemQueryIterator<IdCodeCount>(queryText: sqlS, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
+                        {
+                            schoolKeys.Add(item);
+                        }
+                        string sqlcount = "select value count(1) from c where c.pk='LessonRecord'";
+                        foreach (var key in schoolKeys)
+                        {
+                            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).
+                          GetItemQueryIterator<int>(queryText: sqlcount, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"LessonRecord-{key.id}") }))
+                            {
+                                key.count = item;
+                                break;
+                            }
+                        }
+                        foreach (var key in teacherKeys)
+                        {
+                            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).
+                          GetItemQueryIterator<int>(queryText: $"select value count(1) from c where c.pk='LessonRecord' and c.tmdid='{key.id}'",
+                          requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"LessonRecord") }))
+                            {
+                                key.count = item;
+                                break;
+                            }
+                        }
+                        schoolKeys.AddRange(teacherKeys);
+                        //以下代码作用,用于根据当前拥有的课例数判断区分学校和个人使用课例频率越多的,
+                        //并均分每次需要处理的学校和个人容器个数,避免每次处理批次花费时间相差太大。
+                        //将每个批次处理数量级控制在500-1000左右。
+                        List<IEnumerable<IdCodeCount>> counts = new List<IEnumerable<IdCodeCount>>();
+                        //501-∞
+                        var count501_ = schoolKeys.Where(x => x.count >= 501); //至少500条
+                        counts.AddRange(count501_.Page(1));//1个学校或个人
+                                                           //201-500
+                        var count201_500 = schoolKeys.Where(x => x.count >= 201 && x.count <= 500); //至少603条-1500条
+                        counts.AddRange(count201_500.Page(3));//2个学校或个人
+                                                              //100-200
+                        var count100_200 = schoolKeys.Where(x => x.count >= 100 && x.count <= 200);//至少500条-1000条
+                        counts.AddRange(count100_200.Page(10));//5个学校或个人
+                                                              //51-99
+                        var count51_99 = schoolKeys.Where(x => x.count >= 51 && x.count <= 99);//至少500条-990条
+                        counts.AddRange(count51_99.Page(10));//10个学校或个人
+                                                             //21-50
+                        var count21_50 = schoolKeys.Where(x => x.count >= 21 && x.count <= 50);//至少410条-1000条
+                        counts.AddRange(count21_50.Page(20));//20个学校或个人
+                                                             //10-20
+                        var count10_20 = schoolKeys.Where(x => x.count >= 10 && x.count <= 20);//至少500条-1000条
+                        counts.AddRange(count10_20.Page(50));//50个学校或个人
+                                                             //5-9
+                        var count0_9 = schoolKeys.Where(x => x.count >= 5 && x.count <= 9);//至少500条-900条
+                        counts.AddRange(count0_9.Page(100));//100个学校或个人
+                                                            //2-4
+                        var count2_4 = schoolKeys.Where(x => x.count >= 2 && x.count <= 4);//至少600条-1200条
+                        counts.AddRange(count2_4.Page(300));
+                        //0-1,已经处理过一次,不用再处理
+                        var count0_1 = schoolKeys.Where(x => x.count ==1);//至少500,就算没有课例也算一次。
+                        counts.AddRange(count0_1.Page(1000));
+                        int field = 1;
+                        foreach (var item in counts)
+                        {
+                            if (item.Any())
+                            {
+                                bool stuallstatus = await _azureRedis.GetRedisClient(8).HashSetAsync($"LessonRecord:Unused:Lock:{location}", field,
+                                    new UnusedLock { field = field, status = 0, item = item }.ToJsonString());
+                                field += 1;
+                            }
+
+                        }
+                        await _dingDing.SendBotMsg($"{location},获取到:{schoolKeys.Count} 个学校和个人的容器\n" +
+                            $"大概要处理:{schoolKeys.Sum(x => x.count) + schoolKeys.Where(x => x.count >= 0).Count()} 条数据\n" +
+                            $"将数据分为:{field - 1} 次处理,每次处理500-1000条数据。", GroupNames.醍摩豆服務運維群組);
+                    }
+                    //key存在的时候 开始进行数据处理
+                    var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"LessonRecord:Unused:Lock:{location}");
+                    List<UnusedLock> unuseds = new List<UnusedLock>();
+                    foreach (var rcd in records)
+                    {
+                        var value = rcd.Value.ToString().ToObject<UnusedLock>();
+                        unuseds.Add(value);
+                    }
+                    int max = unuseds.Max(x => x.field);
+                    int index = max + 1;
+                    var unusedLock = unuseds.Where(s => s.status == 0)?.OrderBy(x => x.field)?.First();
+                    if (unusedLock != null)
+                    {
+                        var stime = DateTimeOffset.UtcNow;
+                        long s = stime.ToUnixTimeMilliseconds();
+                        string sdata = stime.ToString("yyyy-MM-dd HH:mm:ss");
+                        await _dingDing.SendBotMsg($"{location}-开始第{unusedLock.field}轮清理冗余的课例记录文件...\n开始时间:{sdata}\n清理容器有{unusedLock.item.Select(x => $"{x.name}-{x.id}").ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                        //将当前的标记为1锁定。
+                        bool stuallstatus = await _azureRedis.GetRedisClient(8).HashSetAsync($"LessonRecord:Unused:Lock:{location}", unusedLock.field,
+                                   new UnusedLock { field = unusedLock.field, status = 1, item = unusedLock.item }.ToJsonString());
+                        List<KeyValuePair<string, List<string>>> deleteUrls = new List<KeyValuePair<string, List<string>>>();
+                        foreach (IdCodeCount idCode in unusedLock.item)
+                        {
+                            try
+                            {
+                                List<string> urls = new List<string>();
+                                var ContainerClient = _azureStorage.GetBlobContainerClient(idCode.id);
+                                List<string> items = await ContainerClient.List("records");
+                                if (items.IsNotEmpty())
+                                {
+                                    HashSet<string> set = new HashSet<string>();
+                                    items.ForEach(z => {
+                                        var uri = z.Split("/");
+                                        if (uri.Length > 1)
+                                        {
+                                            set.Add(uri[1]);
+                                        }
+                                    });
+                                    if (set.Any())
+                                    {
+                                        string tbname = idCode.code.Equals("Teacher") ? Constant.Teacher : Constant.School;
+                                        string pk = idCode.code.Equals("Teacher") ? "LessonRecord" : $"LessonRecord-{idCode.id}";
+                                        string sql = $"select value c.id from c where c.pk='LessonRecord' and  c.id in ({string.Join(",", set.Select(m => $"'{m}'"))})";
+                                        List<string> ids = new List<string>();
+                                        await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname)
+                                            .GetItemQueryIterator<string>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey(pk) }))
+                                        {
+                                            ids.Add(item);
+                                        }
+                                        var notin = set.Except(ids);
+
+                                        if (notin.Any())
+                                        {
+                                            foreach (var not in notin)
+                                            {
+                                                if (!string.IsNullOrWhiteSpace(not)) {
+                                                    string url = $"records/{not}";
+                                                    long id = -1;
+                                                    long.TryParse(not, out id);
+                                                    if (id > -1)
+                                                    {
+                                                        id = _snowflakeId.ParseIdToTimeStamp(id);
+                                                    }
+                                                    if (id > -1)
+                                                    {
+                                                        //72小时之外的数据。需要被删除 72 * 60 * 60 *1000= 259200000
+                                                        //当前时间-课例产生的时间戳
+                                                        if (s - id > 259200000)
+                                                        {
+                                                            urls.Add(url);
+                                                            await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, idCode.id, new List<string> { url });
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                if (urls.IsNotEmpty()) {
+                                    deleteUrls.Add(new KeyValuePair<string, List<string>>($"{idCode.name}-{idCode.id}", urls));
+                                }
+                            }
+                            catch (Exception ex)
+                            {
+                                //异常的学校,需要将数据放回redis 重新处理。
+                                await _azureRedis.GetRedisClient(8).HashSetAsync($"LessonRecord:Unused:Lock:{location}", index,
+                                   new UnusedLock { field = index, status = 0, item = new List<IdCodeCount>() { idCode } }.ToJsonString());
+                                index += 1;
+                                await _dingDing.SendBotMsg($"{location}-第{unusedLock.field}轮清理时容器:{idCode.id},类型:{idCode.code}出现异常。\n将{idCode.id}重新加入队列,队列编号:{index}\n" +
+                                    $"异常信息:{ex.Message},{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                            }
+                        }
+                        await _azureRedis.GetRedisClient(8).HashDeleteAsync($"LessonRecord:Unused:Lock:{location}", unusedLock.field);
+                        var etime = DateTimeOffset.UtcNow;
+                        long e = etime.ToUnixTimeMilliseconds();
+                        string edata = etime.ToString("yyyy-MM-dd HH:mm:ss");
+                        long d = (e - s) / 1000;
+                        string timeStr = d >= 60 ? Math.Round(d / 60.0) + "分" : d + "秒";
+                        List<string> content = new List<string>();
+                        foreach (var url in deleteUrls)
+                        {
+                            if (url.Value.IsNotEmpty()) {
+                                content.Add($"{url.Key}\n   {string.Join("  \t\n", url.Value)}");
+                            }
+                        }
+                        if (content.IsNotEmpty())
+                        {
+                            string str = string.Join("\n", content);
+                            await _dingDing.SendBotMsg($"{location}-结束第{unusedLock.field}轮清理冗余的课例记录文件...\n结束时间:{edata}\n耗时:{timeStr}\n清理内容:\n{str}", GroupNames.醍摩豆服務運維群組);
+                        }
+                        else {
+                          //  await _dingDing.SendBotMsg($"{location}-结束第{unusedLock.field}轮清理冗余的课例记录文件...\n结束时间:{edata}\n耗时:{timeStr}\n清理内容:暂无", GroupNames.醍摩豆服務運維群組);
+                        }
+                    }
+                }
+            } catch (Exception ex) {
+                await _dingDing.SendBotMsg($"{location} 清理时容器出现异常。\n异常信息:{ex.Message},{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+            }
+        }
 
+        public class UnusedLock { 
+            public int field { get; set; }
+            /// <summary>
+            /// 0默认未被执行,1 正在执行中
+            /// </summary>
+            public int status { get; set; }
+            public IEnumerable<IdCodeCount> item { get; set; } = new List<IdCodeCount>();
+        }
+        public class IdCodeCount { 
+            public string id { get; set; }
+            public string name { get; set; }
+            public string code { get; set; }
+            public int count { get; set; }
         }
     }
 }

+ 22 - 0
TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeID.cs

@@ -125,6 +125,28 @@ namespace TEAMModelOS.SDK.DI
             return sb.ToString();
         }
 
+        /// <summary>
+        /// 解析分散式ID,并转换为时间字符串。
+        /// </summary>
+        /// <returns></returns>
+        public string ParseIdToTimeString(long Id, string format = "yyyy-MM-dd HH:mm:ss")
+        {
+            
+            var timestamp = (Id >> timestampLeftShift);
+            var time = Jan1st1970.AddMilliseconds(timestamp + twepoch);
+            string timeString= time.ToLocalTime().ToString(format);
+            return timeString;
+        }
+        /// <summary>
+        /// 解析分散式ID,并转换为时间戳。
+        /// </summary>
+        /// <returns></returns>
+        public long ParseIdToTimeStamp(long Id)
+        {
+            var timestamp = (Id >> timestampLeftShift);
+            long stime = timestamp + twepoch;
+            return stime;
+        }
         /// <summary>
         /// 阻塞到下一個毫秒,直到獲得新的時間戳
         /// </summary>

+ 27 - 0
TEAMModelOS.SDK/Helper/Common/TaskAll/BatchTask.cs

@@ -51,5 +51,32 @@ namespace TEAMModelOS.SDK
                 }
             }
         }
+
+
+        public static   List<IEnumerable<T>> Page<T>(this IEnumerable<T> tasks, int pagesize)
+        {
+            if (tasks != null  && tasks.Any())
+            {
+                if (tasks.Count() <= pagesize)
+                {
+                    return new List<IEnumerable<T>> { tasks };
+                }
+                else
+                {
+                    List<IEnumerable<T>> ts = new List<IEnumerable<T>>();
+                    int pages = (tasks.Count() + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
+                    for (int i = 0; i < pages; i++)
+                    {
+                        var lists = tasks.Skip((i) * pagesize).Take(pagesize).ToList();
+                        ts.Add(lists);
+                    }
+                    return ts;
+                }
+            }
+            else
+            {
+                return new List<IEnumerable<T>> ();
+            }
+        }
     }
 }

+ 5 - 1
TEAMModelOS.SDK/Helper/Network/IP2Region/IPSearcher.cs

@@ -380,7 +380,11 @@ namespace TEAMModelOS.SDK
                 DataBlock block = await MemorySearchAsync(ip);
                 if (block != null)
                 {
-                    string region = block.Region.Replace("0|0|0|0|", "").Replace("0|0|0|", "").Replace("|0|0|0|0", "").Replace("|0|0|0|", "").Replace("|0|0|0", "").Replace("|0|0|", "").Replace("|0|0", "").Replace("|0|", "¡¤").Replace("|0", "").Replace("|", "¡¤");
+                    string region = block.Region.Replace("0|0|0|0|", "").Replace("0|0|0|", "").Replace("|0|0|0|0", "").Replace("|0|0|0|", "").Replace("|0|0|0", "").Replace("|0|0|", "").Replace("|0|0", "").Replace("|0|", "·").Replace("|0", "").Replace("|", "·");
+                    if (!string.IsNullOrWhiteSpace(region))
+                    {
+                        region = region.Replace("中国·", "").Replace("中国", "").Replace("�湾�", "�湾");
+                    }
                     return region;
                 }
                 else { return null; }

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/BI/BICommon/MonthStartEnd.cs

@@ -70,7 +70,7 @@ namespace TEAMModelOS.SDK.Models
     {
         public string name { get; set; }
         public int lessCnt { get; set; }
-        public int interCnt { get; set; }
+        public double interCnt { get; set; }
         public int actCnt { get; set; }
     }
 

+ 5 - 0
TEAMModelOS.SDK/Models/Cosmos/BI/StaticValue.cs

@@ -14,6 +14,11 @@ namespace TEAMModelOS.SDK.Models.Cosmos.BI
         /// </summary>
         public static List<string> suffixName = new() { ".js", ".css", ".ico", ".aspx", ".php", ".aws", ".html" };
 
+        /// <summary>
+        /// 文件类型 cosmosDB
+        /// </summary>
+        public static List<string> fileType = new() { "audio", "doc", "image", "other", "records", "res", "video"};
+
 
     }
 }

+ 15 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/GroupList.cs

@@ -84,6 +84,10 @@ namespace TEAMModelOS.SDK.Models
         /// 个人名单是否开放 加入。0 不允许,1 允许。
         /// </summary>
         public int joinLock { get; set; } = 1;
+        /// <summary>
+        ///补充毕业0在校,1毕业 
+        /// </summary>
+        public int graduate { get; set; } = 0;
     }
 
     public class  Member
@@ -112,6 +116,9 @@ namespace TEAMModelOS.SDK.Models
         public string groupId { get; set; }
         public string groupName { get; set; }
         public string nickname { get; set; }
+        //补充毕业
+        //0在校,1毕业 
+        public int graduate { get; set; } = 0;
     }
     
     public class RMember
@@ -161,6 +168,9 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public string groupName { get; set; }
         public string nickname { get; set; }
+        //补充毕业
+        //0在校,1毕业 
+        public int graduate { get; set; } = 0;
 
     }
     public class GroupListGrp
@@ -219,6 +229,9 @@ namespace TEAMModelOS.SDK.Models
         /// 个人名单是否开放 加入。0 不允许,1 允许。
         /// </summary>
         public int joinLock { get; set; } =1;
+        //补充毕业
+        //0在校,1毕业 
+        public int graduate { get; set; } = 0;
     }
 
     public class GroupListDtoImpt {
@@ -263,6 +276,8 @@ namespace TEAMModelOS.SDK.Models
         /// 个人名单是否开放 加入。0 不允许,1 允许。
         /// </summary>
         public int joinLock { get; set; } = 1;
+        //0在校,1毕业 
+        public int graduate { get; set; } = 0;
     }
     public class CourseGroupList
     {

+ 9 - 4
TEAMModelOS.SDK/Models/Cosmos/School/Class.cs

@@ -51,22 +51,27 @@ namespace TEAMModelOS.SDK.Models
         /// TBL IRS 类型区分
         /// </summary>
         //public string style { get; set; }
-        public int status { get; set; } = 1;        
+        
         /// <summary>
         /// 关联教室的id
         /// </summary>
         public string room { get; set; }
         //学校编码
         public string school { get; set; }
+
         /// <summary>
         /// 教室属性,普通 /专设的教室
         /// </summary>
         //public string openType { get; set; }
-       // public string scope { get; set; }
+        // public string scope { get; set; }
         /// <summary>
         /// 学生名单数据来源 1是不同学校的学生账号,2是扫码加入的醍摩豆ID
         /// </summary>
-        //public int? source { get; set; }
-        
+        ///public int? source { get; set; }
+
+        /// <summary>
+        ///补充毕业0在校,1毕业 
+        /// </summary>
+        public int graduate { get; set; } = 0;
     }
 }

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

@@ -48,10 +48,10 @@ namespace TEAMModelOS.SDK.Models
         /// 性别 M( male,男) F (female 女)  N(secret 保密) 
         /// </summary>
         public string gender { get; set; }
-        
+
         //补充留级信息
-        //0在校,1留级,2退学 3毕业
-        public int status { get; set; } = 0;
+        //0在校,1毕业 
+        public int graduate { get; set; } = 0;
         /// <summary>
         /// 保留当天的登录信息
         /// </summary>

+ 155 - 22
TEAMModelOS.SDK/Models/Service/GroupListService.cs

@@ -71,8 +71,9 @@ namespace TEAMModelOS.SDK
         /// <param name="memberType">成员类型</param>
         /// <param name="school">成员所在的学校 ,可为空</param>
         /// <param name="groupTypes">过滤名单的类型集合,不传则是全部</param>
+        /// <param name="graduate">毕业类型0在校,1毕业 , -1查全部。</param>
         /// <returns></returns>
-        public static async Task<List<GroupListGrp>> GetMemberInGroupList(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, DingDing _dingDing, string memberId, int memberType, string school,List<string> groupTypes) {
+        public static async Task<List<GroupListGrp>> GetMemberInGroupList(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, DingDing _dingDing, string memberId, int memberType, string school,List<string> groupTypes,int graduate =-1) {
 
             List<GroupListGrp> groupLists = new List<GroupListGrp>();
             if (groupTypes.IsEmpty() || groupTypes.Contains("class")) {
@@ -105,8 +106,20 @@ namespace TEAMModelOS.SDK
                                 type = "class",
                                 no = clazz.no,
                                 leader = clazz.teacher?.id,
+                                graduate=clazz.graduate,
                             };
-                            groupLists.Add(groupList);
+                            //graduate传入的状态>=0 表示指定状态查询,且传入的状态与数据库的状态一致。
+                            if (graduate >= 0   )
+                            {
+                                if (groupList.graduate == graduate) {
+                                    groupLists.Add(groupList);
+                                }
+                            }
+                            //全部。
+                            else if(graduate == -1)
+                            {
+                                groupLists.Add(groupList);
+                            }
                         }
                         catch (CosmosException ex) when (ex.Status == 404)
                         {
@@ -499,8 +512,18 @@ namespace TEAMModelOS.SDK
             }
             return list;
         }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="client"></param>
+        /// <param name="_dingDing"></param>
+        /// <param name="classes"></param>
+        /// <param name="school"></param>
+        /// <param name="SummarySql"></param>
+        /// <param name="graduate">毕业类型0在校,1毕业 , -1查全部。</param>
+        /// <returns></returns>
         public static async Task<List<GroupListDto>> GetGroupListListids(CosmosClient client, DingDing _dingDing, List<string> classes, string school,
-            string SummarySql = " c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.leader ,c.froms ,c.joinLock ")
+            string SummarySql = " c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.leader ,c.froms ,c.joinLock " ,int graduate = -1)
         {
             classes.RemoveAll(x => x == null);
             if (!classes.IsNotEmpty()) {
@@ -551,7 +574,7 @@ namespace TEAMModelOS.SDK
                         string insql = string.Join(",", classes.Select(x => $"'{x}'"));
                         //搜寻没有关联学生的行政班
                         await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupListDto>(queryText: 
-                            $"select   c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
+                            $"select   c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader ,c.graduate from c where c.id in ({insql})",
                                 requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
                         {
                             ///行政班(学生搜寻classId动态返回)class
@@ -568,8 +591,22 @@ namespace TEAMModelOS.SDK
                                 leader = item.leader,
                                 no = item.no,
                                 pk = "GroupList",
+                                graduate = item.graduate
                             };
-                            groupLists.Add(group);
+                            //graduate传入的状态>=0 表示指定状态查询,且传入的状态与数据库的状态一致。
+                            if (graduate >= 0)
+                            {
+                                if (group.graduate == graduate)
+                                {
+                                    groupLists.Add(group);
+                                }
+                            }
+                            //全部。
+                            else 
+                            {
+                                groupLists.Add(group);
+                            }
+                          //  groupLists.Add(group);
                         }
                         //取差集,减少二次搜寻
                         classes = classes.Except(groupLists.Select(y => y.id)).ToList();
@@ -623,7 +660,19 @@ namespace TEAMModelOS.SDK
             }
             return groupLists;
         }
-        public static async Task<(List<RMember>, List<RGroupList> groups)> GetStutmdidListids(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, DingDing _dingDing, List<string> classes, string school, List<(string, List<string>)> groupids = null)
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="_coreAPIHttpService"></param>
+        /// <param name="client"></param>
+        /// <param name="_dingDing"></param>
+        /// <param name="classes"></param>
+        /// <param name="school"></param>
+        /// <param name="groupids"></param>
+        /// <param name="graduate">毕业类型0在校,1毕业 , -1查全部。</param>
+        /// <returns></returns>
+        public static async Task<(List<RMember>, List<RGroupList> groups)> GetStutmdidListids(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, DingDing _dingDing, 
+            List<string> classes, string school, List<(string, List<string>)> groupids = null,  int graduate = -1)
         {
             List<RMember> members = new List<RMember>();
             List<RGroupList> groupLists = new List<RGroupList>();
@@ -639,7 +688,9 @@ namespace TEAMModelOS.SDK
             {
                 //默认的教研组
                 members = new List<RMember>();
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdInfo>(queryText: $"SELECT  c.id,c.name,c.picture  FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
+                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
+                    GetItemQueryIterator<TmdInfo>(queryText: $"SELECT  c.id,c.name,c.picture  FROM c ", 
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
                 {
                     RMember member = new RMember
                     {
@@ -690,7 +741,20 @@ namespace TEAMModelOS.SDK
                         await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select value(c) from c where c.classId in ({sql})",
                             requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{school}") }))
                         {
-                            students.Add(item);
+                            //graduate传入的状态>=0 表示指定状态查询,且传入的状态与数据库的状态一致。
+                            if (graduate >= 0)
+                            {
+                                if (item.graduate == graduate)
+                                {
+                                    students.Add(item);
+                                }
+                            }
+                            //全部。
+                            else  
+                            {
+                                students.Add(item);
+                            }
+                            //  students.Add(item);
                         }
                         //取差集,减少二次搜寻
                         classes = classes.Except(students.Select(y => y.classId)).ToList();
@@ -700,7 +764,7 @@ namespace TEAMModelOS.SDK
                         string insql = string.Join(",", classes.Select(x => $"'{x}'"));
                         //搜寻没有关联学生的行政班
                         await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School")
-                            .GetItemQueryIterator<RGroupList>(queryText: $"select  c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader    from c where c.id in ({insql})",
+                            .GetItemQueryIterator<RGroupList>(queryText: $"select  c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader ,c.graduate   from c where c.id in ({insql})",
                                 requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
                         {
                             ///行政班(学生搜寻classId动态返回)class
@@ -720,8 +784,24 @@ namespace TEAMModelOS.SDK
                                 pk = "GroupList",
                                 leader = item.leader,
                                 no = item.no,
+                                graduate = item.graduate
                             };
-                            groupLists.Add(group);
+
+                            //graduate传入的状态>=0 表示指定状态查询,且传入的状态与数据库的状态一致。
+                            if (graduate >= 0)
+                            {
+                                if (group.graduate == graduate)
+                                {
+                                    groupLists.Add(group);
+                                }
+                            }
+                            //全部。
+                            else  
+                            {
+                                groupLists.Add(group);
+                            }
+
+                            //groupLists.Add(group);
                         }
                         //取差集,减少二次搜寻
                         classes = classes.Except(groupLists.Select(y => y.id)).ToList();
@@ -765,7 +845,7 @@ namespace TEAMModelOS.SDK
                     var list = item.Value.GroupBy(x => x.type).Select(y => new { key = y.Key, list = y.ToList() });
                     foreach (var group in list)
                     {
-                        (List<RGroupList> rgroups, List<RMember> rmembers) = await GetGroupListMemberInfo(_coreAPIHttpService, client, group.key, group.list, item.Key, _dingDing, school);
+                        (List<RGroupList> rgroups, List<RMember> rmembers) = await GetGroupListMemberInfo(_coreAPIHttpService, client, group.key, group.list, item.Key, _dingDing, school,graduate);
                         members.AddRange(rmembers);
                     }
                 }
@@ -775,7 +855,7 @@ namespace TEAMModelOS.SDK
                     List<string> sqlList = students.Select(x => x.classId).ToList();
                     string insql = string.Join(",", sqlList.Select(x => $"'{x}'"));
                     await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
-                        GetItemQueryIterator<RGroupList>(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
+                        GetItemQueryIterator<RGroupList>(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader  ,c.graduate from c where c.id in ({insql})",
                               requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
                     {
                         ///行政班(学生搜寻classId动态返回)class
@@ -793,7 +873,7 @@ namespace TEAMModelOS.SDK
                                 //groupId=y.groupId,
                                 groupName = y.groupName,
                                 irs = y.irs,
-                                
+                                graduate = y.graduate,
                             }).ToList();
                         members.AddRange(smembers);
 
@@ -811,9 +891,23 @@ namespace TEAMModelOS.SDK
                             scount = smembers.Count,
                             no = item.no,
                             leader = item.leader,
-                            pk = "GroupList"
+                            pk = "GroupList",
+                            graduate = item.graduate
                         };
-                        groupLists.Add(group);
+                        //graduate传入的状态>=0 表示指定状态查询,且传入的状态与数据库的状态一致。
+                        if (graduate >= 0)
+                        {
+                            if (group.graduate == graduate)
+                            {
+                                groupLists.Add(group);
+                            }
+                        }
+                        //全部。
+                        else  
+                        {
+                            groupLists.Add(group);
+                        }
+                       // groupLists.Add(group);
                     }
                     //去重。
                     members = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
@@ -858,7 +952,18 @@ namespace TEAMModelOS.SDK
                 return (members, groupLists);
             }
         }
-        public static async Task<List<RGroupList>> GetGroupListMemberByType(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, string type, List<string> scopes, string school, DingDing _dingDing)
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="_coreAPIHttpService"></param>
+        /// <param name="client"></param>
+        /// <param name="type"></param>
+        /// <param name="scopes"></param>
+        /// <param name="school"></param>
+        /// <param name="_dingDing"></param>
+        /// <param name="graduate">毕业类型0在校,1毕业 , -1查全部。</param>
+        /// <returns></returns>
+        public static async Task<List<RGroupList>> GetGroupListMemberByType(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, string type, List<string> scopes, string school, DingDing _dingDing, int graduate = -1)
         {
             StringBuilder sql = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='{type}'");
 
@@ -908,13 +1013,26 @@ namespace TEAMModelOS.SDK
                 var list = item.Value.GroupBy(x => x.type).Select(y => new { key = y.Key, list = y.ToList() });
                 foreach (var group in list)
                 {
-                    (List<RGroupList> rgroups, List<RMember> rmembers) = await GetGroupListMemberInfo(_coreAPIHttpService, client, group.key, group.list, item.Key, _dingDing, school);
+                    (List<RGroupList> rgroups, List<RMember> rmembers) = await GetGroupListMemberInfo(_coreAPIHttpService, client, group.key, group.list, item.Key, _dingDing, school,graduate);
                 }
             }
             var lists = groups.SelectMany(x => x.Value).ToList();
             return lists;
         }
-        public static async Task<(List<RGroupList> groups, List<RMember> members)> GetGroupListMemberInfo(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, string type, List<RGroupList> groups, string groupTbname, DingDing _dingDing, string school)
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="_coreAPIHttpService"></param>
+        /// <param name="client"></param>
+        /// <param name="type"></param>
+        /// <param name="groups"></param>
+        /// <param name="groupTbname"></param>
+        /// <param name="_dingDing"></param>
+        /// <param name="school"></param>
+        /// <param name="graduate">毕业类型0在校,1毕业 , -1查全部。</param>
+        /// <returns></returns>
+        public static async Task<(List<RGroupList> groups, List<RMember> members)> GetGroupListMemberInfo(CoreAPIHttpService _coreAPIHttpService, CosmosClient client, 
+            string type, List<RGroupList> groups, string groupTbname, DingDing _dingDing, string school, int graduate = -1)
         {
 
             try
@@ -933,7 +1051,7 @@ namespace TEAMModelOS.SDK
                         var ids = item.list.Select(x => x.id).ToList();
                         if (ids.IsNotEmpty())
                         {
-                            StringBuilder stuSql = new StringBuilder($"SELECT distinct c.name,c.id,c.code,c.picture,c.no,c.irs,c.classId FROM c ");
+                            StringBuilder stuSql = new StringBuilder($"SELECT distinct c.name,c.id,c.code,c.picture,c.no,c.irs,c.classId ,c.graduate FROM c ");
                             string insql = string.Join(",", ids.Select(x => $"'{x}'"));
                             stuSql.Append($"where  c.id in ({insql})");
                             await foreach (var student in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: stuSql.ToString(),
@@ -1104,6 +1222,7 @@ namespace TEAMModelOS.SDK
                    // x.nickname = string.IsNullOrWhiteSpace(x.nickname) ? student?.name:x.nickname;
                     x.picture = student?.picture;
                     x.classId = student?.classId;
+                    x.graduate = student.graduate;
                 });
                 var mbs = tmdids;
                 mbs.AddRange(students);
@@ -1132,6 +1251,7 @@ namespace TEAMModelOS.SDK
                       //  y.nickname =  string.IsNullOrWhiteSpace(y.nickname) ? student?.nickname : y.nickname; 
                         y.picture = student?.picture;
                         y.classId = student?.classId;
+                        y.graduate = student.graduate;
                     }
                 }));
 
@@ -1152,7 +1272,22 @@ namespace TEAMModelOS.SDK
                         });
                     }
                 }
-                return (groups, mbs);
+                if (graduate >= 0)
+                {
+                    groups= groups.FindAll(x => x.graduate == graduate);
+                    if (groups != null) {
+                        groups.ForEach(x =>
+                        {
+                            x.members.RemoveAll(y => y.graduate != graduate);
+                        });
+                    }
+                    mbs.RemoveAll(z => z.graduate != graduate);
+                }
+                //直接返回
+                else {
+                    return (groups, mbs);
+                }
+              
             }
             catch (Exception ex)
             {
@@ -1160,8 +1295,6 @@ namespace TEAMModelOS.SDK
             }
             return (null, null);
         }
-
-
     }
 
 

+ 0 - 3
TEAMModelOS.SDK/Models/Service/LoginService.cs

@@ -359,9 +359,6 @@ namespace TEAMModelOS.SDK.Models.Service
             }
             string ip = IpPort.Split(":")[0];
             string region = await _searcher.SearchIpAsync(ip);
-            if (!string.IsNullOrWhiteSpace(region)) {
-                region = region.Replace("中国·", "").Replace("中国", "").Replace("台湾省", "台湾");
-            }
             return (ip, region);
         }
 

+ 81 - 125
TEAMModelOS/ClientApp/public/lang/en-US.js

@@ -1,18 +1,18 @@
 const LANG_EN_US = {
     assessment: {
-        moreCond: '選擇更多條件',
-        unit1: '',
-        unit2: '',
+        moreCond: 'Select more criteria',
+        unit1: 'Total',
+        unit2: 'People',
         good: 'Excellent',
         normal: 'Qualified',
         bad: 'Unqualified',
-        noStart: '未進行',
-        export: '導出',
-        open: '展開',
-        close: '收起',
-        otherAppraise: '互評',
-        on: '開啟',
-        off: '關閉',
+        noStart: 'Not Done',
+        export: 'Export',
+        open: 'Expand',
+        close: 'Close',
+        otherAppraise: 'Mutual Evaluation',
+        on: 'On',
+        off: 'Off',
         toProvince: '推送省平臺',
         noData: '當前條件下未匹配到教師數據',
         noGroup: '未分組',
@@ -25,20 +25,20 @@ const LANG_EN_US = {
         minute: 'minutes',
         noSubmitNum: '未提交數',
         noAbility: '暫無認證材料記錄',
-        selfAppraise: '自評',
-        schoolAppraise: '校評',
+        selfAppraise: 'Self-evaluation',
+        schoolAppraise: 'School-evaluation',
         finalName: '最後評價人',
         finalTime: '最後評價時間',
-        noSchoolAppraise: '暫無校評數據',
+        noSchoolAppraise: 'No school-evaluation data yet',
         comment: '已評論',
         tip1: '教師未提交認證材料,無法評審',
         tip2: '前往評審教師提交的認證材料',
         goAppraise: '去評審',
         noOffline: 'No school study records yet',
-        hasPdf: '已提交PDF',
-        noPdf: '未提交PDF',
-        hasUpload: '已上傳',
-        noUpload: '未上傳',
+        hasPdf: 'PDF submitted',
+        noPdf: 'PDF not submitted',
+        hasUpload: 'Uploaded',
+        noUpload: 'Not Uploaded',
         noVideo: '暫未上傳課堂實錄',
         reAppraise: '重新評審',
         commentDetails: '評論詳情',
@@ -53,15 +53,15 @@ const LANG_EN_US = {
         tip4: '最少有',
         tip5: '個能力點的認證材料合格即可獲得學時',
         tip6: '認證材料必須全部通過才能獲得學時',
-        allNormal: '全部合格',
+        allNormal: 'All Qualified',
         tip7: 'According to the requirements of the provincial platform, teachers must meet the following conditions to receive Study Length for school study activities: 1. At least one school study activity in ten Study Length requires submission of homework. 2. Successful submission of PDF homework in the activity',
-        allPass: '全部通過',
-        tip8: '教師提交課堂實錄併且考核通過後即可獲得5學時',
+        allPass: 'All Pass',
+        tip8: '教師提交課堂實錄並且審核通過後即可獲得5學時',
         atName: '被評價人',
         type: 'Evaluation Type',
         score: 'Evaluation Results',
         time: '評論時間',
-        header1: '姓名',
+        header1: 'Name',
         header2: '總學時',
         header3: '線上研修學時',
         header4: '未修滿能力點',
@@ -88,7 +88,7 @@ const LANG_EN_US = {
         tip14: '設置失敗!',
         tip15: '當前教師暫未上傳活動pdf作業,無法通過!',
         tip16: '操作成功!',
-        tip17: '確認將所有教師參與的 不需要提交的 以及 需要且已經提交PDF 的研修活動全部設置為通過嗎?',
+        tip17: '確認將所有教師參與的 不需要提交的 以及 需要且已經提交PDF 的研修活動全部設置為通過嗎?',
         tip18: '確認將所有教師已經自評過的微能力點全部設置為合格嗎?',
         tip19: '操作失敗!',
         tip20: '確認將所有教師已提交的課堂實錄全部設置為合格嗎?',
@@ -99,21 +99,23 @@ const LANG_EN_US = {
     },
     // 研修模块
     ability: {
-        reSubmit: '重新提交',
+        reSubmit: 'Resubmit',
         samePointAppraise: 'Competency Mutual Evaluation',
         otherResult: 'Mutual Evaluation Results',
         schoolResult: 'School-evaluation Results',
         noCount: ' (Not counted as Study Length)',
-        checkMan: '考核人員',
-        appraiseTip1: '學校暫未開啟互評!請聯繫學校管理員處理!',
+        checkMan: 'Reviewer',
+        appraiseTip1: 'The school has not opened mutual evaluation yet! Please contact the school administrator.',
         appraiseTip2: '請優先對互評次數為0的老師進行互評!',
         check: {
-            isCheck: '是否为考核人员',
-            tip1: '确认修改当前教师的審核人员身份吗?',
-            tip2: '已添加',
-            tip3: '为審核人员',
-            tip4: '已取消',
-            tip5: '的審核人员身份!',
+            joinMan: 'Trainee',
+            checkMan: 'Inspector',
+            isCheck: 'Whether a reviewer',
+            tip1: 'Do you confirm to change this teacher reviewer status?',
+            tip2: 'Added ',
+            tip3: 'as a reviewer',
+            tip4: '',
+            tip5: 'has been removed as a reviewer!',
         },
         points: {
             doc: '文檔類',
@@ -181,8 +183,8 @@ const LANG_EN_US = {
         fileName: '評審結果統計',
         noSpot: '未抽查',
         defaultGroup: '默認組別',
-        appraiseOther: '互評',
-        appraiseSelf: '自評',
+        appraiseOther: 'Mutual Evaluation',
+        appraiseSelf: 'Self-evaluation',
         appraiseTip: '您自己的材料只能由其它管理員進行評價!',
         allAbilities: '全部能力點',
         review: {
@@ -484,8 +486,8 @@ const LANG_EN_US = {
         classroom: 'Classroom:',
         expiredData: 'Expiry Date:',
         hadExp: '(Expired)',
-        unused: '(None activate)',
-        forever: '(Permanent License)',
+        unused: '(Not activated)',
+        forever: '(Permanent)',
         useInfo: 'Use Status:',
         unband: 'Unbind Device',
         cancel: 'Cancel',
@@ -1036,7 +1038,7 @@ const LANG_EN_US = {
         cc7: 'Personal',
         cc8: 'No HiTeach CC access: You have not joined a school yet',
         cc9: 'No HiTeach CC access: The school has not yet purchased authorization',
-        filterExp:'Filter is about to expire',
+        filterExp: 'Filter is about to expire',
 
         //ManageClass.vue
         stuMgt: 'Student Management',
@@ -1152,6 +1154,36 @@ const LANG_EN_US = {
         cusNameRepeat: 'The same course name already exists',
         noClassInfo: 'No class information found yet',
         noRoomInfo: 'No classroom information found yet',
+        cusImp1: 'Template for importing course:',
+        cusImp2: "Notice: If there is a teacher with the same name in the school, please use the teacher's TEAM Model user ID to import for the teacher field. ",
+        cusImp3: 'Inconsistent course basic information',
+        cusImp4: 'Missing course required information',
+        cusImp5: 'Missing instructor/teacher information',
+        cusImp6: 'Repetition of current course instructors/teachers',
+        cusImp7: 'Incorrect or non-existent instructor/teacher name',
+        cusImp8: 'Incorrect or non-existent subject name',
+        cusImp9: 'Incorrect or non-existent class name',
+        cusImp10: 'Confirm Import',
+        cusImp11: 'Re-import',
+        cusImp12: 'Go back to Course Management',
+        cusImp13: "subject: Course's Subject (required). The imported subjects need to be preset in the School Basic Settings",
+        cusImp14: 'course: Course Name (required). If the imported course already exists in the school, the course data will be updated; if the imported course does not exist, a new course will be created',
+        cusImp15: 'courseNo: Course ID (optional)',
+        cusImp16: 'courseDesc: Course Description (optional)',
+        cusImp17: 'teacher: Instructor/Teacher (optional). If multiple teachers teach the same course, you need to copy the course information and create an additional row',
+        cusImp18: 'classes: Class (optional). If there are multiple classes taught by the teacher, use commas to separate them.',
+        cusImp19: 'Subject',
+        cusImp20: 'Course',
+        cusImp21: 'Course ID',
+        cusImp22: 'Course Description',
+        cusImp23: 'Instructor/Teacher ',
+        cusImp24: 'Class',
+        cusImp25: 'Abnormal Information',
+        cusImp26: 'Please check the table data',
+        cusImp27: 'Please check if the table information is correct',
+        cusImp28: 'Imported successfully',
+        cusImp29: 'The imported fields are incomplete, please check the imported data',
+
 
         //MgtStuList.vue
         nameList: 'Name list',
@@ -2267,7 +2299,7 @@ const LANG_EN_US = {
             error1: "Failed to start",
             message1: "Switch to my topic",
             message2: "Switch to reply to my topic",
-            report: ["Illegal info", "Pornography info", "Privacy disclosure", "Personal attack", "Spam marketing"],
+            report: ["Illegal Content", "Sexsual Content", "Privacy Disclosure", "Personal Attack", "Spam"],
         },
         // 活动
         activity: {
@@ -2320,8 +2352,8 @@ const LANG_EN_US = {
             tips: "Your study has been completed, go fill out the summary.",
             compulsory: "Required",
             electiveCourse: "Competency",
-            sendSummary: "填寫研修總結",
-            plaSummary: "請填寫您的研修總結",
+            sendSummary: "Fill out study summary",
+            plaSummary: "Please fill in your study summary",
             openReport: "View report",
             message5: "All certification materials must be passed to receive credits",
         }
@@ -3314,8 +3346,8 @@ const LANG_EN_US = {
         formErr: 'Please check if the information is filled out correctly and completely',
         imgTips: 'Note:The image format only supports jpg, jpeg, png; the size of the image cannot exceed 1M; the file name cannot contain special characters.',
         ptText: 'Resource Platform Link',
-        text1: 'District Resource Sites',
-        text2: 'School Resource Sites',
+        text1: 'District Resource Platform',
+        text2: 'School Resource Platform',
     },
     // 注册相关
     regist: {
@@ -5916,7 +5948,7 @@ const LANG_EN_US = {
         PLAnswerRate: 'High Group Correct Rate',
         R1R6LineTitle: 'R1-R6 Answering Curve',
         noKnowPointTip: 'No key concept data was collected under this subject',
-        lostStu: 'Absentee Number',
+        lostStu: 'Absentee No.',
         showAnalysis: 'Data Analysis',
         allSubjects: 'All Subject',
         noData: 'No valid data yet!',
@@ -5971,8 +6003,8 @@ const LANG_EN_US = {
         echarts_text9: 'Current Grade',
         echarts_text10: 'Filter',
         echarts_text11: 'Test Time',
-        echarts_text12: 'Participant Number',
-        echarts_text13: 'Actual number of participants',
+        echarts_text12: 'Participant No.',
+        echarts_text13: 'Actual No. of participants',
         echarts_text14: 'Participation Rate',
         echarts_text15: 'Average Score',
         echarts_text16: 'Achievement Index',
@@ -6361,82 +6393,6 @@ const LANG_EN_US = {
             address: 'Venue:',
             time: 'Time:',
             noTrain: 'No school study activities yet',
-        },
-        detail: {
-            back: '返回研修總覽',
-            hour: 'Study Length',
-            presenter: 'Speaker:',
-            topic: 'Theme:',
-            address: 'Venue:',
-            time: 'Time:',
-            delete: 'Delete',
-            checkHour: '學時審核',
-            pass: '通過',
-            fail: '不通過',
-            checkStatus1: '未審核',
-            checkStatus2: '已通過',
-            checkStatus3: '未通過',
-            signLable: '簽到詳情',
-            signStatus1: '已簽到',
-            signStatus2: '遲到',
-            signStatus3: '未簽到',
-            hwLabel: '作業詳情',
-            hwView: 'View',
-            hwDownload: 'Download',
-            quLabel: '問卷反饋',
-            viewDetail: '查看詳情',
-            noAnswer: '暫未作答',
-            examLabel: '評量反饋',
-            signQrCode: '簽到碼',
-            isStart: '是否開始簽到:',
-            autoFresh: '定時刷新(10s):',
-            fullScreen: '全螢幕顯示',
-            signCount: '簽到統計',
-            signRate: '簽到率',
-            hwCount: '作業統計',
-            submit: '已提交',
-            unsubmit: '未提交',
-            sunmitRate: '提交率',
-            quCount: '問卷統計',
-            examCount: '評量統計',
-            hasAnswer: '已作答',
-            unAnswer: '未作答',
-            peopleUnit: '人',
-            hourCount: '學時審核',
-            passRate: '通過率',
-            qrCodeText: '掃碼簽到',
-            viewHwTitle: '查看作業',
-            teacherName: '教師姓名:',
-            updTime: '上傳時間:',
-            hwFile: '作業附件:',
-            viewTips: '文件類型不支持線上預覽,請下載文件',
-            downloadFile: '下載文件',
-            answerTitle: 'Answering Details',
-            name: '姓名',
-            signTime: '簽到時間',
-            status: '狀態',
-            updTime: '提交時間',
-            action: '操作',
-            answerTime: '作答時間',
-            delTitle: '刪除活動',
-            delContent: '是否確認刪除',
-            delContent1: '刪除區級活動後,相關學校將無法參與此活動,確認刪除活動嗎? ',
-            yes: '是',
-            no: '否',
-            delOk: '刪除成功',
-            delErr: '刪除失敗',
-            saveOk: '保存成功',
-            saveErr: '保存失敗',
-            examErrInfo: '評量資訊獲取失敗',
-            hwErrInfo: '作業資訊獲取失敗',
-            hwUpdTime: '作業提交時間',
-            quAsTime: '完成問卷時間',
-            examAsTime: '完成評量時間',
-            referAnswer: '參考答案',
-            signNow: '立即簽到',
-            signOk: '簽到成功',
-            unStart: '未開始簽到',
-            school: '學校:'
         }
     },
     //研修
@@ -6510,11 +6466,11 @@ const LANG_EN_US = {
         td67: '查詢簽到數據失敗',
         td68: '獲取作業提交數據失敗',
         td69: 'Pass Rate Statistics',
-        td70: '能力維度選修占比',
-        td71: '能力點選修占比',
+        td70: 'Competency Type Elective Ratio',
+        td71: 'Competency Elective No.',
         td72: '研修小組統計',
         td73: '暫無小組數據',
-        td74: '未分組',
+        td74: 'Not grouped',
         td75: 'View Member',
         td76: 'completed online study',
         td77: 'completed certified material',
@@ -6569,7 +6525,7 @@ const LANG_EN_US = {
         td126: '繼續上傳',
         td127: '(資料可以上傳多份)',
         td128: '根據省平臺要求,教師必須滿足以下條件才可獲得校本研修活動學時: 1、10學時中至少有一次需提交作業的校本研修活動 2、在活動中成功提交PDF作業',
-        td129: 'Batch Pass',
+        td129: 'Batch Qualified',
         td130: '請選擇學校老師參加並發布活動',
         td131: '選擇老師',
         td132: '繼續挑選(已選',
@@ -6596,7 +6552,7 @@ const LANG_EN_US = {
         td153: 'Unqualified',
         td154: '的老師',
         td155: '批量處理',
-        td156: '確認將所選老師全部設置為合格嗎?',
+        td156: 'Do you confirm that all the teachers you have selected are qualified?',
         td157: '問卷作答數據獲取失敗',
         td158: '獲取作業提交數據失敗',
         td159: '獲取名單列表失敗',

+ 33 - 2
TEAMModelOS/ClientApp/public/lang/zh-CN.js

@@ -108,7 +108,9 @@ const LANG_ZH_CN = {
         appraiseTip1: '学校暂未开启互评!请联系学校管理员处理!',
         appraiseTip2: '请优先对互评次数为0的老师进行互评!',
         check: {
-            isCheck: '是否为考核人员',
+            joinMan: '参训人员',
+            checkMan: '审核人员',
+            isCheck: '是否为审核人员',
             tip1: '确认修改当前教师的审核人员身份吗?',
             tip2: '已添加',
             tip3: '为审核人员',
@@ -1036,7 +1038,7 @@ const LANG_ZH_CN = {
         cc7: '个人内容',
         cc8: '暂无HiTeachCC使用权限:未加入学校',
         cc9: '暂无HiTeachCC使用权限:学校尚未购买授权',
-        filterExp:'筛选即将到期',
+        filterExp: '筛选即将到期',
 
         //ManageClass.vue
         stuMgt: '学生管理',
@@ -1152,6 +1154,35 @@ const LANG_ZH_CN = {
         cusNameRepeat: '课程名称重复',
         noClassInfo: '暂未找到班级信息',
         noRoomInfo: '暂未找到教室信息',
+        cusImp1:'导入课程范本:',
+        cusImp2:'重要提示:如果学校存在教师同名,教师栏位请使用教师醍摩豆Id进行导入。',
+        cusImp3:'课程基础信息不一致',
+        cusImp4:'缺少课程必填信息',
+        cusImp5:'缺少授课教师信息',
+        cusImp6:'当前课程授课教师重复',
+        cusImp7:'授课教师名称错误或不存在',
+        cusImp8:'学科名称错误或不存在',
+        cusImp9:'班级名称错误或不存在:',
+        cusImp10:'确认导入',
+        cusImp11:'重新导入',
+        cusImp12:'返回课程管理',
+        cusImp13:'subject: 课程学科(必填),导入的学科需要在学校基础预设',
+        cusImp14:'course: 课程名称(必填),如果导入的课程已经在学校存在,则会更新当前课程数据;如果导入的课程不存在则会新建课程',
+        cusImp15:'courseNo: 课程编码(选填)',
+        cusImp16:'courseDesc: 课程描述(选填)',
+        cusImp17:'teacher: 授课教师(选填),如果多个老师教授同一个课程,需要复制课程信息,新建一行',
+        cusImp18:'classes: 教师授课班级(选填),如果多个班级可以使用逗号分隔。',
+        cusImp19:'学科',
+        cusImp20:'课程',
+        cusImp21:'课程编码',
+        cusImp22:'课程描述',
+        cusImp23:'授课教师',
+        cusImp24:'授课班级',
+        cusImp25:'异常信息',
+        cusImp26:'请检查表格数据',
+        cusImp27:'请检查表格信息是否正确',
+        cusImp28:'导入成功',
+        cusImp29:'汇入表格栏位不完整,请检查汇入表格数据',
 
         //MgtStuList.vue
         nameList: '名单',

+ 38 - 6
TEAMModelOS/ClientApp/public/lang/zh-TW.js

@@ -56,7 +56,7 @@ const LANG_ZH_TW = {
         allNormal: '全部合格',
         tip7: '根據省平臺要求,教師必須滿足以下條件才可獲得校本研習活動學時: 1.10學時中至少有一次需提交作業的校本研習活動 2.在活動中成功提交PDF作業',
         allPass: '全部通過',
-        tip8: '教師提交課堂實錄併且考核通過後即可獲得5學時',
+        tip8: '教師提交課堂實錄並且審核通過後即可獲得5學時',
         atName: '被評價人',
         type: '評價類型',
         score: '評價結果',
@@ -88,7 +88,7 @@ const LANG_ZH_TW = {
         tip14: '設定失敗!',
         tip15: '當前教師暫未上傳活動pdf作業,無法通過!',
         tip16: '操作成功!',
-        tip17: '確認將所有教師參與的 不需要提交的 以及 需要且已經提交PDF 的研習活動全部設定為通過嗎?',
+        tip17: '確認將所有教師參與的 不需要提交的 以及 需要且已經提交PDF 的研習活動全部設定為通過嗎?',
         tip18: '確認將所有教師已經自評過的增能項目全部設定為合格嗎?',
         tip19: '操作失敗!',
         tip20: '確認將所有教師已提交的課堂實錄全部設定為合格嗎?',
@@ -104,11 +104,13 @@ const LANG_ZH_TW = {
         otherResult: '互評結果',
         schoolResult: '校評結果',
         noCount: '(不計入學時)',
-        checkMan: '核人員',
+        checkMan: '核人員',
         appraiseTip1: '學校暫未開啟互評!請聯繫學校管理員處理!',
         appraiseTip2: '請優先對互評次數為0的老師進行互評!',
         check: {
-            isCheck: '是否為考核人員',
+            joinMan: '參訓人員',
+            checkMan: '審核人員',
+            isCheck: '是否為審核人員',
             tip1: '確認修改當前教師的審核人員身份嗎?',
             tip2: '已新增',
             tip3: '為審核人員',
@@ -1036,7 +1038,7 @@ const LANG_ZH_TW = {
         cc7: '個人教材',
         cc8: '暫無HiTeach CC使用權限:未加入學校',
         cc9: '暫無HiTeach CC使用權限:學校尚未購買授權',
-        filterExp:'篩選即將到期',
+        filterExp: '篩選即將到期',
 
         //ManageClass.vue
         stuMgt: '學生管理',
@@ -1152,6 +1154,36 @@ const LANG_ZH_TW = {
         cusNameRepeat: '課程名稱重複',
         noClassInfo: '暫未找到班級資訊',
         noRoomInfo: '暫未找到教室資訊',
+        cusImp1: '匯入課程範本:',
+        cusImp2: '重要提示:如果學校存在同名教師,教師欄位請使用醍摩豆用戶編號進行匯入。 ',
+        cusImp3: '課程基礎資訊不一致',
+        cusImp4: '缺少課程必填資訊',
+        cusImp5: '缺少授課教師資訊',
+        cusImp6: '當前課程授課教師重複',
+        cusImp7: '授課教師名稱錯誤或不存在',
+        cusImp8: '學科名稱錯誤或不存在',
+        cusImp9: '班級名稱錯誤或不存在',
+        cusImp10: '確認匯入',
+        cusImp11: '重新匯入',
+        cusImp12: '返回課程管理',
+        cusImp13: 'subject: 課程學科(必填),匯入的學科需要已經存在學校基礎設定裡',
+        cusImp14: 'course: 課程名稱(必填),如果匯入的課程已經在學校存在,則會更新當前課程數據;如果匯入的課程不存在則會新建課程',
+        cusImp15: 'courseNo: 課程編碼(選填)',
+        cusImp16: 'courseDesc: 課程描述(選填)',
+        cusImp17: 'teacher: 授課教師(選填), 如果多個老師教授同一個課程,需要複製課程資訊,新建一行',
+        cusImp18: 'classes: 教師授課班級(選填), 如果多個班級可以使用逗號分隔。 ',
+        cusImp19: '學科',
+        cusImp20: '課程',
+        cusImp21: '課程編碼',
+        cusImp22: '課程描述',
+        cusImp23: '授課教師',
+        cusImp24: '授課班級',
+        cusImp25: '異常資訊',
+        cusImp26: '請檢查表格資料',
+        cusImp27: '請檢查表格資訊是否正確',
+        cusImp28: '匯入成功',
+        cusImp29: '匯入表格欄位不完整,請檢查匯入表格資料',
+
 
         //MgtStuList.vue
         nameList: '名單',
@@ -5318,7 +5350,7 @@ const LANG_ZH_TW = {
             unlockTips: '解鎖菜單欄',
             platform: '資源平臺',
             trainList: '研習名單',
-            trainCheck: '研習核',
+            trainCheck: '研習核',
             activity: '活動平臺',
             trainSystem: '研習平臺'
         },

+ 0 - 43
TEAMModelOS/ClientApp/src/api/courseMgmt.js

@@ -15,53 +15,10 @@ export default {
     deleteCourse: function (data) {
         return post('/school/course/delete', data)
     },
-    //管理员保存排课数据——单堂设置
-    upsertPlanDto: function (data) {
-        return post('/school/course/upsert-management', data)
-    },
-    //管理员保存排课数据——批量导入
-    importAllPlan: function (data) {
-        return post('/api/Course/importAllPlan', data)
-    },
-    //任课教师保存课程附属信息
-    upsertPlan: function (data) {
-        return post('/api/Course/upsertPlan', data)
-    },
-    //查询课程安排数据 (废弃,已经没有courseManagement结构)
-    findPlan: function (data) {
-        return post('/school/course/find-management', data)
-    },
-    //删除课程安排数据
-    deletePlan: function (data) {
-        return post('/api/Course/deletePlan', data)
-    },
-    //删除一节课的安排
-    deleteTime: function (data) {
-        return post('/api/Course/deleteTime', data)
-    },
-    //虚拟教室添加学生
-    addClassroom: function (data) {
-        return post('/api/ClassStudent/upsert', data)
-    },
     //获取教师列表
     getSchoolTeacher: function (data) {
         return post('/school/teacher/get-teacher-all', data)
     },
-    //获取教师标准课程列表 (废弃原来courseManagement)
-    // (课程数据结构调整后校本和个人课程结构相同,用统一的API,此API废弃)
-    getSchoolCusMgt: function (data) {
-        return post('/school/course/find-course', data)
-    },
-    //获取教师个人课程列表
-    // (课程数据结构调整后校本和个人课程结构相同,用统一的API,此API废弃)
-    getPrivateCusMgt: function (data) {
-        return post('/school/course/find-teacher-course', data)
-    },
-    //新增/修改个人课程 
-    // (课程数据结构调整后校本和个人课程结构相同,用统一的API,此API废弃)
-    upsertPrivateCus: function (data) {
-        return post('/school/course/upsert-teacher-course', data)
-    },
     //更新保存标准课程公告
     upsertNotice: function (data) {
         return post('/school/course/upsert-notice', data)

+ 1 - 1
TEAMModelOS/ClientApp/src/api/login.js

@@ -115,6 +115,7 @@ export default {
 			info.toArea = areas.length && !joinSchools.length
 
 			if (defaultschool && defaultschool != 'null') {
+				store.commit('student/setStudents',[])
 				// 取得使用者的在該學校的設定檔
 				await this.getTeacherSchoolInfo({
 					id_token: id_token,
@@ -129,7 +130,6 @@ export default {
 						localStorage.setItem("currArea", JSON.stringify((res.currArea && res.currArea.homeworkType) ? res.currArea.homeworkType : []))
 						store.dispatch('user/setSchoolCode', defaultschool)
 						store.dispatch('user/setSchoolProfile', res)
-						store.commit('student/setStudents',[])
 						result = res
 					}
 				}).catch(err => {

二进制
TEAMModelOS/ClientApp/src/assets/image/cus-import-cn.png


二进制
TEAMModelOS/ClientApp/src/assets/image/cus-import-en.png


二进制
TEAMModelOS/ClientApp/src/assets/image/cus-import-tw.png


+ 4 - 4
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -330,11 +330,11 @@ export default {
             {
               icon: 'iconfont icon-kecheng',
               name: this.$t('system.menu.cusMgt'),
-              router: '/home/NewCusMgt',
+              router: '/home/CusMgt',
               tag: '',
               role: 'admin',
               permission: 'course-read|course-upd',
-              menuName: 'NewCusMgt',
+              menuName: 'CusMgt',
               isShow: this.IES5Menu
             },
             // 教室管理
@@ -980,9 +980,9 @@ export default {
 html,
 body {
   // font-family:"Microsoft YaHei",'微軟正黑體','Microsoft JhengHei UI','Microsoft JhengHei';
-  // font-family: "微軟正黑體", "Microsoft JhengHei UI", "Microsoft JhengHei";
+  font-family: "微軟正黑體", "Microsoft JhengHei UI", "Microsoft JhengHei";
 }
-.menu-tooltips .ivu-tooltip-inner{
+.menu-tooltips .ivu-tooltip-inner {
   word-break: break-word;
   text-align: left;
 }

+ 419 - 418
TEAMModelOS/ClientApp/src/common/BaseNotification.vue

@@ -1,436 +1,437 @@
 <template>
-	<div class="base-notification">
-		<Badge :count="msgArr.length">
-			<Icon type="md-notifications" size="20"  @click="openDrawer"/>
-		</Badge>
-		<Drawer :title="$t('utils.newNotice')" v-model="isOpen" width="400" class-name="base-notification" transfer :closable="false">
-			<div class="notice-header" slot="header">
-				<span style="font-size: 18px;font-weight: bold;">{{ $t('utils.newNotice') }}</span>
-				<span style="color:red;font-size: 12px;cursor: pointer;" v-if="msgArr.length"
-					@click="clearAllMsgs">{{ $t('utils.clearAllMsgs') }}</span>
-			</div>
-			<div class="notice-wrap" v-if="isOpen">
-				<div v-if="!msgArr.length" class="notice-empty">
-					<img src="@/assets/image/none.png" width="300px">
-					{{ $t('notice.noData') }}
-				</div>
-				<div class="notice-item" v-for="(item,index) in msgArr" :key="index" @click="doClickMsg(item,index)" v-else>
-					<span style="position: absolute;right: 5px;top: 15px;">
-						<Icon type="md-close" color="#ababab" size="20" @click.stop="doDeleteMsg(item,index)"/>
-					</span>
-					<p class="item-name"><Icon type="ios-checkmark-circle" color="#17ac5a" size="18" style="margin-right: 5px;"/>{{ getMsgType(item) }}</p>
-					<p class="item-content">
-						<span>{{ getMsgContent(item) }}</span>
-						<span class="item-time" :title="$tools.formatTime(item.body.time)">{{ getMsgTime(item) }}</span>
-					</p>
-				</div>
-			</div>
-		</Drawer>
-	</div>
+  <div class="base-notification">
+    <Badge :count="msgArr.length">
+      <Icon type="md-notifications" size="20" @click="openDrawer" />
+    </Badge>
+    <Drawer :title="$t('utils.newNotice')" v-model="isOpen" width="400" class-name="base-notification" transfer :closable="false">
+      <div class="notice-header" slot="header">
+        <span style="font-size: 18px;font-weight: bold;">{{ $t('utils.newNotice') }}</span>
+        <span style="color:red;font-size: 12px;cursor: pointer;" v-if="msgArr.length" @click="clearAllMsgs">{{ $t('utils.clearAllMsgs') }}</span>
+      </div>
+      <div class="notice-wrap" v-if="isOpen">
+        <div v-if="!msgArr.length" class="notice-empty">
+          <img src="@/assets/image/none.png" width="300px">
+          {{ $t('notice.noData') }}
+        </div>
+        <div class="notice-item" v-for="(item,index) in msgArr" :key="index" @click="doClickMsg(item,index)" v-else>
+          <span style="position: absolute;right: 5px;top: 15px;">
+            <Icon type="md-close" color="#ababab" size="20" @click.stop="doDeleteMsg(item,index)" />
+          </span>
+          <p class="item-name">
+            <Icon type="ios-checkmark-circle" color="#17ac5a" size="18" style="margin-right: 5px;" />{{ getMsgType(item) }}
+          </p>
+          <p class="item-content">
+            <span>{{ getMsgContent(item) }}</span>
+            <span class="item-time" :title="$tools.formatTime(item.body.time)">{{ getMsgTime(item) }}</span>
+          </p>
+        </div>
+      </div>
+    </Drawer>
+  </div>
 </template>
 
 <script>
-	export default {
-		props: {
-			msgs: {
-				type: Array,
-				default: () => []
-			}
-		},
-		data(vm) {
-			return {
-				isOpen:false,
-				msgArr:[],
-				msgTypes: {
-					'request_school': vm.$t('notice.type1'), // 管理员收到他人申请加入的通知
-					'invite_school': vm.$t('notice.type2'), // 你收到学校邀请你的通知
-					'remove_school': vm.$t('notice.type3'), // 学校将你移除的通知
-					'request-join_school': vm.$t('notice.type1'), // 学校同意你的加入请求
-					'invite-join_school': vm.$t('notice.type2'), // 某人已同意你对他的邀请
-					'coedit_syllabus': vm.$t('notice.type4'), // 邀请课纲共编的通知
-					'share_syllabus': vm.$t('notice.type4'), // 个人课纲分享的通知
-					'transfer-admin_school': vm.$t('notice.type5'), // 管理员转移的通知
-					'scoring-arb_school': vm.$t('notice.type6'), // 仲裁卷阅卷任务分配通知
-					'scoring-err_school': vm.$t('notice.type6'), // 异常卷阅卷任务分配通知
-					'scoring-mark_school': vm.$t('notice.type6'), // 普通阅卷任务分配通知
-					'scan-join_groupList': vm.$t('notice.type7'), // 普通阅卷任务分配通知
-					'scan-join_school': vm.$t('notice.type7'), // 普通阅卷任务分配通知
-					'submitanswer_homework': vm.$t('notice.type8'), // 作业提交通知
-					'expire_lessonRecord': vm.$t('notice.type9'), // 课例过期通知
-				}
-			}
-		},
-		methods: {
-			/* 打开抽屉 */
-			openDrawer(){
-				this.isOpen = true
-			},
-			/* 清空所有消息 */
-			clearAllMsgs() {
-				this.$Modal.confirm({
-					title: this.$t('settings.modalTip4'),
-					content: this.$t('utils.clearAllTip'),
-					onOk: () => {
-						if(this.msgArr.length < 2){
-							this.msgArr = []
-						}else{
-							let groups = this._.groupBy(this.msgArr, 'from')
-							Object.keys(groups).forEach(from => {
-								this.delMsgs(from,groups[from].map(i => i.indexNum))
-							})
-							this.msgArr = []
-						}
-						localStorage.removeItem('msgs')
-					}
-				})
-			},
-			/* 获取消息通知类型 */
-			getMsgType(msg) {
-				return `${this.msgTypes[msg.label]}`
-			},
-			/* 获取消息通知时间 */
-			getMsgTime(msg) {
-				return this.$tools.getDateDiff(msg.body.time)
-			},
-			/* 获取消息通知内容 */
-			getMsgContent(msg) {
-				let body = msg.body
-				switch (msg.label) {
-					case 'request_school':
-						return `${body.tmdname}(${body.tmdid}) ${this.$t('notice.tip1')} ${body.schoolname}`
-						break;
-					case 'invite_school':
-						return `${body.tmdname}(${body.tmdid}) ${this.$t('notice.tip2')} ${body.schoolname}`
-						break;
-					case 'request-join_school':
-						return `${body.schoolname} ${this.$t('notice.tip3')}`
-						break;
-					case 'invite-join_school':
-						return `${body.tmdname}(${body.tmdid}) ${this.$t('notice.tip4')} ${body.schoolname} ${this.$t('notice.tip5')}`
-						break;
-					case 'remove_school':
-						return `${body.schoolname} ${this.$t('notice.tip6')}`
-						break;
-					case 'coedit_syllabus':
-						return `${body.tmdname} ${this.$t('notice.tip7')} 【${body.vname}】`
-						break;
-					case 'share_syllabus':
-						return `${body.tmdname} ${this.$t('notice.tip8')} 【${body.vname}】`
-						break;
-					case 'transfer-admin_school':
-						return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip9')}`
-						break;
-					case 'scoring-arb_school':
-						return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip12')}【${body.examname}】 `
-						break;
-					case 'scoring-err_school':
-						return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip11')}【${body.examname}】 `
-						break;
-					case 'scoring-mark_school':
-						return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip10')}【${body.examname}】 `
-						break;
-					case 'scan-join_groupList':
-						return `${body.tmdname} ${this.$t('notice.tip14')}  【${body.groupListName}】`
-						break;
-					case 'scan-join_school':
-						return `${body.tmdname} ${this.$t('notice.tip13')}  【${body.schoolname}】`
-						break;	
-					case 'submitanswer_homework':
-						return `${body.tmdname} ${this.$t('notice.tip15')}  【${body.sname}】${this.$t('notice.tip16')}`
-						break;
-					case 'expire_lessonRecord':
-						return `${this.$t('notice.tip17')}【${this.$tools.formatTime(body.stime)}】${this.$t('notice.tip18')}【${body.sname}】${this.$t('notice.tip19')} 【${this.$tools.formatTime(body.expire)}】${this.$t('notice.tip20')}`
-						break;		
-					default:
-						break;
-				}
-			},
-			/* 消息通知点击触发 */
-			doClickMsg(msg, index) {
-				let body = msg.body
-				let routerInfo = null
-				console.log(msg);
-				switch (msg.label) {
-					case 'request_school':
-						routerInfo = {
-							name: "teachermgmt"
-						}
-						break;
-					case 'invite-join_school':
-						routerInfo = {
-							name: "teachermgmt"
-						}
-						break;
-					case 'invite_school':
-						routerInfo = {
-							name: "settings"
-						}
-						break;
-					case 'coedit_syllabus':
-						routerInfo = {
-							name: "syllabus",
-							params:{
-								tabName:'fromCreate',
-								id:body.vid
-							}
-						}
-						break;
-					case 'scoring-arb_school':
-						routerInfo = {
-							name: "taskList"
-						}
-						break;
-					case 'scoring-err_school':
-						routerInfo = {
-							name: "taskList"
-						}
-						break;
-					case 'scoring-mark_school':
-						routerInfo = {
-							name: "taskList"
-						}
-						break;
-					case 'share_syllabus':
-						routerInfo = {
-							name: "personalSyllabus",
-							params:{
-								tabName:'fromShare',
-								id:body.vid
-							}
-						}
-						break;
-					case 'scan-join_school':
-						routerInfo = {
-							name: "teachermgmt"
-						}
-						break;
-					case 'scan-join_groupList':
-						routerInfo = {
-							name: "myCourse",
-						}
-						break;	
-					case 'submitanswer_homework':
-						routerInfo = {
-							name: "manageHomeWork",
-							params:{
-								ac:{
-									id:body.sid
-								}
-							}
-						}
-						break;
-					case 'expire_lessonRecord':
-						routerInfo = {
-							name: "myCourse",
-						}
-						break;				
-					default:
-						break;
-				}
-				this.changeSchool(body.schoolcode, routerInfo)
-				this.isOpen = false
-			},
-			/* 删除单条消息 */
-			doDeleteMsg(msg,index){
-				this.msgArr.splice(index, 1)
-				this.delMsgs(msg.from, [msg.indexNum])
-			},
-			/* 点击通知判断是否切换学校 */
-			changeSchool(schoolCode, routerInfo) {
-				return new Promise((r, j) => {
-					if (!routerInfo) return
-					// 如果是同一学校则不做处理
-					if (schoolCode === this.$store.state.userInfo.schoolCode || !schoolCode || routerInfo.name ===
-						'settings') {
-						this.$router.push(routerInfo)
-						return
-					}
-					// 需要切换学校
-					let user = this.$store.state.user.userProfile || JSON.parse(decodeURIComponent(localStorage
-						.user_profile, "utf-8"));
-					let joinSchools = user.schools && user.schools.length ? user.schools.filter(i => i.status ===
-						'join') : null
-					if (joinSchools && joinSchools.length) {
-						joinSchools.forEach(i => {
-							if (!i.area) {
-								i.area = {
-									name: this.$t('ability.otherSch')
-								}
-							}
-						})
-						let areaName = joinSchools.find(i => i.schoolId === schoolCode).area.name
-						if (areaName !== sessionStorage.getItem('areaName')) {
-							this.$Modal.confirm({
-								title: this.$t('settings.modalTip4'),
-								content: this.$t('settings.modalTip9'),
-								onOk: () => {
-									this.$EventBus.$emit('resetAreaIndex', {
-										areaName: areaName,
-										schoolCode: schoolCode,
-										routerInfo: routerInfo
-									})
-									r(200)
-								},
-								onCancel: () => {
-									r(500)
-								}
-							})
-						} else {
-							this.$EventBus.$emit('resetAreaIndex', {
-								areaName: areaName,
-								schoolCode: schoolCode,
-								routerInfo: routerInfo
-							})
-							r(200)
-						}
-					} else {
-						r(500)
-					}
-				})
-			},
-			/* API删除通知 */
-			async delMsgs(from, idArr) {
-				try {
-					let srvAdr = this.$store.state.config.srvAdr
-					let host = srvAdr == 'Global' ? this.$store.state.config.Global.coreAPIUrl : this.$store.state.config.China.coreAPIUrl
-					await this.$api.service.delNotification(host,{
-						"from": from,
-						"receiver": this.$store.state.userInfo.TEAMModelId,
-						"indexNums": idArr
-					})
-				} catch (e) {
-					this.$Message.error('remove fail')
-				}
+export default {
+  props: {
+    msgs: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data(vm) {
+    return {
+      isOpen: false,
+      msgArr: [],
+      msgTypes: {
+        'request_school': vm.$t('notice.type1'), // 管理员收到他人申请加入的通知
+        'invite_school': vm.$t('notice.type2'), // 你收到学校邀请你的通知
+        'remove_school': vm.$t('notice.type3'), // 学校将你移除的通知
+        'request-join_school': vm.$t('notice.type1'), // 学校同意你的加入请求
+        'invite-join_school': vm.$t('notice.type2'), // 某人已同意你对他的邀请
+        'coedit_syllabus': vm.$t('notice.type4'), // 邀请课纲共编的通知
+        'share_syllabus': vm.$t('notice.type4'), // 个人课纲分享的通知
+        'transfer-admin_school': vm.$t('notice.type5'), // 管理员转移的通知
+        'scoring-arb_school': vm.$t('notice.type6'), // 仲裁卷阅卷任务分配通知
+        'scoring-err_school': vm.$t('notice.type6'), // 异常卷阅卷任务分配通知
+        'scoring-mark_school': vm.$t('notice.type6'), // 普通阅卷任务分配通知
+        'scan-join_groupList': vm.$t('notice.type7'), // 普通阅卷任务分配通知
+        'scan-join_school': vm.$t('notice.type7'), // 普通阅卷任务分配通知
+        'submitanswer_homework': vm.$t('notice.type8'), // 作业提交通知
+        'expire_lessonRecord': vm.$t('notice.type9'), // 课例过期通知
+      }
+    }
+  },
+  methods: {
+    /* 打开抽屉 */
+    openDrawer() {
+      this.isOpen = true
+    },
+    /* 清空所有消息 */
+    clearAllMsgs() {
+      this.$Modal.confirm({
+        title: this.$t('settings.modalTip4'),
+        content: this.$t('utils.clearAllTip'),
+        onOk: () => {
+          if (this.msgArr.length < 2) {
+            this.msgArr = []
+          } else {
+            let groups = this._.groupBy(this.msgArr, 'from')
+            Object.keys(groups).forEach(from => {
+              this.delMsgs(from, groups[from].map(i => i.indexNum))
+            })
+            this.msgArr = []
+          }
+          localStorage.removeItem('msgs')
+        }
+      })
+    },
+    /* 获取消息通知类型 */
+    getMsgType(msg) {
+      return `${this.msgTypes[msg.label]}`
+    },
+    /* 获取消息通知时间 */
+    getMsgTime(msg) {
+      return this.$tools.getDateDiff(msg.body.time)
+    },
+    /* 获取消息通知内容 */
+    getMsgContent(msg) {
+      let body = msg.body
+      switch (msg.label) {
+        case 'request_school':
+          return `${body.tmdname}(${body.tmdid}) ${this.$t('notice.tip1')} ${body.schoolname}`
+          break;
+        case 'invite_school':
+          return `${body.tmdname}(${body.tmdid}) ${this.$t('notice.tip2')} ${body.schoolname}`
+          break;
+        case 'request-join_school':
+          return `${body.schoolname} ${this.$t('notice.tip3')}`
+          break;
+        case 'invite-join_school':
+          return `${body.tmdname}(${body.tmdid}) ${this.$t('notice.tip4')} ${body.schoolname} ${this.$t('notice.tip5')}`
+          break;
+        case 'remove_school':
+          return `${body.schoolname} ${this.$t('notice.tip6')}`
+          break;
+        case 'coedit_syllabus':
+          return `${body.tmdname} ${this.$t('notice.tip7')} 【${body.vname}】`
+          break;
+        case 'share_syllabus':
+          return `${body.tmdname} ${this.$t('notice.tip8')} 【${body.vname}】`
+          break;
+        case 'transfer-admin_school':
+          return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip9')}`
+          break;
+        case 'scoring-arb_school':
+          return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip12')}【${body.examname}】 `
+          break;
+        case 'scoring-err_school':
+          return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip11')}【${body.examname}】 `
+          break;
+        case 'scoring-mark_school':
+          return `${body.schoolname}-${body.tmdname} ${this.$t('notice.tip10')}【${body.examname}】 `
+          break;
+        case 'scan-join_groupList':
+          return `${body.tmdname} ${this.$t('notice.tip14')}  【${body.groupListName}】`
+          break;
+        case 'scan-join_school':
+          return `${body.tmdname} ${this.$t('notice.tip13')}  【${body.schoolname}】`
+          break;
+        case 'submitanswer_homework':
+          return `${body.tmdname} ${this.$t('notice.tip15')}  【${body.sname}】${this.$t('notice.tip16')}`
+          break;
+        case 'expire_lessonRecord':
+          return `${this.$t('notice.tip17')}【${this.$tools.formatTime(body.stime)}】${this.$t('notice.tip18')}【${body.sname}】${this.$t('notice.tip19')} 【${this.$tools.formatTime(body.expire)}】${this.$t('notice.tip20')}`
+          break;
+        default:
+          break;
+      }
+    },
+    /* 消息通知点击触发 */
+    doClickMsg(msg, index) {
+      let body = msg.body
+      let routerInfo = null
+      console.log(msg);
+      switch (msg.label) {
+        case 'request_school':
+          routerInfo = {
+            name: "teachermgmt"
+          }
+          break;
+        case 'invite-join_school':
+          routerInfo = {
+            name: "teachermgmt"
+          }
+          break;
+        case 'invite_school':
+          routerInfo = {
+            name: "settings"
+          }
+          break;
+        case 'coedit_syllabus':
+          routerInfo = {
+            name: "syllabus",
+            params: {
+              tabName: 'fromCreate',
+              id: body.vid
+            }
+          }
+          break;
+        case 'scoring-arb_school':
+          routerInfo = {
+            name: "taskList"
+          }
+          break;
+        case 'scoring-err_school':
+          routerInfo = {
+            name: "taskList"
+          }
+          break;
+        case 'scoring-mark_school':
+          routerInfo = {
+            name: "taskList"
+          }
+          break;
+        case 'share_syllabus':
+          routerInfo = {
+            name: "personalSyllabus",
+            params: {
+              tabName: 'fromShare',
+              id: body.vid
+            }
+          }
+          break;
+        case 'scan-join_school':
+          routerInfo = {
+            name: "teachermgmt"
+          }
+          break;
+        case 'scan-join_groupList':
+          routerInfo = {
+            name: "course",
+          }
+          break;
+        case 'submitanswer_homework':
+          routerInfo = {
+            name: "manageHomeWork",
+            params: {
+              ac: {
+                id: body.sid
+              }
+            }
+          }
+          break;
+        case 'expire_lessonRecord':
+          routerInfo = {
+            name: "course",
+          }
+          break;
+        default:
+          break;
+      }
+      this.changeSchool(body.schoolcode, routerInfo)
+      this.isOpen = false
+    },
+    /* 删除单条消息 */
+    doDeleteMsg(msg, index) {
+      this.msgArr.splice(index, 1)
+      this.delMsgs(msg.from, [msg.indexNum])
+    },
+    /* 点击通知判断是否切换学校 */
+    changeSchool(schoolCode, routerInfo) {
+      return new Promise((r, j) => {
+        if (!routerInfo) return
+        // 如果是同一学校则不做处理
+        if (schoolCode === this.$store.state.userInfo.schoolCode || !schoolCode || routerInfo.name ===
+          'settings') {
+          this.$router.push(routerInfo)
+          return
+        }
+        // 需要切换学校
+        let user = this.$store.state.user.userProfile || JSON.parse(decodeURIComponent(localStorage
+          .user_profile, "utf-8"));
+        let joinSchools = user.schools && user.schools.length ? user.schools.filter(i => i.status ===
+          'join') : null
+        if (joinSchools && joinSchools.length) {
+          joinSchools.forEach(i => {
+            if (!i.area) {
+              i.area = {
+                name: this.$t('ability.otherSch')
+              }
+            }
+          })
+          let areaName = joinSchools.find(i => i.schoolId === schoolCode).area.name
+          if (areaName !== sessionStorage.getItem('areaName')) {
+            this.$Modal.confirm({
+              title: this.$t('settings.modalTip4'),
+              content: this.$t('settings.modalTip9'),
+              onOk: () => {
+                this.$EventBus.$emit('resetAreaIndex', {
+                  areaName: areaName,
+                  schoolCode: schoolCode,
+                  routerInfo: routerInfo
+                })
+                r(200)
+              },
+              onCancel: () => {
+                r(500)
+              }
+            })
+          } else {
+            this.$EventBus.$emit('resetAreaIndex', {
+              areaName: areaName,
+              schoolCode: schoolCode,
+              routerInfo: routerInfo
+            })
+            r(200)
+          }
+        } else {
+          r(500)
+        }
+      })
+    },
+    /* API删除通知 */
+    async delMsgs(from, idArr) {
+      try {
+        let srvAdr = this.$store.state.config.srvAdr
+        let host = srvAdr == 'Global' ? this.$store.state.config.Global.coreAPIUrl : this.$store.state.config.China.coreAPIUrl
+        await this.$api.service.delNotification(host, {
+          "from": from,
+          "receiver": this.$store.state.userInfo.TEAMModelId,
+          "indexNums": idArr
+        })
+      } catch (e) {
+        this.$Message.error('remove fail')
+      }
 
-			}
-		},
-		watch: {
-			msgs: {
-				handler(n, o) {
-					let localMsgs = JSON.parse(localStorage.getItem('msgs'))
-					if (!localMsgs || !localMsgs.length) {
-						this.msgArr = []
-					} else {
-						// 只查询当前站点的消息通知
-						let curLocation = localStorage.getItem('location')
-						this.msgArr = localMsgs.filter(i => {
-							return i.body.location === curLocation
-						})
-					}
-				}
-			},
-			'$store.state.studentWeb.lang'(language) {
-				this.msgTypes = {
-					'request_school': this.$t('notice.type1'), // 管理员收到他人申请加入的通知
-					'invite_school': this.$t('notice.type2'), // 你收到学校邀请你的通知
-					'remove_school': this.$t('notice.type3'), // 学校将你移除的通知
-					'request-join_school': this.$t('notice.type1'), // 学校同意你的加入请求
-					'invite-join_school': this.$t('notice.type2'), // 某人已同意你对他的邀请
-					'coedit_syllabus': this.$t('notice.type4'), // 邀请课纲共编的通知
-					'share_syllabus': this.$t('notice.type4'), // 个人课纲分享的通知
-					'transfer-admin_school': this.$t('notice.type5'), // 管理员转移的通知
-					'scoring-arb_school': this.$t('notice.type6'), // 仲裁卷阅卷任务分配通知
-					'scoring-err_school': this.$t('notice.type6'), // 异常卷阅卷任务分配通知
-					'scoring-mark_school': this.$t('notice.type6'), // 普通阅卷任务分配通知
-					'scan-join_groupList': this.$t('notice.type7'), // 普通阅卷任务分配通知
-					'scan-join_school': this.$t('notice.type7'), // 普通阅卷任务分配通知
-					'submitanswer_homework': this.$t('notice.type8'), // 作业提交通知
-					'expire_lessonRecord': this.$t('notice.type9'), // 课例过期通知
-				}
-			}
-		}
-	}
+    }
+  },
+  watch: {
+    msgs: {
+      handler(n, o) {
+        let localMsgs = JSON.parse(localStorage.getItem('msgs'))
+        if (!localMsgs || !localMsgs.length) {
+          this.msgArr = []
+        } else {
+          // 只查询当前站点的消息通知
+          let curLocation = localStorage.getItem('location')
+          this.msgArr = localMsgs.filter(i => {
+            return i.body.location === curLocation
+          })
+        }
+      }
+    },
+    '$store.state.studentWeb.lang'(language) {
+      this.msgTypes = {
+        'request_school': this.$t('notice.type1'), // 管理员收到他人申请加入的通知
+        'invite_school': this.$t('notice.type2'), // 你收到学校邀请你的通知
+        'remove_school': this.$t('notice.type3'), // 学校将你移除的通知
+        'request-join_school': this.$t('notice.type1'), // 学校同意你的加入请求
+        'invite-join_school': this.$t('notice.type2'), // 某人已同意你对他的邀请
+        'coedit_syllabus': this.$t('notice.type4'), // 邀请课纲共编的通知
+        'share_syllabus': this.$t('notice.type4'), // 个人课纲分享的通知
+        'transfer-admin_school': this.$t('notice.type5'), // 管理员转移的通知
+        'scoring-arb_school': this.$t('notice.type6'), // 仲裁卷阅卷任务分配通知
+        'scoring-err_school': this.$t('notice.type6'), // 异常卷阅卷任务分配通知
+        'scoring-mark_school': this.$t('notice.type6'), // 普通阅卷任务分配通知
+        'scan-join_groupList': this.$t('notice.type7'), // 普通阅卷任务分配通知
+        'scan-join_school': this.$t('notice.type7'), // 普通阅卷任务分配通知
+        'submitanswer_homework': this.$t('notice.type8'), // 作业提交通知
+        'expire_lessonRecord': this.$t('notice.type9'), // 课例过期通知
+      }
+    }
+  }
+}
 </script>
 
 <style lang="less">
-	.base-notification {
-		.ivu-icon {
-			font-size: 22px;
-			color: #d0d0d0;
-			cursor: pointer;
-		}
+.base-notification {
+  .ivu-icon {
+    font-size: 22px;
+    color: #d0d0d0;
+    cursor: pointer;
+  }
 
-		.ivu-poptip-popper {
-			padding: 0;
-			top: 65px !important;
-			z-index: 9999;
-			width: 450px !important;
+  .ivu-poptip-popper {
+    padding: 0;
+    top: 65px !important;
+    z-index: 9999;
+    width: 450px !important;
 
-			.ivu-poptip-body {
-				max-height: 320px;
-				overflow: auto;
-			}
-		}
+    .ivu-poptip-body {
+      max-height: 320px;
+      overflow: auto;
+    }
+  }
 
-		.ivu-badge-count {
-			width: 16px;
-			height: 16px;
-			display: inline-block;
-			border-radius: 50%;
-			color: white;
-			border: none;
-			font-size: 12px;
-			line-height: 16px;
-			text-align: center;
-			margin-left: 10px;
-			min-width: 16px;
-			box-shadow: none;
-			padding: 0;
-		}
+  .ivu-badge-count {
+    width: 16px;
+    height: 16px;
+    display: inline-block;
+    border-radius: 50%;
+    color: white;
+    border: none;
+    font-size: 12px;
+    line-height: 16px;
+    text-align: center;
+    margin-left: 10px;
+    min-width: 16px;
+    box-shadow: none;
+    padding: 0;
+  }
 
-		.notice-empty {
-			display: flex;
-			flex-direction: column;
-			justify-content: center;
-			align-items: center;
-			margin: 20px 0;
-			color: #b3b3b3;
+  .notice-empty {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    margin: 20px 0;
+    color: #b3b3b3;
 
-			.ivu-icon {
-				font-size: 44px;
-				margin-bottom: 20px;
-				color: #6c6c6c;
-			}
-		}
-		
-		.notice-header{
-			display: flex;
-			justify-content: space-between;
-			align-items: center;
-		}
+    .ivu-icon {
+      font-size: 44px;
+      margin-bottom: 20px;
+      color: #6c6c6c;
+    }
+  }
 
-		.notice-wrap {
-			display: flex;
-			flex-direction: column;
+  .notice-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
 
-			.notice-item {
-				position: relative;
-				padding: 5px;
-				color: var(--primary-text-color);
-				border-bottom: 1px solid #e8eaec;
-				cursor: pointer;
-				.item-name {
-					font-size: 16px;
-					font-weight: bold;
-					// color: #fff;
-					margin: 10px 0;
-				}
+  .notice-wrap {
+    display: flex;
+    flex-direction: column;
 
-				.item-content {
-					font-size: 14px;
-					margin-left: 20px;
-					word-break: break-all;
-					white-space: break-spaces;
-					color: var(--second-text-color);
-				}
+    .notice-item {
+      position: relative;
+      padding: 5px;
+      color: var(--primary-text-color);
+      border-bottom: 1px solid #e8eaec;
+      cursor: pointer;
+      .item-name {
+        font-size: 16px;
+        font-weight: bold;
+        // color: #fff;
+        margin: 10px 0;
+      }
 
-				.item-time {
-					margin-top: 25px;
-					font-size: 12px;
-					color: #777777;
-					float: right;
-				}
-			}
-		}
-	}
+      .item-content {
+        font-size: 14px;
+        margin-left: 20px;
+        word-break: break-all;
+        white-space: break-spaces;
+        color: var(--second-text-color);
+      }
+
+      .item-time {
+        margin-top: 25px;
+        font-size: 12px;
+        color: #777777;
+        float: right;
+      }
+    }
+  }
+}
 </style>

+ 274 - 276
TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue

@@ -1,313 +1,311 @@
 <template>
-  <div class="base-school-select">
-    <div v-if="!joinSchools || !joinSchools.length">{{ noJoinSchoolContent }}</div>
-    <div v-else>
-      <!-- 学校切换 -->
-      <Dropdown @on-click="onSchoolSelect" trigger="click">
-        <img class="school-logo" :src="curSchool.picture" style="width: 25px;" />
-        <a href="javascript:void(0)" :class="['base-user-post', areaSchs && areaSchs.length === 1 ? 'single-school' : '']">
-          {{ curSchool.name }}
-          <Icon type="ios-arrow-down"></Icon>
-        </a>
-        <DropdownMenu slot="list">
-          <div v-for="(item,index) in areaSchs" :key="index">
-            <DropdownItem :name="index">
-              <div class="school-item">
-                <img :src="item.picture || defaultLogo" alt="" style="border-radius: 50%;">
-                <span>{{ item.name }}</span>
-              </div>
-            </DropdownItem>
-          </div>
-        </DropdownMenu>
-      </Dropdown>
-      <!-- 学段切换 -->
-      <Dropdown @on-click="onPeriodSelect" v-show="periods.length > 1" style="margin-left: 20px;">
-        <!-- <a href="javascript:void(0)" :class="['base-user-post', periods && periods.length === 1 ? 'single-school' : '']"> -->
-        <!-- ( {{ curPeriod.name }} )
+    <div class="base-school-select">
+        <div v-if="!joinSchools || !joinSchools.length">{{ noJoinSchoolContent }}</div>
+        <div v-else>
+            <!-- 学校切换 -->
+            <Dropdown class="school-select" transfer @on-click="onSchoolSelect" trigger="click">
+                <img class="school-logo" :src="curSchool.picture" style="width: 25px;" />
+                <a href="javascript:void(0)" :class="['base-user-post', areaSchs && areaSchs.length === 1 ? 'single-school' : '']">
+                    {{ curSchool.name }}
+                    <Icon type="ios-arrow-down"></Icon>
+                </a>
+                <DropdownMenu slot="list">
+                    <div v-for="(item,index) in areaSchs" :key="index">
+                        <DropdownItem :name="index">
+                            <div class="school-item">
+                                <img class="school-item-img" :src="item.picture || defaultLogo" alt="" style="border-radius: 50%;">
+                                <span>{{ item.name }}</span>
+                            </div>
+                        </DropdownItem>
+                    </div>
+                </DropdownMenu>
+            </Dropdown>
+            <!-- 学段切换 -->
+            <Dropdown @on-click="onPeriodSelect" transfer v-show="periods.length > 1" style="margin-left: 20px;">
+                <!-- <a href="javascript:void(0)" :class="['base-user-post', periods && periods.length === 1 ? 'single-school' : '']"> -->
+                <!-- ( {{ curPeriod.name }} )
 					<Icon type="ios-arrow-down"></Icon> -->
-        <span class="period-select">
-          &nbsp;
-          {{ curPeriod.name }}
-          <Icon type="md-arrow-dropdown" />
-        </span>
-        <!-- </a> -->
-        <!-- <span class="period-select">{{ curPeriod.name }}</span> -->
-        <DropdownMenu slot="list">
-          <div v-for="(item,index) in periods" :key="index">
-            <DropdownItem :name="index">
-              <div class="school-item">
-                <span>{{ item.name }}</span>
-              </div>
-            </DropdownItem>
-          </div>
-        </DropdownMenu>
-      </Dropdown>
+                <span class="period-select">
+                    &nbsp;
+                    {{ curPeriod.name }}
+                    <Icon type="md-arrow-dropdown" />
+                </span>
+                <!-- </a> -->
+                <!-- <span class="period-select">{{ curPeriod.name }}</span> -->
+                <DropdownMenu slot="list">
+                    <div v-for="(item,index) in periods" :key="index">
+                        <DropdownItem :name="index">
+                            <div class="school-item">
+                                <span>{{ item.name }}</span>
+                            </div>
+                        </DropdownItem>
+                    </div>
+                </DropdownMenu>
+            </Dropdown>
+        </div>
     </div>
-  </div>
 </template>
 
 <script>
 import { mapGetters } from 'vuex'
 import User from '@/service/User.js'
 export default {
-  inject: ['reload'],
-  data() {
-    return {
-      curSchool: {
-        logo: ''
-      },
-      defaultLogo: '',
-      user: {
-        schools: []
-      },
-      joinSchools: [],
-      areaSchs: [],
-      areaList: [],
-      periods: [],
-      curPeriod: {
-        name: ''
-      }
-    }
-  },
-  created() {
-    console.log('BaseSelectSchool初始化')
-    console.log(this.userProfile)
-    this.defaultLogo = require('@/assets/icon/default_school.png')
-    // 获取本地存储中的 用户信息
-    let user = this.$store.state.user.userProfile || JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"));
-    let schoolProfile = localStorage.school_profile ? JSON.parse(decodeURIComponent(localStorage.school_profile,
-      "utf-8")) : undefined;
-    let localPeriodInfo = localStorage.curPeriod ? JSON.parse(localStorage.curPeriod) : null
-    this.user.schools = user.schools
-    let joinSchools = user.schools && user.schools.length ? user.schools.filter(i => i.status === 'join') : null
-    console.log(joinSchools);
-    /* 如果加入的学校都没有归属区 则需要补充‘其他学校’区 */
-    if (joinSchools && joinSchools.length) {
-      joinSchools.forEach(i => {
-        if (!i.area) {
-          i.area = {
-            name: this.$t('ability.otherSch'),
-            access: 0
-          }
-        }
-      })
-    }
-    this.joinSchools = joinSchools
-    // 如果本地存储已经有保存学校信息 则刷新后会直接读取之前的学校信息
-    if (joinSchools && joinSchools.length) {
-      if (schoolProfile) {
-        this.curSchool = joinSchools.find(i => i.schoolId === schoolProfile.school_base.id)
-      } else {
-        this.curSchool = user.defaultschool ? joinSchools.find(i => i.schoolId === user.defaultschool) : joinSchools[0]
-      }
-      this.$store.commit('setSchoolCode', this.curSchool.schoolId)
-      this.areaList = [...new Set(this.joinSchools.map(i => i.area).map(j => j.name))]
-      this.areaSchs = this.joinSchools.filter(i => i.area.name === this.curSchool.area.name)
-      this.periods = this.$store.state.user.schoolProfile.school_base.period
-      this.periods && (this.curPeriod = this.periods[localPeriodInfo && localPeriodInfo.periodIndex ? localPeriodInfo.periodIndex : 0])
-      if (!localPeriodInfo) {
-        this.curPeriod.periodIndex = 0
-        // 保存Vuex
-        this.$store.commit('user/setCurPeriod', this.curPeriod)
-        // 保存Stroage
-        localStorage.setItem('curPeriod', JSON.stringify(this.curPeriod))
-      } else {
-        this.$store.commit('user/setCurPeriod', localPeriodInfo)
-      }
-    } else {
-      this.$Message.warning(this.$t('utils.noShoolTip'))
-    }
-    console.log('当前区域学校 > ', this.areaSchs)
-    console.log('当前学校 > ', this.curSchool)
-    console.log('当前学段 > ', this.curPeriod)
-  },
-  methods: {
-    async onSchoolSelect(val) {
-      /* 如果没有加入的学校或者加入的学校都没有归属区 */
-      if (this.joinSchools.length) {
-        this.joinSchools.forEach(i => {
-          if (!i.area) {
-            i.area = {
-              name: this.$t('ability.otherSch')
+    inject: ['reload'],
+    data() {
+        return {
+            curSchool: {
+                logo: ''
+            },
+            defaultLogo: '',
+            user: {
+                schools: []
+            },
+            joinSchools: [],
+            areaSchs: [],
+            areaList: [],
+            periods: [],
+            curPeriod: {
+                name: ''
             }
-          }
-        })
-      }
-      let curAreaName = sessionStorage.getItem('areaName') || this.areaList[0]
-      this.joinSchools = this.user.schools.filter(i => i.status === 'join')
-      this.areaSchs = this.joinSchools.filter(i => i.area.name === curAreaName)
-      // this.$EventBus.$emit('onGlobalLoading', true)
-      this.curSchool = this.areaSchs[val]
-      let schoolCode = this.areaSchs[val].schoolId
-      this.changeCurSchool(schoolCode)
-    },
-
-    /* 学段选择 */
-    onPeriodSelect(val) {
-      this.curPeriod = this.periods[val]
-      // 保存当前学段的下标 提供给部分模块的select使用
-      this.curPeriod.periodIndex = val
-      // 保存Vuex
-      this.$store.commit('user/setCurPeriod', this.curPeriod)
-      // 保存Stroage
-      localStorage.setItem('curPeriod', JSON.stringify(this.curPeriod))
+        }
     },
-
-    /* 学校切换后针对当前学校CODE进行操作 */
-    changeCurSchool(schoolCode, routerInfo) {
-      // this.$EventBus.$emit('onChangeSchool', {
-      // 	schoolCode: schoolCode
-      // })
-      this.$EventBus.$emit('onGlobalLoading', true)
-      // 更新当前school_code
-      this.$store.dispatch('user/setSchoolCode', schoolCode)
-      // 更新当前school_profile以及access
-      this.$store.dispatch('user/checkSchoolProfile').then(res => {
-        if (res) {
-          this.$User.freshLogin()
+    created() {
+        console.log('BaseSelectSchool初始化')
+        console.log(this.userProfile)
+        this.defaultLogo = require('@/assets/icon/default_school.png')
+        // 获取本地存储中的 用户信息
+        let user = this.$store.state.user.userProfile || JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"));
+        let schoolProfile = localStorage.school_profile ? JSON.parse(decodeURIComponent(localStorage.school_profile,
+            "utf-8")) : undefined;
+        let localPeriodInfo = localStorage.curPeriod ? JSON.parse(localStorage.curPeriod) : null
+        this.user.schools = user.schools
+        let joinSchools = user.schools && user.schools.length ? user.schools.filter(i => i.status === 'join') : null
+        console.log(joinSchools);
+        /* 如果加入的学校都没有归属区 则需要补充‘其他学校’区 */
+        if (joinSchools && joinSchools.length) {
+            joinSchools.forEach(i => {
+                if (!i.area) {
+                    i.area = {
+                        name: this.$t('ability.otherSch'),
+                        access: 0
+                    }
+                }
+            })
         }
-        console.log('切换学校了', this.curSchool, schoolCode)
-        console.log('当前学校的学段信息', this.$store.state.user.schoolProfile.school_base.period)
-        // 将教师列表信息清空
-        this.$store.commit('user/setTeachers', undefined)
-        this.periods = this.$store.state.user.schoolProfile.school_base.period
-        let vuexPeriod = this.$store.state.user.curPeriod
-        let preSchoolCode = localStorage.getItem('cur_schoolCode')
-        // 判断之前已经选择了学段 并且从区级切换回来的是同一学校 则去读取存储的学段数据 否则默认读取第一个学段信息
-        if (vuexPeriod && preSchoolCode && preSchoolCode === schoolCode) {
-          this.onPeriodSelect(vuexPeriod.periodIndex)
+        this.joinSchools = joinSchools
+        // 如果本地存储已经有保存学校信息 则刷新后会直接读取之前的学校信息
+        if (joinSchools && joinSchools.length) {
+            if (schoolProfile) {
+                this.curSchool = joinSchools.find(i => i.schoolId === schoolProfile.school_base.id)
+            } else {
+                this.curSchool = user.defaultschool ? joinSchools.find(i => i.schoolId === user.defaultschool) : joinSchools[0]
+            }
+            this.$store.commit('setSchoolCode', this.curSchool.schoolId)
+            this.areaList = [...new Set(this.joinSchools.map(i => i.area).map(j => j.name))]
+            this.areaSchs = this.joinSchools.filter(i => i.area.name === this.curSchool.area.name)
+            this.periods = this.$store.state.user.schoolProfile.school_base.period
+            this.periods && (this.curPeriod = this.periods[localPeriodInfo && localPeriodInfo.periodIndex ? localPeriodInfo.periodIndex : 0])
+            if (!localPeriodInfo) {
+                this.curPeriod.periodIndex = 0
+                // 保存Vuex
+                this.$store.commit('user/setCurPeriod', this.curPeriod)
+                // 保存Stroage
+                localStorage.setItem('curPeriod', JSON.stringify(this.curPeriod))
+            } else {
+                this.$store.commit('user/setCurPeriod', localPeriodInfo)
+            }
         } else {
-          this.onPeriodSelect(0)
+            this.$Message.warning(this.$t('utils.noShoolTip'))
         }
-        localStorage.removeItem('cacheSchoolFiles')
-        localStorage.removeItem('bankFilterConds')
-        localStorage.setItem('cur_schoolCode', schoolCode)
-        // this.periods && (this.curPeriod = this.periods[0])
-        setTimeout(() => {
-          this.$EventBus.$emit('onGlobalLoading', false)
-        }, 1500)
-        routerInfo = routerInfo || { name: 'home' }
-        // console.error(routerInfo.name);
-        // console.error(this.$route);
-        this.$router.push(routerInfo)
-        if (routerInfo.name === this.$route.name) {
-          this.reload()
-        }
-      });
-    }
-  },
-  mounted() {
-    // 解绑之前的事件 防止多次触发
-    // this.$EventBus.$off('onChangeSchool')
-    // this.$EventBus.$on('onChangeSchool', params => {
-    // 	if (this.curSchool && params.schoolCode !== this.curSchool.schoolId && params.user) {
-    // 		console.log('检测到切换学校')
-    // 		console.log(params)
-    // 		this.user = params.user
-    // 		let joinSchools = params.user.schools.filter(i => i.status === 'join')
-    // 		this.onSchoolSelect(params.isFirst ? 0 : joinSchools.map(j => j.schoolId).indexOf(params.schoolCode))
-    // 	}
-    // })
+        console.log('当前区域学校 > ', this.areaSchs)
+        console.log('当前学校 > ', this.curSchool)
+        console.log('当前学段 > ', this.curPeriod)
+    },
+    methods: {
+        async onSchoolSelect(val) {
+            /* 如果没有加入的学校或者加入的学校都没有归属区 */
+            if (this.joinSchools.length) {
+                this.joinSchools.forEach(i => {
+                    if (!i.area) {
+                        i.area = {
+                            name: this.$t('ability.otherSch')
+                        }
+                    }
+                })
+            }
+            let curAreaName = sessionStorage.getItem('areaName') || this.areaList[0]
+            this.joinSchools = this.user.schools.filter(i => i.status === 'join')
+            this.areaSchs = this.joinSchools.filter(i => i.area.name === curAreaName)
+            // this.$EventBus.$emit('onGlobalLoading', true)
+            this.curSchool = this.areaSchs[val]
+            let schoolCode = this.areaSchs[val].schoolId
+            this.changeCurSchool(schoolCode)
+        },
+
+        /* 学段选择 */
+        onPeriodSelect(val) {
+            this.curPeriod = this.periods[val]
+            // 保存当前学段的下标 提供给部分模块的select使用
+            this.curPeriod.periodIndex = val
+            // 保存Vuex
+            this.$store.commit('user/setCurPeriod', this.curPeriod)
+            // 保存Stroage
+            localStorage.setItem('curPeriod', JSON.stringify(this.curPeriod))
+        },
 
-    // 监听区的切换
-    this.$EventBus.$off('onChangeArea')
-    this.$EventBus.$on('onChangeArea', params => {
-      console.log('区域切换', params);
-      console.log('区域切换', this.joinSchools);
-      if (this.joinSchools && this.joinSchools.length) {
-        this.areaSchs = this.joinSchools.filter(i => i.area.name === params.areaName)
-        console.log(this.areaSchs);
-        this.curSchool = params.schoolCode ? this.areaSchs.find(i => i.schoolId === params.schoolCode) : this.areaSchs[0]
-        let schoolCode = this.curSchool.schoolId
-        this.changeCurSchool(schoolCode, params.routerInfo)
-      }
-    })
-  },
+        /* 学校切换后针对当前学校CODE进行操作 */
+        changeCurSchool(schoolCode, routerInfo) {
+            // this.$EventBus.$emit('onChangeSchool', {
+            // 	schoolCode: schoolCode
+            // })
+            this.$EventBus.$emit('onGlobalLoading', true)
+            // 更新当前school_code
+            this.$store.dispatch('user/setSchoolCode', schoolCode)
+            // 更新当前school_profile以及access
+            this.$store.dispatch('user/checkSchoolProfile').then(res => {
+                if (res) {
+                    this.$User.freshLogin()
+                }
+                console.log('切换学校了', this.curSchool, schoolCode)
+                console.log('当前学校的学段信息', this.$store.state.user.schoolProfile.school_base.period)
+                // 将教师列表信息清空
+                this.$store.commit('user/setTeachers', undefined)
+                this.periods = this.$store.state.user.schoolProfile.school_base.period
+                let vuexPeriod = this.$store.state.user.curPeriod
+                let preSchoolCode = localStorage.getItem('cur_schoolCode')
+                // 判断之前已经选择了学段 并且从区级切换回来的是同一学校 则去读取存储的学段数据 否则默认读取第一个学段信息
+                if (vuexPeriod && preSchoolCode && preSchoolCode === schoolCode) {
+                    this.onPeriodSelect(vuexPeriod.periodIndex)
+                } else {
+                    this.onPeriodSelect(0)
+                }
+                localStorage.removeItem('cacheSchoolFiles')
+                localStorage.removeItem('bankFilterConds')
+                localStorage.setItem('cur_schoolCode', schoolCode)
+                // this.periods && (this.curPeriod = this.periods[0])
+                setTimeout(() => {
+                    this.$EventBus.$emit('onGlobalLoading', false)
+                }, 1500)
+                routerInfo = routerInfo || { name: 'home' }
+                // console.error(routerInfo.name);
+                // console.error(this.$route);
+                this.$router.push(routerInfo)
+                if (routerInfo.name === this.$route.name) {
+                    this.reload()
+                }
+            });
+        }
+    },
+    mounted() {
+        // 解绑之前的事件 防止多次触发
+        // this.$EventBus.$off('onChangeSchool')
+        // this.$EventBus.$on('onChangeSchool', params => {
+        // 	if (this.curSchool && params.schoolCode !== this.curSchool.schoolId && params.user) {
+        // 		console.log('检测到切换学校')
+        // 		console.log(params)
+        // 		this.user = params.user
+        // 		let joinSchools = params.user.schools.filter(i => i.status === 'join')
+        // 		this.onSchoolSelect(params.isFirst ? 0 : joinSchools.map(j => j.schoolId).indexOf(params.schoolCode))
+        // 	}
+        // })
 
-  computed: {
-    noJoinSchoolContent() {
-      let inviteSchools = this.user.schools.filter(i => i.status === 'invite')
-      let requestSchools = this.user.schools.filter(i => i.status === 'request')
-      return requestSchools.length ? `${requestSchools[0].name}(${this.$t('settings.status3')})` : (inviteSchools.length ? `${inviteSchools[0].name}(${this.$t('settings.status2')})` : this.$t('utils.noJoinSchool'))
+        // 监听区的切换
+        this.$EventBus.$off('onChangeArea')
+        this.$EventBus.$on('onChangeArea', params => {
+            console.log('区域切换', params);
+            console.log('区域切换', this.joinSchools);
+            if (this.joinSchools && this.joinSchools.length) {
+                this.areaSchs = this.joinSchools.filter(i => i.area.name === params.areaName)
+                console.log(this.areaSchs);
+                this.curSchool = params.schoolCode ? this.areaSchs.find(i => i.schoolId === params.schoolCode) : this.areaSchs[0]
+                let schoolCode = this.curSchool.schoolId
+                this.changeCurSchool(schoolCode, params.routerInfo)
+            }
+        })
     },
-  }
+
+    computed: {
+        noJoinSchoolContent() {
+            let inviteSchools = this.user.schools.filter(i => i.status === 'invite')
+            let requestSchools = this.user.schools.filter(i => i.status === 'request')
+            return requestSchools.length ? `${requestSchools[0].name}(${this.$t('settings.status3')})` : (inviteSchools.length ? `${inviteSchools[0].name}(${this.$t('settings.status2')})` : this.$t('utils.noJoinSchool'))
+        },
+    }
 }
 </script>
 
 <style lang="less">
 .base-school-select {
-  // font-family: 'NotoSerif', '微软正黑体', 'Microsoft JhengHei UI', 'Microsoft JhengHei', Sans-serif;
-  .ivu-dropdown {
-    .ivu-select-dropdown {
-      width: max-content;
-      width: -webkit-max-content;
-      left: -35%;
-    }
+    // font-family: 'NotoSerif', '微软正黑体', 'Microsoft JhengHei UI', 'Microsoft JhengHei', Sans-serif;
+    .ivu-dropdown {
+        .ivu-select-dropdown {
+            width: max-content;
+            width: -webkit-max-content;
+            left: -35%;
+        }
 
-    .ivu-dropdown-menu {
-      max-height: 600px;
-      overflow: auto;
-    }
+        .ivu-dropdown-menu {
+            max-height: 600px;
+            overflow: auto;
+        }
 
-    .ivu-dropdown-item:hover {
-      background: #83d7ff;
-    }
+        .ivu-dropdown-item:hover {
+            background: #83d7ff;
+        }
 
-    a {
-      color: var(--primary-textColor) !important;
+        a {
+            color: var(--primary-textColor) !important;
 
-      &:hover {
-        color: var(--primary-textColor) !important;
-      }
+            &:hover {
+                color: var(--primary-textColor) !important;
+            }
 
-      .ivu-icon {
-        display: none;
-      }
+            .ivu-icon {
+                display: none;
+            }
 
-      &::after {
-        content: "";
-        display: inline-block;
-        width: 0;
-        height: 0;
-        border-right: solid 6px transparent;
-        border-left: solid 6px transparent;
-        border-top: solid 6px #16b1f3;
-        margin-left: 2px;
-        margin-bottom: 3px;
-      }
+            &::after {
+                content: "";
+                display: inline-block;
+                width: 0;
+                height: 0;
+                border-right: solid 6px transparent;
+                border-left: solid 6px transparent;
+                border-top: solid 6px #16b1f3;
+                margin-left: 2px;
+                margin-bottom: 3px;
+            }
+        }
     }
-  }
 
-  .period-select {
-    font-size: 16px;
-    background: #1cc0f3;
-    padding: 2px 5px;
-    border-radius: 5px;
-    cursor: pointer;
-  }
-
-  .single-school {
-    &::after {
-      display: none !important;
+    .period-select {
+        font-size: 16px;
+        background: #1cc0f3;
+        padding: 2px 5px;
+        border-radius: 5px;
+        cursor: pointer;
     }
-  }
 
-  .school-logo {
-    width: 30px;
-    border-radius: 50%;
-    margin-right: 10px;
-    margin-bottom: 5px;
-    vertical-align: middle;
-  }
+    .single-school {
+        &::after {
+            display: none !important;
+        }
+    }
 
-  .school-item {
+    .school-logo {
+        width: 30px;
+        border-radius: 50%;
+        margin-right: 10px;
+        margin-bottom: 5px;
+        vertical-align: middle;
+    }
+}
+.school-item {
     display: flex;
     align-items: center;
-
-    img {
-      width: 30px;
-      margin-right: 15px;
-    }
-  }
+}
+.school-item-img {
+    width: 30px;
+    margin-right: 15px;
 }
 </style>

+ 210 - 178
TEAMModelOS/ClientApp/src/common/BaseUpload.vue

@@ -1,187 +1,219 @@
 <template>
-	<div class="base-upload-container">
-		<Upload multiple type="drag" action="" :disabled="isLoading" :before-upload="onBeforeUpload" :show-upload-list="false">
-			<div style="padding: 40px 0">
-				<Icon type="ios-cloud-upload" size="100"
-					style="color: #40A8F0;margin: 40px 0;"></Icon>
-				<p style="color: #757575">{{ $t("knowledge.import.tip1") }}</p>
-				<p style="color: #ddd" v-if="acceptTypes.length">({{ $t("knowledge.import.tip2") }}:{{ acceptTypes.join(' / ') }})</p>
-			</div>
-		</Upload>
-		<div class="file-list-box" v-if="!simpleUpload">
-			<div class="file-item" v-for="(item,index) in fileArr" :key="index">
-				<p>
-					<span>{{ item.name }}</span>
-					<span class="tool-remove" v-if="isShowTool">
-						<Icon type="md-close" @click="onRemoveFile(index)"/>
-					</span>
-				</p>
-				<Progress :percent="progressArr[index]" :stroke-width="12"/>
-			</div>
-		</div>
-		<Button  @click="onConfirmUpload" :loading="isLoading"  v-if="!simpleUpload" style="width: 100%;margin: 0 auto;" class="modal-btn" :disabled="!fileArr.length">{{ $t("knowledge.import.tip3") }}</Button>
-	</div>
+  <div class="base-upload-container">
+    <Upload multiple type="drag" action="" :disabled="isLoading" :before-upload="onBeforeUpload" :show-upload-list="false">
+      <div style="padding: 40px 0">
+        <Icon type="ios-cloud-upload" size="100" style="color: #40A8F0;margin: 40px 0;"></Icon>
+        <p style="color: #757575">{{ $t("knowledge.import.tip1") }}</p>
+        <p style="color: #ddd" v-if="acceptTypes.length">({{ $t("knowledge.import.tip2") }}:{{ acceptTypes.join(' / ') }})</p>
+      </div>
+    </Upload>
+    <div class="file-list-box" v-if="!simpleUpload">
+      <div class="file-item" v-for="(item,index) in fileArr" :key="index">
+        <p>
+          <span>{{ item.name }}</span>
+          <span class="tool-remove" v-if="isShowTool">
+            <Icon type="md-close" @click="onRemoveFile(index)" />
+          </span>
+        </p>
+        <Progress :percent="progressArr[index]" :stroke-width="12" />
+      </div>
+    </div>
+    <Button @click="onConfirmUpload" :loading="isLoading" v-if="!simpleUpload" style="width: 100%;margin: 0 auto;" class="modal-btn" :disabled="!fileArr.length">{{ $t("knowledge.import.tip3") }}</Button>
+  </div>
 </template>
 
 <script>
-	import BlobTool from '@/utils/blobTool.js'
-	export default {
-		props: {
-			auth: {
-				type: Object,
-				default: () => {
-					return {
-						sas: '',
-						url: '',
-						name: ''
-					}
-				}
-			},
-			scope: {
-				type: String,
-				default: 'school'
-			},
-			prefix: {
-				type: String,
-				default: ''
-			},
-			simpleUpload:{
-				type:Boolean,
-				default:false
-			},
-			acceptTypes:{
-				type:Array,
-				default:() => []
-			}
-		},
-		data() {
-			return {
-				isLoading:false,
-				isShowTool:true,
-				containerClient: null,
-				fileArr:[],
-				progressArr:[]
-			}
-		},
-		created() {
+import axios from 'axios'
+import BlobTool from '@/utils/blobTool.js'
+export default {
+  props: {
+    auth: {
+      type: Object,
+      default: () => {
+        return {
+          sas: '',
+          url: '',
+          name: ''
+        }
+      }
+    },
+    scope: {
+      type: String,
+      default: 'school'
+    },
+    prefix: {
+      type: String,
+      default: ''
+    },
+    simpleUpload: {
+      type: Boolean,
+      default: false
+    },
+    acceptTypes: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      isLoading: false,
+      isShowTool: true,
+      containerClient: null,
+      fileArr: [],
+      progressArr: []
+    }
+  },
+  created() {
 
-		},
-		methods: {
-			async onBeforeUpload(file) {
-				let nameType = file.name.split('.')[file.name.split('.').length - 1]
-				if(this.$GLOBAL.NotSupport.includes(nameType.toUpperCase())){
-					this.$Message.warning(this.$t('learnActivity.notSupportType')); // 黑名单文件格式不能上传
-					return false
-				}
-				if(this.simpleUpload){
-					this.$emit('uploadFinish',file)
-					return
-				}
-				file.progress = 0
-				this.fileArr.push(file)
-				this.progressArr.push(0)
-				return false
-				
-			},
-			
-			onRemoveFile(index){
-				this.fileArr.splice(index,1)
-			},
-			
-			async onConfirmUpload(){
-				this.isShowTool = false
-				let result = []
-				let containerClient = this.containerClient
-				let list = this.fileArr
-				let that = this
-				let promiseArr = []
-				that.isLoading = true
-				for(let i = 0 ; i < list.length; i++){
-					let file = list[i]
-					promiseArr.push(new Promise(async (r,j) => {
-						try{
-							let blobFile = await containerClient.upload(file, { path:this.prefix },{
-								onProgress: function (e) {
-									that.$set(that.progressArr,i,parseInt(e.loadedBytes * 100 / file.size))
-								}
-							});
-							// 如果上传的是视频文件 则需要获取视频的时长信息和MD5信息
-							if (blobFile.type === 'video' && blobFile.extension.toLowerCase() === 'mp4') {
-								blobFile.duration = await this.$tools.getVideoDuration(file)
-							}
-							if (blobFile.type === 'video' && blobFile.extension.toLowerCase() !== 'mp4') {
-								this.$Message.warning(blobFile.name + this.$t('syllabus.playFailTip'))
-							}
-							let fileMD5 = await this.$tools.getFileMD5(file)
-							blobFile.hash = this.$tools.convertFileMD5ToString(fileMD5)
-							console.log('BaseUpload > md5',blobFile.hash);
-							r(blobFile)
-						}catch(e){
-							this.$Message.error(e.spaceError || 'upload Fail')
-							j(e)
-						}
-					}))
-				}
-				
-				Promise.all(promiseArr).then(result => {
-					this.$emit('uploadFinish',result)
-				}).catch(e => {
-					this.$Message.error('upload Fail!')
-				}).finally(() => {
-					this.fileArr = []
-					this.progressArr = []
-					that.isLoading = false
-				})
-				
-			}
-		},
-		mounted() {
-			if(this.auth.sas){
-				let n = this.auth
-				this.containerClient = new BlobTool(n.url, n.name, n.sas, this.scope)
-			}
-		},
-		watch: {
-			auth: {
-				handler(n, o) {
-					this.containerClient = new BlobTool(n.url, n.name, n.sas, this.scope)
-				}
-			}
-		}
-	}
+  },
+  methods: {
+    async onBeforeUpload(file) {
+      let nameType = file.name.split('.')[file.name.split('.').length - 1]
+      if (this.$GLOBAL.NotSupport.includes(nameType.toUpperCase())) {
+        this.$Message.warning(this.$t('learnActivity.notSupportType')); // 黑名单文件格式不能上传
+        return false
+      }
+      if (this.simpleUpload) {
+        this.$emit('uploadFinish', file)
+        return
+      }
+      file.progress = 0
+      this.fileArr.push(file)
+      this.progressArr.push(0)
+      return false
+
+    },
+
+    onRemoveFile(index) {
+      this.fileArr.splice(index, 1)
+    },
+
+    async onConfirmUpload() {
+      this.isShowTool = false
+      let result = []
+      let containerClient = this.containerClient
+      let list = this.fileArr
+      let that = this
+      let promiseArr = []
+      that.isLoading = true
+      for (let i = 0; i < list.length; i++) {
+        let file = list[i]
+        promiseArr.push(new Promise(async (r, j) => {
+          try {
+            let blobFile = await containerClient.upload(file, { path: this.prefix }, {
+              onProgress: function (e) {
+                that.$set(that.progressArr, i, parseInt(e.loadedBytes * 100 / file.size))
+              }
+            });
+            // 如果上传的是视频文件 则需要获取视频的时长信息和MD5信息
+            if (blobFile.type === 'video' && blobFile.extension.toLowerCase() === 'mp4') {
+              blobFile.duration = await this.$tools.getVideoDuration(file)
+            }
+            if (blobFile.type === 'video' && blobFile.extension.toLowerCase() !== 'mp4') {
+              this.$Message.warning(blobFile.name + this.$t('syllabus.playFailTip'))
+            }
+            let fileMD5 = await this.$tools.getFileMD5(file)
+            blobFile.hash = this.$tools.convertFileMD5ToString(fileMD5)
+            console.log('BaseUpload > md5', blobFile.hash);
+            console.error(blobFile)
+            console.error(this.prefix)
+            // 如果上传的是HTEX文件 则需要访问解压接口后 再删除原压缩包
+            if (blobFile.extension.toLowerCase() === 'htex') {
+              let htexUploadStatus = await this.doUploadHTEX(blobFile)
+              if (htexUploadStatus !== 200) {
+                j(500)
+              }
+            }
+            r(blobFile)
+          } catch (e) {
+            this.$Message.error(e.spaceError || 'upload Fail')
+            j(e)
+          }
+        }))
+      }
+      Promise.all(promiseArr).then(result => {
+        this.$emit('uploadFinish', result)
+      }).catch(e => {
+        this.$Message.error('upload Fail!')
+      }).finally(() => {
+        this.fileArr = []
+        this.progressArr = []
+        that.isLoading = false
+      })
+
+    },
+    /* 处理HTEX文件的上传 */
+    doUploadHTEX(blobFile) {
+      return new Promise(async (r, j) => {
+        axios({
+          method: 'post',
+          url: `${window.location.protocol}//${window.location.host}/import/parse-doc`,
+          data: {
+            file: blobFile.url,
+            scope: this.scope,
+            target: this.prefix,
+          },
+          timeout: 10 * 60 * 1000, //十分钟
+        }).then(
+          parseRes => {
+            r(200)
+          },
+          parseErr => {
+            j(500)
+          }
+        ).finally(() => {
+          this.containerClient.deleteBlob(blobFile.blob)
+        })
+      })
+    }
+  },
+  mounted() {
+    if (this.auth.sas) {
+      let n = this.auth
+      this.containerClient = new BlobTool(n.url, n.name, n.sas, this.scope)
+    }
+  },
+  watch: {
+    auth: {
+      handler(n, o) {
+        this.containerClient = new BlobTool(n.url, n.name, n.sas, this.scope)
+      }
+    }
+  }
+}
 </script>
 
 <style lang="less">
-	.base-upload-container{
-		padding-bottom: 40px;
-		.file-list-box{
-			margin: 20px 5px;
-			width: 100%;
-			max-height: 200px;
-			overflow: auto;
-			
-			.file-item{
-				margin: 10px 0;
-				
-				.tool-remove{
-					color: #b3b3b3;
-					margin-left: 15px;
-					font-size: 14px;
-					cursor: pointer;
-				}
-			}
-			
-			.ivu-progress{
-				margin-top: 10px;
-			}
-			
-			.ivu-progress-text-inner{
-				color: #ddd;
-			}
-			
-			&::-webkit-scrollbar-thumb{
-				background:#dadada !important;
-			}
-		}
-	}
+.base-upload-container {
+  padding-bottom: 40px;
+  .file-list-box {
+    margin: 20px 5px;
+    width: 100%;
+    max-height: 200px;
+    overflow: auto;
+
+    .file-item {
+      margin: 10px 0;
+
+      .tool-remove {
+        color: #b3b3b3;
+        margin-left: 15px;
+        font-size: 14px;
+        cursor: pointer;
+      }
+    }
+
+    .ivu-progress {
+      margin-top: 10px;
+    }
+
+    .ivu-progress-text-inner {
+      color: #ddd;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      background: #dadada !important;
+    }
+  }
+}
 </style>

+ 2 - 2
TEAMModelOS/ClientApp/src/components/coursemgt/StudentList.vue

@@ -154,7 +154,7 @@ export default {
         },
         /**根据学段、年级、班级搜索 */
         filterData() {
-            let data = this.students
+            let data = this._.cloneDeep(this.students)
             // 學制篩選
             if (this.searchPeriod) {
                 data = data.filter(item => {
@@ -241,10 +241,10 @@ export default {
     },
     created() {
         this.initData()
-        this.baseFindStudent()
         this.$store.dispatch('user/getSchoolProfile').then(
             res => {
                 this.schoolBase = res.school_base
+                this.baseFindStudent()
             }
         )
     },

+ 2 - 16
TEAMModelOS/ClientApp/src/components/dashboard/art/BaseStuLineBar.vue

@@ -56,6 +56,8 @@ export default {
         dataZoom: [{
           show: true,
           height: 10,
+          start: data.length > 10 ? 40 : 0,
+          end: data.length > 10 ? 60 : 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',
@@ -205,22 +207,6 @@ export default {
               }
             },
             data: data.map(i => i.average)
-          },
-          {
-            type: 'bar',
-            stack: 'bar',
-            z: 2,
-            zlevel: 2,
-            barGap: '-250%',
-            barWidth: '50%',
-            data: data.map(i => 50),
-            itemStyle: {
-              normal: {
-                color: function (params) {
-                  return params.dataIndex === that.activeIndex ? 'rgba(140,120,250,0.4)' : 'rgba(0,0,0,0)';
-                },
-              }
-            },
           }]
       };
       myChart.clear()

+ 449 - 0
TEAMModelOS/ClientApp/src/components/dashboard/art/BaseYdztRadar.vue

@@ -0,0 +1,449 @@
+<template>
+  <div id="YdztBarDraw" class="art-point-bar"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender(data) {
+      let myChart = this.$echarts.init(document.getElementById('YdztBarDraw'))
+      this.option = {
+        color: [
+          '#0090ff',
+          '#06d3c4',
+          '#ffbc32',
+          '#2ccc44',
+          '#ff3976',
+          '#6173d6',
+          '#914ce5',
+          '#42b1cc',
+          '#ff55ac',
+          '#0090ff',
+          '#06d3c4',
+          '#ffbc32',
+          '#2ccc44',
+          '#26c898',
+          '#6173d6',
+          '#914ce5',
+        ],//数据蛛网线条的颜色,示例中为红黄绿
+        title: {
+          left: 'center',
+          top: '15',
+          textStyle: {
+            color: '#ccc'//统计图标题的文字颜色
+          }
+        },
+        legend: { //图例的设置
+          show: true, //是否显示图例
+          icon: 'circle',//图例形状,示例为原型
+          bottom: 15,//图例离底部的距离
+          itemWidth: 14, // 图例标记的图形宽度。
+          itemHeight: 14, // 图例标记的图形高度。
+          itemGap: 20, // 图例每项之间的间隔。
+          textStyle: {//图例文字的样式设置
+            fontSize: 12,
+            color: '#ade3ff'
+          },
+          data: ['六年级', '1班', '2班', '3班', '4班', '5班', '6班'],//图例的名称数据
+        },
+        radar: [{//每个网格的指数名称,类似于X轴或Y轴上的数据的值大小
+          indicator: [{
+            text: '图像识读',
+            max: 100
+          },
+          {
+            text: '美术表现',
+            max: 100
+          },
+          {
+            text: '审美判断',
+            max: 100
+          },
+          {
+            text: '创意实践',
+            max: 100
+          },
+          {
+            text: '文化理解',
+            max: 100
+          }
+          ],
+          center: ['50%', '50%'],//统计图位置,示例是居中
+          radius: '70%',//统计图大小
+          startAngle: 90,//统计图起始的角度
+          splitNumber: 3,//统计图蛛网的网格分段,示例分为三段
+          // shape: 'circle',//蛛网是圆角还是尖角
+          name: {
+            formatter: '{value}',//蛛网轴尖的数据名称
+            textStyle: {//蛛网轴尖的文字样式
+              fontSize: 14, //外圈标签字体大小
+              color: '#0fa2ef' //外圈标签字体颜色
+            }
+          },
+          splitArea: { // 蛛网在 grid 区域中的分隔区域,默认不显示。
+            show: true,
+            areaStyle: { // 分隔区域的样式设置。
+              color: ['rgba(76, 140, 200, 0.05)', 'rgba(76, 140, 200, 0.1)'], // 分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。
+            }
+          },
+          axisLine: { //蛛网轴线上的颜色,由内向外发散的那条
+            lineStyle: {
+              color: '#153269'
+            }
+          },
+          splitLine: {//蛛网环形的线条颜色
+            lineStyle: {
+              color: '#113865', // 分隔线颜色
+              width: 1, // 分隔线线宽
+            }
+          }
+        },],
+        series: [{
+          name: '',
+          type: 'radar',//统计图专业名称为雷达图,这里叫做蛛网图
+          itemStyle: {//数据样式设置
+            emphasis: {//鼠标悬浮效果
+              lineStyle: {
+                width: 4//线条粗细变成4
+              }
+            }
+          },
+          data: [{
+            name: '六年级',//数据名称
+            value: [56.23, 62.48, 62.06, 54.89, 68.48],
+            areaStyle: {
+              normal: { // 单项区域填充样式
+                color: {
+                  x: 0, //右
+                  y: 0, //下
+                  x2: 1, //左
+                  y2: 1, //上
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(228,52,70,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(228,52,70,0.5)'
+                  }],
+                },
+                opacity: 1 // 区域透明度
+              }
+            },
+            symbolSize: 2.5, // 单个数据标记的大小,可以设置成诸如 10 这样单一的数字,也可以用数组分开表示宽和高,例如 [20, 10] 表示标记宽为20,高为10。
+            label: { // 单个拐点文本的样式设置                            
+              normal: { // 单个拐点文本的样式设置。[ default: false ]
+                position: 'top', // 标签的位置。[ default: top ]
+                distance: 4, // 距离图形元素的距离。当 position 为字符描述值(如 'top'、'insideRight')时候有效。[ default: 5 ]
+                color: '#ccc', // 文字的颜色。如果设置为 'auto',则为视觉映射得到的颜色,如系列色。[ default: "#fff" ]
+                fontSize: 14, // 文字的字体大小
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'//显示分析的数字值,a为统计图名称,b为学生姓名,c为学生这项能力的值
+              }
+            },
+            itemStyle: {
+              normal: { //图形悬浮效果
+                borderColor: '#ccc',//单个数据标记描边的颜色
+                borderWidth: 2.5//单个数据标记描边的大小
+              }
+            },
+          }, {
+            name: '1班',
+            value: [65.02, 60.41, 51.56, 49.64, 69.66],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(215,32,123,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(215,32,123,0.5)'
+                  }],
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '2班',
+            value: [46.42, 61.10, 59.77, 50.38, 54.61],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(167,199,52,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(167,199,52,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '3班',
+            value: [59.86, 59.93, 65.91, 64.73, 72.82],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(67,19,152,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(67,19,152,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '4班',
+            value: [55.86, 68.13, 68.14, 57.25, 75.61],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(67,199,152,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(67,199,152,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '5班',
+            value: [53.69, 62.74, 69.79, 56.34, 72.00],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(67,199,152,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(67,199,152,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '6班',
+            value: [56.32, 62.37, 57.81, 51.45, 65.87],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(167,199,12,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(167,199,12,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }]
+        },]
+      };
+      myChart.setOption(this.option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+    }
+  },
+  mounted() {
+    this.doRender()
+  }
+}
+</script>
+
+<style>
+.art-point-bar {
+  width: 60%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 445 - 0
TEAMModelOS/ClientApp/src/components/dashboard/art/BaseYdztRadarMusic.vue

@@ -0,0 +1,445 @@
+<template>
+  <div id="YdztBarMusic" class="art-point-bar"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender(data) {
+      let myChart = this.$echarts.init(document.getElementById('YdztBarMusic'))
+      this.option = {
+        color: [
+          '#0090ff',
+          '#06d3c4',
+          '#ffbc32',
+          '#2ccc44',
+          '#ff3976',
+          '#6173d6',
+          '#914ce5',
+          '#42b1cc',
+          '#ff55ac',
+          '#0090ff',
+          '#06d3c4',
+          '#ffbc32',
+          '#2ccc44',
+          '#26c898',
+          '#6173d6',
+          '#914ce5',
+        ],//数据蛛网线条的颜色,示例中为红黄绿
+        title: {
+          left: 'center',
+          top: '15',
+          textStyle: {
+            color: '#ccc'//统计图标题的文字颜色
+          }
+        },
+        legend: { //图例的设置
+          show: true, //是否显示图例
+          icon: 'circle',//图例形状,示例为原型
+          bottom: 15,//图例离底部的距离
+          itemWidth: 14, // 图例标记的图形宽度。
+          itemHeight: 14, // 图例标记的图形高度。
+          itemGap: 20, // 图例每项之间的间隔。
+          textStyle: {//图例文字的样式设置
+            fontSize: 12,
+            color: '#ade3ff'
+          },
+          data: ['六年级', '1班', '2班', '3班', '4班', '5班', '6班'],//图例的名称数据
+        },
+        radar: [{//每个网格的指数名称,类似于X轴或Y轴上的数据的值大小
+          indicator: [{
+            text: '音乐要素表现',
+            max: 100
+          },
+          {
+            text: '音乐风格与流派',
+            max: 100
+          },
+          {
+            text: '音乐体裁和形式',
+            max: 100
+          },
+          {
+            text: '音乐常识',
+            max: 100
+          }
+          ],
+          center: ['50%', '50%'],//统计图位置,示例是居中
+          radius: '70%',//统计图大小
+          startAngle: 90,//统计图起始的角度
+          splitNumber: 3,//统计图蛛网的网格分段,示例分为三段
+          // shape: 'circle',//蛛网是圆角还是尖角
+          name: {
+            formatter: '{value}',//蛛网轴尖的数据名称
+            textStyle: {//蛛网轴尖的文字样式
+              fontSize: 14, //外圈标签字体大小
+              color: '#0fa2ef' //外圈标签字体颜色
+            }
+          },
+          splitArea: { // 蛛网在 grid 区域中的分隔区域,默认不显示。
+            show: true,
+            areaStyle: { // 分隔区域的样式设置。
+              color: ['rgba(76, 140, 200, 0.05)', 'rgba(76, 140, 200, 0.1)'], // 分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。
+            }
+          },
+          axisLine: { //蛛网轴线上的颜色,由内向外发散的那条
+            lineStyle: {
+              color: '#153269'
+            }
+          },
+          splitLine: {//蛛网环形的线条颜色
+            lineStyle: {
+              color: '#113865', // 分隔线颜色
+              width: 1, // 分隔线线宽
+            }
+          }
+        },],
+        series: [{
+          name: '',
+          type: 'radar',//统计图专业名称为雷达图,这里叫做蛛网图
+          itemStyle: {//数据样式设置
+            emphasis: {//鼠标悬浮效果
+              lineStyle: {
+                width: 4//线条粗细变成4
+              }
+            }
+          },
+          data: [{
+            name: '六年级',//数据名称
+            value: [56.23, 62.48, 62.06, 54.89, 68.48],
+            areaStyle: {
+              normal: { // 单项区域填充样式
+                color: {
+                  x: 0, //右
+                  y: 0, //下
+                  x2: 1, //左
+                  y2: 1, //上
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(228,52,70,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(228,52,70,0.5)'
+                  }],
+                },
+                opacity: 1 // 区域透明度
+              }
+            },
+            symbolSize: 2.5, // 单个数据标记的大小,可以设置成诸如 10 这样单一的数字,也可以用数组分开表示宽和高,例如 [20, 10] 表示标记宽为20,高为10。
+            label: { // 单个拐点文本的样式设置                            
+              normal: { // 单个拐点文本的样式设置。[ default: false ]
+                position: 'top', // 标签的位置。[ default: top ]
+                distance: 4, // 距离图形元素的距离。当 position 为字符描述值(如 'top'、'insideRight')时候有效。[ default: 5 ]
+                color: '#ccc', // 文字的颜色。如果设置为 'auto',则为视觉映射得到的颜色,如系列色。[ default: "#fff" ]
+                fontSize: 14, // 文字的字体大小
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'//显示分析的数字值,a为统计图名称,b为学生姓名,c为学生这项能力的值
+              }
+            },
+            itemStyle: {
+              normal: { //图形悬浮效果
+                borderColor: '#ccc',//单个数据标记描边的颜色
+                borderWidth: 2.5//单个数据标记描边的大小
+              }
+            },
+          }, {
+            name: '1班',
+            value: [65.02, 60.41, 51.56, 49.64, 69.66],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(215,32,123,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(215,32,123,0.5)'
+                  }],
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '2班',
+            value: [46.42, 61.10, 59.77, 50.38, 54.61],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(167,199,52,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(167,199,52,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '3班',
+            value: [59.86, 59.93, 65.91, 64.73, 72.82],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(67,19,152,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(67,19,152,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '4班',
+            value: [55.86, 68.13, 68.14, 57.25, 75.61],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(67,199,152,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(67,199,152,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '5班',
+            value: [53.69, 62.74, 69.79, 56.34, 72.00],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(67,199,152,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(67,199,152,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }, {
+            name: '6班',
+            value: [56.32, 62.37, 57.81, 51.45, 65.87],
+            symbolSize: 2.5,
+            itemStyle: {
+              normal: {
+                borderColor: '#ccc',
+                borderWidth: 2.5,
+              }
+            },
+            areaStyle: {
+              normal: {
+                color: {
+                  type: 'linear',
+                  x: 0,
+                  y: 0,
+                  x2: 1,
+                  y2: 1,
+                  colorStops: [{
+                    offset: 0,
+                    color: 'rgba(167,199,12,0.5)'
+                  }, {
+                    offset: 0.5,
+                    color: 'rgba(0,0,0,0)'
+                  }, {
+                    offset: 1,
+                    color: 'rgba(167,199,12,0.5)'
+                  }],
+                  globalCoord: false
+                },
+                opacity: 1
+              }
+            },
+            label: {
+              normal: {
+                position: 'top',
+                distance: 4,
+                color: '#ccc',
+                fontSize: 14,
+              },
+              emphasis: {
+                show: true,
+                formatter: '{c}'
+              }
+            },
+          }]
+        },]
+      };
+      myChart.setOption(this.option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+    }
+  },
+  mounted() {
+    this.doRender()
+  }
+}
+</script>
+
+<style>
+.art-point-bar {
+  width: 60%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 57 - 4
TEAMModelOS/ClientApp/src/components/dashboard/art/LeftCenter.vue

@@ -2,12 +2,15 @@
   <div id="bottomLeft2">
     <p class="dashboard-block-title">
       <Icon type="md-pulse" />
-      <span>知识点得分率统计</span>
+      <span>{{ isYdzt ? '基础知识各维度得分情况' : '知识点得分率统计' }}</span>
       <dv-decoration-1 class="dv-dec-3" />
     </p>
     <div style="display:flex;height:100%">
-      <BaseKnowPie />
-      <BasePointLineBar />
+      <BaseKnowPie v-if="!isYdzt" />
+      <BasePointLineBar v-if="!isYdzt" />
+      <BaseYdztRadar v-if="isYdzt && !isMusic" />
+      <BaseYdztRadarMusic v-if="isYdzt && isMusic" />
+      <dv-scroll-board :config="isMusic ? config : configDraw" style="width:96%;margin-left:2%" v-if="isYdzt" />
     </div>
   </div>
 </template>
@@ -15,11 +18,61 @@
 <script>
 import BasePointLineBar from '@/components/dashboard/art/BasePointLineBar.vue'
 import BaseKnowPie from '@/components/dashboard/art/BaseKnowPie.vue'
+import BaseYdztRadar from '@/components/dashboard/art/BaseYdztRadar.vue'
+import BaseYdztRadarMusic from '@/components/dashboard/art/BaseYdztRadarMusic.vue'
 
 export default {
   components: {
     BasePointLineBar,
-    BaseKnowPie
+    BaseKnowPie,
+    BaseYdztRadar,
+    BaseYdztRadarMusic
+  },
+  data() {
+    return {
+      config: {
+        header: ["班级", "音乐要素表现", "音乐风格与流派", "音乐体裁和形式", "音乐常识"],
+        data: [
+          ['六年级', '53.06%', '50.34%', '63.74%', '44.41%'],
+          ['1班', '52.27%', '51.45%', '63.35%', '45.22%'],
+          ['2班', '50.77%', '39.77%', '62.42%', '44.55%'],
+          ['3班', '53.62%', '48.86%', '62.84%', '46.82%'],
+          ['4班', '55.61%', '50.72%', '64.81%', '45.22%'],
+          ['5班', '55.45%', '52.17%', '60.19%', '38.26%'],
+          ['6班', '50.57%', '58.51%', '68.74%', '46.52%'],
+        ],
+        rowNum: 8, //表格行数
+        headerHeight: 35,
+        headerBGC: "#0f1325", //表头
+        oddRowBGC: "#0f1325", //奇数行
+        evenRowBGC: "#171c33", //偶数行
+      },
+      configDraw: {
+        header: ["班级", "图像识读", "美术表现", "审美判断", "创意实践", "文化理解"],
+        data: [
+          ['六年级', '56.23%', '62.48%', '62.06%', '54.89%', '68.48%'],
+          ['1班', '65.02%', '60.41%', '51.56%', '49.64%', '69.66%'],
+          ['2班', '46.42%', '61.10%', '59.77%', '50.38%', '54.61%'],
+          ['3班', '59.86%', '59.93%', '65.91%', '64.73%', '72.82%'],
+          ['4班', '55.86%', '68.13%', '68.14%', '57.25%', '75.61%'],
+          ['5班', '53.69%', '62.74%', '69.79%', '56.34%', '72.00%'],
+          ['6班', '56.32%', '62.37%', '57.81%', '51.45%', '65.87%'],
+        ],
+        rowNum: 8, //表格行数
+        headerHeight: 35,
+        headerBGC: "#0f1325", //表头
+        oddRowBGC: "#0f1325", //奇数行
+        evenRowBGC: "#171c33", //偶数行
+      }
+    }
+  },
+  computed: {
+    isYdzt() {
+      return localStorage.getItem('login_schoolCode') === 'ydzt'
+    },
+    isMusic() {
+      return this.$store.state.dashboard.subject === 'music'
+    }
   }
 }
 </script>

+ 65 - 11
TEAMModelOS/ClientApp/src/components/dashboard/art/RightTop.vue

@@ -25,10 +25,10 @@ import BaseClassLineBar from '@/components/dashboard/art/BaseClassLineBar.vue'
 import BaseStuLineBar from '@/components/dashboard/art/BaseStuLineBar.vue'
 import LeftCenter from '@/components/dashboard/art/LeftCenter.vue'
 export default {
-  props:{
-    school:{
-      type:String,
-      default:''
+  props: {
+    school: {
+      type: String,
+      default: ''
     }
   },
   components: {
@@ -49,21 +49,38 @@ export default {
     onSelect(val) {
       console.log(val);
       if (val.length === 1) {
-        this.$store.commit('setRandomArtData', 'all')
+        this.$store.commit('setRandomArtData', this.isYdzt ? 'grade' : 'all')
+
       } else if (val.length === 2) {
-        this.$store.commit('setRandomArtData', 'grade')
+        // this.$store.commit('setRandomArtData', this.isYdzt ? 'single' : 'grade')
+        if (!this.isYdzt) {
+          this.$store.commit('setRandomArtData', 'grade')
+        } else {
+          this.$store.commit('setYdztStuData', val)
+        }
       } else {
-        this.$store.commit('setRandomArtData', 'single')
+        if (!this.isYdzt) {
+          this.$store.commit('setRandomArtData', 'single')
+        }
       }
     }
   },
+  mounted() {
+    if (this.isYdzt) {
+      this.cascaderVal = ['grade6']
+      this.$store.commit('setRandomArtData', 'grade')
+    }
+  },
   computed: {
     classType() {
       console.log(this.$store.state.dashboard.classType);
       return this.$store.state.dashboard.classType
     },
-    classData(){
-      if(this.school == '成都市青羊实验中学'){
+    isYdzt() {
+      return localStorage.getItem('login_schoolCode') === 'ydzt'
+    },
+    classData() {
+      if (this.school == '成都市青羊实验中学') {
         return [{
           value: 'all',
           label: '全校',
@@ -158,7 +175,7 @@ export default {
             // }
           ],
         }]
-      }else{
+      } else {
         let data = [{
           value: 'all',
           label: '全校',
@@ -195,7 +212,7 @@ export default {
             }
           ]
         }]
-        if(!this.school){
+        if (!this.school) {
           data[0].children.push({
             value: 'grade6',
             label: '六年级',
@@ -227,6 +244,43 @@ export default {
             ]
           })
         }
+
+        if (this.isYdzt) {
+          data = [
+            {
+              value: 'grade6',
+              label: '六年级',
+              children: [
+                {
+                  value: 'class1',
+                  label: '1班',
+                },
+                {
+                  value: 'class2',
+                  label: '2班',
+                },
+                {
+                  value: 'class3',
+                  label: '3班',
+                },
+                {
+                  value: 'class4',
+                  label: '4班',
+                },
+                {
+                  value: 'class5',
+                  label: '5班',
+                },
+                {
+                  value: 'class6',
+                  label: '6班',
+                }
+              ]
+            }
+          ]
+        }
+
+
         return data
       }
     }

+ 410 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseList.less

@@ -0,0 +1,410 @@
+@import '~@/assets/student-web/component_styles/color.less';
+
+.courselist-view {
+
+    .list {
+        width: 25%;
+
+        .tableViewBtn,
+        .listViewBtn {
+            display: inline-block;
+            position: fixed;
+            right: 20px;
+            top: -50px;
+            z-index: 999;
+
+            &:hover {
+                color: @primary;
+                cursor: pointer
+            }
+        }
+
+        .chooseView {
+            color: @primary;
+        }
+
+        .listViewBtn {
+            right: 50px;
+        }
+
+        .listViewBtn {
+            display: inline-block;
+            position: absolute;
+        }
+
+        .addCourseIcon {
+            font-size: 60px;
+            margin: 10px;
+        }
+
+        .typeMark {
+            text-align: center;
+            background-color: @primary;
+            color: white;
+            font-size: 14px;
+            padding: 1px 10px;
+            border-radius: 10px;
+            margin-right: 10px;
+            margin-top: 3px;
+        }
+
+        .list-block {
+            margin-top: 10px;
+
+            .list-table {
+                margin: 0 10px;
+
+                .table-item {
+                    cursor: pointer;
+                }
+
+                .list-name {
+                    font-weight: bold;
+                    font-size: 16px;
+                    margin-top: 5px;
+                }
+            }
+
+            .list-item-no {
+                text-align: center;
+            }
+        }
+
+        .list-item {
+            height: auto;
+            padding-left: 3%;
+            padding: 0;
+
+            .basic-info {
+                display: none;
+            }
+
+            &:hover {
+                .basic-info {
+                    display: inline-block;
+                }
+            }
+
+            .list-item-info {
+                width: 100% !important;
+                padding: 15px 30px 15px 30px;
+
+                &>span {
+                    float: right;
+                }
+
+            }
+
+            .time-box {
+                // color: #515a6e;
+                // background-color: #F8F8F9;
+                width: 100%;
+                // padding: 10px 20px 10px 30px;
+                margin-top: 15px;
+
+                &>p {
+                    margin-bottom: 5px;
+                }
+            }
+        }
+
+        .ivu-tabs-tabpane {
+            padding-bottom: 100px;
+            height: 92vh;
+            overflow: auto;
+        }
+
+        .courseTable {
+            margin: 20px;
+
+            .table-time {
+                font-size: 8px;
+            }
+
+            .courseName {
+                font-size: 12px;
+                color: #515a6e;
+                font-weight: bolder;
+            }
+
+            .list-item-typeMark {
+                width: auto;
+                text-align: center;
+                background-color: #dfdfdf;
+                padding: 1px 5px;
+                border-radius: 10px;
+                margin-top: 3px;
+            }
+        }
+
+        .table-item-selected {
+            font-weight: bolder !important;
+            color: @secondary;
+            // background-color: #d4ede1;
+        }
+
+        .table-item-selected {
+            .list-item-typeMark {
+                text-align: center;
+                color: white;
+                background-color: @secondary;
+                padding: 1px 5px !important;
+                border-radius: 10px;
+                margin-top: 3px;
+            }
+        }
+    }
+
+    .courseContentEn {
+        width: 50% !important;
+    }
+
+    .course-content {
+        position: relative;
+        float: right;
+        width: 75%;
+        padding: 2%;
+        height: auto;
+
+        @media screen and (max-width: 991px) {
+            padding-top: 4% !important;
+        }
+
+        h1,
+        h2,
+        h3,
+        h4,
+        h5,
+        h6 {
+            display: block;
+        }
+
+        .course-subject {
+            color: @primary;
+        }
+
+        .basic-title {
+            color: #959494;
+            font-size: 16px;
+
+            &:not(:first-child) {
+                margin-top: 36px;
+            }
+        }
+
+        .basic-data {
+            color: #515a6e;
+            font-weight: bolder;
+            font-size: 16px;
+        }
+
+        .group-title {
+            background-color: #ececec;
+            border-radius: 4px;
+            padding: 5px 15px;
+            margin-bottom: 10px;
+        }
+
+        .group-student {
+            border: 1px solid @border;
+            display: inline-block;
+            padding: 10px;
+            width: 22%;
+            position: relative;
+            margin: 10px;
+
+            td,
+            th {
+                border-bottom: none;
+            }
+
+            .student-no {
+                position: relative;
+                width: 5% !important;
+            }
+        }
+
+        .group-studentEn {
+            width: 30%;
+        }
+
+        @media screen and (max-width: 1366px) {
+            .group-student {
+                width: 30% !important;
+            }
+        }
+
+        @media screen and (max-width: 991px) {
+            .group-student {
+                width: 40% !important;
+            }
+        }
+
+        .my-name {
+            color: #24b880;
+        }
+
+        .list-block-box {
+            // border-right: 1px solid @border;
+            height: 100%;
+            overflow: auto;
+            margin-top: 0px;
+            padding-bottom: 100px;
+            z-index: 5;
+            // width: 25%;
+            background-color: #fff;
+            box-shadow: 4px 1px 10px rgb(0 0 0 / 10%);
+
+            .list-item {
+                list-style-type: none;
+                width: 100%;
+                border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+                padding: 15px 10px 15px 15px;
+                position: relative;
+
+                &:hover {
+                    background: linear-gradient(-0.75turn, #fafafa, #d4ede1);
+                    color: #03966a;
+                    cursor: pointer;
+                }
+
+                .list-item-info {
+                    padding-right: 20px;
+                    position: relative;
+                    display: flex;
+
+                    .list-item-title {
+                        font-weight: bolder;
+                        font-size: 14px;
+                        line-height: 22px;
+                    }
+
+                    .list-item-time {
+                        span {
+                            display: block;
+                        }
+                    }
+                }
+
+                .record-poster-wrap {
+                    width: 120px;
+                    height: 65px;
+                    background-size: contain;
+                    background-repeat: no-repeat;
+                    background-position: center;
+                    margin-right: 20px;
+                }
+
+                .upload {
+                    position: absolute;
+                    top: 40%;
+                    right: 20px;
+                }
+            }
+
+            .list-item-selected {
+                background: linear-gradient(-0.75turn, #fafafa, #d4ede1);
+                color: #03966a;
+                cursor: pointer;
+                // width: 100%;
+            }
+        }
+
+        .info-icon {
+            text-align: right;
+            overflow: hidden;
+
+            &>span:first-child {
+                float: left;
+                font-size: 16px;
+            }
+        }
+
+        .mates-head {
+            margin-bottom: 10px;
+            display: flex;
+            justify-content: space-between;
+
+            .change-name-icon {
+                // display: none;
+                opacity: 0;
+                margin-left: 10px;
+                cursor: pointer;
+            }
+
+            .nick-name {
+                margin-right: 50px;
+            }
+
+            &:hover {
+                .change-name-icon {
+                    // display: inline-block;
+                    opacity: 1;
+                }
+            }
+
+
+        }
+    }
+
+    .group-btn {
+        cursor: pointer;
+        z-index: 1;
+        float: right;
+        position: relative;
+        top: 35px;
+        right: 6%;
+        font-size: 25px;
+    }
+
+    .group-on {
+        color: @primary;
+    }
+}
+
+.hide-sidebar * {
+    width: 0px !important;
+    transition: ease-out 0.3s;
+}
+
+.course-content-span {
+    padding: 2%;
+    width: 100% !important;
+    transition: 0.5s;
+}
+
+.no-bar {
+    width: 100%;
+}
+
+/* @media screen and (max-width: 768px) {
+    .course-list .list {
+      width: 100%;
+    }
+} */
+
+@media screen and (max-width: 1280px) {
+    .list {
+        width: 33%;
+    }
+
+    .course-content {
+        width: 67%;
+    }
+}
+
+@media screen and (max-width: 1024px) {
+    .list {
+        width: 40%;
+    }
+
+    .course-content {
+        width: 100%;
+    }
+}
+
+@media screen and (max-width: 768px) {
+    .list {
+        width: 100%;
+    }
+}

文件差异内容过多而无法显示
+ 1184 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView.vue


+ 136 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/ActivityView.less

@@ -0,0 +1,136 @@
+@import '~@/assets/student-web/component_styles/color.less';
+
+.activity-view {
+    height: 69vh;
+    display: flex;
+
+    .activity-list{
+        width: 25%;
+        box-shadow: 4px 1px 10px rgb(0 0 0 / 10%);
+        border-right: 1px solid rgba(0, 0, 0, 0.1);
+    }
+
+    
+    
+    .list-item-selected {
+        background: @bgcHover;
+        color: @titleHover;
+        cursor: pointer;
+        width: 100%;
+    }
+
+    .list-new {
+        display: flex;
+        justify-content: space-between;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+        padding: 15px 10px 15px 25px;
+        
+        &:hover{
+            background: linear-gradient(-270deg, #fafafa, #d4ede1);
+            color: #03966a;
+            cursor: pointer;
+        }
+
+        .list-item-title {
+            font-weight: bolder;
+            font-size: 14px;
+            line-height: 22px;
+            
+            .list-item-typeMark {
+                text-align: center;
+                background-color: @titleMarkbgc;
+                border-radius: 10px;
+            }
+        }
+
+        .list-item-time {
+            color: #8f8787;
+            font-size: 12px;
+        }
+
+        .list-new-type {
+            width: 15%;
+            display: flex;
+            justify-content: center;
+            flex-direction: column;
+        }
+
+        .list-new-unDone {
+            font-size: 10px;
+            font-weight: bolder;
+            padding: 5px;
+            border-radius: 4px;
+            text-align: center;
+            border: 1px solid;
+        }
+
+        .isAllowRetry {
+            color: #fff;
+            background-color: #64ae16;
+            border: none;
+        }
+
+        .isWrongPra {
+            margin-top: 10px;
+        }
+        
+        .tag-style {
+            border: 1px solid;
+            padding: 0 5px;
+            border-radius: 3px;
+            margin-right: 10px;
+        }
+
+        
+        .paper-item-school {
+            font-weight: bolder;
+            height: 20px;
+            line-height: 18px;
+            // padding: 5px 2px;
+            // margin-top: 10px;
+            // margin-right: 20px;
+            margin-bottom: 5px;
+            cursor: pointer;
+            display: inline-flex;
+            font-size: 12px;
+    
+            
+            .other-owner {
+                background-color: #ababab;
+                color: #fff;
+                border-radius: 5px 0 0 5px;
+            }
+    
+            .paper-owner {
+                background-color: #ababab;
+                color: #fff;
+                border-radius: 5px 0 0 5px;
+            }
+    
+            .paper-extType{
+                border: 1px solid #ababab;
+                border-radius: 0 5px 5px 0;
+                border-left: none;
+            }
+    
+            .paper-source{
+                border: 1px solid #ababab;
+                // border-radius: 0 5px 5px 0;
+            }
+
+            & > span{
+                padding: 0 5px;
+                white-space: pre;
+            }
+    
+            & > p {
+                margin-left: 10px;
+                font-size: 14px;
+            }
+        }
+    }
+    
+    .activity-content {
+        width: 75%;
+    }
+}

+ 380 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/ActivityView.vue

@@ -0,0 +1,380 @@
+<template>
+    <div>
+        <Loading v-show="isLoad" bgColor="rgba(0, 0, 0, 0.3)"></Loading>
+        <div class="activity-view" v-if="activityList.length">
+            <!-- 列表 -->
+            <div class="activity-list">
+                <vuescroll>
+                    <div :id="`event${item.id}`"
+                        class="list-new"
+                        v-for="(item, index) in activityList"
+                        :key="index"
+                        @click="sentSelectedEventTitle(item)"
+                        :class="{ 'list-item-selected': selectedCondition(item)}"
+                    >
+                        <div>
+                            <div v-if="item.type === 'Exam'">
+                                <div class="paper-item-school">
+                                    <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
+                                    <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
+                                    <span class="paper-source" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab'}" v-if="item.source === '0'">
+                                        {{ $t("studentWeb.exam.source.evMode1") }}
+                                    </span>
+                                    <span class="paper-source" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#2f98a9'}" v-if="item.source === '1'">
+                                        {{ $t("studentWeb.exam.source.evMode2") }}
+                                    </span>
+                                    <span class="paper-source" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}" v-if="item.source === '2'">
+                                        {{ $t("studentWeb.exam.source.evMode3") }}
+                                    </span>
+                                    <span v-if="item.ext.type === 'regular'" class="paper-extType"
+                                            style="color: #dc8f57;"
+                                    >
+                                        {{ $t('totalAnalysis.ti_text6') }}
+                                    </span>
+                                    <span v-if="item.ext.type === 'simulation'" class="paper-extType"
+                                            style="color: #76ae38;"
+                                    >
+                                        {{ $t('totalAnalysis.ti_text7') }}
+                                    </span>
+                                    <span v-if="item.ext.type === 'normal'" class="paper-extType"
+                                            style="color: #a69b17;"
+                                    >
+                                        {{ $t('totalAnalysis.ti_text8') }}
+                                    </span>
+                                </div>
+                                <p class="list-item-title">
+                                    <span>{{ item.name }}</span>
+                                </p>
+                            </div>
+                            <div class="paper-item-school" v-else>
+                                <span class="other-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
+                                <span class="other-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
+                                <p>{{ item.name }}</p>
+                            </div>
+                            <p style="font-size:12px; margin-top: 5px; word-break: keep-all;">
+                                <span v-if="item.type === 'Exam' && item.ext">
+                                    <span v-if="item.ext.subjects">
+                                        <span v-for="(item, index) in item.ext.subjects" :key="index" class="tag-style"
+                                                style="border-color: #499c8d; color: #499c8d;"
+                                        >
+                                            {{ item.name }}
+                                        </span>
+                                    </span>
+                                </span>
+                                <span v-if="item.type === 'Exam' && item.className.length">
+                                    <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
+                                        style="border-color: #8f8787; color: #8f8787;">
+                                        {{ clasNa }}
+                                    </span>
+                                </span>
+                                <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.creatorName">{{ item.creatorName }}</span>
+                            </p>
+                            <p class="list-item-time">
+                                {{ item.startTime2 }} ~ {{ item.endTime2 }}
+                            </p>
+                        </div>
+                        <div class="list-new-type">
+                            <span style="font-size: 12px; text-align: center;">{{ item.tempsub }}</span>
+                            <div class="list-new-unDone isAllowRetry" v-show="item.progress === 'going'">
+                                <span>{{$t("studentWeb.public.going")}}</span>
+                            </div>
+                            <div class="list-new-unDone" v-show="item.progress === 'finish'">
+                                <span class="isOvertime">{{ item.type === 'Exam' ? $t("studentWeb.exam.finishOk") : $t("studentWeb.public.finish")}}</span>
+                            </div>
+                            <div class="list-new-unDone" v-show="item.progress === 'noAns'" style="border-color: red;">
+                                <span style="color: red;">{{$t("studentWeb.exam.missExam")}}</span>
+                            </div>
+                            <div class="list-new-unDone" v-show="item.progress === 'noScore'" style="border-color: #ac9263;">
+                                <span style="color: #ac9263;">{{$t("studentWeb.exam.noScoreType")}}</span>
+                            </div>
+                        </div>
+                    </div>
+                </vuescroll>
+            </div>
+            <!-- 内容 -->
+            <div v-if="activityList.length" class="activity-content">
+                <vuescroll>
+                    <div style="margin: 0 70px;">
+                        <PaperView v-if="getItemTitle.type === 'Exam'" />
+                        <Homework v-if="getItemTitle.type === 'Homework'" />
+                        <Vote v-if="getItemTitle.type === 'Vote'" />
+                        <QuesNaire v-if="getItemTitle.type === 'Survey'" />
+                    </div>
+                </vuescroll>
+            </div>
+        </div>
+        <div v-else style="font-size: 25px; text-align: center; margin-top: 5%;">
+            暂没有活动
+        </div>
+    </div>
+</template>
+
+<script>
+import Loading from '@/common/Loading.vue';
+import { mapGetters, mapState } from 'vuex'
+import PaperView from '../../EventView/EventContentTypeTemplate/PaperViewBox/PaperView.vue';
+import Homework from '../../EventView/EventContentTypeTemplate/Homework.vue';
+import Vote from '../../EventView/EventContentTypeTemplate/Vote.vue';
+import QuesNaire from '../../EventView/EventContentTypeTemplate/QuesNaire.vue';
+
+export default {
+    name: "ActivityView",
+    components: {
+        PaperView,
+        Homework,
+        Vote,
+        QuesNaire,
+        Loading,
+    },
+    data () {
+        return {
+            activityList: [],
+            isLoad: false,
+            countDown: null,
+        }
+    },
+    props: {
+        needParam: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    mounted () {
+        this.getActivity()
+        this.selectedCondition(this.getItemTitle);
+    },
+    methods: {
+        getActivity() {
+            this.isLoad = true
+            this.activityList.length = 0
+            let params = {}
+            // 醍摩豆登陆——> roles有teacher
+            if (this.userInfo.scope === "tmduser") {
+                params = {
+                    userid: this.userInfo.sub,
+                    userType: "tmdid",
+                    school: this.userInfo.azp
+                }
+            }
+            // 学生账号登陆
+            else {
+                params = {
+                    userid: this.userInfo.sub,
+                    userType: "schoolid",
+                    school: this.userInfo.azp
+                }
+            }
+            this.$api.studentWeb.getActivityInfo(params).then(async res => {
+                if (res.datas.length) {
+                    /* 
+                        source: 0(线上评量) / 1(课中评量) / 2(阅卷评量)
+                    */
+                    let ids = []
+                    let idsSchool = []
+                    let teaIds = []
+                    res.datas.forEach(item => {
+                        if(item.owner === 'school') {
+                            idsSchool.push(item.classIds)
+                        } else {
+                            ids.push(item.classIds)
+                        }
+                        teaIds.push(item.creatorId)
+                    })
+                    let teaidNames = []
+                    teaidNames = await this.getTeacherName(teaIds)
+                    idsSchool = [].concat.apply([], idsSchool)
+                    ids = [].concat.apply([], ids)
+                    let namesSchool = idsSchool.length ? await this.getClassName(idsSchool, true) : []
+                    let names = ids.length ? await this.getClassName(ids) : []
+                    for (let item of res.datas) {
+                        item.startTime2 = this.dateFormat(item.startTime)
+                        item.endTime2 = this.dateFormat(item.endTime)
+                        item.progress = this.timeStatus(item, true)
+                        item.className = []
+                        item.classIds.forEach(classId => {
+                            let arrSchool = namesSchool.filter(na => {
+                                return na.id === classId
+                            })
+                            if(arrSchool.length) {
+                                item.className.push(arrSchool[0].name)
+                            }
+                            let arr = names.filter(na => {
+                                return na.id === classId
+                            })
+                            if(arr.length) {
+                                item.className.push(arr[0].name)
+                            }
+                        });
+                        item.tempsub = ""
+                        let nameIds = undefined
+                        nameIds = teaidNames.find(names => {
+                            return names.id === item.creatorId
+                        })
+                        item.creatorName = !nameIds ? undefined : nameIds.name
+                    }
+                    res.datas = res.datas.sort(function (a, b) {
+                        return b.startTime - a.startTime //时间正序
+                    });
+                    this.activityList = res.datas.filter(item => {
+                        let ownerClass = item.classIds.find(classId => {
+                            return this.needParam.classes.includes(classId)
+                        })
+                        return ownerClass
+                    })
+                    if(this.activityList.length) {
+                        let twoDay = 24 * 3600 * 1000 * 2
+                        this.countDown = setInterval(() => {
+                            let timeNow = new Date()
+                            for (const item of this.activityList) {
+                                let timeSub = item.endTime - timeNow
+                                item.tempsub = (item.taskStatus === -1 && timeSub > 0 && timeSub < twoDay) ? this.getTimeSub(timeSub) : ""
+                            }
+                        }, 1000)
+                    }
+                    // 没有选择的时候,默认展示第一个
+                    // if (this.getIsSelectedNow === false) {
+                        this.sentSelectedEventTitle(this.activityList[0])
+                    // }
+                }
+            }).finally(() => {
+                this.isLoad = false
+            })
+        },
+        getClassName(ids, type) {
+            return new Promise((r, j) => {
+                let params = {ids}
+                if(type) {
+                    params.schoolId = this.userInfo.azp
+                }
+                this.$api.learnActivity.getClassNameByIds(params).then(res => {
+                    if(res.groups) {
+                        r(res.groups)
+                    } else {
+                        r([])
+                    }
+                }).catch(e => {
+                    j(e)
+                })
+            })
+        },
+        getTeacherName(id) {
+            return new Promise((r, j) => {
+                this.$api.studentWeb.getTeacherName({id}).then(res => {
+                    r(res)
+                }).catch(e => {
+                    j(e)
+                })
+            })
+        },
+        getTimeSub(sub) {
+            // 天数
+            var days = Math.floor(sub / (24 * 3600 * 1000))
+            // 小时
+            var leave1 = sub % (24 * 3600 *1000)
+            var hours = Math.floor(leave1 / (3600 * 1000))
+            if(hours < 10) {
+                hours = "0" + hours
+            }
+            // 分钟
+            var leave2 = leave1 % (3600 * 1000)
+            var minutes = Math.floor(leave2 / (60 * 1000))
+            if(minutes < 10) {
+                minutes = "0" + minutes
+            }
+            // 秒
+            var leave3 = leave2 % (60 * 1000);
+            var seconds = Math.round(leave3 / 1000);
+            if (seconds < 10) {
+                seconds = "0" + seconds;
+            }
+            
+            return (days ? (days + this.$t("studentWeb.public.day")) : '') + hours + this.$t("studentWeb.public.hour") + minutes + this.$t("studentWeb.public.minute")
+        },
+        selectedCondition(item) {
+            if (
+                this.getIsSelectedNow === true &&
+                this.getItemTitle.id === item.id
+            ) {
+                return true;
+            } else return false;
+        },
+        timeStatus(data, type) {
+            // type:只获取活动是否结束
+            let date = (new Date()).getTime() //当前时间
+            if (date >= data.endTime) {
+                if(type) {
+                    return 'finish'
+                } else if(data.eventType != 'Exam'){
+                    return 'finish'
+                } else {
+                    // 线上评测、未作答
+                    if(data.taskStatus === -1 && data.source === '0') {
+                        // 缺考
+                        return 'noAns'
+                    } else if(!data.sStatus) {
+                        // 以前的sStatus都为0,所以全是未评分
+                        // 未评分
+                        return 'noScore'
+                    } else {
+                        // 已结束
+                        return 'finish'
+                    }
+                }
+            } else {
+                return 'going'
+            }
+        },
+        //时间格式化处理
+        dateFormat(timestamp) {
+            var date = new Date(timestamp)
+            var Y = date.getFullYear() + '-'
+            var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
+            var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' '
+            var H = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ":"
+            var Min = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())
+            var S = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()) + " "
+            return Y + M + D + H + Min;
+        },
+        // 展示活动
+        async sentSelectedEventTitle(item) {
+            console.log(item);
+            // this.$store.commit("ToggleSidebar", false);
+            // 活动信息
+            this.$store.commit("SetPaperInfo", item)
+            ////改變ItemName的狀態 vuex mutations
+            this.$store.commit("ChangeItemName", item);
+            localStorage.setItem("Item", encodeURIComponent(JSON.stringify(item)))
+            ////重置問卷
+            this.$store.commit('resetSurvey', true)
+            ////重置預習活動
+            this.$store.commit("PassPhaseTest", 0); //通过阶段
+            this.$store.commit("ChangeCurrentPhase", 0); //单元阶段
+            this.$store.commit("ChangeCurrentSelectedReadingName", 1); //选中教材
+            this.$store.commit("ToggleSentCurrentphase", false); //显示单元测验的答案
+            this.$store.commit("SetCurrentQuestionNo", 0);
+            this.$store.commit("SetTrytestCount", [0, 0, 0]);
+        },
+    },
+    computed: {
+        ...mapState({
+            userInfo: state => state.userInfo,
+        }),
+        ...mapGetters([
+            "getSidebarisOpen",
+            "getIsSelectedNow",
+            "getItemTitle",
+        ])
+    },
+    beforeDestroy () {
+        clearInterval(this.countDown)
+        this.countDown = null
+    },
+}
+</script>
+
+
+<style lang="less" scoped>
+@import "./ActivityView.less";
+</style>

+ 77 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/SchoolReport.less

@@ -0,0 +1,77 @@
+@import '~@/assets/student-web/component_styles/color.less';
+
+.report-head {
+    display: flex;
+    justify-content: space-between;
+
+    .base-info {
+        display: flex;
+        flex-direction: column;
+        align-items: flex-start;
+        margin-right: 50px;
+        padding-top: 1%;
+
+        & > span {
+            margin-bottom: 5px;
+        }
+    }
+
+    .filter-type{
+        padding: 1%;
+        margin-bottom: 20px;
+
+        & > div{
+            margin-bottom: 12px;
+
+            &:last-child {
+                margin-bottom: 0;
+                // margin-top: 10px;
+            }
+        }
+
+        .type-name {
+            margin-right: 10px;
+            font-weight: bold;
+        }
+        
+        .point-box {
+            border: 1px solid #24B880;
+            background-color: @primary;
+            color: #fff;
+            padding: 3px 5px;
+            border-radius: 5px;
+            margin-right: 10px;
+            display: inline-block;
+
+            .ivu-icon{
+                cursor: pointer;
+                margin-left: 5px;
+            }
+        }
+
+        .ivu-icon-md-add-circle {
+            // font-weight: bold;
+            cursor: pointer;
+        }
+
+        .have-total {
+            display: inline-block;
+            float: right;
+
+            & > span{
+                font-size: 18px;
+                font-weight: bold;
+                color: #de0000;
+                margin: 0 5px;
+            }
+        }
+    }
+}
+
+.tag-style {
+    border: 1px solid;
+    padding: 0 5px;
+    border-radius: 3px;
+    margin-right: 10px;
+    font-size: 12px;
+}

+ 317 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseView/SchoolReport.vue

@@ -0,0 +1,317 @@
+<template>
+    <div class="achievement-report">
+        <div class="report-head student-check">
+            <div class="filter-type">
+                <div>
+                    <span class="type-name">{{ $t('studentWeb.baseInfo.examMode') }}:</span>
+                    <RadioGroup v-model="filterType.sourceType" type="button" button-style="solid">
+                        <Radio v-for="(item, index) in sourceTypeList" :key="index" :label="item.type">{{ item.name }}</Radio>
+                    </RadioGroup>
+                </div>
+                <!-- <div>
+                    <span class="type-name">{{ $t('studentWeb.baseInfo.examStatus') }}:</span>
+                    <RadioGroup v-model="examType" type="button" button-style="solid">
+                        <Radio v-for="(item, index) in examTypeList" :key="index + 1" :label="item.type">{{ item.name }}</Radio>
+                    </RadioGroup>
+                </div> -->
+                <div>
+                    <span class="type-name">{{ $t('studentWeb.baseInfo.examStatus') }}:</span>
+                    <RadioGroup v-model="filterType.ownerType" type="button" button-style="solid">
+                        <Radio v-for="(item, index) in ownerTypeList" :key="index" :label="item.type">{{ item.name }}</Radio>
+                    </RadioGroup>
+                </div>
+            </div>
+            <p class="base-info">
+                <span v-if="classInfo.teaName">
+                    <Icon type="ios-contact-outline" style="font-weight: bold; margin-right: 5px;" />{{ $t('studentWeb.baseInfo.teacher') }}
+                    <span class="base-info-text">{{ classInfo.teaName }}</span>
+                </span>
+                <span v-if="classInfo.name">
+                    <Icon custom="iconfont icon-mingdan" style="font-weight: bold; margin-right: 5px;" />{{ $t('studentWeb.baseInfo.subjectName') }}
+                    <span class="base-info-text">{{ classInfo.name }}</span>
+                </span>
+                <span>
+                    <Icon type="ios-contact-outline" style="font-weight: bold; margin-right: 5px;" />{{ $t('studentWeb.baseInfo.nowStu') }}
+                    <span class="base-info-text">{{ $store.state.userInfo.name }}</span>
+                </span>
+            </p>
+        </div>
+        <!-- <Table :columns="schoolRepCol" :data="showSchoolRep" :span-method="handleSpan"> -->
+        <Table :columns="schoolRepCol" :data="showSchoolRep" height="550">
+            <template slot-scope="{ row }" slot="tag">
+                <!-- <p>{{ row.name }}</p> -->
+                <span class="tag-style">{{ row.tag.owner === 'school' ? $t('studentWeb.public.school') : $t('studentWeb.public.private')}}</span>
+                <span class="tag-style" v-if="row.tag.source">{{ row.tag.source }}</span>
+                <span class="tag-style" v-if="row.tag.type">{{ row.tag.type }}</span>
+                <!-- <span class="tag-style">{{ row.tag.class }}</span> -->
+                <!-- <span class="tag-style">{{ row.tag.list }}</span> -->
+            </template>
+            <!-- <template slot-scope="{ row }" slot="score">
+                <span v-for="(item, index) in row.score" :key="index" style="margin-right: 10px;">{{ item }}</span>
+            </template> -->
+        </Table>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "",
+    components: {
+    },
+    props: {
+        classInfo: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+    },
+    data () {
+        return {
+            schoolRepCol: [
+                /* {
+                    width: 50,
+                    type: 'expand',
+                }, */
+                {
+                    title: this.$t("studentWeb.myAchievement.name"),
+                    // slot: "name",
+                    key: 'examName',
+                    align: "center"
+                    // tree: true,
+                    // width: 500,
+                },
+                /* {
+                    title: '创建人',
+                    key: 'creator',
+                    align: "center"
+                },
+                {
+                    title: '学科',
+                    key: 'class',
+                    align: "center"
+                }, */
+                {
+                    title: this.$t("studentWeb.myAchievement.score"),
+                    // slot: "score",
+                    key: "score",
+                    align: "center"
+                },
+                {
+                    title: this.$t("studentWeb.myAchievement.tag"),
+                    slot: "tag",
+                    width: 500,
+                    align: "center"
+                },
+                /* {
+                    title: '名单',
+                    key: 'list'
+                }, */
+                {
+                    title: this.$t("studentWeb.myAchievement.createTime"),
+                    key: 'time',
+                    align: "center"
+                }
+            ],
+            schoolRep: [],
+            showSchoolRep: [],
+            filterType: {
+                ownerType: "all",
+                sourceType: "all",
+            },
+            ownerType: "all",
+            sourceType: "all",
+            examType: "all",
+            ownerTypeList: [
+                {
+                    type: "all",
+                    name: this.$t('studentWeb.type.all')
+                },
+                {
+                    type: "school",
+                    name: this.$t('studentWeb.public.school')
+                },
+                {
+                    type: "teacher",
+                    name: this.$t('studentWeb.public.private')
+                },
+            ],
+            sourceTypeList: [
+                {
+                    type: "all",
+                    name: this.$t('studentWeb.type.all')
+                },
+                {
+                    type: "0",
+                    name: this.$t("studentWeb.exam.source.evMode1")
+                },
+                {
+                    type: "1",
+                    name: this.$t("studentWeb.exam.source.evMode2")
+                },
+                {
+                    type: "2",
+                    name: this.$t("studentWeb.exam.source.evMode3")
+                },
+            ],
+            examTypeList: [
+                {
+                    type: "all",
+                    name: this.$t('studentWeb.type.all')
+                },
+                {
+                    type: "normal",
+                    name: this.$t('totalAnalysis.ti_text8')
+                },
+                {
+                    type: "simulation",
+                    name: this.$t('totalAnalysis.ti_text7')
+                },
+                {
+                    type: "regular",
+                    name: this.$t('totalAnalysis.ti_text6')
+                },
+            ],
+            num: [],
+        }
+    },
+    mounted () {
+        /* this.showSchoolRep.forEach((item, index) => {
+            for (let i = index + 1; i < this.showSchoolRep.length; i++) {
+                if(item.id === this.showSchoolRep[i].id && !this.num.includes(index)) {
+                    this.num.push(i)
+                }
+            }
+        }); */
+        this.getReportList(this.classInfo)
+    },
+    methods: {
+        getReportList(classInfo) {
+            this.showSchoolRep = []
+            this.schoolRep = []
+            console.log(classInfo);
+            let cId = classInfo.classId.concat(classInfo.stuList)
+            let param = {
+                courseId: classInfo.id,
+                // code: classInfo.scope === "school" ? classInfo.school : classInfo.creatorId,
+                cId,
+                stuId: this.$store.state.userInfo.sub,
+            }
+            if(classInfo.subject.id) {
+                param.subjectId = classInfo.subject.id
+            }
+            this.$api.studentWeb.getClassScore(param).then(res => {
+                // 404表示没有评测记录
+                if(res.code === 404) {
+                    // this.showSchoolRep = []
+                } else if(res.info) {
+                    res.info.forEach(item => {
+                        item.tag = {
+                            source: item.source === '0' ? this.$t("studentWeb.exam.source.evMode1")
+                                    : (item.source === '1' ? this.$t("studentWeb.exam.source.evMode2")
+                                    : (item.source === '2' ? this.$t("studentWeb.exam.source.evMode3") : null)),
+                            type: (item.eType && item.eType.id) ? item.eType.name : null,
+                            owner: item.owner
+                        }
+                        item.total = 0
+                        // 学校评测才会存在多科,要匹配对应的科目
+                        if(item.owner === 'school') {
+                            let subIndex = item.subject.findIndex(sub => {
+                                return sub.id === classInfo.subject.id
+                            })
+                            if(subIndex != -1) {
+                                item.point[subIndex].forEach(point => {
+                                    item.total += point
+                                })
+                            }
+                        } else {
+                            // 个人评测只存在一张试卷
+                            item.point[0].forEach(point => {
+                                item.total += point
+                            })
+                        }
+                        item.total.toFixed(0)
+                        item.time = this.dateFormat(item.createTime)
+                        item.score = `${item.sum} / ${item.total}`
+                        this.schoolRep.push(item)
+                    })
+                    this.schoolRep.reverse()
+                    this.showSchoolRep = [...this.schoolRep]
+                }
+            })
+        },
+        //时间格式化处理
+        dateFormat(timestamp) {
+            var date = new Date(timestamp)
+            var Y = date.getFullYear() + '-'
+            var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
+            var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' '
+            var H = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ":"
+            var Min = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())
+            var S = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()) + " "
+            return Y + M + D + H + Min;
+        },
+        handleSpan ({ row, column, rowIndex, columnIndex }) {
+            // 要把后面相同的使用[0, 0]隐藏掉
+            if(this.num.includes(rowIndex)) {
+                if(columnIndex != 2 && columnIndex != 3) {
+                    return [0, 0]
+                }
+            } else {
+                if(columnIndex != 2 && columnIndex != 3) {
+                    let x = row.mergeCol ? row.mergeCol : 1
+                    let y = 1
+                    return [x, y]
+                }
+            }
+        }
+    },
+    watch: {
+        filterType: {
+            deep: true,
+            handler(n, o) {
+                this.showSchoolRep = []
+                if(n.sourceType === '0') {
+                    this.showSchoolRep = this.schoolRep.filter(item => {
+                        return item.source === '0'
+                    })
+                } else if(n.sourceType === '1') {
+                    this.showSchoolRep = this.schoolRep.filter(item => {
+                        return item.source === '1'
+                    })
+                } else if(n.sourceType === '2') {
+                    this.showSchoolRep = this.schoolRep.filter(item => {
+                        return item.source === '2'
+                    })
+                } else {
+                    this.showSchoolRep = this.schoolRep
+                }
+
+                if(n.ownerType === "teacher") {
+                    this.showSchoolRep = this.showSchoolRep.filter(item => {
+                        return item.owner === "teacher"
+                    })
+                } else if(n.ownerType === "school") {
+                    this.showSchoolRep = this.showSchoolRep.filter(item => {
+                        return item.owner === "school"
+                    })
+                }
+            }
+        }
+    }
+}
+</script>
+
+<style lang="less" scoped>
+@import "./SchoolReport.less";
+</style>
+
+<style lang="less">
+@import "../../WrongQusetion/iViewStyle.less";
+
+.achievement-report {
+    .ivu-tabs-tabpane td:nth-child(2) {
+        text-align: center !important;
+    }
+}
+</style>

+ 162 - 0
TEAMModelOS/ClientApp/src/components/student-web/CourseView/CourseiView.less

@@ -0,0 +1,162 @@
+.courselist-view {
+    overflow: hidden;
+}
+
+.ivu-modal-body {
+    min-height: 420px !important;
+}
+
+/* iview样式修改 */
+.course-content {
+
+    //分頁組件
+    .ivu-tabs-nav {
+        float: left !important;
+
+        text-align: center;
+        margin-top: 20px;
+        position: relative;
+
+        @media screen and (max-width: 1366px) {
+            margin-top: 8px;
+        }
+    }
+
+    .ivu-tabs-tab {
+        text-align: center !important;
+
+        font-size: 20px;
+        margin: 0px 10px;
+        width: auto;
+
+    }
+
+    .ivu-tabs-tab:hover {
+        text-align: center !important;
+        color: #24b880 !important;
+    }
+
+    .ivu-tabs-tab.ivu-tabs-tab-active.ivu-tabs-tab-focused {
+        color: #24b880 !important;
+        font-weight: bolder;
+        border-bottom: 5px solid #24b880 !important;
+        margin: 0px 10px;
+        width: auto;
+    }
+
+    .ivu-tabs-ink-bar {
+        height: 0px;
+    }
+
+    .ivu-tabs-tabpane {
+        position: relative;
+        margin: 10px 0px;
+        overflow-x: hidden;
+
+        table {
+            font-weight: 400;
+            border-collapse: collapse;
+            width: 100%;
+        }
+
+        td,
+        th {
+            font-size: 16px;
+            text-align: center;
+            border-bottom: 1px solid #dddddd;
+            padding: 5px 0px;
+
+            @media screen and (max-width: 1366px) {
+                font-size: 14px;
+            }
+
+            &:nth-child(2) {
+                // text-align: left;
+            }
+        }
+
+        /*
+        tr:nth-child(even) {
+            background-color: #dddddd;
+        }*/
+        td {
+
+            &:first-child,
+            &:last-child {
+                width: 20%;
+            }
+
+            &:nth-child(2) {
+                // text-align: left;
+            }
+        }
+
+        /*  &:last-child {
+            margin-top: -16px;
+            // padding-top: 10px;
+            height: auto;
+        } */
+    }
+
+    .ivu-collapse-simple {
+        border: none !important;
+    }
+
+    .ivu-collapse>.ivu-collapse-item>.ivu-collapse-header {
+        padding-left: 0px;
+        font-weight: bolder;
+        color: #24b880;
+    }
+
+    .info-icon .ivu-icon {
+        // font-weight: bold;
+        margin-right: 10px;
+        cursor: pointer;
+    }
+
+
+    .change-name>.ivu-icon {
+        margin-left: 10px;
+        cursor: pointer;
+    }
+}
+
+.list {
+    .ivu-tabs-nav {
+        float: left !important;
+
+        text-align: center;
+        margin-top: 20px;
+        position: relative;
+
+        @media screen and (max-width: 1366px) {
+            margin-top: 8px;
+        }
+    }
+
+    .ivu-tabs-tab {
+        text-align: center !important;
+
+        // font-size: 20px;
+        margin: 0px 10px;
+        width: auto;
+
+    }
+
+    .ivu-tabs-tab:hover {
+        text-align: center !important;
+        color: #24b880 !important;
+    }
+
+    .ivu-tabs-tab.ivu-tabs-tab-active.ivu-tabs-tab-focused {
+        color: #24b880 !important;
+        font-weight: bolder;
+        border-bottom: 5px solid #24b880 !important;
+        margin: 0px 10px;
+        width: auto;
+    }
+
+    .ivu-tabs-ink-bar {
+        height: 0px;
+    }
+}

+ 226 - 0
TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.less

@@ -0,0 +1,226 @@
+.lightBox {
+    position: fixed !important;
+    width: 100%;
+    /* Full width (cover the whole page) */
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.651);
+    z-index: 99;
+    top: 0px;
+    left: 0px;
+    text-align: center;
+}
+
+.lightboxImg {
+    margin-top: 7.5%;
+    margin-left: 1.5%;
+    width: 40%;
+    position: relative;
+}
+
+.Imgtext {
+    color: white;
+    position: relative;
+    text-align: left;
+    top: 0%;
+    left: 29.5%;
+    font-weight: 900;
+}
+
+.ImgCloseIcon {
+    color: white;
+    position: fixed;
+    font-size: 40px;
+    right: 0;
+    margin: 20px;
+    cursor: pointer;
+}
+
+.ImgleftBtn,
+.ImgrightBtn {
+    background: rgba(0, 0, 0, 0.85);
+    color: #ffffff;
+    font-size: 24px;
+    height: 60px;
+    width: 60px;
+    border: none;
+    border-radius: 5px;
+    cursor: pointer;
+    outline: none;
+}
+
+.ImgleftBtn:hover,
+.ImgrightBtn:hover {
+    background: #03966a;
+}
+
+.ImgleftBtn {
+    position: absolute;
+    top: 40%;
+    left: 25%;
+}
+
+.ImgrightBtn {
+    position: absolute;
+    top: 40%;
+    right: 26%;
+}
+
+.dec {
+    margin-top: 20px;
+
+    .referlink {
+        color: #24b880;
+        font-weight: 900;
+
+        &:hover {
+            color: #1c8d62;
+        }
+    }
+
+    img {
+        max-width: 300px !important;
+    }
+
+    li {
+        list-style: none;
+        border-bottom: 1px solid rgba(128, 128, 128, 0.164);
+
+        &:last-child {
+            border-bottom: none;
+        }
+
+        .referdoclink {
+            font-size: 14px;
+            line-height: 42px;
+            color: #484848;
+            font-weight: 400;
+
+            &:hover {
+                color: #24b880;
+            }
+        }
+
+        .docIcon {
+            color: #484848;
+            font-size: 24px;
+            top: 2px;
+            position: relative;
+        }
+    }
+
+    .decImg {
+        background-repeat: no-repeat;
+        background-size: cover;
+        background-position: center;
+        border: 2px solid gray;
+        border-radius: 4px;
+        position: relative;
+        margin-top: 20px;
+        text-align: center;
+        width: 100%;
+        height: 0;
+        padding-bottom: 80%;
+        cursor: pointer;
+        border: none;
+
+        &:hover {
+            box-shadow: 0px 1px 13px rgba(0, 0, 0, 0.2);
+            transform: scale(1.02);
+            transition: 0.5s ease;
+        }
+    }
+
+    .decImgs {
+        position: relative;
+    }
+
+    .carouselImg {
+        background-repeat: no-repeat;
+        background-size: cover;
+        background-position: center;
+        border: 2px solid gray;
+        position: relative;
+        width: 100%;
+        height: 0;
+        padding-bottom: 80%;
+        border: none;
+        border-radius: 4px;
+    }
+
+    .decImglasthint {
+        position: relative;
+        color: #ffffff;
+        font-size: 40px;
+        padding-top: 22%;
+        margin: auto;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+    }
+}
+
+@media screen and (max-width: 991px) {
+    .lightboxImg {
+        margin-top: 20%;
+        width: 60%;
+    }
+
+    .Imgtext {
+        left: 19.5%;
+    }
+
+    .ImgleftBtn {
+        left: 10%;
+    }
+
+    .ImgrightBtn {
+        right: 10%;
+    }
+
+    .dec li {
+        padding: 10px 0px;
+
+        .referdoclink {
+            line-height: 20px;
+        }
+    }
+}
+
+@media screen and (max-width: 767px) {
+    .lightboxImg {
+        margin-top: 30%;
+        width: 60%;
+    }
+}
+
+@media screen and (max-width: 1366px) {
+    .lightboxImg {
+        margin-top: 10%;
+        width: 40%;
+    }
+}
+
+@media screen and (max-width: 1280px) {
+    .lightboxImg {
+        margin-top: 8%;
+        width: 54%;
+    }
+
+    .Imgtext {
+        left: 22.5%;
+    }
+
+    .ImgleftBtn {
+        left: 15%;
+    }
+
+    .ImgrightBtn {
+        right: 15%;
+    }
+}
+
+@media screen and (max-width: 1280px) and (min-width: 992px) {
+    .dec .decImglasthint {
+        padding-top: 16%;
+    }
+}

+ 5 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.vue

@@ -95,5 +95,9 @@
 </script>
 
 <style scoped>
-    @import "~@/assets/student-web/component_styles/billboard-lightbox.css";
+    /* @import "~@/assets/student-web/component_styles/billboard-lightbox.css"; */
 </style>
+
+<style lang="less" scoped>
+@import "./BillBoardandLightBox.less";
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContent.vue

@@ -31,7 +31,7 @@
     import Homework from "./EventContentTypeTemplate/Homework";
     import PreviewMission from "./EventContentTypeTemplate/PreviewMission";
     import Vote from "./EventContentTypeTemplate/Vote";
-    import PaperView from "./EventContentTypeTemplate/PaperView";
+    import PaperView from "./EventContentTypeTemplate/PaperViewBox/PaperView";
     import VoteHint from "./EventContentTypeTemplate/VoteHint";
     import QuesNaire from "./EventContentTypeTemplate/QuesNaire";
     import { mapGetters } from 'vuex';

TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.less → TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/LessonTestReport.less


+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue

@@ -391,8 +391,8 @@
 
 <script>
     import pdf from 'vue-pdf'
-    import LessonTestReportCharts from "./LessonTestReportCharts/LessonTestReportCharts";
-    import QuCount from './LessonTestReportCharts/QuCount.vue';
+    import LessonTestReportCharts from "../LessonTestReportCharts/LessonTestReportCharts";
+    import QuCount from '../LessonTestReportCharts/QuCount.vue';
     import SubjectMould from './SubjectMould.vue';
     import Loading from "vue-loading-overlay";
     import "vue-loading-overlay/dist/vue-loading.css";

TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.less → TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperTest.less


+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.vue

@@ -415,8 +415,8 @@
     /* import Loading from "vue-loading-overlay";
     import "vue-loading-overlay/dist/vue-loading.css"; */
     import Loading from '@/common/Loading.vue'
-    import Compose from './composePaper.vue'
-    import Complete from './completePaper.vue'
+    import Compose from '../composePaper.vue'
+    import Complete from '../completePaper.vue'
     import { mapGetters } from 'vuex';
     export default {
         name: "PaperTest",

TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView-style.less → TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperView-style.less


TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.less → TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperView.less


+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue

@@ -74,9 +74,9 @@
     import "vue-loading-overlay/dist/vue-loading.css"; */
     import Loading from '@/common/Loading.vue'
     import { mapGetters, mapState } from 'vuex';
-    import EventBasicInfo from "../../EventBasicInfo";
+    import EventBasicInfo from "../../../EventBasicInfo";
     import LessonTestReport from "./LessonTestReport";
-    import StudentScore from "./LessonTestReportCharts/StudentScore";
+    import StudentScore from "../LessonTestReportCharts/StudentScore";
     // import PaperTest from "./PaperTest";
     export default {
         name: "PaperView",

TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/SubjectMould.vue → TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/SubjectMould.vue


+ 184 - 0
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.less

@@ -0,0 +1,184 @@
+.list-new {
+    display: flex;
+    border-bottom: 1px solid rgba(0, 0, 0, .1);
+    padding: 15px 10px 15px 25px;
+
+    &:hover {
+        background: linear-gradient(-270deg, #fafafa, #d4ede1);
+        color: #03966a;
+        cursor: pointer;
+    }
+
+    &-icon {
+        width: 10%;
+        margin-right: 30px;
+        display: flex;
+        justify-content: center;
+        flex-direction: column;
+
+        .svg-icon {
+            width: 40px;
+            height: 40px;
+        }
+    }
+
+    &-test {
+        width: 60%;
+        font-weight: bolder;
+        font-size: 14px;
+        line-height: 22px;
+        margin-right: 20px;
+        clear: both;
+
+        .list-item-typeMark {
+            text-align: center;
+            background-color: #dfdfdf;
+            border-radius: 10px;
+            padding: 1px 10px;
+            margin: 0 8px 0 -10px;
+        }
+
+        .list-item-time {
+            color: #8f8787;
+            font-size: 12px;
+        }
+
+        /* .list-item-title {
+            font-size: 16px;
+            margin: 5px 0;
+        } */
+
+        .isScore {
+            float: right;
+        }
+    }
+
+    &-type {
+        width: 20%;
+        display: flex;
+        justify-content: center;
+        flex-direction: column;
+
+        .list-new-unDone {
+            font-size: 10px;
+            font-weight: bolder;
+            // color: #fff;
+            padding: 5px;
+            border-radius: 4px;
+            text-align: center;
+            border: 1px solid;
+
+
+        }
+
+        .isAllowRetry {
+            color: #fff;
+            background-color: #64ae16;
+            border: none;
+        }
+
+        .isWrongPra {
+            margin-top: 10px;
+        }
+    }
+
+    .text-long {
+        max-width: 150px;
+        height: 16px;
+        line-height: 16px;
+        display: inline-block;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+    }
+
+    .paper-item-school {
+        font-weight: bolder;
+        height: 20px;
+        line-height: 18px;
+        // padding: 5px 2px;
+        // margin-top: 10px;
+        // margin-right: 20px;
+        margin-bottom: 5px;
+        cursor: pointer;
+        display: inline-flex;
+        font-size: 12px;
+
+        .other-owner {
+            background-color: #ababab;
+            color: #fff;
+            border-radius: 5px 0 0 5px;
+        }
+
+        .paper-owner {
+            background-color: #ababab;
+            color: #fff;
+            border-radius: 5px 0 0 5px;
+        }
+
+        .paper-extType {
+            border: 1px solid #ababab;
+            border-radius: 0 5px 5px 0;
+            border-left: none;
+        }
+
+        .paper-source {
+            border: 1px solid #ababab;
+            // border-radius: 0 5px 5px 0;
+        }
+
+        &>span {
+            padding: 0 5px;
+            white-space: pre;
+        }
+
+        &>p {
+            margin-left: 10px;
+            font-size: 14px;
+        }
+    }
+}
+
+// 未开展标识
+.dev-top {
+    .develop {
+        position: absolute;
+        top: 1px;
+        right: -13px;
+        font-size: xx-small;
+        color: #fff;
+        padding: 2px 5px;
+        z-index: 99;
+        transform: scale(0.7) rotate(45deg);
+    }
+
+    &::after {
+        position: absolute;
+        content: " ";
+        right: 0px;
+        top: -4px;
+        z-index: 0;
+        width: 33px;
+        height: 20px;
+        background-color: #64AE16;
+        transform: skewY(45deg);
+    }
+}
+
+@media screen and (max-width: 1280px) {
+    .list {
+        width: 33%;
+    }
+}
+
+@media screen and (max-width: 1024px) {
+    .list {
+        width: 50%;
+    }
+}
+
+@media screen and (max-width: 768px) {
+    .list {
+        width: 100%;
+    }
+}

+ 295 - 326
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -1,324 +1,322 @@
 <template>
     <div>
         <Loading v-show="isLoad" bgColor="rgba(0, 0, 0, 0.3)"></Loading>
-        <!-- <div class="event-list"> -->
-            <div class="list" v-show="getSidebarisOpen">
-                <!--活動搜尋與篩選區域-->
-                <div class="event-selector-block">
-                    <div class="search">
-                        <div class="search-btn" @click="openSearch = !openSearch">
-                            <svg-icon icon-class="search"
-                                    class="searchIcon"
-                                    :class="{ openSearch: openSearch }" />
-                        </div>          
-                        <div class="search-wrapper" :class="{ openSearch: openSearch }">
-                            <Input type="text" v-model="search" :placeholder="$t('studentWeb.public.search')" clearable />
-                        </div>
-                    </div>
-                    <!--下拉選單-->
-                    <div>
-                        <Dropdown>
-                            <a href="javascript:void(0)" class="list-title">
-                                <span>{{ selectedEventStatusNow }}</span>
-                                <Icon type="ios-arrow-down"></Icon>
-                            </a>
-                            <DropdownMenu slot="list">
-                                <div @click="sentEventStatus(item)" v-for="(item, index) in $t('studentWeb.state')" :key="index">
-                                    <DropdownItem>{{ item.status }}</DropdownItem>
-                                </div>
-                            </DropdownMenu>
-                        </Dropdown>
+        <div class="list" v-show="getSidebarisOpen">
+            <!--活動搜尋與篩選區域-->
+            <div class="event-selector-block">
+                <div class="search">
+                    <div class="search-btn" @click="openSearch = !openSearch">
+                        <svg-icon icon-class="search"
+                                class="searchIcon"
+                                :class="{ openSearch: openSearch }" />
+                    </div>          
+                    <div class="search-wrapper" :class="{ openSearch: openSearch }">
+                        <Input type="text" v-model="search" :placeholder="$t('studentWeb.public.search')" clearable />
                     </div>
-                    <!---按鈕搜尋區(多選)--->
-                    <div class="icon-selector" v-if="hideIconbtn == false && showType.length > 1">
-                        <RadioGroup v-model="eventTypeCheckers"
-                                    class="icon-selector-group"
-                                    @on-change="predealMockdatafirstItem()"
-                        >
-                            <div class="icon-btn"
-                                @click="selectAllType()"
-                                :title="$t('studentWeb.type.all')"
-                                :class="{'icon-btn-selected': eventTypeCheckers == ''}">
-                                <svg-icon icon-class="alltext" class="innerIcon Icon-0" />
+                </div>
+                <!--下拉選單-->
+                <div>
+                    <Dropdown>
+                        <a href="javascript:void(0)" class="list-title">
+                            <span>{{ selectedEventStatusNow }}</span>
+                            <Icon type="ios-arrow-down"></Icon>
+                        </a>
+                        <DropdownMenu slot="list">
+                            <div @click="sentEventStatus(item)" v-for="(item, index) in $t('studentWeb.state')" :key="index">
+                                <DropdownItem>{{ item.status }}</DropdownItem>
                             </div>
-                            <template>
-                                <Radio :label="iconBtn.eventType"
-                                    v-for="(iconBtn, index) in showTypeNametoIcon"
-                                    :key="'type' + index"
-                                    class="icon-btn"
-                                    :title="iconBtn.title"
-                                    :class="{'icon-btn-selected': eventTypeCheckers.indexOf(iconBtn.eventType) != -1}"
-                                    :style="{'display': iconBtn.eventType == 'Preview' ? 'none' : ''}"
-                                >
-                                    <svg-icon :icon-class="iconBtn.iconClass"
-                                            class="innerIcon"
-                                            :class="`Icon-${index + 1}`" 
-                                    />
-                                    <p>{{ iconBtn.title }}</p>
-                                    <div class="dev-top" v-if="iconBtn.eventType == 'Preview'">
-                                        <span class="develop">{{ $t("studentWeb.public.develop") }}</span>
-                                    </div>
-                                </Radio>
-                            </template>
-                        </RadioGroup>
-                    </div>
-                    <!---按鈕搜尋區(多選)--->
-                    <div style="margin-top: 10px;">
-                        <span>{{ $t("studentWeb.choiceTime") }}:</span>
-                        <DatePicker type="date" :value="choDate" :options="options" @on-change="dateChange" :placeholder="$t('studentWeb.missionListCardPlace')" />
-                    </div>
+                        </DropdownMenu>
+                    </Dropdown>
                 </div>
-                <!--活動清單分頁-->
-                <div class="list-block"
-                    :style="{ height: !hideIconbtn ? '84vh' : '90vh' }">
-                    <!-- 空 -->
-                    <div v-show="isListNoItem" class="emptycondition">
-                        <svg-icon icon-class="empty-white-box" class="empty-Icon" />
-                        <br />
-                        {{ $t("studentWeb.empty") }}
-                    </div>
-                    <vuescroll>
-                        <div v-if="!isListNoItem" style="margin-bottom: 100px">
-                            <div :id="`event${item.id}`"
-                                class="list-new"
-                                @click="sentSelectedEventTitle(item)"
-                                :class="{ 'list-item-selected': selectedCondition(item) }"
-                                v-for="(item, index) in eventShow"
-                                :key="index"
+                <!---按鈕搜尋區(多選)--->
+                <div class="icon-selector" v-if="hideIconbtn == false && showType.length > 1">
+                    <RadioGroup v-model="eventTypeCheckers"
+                                class="icon-selector-group"
+                                @on-change="predealMockdatafirstItem()"
+                    >
+                        <div class="icon-btn"
+                            @click="selectAllType()"
+                            :title="$t('studentWeb.type.all')"
+                            :class="{'icon-btn-selected': eventTypeCheckers == ''}">
+                            <svg-icon icon-class="alltext" class="innerIcon Icon-0" />
+                        </div>
+                        <template>
+                            <Radio :label="iconBtn.eventType"
+                                v-for="(iconBtn, index) in showTypeNametoIcon"
+                                :key="'type' + index"
+                                class="icon-btn"
+                                :title="iconBtn.title"
+                                :class="{'icon-btn-selected': eventTypeCheckers.indexOf(iconBtn.eventType) != -1}"
+                                :style="{'display': iconBtn.eventType == 'Preview' ? 'none' : ''}"
                             >
-                                <div class="list-new-icon">
-                                    <svg-icon v-if="item.type === 'Homework'" icon-class="doc" color="#f0be72" />
-                                    <svg-icon v-if="item.type === 'Preview'" icon-class="selflearninginTime" />
-                                    <svg-icon v-if="item.type === 'Exam'" icon-class="multiTest" color="#94a1e4" />
-                                    <svg-icon v-if="item.type === 'Vote'" icon-class="vote" color="#6a9a8b" />
-                                    <svg-icon v-if="item.type === 'Survey'" icon-class="quesnaire" color="#d19f9c" />
+                                <svg-icon :icon-class="iconBtn.iconClass"
+                                        class="innerIcon"
+                                        :class="`Icon-${index + 1}`" 
+                                />
+                                <p>{{ iconBtn.title }}</p>
+                                <div class="dev-top" v-if="iconBtn.eventType == 'Preview'">
+                                    <span class="develop">{{ $t("studentWeb.public.develop") }}</span>
                                 </div>
-                                <div v-if="item.type === 'Exam'" class="list-new-test">
-                                    <div class="paper-item-school">
-                                        <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
-                                        <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
-                                        <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab'}" v-if="item.source === '0'">
-                                            {{ $t("studentWeb.exam.source.evMode1") }}
-                                        </span>
-                                        <span class="paper-source" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#2f98a9'}" v-if="item.source === '1'">
-                                            {{ $t("studentWeb.exam.source.evMode2") }}
-                                        </span>
-                                        <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}" v-if="item.source === '2'">
-                                            {{ $t("studentWeb.exam.source.evMode3") }}
-                                        </span>
-                                        
-                                        <!-- 课中评量才判断:qamode:0(书面问答),1(纸本测验) -->
-                                        <template v-if="item.source === '1'">
-                                            <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}"
-                                                v-if="item.qamode"
-                                            >
-                                                {{ $t("studentWeb.exam.source.evMode21") }}
-                                            </span>
-                                            <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}"
-                                                v-else
-                                            >
-                                                {{ $t("studentWeb.exam.source.evMode22") }}
-                                            </span>
-                                        </template>
-                                        <span v-if="item.ext.type === 'regular'" class="paper-extType"
-                                            :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#dc8f57'}"
-                                        >
-                                            {{ $t('totalAnalysis.ti_text6') }}
-                                        </span>
-                                        <span v-if="item.ext.type === 'simulation'" class="paper-extType"
-                                            :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#76ae38'}"
+                            </Radio>
+                        </template>
+                    </RadioGroup>
+                </div>
+                <!---按鈕搜尋區(多選)--->
+                <div style="margin-top: 10px;">
+                    <span>{{ $t("studentWeb.choiceTime") }}:</span>
+                    <DatePicker type="date" :value="choDate" :options="options" @on-change="dateChange" :placeholder="$t('studentWeb.missionListCardPlace')" />
+                </div>
+            </div>
+            <!--活動清單分頁-->
+            <div class="list-block"
+                :style="{ height: !hideIconbtn ? '84vh' : '90vh' }">
+                <!-- 空 -->
+                <div v-show="isListNoItem" class="emptycondition">
+                    <svg-icon icon-class="empty-white-box" class="empty-Icon" />
+                    <br />
+                    {{ $t("studentWeb.empty") }}
+                </div>
+                <vuescroll>
+                    <div v-if="!isListNoItem" style="margin-bottom: 100px">
+                        <div :id="`event${item.id}`"
+                            class="list-new"
+                            @click="sentSelectedEventTitle(item)"
+                            :class="{ 'list-item-selected': selectedCondition(item) }"
+                            v-for="(item, index) in eventShow"
+                            :key="index"
+                        >
+                            <div class="list-new-icon">
+                                <svg-icon v-if="item.type === 'Homework'" icon-class="doc" color="#f0be72" />
+                                <svg-icon v-if="item.type === 'Preview'" icon-class="selflearninginTime" />
+                                <svg-icon v-if="item.type === 'Exam'" icon-class="multiTest" color="#94a1e4" />
+                                <svg-icon v-if="item.type === 'Vote'" icon-class="vote" color="#6a9a8b" />
+                                <svg-icon v-if="item.type === 'Survey'" icon-class="quesnaire" color="#d19f9c" />
+                            </div>
+                            <div v-if="item.type === 'Exam'" class="list-new-test">
+                                <div class="paper-item-school">
+                                    <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
+                                    <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
+                                    <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab'}" v-if="item.source === '0'">
+                                        {{ $t("studentWeb.exam.source.evMode1") }}
+                                    </span>
+                                    <span class="paper-source" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#2f98a9'}" v-if="item.source === '1'">
+                                        {{ $t("studentWeb.exam.source.evMode2") }}
+                                    </span>
+                                    <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}" v-if="item.source === '2'">
+                                        {{ $t("studentWeb.exam.source.evMode3") }}
+                                    </span>
+                                    
+                                    <!-- 课中评量才判断:qamode:0(书面问答),1(纸本测验) -->
+                                    <template v-if="item.source === '1'">
+                                        <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}"
+                                            v-if="item.qamode"
                                         >
-                                            {{ $t('totalAnalysis.ti_text7') }}
+                                            {{ $t("studentWeb.exam.source.evMode21") }}
                                         </span>
-                                        <span v-if="item.ext.type === 'normal'" class="paper-extType"
-                                            :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#a69b17'}"
+                                        <span class="paper-extType" :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#b68268'}"
+                                            v-else
                                         >
-                                            {{ $t('totalAnalysis.ti_text8') }}
+                                            {{ $t("studentWeb.exam.source.evMode22") }}
                                         </span>
-                                    </div>
-                                    <p class="list-item-title">
-                                        <!-- <span class="list-item-typeMark">
-                                            {{ item.source === '0' ? $t("studentWeb.exam.source.evMode1") : (item.source === '1' ? $t("studentWeb.exam.source.evMode2") : $t("studentWeb.exam.source.evMode3"))}}
-                                        </span> -->
-                                        <span>{{ item.name }}</span>
-                                    </p>
-                                    <!-- 暂时不改 -->
-                                    <!-- <p class="list-item-time isScore" v-show="timeStatus(item) == 'finish'">
-                                        得分率:20%
-                                    </p> -->
-                                    <p style="font-size:12px; margin-top: 5px; word-break: keep-all;">
-                                        <span v-if="item.ext">
-                                            <span v-if="item.ext.subjects">
-                                                <span v-for="(item, index) in item.ext.subjects" :key="index" :title="item.name"
-                                                    style="border-color: #499c8d; color: #499c8d;" class="tag-style text-long"
-                                                >
-                                                    {{ item.name }}
-                                                </span>
-                                            </span>
-                                        </span>
-                                        <span v-if="item.className.length">
-                                            <span v-for="(clasNa, index) in item.className" :key="index" :title="clasNa"
-                                                style="border-color: #8f8787; color: #8f8787;" class="tag-style text-long"
+                                    </template>
+                                    <span v-if="item.ext.type === 'regular'" class="paper-extType"
+                                        :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#dc8f57'}"
+                                    >
+                                        {{ $t('totalAnalysis.ti_text6') }}
+                                    </span>
+                                    <span v-if="item.ext.type === 'simulation'" class="paper-extType"
+                                        :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#76ae38'}"
+                                    >
+                                        {{ $t('totalAnalysis.ti_text7') }}
+                                    </span>
+                                    <span v-if="item.ext.type === 'normal'" class="paper-extType"
+                                        :style="{'border-color': item.owner === 'school' ? '#88a1d8' :'#ababab', color: '#a69b17'}"
+                                    >
+                                        {{ $t('totalAnalysis.ti_text8') }}
+                                    </span>
+                                </div>
+                                <p class="list-item-title">
+                                    <!-- <span class="list-item-typeMark">
+                                        {{ item.source === '0' ? $t("studentWeb.exam.source.evMode1") : (item.source === '1' ? $t("studentWeb.exam.source.evMode2") : $t("studentWeb.exam.source.evMode3"))}}
+                                    </span> -->
+                                    <span>{{ item.name }}</span>
+                                </p>
+                                <!-- 暂时不改 -->
+                                <!-- <p class="list-item-time isScore" v-show="timeStatus(item) == 'finish'">
+                                    得分率:20%
+                                </p> -->
+                                <p style="font-size:12px; margin-top: 5px; word-break: keep-all;">
+                                    <span v-if="item.ext">
+                                        <span v-if="item.ext.subjects">
+                                            <span v-for="(item, index) in item.ext.subjects" :key="index"
+                                                class="tag-style tag-subject text-long" :title="item.name"
                                             >
-                                                {{ clasNa }}
+                                                {{ item.name }}
                                             </span>
                                         </span>
-                                        <span class="tag-style text-long" style="border-color: #6b6ba9; color: #6b6ba9;"
-                                            v-if="item.teacherName" :title="item.teacherName"
-                                        >{{ item.teacherName }}</span>
-                                    </p>
-                                    <p class="list-item-time">
-                                        {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
-                                    </p>
-                                </div>
-                                <div v-if="item.type === 'Vote'" class="list-new-test">
-                                    <div class="paper-item-school">
-                                        <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
-                                        <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
-                                        <span class="paper-extType"
-                                        >
-                                            {{ $t('studentWeb.home.vote') }}
-                                        </span>
-                                        <!-- <span>
-                                            {{ item.name }}
-                                        </span> -->
-                                        <!-- <p>{{ item.name }}</p> -->
-                                    </div>
-                                    <p class="list-item-title">
-                                        <!-- <span class="list-item-typeMark">{{item.owner == 'school' ? $t('studentWeb.public.schoolVote'):$t('studentWeb.public.privateVote')}}</span> -->
-                                        <span>{{ item.name }}</span>
-                                    </p>
-                                    <p style="font-size:12px; margin-top: 5px;">
-                                        <!-- <span style="border-color: #5783e7; color: #5783e7;" class="tag-style"
-                                                v-if="item.owner === 'school'"
+                                    </span>
+                                    <span v-if="item.className.length">
+                                        <span v-for="(clasNa, index) in item.className" :key="index"
+                                            class="tag-style tag-normal text-long" :title="clasNa"
                                         >
-                                            {{ $t('studentWeb.public.school') }}
-                                        </span>
-                                        <span style="border-color: #c4937b; color: #c4937b;" class="tag-style"
-                                                v-else>
-                                            {{ $t('studentWeb.public.private') }}
-                                        </span> -->
-                                        <span v-if="item.className.length">
-                                            <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
-                                                style="border-color: #8f8787; color: #8f8787;">
-                                                {{ clasNa }}
-                                            </span>
+                                            {{ clasNa }}
                                         </span>
-                                        <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.teacherName">{{ item.teacherName }}</span>
-                                    </p>
-                                    <p class="list-item-time">
-                                        {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
-                                    </p>
+                                    </span>
+                                    <span class="tag-style tag-teacher text-long" v-if="item.teacherName" :title="item.teacherName">
+                                        {{ item.teacherName }}
+                                    </span>
+                                </p>
+                                <p class="list-item-time">
+                                    {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
+                                </p>
+                            </div>
+                            <div v-if="item.type === 'Vote'" class="list-new-test">
+                                <div class="paper-item-school">
+                                    <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
+                                    <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
+                                    <span class="paper-extType"
+                                    >
+                                        {{ $t('studentWeb.home.vote') }}
+                                    </span>
+                                    <!-- <span>
+                                        {{ item.name }}
+                                    </span> -->
+                                    <!-- <p>{{ item.name }}</p> -->
                                 </div>
-                                <div v-if="item.type === 'Survey'" class="list-new-test">
-                                    <div class="paper-item-school">
-                                        <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
-                                        <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
-                                        <span class="paper-extType"
-                                        >
-                                            {{ $t('studentWeb.home.survey') }}
-                                        </span>
-                                        <!-- <span>
-                                            {{ item.name }}
-                                        </span> -->
-                                        <!-- <p>{{ item.name }}</p> -->
-                                    </div>
-                                    <p class="list-item-title">
-                                        <!-- <span class="list-item-typeMark">{{item.owner == 'school' ? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span> -->
-                                        <span>{{ item.name }}</span>
-                                    </p>
-                                    <p style="font-size:12px; margin-top: 5px;">
-                                        <!-- <span style="border-color: #5783e7; color: #5783e7;" class="tag-style"
-                                                v-if="item.owner === 'school'"
-                                        >
-                                            {{ $t('studentWeb.public.school') }}
+                                <p class="list-item-title">
+                                    <!-- <span class="list-item-typeMark">{{item.owner == 'school' ? $t('studentWeb.public.schoolVote'):$t('studentWeb.public.privateVote')}}</span> -->
+                                    <span>{{ item.name }}</span>
+                                </p>
+                                <p style="font-size:12px; margin-top: 5px;">
+                                    <!-- <span style="border-color: #5783e7; color: #5783e7;" class="tag-style"
+                                            v-if="item.owner === 'school'"
+                                    >
+                                        {{ $t('studentWeb.public.school') }}
+                                    </span>
+                                    <span style="border-color: #c4937b; color: #c4937b;" class="tag-style"
+                                            v-else>
+                                        {{ $t('studentWeb.public.private') }}
+                                    </span> -->
+                                    <span v-if="item.className.length">
+                                        <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
+                                            style="border-color: #8f8787; color: #8f8787;">
+                                            {{ clasNa }}
                                         </span>
-                                        <span style="border-color: #c4937b; color: #c4937b;" class="tag-style"
-                                                v-else>
-                                            {{ $t('studentWeb.public.private') }}
-                                        </span> -->
-                                        <span v-if="item.className.length">
-                                            <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
-                                                style="border-color: #8f8787; color: #8f8787;">
-                                                {{ clasNa }}
-                                            </span>
-                                        </span>
-                                        <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.teacherName">{{ item.teacherName }}</span>
-                                    </p>
-                                    <p class="list-item-time">
-                                        {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
-                                    </p>
+                                    </span>
+                                    <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.teacherName">{{ item.teacherName }}</span>
+                                </p>
+                                <p class="list-item-time">
+                                    {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
+                                </p>
+                            </div>
+                            <div v-if="item.type === 'Survey'" class="list-new-test">
+                                <div class="paper-item-school">
+                                    <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
+                                    <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
+                                    <span class="paper-extType"
+                                    >
+                                        {{ $t('studentWeb.home.survey') }}
+                                    </span>
+                                    <!-- <span>
+                                        {{ item.name }}
+                                    </span> -->
+                                    <!-- <p>{{ item.name }}</p> -->
                                 </div>
-                                <div v-if="item.type === 'Homework'" class="list-new-test">
-                                    <div class="paper-item-school">
-                                        <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
-                                        <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
-                                        <span class="paper-source">
-                                            {{ $t('studentWeb.home.homework') }}
-                                        </span>
-                                        <span class="paper-extType" v-if="item.mustSubmit" style="color: #dc8f57;"
-                                        >
-                                            {{ $t("studentWeb.public.mustFile") }}
-                                        </span>
-                                        <!-- <span>
-                                            {{ item.name }}
-                                        </span> -->
-                                        <!-- <p>{{ item.name }}</p> -->
-                                    </div>
-                                    <p class="list-item-title">
-                                        <!-- <span class="list-item-typeMark">{{item.owner == 'school' ? $t('studentWeb.public.schoolHomework'):$t('studentWeb.public.privateHomework')}}</span> -->
-                                        <span>{{ item.name }}</span>
-                                    </p>
-                                    <p style="font-size:12px; margin-top: 5px;">
-                                        <!-- <span style="border-color: #5783e7; color: #5783e7;" class="tag-style"
-                                                v-if="item.owner === 'school'"
-                                        >
-                                            {{ $t('studentWeb.public.school') }}
+                                <p class="list-item-title">
+                                    <!-- <span class="list-item-typeMark">{{item.owner == 'school' ? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span> -->
+                                    <span>{{ item.name }}</span>
+                                </p>
+                                <p style="font-size:12px; margin-top: 5px;">
+                                    <!-- <span style="border-color: #5783e7; color: #5783e7;" class="tag-style"
+                                            v-if="item.owner === 'school'"
+                                    >
+                                        {{ $t('studentWeb.public.school') }}
+                                    </span>
+                                    <span style="border-color: #c4937b; color: #c4937b;" class="tag-style"
+                                            v-else>
+                                        {{ $t('studentWeb.public.private') }}
+                                    </span> -->
+                                    <span v-if="item.className.length">
+                                        <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
+                                            style="border-color: #8f8787; color: #8f8787;">
+                                            {{ clasNa }}
                                         </span>
-                                        <span style="border-color: #c4937b; color: #c4937b;" class="tag-style"
-                                                v-else>
-                                            {{ $t('studentWeb.public.private') }}
-                                        </span> -->
-                                        <span v-if="item.className.length">
-                                            <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
-                                                style="border-color: #8f8787; color: #8f8787;">
-                                                {{ clasNa }}
-                                            </span>
+                                    </span>
+                                    <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.teacherName">{{ item.teacherName }}</span>
+                                </p>
+                                <p class="list-item-time">
+                                    {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
+                                </p>
+                            </div>
+                            <div v-if="item.type === 'Homework'" class="list-new-test">
+                                <div class="paper-item-school">
+                                    <span class="paper-owner" v-if="item.owner === 'school'" style="background-color: #88a1d8;">{{ $t('studentWeb.public.school') }}</span>
+                                    <span class="paper-owner" v-else>{{ $t('studentWeb.public.private') }}</span>
+                                    <span class="paper-source">
+                                        {{ $t('studentWeb.home.homework') }}
+                                    </span>
+                                    <span class="paper-extType" v-if="item.mustSubmit" style="color: #dc8f57;"
+                                    >
+                                        {{ $t("studentWeb.public.mustFile") }}
+                                    </span>
+                                    <!-- <span>
+                                        {{ item.name }}
+                                    </span> -->
+                                    <!-- <p>{{ item.name }}</p> -->
+                                </div>
+                                <p class="list-item-title">
+                                    <!-- <span class="list-item-typeMark">{{item.owner == 'school' ? $t('studentWeb.public.schoolHomework'):$t('studentWeb.public.privateHomework')}}</span> -->
+                                    <span>{{ item.name }}</span>
+                                </p>
+                                <p style="font-size:12px; margin-top: 5px;">
+                                    <!-- <span style="border-color: #5783e7; color: #5783e7;" class="tag-style"
+                                            v-if="item.owner === 'school'"
+                                    >
+                                        {{ $t('studentWeb.public.school') }}
+                                    </span>
+                                    <span style="border-color: #c4937b; color: #c4937b;" class="tag-style"
+                                            v-else>
+                                        {{ $t('studentWeb.public.private') }}
+                                    </span> -->
+                                    <span v-if="item.className.length">
+                                        <span v-for="(clasNa, index) in item.className" :key="index" class="tag-style"
+                                            style="border-color: #8f8787; color: #8f8787;">
+                                            {{ clasNa }}
                                         </span>
-                                        <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.teacherName">{{ item.teacherName }}</span>
-                                    </p>
-                                    <p class="list-item-time">
-                                        {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
-                                    </p>
+                                    </span>
+                                    <span class="tag-style" style="border-color: #6b6ba9; color: #6b6ba9;" v-if="item.teacherName">{{ item.teacherName }}</span>
+                                </p>
+                                <p class="list-item-time">
+                                    {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
+                                </p>
+                            </div>
+                            <div class="list-new-type">
+                                <span style="font-size: 12px; text-align: center;">{{ item.tempsub }}</span>
+                                <div class="list-new-unDone isAllowRetry" v-show="item.stuProgress === 'going'">
+                                    <span>{{ $t("studentWeb.public.going") }}</span>
                                 </div>
-                                <div class="list-new-type">
-                                    <span style="font-size: 12px; text-align: center;">{{ item.tempsub }}</span>
-                                    <div class="list-new-unDone isAllowRetry" v-show="item.stuProgress === 'going'">
-                                        <span>{{ $t("studentWeb.public.going") }}</span>
-                                    </div>
-                                    <div class="list-new-unDone" v-show="item.stuProgress === 'finish'">
-                                        <span class="isOvertime">{{ item.type === 'Exam' ? $t("studentWeb.exam.finishOk") : $t("studentWeb.public.finish")}}</span>
-                                    </div>
-                                    <div class="list-new-unDone" v-show="item.stuProgress === 'noAns'" style="border-color: red;">
-                                        <span style="color: red;">{{$t("studentWeb.exam.missExam")}}</span>
-                                    </div>
-                                    <div class="list-new-unDone" v-show="item.stuProgress === 'noScore'" style="border-color: #ac9263;">
-                                        <span style="color: #ac9263;">{{$t("studentWeb.exam.noScoreType")}}</span>
-                                    </div>
-                                    
-                                    <!-- 暂时不改 -->
-                                    <!-- <div class="list-new-unDone isWrongPra" v-show="timeStatus(item) == 'finish' && item.type == 'Exam'">
-                                        <span class="">{{$t("studentWeb.exam.report.wrongPractice")}}</span>
-                                    </div> -->
+                                <div class="list-new-unDone" v-show="item.stuProgress === 'finish'">
+                                    <span class="isOvertime">{{ item.type === 'Exam' ? $t("studentWeb.exam.finishOk") : $t("studentWeb.public.finish")}}</span>
                                 </div>
-                                    
+                                <div class="list-new-unDone" v-show="item.stuProgress === 'noAns'" style="border-color: red;">
+                                    <span style="color: red;">{{$t("studentWeb.exam.missExam")}}</span>
+                                </div>
+                                <div class="list-new-unDone" v-show="item.stuProgress === 'noScore'" style="border-color: #ac9263;">
+                                    <span style="color: #ac9263;">{{$t("studentWeb.exam.noScoreType")}}</span>
+                                </div>
+                                
+                                <!-- 暂时不改 -->
+                                <!-- <div class="list-new-unDone isWrongPra" v-show="timeStatus(item) == 'finish' && item.type == 'Exam'">
+                                    <span class="">{{$t("studentWeb.exam.report.wrongPractice")}}</span>
+                                </div> -->
                             </div>
+                                
                         </div>
-                    </vuescroll>
-                    <div class="list-end"></div>
-                </div>
+                    </div>
+                </vuescroll>
+                <div class="list-end"></div>
             </div>
-        <!-- </div> -->
+        </div>
         <div class="eventContentArea-view" :class="{'no-bar': !getSidebarisOpen}">
             <!--<VoteHint v-if="this.$store.getters.getisVoteResulthover==true"/>-->
             <template v-if="nowActivity">
@@ -354,7 +352,7 @@ import { mapGetters, mapState } from 'vuex';
 import Homework from "./EventContentTypeTemplate/Homework";
 import PreviewMission from "./EventContentTypeTemplate/PreviewMission";
 import Vote from "./EventContentTypeTemplate/Vote";
-import PaperView from "./EventContentTypeTemplate/PaperView";
+import PaperView from "./EventContentTypeTemplate/PaperViewBox/PaperView.vue";
 import VoteHint from "./EventContentTypeTemplate/VoteHint";
 import QuesNaire from "./EventContentTypeTemplate/QuesNaire";
     export default {
@@ -997,40 +995,11 @@ import QuesNaire from "./EventContentTypeTemplate/QuesNaire";
     };
 </script>
 
-<style scoped>
-/* @import "~@/assets/student-web/component_styles/event-list-new.css"; */
-</style>
-
 <style lang="less">
-@import "~@/assets/student-web/component_styles/event-list.less";
+@import "./EventiView.less";
 @import "EventContent.less";
 </style>
 
 <style lang="less" scoped>
-@import "~@/assets/student-web/component_styles/event-list-new.less";
-// 未开展标识
-.dev-top{
-    .develop{
-        position: absolute;
-        top: 1px;
-        right: -13px;
-        font-size: xx-small;
-        color: #fff;
-        padding: 2px 5px;
-        z-index: 99;
-        transform: scale(0.7) rotate(45deg);
-    }
-
-    &::after{
-        position: absolute;
-        content: " ";
-        right: 0px;
-        top: -4px;
-        z-index: 0;
-        width: 33px;
-        height: 20px;
-        background-color: #64AE16;
-        transform: skewY(45deg);
-    }
-}
+@import "./EventList.less";
 </style>

+ 36 - 36
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventView.vue

@@ -113,45 +113,45 @@
     };
 </script>
 <style scoped>
-    .hide-sidebars {
-        /*width: 0%;*/
-        transition: ease-out 0.3s;
-        display:none;
-    }
+.hide-sidebars {
+    /*width: 0%;*/
+    transition: ease-out 0.3s;
+    display:none;
+}
 
-      .eventContentArea-view {
-          float: right;
-          width: 75%;
-      }
+.eventContentArea-view {
+    float: right;
+    width: 75%;
+}
 
-      .eventContentArea-Span {
-          padding: 1% 10%;
-          width: 100%;
-      }
+.eventContentArea-Span {
+    padding: 1% 10%;
+    width: 100%;
+}
 
-      .eventContentArea-left {
-          width: 80%;
-          float: left;
-          padding: 1% 7%;
-          transition: 0s;
-      }
+.eventContentArea-left {
+    width: 80%;
+    float: left;
+    padding: 1% 7%;
+    transition: 0s;
+}
 
-      .nextItemBtn {
-          position: fixed;
-          bottom: 4%;
-          right: 3%;
-          background-color: #d8d8d8;
-          color: #515a6e;
-          z-index: 3;
-          padding: 7px;
-          cursor: pointer;
-          border-radius: 3px;
-          font-weight: bolder;
-      }
+.nextItemBtn {
+    position: fixed;
+    bottom: 4%;
+    right: 3%;
+    background-color: #d8d8d8;
+    color: #515a6e;
+    z-index: 3;
+    padding: 7px;
+    cursor: pointer;
+    border-radius: 3px;
+    font-weight: bolder;
+}
 
-          .nextItemBtn:hover {
-              background-color: rgb(100, 174, 22) !important;
-              color: white;
-              border: none;
-          }
+.nextItemBtn:hover {
+    background-color: rgb(100, 174, 22) !important;
+    color: white;
+    border: none;
+}
 </style>

+ 210 - 0
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventiView.less

@@ -0,0 +1,210 @@
+@import '~@/assets/student-web/component_styles/color.less';
+
+.event-selector-block {
+    padding: 17px 25px;
+
+    .list-title {
+        font-size: 18px;
+        text-decoration: none;
+        color: #515a6e;
+    }
+
+    .icon-selector {
+        margin-top: 18px;
+        margin-bottom: 10px;
+
+        .ivu-checkbox-group .ivu-checkbox-wrapper .ivu-checkbox {
+            display: none;
+        }
+
+        .ivu-radio {
+            display: none;
+        }
+
+        .icon-selector-group {
+            display: flex;
+
+            .ivu-radio-wrapper {
+                margin-left: 10px;
+                margin-right: 0;
+                overflow: hidden;
+
+                .innerIcon {
+                    margin-left: 0;
+                }
+            }
+        }
+
+        li {
+            display: inline-block;
+            margin-right: 10px;
+        }
+
+
+        .icon-btn {
+            height: 48px;
+            width: 48px;
+            background: #d8d8d8;
+            border-radius: 4px;
+            margin-bottom: 2px;
+
+            &:hover {
+                cursor: pointer;
+                background: rgb(36, 184, 128);
+                color: white;
+            }
+
+            &>p {
+                text-align: center;
+                font-size: 13px;
+            }
+
+            .innerIcon {
+                width: 24px;
+                height: 24px;
+                position: relative;
+            }
+
+            .Icon-0 {
+                top: 12px;
+                left: 12px;
+            }
+
+            .Icon-1,
+            .Icon-4 {
+                top: 6px;
+                left: 12px;
+            }
+
+            .Icon-2 {
+                top: 6px;
+                left: 15px;
+            }
+
+            .Icon-3,
+            .Icon-5 {
+                top: 6px;
+                left: 13px;
+            }
+
+        }
+
+        input[type="checkbox"] {
+            visibility: hidden;
+            margin-left: -12px;
+        }
+
+        input[type="checkbox"]:checked~.icon-btn {
+            background: rgb(36, 184, 128);
+            color: white;
+        }
+
+        .icon-btn-selected {
+            background: rgb(36, 184, 128);
+            color: white;
+        }
+    }
+
+    .ivu-select-dropdown {
+        width: 50% !important;
+        border-radius: 4px !important;
+        padding: 10px 0px;
+
+        .ivu-dropdown-item {
+            font-size: 18px !important;
+            font-weight: 400;
+            padding-left: 20px;
+        }
+    }
+
+    .ivu-date-picker {
+        width: 80%;
+    }
+
+    /*修改iviewTab控件*/
+    .ivu-tabs-nav {
+        float: none !important;
+        position: relative;
+        text-align: center;
+    }
+
+    .ivu-tabs-tab {
+        width: auto;
+        padding: 8px 20px;
+        position: relative;
+        font-size: 14px;
+        color: #878787;
+        font-weight: 600;
+        margin: 0px 30px;
+
+        &:hover {
+            color: @primary  !important;
+        }
+    }
+
+    .ivu-tabs-tab.ivu-tabs-tab-active.ivu-tabs-tab-focused {
+        color: @primary  !important;
+        width: auto;
+        padding: 8px 20px;
+        border-bottom: 7px solid @primary  !important;
+        text-align: center;
+    }
+
+    .ivu-tabs-ink-bar {
+        height: 0px;
+    }
+
+    .ivu-tabs-tabpane {
+        margin-top: -16px;
+
+        height: 830px;
+        overflow: auto;
+    }
+
+    .event-list {
+        z-index: 10;
+
+        /*修改iviewTab控件*/
+        .list-block {
+            border-top: 1px solid @border;
+            overflow: auto;
+        }
+
+        @media screen and (max-width: 1366px) {
+            .icon-selector {
+                .icon-btn {
+                    height: 40px;
+                    width: 40px;
+
+                    .innerIcon {
+                        width: 22px;
+                        height: 22px;
+                        position: relative;
+                    }
+
+                    .Icon-0,
+                    .Icon-1,
+                    .Icon-4 {
+                        top: 22%;
+                        left: 23%;
+                    }
+
+                    .Icon-2 {
+                        top: 24%;
+                        left: 30%;
+                    }
+
+                    .Icon-3 {
+                        top: 22%;
+                        left: 26%;
+                    }
+
+                    .Icon-5 {
+                        top: 22%;
+                        left: 26%;
+                    }
+                }
+            }
+        }
+    }
+}

+ 36 - 36
TEAMModelOS/ClientApp/src/components/student-web/EventView/ExamView.vue

@@ -44,45 +44,45 @@
     };
 </script>
 <style scoped>
-    .hide-sidebars {
-        /*width: 0%;*/
-        transition: ease-out 0.3s;
-        display:none;
-    }
+.hide-sidebars {
+    /*width: 0%;*/
+    transition: ease-out 0.3s;
+    display:none;
+}
 
-      .eventContentArea-view {
-          float: right;
-          width: 75%;
-      }
+.eventContentArea-view {
+    float: right;
+    width: 75%;
+}
 
-      .eventContentArea-Span {
-          padding: 1% 10%;
-          width: 100%;
-      }
+.eventContentArea-Span {
+    padding: 1% 10%;
+    width: 100%;
+}
 
-      .eventContentArea-left {
-          width: 80%;
-          float: left;
-          padding: 1% 7%;
-          transition: 0s;
-      }
+.eventContentArea-left {
+    width: 80%;
+    float: left;
+    padding: 1% 7%;
+    transition: 0s;
+}
 
-      .nextItemBtn {
-          position: fixed;
-          bottom: 4%;
-          right: 3%;
-          background-color: #d8d8d8;
-          color: #515a6e;
-          z-index: 3;
-          padding: 7px;
-          cursor: pointer;
-          border-radius: 3px;
-          font-weight: bolder;
-      }
+.nextItemBtn {
+    position: fixed;
+    bottom: 4%;
+    right: 3%;
+    background-color: #d8d8d8;
+    color: #515a6e;
+    z-index: 3;
+    padding: 7px;
+    cursor: pointer;
+    border-radius: 3px;
+    font-weight: bolder;
+}
 
-          .nextItemBtn:hover {
-              background-color: rgb(100, 174, 22) !important;
-              color: white;
-              border: none;
-          }
+.nextItemBtn:hover {
+    background-color: rgb(100, 174, 22) !important;
+    color: white;
+    border: none;
+}
 </style>

+ 36 - 36
TEAMModelOS/ClientApp/src/components/student-web/EventView/HomeworkView.vue

@@ -44,45 +44,45 @@
     };
 </script>
 <style scoped>
-    .hide-sidebars {
-        /*width: 0%;*/
-        transition: ease-out 0.3s;
-        display:none;
-    }
+.hide-sidebars {
+    /*width: 0%;*/
+    transition: ease-out 0.3s;
+    display:none;
+}
 
-      .eventContentArea-view {
-          float: right;
-          width: 75%;
-      }
+.eventContentArea-view {
+    float: right;
+    width: 75%;
+}
 
-      .eventContentArea-Span {
-          padding: 1% 10%;
-          width: 100%;
-      }
+.eventContentArea-Span {
+    padding: 1% 10%;
+    width: 100%;
+}
 
-      .eventContentArea-left {
-          width: 80%;
-          float: left;
-          padding: 1% 7%;
-          transition: 0s;
-      }
+.eventContentArea-left {
+    width: 80%;
+    float: left;
+    padding: 1% 7%;
+    transition: 0s;
+}
 
-      .nextItemBtn {
-          position: fixed;
-          bottom: 4%;
-          right: 3%;
-          background-color: #d8d8d8;
-          color: #515a6e;
-          z-index: 3;
-          padding: 7px;
-          cursor: pointer;
-          border-radius: 3px;
-          font-weight: bolder;
-      }
+.nextItemBtn {
+    position: fixed;
+    bottom: 4%;
+    right: 3%;
+    background-color: #d8d8d8;
+    color: #515a6e;
+    z-index: 3;
+    padding: 7px;
+    cursor: pointer;
+    border-radius: 3px;
+    font-weight: bolder;
+}
 
-          .nextItemBtn:hover {
-              background-color: rgb(100, 174, 22) !important;
-              color: white;
-              border: none;
-          }
+.nextItemBtn:hover {
+    background-color: rgb(100, 174, 22) !important;
+    color: white;
+    border: none;
+}
 </style>

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseView/ActivityView.vue

@@ -112,7 +112,7 @@
 <script>
 import Loading from '@/common/Loading.vue';
 import { mapGetters, mapState } from 'vuex'
-import PaperView from '../../EventView/EventContentTypeTemplate/PaperView.vue';
+import PaperView from '../../EventView/EventContentTypeTemplate/PaperViewBox/PaperView.vue';
 import Homework from '../../EventView/EventContentTypeTemplate/Homework.vue';
 import Vote from '../../EventView/EventContentTypeTemplate/Vote.vue';
 import QuesNaire from '../../EventView/EventContentTypeTemplate/QuesNaire.vue';

+ 0 - 0
TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeViewnnnnew.less


部分文件因为文件数量过多而无法显示