Browse Source

Merge branch 'develop3.0-tmd' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0-tmd

CrazyIter_Bin 4 years ago
parent
commit
e922d2c519
28 changed files with 2371 additions and 1846 deletions
  1. 6 2
      TEAMModelOS/ClientApp/src/api/courseMgmt.js
  2. 92 0
      TEAMModelOS/ClientApp/src/common/BasePdSelect.vue
  3. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.vue
  4. 2 4
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue
  5. 4 7
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue
  6. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/completePaper.vue
  7. 12 6
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/composePaper.vue
  8. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue
  9. 0 5
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/MissionListCard.vue
  10. 351 385
      TEAMModelOS/ClientApp/src/locale/lang/en-US/studentWeb.js
  11. 2 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/index.js
  12. 58 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/knowledge.js
  13. 405 394
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/studentWeb.js
  14. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/index.js
  15. 58 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/knowledge.js
  16. 440 419
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/studentWeb.js
  17. 54 59
      TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue
  18. 6 6
      TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/AddBlock.vue
  19. 5 31
      TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/AddPoint.vue
  20. 10 11
      TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/ComposeBlock.vue
  21. 100 0
      TEAMModelOS/ClientApp/src/view/newcourse/ClassTable.less
  22. 458 0
      TEAMModelOS/ClientApp/src/view/newcourse/ClassTable.vue
  23. 8 3
      TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.less
  24. 132 369
      TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.vue
  25. 4 4
      TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue
  26. 2 0
      TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue
  27. 102 118
      TEAMModelOS/Controllers/School/ClassRoomController.cs
  28. 54 18
      TEAMModelOS/Controllers/School/CourseController.cs

+ 6 - 2
TEAMModelOS/ClientApp/src/api/courseMgmt.js

@@ -31,7 +31,7 @@ export default {
     upsertPlan: function (data) {
         return post('/api/Course/upsertPlan', data)
     },
-    //查询课程安排数据
+    //查询课程安排数据 (废弃,已经没有courseManagement结构)
     findPlan: function (data) {
         return post('/school/course/find-management', data)
     },
@@ -89,5 +89,9 @@ export default {
     //根据stulist ids换取详细信息
     findListSummary: function (data) {
         return post('/school/course/get-summary-list', data)
-    }
+    },
+    //查询课程安排数据 (废弃,已经没有courseManagement结构)
+    findCusByClass: function (data) {
+        return post('/school/course/find-course-by-classId', data)
+    },
 }

+ 92 - 0
TEAMModelOS/ClientApp/src/common/BasePdSelect.vue

@@ -0,0 +1,92 @@
+<template>
+    <div class="pd-select-wrap">
+        <Dropdown class="sort-dropdown" trigger="click" placement="bottom-start" @on-click="function(e){ filterPeriod = e }" @on-visible-change="dropdownStates" v-if="$store.state.user.schoolProfile.school_base">
+            <span style="cursor: pointer;">
+                {{$t('schoolBaseInfo.pdLabel')}}
+                <b class="title">{{ filterPeriodName }}</b>
+                <Icon type="ios-arrow-down" style="margin-left:8px;"></Icon>
+            </span>
+            <DropdownMenu slot="list" v-for="(item,index) in periods" :value="item.id" :key="index">
+                <DropdownItem :name="item.id">{{ item.name }}</DropdownItem>
+            </DropdownMenu>
+        </Dropdown>
+    </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+    name: 'BasePdSelect',
+    props: {
+    },
+    data() {
+        return {
+            filterPeriod: '',
+        }
+    },
+    created() {
+        this.$store.dispatch('user/getSchoolProfile').then(
+            (res) => {
+                if (res) {
+                    if (this.periods) this.filterPeriod = this.periods[0].id
+                }
+            },
+            (err) => {
+                this.$Message.error('API error!')
+            }
+        )
+    },
+    methods: {
+        dropdownStates(flag) {
+            // if (!flag) this.filterByPeriod()
+        }
+    },
+    computed: {
+        ...mapGetters({
+            periods: 'user/getPeriods', // 學制s
+        }),
+        filterPeriodName: function () {
+            let data = this.periods
+            let pId = this.filterPeriod
+            let name = ''
+            if (pId !== '') {
+                let temp = data.filter(item => {
+                    return pId == item.id
+                })
+                if (temp.length > 0) name = temp[0].name
+            }
+            return name
+        },
+    },
+    watch: {
+        filterPeriod() {
+            this.$emit('pd-change', this.filterPeriod)
+        }
+    }
+}
+</script>
+<style lang="less">
+.pd-select-wrap{
+    display: inline-block;
+}
+.sort-dropdown {
+    .title {
+        color: white;
+        font-size: 14px;
+    }
+    .ivu-select-dropdown {
+        background-color: #2d2d2d;
+        border-radius: 2px;
+        border: 1px #464646 solid;
+        .ivu-dropdown-menu {
+            li {
+                color: #ccc;
+                font-size: 12px !important;
+                &:hover {
+                    color: #2d2d2d;
+                }
+            }
+        }
+    }
+}
+</style>

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

@@ -47,7 +47,7 @@
                 targetImg: "",
                 columns: [
                     {
-                        title: '投票时间',
+                        title: this.$t('studentWeb.vote.voteTime'),
                         key: 'time',
                         sortable: true
                     },

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

@@ -139,13 +139,13 @@
                                             k++
                                         }
                                     }
-                                    if (k == 0) {
+                                    if (k == 0 && this.paperData[i].progress == 'finish') {
                                         isTest++
                                     }
                                 }
                             }
                         }
-                        if (isTest == this.paperData.length) {
+                        if (isTest == this.paperData.length ) {
                             this.isTestOver = true
                         }
                         this.opentestWithSubject(this.paperData[0])
@@ -172,7 +172,6 @@
                 }
             },
             async getPaper(data) {
-                console.log('paper', data)
                 this.isExamDown = false
                 this.isLoad = true
                 this.selectData = {}
@@ -184,7 +183,6 @@
                         code: key[key.length - 1],
                         blob: data.blob
                     }
-                    console.log('评测信息',this.$store.getters.getItemTitle)
                     let exam = {}
                     for (let item of this.examData) {
                         if (data.paperId == item.id) {

+ 4 - 7
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue

@@ -144,7 +144,6 @@
 					}
 				}
 				this.$forceUpdate()
