Browse Source

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

liqk 4 years ago
parent
commit
a07f01eeaf

+ 7 - 0
TEAMModelOS/ClientApp/src/api/evaluation.js

@@ -0,0 +1,7 @@
+import { fetch, post } from '@/api/http'
+
+export default {
+    getFilterCount: function (data) {        
+        return post('/item/cond-count', data)
+    }
+}

+ 1 - 1
TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue

@@ -182,7 +182,7 @@
 			}
 		},
 		data() {
-			return {
+			return { 
 				examPropScope:null,
 				dataLoading: false,
 				exersicesType: this.$GLOBAL.EXERCISE_TYPES(),

+ 5 - 8
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue

@@ -182,7 +182,7 @@
 			// 提取富文本内容中的文本
 			getSimpleText(html) {
 				var r = /<(?!img|video|audio).*?>/g;
-				return html.replace(r, "");
+				return html.replace(r, "").replace(/&nbsp;/g, ' ');
 			},
 			
 			// 检测是否有空选项
@@ -354,12 +354,7 @@
 					return 0 
 				}
 			},
-			
-			// 提取富文本内容中的文本
-			getSimpleText(html) {
-				var r = /<(?!img|video|audio).*?>/g;
-				return html.replace(r, "");
-			},
+
 			
 			async getQnRecord(item) {
 				return new Promise(async (r, j) => {
@@ -434,7 +429,9 @@
 			isEdit:{
 				handler(n,o){
 					this.editable = n
-				}
+					console.log(n)
+				},
+				immediate:true
 			}
 		}
 	};

+ 1 - 1
TEAMModelOS/ClientApp/src/utils/blobTool.js

@@ -537,7 +537,7 @@ export default class BlobTool {
                                     }], cont)
                                 }
                             }
-                            r('复制结束后')
+                            r(blobItem)
                         }
                     })
                 })

