فهرست منبع

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

CrazyIter_Bin 4 سال پیش
والد
کامیت
54845016df

+ 10 - 8
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -214,32 +214,34 @@
                         icon: 'iconfont icon-activityS',
                         name: this.$t('system.menu.scAc'),
                         router: '',
-                        role: 'admin',
-                        permission: 'schoolAc-read|schoolAc-upd',
+                        // role: 'admin',
+                        // permission: 'schoolAc-read|schoolAc-upd',
+                        role: 'teacher|admin',
+                        permission: '',
                         child: [
                             {
                                 icon: 'iconfont icon-test',
                                 name: this.$t('system.menu.scEv'),
                                 router: '/home/schoolEvaluation',
                                 tag: '*',
-                                role: 'admin',
-                                permission: 'schoolAc-read|schoolAc-upd'
+                                role: 'teacher|admin',
+                                permission: ''
                             },
                             {
                                 icon: 'iconfont icon-vote',
                                 name: this.$t('system.menu.scVote'),
                                 router: '/home/manageVote',
                                 tag: '*',
-                                role: 'admin',
-                                permission: 'schoolAc-read|schoolAc-upd'
+                                role: 'teacher|admin',
+                                permission: ''
                             },
                             {
                                 icon: 'iconfont icon-questionnaire',
                                 name: this.$t('system.menu.scQu'),
                                 router: '/home/manageQuestionnaire',
                                 tag: '*',
-                                role: 'admin',
-                                permission: 'schoolAc-read|schoolAc-upd'
+                                role: 'teacher|admin',
+                                permission: ''
                             },
                         ]
                     },

+ 11 - 11
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue

@@ -1,34 +1,34 @@
 <template>
 	<div class="component-qn-form">
 		<Form ref="qnForm" :model="qnForm" label-position="top" :rules="ruleValidate" :disabled="!qnFormEdit">
-			<FormItem label="问卷名称" prop="name">
-				<Input :class="!qnFormEdit ? 'qn-form-disabled':''" v-model="qnForm.name" placeholder="请输入问卷名称"></Input>
+			<FormItem :label="$t('survey.form.name')" prop="name">
+				<Input :class="!qnFormEdit ? 'qn-form-disabled':''" v-model="qnForm.name" :placeholder="$t('survey.form.namePlace')"></Input>
 			</FormItem>
 
-			<FormItem label="问卷对象" prop="targetClassIds">
+			<FormItem :label="$t('survey.form.target')" prop="targetClassIds">
 				<RadioGroup v-model="classType" @on-change="onClassTypeChange" v-if="qnFormEdit">
-				        <Radio label="private">个人班级</Radio>
-				        <Radio label="school">校本班级</Radio>
+				        <Radio label="private">{{ $t('survey.form.privateClass') }}</Radio>
+				        <Radio label="school">{{ $t('survey.form.schoolClass') }}</Radio>
 				</RadioGroup>
 				<div v-if="!qnFormEdit && curQnItem" class="vote-class">
 					<span v-for="item in curQnItem.targetClassIds" class="vote-class-item">{{ getTargetName(item) }}</span>
 				</div>
-				<Select multiple v-model="qnForm.targetClassIds" :class="!qnFormEdit ? 'qn-form-disabled':''" placeholder="请选择问卷发布对象" v-else>
+				<Select multiple v-model="qnForm.targetClassIds" :class="!qnFormEdit ? 'qn-form-disabled':''" :placeholder="$t('survey.form.targetPlace')" v-else>
 					<!-- <Option v-for="(item,index) in classRooms" :value="item.id" :key="index">{{ item.name }}</Option> -->
 						<Option v-for="item in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="item.id">{{ item.name }}</Option>
 						<!-- <Option v-for="item in classRooms" :value="item.id" :key="item.id">{{ item.name }}</Option> -->
 				</Select>
 			</FormItem>
 
-			<FormItem label="起止时间" prop="rangeTime">
+			<FormItem :label="$t('survey.form.time')" prop="rangeTime">
 				<DatePicker type="datetimerange" @on-change="onChangeRange" format="yyyy-MM-dd HH:mm" :class="!qnFormEdit ? 'qn-form-disabled':''"
-				 :editable="isDateEdit" placeholder="请选择问卷起止时间" :value="[qnForm.startTime,qnForm.endTime]">
+				 :editable="isDateEdit" :placeholder="$t('survey.form.endTimePlace')" :value="[qnForm.startTime,qnForm.endTime]">
 
 				</DatePicker>
 			</FormItem>
 
 
-			<FormItem label="问卷描述" prop="description">
+			<FormItem :label="$t('survey.form.description')" prop="description">
 				<div ref="descriptionEditor" style="text-align:left" v-show="qnFormEdit"></div>
 				<div v-html="qnForm.description" v-show="!qnFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff"></div>
 			</FormItem>
@@ -179,7 +179,7 @@
 							console.log(params)
 							resolve(params)
 						} else {
-							this.$Message.error('请将信息填写完整')
+							this.$Message.error(this.$t('survey.form.noCompleteTip'))
 						}
 					})
 				})
@@ -199,7 +199,7 @@
 							r(res.courses)
 						} else {
 							j(500)
-							this.$Message.error('获取数据失败')
+							this.$Message.error(this.$t('survey.getDataFailTip'))
 						}
 					})
 				})

+ 22 - 22
TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue

@@ -1,33 +1,33 @@
 <template>
     <div class="component-vote-form">
         <Form ref="voteForm" :model="voteForm" label-position="top" :rules="ruleValidate" :disabled="!voteFormEdit">
-            <FormItem label="投票名称" prop="name">
+            <FormItem :label="$t('vote.form.name')" prop="name">
                 <Input :class="!voteFormEdit ? 'vote-form-disabled':''" v-model="voteForm.name" placeholder="请输入投票名称"></Input>
             </FormItem>
-            <FormItem label="投票对象" prop="targetClassIds">
+            <FormItem :label="$t('vote.form.target')" prop="targetClassIds">
 				<RadioGroup v-model="classType" @on-change="onClassTypeChange" v-if="voteFormEdit">
-				        <Radio label="private">个人班级</Radio>
-				        <Radio label="school">校本班级</Radio>
+				        <Radio label="private">{{ $t('vote.form.privateClass') }}</Radio>
+				        <Radio label="school">{{ $t('vote.form.schoolClass') }}</Radio>
 				</RadioGroup>
 				<div v-if="!voteFormEdit && curVoteItem" class="vote-class">
 					<span v-for="item in curVoteItem.targetClassIds" class="vote-class-item">{{ getTargetName(item) }}</span>
 				</div>
-				<Select multiple v-model="voteForm.targetClassIds" :class="!voteFormEdit ? 'vote-form-disabled':''" placeholder="请选择投票发布对象" not-found-text="暂未创建班级" v-else>
+				<Select multiple v-model="voteForm.targetClassIds" :class="!voteFormEdit ? 'vote-form-disabled':''" :placeholder="$t('vote.form.targetPlace')" :not-found-text="$t('vote.form.noFoundText')" v-else>
 				   	<Option v-for="item in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="item.id">{{ item.name }}</Option>
 				</Select>
             </FormItem>
 			
