Forráskód Böngészése

Merge branch 'develop5.0-tmd' of http://106.12.23.251:10000/TEAMMODEL/TEAMModelOS into develop5.0-tmd

OnePsycho 4 éve
szülő
commit
3906bd324c
46 módosított fájl, 1246 hozzáadás és 2072 törlés
  1. 8 0
      TEAMModelOS.SDK/Models/Cosmos/Common/Syllabus.cs
  2. 1 1
      TEAMModelOS.SDK/Models/Cosmos/Common/Vote.cs
  3. 2 2
      TEAMModelOS.SDK/Models/Cosmos/Teacher/Share.cs
  4. 5 0
      TEAMModelOS/ClientApp/src/api/studentWeb.js
  5. 14 7
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContent.vue
  6. 19 17
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  7. 0 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.vue
  8. 16 11
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue
  9. 48 22
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue
  10. 50 23
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue
  11. 12 5
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventView.vue
  12. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/en-US/cusMgt.js
  13. 56 21
      TEAMModelOS/ClientApp/src/locale/lang/en-US/learnActivity.js
  14. 8 5
      TEAMModelOS/ClientApp/src/locale/lang/en-US/stuAccount.js
  15. 10 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/task.js
  16. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/cusMgt.js
  17. 46 10
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/learnActivity.js
  18. 2 2
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/serviceDriveAuth.js
  19. 9 6
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/stuAccount.js
  20. 10 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/task.js
  21. 3 5
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/teachermgmt.js
  22. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/cusMgt.js
  23. 44 9
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/learnActivity.js
  24. 10 7
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/stuAccount.js
  25. 10 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/task.js
  26. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/teachermgmt.js
  27. 10 10
      TEAMModelOS/ClientApp/src/router/routes.js
  28. 3 1
      TEAMModelOS/ClientApp/src/store/module/user.js
  29. 33 2
      TEAMModelOS/ClientApp/src/utils/js-fn.js
  30. 25 19
      TEAMModelOS/ClientApp/src/view/joinclass/JoinClass.vue
  31. 0 1364
      TEAMModelOS/ClientApp/src/view/learnactivity/markpaper/MarkView.vue
  32. 23 4
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue
  33. 418 400
      TEAMModelOS/ClientApp/src/view/student-account/AddStudent.vue
  34. 1 1
      TEAMModelOS/ClientApp/src/view/student-account/ClassMgt.vue
  35. 6 2
      TEAMModelOS/ClientApp/src/view/student-account/Index.vue
  36. 39 29
      TEAMModelOS/ClientApp/src/view/task/mark/ByQu.vue
  37. 45 37
      TEAMModelOS/ClientApp/src/view/task/mark/ByStu.vue
  38. 8 4
      TEAMModelOS/ClientApp/src/view/task/mark/ProgPie.vue
  39. 2 2
      TEAMModelOS/ClientApp/src/view/task/mark/QuProg.vue
  40. 13 9
      TEAMModelOS/ClientApp/src/view/task/mark/StuProg.vue
  41. 39 0
      TEAMModelOS/Controllers/Common/CommonController.cs
  42. 11 9
      TEAMModelOS/Controllers/Common/SurveyController.cs
  43. 11 9
      TEAMModelOS/Controllers/Common/VoteController.cs
  44. 15 3
      TEAMModelOS/Controllers/Item/ItemController.cs
  45. 11 3
      TEAMModelOS/Controllers/School/StudentController.cs
  46. 146 6
      TEAMModelOS/Controllers/Syllabus/ShareController.cs

+ 8 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/Syllabus.cs

@@ -34,5 +34,13 @@ namespace TEAMModelOS.SDK.Models
         public string tmdname { get; set; }
         public bool coedit { get; set; }
         public bool share { get; set; }
+        /// <summary>
+        /// 共编-是否同意
+        /// </summary>
+        public int cagree { get; set; } = 0;
+        /// <summary>
+        /// 分享-是否同意
+        /// </summary>
+        public int sagree { get; set; } = 0;
     }
 }

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/Common/Vote.cs

@@ -27,7 +27,7 @@ namespace TEAMModelOS.SDK.Models
         /// <summary>
         /// 学校编码或教师tmdid
         /// </summary>
-        [Required(ErrorMessage = "school 必须设置")]
+       // [Required(ErrorMessage = "school 必须设置")]
         public string school { get; set; }
         /// <summary>
         /// 投票名称

+ 2 - 2
TEAMModelOS.SDK/Models/Cosmos/Teacher/Share.cs

@@ -68,11 +68,11 @@ namespace TEAMModelOS.SDK.Models
         /// <summary>
         /// 共编-是否同意
         /// </summary>
-        public bool cagree { get; set; } = false;
+        public int cagree { get; set; } = 0;
         /// <summary>
         /// 分享-是否同意
         /// </summary>
-        public bool sagree { get; set; } = false;
+        public int sagree { get; set; } =0;
     }
     /// <summary>
     /// 主动分享给谁,当接收者接收并完成相关资源复制后则删除本条数据。

+ 5 - 0
TEAMModelOS/ClientApp/src/api/studentWeb.js

@@ -225,4 +225,9 @@ export default {
 	isAnswerd: function (data) {
 	    return post('/common/survey/answered',data)
 	},
+
+    // 删除不存在的投票和问卷
+    delActivity: function (data) {
+        return post("/common/delete-activity", data)
+    }
 }

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

@@ -1,26 +1,26 @@
 <template>
     <div class="event-content">
         <!--<VoteHint v-if="this.$store.getters.getisVoteResulthover==true"/>-->
-        <div v-if="this.$store.getters.getIsSelectedNow">
+        <div v-if="getIsSelectedNow">
 
-            <!--<div v-if="this.$store.getters.getItemTitle.eventType=='preview'">
+            <!--<div v-if="getItemTitle.eventType=='preview'">
               <PreviewMission/>
             </div>
-            <div v-if="this.$store.getters.getItemTitle.eventType=='homeWork'">
+            <div v-if="getItemTitle.eventType=='homeWork'">
               <Homework/>
             </div>-->
-            <div v-if="this.$store.getters.getItemTitle.eventType == 'Exam'">
+            <div v-if="getItemTitle.eventType == 'Exam'">
                 <PaperView />
             </div>
-            <div v-if="this.$store.getters.getItemTitle.eventType == 'Vote'">
+            <div v-if="getItemTitle.eventType == 'Vote'">
                 <Vote />
             </div>
-            <div v-if="this.$store.getters.getItemTitle.eventType == 'Survey'">
+            <div v-if="getItemTitle.eventType == 'Survey'">
                 <QuesNaire />
             </div>
         </div>
         <!-- 如果篩選時未選的時候預設顯示列表第一個-->
-        <div class="noSelected" v-if="!this.$store.getters.getIsSelectedNow">
+        <div class="noSelected" v-if="!getIsSelectedNow">
             <h3>{{$t("studentWeb.event.selectActivity")}}</h3>
         </div>
 
@@ -34,6 +34,7 @@
     import PaperView from "./EventContentTypeTemplate/PaperView";
     import VoteHint from "./EventContentTypeTemplate/VoteHint";
     import QuesNaire from "./EventContentTypeTemplate/QuesNaire";
+import { mapGetters } from 'vuex';
     export default {
         name: "EventContent",
         components: {
@@ -51,6 +52,12 @@
         data() {
             return {
             };
+        },
+        computed: {
+            ...mapGetters([
+                "getIsSelectedNow",
+                "getItemTitle"
+            ])
         }
     };
 </script>

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

@@ -1,11 +1,11 @@
 <template>
     <div class="lesson-test-report">
         <div class="scoreboard">
-            <div v-show="$store.getters.getItemTitle.progress == 'finish' && testState == 1">
+            <div v-show="getItemTitle.progress == 'finish' && testState == 1">
                 <svg-icon icon-class="handonHint" class="warm-icon" />
                 <span class="warm-hint">{{ $t("studentWeb.exam.timeoutHint") }}</span>
             </div>
-            <span v-show="$store.getters.getItemTitle.progress != 'finish' && testState == 1" @click="showTest" style="color: #03966a;width: 100%;cursor: pointer;font-size:18px;font-weight: 800;text-align: center">
+            <span v-show="getItemTitle.progress != 'finish' && testState == 1" @click="showTest" style="color: #03966a;width: 100%;cursor: pointer;font-size:18px;font-weight: 800;text-align: center">
                 {{$t("studentWeb.exam.report.anwser")}}
             </span>
             <h4 v-show='testState == 2'>{{$t("studentWeb.exam.report.noRes")}}</h4>
@@ -315,6 +315,7 @@
     import LessonTestReportCharts from "./LessonTestReportCharts/LessonTestReportCharts";
     import Loading from "vue-loading-overlay";
     import "vue-loading-overlay/dist/vue-loading.css";
+import { mapGetters } from 'vuex';
     export default {
         name: "LessonTestReport",
         components: {
@@ -344,17 +345,17 @@
                 //loading畫面
                 closeAnsDetail: false,
                 checkedAns: ["right", "wrong", "noAns"],
-                testState: 0,// 表示有没有作答
+                testState: 0, //表示有没有作答
                 paperData: [], //所有题目信息
-                ansData: [],
+                ansData: [], //题目的作答答案
                 repairSource: {
                     normal: [],
                     file: []
                 },
                 repairData: [],
-                previewStatus: false,
+                previewStatus: false, //展示补救资源
                 previewFile: {},
-                numPages:null
+                numPages: null
             };
         },
         mounted() {
@@ -366,7 +367,7 @@
                 this.previewStatus = !this.previewStatus
                 this.previewFile = {}
             },
-           async getItemData(data) {
+            async getItemData(data) {
                this.previewStatus = false
                 if (data.file) {
                     this.previewFile = this._.cloneDeep(data)
@@ -444,7 +445,6 @@
             },
             showTest() {
                 if (this.examInfo.subject !== undefined) {
-                    console.log(this.examInfo);
                     this.$store.commit("ToggleLessonTestPopWithSubject", this.examInfo)
                 }
             },
@@ -478,11 +478,11 @@
                     }
                 }
             },
