Pārlūkot izejas kodu

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

zhouj1203@hotmail.com 4 gadi atpakaļ
vecāks
revīzija
0cc5a1ce41
41 mainītis faili ar 305 papildinājumiem un 144 dzēšanām
  1. 3 3
      TEAMModelOS/ClientApp/src/api/learnActivity.js
  2. 5 5
      TEAMModelOS/ClientApp/src/api/newEvaluation.js
  3. 2 2
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  4. 2 2
      TEAMModelOS/ClientApp/src/common/BasePackage.vue
  5. 25 18
      TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue
  6. 1 1
      TEAMModelOS/ClientApp/src/components/coursemgmt/StudentList.vue
  7. 2 2
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwTable.vue
  8. 7 7
      TEAMModelOS/ClientApp/src/components/learnactivity/ChooseContent.vue
  9. 3 3
      TEAMModelOS/ClientApp/src/components/learnactivity/ContentFileList.vue
  10. 2 3
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseKnowledgeDetail.vue
  11. 1 4
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseKnowledgeRadar.vue
  12. 4 4
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseRadar.vue
  13. 10 0
      TEAMModelOS/ClientApp/src/router/routes.js
  14. 2 2
      TEAMModelOS/ClientApp/src/view/Home.vue
  15. 13 4
      TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue
  16. 7 2
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue
  17. 8 1
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue
  18. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue
  19. 10 1
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseFilter.vue
  20. 2 2
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.vue
  21. 3 3
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  22. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/index.vue
  23. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.vue
  24. 2 2
      TEAMModelOS/ClientApp/src/view/newcourse/CourseBaseSetting.vue
  25. 9 7
      TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue
  26. 3 3
      TEAMModelOS/ClientApp/src/view/student-account/AddStudent.vue
  27. 1 1
      TEAMModelOS/ClientApp/src/view/student-account/ImportStudent.vue
  28. 3 3
      TEAMModelOS/ClientApp/src/view/student-account/Index.vue
  29. 2 2
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/KnowledgeAnalysis/ScoreDetails.vue
  30. 2 2
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/LevelAnalysis/ScoreDetails.vue
  31. 1 0
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue
  32. 1 0
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue
  33. 3 3
      TEAMModelOS/ClientApp/src/view/teachcontent/index.vue
  34. 2 2
      TEAMModelOS/ClientApp/src/view/teachermgmt/Index.vue
  35. 4 4
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/personnel/Index.vue
  36. 3 3
      TEAMModelOS/ClientApp/src/view/teachermgmt/components/userList/Index.vue
  37. 90 23
      TEAMModelOS/Controllers/Exam/ImportExerciseController.cs
  38. 7 7
      TEAMModelOS/Controllers/Exam/PaperController.cs
  39. 1 1
      TEAMModelOS/Controllers/School/ClassRoomController.cs
  40. 4 4
      TEAMModelOS/Controllers/Syllabus/ItemInfoController.cs
  41. 52 5
      TEAMModelOS/JsonFile/Core/LangConfig.json

+ 3 - 3
TEAMModelOS/ClientApp/src/api/learnActivity.js

@@ -4,19 +4,19 @@ export default {
      *保存试卷
      */
     SaveExamPaper: function (data) {
-        return post('/api/Paper/upsert', data)
+        return post('/school/Paper/upsert', data)
     },
     /*
      *查询试卷
      */
     FindExamPaper: function (data) {
-        return post('/api/Paper/find', data)
+        return post('/school/Paper/find', data)
     },
     /*
      *删除试卷
      */
     DeleteExamPaper: function (data) {
-        return post('/api/Paper/delete', data)
+        return post('/school/Paper/delete', data)
     },
     /*
      *删除评测信息

+ 5 - 5
TEAMModelOS/ClientApp/src/api/newEvaluation.js

@@ -8,14 +8,14 @@ export default {
      * @param {any} data
      */
     SaveSingleExercise: function(data) {
-        return post('/api/ItemInfo/upsert', data)
+        return post('/common/item/upsert', data)
     },
     /**
      * 批量更新保存试题
      * @param {any} data
      */
     SaveAllExercise: function(data) {
-        return post('/api/ItemInfo/upsertAll', data)
+        return post('/common/item/upsertAll', data)
     },
 
     /**
@@ -23,7 +23,7 @@ export default {
      * @param {any} data
      */
     FindExerciseList: function(data) {
-        return post('/api/ItemInfo/find', data)
+        return post('/common/item/find', data)
     },
 
     /**
@@ -39,7 +39,7 @@ export default {
      * @param {any} data
      */
     FindExerciseById: function(data) {
-        return post('/api/ItemInfo/findByIds', data)
+        return post('/common/item/findByIds', data)
     },
 
     /**
@@ -47,7 +47,7 @@ export default {
      * @param {any} data
      */
     DeleteExamItem: function(data) {
-        return post('/api/ItemInfo/delete', data)
+        return post('/common/item/delete', data)
     }
 
 }

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

