Browse Source

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

OnePsycho 4 years ago
parent
commit
8bb2a0cf3b

+ 9 - 8
TEAMModelFunction/TriggerVote.cs

@@ -8,6 +8,7 @@ using System.Text.Json;
 using System.Threading.Tasks;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos;
 
@@ -70,10 +71,11 @@ namespace TEAMModelFunction
                                 endTime = vote.endTime,
                                 scode = vote.code,
                                 scope = vote.scope,
-                                classes = vote.classes,
-                                tmdids = vote.tmdids,
+                                classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
+                                tmdids = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string> { "" },
                                 progress= "going",
-                                owner =vote.owner
+                                owner =vote.owner,
+                                subjects = new List<string> { "" }
                             };
                             await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
                         }
@@ -90,9 +92,10 @@ namespace TEAMModelFunction
                                 scode = vote.code,
                                 scope = vote.scope,
                                 progress = "going",
-                                classes = vote.classes,
-                                owner = vote.owner
-                                // tmdids = vote.tmdids
+                                classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
+                                owner = vote.owner,
+                                tmdids = new List<string> { "" },
+                                subjects= new List<string> { ""}
                             };
                             await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
                         }
@@ -155,8 +158,6 @@ namespace TEAMModelFunction
                         {
                             await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Vote>(vote, vote.id, new Azure.Cosmos.PartitionKey(vote.code));
                         }
-
-
                         //更新结束状态
                         if (vote.scope == "school" || vote.scope == "teacher")
                         {

+ 3 - 3
TEAMModelOS.SDK/Models/Cosmos/Common/ActivityData.cs

@@ -80,9 +80,9 @@ namespace TEAMModelOS.SDK.Models.Cosmos
         /// private/school/teacher
         /// </summary>
         public string scope { get; set; }
-        public List<string> classes { get; set; }
-        public List<string> tmdids { get; set; }
+        public List<string> classes { get; set; } = new List<string> { "" };
+        public List<string> tmdids { get; set; } = new List<string> { "" };
         public string owner { get; set; }
-        public List<string> subjects { get; set; }
+        public List<string> subjects { get; set; } = new List<string> { "" };
     }
 }

+ 1 - 1
TEAMModelOS/ClientApp/src/api/knowledge.js

