Procházet zdrojové kódy

Merge branch 'develop6.0-tmd' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop6.0-tmd

CrazyIter_Bin před 3 roky
rodič
revize
3a4f0bb5fd
68 změnil soubory, kde provedl 2665 přidání a 961 odebrání
  1. 1 1
      TEAMModelBI/ClientApp/public/index.html
  2. 7 0
      TEAMModelBI/ClientApp/src/api/index.js
  3. 0 142
      TEAMModelBI/ClientApp/src/components/echarts/PiegangedBar.vue
  4. 7 8
      TEAMModelBI/ClientApp/src/components/echarts/schoolPie.vue
  5. 85 0
      TEAMModelBI/ClientApp/src/components/echarts/commonBar.vue
  6. 13 140
      TEAMModelBI/ClientApp/src/components/echarts/commonLine.vue
  7. 11 92
      TEAMModelBI/ClientApp/src/components/echarts/commonPie.vue
  8. 85 0
      TEAMModelBI/ClientApp/src/components/echarts/conventionPie.vue
  9. 13 81
      TEAMModelBI/ClientApp/src/components/echarts/doublePie.vue
  10. 80 0
      TEAMModelBI/ClientApp/src/components/echarts/liquidfill.vue
  11. 3 3
      TEAMModelBI/ClientApp/src/components/echarts/test.vue
  12. 1315 37
      TEAMModelBI/ClientApp/src/view/areaServe/statistics.vue
  13. 16 3
      TEAMModelBI/ClientApp/src/view/schoolServe/school.vue
  14. 28 27
      TEAMModelBI/Controllers/Census/ActivitySticsController.cs
  15. 72 11
      TEAMModelBI/Controllers/Census/LessonSticsController.cs
  16. 13 0
      TEAMModelBI/Models/MonthStartEnd.cs
  17. 0 1
      TEAMModelBI/TEAMModelBI.csproj
  18. 64 0
      TEAMModelBI/Tool/CosmosBank/ActivityWay.cs
  19. 61 0
      TEAMModelBI/Tool/CosmosBank/LessonStatisWay.cs
  20. 51 0
      TEAMModelBI/Tool/CosmosBank/ProductWay.cs
  21. 1 1
      TEAMModelOS.FunctionV4/CosmosDB/TriggerExam.cs
  22. 3 1
      TEAMModelOS/ClientApp/src/api/http.js
  23. binární
      TEAMModelOS/ClientApp/src/assets/image/teacher-import.png
  24. 9 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.less
  25. 17 12
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  26. 4 4
      TEAMModelOS/ClientApp/src/locale/lang/en-US/cusMgt.js
  27. 8 8
      TEAMModelOS/ClientApp/src/locale/lang/en-US/home.js
  28. 5 2
      TEAMModelOS/ClientApp/src/locale/lang/en-US/learnActivity.js
  29. 56 56
      TEAMModelOS/ClientApp/src/locale/lang/en-US/lessonRecord.js
  30. 6 6
      TEAMModelOS/ClientApp/src/locale/lang/en-US/notice.js
  31. 6 6
      TEAMModelOS/ClientApp/src/locale/lang/en-US/researchCenter.js
  32. 8 8
      TEAMModelOS/ClientApp/src/locale/lang/en-US/schoolBaseInfo.js
  33. 2 2
      TEAMModelOS/ClientApp/src/locale/lang/en-US/stuAccount.js
  34. 15 15
      TEAMModelOS/ClientApp/src/locale/lang/en-US/studentWeb.js
  35. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/en-US/survey.js
  36. 4 4
      TEAMModelOS/ClientApp/src/locale/lang/en-US/system.js
  37. 80 53
      TEAMModelOS/ClientApp/src/locale/lang/en-US/teachermgmt.js
  38. 2 2
      TEAMModelOS/ClientApp/src/locale/lang/en-US/train.js
  39. 5 2
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/learnActivity.js
  40. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/lessonRecord.js
  41. 27 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/teachermgmt.js
  42. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/cusMgt.js
  43. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/evaluation.js
  44. 7 4
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/learnActivity.js
  45. 3 3
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/lessonRecord.js
  46. 2 2
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/researchCenter.js
  47. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/schoolBaseInfo.js
  48. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/system.js
  49. 49 23
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/teachermgmt.js
  50. 19 8
      TEAMModelOS/ClientApp/src/store/module/user.js
  51. 1 0
      TEAMModelOS/ClientApp/src/view/Home.vue
  52. 6 4
      TEAMModelOS/ClientApp/src/view/auth/SpaceInfo.vue
  53. 13 2
      TEAMModelOS/ClientApp/src/view/homepage/HomePage.vue
  54. 6 4
      TEAMModelOS/ClientApp/src/view/homepage/SpaceInfo.vue
  55. 4 2
      TEAMModelOS/ClientApp/src/view/learnactivity/ExamMgt.vue
  56. 128 71
      TEAMModelOS/ClientApp/src/view/learnactivity/echarts/QuCount.vue
  57. 1 5
      TEAMModelOS/ClientApp/src/view/learnactivity/tabs/DataView.vue
  58. 10 6
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less
  59. 17 11
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue
  60. 5 1
      TEAMModelOS/ClientApp/src/view/teachermgmt/Index.vue
  61. 48 35
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/import/Import.vue
  62. 8 0
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/mgt/TeacherMgt.less
  63. 58 16
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/mgt/TeacherMgt.vue
  64. 13 0
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/personnel/Index.less
  65. 65 28
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/personnel/Index.vue
  66. 4 0
      TEAMModelOS/Controllers/Client/HiTeachController.cs
  67. 8 1
      TEAMModelOS/Controllers/Client/HiTeachccControlller.cs
  68. 1 0
      TEAMModelOS/Controllers/XTest/FixDataController.cs

+ 1 - 1
TEAMModelBI/ClientApp/public/index.html

@@ -11,7 +11,7 @@
     </title>
 </head>
 <script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
-<script src="https://at.alicdn.com/t/font_2934132_7la2600x4ah.js"></script>
+<script src="https://at.alicdn.com/t/font_2934132_4jn9g2jtuel.js"></script>
 
 <body>
     <noscript>

+ 7 - 0
TEAMModelBI/ClientApp/src/api/index.js

@@ -192,5 +192,12 @@ export default {
     //根据选择类型查询数据
     searchTypedata(data) {
         return post('/jointly/get-info', data)
+    },
+
+
+    //区域服务
+    //获取全区的数据
+    getAlldata(data) {
+        return post('/activity/get-all', data)
     }
 }

+ 0 - 142
TEAMModelBI/ClientApp/src/components/echarts/PiegangedBar.vue