@@ -160,7 +160,7 @@
                             {
                                 icon: 'iconfont icon-question-bank',
                                 name: '校本题目/库',
-                                router: '/home/evaluation/testPaperList',
+                                router: '/home/evaluation/schoolBank',
                                 tag: '',
                                 role: 'teacher|admin',
                                 permission: '',
@@ -292,7 +292,7 @@
                             {
                                 icon: 'iconfont icon-question-bank',
                                 name: '个人题目/库',
-                                router: '/home/evaluation/testPaperList',
+                                router: '/home/evaluation/personalBank',
                                 tag: '',
                                 role: 'teacher|admin',
                                 permission: '',

+ 2 - 2
TEAMModelOS/ClientApp/src/common/BasePackage.vue

@@ -29,11 +29,11 @@
                             this.sasString = res.result.data.SAS
                             this.downloadFile(list)
                         } else {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 25 - 18
TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue

@@ -1,16 +1,16 @@
 <template>
 	<div class="base-school-select">
 			<Dropdown @on-click="onSchoolSelect">
-				<img class="school-logo" :src="curSchool.logo" />
-				<a href="javascript:void(0)" class="base-user-post">
+				<img class="school-logo" :src="curSchool.logo || 'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png'" />
+				<a href="javascript:void(0)" :class="['base-user-post', user.schools.length === 1 ? 'single-school' : '']">
 					{{ curSchool.name }}
 					<Icon type="ios-arrow-down"></Icon>
 				</a>
 				<DropdownMenu slot="list">
-					<div v-for="(item,index) in user.schoolList" :key="index">
+					<div v-for="(item,index) in user.schools" :key="index">
 						<DropdownItem :name="index">
 							<div class="school-item">
-								<img :src="item.logo" alt="">
+								<img :src="item.logo || 'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png'" alt="">
 								<span>{{ item.name }}</span>
 							</div>
 						</DropdownItem>
@@ -26,28 +26,29 @@
 	export default {
 		data() {
 			return {
-				curSchool: '醍摩豆学院',
+				curSchool: null,
 				user:{
-					schoolList:[{
-						logo:'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png',
-						name:'醍摩豆学院'
-					},{
-						logo:'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png',
-						name:'成都青城山学校'
-					},{
-						logo:'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png',
-						name:'高新区芳草小学'
-					}]
+					schools:[]
 				}
-				
 			}
 		},
 		created() {
-			this.curSchool = this.user.schoolList[0]
+			// 获取本地存储中的 用户信息
+			let user = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"));
+			if(user.schools){
+				// 拿到用户管理的schools 必须是已加入的学校
+				let schools = user.schools.filter(i => i.status === 'join')
+				if(schools.length){
+					this.user.schools = schools
+					this.curSchool = user.defaultschool ? schools.filter(i => i.schoolId === user.defaultschool)[0] : schools[0]
+				}
+			}else{
+				this.$Message.warning('用户暂无学校列表数据')
+			}
 		},
 		methods: {
 			onSchoolSelect(val){
-				this.curSchool = this.user.schoolList[val]
+				this.curSchool = this.user.schools[val]
 			}
 		},
 
@@ -92,6 +93,12 @@
 			}
 		}
 		
+		.single-school{
+			&::after{
+				display: none !important;
+			}
+		}
+		
 		.school-logo{
 			width: 30px;
 			border-radius: 50%;

+ 1 - 1
TEAMModelOS/ClientApp/src/components/coursemgmt/StudentList.vue

@@ -217,7 +217,7 @@
                             [...this.tableShowData] = this.tableData
                             this.tableLoading = false
                         } else {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                             this.tableLoading = false
                         }
                     },

+ 2 - 2
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwTable.vue

@@ -574,11 +574,11 @@
                         if (res.error == null) {
                             this.sasString = res.result.data.SAS
                         } else {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 7 - 7
TEAMModelOS/ClientApp/src/components/learnactivity/ChooseContent.vue

@@ -554,7 +554,7 @@
                                 }
                             },
                             (err) => {
-                                alert('API error!')
+                                this.$Message.error('API error!')
                             }
                         )
                     } else {
@@ -579,7 +579,7 @@
                                 }
                             },
                             (err) => {
-                                alert('API error!')
+                                this.$Message.error('API error!')
                             }
                         )
                     } else {
@@ -634,11 +634,11 @@
                         if (res.error == null) {
                             this.syllabusList = res.result.data
                         } else {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },
@@ -664,7 +664,7 @@
                         this.getVolumes()
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },
@@ -682,11 +682,11 @@
                                 this.getSyllabus()
                             }
                         } else {
-                            alert('API error111!')
+                            this.$Message.error('API error111!')
                         }
                     },
                     (err) => {
-                        alert('API error222!')
+                        this.$Message.error('API error222!')
                     }
                 )
             },

+ 3 - 3
TEAMModelOS/ClientApp/src/components/learnactivity/ContentFileList.vue

@@ -1,4 +1,4 @@
-<template>
+<template>
     <div class="content-file-wrap">
         <div v-for="(item,index) in sasRes" class="content-file-item" :key="index">
             <div class="file-icon">
@@ -59,11 +59,11 @@
                             this.blobContainer = res.result.data.Container
                             this.urlString = res.result.data.Url
                         } else {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 2 - 3
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseKnowledgeDetail.vue

@@ -37,7 +37,7 @@
                                 color: 'rgba(128,128,128,0.1)'
                             }
                         },