+ 124 - 36
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -10,13 +10,11 @@ import { app } from '@/boot-app.js'
 
 
 export default {
-	
 	/* 根据登录后的用户信息获取blobHOST域名 */
 	getBlobHost(){
 		let s = store.state.user.userProfile.blob_uri || store.state.user.studentProfile.blob_uri || 'https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn'
 		return s.split(s.substring(s.lastIndexOf('/')))[0]
 	},
-	
 	/* 获取试题保存在Blob的JSON文件 */
 	createBlobItem(item){
 		return new Promise((r,j) => {
@@ -53,7 +51,6 @@ export default {
 			r(itemJson)
 		})
 	},
-	
 	/* 获取保存在COSMOS里面的试题格式 */
 	createCosmosItem(item){
 		return new Promise((r,j) => {
@@ -81,7 +78,6 @@ export default {
 			r(cosmosItem)
 		})
 	},
-	
 	/* 生成试卷的index.json文件格式 */
 	createBlobPaper(paper,slides){
 		return new Promise((r,j) => {
@@ -102,7 +98,6 @@ export default {
 			r(paperItem)
 		})
 	},
-	
 	/* 生成试卷保存在cosmos的数据结构 */
 	createCosmosPaper(paper){
 		return new Promise((r,j) => {
@@ -124,7 +119,41 @@ export default {
 			r(paperItem)
 		})
 	},
-	
+	/* 根据醍摩豆ID获取对应用户Blob内部的完整试题 */
+	getFullItemByTmdId(tmdId,blob){
+		return new Promise(async (r,j) => {
+			let privateSas = await this.getBlobPrivateSas(tmdId)
+			let fullPath = this.getBlobHost() +  '/' + tmdId + blob + privateSas
+			let jsonData = JSON.parse(await $tools.getFile(fullPath))
+			// 如果是综合题 那就拿到children里面的小题id集合 去换取小题的blobJSON文件 然后替换children的内容
+			if(jsonData.exercise.children.length && jsonData.exercise.type === 'compose'){
+				let childrenUrls = jsonData.exercise.children.map(i => this.getBlobHost() +  '/' + tmdId + '/item/' + i + '/' + i + '.json' + privateSas)
+				jsonData.exercise.children = await this.getFullChildren(childrenUrls,tmdId)
+			}
+			// 调整渲染试题数据结构
+			jsonData.exercise.question = jsonData.item[0].question
+			jsonData.exercise.blob = fullPath
+			jsonData.exercise.code = tmdId
+			jsonData.exercise.option = jsonData.item[0].option
+			jsonData.exercise.id = jsonData.id
+			jsonData.exercise.pid = jsonData.pid
+			jsonData.exercise = await this.doAddHost(jsonData.exercise,null,tmdId)
+			r(jsonData.exercise)
+		})
+	},
+	/* 根据醍摩豆ID获取对应BLOB个人容器授权信息 */
+	getBlobPrivateSas(tmdId){
+		return new Promise((r,j) => {
+			$api.blob.blobSasR({
+				name:tmdId,
+				role:'teacher'
+			}).then(res => {
+				if(!res.error){
+					r('?' + res.sas)
+				}
+			})
+		})
+	},
 	/* 获取完整的试题数据 */
 	getFullItem(list,examScope){
 		console.log('接受到的examScope',examScope)
@@ -140,24 +169,30 @@ export default {
 						const blobHost = curScope === 'school' ?  JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri :  JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8")).blob_uri
 						// 根据试题的Blob地址 去读取JSON文件
 						let sasString = curScope === 'school' ?  await $tools.getSchoolSas() : await $tools.getPrivateSas()
-						let jsonInfo = list[i].blob.includes('https://') ? await $tools.getFile(list[i].blob + sasString.sas) : await $tools.getFile(blobHost + list[i].blob + sasString.sas)
-						let jsonData = JSON.parse(jsonInfo)
-						// 如果是综合题 那就拿到children里面的小题id集合 去换取小题的blobJSON文件 然后替换children的内容
-						if(jsonData.exercise.children.length && jsonData.exercise.type === 'compose'){
-							let childrenUrls = jsonData.exercise.children.map(i => blobHost + '/item/' + i + '/' + i + '.json' + sasString.sas)
-							jsonData.exercise.children = await this.getFullChildren(childrenUrls,list[i].code)
+						try{
+							let jsonInfo = list[i].blob.includes('https://') ? await $tools.getFile(list[i].blob + sasString.sas) : await $tools.getFile(blobHost + list[i].blob + sasString.sas)
+							let jsonData = JSON.parse(jsonInfo)
+							// 如果是综合题 那就拿到children里面的小题id集合 去换取小题的blobJSON文件 然后替换children的内容
+							if(jsonData.exercise.children.length && jsonData.exercise.type === 'compose'){
+								let childrenUrls = jsonData.exercise.children.map(i => blobHost + '/item/' + i + '/' + i + '.json' + sasString.sas)
+								jsonData.exercise.children = await this.getFullChildren(childrenUrls,list[i].code)
+							}
+							// 调整渲染试题数据结构
+							jsonData.id = list[i].id
+							jsonData.exercise.question = jsonData.item[0].question
+							jsonData.exercise.createTime = list[i].createTime || 0
+							jsonData.exercise.blob = list[i].blob
+							jsonData.exercise.code = list[i].code
+							jsonData.exercise.option = jsonData.item[0].option
+							jsonData.exercise.id = list[i].id
+							jsonData.exercise.pid = jsonData.pid
+							jsonData.exercise = await this.doAddHost(jsonData.exercise)
+							r(jsonData.exercise)
+						}catch(e){
+							console.log(e)
+							this.$Message.error(e)
 						}
-						// 调整渲染试题数据结构
-						jsonData.id = list[i].id
-						jsonData.exercise.question = jsonData.item[0].question
-						jsonData.exercise.createTime = list[i].createTime || 0
-						jsonData.exercise.blob = list[i].blob
-						jsonData.exercise.code = list[i].code
-						jsonData.exercise.option = jsonData.item[0].option
-						jsonData.exercise.id = list[i].id
-						jsonData.exercise.pid = jsonData.pid
-						jsonData.exercise = await this.doAddHost(jsonData.exercise)
-						r(jsonData.exercise)
+						
 					}else{
 						r(null)
 					}
@@ -172,12 +207,11 @@ export default {
 			})
 		})
 	},
-	
-	/* 给富文本添加 */
-	doAddHost(exerciseItem,paperItem){
+	/* 给富文本添加 cntr是防止读取的是其他用户的BLOB */
+	doAddHost(exerciseItem,paperItem,cntr){
 		/* 如果操作的是试卷内的试题 则需要拿试卷的code来作为containerName */
 		let curScope = paperItem ? paperItem.scope : exerciseItem.scope
-		let container = curScope === 'school' ? store.state.userInfo.schoolCode : store.state.userInfo.TEAMModelId
+		let container = cntr || (curScope === 'school' ? store.state.userInfo.schoolCode : store.state.userInfo.TEAMModelId)
 		let isSubjective = exerciseItem.type === 'complete' || exerciseItem.type === 'subjective' || exerciseItem.type === 'compose'
 		let richTextObj = {
 			question: exerciseItem.question,
@@ -245,7 +279,6 @@ export default {
 			})
 		})
 	},
-	
 	/* 保存综合题小题 */
 	saveChildren(children,containerClient){
 		return new Promise((resolve,reject) => {
@@ -289,7 +322,6 @@ export default {
 		})
 		
 	},
-	
 	/* 获取综合题子题的Blob数据 */
 	getFullChildren(urls,code){
 		return new Promise((resolve,reject) => {
@@ -317,7 +349,66 @@ export default {
 			})
 		})
 	},
-	
+	/* 根据醍摩豆ID获取对应用户Blob内部的完整试卷 */
+	getFullPaperByTmdId(tmdId,blob){
+		return new Promise(async (r,j) => {
+			console.log('根据ID获取试题')
+			let privateSas = await this.getBlobPrivateSas(tmdId)
+			let fullPath = this.getBlobHost() +  '/' + tmdId + blob + '/index.json' + privateSas
+			try{
+				let jsonInfo = await $tools.getFile(fullPath)
+				let jsonData = JSON.parse(jsonInfo)
+				// 获取试卷包含的试题数据并包装好
+				if(jsonData.slides && jsonData.slides.length){
+					let promiseArr = []
+					let allItems = []
+					jsonData.item = []
+					const path = this.getBlobHost() +  '/' + tmdId + blob
+					jsonData.slides.forEach(async (item,index) => {
+						promiseArr.push(new Promise(async (resolve,reject) => {
+							try{
+								// 获取题目JSON并且包装成完整试题对象
+								let itemJson = JSON.parse(await $tools.getFile(path + '/' + item.url + privateSas))
+								itemJson.exercise.question = itemJson.item[0].question
+								itemJson.exercise.option = itemJson.item[0].option
+								itemJson.exercise.id = itemJson.id 
+								itemJson.exercise.pid = itemJson.pid 
+								itemJson.exercise.blob = path + '/' + item.url // 添加blob是方便在保存试卷是 refresh 与导入的试题区分开
+								itemJson.exercise.score = item.scoring ? item.scoring.score : 0
+								try{
+									itemJson.exercise = await this.doAddHost(itemJson.exercise,{ name : jsonData.name },tmdId) // 检测试题中的富文本 为有src为相对路径的音视频文件添加blob的HOST地址
+									resolve(itemJson.exercise)
+								}catch(e){
+									reject(e)
+								}
+							}catch(e){
+								reject(e)
+							}
+						}))
+					})
+					
+					Promise.all(promiseArr).then(res => {
+						res.forEach((resItem,resIndex) => {
+							resItem.children = []
+							if(resItem.pid){
+								let pItem = res.filter(i => i.id === resItem.pid)[0]
+								pItem.children.push(resItem)
+								pItem.score = pItem.score + resItem.score
+							}
+						})
+						jsonData.item = res.filter(i => !i.pid)
+						r(jsonData)
+					}).catch(e => {
+						// Message.error('试卷文件读取失败')
+						j(e)
+					})
+				}
+			}catch(e){
+				console.log(e)
+				j(e)
+			}
+		})
+	},
 	/* 获取完整的试卷数据 */
 	getFullPaper(paper,examScope){
 		console.log(paper)
@@ -385,8 +476,6 @@ export default {
 			}
 		})
 	},