@@ -1,142 +0,0 @@
-<!--基础折线图-->
-<template>
-    <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%',
-        },
-        mapData: {
-            type: Object,
-            default: () => {},
-        },
-        title: {
-            type: String,
-            default: '',
-        },
-    },
-    setup(props) {
-        console.log(props.mapData, '传进来的值')
-        const myEcharts = ref(null)
-        let { proxy } = getCurrentInstance()
-        const chart = new InitChart(props, myEcharts)
-        onMounted(() => {
-            chart.init(props.mapData, proxy)
-        })
-        watch(
-            props,
-            (nweProps) => {
-                nextTick(() => {
-                    nweProps ? chart.init(props.mapData, 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 value = 0.6
-        var data = [value]
-        this.state.chart && this.destory()
-        this.state.chart = echarts.init(this.myEcharts.value)
-        this.state.chart.setOption({
-            backgroundColor: '#fff',
-            title: [
-                {
-                    text: '空间已使用率',
-                    x: '12%',
-                    y: '82%',
-                    textStyle: {
-                        fontSize: 14,
-                        fontWeight: '100',
-                        color: '#2e86de',
-                        lineHeight: 16,
-                        textAlign: 'center',
-                    },
-                },
-            ],
-            series: [
-                {
-                    type: 'liquidFill',
-                    radius: '70%',
-                    center: ['25%', '45%'],
-                    color: [
-                        {
-                            type: 'linear',
-                            x: 0,
-                            y: 0,
-                            x2: 1,
-                            y2: 1,
-                            colorStops: [
-                                {
-                                    offset: 0,
-                                    color: '#00FFFF',
-                                },
-                                {
-                                    offset: 1,
-                                    color: '#76EE00',
-                                },
-                            ],
-                            globalCoord: false,
-                        },
-                    ],
-                    data: data, // data个数代表波浪数
-                    backgroundStyle: {
-                        borderWidth: 1,
-                        color: 'RGBA(51, 66, 127, 0.7)',
-                    },
-                    label: {
-                        normal: {
-                            textStyle: {
-                                fontSize: 24,
-                                color: '#8395a7',
-                            },
-                        },
-                    },
-                    outline: {
-                        // show: false
-                        borderDistance: 0,
-                        itemStyle: {
-                            borderWidth: 2,
-                            borderColor: '#fff',
-                        },
-                    },
-                },
-            ],
-        })
-        window.addEventListener('resize', () => {
-            this.state.chart.resize()
-        })
-    }
-
-    destory() {
-        this.state.chart.dispose()
-        window.removeEventListener('resize', () => {
-            console.log('事件移除')
-        })
-    }
-}
-</script>
-<style lang="less"></style>
-

+ 7 - 8
TEAMModelBI/ClientApp/src/components/echarts/schoolPie.vue

@@ -60,9 +60,9 @@ class InitChart {
         this.state.chart && this.destory()
         this.state.chart = echarts.init(this.myEcharts.value)
         this.state.chart.setOption({
-            color: ['#ef5777', '#0fbcf9', '#0be881', '#575fcf', '#ffd32a'],
+            color: ['#ff7979', '#badc58', '#7ed6df', '#f6e58d', '#686de0'],
             legend: {
-                right: '0%',
+                right: '-2%',
                 orient: 'vertical',
                 itemWidth: 8,
                 itemHeight: 8, // 修改icon图形大小
@@ -77,9 +77,9 @@ class InitChart {
             },
             series: [
                 {
-                    name: '版本占比',
+                    name: '活动占比',
                     type: 'pie',
-                    radius: '90%',
+                    radius: '70%',
                     center: ['50%', '50%'],
                     itemStyle: {
                         borderRadius: 2,
@@ -91,10 +91,9 @@ class InitChart {
                         },
                     },
                     data: [
-                        { value: 1340, name: '师大附小' },
-                        { value: 380, name: '外国语小学' },
-                        { value: 658, name: '树德中学' },
-                        { value: 936, name: '川大附中' },
+                        { value: 1340, name: '评量测验' },
+                        { value: 380, name: '投票活动' },
+                        { value: 658, name: '问卷调查' },
                     ],
                 },
             ],

+ 85 - 0
TEAMModelBI/ClientApp/src/components/echarts/commonBar.vue

@@ -0,0 +1,85 @@
+<!--基础折线图-->
+<template>
+    <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%',
+        },
+        barData: {
+            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.barData, proxy)
+        })
+        watch(
+            props,
+            (nweProps) => {
+                nextTick(() => {
+                    nweProps ? chart.init(props.barData, 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) {
+        console.log(datas, '柱状图的调用')
+        this.state.chart && this.destory()
+        this.state.chart = echarts.init(this.myEcharts.value)
+        this.state.chart.setOption({
+            title: datas.title ? datas.title : '',
+            tooltip: datas.tooltip ? datas.tooltip : '',
+            legend: datas.legend ? datas.legend : '',
+            grid: datas.grid ? datas.grid : '',
+            xAxis: datas.xAxis ? datas.xAxis : '',
+            yAxis: datas.yAxis ? datas.yAxis : '',
+            dataZoom: datas.dataZoom ? datas.dataZoom : '',
+            series: datas.series ? datas.series : '',
+        })
+        window.addEventListener('resize', () => {
+            this.state.chart.resize()
+        })
+    }
+
+    destory() {
+        this.state.chart.dispose()
+        window.removeEventListener('resize', () => {
+            console.log('事件移除')
+        })
+    }
+}
+</script>
+<style lang="less"></style>
+

+ 13 - 140
TEAMModelBI/ClientApp/src/components/echarts/commonLine.vue

@@ -1,4 +1,3 @@
-<!--基础折线图-->
 <template>
     <div ref="myEcharts" :style="{ height, width }"></div>
 </template>
@@ -16,9 +15,9 @@ export default {
             type: String,
             default: '100%',
         },
-        mapData: {
+        lineData: {
             type: Array,
-            default: () => [],
+            default: () => {},
         },
         title: {
             type: String,
@@ -26,18 +25,17 @@ export default {
         },
     },
     setup(props) {
-        console.log(props.mapData, '传进来的值')
         const myEcharts = ref(null)
         let { proxy } = getCurrentInstance()
         const chart = new InitChart(props, myEcharts)
         onMounted(() => {
-            chart.init(props.mapData, proxy)
+            chart.init(props.lineData, proxy)
         })
         watch(
             props,
             (nweProps) => {
                 nextTick(() => {
-                    chart.init(props.mapData, proxy)
+                    nweProps ? chart.init(props.lineData, proxy) : ''
                 })
             },
             { immediate: true, deep: true }
@@ -56,151 +54,26 @@ class InitChart {
         }
     }
     init(datas, proxy) {
+        console.log(datas, 'line调用')
         this.state.chart && this.destory()
         this.state.chart = echarts.init(this.myEcharts.value)
-
         this.state.chart.setOption({
-            backgroundColor: '#fff',
-            grid: {
-                top: '17%',
-                bottom: '22%',
-                left: '4%',
-                right: '3%',
-            },
+            title: datas.title ? datas.title : {},
+            backgroundColor: datas.backgroundColor ? datas.backgroundColor : '#fff',
+            grid: datas.grid ? datas.grid : '',
             tooltip: {
                 trigger: 'axis',
                 axisPointer: {
                     type: 'line',
                     lineStyle: {
-                        color: '#FF8736',
-                    },
-                },
-            },
-            xAxis: {
-                boundaryGap: true, // 默认,坐标轴留白策略
-                axisLine: {
-                    // 坐标轴轴线相关设置。数学上的x轴
-                    show: true,
-                    lineStyle: {
-                        color: '#85B1B4',
-                    },
-                },
-                axisLabel: {
-                    // 坐标轴刻度标签的相关设置
-                    textStyle: {
-                        color: '#709FD9',
-                        margin: 15,
+                        color: datas.tooltipColor ? datas.tooltipColor : '#ccc',
                     },
                 },
-                splitLine: {
-                    show: false,
-                },
-                axisTick: {
-                    show: true,
-                    alignWithLabel: true,
-                },
-                data: ['第一周', '第二周', '第三周', '第四周', '第五周', '第六周', '第七周', '第八周', '第九周'],
-            },
-            yAxis: {
-                axisLine: {
-                    show: true,
-                    color: '#85B1B4',
-                },
-                axisLabel: {
-                    // 坐标轴刻度标签的相关设置
-                    show: true,
-                    textStyle: {
-                        color: '#709FD9',
-                        margin: 15,
-                    },
-                },
-                splitLine: {
-                    show: true,
-                },
-                axisTick: {
-                    show: true,
-                },
             },
-            dataZoom: [
-                {
-                    show: true,
-                    height: 15,
-                    xAxisIndex: [0, 1],
-                    bottom: 10,
-                    right: '8%',
-                    left: '5%',
-                    start: 0,
-                    end: 100,
-                    backgroundColor: 'rgba(0,0,0,0)',
-                    handleIcon: 'path://M306.1,413c0,2.2-1.8,4-1,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
-                    handleSize: '110%',
-                    handleStyle: {
-                        color: '#999999',
-                    },
-                    textStyle: {
-                        color: '#999999',
-                    },
-                    borderColor: '',
-                    zoomOnMouseWheel: false,
-                    moveOnMouseMove: true,
-                    moveOnMouseWheel: true,
-                },
-                {
-                    type: 'inside',
-                    show: true,
-                    height: 15,
-                    start: 1,
-                    end: 100,
-                },
-            ],
-            series: [
-                {
-                    type: 'scatter',
-                    symbolSize: 10,
-                    itemStyle: {
-                        color: '#3498db',
-                    },
-                    silent: true,
-                    tooltip: {
-                        show: false,
-                    },
-                    markPoint: {
-                        data: [
-                            { type: 'max', name: 'Max' },
-                            { type: 'min', name: 'Min' },
-                        ],
-                        label: {
-                            color: '#FFF', // 文字颜色
-                            padding: [0, 0, 5, 0], // 可用padding调整图片内文字距离
-                            show: true,
-                        },
-                    },
-                    data: [200, 180, 280, 90, 160, 320, 180, 369, 571],
-                },
-                {
-                    type: 'line',
-                    symbol: 'circle',
-                    symbolSize: 16,
-                    symbol: 'path://M488 187.381L242.872 328.906a48 48 0 0 0-24 41.57v283.049a48 48 0 0 0 24 41.569L488 836.619a48 48 0 0 0 48 0l245.128-141.525a48 48 0 0 0 24-41.57V370.476a48 48 0 0 0-24-41.569L536 187.381a48 48 0 0 0-48 0z m32 27.713l245.128 141.525a16 16 0 0 1 8 13.856v283.05a16 16 0 0 1-8 13.856L520 808.906a16 16 0 0 1-16 0L258.872 667.381a16 16 0 0 1-8-13.856v-283.05a16 16 0 0 1 8-13.856L504 215.094a16 16 0 0 1 16 0z',
-                    lineStyle: {
-                        color: '#3498db',
-                    },
-                    itemStyle: {
-                        color: '#3498db',
-                        borderWidth: 1,
-                        borderColor: '#3498db',
-                    },
-                    label: {
-                        show: true,
-                        position: 'top',
-                        textStyle: {
-                            color: '#fff',
-                        },
-                    },
-
-                    data: [200, 180, 280, 90, 160, 320, 180, 369, 571],
-                },
-            ],
+            xAxis: datas.xAxis ? datas.xAxis : {},
+            yAxis: datas.yAxis ? datas.yAxis : {},
+            dataZoom: datas.dataZoom ? datas.dataZoom : '',
+            series: datas.series ? datas.series : [],
         })
         window.addEventListener('resize', () => {
             this.state.chart.resize()

+ 11 - 92
TEAMModelBI/ClientApp/src/components/echarts/commonPie.vue

@@ -16,9 +16,9 @@ export default {
             type: String,
             default: '100%',
         },
-        mapData: {
-            type: Array,
-            default: () => [],
+        proportionData: {
+            type: Object,
+            default: () => {},
         },
         title: {
             type: String,
@@ -26,18 +26,17 @@ export default {
         },
     },
     setup(props) {
-        console.log(props.mapData, '传进来的值')
         const myEcharts = ref(null)
         let { proxy } = getCurrentInstance()
         const chart = new InitChart(props, myEcharts)
         onMounted(() => {
-            chart.init(props.mapData, proxy)
+            chart.init(props.proportionData, proxy)
         })
         watch(
             props,
             (nweProps) => {
                 nextTick(() => {
-                    chart.init(props.mapData, proxy)
+                    nweProps ? chart.init(props.proportionData, proxy) : ''
                 })
             },
             { immediate: true, deep: true }
@@ -56,95 +55,15 @@ class InitChart {
         }
     }
     init(datas, proxy) {
+        console.log(datas, '简单pie的调用')
         this.state.chart && this.destory()
         this.state.chart = echarts.init(this.myEcharts.value)
-
         this.state.chart.setOption({
-            title: {
-                text: '研修学校占比',
-                textStyle: {
-                    color: '#595959',
-                    fontSize: 14,
-                },
-                // subtext: '年度任务总数:18个',
-                // subtextStyle: {
-                //     fontSize: 14,
-                //     color: '#8C8C8C',
-                // },
-                itemGap: 20,
-                left: 'center',
-                top: '55%',
-            },
-            angleAxis: {
-                max: 100,
-                clockwise: true, // 逆时针
-                // 隐藏刻度线
-                show: false,
-            },
-            radiusAxis: {
-                type: 'category',
-                show: true,
-                axisLabel: {
-                    show: false,
-                },
-                axisLine: {
-                    show: false,
-                },
-                axisTick: {
-                    show: false,
-                },
-            },
-            polar: {
-                center: ['50%', '50%'],
-                radius: '110%', //图形大小
-            },
-            series: [
-                {
-                    type: 'bar',
-                    data: [32],
-                    showBackground: true,
-                    coordinateSystem: 'polar',
-                    roundCap: true,
-                    barWidth: 8,
-                    itemStyle: {
-                        normal: {
-                            opacity: 1,
-                            color: '#1890FF',
-                        },
-                    },
-                    z: 10,
-                },
-                {
-                    type: 'bar',
-                    data: [100],
-                    showBackground: true,
-                    barGap: '-100%',
-                    coordinateSystem: 'polar',
-                    roundCap: true,
-                    barWidth: 8,
-                    itemStyle: {
-                        normal: {
-                            opacity: 1,
-                            color: '#E7E9EB',
-                        },
-                    },
-                },
-                {
-                    type: 'pie',
-                    data: [1],
-                    radius: '90%',
-                    itemStyle: {
-                        color: 'transparent',
-                    },
-                    label: {
-                        show: true,
-                        position: 'center',
-                        formatter: 32 + '%',
-                        color: '#1890FF',
-                        fontSize: 22,
-                    },
-                },
-            ],
+            title: datas.title ? datas.title : '',
+            angleAxis: datas.angleAxis ? datas.angleAxis : '',
+            radiusAxis: datas.radiusAxis ? datas.radiusAxis : '',
+            polar: datas.polar ? datas.polar : '',
+            series: datas.series ? datas.series : '',
         })
         window.addEventListener('resize', () => {
             this.state.chart.resize()

+ 85 - 0
TEAMModelBI/ClientApp/src/components/echarts/conventionPie.vue

@@ -0,0 +1,85 @@
+<!--基础折线图-->
+<template>
+    <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%',
+        },
+        pieData: {
+            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.pieData, proxy)
+        })
+        watch(
+            props,
+            (nweProps) => {
+                nextTick(() => {
+                    nweProps ? chart.init(props.pieData, 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) {
+        console.log(datas, '1111111111111111')
+        this.state.chart && this.destory()
+        this.state.chart = echarts.init(this.myEcharts.value)
+        this.state.chart.setOption({
+            title: datas.title ? datas.title : '',
+            color: datas.color ? datas.color : '',
+            legend: datas.legend ? datas.legend : '',
+            tooltip: {
+                trigger: 'item',
+                formatter: '{a} <br/>{b}: {c} ({d}%)',
+            },
+            series: datas.series ? datas.series : '',
+        })
+        window.addEventListener('resize', () => {
+            this.state.chart.resize()
+        })
+    }
+
+    destory() {
+        this.state.chart.dispose()
+        window.removeEventListener('resize', () => {
+            console.log('事件移除')
+        })
+    }
+}
+</script>
+<style lang="less"></style>
+

+ 13 - 81
TEAMModelBI/ClientApp/src/components/echarts/doublePie.vue

@@ -16,7 +16,7 @@ export default {
             type: String,
             default: '100%',
         },
-        mapData: {
+        doublePieData: {
             type: Object,
             default: () => {},
         },
@@ -26,18 +26,17 @@ export default {
         },
     },
     setup(props) {
-        console.log(props.mapData, '传进来的值')
         const myEcharts = ref(null)
         let { proxy } = getCurrentInstance()
         const chart = new InitChart(props, myEcharts)
         onMounted(() => {
-            chart.init(props.mapData, proxy)
+            chart.init(props.doublePieData, proxy)
         })
         watch(
             props,
             (nweProps) => {
                 nextTick(() => {
-                    nweProps ? chart.init(props.mapData, proxy) : ''
+                    nweProps ? chart.init(props.doublePieData, proxy) : ''
                 })
             },
             { immediate: true, deep: true }
@@ -56,90 +55,23 @@ class InitChart {
         }
     }
     init(datas, proxy) {
-        var color = ['#78e08f ', '#3498db', '#fa983a', '#5555FF', '#079992']
-        var data = [
-            { value: 9, name: '高教' },
-            { value: 33, name: '普教' },
-        ]
+        // 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: color,
+            color: datas.color ? datas.color : '',
             tooltip: {
                 trigger: 'item',
                 formatter: '{a} <br/>{b}: {c} ({d}%)',
             },
-            legend: {
-                orient: 'vertical',
-                right: 0,
-                top: '15%',
-                // width:,
-                // height:,
-
-                // 图例颜色块宽高
-                itemWidth: 15,
-                itemHeight: 15,
-                // 		// 图例字体大小
-                textStyle: {
-                    fontSize: 12,
-                },
-                formatter: function (name) {
-                    var total = 0
-                    var target
-                    for (var i = 0, l = data.length; i < l; i++) {
-                        total += data[i].value
-                        if (data[i].name == name) {
-                            target = data[i].value
-                        }
-                    }
-                    // return name + ' ' + ((target / total) * 100).toFixed(2) + '%'
-                    return name
-                },
-                data: [
-                    { value: 10, name: '小学' },
-                    { value: 3, name: '初中' },
-                    { value: 7, name: '高中' },
-                    { value: 3, name: '职高类' },
-                ],
-            },
-            series: [
-                {
-                    // name:'访问来源',
-                    name: '类型',
-                    type: 'pie',
-                    selectedMode: 'single',
-                    radius: [0, '55%'],
-                    label: {
-                        normal: {
-                            position: 'inner',
-                            fontSize: 12,
-                        },
-                    },
-                    labelLine: {
-                        normal: {
-                            show: false,
-                        },
-                    },
-                    data: data,
-                    // [
-                    //     { value: 10, name: '小学' },
-                    //     { value: 3, name: '初中' },
-                    //     { value: 7, name: '高中' },
-                    //     { value: 3, name: '职高类' },
-                    // ],
-                },
-                {
-                    name: '学段占比',
-                    type: 'pie',
-                    radius: ['65%', '90%'],
-                    data: [
-                        { value: 10, name: '小学' },
-                        { value: 3, name: '初中' },
-                        { value: 7, name: '高中' },
-                        { value: 3, name: '职高类' },
-                    ],
-                },
-            ],
+            legend: datas.legend ? datas.legend : {},
+            series: datas.series ? datas.series : [],
         })
         window.addEventListener('resize', () => {
             this.state.chart.resize()

+ 80 - 0
TEAMModelBI/ClientApp/src/components/echarts/liquidfill.vue

@@ -0,0 +1,80 @@
+<!--基础折线图-->
+<template>
+    <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%',
+        },
+        liquidfillData: {
+            type: Object,
+            default: () => {},
+        },
+        title: {
+            type: String,
+            default: '',
+        },
+    },
+    setup(props) {
+        console.log(props.liquidfillData, '传进来的值')
+        const myEcharts = ref(null)
+        let { proxy } = getCurrentInstance()
+        const chart = new InitChart(props, myEcharts)
+        onMounted(() => {
+            chart.init(props.liquidfillData, proxy)
+        })
+        watch(
+            props,
+            (nweProps) => {
+                nextTick(() => {
+                    nweProps ? chart.init(props.liquidfillData, 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) {
+        this.state.chart && this.destory()
+        this.state.chart = echarts.init(this.myEcharts.value)
+        this.state.chart.setOption({
+            backgroundColor: datas.backgroundColor ? datas.backgroundColor : '#fff',
+            title: datas.title ? datas.title : [],
+            series: datas.series ? datas.series : [],
+        })
+        window.addEventListener('resize', () => {
+            this.state.chart.resize()
+        })
+    }
+
+    destory() {
+        this.state.chart.dispose()
+        window.removeEventListener('resize', () => {
+            console.log('事件移除')
+        })
+    }
+}
+</script>
+<style lang="less"></style>
+

+ 3 - 3
TEAMModelBI/ClientApp/src/components/echarts/test.vue

@@ -60,7 +60,7 @@ class InitChart {
         this.state.chart = echarts.init(this.myEcharts.value)
         this.state.chart.setOption({
             title: {
-                text: '数据全区占比',
+                text: '研修完成度',
                 textStyle: {
                     color: '#595959',
                     fontSize: 14,
@@ -100,7 +100,7 @@ class InitChart {
             series: [
                 {
                     type: 'bar',
-                    data: [45],
+                    data: [60],
                     showBackground: true,
                     coordinateSystem: 'polar',
                     roundCap: true,
@@ -138,7 +138,7 @@ class InitChart {
                     label: {
                         show: true,
                         position: 'center',
-                        formatter: 45 + '%',
+                        formatter: 60 + '%',
                         color: '#1890FF',
                         fontSize: 22,
                     },

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1315 - 37
TEAMModelBI/ClientApp/src/view/areaServe/statistics.vue


+ 16 - 3
TEAMModelBI/ClientApp/src/view/schoolServe/school.vue

@@ -90,7 +90,12 @@
     <!--编辑学校页面-->
     <div class="schoolDeatils">
         <div class="backbtn" v-if="models==='details' && PowerShow">
-            <el-button type="primary" icon="el-icon-back" @click="schoolClose">返回</el-button>
+            <el-button type="primary" size="small" @click="schoolClose">
+                <svg class="back-icon" aria-hidden="true">
+                    <use xlink:href="#icon-fanhui"></use>
+                </svg>
+                返回
+            </el-button>
             <el-button class="changebtn" v-if="store.state.changbtnShow && changebtns" @click="getSetschool()">
                 <svg class="changebtn-areaicon" aria-hidden="true">
                     <use xlink:href="#icon-wenjian"></use>
@@ -637,8 +642,10 @@ export default {
 .backbtn {
     text-align: left;
     position: absolute;
-    top: 0%;
-    right: 3px;
+    top: 0.5%;
+    right: 10px;
+    z-index: 999;
+    line-height: 40px;
 }
 .school-formbox {
     width: 85%;
@@ -872,6 +879,12 @@ export default {
     fill: currentColor;
     margin-right: 3px;
 }
+.back-icon {
+    width: 14px;
+    height: 14px;
+    fill: currentColor;
+    margin-right: 3px;
+}
 </style>
 <style>
 .schoolbox .el-cascader {

+ 28 - 27
TEAMModelBI/Controllers/Census/ActivitySticsController.cs

@@ -15,6 +15,7 @@ using System.Text;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelBI.Models;
 using TEAMModelOS.SDK;
+using TEAMModelBI.Tool.CosmosBank;
 
 namespace TEAMModelBI.Controllers.Census
 {
@@ -247,14 +248,15 @@ namespace TEAMModelBI.Controllers.Census
                 schools.Add(item);
             }
 
-            long exemAreaCount = 0;
-            long surveyAreaCount = 0;
-            long voteAreaCount = 0;
-            long homeworkAreaCount = 0;
+            long exemAreaCount = 0;  //评测活动
+            long surveyAreaCount = 0;  //问卷
+            long voteAreaCount = 0;   //投票
+            long homeworkAreaCount = 0;   //作业活动
 
             List<ActivityCount> activityCount = new();
             foreach (var school in schools)
             {
+
                 ActivityCount tempCount = new ActivityCount() { id = school.id, name = school.name != null ? school.name : school.id };
                 foreach (var type in types)
                 {
@@ -321,7 +323,7 @@ namespace TEAMModelBI.Controllers.Census
             long homeworkAreaCount = 0;  //作业活动
             long weekActivity = 0; //周活动数量
             long termActivity=0;   //学期活动
-            int Basics = 0; //基础版数
+            int basics = 0; //基础版数
             int standard = 0; //标准版数
             int major = 0;   //专业版数
             int geCount = 0; //普教
@@ -331,7 +333,6 @@ namespace TEAMModelBI.Controllers.Census
             List<SchoolLesson> schoolLessons = new();  //学校课例集合 
             List<SchoolInfo> schoolInfos = new();
 
-
             int totalTime = 0;
             foreach (var school in schools)
             {
@@ -369,7 +370,7 @@ namespace TEAMModelBI.Controllers.Census
                     major += 1;
                 else if (school.size >= 300 && school.scale >= 500)
                     standard += 1;
-                else Basics += 1;
+                else basics += 1;
 
                 //课例
                 int lessCount = await CommonFind.FindTotals(cosmosClient, "select count(c.id) totals from c", "School", $"LessonRecord-{school.id}");
@@ -381,7 +382,6 @@ namespace TEAMModelBI.Controllers.Census
                     count = lessCount
                 };
 
-
                 SchoolInfo schoolInfo = new() { 
                     id = school.id, 
                     name = school.name,
@@ -392,7 +392,7 @@ namespace TEAMModelBI.Controllers.Census
                     trainCount = tempCount 
                 };
 
-                ActivityCount tempActivity = new ActivityCount() { id = school.id, name = school.name != null ? school.name : school.id };
+                ActivityCount tempActivity = new() { id = school.id, name = school.name != null ? school.name : school.id };
                 foreach (var type in types)
                 {
                     long totals = await CommonFind.FindTotals(cosmosClient, $"select COUNT(c.id) AS totals from c where c.pk='{type}' and c.school='{school.id}' ", new List<string>() { "Common" });
@@ -426,7 +426,7 @@ namespace TEAMModelBI.Controllers.Census
                 schoolLessons.Add(schoolLesson);
             }
 
-            return Ok(new { state = 200, schoolCount = schools.Count, countArea, weekActivity, termActivity, totalTime, appraiseArea, examAreaCount, surveyAreaCount, voteAreaCount, homeworkAreaCount, schools = schoolInfos, schoolLessons });
+            return Ok(new { state = 200, schoolCount = schools.Count, countArea, weekActivity, termActivity, totalTime, appraiseArea, examAreaCount, surveyAreaCount, voteAreaCount, homeworkAreaCount, major, standard, oeCount, schools = schoolInfos, schoolLessons });
         }
 
         /// <summary>
@@ -460,6 +460,12 @@ namespace TEAMModelBI.Controllers.Census
             int tecCount = 0;    //教师数量
             int scCount = 0;    //学校数量
 
+            int basics = 0; //基础版数
+            int standard = 0; //标准版数
+            int major = 0;   //专业版数
+            long resourceCount = 0; //累计资源
+            long totalTime = 0; //总学时
+
             foreach (var area in areaInfos) 
             {
                 List<RecSchool> recSchools = new();
@@ -471,7 +477,11 @@ namespace TEAMModelBI.Controllers.Census
                 recSchools.ForEach(x => { if (x.type == 2) heCount += 1; else if (x.type == 1) geCount += 1; else oeCount += 1; });
                 allSize += recSchools.Select(s => s.size).Sum();
                 area.schoolCount = recSchools.Count;
-
+                //统计服务
+                var (tempb, temps, tempm) = await ProductWay.GetVersionCount(cosmosClient, recSchools);
+                basics += tempb;
+                standard += temps;
+                major += tempm;
                 int tempCount = await CommonFind.GetPeopleNumber(cosmosClient, "School", recSchools?.Select(x => x.id).ToList(), "Teacher");
 
                 tecCount += tempCount;
@@ -496,14 +506,17 @@ namespace TEAMModelBI.Controllers.Census
                 allActivity += totals;
                 activitys.Add(type, totals);
             }
-            
-            allLess = await CommonFind.FindTotals(cosmosClient, "select count(c.id) as totals from c where c.pk='LessonRecord'", new List<string>() { "School" });
+
+            allLess = await CommonFind.FindTotals(cosmosClient, "select count(c.id) as totals from c where c.pk='LessonRecord'", new List<string>() { "School", "Teacher" });
             weekLess = await CommonFind.FindTotals(cosmosClient, $"select count(c.id) as totals from c where c.pk='LessonRecord' and c.startTime>={weekStart} and c.startTime <={weekEnd}", new List<string>() { "School", "Teacher" });
             termLess = await CommonFind.FindTotals(cosmosClient, $"select count(c.id) as totals from c where c.pk='LessonRecord' and c.startTime>={termStart} and c.startTime <={termEnd}", new List<string>() { "School","Teacher" });
 
-            return Ok(new { state = 200, areaCount = areaInfos.Count, allSize, heCount, geCount, oeCount, allLess, termLess, weekLess, allActivity, termActivity, weekActivity, areaInfos });
+            totalTime = await CommonFind.FindTotals(cosmosClient, "select sum(c.totalTime) as totals from c where c.pk='TeacherTrain'", new List<string>() { "Teacher" });
+            resourceCount = await CommonFind.FindTotals(cosmosClient, "select count(c.id) as totals from c where c.pk='Bloblog'", new List<string>() { "School", "Teacher" });
+
+            return Ok(new { state = 200, areaCount = areaInfos.Count, allSize, heCount, geCount, oeCount, allLess, termLess, weekLess, allActivity, termActivity, weekActivity, resourceCount, basics, standard, major, totalTime, activitys, areaInfos });
         }
-                
+
 
         /// <summary>
         /// 依据活动Id查询活动详情信息  数据管理工具——查询工具
@@ -564,18 +577,6 @@ namespace TEAMModelBI.Controllers.Census
             public int stuCount { get; set; }
         }
 
-        /// <summary>
-        /// 区级下学校信息显示
-        /// </summary>
-        public record RecSchool
-        {
-            public string id { get; set; }
-            public string name { get; set; }
-            public string picture { get; set; }
-            public int type { get; set; }
-            public int size { get; set; }
-            public int scale { get; set; }
-        }
 
         private class SchoolInfo
         {

+ 72 - 11
TEAMModelBI/Controllers/Census/LessonSticsController.cs

@@ -16,6 +16,7 @@ using TEAMModelOS.SDK.Extension;
 using System.Text;
 using TEAMModelBI.Tool;
 using MathNet.Numerics.LinearAlgebra.Double;
+using TEAMModelBI.Tool.CosmosBank;
 
 namespace TEAMModelBI.Controllers.Census
 {
@@ -27,6 +28,7 @@ namespace TEAMModelBI.Controllers.Census
         private readonly AzureStorageFactory _azureStorage;
         private readonly DingDing _dingDing;
         private readonly Option _option;
+        public readonly List<string> types = new() { "Exam", "Survey", "Vote", "Homework" };
 
         public LessonSticsController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureFactory, DingDing dingDing, IOptionsSnapshot<Option> option)
         {
@@ -325,11 +327,17 @@ namespace TEAMModelBI.Controllers.Census
         [HttpPost("get-areacount")]
         public async Task<IActionResult> GetAreaCount(JsonElement jsonElement) 
         {
-            if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
+            if(!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
             List<string> schools = new();
             var cosmosClient = _azureCosmos.GetCosmosClient();
 
-            schools = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c where c.areaId='{areaId}'", "Base");
+            StringBuilder scSqlTxt = new("select c.id from c");
+            if (!string.IsNullOrEmpty($"{areaId}"))
+            {
+                scSqlTxt.Append($" where c.areaId='{areaId}'");
+            }
+
+            schools = await CommonFind.FindSchoolIds(cosmosClient, scSqlTxt.ToString(), "Base");
 
             //所有的课程记录
             List<LessonRecord> records = new();
@@ -376,6 +384,7 @@ namespace TEAMModelBI.Controllers.Census
             return Ok(new { state = 200, lessonCount = records.Count, teachCount, dayCount, weekCount, monthCount, termCount });
         }
 
+
         /// <summary>
         /// 统计区级一年每周的课例数据趋势
         /// </summary>
@@ -385,18 +394,29 @@ namespace TEAMModelBI.Controllers.Census
         [HttpPost("get-weekcount")]
         public async Task<IActionResult> GetWeekCount(JsonElement jsonElement) 
         {
-            if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
+            jsonElement.TryGetProperty("areaId", out JsonElement areaId);
 
-            Dictionary<int, double> weeks = new();
+            //Dictionary<int, double> weeks = new();
+            List<double> weeks = new();
             var cosmosClient = _azureCosmos.GetCosmosClient();
 
             int year = DateTimeOffset.UtcNow.Year;
             int dayOfweek = (int)DateTimeOffset.Parse($"{year}-1-1").DayOfWeek;
+            int currentTime = DateTimeOffset.UtcNow.DayOfYear / 7 + 1;
+            int currentTime1 = DateTimeOffset.UtcNow.DayOfYear / 7;
+
             var sqlTxts = "select value(c) from c";
             List<LessonCount> scount = new();
             List<LessonCount> tcount = new();
 
-            List<string> schools = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c where c.areaId='{areaId}'", "Base");
+            StringBuilder sqlTxt = new("select c.id from c");
+            if (!string.IsNullOrEmpty($"{areaId}"))
+            {
+                sqlTxt.Append($" where c.areaId='{areaId}'");
+            }
+
+            List<string> schools = await CommonFind.FindSchoolIds(cosmosClient, sqlTxt.ToString(), "Base");
+
             foreach (var sId in schools)
             {
                 await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<LessonCount>(queryText:sqlTxts,requestOptions:new QueryRequestOptions() { PartitionKey =new PartitionKey($"LessonCount-{sId}-{year}")}))
@@ -448,21 +468,23 @@ namespace TEAMModelBI.Controllers.Census
                 int sweeks = days / 7;
                 //查询天数
                 int dayYear = 0;
-                if (sweeks > 0)
+                if (currentTime > 0)
                 {
-                    for (int i = 1; i <= sweeks; i++)
+                    for (int i = 0; i <= currentTime; i++)
                     {
-                        if (i == 1)
+                        if (i == 0)
                         {
                             var bsum = bmatrix.SubMatrix(dayYear, dd, 0, bmatrix.ColumnCount).ColumnSums().Sum();
                             dayYear += dd;
-                            weeks.Add(i, bsum);
+                            //weeks.Add(i, bsum);
+                            weeks.Add(bsum);
                         }
                         else
                         {
                             var bsum = bmatrix.SubMatrix(dayYear, 7, 0, bmatrix.ColumnCount).ColumnSums().Sum();
                             dayYear += 7;
-                            weeks.Add(i, bsum);
+                            //weeks.Add(i, bsum);
+                            weeks.Add(bsum);
                         }
                     }
                 }
@@ -471,13 +493,43 @@ namespace TEAMModelBI.Controllers.Census
                 if (stary > 0 && stary < 7)
                 {
                     var bsum = bmatrix.SubMatrix(dayYear, stary - 1, 0, bmatrix.ColumnCount).ColumnSums().Sum();
-                    weeks.Add((sweeks + 1), bsum);
+                    //weeks.Add((sweeks + 1), bsum);
+                    weeks.Add(bsum);
                 }
             }
 
             return Ok(new { state = 200, weeks });
         }
 
+        /// <summary>
+        /// 统计所有区级的课例和活动
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("get-allarea")]
+        public async Task<IActionResult> GetAllArea()
+        {
+            var cosmosClient = _azureCosmos.GetCosmosClient();
+
+            List<AllAreaInfo> areaInfos = new();
+            await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Normal").GetItemQueryIterator<AllAreaInfo>(queryText: $"select c.id,c.name,c.standard,c.standardName from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base-Area") }))
+            {
+                areaInfos.Add(item);
+            }
+
+            foreach (var area in areaInfos)
+            {
+                List<string> schooId = await CommonFind.FindSchoolIds(cosmosClient,$"select c.id from c where c.areaId='{area.id}'","Base");
+                List<string> tecId = await CommonFind.FindRolesId(cosmosClient, schooId);
+
+                area.lessCount = await LessonStatisWay.GetAll(cosmosClient, schooId, tecId);
+                area.activityCount = await ActivityWay.GetAll(cosmosClient, schooId, tecId);
+            }
+
+
+            return Ok(new { state = 200 , areaInfos });
+        }
+
+
         /// <summary>
         /// 依据课例Id获取课例详情   数据管理工具——查询工具
         /// </summary>
@@ -505,7 +557,16 @@ namespace TEAMModelBI.Controllers.Census
 
 
 
+        public record AllAreaInfo
+        {
+            public string id { get; set; }
+            public string name { get; set; }
+            public string standard { get; set; }
+            public string standardName { get; set; }
+            public int lessCount { get; set; }
+            public int activityCount { get; set; }
 
+        }
 
         public record SchoolLen 
         {

+ 13 - 0
TEAMModelBI/Models/MonthStartEnd.cs

@@ -19,5 +19,18 @@
         public string tmdName { get; set; }
     }
 
+    /// <summary>
+    /// 学校信息显示
+    /// </summary>
+    public record RecSchool
+    {
+        public string id { get; set; }
+        public string name { get; set; }
+        public string picture { get; set; }
+        public int type { get; set; }
+        public int size { get; set; }
+        public int scale { get; set; }
+    }
+
 
 }

+ 0 - 1
TEAMModelBI/TEAMModelBI.csproj

@@ -27,7 +27,6 @@
 	</ItemGroup>
 
 	<ItemGroup>
-		<Folder Include="Tool\Cosmos\StudentBank\" />
 		<Folder Include="wwwroot\" />
 	</ItemGroup>
 	<PropertyGroup>

+ 64 - 0
TEAMModelBI/Tool/CosmosBank/ActivityWay.cs

@@ -0,0 +1,64 @@
+using Azure.Cosmos;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace TEAMModelBI.Tool.CosmosBank
+{
+    public class ActivityWay
+    {
+        public static List<string> types = new() { "Exam", "Survey", "Vote", "Homework" };
+
+        /// <summary>
+        /// 依据学校Id、教师Id统计活动总数
+        /// </summary>
+        /// <param name="cosmosClient"></param>
+        /// <param name="scIds"></param>
+        /// <param name="tecIds"></param>
+        /// <returns></returns>
+        public async static Task<int> GetAll(CosmosClient cosmosClient, List<string> scIds = null, List<string> tecIds = null)
+        {
+            int totals = 0;
+            string sqlTxt = "select count(c.id) as totals from c";
+            foreach (string type in types)
+            {
+                if (scIds.Count > 0)
+                {
+                    foreach (string sc in scIds)
+                    {
+                        await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{type}-{sc}") }))
+                        {
+                            using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
+                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
+                            {
+                                foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                {
+                                    totals += obj.GetProperty("totals").GetInt32();
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (tecIds.Count > 0)
+                {
+                    foreach (string sc in scIds)
+                    {
+                        await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{type}-{sc}") }))
+                        {
+                            using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
+                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
+                            {
+                                foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                {
+                                    totals += obj.GetProperty("totals").GetInt32();
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            return totals;
+        }
+    }
+}

+ 61 - 0
TEAMModelBI/Tool/CosmosBank/LessonStatisWay.cs

@@ -0,0 +1,61 @@
+using Azure.Cosmos;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace TEAMModelBI.Tool.CosmosBank
+{
+    public class LessonStatisWay
+    {
+        /// <summary>
+        /// 依据学校Id、教师Id统计课例总数
+        /// </summary>
+        /// <param name="cosmosClient"></param>
+        /// <param name="scIds"></param>
+        /// <param name="tecIds"></param>
+        /// <returns></returns>
+        public async static Task<int> GetAll(CosmosClient cosmosClient, List<string> scIds = null, List<string> tecIds = null)
+        {
+            int totals = 0;
+            string sqlTxt = "select count(c.id) as totals from c";
+            if (scIds.Count > 0)
+            {
+                foreach (string sc in scIds)
+                {
+                    await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{sc}") }))
+                    {
+                        using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
+                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
+                        {
+                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                            {
+                                totals += obj.GetProperty("totals").GetInt32();
+                            }
+                        }
+                    }
+                }
+            }
+            if (tecIds.Count > 0)
+            {
+                foreach (string sc in scIds)
+                {
+                    await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{sc}") }))
+                    {
+                        using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
+                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
+                        {
+                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                            {
+                                totals += obj.GetProperty("totals").GetInt32();
+                            }
+                        }
+                    }
+                }
+            }
+
+            return totals;
+        }
+
+
+    }
+}

+ 51 - 0
TEAMModelBI/Tool/CosmosBank/ProductWay.cs

@@ -0,0 +1,51 @@
+using Azure.Cosmos;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelBI.Models;
+
+namespace TEAMModelBI.Tool.CosmosBank
+{
+    public class ProductWay
+    {
+        /// <summary>
+        /// 依据学校信息统计版本数量
+        /// </summary>
+        /// <param name="cosmosClient"></param>
+        /// <param name="scIds"></param>
+        /// <returns></returns>
+        public async static Task<(int bCount, int sCount, int mCount)> GetVersionCount(CosmosClient cosmosClient, List<RecSchool> scIds) 
+        {
+            int totals = 0;
+
+            int basics = 0; //基础版数
+            int standard = 0; //标准版数
+            int major = 0;   //专业版数
+            foreach (var sc in scIds) 
+            {
+                string sqlTxt = $"select array_length(c.service) as totals from c where c.id='{sc.id}'";
+                await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: sqlTxt.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("ProductSum") }))
+                {
+                    using 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())
+                        {
+                            totals += obj.GetProperty("totals").GetInt32();
+                        }
+                    }
+                }
+
+                if (totals > 0)
+                    major += 1;
+                else if (sc.size >= 300 && sc.scale >= 500)
+                    standard += 1;
+                else basics += 1;
+
+            }
+
+            return (basics, standard, major);
+        }
+
+    }
+}

+ 1 - 1
TEAMModelOS.FunctionV4/CosmosDB/TriggerExam.cs

@@ -749,7 +749,7 @@ namespace TEAMModelOS.FunctionV4
                         sStatus = iss ? 1 : 0,
                         classIds = classIds.ToList()
 
-                    }); ;
+                    });
                 });
             }
             if (addStudentsCls.IsNotEmpty())

+ 3 - 1
TEAMModelOS/ClientApp/src/api/http.js

@@ -16,7 +16,6 @@ const NO_ACCESS_API = [
     '/common/study/sign-in',
     'third/sso/opt-tmdid-bind',
     '/sc/bind',
-    '/oauth2/profile',
 	'/core/get-short-url',
 	'/core/get-long-url'
 ]
@@ -67,6 +66,7 @@ axios.interceptors.request.use(
         if (webEndTime && time_now > webEndTime) {
             console.log('长时间未操作,重新登录', config)
             loginOut()
+            localStorage.setItem('loginOut','长时间未操作')
             return
         }
         let access_token = localStorage.getItem('access_token')
@@ -102,6 +102,7 @@ axios.interceptors.request.use(
         if (!auth_token) {
             console.log('auth_token失败', config)
             loginOut()
+            localStorage.setItem('loginOut','auth_token失败')
             return
         }
         //通过验证设置对应参数
@@ -192,6 +193,7 @@ async function refreshToken() {
             refreshing = false
             console.log('token刷新失败,退出重新登录')
             loginOut()
+            localStorage.setItem('loginOut','refreshToken')
         }
     )
 }

binární
TEAMModelOS/ClientApp/src/assets/image/teacher-import.png


+ 9 - 0
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.less

@@ -191,6 +191,15 @@
         margin-bottom: 10px;
         text-align: center;
         font-size: 18px;
+
+        & > img {
+            width: 50%;
+        }
+    }
+
+    .page-footer {
+        text-align: center;
+        padding: 10px 0;
     }
 }
 

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

@@ -362,28 +362,33 @@
                 <div style="display: flex;">
                     <div style="width: 50%;">
                         <template v-if="!imgList.length">
-                            <p class="no-img">
-                                <Icon type="ios-alert" color="#FA6400" />
-                                {{ $t("studentWeb.exam.message.noQamode") }}
-                            </p>
+                            <div class="no-img">
+                                <img src="@/assets/image/none.png" >
+                                <p>
+                                    <Icon type="ios-alert" color="#FA6400" />
+                                    {{ $t("studentWeb.exam.message.noQamode") }}
+                                </p>
+                            </div>
                         </template>
-                        <template v-else-if="imgList.length === 1">
+                        <!-- <template v-else-if="imgList.length === 1">
                             <div class="left-img" @click="$hevueImgPreview(imgList[0])">
                                 <img :src="imgList[0]" alt="">
                             </div>
-                        </template>
-                        <template v-else-if="imgList.length > 1">
-                            <Carousel v-model="CarouselIndex" loop>
+                        </template> -->
+                        <template v-else-if="imgList.length">
+                            <Carousel v-model="CarouselIndex">
                                 <CarouselItem v-for="(img, indexs) in imgList" :key="indexs">
                                     <!-- 不是综合题 -->
                                     <div class="left-img" @click="$hevueImgPreview(img)">
-                                        <!-- <div class="que-item"> -->
-                                            <img :src="img" alt="">
-                                        <!-- </div> -->
-                                        <!-- <p v-if="!paperInfo.attachments" style="margin-bottom: 10px;">当前题目没有图片</p> -->
+                                        <img :src="img" alt="">
                                     </div>
                                 </CarouselItem>
                             </Carousel>
+                            <p class="page-footer">
+                                {{ $t('answerSheet.tip2') }} {{ CarouselIndex + 1 }} {{ $t('answerSheet.tip21') }}
+                                /
+                                {{ $t('answerSheet.tip9') }} {{ imgList.length }} {{ $t('answerSheet.tip21') }}
+                            </p>
                         </template>
                     </div>
                     <div style="width: 50%; margin-left: 20px; height: 500px;">

+ 4 - 4
TEAMModelOS/ClientApp/src/locale/lang/en-US/cusMgt.js

@@ -15,7 +15,7 @@ export default {
     noCusDesc: 'No course description yet',
     cusPd: "School System",
     pdHolder: 'Please choose school system',
-    cusSubject: "School System",
+    cusSubject: "Subject",
     sjHolder: 'Please choose subject',
     cusTeachers: 'Instructor',
     teacherHolder: 'Please choose instructor',
@@ -157,7 +157,7 @@ export default {
     fvtErr: 'Failed to collect',
     unfvtOk: 'Removed from collection',
     unfvtErr: 'Failed to remove',
-    recordTips: '溫馨提示:個人課程課堂記錄只保留最近30條記錄,超過30條會自動刪除最早的記錄。',
+    recordTips: 'Note: Only the last 30 records will be kept for personal courses. The earliest records will be deleted automatically if exceed 30.',
 
     //ManageClass.vue
     stuMgt: 'Student Management',
@@ -311,7 +311,7 @@ export default {
     startLabel: 'Start',
     endLabel: 'End',
     typeLabel: 'Type',
-    lessonTime: 'Class time',
+    lessonTime: 'Class Time',
     restTime: 'Break / Other Time',
     nameTips: 'Please enter the node name',
     typeTips: 'Please set the node type',
@@ -368,7 +368,7 @@ export default {
 
     //ClassRecord.vue
     rcd: {
-        ctime: 'Class time:',
+        ctime: 'Class Time:',
         rtn: 'Click to go back',
         rcdLabel: 'Interaction Records',
         enote: 'E-Note',

+ 8 - 8
TEAMModelOS/ClientApp/src/locale/lang/en-US/home.js

@@ -76,13 +76,13 @@ export default{
     weekCount: "This week's lesson",
     dayCount: "Today's lesson",
     cusTableErr: 'Failed to get the class schedule',
-    count1:'學校課程',
-    count2:'任教班級',
-    count3:'個人課程',
-    count4:'個人名單',
-    count5:'課綱數量',
-    count6:'試卷數量',
-    count7:'題目數量',
-    count8:'資源數量',
+    count1: 'School Course',
+    count2: 'Classes Taught',
+    count3: 'Personal Course',
+    count4: 'Personal List',
+    count5: 'Syllabus No.',
+    count6: 'Exam File No.',
+    count7: 'Question No.',
+    count8: 'Resource No.',    
     spaceInfo:'空間使用情況'
 }

+ 5 - 2
TEAMModelOS/ClientApp/src/locale/lang/en-US/learnActivity.js

@@ -305,7 +305,10 @@ export default {
         failedNum: 'Non-Passer',
         complyCount: 'Passer Number',
         simpleErr: 'Failed to search statistical data',
-        dataErr: 'The assessment statistical data error!'
+        dataErr: 'The assessment statistical data error!',
+        quCorrectRate:'試題正確率',
+        cc:'及格人數',
+        rac:'比率 (人數):'
     },
 
     mark: {
@@ -452,7 +455,7 @@ export default {
         rect: 'Quadrilateral',
         seal: 'Stamp',
         clear: 'Clear Annotation',
-        eraser: '橡皮擦',
+        eraser: 'Eraser',
         marked: '已閱',
         unmark: '未閱',
         fullScore: '滿分',

+ 56 - 56
TEAMModelOS/ClientApp/src/locale/lang/en-US/lessonRecord.js

@@ -1,26 +1,26 @@
 export default {
-	all:'不限',
-	cate:'類別',
-	range:'範圍',
-	rangeTip:'選擇起止時間',
-	more:'更多',
-	close:'收起',
-	edit:'編輯記錄',
-	editTitle:'編輯課例',
-	addTitle:'新增課例',
-	week:'本周',
-	month:'本月',
-	semester:'本學期',
-	custom:'自定義範圍',
-	lessonInfo:'課程信息',
-	form:{
-		name:'課例名稱',
-		place1:'請輸入課例的名稱...',
-		teacher:'授課教師',
-		place2:'請輸入授課教師姓名...'
+	all: 'All',
+	cate: 'Category',
+	range: 'Time',
+	rangeTip: 'Select Time',
+	more: 'More',
+	close: 'Close',
+	edit: 'Edit Record',
+	editTitle: 'Edit Lesson',
+	addTitle: 'Add Lesson',
+	week: 'Week',
+	month: 'Month',
+	semester: 'Semester',
+	custom: 'Customized Time',
+	lessonInfo: 'Lesson Information',
+	form: {
+		name: 'Lesson Name',
+		place1: 'Please enter lesson name...',
+		teacher: 'Teacher',
+		place2: 'Please enter teacher name...'
 	},
 	count1: 'Total Lesson',
-	count2: 'Teacher No.',
+	count2: 'Participating Teachers',
 	count3: 'Accumulated Task',
 	count4: 'Accumulated Work',
 	count5: 'Accumulated Test Question',
@@ -66,41 +66,41 @@ export default {
 	tagTip3: 'There can be no empty categories',
 	saveSuc: 'Save successfully',
 	echarts:{
-		count1:'課例總數',
-		count2:'今日課例',
-		count3:'本周課例',
-		count4:'本月課例',
-		count5:'本學期課例',
-		count6:'教師數',
-		count7:'累計任務數',
-		count8:'累計作品數',
-		count9:'累計測驗題數',
-		count10:'累計互動總數',
-		title1:'智慧課堂統計',
-		pie1:'教研組',
-		pie2:'課例類別',
-		pie3:'年級',
-		pie4:'科目',
-		title2:'課例趨勢圖',
-		title3:'活動類型分析',
-		title4:'常用科技手段統計',
-		noData:'暫無數據',
-		weekUtil:'第',
-		week:'',
-		count:'課例數量',
-		ac1:'線上評測(校)',
-		ac2:'課中評測(校)',
-		ac3:'閱卷評測(校)',
-		ac4:'線上評測(個)',
-		ac5:'課中評測(個)',
-		ac6:'閱卷評測(個)',
-		ac7:'作業活動',
-		ac8:'自主學習',
-		online:'線上',
-		offline:'線下',
-		mid:'課中',
-		noGroup:'未分組',
-		noType:'未分類',
-		unit:'單位:堂'
+		count1: 'Total Lesson No.',
+		count2: 'Today',
+		count3: 'Week',
+		count4: 'Month',
+		count5: 'Semester',
+		count6: 'Teacher No.',
+		count7: 'Accumulated Task',
+		count8: 'Accumulated Work',
+		count9: 'Accumulated Test Question',
+		count10: 'Accumulated Interaction',
+		title1: 'Smarter Lesson Statistics',
+		pie1: 'Pedagogical Research Team',
+		pie2: 'Lesson Category',
+		pie3: 'Grade',
+		pie4: 'Subject',
+		title2: 'Lesson Trend Chart',
+		title3: 'Activity Type Analysis',
+		title4: 'Commonly used technology statistics',
+		noData: 'No data yet',
+		weekUtil: 'Week',
+		week: '',
+		count: 'Lesson No.',
+		ac1: 'Online Assessment (School)',
+		ac2: 'Smarter Classroom Assessment (School)',
+		ac3: 'OMR & Writing Assessment (School)',
+		ac4: 'Online Assessment (Personal)',
+		ac5: 'Smarter Classroom Assessment (Personal)',
+		ac6: 'OMR & Writing Assessment (Personal)',
+		ac7: 'Homework',
+		ac8: 'Self-directed Learning',
+		online: 'Online',
+		offline: 'Offline',
+		mid: 'In-class',
+		noGroup: 'Not grouped',
+		noType: 'Not categorized',
+		unit: 'Unit: Lesson'
 	}
 }

+ 6 - 6
TEAMModelOS/ClientApp/src/locale/lang/en-US/notice.js

@@ -5,10 +5,10 @@ export default {
 	type3: 'Removal Notification',
 	type4: 'Syllabus Notification',
 	type5: 'Administrator Transfer Notification',
-	type6: 'Marking Test Assignment Notification',
+	type6: 'Marking Task Assignment Notification',
 	type7: 'Scan Code Join Notification',
 	type8: 'Homework Submission Notification',
-	type9:'課例過期通知',
+	type9: 'Course Record Expiry Notification',
 	tip1: 'applies to join',
 	tip2: 'has invited you to join',
 	tip3: 'has granted your request to join',
@@ -25,8 +25,8 @@ export default {
 	tip14: 'scanned the code to join the list',
 	tip15: 'completed the homework submission of',
 	tip16: '',
-	tip17:'您於',
-	tip18:'教學的課堂',
-	tip19:',由於超過課例最大保存數量,將於',
-	tip20:'失效'
+	tip17: 'The lesson you taught on',
+	tip18: ',',
+	tip19: ', will expire on',
+	tip20: 'because it exceeds the maximum number of saved lessons record.'
 }

+ 6 - 6
TEAMModelOS/ClientApp/src/locale/lang/en-US/researchCenter.js

@@ -1,14 +1,14 @@
 export default{
 	dashboard: {
-		title: '智慧校園大數據駕駛艙',
-		block1: '教學教研',
-		block2: '教室物聯',
-		block3: '德育評價',
-		block4: '學情分析',
+		title: 'Smart Campus Big Data',
+		block1: 'Teaching & Research',
+		block2: 'Classroom IoT',
+		block3: 'Moral Education Evaluation',
+		block4: 'Learning Status Analysis',
 		comingSoon: 'Coming Soon',
 		loading: 'Loading',
 		quit: 'Exit',
-		title2: '教學大數據',
+		title2: 'Teaching Big Data',
 	},
     // 播放视频
     video: {

+ 8 - 8
TEAMModelOS/ClientApp/src/locale/lang/en-US/schoolBaseInfo.js

@@ -24,8 +24,8 @@ export default {
   periodSettingLabel: 'School System',
   order: 'Sort by creation time',
   semesterSetting: 'Semester (Quarter) Setting',
-  gradeSetting: '年級名稱順序設置',
-  gradeTips: '年級順序設置,例如:\n一年級\n二年級\n三年級',
+  gradeSetting: 'Grade Level Settings',
+  gradeTips: 'Grade level order setting, for example: \n Grade 1 \n Grade 2 \n Grade 3',
   subjectSetting: 'Subject Settings',
   semesterNum: 'Semester Number:',
   gradeNum: 'Grade Number:',
@@ -65,7 +65,7 @@ export default {
   setCampus: 'Please set your campus',
   smHolder: 'Set semester...',
   subjectHolder: 'Set subject...',
-  profsHolder: 'Set subject...',
+  profsHolder: 'Set professional...',
   noSubject: 'No subject yet',
   anaLabel: 'Learning Status Settings',
   exTypeLabel: 'Test Type:',
@@ -107,7 +107,7 @@ export default {
   semStartTips:'Please set whether it is the enrollment semester',
   gradeNameTips:'Please set the grade name',
   examNameTips:'Please set the exam type',
-  profNameTips:'Please set the professional subject name',
+  profNameTips:'Please set the professional name',
   anaNameTips:'Please complete the learning status analysis setting',
   campNameTips:'Please enter the school district name',
   subjectNameTips:'Please enter the subject name',
@@ -115,7 +115,7 @@ export default {
   delTimeContent:'Are you sure you want to delete the current schedule?',
   setStartTitps:'Set as enrollment semester',
   periodCountTips:'The number of school systems is allocated based on school purchases, and schools can only edit school system names, not add or delete school system.',
-  cgCountTips:'學院數量根據學校購買進行分配,學校只能進行編輯學院名稱,不能新增和刪除學院。',
+  cgCountTips:'The number of colleges is allocated based on school purchases, and schools can only edit college names',  
   addSubjectType:'添加方式',
   addSubjectType1:'新建學科',
   addSubjectType2:'選擇已有學科',
@@ -143,7 +143,7 @@ export default {
   codeSearchHolder: 'Search',
   classroomCodeHolder: 'eg: 1',
   classroomNameHolder: 'eg: 101',
-  classNameHolder:'eg:202201',
+  classNameHolder: 'eg: 2022001',
   headmasterHolder: 'Can search by name...',
   hiTeachHolder: 'Please select the available serial number from the list on the right...',
   noHiTeachTips: 'No available serial number',
@@ -247,8 +247,8 @@ export default {
   graduated:'Graduated',
   classLabel:'Class ID',
   profession:'Professional Subject',
-  professionLabel: '專業名稱/類型名稱',
-  professionLabel1: '班級專業名稱/班級類型名稱',
+  professionLabel: 'Professional Name / Type Name',
+  professionLabel1: 'Class Professional Name / Class Type Name',
   noProfession:'No professional subject set yet',
   all:'All',
   noSet:'Not set',

+ 2 - 2
TEAMModelOS/ClientApp/src/locale/lang/en-US/stuAccount.js

@@ -15,8 +15,8 @@ export default {
 	// Index.vue
 	menuAuth: 'Authorization Management',
 	importStu: 'Import List',
-	exportStu: '導出名單',
-	stuNameList:'學生名單',
+	exportStu: 'Export List',
+	stuNameList: 'Student List',
 	addStu: 'Add Student',
 	editInfo: 'Edit Information',
 	delStu: 'Delete Student',

+ 15 - 15
TEAMModelOS/ClientApp/src/locale/lang/en-US/studentWeb.js

@@ -300,13 +300,13 @@ export default {
         timeLong: "Duration:",
         period: 'Activity Duration:',
         postTime: 'Start Time:',
-        classTime: 'Class time',
+        classTime: 'Class Time',
         unFinished: 'Unfinished',
         Fineshed: 'Completed',
         Closed: 'Ended',
         duration: "Duration",
         subjectName: "Course Name:",
-        examMode: "Mode",
+        examMode: "Method",
         examStatus: "Status",
     },
     billboard: {
@@ -388,8 +388,8 @@ export default {
         contentPage: 'Homework Content',
         classComment: "Classmate Mutual Evaluation",
         scorePage: 'Score and Comment',
-        score: 'From Teacher',
-        classmatesComments: 'From Classmates',
+        score: 'From Teacher:',
+        classmatesComments: 'From Classmates:',
         comment: 'Comment: ',
         supcomment: 'Additional Comments: ',
         delTitle: "The homework has been deleted, do you want to delete this record?",
@@ -577,7 +577,7 @@ export default {
             score: 'Score',
             keyPointPerformance: 'Key concept Performance Distribution',
             me: 'Personal',
-            allClass: '所有班級',
+            allClass: 'All Class',
             participantClass: 'Whole Class',
             participantAverage: 'Whole School',
             recognizePerformance: 'Cognitive Level Radar Chart'
@@ -637,11 +637,11 @@ export default {
             evMode1: 'Online Assessment',
             evMode2: 'Smarter Classroom Assessment',
             evMode3: 'OMR & Writing Assessment',
-            evMode21: '紙本測驗',
-            evMode22: '書面問答',
+            evMode21: 'SelfPace Test (Instant Paper)',
+            evMode22: 'SelfPace Test (IES)',
         },
         missExam: "Absent",
-        nojoin: "未參與",
+        nojoin: "Absent",
         noScoreType: "Not graded",
         finishOk: "Graded",
         practiceType: {
@@ -655,7 +655,7 @@ export default {
             noWrong: "This assessment does not have incorrectly answered questions!",
             noStar: "This assessment does not have starred questions!",
             nojoin: "You did not join this activity",
-            noQamode: "此次紙本測驗沒有圖片示例",
+            noQamode: "There is no attached picture for this paper test",
         }
     },
     queNaire: {
@@ -689,7 +689,7 @@ export default {
         link: 'Share Link',
         noContent: "No interaction record",
         yourFile: "Work you uploaded:",
-        noFile: "Not uploaded works",
+        noFile: "You did not upload a work",
         noanswer: "Not answered",
         dataCount: {
             attendTrue: "Present",
@@ -712,9 +712,9 @@ export default {
         noCourse: "No course yet",
         baseInfo: 'Basic Information',
         description: 'Course Overview',
-        tableMode: "課表模式",
+        tableMode: "Schedule Mode",
         nameList: "Classmates Name List",
-        scoreList: "成績清單",
+        scoreList: "Grade List",
         classmates: 'Classmates list',
         classmates1: 'TEAM Model List',
         classRecord: "Lesson Records",
@@ -722,7 +722,7 @@ export default {
         hwRecord: "Homework List",
         voteRecord: "Poll Activity",
         surRecord: "Survey Activity",
-        activityList: "活動清單",
+        activityList: "Activity List",
         classID: 'Course Code',
         classTime: 'Class Time',
         classroom: 'Classroom',
@@ -733,8 +733,8 @@ export default {
         seatNo: 'Seat No.',
         stuNum: 'Student ID',
         tmdNum: "TEAM Model Account",
-        stuAccount: "學生帳號",
-        accountType: "帳號類型",
+        stuAccount: "Student Account",
+        accountType: "Account Type",
         name: 'Name',
         group: 'Group',
         no1: "Group",

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/en-US/survey.js

@@ -104,6 +104,6 @@ export default {
 	noMatchData:'No matching data',
 	getFileFailTip:'Failed to read data',
 	backToRecord:'Back to Activity Record',
-	noFoundAc:'Activity not found, please select again!'
+	noFoundAc:'Specified ID activity not found, please select again!'
 	
 }

+ 4 - 4
TEAMModelOS/ClientApp/src/locale/lang/en-US/system.js

@@ -1,5 +1,5 @@
 export default {
-	wechatTip:'關註醍摩豆微信公眾號咨詢',
+    wechatTip:'關注醍摩豆微信公眾號咨詢',
     preview:'Preview',
     title:'TEAM Model Cloud',
     hostTitle:{
@@ -10,8 +10,8 @@ export default {
     development:'Features are under development, stay tuned!',
 	goHome:'Home Page',
     changePlat:'Switch Platform',
-	noSupport:'Not provided',
-	help:'Help Doc',
+    noSupport:'Not provided yet',
+    help:'Help Document',
     menu:{
         school:'School',
         private:'Personal',
@@ -71,7 +71,7 @@ export default {
         research:'Lesson',
         researchBoard:'Data Board',
         cusVideos:'Lesson Data',
-        cusVideoMgt:'Lesson Management',
+        cusVideoMgt:'Records',
         lockTips:'Lock Menu Bar',
         unlockTips:'Unlock Menu Bar',
         platform:'Resource Platform',

+ 80 - 53
TEAMModelOS/ClientApp/src/locale/lang/en-US/teachermgmt.js

@@ -64,64 +64,65 @@ export default {
         info20: 'This user has already been invited!',
         info21: 'The invited user has already joined the school!',
         noIdCol: 'There is no id column in the imported form, please check the form data! ',
-        spaceTips1:'請設置每人分配的空間大小',
-        spaceTips2:'請選擇需要分配空間的教師職稱',
-        spaceTips3:'請勾選需要分配空間的教師',
-        saveOk:'保存成功'
+        spaceTips1: 'Please set the size of space allocated per person',
+        spaceTips2: 'Please select the teacher title for which space is to be allocated',
+        spaceTips3: 'Please select the teachers who need to allocate space',
+        saveOk: 'Save successfully'
     },
     job: {
         'jobTitle': 'Add Title',
         'teacher':'Teacher'
     },
     authority:{
-        'classroom': '教室管理',
-        'classroom-read': '檢視教室資料',
-        'classroom-upd': '變更教室設定',
-        'schoolSetting': '學校基礎數據管理',
-        'schoolSetting-read': '檢視學校基礎設定',
-        'schoolSetting-upd': '變更學校基礎設定',
-        'student': '學生賬號管理',
-        'student-read': '檢視學生賬號',
-        'student-upd': '變更學生賬號',
-        'teacher': '教師賬號管理',
-        'teacher-read': '檢視教師賬號',
-        'teacher-upd': '變更教師賬號',
-        'course': '課程設置管理',
-        'course-read': '查看課程設置信息',
-        'course-upd': '修改課程設置信息',
-        'newCoursePlan': '排課管理',
-        'coursePlan-read': '查看排課信息',
-        'coursePlan-upd': '修改排課信息',
-        'serviceDriveAuth': '授權管理',
-        'auth-read': '查看授權管理信息',
-        'auth-upd': '修改授權管理信息',
-        'syllabus': '學校課綱管理',
-        'syllabus-read': '查看學校課綱信息',
-        'syllabus-upd': '修改學校課綱信息',
-        'schoolContent': '學校內容管理',
-        'content-read': '查看學校內容信息',
-        'content-upd': '修改學校內容信息',
-        'schoolBank': '學校題庫管理',
-        'exercise-read': '查看學校題庫信息',
-        'exercise-upd': '修改學校題庫信息',
-        'knowledge': '知識點庫管理',
-        'knowledge-read': '查看知識點庫信息',
-        'knowledge-upd': '修改知識點庫信息',
-        'analysis': '學情分析',
-        'analysis-read': '查看學校學情分析',
-        'scboard': '統計分析',
-        'scboard-read': '查看統計分析',
-        'schoolAc': '學校活動',
-        'schoolAc-read': '查看學校活動',
-        'schoolAc-upd': '發布學校活動',
-        'train': '研修中心',
-        'train-read': '查看研修中心數據',
-        'train-upd': '管理研修中心數據',
-        'dashboard':'數據看板',
-        'dashboard-read':'數據看板查看權限',
-        'research':'課例中心模塊',
-        'research-read':'課例中心查看權限',
-        'research-upd':'課例中心管理(修改)權限'
+        'classroom': 'Classroom Settings',
+        'system': 'School Basic Data Management',
+        'studentAccount': 'Student Account Management',
+        'teachermgmt': 'Teacher Account Management',
+        'classroom-read': 'View Classroom Information',
+        'classroom-upd': 'Change Classroom Settings',
+        'schoolSetting-read': 'View School Basic Settings',
+        'schoolSetting-upd': 'Change School Basic Settings',
+        'student-read': 'View Student Account',
+        'student-upd': 'Change Student Account',
+        'teacher-checkTeacher': 'Check if the teacher can view',
+        'teacher-read': 'View Teacher Account',
+        'teacher-upd': 'Change Teacher Account',
+        'manageCourse': ' Course Setting Management',
+        'course-read': 'View Course Setting Information',
+        'course-upd': 'Modify Course Setting Information',
+        'newCoursePlan': 'Course Scheduling Management',
+        'coursePlan-read': 'View Course Scheduling Information',
+        'coursePlan-upd': 'Modify Course Scheduling Information',
+        'serviceDriveAuth': 'Authorization Management',
+        'auth-read': 'View Authorization Management Information',
+        'auth-upd': 'Modify Authorization Management Information',
+        'syllabus': 'School Syllabus Management',
+        'syllabus-read': 'View School Syllabus Information',
+        'syllabus-upd': 'Modify School Syllabus Information',
+        'schoolContent': 'School Content Management',
+        'content-read': 'View School Content Information',
+        'content-upd': 'Modify School Content Information',
+        'schoolBank': 'School Question Bank Management ',
+        'exercise-read': 'View School Question Bank Information',
+        'exercise-upd': 'Modify School Question Bank Information',
+        'knowledge': 'Key Concept Bank Management ',
+        'knowledge-read': 'View Key Concept Bank Information',
+        'knowledge-upd': 'Modify knowledge Key Concept Bank Information',
+        'analysis': 'Learning Status Analysis',
+        'analysis-read': 'View School Learning Status Analysis',
+        'scboard': 'Statistical Data',
+        'scboard-read': 'View Statistical Data',
+        'schoolAc': 'School Activity',
+        'schoolAc-read': 'View School Activity',
+        'schoolAc-upd': 'Start School Activity',
+        'trainAll': 'Seminar Center',
+        'train-read': 'View Seminar Center Data',
+        'train-upd': 'Manage Seminar Center Data',
+        'dashboard': 'Data Board',
+        'dashboard-read': 'View Data Board',
+        'research': 'Lesson Management',
+        'research-read': 'View Lesson Management',
+        'research-upd': 'Modify Lesson Management'
     },
     modal:{
         text1: 'The authorization of this account has been changed, do you want to give this account a more appropriate title?',
@@ -262,5 +263,31 @@ export default {
     confirm: 'Confirm',
     cancel: 'Cancel',
     filter: '篩選',
-    reset: '重置'
+    reset: '重置',
+    teacherStatus1:'未加入',
+    teacherStatus2:'邀請中',
+    teacherStatus3:'已加入',
+    importTips1:'導入教師範本:',
+    importTips2:'欄位說明:',
+    importTips3:'1. name: 教師姓名,必填;',
+    importTips4:'2. phone: 教師手機號,選填;',
+    importTips5:'3. email: 教師郵箱,選填;',
+    importTips6:'4. tmdid: 教師醍摩豆ID,選填;',
+    importTips7:'5. note: 教師備註信息,選填;',
+    importTips8:'溫馨提示:如果導入教師醍摩豆ID,或者導入的手機或郵箱已註冊醍摩豆ID,系統會自動邀請老師加入學校。',
+    importTips9:'點擊或者拖拽文件導入',
+    impText1:'導入總人數:',
+    impText2:'僅導入姓名:',
+    impText3:'系統將自動邀請:',
+    impText4:'重新導入',
+    impText5:'確認導入',
+    impText6:'導入成功',
+    impText7:'繼續導入',
+    impTd1:'姓名',
+    impTd2:'手機',
+    impTd3:'郵箱',
+    impTd4:'醍摩豆ID',
+    impTd5:'備註',
+    joinTips1:'溫馨提示:學校存在僅導入名字的老師,如果對應當前老師賬號,可以進行綁定修改教師加入學校的狀態。如果當前老師賬號不為學校導入對應的老師可以不用進行綁定。',
+    joinTips2:'綁定學校尚未加入的老師:'
 }

+ 2 - 2
TEAMModelOS/ClientApp/src/locale/lang/en-US/train.js

@@ -119,7 +119,7 @@ export default {
         signQrCode: '簽到碼',
         isStart: '是否開始簽到:',
         autoFresh: '定時刷新(10s):',
-        fullScreen: '全顯示',
+        fullScreen: '全螢幕顯示',
         signCount: '簽到統計',
         signRate: '簽到率',
         hwCount: '作業統計',
@@ -140,7 +140,7 @@ export default {
         hwFile: '作業附件:',
         viewTips: '文件類型不支持線上預覽,請下載文件',
         downloadFile: '下載文件',
-        answerTitle: '作答詳情',
+        answerTitle: 'Answering Details',
         name: '姓名',
         signTime: '簽到時間',
         status: '狀態',

+ 5 - 2
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/learnActivity.js

@@ -300,12 +300,15 @@ export default {
         total: '总分',
         avgScore1: '总均分',
         totalLabel: '总量',
-        scoreMat: '分数段统计',
+        scoreMat: '成绩分布图',
         complyNum: '及格',
         failedNum: '不及格',
         complyCount:'及格人数统计',
         simpleErr:'查询统计数据失败',
-        dataErr:'评测统计数据出错啦'
+        dataErr:'评测统计数据出错啦',
+        quCorrectRate:'试题正确率',
+        cc:'及格人数',
+        rac:'比率 (人数):'
     },
 
     mark: {

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/lessonRecord.js

@@ -20,7 +20,7 @@ export default {
 		place2:'请输入授课教师姓名...'
 	},
 	count1:'课堂记录总数',
-	count2:'教师数',
+	count2:'参与教师数',
 	count3:'累计任务数',
 	count4:'累计作品数',
 	count5:'累计测验总题数',

+ 27 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/teachermgmt.js

@@ -262,5 +262,31 @@ export default {
     confirm: '确认',
     cancel: '取消',
     filter: '筛选',
-    reset: '重置'
+    reset: '重置',
+    teacherStatus1:'未加入',
+    teacherStatus2:'邀请中',
+    teacherStatus3:'已加入',
+    importTips1:'导入教师范本:',
+    importTips2:'栏位说明:',
+    importTips3:'1. name: 教师姓名,必填;',
+    importTips4:'2. phone: 教师手机号,选填;',
+    importTips5:'3. email: 教师邮箱,选填;',
+    importTips6:'4. tmdid: 教师醍摩豆ID,选填;',
+    importTips7:'5. note: 教师备注信息,选填;',
+    importTips8:'温馨提示:如果导入教师醍摩豆ID,或者导入的手机或邮箱已注册醍摩豆ID,系统会自动邀请老师加入学校。',
+    importTips9:'点击或者拖拽文件导入',
+    impText1:'导入总人数:',
+    impText2:'仅导入姓名:',
+    impText3:'系统将自动邀请:',
+    impText4:'重新导入',
+    impText5:'确认导入',
+    impText6:'导入成功',
+    impText7:'继续导入',
+    impTd1:'姓名',
+    impTd2:'手机',
+    impTd3:'邮箱',
+    impTd4:'醍摩豆ID',
+    impTd5:'备注',
+    joinTips1:'温馨提示:学校存在仅导入名字的老师,如果对应当前老师账号,可以进行绑定修改教师加入学校的状态。如果当前老师账号不为学校导入对应的老师可以不用进行绑定。',
+    joinTips2:'绑定学校尚未加入的老师:'
 }

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/cusMgt.js

@@ -278,7 +278,7 @@ export default {
     nameList: '名單',
     remvStu: '移除學生',
     editStu: '設置IRS',
-    goBack: '返回上',
+    goBack: '返回上',
     delListTitle: '刪除選課班',
     notSet: '未設置',
     irsTips1: '1、按照名單順序快速設置IRS號碼;',

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/evaluation.js

@@ -351,7 +351,7 @@ export default {
 		shareResource: '個人分享',
 		shareItem: '分享個人試題',
 		sharePaper: '分享個人試卷',
-		back: '返回上',
+		back: '返回上',
 		checkItem: '已選試題',
 		checkPaper: '已選試卷',
 		shareTo: '分享到',

+ 7 - 4
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/learnActivity.js

@@ -265,7 +265,7 @@ export default {
         tipsLabel: '溫馨提示:',
         crtTips1: '1. 主觀題是根據學生得分達到題目配分的80%則判斷為正確;',
         crtTips2: '2. 更多詳細數據分析,請前往學情分析查看。',
-        crtErr: '數據載失敗',
+        crtErr: '數據載失敗',
         noSeeRpt: '學生尚未作答,無法查看學生個人報告',
         crtRateTitle: '正確率統計',
         crtLabel: '正確',
@@ -300,12 +300,15 @@ export default {
         total: '總分',
         avgScore1: '總均分',
         totalLabel: '總量',
-        scoreMat: '分數段統計',
+        scoreMat: '成績分布圖',
         complyNum: '及格',
         failedNum: '不及格',
         complyCount: '及格人數統計',
         simpleErr: '查詢統計數據失敗',
-        dataErr:'評量統計數據出錯啦'
+        dataErr:'評量統計數據出錯啦',
+        quCorrectRate:'試題正確率',
+        cc:'及格人數',
+        rac:'比率 (人數):'
     },
 
     mark: {
@@ -431,7 +434,7 @@ export default {
         delTask: '刪除閱卷任務',
         delTaskTips: '刪除閱卷任務後,當前評量的所有閱卷老師的閱卷任務以及閱卷數據都將被刪除,確認刪除閱卷任務嗎? ',
         distribution: '題目配分:',
-        loadAll: '已載所有數據',
+        loadAll: '已載所有數據',
 
         //ByqU.vue & ByStu.vue
         quit: '退出閱卷',

+ 3 - 3
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/lessonRecord.js

@@ -12,7 +12,7 @@ export default {
 	month:'本月',
 	semester:'本學期',
 	custom:'自定義範圍',
-	lessonInfo:'課程信息',
+	lessonInfo:'課堂資訊',
 	form:{
 		name:'課例名稱',
 		place1:'請輸入課例的名稱...',
@@ -20,7 +20,7 @@ export default {
 		place2:'請輸入授課教師姓名...'
 	},
 	count1:'課堂記錄總數',
-	count2:'教師數',
+	count2:'參與教師數',
 	count3:'累計任務數',
 	count4:'累計作品數',
 	count5:'累計測驗總題數',
@@ -86,7 +86,7 @@ export default {
 		title4:'常用科技手段統計',
 		noData:'暫無數據',
 		weekUtil:'第',
-		week:'',
+		week:'',
 		count:'課例數量',
 		ac1:'線上評測(校)',
 		ac2:'課中評測(校)',

+ 2 - 2
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/researchCenter.js

@@ -1,12 +1,12 @@
 export default {
 	dashboard: {
 		title: '智慧校園大數據',
-		block1: '教學數據',
+		block1: '教學教研',
 		block2: '教室物聯',
 		block3: '德育評價',
 		block4: '學情分析',
 		comingSoon: '即將上線',
-		loading: '載中',
+		loading: '載中',
 		quit: '退出',
 		title2: '教學大數據',
 	},

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/schoolBaseInfo.js

@@ -24,7 +24,7 @@ export default {
   periodSettingLabel: '學制',
   order: '依建立時間排序',
   semesterSetting: '學期(季)設定',
-  gradeSetting: '年級名稱順序設置',
+  gradeSetting: '年級設定',
   gradeTips: '年級順序設置,例如:\n一年級\n二年級\n三年級',
   subjectSetting: '學科設定',
   semesterNum: '學期數:',

+ 1 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/system.js

@@ -1,5 +1,5 @@
 export default {
-	wechatTip:'關註醍摩豆微信公眾號咨詢',
+    wechatTip:'關注醍摩豆微信公眾號咨詢',
     preview: '預覽',
     title: '醍摩豆雲平台',
     hostTitle: {

+ 49 - 23
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/teachermgmt.js

@@ -80,37 +80,37 @@ export default {
         'schoolSetting': '學校基礎數據管理',
         'schoolSetting-read': '檢視學校基礎設定',
         'schoolSetting-upd': '變更學校基礎設定',
-        'student': '學生號管理',
-        'student-read': '檢視學生號',
-        'student-upd': '變更學生號',
-        'teacher': '教師號管理',
-        'teacher-read': '檢視教師號',
-        'teacher-upd': '變更教師號',
+        'student': '學生號管理',
+        'student-read': '檢視學生號',
+        'student-upd': '變更學生號',
+        'teacher': '教師號管理',
+        'teacher-read': '檢視教師號',
+        'teacher-upd': '變更教師號',
         'course': '課程設置管理',
-        'course-read': '查看課程設置信息',
-        'course-upd': '修改課程設置信息',
+        'course-read': '查看課程設置資訊',
+        'course-upd': '修改課程設置資訊',
         'newCoursePlan': '排課管理',
-        'coursePlan-read': '查看排課信息',
-        'coursePlan-upd': '修改排課信息',
+        'coursePlan-read': '查看排課資訊',
+        'coursePlan-upd': '修改排課資訊',
         'serviceDriveAuth': '授權管理',
-        'auth-read': '查看授權管理信息',
-        'auth-upd': '修改授權管理信息',
+        'auth-read': '查看授權管理資訊',
+        'auth-upd': '修改授權管理資訊',
         'syllabus': '學校課綱管理',
-        'syllabus-read': '查看學校課綱信息',
-        'syllabus-upd': '修改學校課綱信息',
+        'syllabus-read': '查看學校課綱資訊',
+        'syllabus-upd': '修改學校課綱資訊',
         'schoolContent': '學校內容管理',
-        'content-read': '查看學校內容信息',
-        'content-upd': '修改學校內容信息',
+        'content-read': '查看學校內容資訊',
+        'content-upd': '修改學校內容資訊',
         'schoolBank': '學校題庫管理',
-        'exercise-read': '查看學校題庫信息',
-        'exercise-upd': '修改學校題庫信息',
+        'exercise-read': '查看學校題庫資訊',
+        'exercise-upd': '修改學校題庫資訊',
         'knowledge': '知識點庫管理',
-        'knowledge-read': '查看知識點庫信息',
-        'knowledge-upd': '修改知識點庫信息',
+        'knowledge-read': '查看知識點庫資訊',
+        'knowledge-upd': '修改知識點庫資訊',
         'analysis': '學情分析',
         'analysis-read': '查看學校學情分析',
-        'scboard': '統計分析',
-        'scboard-read': '查看統計分析',
+        'scboard': '統計數據',
+        'scboard-read': '查看統計數據',
         'schoolAc': '學校活動',
         'schoolAc-read': '查看學校活動',
         'schoolAc-upd': '發布學校活動',
@@ -262,5 +262,31 @@ export default {
     confirm: '確認',
     cancel: '取消',
     filter: '篩選',
-    reset: '重置'
+    reset: '重置',
+    teacherStatus1:'未加入',
+    teacherStatus2:'邀請中',
+    teacherStatus3:'已加入',
+    importTips1:'導入教師範本:',
+    importTips2:'欄位說明:',
+    importTips3:'1. name: 教師姓名,必填;',
+    importTips4:'2. phone: 教師手機號,選填;',
+    importTips5:'3. email: 教師郵箱,選填;',
+    importTips6:'4. tmdid: 教師醍摩豆ID,選填;',
+    importTips7:'5. note: 教師備註信息,選填;',
+    importTips8:'溫馨提示:如果導入教師醍摩豆ID,或者導入的手機或郵箱已註冊醍摩豆ID,系統會自動邀請老師加入學校。',
+    importTips9:'點擊或者拖拽文件導入',
+    impText1:'導入總人數:',
+    impText2:'僅導入姓名:',
+    impText3:'系統將自動邀請:',
+    impText4:'重新導入',
+    impText5:'確認導入',
+    impText6:'導入成功',
+    impText7:'繼續導入',
+    impTd1:'姓名',
+    impTd2:'手機',
+    impTd3:'郵箱',
+    impTd4:'醍摩豆ID',
+    impTd5:'備註',
+    joinTips1:'溫馨提示:學校存在僅導入名字的老師,如果對應當前老師賬號,可以進行綁定修改教師加入學校的狀態。如果當前老師賬號不為學校導入對應的老師可以不用進行綁定。',
+    joinTips2:'綁定學校尚未加入的老師:'
 }

+ 19 - 8
TEAMModelOS/ClientApp/src/store/module/user.js

@@ -55,6 +55,15 @@ export default {
                 return []
             }
         },
+        getTeacherImport: state => {
+            if (state.teachers !== undefined) {
+                return state.teachers.filter(
+                    user => user.status == 'import'
+                )
+            } else {
+                return []
+            }
+        },
         getTeacherInvited: state => {
             if (state.teachers !== undefined) {
                 return state.teachers.filter(
@@ -271,9 +280,9 @@ export default {
         delTeacher(state, ids) {
             if (ids && ids.length) {
                 let teachers = state.teachers
-                let count = teachers.length - 1 
+                let count = teachers.length - 1
                 for (let i = count; i >= 0; i--) {
-                    if (ids.includes(teachers[i].id)) {
+                    if (ids.includes(teachers[i].id) || ids.includes(teachers[i].name)) {
                         teachers.splice(i, 1)
                     }
                 }
@@ -374,17 +383,19 @@ export default {
             return new Promise(
                 (resolve, reject) => {
                     let school_code = context.state.schoolCode
-                    let id = params.id
-                    let status = params.status
+                    let { id, status, importName } = params
                     if (typeof school_code !== 'undefined' && school_code !== undefined && typeof id !== 'undefined' && id !== undefined) {
-                        apiTools.schoolUser.updStatusToSchoolUser({
+                        let reqData = {
                             school_code: school_code,
                             id: id,
                             grant_type: status
-                        }).then(
+                        }
+                        if (importName) reqData.importName = importName
+                        apiTools.schoolUser.updStatusToSchoolUser(reqData).then(
                             res => {
                                 // 更新 state.schoolUserList
-                                context.dispatch('updSchoolUserInfo', { id: id, param: { status: status } });
+                                context.commit('setTeachers', undefined);
+                                context.dispatch('getSchoolTeacher');
                                 resolve({
                                     code: 1,
                                     message: 'Upd param successfully.'
@@ -425,7 +436,7 @@ export default {
                                 } else {
                                     // 追加新使用者至 state.schoolUserList
                                     // context.dispatch('addTeacherToSchoolUserList', { user_list: params, grant_type: 'invite' })
-                                    params.forEach(item=>{
+                                    params.forEach(item => {
                                         item.createTime = Math.round((new Date()).getTime() / 1000)
                                     })
                                     context.commit('addTeacher', params)

+ 1 - 0
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -102,6 +102,7 @@ export default {
         if (webEndTime && time_now > webEndTime) {
             console.log('长时间未操作,清空storage,重新登录')
             this.loginOut()
+            localStorage.setItem('loginOut','Home检查长时间未操作')
         }
         this.$store.dispatch('user/checkSchoolCode'); // 設定登入成功的學校簡碼
         this.$store.dispatch('user/checkUserProfile'); // 檢查使用者個人詳細資訊

+ 6 - 4
TEAMModelOS/ClientApp/src/view/auth/SpaceInfo.vue

@@ -122,10 +122,12 @@ export default {
                     formatData.push(content)
                     formatData.push(other)
                     let last = this.SCHOOL_SPACE * 1024 * 1024 * 1024 - res.teachSpace - res.total
-                    formatData.unshift({
-                        name: this.$t('auth.over'),
-                        value: last
-                    })
+                    if (last > 0) {
+                        formatData.unshift({
+                            name: this.$t('auth.over'),
+                            value: last
+                        })
+                    }
                     let percent = last * 100 / (this.SCHOOL_SPACE * 1024 * 1024 * 1024)
                     // percent = 0
                     console.log(percent)

+ 13 - 2
TEAMModelOS/ClientApp/src/view/homepage/HomePage.vue

@@ -18,8 +18,18 @@
 
                     <!-- 空间使用情况 -->
                     <div class="recent-box" style="height:389px;position:relative" v-if="checkHost()">
-                        <p class="chart-title">{{$t('home.spaceInfo')}}</p>
-                        <SpaceInfo style="margin-top:40px"></SpaceInfo>
+                        <p class="chart-title" v-show="spaceStatus == 1">{{$t('home.spaceInfo')}}</p>
+                        <Alert show-icon v-if="spaceStatus == 2" type="warning" style="margin-right:10px">
+                            <p style="font-size:12px">
+                                {{$t('auth.spaceWarning')}}
+                            </p>
+                        </Alert>
+                        <Alert show-icon v-else-if="spaceStatus == 3" type="error" style="margin-right:10px">
+                            <p style="font-size:12px">
+                                {{$t('auth.spaceErr')}}
+                            </p>
+                        </Alert>
+                        <SpaceInfo :style="{marginTop:spaceStatus == 1 ? '40px' : '15px'}" @on-space-warning="spaceStatus = 2" @on-space-error="spaceStatus = 3"></SpaceInfo>
                     </div>
 
                 </div>
@@ -273,6 +283,7 @@ export default {
     inject: ['reload'],
     data() {
         return {
+            spaceStatus: 1, //1:正常 2:空间不足10% 3:空间已满
             recentRcdList: [],
             sizeLoading: false,
             countData: {},

+ 6 - 4
TEAMModelOS/ClientApp/src/view/homepage/SpaceInfo.vue

@@ -122,10 +122,12 @@ export default {
                     formatData.push(content)
                     formatData.push(other)
                     let last = this.PRIVATE_SPACE * 1024 * 1024 * 1024 - res.teachSpace - res.total
-                    formatData.unshift({
-                        name: this.$t('auth.over'),
-                        value: last
-                    })
+                    if (last > 0) {
+                        formatData.unshift({
+                            name: this.$t('auth.over'),
+                            value: last
+                        })
+                    }
                     let percent = last * 100 / (this.PRIVATE_SPACE * 1024 * 1024 * 1024)
                     // percent = 0
                     console.log(percent)

+ 4 - 2
TEAMModelOS/ClientApp/src/view/learnactivity/ExamMgt.vue

@@ -72,7 +72,9 @@
                                 <Tooltip @on-popper-show="getExamTarget(item)">
                                     <Icon class="exam-target" size="20" type="ios-people" />
                                     <div slot="content" style="padding-left:15px;min-width:180px">
-                                        <p style="margin-left:-15px">发布对象:</p>
+                                        <p style="margin-left:-15px">
+                                            {{$t('learnActivity.createEv.evTarget')}}:
+                                        </p>
                                         <ul>
                                             <li v-for="item in examTargets" :key="item.id">
                                                 {{item.name}}
@@ -362,7 +364,7 @@ export default {
             })
         },
         selectBar(index) {
-			this.$EventBus.$emit('EvBarChange',index)
+            this.$EventBus.$emit('EvBarChange', index)
             this.checkScoreSave(this.handleSelectBar, index)
         },
         handleSelectBar(index) {

+ 128 - 71
TEAMModelOS/ClientApp/src/view/learnactivity/echarts/QuCount.vue

@@ -13,78 +13,12 @@ export default {
         }
     },
     data() {
+        let _this = this
         return {
             id: '',
             progressPie: undefined,
-            option: {
-                tooltip: {
-                    trigger: 'item',
-                    formatter: '{b} : {c}' + this.$t('unit.text7')
-                },
-                title: {
-                    "text": '题目正确率统计',
-                    "left": "center",
-                    "top": 0,
-                    "textStyle": {
-                        fontSize: 15
-                    }
-                },
-                dataZoom: [
-                    {
-                        'show': true,
-                        'height': 8,
-                        'xAxisIndex': [
-                            0
-                        ],
-                        bottom: 10,
-                        'start': 0,
-                        handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
-                        handleSize: '100%',
-                        handleStyle: {
-                            color: '#d3dee5'
-
-                        },
-                        textStyle: {
-                            color: '#fff'
-                        },
-                        borderRadius: '5px'
-                    },
-                    {
-                        'type': 'inside',
-                        'show': true,
-                        'height': 15,
-                        'start': 0
-                    }
-                ],
-                grid: {
-                    // width: "90%"
-                    left: 20,
-                    righ: 0
-                },
-                xAxis: {
-                    show: true,
-                    type: 'category',
-                    data: [],
-                    axisLine: {
-                        lineStyle: {
-                            color: "#AAA"
-                        }
-                    },
-                    axisLabel: {
-                        rotate: 0
-                    }
-                },
-                yAxis: {
-                    type: 'value'
-                },
-                series: [
-                    {
-                        data: [],
-                        type: 'bar',
-                        barMaxWidth: 30,
-                    }
-                ]
-            }
+            stuCount: 0,
+            option: {}
         }
     },
     created() {
@@ -104,13 +38,136 @@ export default {
     watch: {
         quData: {
             handler(n, o) {
+                let _this = this
                 this.$nextTick(() => {
+                    if (this.quData.length) _this.stuCount = this.quData[0].correct + this.quData[0].wrong
+                    this.option = {
+                        tooltip: {
+                            trigger: 'item',
+                            formatter: '{b} : {c}' + this.$t('unit.text7')
+                        },
+                        title: {
+                            "text": this.$t('learnActivity.simple.quCorrectRate'),
+                            "left": "center",
+                            "top": 0,
+                            "textStyle": {
+                                fontSize: 15
+                            }
+                        },
+                        tooltip: {
+                            formatter: (params) => {
+                                return `${_this.$t('learnActivity.simple.rac')} ${params.data.toFixed(0)}%(${_this.quData[params.dataIndex].correct}${_this.$t('unit.text7')})`
+                            }
+                        },
+                        dataZoom: [
+                            {
+                                'show': true,
+                                'height': 8,
+                                'xAxisIndex': [
+                                    0
+                                ],
+                                bottom: 10,
+                                handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
+                                // handleSize: '100%',
+                                handleStyle: {
+                                    color: '#d3dee5'
+
+                                },
+                                textStyle: {
+                                    color: '#fff'
+                                },
+                                borderRadius: '5px',
+                            },
+                            {
+                                'type': 'inside',
+                                'show': true,
+                                'height': 15,
+                            }
+                        ],
+                        grid: {
+                            // width: "90%"
+                            left: 30,
+                            righ: 50
+                        },
+                        xAxis: {
+                            show: true,
+                            // name:'题号',
+                            nameLocation: 'end',
+                            type: 'category',
+                            data: [],
+                            axisLine: {
+                                lineStyle: {
+                                    color: "#AAA"
+                                }
+                            },
+                            axisLabel: {
+                                rotate: 0
+                            }
+                        },
+                        yAxis: {
+                            // name:'正确率',
+                            type: 'value'
+                        },
+                        series: [
+                            {
+                                data: [],
+                                type: 'bar',
+                                barMinWidth: 20,
+                                barMaxWidth: 30,
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: (params) => {
+                                        //统计人数的算法
+                                        // if (_this.stuCount > 0) {
+                                        //     return `${(params.data * 100 / _this.stuCount).toFixed(1)}%`
+                                        // } else {
+                                        //     return params.data
+                                        // }
+                                        // 统计正确率的算法
+                                        return `${params.data.toFixed(0)}%`
+                                    },
+                                },
+                                itemStyle: {
+                                    normal: {
+                                        color: function (params) {
+                                            const colorList = ['#ed4014', '#ff9900', '#19be6b']
+                                            //统计人数的算法
+                                            // if (_this.stuCount >= 0) {
+                                            //     let rate = params.data * 100 / _this.stuCount
+                                            //     console.log(params, rate)
+                                            //     if (rate >= 70) {
+                                            //         return colorList[2]
+                                            //     } else if (rate > 50) {
+                                            //         return colorList[1]
+                                            //     } else {
+                                            //         return colorList[0]
+                                            //     }
+                                            // } else {
+                                            //     return colorList[2]
+                                            // }
+                                            // 统计正确率的算法
+                                            if (params.data >= 70) {
+                                                return colorList[2]
+                                            } else if (params.data > 50) {
+                                                return colorList[1]
+                                            } else {
+                                                return colorList[0]
+                                            }
+
+                                        }
+                                    }
+                                }
+                            }
+                        ]
+                    }
                     if (!this.progressPie) {
                         this.progressPie = this.$echarts.init(document.getElementById('qu-score-count' + this.id), 'macarons')
                     }
-                    this.option.series[0].data = this.quData.map(item => item.correct)
+                    this.option.series[0].data = this.quData.map(item => item.correct * 100 / this.stuCount) //计算正确率
                     this.option.xAxis.data = this.quData.map(item => item.quLabel)
-                    if(this.quData.length) this.option.yAxis.max = this.quData[0].correct + this.quData[0].wrong
+                    // if (this.quData.length) this.option.yAxis.max = this.quData[0].correct + this.quData[0].wrong
+                    if (this.quData.length) this.option.yAxis.max = 100 //计算比例不算人数
                     if (this.quData.length > 20) {
                         this.option.dataZoom = [
                             {

+ 1 - 5
TEAMModelOS/ClientApp/src/view/learnactivity/tabs/DataView.vue

@@ -46,7 +46,7 @@
                         {{complyData[0] ? complyData[0].passCount : 0}}
                     </p>
                     <p class="data-text">
-                        及格人数
+                        {{$t('learnActivity.simple.cc')}}
                     </p>
                 </div>
                 <!-- 平均分 -->
@@ -207,7 +207,6 @@ export default {
                     })
                     startScore = endScore + 1
                 }
-                console.log('分数段统计:', segment)
                 return segment
             } else {
                 return []
@@ -215,8 +214,6 @@ export default {
         },
         complyData() {
             if (this.stuTotalScores.length && this.examInfo && this.examInfo.papers) {
-                console.log('评测信息:', this.examInfo)
-                console.log('分数', this.simpleData)
                 let data = []
                 this.simpleData.averageTotal.forEach(item => {
                     let passScore = item.paperScore * 0.6
@@ -229,7 +226,6 @@ export default {
                         failCount: item.total.length - passCount
                     })
                 })
-                console.log('及格人数统计', data)
                 return data
             } else {
                 return []

+ 10 - 6
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less

@@ -195,12 +195,11 @@
             justify-content: center;
 
             .exam-item {
-                margin: 10px 0;
-                padding: 20px 0;
-                // color: #fff;
-				font-size: 12px;
-				font-weight: 300;
-                cursor: pointer;
+			   padding: 25px 0;
+			   font-size: 12px;
+			   font-weight: 300;
+			   cursor: pointer;
+			   border-bottom: 1px solid #f5f5f5;
 
                 &:hover {
                     background: var(--hover-text-color);
@@ -214,6 +213,7 @@
 						display: inline-block;
 						padding: 2px 5px;
                         color: #FFF;
+						border-radius: 4px;
 						
 						&:first-child{
 							margin: 0 5px 0 12px;
@@ -221,6 +221,7 @@
                     }
 
                     .exam-grade {
+						border-radius: 4px;
                         background: #018b99;
                         color: #FFF;
                         padding: 2px 5px;
@@ -229,6 +230,7 @@
                     }
 
                     .exam-name {
+						border-radius: 4px;
                         font-size: 18px;
                         margin-right: 10px;
 						vertical-align: text-bottom;
@@ -237,6 +239,7 @@
                     }
 
                     .exam-subject {
+						border-radius: 4px;
                         background: #419901;
                         color: #FFF;
                         padding: 2px 5px;
@@ -356,6 +359,7 @@
             line-height: 70px;
             font-size: 14px;
             text-align: left;
+			font-weight: bold;
             color: var(--second-text-color);
         }
 

+ 17 - 11
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue

@@ -2,12 +2,6 @@
 	<div class="index-container">
 		<Loading v-show="isLoadingList"></Loading>
 		<vuescroll ref="vs">
-			<!--学校名称部分 -->
-			<!-- 			<div class="section school-info">
-				<div class="school-info-box">
-					<span class="school-info-name">{{ schoolData.name }}{{ $t('totalAnalysis.totalIndex.title') }}</span>
-				</div>
-			</div> -->
 			<div class="section">
 				<!-- 评测数据统计部分 -->
 				<div class="section">
@@ -68,6 +62,13 @@
 
 					<transition name="indexFade">
 						<div class="el-filter-wrap" v-show="isShowFilter">
+							<div class="el-filter-item">
+								<span class="el-filter-title">类型:</span>
+								<RadioGroup v-model="filterScope" type="button" @on-change="filterScopeChange">
+									<Radio label="school">学校评测</Radio>
+									<Radio label="teacher">个人评测</Radio>
+								</RadioGroup>
+							</div>
 							<div class="el-filter-item">
 								<span class="el-filter-title">{{ $t("totalAnalysis.condition1") }}:</span>
 								<RadioGroup v-model="filterPeriod" type="button" @on-change="filterPeriodChange">
@@ -125,9 +126,9 @@
 						<span v-if="!hasCondition">{{$t("totalAnalysis.text9")}}</span>
 						<span v-for="(item, index) in filterList" :key="index" class="filter-item"
 							v-if="item.val">{{ item.val }}
-							<Icon type="ios-close" @click="handleRemove(index, item.keyName)" />
+							<Icon type="ios-close" @click="handleRemove(index, item.keyName)" v-if="item.keyName !== 'period'"/>
 						</span>
-						<span class="list-length">{{ $t("totalAnalysis.text6") }} : {{ examList.length }}
+						<span class="list-length">{{ $t("totalAnalysis.text6") }} : <span style="color:red;font-size: 16px;font-weight: bold;">{{ examList.length }}</span>
 						</span>
 					</div>
 					<div class="section-box list-box">
@@ -142,7 +143,7 @@
 								<span class="exam-name">{{ item.name }}</span>
 								<span class="exam-grade">{{ item.period.name}}</span>
 								<span class="exam-grade" v-for="(grade, gradeIndex) in item.grades"
-									:key="gradeIndex">{{ grade.name}}</span>
+									:key="gradeIndex" v-show="grade.name">{{ grade.name}}</span>
 								<!-- 评测简要数据API暂未返回学科数据 -->
 								<span class="exam-subjects">
 									<span class="exam-subject" v-for="(subject, index) in item.subjects"
@@ -228,6 +229,7 @@
 				searchValue: "",
 				searchList: [],
 				filterYearList:[],
+				filterScope:'school',
 				filterPeriod: vm.$t('totalAnalysis.all'),
 				filterGrade: vm.$t('totalAnalysis.all'),
 				filterTerm: vm.$t('totalAnalysis.all'),
@@ -434,8 +436,7 @@
 				this.filterList.splice(index, 1);
 				switch (name) {
 					case "period":
-						// this.filterPeriod = "全部";
-						// this.filterConditions.period = null;
+						// this.$Message.warning('学段必须指定')
 						break;
 					case "grade":
 						this.filterGrade = this.$t('totalAnalysis.all');
@@ -476,6 +477,10 @@
 				// console.log(this.filterList);
 				this.doFilter();
 			},
+			
+			filterScopeChange(){
+				this.doFilter();
+			},
 
 			filterPeriodChange() {
 				this.filterConditions.period = this.filterPeriod === this.$t('totalAnalysis.all') ? null : this
@@ -548,6 +553,7 @@
 				// 根据条件过滤所有的测验数据
 				this.examList = this.originList.filter((item) => {
 					return (
+						item.owner === this.filterScope && 
 						JSON.stringify(item.period.id).indexOf(curPeriodId || "") >
 						-1 &&
 						JSON.stringify(item.grades.map(i => i.id)).indexOf(this.filterConditions.grade || "") >

+ 5 - 1
TEAMModelOS/ClientApp/src/view/teachermgmt/Index.vue

@@ -24,7 +24,7 @@
                     {{ $t('teachermgmt.page.text2') }}
                     <Badge :count="requestedTeacher.length" class-name="badgesty"></Badge>
                 </span>
-                <span v-if="$access.can('admin.*|teacher-upd')" v-show="isDev" class="pane" @click="paneBtn('import')" :class="{ active: compts === 'import' }">
+                <span v-if="$access.can('admin.*|teacher-upd')" class="pane" @click="paneBtn('import')" :class="{ active: compts === 'import' }">
                     {{ $t('teachermgmt.addTeacher.btn.upload') }}
                 </span>
             </div>
@@ -112,6 +112,10 @@ export default {
     //     }
     // },
     mounted() {
+        this.$EventBus.$off('updTeacherList')
+        this.$EventBus.$on('updTeacherList', val => {
+            this.$store.commit('user/setTeachers', undefined)
+        })
         this.compts = this.$route.name
     }
 }

+ 48 - 35
TEAMModelOS/ClientApp/src/view/teachermgmt/components/import/Import.vue

@@ -4,20 +4,36 @@
         <vuescroll>
             <div class="import-wrap" v-if="viewStatus === 'tips'">
                 <div class="import-tips-box">
-                    <p class="import-title">导入教师范本:</p>
+                    <p class="import-title">{{$t('teachermgmt.importTips1')}}</p>
                     <img class="teacher-import-img" src="../../../../assets/image/teacher-import.png" alt="">
-                    <p class="import-title" style="margin-bottom:0px">栏位说明:</p>
-                    <p class="import-info">1. name: 教师姓名,必填;</p>
-                    <p class="import-info">2. phone: 教师手机号,选填;</p>
-                    <p class="import-info">3. email: 教师邮箱,选填;</p>
-                    <p class="import-info">4. id: 教师醍摩豆ID,选填;</p>
-                    <p class="import-info">5. note: 教师备注信息,选填;</p>
-                    <p class="import-info-tips">温馨提示:如果导入教师醍摩豆ID,或者导入的手机或邮箱已注册醍摩豆ID,系统会自动邀请老师加入学校。</p>
+                    <p class="import-title" style="margin-bottom:0px">
+                        {{$t('teachermgmt.importTips2')}}
+                    </p>
+                    <p class="import-info">
+                        {{$t('teachermgmt.importTips3')}}
+                    </p>
+                    <p class="import-info">
+                        {{$t('teachermgmt.importTips4')}}
+                    </p>
+                    <p class="import-info">
+                        {{$t('teachermgmt.importTips5')}}
+                    </p>
+                    <p class="import-info">
+                        {{$t('teachermgmt.importTips6')}}
+                    </p>
+                    <p class="import-info">
+                        {{$t('teachermgmt.importTips7')}}
+                    </p>
+                    <p class="import-info-tips">
+                        {{$t('teachermgmt.importTips8')}}
+                    </p>
                 </div>
                 <Upload multiple type="drag" action="" :before-upload="customUpload" style="margin-top:20px">
                     <div class="file-area">
                         <Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
-                        <p>点击或者拖拽文件导入</p>
+                        <p>
+                            {{$t('teachermgmt.importTips9')}}
+                        </p>
                     </div>
                 </Upload>
                 <p class="download-text" @click="downloadExample">
@@ -27,19 +43,19 @@
             <div class="excel-data-wrap" v-else-if="viewStatus === 'review'">
                 <div class="import-info-wrap">
                     <span>
-                        导入总人数:
+                        {{$t('teachermgmt.impText1')}}
                     </span>
                     <span class="count-value">
                         {{importData.length}}人
                     </span>
                     <span>
-                        仅导入姓名:
+                        {{$t('teachermgmt.impText2')}}
                     </span>
                     <span class="count-value">
                         {{onlyName.length}}人
                     </span>
                     <span>
-                        系统将自动邀请:
+                        {{$t('teachermgmt.impText3')}}
                     </span>
                     <span class="count-value">
                         {{inviteData.length}}人
@@ -47,11 +63,11 @@
                     <div class="imp-action-wrap">
                         <span @click="importAgain">
                             <Icon type="md-refresh" size="16" />
-                            重新导入
+                            {{$t('teachermgmt.impText4')}}
                         </span>
                         <span @click="confirmImport">
                             <Icon custom="iconfont icon-upload" size="16" />
-                            确认导入
+                            {{$t('teachermgmt.impText5')}}
                         </span>
                     </div>
                 </div>
@@ -61,13 +77,13 @@
             </div>
             <div class="import-finish" v-else-if="viewStatus === 'finish'">
                 <Icon type="md-checkmark-circle" class="import-ok-icon" />
-                <p class="import-result-text">导入成功</p>
-                <div class="import-result-area">
+                <p class="import-result-text">{{$t('teachermgmt.impText6')}}</p>
+                <!-- <div class="import-result-area">
 
-                </div>
+                </div> -->
                 <div class="result-action-wrap">
-                    <Button type="primary" style="width:600px" size="large" @click="importAgain">
-                        继续导入
+                    <Button type="primary" style="width:300px" size="large" @click="importAgain">
+                        {{$t('teachermgmt.impText7')}}
                     </Button>
                 </div>
             </div>
@@ -80,34 +96,30 @@ import excel from '@/utils/excel'
 export default {
     data() {
         return {
-            viewStatus: 'finish', // tips:提示信息 review:预览表格数据 finish:导入成功
+            viewStatus: 'tips', // tips:提示信息 review:预览表格数据 finish:导入成功
             file: undefined,
             title: ['name', 'phone', 'email', 'id', 'note'],
             columns1: [
                 {
-                    title: '姓名',
+                    title: this.$t('teachermgmt.impTd1'),
                     key: 'name'
                 },
                 {
-                    title: '手机',
+                    title: this.$t('teachermgmt.impTd2'),
                     key: 'phone'
                 },
                 {
-                    title: '邮箱',
+                    title: this.$t('teachermgmt.impTd3'),
                     key: 'email'
                 },
                 {
-                    title: '醍摩豆ID',
-                    key: 'id'
+                    title: this.$t('teachermgmt.impTd4'),
+                    key: 'tmdid'
                 },
                 {
-                    title: '备注',
+                    title: this.$t('teachermgmt.impTd5'),
                     key: 'note'
-                },
-                // {
-                //     title: '状态',
-                //     slot: 'status'
-                // }
+                }
             ],
             importData: [],
             onlyName: [],
@@ -125,6 +137,7 @@ export default {
             this.$api.schoolUser.importTeacher(params).then(
                 res => {
                     this.viewStatus = 'finish'
+                    this.$store.commit('user/addTeacher',res.teacherImport?.teachers || [])
                 },
                 err => {
 
@@ -188,7 +201,7 @@ export default {
                     // 处理表格导入数据类型
                     results.forEach(item => {
                         if (item.phone) item.phone = item.phone.toString()
-                        if (item.id) item.id = item.id.toString()
+                        if (item.tmdid) item.tmdid = item.tmdid.toString()
                     })
                     this.importData = results
                     this.onlyName = this.importData.filter(item => !item.phone && !item.email && !item.id)
@@ -282,7 +295,7 @@ export default {
     color: #fff;
     padding: 8px 0px;
     border-radius: 5px;
-    width: 575px;
+    width: 698px;
     cursor: pointer;
     user-select: none;
     text-align: center;
@@ -301,12 +314,12 @@ export default {
     color: #ff9900;
 }
 .file-area {
-    width: 575px;
+    width: 698px;
     padding: 50px;
     background: #f3f3f3;
 }
 .import-wrap {
-    width: 575px;
+    width: 698px;
     height: fit-content;
     margin: auto;
 }

+ 8 - 0
TEAMModelOS/ClientApp/src/view/teachermgmt/components/mgt/TeacherMgt.less

@@ -67,6 +67,7 @@
 .subject-tag{
     cursor: pointer;
     user-select: none;
+    white-space: pre-line;
 }
 
 .role-set-header{
@@ -300,3 +301,10 @@
     position: relative;
     z-index: 99;
 }
+.teacher-status{
+    font-size: 12px;
+    background: #ed4014;
+    border-radius: 3px;
+    padding: 1px 5px;
+    color: white;
+}

+ 58 - 16
TEAMModelOS/ClientApp/src/view/teachermgmt/components/mgt/TeacherMgt.vue

@@ -27,14 +27,22 @@
                             <PersonalPhoto :name="row.name" :picture="row.picture" />
                         </template>
                         <template slot-scope="{ row,index }" slot="subject">
-                            <span :style="{color:row.subjectIds && row.subjectIds.length? '':'red'}" class="subject-tag" @click="showSetSubj(index)">
+                            <p :style="{color:row.subjectIds && row.subjectIds.length? '':'red'}" class="subject-tag" @click="showSetSubj(index)">
                                 {{row.subjectIds && row.subjectIds.length ? getSubjectNames(row.subjectIds) : $t('teachermgmt.notSet')}}
+                            </p>
+                        </template>
+                        <template slot-scope="{ row,index }" slot="name">
+                            <span>
+                                {{row.name}}
+                            </span>
+                            <span v-show="row.status != 'join'" class="teacher-status" :style="{background:row.status == 'invite' ? '#2d8cf0' : ''}">
+                                {{row.status == 'import' ? $t('teachermgmt.teacherStatus1') : row.status == 'invite' ? $t('teachermgmt.teacherStatus2') : ''}}
                             </span>
                         </template>
                         <template slot-scope="{ row }" slot="action" v-if="!activePanel">
-                            <icon v-show="!row.roles.includes('admin')" icon="shield-alt" style="font-size: 13px; color: var(--normal-icon-color); margin-right: 20px; cursor: pointer;" @click="openPanel('single',row)" />
+                            <icon v-show="!row.roles.includes('admin') && row.status == 'join'" icon="shield-alt" style="font-size: 13px; color: var(--normal-icon-color); margin-right: 20px; cursor: pointer;" @click="openPanel('single',row)" />
                             <Icon v-show="!row.roles.includes('admin')" size="16" type="md-trash" style="color: var(--normal-icon-color); cursor: pointer" @click="removeUser(row)" />
-                            <Icon v-show="row.roles.includes('admin') && row.id == $store.state.userInfo.TEAMModelId" type="md-repeat" style="color: var(--normal-icon-color); font-size: 14px; cursor: pointer" @click="transferAdmin(row)" />
+                            <Icon v-show="row.roles.includes('admin') && row.id == $store.state.userInfo.TEAMModelId && row.status == 'join'" type="md-repeat" style="color: var(--normal-icon-color); font-size: 14px; cursor: pointer" @click="transferAdmin(row)" />
                         </template>
                         <!---手動輸入空間欄位-->
                         <template slot-scope="{ row }" slot="spaceShare">
@@ -208,7 +216,7 @@
             <div class="edit-name-content">
                 <span>{{$t('teachermgmt.transferTo')}}</span>
                 <Select v-model="toAdminId" filterable style="margin-top:10px">
-                    <Option v-for="item in teachers" :value="item.id" :key="item.id">
+                    <Option v-for="item in teacherJoin" :value="item.id" :key="item.id">
                         {{ `${item.name}(${item.id})` }}
                     </Option>
                 </Select>
@@ -277,9 +285,23 @@ export default {
     },
     computed: {
         ...mapGetters({
-            teachers: 'user/getTeacherJoined',
+            teacherJoin: 'user/getTeacherJoined',
+            teacherInvite: 'user/getTeacherInvited',
+            teacherImport: 'user/getTeacherImport',
             isKeyInSpace: 'spaceAuth/getIsKeyInSpace'
         }),
+        teachers() {
+            let data = []
+            data.push(...this.teacherJoin)
+            data.push(...this.teacherInvite)
+            data.push(...this.teacherImport)
+            data.forEach(item => {
+                if (item.status != 'join') {
+                    item._disabled = true
+                }
+            })
+            return data
+        },
         pieNumData() {
             let data = [
                 { value: 0, name: this.$t("teachermgmt.usedSpace") },
@@ -337,18 +359,34 @@ export default {
                 },
                 {
                     title: this.$t('teachermgmt.table.th2'),
-                    key: 'name',
+                    slot: 'name',
                     minWidth: 160,
                     maxWidth: 200,
-                    sortable: true
+                    filters: [
+                        {
+                            label: this.$t('teachermgmt.teacherStatus3'),
+                            value: 'join'
+                        },
+                        {
+                            label: this.$t('teachermgmt.teacherStatus2'),
+                            value: 'invite'
+                        },
+                        {
+                            label: this.$t('teachermgmt.teacherStatus1'),
+                            value: 'import'
+                        }
+                    ],
+                    filterMethod(value, row) {
+                        return row.status == value
+                    }
                 },
                 {
                     title: 'ID',
                     minWidth: 160,
                     maxWidth: 200,
                     key: 'id',
+                    sortable: true
                 },
-
                 {
                     title: this.$t('teachermgmt.table.th6'),
                     slot: 'subject',
@@ -410,7 +448,7 @@ export default {
                                                     }
                                                 }
                                             }
-                                        }, this.$t('teachermgmt.table.filter')),
+                                        }, this.$t('teachermgmt.filter')),
                                         h('span', {
                                             on: {
                                                 'click': () => {
@@ -454,7 +492,7 @@ export default {
                     minWidth: 180,
                     render: (h, params) => {
                         let p = ['content-read', 'exercise-read', 'knowledge-read', 'syllabus-read']
-                        let flag = params.row.permissions.some(item => {
+                        let flag = params.row.permissions?.some(item => {
                             return !p.includes(item)
                         })
                         if (params.row.roles.includes('admin')) {
@@ -586,8 +624,8 @@ export default {
                 // 可以客制調整
                 filterData = this.teachers.filter(res => {
                     let a = res.name.toLowerCase()
-                    let b = res.id.toLowerCase()
-                    return a.includes(this.keyWord) || b.includes(this.keyWord)
+                    let b = res.id?.toLowerCase()
+                    return a?.includes(this.keyWord) || b?.includes(this.keyWord)
                 })
             }
             return filterData
@@ -840,6 +878,7 @@ export default {
         //单一设置教师学科
         showSetSubj(index) {
             this.setSubjIndex = index
+            if (this.tableData[index].status != 'join') return
             if (this.tableData[index].subjectIds && this.tableData[index].subjectIds.length) {
                 let subjectInfos = this.$jsFn.getTeacherSubjects(this.tableData[index].subjectIds)
                 this.setSubj = subjectInfos.map(item => [item.periodId, item.subjectId])
@@ -903,7 +942,7 @@ export default {
                     let subNames = item.map(s => s.subjectName)
                     let pdName = item[0].periodName
                     return `${pdName}-${subNames.join('/')}`
-                }).join('; ')
+                }).join('; \n')
             } else {
                 return ''
             }
@@ -947,16 +986,19 @@ export default {
         removeUser(val) {
             // val:使用者的資料(object)
             if (this.$access.can('admin.*|teacher-upd')) {
+                let idText = val.id ? '(' + val.id + ')' : ''
                 this.$Modal.confirm({
                     title: this.$t('teachermgmt.model.delTeacher.title'),
-                    content: '<p>' + this.$t('teachermgmt.model.delTeacher.text1') + ' ' + val.name + '(' + val.id + ') ?</p>',
+                    // content: '<p>' + this.$t('teachermgmt.model.delTeacher.text1') + ' ' + val.name + '(' + val.id + ') ?</p>',
+                    content: `<p> ${this.$t('teachermgmt.model.delTeacher.text1')}  ${val.name} ${idText}?</p>`,
                     onOk: () => {
                         this.$api.schoolUser.rmvSchoolUser({
                             school_code: this.$store.state.userInfo.schoolCode,
-                            id: val.id
+                            id: val.id || undefined,
+                            name: val.id ? undefined : val.name
                         }).then(
                             res => {
-                                this.$store.commit('user/delTeacher', [val.id])
+                                this.$store.commit('user/delTeacher', [val.id || val.name])
                             },
                             err => {
                             }

+ 13 - 0
TEAMModelOS/ClientApp/src/view/teachermgmt/components/personnel/Index.less

@@ -360,4 +360,17 @@
     display: block;
     margin-top: 15px;
     width: 200px;
+}
+.agree-join-content{
+    font-size: 15px;
+}
+.band-teacher-tips{
+    font-size: 14px;
+    color: #ff9900;
+    margin-top: 25px;
+}
+.band-teacher-lable{
+    margin-top: 5px;
+    font-weight: 600;
+    color: #17233d;
 }

+ 65 - 28
TEAMModelOS/ClientApp/src/view/teachermgmt/components/personnel/Index.vue

@@ -290,6 +290,24 @@
                 </transition>
             </div>
         </div>
+        <Modal v-model="agreeStatus" footer-hide className="ed-name-modal">
+            <div slot="header" class="modal-header">
+                {{this.$t('teachermgmt.message.info16')}}
+            </div>
+            <div class="edit-name-content">
+                <p class="agree-join-content">{{`${$t('teachermgmt.message.info17')} ${agreeInfo.name} (${agreeInfo.id})${$t('teachermgmt.message.info18')}?`}}</p>
+                <p class="band-teacher-tips" v-show="isShowBand">
+                    {{this.$t('teachermgmt.joinTips1')}}
+                </p>
+                <p class="band-teacher-lable" v-show="isShowBand">
+                    {{this.$t('teachermgmt.joinTips2')}}
+                </p>
+                <Select v-model="bandTeacher" style="width:100%" clearable v-show="isShowBand">
+                    <Option v-for="item in importTeacher" :value="item.name" :key="item.name">{{ item.name }}</Option>
+                </Select>
+                <Button :loading="btnLoading" @click="confirmJoin" long type="primary" class="confirm-btn">{{ $t('syllabus.confirm') }}</Button>
+            </div>
+        </Modal>
     </div>
 </template>
 
@@ -302,6 +320,10 @@ export default {
     name: 'personnel',
     data() {
         return {
+            bandTeacher: '',
+            agreeInfo: {},
+            btnLoading: false,
+            agreeStatus: false,
             joinQRcode: false,
             inviteLoading: false,
             excelLoading: false,
@@ -348,8 +370,19 @@ export default {
     computed: {
         ...mapGetters({
             dataList: 'user/getTeacherInvitedOrRequested', // 取得被邀請或申請加入此學校的使用者
+            importTeacher: 'user/getTeacherImport', // 
             srvAdr: 'config/getSrvAdr'      // 取得現在的站台位置
         }),
+        isShowBand(){
+            let flag = false
+            if(this.importTeacher.length){
+                let t = this.importTeacher.find(i=>i.name === this.agreeInfo.name)
+                if(!t){
+                    flag = true
+                }
+            }
+            return flag
+        },
         sortCodeText: function () {
             switch (this.sortCode) {
                 case 'time':
@@ -387,6 +420,7 @@ export default {
             this.joinQRcode = undefined
         },
         qrCodeJoin() {
+            this.needUpd = true
             this.serchModel = 'qrcode'
             setTimeout(this.createQRCode, 500)
         },
@@ -697,36 +731,39 @@ export default {
                 )
             }
         },
-        //變更加入狀態 (join:已加入 invite:被邀請 request:申請中)
-        updUserStatus(val, updStatus) { //val:使用者的資料(object)
-            let statusTitle = '';
-            let statusContent = '';
-            if (val.status == 'request' && updStatus == 'join') {
-                statusTitle = this.$t('teachermgmt.message.info16');
-                statusContent = '<p>' + this.$t('teachermgmt.message.info17') + ' ' + val.name + '(' + val.id + ') ' + this.$t('teachermgmt.message.info18') + ' ?</p>';
-            }
-            this.$Modal.confirm({
-                title: statusTitle,
-                content: statusContent,
-                onOk: () => {
-                    this.$store.dispatch('user/updSchoolUserStatus', { id: val.id, status: updStatus }).then(
-                        (res) => {
-                            if (res.code == 1) {
-                                this.$Message.info(this.$t('teachermgmt.message.info3'));
-                            }
-                            else {
-                                alert('Can not update param.')
-                            }
-                            //清空vuex教师列表,保证其他页面获取最新数据
-                            this.$store.commit('teachers/setTeacherList', [])
-                        },
-                        (err) => {
-                            //this.$Message.error('user/updSchoolUserStatus API error!')
-                        }
-                    )
+        confirmJoin() {
+            this.btnLoading = true
+            this.$store.dispatch('user/updSchoolUserStatus', { id: this.agreeInfo.id, status: 'join', importName: this.bandTeacher }).then(
+                (res) => {
+                    if (res.code == 1) {
+                        this.$Message.info(this.$t('teachermgmt.message.info3'));
+                    }
+                    else {
+                        alert('Can not update param.')
+                    }
+                    //清空vuex教师列表,保证其他页面获取最新数据
+                    this.agreeStatus = false
+                    this.$store.commit('teachers/setTeacherList', undefined)
+                },
+                (err) => {
+                    //this.$Message.error('user/updSchoolUserStatus API error!')
                 }
-            });
+            ).finally(() => {
+                this.bandTeacher = undefined
+                this.btnLoading = false
+            })
         },
+        //變更加入狀態 (join:已加入 invite:被邀請 request:申請中)
+        updUserStatus(val, updStatus) { //val:使用者的資料(object)
+            this.agreeStatus = true
+            this.agreeInfo = val
+        }
+    },
+    beforeRouteLeave(to,from,next){
+        if(this.needUpd){
+            this.$EventBus.$emit('updTeacherList')
+        }
+        next(true)
     }
 }
 </script>

+ 4 - 0
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -1483,6 +1483,7 @@ namespace TEAMModelOS.Controllers.Client
                                     examClassResultUpd.studentIds = examClassResultRow.studentIds;
                                     examClassResultUpd.studentAnswers = new List<List<string>>();
                                     examClassResultUpd.studentScores = examClassResultRow.studentScores;
+                                    examClassResultUpd.status = examClassResultRow.status;
                                     examClassResultUpd.sum = examClassResultRow.sum;
                                 }
                             }
@@ -1503,6 +1504,7 @@ namespace TEAMModelOS.Controllers.Client
                             examClassResultUpd.studentIds = examClassResultRow.studentIds;
                             examClassResultUpd.studentAnswers = new List<List<string>>(); //學生作答Blob位置
                             examClassResultUpd.studentScores = examClassResultRow.studentScores;
+                            examClassResultUpd.status = examClassResultRow.status;
                             examClassResultUpd.scope = examClassResultRow.scope;
                             examClassResultUpd.sum = examClassResultRow.sum;
                         }
@@ -1562,6 +1564,7 @@ namespace TEAMModelOS.Controllers.Client
                                     examClassResultUpd.studentIds = examClassResultRow.studentIds;
                                     examClassResultUpd.studentAnswers = new List<List<string>>();
                                     examClassResultUpd.studentScores = examClassResultRow.studentScores;
+                                    examClassResultUpd.status = examClassResultRow.status;
                                     examClassResultUpd.sum = examClassResultRow.sum;
                                 }
                             }
@@ -1582,6 +1585,7 @@ namespace TEAMModelOS.Controllers.Client
                             examClassResultUpd.studentIds = examClassResultRow.studentIds;
                             examClassResultUpd.studentAnswers = new List<List<string>>();
                             examClassResultUpd.studentScores = examClassResultRow.studentScores;
+                            examClassResultUpd.status = examClassResultRow.status;
                             examClassResultUpd.scope = examClassResultRow.scope;
                             examClassResultUpd.sum = examClassResultRow.sum;
                         }

+ 8 - 1
TEAMModelOS/Controllers/Client/HiTeachccControlller.cs

@@ -101,7 +101,14 @@ namespace TEAMModelOS.Controllers.Client
                 foreach (var blobItem in blobs)
                 {
                     var blob = container.GetBlobClient(blobItem.Name);
-                    await blob.DeleteIfExistsAsync();
+                    DateTimeOffset blobTime = (DateTimeOffset)blobItem.Properties.CreatedOn;
+                    var now = DateTimeOffset.UtcNow;
+                    DateTimeOffset today = new DateTimeOffset(now.Year, now.Month, now.Day, 0, 0, 0, 0, TimeSpan.Zero);
+                    int diff = DateTimeOffset.Compare(blobTime, today);
+                    if(diff < 0)
+                    {
+                        await blob.DeleteIfExistsAsync();
+                    }
                 }
                 return Ok(new { error, message });
             }

+ 1 - 0
TEAMModelOS/Controllers/XTest/FixDataController.cs

@@ -1479,6 +1479,7 @@ namespace TEAMModelOS.Controllers
                         schoolTeacher.subjectIds = schoolTeacher.subjectIds == null ? new List<string>() : schoolTeacher.subjectIds;
                         schoolTeacher.status = "join";
                         schoolTeacher.job = "管理员";
+                        schoolTeacher.pk = "Teacher";
                         await client.GetContainer(Constant.TEAMModelOS, Constant.School).CreateItemAsync(schoolTeacher, new PartitionKey($"Teacher-{school.id}"));
                         schoolsTeachers.Add(schoolTeacher);
                     }