-                        padding: 5,
+                        padding: 15,
                         textStyle: {
                             // 提示框内容的样式
                             color: '#fff'
@@ -50,6 +50,7 @@
                     grid: {
                         show: false, // 是否显示直角坐标系网格
                         top: 50, // 相对位置 top\bottom\left\right
+						left:20,
                         height: 480,
                         containLabel: true // gird 区域是否包含坐标轴的刻度标签
                     },
@@ -163,14 +164,12 @@
                                         return '#1b9dff'
                                     }
                                 },
-                                width: 20
                             },
                             emphasis: {
                                 itemStyle: {
                                     color: '#ff9999'
                                 }
                             },
-                            barWidth: 30,
                             data: this.y
                         }]
                 }

+ 1 - 4
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseKnowledgeRadar.vue

@@ -13,12 +13,9 @@
                 radarData: []
             }
         },
-        mounted() {
-            this.radarData = this.getRadarData
-            this.drawLine(this.radarData)
-        },
         methods: {
             drawLine(indicator, data) {
+				console.log(indicator)
                 // 基于准备好的dom,初始化echarts实例
                 let that = this
                 let myRadar = this.$echarts.init(document.getElementById(this.echartsId), 'chalk')

+ 4 - 4
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseRadar.vue

@@ -13,10 +13,9 @@
                 radarData: []
             }
         },
-        mounted() {
-            this.radarData = this.getRadarData
-            this.drawLine(this.radarData)
-        },
+		created() {
+			console.log('1111')
+		},
         methods: {
             drawLine(indicator, data) {
                 // 基于准备好的dom,初始化echarts实例
@@ -46,6 +45,7 @@
                             }
                         },
                         center: ['50%', '50%'],
+						radius:'60%',
                         tooltip: {
                             trigger: 'item'
                         },

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

@@ -231,6 +231,16 @@ export const routes = [
 						name: 'testPaperList',
 						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve)
 					},
+					{
+						path: 'schoolBank',
+						name: 'schoolBank',
+						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve)
+					},
+					{
+						path: 'personalBank',
+						name: 'personalBank',
+						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve)
+					},
 					{
 						path: 'createCompose',
 						name: 'createCompose',

+ 2 - 2
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -10,7 +10,7 @@
 				<BaseUserPoptip @logout="basicMenu('quit')"></BaseUserPoptip>
             </div>
             <div id="content" class="custom-scroll-bar" slot="content">
-                <router-view></router-view>
+                <router-view :key="this.$route.name"></router-view>
             </div>
         </BaseLayout>
 		<Modal v-model="isShowMock" title="作答数据模拟生成" width="400px" class="related-point-modal" style="z-index:99999">
@@ -60,7 +60,7 @@
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 13 - 4
TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue

@@ -3,11 +3,11 @@
 		<!-- 筛选部分 -->
 		<Loading :top="100" v-show="importLoading" type="1"></Loading>
 		<div class="filter-wrap">
-			<div class="filter-item">
+			<div class="filter-item" v-show="!isShowSchoolBank">
 				<span class="filter-title">来源:</span>
 				<RadioGroup v-model="filterOrigin" type="button" @on-change="filterOriginChange">
-					<Radio :label="userId">个人题库</Radio>
 					<Radio :label="schoolCode">学校公用库</Radio>
+					<Radio :label="userId">个人题库</Radio>
 				</RadioGroup>
 			</div>
 			<div class="filter-item">
@@ -212,6 +212,7 @@
 			return {
 				userId: '',
 				schoolCode: '',
+				isShowSchoolBank:false,
 				dataLoading: false,
 				editExerciseModal: false,
 				currentExercise: {},
@@ -258,6 +259,13 @@
 			}
 		},
 		created() {
+			this.$EventBus.$on('showSchoolBank',(val)=> {
+				if(val){
+					this.isShowSchoolBank = val
+				}else{
+					this.isShowSchoolBank = false
+				}
+			})
 			this.getSchoolInfo()
 			this.uploadUrl = 'https://' + window.location.host + '/api/ImportExercise/uploadWord'
 		},