-	
-	
 	/* 获取完整的试卷数据 */
 	getStuPaper(paper, examScope) {
 		let curScope = examScope || paper.scope
@@ -458,18 +547,17 @@ export default {
 			}
 		})
 	},
-	
-	// 提取富文本内容中的文本
+	/* 提取富文本内容中的文本 */
 	getSimpleText(html) {
 		var r = /<\/?(img)[^>]*>/gi;
 		return html.replace(r, "");
 	},
-	
+	/* 判断是否为客观题 */
 	getItemType(type){
 		const objective = ['single','multiple','judge']
 		return objective.includes(type)
 	},
-	
+	/* 获取img标签内的src */
 	getImgSrc(richtext) {
 	    let imgList = [];
 	    richtext.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/g, (match, capture) => {

+ 17 - 1
TEAMModelOS/ClientApp/src/utils/public.js

@@ -1,6 +1,9 @@
 import $api from '@/api'
 import store from '@/store'
 import { app } from '@/boot-app.js'
+import {
+	Message
+} from 'view-design'
 /**
  * 校验blob授权是否过期
  * */
@@ -272,7 +275,19 @@ export default {
 			xhr.open('get', url); //url填写后台的接口地址,如果是post,在formData append参数(参考原文地址)
 			// xhr.responseType = 'arraybuffer';
 			xhr.onload = function(e) {
-				resolve(e.currentTarget.response)
+				switch (e.currentTarget.status){
+					case 200:
+						resolve(e.currentTarget.response)
+						break;
+					case 404:
+						Message.error('未访问到资源!')
+						break;
+					case 403:
+						Message.error('授权异常,无法访问!')
+						break;		
+					default:
+						break;
+				}
 			};
 			xhr.send(formData);
 		})
@@ -423,6 +438,7 @@ export default {
 	 * 获取单个文件授权
 	 */
 	getFileSas(param) {
+		console.log('获取单个文件授权',param)
 		return new Promise((r, j) => {
 			$api.blob.urlSasR({
 				url: param

+ 22 - 19
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -1,7 +1,11 @@
 <template>
 	<div class="pl-container" ref="plContainer">
 		<!-- 条件筛选部分 -->
-		<BaseFilter ref="baseFilter" @onChange="onFilterChange" :filterCounts="filterCounts" :isFilterPaper="isFilterPaper"  v-if="!isPreview"></BaseFilter>
+		<BaseFilter ref="baseFilter" @onChange="onFilterChange" :filterCounts="filterCounts"
+		 :isFilterPaper="isFilterPaper"
+		 @onSearchChange="onSearchChange"
+		 @onCloseSearch="onCloseSearch"
+		   v-if="!isPreview"></BaseFilter>
 
 		<!-- 空数据展示 -->
 		<div v-if="paperList.length === 0" class="no-data-text">
@@ -142,6 +146,7 @@
 				filterParams: {},
 				findCountParams: {},
 				originList: [],
+				originRes:[],
 				schoolInfo: {},
 				filterSort: 'createTime',
 				evaluationInfo: null,
@@ -277,6 +282,7 @@
 					this.getItemsCount(list,filterKey)
 					this.paperList = list
 					this.originList = list
+					this.originRes = JSON.parse(JSON.stringify(list))
 					this.totalNum = list.length
 					this.pageChange(1)
 					setTimeout(() => {
@@ -291,6 +297,20 @@
 				})
 			},
 			
+			/* 搜索词汇发生变化 */
+			onSearchChange(val) {
+				this.originList = this.originRes.filter(i => i.name.indexOf(val) > -1)
+				this.totalNum = this.originList.length
+				this.pageChange(1)
+			},
+			/* 关闭搜索 */
+			onCloseSearch() {
+				this.$refs.baseFilter.searchVal = ''
+				this.originList = JSON.parse(JSON.stringify(this.originRes))
+				this.totalNum = this.originList.length
+				this.pageChange(1)
+			},
+			
 			/* 获取所有学段下的试题总数 */
 			getPeriodCount(papers){
 				let periodIdArr = this.periodList.map(i => i.id)
@@ -349,24 +369,7 @@
 				console.log('要下载的试卷', fullPaperJson)
 			},
 			
-			// async renderAnswerSheet(paper){
-			// 	this.dataLoading = true
-			// 	try{
-			// 		let fullPaperJson = this.fullPaperJson.id === paper.id ? this.fullPaperJson : await this.$evTools.getFullPaper(paper)
-			// 		// this.isShowSheet = true
-			// 		this.dataLoading = false
-			// 		this.$router.push({
-			// 			name: 'answerSheet',
-			// 			params: {
-			// 				paper: fullPaperJson
-			// 			}
-			// 		})
-			// 	}catch(e){
-			// 		this.$Message.error(this.$t('evaluation.paperList.paperErrorTip'))
-			// 		this.dataLoading = false
-			// 	}
-				
-			// },
+
 
 			/**
 			 * 删除试卷

+ 19 - 103
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseFilter.vue

@@ -38,6 +38,8 @@
 					<Icon type="md-arrow-round-down" />
 				</Radio>
 			</RadioGroup>
+			<!-- 试卷列表的搜索功能 -->
+			<Input v-model="searchVal" clearable  placeholder="输入试卷名称进行搜索..." style="width: 300px" @on-click="onCloseSearch" @on-change="onSearchChange"/>
 		</div>
 	</div>
 </template>
@@ -67,6 +69,7 @@
 				userId: "",
 				schoolCode: "",
 				schoolInfo: {},
+				searchVal:'',
 				isShowSchoolBank: false,
 				isShowUploadList: false,
 				exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
@@ -257,6 +260,15 @@
 				});
 				return list;
 			},
+			
+			/* 搜索词汇发生变化 */
+			onSearchChange() {
+				this.$emit('onSearchChange',this.searchVal)
+			},
+			/* 关闭搜索 */
+			onCloseSearch() {
+				this.$emit('onCloseSearch')
+			},
 		},
 
 		mounted() {},
@@ -275,109 +287,13 @@
 	};
 </script>
 
-<style scoped>
-	.filter-wrap {
-		width: 100%;
-		padding: 20px;
-		background: #fff;
-	}
-
-	.filter-wrap .filter-item:first-child {
-		margin-top: 0px;
-	}
-
-	.filter-wrap .filter-item {
-		margin-top: 10px;
-		display: flex;
-	}
-
-	.filter-wrap .filter-title {
-		font-size: 16px;
-		font-weight: bold;
-		margin-right: 10px;
-		min-width: 40px;
-	}
-
-	.filter-wrap .ivu-radio-group {
-		padding-bottom: 4px;
+<style>
+	.filter-wrap .filter-item .ivu-input{
+		border-radius: 100px;
+		padding: 4px 12px;
 	}
-
-	.filter-wrap .ivu-radio-wrapper {
-		padding: 0 10px;
-		margin-left: 15px;
-		height: 28px;
-		line-height: 28px;
-		box-shadow: none !important;
-		border: none !important;
-		font-size: 14px;
-		border-radius: 0 !important;
-	}
-
-	.filter-wrap .ivu-radio-wrapper .ivu-icon {
-		margin-bottom: 2px;
-	}
-
-	.filter-wrap .ivu-radio-wrapper:after,
-	.ivu-radio-group-button .ivu-radio-wrapper:before {
-		content: none;
-	}
-
-	.filter-wrap .ivu-radio-group-item {
-		border-radius: 5px !important;
-	}
-
-	.filter-wrap .ivu-radio-wrapper-checked {
-		background: rgb(16, 171, 231);
-		box-shadow: none !important;
-		color: white;
-	}
-
-	.filter-wrap .ivu-radio-group-button .ivu-radio-wrapper-checked:hover {
-		color: #fff !important;
-	}
-
-	.filter-wrap .ivu-checkbox-group {
-		padding-bottom: 4px;
-		display: inline-block;
-	}
-
-	.filter-wrap .ivu-checkbox-inner,
-	.filter-wrap .ivu-checkbox-checked,
-	.filter-wrap .ivu-checkbox {
-		display: none;
-	}
-
-	.filter-wrap .ivu-checkbox-wrapper {
-		padding: 0 10px;
-		margin-left: 15px;
-		height: 28px;
-		line-height: 28px;
-		box-shadow: none !important;
-		border: none !important;
-		font-size: 14px;
-		border-radius: 0 !important;
-	}
-
-	.filter-wrap .ivu-checkbox-wrapper .ivu-icon {
-		margin-bottom: 2px;
-	}
-
-	.filter-wrap .ivu-checkbox-wrapper:after,
-	.ivu-checkbox-group-button .ivu-checkbox-wrapper:before {
-		content: none;
-	}
-
-	.filter-wrap .ivu-checkbox-group-item {
-		border-radius: 5px !important;
-	}
-
-	.filter-wrap .ivu-checkbox-wrapper-checked {
-		background: rgb(16, 171, 231);
-		box-shadow: none !important;
-		color: white;
-	}
-
-	.filter-wrap .ivu-checkbox-group-button .ivu-checkbox-wrapper-checked:hover {
-		color: #fff !important;
+	
+	.filter-wrap .filter-item .ivu-input-wrapper{
+		margin-left: 30px;
 	}
 </style>

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

@@ -44,7 +44,7 @@
       },
 	  // 判断容器滚动距离
 	  handleScroll(vertical, horizontal, nativeEvent) {
-	  	console.log(vertical.scrollTop)
+	  	// console.log(vertical.scrollTop)
 	  },
 
       

File diff suppressed because it is too large
+ 424 - 186
TEAMModelOS/ClientApp/src/view/syllabus/Syllabus.vue