-				console.log(this.submitArr)
 			},
 
 			submitMessage() {
@@ -158,14 +157,14 @@
 				this.$api.studentWeb.answerSurvey(params).then(async res => {
 					switch (res.msgid){
 						case 1:
-							this.$Message.success('提交成功!')
+							this.$Message.success(this.$t('studentWeb.queNaire.submitSuccess'))
 							this.alreadyAnswered = true
 							break;
 						case 2:
-							this.$Message.error('不在作答时间范围内!')
+                            this.$Message.error(this.$t('studentWeb.queNaire.overTime'))
 							break;
 						case 3:
-							this.$Message.error('作答数据有误!')
+                            this.$Message.error(this.$t('studentWeb.queNaire.answerErr'))
 							break;		
 						default:
 							break;
@@ -294,7 +293,7 @@
 						let itemJson = JSON.parse(await this.$tools.getFile(blobHost + url + sasString.sas))
 						resolve(itemJson)
 					}catch(e){
-						this.$Message.error('文件获取失败!')
+                        this.$Message.error(this.$t('studentWeb.queNaire.fileErr'))
 						reject(e)
 					}
 				})
@@ -309,14 +308,12 @@
 		},
 
 		mounted() {
-			console.log('watch2')
 			this.getSurveyInfo()
 		},
 
 		watch: {
 			$route: {
 				handler() {
-					console.log('watch')
 					this.getSurveyInfo()
 				},
 				// 深度观察监听

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

@@ -1,8 +1,8 @@
 <template>
     <div class="content" v-if="num.length > 0">
         <div class="content-input" v-for="(item,index) of num" :key="index">
-            <span class="complete-index">{{(index+1)}}:</span>
-            <Input @on-change="getInput(index)" v-model="examInfo[index]" placeholder="请输入填空内容" style="width:45%" />
+            <span class="complete-index">{{$t("studentWeb.exam.emput")}}{{(index+1)}}:</span>
+            <Input @on-change="getInput(index)" v-model="examInfo[index]" :placeholder="$t('studentWeb.exam.inputAnswers')" style="width:45%" />
         </div>
     </div>
 </template>

+ 12 - 6
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/composePaper.vue

@@ -1,10 +1,10 @@
 <template>
     <div class="content">
         <div id="textArea"> </div>
-        <Modal v-model="markStatus" fullscreen title="作答" footer-hide  ref="compose">
+        <Modal v-model="markStatus" fullscreen :title="$t('studentWeb.exam.answer')" footer-hide  ref="compose">
                 <BaseMyCanvas v-if="markStatus" :bgImg="markBg" @onCloseModal="closeModal" :isStudent="markStatus" @onSaveCanvas="saveMark"></BaseMyCanvas>
         </Modal>
-        <iframe class="frame"id="answerIframe" :srcdoc="itemInfo.question"></iframe>
+        <iframe class="frame" id="answerIframe" :srcdoc="itemInfo.question"></iframe>
     </div>
 </template>
 <script>
@@ -83,7 +83,7 @@
                     "image", // 插入图片
                 ]
                 this.editor.config.zIndex = 1
-                this.editor.config.placeholder = '请输入作答结果'
+                this.editor.config.placeholder = this.$t('studentWeb.exam.inputAnswers')
                 this.editor.config.height = 300
                 this.editor.config.showLinkImg = false;
                 this.editor.config.uploadImgShowBase64 = true; // 使用 base64 保存图片不建议使用这种,我只是图个方便
@@ -108,10 +108,16 @@
                 answerIframe.contentWindow.document.body.style.width = 'fit-content'
                 answerIframe.contentWindow.document.body.style.minWidth = '600px'
                 answerIframe.contentWindow.document.body.style.backgroundColor = '#f5f5f5'
+                console.log(document.getElementById('answerIframe').contentWindow.document)
                 let iframe = document.getElementById('answerIframe').contentWindow.document.getElementsByTagName('p')
-                console.log(iframe[1].style)
-                iframe[1].style.lineHeight = '50px'
-                iframe[1].style.paddingBottom = '50px'
+                if (iframe.length > 0) {
+                    for (let i = 0; i < iframe.length -1; i++) {
+                        iframe[i].style.lineHeight = '50px'
+                        iframe[i].style.paddingBottom = '30px'
+                    }
+                    iframe[iframe.length -1].style.paddingBottom = '100px'
+                    iframe[iframe.length - 1].style.lineHeight = '50px'
+                }
                 html2canvas(answerIframe.contentWindow.document.body).then(canvas => {
                     this.markStatus = true
                     this.markBg = canvas.toDataURL("image/png");

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

@@ -249,7 +249,7 @@
 
         methods: {
             noData() {
-                this.$Message.warning('此功能暂未开放!')
+                this.$Message.warning(this.$t('studentWeb.public.notice'))
 
             },
             getCurrentLang() {

+ 0 - 5
TEAMModelOS/ClientApp/src/components/student-web/HomeView/MissionListCard.vue

@@ -44,11 +44,6 @@
                                 {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
                             </p>
                         </li>
-                <!--<li class="list-item-unDone">
-                    <PreviewProgressPie v-if=" item.eventType == 'preview'"></PreviewProgressPie>
-                    <PreviewProgressPie :itemID="item.eventID"
-                                        v-if="item.eventType == 'exam'"></PreviewProgressPie>
-                </li>-->
                 </ul>
                 </div>
             </Scroll>

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

@@ -1,418 +1,384 @@
 export default {
-    "home": {
-        "teacher": "teacher",
-        "student": "student",
-        "setting": "Personal Settings",
-        "logout": "Logout",
-        "joinClass": "Join Class",
-        "exam": "evaluation",
-        "vote": "Vote",
-        "survey": "Questionnaire",
+    home: {
+        teacher: 'Teacher',
+        student: 'Student',
+        setting: 'Personal setting',
+        logout: 'Logout',
+        joinClass: 'Join class',
+        exam: 'assessment',
+        vote: 'Vote',
+        survey: 'Questionnaire'
     },
-    "public": {
-        "going": "In progress",
-        "finish": "Finished",
-        "schoolExam": "School Level Evaluation",
-        "privateExam": "Personal Evaluation",
-        "schoolVote": "School-level voting",
-        "privateVote": "Private Vote",
-        "schoolSurvey": "School Level Questionnaire",
-        "privateSurvey": "Personal Survey",
-        "search": "Please enter search content..."
+    public: {
+        noData: 'No data temporarily',
+        going: 'In progress',
+        finish: 'Ended',
+        schoolExam: 'School-level evaluation',
+        privateExam: 'Personal evaluation',
+        schoolVote: 'School-level voting',
+        privateVote: 'Personal vote',
+        schoolSurvey: 'School Level Questionnaire',
+        privateSurvey: 'Personal Questionnaire',
+        search: 'Please enter the query content...'
     },
-    "event": {
-        "allStatus": "All Activity Status",
-        "unFinished": "Unfinished",
-        "Fineshed": "Finished",
-        "Timeout": "Timeout",
-        "makeupExam": "Makeup Exam",
-        "makeupHw": "Makeup available",
-        "selectActivity": "Please select an activity from the list",
-        "allSubject": "All Subjects"
+    event: {
+        allStatus: 'All activity status',
+        unFinished: 'Unfinished',
+        Fineshed: 'Completed',
+        Timeout: 'Timeout',
+        makeupExam: 'Can make up the exam',
+        makeupHw: 'Can make up',
+        selectActivity: 'Please select an activity from the list',
+        allSubject: 'Comprehensive subjects'
     },
-    "settingView-title": "Personal Settings",
-    "teammodel-account-management": {
-        "page-title": "TeamModel Account Management",
-        "name": "Name",
-        "account": "Account",
-        "password": "Password",
-        "phone": "Mobile Number",
-        "e-mail": "E-mail",
-        "binding": "Binding Management",
-        "isbind": "Bind",
-        "unbind": "Unbind",
-        "save": "Save settings"
+    'settingView-title': 'Personal settings',
+    'teammodel-account-management': {
+        'page-title': 'TeamModel account management',
+        name: 'Name',
+        account: 'Account',
+        password: 'Password',
+        phone: 'Mobile phone number',
+        'e-mail': 'E-mail',
+        binding: 'Binding Management',
+        isbind: 'Bind',
+        unbind: 'Unbind',
+        save: 'Save settings'
     },
-    "preference": {
-        "page-title": "Preferences",
-        "UI-theme": "Interface Style Settings",
-        "language": "Language Setting"
+    preference: {
+        'page-title': 'Preferences',
+        'UI-theme': 'Interface style settings',
+        language: 'Language Setting'
     },
-    "change-school": {
-        "page-title": "Switch school",
-        "current-data-school": "Current data source school",
-        "Habook-smart-school": "Habook Smart School"
+    'change-school': {
+        'page-title': 'Switch school',
+        'current-data-school': 'Current data source school',
+        'Habook-smart-school': 'Habook Smart School'
     },
-    "homeView-title": "Homepage Information Overview",
-    "calenderCardTitle": "Calendar",
-    "recentClass": "Recent Class Reminder",
-    "defaultRecentClass": "Introduction to Microprocessor Basics and Applications",
-    "defaultClassTime": "Wednesday 13:30-16:30 (Sections 7-9)",
-    "defaultClassPlace": "F504 Classroom in the Fifth Teaching Building",
-    "todaydeadlineList": "Today Deadline Event Reminder",
-    "endsTodayTime": "Ends Today at 23:59",
-    "coursesCardTitle": "My Course List",
-    "newAddCourse": "The latest addition: Elective Mathematics (2)",
-    "missionListCardTitle": "Activity Task List",
-    "missionListCardLoading": "Loading",
-    "missionListCardReachBottom": "It's the bottom, no activity!",
-    "myProgressBar": {
-        "tasksCompletionRate": "Activity task completion rate",
-        "selfStudyClickRate": "Self-study textbook click rate"
+    'homeView-title': 'Home page information overview',
+    calenderCardTitle: 'Calendar',
+    recentClass: 'Recent class reminder',
+    defaultRecentClass: 'Introduction to Microprocessor Basics and Applications',
+    defaultClassTime: 'Wednesday 13:30-16:30 (Sections 7-9)',
+    defaultClassPlace: 'F504 classroom in the fifth teaching building',
+    todaydeadlineList: 'Today deadline event reminder',
+    endsTodayTime: 'ends today at 23:59',
+    coursesCardTitle: 'My Course List',
+    newAddCourse: 'The latest addition: Elective Mathematics (2)',
+    missionListCardTitle: 'Activity Task List',
+    missionListCardLoading: 'Loading',
+    missionListCardReachBottom: 'It the bottom, no activity! ',
+    myProgressBar: {
+        tasksCompletionRate: 'Activity task completion rate',
+        selfStudyClickRate: 'Self-study textbook click rate'
     },
-    "chartNames": [
-        "Average self-study time",
-        "Monthly self-study hour curve for this semester",
-        "Comparison of the number of activity participation between me and my grade last month",
-        "Comparison chart of average daily self-study time and the whole year level",
-        "Percentage of participation time of various activities and tasks this month",
-        "Self-study activity"
+    chartNames: [
+        'Average self-study time',
+        'Curve of self-study hours per month in this semester',
+        'Last month I compared the number of activities I participated in with my grade',
+        'Comparison of the average daily self-study time and the whole year level',
+        'Percentage of participation time of various activities and tasks this month',
+        'Self-study activity'
     ],
-    "studyTimeChart": {
-        "averageTime": "Minutes/Day",
-        "xAxisData": [
-            "day",
-            "One",
-            "two",
-            "three",
-            "four",
-            "Fives",
-            "six"
+    studyTimeChart: {
+        averageTime: 'minutes/day',
+        xAxisData: [
+            'day',
+            'One',
+            'two',
+            'three',
+            'four',
+            'Fives',
+            'six'
         ]
     },
-    "splineSreaChart": {
-        "xAxisData": [
-            "February",
-            "March",
-            "April",
-            "May",
-            "June"
+    splineSreaChart: {
+        xAxisData: [
+            'February',
+            'March',
+            'April',
+            'May',
+            'June'
         ]
     },
-    "stackBarChart": {
-        "chartMon": "May",
-        "yAxisData": [
-            "I (third grade)",
-            "Third grade",
-            "second grade",
-            "ㄧ Grade"
+    stackBarChart: {
+        chartMon: 'May',
+        yAxisData: [
+            'I (third grade)',
+            'Third grade',
+            'second grade',
+            'Year Grade'
         ],
-        "stackType": [
-            "operation",
-            "Assessment",
-            "Pre-Class Preview",
-            "vote"
+        stackType: [
+            'operation',
+            'Assessment',
+            'Pre-class preview',
+            'vote'
         ]
     },
-    "twoLineChart": {
-        "xAxisData": [
-            "day",
-            "ㄧ",
-            "two",
-            "three",
-            "four",
-            "Fives",
-            "six"
+    twoLineChart: {
+        xAxisData: [
+            'day',
+            'ㄧ',
+            'two',
+            'three',
+            'four',
+            'Fives',
+            'six'
         ]
     },
-    "eventPieChart": {
-        "partType": [
-            "operation",
-            "Assessment",
-            "Pre-Class Preview",
-            "vote"
+    eventPieChart: {
+        partType: [
+            'operation',
+            'Assessment',
+            'Pre-class preview',
+            'vote'
         ]
     },
-    "studyHeatMap": {
-        "xAxisData": [
-            "ㄧ",
-            "two",
-            "three",
-            "four",
-            "Fives"
+    studyHeatMap: {
+        xAxisData: [
+            'ㄧ',
+            'two',
+            'three',
+            'four',
+            'Fives'
         ]
     },
-    "latestNotification": "Latest Notification",
-    "postAt": "Post At",
-    "______________": "______________",
-    "eventView-title": "Activity Task",
-    "nextTask": "Next Task",
-    "allStatus": "All Activity Status",
-    "unFinished": "Unfinished",
-    "Fineshed": "Finished",
-    "Timeout": "Timeout",
-    "makeupExam": "Makeup Exam",
-    "makeupHW": "Makeup available",
-    "empty": "There is currently no data ~",
-    "baseInfo": {
-        "subject": "Subject:",
-        "teacher": "Teacher:",
-        "period": "Activity period:",
-        "postTime": "Post Time:",
-        "classTime": "Class Time",
-        "unFinished": "Unfinished",
-        "Fineshed": "Finished",
-        "Closed": "Closed"
+    latestNotification: 'Latest notification',
+    postAt: 'Posted on',
+    vote: {
+        bollotbox: 'Voting area',
+        submit: 'OK to submit',
+        reVote: 'Vote again',
+        voteSuccess: 'Vote successful',
+        voteDes: 'After the event is over, you can view everyone vote results',
+        timeoutHint: 'Voting time has passed, no more voting, please pay attention to the teacher release of the voting results! ',
+        voteResult: 'The result of this vote is:',
+        voteDesDefault: 'Please choose a desired plan:',
+        tickets: 'ticket',
+        surplusTickets: 'Remaining votes',
+        submitBVote: 'Submit to vote',
+        note: 'Please select at least one option before you vote! ',
+        warning: 'Voting failed, please check the voting information! ',
+        warning2: 'The maximum number of votes has been exceeded! ',
+        voteRes: 'Voting results',
+        voteRecord: 'Vote Record'
     },
-    "billboard": {
-        "description": "Description",
-        "referlink": "referlink data",
-        "attachment": "Attachment",
-        "reference": "reference"
+    homework: {
+        homeworkUpload: 'Job upload area',
+        homeworkUoloadBtn: 'Upload job',
+        homeworkReUoloadBtn: 'Re-upload',
+        CommentClassmatesHomeworkBtn: 'Classmates homework observation and mutual evaluation',
+        uploadSuccess: 'Upload successful',
+        uploadDes: 'After the activity is over, you can view the homework score comments',
+        timeoutHint: 'The homework upload time has ended. The homework score will be calculated as 0 points, or wait for the teacher to open it up. ',
+        contentPage: 'Job content',
+        scorePage: 'Score Comment',
+        score: 'Teacher score',
+        classmatesComments: 'Classmates give comments',
+        comment: 'Give a comment: '
     },
-    "preview": {
-        "checkpoint": "Activity Task",
-        "tutorial": "Programming Textbook",
-        "multiQues": "Multi-question pass module",
-        "previewContent": {
-            "tutorial": "Textbook",
-            "Des": "Content",
-            "Unit": "Unit",
-            "quiz": "Examination in the classroom"
-        },
-        "previous": "Previous Question",
-        "next": "Next Question",
-        "sentAns": "Sent Ans",
-        "tryAgain": "Read the textbook carefully, try again",
-        "nextUnit": "Next Unit",
-        "goHome": "Go Home",
-        "quizRetries": "Quiz Retries",
-        "crossUnitHint": "The last unit test has not been completed. Please complete it before proceeding to this unit test",
-        "timeoutHint": "The pre-class preview activity time has ended, and textbook reading and practice can still be carried out. If it is not completed before the end time, relevant results may be affected."
-    },
-    "vote": {
-        "bollotbox": "Voting Area",
-        "submit": "OK to submit",
-        "reVote": "Vote again",
-        "voteSuccess": "Vote successful",
-        "voteDes": "After the event is over, you can view everyone's voting results",
-        "timeoutHint": "The voting time has passed, and no more voting is possible. Please pay attention to the teacher's release of the voting results!",
-        "voteResult": "The result of this vote is:",
-        "voteDesDefault": "Please select a desired plan:",
-        "tickets": "Tickets",
-        "surplusTickets": "Remaining Tickets",
-        "submitBVote": "Submit to vote",
-        "note": "Please select at least one option before you vote!",
-        "warning": "Voting failed, please check the voting information!",
-        "warning2": "The maximum number of votes has been exceeded!",
-        "voteRes": "Voting Results",
-        "voteRecord": "Vote Record"
-    },
-    "homework": {
-        "homeworkUpload": "Homework Upload Area",
-        "homeworkUoloadBtn": "Upload job",
-        "homeworkReUoloadBtn": "Re-upload",
-        "CommentClassmatesHomeworkBtn": "CommentClassmatesHomeworkBtn",
-        "uploadSuccess": "Upload successful",
-        "uploadDes": "After the activity is over, you can view the assignment score comments",
-        "timeoutHint": "The time for uploading the homework has ended. The grade of this homework will be calculated as 0 points, or waiting for the teacher to open it up.",
-        "contentPage": "Job Content",
-        "scorePage": "Score Comment",
-        "score": "Teacher Score",
-        "classmatesComments": "Classmates Comment",
-        "comment": "Give comment: "
+    classmatesComment: {
+        title: 'Classmates homework observation and mutual evaluation',
+        seatNo: 'seat number',
+        name: 'Name',
+        star: 'star',
+        comment: 'Give a comment',
+        preview: 'Operation preview: file name',
+        unPreview: 'The format of this file currently does not provide preview',
+        download: 'Download file',
+        submitted: 'Submit',
+        inputSomething: 'Input comments and other suggestions',
+        previous: 'Previous',
+        next: 'Next',
+        submitBtn: 'Submit'
     },
-    "classmatesComment": {
-        "title": "Classmates' work observation and mutual evaluation",
-        "seatNo": "seatNo",
-        "name": "Name",
-        "star": "Star",
-        "comment": "Give comment",
-        "preview": "Job Preview: File Name",
-        "unPreview": "This file format does not currently provide preview",
-        "download": "Download File",
-        "submitted": "Submitted",
-        "inputSomething": "Input comments and other suggestions",
-        "previous": "Previous",
-        "next": "Next",
-        "submitBtn": "Submit"
-    },
-    "exam": {
-        "examLink": "Exam Link",
-        "isSubject": "",
-        "subjectNow": "Subject",
-        "examData": "Evaluation Content",
-        "gradeReport": "Grade Report",
-        "gradeAnalyse": "Grade Analysis",
-        "testpop": {
-            "title": "assessment",
-            "completion": "Completion Degree",
-            "practiceMode": "Practice Mode",
-            "all": "Practice all",
-            "onlywrong": "Only practice answering wrong answers",
-            "questions": "Questions",
-            "submitted": "Submitted",
-            "finish": "Finished",
-            "showAns": "Show Answers",
-            "hideAns": "Hide the answer",
-            "hint": "Key Tips",
-            "previous": "Previous Question",
-            "next": "Next Question",
-            "myAnswerSheet": "My Answer Sheet",
-            "exitQuizhint": "Exit Quizhint",
-            "exitQuizhintDe": "The system has detected that you have not yet 'submitted', if you choose 'OK',",
-            "exitQuizhintDes": "The current answer will not be saved, and the test will be re-tested next time",
-            "cancel": "Cancel",
-            "ok": "OK",
-            "submitQuizhint": "Submit Quizhint",
-            "submitQuizhintDes1": "The system test has been completed so far. Are you sure to submit the paper?",
-            "check": "No, need to check again",
-            "conAnswer0": "Currently you have",
-            "conAnswer1": "The question has not been answered (check the answer card in detail)",
-            "conAnswer2": ", please complete the question first!",
-            "conAnswer": "Continue to answer",
-            "okSubmit": "Confirm to submit the paper",
-            "qNo": "Question Number:",
-            "myAns": "Answer",
-            "correction": "正解",
-            "queNo": "Title:",
-            "myAns": "My answer:"
+    exam: {
+        examLink: 'test paper link',
+        isSubject: 'Subject paper',
+        subjectNow: 'Current subject',
+        examData: 'evaluation content',
+        gradeReport: 'Score report',
+        gradeAnalyse: 'Score Analysis',
+        queType: {
+            single: 'Single choice question',
+            multiply: 'Multiple Choice Questions',
+            judge: 'Judgement question',
+            complete: 'Fill in the blanks',
+            subjective: 'Question and Answer Question',
+            compose: 'Comprehensive questions',
+            correct: 'Correct the wrong question',
+            connector: 'Connection question'
+        },
+        submitSuccess: 'The answer information was submitted successfully! ',
+        submitFail: 'Failed to save the answer information! ',
+        msgWarning: 'The answer message is wrong! ',
+        testpop: {
+            title: 'Assessment',
+            completion: 'Completion degree',
+            practiceMode: 'Practice Mode',
+            all: 'Practice all',
+            onlywrong: 'Only practice the wrong answer',
+            questions: 'The question',
+            submitted: 'Submission of paper',
+            finish: 'Completed',
+            showAns: 'Show answers',
+            hideAns: 'Hide the answer',
+            hint: 'Key hint',
+            previous: 'Previous question',
+            next: 'Next question',
+            myAnswerSheet: 'My Answer Sheet',
+            exitQuizhint: 'Leave Quiz Prompt',
+            exitQuizhintDe: 'The system has detected that you have not yet "turned in", if you choose "OK",',
+            exitQuizhintDes: 'The current answer will not be saved, and the test will need to be re-tested next time',
+            cancel: 'Cancel',
+            ok: 'OK',
+            submitQuizhint: 'Reminder for submission of papers',
+            submitQuizhintDes1: 'At present, you have completed the system test. Are you sure to submit the paper? ',
+            check: 'No, need to check again',
+            conAnswer0: 'Currently you have',
+            conAnswer1: 'The question is not answered (check the answer card in detail)',
+            conAnswer2: ', please complete the question first! ',
+            conAnswer: 'Continue to answer',
+            okSubmit: 'Confirm to submit the paper',
+            qNo: 'Question number:',
+            correction: 'right',
+            queNo: 'Title:',
+            myAns: 'My answer:'
         },
-        "report": {
-            "anwser": "Go to answer",
-            "noRes": "The results have not yet been settled",
-            "getScore": "Number of score questions",
-            "answerBack": "Review of the review and answer",
-            "right": "Right",
-            "wrong": "Wrong ",
-            "noScore": "Not Review",
-            "ansRes": "Response result",
-            "testAns": "Reference Answer",
-            "testAnalyse": "Analyze",
-            "repairSource": "Repair Source",
-            "noAns": "No Answer",
-            "linkSource": "Network Resources",
-            "noSource": "No Resources",
-            "fileSource": "File Source",
-            "fileView": "File Preview",
-            "noReview": "This file does not support preview, please download and view!",
-            "pdfErr": "'pdf failed to load'",
-            "noAnalyse": "No analysis yet"
+        report: {
+            anwser: 'Go to answer',
+            noRes: 'Results have not been settled',
+            getScore: 'Number of score questions',
+            answerBack: 'Review of the review and answer',
+            right: 'Answer right',
+            wrong: 'Wrong answer',
+            noScore: 'Not scored',
+            ansRes: 'result of answer',
+            testAns: 'reference answer',
+            testAnalyse: 'Analyze',
+            repairSource: 'remediation resource',
+            noAns: 'No answer',
+            linkSource: 'Network Resources',
+            noSource: 'No resource temporarily',
+            fileSource: 'File Resource',
+            fileView: 'File Preview',
+            noReview: 'This file does not support preview, please download and view! ',
+            pdfErr: 'pdf loading failed',
+            noAnalyse: 'No analysis yet'
         },
-        "timeoutHint": "The evaluation activity time has ended. Overtime will be calculated as 0 points, or wait for the teacher to open the make-up exam.",
-        "contentPage": "Review Content",
-        "scorePage": "Score Report",
-        "practiceHint": "The assessment activity time has ended, you can still click on the test paper link to continue practicing.",
-        "performance": "performance",
-        "reviewAnswers": "Review of answering status",
-        "Chinese": "国文",
-        "Math": "Mathematics",
-        "English": "英文",
-        "score": "Score",
-        "difficulty": "Comprehensive difficulty of examination questions",
-        "average": "Class average score",
-        "rightNum": "The number of my correct answers",
-        "smartComment": "Smart Comment",
-        "keypoint": "Recommended knowledge points for review:",
-        "chart": {
-            "scoreDistribution": "Score Distribution Chart",
-            "participant": "Number of candidates:",
-            "student": "person",
-            "keyPointPerformance": "Knowledge Point Performance Radar Chart",
-            "me": "Individual",
-            "participantAverage": "The whole school",
-            "recognizePerformance": "Recognition Level Radar Chart"
+        timeoutHint: 'The evaluation activity time has ended. Overtime will be calculated as 0 points, or wait for the teacher to open the make-up exam. ',
+        contentPage: 'Review content',
+        scorePage: 'Score report',
+        practiceHint: 'Assessment activity time has ended, you can still click on the test paper link to continue practicing. ',
+        performance: 'Score performance',
+        reviewAnswers: 'Review of answering status',
+        Chinese: '国文',
+        Math: 'Mathematics',
+        English: 'English',
+        score: 'Score',
+        difficulty: 'Comprehensive difficulty of exam questions',
+        average: 'Class average score',
+        rightNum: 'The number of my correct answers',
+        smartComment: 'Smart Comment',
+        keypoint: 'Recommended knowledge points for review:',
+        chart: {
+            scoreDistribution: 'Assessment score distribution map',
+            participant: 'Number of candidates:',
+            student: 'person',
+            keyPointPerformance: 'Knowledge point performance radar chart',
+            me: 'personal',
+            participantAverage: 'The whole school',
+            recognizePerformance: 'Cognitive Level Radar Chart'
         },
-        "studentScore": {
-            "examName": "Exam Name",
-            "examType": "Exam Type",
-            "stableIndex": "Learning stability coefficient",
-            "name": "Name",
-            "stuNo": "Student Number",
-            "class": "class",
-            "allSubScore": "All Subject Scores",
-            "total": "Personal Total Score",
-            "cAverages": "Class Averages",
-            "gAverages": "Grade Averages",
-            "aAverages": "District Averages",
-            "cIndex": "Class Ranking",
-            "gIndex": "Grade Ranking",
-            "aIndex": "District Rank",
-            "onLine": "Whether to enter the line",
-            "subject": "Subject",
-            "score": "Personal Score",
-            "cAverage": "Class Average",
-            "gAverage": "Grade Average",
-            "aAverage": "District-level average",
-            "rAns": "The number of correct answers",
-            "wAns": "Number of wrong answers",
-            "comIndex": "Comprehensive Difficulty",
-            "objItem": "Objective",
-            "subItem": "Subjective",
-            "subjects": "Subjects",
-            "item": "Title",
-            "objItems": "Objective Questions",
-            "subItems": "Subjective questions",
-            "itemIndex": "item number",
-            "standardIndex": "standard answer/partition points",
-            "stuAnsIndex": "Student answer/score",
-            "notice": "【-】--correct answer, 【#】--not answered, 【?】--multiple choice question",
-            "gradeErr": "The grade information is wrong!"
+        studentScore: {
+            examName: 'Exam Name',
+            examType: 'Exam Type',
+            stableIndex: 'Learning stability coefficient',
+            name: 'Name',
+            stuNo: 'Student ID',
+            class: 'Class',
+            allSubScore: 'Full Subject Score',
+            total: 'Personal total score',
+            cAverages: 'Class average score',
+            gAverages: 'Grade Average Score',
+            aAverages: 'District average score',
+            cIndex: 'Class Ranking',
+            gIndex: 'grade ranking',
+            aIndex: 'District rank',
+            onLine: 'Whether to enter the line',
+            subject: 'Subject',
+            score: 'Personal score',
+            cAverage: 'Class average',
+            gAverage: 'Grade Average',
+            aAverage: 'District average',
+            rAns: 'Number of correct answers',
+            wAns: 'Number of wrong answers',
+            comIndex: 'comprehensive difficulty',
+            objItem: 'Objective',
+            subItem: 'Subjective',
+            subjects: 'Subjects',
+            item: 'Title',
+            objItems: 'Objective questions',
+            subItems: 'Subjective questions',
+            itemIndex: 'Question Number',
+            standardIndex: 'standard answer/partition points',
+            stuAnsIndex: 'Student answer/score',
+            notice: '【-】--correct answer, 【#】--no answer, 【?】--multiple choice question',
+            gradeErr: 'The grade information is wrong! '
         },
-        "correctAnswer": "correctAnswer",
-        "wrongAnswer": "Wrong Answer",
-        "unAnswered": "Unanswered",
-        "solution": "Solution",
-        "analysis": "Analysis",
-        "correctRate": "correct rate",
-        "relatedAQues": "Related Questions",
-
+        'correctAnswer': 'correct answer',
+        wrongAnswer: 'Wrong answer',
+        unAnswered: 'Unanswered',
+        solution: 'Solution',
+        analysis: 'Analysis',
+        correctRate: 'correct answer rate',
+        relatedAQues: 'Related Questions'
     },
-    "informview-title": "Notification Overview",
-    "view": "Go to view",
-    "read": "Read",
-    "studyview-title": "self-study",
-    "hiteachview-title": "HiTeach Class Record",
-    "hiteachNote": {
-        "material": "Class Content",
-        "classInteractionRecord": "Class Interaction Record",
-        "qA": "Question and Answer",
-        "qAMulti": "Question and Answer (Multiple Choice)",
-        "reference": "reference answer",
-        "correct": "The answer is correct",
-        "groupQAMulti": "Group QAMulti (multiple choice)",
-        "poImg": "The teacher pushed a picture from Hitach:",
-        "link": "Share Link"
+    'informview-title': 'Notification overview',
+    view: 'Go to view',
+    read: 'Read',
+    'studyview-title': 'self-study',
+    'hiteachview-title': 'HiTeach class record',
+    hiteachNote: {
+        material: 'Class content',
+        classInteractionRecord: 'Class Interaction Record',
+        qA: 'Quick and answer',
+        qAMulti: 'Quick and answer (multiple choice)',
+        reference: 'Reference answer',
+        correct: 'The answer is correct',
+        groupQAMulti: 'Group QAMulti (multiple choice)',
+        poImg: 'The teacher pushed a picture from Hitach:',
+        link: 'Share link'
     },
-    "courseList-title": "My Course List",
-    "defaultClass": "Specify a class",
-    "tempClass": "Temporary Class",
-    "courseContent": {
-        "baseInfo": "Basic Information",
-        "description": "Course Overview",
-        "classmates": "Classmates List",
-        "classID": "Course Code",
-        "classTime": "Class Time",
-        "classroom": "Classroom",
-        "teacher": "Teacher",
-        "co-teacher": "Co-teacher",
-        "addedTime": "Added Course Date",
-        "syllabus": "Syllabus Overview",
-        "seatNo": "seatNo",
-        "name": "Name",
-        "group": "Group"
+    'courseList-title': 'My Course List',
+    defaultClass: 'table set course',
+    tempClass: 'temporary class',
+    courseContent: {
+        baseInfo: 'Basic Information',
+        description: 'Course Overview',
+        classmates: 'Classmates list',
+        classID: 'Course Code',
+        classTime: 'Class Time',
+        classroom: 'Classroom',
+        teacher: 'Teaching teacher',
+        'co-teacher': 'co-teacher',
+        addedTime: 'Join the course date',
+        syllabus: 'Syllabus overview',
+        seatNo: 'seat number',
+        name: 'Name',
+        group: 'Group'
     },
-    "calendar-title": "Calendar-Second Semester of 109 School Year",
-    "today": "Today",
-    "importEvent": "Campus Class Important Events",
-    "deadlineTasks": "Deadline Tasks",
-    "schedule": "Schedule Schedule",
-    "des": "Description",
-    "time": "Time",
-    "place": "Location",
-    "course": "course",
-    "mockcourses": ["Reading and Writing", "English Presentation", "Special Experiments on Electronic Circuits", "Introduction to Computers", "Microprocessor Experiments"],
-    "importEventTitle": "Campus Class Important Events",
-    "Thatday": "Thatday",
-    "deadlineTasksTitle": "DeadlineTasksTitle"
+    'calendar-title': 'Calendar-Second semester of 109 school year',
+    today: 'Today',
+    importEvent: 'Campus Class Important Events',
+    deadlineTasks: 'Deadline activity tasks',
+    schedule: 'Schedule scheduled',
+    des: 'Description',
+    time: 'Time',
+    place: 'Location',
+    course: 'Course',
+    mockcourses: ['Reading and Writing', 'English Presentation', 'Special Experiments on Electronic Circuits', 'Introduction to Computers', 'Microprocessor Experiments'],
+    importEventTitle: 'Campus Class Important Events',
+    Thatday: 'The day',
+    deadlineTasksTitle: 'Activity tasks are not completed at the end of the day'
 }

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

@@ -30,7 +30,7 @@ import survey from './survey'
 import updModal from './updModal'
 import http from './http'
 import utils from './utils'
-
+import knowledge from './knowledge'
 export default {
   schoolBaseInfo,
   classMgmt,
@@ -64,6 +64,7 @@ export default {
   updModal,
   http,
   utils,
+  knowledge,
   test: '测试',
   formConfigP: {
     input: '请输入',

+ 58 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/knowledge.js

@@ -0,0 +1,58 @@
+export default {
+    subject: '科目',
+    label: '名称',
+    blockP: '请输入知识块名称',
+    confirm: '确认',
+    blockWarning: '知识块名称不能为空!',
+    block: '知识块',
+    knowledgeP: '请输入知识点名称,必填项',
+    knowledgeWarning: '知识点名称不能为空!',
+    newBlock: '新增知识块',
+    addBlock: '添加知识块',
+    inputBlock: '输入知识块名称',
+    nowBlock: '现有知识块',
+    nowBlockN: '选择知识块 ( *若所选知识块内已存在添加的知识点则会覆盖 )',
+    selectPoint: '已选知识点',
+    blockWarning2: '已存在同名知识块,请修改名称!',
+    blockWarning3: '知识块名称不能为空',
+    blockWarning4: '无现有知识块选择',
+    period: '当前学段',
+    searchSubject: '搜索学科...',
+    blockCount: '知识块数',
+    point: '知识点',
+    searchPoint: '搜索知识点...',
+    makeBlock: '组成知识块',
+    edit: '编辑',
+    delete: '删除',
+    moveBlock: '移出知识块',
+    searchBlock: '搜索知识块',
+    buildBlock: '新建知识块',
+    pointCount: '知识点数:',
+    editBlock: '编辑知识块',
+    addPoint: '新增知识点',
+    editPoint: '编辑知识点',
+    cancel: '取消',
+    notice: '提示',
+    content0: '确定将',
+    content2: '等',
+    content3: '个知识点移入到知识块',
+    content1: '中(*已存在的知识点会自动忽略)',
+    notice1: '所选知识点已存在该知识块中',
+    notice2: '该知识块已存在当前知识点',
+    content4: '确定将知识点',
+    content5: '移入到知识块',
+    content6: '中?',
+    success: '操作成功!',
+    fail: '操作失败!',
+    warn: '知识块数据获取失败',
+    delBlock: '确认删除该知识块?',
+    delSuccess: '删除成功',
+    delFail: '删除失败',
+    delPoint: '确认删除该知识点?',
+    content7: '确定将知识点',
+    content8: '从知识块',
+    content9: '中移出',
+    moveFail: '移出失败',
+    saveSuccess: '保存数据成功!',
+    saveFail: '保存数据失败!'
+}

+ 405 - 394
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/studentWeb.js

@@ -1,431 +1,442 @@
 export default {
-    "home": {
-        "teacher": "教师",
-        "student": "学生",
-        "setting": "个人设定",
-        "logout": "登出",
-        "joinClass": "加入课程",
-        "exam": "评量",
-        "vote": "投票",
-        "survey": "问卷",
+    home: {
+        teacher: '教师',
+        student: '学生',
+        setting: '个人设定',
+        logout: '登出',
+        joinClass: '加入课程',
+        exam: '评量',
+        vote: '投票',
+        survey: '问卷'
     },
-    "public": {
-        "noData":"暂无数据",
-        "going": "进行中",
-        "finish": "已结束",
-        "schoolExam": "校级评测",
-        "privateExam": "个人评测",
-        "schoolVote": "校级投票",
-        "privateVote": "个人投票",
-        "schoolSurvey": "校级问卷",
-        "privateSurvey":"个人问卷",
-        "search":"请输入查询内容..."
+    public: {
+        noData: '暂无数据',
+        going: '进行中',
+        finish: '已结束',
+        schoolExam: '校级评测',
+        privateExam: '个人评测',
+        schoolVote: '校级投票',
+        privateVote: '个人投票',
+        schoolSurvey: '校级问卷',
+        privateSurvey: '个人问卷',
+        search: '请输入查询内容...',
+        notice: '此功能暂未开放!'
     },
-    "event": {
-        "allStatus": "所有活动状态",
-        "unFinished": "未完成",
-        "Fineshed": "已完成",
-        "Timeout": "已逾时",
-        "makeupExam": "可补考",
-        "makeupHw": "可补交",
-        "selectActivity": "请从列表挑选一个活动",
-        "allSubject":"综合科目"
+    event: {
+        allStatus: '所有活动状态',
+        unFinished: '未完成',
+        Fineshed: '已完成',
+        Timeout: '已逾时',
+        makeupExam: '可补考',
+        makeupHw: '可补交',
+        selectActivity: '请从列表挑选一个活动',
+        allSubject: '综合科目'
     },
-    "settingView-title": "个人设定",
-    "teammodel-account-management": {
-        "page-title": "TeamModel 帐号管理",
-        "name": "姓名",
-        "account": "帐号",
-        "password": "密码",
-        "phone": "手机号码",
-        "e-mail": "E-mail",
-        "binding": "绑定管理",
-        "isbind": "绑定",
-        "unbind": "解除绑定",
-        "save": "储存设定"
+    'settingView-title': '个人设定',
+    'teammodel-account-management': {
+        'page-title': 'TeamModel 帐号管理',
+        name: '姓名',
+        account: '帐号',
+        password: '密码',
+        phone: '手机号码',
+        'e-mail': 'E-mail',
+        binding: '绑定管理',
+        isbind: '绑定',
+        unbind: '解除绑定',
+        save: '储存设定'
     },
-    "preference": {
-        "page-title": "偏好设定",
-        "UI-theme": "介面样式设定",
-        "language": "语系设定"
+    preference: {
+        'page-title': '偏好设定',
+        'UI-theme': '介面样式设定',
+        language: '语系设定'
     },
-    "change-school": {
-        "page-title": "切换学校",
-        "current-data-school": "目前资料来源学校",
-        "Habook-smart-school": "Habook智慧校园"
+    'change-school': {
+        'page-title': '切换学校',
+        'current-data-school': '目前资料来源学校',
+        'Habook-smart-school': 'Habook智慧校园'
     },
-    "homeView-title": "首页资讯总览",
-    "calenderCardTitle": "行事历",
-    "recentClass": "近期上课提醒",
-    "defaultRecentClass": "微处理机基础与应用概论",
-    "defaultClassTime": "星期三 13:30 - 16:30 (第7-9节)",
-    "defaultClassPlace": "第五教学楼 F504 教室",
-    "todaydeadlineList": "今日截止活动提醒 ",
-    "endsTodayTime": "今日23:59截止",
-    "coursesCardTitle": "我的课程清单",
-    "newAddCourse": "最新加入:选修数学(二)",
-    "missionListCardTitle": "活动任务清单",
-    "missionListCardLoading": "载入中",
-    "missionListCardReachBottom": "已经最底,没活动啦!",
-    "myProgressBar": {
-        "tasksCompletionRate": "活动任务完成率",
-        "selfStudyClickRate": "自学教材点阅率"
+    'homeView-title': '首页资讯总览',
+    calenderCardTitle: '行事历',
+    recentClass: '近期上课提醒',
+    defaultRecentClass: '微处理机基础与应用概论',
+    defaultClassTime: '星期三 13:30 - 16:30 (第7-9节)',
+    defaultClassPlace: '第五教学楼 F504 教室',
+    todaydeadlineList: '今日截止活动提醒 ',
+    endsTodayTime: '今日23:59截止',
+    coursesCardTitle: '我的课程清单',
+    newAddCourse: '最新加入:选修数学(二)',
+    missionListCardTitle: '活动任务清单',
+    missionListCardLoading: '载入中',
+    missionListCardReachBottom: '已经最底,没活动啦!',
+    myProgressBar: {
+        tasksCompletionRate: '活动任务完成率',
+        selfStudyClickRate: '自学教材点阅率'
     },
-    "chartNames": [
-        "平均自学时间",
-        "本学期每月自学时数曲线",
-        "上月我与年级的活动参与数比较",
-        "每日平均自学时间与全年级比较图",
-        "本月各类活动任务参与时间占比",
-        "自学活跃度"
+    chartNames: [
+        '平均自学时间',
+        '本学期每月自学时数曲线',
+        '上月我与年级的活动参与数比较',
+        '每日平均自学时间与全年级比较图',
+        '本月各类活动任务参与时间占比',
+        '自学活跃度'
     ],
-    "studyTimeChart": {
-        "averageTime": "分/日",
-        "xAxisData": [
-            "日",
-            "一",
-            "二",
-            "三",
-            "四",
-            "五",
-            "六"
+    studyTimeChart: {
+        averageTime: '分/日',
+        xAxisData: [
+            '日',
+            '一',
+            '二',
+            '三',
+            '四',
+            '五',
+            '六'
         ]
     },
-    "splineSreaChart": {
-        "xAxisData": [
-            "2月",
-            "3月",
-            "4月",
-            "5月",
-            "6月"
+    splineSreaChart: {
+        xAxisData: [
+            '2月',
+            '3月',
+            '4月',
+            '5月',
+            '6月'
         ]
     },
-    "stackBarChart": {
-        "chartMon": "5月",
-        "yAxisData": [
-            "我(三年级)",
-            "三年级",
-            "二年级",
-            "ㄧ年级"
+    stackBarChart: {
+        chartMon: '5月',
+        yAxisData: [
+            '我(三年级)',
+            '三年级',
+            '二年级',
+            'ㄧ年级'
         ],
-        "stackType": [
-            "作业",
-            "评量",
-            "课前预习",
-            "投票"
+        stackType: [
+            '作业',
+            '评量',
+            '课前预习',
+            '投票'
         ]
     },
-    "twoLineChart": {
-        "xAxisData": [
-            "日",
-            "ㄧ",
-            "二",
-            "三",
-            "四",
-            "五",
-            "六"
+    twoLineChart: {
+        xAxisData: [
+            '日',
+            'ㄧ',
+            '二',
+            '三',
+            '四',
+            '五',
+            '六'
         ]
     },
-    "eventPieChart": {
-        "partType": [
-            "作业",
-            "评量",
-            "课前预习",
-            "投票"
+    eventPieChart: {
+        partType: [
+            '作业',
+            '评量',
+            '课前预习',
+            '投票'
         ]
     },
-    "studyHeatMap": {
-        "xAxisData": [
-            "ㄧ",
-            "二",
-            "三",
-            "四",
-            "五"
+    studyHeatMap: {
+        xAxisData: [
+            'ㄧ',
+            '二',
+            '三',
+            '四',
+            '五'
         ]
     },
-    "latestNotification": "最新通知",
-    "postAt": "发布于",
-    "______________": "______________",
-    "eventView-title": "活动任务",
-    "nextTask": "下个活动",
-    "allStatus": "所有活动状态",
-    "unFinished": "未完成",
-    "Fineshed": "已完成",
-    "Timeout": "已逾时",
-    "makeupExam": "可补考",
-    "makeupHW": "可补交",
-    "empty": "目前无资料 ~",
-    "baseInfo": {
-        "subject": "科目:",
-        "teacher": "教师:",
-        "period": "活动期限:",
-        "postTime": "发布时间:",
-        "classTime": "上课时间",
-        "unFinished": "未完成",
-        "Fineshed": "已完成",
-        "Closed": "已结束"
+    latestNotification: '最新通知',
+    postAt: '发布于',
+    '______________': '______________',
+    'eventView-title': '活动任务',
+    nextTask: '下个活动',
+    allStatus: '所有活动状态',
+    unFinished: '未完成',
+    Fineshed: '已完成',
+    Timeout: '已逾时',
+    makeupExam: '可补考',
+    makeupHW: '可补交',
+    empty: '目前无资料 ~',
+    baseInfo: {
+        subject: '科目:',
+        teacher: '教师:',
+        period: '活动期限:',
+        postTime: '发布时间:',
+        classTime: '上课时间',
+        unFinished: '未完成',
+        Fineshed: '已完成',
+        Closed: '已结束'
     },
-    "billboard": {
-        "description": "描述",
-        "referlink": "连结资料",
-        "attachment": "附件",
-        "reference": "参考资料"
+    billboard: {
+        description: '描述',
+        referlink: '连结资料',
+        attachment: '附件',
+        reference: '参考资料'
     },
-    "preview": {
-        "checkpoint": "活动任务",
-        "tutorial": "编序教材",
-        "multiQues": "多题闯关模组",
-        "previewContent": {
-            "tutorial": "教材",
-            "Des": "内容",
-            "Unit": "单元",
-            "quiz": "随堂考"
+    preview: {
+        checkpoint: '活动任务',
+        tutorial: '编序教材',
+        multiQues: '多题闯关模组',
+        previewContent: {
+            tutorial: '教材',
+            Des: '内容',
+            Unit: '单元',
+            quiz: '随堂考'
         },
-        "previous": "上一题",
-        "next": "下一题",
-        "sentAns": "送出答案",
-        "tryAgain": "详读教材,再试一次",
-        "nextUnit": "下一单元",
-        "goHome": "回到首页",
-        "quizRetries": "测验重试次数",
-        "crossUnitHint": "上个单元测验尚未完成,请先完成方可进行本单元测验",
-        "timeoutHint": "课前预习活动时间已结束,仍可进行教材阅读与练习,如于结束时间前未完成,相关成绩可能受到影响。"
+        previous: '上一题',
+        next: '下一题',
+        sentAns: '送出答案',
+        tryAgain: '详读教材,再试一次',
+        nextUnit: '下一单元',
+        goHome: '回到首页',
+        quizRetries: '测验重试次数',
+        crossUnitHint: '上个单元测验尚未完成,请先完成方可进行本单元测验',
+        timeoutHint: '课前预习活动时间已结束,仍可进行教材阅读与练习,如于结束时间前未完成,相关成绩可能受到影响。'
     },
-    "vote": {
-        "bollotbox": "投票区",
-        "submit": "确定送出",
-        "reVote": "再次投票",
-        "voteSuccess": "投票成功",
-        "voteDes": "活动结束后,即可检视大家的投票结果",
-        "timeoutHint": "投票时间已过,无法再进行投票,敬请留意教师发布投票结果!",
-        "voteResult": "本次投票结果为:",
-        "voteDesDefault": "请选择一个想要的方案:",
-        "tickets": "票",
-        "surplusTickets": "剩余票数",
-        "submitBVote": "提交投票",
-        "note": "请至少选择一个选项,再进行投票!",
-        "warning": "投票失败,请检查投票信息!",
-        "warning2": "已超出最大投票数!",
-        "voteRes": "投票结果",
-        "voteRecord":"投票记录"
+    vote: {
+        bollotbox: '投票区',
+        submit: '确定送出',
+        reVote: '再次投票',
+        voteSuccess: '投票成功',
+        voteDes: '活动结束后,即可检视大家的投票结果',
+        timeoutHint: '投票时间已过,无法再进行投票,敬请留意教师发布投票结果!',
+        voteResult: '本次投票结果为:',
+        voteDesDefault: '请选择一个想要的方案:',
+        tickets: '票',
+        surplusTickets: '剩余票数',
+        submitBVote: '提交投票',
+        note: '请至少选择一个选项,再进行投票!',
+        warning: '投票失败,请检查投票信息!',
+        warning2: '已超出最大投票数!',
+        voteRes: '投票结果',
+        voteRecord: '投票记录',
+        voteTime: '投票时间'
     },
-    "homework": {
-        "homeworkUpload": "作业上传区",
-        "homeworkUoloadBtn": "上传作业",
-        "homeworkReUoloadBtn": "重新上传",
-        "CommentClassmatesHomeworkBtn": "同学作业观摩互评",
-        "uploadSuccess": "上传成功",
-        "uploadDes": "活动结束后,即可检视作业成绩评语",
-        "timeoutHint": "作业上传时间已结束,本次作业成绩将以 0分 计算,或等候教师开放补交。",
-        "contentPage": "作业内容",
-        "scorePage": "成绩评语",
-        "score": "教师评分",
-        "classmatesComments": "同学给评",
-        "comment": "给评: "
+    homework: {
+        homeworkUpload: '作业上传区',
+        homeworkUoloadBtn: '上传作业',
+        homeworkReUoloadBtn: '重新上传',
+        CommentClassmatesHomeworkBtn: '同学作业观摩互评',
+        uploadSuccess: '上传成功',
+        uploadDes: '活动结束后,即可检视作业成绩评语',
+        timeoutHint: '作业上传时间已结束,本次作业成绩将以 0分 计算,或等候教师开放补交。',
+        contentPage: '作业内容',
+        scorePage: '成绩评语',
+        score: '教师评分',
+        classmatesComments: '同学给评',
+        comment: '给评: '
     },
-    "classmatesComment": {
-        "title": "同学作业观摩与互评",
-        "seatNo": "座号",
-        "name": "姓名",
-        "star": "星级",
-        "comment": "给评",
-        "preview": "作业预览:档案名称",
-        "unPreview": "这个档案的格式目前不提供预览",
-        "download": "下载档案",
-        "submitted": "提交",
-        "inputSomething": "输入评语与其他建议",
-        "previous": "上一位",
-        "next": "下一位",
-        "submitBtn": "送出"
+    classmatesComment: {
+        title: '同学作业观摩与互评',
+        seatNo: '座号',
+        name: '姓名',
+        star: '星级',
+        comment: '给评',
+        preview: '作业预览:档案名称',
+        unPreview: '这个档案的格式目前不提供预览',
+        download: '下载档案',
+        submitted: '提交',
+        inputSomething: '输入评语与其他建议',
+        previous: '上一位',
+        next: '下一位',
+        submitBtn: '送出'
     },
-    "exam": {
-        "examLink": "试卷链接",
-        "isSubject": "科试卷",
-        "subjectNow": "当前科目",
-        "examData": "评测内容",
-        "gradeReport": "成绩报告",
-        "gradeAnalyse": "成绩分析",
-        "queType": {
-            "single": "单选题",
-            "multiply": "多选题",
-            "judge": "判断题",
-            "complete": "填空题",
-            "subjective": "问答题",
-            "compose": "综合题",
-            "correct": "改错题",
-            "connector":"连线题"
+    exam: {
+        examLink: '试卷链接',
+        isSubject: '科试卷',
+        subjectNow: '当前科目',
+        examData: '评测内容',
+        gradeReport: '成绩报告',
+        gradeAnalyse: '成绩分析',
+        queType: {
+            single: '单选题',
+            multiply: '多选题',
+            judge: '判断题',
+            complete: '填空题',
+            subjective: '问答题',
+            compose: '综合题',
+            correct: '改错题',
+            connector: '连线题'
         },
-        "submitSuccess": "作答信息提交成功!",
-        "submitFail": "作答信息保存失败!",
-        "msgWarning": "作答信息错误!",
-        "testpop": {
-            "title": "评量",
-            "completion": "完成度",
-            "practiceMode": "练习模式",
-            "all": "练习全部",
-            "onlywrong": "只练习答错",
-            "questions": "的题目",
-            "submitted": "交卷",
-            "finish":"已完成",
-            "showAns": "显示答案",
-            "hideAns": "隐藏答案",
-            "hint": "重点提示",
-            "previous": "上一题",
-            "next": "下一题",
-            "myAnswerSheet": "我的答题卡",
-            "exitQuizhint": "离开测验提示",
-            "exitQuizhintDe": "系统检测您尚未「交卷」,如您选择「确定」,",
-            "exitQuizhintDes": "则目前作答将不保存,下次需重新测验",
-            "cancel": "取消",
-            "ok": "确定",
-            "submitQuizhint": "交卷提示",
-            "submitQuizhintDes1": "系统检测目前您已全数作答完成,确定交卷吗?",
-            "check": "否,需再检查",
-            "conAnswer0": "目前您有",
-            "conAnswer1": "题 未作答 (详查答案卡)",
-            "conAnswer2":",请先完成题目作答!",
-            "conAnswer":"继续作答",
-            "okSubmit": "确定交卷",
-            "qNo": "题号:",
-            "myAns": "作答",
-            "correction": "正解",
-            "queNo": "题目:",
-            "myAns":"我的作答:"
+        submitSuccess: '作答信息提交成功!',
+        submitFail: '作答信息保存失败!',
+        msgWarning: '作答信息错误!',
+        testpop: {
+            title: '评量',
+            completion: '完成度',
+            practiceMode: '练习模式',
+            all: '练习全部',
+            onlywrong: '只练习答错',
+            questions: '的题目',
+            submitted: '交卷',
+            finish: '已完成',
+            showAns: '显示答案',
+            hideAns: '隐藏答案',
+            hint: '重点提示',
+            previous: '上一题',
+            next: '下一题',
+            myAnswerSheet: '我的答题卡',
+            exitQuizhint: '离开测验提示',
+            exitQuizhintDe: '系统检测您尚未「交卷」,如您选择「确定」,',
+            exitQuizhintDes: '则目前作答将不保存,下次需重新测验',
+            cancel: '取消',
+            ok: '确定',
+            submitQuizhint: '交卷提示',
+            submitQuizhintDes1: '系统检测目前您已全数作答完成,确定交卷吗?',
+            check: '否,需再检查',
+            conAnswer0: '目前您有',
+            conAnswer1: '题 未作答 (详查答案卡)',
+            conAnswer2: ',请先完成题目作答!',
+            conAnswer: '继续作答',
+            okSubmit: '确定交卷',
+            qNo: '题号:',
+            correction: '正解',
+            queNo: '题目:',
+            myAns: '我的作答:'
         },
-        "report": {
-            "anwser": "前往作答",
-            "noRes": "成绩尚未结算",
-            "getScore": "得分题目数",
-            "answerBack": "评测作答回顾",
-            "right": "答对",
-            "wrong": "答错",
-            "noScore": "未评分",
-            "ansRes": "作答结果",
-            "testAns": "参考答案",
-            "testAnalyse": "解析",
-            "repairSource": "补救资源",
-            "noAns":"未作答",
-            "linkSource": "网络资源",
-            "noSource": "暂无资源",
-            "fileSource": "文件资源",
-            "fileView": "文件预览",
-            "noReview": "该文件暂不支持预览,请下载查看!",
-            "pdfErr":"'pdf 加载失败'",
-            "noAnalyse":"暂无解析"
+        report: {
+            anwser: '前往作答',
+            noRes: '成绩尚未结算',
+            getScore: '得分题目数',
+            answerBack: '评测作答回顾',
+            right: '答对',
+            wrong: '答错',
+            noScore: '未评分',
+            ansRes: '作答结果',
+            testAns: '参考答案',
+            testAnalyse: '解析',
+            repairSource: '补救资源',
+            noAns: '未作答',
+            linkSource: '网络资源',
+            noSource: '暂无资源',
+            fileSource: '文件资源',
+            fileView: '文件预览',
+            noReview: '该文件暂不支持预览,请下载查看!',
+            pdfErr: 'pdf 加载失败',
+            noAnalyse: '暂无解析'
         },
-        "timeoutHint": "评量活动时间已结束,逾时将以0分计算,或等待教师开放补考。",
-        "contentPage": "评量内容",
-        "scorePage": "成绩报告",
-        "practiceHint": "评量活动时间已结束,仍可点击试卷连结,持续练习。",
-        "performance": "成绩表现",
-        "reviewAnswers": "答题状况回顾",
-        "Chinese": "国文",
-        "Math": "数学",
-        "English": "英文",
-        "score": "得分",
-        "difficulty": "考题综合难易度", 
-        "average": "班平均分数",
-        "rightNum": "我的答对题数",
-        "smartComment": "智能点评",
-        "keypoint": "建议复习知识点:",
-        "chart": {
-            "scoreDistribution": "评量成绩分布图",
-            "participant": "应考人数:",
-            "student": "人",
-            "keyPointPerformance": "知识点表现雷达图",
-            "me": "个人",
-            "participantAverage": "全校",
-            "recognizePerformance": "认知层次雷达图"
+        timeoutHint: '评量活动时间已结束,逾时将以0分计算,或等待教师开放补考。',
+        contentPage: '评量内容',
+        scorePage: '成绩报告',
+        practiceHint: '评量活动时间已结束,仍可点击试卷连结,持续练习。',
+        performance: '成绩表现',
+        reviewAnswers: '答题状况回顾',
+        Chinese: '国文',
+        Math: '数学',
+        English: '英文',
+        score: '得分',
+        difficulty: '考题综合难易度',
+        average: '班平均分数',
+        rightNum: '我的答对题数',
+        smartComment: '智能点评',
+        keypoint: '建议复习知识点:',
+        chart: {
+            scoreDistribution: '评量成绩分布图',
+            participant: '应考人数:',
+            student: '人',
+            keyPointPerformance: '知识点表现雷达图',
+            me: '个人',
+            participantAverage: '全校',
+            recognizePerformance: '认知层次雷达图'
         },
-        "studentScore": {
-            "examName": "考试名称",
-            "examType":"考试类型",
-            "stableIndex":"学习稳定系数",
-            "name":"姓名",
-            "stuNo":"学号",
-            "class": "班级",
-            "allSubScore": "全学科成绩",
-            "total":"个人总分",
-            "cAverages":"班级平均分",
-            "gAverages":"年级平均分",
-            "aAverages":"区级平均分",
-            "cIndex":"班级排名",
-            "gIndex":"年级排名",
-            "aIndex":"区级排名",
-            "onLine": "是否进线",
-            "subject":"学科",
-            "score": "个人得分",
-            "cAverage": "班级平均",
-            "gAverage": "年级平均",
-            "aAverage": "区级平均",
-            "rAns":"答对题数",
-            "wAns":"答错题数",
-            "comIndex":"综合难度",
-            "objItem":"客观",
-            "subItem":"主观",
-            "subjects":"科目",
-            "item":"题目",
-            "objItems": "客观题",
-            "subItems": "主观题",
-            "itemIndex":"题号",
-            "standardIndex":"标准答案/配分",
-            "stuAnsIndex":"学生作答/得分",
-            "notice": "【-】--答对,【#】--未作答,【?】--多选题",
-            "gradeErr":"成绩信息错误!"
+        studentScore: {
+            examName: '考试名称',
+            examType: '考试类型',
+            stableIndex: '学习稳定系数',
+            name: '姓名',
+            stuNo: '学号',
+            class: '班级',
+            allSubScore: '全学科成绩',
+            total: '个人总分',
+            cAverages: '班级平均分',
+            gAverages: '年级平均分',
+            aAverages: '区级平均分',
+            cIndex: '班级排名',
+            gIndex: '年级排名',
+            aIndex: '区级排名',
+            onLine: '是否进线',
+            subject: '学科',
+            score: '个人得分',
+            cAverage: '班级平均',
+            gAverage: '年级平均',
+            aAverage: '区级平均',
+            rAns: '答对题数',
+            wAns: '答错题数',
+            comIndex: '综合难度',
+            objItem: '客观',
+            subItem: '主观',
+            subjects: '科目',
+            item: '题目',
+            objItems: '客观题',
+            subItems: '主观题',
+            itemIndex: '题号',
+            standardIndex: '标准答案/配分',
+            stuAnsIndex: '学生作答/得分',
+            notice: '【-】--答对,【#】--未作答,【?】--多选题',
+            gradeErr: '成绩信息错误!'
         },
-        "correctAnswer": "答对",
-        "wrongAnswer": "答错",
-        "unAnswered": "未答",
-        "solution": "解答",
-        "analysis": "解析",
-        "correctRate": "答对率",
-        "relatedAQues": "关联题目",
+        'correctAnswer': '答对',
+        wrongAnswer: '答错',
+        unAnswered: '未答',
+        solution: '解答',
+        analysis: '解析',
+        correctRate: '答对率',
+        relatedAQues: '关联题目',
+        answer: '作答',
+        inputAnswers: '请输入作答结果',
+        emput: '空',
+
     },
-    "informview-title": "通知总览",
-    "view": "前往检视",
-    "read": "已读",
-    "studyview-title": "自主学习",
-    "hiteachview-title": "HiTeach课堂记录",
-    "hiteachNote": {
-        "material": "上课内容",
-        "classInteractionRecord": "课堂互动记录",
-        "qA": "即问即答",
-        "qAMulti": "即问即答(多选)",
-        "reference": "参考答案",
-        "correct": "答案正确",
-        "groupQAMulti": "分组即问即答(多选)",
-        "poImg": "教师从Hiteach推送了一张图:",
-        "link": "分享连结"
+    queNaire: {
+        submitSuccess: '提交成功',
+        overTime: '不在作答时间范围内!',
+        answerErr: '作答数据错误!',
+        fileErr: '问价获取失败!'
     },
-    "courseList-title": "我的课程清单",
-    "defaultClass": "表定课程",
-    "tempClass": "临时课程",
-    "courseContent": {
-        "baseInfo": "基本资讯",
-        "description": "课程概述",
-        "classmates": "同学名单",
-        "classID": "课程代码",
-        "classTime": "上课时间",
-        "classroom": "上课教室",
-        "teacher": "授课教师",
-        "co-teacher": "协同教师",
-        "addedTime": "加入课程日期",
-        "syllabus": "课纲概览",
-        "seatNo": "座号",
-        "name": "姓名",
-        "group": "组别"
+    'informview-title': '通知总览',
+    view: '前往检视',
+    read: '已读',
+    'studyview-title': '自主学习',
+    'hiteachview-title': 'HiTeach课堂记录',
+    hiteachNote: {
+        material: '上课内容',
+        classInteractionRecord: '课堂互动记录',
+        qA: '即问即答',
+        qAMulti: '即问即答(多选)',
+        reference: '参考答案',
+        correct: '答案正确',
+        groupQAMulti: '分组即问即答(多选)',
+        poImg: '教师从Hiteach推送了一张图:',
+        link: '分享连结'
     },
-    "calendar-title": "行事历 - 109学年度第二学期",
-    "today": "今天",
-    "importEvent": "校园班级要事",
-    "deadlineTasks": "截止活动任务",
-    "schedule": "表定课表",
-    "des": "描述",
-    "time": "时间",
-    "place": "地点",
-    "course": "课程",
-    "mockcourses": ["阅读与写作", "英文简报", "电子电路专题实验", "计算机概论", "微处理机实验"],
-    "importEventTitle": "校园班级要事",
-    "Thatday": "当日",
-    "deadlineTasksTitle": "当日截止未完成活动任务"
-}  
+    'courseList-title': '我的课程清单',
+    defaultClass: '表定课程',
+    tempClass: '临时课程',
+    courseContent: {
+        baseInfo: '基本资讯',
+        description: '课程概述',
+        classmates: '同学名单',
+        classID: '课程代码',
+        classTime: '上课时间',
+        classroom: '上课教室',
+        teacher: '授课教师',
+        'co-teacher': '协同教师',
+        addedTime: '加入课程日期',
+        syllabus: '课纲概览',
+        seatNo: '座号',
+        name: '姓名',
+        group: '组别'
+    },
+    'calendar-title': '行事历 - 109学年度第二学期',
+    today: '今天',
+    importEvent: '校园班级要事',
+    deadlineTasks: '截止活动任务',
+    schedule: '表定课表',
+    des: '描述',
+    time: '时间',
+    place: '地点',
+    course: '课程',
+    mockcourses: ['阅读与写作', '英文简报', '电子电路专题实验', '计算机概论', '微处理机实验'],
+    importEventTitle: '校园班级要事',
+    Thatday: '当日',
+    deadlineTasksTitle: '当日截止未完成活动任务'
+}

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

@@ -30,6 +30,7 @@ import survey from './survey'
 import updModal from './updModal'
 import http from './http'
 import utils from './utils'
+import knowledge from './knowledge'
 export default {
   
   schoolBaseInfo,
@@ -64,6 +65,7 @@ export default {
   updModal,
   http,
   utils,
+  knowledge,
   test: '測試',
   formConfigP: {
     input: '請輸入',

+ 58 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/knowledge.js

@@ -0,0 +1,58 @@
+export default {
+    subject: '科目',
+    label: '名稱',
+    blockP: '請輸入知識塊名稱',
+    confirm: '確認',
+    blockWarning: '知識塊名稱不能為空!',
+    block: '知識塊',
+    knowledgeP: '請輸入知識點名稱,必填項',
+    knowledgeWarning: '知識點名稱不能為空! ',
+    newBlock: '新增知識塊',
+    addBlock: '添加知識塊',
+    inputBlock: '輸入知識塊名稱',
+    nowBlock: '現有知識塊',
+    nowBlockN: '選擇知識塊 ( *若所選知識塊內已存在添加的知識點則會覆蓋 )',
+    selectPoint: '已選知識點',
+    blockWarning2: '已存在同名知識塊,請修改名稱! ',
+    blockWarning3: '知識塊名稱不能為空',
+    blockWarning4: '無現有知識塊選擇',
+    period: '當前學段',
+    searchSubject: '搜索學科...',
+    blockCount: '知識塊數',
+    point: '知識點',
+    searchPoint: '搜索知識點...',
+    makeBlock: '組成知識塊',
+    edit: '編輯',
+    delete: '刪除',
+    moveBlock: '移出知識塊',
+    searchBlock: '搜索知識塊',
+    buildBlock: '新建知識塊',
+    pointCount: '知識點數:',
+    editBlock: '編輯知識塊',
+    addPoint: '新增知識點',
+    editPoint: '編輯知識點',
+    cancel: '取消',
+    notice: '提示',
+    content0: '確定將',
+    content2: '等',
+    content3: '個知識點移入到知識塊',
+    content1: '中(*已存在的知識點會自動忽略)',
+    notice1: '所選知識點已存在該知識塊中',
+    notice2: '該知識塊已存在當前知識點',
+    content4: '確定將知識點',
+    content5: '移入到知識塊',
+    content6: '中? ',
+    success: '操作成功! ',
+    fail: '操作失敗! ',
+    warn: '知識塊數據獲取失敗',
+    delBlock: '確認刪除該知識塊?',
+    delSuccess: '刪除成功',
+    delFail: '刪除失敗',
+    delPoint: '確認刪除該知識點?',
+    content7: '確定將知識點',
+    content8: '從知識塊',
+    content9: '中移出',
+    moveFail: '移出失敗',
+    saveSuccess: '保存數據成功! ',
+    saveFail: '保存數據失敗! '
+}

+ 440 - 419
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/studentWeb.js

@@ -1,420 +1,441 @@
 export default {
-	"home": {
-		"teacher": "教師",
-		"student": "學生",
-		"setting": "個人設定",
-		"logout": "登出",
-		"joinClass": "加入課程",
-		"exam": "評量",
-		"vote": "投票",
-		"survey": "問卷",
-	},
-	"public": {
-		"going": "進行中",
-		"finish": "已結束",
-		"schoolExam": "校級評測",
-		"privateExam": "個人評測",
-		"schoolVote": "校級投票",
-		"privateVote": "個人投票",
-		"schoolSurvey": "校級問卷",
-		"privateSurvey": "個人問卷",
-		"search": "請輸入查詢內容..."
-	},
-	"event": {
-		"allStatus": "所有活動狀態",
-		"unFinished": "未完成",
-		"Fineshed": "已完成",
-		"Timeout": "已逾時",
-		"makeupExam": "可補考",
-		"makeupHw": "可補交",
-		"selectActivity": "請從列表挑選一個活動",
-		"allSubject": "綜合科目"
-	},
-	"settingView-title": "個人設定",
-	"teammodel-account-management": {
-		"page-title": "TeamModel 帳號管理",
-		"name": "姓名",
-		"account": "帳號",
-		"password": "密碼",
-		"phone": "手機號碼",
-		"e-mail": "E-mail",
-		"binding": "綁定管理",
-		"isbind": "綁定",
-		"unbind": "解除綁定",
-		"save": "儲存設定"
-	},
-	"preference": {
-		"page-title": "偏好設定",
-		"UI-theme": "介面樣式設定",
-		"language": "語系設定"
-	},
-	"change-school": {
-		"page-title": "切換學校",
-		"current-data-school": "目前資料來源學校",
-		"Habook-smart-school": "Habook智慧校園"
-	},
-	"homeView-title": "首頁資訊總覽",
-	"calenderCardTitle": "行事歷",
-	"recentClass": "近期上課提醒",
-	"defaultRecentClass": "微處理機基礎與應用概論",
-	"defaultClassTime": "星期三 13:30 - 16:30 (第7-9節)",
-	"defaultClassPlace": "第五教學樓 F504 教室",
-	"todaydeadlineList": "今日截止活動提醒 ",
-	"endsTodayTime": "今日23:59截止",
-	"coursesCardTitle": "我的課程清單",
-	"newAddCourse": "最新加入:選修數學(二)",
-	"missionListCardTitle": "活動任務清單",
-	"missionListCardLoading": "載入中",
-	"missionListCardReachBottom": "已經最底,沒活動啦!",
-	"myProgressBar": {
-		"tasksCompletionRate": "活動任務完成率",
-		"selfStudyClickRate": "自學教材點閱率"
-	},
-	"chartNames": [
-		"平均自學時間",
-		"本學期每月自學時數曲線",
-		"上月我與年級的活動參與數比較",
-		"每日平均自學時間與全年級比較圖",
-		"本月各類活動任務參與時間佔比",
-		"自學活躍度"
-	],
-	"studyTimeChart": {
-		"averageTime": "分/日",
-		"xAxisData": [
-			"日",
-			"一",
-			"二",
-			"三",
-			"四",
-			"五",
-			"六"
-		]
-	},
-	"splineSreaChart": {
-		"xAxisData": [
-			"2月",
-			"3月",
-			"4月",
-			"5月",
-			"6月"
-		]
-	},
-	"stackBarChart": {
-		"chartMon": "5月",
-		"yAxisData": [
-			"我(三年級)",
-			"三年級",
-			"二年級",
-			"ㄧ年級"
-		],
-		"stackType": [
-			"作業",
-			"評量",
-			"課前預習",
-			"投票"
-		]
-	},
-	"twoLineChart": {
-		"xAxisData": [
-			"日",
-			"ㄧ",
-			"二",
-			"三",
-			"四",
-			"五",
-			"六"
-		]
-	},
-	"eventPieChart": {
-		"partType": [
-			"作業",
-			"評量",
-			"課前預習",
-			"投票"
-		]
-	},
-	"studyHeatMap": {
-		"xAxisData": [
-			"ㄧ",
-			"二",
-			"三",
-			"四",
-			"五"
-		]
-	},
-	"latestNotification": "最新通知",
-	"postAt": "發佈於",
-	"______________": "______________",
-	"eventView-title": "活動任務",
-	"nextTask": "下個活動",
-	"allStatus": "所有活動狀態",
-	"unFinished": "未完成",
-	"Fineshed": "已完成",
-	"Timeout": "已逾時",
-	"makeupExam": "可補考",
-	"makeupHW": "可補交",
-	"empty": "目前無資料 ~",
-	"baseInfo": {
-		"subject": "科目:",
-		"teacher": "教師:",
-		"period": "活動期限:",
-		"postTime": "發佈時間:",
-		"classTime": "上課時間",
-		"unFinished": "未完成",
-		"Fineshed": "已完成",
-		"Closed": "已結束"
-	},
-	"billboard": {
-		"description": "描述",
-		"referlink": "連結資料",
-		"attachment": "附件",
-		"reference": "參考資料"
-	},
-	"preview": {
-		"checkpoint": "活動任務",
-		"tutorial": "編序教材",
-		"multiQues": "多題闖關模組",
-		"previewContent": {
-			"tutorial": "教材",
-			"Des": "內容",
-			"Unit": "單元",
-			"quiz": "隨堂考"
-		},
-		"previous": "上一題",
-		"next": "下一題",
-		"sentAns": "送出答案",
-		"tryAgain": "詳讀教材,再試一次",
-		"nextUnit": "下一單元",
-		"goHome": "回到首頁",
-		"quizRetries": "測驗重試次數",
-		"crossUnitHint": "上個單元測驗尚未完成,請先完成方可進行本單元測驗",
-		"timeoutHint": "課前預習活動時間已結束,仍可進行教材閱讀與練習,如於結束時間前未完成,相關成績可能受到影響。"
-	},
-	"vote": {
-		"bollotbox": "投票區",
-		"submit": "確定送出",
-		"reVote": "再次投票",
-		"voteSuccess": "投票成功",
-		"voteDes": "活動結束後,即可檢視大家的投票結果",
-		"timeoutHint": "投票時間已過,無法再進行投票,敬請留意教師發布投票結果!",
-		"voteResult": "本次投票結果為:",
-		"voteDesDefault": "請選擇一個想要的方案:",
-		"tickets": "票",
-		"surplusTickets": "剩餘票數",
-		"submitBVote": "提交投票",
-		"note": "請至少選擇一個選項,再進行投票!",
-		"warning": "投票失敗,請檢查投票信息!",
-		"warning2": "已超出最大投票數!",
-		"voteRes": "投票結果",
-		"voteRecord": "投票記錄"
-	},
-	"homework": {
-		"homeworkUpload": "作業上傳區",
-		"homeworkUoloadBtn": "上傳作業",
-		"homeworkReUoloadBtn": "重新上傳",
-		"CommentClassmatesHomeworkBtn": "同學作業觀摩互評",
-		"uploadSuccess": "上傳成功",
-		"uploadDes": "活動結束後,即可檢視作業成績評語",
-		"timeoutHint": "作業上傳時間已結束,本次作業成績將以 0分 計算,或等候教師開放補交。",
-		"contentPage": "作業內容",
-		"scorePage": "成績評語",
-		"score": "教師評分",
-		"classmatesComments": "同學給評",
-		"comment": "給評: "
-	},
-	"classmatesComment": {
-		"title": "同學作業觀摩與互評",
-		"seatNo": "座號",
-		"name": "姓名",
-		"star": "星級",
-		"comment": "給評",
-		"preview": "作業預覽:檔案名稱",
-		"unPreview": "這個檔案的格式目前不提供預覽",
-		"download": "下載檔案",
-		"submitted": "提交",
-		"inputSomething": "輸入評語與其他建議",
-		"previous": "上一位",
-		"next": "下一位",
-		"submitBtn": "送出"
-	},
-	"exam": {
-		"examLink": "試卷鏈接",
-		"isSubject": "科試卷",
-		"subjectNow": "當前科目",
-		"examData": "評測內容",
-		"gradeReport": "成績報告",
-		"gradeAnalyse": "成績分析",
-		"testpop": {
-			"title": "評量",
-			"completion": "完成度",
-			"practiceMode": "練習模式",
-			"all": "練習全部",
-			"onlywrong": "只練習答錯",
-			"questions": "的題目",
-			"submitted": "交卷",
-			"finish": "已完成",
-			"showAns": "顯示答案",
-			"hideAns": "隱藏答案",
-			"hint": "重點提示",
-			"previous": "上一題",
-			"next": "下一題",
-			"myAnswerSheet": "我的答題卡",
-			"exitQuizhint": "離開測驗提示",
-			"exitQuizhintDe": "系統檢測您尚未「交卷」,如您選擇「確定」,",
-			"exitQuizhintDes": "則目前作答將不保存,下次需重新測驗",
-			"cancel": "取消",
-			"ok": "確定",
-			"submitQuizhint": "交卷提示",
-			"submitQuizhintDes1": "系統檢測目前您已全數作答完成,確定交卷嗎?",
-			"check": "否,需再檢查",
-			"conAnswer0": "目前您有",
-			"conAnswer1": "題 未作答 (詳查答案卡)",
-			"conAnswer2": ",請先完成題目作答!",
-			"conAnswer": "繼續作答",
-			"okSubmit": "確定交卷",
-			"qNo": "題號:",
-			"myAns": "作答",
-			"correction": "正解",
-			"queNo": "題目:",
-			"myAns": "我的作答:"
-		},
-		"report": {
-			"anwser": "前往作答",
-			"noRes": "成績尚未結算",
-			"getScore": "得分題目數",
-			"answerBack": "評測作答回顧",
-			"right": "答對",
-			"wrong": "答錯",
-			"noScore": "未評分",
-			"ansRes": "作答結果",
-			"testAns": "參考答案",
-			"testAnalyse": "解析",
-			"repairSource": "補救資源",
-			"noAns": "未作答",
-			"linkSource": "網絡資源",
-			"noSource": "暫無資源",
-			"fileSource": "文件資源",
-			"fileView": "文件預覽",
-			"noReview": "該文件暫不支持預覽,請下載查看!",
-			"pdfErr": "'pdf 加載失敗'",
-			"noAnalyse": "暫無解析"
-		},
-		"timeoutHint": "評量活動時間已結束,逾時將以0分計算,或等待教師開放補考。",
-		"contentPage": "評量內容",
-		"scorePage": "成績報告",
-		"practiceHint": "評量活動時間已結束,仍可點擊試卷連結,持續練習。",
-		"performance": "成績表現",
-		"reviewAnswers": "答題狀況回顧",
-		"Chinese": "國文",
-		"Math": "數學",
-		"English": "英文",
-		"score": "得分",
-		"difficulty": "考題綜合難易度",
-		"average": "班平均分數",
-		"rightNum": "我的答對題數",
-		"smartComment": "智能點評",
-		"keypoint": "建議複習知識點:",
-
-
-		"chart": {
-			"scoreDistribution": "評量成績分佈圖",
-			"participant": "應考人數:",
-			"student": "人",
-			"keyPointPerformance": "知識點表現雷達圖",
-			"me": "個人",
-			"participantAverage": "全校",
-			"recognizePerformance": "認知層次雷達圖"
-		},
-		"studentScore": {
-			"examName": "考試名稱",
-			"examType": "考試類型",
-			"stableIndex": "學習穩定係數",
-			"name": "姓名",
-			"stuNo": "學號",
-			"class": "班級",
-			"allSubScore": "全學科成績",
-			"total": "個人總分",
-			"cAverages": "班級平均分",
-			"gAverages": "年級平均分",
-			"aAverages": "區級平均分",
-			"cIndex": "班級排名",
-			"gIndex": "年級排名",
-			"aIndex": "區級排名",
-			"onLine": "是否進線",
-			"subject": "學科",
-			"score": "個人得分",
-			"cAverage": "班級平均",
-			"gAverage": "年級平均",
-			"aAverage": "區級平均",
-			"rAns": "答對題數",
-			"wAns": "答錯題數",
-			"comIndex": "綜合難度",
-			"objItem": "客觀",
-			"subItem": "主觀",
-			"subjects": "科目",
-			"item": "題目",
-			"objItems": "客觀題",
-			"subItems": "主觀題",
-			"itemIndex": "題號",
-			"standardIndex": "標準答案/配分",
-			"stuAnsIndex": "學生作答/得分",
-			"notice": "【-】--答對,【#】--未作答,【?】--多選題",
-			"gradeErr": "成績信息錯誤!"
-		},
-		"correctAnswer": "答對",
-		"wrongAnswer": "答錯",
-		"unAnswered": "未答",
-		"solution": "解答",
-		"analysis": "解析",
-		"correctRate": "答對率",
-		"relatedAQues": "關聯題目",
-
-	},
-	"informview-title": "通知總覽",
-	"view": "前往檢視",
-	"read": "已讀",
-	"studyview-title": "自主學習",
-	"hiteachview-title": "HiTeach課堂記錄",
-	"hiteachNote": {
-		"material": "上課內容",
-		"classInteractionRecord": "課堂互動記錄",
-		"qA": "即問即答",
-		"qAMulti": "即問即答(多選)",
-		"reference": "參考答案",
-		"correct": "答案正確",
-		"groupQAMulti": "分組即問即答(多選)",
-		"poImg": "教師從Hiteach推送了一張圖:",
-		"link": "分享連結"
-	},
-	"courseList-title": "我的課程清單",
-	"defaultClass": "表定課程",
-	"tempClass": "臨時課程",
-	"courseContent": {
-		"baseInfo": "基本資訊",
-		"description": "課程概述",
-		"classmates": "同學名單",
-		"classID": "課程代碼",
-		"classTime": "上課時間",
-		"classroom": "上課教室",
-		"teacher": "授課教師",
-		"co-teacher": "協同教師",
-		"addedTime": "加入課程日期",
-		"syllabus": "課綱概覽",
-		"seatNo": "座號",
-		"name": "姓名",
-		"group": "組別"
-	},
-	"calendar-title": "行事歷 - 109學年度第二學期",
-	"today": "今天",
-	"importEvent": "校園班級要事",
-	"deadlineTasks": "截止活動任務",
-	"schedule": "表定課表",
-	"des": "描述",
-	"time": "時間",
-	"place": "地點",
-	"course": "課程",
-	"mockcourses": ["閱讀與寫作", "英文簡報", "電子電路專題實驗", "計算機概論", "微處理機實驗"],
-	"importEventTitle": "校園班級要事",
-	"Thatday": "當日",
-	"deadlineTasksTitle": "當日截止未完成活動任務"
-}
+    home: {
+        teacher: '教師',
+        student: '學生',
+        setting: '個人設定',
+        logout: '登出',
+        joinClass: '加入課程',
+        exam: '評量',
+        vote: '投票',
+        survey: '問卷'
+    },
+    public: {
+        noData: '暫無數據',
+        going: '進行中',
+        finish: '已結束',
+        schoolExam: '校級評測',
+        privateExam: '個人評測',
+        schoolVote: '校級投票',
+        privateVote: '個人投票',
+        schoolSurvey: '校級問卷',
+        privateSurvey: '個人問卷',
+        search: '請輸入查詢內容...',
+        noitice: '此功能暫未開放!'
+    },
+    event: {
+        allStatus: '所有活動狀態',
+        unFinished: '未完成',
+        Fineshed: '已完成',
+        Timeout: '已逾時',
+        makeupExam: '可補考',
+        makeupHw: '可補交',
+        selectActivity: '請從列表挑選一個活動',
+        allSubject: '綜合科目'
+    },
+    'settingView-title': '個人設定',
+    'teammodel-account-management': {
+        'page-title': 'TeamModel 帳號管理',
+        name: '姓名',
+        account: '帳號',
+        password: '密碼',
+        phone: '手機號碼',
+        'e-mail': 'E-mail',
+        binding: '綁定管理',
+        isbind: '綁定',
+        unbind: '解除綁定',
+        save: '儲存設定'
+    },
+    preference: {
+        'page-title': '偏好設定',
+        'UI-theme': '介面樣式設定',
+        language: '語系設定'
+    },
+    'change-school': {
+        'page-title': '切換學校',
+        'current-data-school': '目前資料來源學校',
+        'Habook-smart-school': 'Habook智慧校園'
+    },
+    'homeView-title': '首頁資訊總覽',
+    calenderCardTitle: '行事歷',
+    recentClass: '近期上課提醒',
+    defaultRecentClass: '微處理機基礎與應用概論',
+    defaultClassTime: '星期三 13:30 - 16:30 (第7-9節)',
+    defaultClassPlace: '第五教學樓 F504 教室',
+    todaydeadlineList: '今日截止活動提醒 ',
+    endsTodayTime: '今日23:59截止',
+    coursesCardTitle: '我的課程清單',
+    newAddCourse: '最新加入:選修數學(二)',
+    missionListCardTitle: '活動任務清單',
+    missionListCardLoading: '載入中',
+    missionListCardReachBottom: '已經最底,沒活動啦! ',
+    myProgressBar: {
+        tasksCompletionRate: '活動任務完成率',
+        selfStudyClickRate: '自學教材點閱率'
+    },
+    chartNames: [
+        '平均自學時間',
+        '本學期每月自學時數曲線',
+        '上月我與年級的活動參與數比較',
+        '每日平均自學時間與全年級比較圖',
+        '本月各類活動任務參與時間佔比',
+        '自學活躍度'
+    ],
+    studyTimeChart: {
+        averageTime: '分/日',
+        xAxisData: [
+            '日',
+            '一',
+            '二',
+            '三',
+            '四',
+            '五',
+            '六'
+        ]
+    },
+    splineSreaChart: {
+        xAxisData: [
+            '2月',
+            '3月',
+            '4月',
+            '5月',
+            '6月'
+        ]
+    },
+    stackBarChart: {
+        chartMon: '5月',
+        yAxisData: [
+            '我(三年級)',
+            '三年級',
+            '二年級',
+            'ㄧ年級'
+        ],
+        stackType: [
+            '作業',
+            '評量',
+            '課前預習',
+            '投票'
+        ]
+    },
+    twoLineChart: {
+        xAxisData: [
+            '日',
+            'ㄧ',
+            '二',
+            '三',
+            '四',
+            '五',
+            '六'
+        ]
+    },
+    eventPieChart: {
+        partType: [
+            '作業',
+            '評量',
+            '課前預習',
+            '投票'
+        ]
+    },
+    studyHeatMap: {
+        xAxisData: [
+            'ㄧ',
+            '二',
+            '三',
+            '四',
+            '五'
+        ]
+    },
+    latestNotification: '最新通知',
+    postAt: '發佈於',
+    '______________': '______________',
+    'eventView-title': '活動任務',
+    nextTask: '下個活動',
+    allStatus: '所有活動狀態',
+    unFinished: '未完成',
+    Fineshed: '已完成',
+    Timeout: '已逾時',
+    makeupExam: '可補考',
+    makeupHW: '可補交',
+    empty: '目前無資料 ~',
+    baseInfo: {
+        subject: '科目:',
+        teacher: '教師:',
+        period: '活動期限:',
+        postTime: '發佈時間:',
+        classTime: '上課時間',
+        unFinished: '未完成',
+        Fineshed: '已完成',
+        Closed: '已結束'
+    },
+    billboard: {
+        description: '描述',
+        referlink: '連結資料',
+        attachment: '附件',
+        reference: '參考資料'
+    },
+    preview: {
+        checkpoint: '活動任務',
+        tutorial: '編序教材',
+        multiQues: '多題闖關模組',
+        previewContent: {
+            tutorial: '教材',
+            Des: '內容',
+            Unit: '單元',
+            quiz: '隨堂考'
+        },
+        previous: '上一題',
+        next: '下一題',
+        sentAns: '送出答案',
+        tryAgain: '詳讀教材,再試一次',
+        nextUnit: '下一單元',
+        goHome: '回到首頁',
+        quizRetries: '測驗重試次數',
+        crossUnitHint: '上個單元測驗尚未完成,請先完成方可進行本單元測驗',
+        timeoutHint: '課前預習活動時間已結束,仍可進行教材閱讀與練習,如於結束時間前未完成,相關成績可能受到影響。 '
+    },
+    vote: {
+        bollotbox: '投票區',
+        submit: '確定送出',
+        reVote: '再次投票',
+        voteSuccess: '投票成功',
+        voteDes: '活動結束後,即可檢視大家的投票結果',
+        timeoutHint: '投票時間已過,無法再進行投票,敬請留意教師發布投票結果! ',
+        voteResult: '本次投票結果為:',
+        voteDesDefault: '請選擇一個想要的方案:',
+        tickets: '票',
+        surplusTickets: '剩餘票數',
+        submitBVote: '提交投票',
+        note: '請至少選擇一個選項,再進行投票! ',
+        warning: '投票失敗,請檢查投票信息! ',
+        warning2: '已超出最大投票數! ',
+        voteRes: '投票結果',
+        voteRecord: '投票記錄',
+        voteTime: '投票時間'
+    },
+    homework: {
+        homeworkUpload: '作業上傳區',
+        homeworkUoloadBtn: '上傳作業',
+        homeworkReUoloadBtn: '重新上傳',
+        CommentClassmatesHomeworkBtn: '同學作業觀摩互評',
+        uploadSuccess: '上傳成功',
+        uploadDes: '活動結束後,即可檢視作業成績評語',
+        timeoutHint: '作業上傳時間已結束,本次作業成績將以 0分 計算,或等候教師開放補交。 ',
+        contentPage: '作業內容',
+        scorePage: '成績評語',
+        score: '教師評分',
+        classmatesComments: '同學給評',
+        comment: '給評: '
+    },
+    classmatesComment: {
+        title: '同學作業觀摩與互評',
+        seatNo: '座號',
+        name: '姓名',
+        star: '星級',
+        comment: '給評',
+        preview: '作業預覽:檔案名稱',
+        unPreview: '這個檔案的格式目前不提供預覽',
+        download: '下載檔案',
+        submitted: '提交',
+        inputSomething: '輸入評語與其他建議',
+        previous: '上一位',
+        next: '下一位',
+        submitBtn: '送出'
+    },
+    exam: {
+        examLink: '試卷鏈接',
+        isSubject: '科試卷',
+        subjectNow: '當前科目',
+        examData: '評測內容',
+        gradeReport: '成績報告',
+        gradeAnalyse: '成績分析',
+        queType: {
+            single: '單選題',
+            multiply: '多選題',
+            judge: '判斷題',
+            complete: '填空題',
+            subjective: '問答題',
+            compose: '綜合題',
+            correct: '改錯題',
+            connector: '連線題'
+        },
+        submitSuccess: '作答信息提交成功! ',
+        submitFail: '作答信息保存失敗! ',
+        msgWarning: '作答信息錯誤! ',
+        testpop: {
+            title: '評量',
+            completion: '完成度',
+            practiceMode: '練習模式',
+            all: '練習全部',
+            onlywrong: '只練習答錯',
+            questions: '的題目',
+            submitted: '交卷',
+            finish: '已完成',
+            showAns: '顯示答案',
+            hideAns: '隱藏答案',
+            hint: '重點提示',
+            previous: '上一題',
+            next: '下一題',
+            myAnswerSheet: '我的答題卡',
+            exitQuizhint: '離開測驗提示',
+            exitQuizhintDe: '系統檢測您尚未「交卷」,如您選擇「確定」,',
+            exitQuizhintDes: '則目前作答將不保存,下次需重新測驗',
+            cancel: '取消',
+            ok: '確定',
+            submitQuizhint: '交卷提示',
+            submitQuizhintDes1: '系統檢測目前您已全數作答完成,確定交卷嗎? ',
+            check: '否,需再檢查',
+            conAnswer0: '目前您有',
+            conAnswer1: '題 未作答 (詳查答案卡)',
+            conAnswer2: ',請先完成題目作答! ',
+            conAnswer: '繼續作答',
+            okSubmit: '確定交卷',
+            qNo: '題號:',
+            correction: '正解',
+            queNo: '題目:',
+            myAns: '我的作答:'
+        },
+        report: {
+            anwser: '前往作答',
+            noRes: '成績尚未結算',
+            getScore: '得分題目數',
+            answerBack: '評測作答回顧',
+            right: '答對',
+            wrong: '答錯',
+            noScore: '未評分',
+            ansRes: '作答結果',
+            testAns: '參考答案',
+            testAnalyse: '解析',
+            repairSource: '補救資源',
+            noAns: '未作答',
+            linkSource: '網絡資源',
+            noSource: '暫無資源',
+            fileSource: '文件資源',
+            fileView: '文件預覽',
+            noReview: '該文件暫不支持預覽,請下載查看! ',
+            pdfErr: 'pdf 加載失敗',
+            noAnalyse: '暫無解析'
+        },
+        timeoutHint: '評量活動時間已結束,逾時將以0分計算,或等待教師開放補考。 ',
+        contentPage: '評量內容',
+        scorePage: '成績報告',
+        practiceHint: '評量活動時間已結束,仍可點擊試卷連結,持續練習。 ',
+        performance: '成績表現',
+        reviewAnswers: '答題狀況回顧',
+        Chinese: '國文',
+        Math: '數學',
+        English: '英文',
+        score: '得分',
+        difficulty: '考題綜合難易度',
+        average: '班平均分數',
+        rightNum: '我的答對題數',
+        smartComment: '智能點評',
+        keypoint: '建議複習知識點:',
+        chart: {
+            scoreDistribution: '評量成績分佈圖',
+            participant: '應考人數:',
+            student: '人',
+            keyPointPerformance: '知識點表現雷達圖',
+            me: '個人',
+            participantAverage: '全校',
+            recognizePerformance: '認知層次雷達圖'
+        },
+        studentScore: {
+            examName: '考試名稱',
+            examType: '考試類型',
+            stableIndex: '學習穩定係數',
+            name: '姓名',
+            stuNo: '學號',
+            class: '班級',
+            allSubScore: '全學科成績',
+            total: '個人總分',
+            cAverages: '班級平均分',
+            gAverages: '年級平均分',
+            aAverages: '區級平均分',
+            cIndex: '班級排名',
+            gIndex: '年級排名',
+            aIndex: '區級排名',
+            onLine: '是否進線',
+            subject: '學科',
+            score: '個人得分',
+            cAverage: '班級平均',
+            gAverage: '年級平均',
+            aAverage: '區級平均',
+            rAns: '答對題數',
+            wAns: '答錯題數',
+            comIndex: '綜合難度',
+            objItem: '客觀',
+            subItem: '主觀',
+            subjects: '科目',
+            item: '題目',
+            objItems: '客觀題',
+            subItems: '主觀題',
+            itemIndex: '題號',
+            standardIndex: '標準答案/配分',
+            stuAnsIndex: '學生作答/得分',
+            notice: '【-】--答對,【#】--未作答,【?】--多選題',
+            gradeErr: '成績信息錯誤! '
+        },
+        'correctAnswer': '答對',
+        wrongAnswer: '答錯',
+        unAnswered: '未答',
+        solution: '解答',
+        analysis: '解析',
+        correctRate: '答對率',
+        relatedAQues: '關聯題目',
+        answer: '作答',
+        inputAnswers: '請輸入作答結果',
+        emput: '空'
+    },
+    queNaire: {
+        submitSuccess: '提交成功',
+        overTime: '不在作答時間範圍內! ',
+        answerErr: '作答數據錯誤! ',
+        fileErr: '問價獲取失敗! '
+    },
+    'informview-title': '通知總覽',
+    view: '前往檢視',
+    read: '已讀',
+    'studyview-title': '自主學習',
+    'hiteachview-title': 'HiTeach課堂記錄',
+    hiteachNote: {
+        material: '上課內容',
+        classInteractionRecord: '課堂互動記錄',
+        qA: '即問即答',
+        qAMulti: '即問即答(多選)',
+        reference: '參考答案',
+        correct: '答案正確',
+        groupQAMulti: '分組即問即答(多選)',
+        poImg: '教師從Hiteach推送了一張圖:',
+        link: '分享連結'
+    },
+    'courseList-title': '我的課程清單',
+    defaultClass: '表定課程',
+    tempClass: '臨時課程',
+    courseContent: {
+        baseInfo: '基本資訊',
+        description: '課程概述',
+        classmates: '同學名單',
+        classID: '課程代碼',
+        classTime: '上課時間',
+        classroom: '上課教室',
+        teacher: '授課教師',
+        'co-teacher': '協同教師',
+        addedTime: '加入課程日期',
+        syllabus: '課綱概覽',
+        seatNo: '座號',
+        name: '姓名',
+        group: '組別'
+    },
+    'calendar-title': '行事歷 - 109學年度第二學期',
+    today: '今天',
+    importEvent: '校園班級要事',
+    deadlineTasks: '截止活動任務',
+    schedule: '表定課表',
+    des: '描述',
+    time: '時間',
+    place: '地點',
+    course: '課程',
+    mockcourses: ['閱讀與寫作', '英文簡報', '電子電路專題實驗', '計算機概論', '微處理機實驗'],
+    importEventTitle: '校園班級要事',
+    Thatday: '當日',
+    deadlineTasksTitle: '當日截止未完成活動任務'
+}

+ 54 - 59
TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue

@@ -8,7 +8,7 @@
 		<!-- 课纲头部 切换来源以及选择学段 -->
 		<div class="new-syllabus-header common-save-btn">
 			<div class="new-syllabus-select">
-				<span>当前学段:</span>
+				<span>{{$t("knowledge.period")}}:</span>
 				<Select ref="periodSelect" v-model="currentPeriodIndex" style="width:100px;" @on-change="onPeriodChange">
 					<Option v-for="(item,index) in periodList" :value="index" :key="index">{{ item.name }}</Option>
 				</Select>
@@ -25,12 +25,12 @@
 					<div class="ns-header-content" v-if="!isSearchSubject">
 						<span>
 							<Icon type="md-bookmark" color="#fff" size="20" />
-							<span style="margin-left:5px">学科</span>
+							<span style="margin-left:5px">{{$t("knowledge.subject")}}</span>
 						</span>
 						<Icon type="ios-search" color="#fff" size="18" v-show="subjectList.length" style="cursor:pointer" @click="isSearchSubject = true" />
 					</div>
 					<div class="ns-header-search" v-else>
-						<Input icon="ios-close" v-model="searchSubject" placeholder="搜索学科..." autofocus style="width: 100%" @on-click="onSearchSubjectClose"
+						<Input icon="ios-close" v-model="searchSubject" :placeholder="$t('knowledge.searchSubject')" autofocus style="width: 100%" @on-click="onSearchSubjectClose"
 						 @on-change="onSearchSubjectChange" @on-enter="onSearchSubjectChange" />
 					</div>
 				</div>
@@ -42,7 +42,7 @@
 						<div :class='["gl-item",index == activeSubjectIndex ? "item-active":""]' v-for="(item,index) in subjectList" :key="index"
 						 @click="hasModify ? handleConfirmSave({index},'2') : handleSubjectTap(index)">
 							<p class="gl-item-name">{{item.name}}</p>
-							<p class="gl-item-info"><span></span>知识块数:{{ tabIndex === 0  ? schoolBlockCount[index] : privateBlockCount[index]}}</p>
+							<p class="gl-item-info"><span></span>{{$t("knowledge.blockCount")}}:{{ tabIndex === 0  ? schoolBlockCount[index] : privateBlockCount[index]}}</p>
 						</div>
 					</div>
 				</vuescroll>
@@ -56,15 +56,15 @@
 					<div class="ns-header-content" v-if="!isSearchPoint">
 						<span>
 							<Icon type="md-cube" color="#fff" size="20" />
-							<span style="margin-left:5px">知识点 ( {{ originPointList.length }} )</span>
-							<Input icon="ios-close" v-model="searchPoint" v-show="originPointList.length" placeholder="搜索知识点..." autofocus style="width: 300px;margin-left: 20px;"
+							<span style="margin-left:5px">{{$t("knowledge.point")}} ( {{ originPointList.length }} )</span>
+							<Input icon="ios-close" v-model="searchPoint" v-show="originPointList.length" :placeholder="$t('knowledge.searchPoint')" autofocus style="width: 300px;margin-left: 20px;"
 							 @on-click="onSearchClear" @on-blur="isSearchPoint = false" @on-change="onSearchPointChange" @on-enter="onSearchPointChange"
 							 @on-clear="onSearchClear" />
 						</span>
 						<div>
 							<Icon type="md-add" v-if="($access.can('admin.*|Point_Add')) && subjectList.length" color="#fff" size="18" style="cursor:pointer;margin-right:10px"
 							 @click="onAddPoint" />
-							<Button class="btn-compose-block" v-if="checkedPointList.length" @click="onComposeBlock">组成知识块</Button>
+							<Button class="btn-compose-block" v-if="checkedPointList.length" @click="onComposeBlock">{{$t("knowledge.makeBlock")}}</Button>
 						</div>
 					</div>
 					<div class="ns-header-search" v-else>
@@ -80,11 +80,11 @@
 									 @click="onPointCheck(item,index)" draggable="true" @dragstart="onDragStart(item)" @dragend="isDragging = false">
 										<span>{{item}}</span>
 										<span class="point-item-tools">
-											<span class="btn-edit" v-if="$access.can('admin.*|Point_Edit') || tabIndex === 1" title="编辑" @click.stop="onEditPoint(item,index)">
+											<span class="btn-edit" v-if="$access.can('admin.*|Point_Edit') || tabIndex === 1" :title="$t('knowledge.edit')" @click.stop="onEditPoint(item,index)">
 												<Icon type="md-create" size="18" color="#d2d2d2" /></span>
-											<span class="btn-delete" v-if="$access.can('admin.*|Point_Delete') || tabIndex === 1" title="删除" @click.stop="onDeletePoint(item,index)">
+											<span class="btn-delete" v-if="$access.can('admin.*|Point_Delete') || tabIndex === 1" :title="$t('knowledge.delete')" @click.stop="onDeletePoint(item,index)">
 												<Icon type="md-trash" size="20" color="#d2d2d2" /></span>
-											<span class="btn-delete" v-if="$access.can('admin.*|Point_Remove') && isBlockPoint(item)" title="移出知识块"
+											<span class="btn-delete" v-if="$access.can('admin.*|Point_Remove') && isBlockPoint(item)" :title="$t('knowledge.moveBlock')"
 											 @click.stop="onRemovePoint(item)">
 												<Icon type="md-remove-circle" size="20" color="#d2d2d2" /></span>
 										</span>
@@ -103,7 +103,7 @@
 					<div class="ns-header-content" v-if="!isSearchBlock">
 						<span>
 							<Icon type="ios-photos" color="#fff" size="20" />
-							<span style="margin-left:5px">知识块</span>
+							<span style="margin-left:5px">{{$t("knowledge.block")}}</span>
 						</span>
 						<div>
 							<Icon type="md-add" v-if="($access.can('admin.*|Block_Add') || tabIndex === 1)  && subjectList.length" color="#fff" size="18" style="cursor:pointer;margin-right:10px"
@@ -113,7 +113,7 @@
 					</div>
 					<div class="ns-header-search" v-else>
 						<!-- 搜索知识块部分 -->
-						<Input icon="ios-close" v-model="searchBlock" placeholder="搜索知识块..." autofocus style="width: 100%" @on-click="onSearchBlockClose"
+						<Input icon="ios-close" v-model="searchBlock" :placeholder="$t('knowledge.searchBlock')" autofocus style="width: 100%" @on-click="onSearchBlockClose"
 						 @on-change="onSearchBlockChange" @on-enter="onSearchBlockChange" />
 					</div>
 				</div>
@@ -123,23 +123,23 @@
 						<div v-if="blockList.length === 0">
 							<div class="gl-item gl-new-area" v-show="isDragging" @drop="onDragNewEnd" @dragover.prevent>
 								<Icon type="md-add" size="18" />
-								<span style="margin-left: 10px;">新建知识块</span>
+								<span style="margin-left: 10px;">{{$t("knowledge.buildBlock")}}</span>
 							</div>
 							<EmptyData :top="50"></EmptyData>
 						</div>
 						<div v-else>
 							<div class="gl-item gl-new-area" v-show="isDragging" @drop="onDragNewEnd" @dragover.prevent>
 								<Icon type="md-add" size="18" />
-								<span style="margin-left: 10px;">新建知识块</span>
+								<span style="margin-left: 10px;">{{$t("knowledge.buildBlock")}}</span>
 							</div>
 							<div :class='["gl-item","drag-block-item",index == activeBlockIndex ? "item-active":""]' v-for="(item,index) in blockList"
 							 :key="index" @click="handleBlockTap(index,item)" @drop="onDragEnd(item,index,$event)" @dragover.prevent
 							 @dragend="onDragEnd(item,index)" @dragenter="onDragEnter" @dragleave="onDragLeave">
 								<p class="gl-item-name" :title="item.name">{{item.name}}</p>
-								<p class="gl-item-info"><span></span>知识点数:{{item.points ? item.points.length : 0}}</p>
-								<span class="btn-edit" v-if="$access.can('admin.*|Block_Edit') || tabIndex === 1" title="编辑" @click.stop="onEditBlock(index)">
+								<p class="gl-item-info"><span></span>{{$t("knowledge.pointCount")}}:{{item.points ? item.points.length : 0}}</p>
+								<span class="btn-edit" v-if="$access.can('admin.*|Block_Edit') || tabIndex === 1" :title="$t('knowledge.edit')" @click.stop="onEditBlock(index)">
 									<Icon type="md-create" size="20" color="#d2d2d2" /></span>
-								<span class="btn-delete" v-if="$access.can('admin.*|Block_Delete') || tabIndex === 1" title="删除" @click.stop="onDeleteBlock(item)">
+								<span class="btn-delete" v-if="$access.can('admin.*|Block_Delete') || tabIndex === 1" :title="$t('knowledge.delete')" @click.stop="onDeleteBlock(item)">
 									<Icon type="md-trash" size="22" color="#d2d2d2" /></span>
 							</div>
 						</div>
@@ -152,7 +152,7 @@
 
 		<!-- 新增知识块弹窗 -->
 		<Modal v-model="isAddBlock" width="560" footer-hide class="add-volume-modal">
-			<div class="modal-header" slot="header">{{ isEditBlock ? '编辑知识块' : '新增知识块'}}</div>
+			<div class="modal-header" slot="header">{{ isEditBlock ? $t('knowledge.editBlock') : $t('knowledge.addBlock')}}</div>
 			<div class="modal-content">
 				<AddBlock :originData="originSchoolData" :periodIndex="currentPeriodIndex" :subjectIndex="currentSubjectIndex"
 				 :editBlock="editBlock" :addType="pointOwn" @addFinish="onFinishAddBlock" :orginBlock="originBlockList">
@@ -162,7 +162,7 @@
 
 		<!-- 新增知识点弹窗 -->
 		<Modal v-model="isAddPoint" width="560" footer-hide class="add-volume-modal">
-			<div class="modal-header" slot="header">{{ isEditPoint ? '编辑知识点' : '新增知识点'}}</div>
+			<div class="modal-header" slot="header">{{ isEditPoint ? $t('knowledge.editPoint') : $t('knowledge.addPoint')}}</div>
 			<div class="modal-content">
 				<AddPoint :hideBlock="isShowPoints" :schoolParams="schoolParams" :blockData="parentBlock" :orginPoint="originPointList" :pointData="currentPoint"
 				 :addType="pointOwn" @addFinish="onFinishAddPoint">
@@ -172,7 +172,7 @@
 
 		<!-- 组成知识块弹窗 -->
 		<Modal v-model="isComposeBlock" width="680" footer-hide class="add-volume-modal compose-modal">
-			<div class="modal-header" slot="header">组成知识块</div>
+			<div class="modal-header" slot="header">{{$t("knowledge.makeBlock")}}</div>
 			<ComposeBlock :list="checkedPointList" :params="currentParams" :blockList="originBlockList" @onFinish="onComposeFinish"></ComposeBlock>
 		</Modal>
 	</div>
@@ -296,26 +296,26 @@ import { json } from 'd3'
 					let addPointIds = new Set([...checkPointIds].filter(x => !blockPointIds.has(x)))
 					if (addPointIds.size > 0) {
 						this.$Modal.confirm({
-							title: '提示',
-							content: `确定将 ${this.curDragPoint} 等 ${addPointIds.size} 个知识点移入到知识块 ${blockItem.name} 中 (已存在的知识点会自动忽略)?`,
-							okText: '确认',
-							cancelText: '取消',
+                            title: this.$t('knowledge.notice'),
+                            content: `${this.$t('knowledge.content0')} ${this.curDragPoint} ${this.$t('knowledge.content2')} ${addPointIds.size} ${this.$t('knowledge.content3')} ${blockItem.name} ${this.$t('knowledge.content1')}`,
+                            okText: this.$t('knowledge.confirm'),
+                            cancelText: this.$t('knowledge.cancel'),
 							onOk: () => {
 								blockItem.points.push(...addPointIds)
 							}
 						})
 					} else {
-						this.$Message.warning('所选知识点已存在于该知识块中!')
+                        this.$Message.warning(this.$t('knowledge.notice1'))
 					}
 				} else {
 					if (blockItem.points.includes(this.curDragPoint)) {
-						this.$Message.warning('该知识块已存在当前知识点!')
+                        this.$Message.warning(this.$t('knowledge.notice2'))
 					} else {
 						this.$Modal.confirm({
-							title: '提示',
-							content: `确定将知识点 ${this.curDragPoint} 移入到知识块 ${blockItem.name} 中?`,
-							okText: '确认',
-							cancelText: '取消',
+                            title: this.$t('knowledge.notice'),
+                            content: `${this.$t('knowledge.content4')} ${this.curDragPoint} ${this.$t('knowledge.content5')} ${blockItem.name}${this.$t('knowledge.content6')}`,
+                            okText: this.$t('knowledge.confirm'),
+                            cancelText: this.$t('knowledge.cancel'),
 							onOk: () => {
 								blockItem.points.push(this.curDragPoint)
 							}
@@ -349,15 +349,14 @@ import { json } from 'd3'
 							this.isLoading = false
 							this.checkedPointList = []
 							this.initBlockCount()
-							this.$Message.success('操作成功!')
+                            this.$Message.success(this.$t('knowledge.success'))
 							r(200)
 						} else {
                             this.isLoading = false
-							this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
 						}
 					}).catch(err => {
 						j(err)
-						this.$Message.warning('操作失败')
+                        this.$Message.warning(this.$t('knowledge.fail'))
 					})
 				})
 			},
@@ -408,7 +407,6 @@ import { json } from 'd3'
 				this.$api.knowledge.GetSchoolPoints(params).then(res => {
 					console.log(res.length)
                     if (res.length > 0) {
-                        console.log('知识点', JSON.stringify(res))
                         that.pointDatas = res
                         let list = res[0].blocks
                         this.blockList = list
@@ -436,7 +434,7 @@ import { json } from 'd3'
                         this.originBlockList = JSON.parse(JSON.stringify(list))
                     } 
 				}).catch(err => {
-					this.$Message.error('知识块数据获取失败')
+                    this.$Message.error(this.$t('knowledge.warn'))
 					this.isLoadBlocks = false
 				})
 			},
@@ -564,7 +562,7 @@ import { json } from 'd3'
 
 			// 添加知识块完成
 			onFinishAddBlock(val) {
-				this.$Message.success('操作成功!')
+                this.$Message.success(this.$t('knowledge.success'))
 				if (this.isEditBlock) {
 					let code = this.blockList.findIndex(item => item.name.indexOf(this.editBlock.name) > -1)
 					this.blockList[code].name = val.name
@@ -631,10 +629,10 @@ import { json } from 'd3'
 			// 删除知识块事件
 			onDeleteBlock(data) {
 				this.$Modal.confirm({
-					title: '提示',
-					content: '<p>确认删除该知识块?</p>',
-					okText: '确认',
-					cancelText: '取消',
+                    title: this.$t('knowledge.notice'),
+                    content: this.$t('knowledge.delBlock'),
+                    okText: this.$t('knowledge.confirm'),
+                    cancelText: this.$t('knowledge.cancel'),
 					onOk: () => {
 						let that = this
 						this.isLoading = true
@@ -646,10 +644,10 @@ import { json } from 'd3'
 								that.blockCounts = []
 								//that.initBlockCount()
 								that.isLoading = false
-								that.$Message.success('删除成功')
+                                that.$Message.success(this.$t('knowledge.delSuccess'))
 							}, 1000)
 						} else {
-							this.$Message.success('删除失败')
+                            this.$Message.success(this.$t('knowledge.delFail'))
 						}
 					}
 				})
@@ -658,13 +656,13 @@ import { json } from 'd3'
 			// 删除知识点事件
 			onDeletePoint(data) {
 				this.$Modal.confirm({
-					title: '提示',
-					content: '<p>确认删除该知识点?</p>',
-					okText: '确认',
-					cancelText: '取消',
+                    title: this.$t('knowledge.notice'),
+                    content: this.$t('knowledge.delPoint'),
+                    okText: this.$t('knowledge.confirm'),
+                    cancelText: this.$t('knowledge.cancel'),
 					onOk: () => {
 						this.isLoadPoints = true
-                        this.$Message.success('删除成功')
+                        this.$Message.success(this.$t('knowledge.delSuccess'))
                         this.pointList.splice(this.pointList.indexOf(data), 1)
                         if (!this.isShowPoints) this.currentBlock.points.splice(this.currentBlock.points.indexOf(data), 1)
 						this.actionPoint(data, 0)
@@ -677,19 +675,16 @@ import { json } from 'd3'
 			// 移除知识点事件
 			onRemovePoint(data) {
 				this.$Modal.confirm({
-					title: '提示',
-					content: `确定将知识点 ${data} 从知识块 ${this.currentBlock.name} 中移除?`,
-					okText: '确认',
-					cancelText: '取消',
+                    title: this.$t('knowledge.notice'),
+                    content: `${this.$t('knowledge.content7')} ${data} ${this.$t('knowledge.content8')} ${this.currentBlock.name} ${this.$t('knowledge.content9')}`,
+                    okText: this.$t('knowledge.confirm'),
+                    cancelText: this.$t('knowledge.cancel'),
 					onOk: () => {
 						if (this.currentBlock.points.includes(data)) {
 							this.currentBlock.points.splice(this.currentBlock.points.indexOf(data), 1)
 							this.originBlockList = [...this.blockList]
-								//this.curBlockPoints = []
-								//this.currentBlock = null
-								//this.activeBlockIndex = null
 						} else {
-							this.$Message.error('移除失败')
+                            this.$Message.error(this.$t('knowledge.moveFail'))
 						}
 					}
 				})
@@ -760,7 +755,7 @@ import { json } from 'd3'
 					this.checkedPointList = []
 					this.activeBlockIndex = null
 					this.curBlockPoints = []
-					this.$Message.success('操作成功')
+                    this.$Message.success(this.$t('knowledge.success'))
 					//this.initBlockCount()
 				}
 			},
@@ -825,14 +820,14 @@ import { json } from 'd3'
                     console.log(params)
                     this.$api.knowledge.SaveOrUpdateKnowledge(params).then(res => {
                         if (res) {
-							this.$Message.success('保存数据成功')
+                            this.$Message.success(this.$t('knowledge.saveSuccess'))
 							this.getPointsData()
 							this.initBlockCount()
                         } else {
-                            this.$Message.warning('保存数据失败')
+                            this.$Message.warning(this.$t('knowledge.saveFail'))
                         }
                     }).catch(err => {
-                        this.$Message.error('数据保存失败')
+                        this.$Message.error(this.$t('knowledge.saveFail'))
                         this.isLoadBlocks = false
                     })
                 }

+ 6 - 6
TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/AddBlock.vue

@@ -2,13 +2,13 @@
 <template>
     <div class="form-container">
         <Form :model="formTop" label-position="top">
-            <FormItem label="科目">
+            <!--<FormItem :label="$t('knowledge.subject')">
                 <Select v-model="formTop.subject">
                     <Option v-for="(item,index) in currentPeriod.subjects" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
-            </FormItem>
-            <FormItem label="名称">
-                <Input v-model="formTop.name" placeholder="请输入知识块名称,必填项"></Input>
+            </FormItem>-->
+            <FormItem :label="$t('knowledge.label')">
+                <Input v-model="formTop.name" :placeholder="$t('knowledge.blockP')" />
                 <vuescroll>
                     <ul class="search-list" v-show="filterData.length > 0">
                         <li v-for="(list,index) in filterData">
@@ -18,7 +18,7 @@
                 </vuescroll>
             </FormItem>
             <FormItem>
-                <Button @click="handleSubmit" :loading="isLoading">确认</Button>
+                <Button @click="handleSubmit" :loading="isLoading">{{$t("knowledge.confirm")}}</Button>
             </FormItem>
         </Form>
     </div>
@@ -56,7 +56,7 @@
             handleSubmit() {
                 let newName = this.formTop.name
                 if (!newName) {
-                    this.$Message.warning('知识块名称不能为空!')
+                    this.$Message.warning(this.$t('knowledge.blockWarning'))
                 } else {
                     this.isLoading = true
                     let params = {

+ 5 - 31
TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/AddPoint.vue

@@ -2,12 +2,11 @@
 <template>
     <div class="form-container">
         <Form :model="formTop" label-position="top">
-            <FormItem label="知识块" v-show="!hideBlock">
+            <FormItem :label="$t('knowledge.block')" v-show="!hideBlock">
                 <Input v-model="formTop.blockName" disabled />
             </FormItem>
-            <FormItem label="名称">
-                <Input v-model="formTop.name" placeholder="请输入知识点名称,必填项" />
-                <!--<span v-show="filterData.length > 0">已有知识点:</span>-->
+            <FormItem :label="$t('knowledge.label')">
+                <Input v-model="formTop.name" :placeholder="$t('knowledge.knowledgeP')" />
                 <vuescroll>
                     <ul class="search-list" v-show="filterData.length > 0">
                         <li v-for="(list,index) in filterData">
@@ -17,7 +16,7 @@
                 </vuescroll>
             </FormItem>
             <FormItem>
-                <Button @click="handleAddPointSubmit()" :loading="isLoading">确认</Button>
+                <Button @click="handleAddPointSubmit()" :loading="isLoading">{{$t("knowledge.confirm")}}</Button>
             </FormItem>
         </Form>
     </div>
@@ -51,14 +50,10 @@
         methods: {
             // 提交添加
             handleAddPointSubmit() {
-                console.log(this.formTop)
-                console.log(this.orginPoint)
-                console.log(this.filterData)
                 let newName = this.formTop.name
                 if (!newName) {
-                    this.$Message.warning('知识点名称不能为空!')
+                    this.$Message.warning(this.$t('knowledge.knowledgeWarning'))
                 } else {
-                    //let editPointItem = this.currentPoint
                     this.isLoading = true
                     let params = {
                         name: newName,
@@ -73,27 +68,6 @@
                 }
             },
 
-            /**
-             * 保存知识点
-             * @param pointItem
-             * @param BlockItem
-             */
-            savePointAndBlock(pointItem) {
-                this.$api.knowledge.SaveOrUpdateKnowledge([pointItem]).then(res => {
-                    if (!res.error && res.knowledges.length) {
-                        this.$emit('addFinish', res.knowledges[0])
-                        this.closeModal()
-                        this.currentPoint = null
-                        this.isLoading = false
-                    } else {
-                        this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-                    }
-                }).catch(err => {
-                    this.$Message.warning('操作失败')
-                })
-				this.isLoading = false
-            },
-
             // 添加完成 关闭窗口
             closeModal() {
                 this.formTop.name = ''

+ 10 - 11
TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/ComposeBlock.vue

@@ -2,15 +2,15 @@
 <template>
     <div class="compose-container">
         <Tabs value="0" @on-click="onTabChange">
-            <TabPane label="新增知识块" icon="md-folder" name="0">
+            <TabPane :label="$t('knowledge.newBlock')" icon="md-folder" name="0">
                 <div class="tab-content">
-                    <p class="tab-title">添加知识块</p>
-                    <Input v-model="newBlockName" placeholder="输入知识块名称" style="width: 98%;margin-left:1%" />
+                    <p class="tab-title">{{$t("knowledge.addBlock")}}</p>
+                    <Input v-model="newBlockName" :placeholder="$t('knowledge.blockP')" style="width: 98%;margin-left:1%" />
                 </div>
             </TabPane>
-            <TabPane label="现有知识块" icon="md-cube" name="1">
+            <TabPane :label="$t('knowledge.nowBlock')" icon="md-cube" name="1">
                 <div class="tab-content">
-                    <p class="tab-title">选择知识块 ( *若所选知识块内已存在添加的知识点则会覆盖 )</p>
+                    <p class="tab-title">{{$t("knowledge.nowBlockN")}}</p>
                     <Select v-model="selectBlock" transfer style="width: 98%;margin-left:1%">
                         <Option v-for="(item,index) in existBlockList" :value="item.name" :key="index">{{ item.name }}</Option>
                     </Select>
@@ -19,7 +19,7 @@
         </Tabs>
 
         <div class="show-wrap">
-            <p class="tab-title">已选知识点</p>
+            <p class="tab-title">{{$t("knowledge.selectPoint")}}</p>
             <div class="show-list">
                 <span class="point-item" v-for="(item,index) in checkedList" :key="index">
                 {{ item }}
@@ -28,7 +28,7 @@
             </div>
         </div>
 
-        <Button @click="currentTab === '0' ? handleSubmitNew() : handleSubmit()" :loading="isLoading">确认</Button>
+        <Button @click="currentTab === '0' ? handleSubmitNew() : handleSubmit()" :loading="isLoading">{{$t("knowledge.confirm")}}</Button>
     </div>
 </template>
 
@@ -65,7 +65,7 @@
                     let list = this.existBlockList.map(item => item.name)
                     let isExistIndex = list.indexOf(this.newBlockName)
                     if (isExistIndex > -1) {
-                        this.$Message.warning('已存在同名知识块,请修改名称!')
+                        this.$Message.warning(this.$t('knowledge.blockWarning2'))
                         this.isLoading = false
                     } else {
                         let params = {
@@ -77,14 +77,13 @@
                         this.newBlockName = ''
                     }
                 } else {
-                    this.$Message.warning('知识块名称不能为空')
+                    this.$Message.warning(this.$t('knowledge.blockWarning3'))
                     this.isLoading = false
                 }
             },
 
             // 提交新增知识块
             handleSubmit() {
-                console.log('156313561',this.existBlockList)
                 if (this.existBlockList.length) {
                     this.isLoading = true
 					let selectBlockItem = this.existBlockList.filter(item => item.name === this.selectBlock)[0]
@@ -94,7 +93,7 @@
                     this.$emit('onFinish', selectBlockItem)
                     this.isLoading = false
 				}else{
-					this.$Message.warning('无现有知识块选择!')
+					this.$Message.warning(this.$t('knowledge.blockWarning4'))
 				}
                 
             },

+ 100 - 0
TEAMModelOS/ClientApp/src/view/newcourse/ClassTable.less

@@ -0,0 +1,100 @@
+@first-bgColor: #141414;
+@second-bgColor: #1b1b1b;
+@third-bgColor: #222222;
+@borderColor: #424242;
+@primary-textColor: #fff; //文本主颜色
+@second-textColor: #a5a5a5; //文本副级颜色
+@primary-fontSize: 14px;
+@second-fontSize: 16px;
+
+.cus-table-container {
+    width: 100%;
+    // height: ~"calc(100% - 45px)";
+    height: 100%;
+    padding: 15px 0px 15px 10px;
+}
+.sch-title {
+    color: white;
+    text-align: center;
+    font-size: 25px;
+}
+
+.week-day-cell {
+    height: 76px;
+    position: relative;
+    cursor: pointer;
+}
+
+/*.week-day-cell:hover {
+    background: #404040;
+}*/
+
+.week-day-cell:hover {
+    .toggle-status-btn {
+        display: inline-block;
+    }
+}
+
+.vact-status {
+    background: linear-gradient( to top right, rgba(96,96,96, 0) 0%, rgba(96,96,96, 0) calc(50% - 1px), rgba(96,96,96, 1) 50%, rgba(96,96,96, 0) calc(50% + 1px), rgba(96,96,96, 0) 100% ) !important;
+}
+.cus-table-top {
+    width: 100%;
+    position: relative;
+    color: white;
+    // padding-top: 15px;
+}
+
+.course-name {
+    padding: 12px 4px 0px 4px;
+    font-size: 18px;
+    font-weight: 800;
+    text-overflow:ellipsis; 
+    overflow:hidden; 
+    white-space:nowrap; 
+}
+.course-color{
+    color: #ff9900;
+}
+.classroom-color{
+    color: #ff9900 !important;
+}
+.classroom-name {
+    color: #a5a5a5;
+    font-size: 14px;
+}
+.week-day-cell:hover .toggle-status-btn-wrap{
+    display:block;
+}
+.toggle-status-btn-wrap {
+    position: absolute;
+    left: 0px;
+    right: 0px;
+    top: 0px;
+    bottom: 0px;
+    background: rgba(100,100,100,.8);
+    display: none;
+}
+.cell-action-icon{
+    color:white;
+    font-size:22px;
+    margin:25px 5px 0px 5px;
+    &:hover{
+        color:#1cc0f3;
+    }
+
+}
+.am-pm{
+    padding:10px 0px 4px 0px;
+    font-size: 20px;
+    writing-mode: vertical-lr;
+    height:150px;
+    margin: auto;
+    letter-spacing: 4px;
+}
+.no-class-tips{
+    color: white;
+    text-align: center;
+    margin: 15px 0px;
+    font-size: 16px;
+}

+ 458 - 0
TEAMModelOS/ClientApp/src/view/newcourse/ClassTable.vue

@@ -0,0 +1,458 @@
+<template>
+    <div class="cus-table-container dark-iview-table">
+        <vuescroll>
+            <div class="cus-table-top dark-iview-input dark-iview-select">
+                <div class="class-filter-wrap">
+                </div>
+            </div>
+            <Table :columns="timeColumns" disabled-hover :data="timetable" border :span-method="handleSpan" style="width:calc(100% - 15px);margin-top:00px;">
+                <!--上午/下午-->
+                <template slot-scope="{ row, index }" slot="sub">
+                    <p class="am-pm" style="">
+                        {{parseInt(row.time.substr(0,2)) > 12 ? $t('cusMgt.pm') : $t('cusMgt.am')}}
+                    </p>
+                </template>
+                <!--时段-->
+                <template slot-scope="{ row, index }" slot="time">
+                    <p style="padding:10px 0px 4px 0px;font-size: 20px;">
+                        {{row.time}}
+                    </p>
+                    <p style="font-size:12px;padding:4px 0px 10px 0px;">
+                        {{'('+row.label+')'}}
+                    </p>
+                </template>
+                <!--星期一-->
+                <template slot-scope="{ row, column }" slot="MON">
+                    <div :class="row.weeklies.MON.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'">
+                            <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" :title="$t('cusMgt.setCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" :title="$t('cusMgt.modifyCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" :title="$t('cusMgt.cancelCus')" @click="cancelCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="schd.setCus && schd.setTea" type="md-copy" :title="$t('cusMgt.repeat')" @click="copyCell(row, column.slot)" />
+                        </div>
+                        <p :class="['course-name']">{{row.weeklies.MON.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.MON.teacherName}}</p>
+                    </div>
+                </template>
+                <!--星期二-->
+                <template slot-scope="{ row, column }" slot="TUE">
+                    <div :class="row.weeklies.TUE.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'">
+                            <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" :title="$t('cusMgt.setCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" :title="$t('cusMgt.modifyCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" :title="$t('cusMgt.cancelCus')" @click="cancelCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="schd.setCus && schd.setTea" type="md-copy" :title="$t('cusMgt.repeat')" @click="copyCell(row, column.slot)" />
+                        </div>
+                        <p :class="['course-name']">{{row.weeklies.TUE.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.TUE.teacherName}}</p>
+                    </div>
+                </template>
+                <!--星期三-->
+                <template slot-scope="{ row, column }" slot="WED">
+                    <div :class="row.weeklies.WED.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'">
+                            <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" :title="$t('cusMgt.setCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" :title="$t('cusMgt.modifyCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" :title="$t('cusMgt.cancelCus')" @click="cancelCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="schd.setCus && schd.setTea" type="md-copy" :title="$t('cusMgt.repeat')" @click="copyCell(row, column.slot)" />
+                        </div>
+                        <p :class="['course-name']">{{row.weeklies.WED.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.WED.teacherName}}</p>
+                    </div>
+                </template>
+                <!--星期四-->
+                <template slot-scope="{ row, column }" slot="THU">
+                    <div :class="row.weeklies.THU.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'">
+                            <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" :title="$t('cusMgt.setCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" :title="$t('cusMgt.modifyCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" :title="$t('cusMgt.cancelCus')" @click="cancelCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="schd.setCus && schd.setTea" type="md-copy" :title="$t('cusMgt.repeat')" @click="copyCell(row, column.slot)" />
+                        </div>
+                        <p :class="['course-name']">{{row.weeklies.THU.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.THU.teacherName}}</p>
+                    </div>
+                </template>
+                <!--星期五-->
+                <template slot-scope="{ row, column }" slot="FRI">
+                    <div :class="row.weeklies.FRI.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'">
+                            <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" :title="$t('cusMgt.setCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" :title="$t('cusMgt.modifyCus')" @click="selectCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" :title="$t('cusMgt.cancelCus')" @click="cancelCell(row, column.slot)" />
+                            <Icon class="cell-action-icon" v-show="schd.setCus && schd.setTea" type="md-copy" :title="$t('cusMgt.repeat')" @click="copyCell(row, column.slot)" />
+                        </div>
+                        <p :class="['course-name']">{{row.weeklies.FRI.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.FRI.teacherName}}</p>
+                    </div>
+                </template>
+                <!--星期六-->
+                <template slot-scope="{ row, column }" slot="SAT">
+                    <div :class="row.weeklies.SAT.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <p :class="['course-name']">{{row.weeklies.SAT.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.SAT.teacherName}}</p>
+                    </div>
+                </template>
+                <!--星期日-->
+                <template slot-scope="{ row, column }" slot="SUN">
+                    <div :class="row.weeklies.SUN.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
+                        <p :class="['course-name']">{{row.weeklies.SUN.courseName}}</p>
+                        <p :class="['classroom-name']">{{row.weeklies.SUN.teacherName}}</p>
+                    </div>
+                </template>
+            </Table>
+        </vuescroll>
+        <Modal v-model="modalStatus" :title="$t('cusMgt.cusClass')" @on-ok="modalOk" @on-cancel="modalCancel" class-name="dark-iview-modal dark-iview-form dark-iview-select">
+            <Form ref="setCusForm" :model="schd" :label-width="60" label-colon :rules="ruleValidate">
+                <FormItem label="课程" prop="setCus">
+                    <Select v-show="cusListShow.length" v-model="schd.setCus" filterable style="width:90%;" @on-change="getCusFullInfo">
+                        <Option v-for="(item,index) in cusListShow" :key="index" :value="item.id">{{item.name}}</Option>
+                    </Select>
+                </FormItem>
+                <FormItem label="教师" prop="setTea">
+                    <Select v-model="schd.setTea" filterable style="width:90%;" :not-found-text="schd.setCus ? '当前课程未添加授课老师' : '请先选择课程'">
+                        <Option v-for="(item,index) in cusTeaList" :key="index" :value="item.id">{{item.name}}</Option>
+                    </Select>
+                </FormItem>
+            </Form>
+        </Modal>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        periodId: {
+            type: String,
+            default: ''
+        },
+        //课程对象数据
+        schedData: {
+            type: Array,
+            default: () => {
+                return []
+            }
+        },
+        classId: {
+            type: String,
+            default: ''
+        },
+        mode: {
+            type: String,
+            default: 'set' //set:设置模式 view:视图模式,只渲染功能
+        }
+    },
+    data() {
+        return {
+            cusList: [],
+            classList: [],
+            setClass: '',
+            schd: {
+                setCus: '',
+                setTea: ''
+            },
+            ruleValidate: {
+                setCus: [
+                    { required: true, message: '请设置课程', trigger: 'change' }
+                ],
+                setTea: [
+                    { required: true, message: '请设置教师', trigger: 'change' }
+                ]
+            },
+            modalStatus: false,
+            subIndex: 0,
+            schoolBase: {
+                period: []
+            },
+            timeColumns: [
+                {
+                    title: ' ',
+                    slot: 'sub',
+                    width: 80,
+                    align: 'center',
+                    className: 'custom-bg'
+                },
+                {
+                    title: ' ',
+                    slot: 'time',
+                    width: 160,
+                    align: 'center'
+                },
+                {
+                    title: '星期一',
+                    slot: 'MON',
+                    align: 'center'
+                },
+                {
+                    title: '星期二',
+                    slot: 'TUE',
+                    align: 'center'
+                },
+                {
+                    title: '星期三',
+                    slot: 'WED',
+                    align: 'center'
+                },
+                {
+                    title: '星期四',
+                    slot: 'THU',
+                    align: 'center'
+                },
+                {
+                    title: '星期五',
+                    slot: 'FRI',
+                    align: 'center'
+                },
+                {
+                    title: '星期六',
+                    slot: 'SAT',
+                    align: 'center'
+                },
+                {
+                    title: '星期日',
+                    slot: 'SUN',
+                    align: 'center'
+                }
+            ],
+            selectInfo: {}
+        }
+    },
+    methods: {
+        //获取课程完整信息
+        getCusFullInfo(data) {
+            let cusIndex = -1
+            let cus = this.cusList.find((item, index) => {
+                cusIndex = index
+                return item.id == data
+            })
+            if (cus && !cus.schedule) {
+                //获取课程完整信息
+                let requestData = {
+                    'code': this.$store.state.userInfo.schoolCode,
+                    'scope': 'school',
+                    'id': data
+                }
+                this.$api.courseMgmt.findCusInfo(requestData).then(
+                    (res) => {
+                        if (!res.error && res.courses && res.courses.length > 0) {
+                            res.courses[0].schedule = res.courses[0].schedule ? res.courses[0].schedule : []
+                            this.$set(this.cusList, cusIndex, res.courses[0])
+                        }
+                    }
+                )
+            }
+        },
+        copyCell(row, col) {
+            let data = {
+                row,
+                col,
+                cusId: this.schd.setCus,
+                teaId: this.schd.setTea,
+                course: this.cusListShow.find(item => {
+                    return item.id == this.schd.setCus
+                })
+            }
+            this.$emit('selectCell', data)
+        },
+        selectCell(row, col) {
+            this.modalStatus = true
+            this.selectInfo = { row, col }
+        },
+        modalOk() {
+            this.$refs['setCusForm'].validate((valid) => {
+                if (valid) {
+                    let data = this._.cloneDeep(this.selectInfo)
+                    data.cusId = this.schd.setCus //当前设置的课程
+                    data.teaId = this.schd.setTea //当前设置的教师
+                    data.course = this.cusListShow.find(item => {
+                        return item.id == this.schd.setCus
+                    })
+                    this.$emit('selectCell', data)
+                } else {
+                    this.$Message.error('请完成设置信息!')
+                }
+            })
+        },
+        cancelCell(row, col) {
+            // let data = {
+            //     row,
+            //     col,
+            //     cusId: this.schd.setCus,
+            //     teaId: this.schd.setTea,
+            //     course: this.cusListShow.find(item => {
+            //         return item.id == this.schd.setCus
+            //     })
+            // }
+            // this.$emit('cancelCell', { row, col, setClass: row.weeklies[col].classId })
+            console.log(col,row)
+        },
+        modalCancel() {
+
+        },
+        //根据上下午合并单元格
+        handleSpan({ row, column, rowIndex, columnIndex }) {
+            this.getSubIndex()
+            if (rowIndex === 0 && columnIndex === 0) {
+                return [this.subIndex, 1]
+            } else if (rowIndex < this.subIndex && columnIndex === 0) {
+                return [0, 0]
+            }
+            if (rowIndex == this.subIndex && columnIndex === 0) {
+                return [this.timetable.length - this.subIndex, 1]
+            } else if (rowIndex > this.subIndex && columnIndex === 0) {
+                return [0, 0]
+            }
+        },
+        getSubIndex() {
+            for (let index in this.timetable) {
+                if (parseInt(this.timetable[index].time.substr(0, 2)) > 12) {
+                    this.subIndex = parseInt(index)
+                    break
+                }
+            }
+        },
+        //获取课程列表
+        getCourseList() {
+            let requestData = {
+                'code': this.$store.state.userInfo.schoolCode,
+                'scope': 'school'
+            }
+            this.$api.courseMgmt.findCourse(requestData).then(
+                (res) => {
+                    if (res) {
+                        this.cusList = res.courses
+                    }
+                }
+            ).finally(() => {
+                setTimeout(() => {
+                    this.tableLoading = false
+                    this.listLoading = false
+                }, 500)
+            })
+        },
+    },
+    created() {
+        //直接读取登录成功拿到得学校基础信息
+        this.$store.dispatch('user/getSchoolProfile').then(
+            res => {
+                this.schoolBase = res.school_base
+                this.classList = res.school_classes
+            },
+            err => {
+                this.$Message.warning(this.$t('cusMgt.noSchool'))
+            }
+        )
+        this.getCourseList()
+    },
+    watch: {
+        classId() {
+            this.schd = {
+                setCus: '',
+                setTea: ''
+            }
+        }
+    },
+    computed: {
+        //当前课程的授课老师
+        cusTeaList() {
+            if (this.schd.setCus) {
+                let cus = this.cusList.find(item => {
+                    return item.id == this.schd.setCus
+                })
+                if (cus && cus.schedule) {
+                    let all = cus.schedule.map(item => {
+                        return {
+                            id: item.teacherId,
+                            name: item.teacherName
+                        }
+                    })
+                    const res = new Map()
+                    let removeRep = all.filter((a) => !res.has(a.id) && res.set(a.id, 1))
+                    return removeRep
+                } else {
+                    return []
+                }
+            }
+            return []
+        },
+        //筛选当前学段的课程
+        cusListShow() {
+            if (this.periodId) {
+                let res = this.cusList.filter(item => {
+                    return item.period.id == this.periodId
+                })
+                return res
+            }
+            return this.cusList
+        },
+        timetable() {
+            let curPrd = this.schoolBase.period.find(item => {
+                return item.id == this.periodId
+            })
+            curPrd = curPrd || this.schoolBase.period[0] //没有传pdId就默认第一个
+            if (curPrd && curPrd.timetable) {
+                let timetable = this._.cloneDeep(curPrd.timetable)
+                timetable.forEach(item => {
+                    item.weeklies = {
+                        MON: {
+                            status: 1
+                        },
+                        TUE: {
+                            status: 1
+                        },
+                        WED: {
+                            status: 1
+                        },
+                        THU: {
+                            status: 1
+                        },
+                        FRI: {
+                            status: 1
+                        },
+                        SAT: {},
+                        SUN: {},
+                    }
+                    // 根据课程数据补充课程表
+                    this.schedData.forEach(cusItem => {
+                        if (cusItem && cusItem.schedule) {
+                            cusItem.schedule.forEach((schedItem, sIndex) => {
+                                let classInfo = this.classList.find(classItem => {
+                                    return classItem.id == schedItem.classId
+                                })
+                                if (this.classId) {
+                                    if (this.classId != schedItem.classId) {
+                                        return false
+                                    }
+                                }
+                                schedItem.time.forEach(timeItem => {
+                                    if (timeItem.id == item.id) {
+                                        item.weeklies[timeItem.week].courseName = cusItem.name
+                                        item.weeklies[timeItem.week].courseId = cusItem.id
+                                        item.weeklies[timeItem.week].classId = schedItem.classId
+                                        item.weeklies[timeItem.week].classroomName = classInfo ? classInfo.name : '--'
+                                        item.weeklies[timeItem.week].teacherName = schedItem.teacherName
+                                    }
+                                })
+                            })
+
+                        }
+                    })
+                })
+                return timetable
+            } else {
+                return []
+            }
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+@import "./ClassTable.less";
+</style>
+<style lang="less">
+.cus-table-container .ivu-table {
+    width: 100%;
+}
+.ivu-table .custom-bg {
+    background: #404040 !important;
+}
+</style>

+ 8 - 3
TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.less

@@ -118,13 +118,15 @@
 }
 .cus-table {
     width: ~"calc(100% - 15px)";
-    margin-top: 25px;
+    margin-top: 15px;
 }
 .sch-title {
     color: white;
     text-align: center;
-    padding-top: 5px;
-    font-size: 25px;
+    padding-top: 10px;
+    font-size: 20px;
+    // position: sticky;
+    top: 0px;
 }
 .cus-table-top{
     width:100%;
@@ -174,4 +176,7 @@
         cursor: not-allowed !important;
         color: #606060 !important;
     }
+}
+.cus-table-content{
+    height: ~"calc(100% - 45px)";
 }

+ 132 - 369
TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.vue

@@ -3,7 +3,8 @@
         <div class="class-list-wrap">
             <div class="class-list-header">
                 <div v-if="!isSearch">
-                    <span>班级列表</span>
+                    <!-- <span>班级列表</span> -->
+                    <BasePdSelect @pd-change="filterByPeriod"></BasePdSelect>
                     <Icon type="md-search" class="action-btn-icon" @click="toggleSearch" />
                 </div>
                 <div v-else class="dark-iview-input">
@@ -42,111 +43,8 @@
             </div>
             <div class="cus-table-content dark-iview-table">
                 <vuescroll>
-                    <div class="cus-table-top dark-iview-input dark-iview-select">
-                        <div class="semester-filter-wrap">
-                            <!--<span class="label">学期</span>
-                        <Select v-model="semester" size="small" style="width: 200px;display:inline-block;">
-                            <Option v-for="(item,index) in semesterList.semesters" :value="item.semesterCode">{{item.semesterName}}</Option>
-                        </Select>-->
-                        </div>
-                        <h1 class="sch-title">课程表</h1>
-                    </div>
-                    <div v-if="this.classListShow[this.curClassIndex]">
-                        <Table :columns="timeColumns" disabled-hover :data="classListShow[curClassIndex].classPlan" border :span-method="handleSpan" class="cus-table">
-                            <!--上午/下午-->
-                            <template slot-scope="{ row, index }" slot="sub">
-                                <p style="padding:10px 0px 4px 0px;font-size: 20px;">
-                                    {{parseInt(row.time.substr(0,2)) > 12 ? '下午':'上午'}}
-                                </p>
-                            </template>
-                            <!--时段-->
-                            <template slot-scope="{ row, index }" slot="time">
-                                <p style="padding:10px 0px 4px 0px;font-size: 20px;">
-                                    {{row.time}}
-                                </p>
-                                <p style="font-size:12px;padding:4px 0px 10px 0px;">
-                                    {{'('+row.label+')'}}
-                                </p>
-                            </template>
-                            <!--星期一-->
-                            <template slot-scope="{ row, index }" slot="MON">
-                                <div :class="row.weeklies.MON.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div v-if="row.weeklies.MON.status == 1" class="toggle-status-btn-wrap">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'MON')" />
-                                        <Icon v-if="row.weeklies.MON.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'MON')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.MON.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.MON.teacher}}</p>
-                                </div>
-                            </template>
-                            <!--星期二-->
-                            <template slot-scope="{ row, index }" slot="TUE">
-                                <div :class="row.weeklies.TUE.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div v-if="row.weeklies.TUE.status == 1" class="toggle-status-btn-wrap">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'TUE')" />
-                                        <Icon v-if="row.weeklies.TUE.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'TUE')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.TUE.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.TUE.teacher}}</p>
-                                </div>
-                            </template>
-                            <!--星期三-->
-                            <template slot-scope="{ row, index }" slot="WED">
-                                <div :class="row.weeklies.WED.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div v-if="row.weeklies.WED.status == 1" class="toggle-status-btn-wrap">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'WED')" />
-                                        <Icon v-if="row.weeklies.WED.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'WED')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.WED.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.WED.teacher}}</p>
-                                </div>
-                            </template>
-                            <!--星期四-->
-                            <template slot-scope="{ row, index }" slot="THU">
-                                <div :class="row.weeklies.THU.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div class="toggle-status-btn-wrap" v-if="row.weeklies.THU.status == 1">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'THU')" />
-                                        <Icon v-if="row.weeklies.THU.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'THU')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.THU.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.THU.teacher}}</p>
-                                </div>
-                            </template>
-                            <!--星期五-->
-                            <template slot-scope="{ row, index }" slot="FRI">
-                                <div :class="row.weeklies.FRI.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div v-if="row.weeklies.FRI.status == 1" class="toggle-status-btn-wrap">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'FRI')" />
-                                        <Icon v-if="row.weeklies.FRI.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'FRI')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.FRI.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.FRI.teacher}}</p>
-                                </div>
-                            </template>
-                            <!--星期六-->
-                            <template slot-scope="{ row, index }" slot="SAT">
-                                <div :class="row.weeklies.SAT.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div v-if="row.weeklies.SAT.status == 1" class="toggle-status-btn-wrap">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'SAT')" />
-                                        <Icon v-if="row.weeklies.SAT.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'SAT')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.SAT.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.SAT.teacher}}</p>
-                                </div>
-                            </template>
-                            <!--星期日-->
-                            <template slot-scope="{ row, index }" slot="SUN">
-                                <div :class="row.weeklies.SUN.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                                    <div v-if="row.weeklies.SUN.status == 1" class="toggle-status-btn-wrap">
-                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'SUN')" />
-                                        <Icon v-if="row.weeklies.SUN.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'SUN')" />
-                                    </div>
-                                    <p class="course-name">{{row.weeklies.SUN.courseName}}</p>
-                                    <p class="teacher-name">{{row.weeklies.SUN.teacher}}</p>
-                                </div>
-                            </template>
-                        </Table>
-                    </div>
+                    <!-- 班级课程表 -->
+                    <ClassTable v-if="this.classListShow[this.curClassIndex]" :schedData="classCus" :periodId="pdId" @selectCell="selectCell"></ClassTable>
                     <Loading v-if="isLoading" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
                 </vuescroll>
             </div>
@@ -168,35 +66,21 @@
                 </span>
             </div>
         </Modal>
-        <Modal v-model="setCusStatus" title="设置课程" class-name="dark-iview-modal dark-iview-form" @on-ok="confirmSetCus" @on-cancel="cancelSetCus">
-            <Form :model="cusItem" :label-width="90">
-                <FormItem label="课程名称">
-                    <Select v-model="cusItem.courseId">
-                        <Option v-for="(item,index) in courseList" :key="index" :value="item.id">{{item.courseName}}</Option>
-                    </Select>
-                </FormItem>
-                <FormItem label="授课老师">
-                    <Select v-model="cusItem.teacher">
-                        <Option v-for="(item,index) in cusTeaList" :key="index" :value="item.id">{{item.name}}</Option>
-                    </Select>
-                </FormItem>
-            </Form>
-        </Modal>
-        <Modal v-model="cancelCusStatus" title="取消课程" class-name="dark-iview-modal dark-iview-form" @on-ok="confirmCancelCus">
-            <p v-if="delCusInfo.row" style="color:white;font-size:16px;">确认取消当前课程?</p>
-        </Modal>
         <Modal v-model="confImpStatus" title="确认导入" class-name="dark-iview-modal dark-iview-form" @on-ok="importCus">
             <p style="color:white;font-size:16px;">批量导入课程将覆盖班级原来的课表,确认批量导入并且覆盖原来的课表?</p>
         </Modal>
     </div>
 </template>
 <script>
+import ClassTable from "./ClassTable.vue"
 export default {
     components: {
+        ClassTable
     },
     inject: ['reload'],
     data() {
         return {
+            pdId: '',
             confImpStatus: false,
             classFilter: {
                 keyWord: ''
@@ -204,12 +88,6 @@ export default {
             isSearch: false,
             isLoading: false,
             courseList: [],
-            cusItem: {
-                courseId: '',
-                teacher: '',
-                row: {},
-                day: ''
-            },
             delCusInfo: {},
             errorClass: [],
             errorCourse: [],
@@ -218,8 +96,6 @@ export default {
             headerKeys: ['classroomCode', 'courseName', 'courseCode', 'teacher', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'],
             headerTitles: ['班级', '课程名称', '课程编码', '授课老师', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
             importCusStatus: false,
-            setCusStatus: false,
-            cancelCusStatus: false,
             moreClass: false,
             schoolInfo: {},
             subIndex: 0,
@@ -229,175 +105,72 @@ export default {
             curClassIndex: 0,
             tableData: [],
             importData: [],
-            timeColumns: [
-                {
-                    title: ' ',
-                    slot: 'sub',
-                    width: 100,
-                    align: 'center',
-                    className: 'custom-bg'
-                },
-                {
-                    title: ' ',
-                    slot: 'time',
-                    width: 200,
-                    align: 'center'
-                },
-                {
-                    title: '星期一',
-                    slot: 'MON',
-                    align: 'center'
-                },
-                {
-                    title: '星期二',
-                    slot: 'TUE',
-                    align: 'center'
-                },
-                {
-                    title: '星期三',
-                    slot: 'WED',
-                    align: 'center'
-                },
-                {
-                    title: '星期四',
-                    slot: 'THU',
-                    align: 'center'
-                },
-                {
-                    title: '星期五',
-                    slot: 'FRI',
-                    align: 'center'
-                },
-                {
-                    title: '星期六',
-                    slot: 'SAT',
-                    align: 'center'
-                },
-                {
-                    title: '星期日',
-                    slot: 'SUN',
-                    align: 'center'
-                }
-            ]
+            allClassCus: {}
         }
     },
     methods: {
+        filterByPeriod(pd) {
+            console.log(pd)
+            this.pdId = pd
+            this.curClassIndex = 0
+            if (pd) {
+                this.classListShow = this.classList.filter(item => item.periodId == pd || !item.periodId)
+            } else {
+                this.classListShow = [...this.classList]
+            }
+            // 排序
+            this.classListShow = this.dataSort(this.classListShow)
+        },
+        dataSort(data) {
+            switch (this.orderBy) {
+                case 'id': // ID 排序
+                    data.sort(function (a, b) {
+                        let nameA = a.id.toUpperCase(); // ignore upper and lowercase
+                        let nameB = b.id.toUpperCase(); // ignore upper and lowercase
+                        if (nameA < nameB) {
+                            return -1;
+                        }
+                        if (nameA > nameB) {
+                            return 1;
+                        }
+
+                        // names must be equal
+                        return 0;
+                    })
+                    break;
+                case 'state': // 智慧教室排序
+                    data.sort(function (a, b) {
+                        if (a.style == 'smart') {
+                            return 1
+                        } else {
+                            return -1
+                        }
+                    })
+                    break; // 學生總數排序
+                case 'total':
+                    data.sort(function (a, b) {
+                        return b.studCount - a.studCount;
+                    })
+                    break;
+            }
+            return data
+        },
         // 切换课表模式和课程模式
         toggleView() {
             this.$router.push({
                 name: 'NewCusMgt'
             })
         },
-        showCancelCus(row, day) {
-            this.cancelCusStatus = true
-
-            this.delCusInfo.row = row
-            this.delCusInfo.day = day
-        },
-        //确认取消课程
-        confirmCancelCus() {
-            let requestData = {
-                id: this.delCusInfo.row.weeklies[this.delCusInfo.day].courseId,
-                code: this.delCusInfo.row.weeklies[this.delCusInfo.day].teacherCode,
-                classroomCode: this.classListShow[this.curClassIndex].classroomCode,
-                time: this.delCusInfo.row.time,
-                day: this.delCusInfo.day
-            }
-            this.isLoading = true
-            this.$api.courseMgmt.deleteTime(requestData).then(
-                (res) => {
-                    if (!res.error) {
-                        this.$Message.success('取消成功')
-                        this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].teacher = undefined
-                        this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].teacherCode = undefined
-                        this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].courseName = undefined
-                        this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].courseId = undefined
-                        let tempArr = JSON.parse(JSON.stringify(this.classListShow[this.curClassIndex].classPlan))
-                        this.classListShow[this.curClassIndex].classPlan = []
-                        this.classListShow[this.curClassIndex].classPlan = [...tempArr]
-                    }
-                    this.isLoading = false
-                },
-                (err) => {
-                    this.$Message.error('取消失败')
-                    this.isLoading = false
-                }
-            )
-        },
         //关键字搜索班级
         onSearchClass() {
             this.classListShow = this.classList.filter((item) => {
-                return item.classroomName.indexOf(this.classFilter.keyWord) !== -1
+                return item.name.indexOf(this.classFilter.keyWord) !== -1
             })
         },
         /**切换搜索状态 */
         toggleSearch() {
             this.isSearch = !this.isSearch
         },
-        //获取课程列表
-        getCourseList() {
-            let requestData = {
-                code: this.$store.state.userInfo.schoolCode
-            }
-            this.$api.courseMgmt.findCourse(requestData).then(
-                (res) => {
-                    if (res.error == null) {
-                        this.courseList = res.result.data
-                    }
-                },
-                (err) => {
-                    this.$Message.error('API error!')
-                }
-            )
-        },
-        //取消设置课程
-        cancelSetCus() {
-            this.cusItem.teacher = ''
-            this.cusItem.courseId = ''
-        },
-        //确认设置课程
-        confirmSetCus() {
-            this.isLoading = true
-            let requestData = {
-                courseId: this.cusItem.courseId,
-                classroomCode: this.classListShow[this.curClassIndex].classroomCode,
-                code: this.cusItem.teacher,
-                courseTime: {
-                    label: this.cusItem.row.label,
-                    time: this.cusItem.row.time,
-                    day: this.cusItem.day
-                }
-            }
-            this.$api.courseMgmt.upsertPlanDto(requestData).then(
-                (res) => {
-                    if (!res.error && res.result.data) {
-                        this.$set(this.classListShow[this.curClassIndex].classPlan[this.cusItem.row._index].weeklies[this.cusItem.day], 'courseName', this.courseList.filter((item) => {
-                            return item.id == this.cusItem.courseId
-                        })[0].courseName)
-
-                        this.$set(this.classListShow[this.curClassIndex].classPlan[this.cusItem.row._index].weeklies[this.cusItem.day], 'teacher', this.cusTeaList.filter((item) => {
-                            return item.id == this.cusItem.teacher
-                        })[0].name)
-
-                        this.$Message.success('设置成功!')
-                        this.cusItem.teacher = ''
-                        this.cusItem.courseId = ''
-                    } else {
-                        this.$Message.error('设置失败!')
-                    }
-                    this.isLoading = false
-                },
-                (err) => {
-                    this.isLoading = false
-                }
-            )
-        },
-        //显示设置课程对话框
-        showSetCus(row, day) {
-            this.cusItem.row = row
-            this.cusItem.day = day
-            this.setCusStatus = true
-        },
         //处理表格导入的数据
         getTableData(data) {
             this.excelData = data
@@ -512,75 +285,26 @@ export default {
         },
         selectClass(index) {
             this.curClassIndex = index
-            this.isLoading = true
-            if (!this.classListShow[this.curClassIndex].isFull) {
-                this.findClassPlan()
-            } else {
-                setTimeout(() => {
-                    this.isLoading = false
-                }, 500)
-            }
-        },
-        //根据上下午合并单元格
-        handleSpan({ row, column, rowIndex, columnIndex }) {
-            this.getSubIndex()
-            if (rowIndex === 0 && columnIndex === 0) {
-                return [this.subIndex, 1]
-            } else if (rowIndex < this.subIndex && columnIndex === 0) {
-                return [0, 0]
-            }
-            if (rowIndex == this.subIndex && columnIndex === 0) {
-                return [this.schoolInfo.timetable.length - this.subIndex, 1]
-            } else if (rowIndex > this.subIndex && columnIndex === 0) {
-                return [0, 0]
-            }
-        },
-        //计算上下午分割点
-        getSubIndex() {
-            for (let index in this.schoolInfo.timetable) {
-                if (parseInt(this.tableData[index].time.substr(0, 2)) > 12) {
-                    this.subIndex = parseInt(index)
-                    break
-                }
+            let classId = this.classListShow[this.curClassIndex].id
+            if (!this.allClassCus[classId]) {
+                this.isLoading = true
+                this.findClassCus()
             }
         },
+
         //根据班级查询课程安排
-        findClassPlan() {
+        findClassCus() {
             if (this.classListShow.length > 0) {
+                let classId = this.classListShow[this.curClassIndex].id
                 let requestData = {
-                    "classes[*].classroomCode": this.classListShow[this.curClassIndex].classroomCode
+                    id: classId,
+                    code: this.$store.state.userInfo.schoolCode,
+                    scope: 'school'
                 }
-                this.$api.courseMgmt.findPlan(requestData).then(
+                this.$api.courseMgmt.findCusByClass(requestData).then(
                     (res) => {
-                        if (res.error == null) {
-                            let jStr = JSON.stringify(this.tableData)
-                            this.$set(this.classListShow[this.curClassIndex], 'classPlan', JSON.parse(jStr))
-                            for (let planItem of res.result.data) {
-                                let course = this.courseList.filter((item) => {
-                                    return item.id == planItem.id
-                                })
-                                let courseName = course.length > 0 ? course[0].courseName : '无课程名'
-                                let teacher = this.$store.state.teachers.teacherList.filter((item) => {
-                                    return item.id == planItem.code
-                                })
-                                let teacherName = teacher.length > 0 ? teacher[0].name : '无名称'
-                                let realClass = planItem.classes.filter((item) => {
-                                    return item.classroomCode == this.classListShow[this.curClassIndex].classroomCode
-                                })
-                                for (let timeItem of realClass[0].courseTimes) {
-                                    //可优化
-                                    for (let i = 0; i < this.classListShow[this.curClassIndex].classPlan.length; i++) {
-                                        if (timeItem && this.classListShow[this.curClassIndex].classPlan[i].time == timeItem.time) {
-                                            this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].teacher = teacherName
-                                            this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].teacherCode = planItem.code
-                                            this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].courseName = courseName
-                                            this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].courseId = planItem.id
-                                            break
-                                        }
-                                    }
-                                }
-                            }
-                            this.classListShow[this.curClassIndex].isFull = true
+                        if (!res.error) {
+                            this.$set(this.allClassCus, classId, res.courses)
                             this.isLoading = false
                         } else {
                             this.$Message.error('API error!')
@@ -594,9 +318,63 @@ export default {
             } else {
                 this.isLoading = false
             }
-        }
+        },
+        //设置课程事件
+        selectCell(data) {
+            console.log('设置数据', data)
+            //data里面包含当前课程完整信息
+            let course = data.course
+            course.schedule = course.schedule || []
+            let schedule = course.schedule.find(item => {
+                return item.classId == this.classListShow[this.curClassIndex].id && item.teacherId == data.teaId
+            })
+            if (schedule) {
+                schedule.time.push({
+                    week: data.col,
+                    id: data.row.id
+                })
+            } else {
+                schedule = {
+                    classId: this.classListShow[this.curClassIndex].id,
+                    notice: '',
+                    stulist: '',
+                    teacherId: data.teaId,
+                    time: []
+                }
+                schedule.time.push({
+                    week: data.col,
+                    id: data.row.id
+                })
+                course.schedule.push(schedule)
+            }
+            console.log(course)
+            this.updCusInfo(course)
+        },
+        // 更新课程数据
+        updCusInfo(course) {
+            course.code = course.code.replace('Course-', '')
+            this.$api.courseMgmt.saveOrUpdateCourse({
+                course: course,
+                option: 'update',
+                scope: course.scope || 'school'
+            }).then(
+                res => {
+                    this.$Message.success(this.$t('cusMgt.updateOk'))
+                    //更新成功后,更新本地数据,刷新课程表
+                    let classId = this.classListShow[this.curClassIndex].id
+                    this.allClassCus[classId] = this.allClassCus[classId] || []
+                    this.allClassCus[classId].forEach((item, index) => {
+                        if (item.id == course.id) {
+                            this.allClassCus[classId].splice(index, 1, course)
+                        }
+                    })
+                }
+            ).catch(() => {
+                this.$Message.error(this.$t('cusMgt.updateErr'))
+            })
+        },
     },
-    async created() {
+    created() {
         //直接读取登录成功拿到得学校基础信息
         this.$store.dispatch('user/getSchoolProfile').then(
             res => {
@@ -611,34 +389,19 @@ export default {
             err => {
                 this.$Message.warning(this.$t('cusMgt.noSchool'))
             }
-        )
-        this.getCourseList()
-        await this.$store.dispatch('teachers/getTeacherList')
-        this.findClassPlan()
-    },
-    mounted() {
+        ).finally(() => {
+            this.findClassCus()
+        })
     },
     computed: {
-        cusTeaList() {
-            let curCourse = this.courseList.filter((item) => {
-                return item.id == this.cusItem.courseId
-            })
-            if (curCourse.length > 0) {
-                return this.$store.state.teachers.teacherList.filter((item) => {
-                    return curCourse[0].teachers.indexOf(item.id) !== -1
-                })
+        //当前班级对应的课程数据
+        classCus() {
+            let classId = this.classListShow[this.curClassIndex].id
+            if (classId && this.allClassCus[classId]) {
+                return this.allClassCus[classId]
             } else {
                 return []
             }
-        },
-        semesterList() {
-            if (this.classListShow.length > 0) {
-                let data = this.$jsFn.getPeriod(this.$store.state.user.schoolProfile.school_base, this.classListShow[this.curClassIndex].periodCode)
-
-                return data
-            } else {
-                return {}
-            }
         }
     }
 }

+ 4 - 4
TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue

@@ -1087,10 +1087,10 @@ export default {
         },
         // 切换课表模式和课程模式
         toggleView() {
-            // this.$router.push({
-            //     name: 'CoursePlan'
-            // })
-            this.$Message.warning('课表模式开发中...')
+            this.$router.push({
+                name: 'CoursePlan'
+            })
+            // this.$Message.warning('课表模式开发中...')
         },
         dropdownStates(flag) {
             if (!flag) this.filterByPeriod()

+ 2 - 0
TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue

@@ -285,6 +285,7 @@ export default {
             let curPrd = this.schoolBase.period.find(item => {
                 return item.id == this.periodId
             })
+            curPrd = curPrd || this.schoolBase.period[0] //没有传pdId就默认第一个
             if (curPrd && curPrd.timetable) {
                 let timetable = this._.cloneDeep(curPrd.timetable)
                 timetable.forEach(item => {
@@ -307,6 +308,7 @@ export default {
                         SAT: {},
                         SUN: {},
                     }
+                    // 根据课程数据补充课程表
                     this.schedData.forEach(cusItem => {
                         if (cusItem && cusItem.schedule) {
                             cusItem.schedule.forEach((schedItem, sIndex) => {

+ 102 - 118
TEAMModelOS/Controllers/School/ClassRoomController.cs

@@ -54,7 +54,7 @@ namespace TEAMModelOS.Controllers
                 //students = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "classroomCode", classroom.id } });
                 if (option.ToString().Equals("insert"))
                 {
-                    if (classroom.scope.Equals("private"))
+                    /*if (classroom.scope.Equals("private"))
                     {
                         List<string> resultIds = new List<string>();
                         await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
@@ -89,7 +89,7 @@ namespace TEAMModelOS.Controllers
                         }
                     }
                     else
-                    {
+                    {*/
                         List<string> resultIds = new List<string>();
                         await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                         {
@@ -121,47 +121,24 @@ namespace TEAMModelOS.Controllers
                             classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(classroom, new PartitionKey($"Class-{school_code}"));
 
                         }
-                    }
+                   // }
                 }
                 else
                 {
-
-                    if (classroom.scope.Equals("private"))
-                    {
-                        List<string> resultIds = new List<string>();
-                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
-                        {
-                            using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
-                            {
-                                var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
-                                while (accounts.MoveNext())
-                                {
-                                    JsonElement account = accounts.Current;
-                                    resultIds.Add(account.GetProperty("id").GetString());
-                                }
-                            }
-                        }
-                        if (resultIds.Count > 0)
-                        {
-                            return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在!" });
-                        }
-                        //Class own = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Class>(classroom.id, new PartitionKey($"Class-{school_code}"));
-                        classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
-                    }
-                    else
+                    var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
+                    if (response.Status == 200)
                     {
-                        //检查该教室是否是老师创建的个人校本教室
-                        var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
-                        if (response.Status == 200)
+                        using var json = await JsonDocument.ParseAsync(response.ContentStream);
+                        Class @class = json.ToObject<Class>();
+                        if (!@class.no.Equals(classroom.no))
                         {
                             List<string> resultIds = new List<string>();
-                            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
+                            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                             {
-                                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                                using var document = await JsonDocument.ParseAsync(item.ContentStream);
+                                if (document.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                 {
-                                    var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                                    var accounts = document.RootElement.GetProperty("Documents").EnumerateArray();
                                     while (accounts.MoveNext())
                                     {
                                         JsonElement account = accounts.Current;
@@ -173,12 +150,18 @@ namespace TEAMModelOS.Controllers
                             {
                                 return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在!" });
                             }
-                            classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
                         }
-                        else
+                        classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
+                    }
+                    else {
+                        classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(classroom, new PartitionKey($"Class-{school_code}"));
+                    }                                       
+                        //检查该教室是否是老师创建的个人校本教室
+                        /*var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
+                        if (response.Status == 200)
                         {
                             List<string> resultIds = new List<string>();
-                            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
+                            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                             {
                                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
                                 if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -195,87 +178,88 @@ namespace TEAMModelOS.Controllers
                             {
                                 return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在!" });
                             }
-                            /*List<StudentSimple> studentSimples = new List<StudentSimple>();
-                            StringBuilder sql = new StringBuilder();
-                            sql.Append("select A0.id,A0.name,A0.no from c join A0 in c.students ");
-                            Dictionary<string, object> dict = new Dictionary<string, object>();
-                            dict.Add("scope", classroom.scope);
-                            dict.Add("id", classroom.id);
-                            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
-                            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
-                            {
-                                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
-                                {
-                                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                                    {
-                                        studentSimples.Add(obj.ToObject<StudentSimple>());
-                                    }
-                                }
-                            }
-                            classroom.students = studentSimples;*/
-
-                            List<TeacherCourse> course = new List<TeacherCourse>();
-                            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select value(c) from c join A0 in c.classes where A0.id = '{classroom.id}'"))
-                            {
-                                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
-                                {
-                                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                                    {
-                                        course.Add(obj.ToObject<TeacherCourse>());
-                                    }
-                                }
-                            }
-
-                            for (int i = 0; i < course.Count; i++)
-                            {
-                                bool flag = false;
-                                for (int j = 0; j < course[i].classes.Count; j++)
-                                {
-                                    if (!course[i].classes[j].name.Equals(classroom.name))
-                                    {
-                                        flag = true;
-                                        course[i].classes[j].name = classroom.name;
-                                        //break;
-                                    }
-                                    if (!course[i].classes[j].teacher.id.Equals(classroom.teacher.id))
-                                    {
-                                        flag = true;
-                                        course[i].classes[j].teacher.id = classroom.teacher.id;
-                                        course[i].classes[j].teacher.name = classroom.teacher.name;
-                                        //break;
-                                    }
-                                }
-                                if (flag)
-                                {
-                                    await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(course[i], course[i].id, new PartitionKey($"{course[i].code}"));
-                                }
-                            }
-                            //string code = classroom.code.Substring(classroom.pk.Length + 1);
-                            //[Jeff] CourseManagement表廢除 刪除預定:以下CourseManagement更新程序
-                            var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"CourseManagement-{school_code}"));
-                            if (sresponse.Status == 200)
-                            {
-                                using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
-                                CourseManagement classroom1 = json.ToObject<CourseManagement>();
-                                if (!classroom1.name.Equals(classroom.name))
-                                {
-                                    classroom1.name = classroom.name;
-                                    await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom1.code}"));
-                                }
-                                if (!string.IsNullOrEmpty(classroom1.teacher.id) && !string.IsNullOrEmpty(classroom.teacher.id) && !classroom1.teacher.id.Equals(classroom.teacher.id))
-                                {
-                                    classroom1.teacher.name = classroom.teacher.name;
-                                    classroom1.teacher.id = classroom.teacher.id;
-                                    await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom1.code}"));
-                                }
-                            }
-                            ////[Jeff] CourseManagement表廢除 刪除預定:以下CourseManagement更新程序
-                            classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
+                            classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
                         }
-
-                    }
+                        else
+                        {*/
+                        /*                            List<string> resultIds = new List<string>();
+                                                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
+                                                    {
+                                                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                                                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                                                        {
+                                                            var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                                                            while (accounts.MoveNext())
+                                                            {
+                                                                JsonElement account = accounts.Current;
+                                                                resultIds.Add(account.GetProperty("id").GetString());
+                                                            }
+                                                        }
+                                                    }
+                                                    if (resultIds.Count > 0)
+                                                    {
+                                                        return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在!" });
+                                                    }
+                                                    List<TeacherCourse> course = new List<TeacherCourse>();
+                                                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select value(c) from c join A0 in c.classes where A0.id = '{classroom.id}'"))
+                                                    {
+                                                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                                                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                                                        {
+                                                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                                            {
+                                                                course.Add(obj.ToObject<TeacherCourse>());
+                                                            }
+                                                        }
+                                                    }*/
+
+                        /*                            for (int i = 0; i < course.Count; i++)
+                                                    {
+                                                        bool flag = false;
+                                                        for (int j = 0; j < course[i].classes.Count; j++)
+                                                        {
+                                                            if (!course[i].classes[j].name.Equals(classroom.name))
+                                                            {
+                                                                flag = true;
+                                                                course[i].classes[j].name = classroom.name;
+                                                                //break;
+                                                            }
+                                                            if (!course[i].classes[j].teacher.id.Equals(classroom.teacher.id))
+                                                            {
+                                                                flag = true;
+                                                                course[i].classes[j].teacher.id = classroom.teacher.id;
+                                                                course[i].classes[j].teacher.name = classroom.teacher.name;
+                                                                //break;
+                                                            }
+                                                        }
+                                                        if (flag)
+                                                        {
+                                                            await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(course[i], course[i].id, new PartitionKey($"{course[i].code}"));
+                                                        }
+                                                    }*/
+                        //string code = classroom.code.Substring(classroom.pk.Length + 1);
+                        //[Jeff] CourseManagement表廢除 刪除預定:以下CourseManagement更新程序
+                        /*                            var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"CourseManagement-{school_code}"));
+                                                    if (sresponse.Status == 200)
+                                                    {
+                                                        using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
+                                                        CourseManagement classroom1 = json.ToObject<CourseManagement>();
+                                                        if (!classroom1.name.Equals(classroom.name))
+                                                        {
+                                                            classroom1.name = classroom.name;
+                                                            await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom1.code}"));
+                                                        }
+                                                        if (!string.IsNullOrEmpty(classroom1.teacher.id) && !string.IsNullOrEmpty(classroom.teacher.id) && !classroom1.teacher.id.Equals(classroom.teacher.id))
+                                                        {
+                                                            classroom1.teacher.name = classroom.teacher.name;
+                                                            classroom1.teacher.id = classroom.teacher.id;
+                                                            await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom1.code}"));
+                                                        }
+                                                    }*/
+                        ////[Jeff] CourseManagement表廢除 刪除預定:以下CourseManagement更新程序                           
+                        //}
+
+                    //}
 
                 }
                 return Ok(new { classroom });

+ 54 - 18
TEAMModelOS/Controllers/School/CourseController.cs

@@ -852,38 +852,74 @@ namespace TEAMModelOS.Controllers
             if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
             if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
             var client = _azureCosmos.GetCosmosClient();
+            List<Course> courseList = new List<Course>();
             List<object> courses = new List<object>();
             //var query = $"select c.code,c.id,c.name from c join A0 in c.schedule where A0.classId = '{id}'";
             if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
             {
-                var query = $"select c.code,c.id,c.name,A0 schedule from c join A0 in c.schedule where A0.classId = '{id}'";
-                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
+                var query = $"select value(c) from c join A0 in c.schedule where A0.classId = '{id}'";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
                 {
-                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    courseList.Add(item);
+                }
+            }
+            else {
+                var query = $"select value(c) from c join A0 in c.schedule where A0.stulist = '{id}'";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
+                {
+                    courseList.Add(item);
+                }
+            }
+            HashSet<string> teacherIds = new HashSet<string>();
+            foreach (Course course in courseList) {
+                    foreach (Schedule schedule in course.schedule)
                     {
-                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                        {
-                            courses.Add(obj.ToObject<object>());
-                        }
+                        teacherIds.Add(schedule.teacherId);
+                    }
+            }
+            List<(string id, string name)> teachers = new List<(string id, string name)>();
+            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(
+                                queryText: $"select c.id,c.name from c where c.id in ({ string.Join(",", teacherIds.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
+            {
+                using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                {
+                    var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                    while (accounts.MoveNext())
+                    {
+                        JsonElement account = accounts.Current;
+                        teachers.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));                       
                     }
                 }
             }
-            else {
-                var query = $"select c.code,c.id,c.name,A0 schedule from c join A0 in c.schedule where A0.stulist = '{id}'";
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{code}") }))
+            foreach (Course course in courseList) {
+                dynamic courseExtobj = new ExpandoObject();
+                courseExtobj.id = course.id;
+                courseExtobj.name = course.name;
+                courseExtobj.subject = course.subject;
+                courseExtobj.period = course.period;
+                courseExtobj.scope = course.scope;
+                courseExtobj.no = course.no;
+                courseExtobj.code = course.code;
+                courseExtobj.pk = course.pk;
+                List<object> scheList = new List<object>();
+                foreach (Schedule schedule in course.schedule)
                 {
-                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    dynamic scheduleExtobj = new ExpandoObject();
+                    scheduleExtobj.classId = schedule.classId;
+                    scheduleExtobj.teacherId = schedule.teacherId;
+                    if (!string.IsNullOrEmpty(schedule.teacherId))
                     {
-                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                        {
-                            courses.Add(obj.ToObject<object>());
-                        }
+                        scheduleExtobj.teacherName = teachers.FirstOrDefault(c => c.id == schedule.teacherId).name;
                     }
+                    scheduleExtobj.stulist = schedule.stulist;
+                    scheduleExtobj.time = schedule.time;
+                    scheduleExtobj.notice = schedule.notice;
+                    scheList.Add(scheduleExtobj);
                 }
+                courseExtobj.schedule = scheList;
+                courses.Add(courseExtobj);
             }
-            
             return Ok(new { courses });
         }