@@ -298,10 +306,11 @@
 			/** 获取区班校信息 */
 			getSchoolInfo() {
 				this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(res => {
+					console.log(res)
 					this.schoolInfo = JSON.parse(JSON.stringify(res.data))
-					this.schoolCode = res.data.schoolCode
+					this.schoolCode = res.data.id
 					this.userId = this.$store.state.userInfo.TEAMModelId
-					this.filterOrigin = this.$store.state.userInfo.TEAMModelId
+					this.filterOrigin = this.$store.state.userInfo.schoolCode
 					this.periodList = res.data.period
 					this.gradeList = res.data.period[0].grades
 					this.subjectList = res.data.period[0].subjects

+ 7 - 2
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -93,7 +93,7 @@
                 dataLoading: false,
                 randomModal: false,
                 isFilterPaper:true,
-                paperList: new Array(10).fill('1'),
+                paperList: [],
                 periodList: [],
                 gradeList: [],
                 subjectList: [],
@@ -162,7 +162,12 @@
                     setTimeout(() => {
                         that.dataLoading = false
                     }, 1000)
-                })
+                }).catch(err => {
+					setTimeout(() => {
+						this.$Message.error('试卷数据获取失败')
+					    that.dataLoading = false
+					}, 1000)
+				})
             },
 
             /**

+ 8 - 1
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue

@@ -36,7 +36,7 @@
 			}
 		},
 		created() {
-
+			
 		},
 		methods: {
 
@@ -84,6 +84,13 @@
 				this.currentTab = this.$route.params.tabName
 				this.tabName = this.$route.params.tabName
 			}
+			
+			console.log(this.$route)
+			if(this.$route.name === 'schoolBank'){
+				this.$EventBus.$emit('showSchoolBank',true)
+			}else{
+				this.$EventBus.$emit('showSchoolBank',false)
+			}
 		}
 	}
 </script>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue

@@ -490,7 +490,7 @@
 			// 重置编辑器
 			resetEditor() {
 				this.$router.push({
-					name: 'testPaperList',
+					name: 'personalBank',
 					params: {
 						tabName: 'exercise'
 					}

+ 10 - 1
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseFilter.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="filter-wrap">
-        <div class="filter-item">
+        <div class="filter-item" v-show="!isShowSchoolBank">
             <span class="filter-title">来源:</span>
             <RadioGroup v-model="filterOrigin" type="button" @on-change="filterOriginChange">
                 <Radio :label="userId">个人试卷库</Radio>
@@ -89,6 +89,7 @@
                 userId: '',
                 schoolCode: '',
                 schoolInfo: {},
+				isShowSchoolBank:false,
                 isShowUploadList: false,
                 exersicesType: {
                     Single: '单选',
@@ -117,6 +118,14 @@
         },
         created() {
             this.getSchoolInfo()
+			this.$EventBus.$on('showSchoolBank',(val)=> {
+				if(val){
+					this.isShowSchoolBank = val
+					this.filterOrigin = this.schoolCode
+				}else{
+					this.isShowSchoolBank = false
+				}
+			})
         },
         methods: {
             /** 获取区班校信息 */

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

@@ -379,7 +379,7 @@
 						console.log(this.getSimpleText(exerciseItem.question))
 						this.saveExercise(exerciseItem).then(res => {
 							this.$router.push({
-								name: 'testPaperList',
+								name: 'personalBank',
 								params: {
 									tabName: 'exercise'
 								}
@@ -540,7 +540,7 @@
 			// 重置编辑器
 			backToBank() {
 				this.$router.push({
-					name: 'testPaperList',
+					name: 'personalBank',
 					params: {
 						tabName: 'exercise'
 					}

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

@@ -202,7 +202,7 @@
 
 			goBack() {
 				this.$router.push({
-					name: 'testPaperList',
+					name: 'personalBank',
 					params: {
 						tabName: 'paper'
 					}
@@ -320,7 +320,7 @@
 							}
 						},
 						(err) => {
-							alert('API error!')
+							this.$Message.error('API error!')
 						}
 					)
 				})
@@ -439,7 +439,7 @@
 													this.$Message.success(isEdit ? '编辑成功' : '保存成功')
 													this.isLoading = false
 													this.$router.push({
-														name: 'testPaperList',
+														name: 'personalBank',
 														params: {
 															tabName: 'paper'
 														}

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/index/index.vue

@@ -13,7 +13,7 @@
             <ul>
                 <li @click="goRouter('createExercises')">创建习题</li>
                 <li @click="goRouter('exercisesList')">组卷中心</li>
-                <li @click="goRouter('testPaperList')">试卷试题库</li>
+                <li @click="goRouter('personalBank')">试卷试题库</li>
             </ul>
             <!--<Icon type="md-list" />-->
         </div>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.vue

@@ -453,7 +453,7 @@
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 2 - 2
TEAMModelOS/ClientApp/src/view/newcourse/CourseBaseSetting.vue

@@ -150,7 +150,7 @@
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },
@@ -162,7 +162,7 @@
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 9 - 7
TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue

@@ -598,14 +598,16 @@
                         }).then(
                             res => {
                                 if (res) {
-                                    this.$Message.success(this.$t('schoolBaseInfo.csTips3'))
-                                    //this.classroomList[this.curClassIndex].id = res.id
-                                    //this.classroomList[this.curClassIndex].option = null
-                                    this.updated = false
-                                } else {
-                                    if (res.error.code == 4) {
-                                        this.$Message.error('班级编码已经存在,请重新设置班级编码!')
+                                    if (res.error) {
+                                        this.classroomList[this.curClassIndex].option = 'insert'
+                                        this.$Message.error(res.v)
+                                    } else {
+                                        this.$Message.success(this.$t('schoolBaseInfo.csTips3'))
+                                        this.updated = false
                                     }
+                                    
+                                } else {
+                                    this.$Message.error('API error!')
                                 }
                             },
                             err => {

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

@@ -313,12 +313,12 @@
                                     // this.initData();
                                     this.uploadLoading = false
                                 } else {
-                                    alert('API error!')
+                                    this.$Message.error('API error!')
                                 }
                                 this.isLoading = false
                             },
                             (err) => {
-                                alert('API error!')
+                                this.$Message.error('API error!')
                                 this.isLoading = false
                             }
                         )
@@ -339,7 +339,7 @@
                                 this.isLoading = false
                             },
                             (err) => {
-                                alert('API error!')
+                                this.$Message.error('API error!')
                                 this.isLoading = false
                             }
                         )

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

@@ -338,7 +338,7 @@
                                 this.initData()
                                 this.uploadLoading = false
                             } else {
-                                alert('API error!')
+                                this.$Message.error('API error!')
                             }
                         },
                         (err) => {

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

@@ -390,7 +390,7 @@
                                     this.tableLoading = false
                                 },
                                 (err) => {
-                                    alert('API error!')
+                                    this.$Message.error('API error!')
                                     this.tableLoading = false
                                 }
                             )
