Bläddra i källkod

Merge branch 'develop' into PL/develop-BI

Li 2 år sedan
förälder
incheckning
6e10120103
58 ändrade filer med 5524 tillägg och 2842 borttagningar
  1. 46 0
      TEAMModelBI/ClientApp/src/api/index.js
  2. 1 1
      TEAMModelBI/ClientApp/src/components/echarts/commonBar.vue
  3. 68 68
      TEAMModelBI/ClientApp/src/components/echarts/conventionPie.vue
  4. 156 194
      TEAMModelBI/ClientApp/src/components/echarts/gradePie.vue
  5. 3 1
      TEAMModelBI/ClientApp/src/router/index.js
  6. 22 1
      TEAMModelBI/ClientApp/src/store/index.js
  7. 38 0
      TEAMModelBI/ClientApp/src/until/common.js
  8. 1 2
      TEAMModelBI/ClientApp/src/until/http.js
  9. 154 42
      TEAMModelBI/ClientApp/src/view/areamanage/statistics.vue
  10. 1 1
      TEAMModelBI/ClientApp/src/view/common/aside.vue
  11. 4 2
      TEAMModelBI/ClientApp/src/view/index/index.vue
  12. 1285 293
      TEAMModelBI/ClientApp/src/view/schoolmanage/schoolAnalyse.vue
  13. 37 8
      TEAMModelBI/ClientApp/src/view/thirdparty/details.vue
  14. 148 49
      TEAMModelBI/ClientApp/src/view/thirdparty/index.vue
  15. 110 7
      TEAMModelBI/ClientApp/src/view/thirdparty/login.vue
  16. 2 2
      TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs
  17. 894 444
      TEAMModelOS/ClientApp/public/lang/en-US.js
  18. 363 2
      TEAMModelOS/ClientApp/public/lang/zh-CN.js
  19. 433 72
      TEAMModelOS/ClientApp/public/lang/zh-TW.js
  20. 1 1
      TEAMModelOS/ClientApp/src/access/login.js
  21. 132 133
      TEAMModelOS/ClientApp/src/components/evaluation/AnalysisItemTable.vue
  22. 464 470
      TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue
  23. 5 4
      TEAMModelOS/ClientApp/src/components/student-web/ClassRecord/ReceiveBack.vue
  24. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/ClassRecord/StuReceive.vue
  25. 12 12
      TEAMModelOS/ClientApp/src/view/ability/Review.vue
  26. 55 68
      TEAMModelOS/ClientApp/src/view/areaMgmt/AreaData.vue
  27. 3 3
      TEAMModelOS/ClientApp/src/view/areaMgmt/HourProg.vue
  28. 2 2
      TEAMModelOS/ClientApp/src/view/areaMgmt/ResourceMgt.vue
  29. 5 6
      TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolComp.vue
  30. 8 23
      TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolDetail.vue
  31. 3 3
      TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolIndex.vue
  32. 9 9
      TEAMModelOS/ClientApp/src/view/areatrain/Create.vue
  33. 1 2
      TEAMModelOS/ClientApp/src/view/areatrain/PhoneSign.vue
  34. 6 8
      TEAMModelOS/ClientApp/src/view/areatrain/TrainDetail.vue
  35. 102 102
      TEAMModelOS/ClientApp/src/view/assessment/Assessment.vue
  36. 3 2
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  37. 42 42
      TEAMModelOS/ClientApp/src/view/jyzx/application.vue
  38. 26 26
      TEAMModelOS/ClientApp/src/view/jyzx/index.vue
  39. 5 5
      TEAMModelOS/ClientApp/src/view/jyzx/newHomePage.vue
  40. 20 19
      TEAMModelOS/ClientApp/src/view/jyzx/offline.vue
  41. 1 2
      TEAMModelOS/ClientApp/src/view/statistics/AbilityPoint.vue
  42. 32 32
      TEAMModelOS/ClientApp/src/view/statistics/Dashboard.vue
  43. 6 2
      TEAMModelOS/ClientApp/src/view/statistics/Statistics.vue
  44. 15 15
      TEAMModelOS/ClientApp/src/view/statistics/TableData.vue
  45. 14 15
      TEAMModelOS/ClientApp/src/view/train/Create.vue
  46. 7 7
      TEAMModelOS/ClientApp/src/view/train/PhoneSign.vue
  47. 0 1
      TEAMModelOS/ClientApp/src/view/train/SurveyDetail.vue
  48. 53 66
      TEAMModelOS/ClientApp/src/view/train/TrainDetail.vue
  49. 4 4
      TEAMModelOS/ClientApp/src/view/train/TrainMgt.vue
  50. 210 212
      TEAMModelOS/ClientApp/src/view/trainList/Check.vue
  51. 93 104
      TEAMModelOS/ClientApp/src/view/trainList/Join.vue
  52. 1 0
      TEAMModelOS/Controllers/Client/HiTeachController.cs
  53. 3 2
      TEAMModelOS/Controllers/Client/HiTeachccControlller.cs
  54. 3 3
      TEAMModelOS/Controllers/OpenApi/Business/BizLessonRecordController.cs
  55. 139 1
      TEAMModelOS/Controllers/OpenApi/OpenApiService.cs
  56. 1 0
      TEAMModelOS/Controllers/Third/Xkw/Sdk/XkwAPIHttpService.cs
  57. 269 244
      TEAMModelOS/Controllers/Third/Xkw/XkwServiceController.cs
  58. 1 1
      TEAMModelOS/TEAMModelOS.csproj

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

@@ -253,6 +253,14 @@ export default {
     getEmploySizes(data) {
         return post('/bloblog/get-area', data)
     },
+    //获取某个学区内的顾问人员列表
+    getCounselorlist(data) {
+        return post('/area/get-assists', data)
+    },
+    //获取某个学区内的学校列表
+    getAreaSchoolList(data) {
+        return post('/area/get-schools', data)
+    },
 
     //系统配置
     //站点配置
@@ -305,6 +313,34 @@ export default {
         return post('/online/get-edition', data)
     },
 
+    //区校掌握
+    //基础数据以及排行
+    getBasicsData(data) {
+        return post('/schoolcheck/get-assisscbase', data)
+    },
+    //获取当前所有学校所有月份的数据(课例、活动、互动)
+    getAllaspects(data) {
+        return post('/schoolcheck/get-assissc', data)
+    },
+    //获取课例、活动、互动数据 同比较,以及line图
+    getaspects(data) {
+        return post('/schoolcheck/get-assissccnt', data)
+    },
+    //获取某个学校的详细信息
+    schoolDetails(data) {
+        return post('/schoolcheck/get-analyse', data)
+    },
+    //获取所有管理的学校服务模块和各个版本占比
+    getServiceandVersions(data) {
+        return post('/schoolcheck/get-proded', data)
+    },
+    //统计某个学校的年级、科目数据
+    getGradeandSubjects(data) {
+        return post('/schoolcheck/get-ratio', data)
+    },
+
+
+
     //顾问使用(我参与的)
     //学校管理 数据统计
     schoolStatistics(data) {
@@ -346,6 +382,8 @@ export default {
         return post('/business/del-companysc', data)
     },
 
+
+    //第三方企业合作平台相关API
     //获取地址location
     getlocation(key, location) {
         return fetch('https://restapi.amap.com/v3/ip?key=' + key + '&ip=' + location)
@@ -353,5 +391,13 @@ export default {
     //获取天气的API
     getWeather(key, location) {
         return fetch('https://devapi.qweather.com/v7/weather/now?location=' + location + '&key=' + key)
+    },
+    //登录
+    thirdlogins(data) {
+        return post('/common/login/get-bizuserlogin', data)
+    },
+    //注册
+    registerThirdparty(data) {
+        return post('/common/login/set-ropen', data)
     }
 }

+ 1 - 1
TEAMModelBI/ClientApp/src/components/echarts/commonBar.vue

@@ -55,7 +55,7 @@ class InitChart {
     }
   }
   init (datas, proxy) {
-    console.log(datas, '柱状图的调用')
+    console.log(datas, '柱状图的调用123123123')
     this.state.chart && this.destory()
     this.state.chart = echarts.init(this.myEcharts.value)
     this.state.chart.setOption({

+ 68 - 68
TEAMModelBI/ClientApp/src/components/echarts/conventionPie.vue

@@ -1,84 +1,84 @@
 <!--基础折线图-->
 <template>
-    <div ref="myEcharts" :style="{ height, width }"></div>
+  <div ref="myEcharts" :style="{ height, width }"></div>
 </template>
 <script>
 import { ref, onMounted, nextTick, watch, getCurrentInstance } from 'vue'
 import * as echarts from 'echarts'
 export default {
-    name: 'baseBar',
-    props: {
-        width: {
-            type: String,
-            default: '100%',
-        },
-        height: {
-            type: String,
-            default: '100%',
-        },
-        pieData: {
-            type: Object,
-            default: () => {},
-        },
-        title: {
-            type: String,
-            default: '',
-        },
+  name: 'baseBar',
+  props: {
+    width: {
+      type: String,
+      default: '100%',
     },
-    setup(props) {
-        const myEcharts = ref(null)
-        let { proxy } = getCurrentInstance()
-        const chart = new InitChart(props, myEcharts)
-        onMounted(() => {
-            chart.init(props.pieData, proxy)
-        })
-        watch(
-            props,
-            (nweProps) => {
-                nextTick(() => {
-                    nweProps ? chart.init(props.pieData, proxy) : ''
-                })
-            },
-            { immediate: true, deep: true }
-        )
-        return {
-            myEcharts,
-        }
+    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()
-        })
+  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('事件移除')
-        })
-    }
+  destory () {
+    this.state.chart.dispose()
+    window.removeEventListener('resize', () => {
+      console.log('事件移除')
+    })
+  }
 }
 </script>
 <style lang="less"></style>

+ 156 - 194
TEAMModelBI/ClientApp/src/components/echarts/gradePie.vue

@@ -1,213 +1,175 @@
 <!--基础折线图-->
 <template>
-    <div ref="myEcharts" :style="{ height, width }"></div>
+  <div ref="myEcharts" :style="{ height, width }"></div>
 </template>
 <script>
 import { ref, onMounted, nextTick, watch, getCurrentInstance } from 'vue'
 import * as echarts from 'echarts'
 export default {
-    name: 'baseBar',
-    props: {
-        width: {
-            type: String,
-            default: '100%',
-        },
-        height: {
-            type: String,
-            default: '100%',
-        },
-        mapData: {
-            type: Object,
-            default: () => {},
-        },
-        title: {
-            type: String,
-            default: '',
-        },
+  name: 'baseBar',
+  props: {
+    width: {
+      type: String,
+      default: '100%',
     },
-    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,
-        }
+    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,
-        }
+  constructor(props, myEcharts) {
+    this.props = props
+    this.myEcharts = myEcharts
+    this.state = {
+      chart: null,
     }
-    init(datas, proxy) {
-        console.log(datas, '1111111111111111')
-        var data = [
-            {
-                value: 200,
-                name: '一年级',
-            },
-            {
-                value: 110,
-                name: '二年级',
-            },
-            {
-                value: 150,
-                name: '三年级',
-            },
-            {
-                value: 180,
-                name: '四年级',
-            },
-        ]
-        let datum = data.map((v) => v.value)
-        let color = ['#27D099', '#B458F5', '#FCD54B', '#5684F4', '#81ecec', '#ff7675']
-        let data1 = data[0].value + data[1].value + data[2].value + data[3].value
-        let baseData = []
-        for (var i = 0; i < data.length; i++) {
-            baseData.push({
-                value: data[i].value,
-                name: data[i].name,
-                itemStyle: {
-                    normal: {
-                        borderWidth: 30,
-                        shadowBlur: 20,
-                        borderColor: color[i],
-                        borderRadius: 20,
-                    },
-                },
-            })
-        }
-        this.state.chart && this.destory()
-        this.state.chart = echarts.init(this.myEcharts.value)
-        this.state.chart.setOption({
-            title: {
-                text: '年级占比',
-                textStyle: {
-                    fontSize: '12',
-                    color: '#b2bec3',
+  }
+  init (datas, proxy) {
+    console.log(datas, '调用了特殊的echart')
+    if (datas.length === 0) { return }
+    var defaults = [
+      {
+        value: 0,
+        name: '',
+      },
+      {
+        value: 0,
+        name: '',
+      },
+      {
+        value: 0,
+        name: '',
+      },
+
+    ]
+    var data = datas ? datas : defaults
+    let datum = data.map((v) => v.value)
+    let color = ['#27D099', '#B458F5', '#FCD54B', '#5684F4', '#81ecec', '#ff7675']
+    // let data1 = data[0].value + data[1].value + data[2].value + data[3].value
+    let baseData = []
+    for (var i = 0; i < data.length; i++) {
+      baseData.push({
+        value: data[i].value,
+        name: data[i].name,
+        itemStyle: {
+          normal: {
+            borderWidth: 30,
+            shadowBlur: 20,
+            borderColor: color[i],
+            borderRadius: 20,
+          },
+        },
+      })
+    }
+    this.state.chart && this.destory()
+    this.state.chart = echarts.init(this.myEcharts.value)
+    this.state.chart.setOption({
+      title: {
+        text: '年级占比',
+        textStyle: {
+          fontSize: '12',
+          color: '#b2bec3',
+        },
+      },
+      color: color,
+      tooltip: {
+        show: true,
+        trigger: 'item',
+        formatter: '{b} <br/>占比:{d}%',
+      },
+      legend: {
+        orient: 'vertical',
+        right: '10%',
+        top: '35%',
+        itemGap: 50,
+        itemWidth: 12,
+      },
+      grid: {
+        top: 'bottom',
+        left: 40,
+        bottom: 10,
+        width: '50%',
+        height: '50%',
+      },
+      series: [
+        {
+          zlevel: 1,
+          name: '',
+          type: 'pie',
+          selectedMode: 'single',
+          radius: [40, 80],
+          center: ['35%', '50%'],
+          startAngle: 20,
+          // hoverAnimation: false,
+          label: {
+            normal: {
+              position: 'inside',
+              show: true,
+              color: '#fff',
+              formatter: function (params) {
+                return params.percent.toFixed() + '%'
+              },
+              rich: {
+                b: {
+                  fontSize: 16,
+                  lineHeight: 30,
+                  color: '#fff',
                 },
+              },
             },
-            color: color,
-            tooltip: {
-                show: true,
-                trigger: 'item',
-                formatter: '{b} <br/>占比:{d}%',
+          },
+          itemStyle: {
+            normal: {
+              shadowColor: 'rgba(0, 0, 0, 0.2)',
+              shadowBlur: 10,
             },
-            legend: {
-                orient: 'vertical',
-                right: '10%',
-                top: '35%',
-                itemGap: 50,
-                itemWidth: 12,
-            },
-            grid: {
-                top: 'bottom',
-                left: 40,
-                bottom: 10,
-                width: '50%',
-                height: '50%',
-            },
-            series: [
-                {
-                    zlevel: 1,
-                    name: '',
-                    type: 'pie',
-                    selectedMode: 'single',
-                    radius: [40, 80],
-                    center: ['35%', '50%'],
-                    startAngle: 20,
-                    // hoverAnimation: false,
-                    label: {
-                        normal: {
-                            position: 'inside',
-                            show: true,
-                            color: '#fff',
-                            formatter: function (params) {
-                                return params.percent.toFixed() + '%'
-                            },
-                            rich: {
-                                b: {
-                                    fontSize: 16,
-                                    lineHeight: 30,
-                                    color: '#fff',
-                                },
-                            },
-                        },
-                    },
-                    itemStyle: {
-                        normal: {
-                            shadowColor: 'rgba(0, 0, 0, 0.2)',
-                            shadowBlur: 10,
-                        },
-                    },
-                    data: baseData,
-                },
-                {
-                    name: '',
-                    type: 'pie',
-                    selectedMode: 'single',
-                    radius: [40, 80],
-                    center: ['35%', '50%'],
-                    startAngle: 20,
-                    data: [
-                        {
-                            value: data1,
-                            name: '',
-                            label: {
-                                normal: {
-                                    show: false,
-                                    formatter: '{c|{c}辆} \n {a|本日外来\n车辆总数}',
-                                    rich: {
-                                        c: {
-                                            color: '#000',
-                                            fontSize: 20,
-                                            fontWeight: 'bold',
-                                            lineHeight: 2,
-                                            align: 'center',
-                                            padding: [30, 0, 30, 0],
-                                        },
-                                        a: {
-                                            align: 'center',
-                                            color: 'rgb(98,137,169)',
-                                            fontSize: 12,
-                                            padding: [16, 0, -10, -10],
-                                        },
-                                    },
-                                    position: 'center',
-                                },
-                            },
-                        },
-                    ],
-                },
-            ],
-        })
-        window.addEventListener('resize', () => {
-            this.state.chart.resize()
-        })
-    }
+          },
+          data: baseData,
+        },
+      ],
+    })
+    window.addEventListener('resize', () => {
+      this.state.chart.resize()
+    })
+  }
 
-    destory() {
-        this.state.chart.dispose()
-        window.removeEventListener('resize', () => {
-            console.log('事件移除')
-        })
-    }
+  destory () {
+    this.state.chart.dispose()
+    window.removeEventListener('resize', () => {
+      console.log('事件移除')
+    })
+  }
 }
 </script>
 <style lang="less"></style>

+ 3 - 1
TEAMModelBI/ClientApp/src/router/index.js

@@ -198,7 +198,9 @@ const router = createRouter({
 router.beforeEach((to, from, next) => {
     console.log(to, 'router')
     if (to.path === '/login') return next()
-    if (to.path === '/accesslayer') return next()
+    if (to.path === '/login-thirdparty') return next()
+    let thirdUser = localStorage.getItem('thirdUser')
+    if (to.path === '/thirdpartys' && thirdUser) return next()
     let recordUser = JSON.parse(localStorage.getItem('userData'));
     let token = jwt_decode(JSON.parse(localStorage.getItem('id_token')))
     if (!recordUser || !token) return next('/login')

+ 22 - 1
TEAMModelBI/ClientApp/src/store/index.js

@@ -16,7 +16,11 @@ export default createStore({
         changbtnShow: false,
         schoolPower: {},
         nowSchool: {},
-        indexTitle: false
+        indexTitle: false,
+        thirdCorrelation: {},
+        thirdUser: {},
+        areaClickschool: {},
+        areaClickCounselor: ''
     },
     mutations: {
         //修改组织架构
@@ -68,6 +72,23 @@ export default createStore({
         //检测是否是首页显示title
         updateTitlestate(state, value) {
             state.indexTitle = value
+        },
+
+        //第三方平台 用户信息
+        thirdUserInfo(state, value) {
+            state.thirdUser = value
+        },
+        //第三方平台 用户关联企业
+        thirdCorrelationInfo(state, value) {
+            state.thirdCorrelation = value
+        },
+        //学区点击学情查看详情
+        areaClick(state, value) {
+            state.areaClickschool = value
+        },
+        //学区点击顾问查看详情
+        clickCounselor(state, value) {
+            state.areaClickCounselor = value
         }
     },
     actions: {},

+ 38 - 0
TEAMModelBI/ClientApp/src/until/common.js

@@ -85,5 +85,43 @@ export default {
         var strDate = Y + M + D;
         return strDate; //2020-07-30 01:05:54
 
+    },
+    toCode(str) { //加密字符串
+        //定义密钥,36个字母和数字
+        var key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        var l = key.length; //获取密钥的长度
+        var a = key.split(""); //把密钥字符串转换为字符数组
+        var s = "",
+            b, b1, b2, b3; //定义临时变量
+        for (var i = 0; i < str.length; i++) { //遍历字符串
+            b = str.charCodeAt(i); //逐个提取每个字符,并获取Unicode编码值
+            b1 = b % l; //求Unicode编码值得余数
+            b = (b - b1) / l; //求最大倍数
+            b2 = b % l; //求最大倍数的于是
+            b = (b - b2) / l; //求最大倍数
+            b3 = b % l; //求最大倍数的余数
+            s += a[b3] + a[b2] + a[b1]; //根据余数值映射到密钥中对应下标位置的字符
+        }
+        return s; //返回这些映射的字符
+    },
+    fromCode(str) {
+        //定义密钥,36个字母和数字
+        var key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        var l = key.length; //获取密钥的长度
+        var b, b1, b2, b3, d = 0,
+            s; //定义临时变量
+        s = new Array(Math.floor(str.length / 3)); //计算加密字符串包含的字符数,并定义数组
+        b = s.length; //获取数组的长度
+        for (var i = 0; i < b; i++) { //以数组的长度循环次数,遍历加密字符串
+            b1 = key.indexOf(str.charAt(d)); //截取周期内第一个字符串,计算在密钥中的下标值
+            d++;
+            b2 = key.indexOf(str.charAt(d)); //截取周期内第二个字符串,计算在密钥中的下标值
+            d++;
+            b3 = key.indexOf(str.charAt(d)); //截取周期内第三个字符串,计算在密钥中的下标值
+            d++;
+            s[i] = b1 * l * l + b2 * l + b3 //利用下标值,反推被加密字符的Unicode编码值
+        }
+        b = eval("String.fromCharCode(" + s.join(',') + ")");
+        return b; //返回被解密的字符串
     }
 }

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

@@ -17,10 +17,9 @@ axios.interceptors.request.use(
                 'Content-Type': 'application/json',
                 'x-auth-authtoken': JSON.parse(localStorage.id_token),
             }
-        } else if (config.url.indexOf('business') != -1) {
+        } else if (config.url.indexOf('/business/get-info') != -1) {
             config.headers = {
                 'Content-Type': 'application/json',
-                'x-auth-authtoken': JSON.parse(localStorage.id_token),
                 'site': 'china'
             }
         } else {

+ 154 - 42
TEAMModelBI/ClientApp/src/view/areamanage/statistics.vue

@@ -86,7 +86,7 @@
   <!--详细某个学区-->
   <div class="statisticsbox" v-if="showPattern ==='details'">
     <c-scrollbar ref="scrollbarRef" width="100%" height="88vh" trigger="hover" direction="y">
-      <div class="headerbox">
+      <div class="headerbox" v-loading="aspectsLoading.counselorData" element-loading-background="rgba(0, 0, 0, 0.3)">
         <div class="header-title">
           <p class="header-item-name">{{nowArea.name}}</p>
           <p class="header-item-school"><span class="header-item-school-title">学区学校数:</span><span class="header-item-school-content">{{nowArea.schoolCount}}</span></p>
@@ -94,20 +94,15 @@
           <p class="header-item-school"><span class="header-item-school-title">学区学生数:</span><span class="header-item-school-content">{{nowArea.studentCount}}</span></p>
           <p class="header-item-school">
           <div class="header-item-school-title-counselor">学区内顾问:</div>
-          <div class="counselor-item" @click="leaves">
+          <div class="counselor-item" @click="leaves(item)" v-for="item in CounselorList">
             <span class="header-item-school-content">
-              <div class="counselor-img">
-                <PersonalPhoto style="cursor: pointer;" width="30px" height="30px" name="陈明洋"></PersonalPhoto>
+              <div class="counselor-img" v-if="!item.picture">
+                <PersonalPhoto style="cursor: pointer;" width="30px" height="30px" :name="item.name"></PersonalPhoto>
               </div>
-              <div class="counselor-name">陈明洋</div>
-            </span>
-          </div>
-          <div class="counselor-item" @click="leaves">
-            <span class="header-item-school-content">
-              <div class="counselor-img">
-                <PersonalPhoto style="cursor: pointer;" width="30px" height="30px" name="彭礼"></PersonalPhoto>
+              <div class="counselor-img" v-else>
+                <el-image style="width: 30px; height: 30px;border-radius:50%" :src="item.picture" fit="fill" />
               </div>
-              <div class="counselor-name">彭礼</div>
+              <div class="counselor-name">{{item.name}}</div>
             </span>
           </div>
           </p>
@@ -116,11 +111,11 @@
           <svg class="header-back" aria-hidden="true" @click="showPattern='all'">
             <use xlink:href="#icon-fanhui1"></use>
           </svg>
-          <span @click="showPattern='all'">返回总学区</span>
+          <span @click="backIndex">返回总学区</span>
         </div>
       </div>
       <div class="top-resource">
-        <div class="top-aspects" v-for="(item,index) in aspectsData" :key="index">
+        <div class="top-aspects" v-for="(item,index) in aspectsData" :key="index" v-loading="aspectsLoading.headerBasics" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div :class="[item.classname,'left-top-icon']">
             <svg :class="'top-header-icon'" aria-hidden="true">
               <use :xlink:href="item.icon"></use>
@@ -140,7 +135,7 @@
             </div>
           </div>
         </div>
-        <div class="leftbox">
+        <div class="leftbox" v-loading="aspectsLoading.basics" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div class="tagbox">
             <p class="tags basics"><span>基础数据</span></p>
           </div>
@@ -149,7 +144,7 @@
             <p :class="[items.type ==='month' ? 'alonebox-content':'total-alonebox-content']">{{items.num}}</p>
           </div>
         </div>
-        <div class="rightbox">
+        <div class="rightbox" v-loading="aspectsLoading.basics" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div class="tagbox">
             <p class="tags basics"><span>基础数据</span></p>
           </div>
@@ -165,7 +160,7 @@
         </div>
       </div>
       <div class="center-resource">
-        <div class="center-resource-left">
+        <div class="center-resource-left" v-loading="aspectsLoading.class" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div class="tagbox ">
             <p class="tags source"><span>课例数据</span></p>
           </div>
@@ -185,7 +180,7 @@
           </div>
 
         </div>
-        <div class="center-resource-right">
+        <div class="center-resource-right" v-loading="aspectsLoading.classWeek" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div class="tagbox">
             <p class="tags dynamic"><span>课例活跃度</span></p>
           </div>
@@ -193,13 +188,13 @@
         </div>
       </div>
       <div class="bottom-resource">
-        <div class="bottom-leftbox">
+        <div class="bottom-leftbox" v-loading="aspectsLoading.research" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div class="tagbox">
             <p class="tags types"><span>研修进度</span></p>
           </div>
           <DoublePie :doublePieData="areaData.schedule"></DoublePie>
         </div>
-        <div class="bottom-rightbox">
+        <div class="bottom-rightbox" v-loading="aspectsLoading.size" element-loading-background="rgba(0, 0, 0, 0.3)">
           <div class="tagbox">
             <p class="tags interspace"><span>空间使用情况</span></p>
           </div>
@@ -211,12 +206,36 @@
           </div>
         </div>
       </div>
+      <div class="school-Listinfo" v-loading="aspectsLoading.schoolList" element-loading-background="rgba(0, 0, 0, 0.3)">
+        <div class="tagbox">
+          <p class="tags schoolLists"><span>学校列表</span></p>
+        </div>
+        <div class="listbox">
+          <el-table :data="schooltableData" style="width:100%" height="300" empty-text="暂无数据">
+            <el-table-column label="校徽" align="center">
+              <template #default="scope">
+                <div class="school-badge">
+                  <el-image :src="scope.row.picture" fit="fill" />
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="name" label="名称" align="center" />
+            <el-table-column prop="id" label="简码" align="center" />
+            <el-table-column prop="size" label="空间" align="center" />
+            <el-table-column align="center">
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="detailsclick(scope.row)">详情</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
     </c-scrollbar>
   </div>
   <!--详细某个学区end-->
 </template>
 <script>
-import { ref, getCurrentInstance } from 'vue'
+import { ref, getCurrentInstance, watch } from 'vue'
 import CommonPie from '@/components/echarts/commonPie.vue'
 import ConventionPie from '@/components/echarts/conventionPie.vue'
 import CommonLine from '@/components/echarts/commonLine.vue'
@@ -225,6 +244,7 @@ import Liquidfill from '@/components/echarts/liquidfill.vue'
 import CommonBar from '@/components/echarts/commonBar.vue'
 import { ElMessage, ElLoading } from 'element-plus'
 import { useRouter } from 'vue-router'
+import { useStore } from 'vuex'
 import * as echarts from 'echarts'
 import 'echarts-liquidfill'
 export default {
@@ -239,6 +259,7 @@ export default {
   setup () {
     let { proxy } = getCurrentInstance()
     let router = useRouter()
+    const store = useStore()
     let showPattern = ref('all')
     let aspectsData = ref([
       { id: 1, title: '区内学校', num: 0, icon: '#icon-renshixuexiao', classname: 'school' },
@@ -247,6 +268,16 @@ export default {
       { id: 4, title: '产出总数据', num: 0, icon: '#icon-ziyuan1', classname: 'datas' },
       { id: 5, title: '空间总容量', num: 0, icon: '#icon-kongjian', classname: 'size' },
     ])
+    let aspectsLoading = ref({
+      counselorData: true,
+      headerBasics: true,
+      basics: true,
+      class: true,
+      classWeek: true,
+      research: true,
+      size: true,
+      schoolList: true,
+    })
     let activityData = ref({
       total: [
         { id: 1, title: '本周课例数', num: 0, type: 'month' },
@@ -306,6 +337,9 @@ export default {
       classLine: true,
       areaList: true,
     })
+    let schooltableData = ref([])
+    //某个学区顾问列表
+    let CounselorList = ref([])
     //总区域echarts需要数据
     let totalArea = ref({
       //单独的饼图
@@ -744,7 +778,6 @@ export default {
                 color: '#fff',
               },
             },
-
             data: [],
           },
         ],
@@ -1309,7 +1342,7 @@ export default {
                 globalCoord: false,
               },
             ],
-            data: [.6], // data个数代表波浪数
+            data: [0], // data个数代表波浪数
             backgroundStyle: {
               borderWidth: 1,
               color: 'RGBA(51, 66, 127, 0.7)',
@@ -1354,7 +1387,7 @@ export default {
             radius: '90%',
             center: ['50%', '50%'],
             itemStyle: {
-              borderRadius: 2,
+              borderRadius: 8,
             },
             label: {
               normal: {
@@ -1434,11 +1467,13 @@ export default {
             let activityAndclass = { classData: [], activityData: [] }
             let nameData = []
             for (let i in res.areaInfos) {
-              let classdata = { id: res.areaInfos[i].id, value: res.areaInfos[i].lessCount, name: res.areaInfos[i].name }
-              classPie.push(classdata)
-              nameData.push(res.areaInfos[i].name)
-              activityAndclass.classData.push(res.areaInfos[i].lessCount)
-              activityAndclass.activityData.push(res.areaInfos[i].activityCount)
+              if (i < 10) {
+                let classdata = { id: res.areaInfos[i].id, value: res.areaInfos[i].lessCount, name: res.areaInfos[i].name + '(' + res.areaInfos[i].lessCount + ')' }
+                classPie.push(classdata)
+                nameData.push(res.areaInfos[i].name)
+                activityAndclass.classData.push(res.areaInfos[i].lessCount)
+                activityAndclass.activityData.push(res.areaInfos[i].activityCount)
+              }
             }
             totalArea.value.class.series[0].data = classPie
             totalArea.value.classAndactivity.xAxis.data = nameData
@@ -1477,6 +1512,7 @@ export default {
               areaData.value.dynamic.series[0].data = res.weeks
               areaData.value.dynamic.series[1].data = res.weeks
               areaData.value.dynamic.xAxis.data = namedata
+              aspectsLoading.value.classWeek = false
             }
           }
         })
@@ -1490,11 +1526,6 @@ export default {
       if (!areaids) {
         return ElMessage.error('无区域ID')
       }
-      let loadingareas = ElLoading.service({
-        lock: true,
-        text: '正在加载学区数据,请稍等...',
-        background: 'rgba(0, 0, 0, 0.7)',
-      })
       nowArea.value.name = areaids.name
       nowArea.value.schoolCount = areaids.schoolCount
       nowArea.value.teacherCount = areaids.techCount
@@ -1523,26 +1554,59 @@ export default {
             aspectsData.value[1].num = teachNums
             aspectsData.value[2].num = parseInt(res.weekLess) + parseInt(res.weekActivity)
             aspectsData.value[3].num = parseInt(res.allLess) + parseInt(activityData.value.oneself[7].num)
+            aspectsLoading.value.headerBasics = false
           }
           //版本占比
           areaData.value.versions.series[0].data[0].value = res.basics
           areaData.value.versions.series[0].data[1].value = res.standard
           areaData.value.versions.series[0].data[2].value = res.major
+          aspectsLoading.value.basics = false
           //课例活动数据
           for (let s in res.schoolLessons) {
             res.schoolLessons[s].value = res.schoolLessons[s].count
           }
           areaData.value.class.series[0].data = res.schoolLessons
+          aspectsLoading.value.class = false
+          getcounselor(areaids.id)
           getClassLivelys(areaids.id)
-          employSize(areaids.id, loadingareas)
+          employSize(areaids.id)
           researchData(areaids.id)
+          getAreaSchool(areaids.id)
         })
         .catch((res) => {
           ElMessage.error('获取学区统计数据失败')
         })
     }
+    //获取某个学区的顾问情况
+    function getcounselor (val) {
+      if (!val) {
+        ElMessage.error('学区ID异常,无法获取顾问列表')
+        return
+      }
+      let data = { areaId: val }
+      proxy.$api.getCounselorlist(data).then((res) => {
+        console.log(res, '学区顾问')
+        res.state === 200 ? (CounselorList.value = res.areaAssists, aspectsLoading.value.counselorData = false) : ''
+      }).catch((error) => {
+        ElMessage.error('顾问列表获取异常')
+      })
+    }
+    //获取某个学区学校列表
+    function getAreaSchool (val) {
+      if (!val) {
+        ElMessage.error('学区ID异常,无法获取学校列表')
+        return
+      }
+      let data = { areaId: val }
+      proxy.$api.getAreaSchoolList(data).then((res) => {
+        console.log(res, 'xuexiaoliebiao')
+        res.state === 200 ? (schooltableData.value = res.areaSchool, aspectsLoading.value.schoolList = false) : ''
+      }).catch((error) => {
+        ElMessage.error('学区内学校列表获取异常')
+      })
+    }
     //获取某个学区的空间使用率和明细
-    function employSize (areaIds, loadingareas) {
+    function employSize (areaIds) {
       if (!areaIds) {
         return ElMessage.error('无区域ID')
       }
@@ -1566,8 +1630,8 @@ export default {
               }
             }
             areaData.value.sizeProportion.series[0].data = res.typeCount
+            aspectsLoading.value.size = false
             console.log(res, '结果')
-            loadingareas.close()
           }
         })
         .catch((res) => {
@@ -1610,6 +1674,7 @@ export default {
             areaData.value.schedule.legend.data = outer
             areaData.value.schedule.series[0].data = within
             areaData.value.schedule.series[1].data = outer
+            aspectsLoading.value.research = false
           }
         })
         .catch((res) => {
@@ -1628,12 +1693,33 @@ export default {
         // originalDatas.value.push(...res.areas)
       })
     }
-    function leaves () {
+    function backIndex () {
+      aspectsLoading.value.headerBasics = true,
+        aspectsLoading.value.basics = true,
+        aspectsLoading.value.class = true,
+        aspectsLoading.value.classWeek = true,
+        aspectsLoading.value.research = true,
+        aspectsLoading.value.size = true,
+        showPattern.value = 'all'
+    }
+    function leaves (val) {
       // router.push('/home/campus')
+      console.log(val, 3333)
+      store.commit('clickCounselor', val.tmdId)
       router.push({ path: 'campus', query: { pattern: 'area' } })
     }
+    function detailsclick (value) {
+      console.log(value, '66666')
+      let data = value
+      store.commit('areaClick', data)
+      console.log(store.state, '9999999')
+      router.push('/home/campus')
+    }
     getAll()
     getoption()
+    watch(showPattern, (newValue, oldValue) => {
+      newValue === 'all' ? backIndex() : ''
+    })
     return {
       aspectsData,
       showPattern,
@@ -1651,7 +1737,14 @@ export default {
       nowArea,
       researchData,
       loadingTotal,
-      leaves
+      leaves,
+      aspectsLoading,
+      backIndex,
+      schooltableData,
+      getcounselor,
+      CounselorList,
+      getAreaSchool,
+      detailsclick
     }
   },
 }
@@ -2086,8 +2179,15 @@ export default {
   font-size: 14px;
   color: #7f8fa6;
 }
+.school-badge {
+  width: 70px;
+  height: 70px;
+  margin: 0 auto;
+}
+
 .school,
-.basics {
+.basics,
+.schoolLists {
   background: rgb(45, 140, 240);
 }
 .teach,
@@ -2141,6 +2241,10 @@ export default {
   display: inline-block;
   vertical-align: top;
 }
+.counselor-img {
+  width: 30px;
+  height: 30px;
+}
 .counselor-item {
   padding: 3px 5px;
   border: 1px solid #ccc;
@@ -2152,10 +2256,18 @@ export default {
 .counselor-name {
   margin-left: 5px;
 }
+.school-Listinfo {
+  width: 99.6%;
+  margin-top: 0px;
+  padding: 30px 0px 15px 0px;
+  position: relative;
+  background-color: #fff;
+}
 </style>
 
 <style>
-.statisticsbox-all .el-loading-spinner .circular {
-  display: inline;
+.statisticsbox-all .el-loading-spinner .circular,
+.statisticsbox .el-loading-spinner .circular {
+  display: inline !important;
 }
 </style>

+ 1 - 1
TEAMModelBI/ClientApp/src/view/common/aside.vue

@@ -310,7 +310,7 @@ export default {
         let name = userRoles[n]
         console.log(name)
         for (let i in schoolMenus) {
-          if (schoolMenus[i].name === '区校掌握') { continue }
+          // if (schoolMenus[i].name === '区校掌握') { continue }
           schoolMenus[i].role.indexOf('all') != -1 ? menuList.value.push(schoolMenus[i]) : ''
           schoolMenus[i].role.includes(name) ? menuList.value.push(schoolMenus[i]) : ''
           user.azp && schoolMenus[i].role.includes('special') ? menuList.value.push(schoolMenus[i]) : ''

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

@@ -548,7 +548,8 @@ export default {
       { id: 3, title: '学校总数', num: 0, icon: '#icon-all-school', classname: 'datas', state: '1', teach: 0, student: 0, increase: 0 },
       { id: 4, title: '教师总数', num: 0, icon: '#icon-laoshi1', classname: 'teach', state: '1', teach: 0, student: 0, increase: 0 },
       { id: 5, title: '学生总数', num: 0, icon: '#icon-xuesheng1', classname: 'student', state: '1', teach: 0, student: 0, increase: 0 },
-      { id: 6, title: '异常报错', num: 59, icon: '#icon-yichang-1', classname: 'months', state: '0', teach: 0, student: 0, increase: 0 },
+      // { id: 6, title: '异常报错', num: 59, icon: '#icon-yichang-1', classname: 'months', state: '0', teach: 0, student: 0, increase: 0 },
+      { id: 6, title: 'API访问量', num: 0, icon: '#icon-yichang-1', classname: 'months', state: '0', teach: 0, student: 0, increase: 0 },
     ])
     let worldareaAspectsData = ref([
       { id: 1, title: '当前在线人数', num: 0, icon: '#icon-zaixianyonghu2', classname: 'online', state: '0', teach: 0, student: 0, increase: 0 },
@@ -556,7 +557,7 @@ export default {
       { id: 3, title: '学校总数', num: 0, icon: '#icon-all-school', classname: 'datas', state: '1', teach: 0, student: 0, increase: 0 },
       { id: 4, title: '教师总数', num: 0, icon: '#icon-laoshi1', classname: 'teach', state: '1', teach: 0, student: 0, increase: 0 },
       { id: 5, title: '学生总数', num: 0, icon: '#icon-xuesheng1', classname: 'student', state: '1', teach: 0, student: 0, increase: 0 },
-      { id: 6, title: '异常报错', num: 59, icon: '#icon-yichang-1', classname: 'months', state: '0', teach: 0, student: 0, increase: 0 },
+      // { id: 6, title: '异常报错', num: 59, icon: '#icon-yichang-1', classname: 'months', state: '0', teach: 0, student: 0, increase: 0 },
     ])
     let areaLists = ref([
       // { id: 1, name: '醍摩豆智慧学区', schoolNum: 5, teachNum: 830, studentNum: 3340 },
@@ -2304,6 +2305,7 @@ export default {
               areaAspectsData.value[3].increase = res.todayTchCnt
               areaAspectsData.value[4].num = res.stuCnt
               areaAspectsData.value[4].increase = res.todayStuCnt
+              areaAspectsData.value[5].num = res.apiCnt
             } else if (siteValue.value === 'international') {
               worldareaAspectsData.value[0].num = parseInt(res.onStuCnt) + parseInt(res.onTchCnt)
               worldareaAspectsData.value[0].teach = res.onTchCnt

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1285 - 293
TEAMModelBI/ClientApp/src/view/schoolmanage/schoolAnalyse.vue


+ 37 - 8
TEAMModelBI/ClientApp/src/view/thirdparty/details.vue

@@ -60,7 +60,7 @@
                   <el-form-item label="企业秘钥" class="token-box">
                     <div class="tokenbox">
                       <!-- <el-input v-model="setform.token" :rows="2" type="textarea" @input="saveState=true" v-if="PowerShow" /> -->
-                      <el-input v-model="setform.token" :rows="2" type="textarea" disabled />
+                      <el-input v-model="setform.token" :rows="3" type="textarea" disabled />
                     </div>
                     <div class="generatebox" v-if="PowerShow">
                       <el-button type="primary" size="small" @click="againGenerate('token')">重新生成秘钥</el-button>
@@ -122,6 +122,9 @@
               </div>
             </div>
           </el-tab-pane>
+          <el-tab-pane label="人员管理" name="personnel">
+            111
+          </el-tab-pane>
         </el-tabs>
       </div>
       <!--添加关联学校弹窗-->
@@ -164,9 +167,9 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 import { Search } from '@element-plus/icons-vue'
 export default {
   props: {
-    clickDetails: {
+    firmData: {
       default: () => { },
-    }
+    },
   },
   components: {
     Search
@@ -244,8 +247,8 @@ export default {
     }
     //获取企业相关联的学校列表
     function relevanceSchools () {
-      // let companyID = setform.value.rowKey
-      let companyID = '94e4e8de-57cf-4ef9-b2ac-8e48fcb8028a'
+      let companyID = setform.value.rowKey
+      //let companyID = '94e4e8de-57cf-4ef9-b2ac-8e48fcb8028a'
       let data = { id: companyID }
       proxy.$api.relevanceSchool(data).then((res) => {
         console.log(res, '关联学校的列表')
@@ -354,11 +357,33 @@ export default {
         ElMessage.error('API异常,保存失败')
       })
     }
+    //获取当前企业的信息内容
+    function getFirmDetails (item) {
+      let data = { id: item.bizRowKey }
+      console.log(data)
+      // proxy.$api.getAllthirdparty(data).then((res) => {
+      //   console.log(res, '企业信息')
+      //   if (res.state === 200) {
+      //     setform.value = res.companys[0]
+      //     setform.value.imageUrl = res.companys[0].picture
+      //     // relevanceSchools()
+      //   }
+      // }).catch((error) => {
+      //   ElMessage.error('信息获取失败,API异常')
+      // })
+      proxy.$api.getAllthirdparty(data).then((res) => {
+        if (res.state === 200) {
+          setform.value = res.companys[0]
+          setform.value.imageUrl = res.companys[0].picture
+        }
+      })
+    }
     watch(
       props,
       (newsProps) => {
         console.log(newsProps, '传来的值')
-        newsProps.clickDetails ? (setform.value = newsProps.clickDetails, setform.value.imageUrl = newsProps.clickDetails.picture) : ''
+        // newsProps.firmData ? (setform.value = newsProps.firmData, setform.value.imageUrl = newsProps.clickDetails.picture) : ''
+        newsProps.firmData ? getFirmDetails(newsProps.firmData) : ''
       },
       { immediate: true, deep: true }
     )
@@ -369,7 +394,7 @@ export default {
         schoolLists.value = original.value
       }
     })
-    relevanceSchools()
+    // relevanceSchools()
     uploadInt()
     return {
       activeName,
@@ -398,7 +423,8 @@ export default {
       handleUpdErr,
       uploadHeader,
       deltelogos,
-      PowerShow
+      PowerShow,
+      getFirmDetails
     }
   },
 }
@@ -430,6 +456,7 @@ export default {
   padding: 0.5%;
   margin: 0 auto;
   overflow: auto;
+  position: relative;
 }
 .set-basics-title {
   text-align: left;
@@ -477,6 +504,8 @@ export default {
   font-size: 22px;
   font-weight: bold;
   color: #bdc3c7;
+  position: absolute;
+  left: 45%;
 }
 .addrelevancy-icon {
   width: 1.2em;

+ 148 - 49
TEAMModelBI/ClientApp/src/view/thirdparty/index.vue

@@ -1,19 +1,40 @@
 <template>
   <div class="loggedbox" v-if="showModel ==='default'">
+    <div class="topbox">
+      <div class="userright">
+        <el-dropdown placement="bottom-start">
+          <el-icon style="margin-right: 25px;margin-top:8px" v-if="userBasics.picture">
+            <el-avatar :size="40" :src="userBasics.picture"></el-avatar>
+          </el-icon>
+          <PersonalPhoto style="cursor: pointer;" :name="userBasics.name" width="40px" height="40px" v-else></PersonalPhoto>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item @click="quit">
+                <svg class="header-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tuichu"></use>
+                </svg>
+                {{$t(`header.quit`)}}
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
     <div class="header-basics">
       <div class="basics-content">
         <div class="basics-left">
-          <div class="basics-left-title">早上好,XXX,欢迎来到第三方合作平台</div>
+          <div class="basics-left-title">{{welcomeText}},{{userBasics.name}},欢迎来到第三方合作平台</div>
           <div class="basics-left-weather">{{place.province}}{{place.city}} 天气:{{place.weather}}
-            温度:{{place.temp}}摄氏度 风向:{{place.windDir}} 风力:{{place.windScale}} 空气湿度:{{place.humidity}} 能见度:{{place.vis}}公里</div>
+            温度:{{place.temp}}摄氏度 风向:{{place.windDir}} 风力:{{place.windScale}} 相对湿度:{{place.humidity}}% 能见度:{{place.vis}}公里</div>
           <div class="basics-left-content">
             <div class="basics-content-row">
               <div class="basics-text">
                 <div class="basics-text-content">
                   <el-icon>
-                    <Sort />
+                    <Avatar />
                   </el-icon>
-                  今日数据数(123456)
+                  <div>醍摩豆账户:</div>
+                  <div>{{userBasics.tmdId}}</div>
                 </div>
               </div>
               <div class="basics-text">
@@ -21,7 +42,8 @@
                   <el-icon>
                     <OfficeBuilding />
                   </el-icon>
-                  目前管理企业(3)
+                  <div> 目前管理企业</div>
+                  <div>({{correlationFirm.length}})</div>
                 </div>
               </div>
               <div class="basics-text">
@@ -29,19 +51,26 @@
                   <el-icon>
                     <School />
                   </el-icon>
-                  企业关联学校(59)
+                  <div>企业关联学校</div>
+                  <div>(59)</div>
                 </div>
               </div>
             </div>
           </div>
           <div class="account">
-            <div class="account-box"><span>醍摩豆账户:</span><span>1456325879</span></div>
+            <!-- <div class="account-box">
+              <el-icon>
+                <Avatar />
+              </el-icon>
+              <div>醍摩豆账户:</div>
+              <div>{{userBasics.tmdId}}</div>
+            </div> -->
           </div>
         </div>
         <img :src="bgUrl" class="bg-img" />
       </div>
     </div>
-    <div class="center-entrance">
+    <!-- <div class="center-entrance">
       <div class="center-entrance-box">
         <div class="center-header">
           <div class="center-header-text"><span>快捷入口</span></div>
@@ -81,70 +110,50 @@
           </div>
         </div>
       </div>
-    </div>
+    </div> -->
     <div class="bottombox">
       <div class="bottombox-content">
         <div class="bottombox-content-header">
           <div class="header-title"><span>关联企业列表</span></div>
         </div>
-        <div class="school-List">
-          <div class="school-List-item" @click="showModel='details'">
-            <div class="school-List-item-img">
-              <el-image style="" :src="qiyebg" fit="fill" />
-            </div>
-            <div class="enterprise-item-content">
-              <p class="enterprise-item-content-name">醍摩豆(成都)信息技术有限公司</p>
-              <p class="enterprise-item-content-code"><span>信用代码:</span><span>91510104MA62L1YP8J</span></p>
-            </div>
-          </div>
-          <div class="school-List-item" @click="showModel='details'">
-            <div class="school-List-item-img">
-              <el-image style="" :src="qiyebg" fit="fill" />
-            </div>
-            <div class="enterprise-item-content">
-              <p class="enterprise-item-content-name">醍摩豆(成都)信息技术有限公司</p>
-              <p class="enterprise-item-content-code"><span>信用代码:</span><span>91510104MA62L1YP8J</span></p>
-            </div>
-          </div>
-          <div class="school-List-item" @click="showModel='details'">
-            <div class="school-List-item-img">
-              <el-image style="" :src="qiyebg" fit="fill" />
-            </div>
-            <div class="enterprise-item-content">
-              <p class="enterprise-item-content-name">醍摩豆(成都)信息技术有限公司</p>
-              <p class="enterprise-item-content-code"><span>信用代码:</span><span>91510104MA62L1YP8J</span></p>
-            </div>
-          </div>
-          <div class="school-List-item" @click="showModel='details'">
+        <div class="school-List" v-if="correlationFirm.length !=0">
+          <div class="school-List-item" @click="clickItem(item)" v-for="(item,index) in correlationFirm" :key="index">
             <div class="school-List-item-img">
-              <el-image style="" :src="qiyebg" fit="fill" />
+              <el-image style="" :src="item.bizPicture" fit="fill" />
             </div>
             <div class="enterprise-item-content">
-              <p class="enterprise-item-content-name">醍摩豆(成都)信息技术有限公司</p>
-              <p class="enterprise-item-content-code"><span>信用代码:</span><span>91510104MA62L1YP8J</span></p>
+              <p class="enterprise-item-content-name">{{item.bizName}}</p>
+              <p class="enterprise-item-content-code"><span>信用代码:</span><span>{{item.bizCredit}}</span></p>
             </div>
           </div>
         </div>
+        <div class="school-List" v-else-if="correlationFirm.length ===0">
+          <div class="notdatas">暂无关联企业</div>
+        </div>
       </div>
     </div>
   </div>
   <div class="detailsbox" v-else-if="showModel ==='details'">
-    <Detalis @backState="changestate"></Detalis>
+    <Detalis @backState="changestate" :firmData="nowCorrelation"></Detalis>
   </div>
 </template>
 <script>
-import { Sort, OfficeBuilding, School } from '@element-plus/icons-vue'
-import { ref, getCurrentInstance, watch } from 'vue'
+import { Sort, OfficeBuilding, School, Avatar } from '@element-plus/icons-vue'
+import { ref, getCurrentInstance, watch, onMounted } from 'vue'
 import Detalis from './details.vue'
+import { useStore } from 'vuex'
+import { useRouter } from 'vue-router'
 export default {
   components: {
-    Sort, OfficeBuilding, School, Detalis
+    Sort, OfficeBuilding, School, Detalis, Avatar
   },
   setup () {
     let bgUrl = require('@/assets/img/thirdparty-index.png')
     let qiyebg = require('@/assets/img/tmd_logo.png')
+    let router = useRouter()
     let showModel = ref('default')
     let { proxy } = getCurrentInstance()
+    let welcomeText = timer()
     let place = ref({
       province: '',
       city: '',
@@ -156,9 +165,37 @@ export default {
       vis: '',
     })
     let cityCode = ref()
+    const store = useStore()
+    let userBasics = ref(store.state.thirdUser)
+    let correlationFirm = ref([])
+    let nowCorrelation = ref()
+    console.log(store.state, '用户数据是否过来')
+    onMounted(() => {
+      let user = localStorage.getItem('thirdUser')
+      let result = JSON.parse(proxy.$common.fromCode(user))
+      console.log(result, '解析后')
+      userBasics.value = result.user
+      correlationFirm.value = result.correlation
+    })
     function changestate (val) {
       val === 'default' ? showModel.value = 'default' : ''
     }
+    function timer () {
+      var time_now = new Date();
+      var year = time_now.getYear() + 1900;	//年
+      var month = time_now.getMonth();	//月份
+      var day = time_now.getDate();		//日
+      var hour = time_now.getHours();	//小时
+      let welcome = ''
+      if (hour >= 0 && hour < 12) {
+        welcome = "上午好";
+      } else if (hour >= 12 && hour <= 18) {
+        welcome = "下午好";
+      } else {
+        welcome = "晚上好";
+      }
+      return welcome
+    }
     function getlocaltion () {
       proxy.$api.getlocation('753b06a025d7fe62bdca1ff453149bfc', '182.139.161.4').then((res) => {
         console.log(res)
@@ -185,8 +222,16 @@ export default {
           console.log(error)
         })
     }
+    function clickItem (val) {
+      nowCorrelation.value = val
+      showModel.value = 'details'
+    }
+    function quit () {
+      localStorage.clear();
+      router.push('/login-thirdparty')
+    }
     getlocaltion()
-    return { bgUrl, qiyebg, showModel, changestate, test, getlocaltion, cityCode, place }
+    return { bgUrl, qiyebg, showModel, changestate, test, getlocaltion, cityCode, place, userBasics, timer, welcomeText, correlationFirm, nowCorrelation, clickItem, quit }
   },
 }
 </script>
@@ -198,7 +243,8 @@ export default {
 }
 .header-basics,
 .center-entrance,
-.bottombox {
+.bottombox,
+.topbox {
   padding: 12px 16px;
 }
 .basics-content {
@@ -246,6 +292,7 @@ export default {
   display: block;
   max-width: 33.3333333333%;
   flex: 0 0 33.3333333333%;
+  text-align: center;
 }
 .basics-text-content {
   display: flex;
@@ -328,7 +375,7 @@ export default {
   box-sizing: border-box;
   background-color: #fff;
   border-radius: 2px;
-  height: 45vh;
+  height: 61vh;
   padding: 26px 30px;
   overflow: hidden;
   box-shadow: 0 0 7px 1px rgb(0 0 0 / 3%);
@@ -341,14 +388,16 @@ export default {
 }
 .school-List {
   width: 100%;
-  height: 35vh;
+  height: 51vh;
   overflow: auto;
   display: flex;
   justify-content: flex-start;
   flex-wrap: wrap;
+  position: relative;
 }
 .school-List-item {
   width: 25%;
+  height: 260px;
   padding: 1%;
   border: 1px solid #ccc;
   margin-top: 1%;
@@ -386,6 +435,32 @@ export default {
 .account-box {
   width: 32%;
 }
+.basics-text-content div {
+  margin-top: 2px;
+  margin-left: 2px;
+  display: inline-block;
+  vertical-align: top;
+}
+.topbox {
+  position: relative;
+  height: 60px;
+  background-color: #fff;
+  text-align: right;
+}
+.userright {
+  /* width: 70%; */
+  /* text-align: right; */
+  position: absolute;
+  right: 20px;
+}
+.notdatas {
+  position: absolute;
+  top: 45%;
+  left: 45%;
+  font-size: 24px;
+  font-weight: bold;
+  color: #bdc3c7;
+}
 ::-webkit-scrollbar {
   width: 7px; /*滚动条宽度*/
   height: 7px; /*滚动条高度*/
@@ -397,4 +472,28 @@ export default {
   background-color: rgba(221, 222, 224); /*滚动条的背景颜色*/
   border-radius: 5px;
 }
+</style>
+<style>
+.header-icon {
+  width: 1.2em;
+  height: 1.2em;
+  vertical-align: -0.3em;
+  fill: currentColor;
+  overflow: hidden;
+  margin-right: 5px;
+}
+.log-icon {
+  width: 2em;
+  height: 2em;
+  vertical-align: 0.5em;
+  fill: currentColor;
+  overflow: hidden;
+  margin-right: 5px;
+}
+.log-icon:hover {
+  cursor: pointer;
+}
+.logsbox .el-icon-s-order {
+  font-size: 16px;
+}
 </style>

+ 110 - 7
TEAMModelBI/ClientApp/src/view/thirdparty/login.vue

@@ -2,7 +2,7 @@
   <div class="loginbox-thirdparty">
     <div class="loginboxs">
       <div class="login_panle_right"></div>
-      <div class="login_panle_form">
+      <div class="login_panle_form" v-show="loginModels==='default'">
         <div class="login_panle_form_title"><span>第三方企业登录</span></div>
         <div class="login-form">
           <el-form :model="form" label-width="0px">
@@ -25,29 +25,113 @@
               </el-input>
             </el-form-item>
             <el-form-item>
-              <el-button class="loginbtn-thirdparty">注册</el-button>
-              <el-button type="primary" class="loginbtn-thirdparty">登录</el-button>
+              <el-button class="loginbtn-thirdparty" @click="loginModels='register'">注册</el-button>
+              <el-button type="primary" class="loginbtn-thirdparty" @click="logins">登录</el-button>
             </el-form-item>
           </el-form>
         </div>
       </div>
+      <div class="login-panle-register" v-show="loginModels==='register'">
+        <div class="registerbox">
+          <p>注册账号</p>
+          <div class="register-form">
+            <el-form :model="register" label-width="85px">
+              <el-form-item label="用户姓名">
+                <el-input v-model="register.name" placeholder="请输入用户姓名">
+                </el-input>
+              </el-form-item>
+              <el-form-item label="联系方式">
+                <el-input v-model="register.mobile" placeholder="请输入联系方式">
+                </el-input>
+              </el-form-item>
+              <el-form-item label="账户密码">
+                <el-input v-model="register.pwd" placeholder="请输入账户密码">
+                </el-input>
+              </el-form-item>
+              <el-form-item label="邮箱地址">
+                <el-input v-model="register.mail" placeholder="请输入邮箱地址">
+                </el-input>
+              </el-form-item>
+              <el-form-item>
+                <el-button class="loginbtn-thirdparty" @click="registerUser" type="primary">申请账号</el-button>
+                <el-button class="loginbtn-thirdparty" @click="loginModels='default'">返回登录</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
+        </div>
+      </div>
     </div>
   </div>
 </template>
 <script>
 import { ref, reactive, getCurrentInstance } from 'vue'
 import { User, Key } from '@element-plus/icons-vue'
+import { ElMessage, ElLoading } from 'element-plus'
+import { useRouter } from 'vue-router'
+import { useStore } from 'vuex'
 export default {
   components: {
     User,
     Key,
   },
   setup () {
-    const form = reactive({
+    let { proxy } = getCurrentInstance()
+    let router = useRouter()
+    const store = useStore()
+    const form = ref({
       user: '',
       password: '',
     })
-    return { form }
+    let register = ref({
+      name: '',
+      mobile: '',
+      mail: '',
+      pwd: '',
+    })
+    let loginModels = ref('default')
+    function logins () {
+      let uservalue = form.value.user
+      let reg = new RegExp("^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$")
+      var reg_phone = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
+      let resultEmail = reg.test(uservalue)
+      let resultPhone = reg_phone.test(uservalue)
+      console.log(resultEmail, resultPhone)
+      let data = { pwd: form.value.password }
+      if (resultEmail) {
+        data.mail = uservalue
+      } else if (resultPhone) {
+        data.mobile = uservalue
+      } else {
+        data.tmdId = uservalue
+      }
+      let users = {
+        user: {}, correlation: []
+      }
+      proxy.$api.thirdlogins(data).then((res) => {
+        console.log(res, '登录返回')
+        res.state === 404 ? ElMessage.error('账户未注册开放平台,请核实账号')
+          : res.state === 200 ? (ElMessage.success('登录成功,请稍等...'),
+            store.commit('thirdUserInfo', res.bizUser),
+            store.commit('thirdCorrelationInfo', res.relBizInfos),
+            users.user = res.bizUser, users.correlation = res.relBizInfos,
+            localStorage.setItem('thirdUser', proxy.$common.toCode(JSON.stringify(users))),
+            localStorage.setItem('openid_token', JSON.stringify(res.openid_token)),
+            router.push('/thirdpartys'))
+            : res.state === 40301 ? ElMessage.error('密码错误,请重新登录') : ''
+      }).catch((error) => {
+        ElMessage.error('登录请求失败')
+      })
+    }
+    function registerUser () {
+      let data = { name: register.value.name, mobile: register.value.mobile, pwd: register.value.pwd, mail: register.value.mail }
+      proxy.$api.registerThirdparty(register.value).then((res) => {
+        console.log(res, '注册的账号')
+        res.state === 200 ? (ElMessage.success('注册成功'), loginModels.value = 'default') : ''
+      }).catch((error) => {
+        ElMessage.error('注册失败,API异常')
+      })
+    }
+    return { form, logins, proxy, loginModels, register, registerUser }
   },
 }
 </script>
@@ -77,7 +161,14 @@ export default {
     rgba(223, 230, 233, 0.15) 0px -3px 5px;
 }
 .login_panle_form {
-  width: 420px;
+  width: 500px;
+  background-color: #fff;
+  padding: 40px;
+  border-radius: 25px;
+  box-shadow: 2px 3px 7px rgb(0 0 0 / 10%);
+}
+.login-panle-register {
+  width: 500px;
   background-color: #fff;
   padding: 40px;
   border-radius: 25px;
@@ -110,12 +201,24 @@ export default {
   line-height: 1.2em;
   margin-left: 2px;
 }
+.registerbox {
+  width: 100%;
+}
+.registerbox p {
+  text-align: center;
+  font-size: 18px;
+  font-weight: bold;
+}
+.login-form {
+  padding: 1%;
+}
 </style>
 <style>
 .login-form .el-form-item__content {
   text-align: center;
 }
-.login-form .loginbtn-thirdparty {
+.login-form .loginbtn-thirdparty,
+.registerbox .loginbtn-thirdparty {
   width: 48%;
   margin-top: 2%;
 }

+ 2 - 2
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -2207,6 +2207,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
         {
             try
             {
+                await _dingDing.SendBotMsg($"IES5,{_option.Location},Imei AF call\n{msg.ToJsonString()}", GroupNames.成都开发測試群組);
                 using var json = JsonDocument.Parse(msg);
                 if (json.RootElement.TryGetProperty("channel", out JsonElement channel) &&
                     json.RootElement.TryGetProperty("userid", out JsonElement userid) &&
@@ -2215,7 +2216,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                 {
                     var db = _azureCosmos.GetCosmosClient();
                     foreach (var stu in stus.EnumerateArray())
-                    {
+                    {                        
                         await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIterator(
                             queryText: $"SELECT TOP 1 * FROM c WHERE c.stuid = '{stu.GetString()}'",
                             requestOptions: new() { PartitionKey = new($"Imei") }))
@@ -2230,7 +2231,6 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                 await db.GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync<Imei>(imei, imei.id);
                             }
                         }
-
                     }
                 }
             }

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 894 - 444
TEAMModelOS/ClientApp/public/lang/en-US.js


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

@@ -1,6 +1,119 @@
 const LANG_ZH_CN = {
+    assessment: {
+        moreCond: '选择更多条件',
+        unit1: '共',
+        unit2: '人',
+        good: '优秀',
+        normal: '合格',
+        bad: '不合格',
+        noStart: '未进行',
+        export: '导出',
+        open: '展开',
+        close: '收起',
+        otherAppraise: '互评',
+        on: '开启',
+        off: '关闭',
+        toProvince: '推送省平台',
+        noData: '当前条件下未匹配到教师数据',
+        noGroup: '未分组',
+        offline: '校本研修',
+        online: '线上研修',
+        ability: '认证材料',
+        video: '课堂实录',
+        hour: '学时',
+        noOnline: '暂无线上研修记录',
+        minute: '分钟',
+        noSubmitNum: '未提交数',
+        noAbility: '暂无认证材料记录',
+        selfAppraise: '自评',
+        schoolAppraise: '校评',
+        finalName: '最后评价人',
+        finalTime: '最后评价时间',
+        noSchoolAppraise: '暂无校评数据',
+        comment: '已评论',
+        tip1: '教师未提交认证材料,无法评审',
+        tip2: '前往评审教师提交的认证材料',
+        goAppraise: '去评审',
+        noOffline: '暂无校本研修记录',
+        hasPdf: '已提交PDF',
+        noPdf: '未提交PDF',
+        hasUpload: '已上传',
+        noUpload: '未上传',
+        noVideo: '暂未上传课堂实录',
+        reAppraise: '重新评审',
+        commentDetails: '评论详情',
+        homework: '作业提交内容',
+        no: '暂无',
+        allStatus: '全部状态',
+        noSubmit1: '认证材料未提交',
+        noSubmit2: '校本研修作业未提交',
+        noSubmit3: '课堂实录未提交',
+        teacherInfo: '教师信息',
+        tip3: '教师在线上研修观看能力点所关联的视频资源总时长,1学时=45分钟',
+        tip4: '最少有',
+        tip5: '个能力点的认证材料合格即可获得学时',
+        tip6: '认证材料必须全部通过才能获得学时',
+        allNormal: '全部合格',
+        tip7: '根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时: 1.10学时中至少有一次需提交作业的校本研修活动 2.在活动中成功提交PDF作业',
+        allPass: '全部通过',
+        tip8: '教师提交课堂实录并且考核通过后即可获得5学时',
+        atName: '被评价人',
+        type: '评价类型',
+        score: '评价结果',
+        time: '评论时间',
+        header1: '姓名',
+        header2: '总学时',
+        header3: '线上研修学时',
+        header4: '未修满能力点',
+        header5: '已修满的能力点数量',
+        header6: '认证材料学时',
+        header7: '校本研修学时',
+        header8: '课堂实录学时',
+        header9: '认证材料需提交数',
+        header10: '认证材料未提交数',
+        header11: '未提交认证材料能力点',
+        header12: '作业未提交数',
+        header13: '课堂实录是否提交',
+        hasSubmit: '已提交',
+        noSubmit: '未提交',
+        tableName: '研修情况统计表',
+        allGroups: '全部教研组',
+        noSubmitTip: '暂未提交作品,无法查看',
+        tip9: '已将',
+        tip10: '的最终研修结果评定为',
+        noComment: '无评价内容',
+        tip11: '确定',
+        tip12: '互评吗',
+        tip13: '设置成功!当前互评状态为:',
+        tip14: '设置失败!',
+        tip15: '当前教师暂未上传活动pdf作业,无法通过!',
+        tip16: '操作成功!',
+        tip17: '确认将所有教师参与的 不需要提交的 以及 需要并且已经提交PDF 的研修活动全部设置为通过吗?',
+        tip18: '确认将所有教师已经自评过的微能力点全部设置为合格吗?',
+        tip19: '操作失败!',
+        tip20: '确认将所有教师已提交的课堂实录全部设置为合格吗?',
+        tip21: '确认将当前所有教师的校本研修评定为合格吗?',
+        tip22: '批量操作',
+        tip23: '设置成功!',
+        noProvince: '暂未对接省平台',
+    },
     // 研修模块
     ability: {
+        samePointAppraise: '同微能力点互评',
+        otherResult: '互评结果',
+        schoolResult: '校评结果',
+        noCount: '(不计入学时)',
+        checkMan: '考核人员',
+        appraiseTip1: '学校暂未开启互评!请联系学校管理员处理!',
+        appraiseTip2: '请优先对互评次数为0的老师进行互评!',
+        check: {
+            isCheck: '是否为考核人员',
+            tip1: '确认修改当前教师的审核人员身份吗?',
+            tip2: '已添加',
+            tip3: '为审核人员',
+            tip4: '已取消',
+            tip5: '的审核人员身份!',
+        },
         points: {
             doc: '文档类',
             video: '视频类',
@@ -72,6 +185,17 @@ const LANG_ZH_CN = {
         appraiseTip: '您自己的材料只能由其它管理员进行评价!',
         allAbilities: '全部能力点',
         review: {
+            allowLimit: '可上传材料数量:',
+            score: '分',
+            scoreDown: '分以下',
+            scoreUp: '分以上',
+            self: '自评结果',
+            tip6: '温馨提示',
+            tip7: '您未确认“提交评审结果”,无法保存修改内容,是否确认离开?',
+            tip8: '等',
+            tip9: '个文件已更新!',
+            tip10: '删除认证材料',
+            tip11: '确认删除该认证材料吗?',
             task: '任务',
             upload: '上传资料',
             preview: '预览',
@@ -589,8 +713,8 @@ const LANG_ZH_CN = {
         generateErr: '生成失败',
         noStuTip: '未获取到学生数据',
         loadAll: '已加载完所有数据',
-        delete:'删除',
-        edit:'修改'
+        delete: '删除',
+        edit: '修改'
     },
     // 课堂管理
     courseManage: {
@@ -1969,6 +2093,25 @@ const LANG_ZH_CN = {
             okStudy: "已学完",
             noSee: "该文件不支持预览",
             abilyMes: "每个能力点学满对应学时后,多余学时不会计入总学时",
+            fromArea: "来源省平台",
+            fromArea1: "来源:省平台",
+            noStuTime: "不计学时",
+            loadLook: "可下载查看",
+            allEnvir: "全部环境",
+            envirMix: "混合学习环境",
+            multiMedia: "多媒体教学环境",
+            studyEnvir: "智慧学习环境",
+            allDimension: "全部维度",
+            keepRecords: "保存记录",
+            close: "关闭提示",
+            autoSave: "已经自动保存",
+            autoSaving: "自动保存中",
+            addtoAbility: "添加能力点",
+            addtoContent: "请到省平台挑选您想学习的能力点",
+            message4: "该文件缺少信息,无法保存学习记录",
+            had: "已获得",
+            submitExam: "提交评测",
+            timehave: "学时获得",
         },
         // 校本研修
         offline: {
@@ -2035,6 +2178,15 @@ const LANG_ZH_CN = {
             noFile: "暂无文件",
             sendActivity: "活动提交",
             main: "主",
+            message7: "根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时",
+            message8: "1. 10学时中至少有一次需提交作业的校本研修活动。",
+            message9: "2. 在活动中成功提交PDF作业。",
+            noActivity: "暂无活动",
+            tips: "重要提示",
+            tips1: "根据省平台要求,教师上传的作业必须选择一个",
+            tips2: "文档,作为本次活动的主要文件提交到省平台。",
+            mainFile: "主要文件",
+            tips3: "提交前,点击文件名,即可切换主要文件",
         },
         // 应用考核
         application: {
@@ -2163,6 +2315,8 @@ const LANG_ZH_CN = {
             tips: "研修已完成,快去填写总结吧",
             compulsory: "必修",
             electiveCourse: "能力点",
+            sendSummary: "填写研修总结",
+            plaSummary: "请填写您的研修总结",
         }
     },
     // 知识点管理
@@ -6162,6 +6316,213 @@ const LANG_ZH_CN = {
             school: '学校:'
         }
     },
+    //研修
+    td:{
+        td1:'研修统计',
+        td2:'学时统计',
+        td3:'总学时:',
+        td4:'分钟',
+        td5:'学时',
+        td6:'未开始:',
+        td7:'进行中:',
+        td8:'已完成:',
+        td9:'合格率',
+        td10:'学校概览',
+        td11:'学校列表',
+        td12:'导出学校数据',
+        td13:'导出教师数据',
+        td14:'搜索学校',
+        td15:'参训人数',
+        td16:'详情>>>',
+        td17:'未搜索到学校',
+        td18:'暂无学校数据',
+        td19:'学校数量',
+        td20:'总学时',
+        td21:'合格人数',
+        td22:'线上研修',
+        td23:'校本研修',
+        td24:'认证材料',
+        td25:'课堂实录',
+        td26:'未修满',
+        td27:'能力点',
+        td28:'学校',
+        td29:'姓名',
+        td30:'线上研修学时',
+        td31:'所选微能力点',
+        td32:'已修满的能力点数量',
+        td33:'认证材料学时',
+        td34:'校本研修学时',
+        td35:'课堂实录学时',
+        td36:'认证材料需提交数',
+        td37:'已提交认证材料数',
+        td38:'已提交认证材料能力点',
+        td39:'未提交认证材料数',
+        td40:'未提交认证材料能力点',
+        td41:'作业未提交数',
+        td42:'课堂实录是否提交',
+        td43:'已提交',
+        td44:'未提交',
+        td45:'研修情况统计表',
+        td46:'未开始人数',
+        td47:'进行中人数',
+        td48:'已完成人数',
+        td49:'参训总人数',
+        td50:'学校数据统计',
+        td51:'资源列表',
+        td52:'添加资源',
+        td53:'完成率:',
+        td54:'返回区级',
+        td55:'所有学校',
+        td56:'共建',
+        td57:'个试点校,参训人数',
+        td58:'重新上传',
+        td59:'主题',
+        td60:'时间',
+        td61:'地点',
+        td62:'描述',
+        td63:'请选择作业附件上传类型',
+        td64:'签到成功',
+        td65:'数据概览',
+        td66:'的',
+        td67:'查询签到数据失败',
+        td68:'获取作业提交数据失败',
+        td69:'合格率统计',
+        td70:'能力维度选修占比',
+        td71:'能力点选修占比',
+        td72:'研修小组统计',
+        td73:'暂无小组数据',
+        td74:'未分组',
+        td75:'查看成员',
+        td76:'完成线上研修',
+        td77:'完成认证材料',
+        td78:'完成校本研修',
+        td79:'完成课堂记录',
+        td80:'全部完成',
+        td81:'完成率',
+        td82:'优秀',
+        td83:'合格',
+        td84:'不合格',
+        td85:'获取统计数据失败',
+        td86:'数据总览',
+        td87:'详细数据',
+        td88:'搜索',
+        td89:'数据导出',
+        td90:'未完成',
+        td91:'已完成',
+        td92:'教师姓名',
+        td93:'小组',
+        td94:'完成状态',
+        td95:'姓名',
+        td96:'组别',
+        td97:'获取统计数据失败',
+        td98:'根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时:',
+        td99:'1、10学时中至少有一次需提交作业的校本研修活动',
+        td100:'2、在活动中成功提交PDF作业',
+        td101:'提交方式',
+        td102:'所有老师提交',
+        td103:'由组长统一提交',
+        td104:'请设置作业类型',
+        td105:'请设置提交方式',
+        td106:'未分组老师',
+        td107:'创建研修问卷失败',
+        td108:'创建研修评测失败',
+        td109:'输入手机号',
+        td110:'未查询到对应账号!请检查后重试!',
+        td111:'已签到成功,请勿重复操作!',
+        td112:'请输入正确手机号!',
+        td113:'签到失败,请重新签到',
+        td114:'签到成功',
+        td115:'签到失败',
+        td116:'温馨提示:区级活动不计入校本研修学时',
+        td117:'未发布',
+        td118:'进行中',
+        td119:'已结束',
+        td120:'活动视频:',
+        td121:'播放',
+        td122:'删除',
+        td123:'上传',
+        td124:'(视频只能上传一个)',
+        td125:'活动资料:',
+        td126:'继续上传',
+        td127:'(资料可以上传多份)',
+        td128:'根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时: 1、10学时中至少有一次需提交作业的校本研修活动 2、在活动中成功提交PDF作业',
+        td129:'批量合格',
+        td130:'请选择学校老师参加并发布活动',
+        td131:'选择老师',
+        td132:'继续挑选(已选',
+        td133:'位)',
+        td134:'发布活动',
+        td135:'上传中',
+        td136:'上传完成',
+        td137:'添加教师',
+        td138:'教研组',
+        td139:'教研组筛选',
+        td140:'未设置',
+        td141:'查询教研组失败',
+        td142:'请勾选参加活动的老师',
+        td143:'删除文件',
+        td144:'是否确认删除',
+        td145:'删除成功',
+        td146:'删除失败',
+        td147:'文件上传中,请等待文件上传完成',
+        td148:'活动视频只支持mp4文件格式',
+        td149:'学校空间已满',
+        td150:'上传失败',
+        td151:'请选择需要批量处理',
+        td152:'合格',
+        td153:'不合格',
+        td154:'的老师',
+        td155:'批量处理',
+        td156:'确认将所选老师全部设置为合格吗?',
+        td157:'问卷作答数据获取失败',
+        td158:'获取作业提交数据失败',
+        td159:'获取名单列表失败',
+        td160:'获取签到数据失败',
+        td161:'学校',
+        td162:'查询教师列表失败',
+        td163:'对象:',
+        td164:'暂无',
+        td165:'查询研修列表失败',
+        td166:'人数:',
+        td167:'(已同步省平台名单)',
+        td168:'温馨提示:空白分组(分组内没有添加教师)不会被保存。',
+        td169:'保存分组',
+        td170:'分组视图',
+        td171:'列表视图',
+        td172:'移除教师',
+        td173:'添加教师',
+        td174:'组长',
+        td175:'组员',
+        td176:'已绑定',
+        td177:'未绑定',
+        td178:'添加成员',
+        td179:'设为组长',
+        td180:'取消组长',
+        td181:'身份',
+        td182:'状态',
+        td183:'设置成功',
+        td184:'设置失败',
+        td185:'删除组别',
+        td186:'删除组别后,当前组的老师将默认被分配到相邻组别,确认删除吗?',
+        td187:'确认删除所有分组吗?',
+        td188:'请设置所有组名',
+        td189:'保存成功',
+        td190:'保存失败',
+        td191:'请输入组名再添加组别',
+        td192:'组名重复',
+        td193:'请选择需要移除的老师',
+        td194:'批量移除',
+        td195:'确认批量移除',
+        td196:'个参训老师吗?',
+        td197:'移除成功',
+        td198:'移除失败',
+        td199:'移除参训老师',
+        td200:'是否确认移除',
+        td201:'研修名单',
+        td202:'添加成功',
+        td203:'保存研修名单失败',
+        td204:'查询研修名单失败'
+    },
     // 单位管理
     unit: {
         text1: '堂',

+ 433 - 72
TEAMModelOS/ClientApp/public/lang/zh-TW.js

@@ -1,12 +1,125 @@
 const LANG_ZH_TW = {
-    // 研修模块
+    assessment: {
+        moreCond: '選擇更多條件',
+        unit1: '共',
+        unit2: '人',
+        good: '優秀',
+        normal: '合格',
+        bad: '不合格',
+        noStart: '未進行',
+        export: '導出',
+        open: '展開',
+        close: '收起',
+        otherAppraise: '互評',
+        on: '開啟',
+        off: '關閉',
+        toProvince: '推送省平臺',
+        noData: '當前條件下未匹配到教師數據',
+        noGroup: '未分組',
+        offline: '校本研習',
+        online: '線上研習',
+        ability: '認證材料',
+        video: '課堂實錄',
+        hour: '學時',
+        noOnline: '暫無線上研習記錄',
+        minute: '分鐘',
+        noSubmitNum: '未提交數',
+        noAbility: '暫無認證材料記錄',
+        selfAppraise: '自評',
+        schoolAppraise: '校評',
+        finalName: '最後評價人',
+        finalTime: '最後評價時間',
+        noSchoolAppraise: '暫無校評數據',
+        comment: '已評論',
+        tip1: '教師未提交認證材料,無法評審',
+        tip2: '前往評審教師提交的認證材料',
+        goAppraise: '去評審',
+        noOffline: '暫無校本研習記錄',
+        hasPdf: '已提交PDF',
+        noPdf: '未提交PDF',
+        hasUpload: '已上傳',
+        noUpload: '未上傳',
+        noVideo: '暫未上傳課堂實錄',
+        reAppraise: '重新評審',
+        commentDetails: '評論詳情',
+        homework: '作業提交內容',
+        no: '暫無',
+        allStatus: '全部狀態',
+        noSubmit1: '認證材料未提交',
+        noSubmit2: '校本研習作業未提交',
+        noSubmit3: '課堂實錄未提交',
+        teacherInfo: '教師信息',
+        tip3: '教師在線上研習觀看增能項目所關聯的視頻資源總時長,1學時=45分鐘',
+        tip4: '最少有',
+        tip5: '個增能項目的認證材料合格即可獲得學時',
+        tip6: '認證材料必須全部通過才能獲得學時',
+        allNormal: '全部合格',
+        tip7: '根據省平臺要求,教師必須滿足以下條件才可獲得校本研習活動學時: 1.10學時中至少有一次需提交作業的校本研習活動 2.在活動中成功提交PDF作業',
+        allPass: '全部通過',
+        tip8: '教師提交課堂實錄併且考核通過後即可獲得5學時',
+        atName: '被評價人',
+        type: '評價類型',
+        score: '評價結果',
+        time: '評論時間',
+        header1: '姓名',
+        header2: '總學時',
+        header3: '線上研習學時',
+        header4: '未修滿增能項目',
+        header5: '已修滿的增能項目數量',
+        header6: '認證材料學時',
+        header7: '校本研習學時',
+        header8: '課堂實錄學時',
+        header9: '認證材料需提交數',
+        header10: '認證材料未提交數',
+        header11: '未提交認證材料增能項目',
+        header12: '作業未提交數',
+        header13: '課堂實錄是否提交',
+        hasSubmit: '已提交',
+        noSubmit: '未提交',
+        tableName: '研習情況統計錶',
+        allGroups: '全部教研組',
+        noSubmitTip: '暫未提交作品,無法查看',
+        tip9: '已將',
+        tip10: '的最終研習結果評定為',
+        noComment: '無評價內容',
+        tip11: '確定',
+        tip12: '互評嗎',
+        tip13: '設置成功!當前互評狀態為:',
+        tip14: '設置失敗!',
+        tip15: '當前教師暫未上傳活動pdf作業,無法通過!',
+        tip16: '操作成功!',
+        tip17: '確認將所有教師參與的 不需要提交的 以及 需要併且已經提交PDF 的研習活動全部設置為通過嗎?',
+        tip18: '確認將所有教師已經自評過的增能項目全部設置為合格嗎?',
+        tip19: '操作失敗!',
+        tip20: '確認將所有教師已提交的課堂實錄全部設置為合格嗎?',
+        tip21: '確認將當前所有教師的校本研習評定為合格嗎?',
+        tip22: '批量操作',
+        tip23: '設置成功!',
+        noProvince: '暫未對接省平臺',
+    },
+    // 研習模块
     ability: {
+        samePointAppraise: '同增能項目互評',
+        otherResult: '互評結果',
+        schoolResult: '校評結果',
+        noCount: '(不計入學時)',
+        checkMan: '考核人員',
+        appraiseTip1: '學校暫未開啟互評!請聯繫學校管理員處理!',
+        appraiseTip2: '請優先對互評次數為0的老師進行互評!',
+        check: {
+            isCheck: '是否為考核人員',
+            tip1: '確認修改當前教師的審核人員身份嗎?',
+            tip2: '已添加',
+            tip3: '為審核人員',
+            tip4: '已取消',
+            tip5: '的審核人員身份!',
+        },
         points: {
-            doc: '文檔類',
+            doc: '檔類',
             video: '影片類',
-            audio: '音頻類',
+            audio: '音類',
             image: '圖片類',
-            gzip: '壓縮包',
+            gzip: '壓縮',
             dimension1: '學情分析',
             dimension2: '教學設計',
             dimension3: '學法指導',
@@ -37,7 +150,7 @@ const LANG_ZH_TW = {
             ruleTip2: '評分點內容不能為空',
             ruleTip3: '任務描述內容不能為空',
         },
-        uploadTip: '選擇或者拖文件到該區域進行上傳',
+        uploadTip: '選擇或者拖文件到該區域進行上傳',
         confirmUpload: '確認上傳',
         sizeTip: '上傳文件大小不能大於',
         typeTip: '上傳文件格式只能為',
@@ -52,7 +165,7 @@ const LANG_ZH_TW = {
         appraiseDetail: '評價詳情',
         appraise: '評審',
         teacherName: '教師姓名',
-        abilityName: '能力點名稱',
+        abilityName: '增能項目名稱',
         dimension: '維度',
         env: '維度',
         groupName: '教師群組',
@@ -70,8 +183,19 @@ const LANG_ZH_TW = {
         appraiseOther: '互評',
         appraiseSelf: '自評',
         appraiseTip: '您自己的材料只能由其它管理員進行評價!',
-        allAbilities: '全部能力點',
+        allAbilities: '全部增能項目',
         review: {
+            allowLimit: '可上傳材料數量:',
+            score: '分',
+            scoreDown: '分以下',
+            scoreUp: '分以上',
+            self: '自評結果',
+            tip6: '溫馨提示',
+            tip7: '您未確認“提交評審結果”,無法保存修改內容,是否確認離開?',
+            tip8: '等',
+            tip9: '個文件已更新!',
+            tip10: '刪除認證材料',
+            tip11: '確認刪除該認證材料嗎?',
             task: '任務',
             upload: '上傳資料',
             preview: '預覽',
@@ -89,7 +213,7 @@ const LANG_ZH_TW = {
             deleteSuc: '刪除成功!'
         },
         paper: {
-            noData: '當前能力點下暫無檢測試題數據',
+            noData: '當前增能項目下暫無檢測試題數據',
             single: '單選',
             multiple: '多選',
             judge: '是非',
@@ -108,8 +232,8 @@ const LANG_ZH_TW = {
             noSearch: '編號查詢',
             treeView: '查看章節目錄',
             paperView: '查看檢測試卷',
-            ability: '微能力點',
-            place1: '輸入能力點名稱...',
+            ability: '增能項目',
+            place1: '輸入增能項目名稱...',
             compulsory: '必修',
             hour: '總學時',
             count: '成長值',
@@ -122,8 +246,8 @@ const LANG_ZH_TW = {
             import: '匯入試題',
             resource: '關聯資源',
             chapter: '章節',
-            edit: '編輯微能力點',
-            addAbility: '新增微能力點',
+            edit: '編輯增能項目',
+            addAbility: '新增增能項目',
             no: '編號',
             name: '名稱',
             desc: '描述',
@@ -131,11 +255,11 @@ const LANG_ZH_TW = {
             sug: '建議',
             isCompulsory: '選修/必修',
             noCompulsory: '選修',
-            place2: '填寫微能力點編號...',
-            place3: '填寫微能力點名稱...',
-            place4: '填寫微能力點描述資訊...',
-            place5: '填寫微能力點環境...',
-            place6: '填寫微能力點建議...',
+            place2: '填寫增能項目編號...',
+            place3: '填寫增能項目名稱...',
+            place4: '填寫增能項目描述資訊...',
+            place5: '填寫增能項目環境...',
+            place6: '填寫增能項目建議...',
             tip1: '編號不能為空',
             tip2: '名稱不能為空',
         },
@@ -218,7 +342,7 @@ const LANG_ZH_TW = {
             lineTip: '-------密-------封-------線-------內-------不-------要-------答-------題-------'
         },
         sheetTip1: '答題卡製作注意事項',
-        sheetTip2: '1、主觀題作答區域編輯框可通過點擊下邊框拖快速調整高度。',
+        sheetTip2: '1、主觀題作答區域編輯框可通過點擊下邊框拖快速調整高度。',
         sheetTip3: '2、答題卡最多支援 7 頁,如您的內容超出,請進行相應調整,否則無法正常生成答題卡。',
         sheetTip4: '答題卡最多支援 7 頁,請重新調整答題卡內容!',
         sheetTip5: '當前試卷答題卡文件數據丟失,請重新生成!',
@@ -294,7 +418,7 @@ const LANG_ZH_TW = {
             allAc: '活動總覽',
             createAc: '新增活動',
             expertCk: '專家抽查',
-            point: '微能力點',
+            point: '增能項目',
             artData: '藝術總覽',
             student: '素質',
             studentAll: '學生綜合素質監測',
@@ -320,7 +444,7 @@ const LANG_ZH_TW = {
         survey: '問卷',
         teachSpace: '分配給教師',
         homework: '作業',
-        train: '研',
+        train: '研',
         records: '課堂記錄',
         over: '剩餘',
         syllabus: '課綱',
@@ -450,7 +574,7 @@ const LANG_ZH_TW = {
         ctFmText18: '保存成功,稍後我們將與您聯繫',
         ctFmText19: '保存失敗',
         ctFmText20: '智慧教室',
-        ctFmText21: '研中心',
+        ctFmText21: '研中心',
         ctFmText22: '顧問服務',
         ctFmText23: '電子信箱',
         ctFmText24: '請輸入信箱',
@@ -589,8 +713,8 @@ const LANG_ZH_TW = {
         generateErr: '生成失敗',
         noStuTip: '未獲取到學生數據',
         loadAll: '已加載完所有數據',
-        delete:'刪除',
-        edit:'修改'
+        delete: '刪除',
+        edit: '修改'
     },
     // 课堂管理
     courseManage: {
@@ -1716,12 +1840,12 @@ const LANG_ZH_TW = {
         fri: '五',
         sat: '六',
         sun: '日',
-        trainLabel1: '合格能力點',
+        trainLabel1: '合格增能項目',
         trainLabel2: '成果提交',
-        trainLabel3: '區級研',
+        trainLabel3: '區級研',
         trainLabel4: '區級問卷',
         trainLabel5: '區級投票',
-        trainLabel6: '校級研',
+        trainLabel6: '校級研',
         trainLabel7: '校級問卷',
         trainLabel8: '校級投票',
         techScorePct: '科技分占比',
@@ -1928,8 +2052,8 @@ const LANG_ZH_TW = {
             area: "區",
             typeSch: "校級",
             typeArea: "區級",
-            point: "能力點",
-            pointName: "能力點名稱",
+            point: "增能項目",
+            pointName: "增能項目名稱",
             dimension: "維度",
             message: "請選擇舉報類型:",
             success1: "回覆成功",
@@ -1938,10 +2062,10 @@ const LANG_ZH_TW = {
             error: "刪除失敗",
             noData: '暫無數據',
         },
-        // 线上研
+        // 线上研
         online: {
-            checkedPoint: "微能力點",
-            addPoint: "增加能力點",
+            checkedPoint: "增能項目",
+            addPoint: "增加增能項目",
             compulsory: "必修",
             knowledge: "通識",
             elective: "選修",
@@ -1952,13 +2076,13 @@ const LANG_ZH_TW = {
             relTopic: "關聯話題",
             study: "您已學習:",
             time: "學時",
-            tips: "必修能力點已為您預設勾選!點擊確定後就可開始學習",
+            tips: "必修增能項目已為您預設勾選!點擊確定後就可開始學習",
             type: "狀態",
             no: "標號",
             environment: "所屬環境",
-            message1: "增加能力點成功",
+            message1: "增加增能項目成功",
             message2: "已學完本章節",
-            message3: "該能力點已學完",
+            message3: "該增能項目已學完",
             placeholder1: "發起新的話題",
             release: "發布",
             relSucess: "話題發布成功",
@@ -1968,11 +2092,30 @@ const LANG_ZH_TW = {
             noStudy: "未開始學習",
             okStudy: "已學完",
             noSee: "該檔案不支援預覽",
-            abilyMes: "每個能力點學滿對應學時後,多餘學時不會計入總學時",
+            abilyMes: "每個增能項目學滿對應學時後,多餘學時不會計入總學時",
+            fromArea: "來源省平臺",
+            fromArea1: "來源:省平臺",
+            noStuTime: "不計學時",
+            loadLook: "可下載查看",
+            allEnvir: "全部環境",
+            envirMix: "混合學習環境",
+            multiMedia: "多媒體教學環境",
+            studyEnvir: "智慧學習環境",
+            allDimension: "全部維度",
+            keepRecords: "保存記錄",
+            close: "關閉提示",
+            autoSave: "已經自動保存",
+            autoSaving: "自動保存中",
+            addtoAbility: "添加增能項目",
+            addtoContent: "請到省平臺挑選您想學習的增能項目",
+            message4: "該檔案缺少資訊,無法保存學習記錄",
+            had: "已獲得",
+            submitExam: "提交評測",
+            timehave: "學時獲得",
         },
-        // 校本研修
+        // 校本研
         offline: {
-            activity: "研修活動",
+            activity: "研活動",
             info: "詳細資訊",
             creator: "新增者",
             noPeople: "無",
@@ -1980,7 +2123,7 @@ const LANG_ZH_TW = {
             actTime: "活動時間",
             target: "學習對象",
             basicInfo: "基礎資訊",
-            studyTar: "研目標",
+            studyTar: "研目標",
             address: "培訓地點",
             speaker: "主講人",
             type: "類型",
@@ -2014,7 +2157,7 @@ const LANG_ZH_TW = {
             message2: "評量未作答完,請繼續作答",
             placeholder1: "輸入您的回答內容...",
             message3: "刪除成功",
-            delTitle: "研活動已被刪除,是否刪除此條記錄?",
+            delTitle: "研活動已被刪除,是否刪除此條記錄?",
             delOk: "刪除",
             delCancel: "取消",
             answerTime: "截止時間",
@@ -2035,6 +2178,15 @@ const LANG_ZH_TW = {
             noFile: "暫無檔案",
             sendActivity: "活動提交",
             main: "主",
+            message7: "根據省平臺要求,教師必須滿足以下條件才可獲得校本研習活動學時",
+            message8: "1. 10學時中至少有一次需提交作業的校本研習活動。",
+            message9: "2. 在活動中成功提交PDF作業。",
+            noActivity: "暫無活動",
+            tips: "重要提示",
+            tips1: "根據省平臺要求,教師上傳的作業必須選擇一個",
+            tips2: "檔案,作為本次活動的主要檔案提交到省平臺。",
+            mainFile: "主要檔案",
+            tips3: "提交前,點擊檔名,即可切換主要檔案",
         },
         // 应用考核
         application: {
@@ -2078,7 +2230,7 @@ const LANG_ZH_TW = {
             loadOK: "確認上傳",
             videoName: "影片名稱",
             fileSize: "文件大小",
-            loadDes: "選擇或者拖檔案到該區域進行上傳",
+            loadDes: "選擇或者拖檔案到該區域進行上傳",
             loadAuth: "上傳作者",
             size: "大小",
             see: "查看課程及評估",
@@ -2099,7 +2251,7 @@ const LANG_ZH_TW = {
             addTopic: "新增話題",
             topicType: "話題類型",
             normal: "普通話題",
-            point: "能力點話題",
+            point: "增能項目話題",
             allTopic: "所有話題",
             myTopic: "我的話題",
             replyMe: "回覆我的",
@@ -2133,11 +2285,11 @@ const LANG_ZH_TW = {
         },
         homePage: {
             totalTime: '總學時',
-            online: "線上研",
-            offline: "線下研",
+            online: "線上研",
+            offline: "線下研",
             application: "認證材料",
             classRecord: "課堂實錄",
-            studyPoint: "已學能力點",
+            studyPoint: "已學增能項目",
             okPoint: "自我練習",
             achievements: "成果提交",
             area: "區級活動",
@@ -2145,24 +2297,26 @@ const LANG_ZH_TW = {
             areaQue: "區級問卷",
             areaVote: "區級投票",
             school: "校級活动",
-            yanxiu: "研",
+            yanxiu: "研",
             schoolQue: "問卷",
             schoolVote: "投票",
             time: "學時",
             minute: "分鐘",
-            remarks1: "總學時:線上研修 + 校本研修 + 認證材料 + 課堂實錄",
+            remarks1: "總學時:線上研習 + 校本研習 + 認證材料 + 課堂實錄",
             remarks2: "注:各指標達到要求後,多餘學時不再計入總學時",
             remarks3: "注:",
             remarks4: "分鐘 = 1學時",
             summary1: "填寫總結(選填)",
             summary2: "修改總結",
-            message1: "您的研還未完成,不能填寫總結",
+            message1: "您的研還未完成,不能填寫總結",
             message2: "總結已提交",
             message3: "總結提交失敗",
             message4: "總結字數不足50字!",
-            tips: "研已完成,快去填寫總結吧",
+            tips: "研已完成,快去填寫總結吧",
             compulsory: "必修",
-            electiveCourse: "能力點",
+            electiveCourse: "增能項目",
+            sendSummary: "填寫研習總結",
+            plaSummary: "請填寫您的研習總結",
         }
     },
     // 知识点管理
@@ -5050,8 +5204,8 @@ const LANG_ZH_TW = {
         preview: '預覽',
         title: '醍摩豆雲平臺',
         hostTitle: {
-            jinniu: '成都市金牛區研平臺',
-            scyx: '研平臺',
+            jinniu: '成都市金牛區研平臺',
+            scyx: '研平臺',
         },
         loading: '載入中',
         authErr: '權限不足! ',
@@ -5059,7 +5213,7 @@ const LANG_ZH_TW = {
         goHome: '主頁',
         changePlat: '切換平臺',
         noSupport: '暫未提供',
-        help: '幫助文',
+        help: '幫助文',
         menu: {
             school: '學校',
             private: '個人',
@@ -5104,15 +5258,15 @@ const LANG_ZH_TW = {
             acRecord: '活動記錄',
             cusMgt: '課程管理',
             taskList: '任務清單',
-            train: '研中心',
-            trainData: '研數據',
-            abilityPoint: '微能力點',
-            scTrain: '校本研',
+            train: '研中心',
+            trainData: '研數據',
+            abilityPoint: '增能項目',
+            scTrain: '校本研',
             appAbility: '應用能力',
             classRecord: '課堂實錄',
             resourceCenter: '資源中心',
-            trainCount: '研統計',
-            onlineTrain: '線上研',
+            trainCount: '研統計',
+            onlineTrain: '線上研',
             appAssassment: '認證材料',
             discuss: '討論中心',
             policy: '政策文件',
@@ -5124,10 +5278,10 @@ const LANG_ZH_TW = {
             lockTips: '鎖定菜單欄',
             unlockTips: '解鎖菜單欄',
             platform: '資源平臺',
-            trainList: '研名單',
-            trainCheck: '研考核',
+            trainList: '研名單',
+            trainCheck: '研考核',
             activity: '活動平臺',
-            trainSystem: '研平臺'
+            trainSystem: '研平臺'
         },
         compt: {
             cusWare: '教材',
@@ -5379,7 +5533,7 @@ const LANG_ZH_TW = {
         tcUpd4: '姓名',
         tcUpd5: '學科',
         tcUpd6: '職稱',
-        tcUpd7: '職稱,不填寫則預設為師',
+        tcUpd7: '職稱,不填寫則預設為師',
         tcUpd8: '備註',
         page: {
             text1: '教師管理',
@@ -5497,9 +5651,9 @@ const LANG_ZH_TW = {
             'schoolAc': '學校活動',
             'schoolAc-read': '查看學校活動',
             'schoolAc-upd': '發布學校活動',
-            'train': '研中心',
-            'train-read': '查看研中心數據',
-            'train-upd': '管理研中心數據',
+            'train': '研中心',
+            'train-read': '查看研中心數據',
+            'train-upd': '管理研中心數據',
             'dashboard': '校園大數據',
             'dashboard-read': '校園大數據查看權限',
             'research': '課堂紀錄',
@@ -5663,7 +5817,7 @@ const LANG_ZH_TW = {
         importTips6: '4. tmdid: 教師用戶編號,選填;',
         importTips7: '5. note: 教師備註內容,選填;',
         importTips8: '溫馨提示:如果匯入的教師用戶編號,或者匯入的手機或信箱已註冊醍摩豆帳號,系統會自動邀請教師加入學校。',
-        importTips9: '點擊或者拖文件匯入',
+        importTips9: '點擊或者拖文件匯入',
         impText: '無效數據(沒有名字):',
         impText1: '匯入總人數:',
         impText2: '僅匯入姓名:',
@@ -5991,7 +6145,7 @@ const LANG_ZH_TW = {
         paperItemsCount: '試卷題數',
         backUp: '回到上層'
     },
-    // 研活动
+    // 研活动
     train: {
         create: {
             lastStep: '上一步',
@@ -6076,17 +6230,17 @@ const LANG_ZH_TW = {
             all: '全部',
             trainTypeLabel: '活動類型:',
             search: '搜尋',
-            toCreate: '新增研',
+            toCreate: '新增研',
             areaLabel: '區級',
             schoolLabel: '校級',
             presenter: '主講人:',
             topic: '主題:',
             address: '地點:',
             time: '時間:',
-            noTrain: '暫無校本研活動',
+            noTrain: '暫無校本研活動',
         },
         detail: {
-            back: '返回研總覽',
+            back: '返回研總覽',
             hour: '學時',
             presenter: '主講人:',
             topic: '主題:',
@@ -6132,7 +6286,7 @@ const LANG_ZH_TW = {
             teacherName: '教師姓名:',
             updTime: '上傳時間:',
             hwFile: '作業附件:',
-            viewTips: '文件類型不支援線上預覽,請下載文件',
+            viewTips: '檔案類型不支援線上預覽,請下載文件',
             downloadFile: '下載文件',
             answerTitle: '作答詳情',
             name: '姓名',
@@ -6162,6 +6316,213 @@ const LANG_ZH_TW = {
             school: '學校:'
         }
     },
+    //研習
+    td:{
+        td1:'研習統計',
+        td2:'學時統計',
+        td3:'總學時:',
+        td4:'分鐘',
+        td5:'學時',
+        td6:'未開始:',
+        td7:'進行中:',
+        td8:'已完成:',
+        td9:'合格率',
+        td10:'學校概覽',
+        td11:'學校列表',
+        td12:'導出學校數據',
+        td13:'導出教師數據',
+        td14:'搜索學校',
+        td15:'參訓人數',
+        td16:'詳情>>>',
+        td17:'未搜索到學校',
+        td18:'暫無學校數據',
+        td19:'學校數量',
+        td20:'總學時',
+        td21:'合格人數',
+        td22:'線上研習',
+        td23:'校本研習',
+        td24:'認證材料',
+        td25:'課堂實錄',
+        td26:'未修滿',
+        td27:'增能項目',
+        td28:'學校',
+        td29:'姓名',
+        td30:'線上研習學時',
+        td31:'所選增能項目',
+        td32:'已修滿的增能項目數量',
+        td33:'認證材料學時',
+        td34:'校本研習學時',
+        td35:'課堂實錄學時',
+        td36:'認證材料需提交數',
+        td37:'已提交認證材料數',
+        td38:'已提交認證材料增能項目',
+        td39:'未提交認證材料數',
+        td40:'未提交認證材料增能項目',
+        td41:'作業未提交數',
+        td42:'課堂實錄是否提交',
+        td43:'已提交',
+        td44:'未提交',
+        td45:'研習情況統計表',
+        td46:'未開始人數',
+        td47:'進行中人數',
+        td48:'已完成人數',
+        td49:'參訓總人數',
+        td50:'學校數據統計',
+        td51:'資源列表',
+        td52:'添加資源',
+        td53:'完成率:',
+        td54:'返回區級',
+        td55:'所有學校',
+        td56:'共建',
+        td57:'個試點校,參訓人數',
+        td58:'重新上傳',
+        td59:'主題',
+        td60:'時間',
+        td61:'地點',
+        td62:'描述',
+        td63:'請選擇作業附件上傳類型',
+        td64:'簽到成功',
+        td65:'數據概覽',
+        td66:'的',
+        td67:'查詢簽到數據失敗',
+        td68:'獲取作業提交數據失敗',
+        td69:'合格率統計',
+        td70:'能力維度選修占比',
+        td71:'增能項目選修占比',
+        td72:'研習小組統計',
+        td73:'暫無小組數據',
+        td74:'未分組',
+        td75:'查看成員',
+        td76:'完成線上研習',
+        td77:'完成認證材料',
+        td78:'完成校本研習',
+        td79:'完成課堂記錄',
+        td80:'全部完成',
+        td81:'完成率',
+        td82:'優秀',
+        td83:'合格',
+        td84:'不合格',
+        td85:'獲取統計數據失敗',
+        td86:'數據總覽',
+        td87:'詳細數據',
+        td88:'搜索',
+        td89:'數據導出',
+        td90:'未完成',
+        td91:'已完成',
+        td92:'教師姓名',
+        td93:'小組',
+        td94:'完成狀態',
+        td95:'姓名',
+        td96:'組別',
+        td97:'獲取統計數據失敗',
+        td98:'根據省平臺要求,教師必須滿足以下條件才可獲得校本研習活動學時:',
+        td99:'1、10學時中至少有一次需提交作業的校本研習活動',
+        td100:'2、在活動中成功提交PDF作業',
+        td101:'提交方式',
+        td102:'所有老師提交',
+        td103:'由組長統一提交',
+        td104:'請設置作業類型',
+        td105:'請設置提交方式',
+        td106:'未分組老師',
+        td107:'創建研習問卷失敗',
+        td108:'創建研習評測失敗',
+        td109:'輸入手機號',
+        td110:'未查詢到對應賬號!請檢查後重試!',
+        td111:'已簽到成功,請勿重復操作!',
+        td112:'請輸入正確手機號!',
+        td113:'簽到失敗,請重新簽到',
+        td114:'簽到成功',
+        td115:'簽到失敗',
+        td116:'溫馨提示:區級活動不計入校本研習學時',
+        td117:'未發布',
+        td118:'進行中',
+        td119:'已結束',
+        td120:'活動視頻:',
+        td121:'播放',
+        td122:'刪除',
+        td123:'上傳',
+        td124:'(視頻只能上傳一個)',
+        td125:'活動資料:',
+        td126:'繼續上傳',
+        td127:'(資料可以上傳多份)',
+        td128:'根據省平臺要求,教師必須滿足以下條件才可獲得校本研習活動學時: 1、10學時中至少有一次需提交作業的校本研習活動 2、在活動中成功提交PDF作業',
+        td129:'批量合格',
+        td130:'請選擇學校老師參加並發布活動',
+        td131:'選擇老師',
+        td132:'繼續挑選(已選',
+        td133:'位)',
+        td134:'發布活動',
+        td135:'上傳中',
+        td136:'上傳完成',
+        td137:'添加教師',
+        td138:'教研組',
+        td139:'教研組篩選',
+        td140:'未設置',
+        td141:'查詢教研組失敗',
+        td142:'請勾選參加活動的老師',
+        td143:'刪除文件',
+        td144:'是否確認刪除',
+        td145:'刪除成功',
+        td146:'刪除失敗',
+        td147:'文件上傳中,請等待文件上傳完成',
+        td148:'活動視頻只支持mp4文件格式',
+        td149:'學校空間已滿',
+        td150:'上傳失敗',
+        td151:'請選擇需要批量處理',
+        td152:'合格',
+        td153:'不合格',
+        td154:'的老師',
+        td155:'批量處理',
+        td156:'確認將所選老師全部設置為合格嗎?',
+        td157:'問卷作答數據獲取失敗',
+        td158:'獲取作業提交數據失敗',
+        td159:'獲取名單列表失敗',
+        td160:'獲取簽到數據失敗',
+        td161:'學校',
+        td162:'查詢教師列表失敗',
+        td163:'對象:',
+        td164:'暫無',
+        td165:'查詢研習列表失敗',
+        td166:'人數:',
+        td167:'(已同步省平臺名單)',
+        td168:'溫馨提示:空白分組(分組內沒有添加教師)不會被保存。',
+        td169:'保存分組',
+        td170:'分組視圖',
+        td171:'列表視圖',
+        td172:'移除教師',
+        td173:'添加教師',
+        td174:'組長',
+        td175:'組員',
+        td176:'已綁定',
+        td177:'未綁定',
+        td178:'添加成員',
+        td179:'設為組長',
+        td180:'取消組長',
+        td181:'身份',
+        td182:'狀態',
+        td183:'設置成功',
+        td184:'設置失敗',
+        td185:'刪除組別',
+        td186:'刪除組別後,當前組的老師將默認被分配到相鄰組別,確認刪除嗎?',
+        td187:'確認刪除所有分組嗎?',
+        td188:'請設置所有組名',
+        td189:'保存成功',
+        td190:'保存失敗',
+        td191:'請輸入組名再添加組別',
+        td192:'組名重復',
+        td193:'請選擇需要移除的老師',
+        td194:'批量移除',
+        td195:'確認批量移除',
+        td196:'個參訓老師嗎?',
+        td197:'移除成功',
+        td198:'移除失敗',
+        td199:'移除參訓老師',
+        td200:'是否確認移除',
+        td201:'研習名單',
+        td202:'添加成功',
+        td203:'保存研習名單失敗',
+        td204:'查詢研習名單失敗'
+    },
     // 单位管理
     unit: {
         text1: '堂',
@@ -6283,7 +6644,7 @@ const LANG_ZH_TW = {
         maxFileSize: "上傳文件大小不能超過100M!",
         fileReadFail: '有試題資料讀取失敗!',
         uploadLoading: '上傳中…',
-        standrad: '能力點版本',
+        standrad: '增能項目版本',
         choose: "選擇",
         draw: '繪製',
         arrow: '畫箭頭',

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

@@ -106,7 +106,7 @@ export default {
 			try {
 				let studentInfo = withToken ? await $api.login.getStuInfoByToken(params) : await $api.login.getStudentInfoByAccount(params)
 				if (studentInfo.error) {
-					app.$Message.warning(studentInfo.error === 1 ? this.$t('login.apiError.text1') : this.$t('login.infoErr'))
+					app.$Message.warning(studentInfo.error === 1 ? app.$t('login.apiError.text1') : app.$t('login.infoErr'))
 					j(studentInfo)
 					return
 				}

+ 132 - 133
TEAMModelOS/ClientApp/src/components/evaluation/AnalysisItemTable.vue

@@ -1,141 +1,140 @@
 <template>
-	<div class="analysis-table">
-		<!-- 表格组件 -->
-		<Table border ref="table" :data="tableData" :columns="dataColumns"></Table>
+  <div class="analysis-table">
+    <!-- 表格组件 -->
+    <Table border ref="table" :data="tableData" :columns="dataColumns"></Table>
 
-
-
-	</div>
+  </div>
 </template>
 <script>
-	export default {
-		props: {
-			analysisJson: {
-				type: Object,
-				default: () => {}
-			},
+export default {
+  props: {
+    analysisJson: {
+      type: Object,
+      default: () => { }
+    },
+
+  },
+  data() {
+    return {
+      tableData: [],
+      dataColumns: [
+        {
+          title: this.$t('totalAnalysis.sca_table_text6'),
+          key: 'areaName',
+          align: 'center'
+        },
+        {
+          title: this.$t('totalAnalysis.ta_table_text4'),
+          key: 'score',
+          align: 'center'
+        },
+        {
+          title: this.$t('totalAnalysis.ta_table_text5'),
+          key: 'diff',
+          align: 'center',
+          render: function (h, params) {
+            return h('span', (Number(params.row.diff)).toFixed(2))
+          }
+        },
+        {
+          title: this.$t('totalAnalysis.ta_table_text6'),
+          key: 'identify',
+          align: 'center',
+          render: function (h, params) {
+            return h('span', (Number(params.row.identify)).toFixed(2))
+          }
+        },
+        {
+          title: this.$t('totalAnalysis.trueAnswerRate'),
+          align: 'center',
+          key: 'classScoreRate'
+        },
+        {
+          title: this.$t('totalAnalysis.PHAnswerRate'),
+          align: 'center',
+          key: 'PH',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.PH)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: this.$t('totalAnalysis.PLAnswerRate'),
+          align: 'center',
+          key: 'PL',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.PL)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: 'R1',
+          align: 'center',
+          key: 'R1',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.R1)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: 'R2',
+          key: 'R2',
+          align: 'center',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.R2)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: 'R3',
+          align: 'center',
+          key: 'R3',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.R3)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: 'R4',
+          align: 'center',
+          key: 'R4',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.R4)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: 'R5',
+          align: 'center',
+          key: 'R5',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.R5)) * 100).toFixed(0) + '%')
+          }
+        },
+        {
+          title: 'R6',
+          align: 'center',
+          key: 'R6',
+          render: function (h, params) {
+            return h('span', ((Number(params.row.R6)) * 100).toFixed(0) + '%')
+          }
+        }
+      ],
+    }
+  },
+  created() {
+
+  },
+  methods: {
 
-		},
-		data() {
-			return {
-				tableData: [],
-				dataColumns: [
-					{
-						title: this.$t('totalAnalysis.sca_table_text6'),
-						key: 'areaName',
-						align: 'center'
-					},
-					{
-						title: this.$t('totalAnalysis.ta_table_text4'),
-						key: 'score',
-						align: 'center'
-					},
-					{
-						title: this.$t('totalAnalysis.ta_table_text5'),
-						key: 'diff',
-						align: 'center',
-						render: function(h, params) {
-							return h('span', (Number(params.row.diff)).toFixed(2))
-						}
-					},
-					{
-						title: this.$t('totalAnalysis.ta_table_text6'),
-						key: 'identify',
-						align: 'center',
-						render: function(h, params) {
-							return h('span', (Number(params.row.identify)).toFixed(2))
-						}
-					},
-					{
-						title: this.$t('totalAnalysis.trueAnswerRate'),
-						align: 'center',
-						key: 'classScoreRate'
-					},
-					{
-						title: this.$t('totalAnalysis.PHAnswerRate'),
-						align: 'center',
-						key: 'PH',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.PH)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: this.$t('totalAnalysis.PLAnswerRate'),
-						align: 'center',
-						key: 'PL',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.PL)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: 'R1',
-						align: 'center',
-						key: 'R1',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.R1)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: 'R2',
-						key: 'R2',
-						align: 'center',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.R2)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: 'R3',
-						align: 'center',
-						key: 'R3',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.R3)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: 'R4',
-						align: 'center',
-						key: 'R4',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.R4)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: 'R5',
-						align: 'center',
-						key: 'R5',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.R5)) * 100).toFixed(0) + '%')
-						}
-					},
-					{
-						title: 'R6',
-						align: 'center',
-						key: 'R6',
-						render: function(h, params) {
-							return h('span', ((Number(params.row.R6)) * 100).toFixed(0) + '%')
-						}
-					}
-				],
-			}
-		},
-		created() {
-			
-		},
-		methods: {
+  },
+  mounted() {
 
-		},
-		mounted() {
-			
-		},
-		watch: {
-			analysisJson:{
-				handler(n,o){
-					this.tableData = [n]
-				},
-				immediate:true,
-				deep:true
-			},
-		}
+  },
+  watch: {
+    analysisJson: {
+      handler(n, o) {
+        console.error('analysisJson', n)
+        this.tableData = [n]
+      },
+      immediate: true,
+      deep: true
+    },
+  }
 
-	}
+}
 </script>

+ 464 - 470
TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue

@@ -1,494 +1,488 @@
 <template>
-	<div class="ev-cp-list-container" style="width: 100%; margin: 0 auto">
-		<!-- 筛选部分结束 -->
-		<!-- 题目列表部分 -->
-		<Loading :top="100" v-show="dataLoading" hideMask></Loading>
-		<div v-if="exerciseList.length === 0" class="no-data-text">
-			<img src="@/assets/icon/no_data_evaluation.png" width="120" />
-			<span style="margin-top: 15px; color: #808080">{{$t('evaluation.noData')}}</span>
-		</div>
-		<div class="cp-content-wrap" ref="mathJaxContainer" v-else>
-			<p style="color: #1b87e6;text-align: end;text-decoration: underline;cursor: pointer;" v-if="!isAnalysis"><span @click="onSelectAll">{{ $t('evaluation.choosePageItems') }}</span></p>
-			<div class="cp-exercise-item" v-for="(item, index) of exerciseList" :key="index">
-				<!-- 题干部分 -->
-				<div class="item-question"  @click="onQuestionToggle(index, item.id, $event)">
-					<div>
-						<div class="item-question-order">
-							{{ pageSize * (pageNum - 1) + index + 1 }} :
-						</div>
-						<div class="item-question-text" v-html="item.question"></div>
-					</div>
-					<span class="item-btn-toggle">
-						<Icon :type="collapseList.indexOf(index) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown' " />
-					</span>
-				</div>
-				<!-- 选项部分 -->
-				<div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options"  @click="onQuestionToggle(index, item.id, $event)">
-					<div class="item-option-content">
-						<div class="item-option-order">
-							<!-- {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} : -->
-							{{ option.code }} :
-						</div>
-						<div class="item-option-text" v-html="option.value"></div>
-					</div>
-				</div>
-				<div class="exercise-item-children" v-if="item.children.length">
-					<BaseChild :children="item.children" :isShowAnalysis="isShowAnalysis" :analysisJson="getChildAnalysisJson(item)" :optionRate="getChildOptionRate(item)" inBank></BaseChild>
-				</div>
-				<transition name="slide" v-if="item.type !== 'compose'">
-					<div v-if="collapseList.includes(exerciseList.indexOf(item))" class="toggle-area">
-						<div>
-							<!-- 答案展示部分 -->
-							<div class="item-explain">
-								<span class="explain-title">【{{$t('evaluation.answer')}}】</span>
-								<div class="item-explain-details">
-									<!-- 问答题答案 -->
-									<div v-if="item.type === 'subjective' || item.type === 'complete' || item.type === 'connector' || item.type === 'correct'">
-										<span v-for="(answer, index) in item.answer" :key="index" v-html="item.answer.length ? answer : $t('utils.noData')"></span>
-									</div>
-									<!-- 问答题答案 -->
-									<div v-else-if="item.type === 'judge'">
-										<span>{{ item.answer.length ? (item.answer[0] === 'A' ? $t('evaluation.isTrue') : $t('evaluation.isFalse')) : $t('utils.noData') }}</span>
-									</div>
-									<!-- 其余题型答案 -->
-									<div v-else>
-										<span :class="[ item.type === 'complete' ? 'item-answer-item' : '' ]" v-for="(answer, index) in item.answer" :key="index">{{ answer }}</span>
-									</div>
-								</div>
-							</div>
-							<!-- 解析部分 -->
-							<div class="item-explain">
-								<span class="explain-title">【{{$t('evaluation.explain')}}】</span>
-								<div class="item-explain-details">
-									<span v-html="item.explain || $t('utils.noData')"></span>
-								</div>
-							</div>
-							<!-- 知识点部分 -->
-							<div class="item-explain">
-								<span class="explain-title">【{{$t('evaluation.knowledgePoints')}}】</span>
-								<div class="item-explain-details">
-									<span v-if="!item.knowledge || !item.knowledge.length">{{ $t('utils.noData') }}</span>
-									<div v-else>
-										<span v-for="(point, pointIndex) in item.knowledge" class="item-point-tag" :key="pointIndex">
-											{{ point }}
-										</span>
-									</div>
-								</div>
-							</div>
-							<!-- 认知层次部分 -->
-							<div class="item-explain">
-								<span class="explain-title" :style="{ color:isShowAnalysis ? '#099209' : '#10abe7' }">【{{$t('evaluation.field')}}】</span>
-								<div class="item-explain-details">
-									<span>{{ exersicesField[item.field - 1] }}</span>
-								</div>
-							</div>
-							<!-- 补救资源部分 -->
-							<div class="item-explain">
-								<span class="explain-title">【{{ $t('evaluation.newExercise.repair') }}】</span>
-								<div class="item-explain-details">
-									<div v-if="item.repair && item.repair.length" style="display: flex;flex-wrap: wrap;">
-										<div class="repair-item" v-for="(link,index) in item.repair">
-											<img :src="$tools.getFileThum(link.type,link.name)" width="20"/>
-											<span class="repair-item-link" @click.stop="onRepairLinkClick(link)">{{ link.name }}</span>
-										</div>
-									</div>
-									<span v-else>{{ $t('utils.noData') }}</span>
-								</div>
-							</div>
-							<div class="item-explain" v-if="isShowAnalysis">
-								<span class="explain-title">【{{ $t('totalAnalysis.showAnalysis') }}】</span>
-								<div class="item-explain-details">
-									<AnalysisItemTable :analysisJson="analysisJson[index]"></AnalysisItemTable>
-									</br>
-									<OptionsTable v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'"
-									 :options="item.option.map(i => i.code)" :optionRate="optionRate[index]"
-									 :answer="item.answer"
-									 ></OptionsTable>
-									 </br>
-									 <Row>
-										 <Col span="12" v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'">
-											<BaseRateLine :ids="'R1R6' + index" :echartsData="getOptionLineData(item,index)"></BaseRateLine>
-										 </Col>
-										 <Col span="12">
-										 	<BaseLine :ids="'rateLine' + index" :echartsData="analysisJson[index]"></BaseLine>
-										 </Col>
-									 </Row>
-									 
-								</div>
-							</div>
-						</div>
-						<!-- 如果是综合题 则加载子题渲染组件 -->
-						<!-- <div v-else>
+  <div class="ev-cp-list-container" style="width: 100%; margin: 0 auto">
+    <!-- 筛选部分结束 -->
+    <!-- 题目列表部分 -->
+    <Loading :top="100" v-show="dataLoading" hideMask></Loading>
+    <div v-if="exerciseList.length === 0" class="no-data-text">
+      <img src="@/assets/icon/no_data_evaluation.png" width="120" />
+      <span style="margin-top: 15px; color: #808080">{{$t('evaluation.noData')}}</span>
+    </div>
+    <div class="cp-content-wrap" ref="mathJaxContainer" v-else>
+      <p style="color: #1b87e6;text-align: end;text-decoration: underline;cursor: pointer;" v-if="!isAnalysis"><span @click="onSelectAll">{{ $t('evaluation.choosePageItems') }}</span></p>
+      <div class="cp-exercise-item" v-for="(item, index) of exerciseList" :key="index">
+        <!-- 题干部分 -->
+        <div class="item-question" @click="onQuestionToggle(index, item.id, $event)">
+          <div>
+            <div class="item-question-order">
+              {{ pageSize * (pageNum - 1) + index + 1 }} :
+            </div>
+            <div class="item-question-text" v-html="item.question"></div>
+          </div>
+          <span class="item-btn-toggle">
+            <Icon :type="collapseList.indexOf(index) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown' " />
+          </span>
+        </div>
+        <!-- 选项部分 -->
+        <div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options" @click="onQuestionToggle(index, item.id, $event)">
+          <div class="item-option-content">
+            <div class="item-option-order">
+              <!-- {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} : -->
+              {{ option.code }} :
+            </div>
+            <div class="item-option-text" v-html="option.value"></div>
+          </div>
+        </div>
+        <div class="exercise-item-children" v-if="item.children.length">
+          <BaseChild :children="item.children" :isShowAnalysis="isShowAnalysis" :analysisJson="getChildAnalysisJson(item)" :optionRate="getChildOptionRate(item)" inBank></BaseChild>
+        </div>
+        <transition name="slide" v-if="item.type !== 'compose'">
+          <div v-if="collapseList.includes(exerciseList.indexOf(item))" class="toggle-area">
+            <div>
+              <!-- 答案展示部分 -->
+              <div class="item-explain">
+                <span class="explain-title">【{{$t('evaluation.answer')}}】</span>
+                <div class="item-explain-details">
+                  <!-- 问答题答案 -->
+                  <div v-if="item.type === 'subjective' || item.type === 'complete' || item.type === 'connector' || item.type === 'correct'">
+                    <span v-for="(answer, index) in item.answer" :key="index" v-html="item.answer.length ? answer : $t('utils.noData')"></span>
+                  </div>
+                  <!-- 问答题答案 -->
+                  <div v-else-if="item.type === 'judge'">
+                    <span>{{ item.answer.length ? (item.answer[0] === 'A' ? $t('evaluation.isTrue') : $t('evaluation.isFalse')) : $t('utils.noData') }}</span>
+                  </div>
+                  <!-- 其余题型答案 -->
+                  <div v-else>
+                    <span :class="[ item.type === 'complete' ? 'item-answer-item' : '' ]" v-for="(answer, index) in item.answer" :key="index">{{ answer }}</span>
+                  </div>
+                </div>
+              </div>
+              <!-- 解析部分 -->
+              <div class="item-explain">
+                <span class="explain-title">【{{$t('evaluation.explain')}}】</span>
+                <div class="item-explain-details">
+                  <span v-html="item.explain || $t('utils.noData')"></span>
+                </div>
+              </div>
+              <!-- 知识点部分 -->
+              <div class="item-explain">
+                <span class="explain-title">【{{$t('evaluation.knowledgePoints')}}】</span>
+                <div class="item-explain-details">
+                  <span v-if="!item.knowledge || !item.knowledge.length">{{ $t('utils.noData') }}</span>
+                  <div v-else>
+                    <span v-for="(point, pointIndex) in item.knowledge" class="item-point-tag" :key="pointIndex">
+                      {{ point }}
+                    </span>
+                  </div>
+                </div>
+              </div>
+              <!-- 认知层次部分 -->
+              <div class="item-explain">
+                <span class="explain-title" :style="{ color:isShowAnalysis ? '#099209' : '#10abe7' }">【{{$t('evaluation.field')}}】</span>
+                <div class="item-explain-details">
+                  <span>{{ exersicesField[item.field - 1] }}</span>
+                </div>
+              </div>
+              <!-- 补救资源部分 -->
+              <div class="item-explain">
+                <span class="explain-title">【{{ $t('evaluation.newExercise.repair') }}】</span>
+                <div class="item-explain-details">
+                  <div v-if="item.repair && item.repair.length" style="display: flex;flex-wrap: wrap;">
+                    <div class="repair-item" v-for="(link,index) in item.repair">
+                      <img :src="$tools.getFileThum(link.type,link.name)" width="20" />
+                      <span class="repair-item-link" @click.stop="onRepairLinkClick(link)">{{ link.name }}</span>
+                    </div>
+                  </div>
+                  <span v-else>{{ $t('utils.noData') }}</span>
+                </div>
+              </div>
+              <div class="item-explain" v-if="isShowAnalysis">
+                <span class="explain-title">【{{ $t('totalAnalysis.showAnalysis') }}】</span>
+                <div class="item-explain-details">
+                  <AnalysisItemTable :analysisJson="analysisJson[index]"></AnalysisItemTable>
+                  </br>
+                  <OptionsTable v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'" :options="item.option.map(i => i.code)" :optionRate="optionRate[index]" :answer="item.answer"></OptionsTable>
+                  </br>
+                  <Row>
+                    <Col span="12" v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'">
+                    <BaseRateLine :ids="'R1R6' + index" :echartsData="getOptionLineData(item,index)"></BaseRateLine>
+                    </Col>
+                    <Col span="12">
+                    <BaseLine :ids="'rateLine' + index" :echartsData="analysisJson[index]"></BaseLine>
+                    </Col>
+                  </Row>
+
+                </div>
+              </div>
+            </div>
+            <!-- 如果是综合题 则加载子题渲染组件 -->
+            <!-- <div v-else>
 							<BaseChild :children="item.children"></BaseChild>
 						</div> -->
-					</div>
-				</transition>
-				
-				<!-- 底部题目操作栏 -->
-				<div class="item-tools">
-					<span class="item-tools-info">{{$t('evaluation.filter.type')}}:{{ exersicesType[item.type] }}</span>
-					<span class="item-tools-info">{{$t('evaluation.filter.diff')}}:{{ exersicesDiff[item.level - 1] }}</span>
-					<!-- <span class="item-tools-info">{{$t('evaluation.filter.level')}}:{{ exersicesField[item.field - 1] }}</span> -->
-					<!-- <span class="item-tools-info">{{$t('evaluation.filter.useCount')}}:{{ item.usageCount || 0 }} {{ $t('unit.text4') }}</span> -->
-					<!-- <span class="item-tools-info">{{$t('evaluation.updateTime')}}:{{ $tools.formatTime(item.createTime)  || 0 }} </span> -->
-					<Button type="info" v-if="!isAnalysis" :style="{backgroundColor:selectList.map(i => i.id).indexOf(item.id) > -1 ? '#bbbbbb' : '#2db7f5'}"
-					 @click.stop="onSelectItem(item,index)">{{ selectList.map(i => i.id).indexOf(item.id) > -1 ? $t('evaluation.remove') : $t('evaluation.choose')}}</Button>
-				</div>
-			</div>
-		</div>
+          </div>
+        </transition>
 
+        <!-- 底部题目操作栏 -->
+        <div class="item-tools">
+          <span class="item-tools-info">{{$t('evaluation.filter.type')}}:{{ exersicesType[item.type] }}</span>
+          <span class="item-tools-info">{{$t('evaluation.filter.diff')}}:{{ exersicesDiff[item.level - 1] }}</span>
+          <!-- <span class="item-tools-info">{{$t('evaluation.filter.level')}}:{{ exersicesField[item.field - 1] }}</span> -->
+          <!-- <span class="item-tools-info">{{$t('evaluation.filter.useCount')}}:{{ item.usageCount || 0 }} {{ $t('unit.text4') }}</span> -->
+          <!-- <span class="item-tools-info">{{$t('evaluation.updateTime')}}:{{ $tools.formatTime(item.createTime)  || 0 }} </span> -->
+          <Button type="info" v-if="!isAnalysis" :style="{backgroundColor:selectList.map(i => i.id).indexOf(item.id) > -1 ? '#bbbbbb' : '#2db7f5'}" @click.stop="onSelectItem(item,index)">{{ selectList.map(i => i.id).indexOf(item.id) > -1 ? $t('evaluation.remove') : $t('evaluation.choose')}}</Button>
+        </div>
+      </div>
+    </div>
 
-		<!-- 底部分页区域 -->
-		<Page :total="totalNum" v-if="!isAnalysis" show-sizer show-total :page-size="pageSize" :current="pageNum" @on-page-size-change="pageSizeChange"
-		 @on-change="pageChange" :page-size-opts="[5, 10, 15, 20]" />
-	</div>
+    <!-- 底部分页区域 -->
+    <Page :total="totalNum" v-if="!isAnalysis" show-sizer show-total :page-size="pageSize" :current="pageNum" @on-page-size-change="pageSizeChange" @on-change="pageChange" :page-size-opts="[5, 10, 15, 20]" />
+  </div>
 </template>
 <script>
-	import blobTool from "@/utils/blobTool.js";
-	import AnalysisItemTable from '@/components/evaluation/AnalysisItemTable'
-	import OptionsTable from '@/components/evaluation/OptionsTable'
-	import BaseLine from '@/components/student-analysis/total/BaseLine.vue'
-	import BaseRateLine from '@/components/student-analysis/total/BaseRateLine.vue'
-	export default {
-		components:{AnalysisItemTable,OptionsTable,BaseRateLine,BaseLine},
-		props:{
-			propsList:{
-				type:Array,
-				default:() => {
-					return []
-				}
-			},
-			analysisJson:{
-				type:Array,
-				default:() => {
-					return []
-				}
-			},
-			optionRate:{
-				type:Array,
-				default:() => {
-					return []
-				}
-			},
-			flatIds:{
-				type:Array,
-				default:() => {
-					return []
-				}
-			},
-			selQue: {
-			    type: Array,
-			    default: () => {
-			        return []
-			    }
-			},
-			isAnalysis:{
-				type:Boolean,
-				default:false
-			},
-			inSyllabus:{
-				type:Boolean,
-				default:false
-			},
-			hasSas:{
-				type:Boolean,
-				default:false
-			},
-			isShowAnalysis: {
-				type: Boolean,
-				default: false
-			},
-			examScope:{
-				type:String,
-				default:null
-			}
-		},
-		data() {
-			return { 
-				examPropScope:null,
-				dataLoading: false,
-				exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
-				exersicesDiff: this.$GLOBAL.EXERCISE_DIFFS(),
-				exersicesField: this.$GLOBAL.EXERCISE_LEVELS(),
-				diffColors: ["#32CF74", "#E8BE15", "#F19300", "#EB5E00", "#D30000"],
-				totalNum: 0,
-				isShowAnswer: true,
-				importLoading: false,
-				pageSize: 5,
-				pageNum: 1,
-				currentPage: 1,
-				collapseList: [],
-				selectList:[],
-				originData: [],
-				exerciseList:[],
-			};
-		},
-		created() {
-			this.pageSize = this.isAnalysis ? 999 : 5
-			this.pageChange(1)
-		},
-		methods: {
-			/* 补救资源点击事件 */
-			onRepairLinkClick(link){
-				window.open(/^(http:|https:)/i.test(link.blobUrl) ? link.blobUrl : "http://" + link.blobUrl)
-			},
-			onSelectAll(){
-				let curPageItems = this.exerciseList
-				if(curPageItems.length){
-					let selectItemIds = this.selectList.map(i => i.id)
-					curPageItems.forEach(i => {
-						if(!selectItemIds.includes(i.id)){
-							this.selectList.push(i)
-						}
-					})
-					this.$emit('on-question-change', this.selectList,0)
-				}
-				this.$Message.success(this.$t('syllabus.doSuc'))
-			},
-			getBlobList(list){
-				return new Promise(async (r,j) => {
-					if(list.length){
-						/* 如果是评测里面的试题 则不需要从getFullItem取 */
-						let blobList = this.examPropScope ? list : await this.$evTools.getFullItem(list,undefined,this.inSyllabus)
-						r(blobList)
-					}else{
-						r([])
-					}
-					
-				})
-			},
-			
-			getOptionLineData(item,index){
-				let result = []
-				let n = this.optionRate[index]
-				let total = this.$store.state.totalAnalysis.analysisJson.all.total // 取总人数
-				let phCount = Math.floor(total * 0.27) //取高分组低分组人数
-				item.option.map(i => i.code).forEach(key => {
-					result.push({
-						option:key,
-						rate:n.record[key] ? ((n.record[key] / total) * 100).toFixed(1) : 0,
-						PH: n.ph[key] ? ((n.ph[key] / phCount) * 100).toFixed(1) : 0,
-						PL: n.pl[key] ? ((n.pl[key] / phCount) * 100).toFixed(1) : 0,
-					})
-				})
-				return result
-			},
-			
-			getChildAnalysisJson(pItem){
-				let result = []
-				pItem.children.forEach(child => {
-					result.push(this.analysisJson[this.flatIds.indexOf(child.id)])
-				})
-				return result
-			},
-			
-			getChildOptionRate(pItem){
-				let result = []
-				pItem.children.forEach(child => {
-					result.push(this.optionRate[this.flatIds.indexOf(child.id)])
-				})
-				return result
-			},
-			
-			onSelectItem(item,index){
-				let arrIndex = this.selectList.map(i => i.id).indexOf(item.id)
-				console.log(arrIndex)
-				if(arrIndex > -1){
-					this.selectList.splice(arrIndex,1)
-					this.$Message.warning(this.$t('evaluation.cancelSuc'))
-				}else{
-					this.selectList.push(item)
-					this.$Message.success(this.$t('evaluation.addSuc'))
-				}
-				this.$emit('on-question-change', this.selectList,0)
-				console.log(this.selectList)
-				console.log(item)
-			},
+import blobTool from "@/utils/blobTool.js";
+import AnalysisItemTable from '@/components/evaluation/AnalysisItemTable'
+import OptionsTable from '@/components/evaluation/OptionsTable'
+import BaseLine from '@/components/student-analysis/total/BaseLine.vue'
+import BaseRateLine from '@/components/student-analysis/total/BaseRateLine.vue'
+export default {
+  components: { AnalysisItemTable, OptionsTable, BaseRateLine, BaseLine },
+  props: {
+    propsList: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    analysisJson: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    optionRate: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    flatIds: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    selQue: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    isAnalysis: {
+      type: Boolean,
+      default: false
+    },
+    inSyllabus: {
+      type: Boolean,
+      default: false
+    },
+    hasSas: {
+      type: Boolean,
+      default: false
+    },
+    isShowAnalysis: {
+      type: Boolean,
+      default: false
+    },
+    examScope: {
+      type: String,
+      default: null
+    }
+  },
+  data() {
+    return {
+      examPropScope: null,
+      dataLoading: false,
+      exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
+      exersicesDiff: this.$GLOBAL.EXERCISE_DIFFS(),
+      exersicesField: this.$GLOBAL.EXERCISE_LEVELS(),
+      diffColors: ["#32CF74", "#E8BE15", "#F19300", "#EB5E00", "#D30000"],
+      totalNum: 0,
+      isShowAnswer: true,
+      importLoading: false,
+      pageSize: 5,
+      pageNum: 1,
+      currentPage: 1,
+      collapseList: [],
+      selectList: [],
+      originData: [],
+      exerciseList: [],
+    };
+  },
+  created() {
+    this.pageSize = this.isAnalysis ? 999 : 5
+    this.pageChange(1)
+  },
+  methods: {
+    /* 补救资源点击事件 */
+    onRepairLinkClick(link) {
+      window.open(/^(http:|https:)/i.test(link.blobUrl) ? link.blobUrl : "http://" + link.blobUrl)
+    },
+    onSelectAll() {
+      let curPageItems = this.exerciseList
+      if (curPageItems.length) {
+        let selectItemIds = this.selectList.map(i => i.id)
+        curPageItems.forEach(i => {
+          if (!selectItemIds.includes(i.id)) {
+            this.selectList.push(i)
+          }
+        })
+        this.$emit('on-question-change', this.selectList, 0)
+      }
+      this.$Message.success(this.$t('syllabus.doSuc'))
+    },
+    getBlobList(list) {
+      return new Promise(async (r, j) => {
+        if (list.length) {
+          /* 如果是评测里面的试题 则不需要从getFullItem取 */
+          let blobList = this.examPropScope ? list : await this.$evTools.getFullItem(list, undefined, this.inSyllabus)
+          r(blobList)
+        } else {
+          r([])
+        }
+
+      })
+    },
+
+    getOptionLineData(item, index) {
+      let result = []
+      let n = this.optionRate[index]
+      let total = this.$store.state.totalAnalysis.analysisJson.all.total // 取总人数
+      let phCount = Math.floor(total * 0.27) //取高分组低分组人数
+      item.option.map(i => i.code).forEach(key => {
+        result.push({
+          option: key,
+          rate: n.record[key] ? ((n.record[key] / total) * 100).toFixed(1) : 0,
+          PH: n.ph[key] ? ((n.ph[key] / phCount) * 100).toFixed(1) : 0,
+          PL: n.pl[key] ? ((n.pl[key] / phCount) * 100).toFixed(1) : 0,
+        })
+      })
+      return result
+    },
+
+    getChildAnalysisJson(pItem) {
+      let result = []
+      pItem.children.forEach(child => {
+        result.push(this.analysisJson[this.flatIds.indexOf(child.id)])
+      })
+      return result
+    },
+
+    getChildOptionRate(pItem) {
+      let result = []
+      pItem.children.forEach(child => {
+        result.push(this.optionRate[this.flatIds.indexOf(child.id)])
+      })
+      return result
+    },
+
+    onSelectItem(item, index) {
+      let arrIndex = this.selectList.map(i => i.id).indexOf(item.id)
+      console.log(arrIndex)
+      if (arrIndex > -1) {
+        this.selectList.splice(arrIndex, 1)
+        this.$Message.warning(this.$t('evaluation.cancelSuc'))
+      } else {
+        this.selectList.push(item)
+        this.$Message.success(this.$t('evaluation.addSuc'))
+      }
+      this.$emit('on-question-change', this.selectList, 0)
+      console.log(this.selectList)
+      console.log(item)
+    },
+
+    /**
+     * 全部展开与全部折叠
+     * @param isAllOpen
+     */
+    onHandleToggle(isAllOpen) {
+      if (isAllOpen) {
+        this.collapseList = [];
+      } else {
+        this.collapseList = [...this.exerciseList.keys()];
+      }
+      console.log(this.collapseList)
+    },
+
+    /**
+     * 题干展开与收缩
+     * @param index
+     * @param id
+     */
+    onQuestionToggle(index, id, e) {
+      console.log(e)
+      let curClassName = e.target.className;
+      if (
+        curClassName === "item-tools" ||
+        curClassName === "richText-video" ||
+        curClassName === "richText-audio"
+      )
+        return;
+      e.stopPropagation();
+      let listIndex = this.collapseList.indexOf(index);
+      if (listIndex > -1) {
+        this.collapseList.splice(listIndex, 1);
+      } else {
+        this.collapseList.push(index);
+        let exerciseItemDom = e.path.filter(
+          (i) => i.className === "exercise-item"
+        );
+        if (exerciseItemDom.length) {
+          this.$emit("pageScroll", exerciseItemDom[0].offsetTop);
+          exerciseItemDom[0].style.border = '2px solid #2db7f5'
+          setTimeout(() => {
+            exerciseItemDom[0].style.border = '2px solid transparent'
+          }, 2000)
+        }
+      }
 
-			/**
-			 * 全部展开与全部折叠
-			 * @param isAllOpen
-			 */
-			onHandleToggle(isAllOpen) {
-				if (isAllOpen) {
-					this.collapseList = [];
-				} else {
-					this.collapseList = [...this.exerciseList.keys()];
-				}
-				console.log(this.collapseList)
-			},
+      this.$emit("toggleChange", this.collapseList);
+    },
 
-			/**
-			 * 题干展开与收缩
-			 * @param index
-			 * @param id
-			 */
-			onQuestionToggle(index, id, e) {
-				console.log(e)
-				let curClassName = e.target.className;
-				if (
-					curClassName === "item-tools" ||
-					curClassName === "richText-video" ||
-					curClassName === "richText-audio"
-				)
-					return;
-				e.stopPropagation();
-				let listIndex = this.collapseList.indexOf(index);
-				if (listIndex > -1) {
-					this.collapseList.splice(listIndex, 1);
-				} else {
-					this.collapseList.push(index);
-					let exerciseItemDom = e.path.filter(
-						(i) => i.className === "exercise-item"
-					);
-					if (exerciseItemDom.length) {
-						this.$emit("pageScroll", exerciseItemDom[0].offsetTop);
-						exerciseItemDom[0].style.border = '2px solid #2db7f5'
-						setTimeout(() => {
-							exerciseItemDom[0].style.border = '2px solid transparent'
-						},2000)
-					}
-				}
 
-				this.$emit("toggleChange", this.collapseList);
-			},
+    /**
+     * 删除筛选条件里面的False值与All值
+     * @param arr
+     */
+    deleteFalse(arr) {
+      let list = JSON.parse(JSON.stringify(arr));
+      list.forEach((item, index) => {
+        if (!item || item === "all") list.splice(index, 1);
+      });
+      return list;
+    },
 
-			
-			/**
-			 * 删除筛选条件里面的False值与All值
-			 * @param arr
-			 */
-			deleteFalse(arr) {
-				let list = JSON.parse(JSON.stringify(arr));
-				list.forEach((item, index) => {
-					if (!item || item === "all") list.splice(index, 1);
-				});
-				return list;
-			},
+    /**
+     * 切换页码操作
+     * @param page
+     */
+    async pageChange(page) {
+      this.dataLoading = true
+      this.pageNum = page;
+      let start = this.pageSize * (page - 1);
+      let end = this.pageSize * page;
+      // 拿到当前页码需要展示的数据
+      this.$emit("pageScroll", 0);
+      let simpleList = this.originData.slice(start, end);
+      console.log('exercise-list > simpleList', simpleList, this.hasSas, this.examPropScope)
+      try {
+        // 执行试题换取完整JSON数据
+        this.exerciseList = this.hasSas && !this.inSyllabus ? simpleList : await this.getBlobList(simpleList);
+        this.currentPage = page;
+        setTimeout(() => {
+          this.dataLoading = false
+        }, 1000)
+      } catch (e) {
+        console.log(e);
+        this.dataLoading = false
+      }
+    },
 
-			/**
-			 * 切换页码操作
-			 * @param page
-			 */
-			async pageChange(page) {
-				this.dataLoading = true
-				this.pageNum = page;
-				let start = this.pageSize * (page - 1);
-				let end = this.pageSize * page;
-				// 拿到当前页码需要展示的数据
-				this.$emit("pageScroll", 0);
-				let simpleList = this.originData.slice(start, end);
-				console.log('exercise-list > simpleList',simpleList,this.hasSas,this.examPropScope)
-				try {
-					// 执行试题换取完整JSON数据
-					this.exerciseList = this.hasSas && !this.inSyllabus ? simpleList : await this.getBlobList(simpleList);
-					this.currentPage = page;
-					setTimeout(() => {
-						this.dataLoading = false
-					},1000)
-				} catch (e) {
-					console.log(e);
-					this.dataLoading = false
-				}
-			},
+    /**
+     * 切换每页显示数量
+     * @param val
+     */
+    pageSizeChange(val) {
+      this.pageSize = val;
+      this.pageChange(1);
+    },
 
-			/**
-			 * 切换每页显示数量
-			 * @param val
-			 */
-			pageSizeChange(val) {
-				this.pageSize = val;
-				this.pageChange(1);
-			},
+  },
+  mounted() {
+    this.selectList = this.selQue
+  },
+  computed: {
+    curScope() {
+      return this.filterOrigin === this.$store.state.userInfo.schoolCode ?
+        "school" :
+        "private";
+    },
+    hasSchool() {
+      return this.$store.state.userInfo.hasSchool;
+    },
+  },
+  watch: {
+    propsList: {
+      handler(n, o) {
+        if (n) {
+          if (n.length) {
+            this.originData = n
+            this.totalNum = n.length
+            this.examPropScope = this.examScope
+            this.pageChange(1)
+          } else {
+            this.dataLoading = true
+            this.originData = []
+            this.exerciseList = []
+            this.totalNum = 0
+            setTimeout(() => {
+              this.dataLoading = false
+            }, 500)
+          }
 
-		},
-		mounted() {
-			this.selectList = this.selQue
-		},
-		computed: {
-			curScope() {
-				return this.filterOrigin === this.$store.state.userInfo.schoolCode ?
-					"school" :
-					"private";
-			},
-			hasSchool() {
-				return this.$store.state.userInfo.hasSchool;
-			},
-		},
-		watch:{
-			propsList:{
-				handler(n,o){
-					if(n){
-						if(n.length){
-							this.originData = n
-							this.totalNum = n.length
-							this.examPropScope = this.examScope
-							this.pageChange(1)
-						}else{
-							this.dataLoading = true
-							this.originData = []
-							this.exerciseList = []
-							this.totalNum = 0
-							setTimeout(() => {
-								this.dataLoading = false
-							},500)
-						}
-						
-					}
-				}
-			},
-			optionRate:{
-				handler(n,o){
-					if(n){
-						// console.log(n)
-					}
-				},
-				immediate:true,
-				deep:true
-			},
-			examScope:{
-				handler(n,o){
-					this.examPropScope = n
-				},
-				immediate:true
-			},
-			selQue:{
-				handler(n,o){
-					if(n){
-						console.log('监听到222',n)
-					}
-				}
-			},
-		}
-	};
+        }
+      }
+    },
+    optionRate: {
+      handler(n, o) {
+        if (n) {
+          console.error(n)
+        }
+      },
+      immediate: true,
+      deep: true
+    },
+    examScope: {
+      handler(n, o) {
+        this.examPropScope = n
+      },
+      immediate: true
+    },
+    selQue: {
+      handler(n, o) {
+        if (n) {
+          console.log('监听到222', n)
+        }
+      }
+    },
+  }
+};
 </script>
 <style src="./ExerciseList.less" lang="less" scoped>
 </style>
 
 <style>
-	.cp-exercise-item .item-question-text img{
-		max-width: 100%;
-	}
+.cp-exercise-item .item-question-text img {
+  max-width: 100%;
+}
 
-	.circle {
-		border: solid 1px red;
-		background-color: red;
-		border-radius: 50%;
-		width: 50px;
-		height: 50px;
-	}
+.circle {
+  border: solid 1px red;
+  background-color: red;
+  border-radius: 50%;
+  width: 50px;
+  height: 50px;
+}
 
-	.slide-enter-active {
-		transition: all 0.3s ease;
-	}
+.slide-enter-active {
+  transition: all 0.3s ease;
+}
 
-	.slide-leave-active {
-		transition: all 0.3s ease;
-	}
+.slide-leave-active {
+  transition: all 0.3s ease;
+}
 
-	.slide-enter,
-	.slide-leave-to {
-		transform: translateY(10px);
-		opacity: 0;
-	}
+.slide-enter,
+.slide-leave-to {
+  transform: translateY(10px);
+  opacity: 0;
+}
 </style>

+ 5 - 4
TEAMModelOS/ClientApp/src/components/student-web/ClassRecord/ReceiveBack.vue

@@ -50,10 +50,10 @@
         <div v-if="previewStatus" class="image-viewer">
             <div style="width:fit-content;position:relative;margin:auto;">
                 <Icon type="md-close" class="close-icon" @click="closePreview" />
-                <video v-if="collateType == 4" id="previewVideo" :src="prevUrl" width="870" controls="controls" style="max-height: 800px;">
+                <video v-if="collateType == 'Video' || collateType == 4" id="previewVideo" :src="prevUrl" width="870" controls="controls" style="max-height: 800px;">
                     {{$t('teachContent.tips8')}}
                 </video>
-                <audio v-else-if="collateType == 3" controls>
+                <audio v-else-if="collateType == 'Audio' || collateType == 3" controls>
                     <source :src="prevUrl">
                     {{$t('teachContent.notAudio')}}
                 </audio>
@@ -160,9 +160,10 @@ export default {
                     //处理完整文件路径
                     let urls = `${sas.url}/${sas.name}/records/${this.recordInfo.id}${stu}?${sas.sas}`
                     let stuId = stu.substring(stu.lastIndexOf('/Clients/') + 9, stu.lastIndexOf('/Task'))
-                    let stuInfo = this.students.find(item => {
+                    // 要把查找的进行深拷贝,不然修改的会是原数组,导致所有的文件地址都是最后一个
+                    let stuInfo = this._.cloneDeep(this.students.find(item => {
                         return item.id === stuId
-                    })
+                    }))
                     stuInfo.url = urls
                     this.receiveData.push(stuInfo)
                 })

+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/ClassRecord/StuReceive.vue

@@ -50,10 +50,10 @@
         <div v-if="previewStatus" class="image-viewer">
             <div style="width:fit-content;position:relative;margin:auto;">
                 <Icon type="md-close" class="close-icon" @click="closePreview" />
-                <video v-if="collateType == 4" id="previewVideo" :src="prevUrl" width="870" controls="controls" style="max-height: 800px;">
+                <video v-if="collateType == 'Video'" id="previewVideo" :src="prevUrl" width="870" controls="controls" style="max-height: 800px;">
                     {{$t('teachContent.tips8')}}
                 </video>
-                <audio v-else-if="collateType == 3" controls>
+                <audio v-else-if="collateType == 'Audio'" controls>
                     <source :src="prevUrl">
                     {{$t('teachContent.notAudio')}}
                 </audio>

+ 12 - 12
TEAMModelOS/ClientApp/src/view/ability/Review.vue

@@ -21,7 +21,7 @@
         </span>
         <div class="task-item" v-for="(task,taskIndex) in std.task" :key="taskIndex">
           <div v-if="curTaskIndexArr[index] === taskIndex">
-            <p class="unit-item-des">{{ task.stddesc }} <span style="color: red;font-weight: bold;">(可上传材料数量:{{ task.limit }})</span> </p>
+            <p class="unit-item-des">{{ task.stddesc }} <span style="color: red;font-weight: bold;">({{$t('ability.review.allowLimit')}}{{ task.limit }})</span> </p>
             <!-- 上传按钮 -->
             <div class="task-upload">
               <Button type="info" icon="md-cloud-upload" class="upload-btn" @click="onUpload(std,index,task)" v-show="stdFileArr[index].length < task.limit && isSelfMode">{{ $t('ability.review.upload') }}</Button>
@@ -50,7 +50,7 @@
                   <Icon type="ios-square-outline" size="18" @click="onCheckAll(index,'1',task.titles)" v-if="appraiseResultArr[index] !== 'good'" />
                   <Icon type="ios-checkbox" size="20" color="#2d8cf0" @click="onCheckAll(index,'1',task.titles)" v-if="appraiseResultArr[index] === 'good'" />
                   {{ $t('ability.good') }}
-                  <span style="font-size:14px">(85分以上)</span>
+                  <span style="font-size:14px">(85{{$t('ability.review.scoreUp')}})</span>
                 </p>
                 <CheckboxGroup v-model="appraiseList[index]" @on-change="onCheckChange(index,'1',task.titles)">
                   <Checkbox v-for="(point,pointIndex) in task.titles.filter(i => i.value === '1')" :key="pointIndex" :label="point.id">{{ point.title }}</Checkbox>
@@ -62,7 +62,7 @@
                   <Icon type="ios-square-outline" size="18" @click="onCheckAll(index,'2',task.titles)" v-if="!isAllNormalArr[index]" />
                   <Icon type="ios-checkbox" size="20" color="#2d8cf0" @click="onCheckAll(index,'2',task.titles)" v-if="isAllNormalArr[index]" />
                   {{ $t('ability.normal') }}
-                  <span style="font-size:14px">(60分~85分)</span>
+                  <span style="font-size:14px">(60{{$t('ability.review.score')}}~85{{$t('ability.review.score')}})</span>
                 </p>
                 <CheckboxGroup v-model="appraiseList[index]" @on-change="onCheckChange(index,'2',task.titles)">
                   <Checkbox v-for="(point,pointIndex) in task.titles.filter(i => i.value === '2')" :key="pointIndex" :label="point.id">{{ point.title }}</Checkbox>
@@ -70,14 +70,14 @@
               </div>
               <div v-if="!task.titles.length">
                 <RadioGroup type="button" v-model="appraiseResultArr[index]" @on-change="getFinalResult()">
-                  <Radio label="good" border>{{ $t('ability.good') }} <span style="font-size:12px">(85分以上)</span></Radio>
-                  <Radio label="normal" border>{{ $t('ability.normal') }} <span style="font-size:12px">(60分~85分)</span></Radio>
-                  <Radio label="bad" border>{{ $t('ability.bad') }} <span style="font-size:12px">(60分以下)</span></Radio>
+                  <Radio label="good" border>{{ $t('ability.good') }} <span style="font-size:12px">(85分{{$t('ability.review.scoreUp')}})</span></Radio>
+                  <Radio label="normal" border>{{ $t('ability.normal') }} <span style="font-size:12px">(60{{$t('ability.review.score')}}~85{{$t('ability.review.score')}})</span></Radio>
+                  <Radio label="bad" border>{{ $t('ability.bad') }} <span style="font-size:12px">(60{{$t('ability.review.scoreDown')}})</span></Radio>
                 </RadioGroup>
               </div>
             </div>
             <div class="appraise-result">
-              <span>{{ isSelfMode ? '自评结果' : $t('ability.result') }}:</span>
+              <span>{{ isSelfMode ? $t('ability.review.self') : $t('ability.result') }}:</span>
               <span class="good" v-if="appraiseResultArr[index] === 'good'">
                 <Icon type="md-happy" size="22" />{{ $t('ability.good') }}
               </span>
@@ -202,8 +202,8 @@ export default {
       } else {
         if (this.hasModify) {
           this.$Modal.confirm({
-            title: '温馨提示',
-            content: '您未确认“提交评审结果”,无法保存修改内容,是否确认离开?',
+            title: this.$t('ability.review.tip6'),
+            content: this.$t('ability.review.tip7'),
             onOk: () => {
               this.$emit('goBack', {
                 needRefresh: needFresh
@@ -307,7 +307,7 @@ export default {
       })
       if (repeatArr.length) {
         res = res.filter(i => !repeatArr.find(j => j.name === i.name))
-        this.$Message.success(`${repeatArr[0].name} 等 ${repeatArr.length} 个文件已更新!`)
+        this.$Message.success(`${repeatArr[0].name} ${this.$t('ability.review.tip8')} ${repeatArr.length} ${this.$t('ability.review.tip9')}`)
       }
       this.$set(this.stdFileArr, this.curUploadIndex, this.stdFileArr[this.curUploadIndex].concat(res))
       this.uploadModal = false
@@ -404,8 +404,8 @@ export default {
     onDelete(file, index, stdIndex) {
       console.log(file);
       this.$Modal.confirm({
-        title: '删除认证材料',
-        content: `确认删除该认证材料吗?`,
+        title: this.$t('ability.review.tip10'),
+        content: this.$t('ability.review.tip11'),
         onOk: () => {
           // 代表是编辑状态下的删除
           if (file.score) {

+ 55 - 68
TEAMModelOS/ClientApp/src/view/areaMgmt/AreaData.vue

@@ -23,7 +23,7 @@
             </div>
             <!-- 网络研修数据统计 -->
             <div class="online-train-wrap">
-                <h4 class="block-title">研修统计</h4>
+                <h4 class="block-title">{{$('td.td1')}}</h4>
                 <div class="online-data-wrap">
                     <div class="percent-wrap border-style">
                         <Percent :count="dimensions"></Percent>
@@ -35,7 +35,7 @@
             </div>
             <!-- 学时数据统计 -->
             <div class="online-train-wrap" style="margin-bottom:40px">
-                <h4 class="block-title">学时统计</h4>
+                <h4 class="block-title">{{$('td.td2')}}</h4>
                 <div class="hour-data-wrap">
                     <div class="hour-data-item border-style" v-for="(item,index) in hourData" :key="index">
                         <p class="hour-data-title">
@@ -43,11 +43,11 @@
                             <!-- <span class="hour-value">({{item.total}}学时)</span> -->
                         </p>
                         <p class="hour-data-info" v-show="index == 0">
-                            {{`总学时:${item.time}分钟`}}
-                            <span>{{`(${item.studyHour}学时)`}}</span>
+                            {{`${$('td.td3')}${item.time}${$('td.td4')}`}}
+                            <span>{{`(${item.studyHour}${$('td.td5')})`}}</span>
                         </p>
                         <p class="hour-data-info" v-show="index !== 0" style="color:white">
-                            学时
+                            {{$('td.td5')}}
                             <!-- {{`总学时:${item.studyHour}学时`}} -->
                         </p>
                         <div class="hour-chart">
@@ -56,23 +56,23 @@
                                 <div>
                                     <p class="legend-item">
                                         <span>
-                                            未开始:{{item.uncomplete}}人
+                                            {{$('td.td6')}}{{item.uncomplete}}{{$('unit.text7')}}
                                         </span>
                                     </p>
                                     <p class="legend-item">
                                         <span>
-                                            进行中:{{item.going}}人
+                                            {{$('td.td7')}}{{item.going}}{{$('unit.text7')}}
                                         </span>
                                     </p>
                                     <p class="legend-item">
                                         <span>
-                                            已完成:{{item.complete}}人
+                                            {{$('td.td8')}}{{item.complete}}{{$('unit.text7')}}
                                         </span>
                                     </p>
                                 </div>
                                 <i-circle :percent="item.percent" :size="70">
                                     <span>{{item.percent}}%</span>
-                                    <p style="font-size:12px;margin-top:5px">合格率</p>
+                                    <p style="font-size:12px;margin-top:5px">{{$('td.td9')}}</p>
                                 </i-circle>
                             </div>
                         </div>
@@ -83,7 +83,7 @@
             <!-- 学校概览 -->
             <div class="online-train-wrap" style="margin-bottom:40px">
                 <div>
-                    <h4 class="block-title">学校概览</h4>
+                    <h4 class="block-title">{{$('td.td10')}}</h4>
                 </div>
                 <div class="school-data-wrap border-style">
                     <SchoolComp :schools="schoolList"></SchoolComp>
@@ -93,14 +93,14 @@
             <!-- 学校列表 -->
             <div class="online-train-wrap" style="margin-bottom:40px">
                 <div>
-                    <h4 class="block-title">学校列表</h4>
+                    <h4 class="block-title">{{$('td.td11')}}</h4>
                     <Button class="export-data-wrap" type="primary" icon="md-cloud-download" @click="exportSchoolData">
-                        导出学校数据
+                        {{$('td.td12')}}
                     </Button>
                     <Button style="margin-right:15px" class="export-data-wrap" type="primary" icon="md-cloud-download" @click="exportTeacherData">
-                        导出教师数据
+                        {{$('td.td13')}}
                     </Button>
-                    <Input v-special-char search placeholder="搜索学校" class="school-search" v-model="keyWord" @on-change="searchSchool" />
+                    <Input v-special-char search :placeholder="$('td.td14')" class="school-search" v-model="keyWord" @on-change="searchSchool" />
                 </div>
                 <div class="school-data-wrap">
                     <div class="school-data-item border-style" v-for="(item,index) in schoolListShow" :key="index">
@@ -108,27 +108,27 @@
                         <div style="margin-left:10px;height:fit-content;">
                             <p class="school-name" :title="item.schoolName">{{item.schoolName}}</p>
                             <p class="school-value">
-                                <span>参训人数:</span>
-                                <span>{{item.trainCount}}</span>
+                                <span>{{$('td.td15')}}:</span>
+                                <span>{{item.trainCount}}{{$('unit.text7')}}</span>
                             </p>
                             <p class="school-value">
-                                <span>未开始:</span>
-                                <span>{{item.pending || 0}}</span>
+                                <span>{{$('td.td6')}}</span>
+                                <span>{{item.pending || 0}}{{$('unit.text7')}}</span>
                             </p>
                             <p class="school-value">
-                                <span>进行中:</span>
-                                <span>{{item.going || 0}}</span>
+                                <span>{{$('td.td7')}}</span>
+                                <span>{{item.going || 0}}{{$('unit.text7')}}</span>
                             </p>
                             <p class="school-value">
-                                <span>已完成:</span>
-                                <span>{{item.finish || 0}}</span>
+                                <span>{{$('td.td8')}}</span>
+                                <span>{{item.finish || 0}}{{$('unit.text7')}}</span>
                             </p>
                             <span class="to-school-detail" @click="toSchoolDetail(index)">
-                                详情>>>
+                                {{$('td.td16')}}
                             </span>
                         </div>
                     </div>
-                    <EmptyData :textContent="keyWord ? '未搜索到学校' : '暂无学校数据'" v-show="!schoolListShow.length"></EmptyData>
+                    <EmptyData :textContent="keyWord ? $('td.td17') : $('td.td18')" v-show="!schoolListShow.length"></EmptyData>
                 </div>
             </div>
         </vuescroll>
@@ -168,35 +168,35 @@ export default {
                     icon: 'ios-people',
                     color: '#2d8cf0',
                     number: 0,
-                    text: '学校数量',
+                    text: this.$('td.td19'),
                     type: 'num'
                 },
                 {
                     icon: 'md-cube',
                     color: '#2db7f5',
                     number: 0,
-                    text: '参训人数',
+                    text: this.$('td.td15'),
                     type: 'num'
                 },
                 {
                     icon: 'md-bookmark',
                     color: '#5cadff',
                     number: 0,
-                    text: '总学时',
+                    text: this.$('td.td20'),
                     type: 'num'
                 },
                 {
                     icon: 'md-thumbs-up',
                     color: '#ff9900',
                     number: 0,
-                    text: '合格人数',
+                    text: this.$('td.td21'),
                     type: 'num'
                 },
                 {
                     icon: 'md-checkmark-circle',
                     color: '#19be6b',
                     number: 0,
-                    text: '合格率',
+                    text: this.$('td.td9'),
                     type: 'rate'
                 },
             ],
@@ -204,23 +204,10 @@ export default {
             isLoading: false,
             dimensions: [],
             pointCount: {},
-            offlineData: [
-                {
-                    label: '教研组',
-                    value: 0
-                }
-            ],
             trainType: [],
-            trainImgs: [
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E4%BF%A1%E6%81%AF%E5%8C%96%E6%95%99%E5%AD%A6%E6%A1%88%E4%BE%8B.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E4%B8%93%E5%AE%B6%E4%B8%93%E9%A2%98%E5%9F%B9%E8%AE%AD.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E5%90%8C%E8%AF%BE%E5%BC%82%E6%9E%84.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E5%90%8C%E8%AF%BE%E5%90%8C%E6%9E%84.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E6%A0%A1%E6%9C%AC2.0%E5%9F%B9%E8%AE%AD.png'
-            ],
             hourData: [
                 {
-                    name: '线上研修',
+                    name: this.$('td.td22'),
                     complete: 0,
                     going: 0,
                     uncomplete: 0,
@@ -229,7 +216,7 @@ export default {
                     time: 0
                 },
                 {
-                    name: '校本研修',
+                    name: this.$('td.td23'),
                     complete: 0,
                     going: 0,
                     uncomplete: 0,
@@ -238,7 +225,7 @@ export default {
                     time: 0
                 },
                 {
-                    name: '认证材料',
+                    name: this.$('td.td24'),
                     complete: 0,
                     going: 0,
                     uncomplete: 0,
@@ -247,7 +234,7 @@ export default {
                     time: 0
                 },
                 {
-                    name: '课堂实录',
+                    name: this.$('td.td25'),
                     complete: 0,
                     going: 0,
                     uncomplete: 0,
@@ -267,27 +254,27 @@ export default {
             console.log(this.teacherData)
             // return
             let m = this.settingHours.limitMinutes
-            let text = `(${m}分钟)`
-            let ss = `未修满${m > 0 ? text : ''}能力点`
+            let text = `(${m}${this.$t('unit.minute')})`
+            let ss = `${this.$t('td.td26')}${m > 0 ? text : ''}${this.$t('td.td27')}`
             const headerMap = [
                 {
-                    title: '学校',
+                    title: this.$t('td.td28'),
                     key: 'schoolName'
                 },
                 {
-                    title: '姓名',
+                    title: this.$t('td.td29'),
                     key: 'name'
                 },
                 {
-                    title: '总学时',
+                    title: this.$t('td.td20'),
                     key: 'totalTime'
                 },
                 {
-                    title: '线上研修学时',
+                    title: this.$t('td.td30'),
                     key: 'online'
                 },
                 {
-                    title: '所选微能力点',
+                    title: this.$t('td.td31'),
                     key: 'points'
                 },
                 {
@@ -295,47 +282,47 @@ export default {
                     key: 'unFinishArr'
                 },
                 {
-                    title: '已修满的能力点数量',
+                    title: this.$t('td.td32'),
                     key: 'finishArr'
                 },
                 {
-                    title: '认证材料学时',
+                    title: this.$t('td.td33'),
                     key: 'ability'
                 },
                 {
-                    title: '校本研修学时',
+                    title: this.$t('td.td34'),
                     key: 'offline'
                 },
                 {
-                    title: '课堂实录学时',
+                    title: this.$t('td.td35'),
                     key: 'video'
                 },
                 {
-                    title: '认证材料需提交数',
+                    title: this.$t('td.td36'),
                     key: 'abilityCount'
                 },
                 {
-                    title: '已提交认证材料数',
+                    title: this.$t('td.td37'),
                     key: 'commitCount'
                 },
                 {
-                    title: '已提交认证材料能力点',
+                    title: this.$t('td.td38'),
                     key: 'commitNoArr'
                 },
                 {
-                    title: '未提交认证材料数',
+                    title: this.$t('td.td39'),
                     key: 'noAbilityCount'
                 },
                 {
-                    title: '未提交认证材料能力点',
+                    title: this.$t('td.td40'),
                     key: 'noAbilityNoArr'
                 },
                 {
-                    title: '作业未提交数',
+                    title: this.$t('td.td41'),
                     key: 'noHwCount'
                 },
                 {
-                    title: '课堂实录是否提交',
+                    title: this.$t('td.td42'),
                     key: 'isSubmitVideo'
                 },
             ]
@@ -360,7 +347,7 @@ export default {
                     noAbilityCount: teacherAilities.filter(i => i.zpscore === -1).length,
                     noAbilityNoArr: teacherAilities.filter(j => j.zpscore === -1).map(k => k.no).join(','),
                     noHwCount: i.offlineCountNo,
-                    isSubmitVideo: i.teacherClasseCount ? '已提交' : '未提交'
+                    isSubmitVideo: i.teacherClasseCount ? this.$t('td.td43') : this.$t('td.td44')
                 }
             })
             const teacherParams = {
@@ -368,7 +355,7 @@ export default {
                 key: keys,
                 data: datas,
                 autoWidth: true,
-                filename: '研修情况统计表'
+                filename: this.$t('td.td45')
             }
             // 所有老师统计
             // this.teacherData.forEach(item => {
@@ -389,11 +376,11 @@ export default {
             // 学校数据统计
             let downloadData = this.schoolList
             const params = {
-                title: ['学校', '未开始人数', '进行中人数', '已完成人数', '参训总人数'],
+                title: [this.$t('td.td28'), this.$t('td.td46'), this.$t('td.td47'), this.$t('td.td48'), this.$t('td.td49')],
                 key: ['schoolName', 'pending', 'going', 'finish', 'trainCount'],
                 data: downloadData,
                 autoWidth: true,
-                filename: '学校数据统计'
+                filename: this.$t('td.td50')
             }
             excel.export_array_to_excel(params)
         },

+ 3 - 3
TEAMModelOS/ClientApp/src/view/areaMgmt/HourProg.vue

@@ -35,21 +35,21 @@ export default {
                         data: [
                             {
                                 value: 1048,
-                                name: '已完成',
+                                name: this.$t('td.td8'),
                                 itemStyle: {
                                     color: '#19be6b'
                                 }
                             },
                             {
                                 value: 735,
-                                name: '进行中',
+                                name: this.$t('td.td7'),
                                 itemStyle: {
                                     color: '#ff9900'
                                 }
                             },
                             {
                                 value: 580,
-                                name: '未开始',
+                                name: this.$t('td.td6'),
                                 itemStyle: {
                                     color: '#ed4014'
                                 }

+ 2 - 2
TEAMModelOS/ClientApp/src/view/areaMgmt/ResourceMgt.vue

@@ -1,10 +1,10 @@
 <template>
     <div class="resource-mgt-container">
         <div class="resource-mgt-header">
-            <span class="resource-label">资源列表</span>
+            <span class="resource-label">{{$('td.td51')}}</span>
             <span class="add-resource">
                 <Icon type="md-add" />
-                添加资源
+                {{$('td.td52')}}
             </span>
         </div>
         <div class="resource-mgt-list">

+ 5 - 6
TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolComp.vue

@@ -24,7 +24,7 @@ export default {
                 color: ['#ed4014', '#ff9900', '#19be6b'],
                 legend: {
                     top: 10,
-                    data: ['未开始', '进行中', '已完成']
+                    data: [this.$t('td.td6'), this.$t('td.td7'), this.$t('td.td8')]
                 },
                 grid: {
                     left: '3%',
@@ -72,23 +72,23 @@ export default {
                 },
                 yAxis: {
                     type: 'value',
-                    name: '学时'
+                    name: this.$t('td.td5')
                 },
                 series: [
                     {
-                        name: '未开始',
+                        name: this.$t('td.td6'),
                         type: 'bar',
                         barMaxWidth: 30,
                         data: []
                     },
                     {
-                        name: '进行中',
+                        name: this.$t('td.td7'),
                         type: 'bar',
                         barMaxWidth: 30,
                         data: []
                     },
                     {
-                        name: '已完成',
+                        name: this.$t('td.td8'),
                         type: 'bar',
                         barMaxWidth: 30,
                         data: []
@@ -115,7 +115,6 @@ export default {
     watch: {
         schools: {
             handler(n, o) {
-                console.log('啦啦啦', n)
                 this.option.xAxis.data = n.map(item => {
                     return item.schoolName
                 })

+ 8 - 23
TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolDetail.vue

@@ -8,21 +8,21 @@
                 <div class="school-info-wrap">
                     <h3 class="school-name">{{schoolInfo.schoolName}}</h3>
                     <p class="school-info-item">
-                        <span class="info-label">参训人数:</span>
-                        <span class="info-value">{{schoolInfo.trainCount}}</span>
+                        <span class="info-label">{{$('td.td15')}}:</span>
+                        <span class="info-value">{{schoolInfo.trainCount}}{{$('unit.text7')}}</span>
                     </p>
                     <!-- <p class="school-info-item">
                         <span class="info-label">总学时:</span>
                         <span class="info-value">{{allStudyHour}}</span>
                     </p> -->
                     <p class="school-info-item">
-                        <span class="info-label">完成率:</span>
+                        <span class="info-label">{{$('td.td53')}}</span>
                         <span class="info-value">{{completeRate}}%</span>
                     </p>
                 </div>
                 <span class="return-list" @click="returnList">
                     <Icon type="md-arrow-back" size="16" />
-                    返回区级
+                    {{$('td.td54')}}
                 </span>
             </div>
             <Dashboard :schoolId="schoolInfo.schoolId"></Dashboard>
@@ -46,24 +46,10 @@ export default {
             dimension: [],
             abilityPoint: [],
             defImg: '',
-            offlineData: [
-                {
-                    label: '教研组',
-                    value: 0
-                }
-            ],
             trainType: [],
-            trainImgs: [
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E4%BF%A1%E6%81%AF%E5%8C%96%E6%95%99%E5%AD%A6%E6%A1%88%E4%BE%8B.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E4%B8%93%E5%AE%B6%E4%B8%93%E9%A2%98%E5%9F%B9%E8%AE%AD.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E5%90%8C%E8%AF%BE%E5%BC%82%E6%9E%84.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E5%90%8C%E8%AF%BE%E5%90%8C%E6%9E%84.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E6%A0%A1%E6%9C%AC2.0%E5%9F%B9%E8%AE%AD.png',
-                'https://teammodeltest.blob.core.chinacloudapi.cn/0-public/image/%E6%A0%A1%E6%9C%AC2.0%E5%9F%B9%E8%AE%AD.png'
-            ],
             hourData: [
                 {
-                    name: '线上研修',
+                    name: this.$('td.td22'),
                     total: 20,
                     complete: 0,
                     going: 0,
@@ -73,7 +59,7 @@ export default {
                     time: 0
                 },
                 {
-                    name: '校本研修',
+                    name: this.$('td.td23'),
                     total: 10,
                     complete: 0,
                     going: 0,
@@ -83,7 +69,7 @@ export default {
                     time: 0
                 },
                 {
-                    name: '认证材料',
+                    name: this.$('td.td24'),
                     total: 15,
                     complete: 0,
                     going: 0,
@@ -93,7 +79,7 @@ export default {
                     time: 0
                 },
                 {
-                    name: '课堂实录',
+                    name: this.$('td.td25'),
                     total: 5,
                     complete: 0,
                     going: 0,
@@ -147,7 +133,6 @@ export default {
     watch: {
         '$route': {
             handler(n, o) {
-                console.log('学校信息', n)
                 this.schoolInfo = n.params
                 if (this.schoolInfo && this.schoolInfo.schoolId) {
                     this.findSchoolData()

+ 3 - 3
TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolIndex.vue

@@ -1,15 +1,15 @@
 <template>
     <div class="areaMgmt-container">
         <div class="header">
-            <span class="title">所有学校</span>
-            <span class="info">(共建 {{ schList.length }} 个试点校,参训人数 {{ totalTeachers }} 人)</span>
+            <span class="title">{{$('td.td55')}}</span>
+            <span class="info">({{$('td.td56')}} {{ schList.length }} {{$('td.td57')}} {{ totalTeachers }} {{$('unit.text7')}})</span>
         </div>
         <div class="content">
             <div class="sch-item" v-for="(item,index) in schList" :key="index" @click="toSchoolDetail(index)">
                 <div class="sch-item-img" :style="{backgroundImage: 'url('+ getLogo(item) +')' }">
                 </div>
                 <p class="sch-item-name">{{ item.name }}</p>
-                <p class="sch-item-info">参训人数:{{ item.count }}</p>
+                <p class="sch-item-info">{{$('td.td15')}}:{{ item.count }}</p>
             </div>
 
         </div>

+ 9 - 9
TEAMModelOS/ClientApp/src/view/areatrain/Create.vue

@@ -53,21 +53,21 @@
                             </div>
                         </Upload>
                         <img v-if="trainInfo.img" :src="trainInfo.img" alt="" width="500">
-                        <p v-show="trainInfo.img" class="repeat-upload" @click="repeatUpload">重新上传</p>
+                        <p v-show="trainInfo.img" class="repeat-upload" @click="repeatUpload">{{$('td.td58')}}</p>
                     </FormItem>
                     <FormItem :label="$t('train.create.presenter')" prop="presenter">
                         <Input v-special-char v-model="trainInfo.presenter" :placeholder="$t('train.create.presenterHolder')"></Input>
                     </FormItem>
-                    <FormItem label="主题" prop="topic">
+                    <FormItem :label="$t('td.td59')" prop="topic">
                         <Input v-special-char v-model="trainInfo.topic" :placeholder="$t('train.create.topicHolder')"></Input>
                     </FormItem>
-                    <FormItem label="时间" prop="time">
+                    <FormItem :label="$t('td.td60')" prop="time">
                         <DatePicker transfer :editable="false" @on-change="getTimeInfo" type="datetimerange" format="yyyy-MM-dd HH:mm" :placeholder="$t('train.create.trainTime')" style="width: 500px"></DatePicker>
                     </FormItem>
-                    <FormItem label="地点" prop="address">
+                    <FormItem :label="$t('td.td61')" prop="address">
                         <Input v-special-char v-model="trainInfo.address" :placeholder="$t('train.create.addressHolder')"></Input>
                     </FormItem>
-                    <FormItem label="描述">
+                    <FormItem :label="$t('td.td62')">
                         <Input v-special-char v-model="trainInfo.desc" type="textarea" :placeholder="$t('train.create.contentHolder')" maxlength="200" show-word-limit :autosize="{minRows: 5, maxRows: 8}"></Input>
                     </FormItem>
                 </Form>
@@ -224,7 +224,7 @@
                             <div class="info-item">
                                 <span class="info-label">
                                     <!-- {{$t('train.create.topic')}} -->
-                                    主题
+                                    {{$t('td.td59')}}
                                 </span>
                                 <span>
                                     {{trainInfo.topic}}
@@ -233,7 +233,7 @@
                             <div class="info-item">
                                 <span class="info-label">
                                     <!-- {{$t('train.create.address')}} -->
-                                    地点
+                                    {{$t('td.td61')}}
                                 </span>
                                 <span>
                                     {{trainInfo.address}}
@@ -242,7 +242,7 @@
                             <div class="info-item">
                                 <span class="info-label">
                                     <!-- {{$t('train.create.trainTime')}}: -->
-                                    时间
+                                    {{$t('td.td60')}}
                                 </span>
                                 <span>
                                     {{trainInfo.time.join(' - ')}}
@@ -375,7 +375,7 @@ export default {
                     { required: true, message: this.$t('train.create.hwDescHolder'), trigger: 'change' }
                 ],
                 hwType: [
-                    { required: true, message: '请选择作业附件上传类型', trigger: 'change' }
+                    { required: true, message: this.$t('td.td63'), trigger: 'change' }
                 ],
                 hwTime: [
                     { required: true, validator: hwTimeV, trigger: 'change' }

+ 1 - 2
TEAMModelOS/ClientApp/src/view/areatrain/PhoneSign.vue

@@ -85,8 +85,7 @@ export default {
             this.p = params
             this.$api.train.signIn(params).then(
                 res => {
-                    this.$Message.success('签到成功')
-
+                    this.$Message.success(this.$t('td.td64'))
                 },
                 err => {
 

+ 6 - 8
TEAMModelOS/ClientApp/src/view/areatrain/TrainDetail.vue

@@ -66,7 +66,7 @@
                     </div>
                     <div class="train-data-wrap">
                         <Tabs v-model="tabName">
-                            <TabPane label="数据概览" name="name" class="tab-pane-wrap" style="height:600px">
+                            <TabPane :label="$t('td.td65')" name="name" class="tab-pane-wrap" style="height:600px">
                                 <Table :columns="columns" :data="tableData" class="table-box" :height="580">
                                     <template slot-scope="{ row,index }" slot="action">
                                         <Button type="success" size="small" @click="audit(index,1)">
@@ -328,7 +328,7 @@
         <!-- 作业附件预览 -->
         <Modal v-model="hwViewStatus" :title="$t('train.detail.viewHwTitle')" width="900">
             <div slot="header">
-                <span>{{tableData[viewIndex] ? tableData[viewIndex].name : $t('train.detail.viewHwTitle')}}{{$t('train.detail.hwFile')}}</span>
+                <span>{{tableData[viewIndex] ? tableData[viewIndex].name : $t('train.detail.viewHwTitle')}}{{$t('td.td66')}}{{$t('train.detail.hwFile')}}</span>
             </div>
             <div v-if="tableData[viewIndex] && tableData[viewIndex].hwData" style="min-height:150px">
                 <span :class="['hw-file-item', hwPreviewFile.name == answer.name ? 'hw-file-item-active':'']" v-for="answer in tableData[viewIndex].hwData" :key="answer.name" @click="handlePreviewHw(answer)">
@@ -690,11 +690,11 @@ export default {
                         this.tableData = []
                         this.tableData = data
                     } else {
-                        this.$Message.error('查询签到数据失败')
+                        this.$Message.error(this.$t('td.td67'))
                     }
                 },
                 err => {
-                    this.$Message.error('查询签到数据失败')
+                    this.$Message.error(this.$t('td.td67'))
                 }
             )
         },
@@ -815,16 +815,14 @@ export default {
                                         this.tableData = []
                                         this.tableData = data
                                     } else {
-                                        this.$Message.error('获取作业提交数据失败')
+                                        this.$Message.error(this.$t('td.td68'))
                                     }
                                 },
                                 ansErr => {
-                                    this.$Message.error('获取作业提交数据失败')
+                                    this.$Message.error(this.$t('td.td68'))
                                 }
                             )
                         }
-
-
                     },
                     err => {
 

+ 102 - 102
TEAMModelOS/ClientApp/src/view/assessment/Assessment.vue

@@ -19,7 +19,7 @@
             </Option>
           </Select>
           <!-- 特殊选择 -->
-          <Select v-model="curNoSubmit" style="width:150px;margin-left: 15px;" @on-change="doFilter" placeholder="选择更多条件" clearable>
+          <Select v-model="curNoSubmit" style="width:150px;margin-left: 15px;" @on-change="doFilter" :placeholder="$t('assessment.moreCond')" clearable>
             <Option v-for="(item,index) in noSubmitList" :value="index" :key="index">
               {{ item }}
             </Option>
@@ -28,45 +28,45 @@
           <Input v-special-char v-model="searchVal" search :placeholder="$t('ability.place1')" style="width: 150px;margin-left: 15px;" @on-search="doFilter" @on-enter="doFilter" />
           <!-- 人数统计 -->
           <span style="margin-left: 10px;">
-            
+            {{ $t('assessment.unit1') }}
             <span style="font-weight: bolder;color: #006EE6;font-size:18px">{{ assessmentList.length }}</span>
-            人&nbsp; 优秀
+            {{ $t('assessment.unit2') }}&nbsp; {{ $t('assessment.good') }}
             <span style="font-weight: bolder;color: #27b686;font-size:18px">{{ countArr[0] }}</span>
-            人({{ rateArr[0] }})&nbsp; 合格:
+            {{ $t('assessment.unit2') }}({{ rateArr[0] }})&nbsp; {{ $t('assessment.normal') }}:
             <span style="font-weight: bolder;color: #e6a714;font-size:18px">{{ countArr[1] }}</span>
-            人({{ rateArr[1] }})&nbsp; 不合格:
+            {{ $t('assessment.unit2') }}({{ rateArr[1] }})&nbsp; {{ $t('assessment.bad') }}:
             <span style="font-weight: bolder;color: #e61b1b;font-size:18px">{{ countArr[2] }}</span>
-            人({{ rateArr[2] }})&nbsp; 未进行:
+            {{ $t('assessment.unit2') }}({{ rateArr[2] }})&nbsp; {{ $t('assessment.noStart') }}:
             <span style="font-weight: bolder;color: #787272;font-size:18px">{{ countArr[3] }}</span>
-            ({{ rateArr[3] }})
+            {{ $t('assessment.unit2') }}({{ rateArr[3] }})
           </span>
         </div>
         <div class="assessment-header-right">
           <span class="tool-item" @click="onExportTable">
             <Icon type="md-download"></Icon>
-            <span>导出</span>
+            <span>{{ $t('assessment.export') }}</span>
           </span>
           <span class="tool-item">
             <i-switch size="large" @on-change="onExpandAllChange">
-              <span slot="open">收起</span>
-              <span slot="close">展开</span>
+              <span slot="open">{{ $t('assessment.close') }}</span>
+              <span slot="close">{{ $t('assessment.open') }}</span>
             </i-switch>
           </span>
           <span class="tool-item">
-            <span>互评</span>
+            <span>{{ $t('assessment.otherAppraise') }}</span>
             <i-switch v-model="isOpenAppraise" size="large" @on-change="onSwitchChange" :before-change="beforeHpAppraiseChange">
-              <span slot="open">开启</span>
-              <span slot="close">关闭</span>
+              <span slot="open">{{ $t('assessment.on') }}</span>
+              <span slot="close">{{ $t('assessment.off') }}</span>
             </i-switch>
           </span>
           <span class="tool-item" @click="doUploadProvince" v-if="hasAreaAccess">
-            <Icon type="ios-paper-plane" size="18" /> {{ `推送省平台` }}
+            <Icon type="ios-paper-plane" size="18" /> {{ $t('assessment.toProvince') }}
           </span>
         </div>
       </div>
       <!-- 研修表格清单部分 -->
       <div class="assessment-table-box">
-        <Table :columns="assessmentCol" :data="assessmentList" stripe border ellipsis :loading="tableLoading" ref="table" :max-height="tableHeight" no-data-text="当前条件下未匹配到教师数据" @on-row-click="onRowClick">
+        <Table :columns="assessmentCol" :data="assessmentList" stripe border ellipsis :loading="tableLoading" ref="table" :max-height="tableHeight" :no-data-text="$t('assessment.noData')" @on-row-click="onRowClick">
           <!-- 个人信息列 -->
           <template slot-scope="{ row,index }" slot="userInfo">
             <div class="user-info">
@@ -78,7 +78,7 @@
                   <p class="user-info-top-group">
                     <Tag color="geekblue" v-if="row.userInfo.groupName">{{ row.userInfo.groupName }}
                     </Tag>
-                    <Tag color="orange" v-else>未分组</Tag>
+                    <Tag color="orange" v-else>{{ $t('assessment.noGroup') }}</Tag>
                   </p>
                 </div>
               </div>
@@ -86,19 +86,19 @@
                 <p class="user-hours">
                   <span>
                     <Icon :type="row.hourStatus.train ? 'ios-checkmark-circle' : 'ios-close-circle'" :color="row.hourStatus.train ? '#29be84' : '#f35050'" size="16" />
-                    校本研修:{{ row.hoursArr[0] }} / {{ settingHours.offlineTime }}
+                    {{ $t('assessment.offline') }}:{{ row.hoursArr[0] }} / {{ settingHours.offlineTime }}
                   </span>
                   <span>
                     <Icon :type="row.hourStatus.online ? 'ios-checkmark-circle' : 'ios-close-circle'" :color="row.hourStatus.online ? '#29be84' : '#f35050'" size="16" />
-                    线上研修:{{ row.hoursArr[1] }} / {{ settingHours.onlineTime }}
+                    {{ $t('assessment.online') }}:{{ row.hoursArr[1] }} / {{ settingHours.onlineTime }}
                   </span>
                   <span>
                     <Icon :type="row.hourStatus.ability ? 'ios-checkmark-circle' : 'ios-close-circle'" :color="row.hourStatus.ability ? '#29be84' : '#f35050'" size="16" />
-                    认证材料:{{ row.hoursArr[2] }} / {{ settingHours.submitTime }}
+                    {{ $t('assessment.ability') }}:{{ row.hoursArr[2] }} / {{ settingHours.submitTime }}
                   </span>
                   <span>
                     <Icon :type="row.hourStatus.video ? 'ios-checkmark-circle' : 'ios-close-circle'" :color="row.hourStatus.video ? '#29be84' : '#f35050'" size="16" />
-                    课堂实录:{{ row.hoursArr[3] }} / {{ settingHours.classTime }}
+                    {{ $t('assessment.video') }}:{{ row.hoursArr[3] }} / {{ settingHours.classTime }}
                   </span>
                 </p>
               </div>
@@ -106,16 +106,16 @@
                 <div class="total-time">
                   <span style="margin-right: 5px;">
                     <!-- <img src="@/assets/image/icon_total.png" width="20"> -->
-                    
+                    {{ $t('assessment.unit1') }}
                   </span>
                   <span :class="['total-hour', isAllTimePass(row) ? 'color-suc' : 'color-fail']">{{ _.sum(row.hoursArr) }}</span>
                   <span>/ {{ settingHours.allTime }}</span>
-                  <span style="margin-left: 10px;">学时</span>
+                  <span style="margin-left: 10px;">{{ $t('assessment.hour') }}</span>
                 </div>
                 <div>
                   <RadioGroup v-model="row.finalScore" type="button" size="small" button-style="solid" @on-change="onFinalScoreChange(row)" @click.stop.native v-if="row.finalScore > 0 && expandedArr.includes(index)">
-                    <Radio :label="2">优秀</Radio>
-                    <Radio :label="1">合格</Radio>
+                    <Radio :label="2">{{ $t('assessment.good') }}</Radio>
+                    <Radio :label="1">{{ $t('assessment.normal') }}</Radio>
                   </RadioGroup>
                 </div>
               </div>
@@ -128,19 +128,19 @@
               <span>
                 <span :class="['total-hour', row.hoursArr[1] >= settingHours.onlineTime ? 'color-suc' : 'color-fail']">{{ row.hoursArr[1] }}</span>
                 <span style="margin: 0 5px;">/ {{ settingHours.onlineTime }}</span>
-                <span>学时</span>
+                <span>{{ $t('assessment.hour') }}</span>
               </span>
               <!-- <Icon :type="expandedArr.includes(index) ? 'ios-arrow-up' : 'ios-arrow-down'" style="cursor: pointer;" size="20" color="#a7a7a7" @click="onExpandChange(index)"/> -->
             </div>
             <div class="analysis-details" v-show="expandedArr.includes(index)">
               <div v-if="row.abilities.length === 0" class="no-train">
                 <img src="../../assets/image/no_data.png" width="80">
-                <span>暂无线上研修记录</span>
+                <span>{{ $t('assessment.noOnline') }}</span>
               </div>
               <div class="abilities-item" v-for="(item,index) in row.abilities" :key="index" @click.stop.prevent="() => {}">
                 <span class="overflow-text" :title="item.name">{{ item.no }}{{ item.name }}</span>
                 <span style="margin-left: 5px;"><span :class="item.videoTime >= getLimitMinutes(item) ? 'color-suc' : 'color-fail'" style="font-weight: bold;font-size: 16px;">{{ Math.min(item.videoTime,getLimitMinutes(item)) }}</span>
-                  / {{ getLimitMinutes(item) }} 分钟</span>
+                  / {{ getLimitMinutes(item) }} {{ $t('assessment.minute') }}</span>
               </div>
             </div>
           </template>
@@ -150,37 +150,37 @@
               <span>
                 <span :class="['total-hour', row.hoursArr[2] >= settingHours.submitTime ? 'color-suc' : 'color-fail']">{{ row.hoursArr[2] }}</span>
                 <span style="margin: 0 5px;">/ {{ settingHours.submitTime }}</span>
-                <span>学时</span>
+                <span>{{ $t('assessment.hour') }}</span>
               </span>
-              <span>未提交数:<span class="count-num">{{ row.abilities.filter(i => i.zpscore === -1).length }}</span></span>
+              <span>{{ $t('assessment.noSubmitNum') }}:<span class="count-num">{{ row.abilities.filter(i => i.zpscore === -1).length }}</span></span>
               <!-- <Icon :type="expandedArr.includes(index) ? 'ios-arrow-up' : 'ios-arrow-down'" style="cursor: pointer;" size="20" color="#a7a7a7" @click="onExpandChange(index)"/> -->
             </div>
             <div class="analysis-details" v-show="expandedArr.includes(index)">
               <div v-if="row.abilities.length === 0" class="no-train">
                 <img src="../../assets/image/no_data.png" width="80">
-                <span>暂无认证材料记录</span>
+                <span>{{ $t('assessment.noAbility') }}</span>
               </div>
               <div class="abilities-item" v-for="(item,index) in row.abilities" :key="index">
                 <span>
                   <Tag color="#848c94" class="appraise-tag">
-                    <span class="appraise-tag-left">自评</span>
+                    <span class="appraise-tag-left">{{ $t('assessment.selfAppraise') }}</span>
                     <span :class="['appraise-tag-right',colorMap[item.zpscore + 1]]">{{ resultMap[item.zpscore + 1] }}</span>
                   </Tag>
                   <Tag color="#848c94" class="appraise-tag" @click.native="doShowComments(item.id,row.userInfo)">
-                    <span class="appraise-tag-left">互评</span>
+                    <span class="appraise-tag-left">{{ $t('assessment.otherAppraise') }}</span>
                     <span :class="['appraise-tag-right',colorMap[item.hpscore + 1]]">{{ resultMap[item.hpscore + 1] }}</span>
                   </Tag>
                   <Tag color="#848c94" class="appraise-tag" @click.native="doShowComments(item.id,row.userInfo)" :title="item.xzscore > -1 ? `最后评价人:${ item.xztmdname }\n最后评价时间:${ $tools.formatTime(item.xztime,'yyyy-MM-dd hh:mm') }` : '暂无校评数据'">
-                    <span class="appraise-tag-left">校评</span>
+                    <span class="appraise-tag-left">{{ $t('assessment.schoolAppraise') }}</span>
                     <span :class="['appraise-tag-right',colorMap[item.xzscore + 1]]">{{ resultMap[item.xzscore + 1] }}</span>
                   </Tag>
-                  <span class="detate-other" :title="'已评论' + item.debateOrther + '人'" @click.stop="doShowMyComments(item.replyIds)">
+                  <span class="detate-other" :title="$t('assessment.comment') + item.debateOrther + $t('assessment.unit2')" @click.stop="doShowMyComments(item.replyIds)">
                     <Icon type="ios-text" size="24" color="#47afff" />
                     <span>{{ item.debateOrther > 0 ? item.debateOrther : 0 }}</span>
                   </span>
                 </span>
                 <span>
-                  <Button type="info" size="small" :title="item.zpscore < 0 ? '教师未提交认证材料,无法评审' : '前往评审教师提交的认证材料'" :disabled="item.zpscore < 0" @click.stop="doReviewAbility(item,row)">去评审</Button>
+                  <Button type="info" size="small" :title="item.zpscore < 0 ? $t('assessment.tip1') : $t('assessment.tip2')" :disabled="item.zpscore < 0" @click.stop="doReviewAbility(item,row)">{{ $t('assessment.goAppraise') }}</Button>
                 </span>
               </div>
             </div>
@@ -191,26 +191,26 @@
               <span>
                 <span :class="['total-hour', row.hoursArr[0] >= settingHours.offlineTime ? 'color-suc' : 'color-fail']">{{ row.hoursArr[0] }}</span>
                 <span style="margin: 0 5px;">/ {{ settingHours.offlineTime }}</span>
-                <span>学时</span>
+                <span>{{ $t('assessment.hour') }}</span>
               </span>
-              <span>未提交数:<span class="count-num">{{ row.trains.filter(item => item.haswork && !item.url).length }}</span></span>
+              <span>{{ $t('assessment.noSubmitNum') }}:<span class="count-num">{{ row.trains.filter(item => item.haswork && !item.url).length }}</span></span>
               <!-- <Icon :type="expandedArr.includes(index) ? 'ios-arrow-up' : 'ios-arrow-down'" style="cursor: pointer;" size="20" color="#a7a7a7" @click="onExpandChange(index)"/> -->
             </div>
             <div class="analysis-details" v-show="expandedArr.includes(index)">
               <div v-if="row.trains.length === 0" class="no-train">
                 <img src="../../assets/image/no_data.png" width="80">
-                <span>暂无校本研修记录</span>
+                <span>{{ $t('assessment.noOffline') }}</span>
               </div>
               <div class="abilities-item" v-for="(item,index) in row.trains" :key="index">
                 <span class="overflow-text" :title="item.name">{{ item.name }}</span>
-                <span>{{ item.sethour }}学时</span>
+                <span>{{ item.sethour }}{{ $t('assessment.hour') }}</span>
                 <span @click.stop.prevent="() => {}">
                   <i-switch size="large" true-color="#07bea3" v-model="item.score === 1" @mousedown.native="trainSwitchMousedown(row,item)" :before-change="beforeTrainChange" @on-change="onTrainSwitchChange(row,$event)">
                     <span slot="open">Pass</span>
                     <span slot="close">Fail</span>
                   </i-switch>
                 </span>
-                <Icon type="ios-folder" style="cursor: pointer;" size="18" :color="item.url ? '#2db694' : '#b6b6b6'" v-if="item.haswork" :title="item.url ? '已提交PDF' : '未提交PDF'" @click.stop="onClickFolder(item)" />
+                <Icon type="ios-folder" style="cursor: pointer;" size="18" :color="item.url ? '#2db694' : '#b6b6b6'" v-if="item.haswork" :title="item.url ? $t('assessment.hasPdf') : $t('assessment.noPdf')" @click.stop="onClickFolder(item)" />
                 <Icon type="ios-folder" style="opacity: 0;" v-if="!item.haswork" />
               </div>
             </div>
@@ -221,36 +221,36 @@
               <span>
                 <span :class="['total-hour', row.hoursArr[3] >= settingHours.classTime ? 'color-suc' : 'color-fail']">{{ row.hoursArr[3] }}</span>
                 <span style="margin: 0 5px;">/ {{ settingHours.classTime }}</span>
-                <span>学时</span>
+                <span>{{ $t('assessment.hour') }}</span>
               </span>
-              <Tag :color="row.video ? 'green' : 'orange'">{{ row.video ? '已上传' : '未上传' }}</Tag>
+              <Tag :color="row.video ? 'green' : 'orange'">{{ row.video ? $t('assessment.hasUpload') : $t('assessment.noUpload') }}</Tag>
               <Icon :type="expandedArr.includes(index) ? 'ios-arrow-up' : 'ios-arrow-down'" style="cursor: pointer;" size="20" color="#a7a7a7" />
             </div>
             <div class="analysis-details" v-show="expandedArr.includes(index)">
               <div v-if="!row.video" class="no-train">
                 <img src="../../assets/image/no_data.png" width="80">
-                <span>暂未上传课堂实录</span>
+                <span>{{ $t('assessment.noVideo') }}</span>
               </div>
               <div class="video-item" v-else>
                 <img class="video-item-poster" :src="getVideoPoster(row)" @error="errorImg($event)" alt="">
                 <span>{{ row.video.name }}</span>
                 <span>
                   <Tag color="#848c94" class="appraise-tag" v-if="row.video.score > -1">
-                    <span class="appraise-tag-left">校评</span>
+                    <span class="appraise-tag-left">{{ $t('assessment.schoolAppraise') }}</span>
                     <span :class="['appraise-tag-right',colorMap[row.video.score + 1]]">{{ resultMap[row.video.score + 1] }}</span>
                   </Tag>
-                  <Button type="info" size="small" style="margin:10px 0" v-if="row.video" @click.stop="doReviewVideo(row)">{{ row.video.score > -1 ? '重新评审' : '去评审' }}</Button>
+                  <Button type="info" size="small" style="margin:10px 0" v-if="row.video" @click.stop="doReviewVideo(row)">{{ row.video.score > -1 ? $t('assessment.reAppraise') : $t('assessment.goAppraise') }}</Button>
                 </span>
               </div>
             </div>
           </template>
           <!-- 操作列 -->
-          <template slot-scope="{ row,index }" slot="action">
+          <!-- <template slot-scope="{ row,index }" slot="action">
             <span style="font-size: 14px;cursor: pointer;color: #10ABE7;font-weight: bold;margin-top: 20px;display: inline-block;" @click="onExpandChange(index)">
               <span style="margin-right: 5px;">{{ expandedArr.includes(index) ? '收起' : '详情' }}</span>
               <Icon :type="expandedArr.includes(index) ? 'ios-arrow-up' : 'ios-arrow-down'" />
             </span>
-          </template>
+          </template> -->
         </Table>
       </div>
     </div>
@@ -260,11 +260,11 @@
     <VideoReview v-if="isReviewVideo" :reviewData="videoData" mode="other" @goBack="videoGoBack"></VideoReview>
     <!-- 展示用户评论弹窗 -->
     <Modal v-model="showCommentModal" width="1200" footer-hide class="tree-modal comment-modal">
-      <p slot="header">评论详情</p>
+      <p slot="header">{{ $t('assessment.commentDetails') }}</p>
       <Table :columns="appraiseColumns" :data="appraiseList" border max-height="600">
         <template slot-scope="{ row }" slot="type">
           <Tag :color="row.type === 'school' ? 'success' : 'warning'">
-            {{ row.type === 'school' ? '校评' : '互评' }}
+            {{ row.type === 'school' ? $t('assessment.schoolAppraise') : $t('assessment.otherAppraise') }}
           </Tag>
         </template>
         <template slot-scope="{ row }" slot="score">
@@ -279,7 +279,7 @@
     </Modal>
     <!-- 展示作业提交PDF选择弹窗 -->
     <Modal v-model="choosePdfModal" width="800" footer-hide class="tree-modal comment-modal">
-      <p slot="header">作业提交内容</p>
+      <p slot="header">{{ $t('assessment.homework') }}</p>
       <div>
         <span class="hw-item" v-for="(item,index) in attachmentList" :key="index" @click="onPreview(item)">{{ item.name }}</span>
       </div>
@@ -316,9 +316,9 @@ export default {
       videoData: null,
       colorMap: ['color-none', 'color-bad', 'color-normal', 'color-good'],
       tagColorMap: ['error', 'primary', 'success'],
-      resultMap: ['暂无', '不合格', '合格', '优秀'],
-      statusList: ['全部状态', '未进行', '不合格', '合格', '优秀'],
-      noSubmitList: ['认证材料未提交', '校本研修作业未提交', '课堂实录未提交'],
+      resultMap: [vm.$t('assessment.no'), vm.$t('assessment.bad'), vm.$t('assessment.normal'), vm.$t('assessment.good')],
+      statusList: [vm.$t('assessment.allStatus'), vm.$t('assessment.noStart'), vm.$t('assessment.bad'), vm.$t('assessment.normal'), vm.$t('assessment.good')],
+      noSubmitList: [vm.$t('assessment.noSubmit1'), vm.$t('assessment.noSubmit2'), vm.$t('assessment.noSubmit3')],
       tableHeight: document.documentElement.clientHeight * 0.86,
       isReviewAbility: false,
       isReviewVideo: false,
@@ -337,7 +337,7 @@ export default {
       assessmentList: [],
       assessmentCol: [
         {
-          title: '教师信息',
+          title: vm.$t('assessment.teacherInfo'),
           slot: 'userInfo',
           className: 'userInfo-column',
           width: 300,
@@ -347,7 +347,7 @@ export default {
           minWidth: 200,
           renderHeader: (h, params) => {
             return h('div', [
-              h('strong', '线上研修'),
+              h('strong', vm.$t('assessment.online')),
               h('Tooltip', {
                 props: {
                   placement: 'right',
@@ -372,7 +372,7 @@ export default {
                   whiteSpace: 'normal',
                   wordBreak: 'break-all'
                 }
-              }, '教师在线上研修观看能力点所关联的视频资源总时长,1学时=45分钟')
+              }, vm.$t('assessment.tip3'))
               ])
 
             ])
@@ -388,7 +388,7 @@ export default {
               }
             }, [
               h('div', [
-                h('strong', '认证材料'),
+                h('strong', vm.$t('assessment.ability')),
                 h('Tooltip', {
                   props: {
                     placement: 'right',
@@ -413,7 +413,7 @@ export default {
                     whiteSpace: 'normal',
                     wordBreak: 'break-all'
                   }
-                }, this.settingHours.limitAbility > 0 ? `最少有${this.settingHours.limitAbility}个能力点的认证材料合格即可获得学时` : `认证材料必须全部通过才能获得学时`)
+                }, this.settingHours.limitAbility > 0 ? `${vm.$t('assessment.tip4')}${this.settingHours.limitAbility}${vm.$t('assessment.tip5')}` : vm.$t('assessment.tip6'))
                 ])
 
               ]),
@@ -435,7 +435,7 @@ export default {
                       vm.doBatchAbility()
                     }
                   }
-                }, '全部合格')
+                }, vm.$t('assessment.allNormal'))
               ])
             ])
           },
@@ -450,7 +450,7 @@ export default {
               },
             }, [
               h('span', [
-                h('strong', '校本研修'),
+                h('strong', vm.$t('assessment.offline')),
                 h('Tooltip', {
                   props: {
                     placement: 'right',
@@ -475,7 +475,7 @@ export default {
                     whiteSpace: 'normal',
                     wordBreak: 'break-all'
                   }
-                }, `根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时: 1.10学时中至少有一次需提交作业的校本研修活动 2.在活动中成功提交PDF作业`)
+                }, vm.$t('assessment.tip7'))
                 ]),
               ]),
               h('Button', {
@@ -496,7 +496,7 @@ export default {
                       vm.doBatchTrain()
                     }
                   }
-                }, '全部通过')
+                }, vm.$t('assessment.allPass'))
               ])
             ])
           },
@@ -510,7 +510,7 @@ export default {
               },
             }, [
               h('span', [
-                h('strong', '课堂实录'),
+                h('strong', vm.$t('assessment.video')),
                 h('Tooltip', {
                   props: {
                     placement: 'right',
@@ -535,7 +535,7 @@ export default {
                     whiteSpace: 'normal',
                     wordBreak: 'break-all'
                   }
-                }, '教师提交课堂实录并且考核通过后即可获得5学时')
+                }, vm.$t('assessment.tip8'))
                 ]),
               ]),
               h('Button', {
@@ -556,7 +556,7 @@ export default {
                       vm.doBatchVideo()
                     }
                   }
-                }, '全部合格')
+                }, vm.$t('assessment.allNormal'))
               ])
             ])
           },
@@ -584,15 +584,15 @@ export default {
         key: 'name'
       },
       {
-        title: `被评价人`,
+        title: vm.$t('assessment.atName'),
         key: 'atName'
       },
       {
-        title: `评价类型`,
+        title: vm.$t('assessment.type'),
         slot: 'type'
       },
       {
-        title: `评价结果`,
+        title: vm.$t('assessment.score'),
         slot: 'score',
       },
       {
@@ -601,7 +601,7 @@ export default {
         width: 500
       },
       {
-        title: `评论时间`,
+        title: vm.$t('assessment.time'),
         key: 'time',
         width: 200,
         sortable: true
@@ -626,7 +626,7 @@ export default {
   methods: {
     /* 导出表格数据 */
     onExportTable() {
-      let header = ['姓名', '总学时', '线上研修学时', '未修满能力点', '已修满的能力点数量', '认证材料学时', '校本研修学时', '课堂实录学时', '认证材料需提交数', '认证材料未提交数', '未提交认证材料能力点', '作业未提交数', '课堂实录是否提交']
+      let header = [this.$t('assessment.header1'), this.$t('assessment.header2'), this.$t('assessment.header3'), this.$t('assessment.header4'), this.$t('assessment.header5'), this.$t('assessment.header6'), this.$t('assessment.header7'), this.$t('assessment.header8'), this.$t('assessment.header9'), this.$t('assessment.header10'), this.$t('assessment.header11'), this.$t('assessment.header12'), this.$t('assessment.header13')]
       let keys = ['name', 'totalTime', 'online', 'unFinishArr', 'finishArr', 'ability', 'offline', 'video', 'abilityCount', 'noAbilityCount', 'noAbilityNoArr', 'noHwCount', 'isSubmitVideo']
       console.log(this.assessmentList)
       let datas = this.assessmentList.map(i => {
@@ -643,7 +643,7 @@ export default {
           noAbilityCount: i.abilities.filter(i => i.zpscore === -1).length,
           noAbilityNoArr: i.abilities.filter(j => j.zpscore === -1).map(k => k.no).join(','),
           noHwCount: i.trains.filter(item => item.haswork && !item.url).length,
-          isSubmitVideo: i.video ? '已提交' : '未提交'
+          isSubmitVideo: i.video ? this.$t('assessment.hasSubmit') : this.$t('assessment.noSubmit')
         }
       })
       const params = {
@@ -651,7 +651,7 @@ export default {
         key: keys,
         data: datas,
         autoWidth: true,
-        filename: this.$store.state.user.schoolProfile.school_base.name + '研修情况统计表'
+        filename: this.$store.state.user.schoolProfile.school_base.name + this.$t('assessment.tableName')
       }
       excel.export_array_to_excel(params)
     },
@@ -697,10 +697,10 @@ export default {
           this.assessmentList = this.getRenderJson(res).sort((a, b) => a.userInfo.name.localeCompare(b.userInfo.name))
           this.originList = this._.cloneDeep(this.assessmentList)
           if (!this.groupList.length) {
-            this.groupList = ['全部教研组', ...new Set(res.teacherTrains.map(i => i.groupName))]
+            this.groupList = [this.$t('assessment.allGroups'), ...new Set(res.teacherTrains.map(i => i.groupName))]
             if (this.groupList.some(i => !i.groupName)) {
               this.groupList = this.groupList.filter(i => i)
-              this.groupList.push('未分组')
+              this.groupList.push(this.$t('assessment.noGroup'))
             }
           }
           this.settingHours = res.setting
@@ -753,7 +753,7 @@ export default {
     /* 点击PDF提交文件图标 */
     async onClickFolder(item) {
       if (!item.url) {
-        this.$Message.warning('暂未提交作品,无法查看')
+        this.$Message.warning(this.$t('assessment.noSubmitTip'))
       } else {
         this.choosePdfModal = true
         this.attachmentList = item.other
@@ -820,7 +820,7 @@ export default {
       }).then(res => {
         if (!res.error) {
           this.originList.find(i => i.userInfo.tmdId === row.userInfo.tmdId).finalScore = row.finalScore
-          this.$Message.success(`已将${row.userInfo.name}的最终研修结果评定为 ${this.resultMap[row.finalScore + 1]}`)
+          this.$Message.success(`${this.$t('assessment.tip9')}${row.userInfo.name}${this.$t('assessment.tip10')} ${this.resultMap[row.finalScore + 1]}`)
         }
       })
     },
@@ -873,7 +873,7 @@ export default {
               name: i.tmdname,
               type: i.roleType,
               score: i.score,
-              content: `无评价内容`,
+              content: this.$t('assessment.noComment'),
               atName: userInfo.name,
               time: this.$tools.formatTime(i.time, 'yyyy-MM-dd hh:mm')
             })
@@ -887,7 +887,7 @@ export default {
     doShowMyComments(replyIds) {
       console.log(replyIds)
       if (!replyIds.length) {
-        this.$Message.warning('无评论数据')
+        this.$Message.warning(this.$t('assessment.noComment'))
       } else {
         this.$api.ability.getReplyInfo({
           school: this.$store.state.userInfo.schoolCode,
@@ -937,7 +937,7 @@ export default {
       this.tableLoading = true
       let submitVal = this.curNoSubmit
       // 教研组名称
-      let groupNameVal = this.curGroup === 0 ? 'all' : (this.groupList[this.curGroup] === '未分组' ? null : this.groupList[this.curGroup])
+      let groupNameVal = this.curGroup === 0 ? 'all' : (this.groupList[this.curGroup] === this.$t('assessment.noGroup') ? null : this.groupList[this.curGroup])
       // 是否合格的状态
       let statusVal = this.curStatus === 0 ? 'all' : this.curStatus - 2
       // 执行过滤操作
@@ -971,7 +971,7 @@ export default {
       return new Promise((resolve) => {
         this.$Modal.confirm({
           title: this.$t('syllabus.modifyTip'),
-          content: `确认 ${this.isOpenAppraise ? '关闭' : '开启'} 互评吗?`,
+          content: `${this.$t('assessment.tip11')} ${this.isOpenAppraise ? this.$t('assessment.off') : this.$t('assessment.on')} ${this.$t('assessment.tip12')}`,
           onOk: () => {
             resolve();
           }
@@ -985,13 +985,13 @@ export default {
         "hpappraise": this.isOpenAppraise ? 1 : 0
       }).then(res => {
         if (!res.error) {
-          this.$Message.success(`设置成功!当前互评状态为:${this.isOpenAppraise ? '开启' : '关闭'}`)
+          this.$Message.success(`${this.$t('assessment.tip13')}:${this.isOpenAppraise ? this.$t('assessment.on') : this.$t('assessment.off')}`)
           localStorage.setItem('hpAppraise', this.isOpenAppraise ? 1 : 0)
         } else {
-          this.$Message.error('设置失败!')
+          this.$Message.error(this.$t('assessment.tip14'))
         }
       }).catch(e => {
-        this.$Message.error('设置失败!')
+        this.$Message.error(this.$t('assessment.tip14'))
       })
     },
     /* 点击校本研修switch时获取点击的对象 */
@@ -1004,7 +1004,7 @@ export default {
       return new Promise((resolve, reject) => {
         // 如果是需要提交作业的活动 但是教师没有提交作业 则不允许通过
         if (!this.curTrainObj.url && this.curTrainObj.haswork) {
-          this.$Message.warning('当前教师暂未上传活动pdf作业,无法通过!')
+          this.$Message.warning(this.$t('assessment.tip15'))
           reject()
         } else {
           resolve();
@@ -1033,9 +1033,9 @@ export default {
           // newScore === 0 ? originItem.hoursArr[0]-- : originItem.hoursArr[0]++
           this.getAssessmentList()
           if (this.curTrainObj.haswork === 0 && newScore === 1) {
-            this.$Message.warning(`根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时: 1.10学时中至少有一次需提交作业的校本研修活动 2.在活动中成功提交PDF作业`)
+            this.$Message.warning(this.$t('assessment.tip7'))
           } else {
-            this.$Message.success(`操作成功!`)
+            this.$Message.success(this.$t('assessment.tip16'))
           }
         }
       })
@@ -1043,8 +1043,8 @@ export default {
     /* 批量通过校本研修 */
     doBatchTrain() {
       this.$Modal.confirm({
-        title: '全部通过',
-        content: `确认将所有教师参与的 不需要提交的 以及 需要并且已经提交PDF 的研修活动全部设置为通过吗?`,
+        title: this.$t('assessment.allPass'),
+        content: this.$t('assessment.tip17'),
         onOk: () => {
           // 判断是否有存在未提交PDF的活动
           let allTrainIds = [...new Set(this.assessmentList.map(i => i.trains).flat(1).map(j => j.id))]
@@ -1076,7 +1076,7 @@ export default {
               "type": batchScore
             }).then(res => {
               if (!res.error) {
-                this.$Message.success(`操作成功!`)
+                this.$Message.success(this.$t('assessment.tip16'))
                 // // 更新源数据
                 // if(noPdfArr.length){
                 // 	let noPdfNames = [...new Set(noPdfArr.map(i => i.tmdName))]
@@ -1105,8 +1105,8 @@ export default {
     /* 批量通过认证材料 */
     doBatchAbility() {
       this.$Modal.confirm({
-        title: '全部合格',
-        content: `确认将所有教师已经自评过的微能力点全部设置为合格吗?`,
+        title: this.$t('assessment.allNormal'),
+        content: this.$t('assessment.tip18'),
         onOk: () => {
           let tmdIds = this.assessmentList.filter(i => i.abilities.some(j => j.zpscore > -1)).map(k => k.userInfo.tmdId)
           this.tableLoading = true
@@ -1116,10 +1116,10 @@ export default {
             roleType: "school"
           }).then(res => {
             if (!res.error) {
-              this.$Message.success('操作成功!')
+              this.$Message.success(this.$t('assessment.tip16'))
               this.getAssessmentList()
             } else {
-              this.$Message.error('操作失败!')
+              this.$Message.error(this.$t('assessment.tip19'))
             }
           })
         }
@@ -1129,8 +1129,8 @@ export default {
     /* 批量通过课堂实录 */
     doBatchVideo() {
       this.$Modal.confirm({
-        title: '全部合格',
-        content: `确认将所有教师已提交的课堂实录全部设置为合格吗?`,
+        title: this.$t('assessment.allNormal'),
+        content: this.$t('assessment.tip20'),
         onOk: () => {
           let hasVideoTmdIds = this.assessmentList.filter(i => i.video).map(j => j.userInfo.tmdId)
           this.tableLoading = true
@@ -1139,10 +1139,10 @@ export default {
             score: 1
           }).then(res => {
             if (!res.error) {
-              this.$Message.success('操作成功!')
+              this.$Message.success(this.$t('assessment.tip16'))
               this.getAssessmentList()
             } else {
-              this.$Message.error('操作失败!')
+              this.$Message.error(this.$t('assessment.tip19'))
             }
           })
         }
@@ -1155,8 +1155,8 @@ export default {
       console.log(this.assessmentList);
       let batchScore = 1
       this.$Modal.confirm({
-        title: '批量操作',
-        content: '确认将当前所有教师的校本研修评定为合格吗?',
+        title: this.$t('assessment.tip22'),
+        content: this.$t('assessment.tip21'),
         onOk() {
           this.tableLoading = true
           this.$api.ability.setFinalScore({
@@ -1164,7 +1164,7 @@ export default {
             "tmdids": that.assessmentList.map(i => i.userInfo.tmdId)
           }).then(res => {
             if (!res.error) {
-              this.$Message.success(`设置成功!`)
+              this.$Message.success(this.$t('assessment.tip23'))
               that.assessmentList.forEach(i => i.finalScore = batchScore)
               that.originList.forEach(i => i.finalScore = batchScore)
               that.tableLoading = false
@@ -1175,7 +1175,7 @@ export default {
     },
     /* 上传省平台 */
     doUploadProvince() {
-      this.$Message.warning('暂未对接省平台')
+      this.$Message.warning(this.$t('assessment.noProvince'))
     },
     /* 图片加载失败处理 */
     errorImg(event) {
@@ -1224,7 +1224,7 @@ export default {
     },
     getStatusCount() {
       return status => {
-        let groupNameVal = this.curGroup === 0 ? 'all' : (this.groupList[this.curGroup] === '未分组' ? null : this.groupList[this.curGroup])
+        let groupNameVal = this.curGroup === 0 ? 'all' : (this.groupList[this.curGroup] === this.$t('assessment.noGroup') ? null : this.groupList[this.curGroup])
         return this.originList.filter(i => i.finalScore === status && (groupNameVal === 'all' ? true : (i.userInfo.groupName === groupNameVal))).length
       }
     }

+ 3 - 2
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -212,8 +212,9 @@ export default {
         this.$api.auth.getXkwItems(this.$route.query).then(res => {
           if (res.itemInfos) {
             r(res)
-          } else {
-            j(null)
+          } else if (res.error === 403) {
+            this.$Message.warning('当前账号学科网授权已过期!组卷失败!')
+            r(null)
           }
         }).catch(err => {
           j(null)

+ 42 - 42
TEAMModelOS/ClientApp/src/view/jyzx/application.vue

@@ -59,7 +59,7 @@
               </Table>
             </div>
           </TabPane>
-          <TabPane label="同微能力点互评" name="name2">
+          <TabPane :label="$t('ability.samePointAppraise')" name="name2">
             <div class="app-table">
               <Select v-model="curAbility" style="width:250px;margin-bottom:10px" @on-change="onAbilityFilter">
                 <Option v-for="(item,index) in myAbilityList" :value="index" :key="index">{{ item.no }} {{ item.name }}</Option>
@@ -124,7 +124,7 @@ export default {
         key: 'name'
       },
       {
-        title: `评价类型`,
+        title: this.$t('ability.type'),
         key: 'type'
       },
       {
@@ -156,22 +156,22 @@ export default {
         width: 100
       },
       {
-        title: '互评结果',
+        title: this.$t('ability.otherResult'),
         slot: "memberAppraise",
         width: 100
       },
       {
-        title: '校评结果',
+        title: this.$t('ability.schoolResult'),
         slot: "schoolAppraise",
         width: 100
       },
       {
         slot: "exerciseScore",
-		renderHeader: (h, params) => {
-			return h('div', [
-				h('strong', this.$t('jyzx.application.testByMe') + '(不计入学时)' ),
-			])
-		}
+        renderHeader: (h, params) => {
+          return h('div', [
+            h('strong', this.$t('jyzx.application.testByMe') + this.$t('ability.noCount')),
+          ])
+        }
       },
       {
         title: this.$t('jyzx.common.action'),
@@ -184,7 +184,7 @@ export default {
         key: "tmdname",
       },
       {
-        title: '教研组',
+        title: this.$t('ability.groupName'),
         key: "groupName",
       },
       {
@@ -192,11 +192,11 @@ export default {
         key: "time",
       },
       {
-        title: `你的评价结果`,
+        title: this.$t('ability.result'),
         slot: "myAppraise",
       },
       {
-        title: `互评次数`,
+        title: this.$t('jyzx.application.disNum'),
         slot: "appraiseCount",
       },
       {
@@ -286,11 +286,11 @@ export default {
         this.isShowDetail = true
         this.appraiseArr = data.otherScore.map((i, index) => {
           return {
-            name: i.roleType === 'school' ? `考核人员` : this.$t(
+            name: i.roleType === 'school' ? this.$t('ability.checkMan') : this.$t(
               'jyzx.application.teacher1'),
             result: i.score,
             content: result[index] || '-',
-            type: i.roleType === 'school' ? `校评结果` : this
+            type: i.roleType === 'school' ? this.$t('assessment.schoolAppraise') : this
               .$t('jyzx.application.evaOther'),
             time: this.$tools.formatTime(i.time)
           }
@@ -307,7 +307,7 @@ export default {
                 .score
             ],
             content: i.replyIds[0],
-            type: i.roleType === 'school' ? `校评结果` : this
+            type: i.roleType === 'school' ? this.$t('assessment.schoolAppraise') : this
               .$t('jyzx.application.evaOther'),
             time: this.$tools.formatTime(i.time)
           }
@@ -332,7 +332,7 @@ export default {
         this.getMyAbilities()
       }
       // 如果是从互评返回,则不视为第一次评价
-      if(params.isFromOtherAppraise){
+      if (params.isFromOtherAppraise) {
         this.isFirstAppraiseOther = false
       }
     },
@@ -416,7 +416,7 @@ export default {
               'member') ? i.sub.otherScore.find(j => j.tmdid === myId && j
                 .roleType === 'member').score : -1
             i.tmdname = i.tmdid.name
-            i.groupName = i.tmdid.groupName || '未分组'
+            i.groupName = i.tmdid.groupName || this.$t('assessment.noGroup')
 
             if (i.appraiseCount === 0) {
               res.abilitySubs.unshift(res.abilitySubs.splice(index, 1)[0]);
@@ -437,18 +437,18 @@ export default {
     /* 互评 */
     appraiseOther(data) {
       console.log(data)
-	  let isOpenAppraise = Number(localStorage.getItem('hpAppraise'))
-	  if(!isOpenAppraise){
-		  this.$Message.warning(`学校暂未开启互评!请联系学校管理员处理!`)
-		  return
-	  }
-	  // 进入互评第一次评价 并且 成员中存在无互评的教师 并且 选择的组员没有我的评价记录
-	  let myId = this.$store.state.userInfo.TEAMModelId
-	  let hasMemberAppraise = data.sub.otherScore.filter(i => i.roleType === 'member').length
-	  let hasMyAppraise = data.sub.otherScore.filter(i => i.roleType === 'member' && i.tmdid === myId).length
-	  
+      let isOpenAppraise = Number(localStorage.getItem('hpAppraise'))
+      if (!isOpenAppraise) {
+        this.$Message.warning(this.$t('ability.appraiseTip1'))
+        return
+      }
+      // 进入互评第一次评价 并且 成员中存在无互评的教师 并且 选择的组员没有我的评价记录
+      let myId = this.$store.state.userInfo.TEAMModelId
+      let hasMemberAppraise = data.sub.otherScore.filter(i => i.roleType === 'member').length
+      let hasMyAppraise = data.sub.otherScore.filter(i => i.roleType === 'member' && i.tmdid === myId).length
+
       if (this.isFirstAppraiseOther && this.hasNoAppraise && !hasMyAppraise && hasMemberAppraise) {
-        this.$Message.warning(`请优先对互评次数为0的老师进行互评!`)
+        this.$Message.warning(this.$t('ability.appraiseTip2'))
       } else {
         let reviewData = {
           id: this.myAbilityList[this.curAbility].id,
@@ -475,20 +475,20 @@ export default {
     }
   },
   beforeRouteLeave(to, from, next) {
-      let reviewRef = this.$refs.reviewRef
-			// 如果在提交材料页面并且有提交变更 则离开的时候 需要询问用户
-      if(this.isReview && reviewRef.hasModify){
-        this.$Modal.confirm({
-					title: '温馨提示',
-                    content: '您未确认“提交评审结果”,无法保存修改内容,是否确认离开?',
-					onOk: () => {
-						next();
-					}
-				});
-      }else{
-        next();
-      }
-	}
+    let reviewRef = this.$refs.reviewRef
+    // 如果在提交材料页面并且有提交变更 则离开的时候 需要询问用户
+    if (this.isReview && reviewRef.hasModify) {
+      this.$Modal.confirm({
+        title: this.$t('ability.review.tip6'),
+        content: this.$t('ability.review.tip7'),
+        onOk: () => {
+          next();
+        }
+      });
+    } else {
+      next();
+    }
+  }
 }
 </script>
 

+ 26 - 26
TEAMModelOS/ClientApp/src/view/jyzx/index.vue

@@ -6,8 +6,8 @@
                 <div class="online-content-header">
                     <span>
                         {{ $t('jyzx.online.checkedPoint') }}
-                        <span style="margin-right: 10px">(学时:{{ totalShow }})</span>
-                        <Checkbox v-model="single" v-if="hasAbilityAuth">来源省平台</Checkbox>
+                        <span style="margin-right: 10px">({{ $t("jyzx.online.studyTime") }}:{{ totalShow }})</span>
+                        <Checkbox v-model="single" v-if="hasAbilityAuth">{{ $t("jyzx.online.fromArea") }}</Checkbox>
                         <Tooltip placement="right-start" max-width="200">
                             <Icon type="ios-alert-outline" />
                             <div slot="content">
@@ -33,7 +33,7 @@
                                 <span class="abli-type" style="color: #7C8EEE; border-color:#7C8EEE" v-if="item.currency === 3">{{ $t('jyzx.online.elective') }}</span>
                             </p>
                             <p style="text-align: right; margin-right: 20px">
-                                <span style="float: left; color: #c51111;" v-if="item.currency === 2">不计学时</span>
+                                <span style="float: left; color: #c51111;" v-if="item.currency === 2">{{ $t('jyzx.online.noStuTime') }}</span>
                                 <span style="float: left;" v-if="item.currency === 1">
                                     <!-- 总计学时是所有分钟相加得到,会与所有能力点已学的学时相加相冲突,所以只show总计的学时 -->
                                     {{ $t('jyzx.online.timeStudy') }}:
@@ -43,7 +43,7 @@
                                 </span>
                                 <span v-show="item.currency === 1 && (setting.limitMinutes === -1 ? item.done : (item.total >= setting.limitMinutes))" style="background-color: #16c18e;color: #fff; padding: 2px 5px;border-radius: 5px;">{{ $t('jyzx.common.complete') }}</span>
                             </p>
-                            <p v-if="item.from" style="text-align:right; margin-right: 20px">来源:省平台</p>
+                            <p v-if="item.from" style="text-align:right; margin-right: 20px">{{ $t('jyzx.online.fromArea1') }}</p>
                         </div>
                     </div>
                 </vuescroll>
@@ -153,7 +153,7 @@
                     <img v-else-if="previewFile.type == 'image'" :src="previewFile.url" style="border-radius: 5px; max-height: 900px; max-width: 870px" />
                     <iframe v-else-if="previewFile.type === 'doc' || previewFile.type === 'pptx'" :src="'https://view.officeapps.live.com/op/view.aspx?src=' + escapeBlobUrl" width="870" height="700" frameborder="1"></iframe>
                     <p v-else @click="loadFile">
-                        {{ $t('jyzx.online.noSee') }},可下载查看
+                        {{ $t('jyzx.online.noSee') }},{{ $t('jyzx.online.loadLook') }}
                         <Icon type="md-download" />
                     </p>
                 </div>
@@ -260,17 +260,17 @@ export default {
             dimension: [
                 {
                     code: 0,
-                    val: "全部维度",
+                    val: this.$t('jyzx.online.allDimension'),
                 },
             ], //维度
             selDimen: 0, //选择的维度
             environment: [
-                "全部环境",
-                "混合学习环境",
-                "多媒体教学环境",
-                "智慧学习环境",
+                this.$t('jyzx.online.allEnvir'),
+                this.$t('jyzx.online.envirMix'),
+                this.$t('jyzx.online.multiMedia'),
+                this.$t('jyzx.online.studyEnvir'),
             ], //环境
-            selEnvi: "全部环境", //选择的环境
+            selEnvi: this.$t('jyzx.online.allEnvir'), //选择的环境
             abliltyId: undefined, //能力点id
             chapterId: 0, //当前章节的id
             topChapterId: 0, //当前章的id
@@ -294,7 +294,7 @@ export default {
             fileRcd: [], //存学习了的资源
             setting: undefined, //标准学时
             single: false,
-            preText: "保存记录",
+            preText: this.$t('jyzx.online.keepRecords'),
             preDisabled: false,
             allChapterId: [],
             needId: {
@@ -331,10 +331,10 @@ export default {
         leaveConfirm(e) {
             e = e || window.event
             if(e) {
-                e.returnValue = "关闭提示"
+                e.returnValue = this.$t('jyzx.online.close')
                 this.setStudyTime(this.fileRcd, this.studyTime)
             }
-            return "关闭提示"
+            return this.$t('jyzx.online.close')
         },
         async preserveTime() {
             this.preDisabled = true
@@ -342,7 +342,7 @@ export default {
                 this.preDisabled = false
             }, 10000)
             if(!this.fileRcd.length) {
-                this.$Message.info("已经自动保存")
+                this.$Message.info(this.$t('jyzx.online.autoSave'))
             }
             // this.preText = "自动保存中"
             let num = this.setStudyTime(this.fileRcd, this.studyTime)
@@ -360,7 +360,7 @@ export default {
                     if(!indirect) {
                         this.changePause()
                         this.isLoading = true
-                        this.preText = "自动保存中"
+                        this.preText = this.$t('jyzx.online.autoSaving')
                     }
                     let params = {
                         tmdid: this.$store.state.userInfo.TEAMModelId,
@@ -374,7 +374,7 @@ export default {
                             this.fileRcd = []
                             this.allStudyFile = res.files
                             localStorage.setItem('fileRcd', JSON.stringify(res.files))
-                            this.$Message.success("保存成功")
+                            this.$Message.success(this.$t('jyzx.offline.success1'))
                             this.$forceUpdate()
                             r(200)
                         }
@@ -398,13 +398,13 @@ export default {
                             })
                         }
                     }).catch(err => {
-                        this.$Message.error("保存失败")
+                        this.$Message.error(this.$t('jyzx.offline.error1'))
                         localStorage.setItem('isPreserve', true)
                         console.log(err);
                         j(err)
                     }).finally(() => {
                         this.isLoading = false
-                        this.preText = "保存记录"
+                        this.preText = this.$t('jyzx.online.keepRecords')
                     })
                 })
             } else {
@@ -901,13 +901,13 @@ export default {
             // 已对接省平台,一个提示信息
             if(this.hasAbilityAuth) {
                 this.$Modal.warning({
-					title: "添加能力点",
-					content: "请到省平台挑选您想学习的能力点",
+					title: this.$t("jyzx.online.addtoAbility"),
+					content: this.$t("jyzx.online.addtoContent"),
 				})
             } else {
                 this.isAddPoint = true;
                 this.selDimen = 0;
-                this.selEnvi = "全部环境";
+                this.selEnvi = this.$t("jyzx.online.allEnvir");
                 // this.showPoint = this.allPoint
             }
         },
@@ -1018,9 +1018,9 @@ export default {
         selAllPoint() {
             console.log(this.selDimen, this.selEnvi,'内容')
             let arr = [];
-            if (!this.selDimen && this.selEnvi == "全部环境") {
+            if (!this.selDimen && this.selEnvi == this.$t("jyzx.online.allEnvir")) {
                 arr = this.allPoint;
-            } else if (this.selEnvi == "全部环境") {
+            } else if (this.selEnvi == this.$t("jyzx.online.allEnvir")) {
                 arr = this.allPoint.filter((item) => {
                     return item.dimension == this.selDimen;
                 });
@@ -1294,7 +1294,7 @@ export default {
         // 滚动到底部
         handleReachBottom() {
             return new Promise((r) => {
-                this.$Message.warning("已经到底了")
+                this.$Message.warning(this.$t("stuAccount.isBottom"))
                 r()
             });
         },
@@ -1362,7 +1362,7 @@ export default {
             console.log(video);
             // 没有hash值,暂时不保存
             if(!video.hash) {
-                this.$Message.error("该文件缺少信息,无法保存学习记录")
+                this.$Message.error(this.$t("jyzx.online.message4"))
             }
             this.isSame = false
             this.studyRecord = undefined

+ 5 - 5
TEAMModelOS/ClientApp/src/view/jyzx/newHomePage.vue

@@ -47,7 +47,7 @@
             <!-- 活动数量统计 -->
             <div class="train-count-wrap">
                 <div class="train-item-box">
-                    <p style="text-align:center;">线上研修</p>
+                    <p style="text-align:center;">{{ $t("jyzx.homePage.online") }}</p>
                     <p>
                         <Icon type="md-arrow-round-forward" color="#ffb01f" />
                     </p>
@@ -74,7 +74,7 @@
                     </div>
                 </div>
                 <div class="train-item-box">
-                    <p style="text-align:center;">区级活动</p>
+                    <p style="text-align:center;">{{ $t("jyzx.homePage.area") }}</p>
                     <p>
                         <Icon type="md-arrow-round-forward" color="#ffb01f" />
                     </p>
@@ -101,7 +101,7 @@
                     </div>
                 </div>
                 <div class="train-item-box">
-                    <p style="text-align:center;">校级活动</p>
+                    <p style="text-align:center;">{{ $t("jyzx.homePage.school") }}</p>
                     <p>
                         <Icon type="md-arrow-round-forward" color="#ffb01f" />
                     </p>
@@ -136,12 +136,12 @@
         </div>
         <Modal
             v-model="isModal"
-            title="填写研修总结"
+            :title="$t('jyzx.homePage.sendSummary')"
             @on-ok="sendSum"
         >
             <Input v-model="summaryNum" maxlength="300"
                 show-word-limit type="textarea" :autosize="{minRows: 8}"
-                placeholder="请填写您的研修总结"
+                :placeholder="$t('jyzx.homePage.plaSummary')"
             />
         </Modal>
     </div>

+ 20 - 19
TEAMModelOS/ClientApp/src/view/jyzx/offline.vue

@@ -15,7 +15,7 @@
                                 <span style="display: inline-block; background: #a2b02e;" v-show="item.owner == 'area'">{{ $t('jyzx.common.area') }}</span>
                                 <span style="display: inline-block; background: #FF9900;" v-show="item.owner == 'school'">{{ $t('jyzx.common.school') }}</span>
                                 {{ item.name }}
-                                <p v-if="item.hour">已获得{{ item.hour }}学时</p>
+                                <p v-if="item.hour">{{ $t("jyzx.online.had") }}{{ item.hour }}{{ $t("jyzx.online.time") }}</p>
                             </div>
                             <p class="status-time" style="padding-left:25px">
                                 {{ item.startTime }} - {{ item.endTime }}
@@ -58,16 +58,16 @@
                                         </div>
                                         <div class="site">
                                             <span class="info-label">{{ $t('jyzx.offline.sendActivity') }}:</span>
-                                            <span @click="goToSubmit(1)" class="subAct" v-if="resource.settings.includes('hw')">{{ resource.settings.includes('hw') ? "提交作业" : "" }}</span>
-                                            <span @click="goToSubmit(2)" class="subAct" v-if="resource.settings.includes('survey')">{{ resource.settings.includes('survey') ? "提交问卷" : "" }}</span>
-                                            <span @click="goToSubmit(3)" class="subAct" v-if="resource.settings.includes('exam')">{{ resource.settings.includes('exam') ? "提交评测" : "" }}</span>
-                                            <span>{{ noActivity ? "暂无活动" : "" }}</span>
+                                            <span @click="goToSubmit(1)" class="subAct" v-if="resource.settings.includes('hw')">{{ resource.settings.includes('hw') ? $t('studentWeb.homework.homeworkUpload') : "" }}</span>
+                                            <span @click="goToSubmit(2)" class="subAct" v-if="resource.settings.includes('survey')">{{ resource.settings.includes('survey') ? $t('survey.studentWeb.submit') : "" }}</span>
+                                            <span @click="goToSubmit(3)" class="subAct" v-if="resource.settings.includes('exam')">{{ resource.settings.includes('exam') ? $t('jyzx.online.submitExam') : "" }}</span>
+                                            <span>{{ noActivity ? $t("jyzx.offline.noActivity") : "" }}</span>
                                         </div>
                                         <div class="site" v-show="resource.owner != 'area'">
-                                            <span class="info-label">学时获得:</span>
-                                            <span style="color: #e61c1c;">根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时:</span>
-                                            <span style="color: #e61c1c; display: inline-block; margin-left: calc(80px + 2%)">1. 10学时中至少有一次需提交作业的校本研修活动。</span>
-                                            <span style="color: #e61c1c; display: inline-block; margin-left: calc(80px + 2%)">2. 在活动中成功提交PDF作业。</span>
+                                            <span class="info-label">{{ $t("jyzx.online.timehave") }}:</span>
+                                            <span style="color: #e61c1c;">{{ $t("jyzx.offline.message7") }}:</span>
+                                            <span style="color: #e61c1c; display: inline-block; margin-left: calc(80px + 2%)">{{ $t("jyzx.offline.message8") }}</span>
+                                            <span style="color: #e61c1c; display: inline-block; margin-left: calc(80px + 2%)">{{ $t("jyzx.offline.message9") }}</span>
                                         </div>
                                     </div>
                                     <div class="img-box" :style="{backgroundImage: `url(${resource.img || defImg})`,}"></div>
@@ -133,13 +133,13 @@
                                 <div class="submitarea" id="homeworkSub" v-if="resource.settings.includes('hw') && workInfo">
                                     <dt class="headeicon"><span class="headeicontitle">{{ $t('jyzx.offline.homework') }}</span></dt>
                                     <div class="target">
-                                        <span class="info-label" style="color: #bf3232; !important">重要提示:</span>
+                                        <span class="info-label" style="color: #bf3232; !important">{{ $t('jyzx.offline.tips') }}:</span>
                                         <span style="margin-bottom: 10px; color: #bf3232;" v-if="mainFile">
-                                            根据省平台要求,教师上传的作业必须选择一个
+                                            {{ $t('jyzx.offline.tips1') }}
                                             <span v-for="(item, index) in mainFile" :key="index">
                                                 {{ item }}
                                             </span>
-                                            文档,作为本次活动的主要文件提交到省平台。
+                                            {{ $t('jyzx.offline.tips2') }}
                                         </span>
                                     </div>
                                     
@@ -156,12 +156,12 @@
                                     <div class="target hw-style" v-if="!leaderSubmit || isLeader">
                                         <div style="margin-bottom: 20px" v-if="answerList">
                                             <p>{{ $t('jyzx.offline.submitFile') }}:
-                                                <span style="float: right; margin-right: 10px; color: #4e77b1; cursor: pointer;" @click="deleteFile">批量删除</span>
+                                                <span style="float: right; margin-right: 10px; color: #4e77b1; cursor: pointer;" @click="deleteFile">{{ $t("cusMgt.delBatch") }}</span>
                                             </p>
                                             <div>
                                                 <Table :ref="{'selection': !leaderSubmit || isLeader}" :columns="fileCol" :data="answerList.content" @on-selection-change="selectionChange">
                                                     <template slot-scope="{row}" slot="name">
-                                                        <span v-show="row.prime" class="school-gade" style="display: inline-block; background: #a2b02e;">主要文件</span>
+                                                        <span v-show="row.prime" class="school-gade" style="display: inline-block; background: #a2b02e;">{{ $t("jyzx.offline.mainFile") }}</span>
                                                         {{ row.name }}
                                                     </template>
                                                     <template slot-scope="{row}" slot="action">
@@ -196,14 +196,14 @@
                                                         <div @click="changeUp(index)" style="width: 100%;">
                                                             {{ item.name }}
                                                             <span>
-                                                                <span v-show="uploadIndex === index" class="school-gade" style="display: inline-block; background: #a2b02e;">主要文件</span>
+                                                                <span v-show="uploadIndex === index" class="school-gade" style="display: inline-block; background: #a2b02e;">{{ $t('jyzx.offline.mainFile') }}</span>
                                                             </span>
                                                                 <Progress :percent="item.progress" status="active" stroke-color="#7CB7F5" />
                                                         </div>
                                                     </div>
                                                 </div>
                                                 <span style="margin: 10px 0; color: #bf3232;">
-                                                    提交前,点击文件名,即可切换主要文件
+                                                    {{ $t('jyzx.offline.tips3') }}
                                                 </span>
                                                 <div style="line-height: 100%; margin-top: 20px">
                                                     <Button type="success" @click="submitHome" style="margin-right: 10px" :disabled="isUpload">
@@ -305,6 +305,7 @@ import DoSurvey from './DoSurvey.vue'
 import DoExam from './DoExam.vue'
 import BlobTool from "@/utils/blobTool.js"
 import { mapGetters } from 'vuex'
+
 export default {
     components: {
         DoSurvey,
@@ -345,18 +346,18 @@ export default {
                     align: 'center',
                 },
                 {
-                    title: "文件名称",
+                    title: this.$t("teachContent.tableC1"),
                     key: "name",
                     align: "center",
                     slot: "name",
                 },
                 {
-                    title: "上传时间",
+                    title: this.$t("jyzx.common.loadTime"),
                     key: "time",
                     align: "center"
                 },
                 {
-                    title: "文件类型",
+                    title: this.$t("studentWeb.homework.table3"),
                     key: "extension",
                     align: "center"
                 },

+ 1 - 2
TEAMModelOS/ClientApp/src/view/statistics/AbilityPoint.vue

@@ -34,7 +34,7 @@ export default {
                 },
                 tooltip: {
                     trigger: 'item',
-                    formatter: '{b} : {c} 人'
+                    formatter: `{b} : {c} ${this.$t('unit.text7')}`
                 },
                 xAxis: {
                     type: 'category',
@@ -71,7 +71,6 @@ export default {
     watch: {
         count: {
             handler(n, o) {
-                console.log('能力点数据', n)
                 if (this.count) {
                     this.option.series[0].data = []
                     this.option.xAxis.data = Object.keys(n)

+ 32 - 32
TEAMModelOS/ClientApp/src/view/statistics/Dashboard.vue

@@ -28,45 +28,45 @@
             </div>
             <!-- 合格率统计 -->
             <div class="pass-rate-box">
-                <p class="pass-rate-label">合格率统计</p>
+                <p class="pass-rate-label">{{$t('td.td69')}}</p>
                 <i-circle :percent="rate1">
                     <span class="value-text">{{rate1}}%</span>
-                    <p class="label-text">线上研修</p>
+                    <p class="label-text">{{$t('td.td22')}}</p>
                 </i-circle>
                 <i-circle :percent="rate3">
                     <span class="value-text">{{rate3}}%</span>
-                    <p class="label-text">认证材料</p>
+                    <p class="label-text">{{$t('td.td24')}}</p>
                 </i-circle>
                 <i-circle :percent="rate2">
                     <span class="value-text">{{rate2}}%</span>
-                    <p class="label-text">校本研修</p>
+                    <p class="label-text">{{$t('td.td23')}}</p>
                 </i-circle>
                 <i-circle :percent="rate4">
                     <span class="value-text">{{rate4}}%</span>
-                    <p class="label-text">课堂实录</p>
+                    <p class="label-text">{{$t('td.td25')}}</p>
                 </i-circle>
             </div>
             <!-- 能力点占比统计 -->
             <div class="training-top-wrap">
                 <div class="percent-wrap">
-                    <p class="pass-rate-label">能力维度选修占比</p>
+                    <p class="pass-rate-label">{{$t('td.td70')}}</p>
                     <Percent :count="dimensions"></Percent>
                 </div>
                 <div class="point-wrap">
-                    <p class="pass-rate-label">能力点选修占比</p>
+                    <p class="pass-rate-label">{{$t('td.td71')}}</p>
                     <AbilityPoint :count="pointCount"></AbilityPoint>
                 </div>
             </div>
             <!-- 小组数据统计 -->
             <div class="group-data-box">
-                <p class="pass-rate-label">研修小组统计</p>
-                <EmptyData v-show="!groupData.length" textContent="暂无小组数据" :top="80"></EmptyData>
+                <p class="pass-rate-label">{{$t('td.td72')}}</p>
+                <EmptyData v-show="!groupData.length" :textContent="$t('td.td73')" :top="80"></EmptyData>
                 <div class="group-item" v-for="(item,index) in groupData" :key="index">
                     <div class="group-info-wrap">
                         <div class="group-img-start" :style="{backgroundImage:`radial-gradient(${colorList[index % 9]},#fff)`}">
                         </div>
                         <div style="text-align: center;">
-                            <h6 class="group-name">{{item.name || '未分组'}}</h6>
+                            <h6 class="group-name">{{item.name || $t('td.td74')}}</h6>
                             <p class="group-info">
                                 {{$t('teachermgmt.peopleNum')}}
                                 {{item.members.length}}
@@ -74,7 +74,7 @@
                             </p>
                             <p class="group-info">
                                 <span class="view-member" @click="viewMember(index)">
-                                    查看成员
+                                    {{$t('td.td75')}}
                                 </span>
                             </p>
                         </div>
@@ -83,41 +83,41 @@
                         <div class="data-item">
                             <p class="data-num">
                                 {{item.onlineCount || 0}}
-                                <span class="people-unit"></span>
+                                <span class="people-unit">{{$t('unit.text7')}}</span>
                             </p>
-                            <p class="data-label">完成线上研修</p>
+                            <p class="data-label">{{$t('td.td76')}}</p>
                         </div>
                         <div class="data-item">
                             <p class="data-num">
                                 {{item.uploadCount || 0}}
-                                <span class="people-unit"></span>
+                                <span class="people-unit">{{$t('unit.text7')}}</span>
                             </p>
-                            <p class="data-label">完成认证材料</p>
+                            <p class="data-label">{{$t('td.td77')}}</p>
                         </div>
                         <div class="data-item">
                             <p class="data-num">
                                 {{item.offlineCount || 0}}
-                                <span class="people-unit"></span>
+                                <span class="people-unit">{{$t('unit.text7')}}</span>
                             </p>
-                            <p class="data-label">完成校本研修</p>
+                            <p class="data-label">{{$t('td.td78')}}</p>
                         </div>
                         <div class="data-item">
                             <p class="data-num">
                                 {{item.classCount || 0}}
-                                <span class="people-unit"></span>
+                                <span class="people-unit">{{$t('unit.text7')}}</span>
                             </p>
-                            <p class="data-label">完成课堂记录</p>
+                            <p class="data-label">{{$t('td.td79')}}</p>
                         </div>
                         <div class="data-item">
                             <p class="data-num">
                                 {{item.totalCount || 0}}
-                                <span class="people-unit"></span>
+                                <span class="people-unit">{{$t('unit.text7')}}</span>
                             </p>
-                            <p class="data-label">全部完成</p>
+                            <p class="data-label">{{$t('td.td80')}}</p>
                         </div>
                         <div class="data-item">
                             <p class="data-num">{{item.rate || 0}}%</p>
-                            <p class="data-label">完成率</p>
+                            <p class="data-label">{{$t('td.td81')}}</p>
                         </div>
                     </div>
                 </div>
@@ -129,13 +129,13 @@
                     <PersonalPhoto :name="item.name" :picture="item.picture" />
                     <span class="teacher-name">{{item.name}}</span>
                     <span class="hour-count-wrap">
-                        <Icon custom="iconfont icon-online" title="线上研修学时" :color="item.onlineTime == 0 ? '#17233d' : item.onlineTime >= onlineTime ? '#19be6b' : '#17233d'" />
+                        <Icon custom="iconfont icon-online" :title="$t('td.td30')" :color="item.onlineTime == 0 ? '#17233d' : item.onlineTime >= onlineTime ? '#19be6b' : '#17233d'" />
                         <span class="teacher-hour-num" :style="{color:item.onlineTime == 0 ? '#17233d' : item.onlineTime >= onlineTime ? '#19be6b' : '#17233d'}">{{item.onlineTime}}</span>
-                        <Icon custom="iconfont icon-submit" title="认证材料学时" :color="item.currency.submitTime == 0 ? '#17233d' : item.currency.submitTime >= submitTime ? '#19be6b' : '#17233d'" />
+                        <Icon custom="iconfont icon-submit" :title="$t('td.td33')" :color="item.currency.submitTime == 0 ? '#17233d' : item.currency.submitTime >= submitTime ? '#19be6b' : '#17233d'" />
                         <span class="teacher-hour-num" :style="{color:item.currency.submitTime == 0 ? '#17233d' : item.currency.submitTime >= submitTime ? '#19be6b' : '#17233d'}">{{item.currency.submitTime}}</span>
-                        <Icon custom="iconfont icon-offline" title="校本研修学时" :color="item.offlineTime == 0 ? '#17233d' : item.offlineTime >= offlineTime ? '#19be6b' : '#17233d'" />
+                        <Icon custom="iconfont icon-offline" :title="$t('td.td34')" :color="item.offlineTime == 0 ? '#17233d' : item.offlineTime >= offlineTime ? '#19be6b' : '#17233d'" />
                         <span class="teacher-hour-num" :style="{color:item.offlineTime == 0 ? '#17233d' : item.offlineTime >= offlineTime ? '#19be6b' : '#17233d'}">{{item.offlineTime}}</span>
-                        <Icon custom="iconfont icon-cus-video" title="课堂实录学时" :color="item.classTime == 0 ? '#17233d' : item.classTime >= videoTime ? '#19be6b' : '#17233d'" />
+                        <Icon custom="iconfont icon-cus-video" :title="$t('td.td35')" :color="item.classTime == 0 ? '#17233d' : item.classTime >= videoTime ? '#19be6b' : '#17233d'" />
                         <span class="teacher-hour-num" :style="{color:item.classTime == 0 ? '#17233d' : item.classTime >= videoTime ? '#19be6b' : '#17233d'}">{{item.classTime}}</span>
                     </span>
                 </div>
@@ -188,35 +188,35 @@ export default {
                     icon: 'ios-people',
                     color: '#2d8cf0',
                     number: 0,
-                    text: '参训人数',
+                    text: this.$t('td.td15'),
                     type: 'num'
                 },
                 {
                     icon: 'ios-people',
                     color: '#19be6b',
                     number: 0,
-                    text: '优秀(人)',
+                    text: `${this.$t('td.td82')}(${this.$t('unit.text7')})`,
                     type: 'num'
                 },
                 {
                     icon: 'md-cube',
                     color: '#2db7f5',
                     number: 0,
-                    text: '合格(人)',
+                    text: `${this.$t('td.td83')}(${this.$t('unit.text7')})`,
                     type: 'num'
                 },
                 {
                     icon: 'md-bookmark',
                     color: '#5cadff',
                     number: 0,
-                    text: '不合格(人)',
+                    text: `${this.$t('td.td84')}(${this.$t('unit.text7')})`,
                     type: 'num'
                 },
                 {
                     icon: 'md-thumbs-up',
                     color: '#ff9900',
                     number: 0,
-                    text: '未开始(人)',
+                    text: `${this.$t('td.td6')}(${this.$t('unit.text7')})`,
                     type: 'num'
                 }
             ]
@@ -336,7 +336,7 @@ export default {
                     }
                 },
                 err => {
-                    this.$Message.error('获取统计数据失败')
+                    this.$Message.error(this.$t('td.td85'))
                 }
             ).finally(() => {
                 this.loading = false

+ 6 - 2
TEAMModelOS/ClientApp/src/view/statistics/Statistics.vue

@@ -1,8 +1,12 @@
 <template>
     <div class="statistics-container">
         <div class="statistics-header">
-            <span @click="tabClick('dashboard')" :class="['statistics-tab',routerName == 'dashboard' ? 'statistics-tab-active':'']">数据总览</span>
-            <span @click="tabClick('tableData')" :class="['statistics-tab',routerName == 'tableData' ? 'statistics-tab-active':'']">详细数据</span>
+            <span @click="tabClick('dashboard')" :class="['statistics-tab',routerName == 'dashboard' ? 'statistics-tab-active':'']">
+                {{$t('td.td86')}}
+            </span>
+            <span @click="tabClick('tableData')" :class="['statistics-tab',routerName == 'tableData' ? 'statistics-tab-active':'']">
+                {{$t('td.td87')}}
+            </span>
         </div>
         <router-view></router-view>
     </div>

+ 15 - 15
TEAMModelOS/ClientApp/src/view/statistics/TableData.vue

@@ -1,10 +1,10 @@
 <template>
     <div class="class-hours-table">
         <div class="table-tools-wrap light-iview-input">
-            <Input v-model="keyword" search placeholder="搜索" style="width:200px" @on-change="serchData" />
+            <Input v-model="keyword" search :placeholder="$t('td.td88')" style="width:200px" @on-change="serchData" />
             <Button type="text" style="float:right; color: #40A8F0" @click="exportData">
                 <Icon type="md-download" />
-                数据导出
+                {{$t('td.td89')}}
             </Button>
         </div>
         <vuescroll>
@@ -32,7 +32,7 @@
                 </template>
                 <template slot-scope="{ row }" slot="status">
                     <span :style="{color:row.totalTime < totalTime ? '#ed4014':'#19be6b'}">
-                        {{ row.totalTime < totalTime ? '未完成' : '已完成' }}
+                        {{ row.totalTime < totalTime ? $t('td.td90') : $t('td.td91') }}
                     </span>
                 </template>
             </Table>
@@ -65,7 +65,7 @@ export default {
                     align: 'center'
                 },
                 {
-                    title: '教师姓名',
+                    title: this.$t('td.td92'),
                     key: 'name'
                 },
                 {
@@ -73,7 +73,7 @@ export default {
                     key: 'id'
                 },
                 {
-                    title: '小组',
+                    title: this.$t('td.td93'),
                     key: 'groupName',
                     filters: [],
                     filterMethod(value, row) {
@@ -82,7 +82,7 @@ export default {
                     }
                 },
                 {
-                    title: '线上研修',
+                    title: this.$t('td.td22'),
                     key: 'onlineTime',
                     slot: 'online',
                     align: 'center',
@@ -96,7 +96,7 @@ export default {
                     }
                 },
                 {
-                    title: '认证材料',
+                    title: this.$t('td.td24'),
                     key: 'currency',
                     slot: 'assessment',
                     align: 'center',
@@ -110,7 +110,7 @@ export default {
                     }
                 },
                 {
-                    title: '校本研修',
+                    title: this.$t('td.td23'),
                     key: 'offlineTime',
                     slot: 'offline',
                     align: 'center',
@@ -124,7 +124,7 @@ export default {
                     }
                 },
                 {
-                    title: '课堂实录',
+                    title: this.$t('td.td25'),
                     key: 'classTime',
                     slot: 'classRecord',
                     align: 'center',
@@ -138,7 +138,7 @@ export default {
                     }
                 },
                 {
-                    title: '总学时',
+                    title: this.$t('td.td20'),
                     key: 'totalTime',
                     slot: 'allHour',
                     align: 'center',
@@ -152,7 +152,7 @@ export default {
                     }
                 },
                 {
-                    title: '完成状态',
+                    title: this.$t('td.td94'),
                     slot: 'status',
                     align: 'center'
                 }
@@ -177,15 +177,15 @@ export default {
                     submitTime: item.currency.submitTime,
                     classTime: item.classTime,
                     alltime: item.totalTime > this.totalTime ? this.totalTime : item.totalTime,
-                    status: item.totalTime < this.totalTime ? '未完成' : '已完成'
+                    status: item.totalTime < this.totalTime ? this.$t('td.td90') : this.$t('td.td91')
                 }
             })
             const params = {
-                title: ['姓名', 'ID', '组别', '线上研修学时', '校本研修学时', '认证材料学时', '课堂记录学时', '总学时', '完成状态'],
+                title: [this.$t('td.td95'), 'ID', this.$t('td.td96'), this.$t('td.td30'), this.$t('td.td34'), this.$t('td.td33'), this.$t('td.td35'), this.$t('td.td20'), this.$t('td.td94')],
                 key: ['name', 'id', 'groupName', 'onlineTime', 'offlineTime', 'submitTime', 'classTime', 'alltime', 'status'],
                 data: downloadData,
                 autoWidth: true,
-                filename: '学时统计'
+                filename: this.$t('td.td2')
             }
             excel.export_array_to_excel(params)
         },
@@ -222,7 +222,7 @@ export default {
                     }
                 },
                 err => {
-                    this.$Message.error('获取统计数据失败')
+                    this.$Message.error(this.$t('td.td97'))
                 }
             ).finally(() => {
                 this.loading = false

+ 14 - 15
TEAMModelOS/ClientApp/src/view/train/Create.vue

@@ -55,7 +55,7 @@
                             </div>
                         </Upload>
                         <img v-if="trainInfo.img" :src="trainInfo.img" alt="" width="500">
-                        <p v-show="trainInfo.img" class="repeat-upload" @click="repeatUpload">重新上传</p>
+                        <p v-show="trainInfo.img" class="repeat-upload" @click="repeatUpload">{{$t('td.td58')}}</p>
                     </FormItem>
                     <FormItem :label="$t('train.create.presenter')" prop="presenter">
                         <Input v-special-char v-model="trainInfo.presenter" :placeholder="$t('train.create.presenterHolder')"></Input>
@@ -98,9 +98,9 @@
                             <!-- 作业信息 -->
                             <div v-if="item.name == 'hw'">
                                 <p class="province-tips">
-                                    根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时:<br />
-                                    1、10学时中至少有一次需提交作业的校本研修活动 <br />
-                                    2、在活动中成功提交PDF作业
+                                    {{$t('td.td98')}}
+                                    {{$t('td.td99')}}<br />
+                                    {{$t('td.td100')}}<br />
                                 </p>
                                 <FormItem :label="$t('train.create.hwName')" prop="hwName">
                                     <Input v-special-char v-model="trainInfo.hwName" :placeholder="$t('train.create.hwNameHolder')"></Input>
@@ -108,13 +108,13 @@
                                 <FormItem :label="$t('train.create.hwDesc')" prop="hwDesc">
                                     <Input v-special-char v-model="trainInfo.hwDesc" type="textarea" :placeholder="$t('train.create.hwDescHolder')" maxlength="200" show-word-limit :autosize="{minRows: 6, maxRows: 8}"></Input>
                                 </FormItem>
-                                <FormItem label="提交方式" prop="leaderSubmit">
+                                <FormItem :label="$t('td.td101')" prop="leaderSubmit">
                                     <RadioGroup v-model="trainInfo.leaderSubmit">
                                         <Radio :label="0">
-                                            <span>所有老师提交</span>
+                                            <span>{{$t('td.td102')}}</span>
                                         </Radio>
                                         <Radio :label="1">
-                                            <span>由组长统一提交</span>
+                                            <span>{{$t('td.td103')}}</span>
                                         </Radio>
                                     </RadioGroup>
                                 </FormItem>
@@ -412,10 +412,10 @@ export default {
                     { required: true, message: this.$t('train.create.hwDescHolder'), trigger: 'change' }
                 ],
                 hwType: [
-                    { required: true, message: '请设置作业类型', trigger: 'change' }
+                    { required: true, message: this.$t('td.td104'), trigger: 'change' }
                 ],
                 leaderSubmit: [
-                    { required: true, message: '请设置提交方式', type: 'number', trigger: 'change' }
+                    { required: true, message: this.$t('td.td105'), type: 'number', trigger: 'change' }
                 ],
                 hwTime: [
                     { required: true, validator: hwEndTimeV, trigger: 'change' }
@@ -547,7 +547,6 @@ export default {
             return flag
         },
         onSave(item) {
-            console.log('题目数据:', item)
             //检查信息是否完整
             if (!this.getSimpleText(item.stemContent) || !this.checkOptionNull(item.optionsContent)) {
                 this.$Message.warning(this.$t('survey.questionaire.noCompleteTip'))
@@ -623,13 +622,13 @@ export default {
                             if (item[0].groupName) {
                                 this.groupList.unshift({
                                     groupId: item[0].groupId || 'default',
-                                    groupName: item[0].groupName || '未分组老师',
+                                    groupName: item[0].groupName || this.$t('td.td106'),
                                     members: item
                                 })
                             } else {
                                 this.groupList.push({
                                     groupId: item[0].groupId || 'default',
-                                    groupName: item[0].groupName || '未分组老师',
+                                    groupName: item[0].groupName || this.$t('td.td106'),
                                     members: item
                                 })
                             }
@@ -653,7 +652,7 @@ export default {
         },
         async publish() {
             this.formatTarget = this.baseInfo.target.map(item => {
-                if (item === '未分组老师') {
+                if (item === this.$t('td.td106')) {
                     return 'default'
                 } else {
                     return item
@@ -784,7 +783,7 @@ export default {
                     await this.doUploadBlob(bInfo, items, 'survey')
                     r(this.saveSurvey(id, answers))
                 } catch (e) {
-                    this.$Message.error('创建研修问卷失败')
+                    this.$Message.error(this.$t('td.td107'))
                     j()
                 }
                 // this.doUploadBlob(bInfo, items, 'survey').then(
@@ -988,7 +987,7 @@ export default {
                         r(this.saveExam(id, answers))
                     },
                     err => {
-                        this.$Message.error('创建研修评测失败')
+                        this.$Message.error(this.$t('td.td108'))
                         j()
                     }
                 )

+ 7 - 7
TEAMModelOS/ClientApp/src/view/train/PhoneSign.vue

@@ -7,9 +7,9 @@
                 </span>
             </p>
             <p class="course-name">{{topic || $t('cusMgt.join.errorInfo')}}</p>
-            <Input v-model="phoneNum" prefix="ios-phone-portrait" type="tel" placeholder="输入手机号" style="width: 300px;margin-top: 20px;height: 40px;" />
-            <p style="color: #F06431;" v-if="notFound">未查询到对应账号!请检查后重试!</p>
-            <p style="color: #20cb98;" v-if="isRepeat">已签到成功,请勿重复操作!</p>
+            <Input v-model="phoneNum" prefix="ios-phone-portrait" type="tel" :placeholder="$t('td.td109')" style="width: 300px;margin-top: 20px;height: 40px;" />
+            <p style="color: #F06431;" v-if="notFound">{{$t('td.td110')}}</p>
+            <p style="color: #20cb98;" v-if="isRepeat">{{$t('td.td111')}}</p>
             <div style="width:fit-content;margin: auto;">
                 <!-- <p class="info-item">
                     <span class="info-lable">
@@ -88,7 +88,7 @@ export default {
             this.notFound = false
             this.isRepeat = false
             if (!this.phoneNum.trim() || !this.isTel(this.phoneNum)) {
-                this.$Message.warning('请输入正确手机号!')
+                this.$Message.warning(this.$t('td.td112'))
                 return
             }
             this.btnLoading = true
@@ -107,16 +107,16 @@ export default {
                         this.isRepeat = true
                         this.btnLoading = false
                     } else if (res.code === 500) { //签到异常
-                        this.$Message.error('签到失败,请重新签到')
+                        this.$Message.error(this.$t('td.td113'))
                         this.btnLoading = false
                     } else {
-                        this.$Message.success('签到成功')
+                        this.$Message.success(this.$t('td.td114'))
                         this.isSign = true
                         this.btnLoading = false
                     }
                 },
                 err => {
-                    this.$Message.error('签到失败')
+                    this.$Message.error(this.$t('td.td115'))
                     this.btnLoading = false
                 }
             )

+ 0 - 1
TEAMModelOS/ClientApp/src/view/train/SurveyDetail.vue

@@ -107,7 +107,6 @@ export default {
 
         async getFullSurvey(surveyItem) {
             this.items = await this.getBlobItems(surveyItem)
-            console.log('题目信息', this.items)
             // 如果是评测需要判断作答对错(只有客观题)
             if (this.survey.code.includes('TrExam') && this.answer) {
                 this.isExam = true

+ 53 - 66
TEAMModelOS/ClientApp/src/view/train/TrainDetail.vue

@@ -10,7 +10,7 @@
                             {{$t('train.detail.back')}}
                         </span>
                         <span class="area-tips" v-if="trainInfo.owner === 'area'">
-                            温馨提示:区级活动不计入校本研修学时
+                            {{$t('td.td116')}}
                         </span>
                     </div>
                     <div class="train-top-info">
@@ -25,7 +25,7 @@
                                 </span>
                                 <!-- 区级活动显示状态 -->
                                 <span :class="trainInfo.progress === 'pending' ? 'status-pending' : trainInfo.progress === 'going' ? 'status-going' : 'status-finish'" v-else>
-                                    {{trainInfo.progress === 'pending' ? '未发布' : trainInfo.progress === 'going' ? '进行中' : '已结束'}}
+                                    {{trainInfo.progress === 'pending' ? $t('td.td117') : trainInfo.progress === 'going' ? $t('td.td118') : $t('td.td119')}}
                                 </span>
                             </p>
                             <div class="info-item">
@@ -62,32 +62,32 @@
                             </div>
                             <div class="info-item" v-if="trainInfo.owner === 'school'">
                                 <span class="info-label">
-                                    活动视频
+                                    {{$t('td.td120')}}
                                 </span>
                                 <span v-if="trainVideo">
                                     <span class="upload-text" @click="handlePreviewFile('video')">
-                                        播放
+                                        {{$t('td.td121')}}
                                     </span>
                                     <!-- <span class="upload-text" @click="downloadTrainFile(trainVideo.url, trainVideo.name)" style="margin-left:10px">
                                         下载
                                     </span> -->
                                     <span class="upload-text" @click="deleteFile('video')" style="margin-left:10px">
-                                        删除
+                                        {{$t('td.td122')}}
                                     </span>
                                     <Upload action="" :show-upload-list="false" :before-upload="handleUpload" style="display:inline-block;margin-left:10px">
-                                        <span class="upload-text" @click="setUpload('video')">重新上传</span>
+                                        <span class="upload-text" @click="setUpload('video')">{{$t('td.td58')}}</span>
                                     </Upload>
                                 </span>
                                 <span v-else>
                                     <Upload action="" :show-upload-list="false" :before-upload="handleUpload" style="display:inline-block">
-                                        <span class="upload-text" @click="setUpload('video')">上传</span>
+                                        <span class="upload-text" @click="setUpload('video')">{{$t('td.td123')}}</span>
                                     </Upload>
-                                    <span class="text-info">(视频只能上传一个)</span>
+                                    <span class="text-info">{{$t('td.td124')}}</span>
                                 </span>
                             </div>
                             <div class="info-item" style="display:flex" v-if="trainInfo.owner === 'school'">
                                 <span class="info-label">
-                                    活动资料:
+                                    {{$t('td.td125')}}
                                 </span>
                                 <span v-if="trainFiles.length">
                                     <span class="train-file-item" v-for="(item,index) in trainFiles" :key="index" @click="handlePreviewFile('file',index)">
@@ -95,14 +95,14 @@
                                         <Icon class="delete-train-file" type="md-close" @click="deleteFile('file',index)" />
                                     </span>
                                     <Upload action="" multiple :show-upload-list="false" :before-upload="handleUpload" style="display:inline-block">
-                                        <span class="upload-text" @click="setUpload('file')">继续上传</span>
+                                        <span class="upload-text" @click="setUpload('file')">{{$t('td.td126')}}</span>
                                     </Upload>
                                 </span>
                                 <span v-else>
                                     <Upload action="" multiple :show-upload-list="false" :before-upload="handleUpload" style="display:inline-block">
-                                        <span class="upload-text" @click="setUpload('file')">上传</span>
+                                        <span class="upload-text" @click="setUpload('file')">{{$t('td.td123')}}</span>
                                     </Upload>
-                                    <span class="text-info">(资料可以上传多份)</span>
+                                    <span class="text-info">{{$t('td.td127')}}</span>
                                 </span>
                             </div>
                         </div>
@@ -111,14 +111,14 @@
                         </p>
                     </div>
                     <p class="province-tips">
-                        根据省平台要求,教师必须满足以下条件才可获得校本研修活动学时: 1、10学时中至少有一次需提交作业的校本研修活动 2、在活动中成功提交PDF作业
+                        {{$t('td.td128')}}
                     </p>
                     <div class="train-data-wrap" v-if="trainInfo.progress != 'pending'">
                         <Tabs v-model="tabName">
                             <Button v-show="tabName == 'name' && trainInfo.owner === 'school'" @click="batchPass(1)" type="success" style="margin-top:5px;margin-right:35px" size="small" slot="extra">
-                                批量合格
+                                {{$t('td.td129')}}
                             </Button>
-                            <TabPane :label="trainInfo.owner === 'school' ? $t('train.detail.checkHour') : '数据总览'" name="name" class="tab-pane-wrap" style="max-height:800px">
+                            <TabPane :label="trainInfo.owner === 'school' ? $t('train.detail.checkHour') : $t('td.td86')" name="name" class="tab-pane-wrap" style="max-height:800px">
                                 <vuescroll style="height:calc(100% - 60px)">
                                     <Table :columns="columns" @on-selection-change="selection => selections = selection" :data="tableData" class="table-box">
                                         <template slot-scope="{ row,index }" slot="action">
@@ -204,10 +204,10 @@
                     </div>
                     <div v-else class="publish-area-activity">
                         <Icon custom="iconfont icon-unpublish" class="unpublish-icon" />
-                        <p class="publish-tips">请选择学校老师参加并发布活动</p>
-                        <Button v-show="!selections.length" class="choose-teacher-btn" @click="addStatus = true">选择老师</Button>
-                        <Button v-show="selections.length" class="choose-teacher-btn" @click="addStatus = true">继续挑选(已选{{selections.length}}位)</Button>
-                        <Button v-show="selections.length" type="success" class="choose-teacher-btn" @click="publishAreaActivity">发布活动</Button>
+                        <p class="publish-tips">{{$t('td.td130')}}</p>
+                        <Button v-show="!selections.length" class="choose-teacher-btn" @click="addStatus = true">{{$t('td.td131')}}</Button>
+                        <Button v-show="selections.length" class="choose-teacher-btn" @click="addStatus = true">{{$t('td.td132')}}{{selections.length}}{{$t('td.td133')}}</Button>
+                        <Button v-show="selections.length" type="success" class="choose-teacher-btn" @click="publishAreaActivity">{{$t('td.td134')}}</Button>
                     </div>
                 </div>
                 <div class="detail-right">
@@ -436,7 +436,7 @@
         <!-- 作业附件预览 -->
         <Modal v-model="hwViewStatus" width="900">
             <div slot="header">
-                <span>{{hwTableData[viewIndex] ? hwTableData[viewIndex].name : $t('train.detail.viewHwTitle')}}{{$t('train.detail.hwFile')}}</span>
+                <span>{{hwTableData[viewIndex] ? hwTableData[viewIndex].name : $t('train.detail.viewHwTitle')}}{{$t('td.td66')}}{{$t('train.detail.hwFile')}}</span>
             </div>
             <div v-if="hwTableData[viewIndex] && hwTableData[viewIndex].hwData" style="min-height:150px">
                 <span :class="['hw-file-item', hwPreviewFile.name == answer.name ? 'hw-file-item-active':'']" v-for="answer in hwTableData[viewIndex].hwData" :key="answer.name" @click="handlePreviewHw(answer)">
@@ -461,7 +461,7 @@
             <SurveyDetail v-if="examInfo && tableData[examIndex]" :survey="examInfo" :answer="tableData[examIndex].examAnswer || []"></SurveyDetail>
         </Modal>
         <Modal v-model="progressStatus" :closable="false" :mask-closable="false" @on-cancel="cancelUpd" @on-ok="closeModal" :loading="modalLoading">
-            <p class="uploading-title">{{uploadStatus ? '上传中' : '上传完成'}}</p>
+            <p class="uploading-title">{{uploadStatus ? $t('td.td135') : $t('td.td136')}}</p>
             <div class="file-list-box">
                 <div class="file-prog-item" v-for="(item,index) in progList" :key="index">
                     <p>
@@ -487,17 +487,17 @@
                 <img v-else-if="previewFile.type == 'image'" :src="previewFile.url" style="border-radius: 5px;max-height: 800px;max-width:870px;" />
             </div>
         </div>
-        <Modal v-model="addStatus" title="添加教师" @on-ok="confirmAdd" :width="1000" :loading="modalLoading">
+        <Modal v-model="addStatus" :title="$t('td.td137')" @on-ok="confirmAdd" :width="1000" :loading="modalLoading">
             <div class="filter-box" style="margin-bottom:10px">
-                教研组:
-                <Select :max-tag-count="2" v-model="filter.groups" style="width:200px" multiple placeholder="教研组筛选">
+                {{$t('td.td138')}}:
+                <Select :max-tag-count="2" v-model="filter.groups" style="width:200px" multiple :placeholder="$t('td.td139')">
                     <Option v-for="item in researches" :value="item.id" :key="item.id">{{ item.name }}</Option>
                 </Select>
                 <!-- <Input v-model="filter.keyword" search placeholder="搜索" style="margin-left:20px;width:200px" /> -->
             </div>
             <Table ref="selectTeacher" :columns="columns2" :height="600" :data="teacherShow" @on-selection-change="selection=>{ selections = selection}">
                 <template slot-scope="{ row }" slot="groupName">
-                    <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || '未设置' }}</span>
+                    <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || $t('td.td140') }}</span>
                 </template>
                 <template slot-scope="{ row }" slot="picture">
                     <PersonalPhoto :name="row.name" :picture="row.picture" />
@@ -537,7 +537,7 @@ export default {
                     slot: 'picture'
                 },
                 {
-                    title: '姓名',
+                    title: this.$t('td.td95'),
                     key: 'name'
                 },
                 {
@@ -545,7 +545,7 @@ export default {
                     key: 'id'
                 },
                 {
-                    title: '教研组',
+                    title: this.$t('td.td138'),
                     key: 'groupName',
                     slot: 'groupName',
                     sortable: true
@@ -891,17 +891,7 @@ export default {
         },
         //查询学校所有老师
         getTeacherAll() {
-            this.$store.dispatch('user/getSchoolTeacher').then(
-                res => {
-                    console.log(res)
-                    if (res.code == 0) {
-                        this.$Message.error('無法取得使用者資料')
-                    }
-                },
-                err => {
-                    this.$Message.error('查询学校教师列表失败')
-                }
-            )
+            this.$store.dispatch('user/getSchoolTeacher')
         },
         //查询学校所有教研组
         getAllResearch() {
@@ -915,11 +905,11 @@ export default {
                     if (res.groups) {
                         this.researches = res.groups
                     } else {
-                        this.$Message.warning('查询教研组失败')
+                        this.$Message.warning(this.$t('td.td141'))
                     }
                 },
                 err => {
-                    this.$Message.error('查询教研组失败')
+                    this.$Message.error(this.$t('td.td141'))
                 }
             )
         },
@@ -929,7 +919,7 @@ export default {
                 this.addStatus = false
             } else {
                 this.modalLoading = false
-                this.$Message.warning('请勾选参加活动的老师')
+                this.$Message.warning(this.$t('td.td142'))
                 setTimeout(() => {
                     this.modalLoading = true
                 })
@@ -997,11 +987,11 @@ export default {
          */
         deleteFile(type, index) {
             if (type) {
-                let fileName = type === 'video' ? '活动视频' : this.trainFiles[index].name
+                let fileName = type === 'video' ? this.$t('td.td120') : this.trainFiles[index].name
                 let blob = type === 'video' ? this.trainVideo.blob : this.trainFiles[index].blob
                 this.$Modal.confirm({
-                    title: '删除文件',
-                    content: `确认删除${fileName}吗?`,
+                    title: this.$t('td.td143'),
+                    content: `${this.$t('td.td144')}${fileName}?`,
                     onOk: () => {
                         let schoolSas = {
                             sas: '?' + this.$store.state.user.schoolProfile.blob_sas,
@@ -1011,7 +1001,7 @@ export default {
                         let blobTool = new BlobTool(schoolSas.url, schoolSas.name, schoolSas.sas, 'school')
                         blobTool.deleteBlob(blob).then(
                             res => {
-                                this.$Message.success('删除成功')
+                                this.$Message.success(this.$t('td.td145'))
                                 if (type === 'video') {
                                     this.trainVideo = undefined
                                 } else {
@@ -1019,13 +1009,13 @@ export default {
                                 }
                             },
                             err => {
-                                this.$Message.error('删除失败')
+                                this.$Message.error(this.$t('td.td146'))
                             }
                         )
                     }
                 })
             } else {
-                this.$Message.error('删除失败')
+                this.$Message.error(this.$t('td.td146'))
             }
         },
         closePreview() {
@@ -1053,7 +1043,7 @@ export default {
          */
         closeModal() {
             if (this.uploadStatus) {
-                this.$Message.warning('文件上传中,请等待文件上传完成')
+                this.$Message.warning(this.$t('td.td147'))
                 this.modalLoading = false
                 setTimeout(() => {
                     this.modalLoading = true
@@ -1068,7 +1058,7 @@ export default {
                 let extension = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
                 if (extension.toLowerCase() != 'mp4') {
                     this.$Message.error({
-                        content: '活动视频只支持mp4文件格式',
+                        content: this.$t('td.td148'),
                         duration: 3
                     })
                     return false
@@ -1116,9 +1106,9 @@ export default {
                 },
                 err => {
                     if (res.code && res.code == 1) {
-                        this.$Message.error('学校空间已满')
+                        this.$Message.error(this.$t('td.td149'))
                     } else {
-                        this.$Message.error('上传失败')
+                        this.$Message.error(this.$t('td.td150'))
                     }
                 }
             )
@@ -1172,12 +1162,12 @@ export default {
         //批量通过
         batchPass(type) {
             if (!this.selections.length) {
-                this.$Message.warning(`请选择需要批量处理${type == 1 ? '合格' : '不合格'}的老师`)
+                this.$Message.warning(`${this.$t('td.td151')}${type == 1 ? $t('td.td152') : $t('td.td153')}$t('td.td154')`)
                 return
             }
             this.$Modal.confirm({
-                title: '批量处理',
-                content: `确认将所选老师全部设置为合格吗?`,
+                title: this.$t('td.td155'),
+                content: this.$t('td.td156'),
                 onOk: () => {
                     let ids = this.selections.map(item => item.id)
                     this.audit(ids, type)
@@ -1235,7 +1225,6 @@ export default {
                     if (res.survey) {
                         // 获取作答数据
                         let sasString = await this.$tools.getSchoolSas()
-                        console.log('学校blob', sasString)
                         let blobHost = res.survey.owner === 'area' ? this.$store.state.user.userProfile.osblob_uri : `${sasString.url}/${sasString.name}`
                         let sas = res.survey.owner === 'area' ? ('?' + this.$store.state.user.userProfile.osblob_sas) : sasString.sas
                         let answerData = await this.$tools.getFile(blobHost + res.survey.recordUrl + sas)
@@ -1266,7 +1255,7 @@ export default {
                     }
                 },
                 err => {
-                    this.$Message.error('问卷作答数据获取失败')
+                    this.$Message.error(this.$t('td.td157'))
                 }
             )
         },
@@ -1336,16 +1325,15 @@ export default {
                                         }
                                     })
                                     this.hwTableData = JSON.parse(JSON.stringify(this.tableData))
-                                    console.log('作业数据', this.hwTableData)
                                     let data = JSON.parse(JSON.stringify(this.tableData))
                                     this.tableData = []
                                     this.tableData = data
                                 } else {
-                                    this.$Message.error('获取作业提交数据失败')
+                                    this.$Message.error(this.$t('td.td158'))
                                 }
                             },
                             ansErr => {
-                                this.$Message.error('获取作业提交数据失败')
+                                this.$Message.error(this.$t('td.td158'))
                             }
                         )
                     }
@@ -1510,11 +1498,11 @@ export default {
                             this.getWorkInfo()
                         }
                     } else {
-                        this.$Message.error('获取名单列表失败')
+                        this.$Message.error(this.$t('td.td159'))
                     }
                 },
                 err => {
-                    this.$Message.error('获取名单列表失败')
+                    this.$Message.error(this.$t('td.td159'))
                 }
             )
         },
@@ -1548,7 +1536,7 @@ export default {
                                     let resData = await this.$api.train.findSummaryTrain(params)
                                     this.checkData = resData.records
                                 } catch (e) {
-                                    this.$Message.error('获取签到数据失败')
+                                    this.$Message.error(this.$t('td.td160'))
                                 }
                             } else {
                                 this.checkData = res.records
@@ -1653,7 +1641,7 @@ export default {
                                 if (this.trainInfo.owner === 'area') {
                                     //获取活动名单
                                     this.columns.splice(2, 0, {
-                                        title: '学校',
+                                        title: this.$t('td.td161'),
                                         key: 'schoolName',
                                         align: 'center'
                                     })
@@ -1695,7 +1683,6 @@ export default {
                 prefix: `train/study/${this.trainInfo.id}/files`
             }).then(
                 res => {
-                    console.log('研修文件', res)
                     if (res.blobList) {
                         res.blobList.forEach(item => {
                             item.url = item.url + schoolSas.sas
@@ -1780,11 +1767,11 @@ export default {
                                 this.getWorkInfo()
                             }
                         } else {
-                            this.$Message.error('查询教师列表失败')
+                            this.$Message.error(this.$t('td.td162'))
                         }
                     },
                     err => {
-                        this.$Message.error('查询教师列表失败')
+                        this.$Message.error(this.$t('td.td162'))
                     }
                 )
             }

+ 4 - 4
TEAMModelOS/ClientApp/src/view/train/TrainMgt.vue

@@ -6,7 +6,7 @@
             <Select v-model="filter.type" style="width:200px" @on-change="filterTrian">
                 <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
             </Select>
-            <span style="margin-left:20px">教研组:</span>
+            <span style="margin-left:20px">{{$t('td.td138')}}:</span>
             <Select v-model="filter.group" style="width:200px" @on-change="filterTrian" clearable>
                 <Option v-for="item in groups" :value="item" :key="item">{{ item }}</Option>
             </Select>
@@ -38,8 +38,8 @@
                         <span>{{item.address}}</span>
                     </div>
                     <div class="info-item">
-                        <span class="info-label">对象:</span>
-                        <span>{{item.gNames || '暂无'}}</span>
+                        <span class="info-label">{{$t('td.td163')}}</span>
+                        <span>{{item.gNames || $t('td.td164')}}</span>
                     </div>
                     <div class="info-item">
                         <span class="info-label">{{$t('train.mgt.time')}}</span>
@@ -169,7 +169,7 @@ export default {
                     this.trainListShow = this.trainList
                 },
                 err => {
-                    this.$Message.error('查询研修列表失败')
+                    this.$Message.error(this.$t('td.td165'))
                 }
             ).then(() => {
                 this.isLoading = false

+ 210 - 212
TEAMModelOS/ClientApp/src/view/trainList/Check.vue

@@ -1,221 +1,219 @@
 <template>
-	<div class="check-container">
-		<div>
-			<Input v-special-char class="serch-inp light-iview-input" suffix="ios-search"
-				:placeholder="$t('teachermgmt.blurryFilter')" v-model="tchSearchVal" @on-change="onSearch" />
-			<!-- <Button @click="doFix">FIX</Button> -->
-			<Table :columns="teacherCol" :data="tchList" :height="tableHeight" stripe ref="tableRef">
-				<template slot-scope="{ row }" slot="avatar">
-					<div style="display: flex;align-items: center;">
-						<PersonalPhoto :name="row.name" :picture="row.picture" />
-					</div>
-				</template>
-				<template slot-scope="{ row }" slot="name">
-					<div style="display: flex;align-items: center;">
-						<span style="margin-left: 10px;">{{ row.name }}</span>
-					</div>
-				</template>
-				<template slot-scope="{ row }" slot="action">
-					<div style="display: flex;align-items: center;">
-						<i-switch true-color="#13ce66" :value="hasAuth(row)" :before-change="handleBeforeChange"
-							@on-change="onSwitchChange(row,$event)"></i-switch>
-					</div>
-				</template>
-			</Table>
-		</div>
-	</div>
+  <div class="check-container">
+    <div>
+      <Input v-special-char class="serch-inp light-iview-input" suffix="ios-search" :placeholder="$t('teachermgmt.blurryFilter')" v-model="tchSearchVal" @on-change="onSearch" />
+      <!-- <Button @click="doFix">FIX</Button> -->
+      <Table :columns="teacherCol" :data="tchList" :height="tableHeight" stripe ref="tableRef">
+        <template slot-scope="{ row }" slot="avatar">
+          <div style="display: flex;align-items: center;">
+            <PersonalPhoto :name="row.name" :picture="row.picture" />
+          </div>
+        </template>
+        <template slot-scope="{ row }" slot="name">
+          <div style="display: flex;align-items: center;">
+            <span style="margin-left: 10px;">{{ row.name }}</span>
+          </div>
+        </template>
+        <template slot-scope="{ row }" slot="action">
+          <div style="display: flex;align-items: center;">
+            <i-switch true-color="#13ce66" :value="hasAuth(row)" :before-change="handleBeforeChange" @on-change="onSwitchChange(row,$event)"></i-switch>
+          </div>
+        </template>
+      </Table>
+    </div>
+  </div>
 </template>
 <script>
-	import BlobTool from '@/utils/blobTool.js'
-	import PersonalPhoto from '@/components/public/personalPhoto/Index.vue'
-	export default {
-		components: {
-			PersonalPhoto
-		},
-		data() {
-			return {
-				tableHeight: document.documentElement.clientHeight * 0.82,
-				tchList: [],
-				originTchList: [],
-				tchSearchVal: '',
-				teacherCol: [{
-						title: ` `,
-						key: 'name',
-						slot: 'avatar',
-						width: 60
-					},
-					{
-						title: this.$t('teachermgmt.table.th2'),
-						key: 'name',
-						sortable: true,
-						width: 250
-					},
-					{
-						title: 'ID',
-						key: 'id',
-						sortable: true,
-					},
-					{
-						title: this.$t('teachermgmt.table.th3'),
-						key: 'job',
-						render: (h, params) => {
-							if (typeof params.row.job === 'undefined' || params.row.job == null || params.row
-								.job === '') {
-								return h('span', this.$t('teachermgmt.job.teacher'))
-							} else {
-								return h('span', params.row.job)
-							}
-						}
-					},
-					{
-						title: '是否为考核人员',
-						key: 'action',
-						slot: 'action'
-					}
-				],
-			}
-		},
-		async created() {
-			this.tchList = await this.getAllTeacher()
-			this.originTchList = this._.cloneDeep(this.tchList)
-		},
-		methods: {
-			doFix() {
-				this.$api.ability.fixMd5Duration({
-					"standard": "standard3",
-					"abilityIds": [
-						"5221d55f-1e36-4bcf-9c83-1b5b5701b306",
-						    "57f1297d-1377-4762-9d9d-191a6ef86fc3",
-						    "20f3c812-34ed-4456-be1e-93797609f67b",
-						    "0ba82919-c152-44ac-b93b-c41ba7071d50",
-						    "d570d16f-0b22-4f6e-b1a6-ddbe24739a64",
-						    "a55ac6bd-90e0-4b01-bee3-11b6390580b1",
-						    "26c5dd3f-098f-429d-a339-f57543796645",
-						    "16abf9be-4cb5-448b-9e18-37455397cd3f"
-					]
-				}).then(result => {
-					let res = result
-					let userProfile2 = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"))
-					let s = userProfile2.osblob_uri
-					let n = {
-						sas: '?' + this.$store.state.user.userProfile.osblob_sas,
-						name: 'teammodelos',
-						url: this.$tools.matchHost(s)
-					}
-					console.time("getImg");
-					let containerClient = new BlobTool(n.url, n.name, n.sas, 'school')
-					let docSas = '?' + userProfile2.osblob_sas
-					let promiseArr = []
+import BlobTool from '@/utils/blobTool.js'
+import PersonalPhoto from '@/components/public/personalPhoto/Index.vue'
+export default {
+  components: {
+    PersonalPhoto
+  },
+  data() {
+    return {
+      tableHeight: document.documentElement.clientHeight * 0.82,
+      tchList: [],
+      originTchList: [],
+      tchSearchVal: '',
+      teacherCol: [{
+        title: ` `,
+        key: 'name',
+        slot: 'avatar',
+        width: 60
+      },
+      {
+        title: this.$t('teachermgmt.table.th2'),
+        key: 'name',
+        sortable: true,
+        width: 250
+      },
+      {
+        title: 'ID',
+        key: 'id',
+        sortable: true,
+      },
+      {
+        title: this.$t('teachermgmt.table.th3'),
+        key: 'job',
+        render: (h, params) => {
+          if (typeof params.row.job === 'undefined' || params.row.job == null || params.row
+            .job === '') {
+            return h('span', this.$t('teachermgmt.job.teacher'))
+          } else {
+            return h('span', params.row.job)
+          }
+        }
+      },
+      {
+        title: this.$t('ability.check.isCheck'),
+        key: 'action',
+        slot: 'action'
+      }
+      ],
+    }
+  },
+  async created() {
+    this.tchList = await this.getAllTeacher()
+    this.originTchList = this._.cloneDeep(this.tchList)
+  },
+  methods: {
+    doFix() {
+      this.$api.ability.fixMd5Duration({
+        "standard": "standard3",
+        "abilityIds": [
+          "5221d55f-1e36-4bcf-9c83-1b5b5701b306",
+          "57f1297d-1377-4762-9d9d-191a6ef86fc3",
+          "20f3c812-34ed-4456-be1e-93797609f67b",
+          "0ba82919-c152-44ac-b93b-c41ba7071d50",
+          "d570d16f-0b22-4f6e-b1a6-ddbe24739a64",
+          "a55ac6bd-90e0-4b01-bee3-11b6390580b1",
+          "26c5dd3f-098f-429d-a339-f57543796645",
+          "16abf9be-4cb5-448b-9e18-37455397cd3f"
+        ]
+      }).then(result => {
+        let res = result
+        let userProfile2 = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"))
+        let s = userProfile2.osblob_uri
+        let n = {
+          sas: '?' + this.$store.state.user.userProfile.osblob_sas,
+          name: 'teammodelos',
+          url: this.$tools.matchHost(s)
+        }
+        console.time("getImg");
+        let containerClient = new BlobTool(n.url, n.name, n.sas, 'school')
+        let docSas = '?' + userProfile2.osblob_sas
+        let promiseArr = []
 
-					for (var i = 0; i < res.length; i++) {
-						let item = res[i]
-						// if(i > 0) return
-						item.children.forEach(j => {
-							if (j.rnodes.length) {
-								j.rnodes.forEach(async k => {
-									let fullLink =
-										`${userProfile2.osblob_uri}${k.link}${docSas}`
-									if (k.type === 'video' && k.duration === 0) {
-										promiseArr.push(new Promise((r, j) => {
-											var vid = document.createElement(
-												'video');
-											vid.src = fullLink;
-											this.$nextTick(() => {
-												vid.addEventListener(
-													'loadedmetadata',
-													function() {
-														console.warn(
-															vid
-															.duration
-														)
-														k.duration =
-															vid
-															.duration
-														// vid.remove()
-														r(200)
-													});
-											})
-										}))
-									}
-								})
-							}
-						})
-					}
-					console.error(promiseArr.length)
-					Promise.all(promiseArr).then(result => {
-						console.timeEnd('getImg')
-						console.log(JSON.stringify(res))
-						// let file = new File([JSON.stringify(res)],  "result.json", {
-						// 	type: "",
-						// });
-					}).catch(e => {
-						console.log(e)
-					})
-				})
-			},
-			/* 搜索教师 */
-			onSearch() {
-				this.tchList = this.originTchList.filter(t => t.name.indexOf(this.tchSearchVal) > -1 || t.id.indexOf(this
-					.tchSearchVal) > -1)
-			},
-			/* 获取学校所有教师列表 */
-			getAllTeacher() {
-				return new Promise((r, j) => {
-					this.$api.schoolUser.getSchoolTeacherAll({
-						school_code: this.$store.state.userInfo.schoolCode
-					}).then(res => {
-						if (!res.error) {
-							r(res.teachers.filter(i => i.status === 'join' && i.id !== this.$store.state
-								.userInfo.TEAMModelId))
-						}
-					})
-				})
-			},
-			handleBeforeChange() {
-				return new Promise((resolve) => {
-					this.$Modal.confirm({
-						title: this.$t('syllabus.modifyTip'),
-						content: `确认修改当前教师的审核人员身份吗?`,
-						onOk: () => {
-							resolve();
-						}
-					});
-				});
-			},
-			onSwitchChange(val, isAdd) {
-				console.log(val, isAdd)
-				this.$api.schoolUser.updPermissionByIds({
-					school_code: this.$store.state.userInfo.schoolCode,
-					ids: [val.id],
-					pmAdd: isAdd ? ['train-appraise'] : [],
-					pmRmv: !isAdd ? ['train-appraise'] : [],
-					job: val.job,
-					mode: "multi"
-				}).then(res => {
-					if (!res.error) {
-						this.$Message.success(isAdd ? `已添加 ${val.name} 为审核人员` : `已取消 ${val.name} 的审核人员身份!`)
-					}
-				})
-			},
-		},
-		computed: {
-			hasAuth() {
-				return row => {
-					return row.permissions.includes('train-appraise')
-				}
-			}
-		}
-	}
+        for (var i = 0; i < res.length; i++) {
+          let item = res[i]
+          // if(i > 0) return
+          item.children.forEach(j => {
+            if (j.rnodes.length) {
+              j.rnodes.forEach(async k => {
+                let fullLink =
+                  `${userProfile2.osblob_uri}${k.link}${docSas}`
+                if (k.type === 'video' && k.duration === 0) {
+                  promiseArr.push(new Promise((r, j) => {
+                    var vid = document.createElement(
+                      'video');
+                    vid.src = fullLink;
+                    this.$nextTick(() => {
+                      vid.addEventListener(
+                        'loadedmetadata',
+                        function () {
+                          console.warn(
+                            vid
+                              .duration
+                          )
+                          k.duration =
+                            vid
+                              .duration
+                          // vid.remove()
+                          r(200)
+                        });
+                    })
+                  }))
+                }
+              })
+            }
+          })
+        }
+        console.error(promiseArr.length)
+        Promise.all(promiseArr).then(result => {
+          console.timeEnd('getImg')
+          console.log(JSON.stringify(res))
+          // let file = new File([JSON.stringify(res)],  "result.json", {
+          // 	type: "",
+          // });
+        }).catch(e => {
+          console.log(e)
+        })
+      })
+    },
+    /* 搜索教师 */
+    onSearch() {
+      this.tchList = this.originTchList.filter(t => t.name.indexOf(this.tchSearchVal) > -1 || t.id.indexOf(this
+        .tchSearchVal) > -1)
+    },
+    /* 获取学校所有教师列表 */
+    getAllTeacher() {
+      return new Promise((r, j) => {
+        this.$api.schoolUser.getSchoolTeacherAll({
+          school_code: this.$store.state.userInfo.schoolCode
+        }).then(res => {
+          if (!res.error) {
+            r(res.teachers.filter(i => i.status === 'join' && i.id !== this.$store.state
+              .userInfo.TEAMModelId))
+          }
+        })
+      })
+    },
+    handleBeforeChange() {
+      return new Promise((resolve) => {
+        this.$Modal.confirm({
+          title: this.$t('syllabus.modifyTip'),
+          content: this.$t('ability.check.tip1'),
+          onOk: () => {
+            resolve();
+          }
+        });
+      });
+    },
+    onSwitchChange(val, isAdd) {
+      console.log(val, isAdd)
+      this.$api.schoolUser.updPermissionByIds({
+        school_code: this.$store.state.userInfo.schoolCode,
+        ids: [val.id],
+        pmAdd: isAdd ? ['train-appraise'] : [],
+        pmRmv: !isAdd ? ['train-appraise'] : [],
+        job: val.job,
+        mode: "multi"
+      }).then(res => {
+        if (!res.error) {
+          this.$Message.success(isAdd ? `${this.$t('ability.check.tip2')} ${val.name} ${this.$t('ability.check.tip3')}` : `${this.$t('ability.check.tip4')} ${val.name} ${this.$t('ability.check.tip5')}`)
+        }
+      })
+    },
+  },
+  computed: {
+    hasAuth() {
+      return row => {
+        return row.permissions.includes('train-appraise')
+      }
+    }
+  }
+}
 </script>
 
 <style lang="less" scoped>
-	.check-container {
-		padding: 10px;
+.check-container {
+  padding: 10px;
 
-		.serch-inp {
-			width: 100%;
-			max-width: 300px;
-			margin-bottom: 10px;
-		}
-	}
+  .serch-inp {
+    width: 100%;
+    max-width: 300px;
+    margin-bottom: 10px;
+  }
+}
 </style>

+ 93 - 104
TEAMModelOS/ClientApp/src/view/trainList/Join.vue

@@ -2,25 +2,25 @@
     <div class="train-join-container">
         <div class="train-join-action">
             <span style="margin-right: 20px;vertical-align: middle;color: #2d8cf0;">
-                人数:{{ isProvince ? ptList.length : joinTeachers.length}}人
-                <span v-show="isProvince">(已同步省平台名单)</span>
+                {{$t('td.td166')}}{{ isProvince ? ptList.length : joinTeachers.length}}{{$t('unit.text7')}}
+                <span v-show="isProvince">{{$t('td.td167')}}</span>
             </span>
-            <span v-show="viewType === 'card'" class="tips-info">温馨提示:空白分组(分组内没有添加教师)不会被保存。</span>
+            <span v-show="viewType === 'card'" class="tips-info">{{$t('td.td168')}}</span>
             <span v-show="isUpdGroup" class="join-action-btn" @click="saveGroup" style="margin-right:20px">
                 <Icon type="ios-albums-outline" />
-                保存分组
+                {{$t('td.td169')}}
             </span>
             <span class="join-action-btn" @click="handleViewType" style="margin-right:20px">
                 <Icon :type="viewType === 'list' ? 'md-card':'md-list' " />
-                {{viewType === 'list' ? '分组视图':'列表视图'}}
+                {{viewType === 'list' ? $t('td.td170') : $t('td.td171')}}
             </span>
             <span class="join-action-btn" @click="rmvBatch" style="margin-right:20px" v-if="viewType === 'list' && !isProvince">
                 <Icon type="md-remove-circle" />
-                移除教师
+                {{$t('td.td172')}}
             </span>
             <span class="join-action-btn" @click="showAddTeacher" v-if="viewType === 'list' && !isProvince">
                 <Icon type="md-add" />
-                添加教师
+                {{$t('td.td173')}}
             </span>
         </div>
         <!-- 表格视图 -->
@@ -32,13 +32,13 @@
                         <PersonalPhoto :name="row.teacherName" :picture="row.picture" />
                     </template>
                     <template slot-scope="{ row }" slot="role">
-                        <span :style="{color:row.tag == 'leader' ? '#2d8cf0' : ''}">{{row.tag == 'leader' ? '组长' : '组员'}}</span>
+                        <span :style="{color:row.tag == 'leader' ? '#2d8cf0' : ''}">{{row.tag == 'leader' ? $t('td.td174') : $t('td.td175')}}</span>
                     </template>
                     <template slot-scope="{ row }" slot="groupName">
-                        <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || '未设置' }}</span>
+                        <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || $t('td.td140') }}</span>
                     </template>
                     <template slot-scope="{ row }" slot="action">
-                        <span :style="{color:row.tmdid ? '#19be6b':'#ed4014'}">{{row.tmdid ? '已绑定' : '未绑定'}}</span>
+                        <span :style="{color:row.tmdid ? '#19be6b':'#ed4014'}">{{row.tmdid ? $t('td.td176') : $t('td.td177')}}</span>
                     </template>
                 </Table>
                 <Table v-else :columns="columns1" :data="joinTeachers" @on-selection-change="selection=>{ removes = selection}" :loading="loading">
@@ -46,10 +46,10 @@
                         <PersonalPhoto :name="row.name" :picture="row.picture" />
                     </template>
                     <template slot-scope="{ row }" slot="role">
-                        <span :style="{color:row.tag == 'leader' ? '#2d8cf0' : ''}">{{row.tag == 'leader' ? '组长' : '组员'}}</span>
+                        <span :style="{color:row.tag == 'leader' ? '#2d8cf0' : ''}">{{row.tag == 'leader' ? $t('td.td174') : $t('td.td175')}}</span>
                     </template>
                     <template slot-scope="{ row }" slot="groupName">
-                        <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || '未设置' }}</span>
+                        <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || $t('td.td140') }}</span>
                     </template>
                     <template slot-scope="{ row,index }" slot="action">
                         <Icon type="md-remove-circle" class="tool-btn" @click="removeTeacher(index)" />
@@ -69,7 +69,7 @@
                         <Icon type="md-close" :color="item.groupName ?  '' : '#fff'" class="close-group-icon" @click="delGroup(index)" />
                     </div>
                     <div class="add-member-wrap" @click="showAddMember(item)">
-                        <span>添加成员</span>
+                        <span>{{$t('td.td178')}}</span>
                     </div>
                     <div class="list-box">
                         <vuescroll>
@@ -79,8 +79,8 @@
                                     <span>{{'('+tItem.id+')'}}</span>
                                     <Icon class="leader-tag" v-show="tItem.tag === 'leader'" custom="iconfont icon-is-leader" color="#ffffff" />
                                     <span class="set-leader">
-                                        <Icon v-if="tItem.tag != 'leader'" custom="iconfont icon-is-leader" title="设为组长" @click="setIsLeader('leader',tItem.id)" color="#2db7f5" />
-                                        <Icon v-else custom="iconfont icon-cancel-leader" title="取消组长" @click="setIsLeader('',tItem.id)" color="#ffffff" />
+                                        <Icon v-if="tItem.tag != 'leader'" custom="iconfont icon-is-leader" :title="$t('td.td179')" @click="setIsLeader('leader',tItem.id)" color="#2db7f5" />
+                                        <Icon v-else custom="iconfont icon-cancel-leader" :title="$t('td.td180')" @click="setIsLeader('',tItem.id)" color="#ffffff" />
                                     </span>
                                 </div>
                                 <!-- <EmptyData :textContent="$t('cusMgt.noStu')" v-if="item.teachers.length == 0"></EmptyData> -->
@@ -96,17 +96,17 @@
             </vuescroll>
         </div>
         <!-- 未对接省平台添加教师 -->
-        <Modal v-model="addStatus" title="添加教师" @on-ok="confirmAdd" :width="1000" @on-cancel="$refs['selectTeacher'].selectAll(false)">
+        <Modal v-model="addStatus" :title="$t('td.td173')" @on-ok="confirmAdd" :width="1000" @on-cancel="$refs['selectTeacher'].selectAll(false)">
             <div class="filter-box">
-                教研组
-                <Select :max-tag-count="2" v-model="filter.groups" style="width:200px" multiple placeholder="教研组筛选">
+                {{$t('td.td138')}}
+                <Select :max-tag-count="2" v-model="filter.groups" style="width:200px" multiple :placeholder="$t('td.td139')">
                     <Option v-for="item in researches" :value="item.id" :key="item.id">{{ item.name }}</Option>
                 </Select>
                 <!-- <Input v-model="filter.keyword" search placeholder="搜索" style="margin-left:20px;width:200px" /> -->
             </div>
             <Table ref="selectTeacher" :columns="columns2" :height="600" :data="teacherShow" @on-selection-change="selection=>{ selections = selection}">
                 <template slot-scope="{ row }" slot="groupName">
-                    <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || '未设置' }}</span>
+                    <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || $t('td.td140') }}</span>
                 </template>
                 <template slot-scope="{ row }" slot="picture">
                     <PersonalPhoto :name="row.name" :picture="row.picture" />
@@ -114,17 +114,17 @@
             </Table>
         </Modal>
         <!-- 分组视图组别添加教师 -->
-        <Modal v-model="addMenberStatus" title="添加成员" @on-ok="groupAddMember" :width="1000" @on-cancel="$refs['selectTeacher'].selectAll(false)">
-            <Input v-model="searchText" suffix="ios-search" placeholder="搜索" style="width: 240px;margin-bottom:10px" />
+        <Modal v-model="addMenberStatus" :title="$t('td.td178')" @on-ok="groupAddMember" :width="1000" @on-cancel="$refs['selectTeacher'].selectAll(false)">
+            <Input v-model="searchText" suffix="ios-search" ::placeholder="$t('td.td88')" style="width: 240px;margin-bottom:10px" />
             <Table ref="addMember" :columns="memberColumn" :height="600" :data="memberDataShow" @on-selection-change="selection=>{ selections = selection}">
                 <template slot-scope="{ row }" slot="picture">
                     <PersonalPhoto :name="row.name || row.teacherName" :picture="row.picture" />
                 </template>
                 <template slot-scope="{ row }" slot="role">
-                    <span :style="{color:row.tag == 'leader' ? '#2d8cf0' : ''}">{{row.tag == 'leader' ? '组长' : '组员'}}</span>
+                    <span :style="{color:row.tag == 'leader' ? '#2d8cf0' : ''}">{{row.tag == 'leader' ? $t('td.td174') : $t('td.td175')}}</span>
                 </template>
                 <template slot-scope="{ row }" slot="groupName">
-                    <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || '未设置' }}</span>
+                    <span :style="{color: row.groupName ? '':'red'}">{{ row.groupName || $t('td.t140') }}</span>
                 </template>
                 <template slot-scope="{ row,index }" slot="action">
                     <Icon type="md-remove-circle" class="tool-btn" @click="removeTeacher(index)" />
@@ -175,7 +175,7 @@ export default {
                     slot: 'picture'
                 },
                 {
-                    title: '姓名',
+                    title: this.$t('td.td95'),
                     key: 'name'
                 },
                 {
@@ -183,7 +183,7 @@ export default {
                     key: 'id'
                 },
                 {
-                    title: '组别',
+                    title: this.$t('td.td96'),
                     slot: 'groupName',
                     key: 'groupName',
                     // sortable: true,
@@ -193,7 +193,7 @@ export default {
                     // }
                 },
                 {
-                    title: '身份',
+                    title: this.$t('td.td181'),
                     slot: 'role'
                 },
                 {
@@ -207,7 +207,7 @@ export default {
                     slot: 'picture'
                 },
                 {
-                    title: '姓名',
+                    title: this.$t('td.td95'),
                     key: 'teacherName'
                 },
                 // {
@@ -220,7 +220,7 @@ export default {
                     // align:'center'
                 },
                 {
-                    title: '组别',
+                    title: this.$t('td.td96'),
                     slot: 'groupName',
                     key: 'groupName',
                     sortable: true,
@@ -234,7 +234,7 @@ export default {
                     }
                 },
                 {
-                    title: '状态',
+                    title: this.$t('td.td182'),
                     slot: 'action'
                 }
             ],
@@ -248,7 +248,7 @@ export default {
                     slot: 'picture'
                 },
                 {
-                    title: '姓名',
+                    title: this.$t('td.td95'),
                     key: 'name'
                 },
                 {
@@ -256,7 +256,7 @@ export default {
                     key: 'id'
                 },
                 {
-                    title: '教研组',
+                    title: this.$t('td.td138'),
                     key: 'groupName',
                     slot: 'groupName',
                     sortable: true
@@ -279,7 +279,6 @@ export default {
                         }
                     })
                 })
-                console.log('初始化数据', this.teachers)
                 return this.teachers
             } else {
                 []
@@ -389,21 +388,21 @@ export default {
                 res => {
                     if (res.list) {
                         this.trainList.id = res.list?.id
-                        this.$Message.success('设置成功')
+                        this.$Message.success(this.$t('td.td183'))
                     } else {
-                        this.$Message.error('设置失败')
+                        this.$Message.error(this.$t('td.td184'))
                     }
                 },
                 err => {
-                    this.$Message.error('设置失败')
+                    this.$Message.error(this.$t('td.td184'))
                 }
             )
         },
         delGroup(index) {
             let length = this.groupData.length
             this.$Modal.confirm({
-                title: '删除组别',
-                content: length > 1 ? '删除组别后,当前组的老师将默认被分配到相邻组别,确认删除吗?' : '确认删除所有分组吗?',
+                title: this.$t('td.td185'),
+                content: length > 1 ? this.$t('td.td186') : this.$t('td.td187'),
                 onOk: () => {
                     let newIndex = 0
                     if (length > 1) {
@@ -437,14 +436,14 @@ export default {
             // 检查是否有未设置组名的学员
             let check = this.trainList.members.every(item => item.groupId && item.groupName)
             if (!check) {
-                this.$Message.warning('请设置所有组名')
+                this.$Message.warning(this.$t('td.td188'))
                 return
             }
             this.$api.common.upsertGroupInfo(this.trainList).then(
                 res => {
                     if (res.list) {
                         this.trainList.id = res.list?.id
-                        this.$Message.success('保存成功')
+                        this.$Message.success(this.$t('td.td189'))
                         this.isUpdGroup = false
                         if (this.isProvince) {
                             let ts = this.trainList.members
@@ -457,11 +456,11 @@ export default {
                             })
                         }
                     } else {
-                        this.$Message.error('保存失败')
+                        this.$Message.error(this.$t('td.td190'))
                     }
                 },
                 err => {
-                    this.$Message.error('保存失败')
+                    this.$Message.error(this.$t('td.td190'))
                 }
             )
         },
@@ -499,13 +498,13 @@ export default {
         addGroup() {
             //检查是否输入
             if (!this.groupName) {
-                this.$Message.warning('请输入组名再添加组别')
+                this.$Message.warning(this.$t('td.td191'))
                 return
             }
             //检查重复
             let names = this.groupData.map(item => item.groupName)
             if (names.includes(this.groupName)) {
-                this.$Message.warning('组名重复')
+                this.$Message.warning(this.$t('td.td192'))
                 return
             }
 
@@ -528,12 +527,12 @@ export default {
         },
         rmvBatch() {
             if (!this.removes.length) {
-                this.$Message.warning('请选择需要移除的老师')
+                this.$Message.warning(this.$t('td.td193'))
                 return
             }
             this.$Modal.confirm({
-                title: '批量移除',
-                content: `确认批量移除${this.removes.length}个参训老师吗?`,
+                title: this.$t('td.td194'),
+                content: `${this.$t('td.td195')}${this.removes.length}${this.$t('td.td196')}`,
                 onOk: () => {
                     let ids = this.removes.map(item => item.id)
                     for (let i = 0; i < this.trainList.members.length; i++) {
@@ -545,14 +544,14 @@ export default {
                     this.$api.common.upsertGroupInfo(this.trainList).then(
                         res => {
                             if (res.list) {
-                                this.$Message.success('移除成功')
+                                this.$Message.success(this.$t('td.td197'))
                                 this.removes = []
                             } else {
-                                this.$Message.error('移除失败')
+                                this.$Message.error(this.$t('td.td198'))
                             }
                         },
                         err => {
-                            this.$Message.error('移除失败')
+                            this.$Message.error(this.$t('td.td198'))
                         }
                     )
                 }
@@ -560,20 +559,20 @@ export default {
         },
         removeTeacher(index) {
             this.$Modal.confirm({
-                title: '移除参训老师',
-                content: `确认移除${this.trainList.members[index].name}吗?`,
+                title: this.$t('td.td199'),
+                content: `${this.$t('td.td200')}${this.trainList.members[index].name}?`,
                 onOk: () => {
                     this.trainList.members.splice(index, 1)
                     this.$api.common.upsertGroupInfo(this.trainList).then(
                         res => {
                             if (res.list) {
-                                this.$Message.success('移除成功')
+                                this.$Message.success(this.$t('td.td197'))
                             } else {
-                                this.$Message.error('移除失败')
+                                this.$Message.error(this.$t('td.td198'))
                             }
                         },
                         err => {
-                            this.$Message.error('移除失败')
+                            this.$Message.error(this.$t('td.td198'))
                         }
                     )
                 }
@@ -651,7 +650,7 @@ export default {
             else {
                 this.trainList.code = this.$store.state.userInfo.schoolCode
                 this.trainList.scope = 'school'
-                this.trainList.name = '研修名单'
+                this.trainList.name = this.$t('td.td201')
                 this.trainList.school = this.$store.state.userInfo.schoolCode
                 this.trainList.type = 'yxtrain'
                 this.selections.forEach(item => {
@@ -663,13 +662,13 @@ export default {
                 res => {
                     if (res.list) {
                         this.trainList.id = res.list.id
-                        this.$Message.success('添加成功')
+                        this.$Message.success(this.$t('td.td202'))
                     } else {
-                        this.$Message.error('保存研修名单失败')
+                        this.$Message.error(this.$t('td.td203'))
                     }
                 },
                 err => {
-                    this.$Message.error('保存研修名单失败')
+                    this.$Message.error(this.$t('td.td203'))
                 }
             )
             this.$refs['selectTeacher'].selectAll(false)
@@ -698,14 +697,14 @@ export default {
                         // this.$Message.warning('暂未添加参训教师名单')
                         this.trainList.code = this.$store.state.userInfo.schoolCode
                         this.trainList.scope = 'school'
-                        this.trainList.name = '研修名单'
+                        this.trainList.name = this.$t('td.td201')
                         this.trainList.school = this.$store.state.userInfo.schoolCode
                         this.trainList.type = 'yxtrain'
                         this.trainList.members = []
                     }
                 },
                 err => {
-                    this.$Message.error('查询研修名单失败')
+                    this.$Message.error(this.$t('td.td204'))
                 }
             )
         },
@@ -721,61 +720,51 @@ export default {
                     if (res.groups) {
                         this.researches = res.groups
                     } else {
-                        this.$Message.warning('查询教研组失败')
+                        this.$Message.warning(this.$t('td.td141'))
                     }
                 },
                 err => {
-                    this.$Message.error('查询教研组失败')
+                    this.$Message.error(this.$t('td.td141'))
                 }
             )
         },
         //查询学校所有老师
         getTeacherAll() {
-            this.$store.dispatch('user/getSchoolTeacher').then(
-                res => {
-                    console.log(res)
-                    if (res.code == 0) {
-                        this.$Message.error('無法取得使用者資料')
+            this.$store.dispatch('user/getSchoolTeacher')
+        },
+        watch: {
+            joinTeachers: {
+                handler(n, o) {
+                    let data = []
+                    let groupRes = this.$jsFn.groupBy(this.joinTeachers, 'groupId')
+                    for (let index in groupRes) {
+                        data.push({
+                            groupName: groupRes[index][0].groupName,
+                            groupId: groupRes[index][0].groupId,
+                            teachers: groupRes[index]
+                        })
                     }
+                    // data.sort((a, b) => {
+                    //     return a.groupName.localeCompare(b.groupName)
+                    // })
+                    console.log(this.emptyGroup)
+                    this.groupData = data
+                    this.groupData.push(...this.emptyGroup)
                 },
-                err => {
-                    this.$Message.error('查询学校教师列表失败')
-                }
-            )
-        }
-    },
-    watch: {
-        joinTeachers: {
-            handler(n, o) {
-                let data = []
-                let groupRes = this.$jsFn.groupBy(this.joinTeachers, 'groupId')
-                for (let index in groupRes) {
-                    data.push({
-                        groupName: groupRes[index][0].groupName,
-                        groupId: groupRes[index][0].groupId,
-                        teachers: groupRes[index]
-                    })
-                }
-                // data.sort((a, b) => {
-                //     return a.groupName.localeCompare(b.groupName)
-                // })
-                console.log(this.emptyGroup)
-                this.groupData = data
-                this.groupData.push(...this.emptyGroup)
-            },
-            deep: true,
-            immediate: true
-        }
-    },
-    created() {
+                deep: true,
+                immediate: true
+            }
+        },
+        created() {
 
-    },
-    mounted() {
-        this.isProvince = sessionStorage.getItem('areaAccess') && sessionStorage.getItem('areaAccess') == 1
-        if (this.isProvince) {
-            this.getProvTeacherList()
-        } else {
-            this.getTrainList()
+        },
+        mounted() {
+            this.isProvince = sessionStorage.getItem('areaAccess') && sessionStorage.getItem('areaAccess') == 1
+            if (this.isProvince) {
+                this.getProvTeacherList()
+            } else {
+                this.getTrainList()
+            }
         }
     }
 }

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

@@ -228,6 +228,7 @@ namespace TEAMModelOS.Controllers.Client
                 //開課記錄保存
                 LessonRecord lr = new()
                 {
+                    school = request.sp.Equals("school") ? request?.school : null,
                     code = request.sp.Equals("school") ? $"LessonRecord-{request.school}" : $"LessonRecord",
                     id = _snowflakeId.NextId().ToString(),  //取得授課ID
                     courseId = request.cid,

+ 3 - 2
TEAMModelOS/Controllers/Client/HiTeachccControlller.cs

@@ -191,7 +191,7 @@ namespace TEAMModelOS.Controllers.Client
                 //觸發IMEI更新消息
                 var stus = students.Select(x => x.id).ToList();
                 var imeimsg = new ServiceBusMessage(new { request.channel, userid = tid, request.school, stus }.ToJsonString());
-                imeimsg.ApplicationProperties.Add("name", "imei");
+                imeimsg.ApplicationProperties.Add("name", "Imei");
                 sbm.Add(imeimsg);
 
                 //取得學校或個人資源
@@ -215,6 +215,7 @@ namespace TEAMModelOS.Controllers.Client
                 //開課記錄保存
                 LessonRecord lr = new()
                 {
+                    school = request.sp.Equals("school") ? request?.school : null,
                     code = request.sp.Equals("school") ? $"LessonRecord-{request.school}" : $"LessonRecord",
                     id = _snowflakeId.NextId().ToString(),  //取得授課ID
                     courseId = request.cid,
@@ -233,7 +234,7 @@ namespace TEAMModelOS.Controllers.Client
                 sbm.Add(messageChange);
 
                 //批量發送消息
-                await _serviceBus.GetServiceBusClient().SendBatchMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), sbm);
+                var s = await _serviceBus.GetServiceBusClient().SendBatchMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), sbm);
 
                 return Ok(new { status = 200, lr.id, client, students, res, size, usize, uri, sas });
             }

+ 3 - 3
TEAMModelOS/Controllers/OpenApi/Business/BizLessonRecordController.cs

@@ -48,9 +48,9 @@ namespace TEAMModelOS.Controllers
             var responseData = await OpenApiService.GetLessonRecord(_azureCosmos,   _configuration,   _serviceBus,
              _option,  _dingDing, id, school, json);
             return Ok(new { responseData });
-        }  
+        }
         /// <summary>
-        /// 获取开课/课例记录
+        /// 获取开课/课例记录数量
         /// </summary>
         /// <param name="json"></param>
         /// <returns></returns>
@@ -60,7 +60,7 @@ namespace TEAMModelOS.Controllers
         public async Task<IActionResult> GetLessonRecordCount(JsonElement json)
         {
             var (id, school) = HttpContext.GetApiTokenInfo();
-            var responseData = await OpenApiService.GetLessonRecord(_azureCosmos, _configuration, _serviceBus,
+            var responseData = await OpenApiService.GetLessonRecordCount(_azureCosmos, _configuration, _serviceBus,
              _option, _dingDing, id, school, json);
             return Ok(new { responseData });
         }

+ 139 - 1
TEAMModelOS/Controllers/OpenApi/OpenApiService.cs

@@ -74,7 +74,143 @@ namespace TEAMModelOS.Controllers
                 return new ResponseData<List<OSchool>>() { code = RespondCode.Error, msg = "服务器错误" };
             }
         }
+        /// <summary>
+        /// josn:
+        /// {
+        ///     "roles":"",
+        ///     "scope":""
+        ///     "pageCount":"",
+        ///     "DESC":"",
+        ///     "ASC":"",
+        ///     "continuationToken":"",
+        ///     "school":"",
+        ///     "tmdid":""
+        /// }
+        /// </summary>
+        /// <param name="azureCosmos"></param>
+        /// <param name="dingDing"></param>
+        /// <param name="id"></param>
+        /// <param name="school"></param>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        /// <exception cref="NotImplementedException"></exception>
+        public static async Task<ResponseData<dynamic>> GetLessonRecordCount(AzureCosmosFactory _azureCosmos, IConfiguration _configuration, AzureServiceBusFactory _serviceBus,
+           Option _option, DingDing _dingDing, string id, string school, JsonElement json)
+        {
+            json.TryGetProperty("roles", out JsonElement _roles);
+            List<string> roles = new List<string>();
+            if (_roles.ValueKind.Equals(JsonValueKind.Array))
+            {
+                roles = _roles.ToJsonString().ToObject<List<string>>();
+            }
+            json.TryGetProperty("managePage", out JsonElement _managePage);
+            bool managePage = false;
+            if (_managePage.ValueKind.Equals(JsonValueKind.True))
+            {
+                managePage = true;
+            }
+            StringBuilder sql = new StringBuilder();
+            sql.Append("select c.id,c.groupIds,c.courseId from c   ");
+            Dictionary<string, object> dict = LessonService.GetLessonCond(json);
+            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
+            string tbname = "";
+            string code = "";
+           
+            List<string> autoTch = new List<string>();
+            string sqlPrivate = "";
+            code = $"LessonRecord-{school}";
+            tbname = "School";
+            List<string> ids = new List<string>();
+            //只查询某个老师的课例
+            if (json.TryGetProperty("tmdid", out JsonElement tmdid) && !string.IsNullOrWhiteSpace($"{tmdid}"))
+            {
+                ids.Add($"{tmdid}");
+            }
+            else
+            {
+                string sqltch = "select distinct value(c.id) from c ";
+                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
+                    .GetItemQueryIterator<string>(queryText: sqltch, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Teacher-{school}") }))
+                {
+                    ids.Add(item);
+                }
+            }
+            if (ids.Any())
+            {
+                string sqlTechbase = $"select distinct value(c.id) from c  where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})  and (array_contains(c.lessonShow,'student') or array_contains(c.lessonShow,'all')) ";
+                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                   .GetItemQueryIterator<string>(queryText: sqlTechbase, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base") }))
+                {
+                    autoTch.Add(item);
+                }
+            }
+            int count = 0;
+
+            string sqlShow = "";
+            if (roles.Count == 1 && roles.Contains("student"))
+            {
+                string autoSql = "";
+                if (autoTch.Any())
+                {
+                    autoSql = $" or c.tmdid in ({string.Join(",", autoTch.Select(x => $"'{x}'"))})";
+                }
+                sqlShow = $" and (array_contains(c.show,'student') or array_contains(c.show,'all')  {autoSql} ) ";
+            }
+            string sql_status_managePage = " (c.status<>404 or IS_DEFINED(c.status) = false ) and ";
+            if (managePage)
+            {
+                sql_status_managePage = "";
+            }
+            cosmosDbQuery.QueryText = cosmosDbQuery.QueryText.Replace("where", $" where {sql_status_managePage} array_length(c.groupIds)>0 {sqlPrivate} {sqlShow}  and  ");
+            List<LessonRecord> records = new List<LessonRecord>();
+            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetItemQueryIterator<LessonRecord>(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(code) }))
+            {
+                records.Add(item);
+            }
+            if (records.Any())
+            {
+                var groupIds = records.SelectMany(x => x.groupIds).ToHashSet();
+                if (groupIds.Any())
+                {
+                    var groups = await GroupListService.GetGroupListListids(_azureCosmos.GetCosmosClient(), _dingDing, groupIds.ToList(), school, " c.id ");
+                    //获取已经被删除的名单。
+                    var idsExp = groupIds.Except(groups.Select(x => x.id));
+                    if (idsExp.Any())
+                    {
+
 
+                        foreach (var item in records)
+                        {
+                            int countRmv = item.groupIds.RemoveAll(x => idsExp.Contains(x));
+                            if (countRmv > 0)
+                            {
+                                try
+                                {
+                                    LessonRecord record = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<LessonRecord>(item.id, new PartitionKey(code));
+                                    record.groupIds = item.groupIds;
+                                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReplaceItemAsync<LessonRecord>(record, item.id, new PartitionKey(code));
+                                }
+                                catch (CosmosException ex) when (ex.Status == 404)
+                                {
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            count = records.Count;
+            ResponseData<dynamic> resDate = new ResponseData<dynamic>
+            {
+                code = RespondCode.Ok,
+                msg = "成功",
+                data = new
+                {
+                    count = count,
+                }
+            };
+            return resDate;
+        }
         /// <summary>
         /// josn:
         /// {
@@ -262,7 +398,9 @@ namespace TEAMModelOS.Controllers
                         x.groupNames = groupNmae;
                     });
                 }
-                ResponseData<dynamic> resDate = new ResponseData<dynamic> { code= RespondCode.Ok,msg="成功", data =new  { currCount = lessonRecords.Count, continuationToken, lessonRecords } };
+                ResponseData<dynamic> resDate = new ResponseData<dynamic> { code= RespondCode.Ok,msg="成功", data =new  { currCount = lessonRecords.Count, continuationToken,
+                    lessonRecords=  lessonRecords.Select(x => new { x.tmdid, x.tmdname, x.tmdpicture, x.name, x.school, x.startTime, x.duration, x.courseId, x.groupIds, x.periodId, x.subjectId, x.grade, x.id, x.category })
+                } };
                 return resDate;
             }
             catch (Exception)

+ 1 - 0
TEAMModelOS/Controllers/Third/Xkw/Sdk/XkwAPIHttpService.cs

@@ -62,6 +62,7 @@ namespace TEAMModelOS.Controllers.Third.Xkw.Sdk
             string RowKey = $"xkw-{domain}";
             List<OAuthComConfig> configs =   table.FindListByDictSync<OAuthComConfig>(new Dictionary<string, object>() { { "PartitionKey", "OAuthComConfig" }, { "RowKey", RowKey } });
             if (configs.Any()) {
+
                 this.baseUrl = configs[0].ApiUrl;
                 this.appId = configs[0].ApiKey;
                 this.secret = configs[0].ApiSecret;

+ 269 - 244
TEAMModelOS/Controllers/Third/Xkw/XkwServiceController.cs

@@ -130,145 +130,258 @@ namespace TEAMModelOS.Controllers.Third.Xkw
         [Authorize(Roles = "IES")]
         [AuthToken(Roles = "teacher,admin,area,student")]
 #endif
-        public async Task<IActionResult> GetPaperItems(JsonElement json)
+        public  async Task<IActionResult>  GetPaperItems(JsonElement json)
         {
-            if (!json.TryGetProperty("paperid", out JsonElement paperid)) { return BadRequest(); }
-            if (!json.TryGetProperty("openid", out JsonElement openid)) { return BadRequest(); }
-            Dictionary<string, string> dict = new Dictionary<string, string>() { { "id", $"{paperid}" }, { "user_id", $"{openid}" } };
-            var paper = _xkwAPIHttpService.Get<JsonElement>("/xopqbm/zj-saas/users/download-papers/details", dict);
-            List<XkwItem> items = new List<XkwItem>();
-            string ps = paper.ToJsonString();
-            XkwDto course = null ;
-            List<XkwPaperPart> xkwPapers = new List<XkwPaperPart>();
-            if (paper.TryGetProperty("code", out JsonElement code) && $"{code}".Equals("2000000"))
+            try
             {
-                
-                    if (paper.TryGetProperty("data", out JsonElement data)  &&  data.TryGetProperty("course_id", out JsonElement course_id)) {
-                    course =  XkwConstant.xkwCourses.Find(x => $"{course_id}".Equals($"{x.id}"));
-                    if (course != null) {
-                        if (data.TryGetProperty("body", out JsonElement body)) {
-                            List<XkwPaperPart> paperParts = body.ToObject<List<XkwPaperPart>>();
-                            xkwPapers.AddRange(paperParts);
-                            items.AddRange(paperParts.SelectMany(x => x.part_body).SelectMany(z=>z.questions));
+                if (!json.TryGetProperty("paperid", out JsonElement paperid)) { return BadRequest(); }
+                if (!json.TryGetProperty("openid", out JsonElement openid)) { return BadRequest(); }
+                Dictionary<string, string> dict = new Dictionary<string, string>() { { "id", $"{paperid}" }, { "user_id", $"{openid}" } };
+                var paper = _xkwAPIHttpService.Get<JsonElement>("/xopqbm/zj-saas/users/download-papers/details", dict);
+                List<XkwItem> items = new List<XkwItem>();
+                string ps = paper.ToJsonString();
+                XkwDto course = null;
+                List<XkwPaperPart> xkwPapers = new List<XkwPaperPart>();
+                if (paper.TryGetProperty("code", out JsonElement code) && $"{code}".Equals("2000000"))
+                {
+
+                    if (paper.TryGetProperty("data", out JsonElement data) && data.TryGetProperty("course_id", out JsonElement course_id))
+                    {
+                        course = XkwConstant.xkwCourses.Find(x => $"{course_id}".Equals($"{x.id}"));
+                        if (course != null)
+                        {
+                            if (data.TryGetProperty("body", out JsonElement body))
+                            {
+                                List<XkwPaperPart> paperParts = body.ToObject<List<XkwPaperPart>>();
+                                xkwPapers.AddRange(paperParts);
+                                items.AddRange(paperParts.SelectMany(x => x.part_body).SelectMany(z => z.questions));
+                            }
                         }
                     }
                 }
-            }
-            List<XkwItemInfo> itemInfos = new List<XkwItemInfo>();
-            List<XkwDto> xkw_points = new List<XkwDto>();
-            var kpoint_ids=items.SelectMany(x => x.kpoint_ids).ToHashSet();
-            if (kpoint_ids.Any()) {
-                Dictionary<string, string> dict_pointids = new Dictionary<string, string>() { { "ids", String.Join(",", kpoint_ids.Select(x => x)) } };
-                var points = _xkwAPIHttpService.Get<JsonElement>("/xopqbm/knowledge-points", dict_pointids);
+                List<XkwItemInfo> itemInfos = new List<XkwItemInfo>();
+                List<XkwDto> xkw_points = new List<XkwDto>();
+                var kpoint_ids = items.SelectMany(x => x.kpoint_ids).ToHashSet();
+                if (kpoint_ids.Any())
+                {
+                    Dictionary<string, string> dict_pointids = new Dictionary<string, string>() { { "ids", String.Join(",", kpoint_ids.Select(x => x)) } };
+                    var points = _xkwAPIHttpService.Get<JsonElement>("/xopqbm/knowledge-points", dict_pointids);
 
-                if (points.TryGetProperty("code", out JsonElement pcode) && $"{pcode}".Equals("2000000")) {
-                    if (points.TryGetProperty("data", out JsonElement pdata)) {
-                        xkw_points = pdata.ToObject<List<XkwDto>>();
+                    if (points.TryGetProperty("code", out JsonElement pcode) && $"{pcode}".Equals("2000000"))
+                    {
+                        if (points.TryGetProperty("data", out JsonElement pdata))
+                        {
+                            xkw_points = pdata.ToObject<List<XkwDto>>();
+                        }
                     }
                 }
-            }
-            int index = 1;
-            items.ForEach(x => {
-                //x.kpoint_ids
-                //设置默认难度,和默认认知层次
-                int field = 1;
-                int level = 3;
-                List<string> gradeNames = new List<string>();
-                List<string> knowledge = new List<string>();
-                bool objective = false;
-                string tag = "";
-                foreach (var difct in XkwConstant.xkwDifficulties)
-                {
-                    if (x.difficulty < difct.ceiling && x.difficulty >= difct.flooring)
+                int index = 1;
+                items.ForEach(x => {
+                    //x.kpoint_ids
+                    //设置默认难度,和默认认知层次
+                    int field = 1;
+                    int level = 3;
+                    List<string> gradeNames = new List<string>();
+                    List<string> knowledge = new List<string>();
+                    bool objective = false;
+                    string tag = "";
+                    foreach (var difct in XkwConstant.xkwDifficulties)
                     {
-                        level = difct.level;
+                        if (x.difficulty < difct.ceiling && x.difficulty >= difct.flooring)
+                        {
+                            level = difct.level;
+                        }
                     }
-                }
-                var grades = XkwConstant.xkwGrades.FindAll(g => x.grade_ids.Contains(g.id));
-                if (grades.Any())
-                {
-                    gradeNames = grades.Select(g => g.name).ToList();
-                }
-                if (x.kpoint_ids.Any())
-                {
-                    var points = xkw_points.FindAll(p => x.kpoint_ids.Contains(p.id));
-                    if (points.Any())
+                    var grades = XkwConstant.xkwGrades.FindAll(g => x.grade_ids.Contains(g.id));
+                    if (grades.Any())
                     {
+                        gradeNames = grades.Select(g => g.name).ToList();
+                    }
+                    if (x.kpoint_ids.Any())
+                    {
+                        var points = xkw_points.FindAll(p => x.kpoint_ids.Contains(p.id));
+                        if (points.Any())
+                        {
 
-                        knowledge.AddRange(points.Select(x => x.name));
+                            knowledge.AddRange(points.Select(x => x.name));
+                        }
                     }
-                }
-                var type = XkwConstant.xkwQuestionTypes.Find(t => t.id == x.type_id);
-                //判断是否 主客观题
-                if (type != null)
-                {
-                   objective = type.objective;
-                   tag = type.name;
-                }
-                else
-                {
-                   objective = false;
-                }
-                string classpattern = "class=\"([^\"]*)\"";
-                string pattern = "<span([^>]{0,})>";
-                string table_pattern = "<table([^>]{0,})>";
-                string apattern = "<a([^>]{0,})></a>";
+                    var type = XkwConstant.xkwQuestionTypes.Find(t => t.id == x.type_id);
+                    //判断是否 主客观题
+                    if (type != null)
+                    {
+                        objective = type.objective;
+                        tag = type.name;
+                    }
+                    else
+                    {
+                        objective = false;
+                    }
+                    string classpattern = "class=\"([^\"]*)\"";
+                    string pattern = "<span([^>]{0,})>";
+                    string table_pattern = "<table([^>]{0,})>";
+                    string apattern = "<a([^>]{0,})></a>";
 
 
-                string rg_qml_sq = "<div[^>]{0,}\\s*qml-sq[^>]{0,}>";
-                //string stem = x.stem.Replace("</table>", "");
-                string[] questiones = Regex.Split(x.stem, rg_qml_sq);
-                string rg_qml_an_sq = "\\d+\\s*\\.\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>" +
-                "|(\\d+\\s*)\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>" +
-                "|\\d+\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>" +
-                "|(\\d+\\s*)\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>";
-                var answers = Regex.Split(x.answer, rg_qml_an_sq);
-                string rg_qml_exps_sq = "<div[^>]{0,}\\s*exps-sq[^>]{0,}>";
-                var explains = Regex.Split(x.explanation, rg_qml_exps_sq);
-                if (questiones.Length > 1)
-                {
-                    index += 1;
-                    XkwItemInfo itemInfo = new XkwItemInfo
+                    string rg_qml_sq = "<div[^>]{0,}\\s*qml-sq[^>]{0,}>";
+                    //string stem = x.stem.Replace("</table>", "");
+                    string[] questiones = Regex.Split(x.stem, rg_qml_sq);
+                    string rg_qml_an_sq = "\\d+\\s*\\.\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>" +
+                    "|(\\d+\\s*)\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>" +
+                    "|\\d+\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>" +
+                    "|(\\d+\\s*)\\s*<span[^>]{0,}\\s*qml-an-sq[^>]{0,}>";
+                    var answers = Regex.Split(x.answer, rg_qml_an_sq);
+                    string rg_qml_exps_sq = "<div[^>]{0,}\\s*exps-sq[^>]{0,}>";
+                    var explains = Regex.Split(x.explanation, rg_qml_exps_sq);
+                    if (questiones.Length > 1)
                     {
-                        source = 3,
-                        shaCode = ShaHashHelper.GetSHA1(x.stem),
-                        id = x.id,
-                        order = index,
-                        subjectName = course?.subject_name,
-                        periodName = course?.stage_name,
-                        field = field,
-                        level = level,
-                        gradeNames = gradeNames,
-                        knowledge = knowledge,
-                        objective = objective,
-                        tag = tag,
-                        question = questiones[0],
-                        type = "compose",
-                    };
-                    itemInfos.Add(itemInfo);
-                    for (int i = 1; i < questiones.Length; i++) {
                         index += 1;
-                        XkwItemInfo child_itemInfo = new XkwItemInfo
+                        XkwItemInfo itemInfo = new XkwItemInfo
+                        {
+                            source = 3,
+                            shaCode = ShaHashHelper.GetSHA1(x.stem),
+                            id = x.id,
+                            order = index,
+                            subjectName = course?.subject_name,
+                            periodName = course?.stage_name,
+                            field = field,
+                            level = level,
+                            gradeNames = gradeNames,
+                            knowledge = knowledge,
+                            objective = objective,
+                            tag = tag,
+                            question = questiones[0],
+                            type = "compose",
+                        };
+                        itemInfos.Add(itemInfo);
+                        for (int i = 1; i < questiones.Length; i++)
+                        {
+                            index += 1;
+                            XkwItemInfo child_itemInfo = new XkwItemInfo
+                            {
+                                pid = x.id,
+                                source = 3,
+                                id = $"{x.id}-{i}",
+                                order = index,
+                                subjectName = course?.subject_name,
+                                periodName = course?.stage_name,
+                                field = field,
+                                level = level,
+                                gradeNames = gradeNames,
+                                knowledge = knowledge,
+                                objective = objective,
+                                tag = "",
+
+                            };
+                            questiones[i] = questiones[i].Replace("<div class=\"qml-stem\"><br/>", "");
+                            if (questiones[i].Contains("qml-og"))
+                            {
+                                child_itemInfo.objective = true;
+                                string shtml = questiones[i];
+                                //去除class 以及span标签"
+                                shtml = Regex.Replace(shtml, table_pattern, "").Replace("</table>", "").Replace("<tr>", "").Replace("<td>", "").Replace("</td>", "").Replace("</tr>", "");
+                                //shtml = Regex.Replace(shtml, classpattern, "");
+                                //shtml = Regex.Replace(shtml, pattern, "");
+                                //shtml = Regex.Replace(shtml, apattern, "");
+                                //shtml = shtml.Replace(" close=\"\" separators=\" | \">", "");
+                                //shtml = shtml.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
+                                //处理 标签中包含的空格字符
+
+                                //处理题干
+                                (List<CodeValue> options, string question) = OptionProcess(shtml);
+                                child_itemInfo.option = options;
+                                child_itemInfo.opts = options.Count;
+                                child_itemInfo.question = question;
+
+
+                                //处理答案
+                                //去除class 以及span标签"
+                                if (answers.Length - 1 >= i)
+                                {
+                                    string ahtml = answers[i];
+                                    ahtml = Regex.Replace(ahtml, classpattern, "");
+                                    ahtml = Regex.Replace(ahtml, pattern, "");
+                                    ahtml = Regex.Replace(ahtml, apattern, "");
+                                    ahtml = ahtml.Replace(" close=\"\" separators=\" | \">", "");
+                                    ahtml = ahtml.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
+                                    HashSet<string> ans = new HashSet<string>();
+                                    var anstr = BlankTag(ahtml);
+                                    for (int idx = 0; idx < 26; idx++)
+                                    {
+                                        anstr = anstr.Replace(aza[idx], azh[idx]);
+                                    }
+
+                                    anstr.Select(s => s.ToString()).ToList().ForEach(x =>
+                                    {
+                                        ans.Add(x);
+                                    });
+                                    child_itemInfo.answerHtml = answers[0];
+                                    child_itemInfo.answer = ans.ToList();
+                                    if (ans.Count > 1)
+                                    {
+                                        child_itemInfo.type = "multiple";
+                                    }
+                                    else
+                                    {
+                                        child_itemInfo.type = "single";
+                                    }
+                                }
+                                //处理解析
+                                if (explains.Length - 1 >= i)
+                                {
+                                    child_itemInfo.explain = explains[i];
+
+                                }
+                            }
+                            else
+                            {
+                                child_itemInfo.type = "subjective";
+                                child_itemInfo.objective = false;
+
+                                if (explains.Length - 1 >= i)
+                                {
+                                    child_itemInfo.explain = explains[i];
+                                }
+                                if (answers.Length - 1 >= i)
+                                {
+                                    child_itemInfo.answer = new List<string> { answers[i] };
+                                }
+                                child_itemInfo.question = questiones[i];
+
+                            }
+
+                            string rg_ques_no = "<span[^>]{0,}\\s*ques-no[^>]{0,}>[\\s\\S]*?</span>";
+                            child_itemInfo.question = Regex.Replace(child_itemInfo.question, rg_ques_no, "");
+                            child_itemInfo.shaCode = ShaHashHelper.GetSHA1(child_itemInfo.question);
+                            itemInfo.children.Add(child_itemInfo);
+                            //itemInfos.Add(child_itemInfo);
+                        }
+                    }
+                    else
+                    {
+                        XkwItemInfo itemInfo = new XkwItemInfo
                         {
-                            pid = x.id,
                             source = 3,
-                            id = $"{x.id}-{i}",
+                            shaCode = ShaHashHelper.GetSHA1(x.stem),
+                            id = x.id,
                             order = index,
+                            explain = x.explanation,
                             subjectName = course?.subject_name,
                             periodName = course?.stage_name,
+                            // explain = x.explanation.Replace("【分析】", "分析:").Replace("【详解】", "详解:")
                             field = field,
                             level = level,
                             gradeNames = gradeNames,
                             knowledge = knowledge,
                             objective = objective,
-                            tag = "",
-                            
+                            tag = tag
                         };
-                        questiones[i]= questiones[i].Replace("<div class=\"qml-stem\"><br/>", "");
-                        if (questiones[i].Contains("qml-og"))
+                        index += 1;
+                        //如果是客观题,则需要处理选项和答案。
+                        if (itemInfo.objective)
                         {
-                            child_itemInfo.objective = true;
-                            string shtml = questiones[i];
+
+                            string shtml = x.stem;
                             //去除class 以及span标签"
                             shtml = Regex.Replace(shtml, table_pattern, "").Replace("</table>", "").Replace("<tr>", "").Replace("<td>", "").Replace("</td>", "").Replace("</tr>", "");
                             //shtml = Regex.Replace(shtml, classpattern, "");
@@ -280,154 +393,66 @@ namespace TEAMModelOS.Controllers.Third.Xkw
 
                             //处理题干
                             (List<CodeValue> options, string question) = OptionProcess(shtml);
-                            child_itemInfo.option = options;
-                            child_itemInfo.opts = options.Count;
-                            child_itemInfo.question = question;
-
+                            itemInfo.option = options;
+                            itemInfo.opts = options.Count;
+                            itemInfo.question = question;
 
                             //处理答案
                             //去除class 以及span标签"
-                            if (answers.Length - 1 >= i) {
-                                string ahtml = answers[i];
-                                ahtml = Regex.Replace(ahtml, classpattern, "");
-                                ahtml = Regex.Replace(ahtml, pattern, "");
-                                ahtml = Regex.Replace(ahtml, apattern, "");
-                                ahtml = ahtml.Replace(" close=\"\" separators=\" | \">", "");
-                                ahtml = ahtml.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
-                                HashSet<string> ans = new HashSet<string>();
-                                var anstr = BlankTag(ahtml);
-                                for (int idx = 0; idx < 26; idx++)
-                                {
-                                    anstr = anstr.Replace(aza[idx], azh[idx]);
-                                }
-
-                                anstr.Select(s => s.ToString()).ToList().ForEach(x =>
-                                {
-                                    ans.Add(x);
-                                });
-                                child_itemInfo.answerHtml = answers[0];
-                                child_itemInfo.answer = ans.ToList();
-                                if (ans.Count > 1)
-                                {
-                                    child_itemInfo.type = "multiple";
-                                }
-                                else
-                                {
-                                    child_itemInfo.type = "single";
-                                }
-                            }
-                            //处理解析
-                            if (explains.Length - 1 >= i)
+                            string ahtml = x.answer;
+                            ahtml = Regex.Replace(ahtml, classpattern, "");
+                            ahtml = Regex.Replace(ahtml, pattern, "");
+                            ahtml = Regex.Replace(ahtml, apattern, "");
+                            ahtml = ahtml.Replace(" close=\"\" separators=\" | \">", "");
+                            ahtml = ahtml.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
+                            HashSet<string> ans = new HashSet<string>();
+                            var anstr = BlankTag(ahtml);
+                            for (int idx = 0; idx < 26; idx++)
                             {
-                                child_itemInfo.explain = explains[i];
-
+                                anstr = anstr.Replace(aza[idx], azh[idx]);
                             }
-                        }
-                        else {
-                            child_itemInfo.type = "subjective";
-                            child_itemInfo.objective = false;
-                           
-                            if (explains.Length - 1 >= i) {
-                                child_itemInfo.explain = explains[i];
+
+                            anstr.Select(s => s.ToString()).ToList().ForEach(x =>
+                            {
+                                ans.Add(x);
+                            });
+                            itemInfo.answerHtml = x.answer;
+                            itemInfo.answer = ans.ToList();
+                            if (ans.Count > 1)
+                            {
+                                itemInfo.type = "multiple";
                             }
-                            if (answers.Length - 1 >= i)
+                            else
                             {
-                                child_itemInfo.answer = new List<string> { answers[i] };
+                                itemInfo.type = "single";
                             }
-                            child_itemInfo.question = questiones[i];
-                          
-                        }
-
-                        string rg_ques_no = "<span[^>]{0,}\\s*ques-no[^>]{0,}>[\\s\\S]*?</span>";
-                        child_itemInfo.question=Regex.Replace(child_itemInfo.question, rg_ques_no,"");
-                        child_itemInfo.shaCode = ShaHashHelper.GetSHA1(child_itemInfo.question);
-                        itemInfo.children.Add(child_itemInfo);
-                        //itemInfos.Add(child_itemInfo);
-                    }
-                }
-                else {
-                    XkwItemInfo itemInfo = new XkwItemInfo
-                    {
-                        source = 3,
-                        shaCode = ShaHashHelper.GetSHA1(x.stem),
-                        id = x.id,
-                        order = index,
-                        explain = x.explanation,
-                        subjectName = course?.subject_name,
-                        periodName = course?.stage_name,
-                        // explain = x.explanation.Replace("【分析】", "分析:").Replace("【详解】", "详解:")
-                        field =field,
-                        level = level,
-                        gradeNames =gradeNames,
-                        knowledge =knowledge,
-                        objective = objective,
-                        tag =tag
-                    };
-                    index += 1;
-                    //如果是客观题,则需要处理选项和答案。
-                    if (itemInfo.objective)
-                    {
-                       
-                        string shtml = x.stem;
-                        //去除class 以及span标签"
-                        shtml = Regex.Replace(shtml, table_pattern, "").Replace("</table>", "").Replace("<tr>", "").Replace("<td>", "").Replace("</td>", "").Replace("</tr>", "");
-                        //shtml = Regex.Replace(shtml, classpattern, "");
-                        //shtml = Regex.Replace(shtml, pattern, "");
-                        //shtml = Regex.Replace(shtml, apattern, "");
-                        //shtml = shtml.Replace(" close=\"\" separators=\" | \">", "");
-                        //shtml = shtml.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
-                        //处理 标签中包含的空格字符
-
-                        //处理题干
-                        (List<CodeValue> options, string question) = OptionProcess(shtml);
-                        itemInfo.option = options;
-                        itemInfo.opts = options.Count;
-                        itemInfo.question = question;
-
-                        //处理答案
-                        //去除class 以及span标签"
-                        string ahtml = x.answer;
-                        ahtml = Regex.Replace(ahtml, classpattern, "");
-                        ahtml = Regex.Replace(ahtml, pattern, "");
-                        ahtml = Regex.Replace(ahtml, apattern, "");
-                        ahtml = ahtml.Replace(" close=\"\" separators=\" | \">", "");
-                        ahtml = ahtml.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
-                        HashSet<string> ans = new HashSet<string>();
-                        var anstr = BlankTag(ahtml);
-                        for (int idx = 0; idx < 26; idx++)
-                        {
-                            anstr = anstr.Replace(aza[idx], azh[idx]);
-                        }
-
-                        anstr.Select(s => s.ToString()).ToList().ForEach(x =>
-                        {
-                            ans.Add(x);
-                        });
-                        itemInfo.answerHtml = x.answer;
-                        itemInfo.answer = ans.ToList();
-                        if (ans.Count > 1)
-                        {
-                            itemInfo.type = "multiple";
                         }
                         else
                         {
-                            itemInfo.type = "single";
+                            itemInfo.type = "subjective";
+                            itemInfo.question = x.stem;
+                            itemInfo.answer = new List<string>() { HtmlHelper.DoUselessTag(x.answer.ToString()) };
                         }
+                        itemInfos.Add(itemInfo);
                     }
-                    else
-                    {
-                        itemInfo.type = "subjective";
-                        itemInfo.question = x.stem;
-                        itemInfo.answer = new List<string>() { HtmlHelper.DoUselessTag(x.answer.ToString()) };
-                    }
-                    itemInfos.Add(itemInfo);
-                }
 
-            });
-            HashSet<string> gradeNames = new HashSet<string>();
-            gradeNames = itemInfos.SelectMany(x => x.gradeNames).ToHashSet();
-           // await _dingDing.SendBotMsg($"学科网推送消息:{authCode.ToJsonString()}", GroupNames.成都开发測試群組);
-            return Ok(new { xkwPapers,periodName = course.stage_name, subjectName=course.subject_name, gradeNames, knowledge=xkw_points.Select(x=>x.name), itemInfos, paper });
+                });
+                HashSet<string> gradeNames = new HashSet<string>();
+                gradeNames = itemInfos.SelectMany(x => x.gradeNames).ToHashSet();
+                // await _dingDing.SendBotMsg($"学科网推送消息:{authCode.ToJsonString()}", GroupNames.成都开发測試群組);
+                return Ok(new { xkwPapers, periodName = course.stage_name, subjectName = course.subject_name, gradeNames, knowledge = xkw_points.Select(x => x.name), itemInfos, paper });
+            } catch (Exception ex) {
+                if (ex.Message.Contains("客户已关闭") || ex.Message.Contains("403"))
+                {
+                    return Ok(new { error = 403, message="学科网该账号授权已到期!" });
+                }
+                else
+                {
+                    await _dingDing.SendBotMsg($"学科网组卷错误:{ex.Message}\n{ex.StackTrace}\n{json.ToJsonString()}", GroupNames.成都开发測試群組);
+                    return BadRequest($"学科网组卷错误:{ex.Message}\n{ex.StackTrace}\n{json.ToJsonString()}");
+                }
+               
+            }
         }
 
         private string BlankTag(string tagHtml)

+ 1 - 1
TEAMModelOS/TEAMModelOS.csproj

@@ -43,7 +43,7 @@
     <AssemblyVersion>5.2206.29.1</AssemblyVersion>
     <FileVersion>5.2206.29.1</FileVersion>
     <Description>TEAMModelOS(IES5)</Description>
-    <PackageReleaseNotes>IES版本说明版本切换标记20220624</PackageReleaseNotes>
+    <PackageReleaseNotes>IES版本说明版本切换标记202200701</PackageReleaseNotes>
     <PackageId>TEAMModelOS</PackageId>
     <Authors>teammodel</Authors>
     <Company>醍摩豆(成都)信息技术有限公司</Company>