-			<FormItem label="起止时间" prop="rangeTime">
+			<FormItem :label="$t('vote.form.time')" prop="rangeTime">
 			    <!-- <DatePicker type="datetime" :class="!voteFormEdit ? 'vote-form-disabled':''" :editable="isDateEdit" placeholder="请选择投票结束时间" v-model="voteForm.endTime"  :options="endTimeOptions"></DatePicker> -->
-				<DatePicker type="datetimerange" transfer @on-change="onChangeRange" format="yyyy-MM-dd HH:mm" :class="!voteFormEdit ? 'vote-form-disabled':''" :editable="isDateEdit" :value="[voteForm.startTime,voteForm.endTime]" placeholder="请选择投票结束时间"></DatePicker>
+				<DatePicker type="datetimerange" transfer @on-change="onChangeRange" format="yyyy-MM-dd HH:mm" :class="!voteFormEdit ? 'vote-form-disabled':''" :editable="isDateEdit" :value="[voteForm.startTime,voteForm.endTime]" :placeholder="$t('vote.form.endTimePlace')"></DatePicker>
 			</FormItem>
 
-            <FormItem label="投票描述" prop="description">
+            <FormItem :label="$t('vote.form.description')" prop="description">
                 <div ref="descriptionEditor" style="text-align:left" v-show="voteFormEdit"></div>
                 <div v-html="voteForm.description" v-show="!voteFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff"></div>
             </FormItem>
 
-            <FormItem label="选项设置" prop="attachment" ref="optionsBox">
+            <FormItem :label="$t('vote.form.optionSetting')" prop="attachment" ref="optionsBox">
 				<div v-if="voteOptions.length">
 					<div v-for="(item,index) in voteOptions" :key="index" class="option-editor-wrap">
 						<div v-show="voteFormEdit" style="display: flex;">
@@ -41,7 +41,7 @@
 					</div>
 				</div>
                 
-                <p style="float:right;color:#BDBDBD;cursor:pointer" @click="onAddOption" v-show="voteFormEdit"><Icon type="md-add" />添加选项</p>
+                <p style="float:right;color:#BDBDBD;cursor:pointer" @click="onAddOption" v-show="voteFormEdit"><Icon type="md-add" />{{ $t('vote.form.addOption') }}</p>
             </FormItem>
 
             <!--<FormItem label="投票记录" prop="isReset" v-show="editable && isEdit">
@@ -50,20 +50,20 @@
                 </CheckboxGroup>
             </FormItem>-->
 
-            <FormItem label="可投票数" prop="selectMax">
+            <FormItem :label="$t('vote.form.selectNum')" prop="selectMax">
                 <!--<Input :class="!voteFormEdit ? 'vote-form-disabled':''" v-model="voteForm.count" placeholder="请输入投票名称"></Input>-->
                 <InputNumber :max="10" :min="1" v-model="voteForm.selectMax"></InputNumber>
             </FormItem>
 
-            <FormItem label="其他" prop="secret">
+            <FormItem :label="$t('vote.form.other')" prop="secret">
                 <CheckboxGroup v-model="voteForm.secret">
-                    <Checkbox label="secret">开启匿名投票</Checkbox>
+                    <Checkbox label="secret">{{ $t('vote.form.openSecret') }}</Checkbox>
                 </CheckboxGroup>
             </FormItem>
 
             <FormItem v-show="voteFormEdit">
-                <Button type="primary" class="btn-save" @click="handleSubmit('voteForm')" :loading="isBtnLoading">保存</Button>
-                <Button @click="handleCancel('voteForm')" class="btn-reset" style="margin-left: 8px">取消</Button>
+                <Button type="primary" class="btn-save" @click="handleSubmit('voteForm')" :loading="isBtnLoading">{{ $t('vote.form.save') }}</Button>
+                <Button @click="handleCancel('voteForm')" class="btn-reset" style="margin-left: 8px">{{ $t('vote.form.cancel') }}</Button>
             </FormItem>
         </Form>
     </div>
@@ -218,7 +218,7 @@
 						console.log(params)
 						/* 保存BLOB以及COSMOS */
 						this.saveorUpdateVote({ vote: params, reset: isReset }).then(res => {
-						    this.$Message.success((this.isEdit && this.editInfo.id) ? '修改成功!' : '添加成功!')
+						    this.$Message.success((this.isEdit && this.editInfo.id) ? this.$t('vote.form.editSuc') : this.$t('vote.form.addSuc'))
 						    this.$emit('onAddSuccess')
 						    this.isBtnLoading = false
 						}).catch(error => {
@@ -229,9 +229,9 @@
                     } else {
 						this.isBtnLoading = false
 						if(this.voteOptionsContent.length){
-							this.$Message.error('请将信息填写完整')
+							this.$Message.error(this.$t('vote.form.noCompleteTip'))
 						}else{
-							this.$Message.error('投票选项个数不能为空!')
+							this.$Message.error(this.$t('vote.form.noOptionTip'))
 						}
                     }
                 })
@@ -340,7 +340,7 @@
                         editor.create()
                     })
                 } else {
-                    this.$Message.warning('最多只有10个选项!')
+                    this.$Message.warning(this.$t('vote.form.optionNumsTip'))
                 }
             },
 
@@ -355,7 +355,7 @@
             				r(res.courses)
             			} else {
             				j(500)
-            				this.$Message.error('获取数据失败')
+            				this.$Message.error(this.$t('vote.form.getDataFailTip'))
             			}
             		})
             	})
@@ -397,7 +397,7 @@
                 const check = this.uploadList.length < 5;
                 if (!check) {
                     this.$Notice.warning({
-                        title: '最多只能上传5个附件'
+                        title: this.$t('vote.form.attachmentMaxTip')
                     });
                 }
                 return check;