@@ -6,7 +6,7 @@ export default {
     },
     // 批量更新保存知识点知识块
     SaveOrUpdateKnowledge: function(data) {
-        return post('/knowledge/upsert-all', data)
+        return post('/knowledges/upsert', data)
     },
     SaveOrUpdateSchoolPoint: function(data) {
         return post('/knowledge/SaveOrUpdateAllSchoolPoint', data)

+ 3 - 3
TEAMModelOS/ClientApp/src/common/UploadModal.vue

@@ -1,7 +1,7 @@
 <template>
     <Modal v-model="uploadStatus" :ok-text="textLoading ? $t('updModal.uploading') : isComplete ? $t('updModal.complete'):$t('updModal.comfirmUpd')" :cancel-text="$t('updModal.cancelUpd')" :title="$t('teachContent.btnUpload')" class="upload-modal dark-iview-modal" width="660" :mask-closable="false" :closable="false" @on-ok="modalOk" @on-cancel="modalCancel" :loading="modalLoading">
         <div class="upload-file-box">
-            <Upload type="drag" action="" :show-upload-list="false" multiple :before-upload="customUpload" class="upload-wrap" :disabled="textLoading" >
+            <Upload type="drag" action="" :show-upload-list="false" multiple :before-upload="customUpload" class="upload-wrap" :disabled="textLoading">
                 <Icon class="upload-icon" custom="iconfont icon-upload" v-show="!uploadedList.length" />
                 <p class="upload-text" :style="{marginTop: uploadedList.length ? '25px':'0px'}">
                     <Icon size="24" style="font-size: 22px;vertical-align: baseline;margin-right: 5px;" custom="iconfont icon-upload" v-show="uploadedList.length" />
@@ -294,7 +294,7 @@ export default {
                                 scope: this.routerScope
                             }).then(
                                 parseRes => {
-                                    this.containerClient.deleteBlob(delBlob)
+                                    this.containerClient.deleteBlob(delBlob, res.size)
                                     this.uploadedList[index].blob = `/res/${res.name}/index.json`
                                     this.uploadedList[index].extension = 'HTEX'
                                     this.uploadedList[index].name = res.name.replace('pptx', 'HTEX').replace('PPTX', 'HTEX')
@@ -349,7 +349,7 @@ export default {
                 this.textLoading = false
                 this.isComplete = true
                 this.modalLoading = false
-                
+
             }
         },
         //处理图片缩略图

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

@@ -267,6 +267,12 @@ export const routes = [
 				name: 'myCourse',
 				component: resolve => require(['@/view/newcourse/MyCourse.vue'], resolve)
 			},
+			//我的课程查看评测详细数据
+			{
+				path: 'EvDetail',
+				name: 'EvDetail',
+				component: resolve => require(['@/view/newcourse/EvDetail.vue'], resolve)
+			},
 			{
 				path: 'CourseTable',
 				name: 'CourseTable',

+ 44 - 34
TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.less

@@ -23,6 +23,18 @@
         padding: 0 20px;
         z-index: 1;
 
+        .school-tools {
+            font-size: var(--font-size-normal);
+            margin-right: 30px;
+            margin-top: 13px;
+            float: right;
+        }
+
+        .school-tools .ivu-icon {
+            font-size: @font-size-large;
+            margin-right: 5px;
+            vertical-align: text-top;
+        }
 
         span {
             margin-right: 10px;
@@ -45,17 +57,17 @@
         height: calc(100% - 70px);
         width: 100%;
         .fl-row-center;
-		
-		.drag-active{
-			 background-color: rgba(149, 149, 149, 0.2);
-		}
-		
-		.gl-new-area{
-			text-align: center;
-			color:@primary-textColor;
-			background: #3e3e3e;
-			padding: 35px 0 !important;
-		}
+
+        .drag-active {
+            background-color: rgba(149, 149, 149, 0.2);
+        }
+
+        .gl-new-area {
+            text-align: center;
+            color: @primary-textColor;
+            background: #3e3e3e;
+            padding: 35px 0 !important;
+        }
 
         .ns-col {
             position: relative;
@@ -133,11 +145,12 @@
                     overflow: hidden;
                     text-overflow: ellipsis;
                     white-space: nowrap;
-					pointer-events: none;
+                    pointer-events: none;
                 }
 
                 .gl-item-info {
-					pointer-events: none;
+                    pointer-events: none;
+
                     span {
                         margin-top: 15px
                     }
@@ -199,7 +212,7 @@
                 background: #0f9272;
                 border: none;
                 color: #fff;
-                margin-left:20px;
+                margin-left: 20px;
             }
 
             .points-wrap {
@@ -208,7 +221,7 @@
                 padding-top: 20px;
 
                 .point-item {
-					position:relative;
+                    position: relative;
                     margin: 10px;
                     padding: 5px 30px;
                     border-radius: 50px;
@@ -219,7 +232,6 @@
                     &-tools {
                         margin-left: 10px;
                         // display: none;
-
                         .btn-delete {
                             margin-left: 4px;
                         }
@@ -229,24 +241,22 @@
                 .point-item-active {
                     background: #0f9272 !important;
                 }
-				
-				// .block-point-item:before{
-				// 	content:'';
-				// 	display:block;
-				// 	width:8px;
-				// 	height:14px;
-				// 	border-right:#fff solid 2px;
-				// 	border-bottom:#fff solid 2px;
-				// 	transform:rotate(35deg);
-				// 	position:absolute;
-				// 	bottom:12px;
-				// 	left:12px;
-				// 	z-index:2;
-				// }
-				
-				.block-point-item{
-					background-color: #006988;
-				}
+                // .block-point-item:before{
+                // 	content:'';
+                // 	display:block;
+                // 	width:8px;
+                // 	height:14px;
+                // 	border-right:#fff solid 2px;
+                // 	border-bottom:#fff solid 2px;
+                // 	transform:rotate(35deg);
+                // 	position:absolute;
+                // 	bottom:12px;
+                // 	left:12px;
+                // 	z-index:2;
+                // }
+                .block-point-item {
+                    background-color: #006988;
+                }
 
                 .point-item:hover {
                     .point-item-tools {

+ 159 - 100
TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue

@@ -13,7 +13,7 @@
 					<Option v-for="(item,index) in periodList" :value="index" :key="index">{{ item.name }}</Option>
 				</Select>
 			</div>
-			<Button v-if="$access.ability('admin','schoolSetting-upd').validateAll" class="school-tools" :loading="isLoading"  icon="ios-albums-outline">{{$t('schoolBaseInfo.saveInfo')}}</Button>
+			<Button v-if="$access.ability('admin','schoolSetting-upd').validateAll" class="school-tools" :disabled="!updated"  icon="ios-albums-outline" @click="saveData()">{{$t('schoolBaseInfo.saveInfo')}}</Button>
 		</div>
 		<!-- 主体内容 -->
 		<div class="new-syllabus-content">
@@ -249,7 +249,9 @@
 				checkedPointList: [],
 				curBlockPoints: [],
 				curDragPoint: null,
-				pointIndex: null
+				pointIndex: null,
+				pointDatas: {},
+                updated:false
 			}
 		},
 		components: {
@@ -345,7 +347,6 @@
 			/* 保存最新知识块内容 */
 			savePointAndBlock(pointItem) {
 				return new Promise((r, j) => {
-					console.log(pointItem)
 					pointItem.code = pointItem.code.replace('Knowledge-', '')
 					this.$api.knowledge.SaveOrUpdateKnowledge([pointItem]).then(res => {
 						if (!res.error && res.knowledges) {
@@ -368,7 +369,6 @@
 			initSchoolData() {
 				this.$store.dispatch('user/getSchoolProfile').then(res => {
 					let schoolBaseInfo = res.school_base
-					console.log('学校基本数据', schoolBaseInfo)
 					if (schoolBaseInfo) {
 						this.schoolInfo = schoolBaseInfo
 						this.originSchoolData = schoolBaseInfo // 默认选择第一个
@@ -387,33 +387,35 @@
 
 			// 获取当前册别数量(每次都获取最新的数据)
 			initBlockCount() {
-				 if (this.blockCounts.length) {
-				 	this.schoolBlockCount = this.blockCounts[this.currentPeriodIndex].map(i => i[0])
-				 	this.privateBlockCount = this.blockCounts[this.currentPeriodIndex].map(i => i[1])
-				 } else {
-				this.$api.syllabus.FindBlockCount({
-					code: this.$store.state.userInfo.schoolCode
-				}).then(res => {
-					if (!res.error) {
-						this.$nextTick(() => {
-							this.blockCounts = res
-							this.schoolBlockCount = res[this.currentPeriodIndex || 0].map(i => i[0])
-							this.privateBlockCount = res[this.currentPeriodIndex || 0].map(i => i[1])
-						})
-					} else {
-						this.$Message.warning('获取数据失败')
-					}
-				})
-				 }
+				if (this.blockCounts.length) {
+					this.schoolBlockCount = this.blockCounts[this.currentPeriodIndex].map(i => i[0])
+					this.privateBlockCount = this.blockCounts[this.currentPeriodIndex].map(i => i[1])
+				} else {
+					this.$api.syllabus.FindBlockCount({
+						code: this.$store.state.userInfo.schoolCode
+					}).then(res => {
+						if (!res.error) {
+							this.$nextTick(() => {
+								this.blockCounts = res
+								this.schoolBlockCount = res[this.currentPeriodIndex || 0].map(i => i[0])
+								this.privateBlockCount = res[this.currentPeriodIndex || 0].map(i => i[1])
+							})
+						} else {
+							this.$Message.warning('获取数据失败')
+						}
+					})
+				}
 			},
 
 			// 根据学科获取所有知识块信息
 			getBlocksData() {
 				let that = this
+				that.pointDatas = []
 				let params = JSON.parse(JSON.stringify(this.currentParams))
 				params.type = 0
 				this.$api.knowledge.GetSchoolPoints(params).then(res => {
 					if (res.length) {
+						that.pointDatas = res
 						let list = res[0].blocks
 						this.blockList = list
 						this.originBlockList = JSON.parse(JSON.stringify(list))
@@ -433,15 +435,12 @@
 			// 根据学科获取学科下所有知识点数据
 			getPointsData() {
 				let that = this
-				console.log('知识点数据', this.currentParams)
 				//this.currentParams.type = 1
 				this.$api.knowledge.GetSchoolPoints(this.currentParams).then(res => {
-					console.log(res)
 					if (res.length) {
+
 						this.pointList = res[0].points
-						console.log('456456456', this.pointList)
 						this.originPointList = JSON.parse(JSON.stringify(res[0].points))
-						console.log(this.originPointList)
 						setTimeout(function () {
 							that.isLoadPoints = false
 						}, 800)
@@ -508,7 +507,6 @@
 
 			// 学科点击事件
 			handleSubjectTap(index) {
-				console.log(index)
 				this.checkedPointList = []
 				this.blockList = []
 				this.originBlockList = []
@@ -530,9 +528,6 @@
 
 			// 知识块点击事件
 			handleBlockTap(index, item) {
-				console.log(index)
-				console.log(item)
-				console.log(this.activeBlockIndex)
 				if (index === this.activeBlockIndex) {
 					this.activeBlockIndex = null
 					this.curBlockPoints = []
@@ -553,7 +548,6 @@
 			// 把当前知识块的知识点排到最前面
 			toStartPosition(points) {
 				points.forEach(i => {
-					console.log(i)
 					let pointIds = this.pointList.map(i => i)
 					if (pointIds.includes(i)) {
 						let index = pointIds.indexOf(i)
@@ -570,10 +564,10 @@
 				if (this.isEditBlock) {
 					let code = this.blockList.findIndex(item => item.name.indexOf(this.editBlock.name) > -1)
 					this.blockList[code].name = val.name
-                    this.originBlockList = JSON.parse(JSON.stringify(this.blockList))
 				} else {
-                    this.blockList.push(val)
-				}
+					this.blockList.push(val)
+				} 
+				this.originBlockList = [...this.blockList]
 				this.editBlock = {}
 				this.isAddBlock = false // 关闭窗口
 				this.blockCounts = []
@@ -586,12 +580,28 @@
 				let that = this
 				this.isLoadPoints = true
 				if (this.isEditPoint) {
-					this.pointList[this.editPointIndex] = val
+					this.pointList[this.editPointIndex] = val.name
+                    this.actionPoint(this.currentPoint, val)
+					//if (this.findPointIndex(this.currentPoint) > 0) {
+					//	this.$Modal.confirm({
+					//		title: '提示',
+					//		content: '<p>当前知识点已关联相关知识块,是否继续修改?</p>',
+					//		okText: '确认',
+					//		cancelText: '取消',
+					//		onOk: () => {
+					//			this.isLoading = true
+					//			setTimeout(() => {
+					//				that.isLoading = false
+					//				that.$Message.success('操作成功!')
+					//			}, 500)
+					//		}
+					//	})
+					//}
 				} else {
 					if (!this.isShowPoints) this.currentBlock.points.push(val.id)
 					this.pointList.push(val.name)
 				}
-				this.$Message.success('操作成功!')
+				this.originPointList = [...this.pointList]
 				this.isAddPoint = false // 关闭窗口
 				this.isEditPoint = false
 				setTimeout(function () {
@@ -599,7 +609,36 @@
 					that.initBlockCount()
 				}, 400)
 			},
+			//查询当前关联的知识块数据
+			findPointIndex(datas) {
+				let data = 0
+				for (let item of this.blockList) {
+					if (this.isEditPoint) {
+						let code = item.points.findIndex(items => items.indexOf(datas) > -1)
+						if (code !== -1) {
+							data++
+						}
+					}
+				}
+				return data
+			},
+
+			//处理关联的知识点数据(修改和删除)
+			actionPoint(data, val) {
+				if (data) {
+					for (let item of this.blockList) {
+						if (this.isEditPoint) {
+							let code = item.points.findIndex(items => items.indexOf(data) > -1)
+							if (code !== -1) {
+								item.points[code] = val.name
+							}
+						} else {
+							item.points.splice(item.points.findIndex(item => item === data), 1)
+						}
+					}
 
+				}
+			},
 			// 删除知识块事件
 			onDeleteBlock(data) {
 				this.$Modal.confirm({
@@ -610,19 +649,19 @@
 					onOk: () => {
 						let that = this
 						this.isLoading = true
-                        if (this.blockList.indexOf(data) !== -1) {
-								this.blockList.splice(this.blockList.indexOf(data), 1)
-								this.originBlockList.splice(this.originBlockList.indexOf(data), 1)
-								this.handleBlockTap(0, this.blockList.length ? this.blockList[0] : null)
-								setTimeout(() => {
-									that.blockCounts = []
-									that.initBlockCount()
-									that.isLoading = false
-									that.$Message.success('删除成功')
-								}, 1000)
-							} else {
-								this.$Message.success('删除失败')
-							}
+						if (this.blockList.indexOf(data) !== -1) {
+							this.blockList.splice(this.blockList.indexOf(data), 1)
+							this.originBlockList.splice(this.originBlockList.indexOf(data), 1)
+							this.handleBlockTap(0, this.blockList.length ? this.blockList[0] : null)
+							setTimeout(() => {
+								that.blockCounts = []
+								that.initBlockCount()
+								that.isLoading = false
+								that.$Message.success('删除成功')
+							}, 1000)
+						} else {
+							this.$Message.success('删除失败')
+						}
 					}
 				})
 			},
@@ -636,23 +675,12 @@
 					cancelText: '取消',
 					onOk: () => {
 						this.isLoadPoints = true
-						this.$api.knowledge.DeleteSchoolPoint({
-							code: data.code.replace('Knowledge-', ''),
-							id: data.id
-						}).then(res => {
-							if (!res.error) {
-								this.$Message.success('删除成功')
-								this.originPointList.splice(this.originPointList.indexOf(data), 1)
-								if (!this.isShowPoints) this.currentBlock.points.splice(this.currentBlock.points.indexOf(data.id), 1)
-								this.pageChange(this.currentPage)
-								this.isLoadPoints = false
-							} else {
-								this.$Message.warning('删除失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-							}
-						}).catch(err => {
-							console.log(err)
-							this.$Message.warning('删除失败')
-						})
+                        this.$Message.success('删除成功')
+                        this.pointList.splice(this.pointList.indexOf(data), 1)
+                        if (!this.isShowPoints) this.currentBlock.points.splice(this.currentBlock.points.indexOf(data), 1)
+						this.actionPoint(data, 0)
+						this.originPointList = [...this.pointList]
+                        this.isLoadPoints = false
 					}
 				})
 			},
@@ -661,20 +689,16 @@
 			onRemovePoint(data) {
 				this.$Modal.confirm({
 					title: '提示',
-					content: `确定将知识点 ${data.name} 从知识块 ${this.currentBlock.name} 中移除?`,
+					content: `确定将知识点 ${data} 从知识块 ${this.currentBlock.name} 中移除?`,
 					okText: '确认',
 					cancelText: '取消',
 					onOk: () => {
-						if (this.currentBlock.points.includes(data.id)) {
-							let that = this
-							this.currentBlock.points.splice(this.currentBlock.points.indexOf(data.id), 1)
-							this.savePointAndBlock(this.currentBlock).then(r => {
-								this.curBlockPoints = []
-								this.currentBlock = null
-								this.activeBlockIndex = null
-								that.handleSubjectTap(that.currentSubjectIndex)
-							})
-
+						if (this.currentBlock.points.includes(data)) {
+							this.currentBlock.points.splice(this.currentBlock.points.indexOf(data), 1)
+							this.originBlockList = [...this.blockList]
+								//this.curBlockPoints = []
+								//this.currentBlock = null
+								//this.activeBlockIndex = null
 						} else {
 							this.$Message.error('移除失败')
 						}
@@ -686,12 +710,7 @@
 			onEditBlock(data) {
 				this.isAddBlock = true // 打开新增窗口
 				this.isEditBlock = true // 设置成编辑状态
-				console.log('121321313131')
-				console.log(this.blockList)
-				console.log(data)
 				this.editBlock = this.blockList[data]
-                console.log(this.editBlock)
-
 			},
 
 			// 新增知识块事件
@@ -713,9 +732,6 @@
 
 			// 编辑知识点事件
 			onEditPoint(data, index) {
-				console.log('知识点数据')
-				console.log(data, index)
-				console.log(this.currentBlock)
 				this.isAddPoint = true // 打开新增窗口
 				this.isEditPoint = true // 设置成编辑状态
 				this.currentPoint = data
@@ -725,11 +741,6 @@
 
 			// 知识点点击事件
 			onPointCheck(item, index) {
-				console.log('000000000000000.000000000000000000')
-				console.log(item)
-				console.log(index)
-				console.log(this.checkedPointList)
-				console.log(this.isShowPoints)
 				if (this.isShowPoints) {
 					let list = this.checkedPointList
 					let isExistIndex = list.indexOf(item)
@@ -750,24 +761,23 @@
 			onComposeFinish(val) {
 				if (val) {
 					let code = this.blockList.findIndex(item => item.name.indexOf(val.name) > -1)
-					console.log(code)
 					if (code == -1) {
-                    this.blockList.push(val)
+						this.blockList.push(val)
 					} else {
-					this.blockList[code].points = val.points
+						this.blockList[code].points = val.points
 					}
-                    this.originBlockList = JSON.parse(JSON.stringify(this.blockList))
+					this.originBlockList = [...this.blockList]
+					console.log(this.originBlockList)
 					this.isComposeBlock = false
 					this.checkedPointList = []
 					this.activeBlockIndex = null
 					this.curBlockPoints = []
-					//this.handleSubjectTap(this.currentSubjectIndex)
 					this.$Message.success('操作成功')
 					this.initBlockCount()
 				}
 
 			},
-			 
+
 			// 搜索知识块输入框onchange事件
 			onSearchBlockChange() {
 				this.blockList = this.originBlockList.filter(item => item.name.indexOf(this.searchBlock) > -1)
@@ -818,7 +828,26 @@
 					this.pageChange(page - 1)
 				}
 			},
-
+			//保存修改后的数据
+			saveData() {
+				console.log(this.pointDatas)
+                if (this.updated) {
+                    let params = {}
+                    params = this.pointDatas[0]
+                    params.points = [...this.originPointList]
+                    params.blocks = [...this.originBlockList]
+                    this.$api.knowledge.SaveOrUpdateKnowledge(params).then(res => {
+                        if (res) {
+                            this.$Message.success('保存数据成功')
+                        } else {
+                            this.$Message.warning('保存数据失败')
+                        }
+                    }).catch(err => {
+                        this.$Message.error('数据保存失败')
+                        this.isLoadBlocks = false
+                    })
+                }
+            },
 			// 切换每页显示页数
 			pageSizeChange(val) {
 				this.pageSize = val
@@ -828,9 +857,39 @@
 
 		},
 		mounted() {
-
-
 		},
+		watch: {
+            originBlockList: {
+				handler(newValue, oldValue) {
+					console.log(newValue)
+					this.updated = true
+                }
+			},
+            originPointList: {
+				handler(newValue, oldValue) {
+					console.log(newValue)
+					this.updated = true
+                }
+            },
+		},
+        beforeRouteLeave(to, from, next) {
+            if (this.updated) {
+                let config = {
+                    title: this.$t('schoolBaseInfo.saveWarning'),
+                    content: this.$t('schoolBaseInfo.ssTips8'),
+                    okText: this.$t('schoolBaseInfo.leaveText'),
+                    onOk: () => {
+                        next()
+                    },
+                    onCancel: () => {
+                        next(false)
+                    }
+                }
+                this.$Modal.confirm(config)
+            } else {
+                next()
+            }
+        },
 		computed: {
 			dragOptions() {
 				return {
@@ -854,7 +913,7 @@
 	}
 </script>
 
-<style>
+<style >
 	.new-syllabus-header .ivu-select-single .ivu-select-selection,
 	.funnel-box .ivu-select-single .ivu-select-selection {
 		background: transparent;

+ 3 - 13
TEAMModelOS/ClientApp/src/view/knowledge-point/index/operation/AddPoint.vue

@@ -51,21 +51,11 @@
                     this.uuid = Math.uuid()
 					console.log(this.schoolInfos)
                     let params = {
-                        type: 1,
                         name: newName,
-                        alias: newName,
-                        subjectId: editPointItem ? editPointItem.subjectId : this.schoolInfos.subjectId,
-                        code: this.addPointType === 'school' ? this.schoolInfos.schoolCode : this.$store.state.userInfo.TEAMModelID, // //判断当前添加为校本或者个人知识点
-                        order: 706,
-                        status: 1,
-                        knowledgeId: editPointItem ? editPointItem.knowledgeId : this.uuid,
-                        periodId: editPointItem ? editPointItem.periodId : this.schoolInfos.period,
-                        source: 1,
-                        points: this.blockDatas ? [this.blockDatas.id] : [],
-                        id: editPointItem ? editPointItem.id : null,
                     }
-					console.log(params)
-                    this.savePointAndBlock(params)
+                    console.log(params)
+                    this.$emit('addFinish', params)
+                        this.isLoading = false
                 }
             },
 

+ 0 - 11
TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue

@@ -64,15 +64,6 @@
                     <span :class="curBarIndex == 1 ? 'evalustion-bar-item line-bottom-active line-bottom':'evalustion-bar-item line-bottom'" @click="selectBar(1)">
                         {{$t('learnActivity.mgtScEv.tab2')}}
                     </span>
-                    <!-- <div style="float:right;" v-show="evaListShow[curEvaIndex] && evaListShow[curEvaIndex].progress == 'going'"> -->
-                    <!-- <div style="float:right;">
-                        <Tooltip :content="$t('learnActivity.mgtScEv.autoTips1')" :max-width="240">
-                            <Button type="success" size="small" :loading="answerLoading" class="mock-stu-answer" @click="mockAnswer">{{$t('learnActivity.mgtScEv.autoAnswer')}}</Button>
-                        </Tooltip>
-                        <Tooltip :content="$t('learnActivity.mgtScEv.autoTips2')" :max-width="240">
-                            <Button type="warning" size="small" :loading="scoreLoading" class="mock-tea-scoring" @click="mockScoring">{{$t('learnActivity.mgtScEv.autoScore')}}</Button>
-                        </Tooltip>
-                    </div> -->
                 </div>
                 <!--试卷信息-->
                 <div :class="curBarIndex == 1 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="curBarIndex == 1">
@@ -92,7 +83,6 @@
                 <div :class="curBarIndex == 0 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="curBarIndex == 0">
                     <Scoring :examInfo="examDetaiInfo" ref="score-box"></Scoring>
                 </div>
-
             </div>
         </Split>
     </div>
@@ -332,7 +322,6 @@ export default {
             var D = date.getDate() + ' '
             return Y + M + D;
         },
-
         //查询评测列表
         findEvaluation() {
             let requestData = {

+ 113 - 0
TEAMModelOS/ClientApp/src/view/newcourse/EvDetail.less

@@ -0,0 +1,113 @@
+@first-bgColor: #141414;
+@second-bgColor: #1b1b1b;
+@third-bgColor: #222222;
+@borderColor: #424242;
+@primary-textColor: #fff; //文本主颜色
+@second-textColor: #a5a5a5; //文本副级颜色
+@primary-fontSize: 14px;
+@second-fontSize: 16px;
+.evaluation-detail-wrap {
+    /*width: ~"calc(100% - 400px)";*/
+    width:100%;
+    height: 100%;
+    padding-left: 15px;
+}
+.evaluation-detail-wrap {
+
+    .evaluation-detail-bar {
+        width: 100%;
+        height: 45px;
+        line-height: 45px;
+        border-bottom: 1px solid @borderColor;
+        color: @second-textColor;
+
+        .edit-evaluation {
+            float: right;
+            margin-right: 45px;
+            display: inline-block;
+            cursor: pointer;
+            color: white;
+        }
+
+        .edit-evaluation:hover {
+            color: aqua;
+        }
+
+        .evalustion-bar-item {
+            margin-right: 30px;
+            display: inline-block;
+            cursor: pointer;
+            line-height: 38px;
+        }
+
+        .evalustion-bar-item-active {
+            color: white;
+            border-bottom: 2px solid white;
+        }
+    }
+
+    .evaluation-base-info {
+        width: 100%;
+        height: ~"calc(100% - 45px)";
+
+        .evalustion-base-attr {
+            width: 350px;
+            height: 100%;
+            border-right: 1px solid @borderColor;
+
+            .evalustion-base-attr-header {
+                height: 45px;
+                line-height: 45px;
+                color: @second-textColor;
+                border-bottom: 1px solid @borderColor;
+                margin-bottom: 25px;
+            }
+
+            .evaluation-attr-form {
+                margin-right: 15px;
+                /*color: white;*/
+            }
+        }
+
+        .evaluation-test-paper-header {
+            height: 45px;
+            line-height: 45px;
+            color: @second-textColor;
+            border-bottom: 1px solid @borderColor;
+            margin-bottom:15px;
+        }
+    }
+}
+.test-paper-detail {
+    width: 100%;
+    height: 100%;
+    color: white;
+}
+.test-paper-detail .back-to-top {
+    position: fixed;
+    right: 50px;
+    bottom: 30px;
+    height: 48px;
+    width: 50px;
+    background: #595959;
+    z-index: 99999;
+    cursor: pointer;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+}
+
+.test-paper-detail .back-to-top:hover {
+    background: rgb(128,128,128);
+}
+
+.test-paper-detail .back-to-top .ivu-icon {
+    font-size: 26px;
+    color: white;
+}
+.back-to-cus{
+    float: right;
+    margin-right: 10px;
+    margin-top: 10px;
+}

+ 131 - 0
TEAMModelOS/ClientApp/src/view/newcourse/EvDetail.vue

@@ -0,0 +1,131 @@
+<template>
+    <div class="evaluation-detail-wrap">
+        <!--顶部菜单-->
+        <div class="evaluation-detail-bar">
+            <span :class="curBarIndex == 0 ? 'evalustion-bar-item line-bottom-active line-bottom':'evalustion-bar-item line-bottom'" @click="curBarIndex = 0">
+                {{$t('learnActivity.mgtScEv.tab1')}}
+            </span>
+            <span :class="curBarIndex == 1 ? 'evalustion-bar-item line-bottom-active line-bottom':'evalustion-bar-item line-bottom'" @click="curBarIndex = 1">
+                {{$t('learnActivity.mgtScEv.tab2')}}
+            </span>
+            <Button type="info" size="small" @click="goBack" class="back-to-cus">
+                <Icon custom="iconfont icon-arrow" size="12" style="vertical-align: baseline;" />
+                返回
+            </Button>
+        </div>
+        <!--试卷信息-->
+        <div :class="curBarIndex == 1 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="curBarIndex == 1">
+            <div class="test-paper-detail" style="margin-top:5px;">
+                <vuescroll ref="test-paper-detail" @handle-scroll="checkBackTop">
+                    <!--试卷题目信息-->
+                    <TestPaper v-if="examInfo && examInfo.papers" :paper="examInfo.papers[curSubIndex]" style="color:#515a6e;margin-top:-30px;" :isShowTools="false" isExamPaper></TestPaper>
+                    <EmptyData v-else style="margin-top:60px;"></EmptyData>
+                    <!--返回顶部-->
+                    <div class="back-to-top fl-col-center" :title="$t('learnActivity.mgtScEv.returnTop')" v-if="showBack" @click="handleBackToTop">
+                        <Icon type="ios-arrow-up" />
+                    </div>
+                </vuescroll>
+            </div>
+        </div>
+        <!-- 试卷评测打分 -->
+        <div :class="curBarIndex == 0 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="curBarIndex == 0">
+            <Scoring :examInfo="examInfo" ref="score-box"></Scoring>
+        </div>
+    </div>
+</template>
+<script>
+import TestPaper from '@/view/evaluation/index/TestPaper.vue'
+import Scoring from '@/view/learnactivity/Scoring.vue'
+export default {
+    components: {
+        TestPaper,
+        Scoring
+    },
+    data() {
+        return {
+            showBack: false,
+            curBarIndex: 0,
+            curSubIndex: 0,
+            isLoading: false,
+            examInfo: {}
+        }
+    },
+    methods: {
+        goBack() {
+            this.$router.push({
+                path: '/home/myCourse'
+            })
+        },
+        /**
+         * 判断是否显示回到顶部按钮
+         * @param vertical
+         * @param horizontal
+         * @param nativeEvent
+         */
+        checkBackTop(vertical, horizontal, nativeEvent) {
+            if (vertical.scrollTop > 100) {
+                this.showBack = true
+            } else {
+                this.showBack = false
+            }
+        },
+        /**vuescroll回到顶部 */
+        handleBackToTop() {
+            this.$refs['test-paper-detail'].scrollTo(
+                { y: '0' }, 300
+            )
+        },
+        //查询当前评测的完整信息
+        findExamInfo(examId, code) {
+            let requestData = {
+                id: examId,
+                code: code
+            }
+            this.isLoading = true
+            this.$api.learnActivity.FindExamInfos(requestData).then(
+                async res => {
+                    if (!res.error) {
+                        let resData = res.examInfo[0]
+                        resData.score = 0
+                        for (let index in resData.papers) {
+                            resData.score += resData.papers[index].point.reduce((total, item) => {
+                                return total + parseInt(item)
+                            }, 0)
+                            if (resData.papers[index].blob) {
+                                let blob = resData.papers[index].blob
+                                resData.papers[index].examScope = resData.scope
+                                resData.papers[index].examId = resData.id
+                                resData.papers[index] = await this.$evTools.getFullPaper(resData.papers[index])
+                                resData.papers[index].blob = blob
+                                resData.score += resData.papers[index].score
+                            }
+                        }
+                        this.examInfo = resData
+                    } else {
+                        this.$Message.error('API ERROR!')
+                    }
+                },
+                err => {
+                    this.$Message.error('API ERROR!')
+                }
+            ).finally(() => {
+                this.isLoading = false;
+            })
+        }
+    },
+    created() {
+        let examId = this.$route.query.examId
+        let code = this.$route.query.code
+        if (examId && code) {
+            this.findExamInfo(examId, code)
+        } else {
+            this.$Message.error('参数错误,无法查看当前评测数据')
+        }
+    }
+}
+</script>
+<style scoped lang="less">
+@import "./EvDetail.less";
+</style>
+<style lang="less">
+</style>

+ 17 - 0
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.less

@@ -131,4 +131,21 @@
 .action-btn-wrap {
     margin-left:20px;
     cursor:pointer;
+}
+.evaluation-status-tag {
+    padding: 1px 2px;
+    border: 1px solid #1CC0F3;
+    margin-left: 2px;
+    border-radius: 2px;
+    font-size:12px;
+    vertical-align: text-bottom;
+}
+.ev-attr-wrap{
+    margin-right: 20px;
+    color: white;
+    margin-top: 5px;
+    display: inline-block;
+    .attr-label{
+        color: #a5a5a5;
+    }
 }

+ 173 - 3
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -35,7 +35,7 @@
                             <div v-for="(item,index) in courseListP" :key="index" @click="selectCourse(index)" :class="index === curCusIndex ? 'course-list-item block-bg block-bg-active':'course-list-item block-bg'">
                                 <p class="course-name">
                                     {{item.name}}
-                                    <Icon type="ios-information-circle-outline" @click="toggleCusInfo" :title="$t('cusMgt.cusInfo')"/>
+                                    <Icon type="ios-information-circle-outline" @click="toggleCusInfo" :title="$t('cusMgt.cusInfo')" />
                                 </p>
                                 <p class="course-code">
                                     <Icon type="md-pricetags" />
@@ -80,9 +80,11 @@
                 </div>
             </div>
             <div class="course-classroom-info" id="table-height">
-                <div class="course-classroom-info-header" style="padding-right:50px;">
+                <div class="course-classroom-info-header" style="padding-right:30px;">
                     <span @click="tabName = 'record'" :class="tabName == 'record' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">课堂记录</span>
+                    <span @click="getActivityList()" :class="tabName == 'activity' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">活动记录</span>
                     <span @click="tabName = 'stus'" :class="tabName == 'stus' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">{{$t('courseManage.classroom.studentList')}}</span>
+
                     <div style="float:right;color:white;" v-if="(listType == 'private' && tabName == 'stus') || (listType == 'school' && tabName == 'stus' && classList[curClassIndex].openType == 2)">
                         <span class="action-btn-wrap" @click="delStudents">
                             <Icon type="md-trash" size="16" />
@@ -101,7 +103,16 @@
                             分组视图
                         </span>-->
                     </div>
+                    <div style="float:right;color:white;" v-if="tabName == 'activity'" class="dark-iview-select">
+                        <span class="action-btn-wrap" @click="delStudents">
+                            活动类型:
+                        </span>
+                        <Select v-model="curAcType" style="width:160px" size="small">
+                            <Option v-for="item in acTypeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+                        </Select>
+                    </div>
                 </div>
+                <!-- 学生名单 -->
                 <div class="course-classroom-info-content dark-iview-table animated fadeIn" v-show="tabName == 'stus'">
                     <vuescroll style="height:100%;">
                         <Table :columns="studentColumn" :data="students" @on-selection-change="(selections)=>{delSelection = selections}" :height="tableHeight" class="system-classroom-table" :loading="stuLoading" no-data-text="暂无学生">
@@ -118,6 +129,7 @@
                         </Table>
                     </vuescroll>
                 </div>
+                <!-- 课堂记录 -->
                 <div v-show="tabName == 'record'" class="animated fadeIn class-record-wrap">
                     <vuescroll>
                         <List>
@@ -147,6 +159,47 @@
                         <p style="width:100%;text-align:center;color:#808080;margin-top:20px;">暂未对接HiTeach上传数据</p>
                     </vuescroll>
                 </div>
+                <!-- 活动记录 -->
+                <div v-show="tabName == 'activity'" class="animated fadeIn class-record-wrap">
+                    <vuescroll>
+                        <List>
+                            <ListItem v-for="(item,index) in evList" :key="index" style="border-color:#505050;cursor: pointer;">
+                                <ListItemMeta @click.native="toEvDetail(index)">
+                                    <p slot="title" class="record-name">
+                                        {{item.name}}
+                                        <span class="evaluation-status-tag" :style="{ borderColor: item.progress == 'pending' ? '#0BADD4' : item.progress == 'going' ? '#1CC0F3' : '#ed4014', color: (item.progress == 'pending' ? '#0BADD4' : item.progress == 'going' ? '#1CC0F3' : '#ed4014')}">
+                                            {{ item.progress == 'pending' ? $t('learnActivity.mgtScEv.pending') : item.progress == 'going' ? $t('learnActivity.mgtScEv.going') : $t('learnActivity.mgtScEv.finish') }}
+                                        </span>
+                                    </p>
+                                    <span slot="avatar" style="margin-top:12px;display: inline-block;margin-left:10px;">
+                                        <Icon custom="iconfont icon-test" size="30" color="white" />
+                                    </span>
+                                    <div slot="description">
+                                        <span class="ev-attr-wrap">
+                                            <span class="attr-label">
+                                                <Icon type="md-time" size="16" />
+                                                {{$t('learnActivity.mgtScEv.createTime')}}
+                                            </span>
+                                            <span class="attr-value">
+                                                {{dateFormat(item.startTime)}}
+                                            </span>
+                                        </span>
+                                        <span class="ev-attr-wrap">
+                                            <span class="attr-label">
+                                                <Icon type="ios-cube" size="14" />
+                                                {{$t('learnActivity.mgtScEv.evType')}}
+                                            </span>
+                                            <span class="attr-value">
+                                                {{getTypeLabel(item.type)}}
+                                            </span>
+                                        </span>
+                                    </div>
+                                </ListItemMeta>
+                            </ListItem>
+                        </List>
+                        <!-- <p style="width:100%;text-align:center;color:#808080;margin-top:20px;">暂未对接活动列表数据</p> -->
+                    </vuescroll>
+                </div>
             </div>
         </div>
         <Drawer :title="$t('cusMgt.cusInfo')" class-name="dark-iview-drawer" width="450" :closable="false" v-model="showCusInfo" @on-close="baseEditStatus = true">
@@ -241,6 +294,34 @@ export default {
             }
         }
         return {
+            acTypeList: [
+                {
+                    label: '评测',
+                    value: 'ev'
+                },
+                {
+                    label: '投票',
+                    value: 'vote'
+                },
+                {
+                    label: '问卷',
+                    value: 'qu'
+                },
+                {
+                    label: '作业',
+                    value: 'hw'
+                },
+                {
+                    label: '自主学习',
+                    value: 'sl'
+                }
+            ],
+            curAcType: 'ev',
+            evList: [],//评测列表
+            voteList: [],//投票列表
+            quList: [],//问卷列表
+            hwList: [],//作业列表
+            slList: [],//自主学习
             delSelection: [],
             selections: [],
             schoolClassList: [],
@@ -270,7 +351,7 @@ export default {
                     sortable: true
                 },
                 {
-                    title:this.$t('cusMgt.stuClassCol4'),
+                    title: this.$t('cusMgt.stuClassCol4'),
                     slot: 'groupId',
                     align: 'center',
                     sortable: true
@@ -323,6 +404,84 @@ export default {
         }
     },
     methods: {
+        /**获取type对应的label */
+        getTypeLabel(code) {
+            for (let item of this.$GLOBAL.EV_TYPE()) {
+                if (item.value == code) {
+                    return item.label
+                }
+            }
+        },
+        //时间戳转换
+        dateFormat(timestamp) {
+            var date = new Date(timestamp)
+            var Y = date.getFullYear() + '-'
+            var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
+            var D = date.getDate() + ' '
+            return Y + M + D;
+        },
+        //获取活动列表
+        getActivityList() {
+            this.tabName = 'activity'
+            switch (this.curAcType) {
+                case 'ev':
+                    if (this.evList.length) break //首次(数组为空)访问数据
+                    this.getEvList()
+                    break
+                case 'vote':
+                    if (this.evList.length) break
+                    this.getVoteList()
+                    break
+                case 'qu':
+                    if (this.evList.length) break
+                    this.getQuList()
+                    break
+                case 'hw':
+                    if (this.evList.length) break
+                    this.getHwList()
+                    break
+                case 'sl':
+                    if (this.evList.length) break
+                    this.getSlList()
+                    break
+                default:
+                    break
+            }
+        },
+        //获取评测列表
+        getEvList() {
+            let requestData = {
+                code: this.$store.state.userInfo.TEAMModelId
+            }
+            this.$api.learnActivity.FindExamInfo(requestData).then(
+                res => {
+                    if (!res.error) {
+                        res.examInfo = res.examInfo.sort((a, b) => {
+                            return a.createTime - b.createTime > 0 ? -1 : 1
+                        })
+                        this.evList = res.examInfo
+                    } else {
+                        this$Message.error('API ERROR!')
+                    }
+                }
+            )
+        },
+        //获取投票列表
+        getVoteList() {
+
+        },
+        //获取问卷列表
+        getQuList() {
+
+        },
+        //获取作业列表
+        getHwList() {
+
+        },
+        //获取自主学习列表
+        getSlList() {
+
+        },
         getClassType(scope, openType) {
             if (this.listType == 'private') {
                 return {
@@ -742,12 +901,23 @@ export default {
                 this.findClassStu()
             }
         },
+        //查看课堂记录详情
         toClassRecoerd() {
             this.listLoading = true
             setTimeout(() => {
                 this.$router.push({ path: '/home/classRecord' })
             }, 500)
         },
+        // 查看评测详情
+        toEvDetail(index) {
+            this.$router.push({
+                path: '/home/evDetail',
+                query: {
+                    examId: this.evList[index].id,
+                    code: this.evList[index].code
+                }
+            })
+        },
         //删除个人课程
         delCourse() {
             this.$Modal.confirm({

+ 8 - 2
TEAMModelOS/Controllers/Common/VoteController.cs

@@ -69,7 +69,6 @@ namespace TEAMModelOS.Controllers.Learn
                 //新增Vote
                 var client = _azureCosmos.GetCosmosClient();
                 request.code = request.pk + "-" + request.code;
-                
                 long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 request.createTime = now;
                 if (string.IsNullOrEmpty(request.id))
@@ -82,7 +81,6 @@ namespace TEAMModelOS.Controllers.Learn
                     else { 
                         request.progress = "going"; 
                     }
-                        
                     request = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request, new PartitionKey($"{request.code}"));
                 }
                 else
@@ -92,6 +90,14 @@ namespace TEAMModelOS.Controllers.Learn
                     {
                         return Ok(new { v = "活动正在进行中" });
                     }
+                    if (request.startTime > now)
+                    {
+                        request.progress = "pending";
+                    }
+                    else
+                    {
+                        request.progress = "going";
+                    }
                     request.progress = info.progress;
                     request = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request, info.id, new PartitionKey($"{info.code}"));
                 }

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

@@ -45,7 +45,7 @@ namespace TEAMModelOS.Controllers
         /// <returns></returns>
         [ProducesDefaultResponseType]
         [HttpPost("stu-find-activity")]
-        [AuthToken(Roles = "student")]
+       // [AuthToken(Roles = "student")]
         public async Task<IActionResult> FindStu(JsonElement request)
         {
             var (id, name, pic,school) = HttpContext.GetAuthTokenInfo();

+ 50 - 38
TEAMModelOS/Services/Common/ActivityStudentService.cs

@@ -76,15 +76,13 @@ namespace TEAMModelOS.Services.Common
                             case "once":
                                 // //如果是只能投票一次的活动则直接获取Redis的第一条 只能投一次
                                 Field = $"{userid}-once";
-                                RedisValue[] values = _azureRedis.GetRedisClient(8).HashValues($"Vote:Record:{vote.id}_{vote.code}");
+                                HashEntry[] values = _azureRedis.GetRedisClient(8).HashGetAll($"Vote:Record:{vote.id}_{vote.code}");
                                 if (values != null  && values.Length > 0)
                                 {
-                                    
                                     value = new RedisValue();
                                     foreach (var val in values) {
-                                        VoteRecord record = val.ToString().ToObject<VoteRecord>();
-                                        if (record.userid==userid) {
-                                            value = val;
+                                        if (val.Name.ToString() == Field) {
+                                            value = val.Value;
                                             break;
                                         }
                                     }
@@ -142,6 +140,8 @@ namespace TEAMModelOS.Services.Common
                     record.userid = userid;
                     //保存投票记录
                     bool status = await _azureRedis.GetRedisClient(8).HashSetAsync($"Vote:Record:{vote.id}_{vote.code}", Field, record.ToJsonString());
+                    //单独保存每个人方便查询的记录
+                    bool stuallstatus = await _azureRedis.GetRedisClient(8).HashSetAsync($"Vote:Record:{vote.id}_{vote.code}:{userid}", Field, record.ToJsonString());
                     //当前投票分组计数存入活动的Redis
                     var group_opt= option.GroupBy(x => x);
                     foreach (var opt in group_opt) {
@@ -161,6 +161,8 @@ namespace TEAMModelOS.Services.Common
                     //保存投票记录
                     VoteRecord record = new VoteRecord { opt = option, time = curr, userid = userid };
                     bool status = await _azureRedis.GetRedisClient(8).HashSetAsync($"Vote:Record:{vote.id}_{vote.code}", Field, record.ToJsonString());
+                    //单独保存每个人方便查询的记录
+                    bool stuallstatus = await _azureRedis.GetRedisClient(8).HashSetAsync($"Vote:Record:{vote.id}_{vote.code}:{userid}", Field, record.ToJsonString());
                     //当前投票分组计数存入活动的Redis
                     var group_opt = option.GroupBy(x => x);
                     foreach (var opt in group_opt)
@@ -212,11 +214,18 @@ namespace TEAMModelOS.Services.Common
         /// <returns></returns>
         public static async Task<(List<ActivityData> datas, string continuationTokenSchool,string continuationTokenTeacher)> FindAsStu( JsonElement requert, string id,string school, AzureCosmosFactory _azureCosmos,AzureRedisFactory _azureRedis)
         {
+            if (string.IsNullOrWhiteSpace(id)) {
+                id = requert.GetProperty("userid").GetString();
+            }
+            if (string.IsNullOrWhiteSpace(school))
+            {
+                school = requert.GetProperty("school").GetString();
+            }
             //开始时间,默认最近三十天
             var stimestamp = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds();
-            if (!requert.TryGetProperty("stime", out JsonElement stime))
+            if (requert.TryGetProperty("stime", out JsonElement stime))
             {
-                if (stime.TryGetInt64(out long data))
+                if (!stime.ValueKind.Equals(JsonValueKind.Undefined) && !stime.ValueKind.Equals(JsonValueKind.Null) &&stime.TryGetInt64(out long data))
                 {
                     stimestamp = data;
                 } 
@@ -226,30 +235,30 @@ namespace TEAMModelOS.Services.Common
             var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             string etimesql = $" and c.startTime <= {etimestamp}   ";
             var progresssql = "";
-            if (!requert.TryGetProperty("progress", out JsonElement progress))
+            if (requert.TryGetProperty("progress", out JsonElement progress))
             {
 
                 if (!progress.ValueKind.Equals(JsonValueKind.Undefined) && !progress.ValueKind.Equals(JsonValueKind.Null) && progress.ValueKind.Equals(JsonValueKind.String))
                 {
-                    progresssql = $" and c.progress='{progresssql}' ";
+                    progresssql = $" and c.progress='{progress}' ";
                 }
             }
             var typesql = "";
-            if (!requert.TryGetProperty("type", out JsonElement type))
+            if (requert.TryGetProperty("type", out JsonElement type))
             {
 
                 if (!type.ValueKind.Equals(JsonValueKind.Undefined) && !type.ValueKind.Equals(JsonValueKind.Null) && type.ValueKind.Equals(JsonValueKind.String))
                 {
-                    typesql = $" and c.type='{typesql}' ";
+                    typesql = $" and c.type='{type}' ";
                 }
             }
             string continuationTokenSchool = null;
             string continuationTokenTeacher = null;
             //默认不指定返回大小
             int? topcout = null;
-            if (!requert.TryGetProperty("count", out JsonElement jcount))
+            if (requert.TryGetProperty("count", out JsonElement jcount))
             {
-                if (jcount.TryGetInt32(out int data))
+                if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data))
                 {
                     topcout = data;
                 } 
@@ -257,7 +266,7 @@ namespace TEAMModelOS.Services.Common
             //是否需要进行分页查询,默认不分页
             bool iscontinuation = false;
             //如果指定了返回大小
-            if (!requert.TryGetProperty("continuationTokenSchool", out JsonElement continuationSchool))
+            if (requert.TryGetProperty("continuationTokenSchool", out JsonElement continuationSchool))
             {
                 //指定了cancellationToken continuationSchool
                 if (!continuationSchool.ValueKind.Equals(JsonValueKind.Null) && continuationSchool.ValueKind.Equals(JsonValueKind.String))
@@ -267,7 +276,7 @@ namespace TEAMModelOS.Services.Common
                 }
             }
             //如果指定了返回大小
-            if (!requert.TryGetProperty("continuationTokenTeacher", out JsonElement continuationTeacher))
+            if (requert.TryGetProperty("continuationTokenTeacher", out JsonElement continuationTeacher))
             {
                 //指定了cancellationToken 表示需要进行分页
                 if (!continuationTeacher.ValueKind.Equals(JsonValueKind.Null) && continuationTeacher.ValueKind.Equals(JsonValueKind.String))
@@ -283,7 +292,7 @@ namespace TEAMModelOS.Services.Common
             string joinSqlClasses = "";
             string andSqlClasses = "";
             List<string> classes=null;
-            if (!requert.TryGetProperty("classes", out JsonElement jclasses))
+            if ( requert.TryGetProperty("classes", out JsonElement jclasses))
             {
                 if (jclasses.ValueKind is JsonValueKind.Array ) {
                     classes = jclasses.ToObject<List<string>>();
@@ -307,7 +316,7 @@ namespace TEAMModelOS.Services.Common
             //科目
             string joinSqlSubjects = "";
             string andSqlSubjects = "";
-            if (!requert.TryGetProperty("subjects", out JsonElement jsubjects))
+            if ( requert.TryGetProperty("subjects", out JsonElement jsubjects))
             {
                 if (jsubjects.ValueKind is JsonValueKind.Array)
                 {
@@ -321,24 +330,27 @@ namespace TEAMModelOS.Services.Common
                     }
                 }
             }
-            string querySchool = $" SELECT distinct  value c   FROM c  {joinSqlTmdids} {joinSqlClasses} {joinSqlSubjects}  where {stimesql}  {etimesql} and c.pk='Activity' {progresssql}  {typesql}  {andSqlSubjects}  {tgSql}";
             List<ActivityData> datas = new List<ActivityData>();
             var client = _azureCosmos.GetCosmosClient();
-            //查询数据归属学校的
-            await foreach (var item in client.GetContainer("TEAMModelOS","School").GetItemQueryStreamIterator(querySchool, continuationToken: continuationTokenSchool, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Activity-{id}") }))
-            {
-                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+            if (!string.IsNullOrWhiteSpace(school)) {
+                string querySchool = $" SELECT distinct  value c   FROM c  {joinSqlTmdids} {joinSqlClasses} {joinSqlSubjects}  where {stimesql}  {etimesql} and c.pk='Activity' {progresssql}  {typesql}  {andSqlSubjects}  {tgSql}";
+               
+                //查询数据归属学校的
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(querySchool, continuationToken: continuationTokenSchool, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Activity-{school}") }))
                 {
-                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                    {
-                        datas.Add(obj.ToObject<ActivityData>());
-                    }
-                    //如果需要分页则跳出
-                    if (iscontinuation)
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        continuationTokenSchool = item.GetContinuationToken();
-                        break;
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            datas.Add(obj.ToObject<ActivityData>());
+                        }
+                        //如果需要分页则跳出
+                        if (iscontinuation)
+                        {
+                            continuationTokenSchool = item.GetContinuationToken();
+                            break;
+                        }
                     }
                 }
             }
@@ -363,9 +375,9 @@ namespace TEAMModelOS.Services.Common
                 }
             }
             bool tips = false;
-            if (!requert.TryGetProperty("tips", out JsonElement jtips))
+            if (requert.TryGetProperty("tips", out JsonElement jtips))
             {
-                if (!jtips.ValueKind.Equals(JsonValueKind.Null) && !jtips.ValueKind.Equals(JsonValueKind.True))
+                if (!jtips.ValueKind.Equals(JsonValueKind.Undefined) && !jtips.ValueKind.Equals(JsonValueKind.Null) && (jtips.ValueKind.Equals(JsonValueKind.True)|| jtips.ValueKind.Equals(JsonValueKind.False)))
                 {
                     tips = jtips.GetBoolean();
                 }
@@ -384,32 +396,32 @@ namespace TEAMModelOS.Services.Common
                             activityTips = DoVoteTips;
                             //msgid, //0不能投票,1可以投票,2不在时间范围内,3周期内的可投票数不足
                             //voteCount 可用投票数
-                            res = activityTips(data, _azureCosmos, id, _azureRedis);
+                            res =await activityTips(data, _azureCosmos, id, _azureRedis);
                             break;
                         //问卷
                         case "survey":
                             //msgid 0 已作答, 1未作答,2,未完成
                             activityTips = DoSurveyTips;
-                            res = activityTips(data, _azureCosmos, id, _azureRedis);
+                            res = await activityTips(data, _azureCosmos, id, _azureRedis);
                             break;
                         //评测
                         case "exam":
                             //msgid 0 已作答, 1未作答,2,未完成, 用时间控制 相关发布状态,并且展示相应的结果
                             activityTips = DoExamTips;
-                            res = activityTips(data, _azureCosmos, id, _azureRedis);
+                            res = await activityTips(data, _azureCosmos, id, _azureRedis);
                             break;
                         //学习活动
                         case "learn":
                             //msgid 0 已完成, 1未开始,2,未完成
                             activityTips = DoLearnTips;
-                            res = activityTips(data, _azureCosmos, id, _azureRedis);
+                            res = await activityTips(data, _azureCosmos, id, _azureRedis);
                             break;
                         //作业活动
                         case "homework":
                             //msgid 0 已作答, 1未作答,2,未完成,3已批改,且有错误,4已批改,已完成
                             //index:0,1,5 错误题序
                             activityTips = DoHomeworkTips;
-                            res = activityTips(data, _azureCosmos, id, _azureRedis);
+                            res = await activityTips(data, _azureCosmos, id, _azureRedis);
                             break;
                         default: break;
                     }