@@ -451,7 +451,7 @@
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },
@@ -553,7 +553,7 @@
                             [...this.tableShowData] = this.tableData
                             this.tableLoading = false
                         } else {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                             this.tableLoading = false
                         }
                     },

+ 2 - 2
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/KnowledgeAnalysis/ScoreDetails.vue

@@ -7,7 +7,7 @@
                 <div v-show="!isShowRadar">
                     <BaseDetailBar echartsId="knowDetailBar" :echartData="knowledgeData" @handleItemClick="handleItemClick" ref="detailsBar"></BaseDetailBar>
                 </div>
-                <div v-show="isShowRadar">
+                <div v-if="isShowRadar">
                     <BaseRadar echartsId="knowRadar"></BaseRadar>
                 </div>
             </Col>
@@ -49,7 +49,7 @@
         },
         data() {
             return {
-                isShowRadar: true,
+                isShowRadar: false,
                 tableData: [],
                 classDatas: [],
                 currentPoint: '',

+ 2 - 2
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/LevelAnalysis/ScoreDetails.vue

@@ -7,7 +7,7 @@
                 <div v-show="!isShowRadar">
                     <BaseDetailBar echartsId="levelDetailBar" :echartData="levelData" @handleItemClick="handleItemClick" ref="detailsBar"></BaseDetailBar>
                 </div>
-                <div v-show="isShowRadar">
+                <div v-if="isShowRadar">
                     <BaseRadar echartsId="levelRadar"></BaseRadar>
                 </div>
             </Col>
@@ -45,7 +45,7 @@
         },
         data() {
             return {
-                isShowRadar: true,
+                isShowRadar: false,
                 tableData: [],
                 classDatas: [],
                 currentPoint: '应用',

+ 1 - 0
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue

@@ -470,6 +470,7 @@
 
             // 返回题目区域总分 字符串换算
             sumArr(arr) {
+				console.log(arr)
                 return arr.reduce((a,b) => a + b)
             }
         },

+ 1 - 0
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue

@@ -54,6 +54,7 @@
                     <div slot="content" class="index-wrap">
                         <span v-for="(item,index) in exerciseIndexList"
                               :key="index"
+							  :title="index"
                               class="exercise-item-index"
                               @click="onIndexClick(item)"
                               :style="{background: (+item > 9 ? item : '0' + item) === currentExerciseIndex ? '#d482ab':'#018B99' }">

+ 3 - 3
TEAMModelOS/ClientApp/src/view/teachcontent/index.vue

@@ -474,7 +474,7 @@
                             }
                         },
                         (err) => {
-                            alert('API error!')
+                            this.$Message.error('API error!')
                         }
                     )
                 }
@@ -495,7 +495,7 @@
                         this.acticveFileIndex = -1
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },
@@ -615,7 +615,7 @@
                         }
                     },
                     (err) => {
-                        alert('API error!')
+                        this.$Message.error('API error!')
                     }
                 )
             },

+ 2 - 2
TEAMModelOS/ClientApp/src/view/teachermgmt/Index.vue

@@ -58,11 +58,11 @@ export default {
         this.$store.dispatch('user/getSchoolTeacher').then(
               (res) => {
                   if (res.code == 0) {
-                      alert('無法取得使用者資料')
+                      this.$Message.error('無法取得使用者資料')
                   }
               },
               (err) => {
-                  alert('user/setSchoolTeacher API error!')
+                  this.$Message.error('user/setSchoolTeacher API error!')
               }
           )
     },

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

@@ -369,7 +369,7 @@ export default {
                             }
                         },
                         (err) => {
-                            alert('user/setSchoolUser API error!')
+                            this.$Message.error('user/setSchoolUser API error!')
                         }
                     )
                 },
@@ -491,7 +491,7 @@ export default {
                     }
                 },
                 (err) => {
-                    alert('user/addSchoolUser API error!')
+                    this.$Message.error('user/addSchoolUser API error!')
                 })
             }
         },
@@ -555,7 +555,7 @@ export default {
                         }
                     },
                     (err) => {
-                        alert('user/setSchoolUser API error!')
+                        this.$Message.error('user/setSchoolUser API error!')
                     }
                 )
             }
@@ -582,7 +582,7 @@ export default {
                             }
                         },
                         (err) => {
-                            alert('user/updSchoolUserStatus API error!')
+                            this.$Message.error('user/updSchoolUserStatus API error!')
                         }
                     )
                 }

+ 3 - 3
TEAMModelOS/ClientApp/src/view/teachermgmt/components/userList/Index.vue