@@ -458,7 +458,7 @@
             getTargetName(classId){
 				if(this.classRooms.length){
 					let targetIndex = this.classRooms.map(i => i.id).indexOf(classId)
-					return targetIndex > -1 ?  this.classRooms[targetIndex].name : '未匹配数据'
+					return targetIndex > -1 ?  this.classRooms[targetIndex].name : this.$t('vote.form.noMatchDataTip')
 				}else{
 					this.getClassrooms(this.userInfo.TEAMModelId).then(res => {
 						return res.filter(i => i.id === classId)[0].name

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

@@ -181,11 +181,11 @@ export default {
 		downloadDetails:'下载模板制作详情说明',
 		importTips:'导入注意事项',
 		tips1:'点击上方上传图标选择文件',
-		tips2:'只支持".docx"格式的文件导入,请按照模板格式导入',
+		tips2:'只支持".docx,.xlsx,.xls"格式的文件导入,请按照模板格式导入',
 		tips3:'导入题型暂时只支持单选、多选、判断、填空、问答以及综合题型',
 		tips4:'请保持模板语言与当前浏览器语言一致',
 		tips5:'更多注意事项请查看模板制作详情说明',
-		warningTips1:'上传格式仅支持 docx,请重新上传!',
+		warningTips1:'上传格式仅支持 docx/xlsx/xls ,请重新上传!',
 		warningTips2:'最大上传大小为10M,请重新上传!',
 		warningTips3:'试题数据读取完成!',
 		warningTips4:'未解析出符合条件的试题,请检查导入格式是否按照模板文件修改!',

+ 4 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/index.js

@@ -25,6 +25,8 @@ import global from './global'
 import system from './system'
 import cusMgt from './cusMgt'
 import home from './home'
+import vote from './vote'
+import survey from './survey'
 export default {
   schoolBaseInfo,
   classMgmt,
@@ -53,6 +55,8 @@ export default {
   system,
   cusMgt,
   home,
+  vote,
+  survey,
   test: '测试',
   formConfigP: {
     input: '请输入',

+ 54 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/survey.js

@@ -0,0 +1,54 @@
+export default {
+    list:'问卷活动列表',
+	pending:'待发布',
+	going:'进行中',
+	finish:'已结束',
+	surveyDetails:'问卷详情',
+	undo:'撤销发布',
+	edit:'编辑问卷',
+	save:'保存问卷',
+	cancelEdit:'取消编辑',
+	surveyResult:'问卷数据',
+	addItem:'新增题目',
+	single:'单选题',
+	multiple:'多选题',
+	judge:'判断题',
+	defaultName:'预设问卷名称',
+	isExistTip:'已存在未保存的问卷活动!',
+	getDataFailTip:'获取数据失败!',
+	deletesurvey:'删除问卷',
+	deleteConfirmTip:'确认删除该问卷活动?',
+	cancelSurvey:'取消发布',
+	cancelConfirmTip:'确认取消发布该问卷活动?',
+	deleteSuc:'删除成功',
+	deleteFail:'删除失败',
+	doSuc:'操作成功',
+	doFail:'操作失败',
+	noData:'暂无数据',
+	form:{
+		name:'问卷名称',
+		namePlace:'请输入问卷名称',
+		target:'问卷对象',
+		privateClass:'个人班级',
+		schoolClass:'校本班级',
+		targetPlace:'请选择问卷发布对象',
+		noFoundText:'暂未创建班级',
+		time:'起止时间',
+		endTimePlace:'请选择问卷结束时间',
+		description:'问卷描述',
+		optionSetting:'选项设置',
+		addOption:'添加选项',
+		selectNum:'可问卷数',
+		other:'其他',
+		openSecret:'开启匿名问卷',
+		save:'保存',
+		cancel:'取消',
+		editSuc:'修改成功',
+		addSuc:'添加成功',
+		noCompleteTip:'请将信息填写完整',
+		noOptionTip:'问卷选项个数不能为空!',
+		attachmentMaxTip:'最多只能上传5个附件',
+		optionNumsTip:'最多只能有10个选项',
+		noMatchDataTip:'未匹配数据'
+	}
+}

+ 49 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/vote.js

@@ -0,0 +1,49 @@
+export default {
+    list:'投票活动列表',
+	pending:'待发布',
+	going:'进行中',
+	finish:'已结束',
+	voteDetails:'投票详情',
+	edit:'编辑',
+	voteResult:'投票数据',
+	optionView:'选项清单试图',
+	stuListView:'学生清单视图',
+	defaultName:'预设投票名称',
+	isExistTip:'已存在未保存的投票活动!',
+	getDataFailTip:'获取数据失败!',
+	serverErrorTip:'投票活动接口调整中,请稍后再试!',
+	deleteVote:'删除投票',
+	deleteConfirmTip:'确认删除该投票活动?',
+	deleteSuc:'删除成功',
+	deleteFail:'删除失败',
+	option:'选项',
+	noVote:'未投票',
+	noData:'暂无数据',
+	getClassDataFailTip:'获取班级学生数据异常',
+	form:{
+		name:'投票名称',
+		namePlace:'请输入投票名称',
+		target:'投票对象',
+		privateClass:'个人班级',
+		schoolClass:'校本班级',
+		targetPlace:'请选择投票发布对象',
+		noFoundText:'暂未创建班级',
+		time:'起止时间',
+		endTimePlace:'请选择投票结束时间',
+		description:'投票描述',
+		optionSetting:'选项设置',
+		addOption:'添加选项',
+		selectNum:'可投票数',
+		other:'其他',
+		openSecret:'开启匿名投票',
+		save:'保存',
+		cancel:'取消',
+		editSuc:'修改成功',
+		addSuc:'添加成功',
+		noCompleteTip:'请将信息填写完整',
+		noOptionTip:'投票选项个数不能为空!',
+		attachmentMaxTip:'最多只能上传5个附件',
+		optionNumsTip:'最多只能有10个选项',
+		noMatchDataTip:'未匹配数据'
+	}
+}

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

@@ -181,11 +181,11 @@ export default {
 		downloadDetails: '下載範本製作詳情說明',
 		importTips: '導入注意事項',
 		tips1: '點擊上方上傳圖標選擇檔案',
-		tips2: '只支持“.docx”格式的檔案導入,請按照範本格式導入',
+		tips2: '只支持“.docx,.xlsx,.xls”格式的檔案導入,請按照範本格式導入',
 		tips3: '導入題型暫時只支持單選、多選、判斷、填空、問答以及綜合題型',
 		tips4: '請保持範本語言與當前瀏覽器語言一致',
 		tips5: '更多注意事項請查看範本製作詳情說明',
-		warningTips1: '上傳格式僅支持docx,請重新上傳!',
+		warningTips1: '上傳格式僅支持 docx/xlsx/xls ,請重新上傳!',
 		warningTips2: '最大上傳大小為10M,請重新上傳!',
 		warningTips3: '試題數據讀取完成!',
 		warningTips4: '未解析出符合條件的試題,請檢查導入格式是否按照範本檔案修改!',

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

@@ -25,7 +25,8 @@ import global from './global'
 import system from './system'
 import cusMgt from './cusMgt'
 import home from './home'
-
+import vote from './vote'
+import survey from './survey'
 export default {
   
   schoolBaseInfo,
@@ -55,6 +56,8 @@ export default {
   system,
   cusMgt,
   home,
+  vote,
+  survey,
   test: '測試',
   formConfigP: {
     input: '請輸入',

+ 54 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/survey.js

@@ -0,0 +1,54 @@
+export default {
+	list: '問卷活動清單',
+	pending: '待發佈',
+	going: '進行中',
+	finish: '已結束',
+	surveyDetails: '問卷詳情',
+	undo: '撤銷發佈',
+	edit: '編輯問卷',
+	save: '保存問卷',
+	cancelEdit: '取消編輯',
+	surveyResult: '問卷數據',
+	addItem: '新增題目',
+	single: '單選題',
+	multiple: '复选题',
+	judge: '判斷題',
+	defaultName: '預設問卷名稱',
+	isExistTip: '已存在未保存的問卷活動!',
+	getDataFailTip: '獲取數據失敗!',
+	deletesurvey: '删除問卷',
+	deleteConfirmTip: '確認删除該問卷活動?',
+	cancelSurvey: '取消發佈',
+	cancelConfirmTip: '確認取消發佈該問卷活動?',
+	deleteSuc: '删除成功',
+	deleteFail: '删除失敗',
+	doSuc: '操作成功',
+	doFail: '操作失敗',
+	noData: '暫無數據',
+	form: {
+		name: '問卷名稱',
+		namePlace: '請輸入問卷名稱',
+		target: '問卷對象',
+		privateClass: '個人班級',
+		schoolClass: '校本班級',
+		targetPlace: '請選擇問卷發佈對象',
+		noFoundText: '暫未創建班級',
+		time: '起止時間',
+		endTimePlace: '請選擇問卷結束時間',
+		description: '問卷描述',
+		optionSetting: '選項設定',
+		addOption: '添加選項',
+		selectNum: '可問卷數',
+		other: '其他',
+		openSecret: '開啟匿名問卷',
+		save: '保存',
+		cancel: '取消',
+		editSuc: '修改成功',
+		addSuc: '添加成功',
+		noCompleteTip: '請將資訊填寫完整',
+		noOptionTip: '問卷選項個數不能為空!',
+		attachmentMaxTip: '最多只能上傳5個附件',
+		optionNumsTip: '最多只能有10個選項',
+		noMatchDataTip: '未匹配數據'
+	}
+}

+ 49 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/vote.js

@@ -0,0 +1,49 @@
+export default {
+	list: '投票活動清單',
+	pending: '待發佈',
+	going: '進行中',
+	finish: '已結束',
+	voteDetails: '投票詳情',
+	edit: '編輯',
+	voteResult: '投票數據',
+	optionView: '選項清單試圖',
+	stuListView: '學生清單視圖',
+	defaultName: '預設投票名稱',
+	isExistTip: '已存在未保存的投票活動!',
+	getDataFailTip: '獲取數據失敗!',
+	serverErrorTip: '投票活動介面調整中,請稍後再試!',
+	deleteVote: '删除投票',
+	deleteConfirmTip: '確認删除該投票活動?',
+	deleteSuc: '删除成功',
+	deleteFail: '删除失敗',
+	option: '選項',
+	noVote: '未投票',
+	noData: '暫無數據',
+	getClassDataFailTip: '獲取班級學生數據异常',
+	form: {
+		name: '投票名稱',
+		namePlace: '請輸入投票名稱',
+		target: '投票對象',
+		privateClass: '個人班級',
+		schoolClass: '校本班級',
+		targetPlace: '請選擇投票發佈對象',
+		noFoundText: '暫未創建班級',
+		time: '起止時間',
+		endTimePlace: '請選擇投票結束時間',
+		description: '投票描述',
+		optionSetting: '選項設定',
+		addOption: '添加選項',
+		selectNum: '可投票數',
+		other: '其他',
+		openSecret: '開啟匿名投票',
+		save: '保存',
+		cancel: '取消',
+		editSuc: '修改成功',
+		addSuc: '添加成功',
+		noCompleteTip: '請將資訊填寫完整',
+		noOptionTip: '投票選項個數不能為空!',
+		attachmentMaxTip: '最多只能上傳5個附件',
+		optionNumsTip: '最多只能有10個選項',
+		noMatchDataTip: '未匹配數據'
+	}
+}

+ 34 - 9
TEAMModelOS/ClientApp/src/store/index.js

@@ -12,7 +12,7 @@ import teachers from './module/teachers'
 import studentWeb from './module/studentWeb'
 import scboard from './module/scboard'
 import serviceDriveAuth from './module/serviceDriveAuth'
-import  { GLOBAL }  from '@/static/Global.js'
+import { GLOBAL } from '@/static/Global.js'
 import spaceAuth from './module/spaceAuth'
 import studentAclassOneAuth from './module/studentAclassOneAuth'
 
@@ -33,15 +33,40 @@ const mutations = {
     setSchoolSas(state, obj) {
         state.schoolSas = obj
     },
-    setUserInfo(state, obj) {
+    setUserInfo(state, obj) { //obj还是原来的逻辑传参,没有变化。只是这里内部逻辑添加了判断是否为班主任,班主任对应的班级id,以及授课班级id三个字段的处理逻辑
         obj.schoolCode = obj.schoolCode || GLOBAL.DEFAULT_SCHOOL_CODE
         obj.hasSchool = obj.schoolCode !== GLOBAL.DEFAULT_SCHOOL_CODE
-		state.userInfo = obj
-	},
-	setSchoolCode(state,obj){
-		state.userInfo.schoolCode = obj || GLOBAL.DEFAULT_SCHOOL_CODE
-		state.userInfo.hasSchool = obj !== GLOBAL.DEFAULT_SCHOOL_CODE
-	}
+        obj.isHeadmaster = false      //默认不是班主任
+        obj.mgtClasses = []           //班主任管理的班级id
+        obj.teachClasses = []         //授课班级id
+        let schoolStr = localStorage.getItem('school_profile')
+        if (schoolStr) {
+            schoolStr = decodeURIComponent(schoolStr, "utf-8")
+            let schoolJson = JSON.parse(schoolStr)
+            let mgtClasses = schoolJson.school_classes.filter(item=>{
+                return item.teacher.id == obj.TEAMModelId
+            })
+            if(mgtClasses.length){
+                obj.isHeadmaster = true //是班主任
+                obj.mgtClasses = mgtClasses.map(item=>{
+                    return item.id
+                })
+            }
+            if(schoolJson.school_courses){
+                schoolJson.school_courses.forEach(item => {
+                    let classIds = item.classes.map(classItem =>{
+                        return classItem.id
+                    })
+                    obj.teachClasses.push(...classIds)
+                })
+            }
+        }
+        state.userInfo = obj
+    },
+    setSchoolCode(state, obj) {
+        state.userInfo.schoolCode = obj || GLOBAL.DEFAULT_SCHOOL_CODE
+        state.userInfo.hasSchool = obj !== GLOBAL.DEFAULT_SCHOOL_CODE
+    }
 }
 
 // ACTIONS
@@ -64,7 +89,7 @@ export default new Vuex.Store({
             TEAMModelId: '',
             name: '',
             schoolCode: '',
-			hasSchool:false
+            hasSchool: false
         }
     },
     modules: {

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

@@ -123,7 +123,7 @@
 								<div class="item-explain" v-show="isShowAnswer">
 									<span class="explain-title">【{{$t('evaluation.filter.level')}}】</span>
 									<div class="item-explain-details">
-										{{ item.level ? exersicesField[item.level - 1] : exersicesField[0]}}
+										{{ item.field ? exersicesField[item.field - 1] : exersicesField[0]}}
 									</div>
 								</div>
 							</div>

+ 90 - 5
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseImport.vue

@@ -4,7 +4,7 @@
                 <Upload multiple
                         :action="uploadUrl"
                         :headers="headers"
-                        :format="['docx']"
+                        :format="['docx','xlsx','xls']"
                         :on-format-error="handleFormatError"
                         :show-upload-list="isShowList"
                         :before-upload="beforeUpload"
@@ -51,6 +51,7 @@
     </div>
 </template>
 <script>
+	import excel from '@/utils/excel.js'
 	import FileSaver from "file-saver";
     export default {
         props: ['period', 'subject'],
@@ -78,7 +79,8 @@
 					url:'/download/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF%E8%8B%B1%E8%AF%AD.docx',
 					fileName:'TitleTemplate.docx'
 				}],
-				hostName:''
+				hostName:'',
+				fieldArr:['記憶记忆1','理解2','應用应用3','分析4','创造創造5','评价評鑒6']
             }
         },
         created() {
@@ -144,11 +146,94 @@
             },
 
             /** 选择文件上传之前 */
-            beforeUpload() {
-                this.isBtnLoading = true
-                this.isSelectFinish = true
+            beforeUpload(file) {
+				this.isBtnLoading = true
+				this.isSelectFinish = true
+				// 如果是excel格式文档 则需要进行对应解析
+				if(this.isExcel(file)){
+					let excelResult = []
+					this.readExcel(file,data => {
+						if(data.results.length){
+							data.results.forEach(item => {
+								excelResult.push({
+									question:item.Question || '',
+									answer:item.Answer ? [item.Answer] : [],
+									knowledge:item.Concept ? item.Concept.split(',') : [],
+									field:this.getItemField(item),
+									score:item.Point || 0,
+									type:item.Type,
+									children:[],
+									option:this.getItemOptions(item)
+								})
+							})
+							this.$Message.success(this.$t('evaluation.importFile.warningTips3'))
+							this.$emit('importFinish',excelResult)
+							this.isImportFinish = false
+							this.isBtnLoading = false
+							this.exerciseList = []
+						}
+					})
+					return false
+				}
             },
 
+			
+			/* 获取表格解析试题的选项 */
+			getItemOptions(item){
+				let options = []
+				let optionIndex = 0
+				if(item.Type === 'judge'){
+					return [{
+						code:'A',
+						value:'对'
+					},{
+						code:'B',
+						value:'错'
+					}]
+				}else{
+					for(let key in item){
+						if(key.includes('Option')){
+							options.push({
+								code: String.fromCharCode(64 + parseInt(optionIndex + 1)),
+								value:item[key]
+							})
+							optionIndex++
+						}
+					}
+					return options
+				}
+				
+				
+			},
+			
+			/* 获取表格解析试题的认知层次 */
+			getItemField(item){
+				for (let i in this.fieldArr) {
+					if(this.fieldArr[i].includes(item.Edu_Goal)){
+						return + i + 1
+						break
+					}
+				}
+			},
+			
+			
+			/* 判断上传的是否为excel表格文件 */
+			isExcel(file){
+				let  fileType = file.name.split('.')[file.name.split('.').length - 1]
+				return  fileType === 'xlsx' || fileType === 'xls'
+			},
+			
+			/* 解析excel表格 */
+			readExcel(file, callback) {
+			    var reader = new FileReader();
+			    reader.onload = function (e) {
+			        var data = e.target.result;
+			        var workbook = excel.read(data, 'binary');                
+			        if (callback) callback(workbook);
+			    };
+			    reader.readAsBinaryString(file);
+			},
+
             /**
              * 当上传文件格式错误
              * @param

+ 39 - 16
TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue

@@ -5,7 +5,17 @@
             <!--评测列表-->
             <div class="evaluation-list-wrap" slot="left">
                 <div class="evaluation-list-title">
-                    <span>{{$t('learnActivity.mgtScEv.listLabel')}}</span>
+                    <span v-if="!$store.state.userInfo.isHeadmaster">{{$t('learnActivity.mgtScEv.listLabel')}}</span>
+                    <Dropdown v-else class="sort-dropdown" trigger="click" placement="bottom-start" @on-click="function(e){ curEvValue = e }" @on-visible-change="dropdownStates">
+                        <span style="cursor: pointer;">
+                            <!-- {{$t('learnActivity.mgtScEv.period')}} -->
+                            <b class="title">{{ curEvLabel }}</b>
+                            <Icon type="ios-arrow-down" style="margin-left:8px;"></Icon>
+                        </span>
+                        <DropdownMenu slot="list" v-for="(item,index) in evFilter" :value="item.value" :key="index">
+                            <DropdownItem :name="item.value">{{ item.label }}</DropdownItem>
+                        </DropdownMenu>
+                    </Dropdown>
                     <Icon type="md-add" class=" to-create-icon" @click="goToCreate" :title="$t('learnActivity.mgtScEv.create')" />
                     <Icon type="md-trash" v-show="evaListShow.length" class="to-create-icon" :title="$t('learnActivity.mgtScEv.delete')" @click="deleteEvaluation" />
                     <Icon type="md-create" v-show="evaListShow.length && evaListShow[curEvaIndex].progress == 'pending'" class="to-create-icon" @click="editEvaluation" :title="$t('learnActivity.mgtScEv.edit')" />
@@ -98,6 +108,7 @@ export default {
     inject: ['reload'],
     data() {
         return {
+            curEvValue:0,
             split1: 0.2,
             scope: '',//school 校本 private 个人
             showBack: false,
@@ -109,15 +120,34 @@ export default {
             examDetaiInfo: {},
             targetList: [],
             isLoading: false,
-            filterPeriod: undefined,
             schoolBase: {
                 period: []
             },
+            evFilter:[
+                {
+                    label:'我发布的评测',
+                    value:0
+                },
+                {
+                    label:'数学评测',
+                    value:1
+                },
+                {
+                    label:'英语评测',
+                    value:2
+                }
+            ],
             scoreLoading: false,
             answerLoading: false
         }
     },
     methods: {
+        dropdownStates(flag) {
+            if (!flag) this.filterByTag()
+        },
+        filterByTag() {
+            this.curEvaIndex = 0
+        },
         // 模拟教师评分数据
         mockScoring() {
             this.scoreLoading = true
@@ -387,10 +417,6 @@ export default {
             (res) => {
                 if (res) {
                     this.schoolBase = res.school_base
-                    // 預設搜尋給第一個
-                    if (res.school_base.period && res.school_base.period.length) {
-                        this.filterPeriod = res.school_base.period[0].id
-                    }
                 }
             }
         ).finally(() => {
@@ -410,16 +436,13 @@ export default {
         }
     },
     computed: {
-        filterPeriodName: function () {
-            let pId = this.filterPeriod
-            let name = ''
-            if (pId) {
-                let temp = this.$store.state.user.schoolProfile.school_base.period.filter(item => {
-                    return pId == item.id
-                })
-                if (temp.length > 0) name = temp[0].name
-            }
-            return name
+        curEvLabel: function () {
+            let value = this.curEvValue
+            console.log(this.curEvValue)
+            let curObj = this.evFilter.find(item=>{
+                return item.value == value
+            })
+            return curObj.label
         },
     }
 }

+ 6 - 4
TEAMModelOS/ClientApp/src/view/learnactivity/MgtSchoolEva.vue

@@ -15,9 +15,9 @@
                             <DropdownItem :name="item.id">{{ item.name }}</DropdownItem>
                         </DropdownMenu>
                     </Dropdown>
-                    <Icon type="md-add" class=" to-create-icon" @click="goToCreate" :title="$t('learnActivity.mgtScEv.create')" />
-                    <Icon type="md-trash" v-show="evaListShow.length" class="to-create-icon" :title="$t('learnActivity.mgtScEv.delete')" @click="deleteEvaluation" />
-                    <Icon type="md-create" v-show="evaListShow.length && evaListShow[curEvaIndex] && evaListShow[curEvaIndex].progress == 'pending'" class="to-create-icon" @click="editEvaluation" :title="$t('learnActivity.mgtScEv.edit')" />
+                    <Icon type="md-add" class=" to-create-icon" @click="goToCreate" :title="$t('learnActivity.mgtScEv.create')" v-if="$access.can('admin.*|schoolAc-upd')"/>
+                    <Icon type="md-trash" v-show="evaListShow.length" class="to-create-icon" :title="$t('learnActivity.mgtScEv.delete')" @click="deleteEvaluation" v-if="$access.can('admin.*|schoolAc-upd')"/>
+                    <Icon type="md-create" v-show="evaListShow.length && evaListShow[curEvaIndex] && evaListShow[curEvaIndex].progress == 'pending'" class="to-create-icon" @click="editEvaluation" :title="$t('learnActivity.mgtScEv.edit')" v-if="$access.can('admin.*|schoolAc-upd')"/>
                 </div>
                 <div class="evaluation-list-main">
                     <vuescroll>
@@ -330,8 +330,10 @@ export default {
 
         //查询评测列表
         findEvaluation() {
+            console.log('123456',this.$access.hasRole('admin'))
             let requestData = {
-                code: this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
+                code: this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
+                classIds:this.$access.hasRole('admin') ? undefined : this.$store.state.userInfo.teachClasses
             }
             this.$api.learnActivity.FindExamInfo(requestData).then(
                 res => {

+ 2 - 0
TEAMModelOS/ClientApp/src/view/login/Index.vue

@@ -409,6 +409,7 @@ export default {
               }).catch(err=>{
                 isFail = true
               })
+              console.log('res***',result)
               if(isFail){
                 this.loginErrText = this.$t('login.apiError.text1')
                 this.loading = false
@@ -538,6 +539,7 @@ export default {
       await this.$api.login.loginIES(item, schoolCode).then( res => {
         result = res
       })
+      console.log('////',result)
 
       //設定權限並登入
       let identity = localStorage.getItem('identity')

+ 26 - 30
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -13,7 +13,7 @@
 					<!-- 问卷活动列表 -->
 					<div class="qn-col qn-list-box">
 						<div class="qn-box-header">
-							<span>问卷列表</span>
+							<span>{{ $t('survey.list') }}</span>
 							<div>
 								<Icon type="md-trash" class="to-create-icon" @click="onDeleteQn" style="margin-left: 10px" v-if="qnList.length && ($access.can('admin.*|schoolAc-upd') || isPrivate)" />
 								<Icon type="md-add" class="to-create-icon" @click="goToCreate" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" />
@@ -33,7 +33,7 @@
 											<span class="qn-item-nums">
 												<Icon type="md-time" size="14" style="margin-right: 5px" />{{ $tools.formatTime(item.startTime) }}</span>
 											<span class="qn-item-status" :style="{ background: item.progress === 'pending' ? '#0BADD4'  : item.progress === 'going' ? '#12a568' : '#949594', }">
-												{{ item.progress === "pending" ? "待发布" : item.progress === "going"  ? "进行中" : "已结束"  }}
+												{{ item.progress === "pending" ? $t('survey.pending') : item.progress === "going"  ? $t('survey.going') : $t('survey.finish')  }}
 											</span>
 										</div>
 									</div>
@@ -48,12 +48,12 @@
 							<!-- 问卷基础信息展示 -->
 							<div class="qn-col qn-info-box">
 								<div class="qn-box-header">
-									<span>问卷详情</span>
+									<span>{{ $t('survey.surveyDetails') }}</span>
 									<div class="qn-box-header-tools">
 										<!-- <span class="qn-box-header-tools-tool" v-show="currentQn.status !== 300 && qnList.length">
 											<Icon type="md-create" size="18" title="编辑" @click="onEditQn" /></span> -->
 										<span class="qn-box-header-tools-tool" v-show="currentQn.progress === 'going' && qnList.length">
-											<Icon type="md-undo" size="18" title="取消发布" @click="onCancelQn" style="margin-left: 8px" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" /></span>
+											<Icon type="md-undo" size="18" :title="$t('survey.undo')" @click="onCancelQn" style="margin-left: 8px" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" /></span>
 									</div>
 								</div>
 								<vuescroll ref="qnDetailsScroll">
@@ -70,19 +70,19 @@
 							<!-- 问卷提交数据 -->
 							<div class="qn-col qn-data-box">
 								<div class="qn-box-header">
-									<span>问卷数据</span>
+									<span>{{ $t('survey.surveyResult') }}</span>
 									<div class="qn-box-header-tools" v-show="!isEmptyData">
 										<div class="qn-box-header-tools-tool" style="margin-right: 25px" v-show="currentQn.progress !== 'finish' && editable">
 											<Icon type="md-list-box" color="#dcdcdc" />
 											<Dropdown @on-click="onAddItem">
 												<Button>
-													新增题目
+													{{ $t('survey.addItem') }}
 													<Icon type="ios-arrow-down"></Icon>
 												</Button>
 												<DropdownMenu slot="list">
-													<DropdownItem name="single">单选题</DropdownItem>
-													<DropdownItem name="multiple">多选题</DropdownItem>
-													<DropdownItem name="judge">判断题</DropdownItem>
+													<DropdownItem name="single">{{ $t('survey.single') }}</DropdownItem>
+													<DropdownItem name="multiple">{{ $t('survey.multiple') }}</DropdownItem>
+													<DropdownItem name="judge">{{ $t('survey.judge') }}</DropdownItem>
 												</DropdownMenu>
 											</Dropdown>
 										</div>
@@ -92,16 +92,16 @@
 										</div> -->
 										<div class="qn-box-header-tools-tool" @click="onEditQn" v-show="currentQn.progress === 'pending' && qnList.length && !editable && ($access.can('admin.*|schoolAc-upd') || isPrivate)">
 											<Icon type="md-create" color="#209460" />
-											<span>编辑问卷</span>
+											<span>{{ $t('survey.edit') }}</span>
 										</div>
 							
 										<div class="qn-box-header-tools-tool" v-show="editable" style="margin-right: 20px">
-											<Button class="btn-save" icon="md-folder" :loading="isBtnLoading" @click="onSaveQn">保存问卷</Button>
+											<Button class="btn-save" icon="md-folder" :loading="isBtnLoading" @click="onSaveQn">{{ $t('survey.save') }}</Button>
 										</div>
 							
 										<div class="qn-box-header-tools-tool" @click="onCancelEditQn" v-show="editable">
 											<Icon type="md-create" color="#209460" />
-											<span>取消编辑</span>
+											<span>{{ $t('survey.cancelEdit') }}</span>
 										</div>
 									</div>
 								</div>
@@ -160,10 +160,10 @@
 			goToCreate() {
 				let hasNoSaveQn = this.qnList.filter(i => !i.id).length
 				if (hasNoSaveQn) {
-					this.$Message.warning("已存在未保存的问卷!");
+					this.$Message.warning(this.$t('survey.isExistTip'));
 				} else {
 					let defaultQn = {
-						name: "预设问卷名称",
+						name: this.$t('survey.defaultName'),
 						targetClassIds: [],
 						endTime: "",
 						startTime: "",
@@ -186,10 +186,8 @@
 			/** 删除当前问卷 */
 			onDeleteQn() {
 				this.$Modal.confirm({
-					title: "删除问卷",
-					content: "<p>确认删除该问卷?</p>",
-					okText: "确认",
-					cancelText: "取消",
+					title: this.$t('survey.deletesurvey'),
+					content: this.$t('survey.deleteConfirmTip'),
 					onOk: () => {
 						this.isLoading = true;
 
@@ -203,19 +201,19 @@
 								.then((res) => {
 									if (!res.error) {
 										this.isLoading = false;
-										this.$Message.success("操作成功");
+										this.$Message.success(this.$t('survey.deleteSuc'));
 										this.handleTabClick(
 											this.$route.name === "manageQuestionnaire" ? 0 : 1
 										);
 									} else {
 										this.isLoading = false;
-										this.$Message.success("操作失败");
+										this.$Message.error(this.$t('survey.deleteFail'));
 									}
 								});
 						} else {
 							this.qnList.splice(this.qnList.indexOf(this.currentQn), 1);
 							this.isLoading = false;
-							this.$Message.success("操作成功");
+							this.$Message.success(this.$t('survey.deleteSuc'));
 							if (this.qnList.length) this.onQnClick(this.qnList[0], 0);
 						}
 					},
@@ -241,7 +239,7 @@
 						}
 						this.isLoadList = false;
 					} else {
-						this.$Message.error("获取数据失败");
+						this.$Message.error(this.$t('survey.getDataFailTip'));
 					}
 				});
 			},
@@ -259,7 +257,7 @@
 							if (!res.error && res.surveys) {
 								r(res.surveys[0]);
 							} else {
-								this.$Message.error("获取数据失败");
+								this.$Message.error(this.$t('survey.getDataFailTip'));
 							}
 						});
 				});
@@ -313,7 +311,7 @@
 						reset: false,
 					})
 					.then((res) => {
-						this.$Message.success("操作成功");
+						this.$Message.success(this.$t('survey.doSuc'));
 						this.$refs.qnForm.qnFormEdit = false;
 						this.editable = false;
 						this.isLoading = false;
@@ -429,10 +427,8 @@
 			/* 取消发布问卷 */
 			onCancelQn() {
 				this.$Modal.confirm({
-					title: "取消发布",
-					content: "<p>确认取消发布该问卷?</p>",
-					okText: "确认",
-					cancelText: "取消",
+					title: this.$t('survey.cancelSurvey'),
+					content: this.$t('survey.cancelConfirmTip'),
 					onOk: () => {
 						this.isLoading = true;
 						this.$api.questionnaire
@@ -442,11 +438,11 @@
 							.then((res) => {
 								if (!res.error) {
 									this.isLoading = false;
-									this.$Message.success("操作成功");
+									this.$Message.success(this.$t('survey.doSuc'));
 									this.getQnList();
 								} else {
 									this.isLoading = false;
-									this.$Message.success("操作失败");
+									this.$Message.success(this.$t('survey.doFail'));
 								}
 							});
 					},

+ 20 - 28
TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue

@@ -1,12 +1,6 @@
 <template>
 	<div class="hw-container">
 		<Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoading"></Loading>
-		<div class="hw-header" style="display: none;">
-			<div>
-				<span :class="tabIndex == 0 ? 'tab-active' : ''" @click="handleTabClick(0)">校本投票</span>
-				<span :class="tabIndex == 1 ? 'tab-active' : ''" @click="handleTabClick(1)">个人投票</span>
-			</div>
-		</div>
 		<div class="hw-box dark-iview-split">
 
 			<Split v-model="split1">
@@ -14,7 +8,7 @@
 					<!-- 投票活动列表 -->
 					<div class="hw-col hw-list-box">
 						<div class="hw-box-header">
-							<span>投票活动列表</span>
+							<span>{{ this.$t('vote.list') }}</span>
 							<span>
 								<Icon type="md-trash" class="to-create-icon" @click="onDeleteVote" style="margin-left:10px" v-if="voteList.length && ($access.can('admin.*|schoolAc-upd') || isPrivate)" />
 								<Icon type="md-add" class="to-create-icon" @click="goToCreate" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" />
@@ -33,7 +27,7 @@
 										<div class="hw-item-info">
 											<span class="hw-item-nums">
 												<Icon type="md-time" size="14" style="margin-right:5px" />{{ $tools.formatTime(item.startTime) }}</span>
-											<span class="hw-item-status" :style="{ background: (item.progress === 'pending' ? '#0BADD4' : item.progress === 'going' ? '#088951' : '#949594')}">{{ item.progress === 'pending' ? '待发布' : item.progress === 'going' ? '进行中' : '已结束' }}</span>
+											<span class="hw-item-status" :style="{ background: (item.progress === 'pending' ? '#0BADD4' : item.progress === 'going' ? '#088951' : '#949594')}">{{ item.progress === 'pending' ? $t('vote.pending') : item.progress === 'going' ? $t('vote.going') : $t('vote.finish') }}</span>
 										</div>
 									</div>
 								</div>
@@ -48,10 +42,10 @@
 							<!-- 投票基础信息展示 -->
 							<div class="hw-col hw-info-box">
 								<div class="hw-box-header">
-									<span>投票详情</span>
+									<span>{{ $t('vote.voteDetails') }}</span>
 									<div class="hw-box-header-tools">
 										<span class="hw-box-header-tools-tool" v-show="currentVote.progress === 'pending'">
-											<Icon type="md-create" size="18" title="编辑" @click="onEditVote" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" /></span>
+											<Icon type="md-create" size="18" :title="$t('vote.edit')" @click="onEditVote" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" /></span>
 									</div>
 								</div>
 								<vuescroll>
@@ -68,10 +62,10 @@
 							<!-- 投票提交数据 -->
 							<div class="hw-col hw-data-box">
 								<div class="hw-box-header">
-									<span>投票数据</span>
+									<span>{{ $t('vote.voteResult') }}</span>
 									<div class="hw-box-header-tools">
 										<span class="hw-box-header-tools-tool" @click="changeTableView" v-show="tableData.length && currentVote.progress !== 'pending'">
-											<Icon type="md-podium" />{{ isOptionView ? '学生清单视图' : '选项清单视图' }}</span>
+											<Icon type="md-podium" />{{ isOptionView ? $t('vote.optionView') : $t('vote.optionView') }}</span>
 									</div>
 								</div>
 								<div v-if="voteList.length === 0 || hasNewAdd || currentVote.progress === 'pending'">
@@ -143,10 +137,10 @@
 			goToCreate() {
 				let hasNoSaveVote = this.voteList.filter(i => !i.id).length
 				if (hasNoSaveVote) {
-					this.$Message.warning("已存在未保存的投票活动!");
+					this.$Message.warning(this.$t('vote.isExistTip'));
 				} else {
 					let defaultVote = {
-						name: '预设投票名称',
+						name: this.$t('vote.defaultName'),
 						code: this.tabIndex === 0 ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
 						targetClassIds: [],
 						options: [{
@@ -194,10 +188,10 @@
 						}
 						this.isLoadList = false
 					} else {
-						this.$Message.error('获取数据失败')
+						this.$Message.error(this.$t('vote.getDataFailTip'))
 					}
 				}).catch(err => {
-					this.$Message.error('投票活动接口调整中,请稍后再试~')
+					this.$Message.error(this.$t('vote.serverErrorTip'))
 					this.isLoadList = false
 				})
 			},
@@ -230,10 +224,8 @@
 			/** 删除当前投票 */
 			onDeleteVote() {
 				this.$Modal.confirm({
-					title: '删除投票',
-					content: '<p>确认删除该投票活动?</p>',
-					okText: '确认',
-					cancelText: '取消',
+					title: this.$t('vote.deleteVote'),
+					content: this.$t('vote.deleteConfirmTip'),
 					onOk: () => {
 						this.isLoading = true
 						if (this.currentVote.id) {
@@ -244,20 +236,20 @@
 							}).then(res => {
 								if (!res.error) {
 									this.isLoading = false
-									this.$Message.success('操作成功')
+									this.$Message.success(this.$t('vote.deleteSuc'))
 									this.handleTabClick(this.$route.name === 'manageVote' ? 0 : 1)
 								} else {
 									this.isLoading = false
-									this.$Message.error('操作失败')
+									this.$Message.error(this.$t('vote.deleteFail'))
 								}
 							}).catch(err => {
 								this.isLoading = false
-								this.$Message.error('删除失败')
+								this.$Message.error(this.$t('vote.deleteFail'))
 							})
 						} else {
 							this.voteList.splice(this.voteList.indexOf(this.currentVote), 1)
 							this.isLoading = false
-							this.$Message.success('操作成功')
+							this.$Message.success(this.$t('vote.deleteSuc'))
 							if (this.voteList.length) this.onVoteClick(this.voteList[0], 0)
 						}
 					}
@@ -302,7 +294,7 @@
 							records.forEach((item, index) => {
 								arr.push({
 									// option: this.getSimpleText(item.optionValue),
-									option: item.optionKey ? '选项' + (index + 1) : '未投票',
+									option: item.optionKey ? this.$t('vote.option') + (index + 1) : this.$t('vote.noVote'),
 									key: item.optionKey || '',
 									result: item.students
 								})
@@ -311,7 +303,7 @@
 							console.log(this.studentsTable)
 							this.studentsTable.forEach(i => {
 								let matchList = list.filter(j => j.id === i.code)
-								i.name = matchList.length ? matchList[0].name : '暂无数据'
+								i.name = matchList.length ? matchList[0].name : this.$t('vote.noData')
 							})
 							console.log(arr)
 							this.tableData = arr
@@ -320,11 +312,11 @@
 						}
 						this.isLoading = false
 					} else {
-						this.$Message.error('获取数据失败')
+						this.$Message.error(this.$t('vote.getDataFailTip'))
 						this.isLoading = false
 					}
 				}).catch(err => {
-					this.$Message.error('获取班级学生数据异常')
+					this.$Message.error(this.$t('vote.getClassDataFailTip'))
 					this.isLoading = false
 				})
 			},

+ 29 - 18
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -216,17 +216,27 @@ namespace TEAMModelOS.Controllers
         {
             try
             {
-                //ResponseBuilder builder = ResponseBuilder.custom();
-                //if (!requert.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
                 if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-                //if (!requert.TryGetProperty("school", out JsonElement school_code)) return BadRequest();
-                //if (!requert.TryGetProperty("scope", out JsonElement scope)) 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 client = _azureCosmos.GetCosmosClient();
-                List<ExamInfo> examInfo = new List<ExamInfo>();
                 var query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope from c ";
+                if (requert.TryGetProperty("classIds", out JsonElement classIds)) {
+                    List<string> ids = classIds.ToObject<List<string>>();
+                    HashSet<string> strs = new HashSet<string>();
+                    if (ids.Count > 1)
+                    {
+                        foreach (string id in ids) {
+                            strs.Add($"array_contains(c.targetClassIds,'{id}')");
+                        }                           
+                    }
+                    else
+                    {
+                        string ssr = ids.Count > 0 ? ids[0] : "";
+                        strs.Add($"array_contains(c.targetClassIds,'{ssr}')");
+                    }
+                    string ss = string.Join(" or ", strs);
+                    query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope from c where ({ss})";
+                };
+                var client = _azureCosmos.GetCosmosClient();
+                List<ExamInfo> examInfo = new List<ExamInfo>();                
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{code}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
@@ -385,16 +395,17 @@ namespace TEAMModelOS.Controllers
                         }
                     }    */                
                     int newIndex = result.studentIds.IndexOf(studentId.ToString());
-                    /*if (flagCount != standard.Count)
+/*                    if (flagCount != standard.Count)
                     {*/
-/*                    StringBuilder builder = new StringBuilder();
-                    builder.Append(result.examId + "/");
-                    builder.Append(result.subjectId + "/");
-                    builder.Append(studentId);*/
-                        string FileName = result.examId + "/" + result.subjectId + "/" + studentId;
-                        string blob = FileName + "/" + "ans.json";
-                        tasks.Add(_azureStorage.UploadFileByContainer(school.ToString(), ans.ToJsonString(), "exam", FileName + "/" + "ans.json", false));
-                        result.studentAnswers[newIndex].Add(blob);
+                        StringBuilder builder = new StringBuilder();
+                        builder.Append(result.examId).Append("/");
+                        builder.Append(result.subjectId).Append("/");
+                        builder.Append(studentId).Append("/");
+                        builder.Append("ans.json");
+                        /*string FileName = result.examId + "/" + result.subjectId + "/" + studentId;
+                        string blob = FileName + "/" + "ans.json";*/
+                        tasks.Add(_azureStorage.UploadFileByContainer(school.ToString(), ans.ToJsonString(), "exam", builder.ToString(), false));
+                        result.studentAnswers[newIndex].Add(builder.ToString());
                     //}                  
                     for (int i = 0; i < ans.Count; i++)
                     {