-            //获取学生作答数据
+            // 获取学生作答数据
             async getItem(data) {
                 let datas = []
                 if (data !== undefined) {
-                    let codes = this.$store.getters.getItemTitle
+                    let codes = this.getItemTitle
                     let code = {
                         scope: codes.scope,
                         code: codes.scope === 'school' ? codes.school : codes.creatorId,
@@ -496,7 +496,7 @@
                     return []
                 }
             },
-            //处理学生作答数据blob地址
+            // 处理学生作答数据blob地址
             formUrl(data) { 
                 let a = ""
                 if (data.blob.indexOf('https://teammodelstorage') > -1) {
@@ -504,7 +504,7 @@
                 } else {
                     let blobUrl = JSON.parse(decodeURIComponent(localStorage.student_profile, "utf-8")).blob_uri
                     let studentBlob = blobUrl.split('/')
-                    let url = data.scope == 'school' ? blobUrl : "https://" + studentBlob[studentBlob.length - 2] + '/' + this.$store.getters.getItemTitle.creatorId
+                    let url = data.scope == 'school' ? blobUrl : "https://" + studentBlob[studentBlob.length - 2] + '/' + this.getItemTitle.creatorId
                     a = `${url}/exam/${data.blob}`
                 }
                 return a 
@@ -513,9 +513,9 @@
                 let paper = []
                 this.paperData.length = 0
                 this.ansData.length = 0
-                let data = this.$store.getters.getPaperInfo.item
+                let data = this.getPaperInfo.item
                 let exam = [...data]
-                if (this.$store.getters.getPaperInfo.item.length) {
+                if (this.getPaperInfo.item.length) {
                     for (let i = 0; i < exam.length; i++) {
                         if (exam[i].repair == undefined) {
                             exam[i].repair = []
@@ -562,9 +562,11 @@
             },
         },
         computed: {
+            ...mapGetters([
+                "getItemTitle",
+                "getPaperInfo",
+            ]),
             testScore() {
-                console.log(this.examInfo);
-                console.log(this.paperInfo);
                 let data = 0
                 if (this.examInfo.subject !== undefined) {
                     for (let item of this.examInfo.stuScore) {
@@ -589,7 +591,7 @@
                         noAns:0,
                         wrong:0,
                     }
-                    if (this.paperData[0]!= undefined) {
+                    if (this.paperData[0] != undefined) {
                         for (let i = 0; i < this.examInfo.stuScore.length; i++) {
                             if (this.examInfo.stuScore[i] == -1) {
                                 info.noAns++

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

@@ -272,7 +272,6 @@
             Complete
         },
         created() {
-            console.log(this.getItemTitle);
             this.WarmMessageisOpen = false;
             this.showMessageNum = 0;
         },

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

@@ -1,7 +1,7 @@
 <template>
     <div class="lesson-test">
         <br />
-        <PaperTest :papers="selectData" v-if="this.$store.getters.getisOpenLessonTestPopNow" /> 
+        <PaperTest :papers="selectData" v-if="getisOpenLessonTestPopNow" /> 
         <div>
             <div class="load-box">
                 <load :active.sync="isLoad"
@@ -27,7 +27,7 @@
                                  :class="['paper-item',item.paperId == chooseData.paperId ? 'paper-choose' : '']"
                                  @click="opentestWithSubject(item)">
                                 <svg-icon icon-class="test" class="title-icon" />
-                                <span style="margin-top:5px">{{ item.subject.name }}{{$store.getters.getItemTitle.scope == 'school' ? $t('studentWeb.exam.isSubject'):''}}</span>
+                                <span style="margin-top:5px">{{ item.subject.name }}{{getItemTitle.scope == 'school' ? $t('studentWeb.exam.isSubject'):''}}</span>
                                 <div :class="{ unfinished: item.stuAns.length == 0 ,finished:item.stuAns.length != 0 }">
                                     <Icon style="margin-top:-10px;margin-left:-8px;" type="ios-checkmark" size="36" />
                                 </div>
@@ -43,7 +43,7 @@
                     </div>
                 </TabPane>
                 <!-- 成绩分析 -->
-                <TabPane :label="$t('studentWeb.exam.gradeReport')" v-if="isTestOver && $store.getters.getItemTitle.owner == 'school'" name="analyse">
+                <TabPane :label="$t('studentWeb.exam.gradeReport')" v-if="isTestOver && getItemTitle.owner == 'school'" name="analyse">
                     <div class="title-rect-group">
                         <!-- <div class="title-rect" /> -->
                         <h2 class="title-rect-name">{{$t("studentWeb.exam.gradeAnalyse")}}</h2>
@@ -60,6 +60,7 @@
 <script>
     import Load from "vue-loading-overlay";
     import "vue-loading-overlay/dist/vue-loading.css";
+import { mapGetters } from 'vuex';
     import EventBasicInfo from "../../EventBasicInfo";
     import LessonTestReport from "./LessonTestReport";
     import StudentScore from "./LessonTestReportCharts/StudentScore";
@@ -78,7 +79,7 @@
         },
         mounted() {
             this.selectTab = "test"
-            this.privateType = this.$store.getters.getItemTitle.owner
+            this.privateType = this.getItemTitle.owner
         },
         data() {
             return {
@@ -110,9 +111,9 @@
                 this.chooseData = {}
                 this.isTestOver = false
                 this.isLoad = true
-                if (this.$store.getters.getItemTitle.name !== undefined) {
-                    let paper = this.$store.getters.getItemTitle
-                    let codes = this.$store.getters.getItemTitle.scope == 'school' ? this.$store.getters.getItemTitle.school : this.$store.getters.getItemTitle.creatorId
+                if (this.getItemTitle.name !== undefined) {
+                    let paper = this.getItemTitle
+                    let codes = this.getItemTitle.scope == 'school' ? this.getItemTitle.school : this.getItemTitle.creatorId
                     let req = {
                         id: paper.id,
                         studentId: this.$store.state.userInfo.sub,
@@ -178,8 +179,7 @@
                 this.isLoad = true
                 this.selectData = {}
                 this.chooseData = {}
-                console.log(this.$store.getters.getItemTitle);
-                let codes = this.$store.getters.getItemTitle.scope == 'school' ? data.school : data.creatorId
+                let codes = this.getItemTitle.scope == 'school' ? data.school : data.creatorId
                 if (data.blob !== undefined && data.blob !== "") {
                     let code = {
                         scope: this.paperCtn,
@@ -235,8 +235,13 @@
             },
         },
         computed: {
+            ...mapGetters([
+                "getisOpenLessonTestPopNow",
+                "getItemTitle",
+                "getCurrentSubject",
+            ]),
             listData() {
-                return this.$store.getters.getCurrentSubject;
+                return this.getCurrentSubject;
             }
         },
         watch: {
@@ -251,7 +256,7 @@
             },
             listData: {
                 handler() {
-                    if (this.$store.getters.getCurrentSubject == '') {
+                    if (this.getCurrentSubject == '') {
                         this.getPaperData()
                     }
                 },

+ 48 - 22
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue

@@ -94,6 +94,7 @@
 	import QuesNaireReport from "./QuesNaireReport";
 	import EventBasicInfo from "../../EventBasicInfo";
 	import BillBoardandLightBox from "../../EventView/BillBoardandLightBox";
+import { mapGetters } from 'vuex';
 	export default {
 		name: "QuesNaire",
 		components: {
@@ -181,22 +182,22 @@
 				this.WarmMessageisOpen = false;
 			},
 			createdSaveCheckers() {
-				if (this.$store.getters.getResetSurvey == true) {
+				if (this.getResetSurvey == true) {
 					this.checkers = [];
 					var mockcheckersheet = [];
 					for (let i = 0; i < 10; i++) {
 						if (
-							this.$store.getters.getItemTitle.isDone == false &&
-							this.$store.getters.getFinishedItem.includes(
-								this.$store.getters.getItemTitle.eventID
+							this.getItemTitle.isDone == false &&
+							this.getFinishedItem.includes(
+								this.getItemTitle.eventID
 							) == false
 						) {
 							mockcheckersheet.push([]);
 						} else if (
-							this.$store.getters.getFinishedItem.includes(
-								this.$store.getters.getItemTitle.eventID
+							this.getFinishedItem.includes(
+								this.getItemTitle.eventID
 							) == true ||
-							this.$store.getters.getItemTitle.isDone == true
+							this.getItemTitle.isDone == true
 						) {
 							mockcheckersheet.push("B");
 						}
@@ -211,7 +212,7 @@
 				}
 			},
 			qesNaire() {
-				return this.$store.getters.getItemTitle.qesNaire;
+				return this.getItemTitle.qesNaire;
 			},
 			
 			/* 判断当前学生是否已作答该问卷 */
@@ -227,23 +228,27 @@
 			//获取投票数据
 			// 获取surveyInfo的数据
 			async getSurveyInfo() {
-				if (this.$store.getters.getItemTitle.id) {
+				if (this.getItemTitle.id) {
 					let params = {
-						"id": this.$store.getters.getItemTitle.id,
-						"code": this.$store.getters.getItemTitle.scode
+						"id": this.getItemTitle.id,
+						"code": this.getItemTitle.scode
 					}
 					let isAnswerd = await this.isAnswerd(params)
 					if(!isAnswerd){
 						// 没有提交
 						this.$api.studentWeb.getSurveyInfo(params).then(async res => {
 							if (res) {
-								this.surveyInfo = res.survey
-								this.surveyInfo.items = await this.getBlobItems(res.survey)
-								this.submitArr = []
-								this.surveyInfo.items.forEach(i => {
-									this.submitArr.push([])
-								})
-								this.$forceUpdate()
+								if(res.status == 404) {
+									this.delActivity()
+								} else if(res.status == 200) {
+									this.surveyInfo = res.survey
+									this.surveyInfo.items = await this.getBlobItems(res.survey)
+									this.submitArr = []
+									this.surveyInfo.items.forEach(i => {
+										this.submitArr.push([])
+									})
+									this.$forceUpdate()
+								}
 							}
 						}).catch(err => {
 							console.log(err)
@@ -251,12 +256,25 @@
 					}else{
 						this.alreadyAnswered = true
 					}
-					
 				}
-				
-				console.log(this.alreadyAnswered)
-				console.log(this.surveyInfo)
 			},
+			// 删除不存在的问卷
+            delActivity() {
+                let param = {
+                    'id': this.getItemTitle.id,
+                    'code': this.getItemTitle.code,
+                    "role": "teacher"
+                }
+                this.$api.studentWeb.delActivity(param).then(res => {
+                    if(res) {
+						if(res.status == 500) {
+							this.$Message.warning('问卷已删除!')
+						}
+					}
+                }).finally(()=>{
+                    this.isLoad = false
+                })
+            },
 
 			// 获取blob里的问卷内容
 			getBlobItems(qnItem) {
@@ -332,6 +350,14 @@
 				deep: true
 			},
 		},
+		
+		computed: {
+			...mapGetters([
+				"getItemTitle",
+				"getResetSurvey",
+				"getFinishedItem"
+			])	
+		},
 	};
 </script>
 

+ 50 - 23
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue

@@ -10,7 +10,7 @@
         <EventBasicInfo />
         <div>
             <!--超时-->
-            <div v-if="this.$store.getters.getItemTitle.endTime <= '2020.02.10'">
+            <div v-if="getItemTitle.endTime <= '2020.02.10'">
                 <br />
                 <div class="dec animate__animated animate__bounceInLeft">
                     <svg-icon icon-class="handonHint" class="warm-icon" />
@@ -126,6 +126,7 @@
     import BillBoardandLightBox from "../../EventView/BillBoardandLightBox";
     import VoteResultChart from "./VoteResultChart";
     import Load from "vue-loading-overlay";
+    import { mapGetters } from 'vuex';
     export default {
         name: "Vote",
         components: {
@@ -164,11 +165,11 @@
         methods: {
             //获取个人投票结果数据
             getVoteRecord() {
-                if (this.$store.getters.getItemTitle.id) {
+                if (this.getItemTitle.id) {
                     this.voteRes = {}
                     let params = {
-                        "id": this.$store.getters.getItemTitle.id,
-                        "code": this.$store.getters.getItemTitle.scode,
+                        "id": this.getItemTitle.id,
+                        "code": this.getItemTitle.scode,
                         "userid": this.$store.state.userInfo.sub
                     }
                     this.$api.studentWeb.getVoteResult(params).then(res => {
@@ -185,37 +186,60 @@
             },
             //获取活动投票结果数据
             getVoteInfo() {
-                if (this.$store.getters.getItemTitle.id) {
+                if (this.getItemTitle.id) {
                     let params = {
-                        "id": this.$store.getters.getItemTitle.id,
-                        "code": this.$store.getters.getItemTitle.scode
+                        "id": this.getItemTitle.id,
+                        "code": this.getItemTitle.scode
                     }
                     this.isLoad = true
                     this.$api.studentWeb.getVoteInfo(params).then(res => {
                         if (res) {
-                            this.showResult = false
-                            this.isResult = false
-                            for (let item of res.vote.options) {
-                                item.count = 0
-                            }
-                            this.voteInfo = res.vote
-                            if (res.vote.progress == "finish") {
-                                this.getVoteRecord()
-                                this.getVoteRes()
-                                this.isResult = true
-                            } else {
-                                this.getVoteRecord()
+                            if(res.status == 404) {
+                                this.delActivity()
+                            } else if(res.status == 200) {
+                                this.showResult = false
+                                this.isResult = false
+                                for (let item of res.vote.options) {
+                                    item.count = 0
+                                }
+                                this.voteInfo = res.vote
+                                if (res.vote.progress == "finish") {
+                                    this.getVoteRecord()
+                                    this.getVoteRes()
+                                    this.isResult = true
+                                } else {
+                                    this.getVoteRecord()
+                                }
                             }
                         }
+                    }).catch(err => {
+                        console.log(err)
                     })
                 }
             },
-           async getVoteRes() {
+            async getVoteRes() {
                 if (this.voteInfo.recordUrl !== "") {
                     let data = await this.getBlobItems(this.voteInfo)
                     this.setData(data[0])
                 }
             },
+            // 删除不存在的投票
+            delActivity() {
+                let param = {
+                    'id': this.getItemTitle.id,
+                    'code': this.getItemTitle.code,
+                    "role": "teacher"
+                }
+                this.$api.studentWeb.delActivity(param).then(res => {
+                    if(res) {
+                        if(res.status == 500) {
+                            this.$Message.warning('投票已删除!')
+                        }
+                    }
+                }).finally(()=>{
+                    this.isLoad = false
+                })
+            },
             // 获取blob里的试题数据
             getBlobItems(qnItem) {
                 let key = this.voteInfo.code.split('-')
@@ -364,8 +388,8 @@
                 this.clickbutnoChoose = false;
                 if (this.voteChecked.length) {
                     let params = {
-                        "id": this.$store.getters.getItemTitle.id,
-                        "code": this.$store.getters.getItemTitle.scode,
+                        "id": this.getItemTitle.id,
+                        "code": this.getItemTitle.scode,
                         "option": {}
                     }
                     for (let item of this.voteChecked) {
@@ -396,8 +420,11 @@
             },
         },
         computed: {
+            ...mapGetters([
+                "getItemTitle",
+            ]),
             listData() {
-                return this.$store.getters.getItemTitle.id;
+                return this.getItemTitle.id;
             },
             voteCount() {
                 if (this.voteInfo.voteNum !== undefined) {

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

@@ -1,8 +1,8 @@
 <template>
     <div class="event-view">
-        <EventList :class="{ 'hide-sidebars': $store.getters.getSidebarisOpen == false}"></EventList>
-        <EventContentArea :class="{'eventContentArea-Span': $store.getters.getSidebarisOpen == false}"></EventContentArea>
-        <!--<CommentList v-if=" $store.getters.getOpenCommentList == true && $store.getters.getSidebarisOpen == false" />-->
+        <EventList :class="{ 'hide-sidebars': getSidebarisOpen == false}"></EventList>
+        <EventContentArea :class="{'eventContentArea-Span': getSidebarisOpen == false}"></EventContentArea>
+        <!--<CommentList v-if=" $store.getters.getOpenCommentList == true && getSidebarisOpen == false" />-->
     </div>
 </template>
 
@@ -10,6 +10,7 @@
     import CommentList from "./CommentList.vue";
     import EventList from "./EventList";
     import EventContentArea from "./EventContentArea.vue";
+    import { mapGetters } from 'vuex';
     export default {
         name: "EventView",
         components: {
@@ -38,7 +39,7 @@
                 this.selectedEventStatusNow = "所有活動狀態";
                 this.eventTypeCheckers = [];
                 let targetItem = document.getElementById(
-                    `event${this.$store.getters.getItemTitle.eventID}`
+                    `event${this.getItemTitle.eventID}`
                 );
                 let scrollList = document.querySelectorAll(".event-list .list-block")[0];
 
@@ -59,7 +60,7 @@
             gotoNextItem() {
                 let nextItems = [];
                 for (let i = 0; i <= this.mockdata.length; i++) {
-                    if (this.$store.getters.getItemTitle == this.mockdata[i]) {
+                    if (this.getItemTitle == this.mockdata[i]) {
                         let j = i + 1;
                         if (
                             j < this.mockdata.length && this.eventPageType.includes(this.mockdata[j].eventType)
@@ -97,6 +98,12 @@
                 }
             },
         },
+        computed: {
+            ...mapGetters([
+                "getSidebarisOpen",
+                "getItemTitle"
+            ])
+        }
     };
 </script>
 <style scoped>

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

@@ -3,7 +3,7 @@ export default {
     searchHolder:'搜索',
     delBatch:'批量删除',
     delCus:'删除课程',
-    addCus:'添加课程',
+    addCus:'新增课程',
     editCus:'编辑课程',
     noTeacher:'暂无',
     cusName:'课程名称',

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

@@ -22,7 +22,7 @@ export default{
         autoTips2:'此功能仅用于展示情景快速模拟教师评分数据,且分数为随机生成,仅供参考!',
         autoScore:'一键评分',
         autoAnswer:'一键作答',
-        evSubject:'测试科:',
+        evSubject:'测试科:',
         returnTop:'返回顶部',
         mockOk:'模拟成功',
         mockErr:'模拟失败',
@@ -56,7 +56,7 @@ export default{
         evType:'评测类型',
         examType:'考试类别',
         courseType:'课程类别',
-        cusLabel1:'校课程',
+        cusLabel1:'校课程',
         cusLabel2:'个人课程',
         evTarget:'施测对象',
         publishType:'发布方式',
@@ -65,7 +65,7 @@ export default{
         endTime:'结束时间',
         eTimeHolder:'请选择结束时间',
         addSubject:'添加学科',
-        noSubject:'暂无科,请添加科',
+        noSubject:'暂无科,请添加科',
         noSubject1:'* 请先选择测试学段',
         papersLabel:'试卷库',
         perviewLabel:'试卷预览',
@@ -87,13 +87,13 @@ export default{
         formWarning:'请先完善评测基础信息!',
         paperWarning:'请挑选或导入试卷!',
         paperWarning1:'还没有试卷,请挑选或导入试卷!',
-        pdWarning:'请添加测试科!',
+        pdWarning:'请添加测试科!',
         publishOk:'评测发布成功!',
         togglePeriod:'切换学段',
         togglePdTip1:'您已添加',
-        togglePdTip2:'的测试科,如果现在切换学段会清空已选科,确定切换学段吗?',
+        togglePdTip2:'的测试科,如果现在切换学段会清空已选科,确定切换学段吗?',
         toggleOkText:'切换',
-        delPdTitle:'删除科',
+        delPdTitle:'删除科',
         delPdContent:'是否确认删除',
         delOk:'删除成功',
         pdTips:'请先选择测试学段!',
@@ -103,12 +103,12 @@ export default{
     manual:{
         source:'来源:',
         sourceP:'个人试卷库',
-        sourceS:'校试卷库',
+        sourceS:'校试卷库',
         pdLabel:'学段:',
         subjectLabel:'学科:',
         gradeLabel:'年级:',
         fitPd:'适用学段:',
-        fitSubject:'适用科:',
+        fitSubject:'适用科:',
         quCount:'题量:',
         useCount:'使用次数:',
         stdPaper:'已选试卷',
@@ -213,19 +213,11 @@ export default{
     },
 
     mark:{
-        baseSetting:'基础设置',
-        markMode:'阅卷模式',
-        full:'完整阅卷',
-        question:'指定题目',
         markNum:'阅卷次数',
-        allocation:'分配方式',
-        random:'随机分配',
-        class:'按班分配',
-        scoreDiff:'分差',
         markRole:'阅卷角色',
-        errRole:'异常处理',
-        arb:'仲裁教师',
-        markRole:'阅卷教师',
+        errRole:'异常处理',
+        arb:'仲裁教师',
+        markRole:'阅卷教师',
         noTea:'暂无教师',
         remove:'移除',
         addTea:'添加阅卷老师',
@@ -252,7 +244,7 @@ export default{
         unassigned:'未分配',
         teaProgress:'教师阅卷进度',
         schedule:'调度',
-        subject:'科',
+        subject:'科',
         stuNum:'考试人数',
         scanProg:'扫描进度',
         assignStatus:'阅卷分配',
@@ -264,6 +256,49 @@ export default{
         progress:'进度',
         action:'操作',
         addTeaTitle:'添加阅卷老师',
-        markNum:'阅卷量'
+        markNum:'阅卷量',
+        //ByqU.vue & ByStu.vue
+        quit:'退出阅卷',
+        examName:'考试名称:',
+        reviewType:'阅卷方式:',
+        byQu:'按题阅卷',
+        byStu:'按人阅卷',
+        stuId:'学生Id',
+        score:'分数:',
+        curQu:'当前题号:',
+        quProg:'题目进度',
+        exception:'异常申报',
+        move:'移动',
+        text:'文字',
+        brush:'画笔',
+        arrow:'箭头',
+        oval:'椭圆',
+        rect:'方框',
+        seal:'印章',
+        clear:'清除批注',
+        marked:'已阅',
+        unmark:'未阅',
+        fullScore:'满分',
+        zeroScore:'零分',
+        submit:'提交分数',
+        setting1:'打分自动切换学生',
+        setting2:'完成批阅自动弹出切换',
+        setting3:'打分自动切换题目',
+        setting4:'完成阅卷自动获取新学生',
+        toggleQu:'切换题目',
+        toggleStu:'切换学生',
+        saveErr:'保存失败',
+        noSocreErr:'请先打分',
+        completeQu:'当前题目已阅完,请切换题目',
+        completeStu:'当前完成当前学生评分,如果继续评分,请切换学生',
+        noAnswer:'未作答',
+        stuInfoErr:'学生信息异常',
+        ummarkQu:'未阅题目',
+        unmarkContent:'题目尚未评分,是否跳转到对应题目继续评分?',
+        finished:'已阅完',
+        noUnMarkStu:'已无未阅学生,请挑选进行中的学生继续阅卷。',
+        completeTask:'您已完成阅卷任务',
+        // ProgPie.vue
+        marking:'进行中'
     }
 }

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

@@ -37,8 +37,8 @@ export default {
   delOk:'删除成功',
   isBottom:'已经到底了',
   edit:'修改',
-  adminClass:'行政班管理',
-  teachClass:'教學班管理',
+  adminClass:'行政班',
+  teachClass:'教學班',
   stuMgt:'學生管理',
 
   // AddStudent.vue
@@ -51,9 +51,9 @@ export default {
   stuNameHolder: '请输入学生名称',
   stuSeatNo: '座位号',
   stuSeatNoHolder: '请设置座位号',
-  classroomInfo: '教室信息',
-  classroomInfoHolder: '请选择教室',
-  newClassroom: '建立新教室',
+  classroomInfo: '班級',
+  classroomInfoHolder: '请选择班級',
+  newClassroom: '建立新班級',
   periodInfo: '学制',
   gradeInfo: '年级',
   submitAccount: '建立账号',
@@ -62,6 +62,9 @@ export default {
   chooseNum: '总计:',
   numUnit: '条',
   academicYear: '学年度',
+  noMatch:'暫無匹配數據',
+  stuIdErr:'學生賬號不能為空',
+  stuIdErr1:'學生賬號只能包含數字',
 
   // ImportStudent.vue
   importTitle: '导入学生名单',

+ 10 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/task.js

@@ -13,4 +13,14 @@ export default {
     mLabel6:'人數',    
     markProg:'批閱進度',    
     mark:'批閱',
+    objectiveQu:'客观题已由系统自动完成评分。',
+    lastLabel1:'还剩',
+    lastLabel2:'人未阅,',
+    continue:'继续阅卷',
+    totalLabel1:'阅卷总量',
+    totalLabel2:'人,',
+    start:'开始阅卷',
+    noUnmark:'暂无未阅学生',
+    noMarking:'暂无进行中学生',
+    noMarked:'暂无已阅学生',
 }

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

@@ -3,7 +3,7 @@ export default {
     searchHolder:'搜索',
     delBatch:'批量删除',
     delCus:'删除课程',
-    addCus:'添加课程',
+    addCus:'新增课程',
     editCus:'编辑课程',
     noTeacher:'暂无',
     cusName:'课程名称',

+ 46 - 10
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/learnActivity.js

@@ -12,7 +12,8 @@ export default{
         finish:'已结束',
         endTime:'结束时间:',
         stop:'立即结束',
-        evType:'测试类型:',
+        evType:'评测类型:',
+        evMode:'评测模式:',
         stuCount:'施测人数:',
         nodata:'暂无评测',
         tab1:'评测数据',
@@ -212,15 +213,7 @@ export default{
     },
 
     mark:{
-        baseSetting:'基础设置',
-        markMode:'阅卷模式',
-        full:'完整阅卷',
-        question:'指定题目',
         markNum:'阅卷次数',
-        allocation:'分配方式',
-        random:'随机分配',
-        class:'按班分配',
-        scoreDiff:'分差',
         markRole:'阅卷角色',
         errRole:'异常处理',
         arb:'仲裁教师',
@@ -263,6 +256,49 @@ export default{
         progress:'进度',
         action:'操作',
         addTeaTitle:'添加阅卷老师',
-        markNum:'阅卷量'
+        markNum:'阅卷量',
+        //ByqU.vue & ByStu.vue
+        quit:'退出阅卷',
+        examName:'考试名称:',
+        reviewType:'阅卷方式:',
+        byQu:'按题阅卷',
+        byStu:'按人阅卷',
+        stuId:'学生Id',
+        score:'分数:',
+        curQu:'当前题号:',
+        quProg:'题目进度',
+        exception:'异常申报',
+        move:'移动',
+        text:'文字',
+        brush:'画笔',
+        arrow:'箭头',
+        oval:'椭圆',
+        rect:'方框',
+        seal:'印章',
+        clear:'清除批注',
+        marked:'已阅',
+        unmark:'未阅',
+        fullScore:'满分',
+        zeroScore:'零分',
+        submit:'提交分数',
+        setting1:'打分自动切换学生',
+        setting2:'完成批阅自动弹出切换',
+        setting3:'打分自动切换题目',
+        setting4:'完成阅卷自动获取新学生',
+        toggleQu:'切换题目',
+        toggleStu:'切换学生',
+        saveErr:'保存失败',
+        noSocreErr:'请先打分',
+        completeQu:'当前题目已阅完,请切换题目',
+        completeStu:'当前完成当前学生评分,如果继续评分,请切换学生',
+        noAnswer:'未作答',
+        stuInfoErr:'学生信息异常',
+        ummarkQu:'未阅题目',
+        unmarkContent:'题目尚未评分,是否跳转到对应题目继续评分?',
+        finished:'已阅完',
+        noUnMarkStu:'已无未阅学生,请挑选进行中的学生继续阅卷。',
+        completeTask:'您已完成阅卷任务',
+        // ProgPie.vue
+        marking:'进行中'
     }
 }

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

@@ -52,7 +52,7 @@ export default {
 
   //SpaceStatus.vue
   智慧教学服務空間狀態: '智慧教学服务空间状态',
-  分配教空間: '分配教学空间',
+  分配教空間: '分配教学空间',
   空間總數: '空间总数',
   已使用空間總數: '已使用空间总数',
   空間使用狀況: '空间使用状况',
@@ -175,7 +175,7 @@ export default {
   '先輸入有效數字,並進行勾選,再套用': '先输入有效数字,并进行勾选,再套用',
 
   //store/spaceAuth.js
-  校已使用空間:'学校已使用空间',
+  校已使用空間:'学校已使用空间',
   已分配給教師空間:'已分配给教师空间',
   剩餘空間:'剩余空间'
 }

+ 9 - 6
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/stuAccount.js

@@ -37,8 +37,8 @@ export default {
   delOk:'删除成功',
   isBottom:'已经到底了',
   edit:'修改',
-  adminClass:'行政班管理',
-  teachClass:'教学班管理',
+  adminClass:'行政班',
+  teachClass:'教学班',
   stuMgt:'学生管理',
 
   // AddStudent.vue
@@ -51,9 +51,9 @@ export default {
   stuNameHolder: '请输入学生名称',
   stuSeatNo: '座位号',
   stuSeatNoHolder: '请设置座位号',
-  classroomInfo: '教室信息',
-  classroomInfoHolder: '请选择教室',
-  newClassroom: '建立新教室',
+  classroomInfo: '班级',
+  classroomInfoHolder: '请选择班级',
+  newClassroom: '建立新班级',
   periodInfo: '学段',
   gradeInfo: '年级',
   submitAccount: '建立账号',
@@ -61,7 +61,10 @@ export default {
   chooseInfo: '选取项目',
   chooseNum: '总计:',
   numUnit: '条',
-  academicYear: '学年度',
+  academicYear: '学级',
+  noMatch:'暂无匹配数据',
+  stuIdErr:'学生账号不能为空',
+  stuIdErr1:'学生账号只能包含数字',
 
   // ImportStudent.vue
   importTitle: '导入学生名单',

+ 10 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/task.js

@@ -13,4 +13,14 @@ export default {
     mLabel6:'人数',
     markProg:'批阅进度',
     mark:'批阅',
+    objectiveQu:'客观题已由系统自动完成评分。',
+    lastLabel1:'还剩',
+    lastLabel2:'人未阅,',
+    continue:'继续阅卷',
+    totalLabel1:'阅卷总量',
+    totalLabel2:'人,',
+    start:'开始阅卷',
+    noUnmark:'暂无未阅学生',
+    noMarking:'暂无进行中学生',
+    noMarked:'暂无已阅学生',
 }

+ 3 - 5
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/teachermgmt.js

@@ -96,15 +96,13 @@ export default {
         'knowledge': '知识点库管理',
         'knowledge-read': '查看知识点库信息',
         'knowledge-upd': '修改知识点库信息',
-        'totalIndex': '学情分析',
+        'analysis': '学情分析',
         'analysis-read': '查看学校学情分析',
         'scboard': '统计分析',
         'scboard-read': '查看统计分析',
         'schoolAc': '学校活动',
         'schoolAc-read': '查看学校活动',
-        'schoolAc-upd':'发布学校活动',
-        'schoolEvaluation':'模拟评测数据',
-        'mock-eva':'一键模拟评测作答和评分数据'
+        'schoolAc-upd':'发布学校活动'
     },
     modal:{
         text1: '此账号权限已变更,是否要给此账号更加合适的职称',
@@ -131,7 +129,7 @@ export default {
             sendInvite:'发送邀请',
             backHome: '重新检索'
         },
-        content: '<span>请输入<span class="point">教师账号</span>、<span class="point">电话</span>或<span class="point">电子信箱</span >等资讯进行搜寻</span>',
+        content: '<span>请输入<span class="point">手机号</span>、<span class="point">醍摩豆Id</span>或<span class="point">电子信箱</span >等资讯进行搜寻</span>',
         skyBox:{
             text1: '本次搜寻结果',
             text2: '档案资料数',

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

@@ -3,7 +3,7 @@ export default {
     searchHolder: '搜尋',
     delBatch: '批量刪除',
     delCus: '刪除課程',
-    addCus: '添加課程',
+    addCus: '新增課程',
     editCus: '編輯課程',
     noTeacher: '暫無',
     cusName: '課程名稱',

+ 44 - 9
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/learnActivity.js

@@ -213,15 +213,7 @@ export default {
     },
 
     mark: {
-        baseSetting: '基礎設定',
-        markMode: '閱卷模式',
-        full: '完整閱卷',
-        question: '指定題目',
         markNum: '閱卷次數',
-        allocation: '分配方式',
-        random: '隨機分配',
-        class: '按班分配',
-        scoreDiff: '分差',
         markRole: '閱卷職務',
         errRole: '異常處理:',
         arb: '仲裁教師:',
@@ -264,6 +256,49 @@ export default {
         progress: '進度',
         action: '操作',
         addTeaTitle: '增加閱卷老師',
-        markNum: '閱卷量'
+        markNum: '閱卷量',
+        //ByqU.vue & ByStu.vue
+        quit:'退出閱卷',
+        examName:'考試名稱:',
+        reviewType:'閱卷方式:',
+        byQu:'按題閱卷',
+        byStu:'按人閱卷',
+        stuId:'學生Id',
+        score:'分數:',
+        curQu:'當前題號:',
+        quProg:'題目進度',
+        exception:'異常申報',
+        move:'移動',
+        text:'文字',
+        brush:'畫筆',
+        arrow:'箭頭',
+        oval:'橢圓',
+        rect:'方框',
+        seal:'印章',
+        clear:'清除批註',
+        marked:'已閱',
+        unmark:'未閱',
+        fullScore:'滿分',
+        zeroScore:'零分',
+        submit:'提交分數',
+        setting1:'打分自動切換學生',
+        setting2:'完成批閱自動彈出切換',
+        setting3:'打分自動切換題目',
+        setting4:'完成閱卷自動獲取新學生',
+        toggleQu:'切換題目',
+        toggleStu:'切換學生',
+        saveErr:'保存失敗',
+        noSocreErr:'請先打分',
+        completeQu:'當前題目已閱完,請切換題目',
+        completeStu:'當前完成當前學生評分,如果繼續評分,請切換學生',
+        noAnswer:'未作答',
+        stuInfoErr:'學生信息異常',
+        ummarkQu:'未閱題目',
+        unmarkContent:'題目尚未評分,是否跳轉到對應題目繼續評分? ',
+        finished:'已閱完',
+        noUnMarkStu:'已無未閱學生,請挑選進行中的學生繼續閱卷。 ',
+        completeTask:'您已完成閱卷任務',
+        // ProgPie.vue
+        marking:'進行中'
     }
 }

+ 10 - 7
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/stuAccount.js

@@ -37,8 +37,8 @@ export default {
   delOk: '刪除成功',
   isBottom: '已經到底了',
   edit:'修改',
-  adminClass:'行政班管理',
-  teachClass:'教學班管理',
+  adminClass:'行政班',
+  teachClass:'教學班',
   stuMgt:'學生管理',
 
   //AddStudent.vue
@@ -51,17 +51,20 @@ export default {
   stuNameHolder: '請輸入學生名稱',
   stuSeatNo: '座位號',
   stuSeatNoHolder: '請設定座位號',
-  classroomInfo: '教室資訊',
-  classroomInfoHolder: '請選擇教室',
-  newClassroom: '建立新教室',
-  periodInfo: '學制資訊',
+  classroomInfo: '班級',
+  classroomInfoHolder: '請選擇班級',
+  newClassroom: '建立新班級',
+  periodInfo: '學制',
   gradeInfo: '年級',
   submitAccount: '建立帳號',
   submitActive: '儲存',
   chooseInfo: '選取項目',
   chooseNum: '總計:',
   numUnit: '條',
-  academicYear: '學年度',
+  academicYear: '學級',
+  noMatch:'暫無匹配數據',
+  stuIdErr:'學生賬號不能為空',
+  stuIdErr1:'學生賬號只能包含數字',
 
   //ImportStudent.vue
   importTitle: '匯入學生名單',

+ 10 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/task.js

@@ -13,4 +13,14 @@ export default {
     mLabel6:'人數',    
     markProg:'批閱進度',    
     mark:'批閱',
+    objectiveQu:'客觀題已由系統自動完成評分。 ',
+    lastLabel1:'還剩',
+    lastLabel2:'人未閱,',
+    continue:'繼續閱卷',
+    totalLabel1:'閱卷總量',
+    totalLabel2:'人,',
+    start:'開始閱卷',
+    noUnmark:'暫無未閱學生',
+    noMarking:'暫無進行中學生',
+    noMarked:'暫無已閱學生',
 }

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

@@ -129,7 +129,7 @@ export default {
             sendInvite:'發送邀請',
             backHome: '重新檢索'
         },
-        content: '<span>請輸入<span class="point">教師帳號</span>、<span class="point">電話</span>或<span class="point">電子信箱</span>等資訊進行搜尋</span>',
+        content: '<span>請輸入<span class="point">手機號</span>、<span class="point">醍摩豆Id</span>或<span class="point">電子信箱</span>等資訊進行搜尋</span>',
         skyBox:{
             text1: '本次搜尋結果',
             text2: '檔案資料數',

+ 10 - 10
TEAMModelOS/ClientApp/src/router/routes.js

@@ -91,11 +91,11 @@ export const routes = [
 		path: '/joinclass',
 		component: resolve => require(['@/view/joinclass/JoinClass.vue'], resolve)
 	},
-	{
-		path: '/MarkView',
-		name:'FullMarkView',
-		component: resolve => require(['@/view/learnactivity/markpaper/MarkView.vue'], resolve)
-	},
+	// {
+	// 	path: '/MarkView',
+	// 	name:'FullMarkView',
+	// 	component: resolve => require(['@/view/learnactivity/markpaper/MarkView.vue'], resolve)
+	// },
 	{
 		path: '/schoolList',
 		component: Home,
@@ -238,11 +238,11 @@ export const routes = [
 			]
 		},
 		//废弃 阅卷和批注代码混合,不方便维护
-		{
-			path: 'MarkView',
-			name:'MarkView',
-			component: resolve => require(['@/view/learnactivity/markpaper/MarkView.vue'], resolve)
-		},
+		// {
+		// 	path: 'MarkView',
+		// 	name:'MarkView',
+		// 	component: resolve => require(['@/view/learnactivity/markpaper/MarkView.vue'], resolve)
+		// },
 		// 按人阅卷
 		{
 			path: 'ByStu',

+ 3 - 1
TEAMModelOS/ClientApp/src/store/module/user.js

@@ -155,8 +155,10 @@ export default {
         },
         getRooms: state => {
             return state.schoolProfile.school_rooms
+        },
+        getSchoolBase: state => {
+            return state.schoolProfile.school_base
         }
-
     },
     mutations: {
         setSchoolUserList(state, data) {

+ 33 - 2
TEAMModelOS/ClientApp/src/utils/js-fn.js

@@ -249,7 +249,7 @@ function findChartIndex(str, cha, num) {
 }
 
 /**
- * 根据班级学年年级名称
+ * 根据学年获取年级名称
  * @param data 学校基础数据 schoolProfile.school_base
  * @param curPd 当前学段id
  * @param year 学年
@@ -283,6 +283,36 @@ function getGradeNameByYear(data, curPd, year) {
         return '- -'
     }
 }
+/**
+ * 根据班级学年年级名称
+ * @param data 学校基础数据 schoolProfile.school_base
+ * @param curPd 当前学段id
+ * @param grade 年级index
+ */
+function getYearByGrade(data, curPd, grade) {
+    let date = new Date()
+    let curYear = date.getFullYear()
+    let month = date.getMonth() + 1
+    if (grade > -1 && data && data.period && curPd) {
+        let pData = data.period.find(item => {
+            return item.id == curPd
+        })
+        if (pData) {
+            let start = pData.semesters.find(item => {
+                return item.start == 1
+            })
+            // 根据入学月份确定当前年级和学级的关系
+            if (start && month < start.month) {
+                curYear--
+            }
+            return curYear - grade
+        } else {
+            return curYear
+        }
+    } else {
+        return curYear
+    }
+}
 
 export default {
     groupBy,
@@ -302,5 +332,6 @@ export default {
     formatBytes,
     uuid,
     findChartIndex,
-    getGradeNameByYear
+    getGradeNameByYear,
+    getYearByGrade
 }

+ 25 - 19
TEAMModelOS/ClientApp/src/view/joinclass/JoinClass.vue

@@ -10,22 +10,25 @@
                 </Divider> -->
             </p>
             <p class="course-name">{{cusName}}</p>
-            <p class="info-item">
-                <span class="info-lable">
-                    教师:
-                </span>
-                <span class="info-value">
-                    {{tName}}
-                </span>
-            </p>
-            <p class="info-item">
-                <span class="info-lable">
-                    名单:
-                </span>
-                <span class="info-value">
-                    {{listName}}
-                </span>
-            </p>
+            <div style="width:fit-content;margin: auto;">
+                <p class="info-item">
+                    <span class="info-lable">
+                        教师:
+                    </span>
+                    <span class="info-value">
+                        {{tName}}
+                    </span>
+                </p>
+                <p class="info-item">
+                    <span class="info-lable">
+                        名单:
+                    </span>
+                    <span class="info-value">
+                        {{listName}}
+                    </span>
+                </p>
+            </div>
+
             <div class="join-btn" @click="joinList()">
                 立即加入
             </div>
@@ -74,7 +77,8 @@ export default {
     background-image: url("../../assets/image/bak_light.jpg");
 }
 .join-btn {
-    width: fit-content;
+    // width: fit-content;
+    width: 100%;
     margin: auto;
     margin-top: 60px;
     text-align: center;
@@ -86,7 +90,7 @@ export default {
     letter-spacing: 2px;
     font-weight: 400;
     user-select: none;
-    &:hover{
+    &:hover {
         background: rgba(25, 190, 107, 0.5);
         color: white;
     }
@@ -98,11 +102,13 @@ export default {
     font-family: cursive;
 }
 .join-main-box {
-    width: 100%;
+    max-width: 90%;
+    width: fit-content;
     text-align: center;
     .info-item {
         margin-top: 20px;
         font-size: 15px;
+        width: fit-content;
     }
     .info-lable {
         color: #a5a5a5;

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 1364
TEAMModelOS/ClientApp/src/view/learnactivity/markpaper/MarkView.vue


+ 23 - 4
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -28,7 +28,7 @@
                         <div v-for="(item,index) in courseListShow" :key="index" @click="selectCourse(index)" :class="index === curCusIndex ? 'course-list-item block-bg block-bg-active':'course-list-item block-bg'">
                             <p class="course-name">
                                 {{item.name}}
-                                <Icon type="ios-information-circle-outline" @click="toggleCusInfo" :title="$t('cusMgt.cusInfo')" />
+                                <!-- <Icon type="ios-information-circle-outline" @click="toggleCusInfo" :title="$t('cusMgt.cusInfo')" /> -->
                             </p>
                             <p class="course-code">
                                 <Icon type="md-pricetags" />
@@ -318,7 +318,7 @@
             <StudentList @getSelectInfo="(selction)=>{selections = selction}"></StudentList>
         </Modal>
         <div class="qr-code-wrap" v-show="showQrStatus" @click="showQrStatus = false">
-            <div id="qrcode" :class="showQrStatus ? 'animated fadeIn':'animated fadeOut'" ref="qrcode" style="padding:20px;background-color:white;width:320px;margin:auto;">
+            <div @click.stop id="qrcode" :class="showQrStatus ? 'animated fadeIn':'animated fadeOut'" ref="qrcode" style="padding:20px;background-color:white;width:320px;margin:auto;">
                 <span class="qr-code-text">扫码加入名单</span>
             </div>
         </div>
@@ -1000,8 +1000,27 @@ export default {
 
             //这里需要根据站点动态拼接域名
             let addr = this.$store.state.config.srvAdr
-            let host = ''
-            let url = `http://teammodelos-test.chinacloudsites.cn/joinclass?tId=${tId}&listName=${listName}&tName=${tName}&listId=${listId}&cusName=${cusName}`
+            let type = this.$store.state.config.srvAdrType
+            let host
+            //国际站
+            if (addr == 'Global') {
+                if (type == 'product') {
+                    // 正式站
+                    host = this.$store.state.config[addr].domainUrl[0].url
+                } else {
+                    // 测试站
+                    host = this.$store.state.config[addr].domainUrl[1].url
+                }
+            }
+            // 大陆站
+            else {
+                if (type == 'product') {
+                    host = this.$store.state.config.China.domainUrl[0].url
+                } else {
+                    host = this.$store.state.config.China.domainUrl[1].url
+                }
+            }
+            let url = `${host}/joinclass?tId=${tId}&listName=${listName}&tName=${tName}&listId=${listId}&cusName=${cusName}`
             console.log(url)
             this.createQRCode(url)
         },

+ 418 - 400
TEAMModelOS/ClientApp/src/view/student-account/AddStudent.vue

@@ -1,69 +1,69 @@
 <style lang="less" scoped>
-    @import './AddStudent.less';
+@import "./AddStudent.less";
 </style>
 <style lang="less">
-    .add-student .ivu-input, .add-student .ivu-input-number {
-        background: none;
-        border: none;
-        border-bottom: 1px solid #505050;
-        border-radius: 0px;
-        color: white;
-        font-size: 16px;
-    }
+.add-student .ivu-input,
+.add-student .ivu-input-number {
+    background: none;
+    border: none;
+    border-bottom: 1px solid #505050;
+    border-radius: 0px;
+    color: white;
+    font-size: 16px;
+}
 
-    .add-student .ivu-input-number{
-        width: 100%;
-    }
+.add-student .ivu-input-number {
+    width: 100%;
+}
 
-    .add-student .ivu-modal-footer {
-        border: none;
-    }
-    .add-student .ivu-form-item-label {
-        color: #929292;
-    }
+.add-student .ivu-modal-footer {
+    border: none;
+}
+.add-student .ivu-form-item-label {
+    color: #929292;
+}
 
-    .add-student .ivu-form-item-required .ivu-form-item-label:before {
-        color: #6DE2C4;
-    }
+.add-student .ivu-form-item-required .ivu-form-item-label:before {
+    color: #6de2c4;
+}
 
-    .add-student .ivu-form-item-error .ivu-input:focus {
-        border: none;
-    }
-
-    .add-student .ivu-input-group-prepend {
-        border: none;
-        background: none;
-        color: white;
-        font-size: 14px;
-    }
+.add-student .ivu-form-item-error .ivu-input:focus {
+    border: none;
+}
 
-    .add-student .ivu-checkbox-wrapper {
-        float: right;
-        color: #929292;
-    }
+.add-student .ivu-input-group-prepend {
+    border: none;
+    background: none;
+    color: white;
+    font-size: 14px;
+}
 
-    .add-student .ivu-checkbox-inner {
-        background: none;
-        border-color: #6DE2C4;
-    }
+.add-student .ivu-checkbox-wrapper {
+    float: right;
+    color: #929292;
+}
 
-    .add-student .ivu-checkbox-checked .ivu-checkbox-inner:after {
-        border-color: #6DE2C4;
-    }
+.add-student .ivu-checkbox-inner {
+    background: none;
+    border-color: #6de2c4;
+}
 
-    .account-form .ivu-select-selection {
-        border-color: #505050;
-    }
+.add-student .ivu-checkbox-checked .ivu-checkbox-inner:after {
+    border-color: #6de2c4;
+}
 
-        .account-form .ivu-select-selection:hover {
-            border-color: #57a3f3;
-        }
+.account-form .ivu-select-selection {
+    border-color: #505050;
+}
 
-    .account-form .ivu-select-input {
-        color: white;
-        font-size: 16px;
-    }
+.account-form .ivu-select-selection:hover {
+    border-color: #57a3f3;
+}
 
+.account-form .ivu-select-input {
+    color: white;
+    font-size: 16px;
+}
 </style>
 <template>
 
@@ -73,13 +73,12 @@
             <!-- ID -->
             <FormItem :label="$t('stuAccount.accountInfo')" prop="id">
                 <Input v-model="studentInfo.id" :placeholder="$t('stuAccount.accountHolder')" @on-change="setPassword(same)">
-                <!-- <span slot="prepend">{{schoolCode}}#</span> 前方 -->
                 </Input>
-                <input type="text" style="position:fixed;z-index:-10000;width:0;border:none"/>
+                <input type="text" style="position:fixed;z-index:-10000;width:0;border:none" />
             </FormItem>
             <!-- 密碼 -->
             <FormItem :label="$t('stuAccount.passwordInfo')" prop="pw">
-                <input type="password" style="position:fixed;z-index:-10000;width:0;border:none"/>
+                <input type="password" style="position:fixed;z-index:-10000;width:0;border:none" />
                 <Input v-model="studentInfo.pw" type="password" password :placeholder="$t('stuAccount.passwordHolder')"></Input>
                 <Checkbox v-model="same" @on-change="setPassword">{{$t('stuAccount.isSame')}}</Checkbox>
             </FormItem>
@@ -91,7 +90,7 @@
             <div style="display:flex;justify-content: space-between;">
                 <!-- 學制 -->
                 <FormItem :label="$t('stuAccount.periodInfo')" style="width:45%">
-                    <Select v-model="searchPeriod" style="width: 100%;" :placeholder="$t('stuAccount.periodHolder')" clearable >
+                    <Select v-model="searchPeriod" style="width: 100%;" :placeholder="$t('stuAccount.periodHolder')" clearable>
                         <Option v-for="(item, index) in periods" :value="item.id" :key="index">{{ item.name }}</Option>
                     </Select>
                 </FormItem>
@@ -104,8 +103,8 @@
             </div>
             <!-- 教室資訊 -- 班级 -->
             <FormItem :label="$t('stuAccount.classroomInfo')" prop="classId">
-                <Select filterable style="width:100%" :placeholder="$t('stuAccount.classroomInfoHolder')" v-model="studentInfo.classId" clearable>
-                    <Option v-for="(item,index) in filterClasses" :value="item.id" :key="index" @click.native="setCurrentClassDetail(item)">{{ item.name }}</Option>
+                <Select filterable style="width:100%" :placeholder="$t('stuAccount.classroomInfoHolder')" v-model="studentInfo.classId" clearable :not-found-text="searchGrade ? '暂无匹配数据' : $t('stuAccount.sltPdFirst')">
+                    <Option v-for="(item,index) in filterClasses" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
                 <span style="float:right;color:#6DE2C4;cursor:pointer;text-decoration:underline;font-size:12px;" @click="createClassroom">{{$t('stuAccount.newClassroom')}}</span>
             </FormItem>
@@ -114,16 +113,17 @@
                 <FormItem :label="$t('stuAccount.stuSeatNo')" prop="no" style="width:45%">
                     <InputNumber v-model="studentInfo.no" :min="1" :placeholder="$t('stuAccount.stuSeatNoHolder')"></InputNumber>
                 </FormItem>
-                <!-- 學級 -->
-                <FormItem :label="$t('stuAccount.gradeInfo')" prop="gradeCode" style="width:45%">
-                    <span style="color:white;">{{ gradeName }}</span>
-                </FormItem>
-            </div>
-            <div style="display:flex;justify-content: space-between;">
                 <!-- 學年度 -->
                 <FormItem :label="$t('stuAccount.academicYear')" prop="year" style="width:45%">
                     <InputNumber v-model="studentInfo.year" :editable="false"></InputNumber>
                 </FormItem>
+                <!-- 學級 -->
+                <!-- <FormItem :label="$t('stuAccount.gradeInfo')" prop="gradeCode" style="width:45%">
+                    <span style="color:white;">{{ gradeName }}</span>
+                </FormItem> -->
+            </div>
+            <div style="display:flex;justify-content: space-between;">
+
             </div>
         </Form>
 
@@ -155,9 +155,9 @@
                 <FormItem :label="$t('stuAccount.stuSeatNo')" prop="no" style="width:45%">
                     <Input type="number" number v-model="editStudentInfo[0].no" :min="1" :placeholder="$t('stuAccount.stuSeatNoHolder')"></Input>
                 </FormItem>
-                <FormItem :label="$t('stuAccount.gradeInfo')" prop="gradeCode" style="width:45%">
+                <!-- <FormItem :label="$t('stuAccount.gradeInfo')" prop="gradeCode" style="width:45%">
                     <span style="color:white;">{{ gradeName }}</span>
-                </FormItem>
+                </FormItem> -->
             </div>
             <div style="display:flex;justify-content: space-between;" v-if="editStudentInfo.length == 1">
                 <!-- 學年度 -->
@@ -171,350 +171,384 @@
     </div>
 </template>
 <script>
-    import fn from '@/utils/js-fn.js'
-    import { mapGetters } from 'vuex'
+import fn from '@/utils/js-fn.js'
+import { mapGetters } from 'vuex'
 // import { delete } from 'vuedraggable'
 
-    export default {
-        props: {
-            isShow: {
-                type: Boolean,
-                default: false
-            },
-            schoolCode: {
-                type: String,
-                default: ''
+export default {
+    props: {
+        isShow: {
+            type: Boolean,
+            default: false
+        },
+        schoolCode: {
+            type: String,
+            default: ''
+        },
+        editStudentInfo: {
+            type: Array,
+            default: () => {
+                return [
+                    {
+                        classId: ''
+                    }
+                ]
+            }
+        },
+        bizType: {
+            type: Number,
+            default: 0 //1新增 2编辑
+        }
+    },
+    data() {
+        // 验证只能是数字
+        const validateId = (rule, value, callback) => {
+            if (!value) {
+                return callback(new Error(this.$t('stuAccount.stuIdErr')))
+            }
+            let zg = /^[0-9]+$/
+            if (zg.test(value)) {
+                callback()
+            } else {
+                callback(new Error(this.$t('stuAccount.stuIdErr1')))
+            }
+        }
+        const validateSeatNo = (rule, value, callback) => {
+            let flag = (value == null || typeof value == 'undefined' || value === '')
+            if (flag && (this.studentInfo.classId != null && typeof this.studentInfo.classId != 'undefined' && this.studentInfo.classId !== '')) {
+                callback(new Error('学生座位号不能为空'));
+            } else {
+                callback();
+            }
+        };
+        const validateclassId = (rule, value, callback) => {
+            if (value === '' && (this.studentInfo.no != null && typeof this.studentInfo.no != 'undefined' && this.studentInfo.no !== '')) {
+                callback(new Error('班级资讯不能为空'));
+            } else {
+                callback()
+            }
+        };
+        const validatePw = (rule, value, callback) => {
+            if (this.bizType == 1 && value === '') {
+                callback(new Error('密码不能为空'));
+            } else {
+                callback()
+            }
+        };
+        return {
+            fn,
+            isLoading: false,
+            test: true,
+            showError: false,
+            isFull: false,
+            classroomList: [],
+            same: '',
+            list: [],
+            studentInfo: {
+                name: '',
+                id: '',
+                no: null,
+                classId: '',
+                className: '',
+                // periodCode:'',
+                // gradeCode:'',
+                pw: '',
+                year: new Date().getFullYear()
             },
-            editStudentInfo: {
-                type: Array,
-                default: () => {
-                    return [
-                        {
-                            classId: ''
-                        }
-                    ]
-                }
+            // gradeName: '',
+            ruleValidate: {
+                id: [
+                    { validator: validateId, required: true, trigger: 'change' }
+                ],
+                pw: [
+                    // { required: true, message: '密码不能为空', trigger: 'blur' }
+                    { validator: validatePw, trigger: 'blur' }
+                ],
+                name: [
+                    { required: true, message: '学生姓名不能为空', trigger: 'blur' }
+                ],
+                no: [
+                    { validator: validateSeatNo, type: 'number', trigger: 'blur' }
+                ],
+                classId: [
+                    { validator: validateclassId, trigger: 'blur' },
+                ]
             },
-            bizType: {
-                type: Number,
-                default: 0 //1新增 2编辑
+            modal_loading: false,
+            searchPeriod: '',
+            searchGrade: ''
+        }
+    },
+    computed: {
+        ...mapGetters({
+            periods: 'user/getPeriods', // 學制s
+            grades: 'user/getGrades', // 年級
+            classes: 'user/getClasses', // 教室ID,
+            students: 'schoolBaseInfo/getStudent', // 學生List
+            schoolBase: 'user/getSchoolBase', // 学校基础设置
+        }),
+        filterGrades: function () {
+            var data = this.grades
+            console.log(this.schoolBase)
+            if (this.searchPeriod) {
+                let periodId = this.searchPeriod
+                data = data.filter(function (item) {
+                    return item.periodId == periodId
+                })
+                return data
+            } else {
+                return []
             }
         },
-        data() {
-            const validateSeatNo = (rule, value, callback) => {
-                let flag = (value == null || typeof value == 'undefined' || value === '')
-                if (flag && (this.studentInfo.classId != null && typeof this.studentInfo.classId != 'undefined' && this.studentInfo.classId !=='')) {
-                    callback(new Error('学生座位号不能为空'));                    
-                } else {
-                    callback();
-                }
-            };
-            const validateclassId = (rule, value, callback) => {
-                if (value === '' &&  (this.studentInfo.no != null && typeof this.studentInfo.no != 'undefined' && this.studentInfo.no !=='')) {
-                    callback(new Error('班级资讯不能为空'));
-                } else {
-                    callback()
-                }
-            };
-            const validatePw = (rule, value, callback) => {
-                if(this.bizType == 1 && value === ''){
-                    callback(new Error('密码不能为空'));
-                } else {
-                    callback()
-                }
-            };            
-            return {
-                fn,
-                isLoading: false,
-                test: true,
-                showError: false,
-                isFull: false,
-                classroomList: [],
-                same: '',
-                list: [],
-                studentInfo: {
-                    name: '',
-                    id: '',
-                    no: null,
-                    classId:'',
-                    className:'',
-                    // periodCode:'',
-                    // gradeCode:'',
-                    pw: '',
-                    year: new Date().getFullYear()
-                },
-                gradeName:'',
-                ruleValidate: {
-                    id: [
-                        { required: true, message: '账号不能为空', trigger: 'blur' }
-                    ],
-                    pw: [
-                        // { required: true, message: '密码不能为空', trigger: 'blur' }
-                        { validator: validatePw, trigger: 'blur' }
-                    ],
-                    name: [
-                        { required: true, message: '学生姓名不能为空', trigger: 'blur' }
-                    ],
-                    no: [
-                        { validator: validateSeatNo, type: 'number', trigger: 'blur' }
-                    ],
-                    classId: [
-                        { validator: validateclassId, trigger: 'blur' },
-                    ]
-                },
-                modal_loading: false,
-                searchPeriod: '',
-                searchGrade: ''
+        filterClasses() {
+            var data = this.classes
+            if (this.searchGrade > -1) {
+                let year = this.$jsFn.getYearByGrade(this.schoolBase, this.searchPeriod, this.searchGrade)
+                console.log(year)
+                data = data.filter((item)=>{
+                    return item.year == year && item.periodId == this.searchPeriod
+                })
+                console.log('班级', data)
+                return data
+            } else {
+                return []
             }
         },
-        computed: {
-            ...mapGetters({
-                periods: 'user/getPeriods', // 學制s
-                grades: 'user/getGrades', // 年級
-                classes: 'user/getClasses', // 教室ID,
-                students: 'schoolBaseInfo/getStudent', // 學生List
-            }),
-            filterGrades: function() {
-                var data = this.grades
-                if (this.searchPeriod) {
-                    let periodId = this.searchPeriod
-                    data = data.filter(function(item) {
-                        return item.periodId == periodId
-                    })
-                    return data
-                } else {
-                    return []
-                }
+        show: {
+            get() {
+                // if (this.bizType == 2 && this.isShow == true) {
+                //  if (this.editStudentInfo.length == 1) {
+                //    let arr = this.editStudentInfo[0].id.split("#");
+                //    if (arr.length > 1) {
+                //      this.editStudentInfo[0].id = arr[1];
+                //    } else {
+                //      alert("学生账号格式错误!");
+                //    }
+                //  }
+                // }
+                return this.isShow
             },
-            filterClasses: function() {
-                var data = this.classes
-                if (this.searchGrade) {
-                    let gradeId = this.searchGrade
-                    data = data.filter(function(item) {
-                        return item.gradeId == gradeId && item.openType == '1'
-                    })
-                    return data
-                } else {
-                    return []
-                }
-            },
-            show: {
-                get() {
-                    // if (this.bizType == 2 && this.isShow == true) {
-                    //  if (this.editStudentInfo.length == 1) {
-                    //    let arr = this.editStudentInfo[0].id.split("#");
-                    //    if (arr.length > 1) {
-                    //      this.editStudentInfo[0].id = arr[1];
-                    //    } else {
-                    //      alert("学生账号格式错误!");
-                    //    }
-                    //  }
-                    // }
-                    return this.isShow
-                },
-                set(value) {
-                }
+            set(value) {
             }
+        }
+    },
+    methods: {
+
+        cancel() {
+            this.same = false
+            this.$parent.addStudentStatus = false
+            this.$emit('saveStudentInfo', {
+                action: 0
+            })
         },
-        methods: {
-            
-            cancel() {
-                this.same = false
-                this.$parent.addStudentStatus = false
-                this.$emit('saveStudentInfo', {
-                    action: 0
+        setPassword(data) {
+            //bizType 编辑
+            if (this.bizType == 2) {
+                this.$set(this.editStudentInfo[0], 'pw', data ? this.editStudentInfo[0].id : '')
+            } else {
+                this.studentInfo.pw = data ? this.studentInfo.id : ''
+            }
+        },
+        // setCurrentClassDetail(item) {
+        //     this.$store.dispatch('user/getGradeById', item.gradeId).then(res => {
+        //         if (res.length == 0) {
+        //             this.gradeName = '暫無資訊'
+        //         } else {
+        //             this.gradeName = res.name
+        //         }
+        //     })
+        // },
+        getClassroom() {
+            this.classroomList = this.$store.state.schoolBaseInfo.classroomList
+            if (this.classroomList.length == 0) {
+                this.$api.schoolSetting.findClassInfo({
+                    SchoolCode: this.schoolCode
+                }).then(res => {
+                    if (res.error == null) {
+                        if (res.result.data.length > 0) {
+                            this.classroomList = res.result.data
+                        }
+                    }
                 })
-            },
-            setPassword(data) {
-                //bizType 编辑
+            }
+        },
+        confirm() {
+            this.showError = true
+            if (this.isFull) {
+                this.same = false
+                // 编辑信息
                 if (this.bizType == 2) {
-                    this.$set(this.editStudentInfo[0], 'pw', data ? this.editStudentInfo[0].id : '')
-                } else {
-                    this.studentInfo.pw = data ? this.studentInfo.id : ''
-                }
-            },
-            setCurrentClassDetail(item){
-                this.$store.dispatch('user/getGradeById', item.gradeId).then(res=>{
-                    if(res.length == 0){
-                        this.gradeName = '暫無資訊'
-                    } else {
-                        this.gradeName = res.name
-                    }
-                })   
-            },
-            getClassroom() {
-                this.classroomList = this.$store.state.schoolBaseInfo.classroomList
-                if (this.classroomList.length == 0) {
-                    this.$api.schoolSetting.findClassInfo({
-                        SchoolCode: this.schoolCode
-                    }).then(res => {
-                        if (res.error == null) {
-                            if (res.result.data.length > 0) {
-                                this.classroomList = res.result.data
-                            }
-                        }
-                    })
-                }
-            },
-            confirm() {
-                this.showError = true
-                if (this.isFull) {
-                    this.same = false
-                    if (this.bizType == 2) {
-
-                        this.isLoading = true
-                        let stringify = JSON.stringify( this.editStudentInfo)
-                        let parse = JSON.parse(stringify)
-                        let apiData = []
-                        if(parse.length == 1){
-                            let temp = parse.map(function(item){
-                                let data = {
-                                    id: item.id,
-                                    year: item.year ? item.year.toString() : '',
-                                    no: item.no ? item.no.toString() : '',
-                                    name: item.name,
-                                    classId: item.classId ? item.classId : ''
-                                }
-                                if(data.classId == '') data.no = ''
-                                return data
-                            })
-                            if(this.isRepeat(temp[0])){
-                                this.$Message.error('請檢查 帳號資訊 或 座號重複 了。')
-                                this.isLoading = false
-                            } else {
-                                apiData = temp
+                    this.isLoading = true
+                    let stringify = JSON.stringify(this.editStudentInfo)
+                    let parse = JSON.parse(stringify)
+                    let apiData = []
+                    if (parse.length == 1) {
+                        let temp = parse.map(function (item) {
+                            let data = {
+                                id: item.id,
+                                year: item.year ? item.year.toString() : '',
+                                no: item.no ? item.no.toString() : '',
+                                name: item.name,
+                                classId: item.classId ? item.classId : ''
                             }
+                            if (data.classId == '') data.no = ''
+                            return data
+                        })
+                        if (this.isRepeat(temp[0])) {
+                            this.$Message.error('請檢查 帳號資訊 或 座號重複 了。')
+                            this.isLoading = false
                         } else {
-                            let classId = parse[0].classId
-                            let temp = parse.map(function(item){
-                                return {
-                                    no : "",
-                                    id: item.id,
-                                    classId: classId,
-                                    name: item.name,
-                                    year: item.year ? item.year.toString() : ''
-                                }
-                            })
                             apiData = temp
                         }
-                        if(apiData.length > 0){                 
-                            // 新增 如果密碼沒被改變就拿掉此Key           
-                            apiData.forEach( (item) =>{
-                                if(item.pw == '******') {
-                                    delete item.pw
-                                }
-                            })
+                    } else {
+                        let classId = parse[0].classId
+                        let temp = parse.map(function (item) {
+                            return {
+                                no: "",
+                                id: item.id,
+                                classId: classId,
+                                name: item.name,
+                                year: item.year ? item.year.toString() : ''
+                            }
+                        })
+                        apiData = temp
+                    }
+                    if (apiData.length > 0) {
+                        // 新增 如果密碼沒被改變就拿掉此Key           
+                        apiData.forEach((item) => {
+                            if (item.pw == '******') {
+                                delete item.pw
+                            }
+                        })
 
-                            this.$api.stuAccount.saveAllStudent(this.schoolCode, apiData).then(
-                                (res) => {
-                                    if (!res.errorId) {
-                                        this.show = false
-                                        this.$emit('saveStudentInfo', {
-                                            action: 2, // 批量修改数据
-                                            studentInfos: res.students
-                                        })
-                                        this.$refs.updateForm.resetFields()
-                                        this.uploadLoading = false
-                                    } else {
-                                        this.$Message.error('API error!')
-                                    }
-                                    this.isLoading = false
-                                },
-                                (err) => {
+                        this.$api.stuAccount.saveAllStudent(this.schoolCode, apiData).then(
+                            (res) => {
+                                if (!res.errorId) {
+                                    this.show = false
+                                    this.$emit('saveStudentInfo', {
+                                        action: 2, // 批量修改数据
+                                        studentInfos: res.students
+                                    })
+                                    this.$refs.updateForm.resetFields()
+                                    this.uploadLoading = false
+                                } else {
                                     this.$Message.error('API error!')
-                                    this.isLoading = false
                                 }
-                            )
-                        }
-                    } else {
-                        this.isLoading = true
-
-                        let apiData = 
+                                this.isLoading = false
+                            },
+                            (err) => {
+                                this.$Message.error('API error!')
+                                this.isLoading = false
+                            }
+                        )
+                    }
+                } 
+                // 新增学生
+                else {
+                    this.isLoading = true
+                    let apiData =
                         [
                             {
-                            "id": this.studentInfo.id,
-                            "no": this.studentInfo.no ? this.studentInfo.no.toString() : '',
-                            "name": this.studentInfo.name,
-                            "year": this.studentInfo.year ? this.studentInfo.year.toString() : '',
-                            "pw": this.studentInfo.pw,
-                            "classId": this.studentInfo.classId,
-                            // Excel 匯入才需要給classname
-                            // "className":this.studentInfo.classroomName ? this.studentInfo.classroomName : ''
+                                "id": this.studentInfo.id,
+                                "no": this.studentInfo.no ? this.studentInfo.no.toString() : '',
+                                "name": this.studentInfo.name,
+                                "year": this.studentInfo.year,
+                                "pw": this.studentInfo.pw,
+                                "classId": this.studentInfo.classId,
+                                // Excel 匯入才需要給classname
+                                // "className":this.studentInfo.classroomName ? this.studentInfo.classroomName : ''
                             }
                         ]
-                        if(this.isRepeat(apiData[0])){
-                            this.$Message.error('請檢查 帳號資訊 或 座號重複 了。')
-                            this.isLoading = false
-                        } else {
-                            this.$api.stuAccount.saveStudent(this.schoolCode, apiData).then(
-                                (res) => {
-                                    if (!res.errorId) {
-                                        this.show = false
-                                        res.gradeId = this.searchGrade
-                                        res.periodId = this.searchPeriod
-                                        this.$emit('saveStudentInfo', {
-                                            action: 1, // 新增学生
-                                            studentInfos: res
-                                        })
-                                        this.$refs.studentInfoForm.resetFields()
-                                    }
-                                    this.isLoading = false
-                                },
-                                (err) => {
-                                    this.$Message.error('API error!')
-                                    this.isLoading = false
+                    if (this.isRepeat(apiData[0])) {
+                        this.$Message.error('請檢查 帳號資訊 或 座號重複 了。')
+                        this.isLoading = false
+                    } else {
+                        this.$api.stuAccount.saveStudent(this.schoolCode, apiData).then(
+                            (res) => {
+                                if (!res.errorId) {
+                                    this.show = false
+                                    res.gradeId = this.searchGrade
+                                    res.periodId = this.searchPeriod
+                                    this.$emit('saveStudentInfo', {
+                                        action: 1, // 新增学生
+                                        studentInfos: res
+                                    })
+                                    this.$refs.studentInfoForm.resetFields()
                                 }
-                            )
-                        }
+                                this.isLoading = false
+                            },
+                            (err) => {
+                                this.$Message.error('API error!')
+                                this.isLoading = false
+                            }
+                        )
                     }
-                } else {
-                    this.$Message.error('请完善信息!')
                 }
-            },
-            createClassroom() {
-                this.$router.push({
-                    path: '/home/classroom'
-                })
-            },
-            isRepeat(data){
-                if(this.bizType == 1){
-                    return this.students.some(function(item){
-                        return (item.id === data.id || (data.classId !='' && data.classId === item.classId && data.no === item.no))
-                    })
-                } else if(this.bizType == 2){
-                    let temp = this.students.filter(function(item){
-                        return (data.classId !='' && data.classId === item.classId && data.no === item.no)
-                    })
-                    if(temp.length > 0){
-                        return !(temp[0].id == data.id)
-                    } else {
-                        return false
-                    }
-                }                
+            } else {
+                this.$Message.error('请完善信息!')
             }
         },
-        created() {
-            // this.getClassroom()
+        createClassroom() {
+            // this.$router.push({
+            //     path: '/home/classroom'
+            // })
+            this.$emit('createClass')
         },
-        mounted() {
-            if (this.bizType == 2 && this.isShow == true) {
-                if (this.editStudentInfo.length == 1) {
-                    this.setCurrentClassDetail(this.editStudentInfo[0])
-                    // let arr = this.editStudentInfo[0].id.split('#')
-                    // if (arr.length > 1) {
-                    //     this.editStudentInfo[0].id = arr[1]
-                    // } else {
-                    //     alert('学生账号格式错误!')
-                    // }
+        isRepeat(data) {
+            if (this.bizType == 1) {
+                return this.students.some(function (item) {
+                    return (item.id === data.id || (data.classId != '' && data.classId === item.classId && data.no === item.no))
+                })
+            } else if (this.bizType == 2) {
+                let temp = this.students.filter(function (item) {
+                    return (data.classId != '' && data.classId === item.classId && data.no === item.no)
+                })
+                if (temp.length > 0) {
+                    return !(temp[0].id == data.id)
+                } else {
+                    return false
                 }
             }
+        }
+    },
+    created() {
+        // this.getClassroom()
+    },
+    mounted() {
+        if (this.bizType == 2 && this.isShow == true) {
+            if (this.editStudentInfo.length == 1) {
+                // this.setCurrentClassDetail(this.editStudentInfo[0])
+                // let arr = this.editStudentInfo[0].id.split('#')
+                // if (arr.length > 1) {
+                //     this.editStudentInfo[0].id = arr[1]
+                // } else {
+                //     alert('学生账号格式错误!')
+                // }
+            }
+        }
+    },
+    watch: {
+        studentInfo: {
+            handler(newValue, oldValue) {
+                if (this.bizType == 1) {
+                    this.showError = false
+                    this.$refs.studentInfoForm.validate((valid) => {
+                        if (valid) {
+                            this.isFull = true
+                        } else {
+                            this.isFull = false
+                        }
+                    })
+                }
+            },
+            deep: true
         },
-        watch: {
-            studentInfo: {
-                handler(newValue, oldValue) {
-                    if (this.bizType == 1) {
-                        this.showError = false
-                        this.$refs.studentInfoForm.validate((valid) => {
+        editStudentInfo: {
+            handler(newValue, oldValue) {
+                this.$nextTick(() => {
+                    this.showError = false
+                    if (this.bizType == 2) {
+                        this.$refs.updateForm.validate((valid) => {
                             if (valid) {
                                 this.isFull = true
                             } else {
@@ -522,32 +556,16 @@
                             }
                         })
                     }
-                },
-                deep: true
+                })
             },
-            editStudentInfo: {
-                handler(newValue, oldValue) {
-                    this.$nextTick(() => {
-                        this.showError = false
-                        if (this.bizType == 2) {
-                            this.$refs.updateForm.validate((valid) => {
-                                if (valid) {
-                                    this.isFull = true
-                                } else {
-                                    this.isFull = false
-                                }
-                            })
-                        }
-                    })
-                },
-                deep: true,
-                immediate: true
-            }
+            deep: true,
+            immediate: true
         }
     }
+}
 </script>
 <style>
-    .account-form .ivu-btn {
-        border:none;
-    }
+.account-form .ivu-btn {
+    border: none;
+}
 </style>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/student-account/ClassMgt.vue

@@ -193,7 +193,7 @@ export default {
         PersonalPhoto, StudentList
     },
     data() {
-        // 验证只能是字母和数字
+        // 验证只能是数字
         const validateCode = (rule, value, callback) => {
             if (!value) {
                 return callback(new Error(this.$t('schoolBaseInfo.classNoErr')))

+ 6 - 2
TEAMModelOS/ClientApp/src/view/student-account/Index.vue

@@ -93,7 +93,7 @@
                             <span>{{ row.no }}</span>
                         </template>
                         <template slot-scope="{ row }" slot="gradeName">
-                            <span>{{ $jsFn.getGradeNameByYear(schoolBase, searchPeriod, row.year) }}</span>
+                            <span>{{ $jsFn.getGradeNameByYear(schoolBase, searchPeriod, row.classYear) }}</span>
                         </template>
                         <template slot-scope="{ row }" slot="action" v-if="authorizationStatus == false">
                             <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
@@ -117,7 +117,7 @@
             <MgtStuList></MgtStuList>
         </div>
         <Modal v-model="addStudentStatus" width="520" class-name="add-student dark-iview-modal" :mask-closable="false">
-            <add-student v-if="addStudentStatus" :schoolCode="$store.state.user.schoolCode" :isShow="addStudentStatus" :editStudentInfo="editStudentInfo" @saveStudentInfo="closeAddStudent" :bizType="bizType"></add-student>
+            <add-student v-if="addStudentStatus" :schoolCode="$store.state.user.schoolCode" :isShow="addStudentStatus" :editStudentInfo="editStudentInfo" @saveStudentInfo="closeAddStudent" :bizType="bizType" @createClass="createClass"></add-student>
             <div slot="footer"></div>
         </Modal>
         <Modal v-model="importStudentStatus" width="70%" class="import-student" :mask-closable="false">
@@ -198,6 +198,10 @@ export default {
         }
     },
     methods: {
+        createClass(){
+            this.addStudentStatus = false
+            this.tab = 'class'
+        },
         /**
          * 重置密碼
          * @param row

+ 39 - 29
TEAMModelOS/ClientApp/src/view/task/mark/ByQu.vue

@@ -4,23 +4,23 @@
         <!-- 头部基础信息 -->
         <div class="mark-header">
             <span class="quit-marking-text">
-                <Icon type="ios-arrow-back" class="quit-marking-icon" title="退出阅卷" @click="quit" />
+                <Icon type="ios-arrow-back" class="quit-marking-icon" :title="$t('learnActivity.mark.quit')" @click="quit" />
             </span>
-            <span class="info-label">考试名称:</span>
+            <span class="info-label">{{$t('learnActivity.mark.examName')}}</span>
             <span class="info-value">{{taskInfo.name}}</span>
-            <span class="info-label">阅卷方式:</span>
-            <span class="info-value">按题阅卷</span>
-            <span class="info-label">当前题号:</span>
+            <span class="info-label">{{$t('learnActivity.mark.reviewType')}}</span>
+            <span class="info-value">{{$t('learnActivity.mark.byQu')}}</span>
+            <span class="info-label">{{$t('learnActivity.mark.curQu')}}</span>
             <span class="info-value cur-qu-index" v-if="childIndex > -1">{{`${quIndex + 1}-${childIndex + 1}`}}</span>
             <span class="info-value cur-qu-index" v-else>{{quIndex + 1}}</span>
-            <span class="info-label">题目进度:</span>
+            <span class="info-label">{{$t('learnActivity.mark.quProg')}}</span>
             <span class="info-value stu-id-info">{{curProg}}</span>
-            <span class="info-label">学生:</span>
+            <span class="info-label">{{$t('learnActivity.mark.stuId')}}</span>
             <span class="info-value stu-id-info">{{stusInfo[stuIndex] ? stusInfo[stuIndex].stuId : ''}}</span>
             <div class="btn-wrap">
                 <span class="action-btn" @click="toggleStatus = !toggleStatus">
                     <Icon type="md-shuffle" class="action-btn-icon" />
-                    切换题目
+                    {{$t('learnActivity.mark.toggleQu')}}
                 </span>
                 <!-- <span class="action-btn">
                     <Icon type="md-refresh" class="action-btn-icon" />
@@ -28,26 +28,26 @@
                 </span> -->
                 <span class="action-btn"  @click="exception">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon" />
-                    异常申报
+                    {{$t('learnActivity.mark.exception')}}
                 </span>
             </div>
         </div>
         <div class="mark-main">
             <!-- 工具条 -->
             <div class="mark-tools-wrap">
-                <Icon custom="iconfont icon-move" class="tool-icon" title="移动" @click="mouseStatus = 'move'" />
-                <Icon custom="iconfont icon-text" class="tool-icon" title="文字批注" @click="mouseStatus = 'text'" />
-                <Icon custom="iconfont icon-mark" class="tool-icon" title="画笔" @click="mouseStatus = 'line'" />
-                <Icon custom="iconfont icon-arrow-mark" class="tool-icon" title="箭头" @click="mouseStatus = 'arrow'" />
-                <Icon custom="iconfont icon-oval" class="tool-icon" title="椭圆" @click="mouseStatus = 'oval'" />
-                <Icon custom="iconfont icon-rect" class="tool-icon" title="方框" @click="mouseStatus = 'rect'" />
+                <Icon custom="iconfont icon-move" class="tool-icon" :title="$t('learnActivity.mark.move')" @click="mouseStatus = 'move'" />
+                <Icon custom="iconfont icon-text" class="tool-icon" :title="$t('learnActivity.mark.text')" @click="mouseStatus = 'text'" />
+                <Icon custom="iconfont icon-mark" class="tool-icon" :title="$t('learnActivity.mark.brush')" @click="mouseStatus = 'line'" />
+                <Icon custom="iconfont icon-arrow-mark" class="tool-icon" :title="$t('learnActivity.mark.arrow')" @click="mouseStatus = 'arrow'" />
+                <Icon custom="iconfont icon-oval" class="tool-icon" :title="$t('learnActivity.mark.oval')" @click="mouseStatus = 'oval'" />
+                <Icon custom="iconfont icon-rect" class="tool-icon" :title="$t('learnActivity.mark.rect')" @click="mouseStatus = 'rect'" />
                 <Poptip transfer placement="right">
-                    <Icon custom="iconfont icon-smile" class="tool-icon" title="图标" />
+                    <Icon custom="iconfont icon-smile" class="tool-icon" :title="$t('learnActivity.mark.seal')" />
                     <div slot="content" class="expression-box">
                         <img v-for="(item,index) in imgs" :key="index" :src="item" alt="" class="expression-img" @click="drawImg(index)">
                     </div>
                 </Poptip>
-                <Icon custom="iconfont icon-fresh" class="tool-icon" title="清除批注" @click="clear" />
+                <Icon custom="iconfont icon-fresh" class="tool-icon" :title="$t('learnActivity.mark.clear')" @click="clear" />
                 <!-- <Icon :custom="isFull ? 'iconfont icon-cancel-full' : 'iconfont icon-full-screen'" class="tool-icon" :title="isFull ? '取消全屏' : '全屏'" @click="togglefull" /> -->
             </div>
             <div class="mark-stage">
@@ -56,12 +56,16 @@
             <!-- 打分部分 -->
             <div class="score-wrap">
                 <div class="quick-score-box score-input-box">
-                    <span>分数:</span>
+                    <span>{{$t('learnActivity.mark.score')}}</span>
                     <InputNumber style="flex:1" :max="10" :min="1" v-model="score" @on-change="setScore"></InputNumber>
                 </div>
                 <div class="quick-score-box">
-                    <Button size="small" type="info" style="margin-right:8px" ghost @click="score = quScoreArr.length - 1">满分</Button>
-                    <Button size="small" type="error" ghost @click="score = 0">零分</Button>
+                    <Button size="small" type="info" style="margin-right:8px" ghost @click="score = quScoreArr.length - 1">
+                        {{$t('learnActivity.mark.fullScore')}}
+                    </Button>
+                    <Button size="small" type="error" ghost @click="score = 0">
+                        {{$t('learnActivity.mark.zeroScore')}}
+                    </Button>
                     <Icon :type="isShowNum ? 'md-eye-off' : 'md-eye'" class="toggle-num-status" @click="isShowNum = !isShowNum" />
                     <div :class="['score-key-box', isShowNum ? '':'hind-key-box']">
                         <vuescroll>
@@ -71,14 +75,20 @@
                         </vuescroll>
                     </div>
                 </div>
-                <Button type="success" class="submit-score" @click="submit()">提交分数</Button>
+                <Button type="success" class="submit-score" @click="submit()">
+                    {{$t('learnActivity.mark.submit')}}
+                </Button>
                 <div class="score-setting-wrap">
                     <div class="score-setting-item">
-                        <span>打分自动切换学生</span>
+                        <span>
+                            {{$t('learnActivity.mark.setting1')}}
+                        </span>
                         <i-switch v-model="autoStu" size="small" />
                     </div>
                     <div class="score-setting-item">
-                        <span>完成整题批阅自动弹出切换</span>
+                        <span>
+                            {{$t('learnActivity.mark.setting2')}}
+                        </span>
                         <i-switch v-model="autoQu" size="small" />
                     </div>
                 </div>
@@ -86,7 +96,7 @@
         </div>
         <!-- 用来单独渲染学生作答数据,提高tocanvas 的效率 -->
         <iframe id="markIframe1" :srcdoc="curAnswer" v-if="curAnswer"></iframe>
-        <Modal v-model="toggleStatus" title="切换题目" :width="800" footer-hide>
+        <Modal v-model="toggleStatus" :title="$t('learnActivity.mark.toggleQu')" :width="800" footer-hide>
             <div class="qu-prog-wrap" style="height:600px">
                 <vuescroll>
                     <QuProg :paperData="paperData" :stusData="stusInfo" :total="taskInfo.count || 1" @getQuIndex="setQuIndex"></QuProg>
@@ -213,11 +223,11 @@ export default {
                         this.getDefStu()
                     },
                     err => {
-                        this.$Message.error('保存失败')
+                        this.$Message.error(this.$t('learnActivity.mark.saveErr'))
                     }
                 )
             } else {
-                this.$Message.warning('请先打分')
+                this.$Message.warning(this.$t('learnActivity.mark.noSocreErr'))
             }
         },
         quit() {
@@ -268,7 +278,7 @@ export default {
                 if (this.autoQu) {
                     this.toggleStatus = true
                 } else {
-                    this.$Message.warning('当前题目已阅完,请切换题目')
+                    this.$Message.warning(this.$t('learnActivity.mark.completeQu'))
                 }
             } else if (!has && this.stusInfo.length < this.taskInfo.count) {
                 //当前学生数据已阅,需要继续随机获取学生进行阅卷
@@ -348,10 +358,10 @@ export default {
                 if (this.stusInfo[this.stuIndex].info.answer) {
                     return this.stusInfo[this.stuIndex].info.answer[this.getScoreIndex(this.quIndex, this.childIndex)]
                 } else {
-                    return this.stusInfo[this.stuIndex].stuId + '未作答'
+                    return this.stusInfo[this.stuIndex].stuId + this.$t('learnActivity.mark.noAnswer')
                 }
             } else {
-                return '学生信息异常'
+                return this.$t('learnActivity.mark.stuInfoErr')
             }
         },
         /**当期题目分数数组 */

+ 45 - 37
TEAMModelOS/ClientApp/src/view/task/mark/ByStu.vue

@@ -4,23 +4,23 @@
         <!-- 头部基础信息 -->
         <div class="mark-header">
             <span class="quit-marking-text">
-                <Icon type="ios-arrow-back" class="quit-marking-icon" title="退出阅卷" @click="quit" />
+                <Icon type="ios-arrow-back" class="quit-marking-icon" :title="$t('learnActivity.mark.quit')" @click="quit" />
             </span>
-            <span class="info-label">考试名称:</span>
+            <span class="info-label">{{$t('learnActivity.mark.examName')}}</span>
             <span class="info-value">{{taskInfo.name}}</span>
-            <span class="info-label">阅卷方式:</span>
-            <span class="info-value">按人阅卷</span>
-            <span class="info-label">学生id:</span>
+            <span class="info-label">{{$t('learnActivity.mark.reviewType')}}</span>
+            <span class="info-value">{{$t('learnActivity.mark.byStu')}}</span>
+            <span class="info-label">{{$t('learnActivity.mark.stuId')}}</span>
             <span class="info-value stu-id-info">{{stuId}}</span>
-            <span class="info-label">分数:</span>
+            <span class="info-label">{{$t('learnActivity.mark.score')}}</span>
             <span class="info-value score-info">{{totalScore}}</span>
-            <span class="info-label">当前题号:</span>
+            <span class="info-label">{{$t('learnActivity.mark.curQu')}}</span>
             <span class="info-value cur-qu-index" v-if="childIndex > -1">{{`${quIndex + 1}-${childIndex + 1}`}}</span>
             <span class="info-value cur-qu-index" v-else>{{quIndex + 1}}</span>
             <div class="btn-wrap">
                 <span class="action-btn" @click="toggleStatus = !toggleStatus">
                     <Icon type="md-shuffle" class="action-btn-icon" />
-                    切换学生
+                    {{$t('learnActivity.mark.toggleStu')}}
                 </span>
                 <!-- <span class="action-btn">
                     <Icon type="md-refresh" class="action-btn-icon" />
@@ -28,26 +28,26 @@
                 </span> -->
                 <span class="action-btn" @click="exception">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon"/>
-                    异常申报
+                    {{$t('learnActivity.mark.exception')}}
                 </span>
             </div>
         </div>
         <div class="mark-main">
             <!-- 工具条 -->
             <div class="mark-tools-wrap">
-                <Icon custom="iconfont icon-move" class="tool-icon" title="移动" @click="mouseStatus = 'move'" />
-                <Icon custom="iconfont icon-text" class="tool-icon" title="文字批注" @click="mouseStatus = 'text'" />
-                <Icon custom="iconfont icon-mark" class="tool-icon" title="画笔" @click="mouseStatus = 'line'" />
-                <Icon custom="iconfont icon-arrow-mark" class="tool-icon" title="箭头" @click="mouseStatus = 'arrow'" />
-                <Icon custom="iconfont icon-oval" class="tool-icon" title="椭圆" @click="mouseStatus = 'oval'" />
-                <Icon custom="iconfont icon-rect" class="tool-icon" title="方框" @click="mouseStatus = 'rect'" />
+                <Icon custom="iconfont icon-move" class="tool-icon" :title="$t('learnActivity.mark.move')" @click="mouseStatus = 'move'" />
+                <Icon custom="iconfont icon-text" class="tool-icon" :title="$t('learnActivity.mark.text')" @click="mouseStatus = 'text'" />
+                <Icon custom="iconfont icon-mark" class="tool-icon" :title="$t('learnActivity.mark.brush')" @click="mouseStatus = 'line'" />
+                <Icon custom="iconfont icon-arrow-mark" class="tool-icon" :title="$t('learnActivity.mark.arrow')" @click="mouseStatus = 'arrow'" />
+                <Icon custom="iconfont icon-oval" class="tool-icon" :title="$t('learnActivity.mark.oval')" @click="mouseStatus = 'oval'" />
+                <Icon custom="iconfont icon-rect" class="tool-icon" :title="$t('learnActivity.mark.rect')" @click="mouseStatus = 'rect'" />
                 <Poptip transfer placement="right">
-                    <Icon custom="iconfont icon-smile" class="tool-icon" title="图标" />
+                    <Icon custom="iconfont icon-smile" class="tool-icon" :title="$t('learnActivity.mark.seal')" />
                     <div slot="content" class="expression-box">
                         <img v-for="(item,index) in imgs" :key="index" :src="item" alt="" class="expression-img" @click="drawImg(index)">
                     </div>
                 </Poptip>
-                <Icon custom="iconfont icon-fresh" class="tool-icon" title="清除批注" @click="clear" />
+                <Icon custom="iconfont icon-fresh" class="tool-icon" :title="$t('learnActivity.mark.clear')" @click="clear" />
                 <!-- <Icon :custom="isFull ? 'iconfont icon-cancel-full' : 'iconfont icon-full-screen'" class="tool-icon" :title="isFull ? '取消全屏' : '全屏'" @click="togglefull" /> -->
             </div>
             <div class="mark-stage">
@@ -56,10 +56,10 @@
                 <div class="qu-index-box">
                     <div class="qu-tips-box">
                         <span class="qu-tips-tag">
-                            已阅
+                            {{$t('learnActivity.mark.marked')}}
                         </span>
                         <span class="qu-tips-tag">
-                            未阅
+                            {{$t('learnActivity.mark.unmark')}}
                         </span>
                     </div>
                     <div>
@@ -81,12 +81,16 @@
             <!-- 打分部分 -->
             <div class="score-wrap">
                 <div class="quick-score-box score-input-box">
-                    <span>分数:</span>
+                    <span>{{$t('learnActivity.mark.score')}}</span>
                     <InputNumber style="flex:1" :max="10" :min="1" v-model="score" @on-change="setScore"></InputNumber>
                 </div>
                 <div class="quick-score-box">
-                    <Button size="small" type="info" style="margin-right:8px" ghost @click="score = 10">满分</Button>
-                    <Button size="small" type="error" ghost @click="score = 0">零分</Button>
+                    <Button size="small" type="info" style="margin-right:8px" ghost @click="score = 10">
+                        {{$t('learnActivity.mark.fullScore')}}
+                    </Button>
+                    <Button size="small" type="error" ghost @click="score = 0">
+                        {{$t('learnActivity.mark.zeroScore')}}
+                    </Button>
                     <Icon :type="isShowNum ? 'md-eye-off' : 'md-eye'" class="toggle-num-status" @click="isShowNum = !isShowNum" />
                     <div :class="['score-key-box', isShowNum ? '':'hind-key-box']">
                         <vuescroll>
@@ -96,14 +100,20 @@
                         </vuescroll>
                     </div>
                 </div>
-                <Button type="success" class="submit-score" @click="submit()">提交分数</Button>
+                <Button type="success" class="submit-score" @click="submit()">
+                    {{$t('learnActivity.mark.submit')}}
+                </Button>
                 <div class="score-setting-wrap">
                     <div class="score-setting-item">
-                        <span>打分自动切换题目</span>
+                        <span>
+                            {{$t('learnActivity.mark.setting3')}}
+                        </span>
                         <i-switch v-model="autoQu" size="small" />
                     </div>
                     <div class="score-setting-item">
-                        <span>完成阅卷自动获取新学生</span>
+                        <span>
+                            {{$t('learnActivity.mark.setting4')}}
+                        </span>
                         <i-switch v-model="autoStu" size="small" />
                     </div>
                 </div>
@@ -111,7 +121,7 @@
         </div>
         <!-- 用来单独渲染学生作答数据,提高tocanvas 的效率 -->
         <iframe id="markIframe" :srcdoc="curAnswer"></iframe>
-        <Modal v-model="toggleStatus" title="切换学生" :width="800" footer-hide>
+        <Modal v-model="toggleStatus" :title="$t('learnActivity.mark.toggleStu')" :width="800" footer-hide>
             <StuProg @getStuId="toByStuView" class="light-stu-prog" :total="taskInfo.count" :stusData="stusData"></StuProg>
         </Modal>
     </div>
@@ -260,17 +270,16 @@ export default {
                 }
                 this.$api.mark.saveScore(requstData).then(
                     res => {
-                        this.$Message.success('保存成功')
                         // 按人阅卷自动跳转下一题
                         this.nextQuestion()
                         this.ansToImg()
                     },
                     err => {
-                        this.$Message.error('保存失败')
+                        this.$Message.error(this.$t('learnActivity.mark.saveErr'))
                     }
                 )
             } else {
-                this.$Message.warning('请先打分')
+                this.$Message.warning(this.$t('learnActivity.mark.noSocreErr'))
             }
         },
         nextQuestion() {
@@ -279,7 +288,7 @@ export default {
                 if (this.autoStu) {
                     this.toggleStatus = true
                 } else {
-                    this.$Message.warning('当前完成当前学生评分,如果继续评分,请切换学生')
+                    this.$Message.warning(this.$t('learnActivity.mark.completeStu'))
                 }
                 return
             }
@@ -356,21 +365,20 @@ export default {
                         }
                         qu = childIndex > -1 ? `${(quIndex + 1)}-${(childIndex + 1)}` : quIndex
                         this.$Modal.confirm({
-                            title: '未阅题目',
-                            content: `${qu}题目尚未评分,是否跳转到对应题目继续评分?`,
+                            title: this.$t('learnActivity.mark.ummarkQu'),
+                            content: `${qu}${this.$t('learnActivity.mark.unmarkContent')}`,
                             onOk: () => {
                                 this.quIndex = quIndex
                                 this.childIndex = childIndex
                             }
                         })
                     } else {
-                        this.$Message.success('已阅完')
+                        this.$Message.success(this.$t('learnActivity.mark.finished'))
                         if (this.autoStu) {
                             //TODE 随机获取下一位学生
                             this.toggleStatus = true
                         }
                     }
-
                 }
             }
             this.score = this.stuScore[this.getScoreIndex(this.quIndex, this.childIndex)] == -1 ? null : this.stuScore[this.getScoreIndex(this.quIndex, this.childIndex)]
@@ -409,10 +417,10 @@ export default {
                         return item.info.score.includes(-1)
                     })
                     if (res.length) {
-                        this.$Message.warning('已无未阅学生,请挑选进行中的学生继续阅卷。')
+                        this.$Message.warning(this.$t('learnActivity.mark.noUnMarkStu'))
                         this.toggleStatus = true
                     } else {
-                        this.$Message.success('您已完成阅卷任务')
+                        this.$Message.success(this.$t('learnActivity.mark.completeTask'))
                     }
 
                 } else {
@@ -505,7 +513,7 @@ export default {
                 this.score = this.stuScore[index] == -1 ? null : this.stuScore[index]
                 return this.stuAnswer[index]
             } else {
-                return this.stuId + '未作答'
+                return this.stuId + this.$t('learnActivity.mark.noAnswer')
             }
 
         },

+ 8 - 4
TEAMModelOS/ClientApp/src/view/task/mark/ProgPie.vue

@@ -34,7 +34,11 @@ export default {
                     itemWidth: 10,
                     itemHeight: 10,
                     left: 'center',
-                    data: ['已阅', '进行中', '未阅'],
+                    data: [
+                        this.$t('learnActivity.mark.marked'),
+                        this.$t('learnActivity.mark.marking'),
+                        this.$t('learnActivity.mark.unmark')
+                    ],
                     textStyle: {
                         color: '#ddd',
                         fontSize: 11,
@@ -49,21 +53,21 @@ export default {
                         data: [
                             {
                                 value: 0,
-                                name: '已阅',
+                                name: this.$t('learnActivity.mark.marked'),
                                 itemStyle: {
                                     color: "#9ff080"
                                 },
                             },
                             {
                                 value: 0,
-                                name: '进行中',
+                                name: this.$t('learnActivity.mark.marking'),
                                 itemStyle: {
                                     color: "#5c7bd9"
                                 },
                             },
                             {
                                 value: 0,
-                                name: '未阅',
+                                name: this.$t('learnActivity.mark.unmark'),
                                 itemStyle: {
                                     color: "#ffdc60"
                                 },

+ 2 - 2
TEAMModelOS/ClientApp/src/view/task/mark/QuProg.vue

@@ -11,7 +11,7 @@
                         <Progress :percent="objectiveQu.includes(childItem.type) ? 100 : byQuPct[getScoreIndex(index,childIndex)]" />
                         <!-- <Progress :percent="byQuPct[getScoreIndex(index,childIndex)]" /> -->
                         <p v-if="objectiveQu.includes(childItem.type)" class="prog-tips" style="color: #19be6b">
-                            客观题已由系统自动完成评分。
+                            {{$t('task.objectiveQu')}}
                         </p>
                         <p v-else class="prog-tips">
                             <span style="margin-right:10px">
@@ -38,7 +38,7 @@
                     <Progress :percent="objectiveQu.includes(item.type) ? 100 : byQuPct[getScoreIndex(index)]" />
                     <!-- <Progress :percent="byQuPct[getScoreIndex(index)]" /> -->
                     <p v-if="objectiveQu.includes(item.type)" class="prog-tips" style="color: #19be6b">
-                        客观题已由系统自动完成评分。
+                        {{$t('task.objectiveQu')}}
                     </p>
                     <p v-else>
                         <span style="margin-right:10px">

+ 13 - 9
TEAMModelOS/ClientApp/src/view/task/mark/StuProg.vue

@@ -18,26 +18,30 @@
                 <div class="stu-wrap">
                     <div class="stu-list-wrap no-stu-wrap" v-show="tabIndex == 0">
                         <p class="no-mark-text" v-if="unmarked > 0 && unmarked < total">
-                            还剩
+                            {{$t('task.lastLabel1')}}
                             <span class="no-mark-count">{{unmarked}}</span>
-                            人未阅,
-                            <span class="continue-mark" @click="toByStuView()">继续阅卷</span>
+                            {{$t('task.lastLabel2')}}
+                            <span class="continue-mark" @click="toByStuView()">
+                                {{$t('task.continue')}}
+                            </span>
                         </p>
                         <p class="no-mark-text" v-else-if="unmarked > 0">
-                            阅卷总量
+                            {{$t('task.totalLabel1')}}
                             <span class="no-mark-count">{{unmarked}}</span>
-                            人,
-                            <span class="continue-mark" @click="toByStuView()">开始阅卷</span>
+                            {{$t('task.totalLabel2')}}
+                            <span class="continue-mark" @click="toByStuView()">
+                                {{$t('task.start')}}
+                            </span>
                         </p>
-                        <EmptyData v-else textContent="暂无未阅学生"></EmptyData>
+                        <EmptyData v-else :textContent="$t('task.noUnmark')"></EmptyData>
                     </div>
                     <div class="stu-list-wrap" v-show="tabIndex == 1">
                         <span class="stu-name" v-for="(item,index) in marking" :key="index" @click="toByStuView(item.stuId)">{{item.stuId}}</span>
-                        <EmptyData textContent="暂无进行中学生" v-show="!marking.length"></EmptyData>
+                        <EmptyData :textContent="$t('task.noMarking')" v-show="!marking.length"></EmptyData>
                     </div>
                     <div class="stu-list-wrap" v-show="tabIndex == 2">
                         <span class="stu-name" v-for="(item,index) in marked" :key="index" @click="toByStuView(item.stuId)">{{item.stuId}}</span>
-                        <EmptyData :top="0" textContent="暂无已阅学生" v-show="!marked.length"></EmptyData>
+                        <EmptyData :top="0" :textContent="$t('task.noMarked')" v-show="!marked.length"></EmptyData>
                     </div>
                 </div>
             </div>

+ 39 - 0
TEAMModelOS/Controllers/Common/CommonController.cs

@@ -15,6 +15,7 @@ using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
 
 namespace TEAMModelOS.Controllers.Common
 {
@@ -250,5 +251,43 @@ namespace TEAMModelOS.Controllers.Common
                 return BadRequest();
             }
         }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("delete-activity")]
+        [AuthToken(Roles = "teacher,admin,student")]
+        public async Task<IActionResult> DeleteActivity(JsonElement element) {
+            try {
+                if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
+                if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
+                if (!element.TryGetProperty("role", out JsonElement role)) return BadRequest();
+                var client = _azureCosmos.GetCosmosClient();
+                if (role.ValueKind.Equals(JsonValueKind.String))
+                {
+                    if (role.GetString().Equals("teacher") || role.GetString().Equals("admin"))
+                    {
+                        await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<StuActivity>($"{id}", new PartitionKey($"{code}"));
+                    }
+                    else if (role.GetString().Equals("student"))
+                    {
+                        await client.GetContainer("TEAMModelOS", "Student").DeleteItemAsync<StuActivity>($"{id}", new PartitionKey($"{code}"));
+                    }
+                    else
+                    {
+                        return Ok(new { status = 500 });
+                    }
+                }
+                else {
+                    return Ok(new { status = 500 });
+                }
+                return Ok(new { status = 200 });
+            } catch (Exception ex) {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},common/delete-activity\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                return Ok(new { status = 500 });
+            }
+        }
     }
 }

+ 11 - 9
TEAMModelOS/Controllers/Common/SurveyController.cs

@@ -279,28 +279,30 @@ namespace TEAMModelOS.Controllers
         [AuthToken(Roles = "teacher,admin,student")]
         public async Task<IActionResult> FindById(JsonElement requert)
         {
+            Survey survey = null;
+            //活动id
+            if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
+            //活动分区
+            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
             try
             {
                 var client = _azureCosmos.GetCosmosClient();
-                //活动id
-                if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
-                //活动分区
-                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-                Survey survey = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Survey>(id.GetString(), new PartitionKey($"{code}"));
+               
+                survey = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Survey>(id.GetString(), new PartitionKey($"{code}"));
                 if (survey != null)
                 {
 
-                    return Ok(new { survey });
+                    return Ok(new { survey , status = 200 });
                 }
                 else
                 {
-                    return BadRequest("id,code不存在!");
+                    return Ok(new { survey, status = 404 });
                 }
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"OS,{_option.Location},common/survey/find-id()\n{ex.Message}{requert.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                return BadRequest(ex.StackTrace);
+                await _dingDing.SendBotMsg($"OS,{_option.Location},common/survey/find-id\n{ex.Message}{ex.StackTrace}\n{id}\n{code}  ", GroupNames.醍摩豆服務運維群組);
+                return Ok(new { survey, status = 404 });
             }
 
         }

+ 11 - 9
TEAMModelOS/Controllers/Common/VoteController.cs

@@ -281,28 +281,30 @@ namespace TEAMModelOS.Controllers.Learn
         [AuthToken(Roles = "teacher,admin,student")]
         public async Task<IActionResult> FindById(JsonElement requert)
         {
+            Vote vote = null;
+            //活动id
+            if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
+            //活动分区
+            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
             try
             {
                 var client = _azureCosmos.GetCosmosClient();
-                //活动id
-                if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
-                //活动分区
-                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-                Vote vote = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(id.GetString(), new PartitionKey($"{code}"));
+              
+                  vote = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(id.GetString(), new PartitionKey($"{code}"));
                 if (vote != null)
                 {
                     
-                    return Ok(new { vote });
+                    return Ok(new { vote, status = 200 });
                 }
                 else
                 {
-                    return BadRequest("id,code不存在!");
+                    return Ok(new { vote, status = 404 });
                 }
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/find-id()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
-                return BadRequest(ex.StackTrace);
+                await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/find-id()\n{ex.Message}\n{id}\n{code}", GroupNames.醍摩豆服務運維群組);
+                return Ok(new { vote,status=404 });
             }
 
         }

+ 15 - 3
TEAMModelOS/Controllers/Item/ItemController.cs

@@ -54,10 +54,22 @@ namespace TEAMModelOS.Controllers
             try
             {
                 var client = _azureCosmos.GetCosmosClient();
-                if (!request.TryGetProperty("periodId", out JsonElement periodId)) return BadRequest();
+                request.TryGetProperty("periodId", out JsonElement periodId);
                 if (!request.TryGetProperty("schoolCode", out JsonElement schoolCode)) return BadRequest();
-                ItemCond itemCond = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<ItemCond>($"{periodId}", new PartitionKey($"ItemCond-{schoolCode}"));
-                return Ok(new { itemCond });
+                if (periodId.ValueKind.Equals(JsonValueKind.String) && !string.IsNullOrEmpty(periodId.GetString()))
+                {
+                    ItemCond itemCond = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<ItemCond>($"{periodId}", new PartitionKey($"ItemCond-{schoolCode}"));
+                    return Ok(new { itemConds = new List<ItemCond>() { itemCond } });
+                }
+                else {
+                    List<ItemCond> items = new List<ItemCond>();
+                    var queryslt = $"SELECT  value(c) FROM c ";
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<ItemCond>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ItemCond-{schoolCode}") }))
+                    {
+                        items.Add(item);
+                    }
+                    return Ok(new { itemConds = items });
+                }
             } catch (Exception ex) {
                 await _dingDing.SendBotMsg($"OS,{_option.Location},item/cond-count()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                 return BadRequest();

+ 11 - 3
TEAMModelOS/Controllers/School/StudentController.cs

@@ -888,7 +888,7 @@ namespace TEAMModelOS.Controllers
                 foreach (var classStud in dicClassStuds)
                 {
                     string classId = null, classNo = null, className = null, gradeId = null, periodId = null;
-                   
+                    int classYear = -1; 
                     if (classInfos.ContainsKey(classStud.Key))
                     {
                         classId = classInfos[classStud.Key].GetProperty("id").GetString();
@@ -896,6 +896,11 @@ namespace TEAMModelOS.Controllers
                         className = classInfos[classStud.Key].GetProperty("name").GetString();
                         //gradeId = classInfos[classStud.Key].GetProperty("gradeId").GetString();
                         periodId = classInfos[classStud.Key].GetProperty("periodId").GetString();
+                        if (classInfos[classStud.Key].TryGetProperty("year", out JsonElement year)) {
+                            if (year.ValueKind.Equals(JsonValueKind.Number)) {
+                                classYear = classInfos[classStud.Key].GetProperty("year").GetInt32();
+                            }
+                        }
                     }
 
                     var tmp = classStud.Value.Select(o =>
@@ -910,7 +915,9 @@ namespace TEAMModelOS.Controllers
                                          classNo,
                                          className,
                                          gradeId,
-                                         periodId
+                                         periodId,
+                                         classYear
+
                                      });
                     ret.AddRange(tmp);
                 }
@@ -928,7 +935,8 @@ namespace TEAMModelOS.Controllers
                         classNo = (string)null,
                         className = (string)null,
                         gradeId = (string)null,
-                        periodId = (string)null
+                        periodId = (string)null,
+                        classYear = -1
                     }));
 
                 return ret;

+ 146 - 6
TEAMModelOS/Controllers/Syllabus/ShareController.cs

@@ -2,6 +2,7 @@ using Azure.Cosmos;
 using HTEXLib.COMM.Helpers;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using System;
 using System.Collections.Generic;
@@ -16,6 +17,7 @@ using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.Services.Common;
 
 namespace TEAMModelOS.Controllers
@@ -31,13 +33,16 @@ namespace TEAMModelOS.Controllers
         private readonly SnowflakeId _snowflakeId;
         private readonly DingDing _dingDing;
         private readonly Option _option;
-
-        public ShareController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
+        private readonly IConfiguration _configuration;
+        private readonly NotificationService _notificationService;
+        public ShareController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService)
         {
             _azureCosmos = azureCosmos;
             _snowflakeId = snowflakeId;
             _dingDing = dingDing;
-            _option = option?.Value;
+            _option = option?.Value; 
+            _configuration = configuration;
+            _notificationService = notificationService;
         }
         /*
          {
@@ -97,9 +102,47 @@ namespace TEAMModelOS.Controllers
                         (Syllabus syllabus, List<Share> shares) = DoAuth(request, syllabusD);
                         shares.ForEach(async x=> {
                             await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Share>(x, new PartitionKey($"{x.code}"));
+                            //发送共编或分享通知
+                            if (x.coedit == true) {
+                                Notification notification = new Notification
+                                {
+                                    hubName = "hita",
+                                    type = "msg",
+                                    from = $"ies5:{request.school}",
+                                    to = new List<string>() { x.code.Replace("Share-","") },
+                                    label = $"coedit_syllabus",
+                                    body = new { biz = "coedit", tmdid = x.issuer,  schoolcode = $"{request.school}",  status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
+                                    expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
+                                };
+                                var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
+                                var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                                var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
+                                var location = _option.Location;
+                                var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+                            }
+                            if (x.share == true)
+                            {
+                                Notification notification = new Notification
+                                {
+                                    hubName = "hita",
+                                    type = "msg",
+                                    from = $"ies5:{request.school}",
+                                    to = new List<string>() { x.code.Replace("Share-", "") },
+                                    label = $"share_syllabus",
+                                    body = new { biz = "share", tmdid = x.issuer, schoolcode = $"{request.school}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
+                                    expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
+                                }; 
+                                var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
+                                var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                                var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
+                                var location = _option.Location;
+                                var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+                            }
+                           
                         });
-                       
                         await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<Syllabus>(syllabus, new PartitionKey($"Syllabus-{request.volumeId}"));
+
+                        
                     }
                 }
                 else if (request.scope.Equals("private"))
@@ -161,7 +204,9 @@ namespace TEAMModelOS.Controllers
                     school = request.school,
                     scope = request.scope,
                     coedit = request.coedit,
-                    share = request.share
+                    share = request.share,
+                    cagree = 0,
+                    sagree = 0
                 };
                 shares.Add(share);
             });
@@ -221,6 +266,101 @@ namespace TEAMModelOS.Controllers
             return (syllabus, shares);
         }
 
+        /// <summary>
+        /// {"code":"教师编码","id":"章节id","agree":1共编同意,2共编拒绝,3分享同意,4分享拒绝} 
+        /// 教师拉取自己收到的分享及共编
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("agree")]
+        // [AuthToken(Roles = "Teacher")]
+        public async Task<IActionResult> Agree(JsonElement request) {
+            try { 
+            if (!request.TryGetProperty("agree", out JsonElement agree)) { return BadRequest(); }
+            if (!request.TryGetProperty("code", out JsonElement code)) { return BadRequest(); }
+            if (!request.TryGetProperty("id", out JsonElement id)) { return BadRequest(); }
+            var client = _azureCosmos.GetCosmosClient();
+            Share share= await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Share>($"{id}", new PartitionKey($"Share-{code}"));
+                if (agree.ValueKind.Equals(JsonValueKind.Number))
+                {
+                    int agreeNum = agree.GetInt32();
+                    if (agreeNum == 1)
+                    {
+                        share.cagree = 1;
+                    }
+                    else if (agreeNum == 2)
+                    {
+                        share.cagree = 2;
+                    }
+                    else if (agreeNum == 3)
+                    {
+                        share.sagree = 1;
+                    }
+                    else if (agreeNum == 4)
+                    {
+                        share.sagree = 2;
+                    }
+                    else
+                    {
+                        return Ok(new { status = 500 });
+                    }
+                    await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Share>(share, $"{id}", new PartitionKey($"Share-{code}"));
+                    Syllabus syllabus = null;
+                    if (share.scope == "school")
+                    {
+                        syllabus = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>($"{id}", new PartitionKey($"Syllabus-{share.volumeId}"));
+                    }
+                    else if (share.scope == "private")
+                    {
+                        syllabus = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>($"{id}", new PartitionKey($"Syllabus-{share.volumeId}"));
+                    }
+                    if (syllabus.auth.IsNotEmpty())
+                    {
+                        syllabus.auth.ForEach(x =>
+                        {
+                            if (x.tmdid == $"{code}")
+                            {
+                                if (agreeNum == 1)
+                                {
+                                    x.cagree = 1;
+                                }
+                                else if (agreeNum == 2)
+                                {
+                                    x.cagree = 2;
+                                }
+                                else if (agreeNum == 3)
+                                {
+                                    x.sagree = 1;
+                                }
+                                else if (agreeNum == 4)
+                                {
+                                    x.sagree = 2;
+                                }
+                            }
+                        });
+                    }
+                    if (share.scope == "school")
+                    {
+                        syllabus = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Syllabus>(syllabus, $"{id}", new PartitionKey($"Syllabus-{share.volumeId}"));
+                    }
+                    else if (share.scope == "private")
+                    {
+                        syllabus = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Syllabus>(syllabus, $"{id}", new PartitionKey($"Syllabus-{share.volumeId}"));
+                    }
+                    return Ok(new { status = 200 });
+                }
+                else
+                {
+                    return Ok(new { status = 500 });
+                }
+            }  catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/agree()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                return Ok(new { status = 500 });
+            }
+
+        }
 
 
         /// <summary>
@@ -299,7 +439,7 @@ namespace TEAMModelOS.Controllers
         /// <returns></returns>
         [ProducesDefaultResponseType]
         [HttpPost("view-share")]
-       // [AuthToken(Roles = "Teacher")]
+       [AuthToken(Roles = "teacher")]
         public async Task<IActionResult> View(ShareView request)
         {
             try