@@ -616,11 +616,11 @@ export default {
                             if (res.code === 1) {
                                 this.$Message.info(this.$t('teachermgmt.message.info1'))
                             } else {
-                                alert('Can not set Auth.')
+                                this.$Message.error('Can not set Auth.')
                             }
                         },
                         (err) => {
-                            alert('user/setSchoolUser API error: ' + err)
+                            this.$Message.error('user/setSchoolUser API error: ' + err)
                         }
                     )
                 }
@@ -744,7 +744,7 @@ export default {
                         this.closeAuthSeting()
                 },
                 (err) => {
-                    alert('user/setSchoolUser API error: ' + err)
+                    this.$Message.error('user/setSchoolUser API error: ' + err)
                 })
             } else {
                 this.$Modal.warning({

+ 90 - 23
TEAMModelOS/Controllers/Exam/ImportExerciseController.cs

@@ -12,6 +12,7 @@ using System.Globalization;
 using System.IdentityModel.Tokens.Jwt;
 using System.IO;
 using System.Linq;
+using System.Net.Http;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
@@ -23,6 +24,7 @@ using TEAMModelOS.SDK.Context.Constant;
 using TEAMModelOS.SDK.Context.Constant.Common;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
 using TEAMModelOS.SDK.Module.AzureBlob.Container;
 using TEAMModelOS.Services;
 using TEAMModelOS.Servicess.Exam;
@@ -39,8 +41,10 @@ namespace TEAMModelOS.Controllers
         private readonly AzureStorageFactory _azureStorage;
         private readonly IWebHostEnvironment _webHostEnvironment;
         private  List<LangConfig> langConfigs { get; set; }
-        public ImportExerciseController(   AzureStorageFactory azureStorage, IWebHostEnvironment webHostEnvironment, HtexGenerator htexGenerator)
+        private readonly IHttpClientFactory _clientFactory;
+        public ImportExerciseController(   AzureStorageFactory azureStorage, IWebHostEnvironment webHostEnvironment, HtexGenerator htexGenerator, IHttpClientFactory clientFactory)
         {
+            _clientFactory = clientFactory;
             this.htexGenerator = htexGenerator;
             _webHostEnvironment = webHostEnvironment;
             _azureStorage = azureStorage;
@@ -74,9 +78,57 @@ namespace TEAMModelOS.Controllers
 
 
         /// <summary>
-        /// docUrl
-        /// folder
-        /// shaCode
+        /// {"url":"https://***.blob.core.cn/xxx/1.pptx"}
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("analysis-pptx")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public async Task<IActionResult> AnalysisPPTX(JsonElement request)
+        {
+            string id_token = HttpContext.GetXAuth("IdToken");
+            if (string.IsNullOrEmpty(id_token)) return BadRequest();
+            var jwt = new JwtSecurityToken(id_token);
+            if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
+            var id = jwt.Payload.Sub;
+
+            request.TryGetProperty("code", out JsonElement code);
+            string azureBlobSAS = System.Web.HttpUtility.UrlDecode(code.ToString(), Encoding.UTF8);
+            (string, string) a = BlobUrlString(azureBlobSAS);
+            string ContainerName = a.Item1;
+            string BlobName = a.Item2;
+            bool flg = IsBlobName(BlobName);
+            var codes = code.ToString().Split("/");
+            var FileName = codes[codes.Length - 1];
+            if (flg)
+            {
+                //TODO 需驗證
+                BlobAuth blobAuth = _azureStorage.GetBlobSasUriRead(ContainerName, BlobName);
+                var response = await _clientFactory.CreateClient().GetAsync(new Uri(blobAuth.url + blobAuth.sas));
+                response.EnsureSuccessStatusCode();
+                Stream stream=  await response.Content.ReadAsStreamAsync();
+                HTEXLib.Htex htex = await PPTXTranslator(id, FileName, stream);
+                return Ok(JsonSerializer.Deserialize<JsonElement>(json: JsonHelper.ToJson(htex, ignoreNullValue: true)));
+            }
+            else { return BadRequest("不是正确的Blob链接!"); }
+        }
+        private static (string, string) BlobUrlString(string sasUrl)
+        {
+            sasUrl = sasUrl.Substring(8);
+            string[] sasUrls = sasUrl.Split("/");
+            string ContainerName;
+            ContainerName = sasUrls[1].Clone().ToString();
+            string item = sasUrls[0] + "/" + sasUrls[1] + "/";
+            string blob = sasUrl.Replace(item, "");
+            return (ContainerName, blob);
+        }
+        public static bool IsBlobName(string BlobName)
+        {
+            return System.Text.RegularExpressions.Regex.IsMatch(BlobName,
+             @"(?!((^(con)$)|^(con)\\..*|(^(prn)$)|^(prn)\\..*|(^(aux)$)|^(aux)\\..*|(^(nul)$)|^(nul)\\..*|(^(com)[1-9]$)|^(com)[1-9]\\..*|(^(lpt)[1-9]$)|^(lpt)[1-9]\\..*)|^\\s+|.*\\s$)(^[^\\\\\\:\\<\\>\\*\\?\\\\\\""\\\\|]{1,255}$)");
+        }
+        /// <summary>
+        /// 
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
@@ -84,9 +136,7 @@ namespace TEAMModelOS.Controllers
         [RequestSizeLimit(102_400_000_00)] //最大10000m左右
         public async Task<IActionResult> UploadPPTX([FromForm] IFormFile file)
         {
-          
-            var day= new DateTimeOffset(DateTime.UtcNow).ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo);
-            string shaCode   = ShaHashHelper.GetSHA1(file.OpenReadStream());
+
             string id_token = HttpContext.GetXAuth("IdToken");
             if (string.IsNullOrEmpty(id_token)) return BadRequest();
             var jwt = new JwtSecurityToken(id_token);
@@ -94,58 +144,75 @@ namespace TEAMModelOS.Controllers
             var id = jwt.Payload.Sub;
             if (!FileType.GetExtention(file.FileName).ToLower().Equals("pptx"))
             {
-                return BadRequest( "type is not pptx!");
+                return BadRequest("type is not pptx!");
             }
-            HTEXLib.Htex htex = htexGenerator.Generator(file.OpenReadStream());
-            htex.name = file.FileName;
+            string FileName = file.FileName;
+            Stream streamFile = file.OpenReadStream();
+
+            HTEXLib.Htex htex = await PPTXTranslator(id, FileName, streamFile);
+            return Ok(JsonSerializer.Deserialize<JsonElement>(json: JsonHelper.ToJson(htex, ignoreNullValue: true)));
+        }
+
+        private async Task<HTEXLib.Htex> PPTXTranslator(string id, string FileName, Stream streamFile)
+        {
+            var day = new DateTimeOffset(DateTime.UtcNow).ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo);
+            string shaCode = ShaHashHelper.GetSHA1(streamFile);
+            HTEXLib.Htex htex = htexGenerator.Generator(streamFile);
+            htex.name = FileName;
             var slides = htex.slides;
             int index = 1;
             List<Task> tasks = new List<Task>();
-            foreach (var slide in slides) {
-                string  text=  JsonHelper.ToJson(slide, ignoreNullValue: false);
+            foreach (var slide in slides)
+            {
+                string text = JsonHelper.ToJson(slide, ignoreNullValue: false);
                 tasks.Add(_azureStorage.UploadFileByContainer(id, text, "pptx", day + "/" + shaCode + "/" + index + ".json", false)
-                    .ContinueWith((Task<AzureBlobModel> blob)=> {
+                    .ContinueWith((Task<AzureBlobModel> blob) =>
+                    {
                         htex.urls.Add(blob.Result.BlobUrl);
                     })
                     );
-               // var blob=  await _azureStorage.UploadFileByContainer(id, text, "pptx", day+"/"+ shaCode +"/"+ index + ".json", false);
-               // htex.urls.Add(blob.BlobUrl);
+                // var blob=  await _azureStorage.UploadFileByContainer(id, text, "pptx", day+"/"+ shaCode +"/"+ index + ".json", false);
+                // htex.urls.Add(blob.BlobUrl);
                 index++;
             }
             await Task.WhenAll(tasks);
             htex.slides = null;
             Dictionary<string, Store> dict = new Dictionary<string, Store>();
             List<Task> tasksFiles = new List<Task>();
-            foreach (var key in htex.stores.Keys) {
-                if (key.EndsWith(".wdp")||key.EndsWith(".xlsx")) {
+            foreach (var key in htex.stores.Keys)
+            {
+                if (key.EndsWith(".wdp") || key.EndsWith(".xlsx"))
+                {
                     htex.stores.Remove(key);
                     continue;
                 }
                 var store = htex.stores[key];
-                Store str = new Store() { path=key,contentType= store.contentType ,isLazy=store.isLazy};
+                Store str = new Store() { path = key, contentType = store.contentType, isLazy = store.isLazy };
                 if (!store.isLazy && store.contentType != null && ContentTypeDict.extdict.TryGetValue(store.contentType, out string ext) && store.url.Contains(";base64,"))
                 {
                     string[] strs = store.url.Split(',');
                     Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
-                    var urlstrs=  key.Split("/");
+                    var urlstrs = key.Split("/");
                     var name = urlstrs[urlstrs.Length - 1];
                     tasksFiles.Add(_azureStorage.UploadFileByContainer(id, stream, "pptx", day + "/" + shaCode + "/" + name, false)
-                        .ContinueWith((Task<AzureBlobModel> blob)=> {
+                        .ContinueWith((Task<AzureBlobModel> blob) =>
+                        {
                             str.url = blob.Result.BlobUrl;
                         })
                         );
                     // var blob = await _azureStorage.UploadFileByContainer(id, stream, "pptx", day + "/" + shaCode + "/" + name, false);
                     //  str.url = blob.BlobUrl;
-                    
+
                 }
-                else {
+                else
+                {
                     str.url = store.url;
                 }
                 dict.TryAdd(key, str);
             }
             await Task.WhenAll(tasksFiles);
             htex.stores = dict;
-            return Ok(JsonSerializer.Deserialize<JsonElement>(json: JsonHelper.ToJson(htex, ignoreNullValue: true)));
+            return htex;
         }
 
 

+ 7 - 7
TEAMModelOS/Controllers/Exam/PaperController.cs

@@ -64,7 +64,7 @@ namespace TEAMModelOS.Controllers
             var client = _azureCosmos.GetCosmosClient();
             List<object> papers = new List<object>();
             var query = $"select c.id,c.subjectCode,c.code,c.periodCode,c.name,c.itemCount,c.level,c.pointItem,c.pointScore,c.score,c.gradeCode from c where c.id = {id}";
-            await foreach (var item in client.GetContainer("TEAMModelOSTemp", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{school_code}") }))
+            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{school_code}") }))
             {
                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
                 if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -101,15 +101,15 @@ namespace TEAMModelOS.Controllers
         public async Task<IActionResult> Find(JsonElement requert)
         {
             //ResponseBuilder builder = ResponseBuilder.custom();
-            if (!requert.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
-            if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
-            var jwt = new JwtSecurityToken(id_token.GetString());
+            //if (!requert.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
+            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
+            /*var jwt = new JwtSecurityToken(id_token.GetString());
             if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
-            var id = jwt.Payload.Sub;
+            var id = jwt.Payload.Sub;*/
             var client = _azureCosmos.GetCosmosClient();
             List<object> papers = new List<object>();
-            var query = $"select * from c where c.id = {id}";
-            await foreach (var item in client.GetContainer("TEAMModelOSTemp", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{school_code}") }))
+            var query = $"select c.id,c.subjectCode,c.code,c.periodCode,c.name,c.itemCount,c.level,c.pointItem,c.pointScore,c.score,c.gradeCode from c";
+            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{code}") }))
             {
                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
                 if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)

+ 1 - 1
TEAMModelOS/Controllers/School/ClassRoomController.cs

@@ -53,7 +53,7 @@ namespace TEAMModelOS.Controllers
                 if (response.Status == 200)
                 {
                     //classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(requert, new PartitionKey($"Classroom-{classroom.code}"));
-                    return Ok(new { ResponseCode.DATA_EXIST, V = "班级编码已经存在!" });
+                    return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在!" });
                 }
                 else
                 {

+ 4 - 4
TEAMModelOS/Controllers/Syllabus/ItemInfoController.cs

@@ -77,9 +77,9 @@ namespace TEAMModelOS.Controllers
         {
 
             var client = _azureCosmos.GetCosmosClient();
-            if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
+            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
             List<object> summary = new List<object>();
-            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select c.id, c.question,c.usageCount,c.level,c.field,c.points,c.type,c.option,c.createTime from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ItemInfo-{school_code}") }))
+            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select c.id, c.question,c.usageCount,c.level,c.field,c.points,c.type,c.option,c.createTime from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ItemInfo-{code}") }))
             {
                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
 
@@ -166,9 +166,9 @@ namespace TEAMModelOS.Controllers
         public async Task<IActionResult> Find(JsonElement requert)
         {
             var client = _azureCosmos.GetCosmosClient();
-            if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
+            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
             List<object> items = new List<object>();
-            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select c.id, c.question,c.usageCount,c.level,c.field,c.points,c.type,c.option,c.createTime from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ItemInfo-{school_code}") }))
+            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select c.id, c.question,c.usageCount,c.level,c.field,c.points,c.type,c.option,c.createTime from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ItemInfo-{code}") }))
             {
                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
 

+ 52 - 5
TEAMModelOS/JsonFile/Core/LangConfig.json

@@ -65,17 +65,64 @@
   {
     "Lang": "zh-HK",
     "Name": "香港",
-    "Alias": "繁體中文"
+    "Alias": "繁體中文",
+    "Item": {
+      "Type": {
+        "Compose": "綜合題",
+        "Single": "單選題",
+        "Multiple": "多選題",
+        "Judge": "判斷題",
+        "Complete": "填空題",
+        "Subjective": "問答題"
+      },
+      "AnswerTag": "答案",
+      "AnalysisTag": "解析",
+      "EndedTag": "結束",
+      "Options": "ABCDEFGHIJKLMN",
+      "Start": "【",
+      "End": "】"
+    }
   },
   {
     "Lang": "zh-MO",
     "Name": "澳門",
-    "Alias": "繁體中文"
+    "Alias": "繁體中文",
+    "Item": {
+      "Type": {
+        "Compose": "綜合題",
+        "Single": "單選題",
+        "Multiple": "多選題",
+        "Judge": "判斷題",
+        "Complete": "填空題",
+        "Subjective": "問答題"
+      },
+      "AnswerTag": "答案",
+      "AnalysisTag": "解析",
+      "EndedTag": "結束",
+      "Options": "ABCDEFGHIJKLMN",
+      "Start": "【",
+      "End": "】"
+    }
   },
   {
     "Lang": "zh-TW",
     "Name": "台灣",
-    "Alias": "繁體中文"
+    "Alias": "繁體中文",
+    "Item": {
+      "Type": {
+        "Compose": "綜合題",
+        "Single": "單選題",
+        "Multiple": "多選題",
+        "Judge": "判斷題",
+        "Complete": "填空題",
+        "Subjective": "問答題"
+      },
+      "AnswerTag": "答案",
+      "AnalysisTag": "解析",
+      "EndedTag": "結束",
+      "Options": "ABCDEFGHIJKLMN",
+      "Start": "【",
+      "End": "】"
+    }
   }
-]
- 
+]