Browse Source

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

zhousheng 4 years ago
parent
commit
284b2e67a5
50 changed files with 553 additions and 624 deletions
  1. 1 1
      TEAMModelOS.SDK/Models/Cosmos/Common/ExamClassResult.cs
  2. 1 0
      TEAMModelOS.SDK/Models/Cosmos/Common/ItemInfo.cs
  3. 2 12
      TEAMModelOS.SDK/Models/Cosmos/Common/Knowledge.cs
  4. 19 32
      TEAMModelOS.SDK/Models/Cosmos/Common/Volume.cs
  5. 2 8
      TEAMModelOS.SDK/Models/Cosmos/School/CourseManagement.cs
  6. 3 8
      TEAMModelOS.SDK/Models/Cosmos/School/ExamAnswer.cs
  7. 2 3
      TEAMModelOS.SDK/Models/Cosmos/School/ExamInfo.cs
  8. 1 0
      TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs
  9. 1 0
      TEAMModelOS.SDK/Models/Cosmos/School/Paper.cs
  10. 1 0
      TEAMModelOS.SDK/Models/Cosmos/School/School.cs
  11. 1 0
      TEAMModelOS.SDK/Models/Cosmos/School/Survey.cs
  12. 1 0
      TEAMModelOS.SDK/Models/Cosmos/School/Vote.cs
  13. 1 1
      TEAMModelOS.SDK/Models/Cosmos/Teacher/TeacherCourse.cs
  14. 3 3
      TEAMModelOS.SDK/TEAMModelOS.SDK.csproj
  15. 9 21
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseJudge.vue
  16. 9 23
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseMultiple.vue
  17. 1 9
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.less
  18. 3 8
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  19. 0 2
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseSingle.less
  20. 11 26
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseSingle.vue
  21. 1 12
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.less
  22. 10 10
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  23. 1 1
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteTable.vue
  24. 17 0
      TEAMModelOS/ClientApp/src/css/dark-el-cascader.less
  25. 5 0
      TEAMModelOS/ClientApp/src/css/site.css
  26. 1 0
      TEAMModelOS/ClientApp/src/view/Home.vue
  27. 6 4
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue
  28. 106 0
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseDiffPie.vue
  29. 25 19
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseObjectivePie.vue
  30. 119 0
      TEAMModelOS/ClientApp/src/view/evaluation/components/BasePointPie.vue
  31. 18 12
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseTypePie.vue
  32. 0 2
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.less
  33. 4 1
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompletion.vue
  34. 3 0
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue
  35. 3 0
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue
  36. 17 13
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.less
  37. 24 32
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.vue
  38. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.less
  39. 69 74
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue
  40. 1 3
      TEAMModelOS/Controllers/Exam/ExamController.cs
  41. 19 7
      TEAMModelOS/Controllers/Exam/ImportExerciseController.cs
  42. 0 1
      TEAMModelOS/Controllers/Exam/PaperController.cs
  43. 0 1
      TEAMModelOS/Controllers/School/ClassRoomController.cs
  44. 0 253
      TEAMModelOS/Controllers/School/ClassStudentController.cs
  45. 16 2
      TEAMModelOS/Controllers/School/CourseController.cs
  46. 0 1
      TEAMModelOS/Controllers/School/SchoolController.cs
  47. 0 2
      TEAMModelOS/Controllers/Syllabus/ItemInfoController.cs
  48. 2 1
      TEAMModelOS/Controllers/Syllabus/VolumeController.cs
  49. 12 13
      TEAMModelOS/Controllers/Task/SurveyController.cs
  50. 1 2
      TEAMModelOS/Controllers/Task/VoteController.cs

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

@@ -11,7 +11,7 @@ namespace TEAMModelOS.SDK.Models
     public class ExamClassResult :CosmosEntity
     {
         public ExamClassResult() {
-            //paper = new PaperSimple();
+            pk = "ExamClassResult";
             studentAnswers = new List<List<List<string>>>();
             studentScores = new List<List<double>>();
             info = new ClassInfo();

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/ItemInfo.cs

@@ -15,6 +15,7 @@ namespace TEAMModelOS.SDK.Models
     {       
         public ItemInfo()
         {
+            pk = "Item";
             children = new List<ItemInfo>();
             option = new List<CodeValue>();
             answer = new List<string>();

+ 2 - 12
TEAMModelOS.SDK/Models/Cosmos/Common/Knowledge.cs

@@ -17,23 +17,13 @@ namespace TEAMModelOS.SDK.Models
     {
         public Knowledge()
         {
+            pk = "Knowledge";
             points = new List<string>();
         }
-        /// <summary>
-        /// 学校编码 如果是教师个人知识点为醍摩豆id 否则为学校编码 
-        /// </summary>
-        [PartitionKey]
-        [Required(ErrorMessage = "{0} 必须填写")]
-        public string code { get; set; }
-        // [PartitionKey(name = "Knowledge")]
-        public string pk { get; set; }
-        public int? ttl { get; set; }
         
-        public string id { get; set; }
         /// <summary>
         /// 标记为知识块,0=知识块 ,1 知识点
-        /// </summary>
-        
+        /// </summary>        
         [Required(ErrorMessage = "{0} 必须填写")]
         public int type { get; set; } = 0;
         /// <summary>

+ 19 - 32
TEAMModelOS.SDK/Models/Cosmos/Common/Volume.cs

@@ -1,4 +1,4 @@
- using System;
+using System;
 using System.Collections.Generic;
 using System.Text;
 using TEAMModelOS.SDK.Context.Attributes.Azure;
@@ -10,83 +10,70 @@ using TEAMModelOS.SDK.DI;
 
 namespace TEAMModelOS.SDK.Models
 {
-    [CosmosDB(Database = "TEAMModelOS", Name = "Common", Monitor =true)]
-    
-    public class Volume :CosmosEntity
+    [CosmosDB(Database = "TEAMModelOS", Name = "Common", Monitor = true)]
+
+    public class Volume : CosmosEntity
     {
-        [PartitionKey]
-        [Required(ErrorMessage = "{0} 必须填写")]
-        public string code { get; set; }
-        // [PartitionKey(name = "SyllabusVolume")]
-        public string pk { get; set; }
-        public int? ttl { get; set; } 
-        /// <summary>
-        /// id生成规则
-        /// </summary>
-        
-        public string id { get; set; }
         /// <summary>
         /// 0默认教学课纲的册别 1个人或单独的专题课纲册别 2,系统课纲
         /// </summary>
-        
+
         public int type { get; set; }
-        
+
 
         /// <summary>
         /// 学段
         /// </summary>
-        
+
         public string periodId { get; set; }
-        
+
 
         /// <summary>
         /// 学科
         /// </summary>
-        
+
         public string subjectId { get; set; }
-        
+
 
         /// <summary>
         /// 年级
         /// </summary>
-        
+
         public string gradeId { get; set; }
-        
+
 
         /// <summary>
         /// 学期code
         /// </summary>
-        
+
         public string semesterId { get; set; }
-        
+
 
         /// <summary>
         /// 状态
         /// </summary>
-     
+
         public int status { get; set; } = 1;
-        
+
 
         /// <summary>
         /// 册别name
         /// </summary>
         [Required(ErrorMessage = "{0} 必须填写")]
         public string volumeName { get; set; }
-        
+
 
         /// <summary>
         /// 册别code
         /// </summary>
         public string volumeCode { get; set; }
-        
+
 
         /// <summary>
         /// 创建者醍摩豆id
         /// </summary>
-        [JsonPropertyName("TEAMModelId")]
-        [JsonProperty("TEAMModelId")]
         public string TEAMModelId { get; set; }
-        
+
         /// <summary>
         /// 共编使用者 的醍摩豆id
         /// </summary>

+ 2 - 8
TEAMModelOS.SDK/Models/Cosmos/School/CourseManagement.cs

@@ -15,17 +15,11 @@ namespace TEAMModelOS.SDK.Models
     {
         public CourseManagement()
         {
+            pk = "CourseManagement";
             courses = new List<CourseSimple>();
             teacher = new Teachers();
         }
-        /// <summary>
-        /// 班级id
-        /// </summary>
-        public string id { get; set; }
-        public int? ttl { get; set; }
-        public string pk { get; set; }
-        [PartitionKey]
-        public string code { get; set; }
+        
         public string name { get; set; }
         public List<CourseSimple> courses { get; set; }
         public Teachers teacher { get; set; }

+ 3 - 8
TEAMModelOS.SDK/Models/Cosmos/School/ExamAnswer.cs

@@ -15,17 +15,12 @@ namespace TEAMModelOS.SDK.Models
     public class ExamAnswer :CosmosEntity
     {
        // [PartitionKey(name = "ExamAnswer")]
-        public string pk { get; set; }
-        public int? ttl { get; set; } 
         public ExamAnswer()
         {
+            pk = "ExamAnswer";
             answer = new List<List<string>>();
         }
-        [JsonProperty(PropertyName = "id")]
-        public string id { get; set; } 
-        public List<List<string>> answer { get; set; }
-        [PartitionKey]
-        [Required(ErrorMessage = "{0} 必须填写")]
-        public string code { get; set; }
+       
+        public List<List<string>> answer { get; set; }       
     }
 }

+ 2 - 3
TEAMModelOS.SDK/Models/Cosmos/School/ExamInfo.cs

@@ -16,14 +16,13 @@ namespace TEAMModelOS.SDK.Models
     public class ExamInfo :CosmosEntity
     { 
         public ExamInfo() {
+            pk = "Exam";
             period = new PeriodSimple();
             grades = new List<Grade>();
             subjects = new List<ExamSubject>();
             papers = new List<PaperSimple>();
             targetClassIds = new List<string>();
-        }
-        [JsonProperty(PropertyName = "id")]
-        public string id { get; set; }
+        }      
 
         public string name { get; set; }
         public string school { get; set; }

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs

@@ -15,6 +15,7 @@ namespace TEAMModelOS.SDK.Models
     {        
         public ExamResult()
         {
+            pk = "ExamResult";
             classes = new List<ClassRange>();
             studentScores = new List<List<double>>();
             studentIds = new List<string>();

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/School/Paper.cs

@@ -16,6 +16,7 @@ namespace TEAMModelOS.SDK.Models
     {
         public Paper()
         {
+            pk = "Paper";
             //item = new List<ItemInfo>();
             scoring = new List<MarkConfig>();
         }

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/School/School.cs

@@ -14,6 +14,7 @@ namespace TEAMModelOS.SDK.Models
     {        
         public School()
         {
+            pk = "Base";
             timeZone = new TimeZone();
             period = new List<Period>();
         }

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/School/Survey.cs

@@ -15,6 +15,7 @@ namespace TEAMModelOS.SDK.Models
     public class Survey : CosmosEntity
     {
         public Survey() {
+            pk = "Survey";
             questions = new List<Questions>();
             classes = new List<Classes>();
         }

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/School/Vote.cs

@@ -16,6 +16,7 @@ namespace TEAMModelOS.SDK.Models
     {   
         public Vote()
         {
+            pk = "Vote";
             options = new List<OptionsVote>();
 
         }

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/Teacher/TeacherCourse.cs

@@ -25,6 +25,6 @@ namespace TEAMModelOS.SDK.Models
         public string scope { get; set; }
         public string code { get; set; }
         public Teachers teacher { get; set; }
-        public List<StudentSimple> students { get; set; } = new List<StudentSimple>();
+        //public List<StudentSimple> students { get; set; } = new List<StudentSimple>();
     }
 }

+ 3 - 3
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -2,9 +2,9 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
-    <Version>3.0.520</Version>
-    <AssemblyVersion>3.0.520.0</AssemblyVersion>
-    <FileVersion>3.0.520.0</FileVersion>
+    <Version>3.0.1211</Version>
+    <AssemblyVersion>3.0.1211.0</AssemblyVersion>
+    <FileVersion>3.0.1211.0</FileVersion>
     <PackageReleaseNotes>520发版</PackageReleaseNotes>
   </PropertyGroup>
 

+ 9 - 21
TEAMModelOS/ClientApp/src/components/questionnaire/BaseJudge.vue

@@ -19,7 +19,7 @@
 	</div>
 </template>
 <script>
-	import E from '@/utils/wangEditor.js'
+	import E from 'wangeditor'
 	import IconText from '@/components/evaluation/IconText.vue'
 	export default {
 		components: {
@@ -60,11 +60,10 @@
 					this.options.forEach((item, i) => {
 						let that = this
 						let editor = new E(that.$refs['singleOption' + i][0])
-						editor.customConfig = this.defaultConfig
-						editor.customConfig.uploadVideoDisable = true,
+						editor.config.uploadVideoDisable = true,
 
 							// 选项编辑器失焦隐藏工具栏
-							editor.customConfig.onblur = function() {
+							editor.config.onblur = function() {
 								let allToolbars = document.getElementsByClassName('qn-option-editor')
 								for (let i = 0; i < allToolbars.length; i++) {
 									if (allToolbars[i].children.length) {
@@ -73,12 +72,9 @@
 								}
 							}
 
-						editor.customConfig.onVideoWarning = (text) => {
-								this.$Message.warning(text)
-							},
 
 							// 选项编辑器内容发生变化时
-							editor.customConfig.onchange = (html) => {
+							editor.config.onchange = (html) => {
 								let key = String.fromCharCode(64 + parseInt(i + 1))
 								let codeArr = this.optionsContent.map(item => item.code)
 								// 如果已经编辑过则 修改选项内容
@@ -120,9 +116,8 @@
 					})
 					this.$nextTick(() => {
 						let editor = new E(that.$refs['singleOption' + newIndex][0])
-						editor.customConfig = this.defaultConfig
 
-						editor.customConfig.onchange = (html) => {
+						editor.config.onchange = (html) => {
 							let key = String.fromCharCode(64 + parseInt(newIndex + 1))
 							let codeArr = this.optionsContent.map(item => item.code)
 							// 如果已经编辑过则 修改选项内容
@@ -205,25 +200,18 @@
 				}
 				setTimeout(function() {
 					let currentToolBar = that.$refs['singleOption' + index][0].children[0]
+					if(currentToolBar.clientWidth < 700){
+						currentToolBar.style.top = '-90px'
+					}
 					currentToolBar.style.visibility = 'visible'
 				}, 100)
 			},
 		},
 		mounted() {
 			let stemEditor = new E(this.$refs.singleEditor)
-			stemEditor.customConfig = this.defaultConfig
-			stemEditor.customConfig.uploadVideoDisable = false
-			stemEditor.customConfig.onchange = (html) => {
+			stemEditor.config.onchange = (html) => {
 				this.stemContent = html
 			}
-			stemEditor.customConfig.onVideoWarning = (text) => {
-					this.$Message.warning(text)
-				},
-
-				// 选择视频文件后的上传Blob操作
-				stemEditor.customConfig.onVideoSelected = async (file) => {
-						this.$tools.doUploadVideo(this, file, stemEditor)
-					},
 					stemEditor.create()
 			this.stemEditor = stemEditor
 			this.initEditors()

+ 9 - 23
TEAMModelOS/ClientApp/src/components/questionnaire/BaseMultiple.vue

@@ -19,7 +19,7 @@
 	</div>
 </template>
 <script>
-	import E from '@/utils/wangEditor.js'
+	import E from 'wangeditor'
 	import IconText from '@/components/evaluation/IconText.vue'
 	export default {
 		components: {
@@ -60,11 +60,10 @@
 					this.options.forEach((item, i) => {
 						let that = this
 						let editor = new E(that.$refs['singleOption' + i][0])
-						editor.customConfig = this.defaultConfig
-						editor.customConfig.uploadVideoDisable = true,
+						editor.config.uploadVideoDisable = true,
 
 							// 选项编辑器失焦隐藏工具栏
-							editor.customConfig.onblur = function() {
+							editor.config.onblur = function() {
 								let allToolbars = document.getElementsByClassName('qn-option-editor')
 								for (let i = 0; i < allToolbars.length; i++) {
 									if (allToolbars[i].children.length) {
@@ -73,12 +72,8 @@
 								}
 							}
 
-						editor.customConfig.onVideoWarning = (text) => {
-								this.$Message.warning(text)
-							},
-
 							// 选项编辑器内容发生变化时
-							editor.customConfig.onchange = (html) => {
+							editor.config.onchange = (html) => {
 								let key = String.fromCharCode(64 + parseInt(i + 1))
 								let codeArr = this.optionsContent.map(item => item.code)
 								// 如果已经编辑过则 修改选项内容
@@ -120,9 +115,7 @@
 					})
 					this.$nextTick(() => {
 						let editor = new E(that.$refs['singleOption' + newIndex][0])
-						editor.customConfig = this.defaultConfig
-
-						editor.customConfig.onchange = (html) => {
+						editor.config.onchange = (html) => {
 							let key = String.fromCharCode(64 + parseInt(newIndex + 1))
 							let codeArr = this.optionsContent.map(item => item.code)
 							// 如果已经编辑过则 修改选项内容
@@ -205,25 +198,18 @@
 				}
 				setTimeout(function() {
 					let currentToolBar = that.$refs['singleOption' + index][0].children[0]
+					if(currentToolBar.clientWidth < 700){
+						currentToolBar.style.top = '-90px'
+					}
 					currentToolBar.style.visibility = 'visible'
 				}, 100)
 			},
 		},
 		mounted() {
 			let stemEditor = new E(this.$refs.singleEditor)
-			stemEditor.customConfig = this.defaultConfig
-			stemEditor.customConfig.uploadVideoDisable = false
-			stemEditor.customConfig.onchange = (html) => {
+			stemEditor.config.onchange = (html) => {
 				this.stemContent = html
 			}
-			stemEditor.customConfig.onVideoWarning = (text) => {
-					this.$Message.warning(text)
-				},
-
-				// 选择视频文件后的上传Blob操作
-				stemEditor.customConfig.onVideoSelected = async (file) => {
-						this.$tools.doUploadVideo(this, file, stemEditor)
-					},
 					stemEditor.create()
 			this.stemEditor = stemEditor
 			this.initEditors()

+ 1 - 9
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.less

@@ -155,16 +155,12 @@
         border-color: @borderColor !important;
         margin-top: 10px;
         z-index: 1 !important;
-
-        .w-e-menu {
-            z-index: 2 !important;
-        }
     }
 
     .w-e-text-container {
         background: #3b3b3b;
         border-color: @borderColor !important;
-        z-index: 1 !important;
+        z-index: 0 !important;
     }
 
     .w-e-text {
@@ -186,10 +182,6 @@
         }
     }
 
-    .w-e-toolbar .w-e-menu:hover i {
-        color: #fff;
-    }
-
     .qn-form-disabled {
 
         .ivu-input, .ivu-select-single .ivu-select-selection,

+ 3 - 8
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue

@@ -34,7 +34,8 @@
 	</div>
 </template>
 <script>
-	import E from '@/utils/wangEditor.js'
+	
+	import E from 'wangeditor'
 	export default {
 		props: {
 			editItem: {
@@ -65,11 +66,6 @@
 				defaultFileList: [],
 				relateFileList: [],
 				uploadUrl: '',
-				defaultConfig: {
-					showLinkImg: false, // 是否展示网络图片链接上传
-					uploadFileName: 'files', // 上传图片后台获取的文件名
-					menus: this.$tools.wangEditorMenuSimple
-				},
 				qnForm: {
 					name: '',
 					targetClassIds: [],
@@ -260,8 +256,7 @@
 
 			/** 初始化问卷详情的富文本编辑器 */
 			let descriptionEditor = new E(this.$refs.descriptionEditor)
-			descriptionEditor.customConfig = this.defaultConfig
-			descriptionEditor.customConfig.onchange = (html) => {
+			descriptionEditor.config.onchange = (html) => {
 				this.qnForm.description = html
 			}
 			descriptionEditor.create()

+ 0 - 2
TEAMModelOS/ClientApp/src/components/questionnaire/BaseSingle.less

@@ -95,12 +95,10 @@
 		        position: absolute;
 		        top: -42px;
 		        left: 0px;
-		        height: 32px;
 		        line-height: 20px;
 		        visibility: hidden;
 		        font-size: 12px;
 		        width: 100%;
-		        background: #6c6c6c !important;
 		    }
 		}
 		

+ 11 - 26
TEAMModelOS/ClientApp/src/components/questionnaire/BaseSingle.vue

@@ -19,7 +19,7 @@
 	</div>
 </template>
 <script>
-	import E from '@/utils/wangEditor.js'
+	import E from 'wangeditor'
 	import IconText from '@/components/evaluation/IconText.vue'
 	export default {
 		components: {
@@ -37,10 +37,6 @@
 				stemContent: '',
 				optionsContent: [],
 				optionEditors: [],
-				defaultConfig: {
-					uploadImgShowBase64: true,
-					menus: this.$tools.wangEditorMenuSimple
-				}
 			}
 		},
 		created() {},
@@ -60,11 +56,10 @@
 					this.options.forEach((item, i) => {
 						let that = this
 						let editor = new E(that.$refs['singleOption' + i][0])
-						editor.customConfig = this.defaultConfig
-						editor.customConfig.uploadVideoDisable = true,
+						editor.config.uploadVideoDisable = true,
 
 							// 选项编辑器失焦隐藏工具栏
-							editor.customConfig.onblur = function() {
+							editor.config.onblur = function() {
 								let allToolbars = document.getElementsByClassName('qn-option-editor')
 								for (let i = 0; i < allToolbars.length; i++) {
 									if (allToolbars[i].children.length) {
@@ -73,12 +68,9 @@
 								}
 							}
 
-						editor.customConfig.onVideoWarning = (text) => {
-								this.$Message.warning(text)
-							},
 
 							// 选项编辑器内容发生变化时
-							editor.customConfig.onchange = (html) => {
+							editor.config.onchange = (html) => {
 								let key = String.fromCharCode(64 + parseInt(i + 1))
 								let codeArr = this.optionsContent.map(item => item.code)
 								// 如果已经编辑过则 修改选项内容
@@ -120,9 +112,7 @@
 					})
 					this.$nextTick(() => {
 						let editor = new E(that.$refs['singleOption' + newIndex][0])
-						editor.customConfig = this.defaultConfig
-
-						editor.customConfig.onchange = (html) => {
+						editor.config.onchange = (html) => {
 							let key = String.fromCharCode(64 + parseInt(newIndex + 1))
 							let codeArr = this.optionsContent.map(item => item.code)
 							// 如果已经编辑过则 修改选项内容
@@ -205,26 +195,21 @@
 				}
 				setTimeout(function() {
 					let currentToolBar = that.$refs['singleOption' + index][0].children[0]
+					if(currentToolBar.clientWidth < 700){
+						currentToolBar.style.top = '-90px'
+					}
 					currentToolBar.style.visibility = 'visible'
 				}, 100)
 			},
 		},
 		mounted() {
 			let stemEditor = new E(this.$refs.singleEditor)
-			stemEditor.customConfig = this.defaultConfig
-			stemEditor.customConfig.uploadVideoDisable = false
-			stemEditor.customConfig.onchange = (html) => {
+			stemEditor.config.uploadVideoDisable = false
+			stemEditor.config.onchange = (html) => {
 				this.stemContent = html
 			}
-			stemEditor.customConfig.onVideoWarning = (text) => {
-					this.$Message.warning(text)
-				},
 
-				// 选择视频文件后的上传Blob操作
-				stemEditor.customConfig.onVideoSelected = async (file) => {
-						this.$tools.doUploadVideo(this, file, stemEditor)
-					},
-					stemEditor.create()
+			stemEditor.create()
 			this.stemEditor = stemEditor
 			this.initEditors()
 

+ 1 - 12
TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.less

@@ -187,16 +187,12 @@
         border-color: @borderColor !important;
         margin-top: 10px;
         z-index: 1 !important;
-
-        .w-e-menu {
-            z-index: 2 !important;
-        }
     }
 
     .w-e-text-container {
         background: #3b3b3b;
         border-color: @borderColor !important;
-        z-index: 1 !important;
+       z-index: 0 !important;
     }
 
     .w-e-text {
@@ -221,10 +217,6 @@
         }
     }
 
-    .w-e-toolbar .w-e-menu:hover i {
-        color: #fff;
-    }
-
     .option-editor-wrap {
         position: relative;
         margin-top: 10px;
@@ -276,12 +268,9 @@
             position: absolute;
             top: -42px;
             left: 0px;
-            height: 32px;
-            line-height: 20px;
             visibility: hidden;
             font-size: 12px;
             width: 100%;
-            background: #6c6c6c !important;
         }
     }
 

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

@@ -65,7 +65,7 @@
     </div>
 </template>
 <script>
-    import E from '@/utils/wangEditor.js'
+    import E from 'wangeditor'
     export default {
         props: {
             editItem: {
@@ -240,11 +240,9 @@
                         this.voteOptions.forEach((item, i) => {
                             let that = this
                             let editor = new E(that.$refs['voteOption' + i][0])
-                            editor.customConfig = this.defaultConfig
-
 
                             // 选项编辑器失焦隐藏工具栏
-                            editor.customConfig.onblur = function () {
+                            editor.config.onblur = function () {
                                 let allToolbars = document.getElementsByClassName('option-editor')
                                 for (let i = 0; i < allToolbars.length; i++) {
                                     if (allToolbars[i].children.length) {
@@ -254,7 +252,7 @@
                             }
 
                             // 选项编辑器内容发生变化时
-                            editor.customConfig.onchange = (html) => {
+                            editor.config.onchange = (html) => {
                                 let key = String.fromCharCode(64 + parseInt(i + 1))
                                 let codeArr = this.voteOptionsContent.map(item => item.code)
                                 // 如果已经编辑过则 修改选项内容
@@ -289,6 +287,10 @@
                 }
                 setTimeout(function () {
                     let currentToolBar = that.$refs['voteOption' + index][0].children[0]
+					console.log(currentToolBar.clientWidth)
+					if(currentToolBar.clientWidth < 700){
+						currentToolBar.style.top = '-90px'
+					}
                     currentToolBar.style.visibility = 'visible'
                 }, 100)
             },
@@ -314,9 +316,8 @@
                     this.voteOptions.push(newIndex)
                     this.$nextTick(() => {
                         let editor = new E(that.$refs['voteOption' + newIndex][0])
-                        editor.customConfig = this.defaultConfig
 
-                        editor.customConfig.onchange = (html) => {
+                        editor.config.onchange = (html) => {
                             let key = String.fromCharCode(64 + parseInt(newIndex + 1))
                             let codeArr = this.voteOptionsContent.map(item => item.code)
                             // 如果已经编辑过则 修改选项内容
@@ -458,8 +459,7 @@
         mounted() {
             //this.initEditors()
             let descriptionEditor = new E(this.$refs.descriptionEditor)
-            descriptionEditor.customConfig = this.defaultConfig
-            descriptionEditor.customConfig.onchange = (html) => { this.voteForm.description = html }
+            descriptionEditor.config.onchange = (html) => { this.voteForm.description = html }
             descriptionEditor.create()
             this.descriptionEditor = descriptionEditor
 
@@ -510,6 +510,6 @@
     }
 </script>
 
-<style lang="less" scoped>
+<style lang="less">
 @import "./BaseVoteForm.less";
 </style>

+ 1 - 1
TEAMModelOS/ClientApp/src/components/vote/BaseVoteTable.vue

@@ -119,6 +119,6 @@
     }
 </script>
 
-<style lang="less" scoped>
+<style lang="less">
     @import "./BaseVoteTable.less";
 </style>

+ 17 - 0
TEAMModelOS/ClientApp/src/css/dark-el-cascader.less

@@ -0,0 +1,17 @@
+.dark-el-cascader {
+    .el-cascader__search-input {
+        background: none;
+        margin-left: 10px;
+        color:white;
+    }
+
+    .el-input__inner::placeholder {
+        color: transparent;
+    }
+
+    .el-input__inner {
+        background: none;
+        border-color: #303030;
+        padding-left: 10px;
+    }
+}

+ 5 - 0
TEAMModelOS/ClientApp/src/css/site.css

@@ -133,6 +133,11 @@ html[white]{ /*白色主題*/
 		display: none;
 	}
 	
+	.w-e-toolbar .w-e-menu{
+		padding: 0 !important;
+		width: 30px !important;
+	}
+	
 	.richText-audio .audio-info{
 		padding: 8px;
 		background-color: #f1f3f4;

+ 1 - 0
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -209,4 +209,5 @@
     @import '../css/dark-iview-card.less';
     @import '../css/dark-iview-poptip.less';
     @import '../css/dark-iview-checkbox.less';
+    @import '../css/dark-el-cascader.less';
 </style>

+ 6 - 4
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -27,7 +27,7 @@
 					</div>
 					<div class="paper-item-tools">
 						<span class="paper-item-tools-edit" @click="onPreviewPaper(paper)">
-							<Icon type="ios-create" />
+							<Icon type="md-eye" />
 							<span>预览</span>
 						</span>
 						<span class="paper-item-tools-edit" @click="goToPaper(paper)" v-if="($access.can('admin.*||exercise-upd') || !isSchool)">
@@ -46,7 +46,7 @@
 				 @on-change="pageChange" :page-size-opts="[5,10,15,20]" />
 			</div>
 			
-			<div class="pl-review-wrap" v-if="isPreview">
+			<div class="pl-review-wrap animated fadeIn" v-if="isPreview">
 				<div class="pl-review-wrap-left">
 					<TestPaper :paper="evaluationInfo" isPreview></TestPaper>
 				</div>
@@ -57,9 +57,11 @@
 						返回列表
 						</p>
 					<h2>试卷分析</h2>
-					<p>(总分:{{ evaluationInfo.score }} 分)</p>
+					<p style="margin-bottom: 20px;margin-top: 10px;">(总分:{{ evaluationInfo.score }} 分)</p>
 					<BaseTypePie :echartsData="evaluationInfo"></BaseTypePie>
-					<!-- <BaseObjectivePie :echartsData="evaluationInfo"></BaseObjectivePie> -->
+					<BaseObjectivePie :echartsData="evaluationInfo"></BaseObjectivePie>
+					<BaseDiffPie :echartsData="evaluationInfo"></BaseDiffPie>
+					<BasePointPie :echartsData="evaluationInfo"></BasePointPie>
 				</div>
 			</div>
 

+ 106 - 0
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseDiffPie.vue

@@ -0,0 +1,106 @@
+<template>
+    <div id="myDiffPie"></div>
+</template>
+
+<script>
+    export default {
+        name: 'BaseDiffPie',
+        props: ['pieId','echartsData'],
+        data() {
+            return {
+                pieData: [],
+				types:['容易','较易','一般','较难','困难']
+            }
+        },
+        methods: {
+
+            drawLine(data) {
+                let that = this
+                // 基于准备好的dom,初始化echarts实例
+                let myPie = this.$echarts.init(document.getElementById('myDiffPie'), 'chalk')
+
+                // 指定图表的配置项和数据
+                var option = {
+                    title: {
+                        'text': '试卷难度分析图',
+                        'left': 'center',
+                        'textStyle': {
+                            'fontSize': 14,
+                            'color': '#595959'
+                        }
+                    },
+					legend: {
+						left: 'center',
+						bottom: 24,
+						itemWidth: 15,
+						itemHeight: 11,
+						itemGap: 20,
+						borderRadius: 4,
+						textStyle: {
+							color: '#262C41',
+							fontSize: 14
+						},
+						formatter: function (name,val) {
+						    return name + ' (' + data.filter(i => i.name === name)[0].value + '道)';
+						}
+					},
+                    color: ['#8378ea', '#e7bcf3', '#9fe6b8', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378ea'],
+                    tooltip: {
+                        trigger: 'item',
+                        formatter: '{a} <br/>{b} : {c} ({d}%)'
+                    },
+                    calculable: true,
+                    series: [
+                        {
+                            name: '题型分布饼图',
+                            type: 'pie',
+                            radius: [0, 80],
+                            data: data
+                        }
+                    ]
+                }
+
+                // 绘制图表
+                myPie.setOption(option)
+
+                window.addEventListener('resize', function() {
+                    myPie.resize()
+                })
+            }
+        },
+        mounted() {
+			let arr = []
+			let typeList = this._.groupBy(this.echartsData.item, 'level')
+			for(let key in typeList){
+				arr.push({
+					value:typeList[key].length,
+					name: this.types[+key - 1]
+				})
+			}
+			this.drawLine(arr)
+        },
+        computed: {
+            // 获取最新知识点占比饼图数据
+            getPieData() {
+                return this.$store.state.totalAnalysis.knowledgeData
+            }
+        },
+        watch: {
+            echartsData(val) {
+
+            }
+        }
+
+    }
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+
+    #myDiffPie {
+        width: 100%;
+        height: 300px;
+        margin: 20px auto;
+        display: block;
+    }
+</style>

+ 25 - 19
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseObjectivePie.vue

@@ -1,10 +1,10 @@
 <template>
-    <div id="myTypePie"></div>
+    <div id="myObjectivePie"></div>
 </template>
 
 <script>
     export default {
-        name: 'BaseTypePie',
+        name: 'BaseObjectivePie',
         props: ['pieId','echartsData'],
         data() {
             return {
@@ -24,20 +24,34 @@
             drawLine(data) {
                 let that = this
                 // 基于准备好的dom,初始化echarts实例
-                let myPie = this.$echarts.init(document.getElementById('myTypePie'), 'chalk')
+                let myPie = this.$echarts.init(document.getElementById('myObjectivePie'), 'chalk')
 
                 // 指定图表的配置项和数据
                 var option = {
                     title: {
-                        'text': '试卷主观客观分布图',
-                        'bottom': '5%',
-                        'left': '35%',
+                        'text': '试卷难度分析图',
+                        'left': 'center',
                         'textStyle': {
                             'fontSize': 14,
                             'color': '#595959'
                         }
                     },
-                    color: ['#37a2da', '#e7bcf3', '#9fe6b8', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378ea'],
+					legend: {
+						left: 'center',
+						bottom: 24,
+						itemWidth: 15,
+						itemHeight: 11,
+						itemGap: 20,
+						borderRadius: 4,
+						textStyle: {
+							color: '#262C41',
+							fontSize: 14
+						},
+						formatter: function (name,val) {
+						    return name + ' (' + data.filter(i => i.name === name)[0].value + '道)';
+						}
+					},
+                    color: ['#ff9f7f', '#37d2da','#37d2da', '#ff9f7f', '#d4e676', '#ff9f7f', '#fb7293'],
                     tooltip: {
                         trigger: 'item',
                         formatter: '{a} <br/>{b} : {c} ({d}%)'
@@ -47,7 +61,7 @@
                         {
                             name: '题型分布饼图',
                             type: 'pie',
-                            radius: [20, 100],
+                            radius: [0, 80],
                             data: data
                         }
                     ]
@@ -80,7 +94,6 @@
 				name:'客观题',
 				value:objectiveCount
 			}]
-			console.log(arr)
 			this.drawLine(arr)
         },
         computed: {
@@ -91,14 +104,7 @@
         },
         watch: {
             echartsData(val) {
-    //             if (!val) return
-				// console.log('接收到图 表信息')
-				// console.log(val)
-				// let typeList = this._.groupBy(val.item, 'type')
-				// for(let key in typeList){
-				// 	console.log(key)
-				// }
-    //             this.drawLine(val)
+
             }
         }
 
@@ -108,9 +114,9 @@
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped>
 
-    #myTypePie {
+    #myObjectivePie {
         width: 100%;
-        height: 380px;
+        height: 300px;
         margin: 20px auto;
         display: block;
     }

+ 119 - 0
TEAMModelOS/ClientApp/src/view/evaluation/components/BasePointPie.vue

@@ -0,0 +1,119 @@
+<template>
+	<div id="myPointPie"></div>
+</template>
+
+<script>
+	export default {
+		name: 'BasePointPie',
+		props: ['pieId', 'echartsData'],
+		data() {
+			return {
+				pieData: [],
+				types: ['容易', '较易', '一般', '较难', '困难']
+			}
+		},
+		methods: {
+
+			drawLine(data) {
+				let that = this
+				// 基于准备好的dom,初始化echarts实例
+				let myPie = this.$echarts.init(document.getElementById('myPointPie'), 'chalk')
+
+				// 指定图表的配置项和数据
+				var option = {
+					title: {
+						'text': '试卷知识点分析图',
+						'left': 'center',
+						'textStyle': {
+							'fontSize': 14,
+							'color': '#595959'
+						}
+					},
+					legend: {
+						left: 'center',
+						bottom: 24,
+						itemWidth: 15,
+						itemHeight: 11,
+						itemGap: 20,
+						borderRadius: 4,
+						textStyle: {
+							color: '#262C41',
+							fontSize: 14
+						},
+						formatter: function(name, val) {
+							return name + ' (' + data.filter(i => i.name === name)[0].value + '道)';
+						}
+					},
+					color: [
+						"#4ea397",
+						"#22c3aa",
+						"#7bd9a5",
+						"#d0648a",
+						"#f58db2",
+						"#f2b3c9"
+					],
+					tooltip: {
+						trigger: 'item',
+						formatter: '{a} <br/>{b} : {c} ({d}%)'
+					},
+					calculable: true,
+					series: [{
+						name: '题型分布饼图',
+						type: 'pie',
+						radius: [0, 80],
+						data: data
+					}]
+				}
+
+				// 绘制图表
+				myPie.setOption(option)
+
+				window.addEventListener('resize', function() {
+					myPie.resize()
+				})
+			}
+		},
+		mounted() {
+			let arr = []
+			let typeList = this._.groupBy(this.echartsData.item, 'points')
+			console.log(typeList)
+			for (let key in typeList) {
+				if (key === '') {
+					arr.push({
+						value: typeList[key].length,
+						name: '未绑定知识点'
+					})
+				} else {
+					arr.push({
+						value: typeList[key].length,
+						name: key
+					})
+				}
+
+			}
+			this.drawLine(arr)
+		},
+		computed: {
+			// 获取最新知识点占比饼图数据
+			getPieData() {
+				return this.$store.state.totalAnalysis.knowledgeData
+			}
+		},
+		watch: {
+			echartsData(val) {
+
+			}
+		}
+
+	}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+	#myPointPie {
+		width: 100%;
+		height: 300px;
+		margin: 20px auto;
+		display: block;
+	}
+</style>

+ 18 - 12
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseTypePie.vue

@@ -30,13 +30,26 @@
                 var option = {
                     title: {
                         'text': '试卷题型分布图',
-                        'bottom': '5%',
-                        'left': '35%',
+                        'left': 'center',
                         'textStyle': {
                             'fontSize': 14,
                             'color': '#595959'
                         }
                     },
+					legend: {
+						left: 'center',
+						bottom: 0,
+						itemWidth: 15,
+						itemHeight: 11,
+						borderRadius: 4,
+						textStyle: {
+							color: '#262C41',
+							fontSize: 14
+						},
+						formatter: function (name,val) {
+						    return name + ' (' + data.filter(i => i.name === name)[0].value + '道)';
+						}
+					},
                     color: ['#37a2da', '#e7bcf3', '#9fe6b8', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378ea'],
                     tooltip: {
                         trigger: 'item',
@@ -47,7 +60,7 @@
                         {
                             name: '题型分布饼图',
                             type: 'pie',
-                            radius: [20, 100],
+                            radius: [0, 80],
                             data: data
                         }
                     ]
@@ -80,14 +93,7 @@
         },
         watch: {
             echartsData(val) {
-    //             if (!val) return
-				// console.log('接收到图 表信息')
-				// console.log(val)
-				// let typeList = this._.groupBy(val.item, 'type')
-				// for(let key in typeList){
-				// 	console.log(key)
-				// }
-    //             this.drawLine(val)
+
             }
         }
 
@@ -99,7 +105,7 @@
 
     #myTypePie {
         width: 100%;
-        height: 380px;
+        height: 320px;
         margin: 20px auto;
         display: block;
     }

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

@@ -154,8 +154,6 @@ exersices-attr-diff {
         position:absolute;
         top:-40px;
         left:0px;
-        height: 40px;
-		
         line-height: 20px;
         visibility:hidden;
         font-size: 12px;

+ 4 - 1
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompletion.vue

@@ -69,7 +69,10 @@
                 }
                 setTimeout(function() {
                     let currentToolBar = that.$refs['editor' + index][0].children[0]
-                    currentToolBar.style.visibility = 'visible'
+                    if(currentToolBar.clientWidth < 700){
+                    	currentToolBar.style.top = '-90px'
+                    }
+					currentToolBar.style.visibility = 'visible'
                 }, 100)
             },
 

+ 3 - 0
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue

@@ -260,6 +260,9 @@
 				}
 				setTimeout(function() {
 					let currentToolBar = that.$refs['singleOption' + index][0].children[0]
+					if(currentToolBar.clientWidth < 700){
+						currentToolBar.style.top = '-90px'
+					}
 					currentToolBar.style.visibility = 'visible'
 				}, 100)
 			},

+ 3 - 0
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue

@@ -229,6 +229,9 @@
 				}
 				setTimeout(function() {
 					let currentToolBar = that.$refs['singleOption' + index][0].children[0]
+					if(currentToolBar.clientWidth < 700){
+						currentToolBar.style.top = '-90px'
+					}
 					currentToolBar.style.visibility = 'visible'
 				}, 100)
 			}

+ 17 - 13
TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.less

@@ -30,7 +30,7 @@
             float: right;
             cursor: pointer;
             margin-top: 6px;
-            margin-right: 40px;
+            margin-right: 10px;
         }
     }
 
@@ -72,27 +72,30 @@
 
             p {
                 display: inline-block;
-                margin-right: 25px;
+                margin-right: 5px;
             }
 
             .subject-item {
                 display: inline-block;
-                margin-right: 30px;
                 color: @second-textColor;
                 cursor: pointer;
                 line-height: 39px;
-                min-width: 50px;
+                padding:0px 20px;
                 font-size: 16px;
                 text-align: center;
+                position: relative;
 
                 .delete-subject-btn {
-                    width: 0px;
-                    transition: all ease 0.2s;
-                    overflow: hidden;
+                    position: absolute;
+                    display: none;
+                    color:white;
+                    font-size:18px;
+                    top:10px;
+                    right:0px;
                 }
 
                 &:hover .delete-subject-btn {
-                    width: 18px;
+                    display: inline-block;
                 }
             }
 
@@ -101,9 +104,9 @@
                 border-bottom: 2px solid white;
                 font-weight: 600;
 
-                .delete-subject-btn {
-                    width: 18px;
-                }
+                /*.delete-subject-btn {
+                    display: inline-block;
+                }*/
             }
         }
     }
@@ -141,8 +144,9 @@
 }
 
 .add-subject-icon {
-    /*float: right;*/
-    /*margin-right: 50px;*/
+    margin-left:15px;
+    color:white;
+    font-size:16px;
     margin-top: 8px;
     cursor: pointer;
 }

+ 24 - 32
TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.vue

@@ -2,13 +2,13 @@
     <div class="create-evaluation-container">
         <div class="create-header">
             <p class="create-header-title" @click="consData">创建评测活动</p>
-            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveEvaluation">发布评测</Button>
+            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveEvaluation" style="margin-right:30px;">发布评测</Button>
             <Button class="btn-save" type="text"  ghost icon="md-arrow-back" @click="confirmToManage">返回上级</Button>
         </div>
         <div class="create-body">
             <div class="evaluation-attr-wrap">
                 <p class="wrap-label">基础信息</p>
-                <div style="width:100%; height:calc(100% - 45px);padding-top:30px;" class="dark-iview-form ivu-select-nochoose">
+                <div style="width:100%; height:calc(100% - 45px);padding-top:30px;" class="dark-iview-form ivu-select-nochoose dark-el-cascader">
                     <Form ref="evaluationInfo" :model="evaluationInfo" label-position="top" class="evaluation-attr-form " label-colon :rules="ruleValidate">
                         <FormItem label="评测名称" prop="name">
                             <Input v-model="evaluationInfo.name" placeholder="评测名称" @on-change="handlePaperName"></Input>
@@ -34,9 +34,7 @@
                             </Select>
                         </FormItem>
                         <FormItem label="施测对象">
-                            <!--<select-tree v-model="queryVal" multiple :treeData="selectData" @on-select-change="selectChange"></select-tree>-->
-                            <el-cascader size="small" clearable filterable v-model="queryVal" :options="curGrades" :props="props" @change="treeChange" collapse-tags placeholder="请先选择学段" style="width:100%;">
-                                <p slot="empty">暂无数据</p>
+                            <el-cascader size="small" :show-all-levels="false" clearable filterable v-model="queryVal" :options="curGrades" :props="props" @change="treeChange"  style="width:100%;">
                             </el-cascader>
                         </FormItem>
                         <FormItem label="发布方式" prop="publish">
@@ -59,38 +57,36 @@
             <div class="evaluation-question-wrap">
                 <div class="wrap-label" v-if="mode == 'school'">
                     <p>测试科目:</p>
-                    <span v-for="(item,index) in evaluationInfo.paperInfo" :key="index" :class="index == currentSubjectIndex ? 'subject-item subject-item-active':'subject-item'" @click="selectSubject(index)">
+                    <span v-for="(item,index) in evaluationInfo.paperInfo" :key="index" :class="index == curSubIndex ? 'subject-item subject-item-active':'subject-item'" @click="selectSubject(index)">
                         {{item.subjectName}}
                         <Icon type="ios-close" size="18" class="delete-subject-btn" @click="deleteSubject(index)" />
                     </span>
-                    <Icon @click="addSubject" type="md-add-circle" title="添加科目" color="white" class="add-subject-icon" size="20" />
+                    <Icon @click="addSubject" type="md-add" title="添加科目" class="add-subject-icon"/>
                 </div>
                 <div class="evaluation-question-main">
                     <EmptyData :top="0" style="padding-top:100px;" v-if="evaluationInfo.paperInfo.length == 0" textContent="暂无科目,请添加科目"></EmptyData>
                     <div class="create-type-wrap" v-if="evaluationInfo.paperInfo.length > 0 || mode == 'class'" >
                         <span>创建方式:</span>
-                        <RadioGroup v-model="evaluationInfo.paperInfo[currentSubjectIndex].createType" style="margin-left:25px;" @on-change="setActiveTab">
+                        <RadioGroup v-model="evaluationInfo.paperInfo[curSubIndex].createType" style="margin-left:25px;" @on-change="setActiveTab">
                             <Radio label="manualPaper">手动挑卷</Radio>
                             <Radio label="import">试卷导入</Radio>
                         </RadioGroup>
                     </div>
-
-
                     <Tabs v-model="activeTab" type="card" class="question-main-tabs" v-if="evaluationInfo.paperInfo.length > 0 || mode == 'class' " name="createTest">
-                        <!--<TabPane label="组题条件" name="auto" v-if="evaluationInfo.paperInfo[currentSubjectIndex].createType == 'auto'" :index="1" tab="createTest">
-                            <AutoCreate :subjectCode="evaluationInfo.paperInfo[currentSubjectIndex].subjectCode" :periodCode="evaluationInfo.paperInfo[currentSubjectIndex].periodCode" @goToPreview="goToPreview" @autoQuestions="getAutoQuestions"></AutoCreate>
+                        <!--<TabPane label="组题条件" name="auto" v-if="evaluationInfo.paperInfo[curSubIndex].createType == 'auto'" :index="1" tab="createTest">
+                            <AutoCreate :subjectCode="evaluationInfo.paperInfo[curSubIndex].subjectCode" :periodCode="evaluationInfo.paperInfo[curSubIndex].periodCode" @goToPreview="goToPreview" @autoQuestions="getAutoQuestions"></AutoCreate>
                         </TabPane>-->
-                        <!--<TabPane label="备选题目" name="manualQuestion" v-if="evaluationInfo.paperInfo[currentSubjectIndex].createType == 'manualQuestion'" :index="2" tab="createTest">
+                        <!--<TabPane label="备选题目" name="manualQuestion" v-if="evaluationInfo.paperInfo[curSubIndex].createType == 'manualQuestion'" :index="2" tab="createTest">
                             <ManualCreate @goToPreview="goToPreview" @selectedQuestion="getSelectedQuestion"></ManualCreate>
                         </TabPane>-->
-                        <TabPane label="备选试卷" name="manualPaper" v-if="evaluationInfo.paperInfo[currentSubjectIndex].createType == 'manualPaper'" :index="3" tab="createTest">
-                            <ManualPaper :periodCode="evaluationInfo.paperInfo[currentSubjectIndex].periodCode" :subjectCode="evaluationInfo.paperInfo[currentSubjectIndex].subjectCode" @selectPaper="selectPaper"></ManualPaper>
+                        <TabPane label="备选试卷" name="manualPaper" v-if="evaluationInfo.paperInfo[curSubIndex].createType == 'manualPaper'" :index="3" tab="createTest">
+                            <ManualPaper :periodId="evaluationInfo.period.id" :gradesObj="evaluationInfo.grades" :subjectId="evaluationInfo.paperInfo[curSubIndex].subjectId" @selectPaper="selectPaper"></ManualPaper>
                         </TabPane>
-                        <TabPane label="导入说明" name="import" v-if="evaluationInfo.paperInfo[currentSubjectIndex].createType == 'import'" :index="4" tab="createTest">
+                        <TabPane label="导入说明" name="import" v-if="evaluationInfo.paperInfo[curSubIndex].createType == 'import'" :index="4" tab="createTest">
                             <ImportCreate @importedQuestions="getImportQuestions" @goToPreview="goToPreview"></ImportCreate>
                         </TabPane>
                         <TabPane label="试题预览" name="preview" :index="5" tab="createTest">
-                            <TeacherPreview :testPaper="evaluationInfo.paperInfo[currentSubjectIndex]" :examAnalysisStatus="examAnalysisStatus"></TeacherPreview>
+                            <TeacherPreview :testPaper="evaluationInfo.paperInfo[curSubIndex]" :examAnalysisStatus="examAnalysisStatus"></TeacherPreview>
                         </TabPane>
                         <TabPane label="学生作答体验" name="student" :index="6" tab="createTest">
                             <StudentPreview></StudentPreview>
@@ -114,6 +110,7 @@
                         <span>{{subjectItem.name}}</span>
                     </Checkbox>
                 </CheckboxGroup>
+                <p v-if="!evaluationInfo.period.id" style="color:white; text-align:center;">* 请先选择测试学段</p>
         </Modal>
         <Modal v-model="goToManageStatus"
                title="管理评测"
@@ -135,7 +132,6 @@
 <script>
     import AutoCreate from './AutoCreate.vue'
     import MultiCascader from './MultiCascader.vue'
-    import SelectTree from './SelectedTree.vue'
     import ManualCreate from './ManualCreate.vue'
     import ManualPaper from './ManualPaper.vue'
     import ImportCreate from './ImportCreate.vue'
@@ -150,7 +146,6 @@
             ImportCreate,
             ManualPaper,
             MultiCascader,
-            SelectTree
         },
         data() {
             const _this = this
@@ -162,7 +157,6 @@
                     lazy: true,
                     //动态获取当前年级下面的班级数据
                     lazyLoad: function (node, resolve) {
-                        console.log('node', node)
                         let level = -1
                         if (node) {
                             level = node.level
@@ -250,7 +244,7 @@
                 },
                 deleteIndex: -1,
                 activeTab: 'manualPaper',
-                currentSubjectIndex: 0,
+                curSubIndex: 0,
                 evaluationInfo: {
                     name: '',
                     targetClassIds: [],
@@ -314,7 +308,6 @@
             },
             //设置考试类型名称
             setExamTypeName(data) {
-                console.log(data)
                 this.evaluationInfo.examType.name = data.label
             },
             //设置学段名称
@@ -372,9 +365,9 @@
                 this.confirmPaperStatus = true
             },
             comfirmSelectPaper() {
-                this.evaluationInfo.paperInfo[this.currentSubjectIndex] = JSON.parse(JSON.stringify(this.selectedPaper))
-                this.evaluationInfo.papers[this.currentSubjectIndex] = JSON.parse(JSON.stringify(this.selectedPaperInfo))
-                this.evaluationInfo.paperInfo[this.currentSubjectIndex].id = undefined
+                this.evaluationInfo.paperInfo[this.curSubIndex] = JSON.parse(JSON.stringify(this.selectedPaper))
+                this.evaluationInfo.papers[this.curSubIndex] = JSON.parse(JSON.stringify(this.selectedPaperInfo))
+                this.evaluationInfo.paperInfo[this.curSubIndex].id = undefined
                 this.goToPreview()
             },
 
@@ -395,15 +388,15 @@
              * @param questions
              */
             getImportQuestions(questions) {
-                if (this.evaluationInfo.paperInfo[this.currentSubjectIndex].item != undefined) {
-                    this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = [...questions, ...this.evaluationInfo.paperInfo[this.currentSubjectIndex].item]
+                if (this.evaluationInfo.paperInfo[this.curSubIndex].item != undefined) {
+                    this.evaluationInfo.paperInfo[this.curSubIndex].item = [...questions, ...this.evaluationInfo.paperInfo[this.curSubIndex].item]
                 } else {
-                    this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = [...questions]
+                    this.evaluationInfo.paperInfo[this.curSubIndex].item = [...questions]
                 }
             },
             goToPreview() {
                 this.activeTab = 'preview'
-                this.evaluationInfo.paperInfo[this.currentSubjectIndex].createType = 'manualPaper'
+                this.evaluationInfo.paperInfo[this.curSubIndex].createType = 'manualPaper'
             },
             checkIsDisabled(code) {
                 return this.evaluationInfo.subjectIds.indexOf(code) !== -1
@@ -424,7 +417,7 @@
                             this.evaluationInfo.subjects.splice(this.deleteIndex, 1)
                             this.evaluationInfo.subjectIds.splice(this.deleteIndex, 1)
                             this.evaluationInfo.paperInfo.splice(this.deleteIndex, 1)
-                            this.currentSubjectIndex = 0
+                            this.curSubIndex = 0
                             this.deleteIndex = -1
                             this.$Message.success('删除成功!')
                         }
@@ -475,7 +468,7 @@
                 }
             },
             selectSubject(index) {
-                this.currentSubjectIndex = index
+                this.curSubIndex = index
                 this.activeTab = this.evaluationInfo.paperInfo[index].createType
             },
             checkData() {
@@ -681,7 +674,6 @@
                     let res = this.schoolBase.period.filter((item) => {
                         return item.id == this.evaluationInfo.period.id
                     })
-                    console.log('grades', res)
                     if (res.length > 0) {
                         return res[0].grades
                     } else {

+ 1 - 1
TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.less

@@ -51,7 +51,7 @@
     margin-bottom: 5px;
     background: #505050;
     align-items: start;
-    border-radius: 5px;
+    border-radius: 2px;
     cursor: pointer;
     position: relative;
 

+ 69 - 74
TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue

@@ -6,20 +6,10 @@
                     <Col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                     <div class="manual-filter-item">
                         <span class="manual-filter-label">来源:</span>
-                        <CheckboxGroup v-model="manualFilter.code" style="display:inline-block;" @on-change="checkAll($event,'code')">
-                            <Checkbox label="all">全部</Checkbox>
-                            <Checkbox :label="$store.state.userInfo.TEAMModelId">个人题库</Checkbox>
-                            <Checkbox :label="$store.state.userInfo.schoolCode">校本题库</Checkbox>
-                        </CheckboxGroup>
-                    </div>
-                    </Col>
-                    <Col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                    <div class="manual-filter-item">
-                        <span class="manual-filter-label">学段:</span>
-                        <CheckboxGroup v-model="manualFilter.gradeCode" style="display: inline-block;" @on-change="checkAll($event,'gradeCode')">
-                            <Checkbox label="all">全部</Checkbox>
-                            <Checkbox v-for="(item,index) in $store.state.user.schoolProfile.periods" :key="index" :label="item.id">{{item.name}}</Checkbox>
-                        </CheckboxGroup>
+                        <RadioGroup v-model="scope" style="display:inline-block;" @on-change="checkFirst">
+                            <Radio  :label="$store.state.userInfo.TEAMModelId">个人题库</Radio>
+                            <Radio  :label="$store.state.userInfo.schoolCode">校本题库</Radio>
+                        </RadioGroup>
                     </div>
                     </Col>
                 </Row>
@@ -28,11 +18,10 @@
                 <Loading :top="100" v-show="isLoading"></Loading>
                 <div class="paper-item" v-for="(item,index) in paperList" :key="index">
                     <div class="paper-item-name">
-                        <!--<span class="paper-item-tag">{{ getSubjectName(paper.subjectCode) }}</span>-->
                         <span>{{(index + 1) + '.  ' + item.name}}</span>
                     </div>
                     <div class="paper-item-info">
-                        <span class="info-item">适用学段:<span class="info-bold">{{$jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo.period,item.periodId).name}}</span></span>
+                        <span class="info-item">适用学段:<span class="info-bold">{{$jsFn.getPeriod(schoolBase.period,item.periodId).name}}</span></span>
                         <span class="info-item">适用科目:<span class="info-bold">{{item.subjectName}}</span></span>
                         <span class="info-item">题量:<span class="info-bold">{{ item.scoring.length > 0 ? item.scoring.length : 0 }}</span></span>
                         <span class="info-item">使用次數:<span class="info-bold">{{item.useCount}}</span></span>
@@ -45,7 +34,7 @@
                 <EmptyData v-if="paperList.length == 0" style="margin-top:100px;" textContent="暂无对应的试卷"></EmptyData>
             </div>
             <div class="page-wrap">
-                <Page :current.sync="currentPage" :total="totalNum" show-total :page-size="pageSize" size="small" show-sizer @on-change="getCurrentPageData" />
+                <Page :current.sync="currentPage" :total="paperList.length" show-total :page-size="pageSize" size="small" show-sizer @on-change="getCurrentPageData" />
             </div>
         </vuescroll>
         <Modal v-model="previewStatus"
@@ -56,24 +45,30 @@
     </div>
 </template>
 <script>
-    import Loading from '@/common/Loading.vue'
     import TestPaper from '@/view/evaluation/index/TestPaper.vue'
     export default {
         components: {
-            Loading,TestPaper
+            TestPaper
         },
         props: {
-            periodCode: {
+            periodId: {
                 type: String,
                 default: ''
             },
-            subjectCode: {
+            subjectId: {
                 type: String,
                 defualt: ''
+            },
+            gradesObj: {
+                type: Array,
+                defualt: []
             }
         },
         data() {
             return {
+                schoolBase: {
+                    period:[]
+                },
                 previewStatus: false,
                 previewPaper: {
                     name: '暂无试卷',
@@ -81,14 +76,14 @@
                     item:[]
                 },
                 isLoading: false,
-                totalNum:0,
                 pageSize: 10,
                 currentPage: 1,
                 dataLoading: false,
                 paperList: [],
-                manualFilter: {
-                    code: ['all'],
-                    gradeCode: ['all'],
+                scope: '',
+                allPaper: {
+                    private: undefined,
+                    school: undefined
                 }
             }
         },
@@ -115,75 +110,75 @@
                 this.previewPaper = data
                 this.previewStatus = true
             },
-            /**
-             * 获取试卷库数量
-             */
-            //getResultCount() {
-            //    let findCountParams = {
-            //        "collectionName": "Paper",
-            //        "queryDict": {
-            //            'code': this.deleteAll(this.manualFilter.code),
-            //            'periodCode': this.periodCode,
-            //            'gradeCode': this.deleteAll(this.manualFilter.gradeCode),
-            //            'subjectCode': this.subjectCode
-            //        }
-            //    }
-            //    this.$api.newEvaluation.FindCount(findCountParams).then(res => {
-            //        this.totalNum = res.result.data[0]
-            //    })
-            //},
             getCurrentPageData() {
                 this.getPaperList()
             },
-            /**
-             * 选择全部逻辑
-             * @param data:选中数据
-             * @param field:字段名
-             */
-            checkAll(data, field) {
-                if (this.manualFilter[field].length !== 1 && this.manualFilter[field].indexOf('all') === 0) {
-                    this.manualFilter[field].splice(this.manualFilter[field].indexOf('all'), 1)
-                } else if (this.manualFilter[field].indexOf('all') > 0) {
-                    this.manualFilter[field].length = 0
-                    this.$set(this.manualFilter[field],0,'all')
+            checkFirst() {
+                let scope = this.scope == this.$store.state.userInfo.TEAMModelId ? 'private' : 'school'
+                if (!this.allPaper[scope]) {
+                    this.getPaperList()
+                } else {
+                    if (scope == 'school') {
+                        this.paperList = this.allPaper[scope].filter(item => {
+                            return item.subjectId == this.subjectId
+                        })
+                    } else {
+                        this.paperList = this.allPaper[scope]
+                    }
                 }
-                this.getResultCount()
-                this.getPaperList()
+                
             },
             /** 获取试卷列表 */
             getPaperList() {
                 this.isLoading = true
+                let scope = this.scope == this.$store.state.userInfo.TEAMModelId ? 'private' : 'school'
                 let params = {
-                    'code': "hbcn",
-                    "scope":"school"
+                    'code': this.scope,
+                    "scope": scope,
+                    'gradeIds[*]': scope == 'school' ? this.gradeIds : undefined,
+                    'periodId': scope == 'school' ? this.periodId : undefined
                 }
                 this.$api.learnActivity.FindExamPaper(params).then(res => {
-                    this.paperList = res.papers
-                    this.totalNum = res.papers.length
+                    this.allPaper[scope] = res.papers
+                    if (this.subjectId && scope == 'school') {
+                        this.paperList = this.allPaper[scope].filter(item => {
+                            return item.subjectId == this.subjectId
+                        })
+                    } else {
+                        this.paperList = res.papers
+                    }
+                }).finally(() => {
                     setTimeout(() => {
                         this.isLoading = false
-                    }, 1000)
+                    }, 500)
                 })
             },
-            deleteAll(data) {
-                if (data.length == 1) {
-                    if (data[0] == 'all') {
-                        return []
-                    } else {
-                        return data
-                    }
-                } else {
-                    return data
-                }
-            },
         },
         created() {
-            //this.getResultCount()
+            this.scope = this.$store.state.userInfo.TEAMModelId
+            this.$store.dispatch('user/getSchoolProfile').then(
+                res => {
+                    this.schoolBase = res.school_base
+                }
+            )
             this.getPaperList()
         },
         computed: {
-            currnetPeroid() {
-                return this.$jsFn.getPeriod(this.$store.state.schoolBaseInfo.schoolBaseInfo, this.periodCode)
+            gradeIds() {
+                if (this.gradesObj) {
+                    return this.gradesObj.map(item => {
+                        return item.id
+                    })
+                } else {
+                    return []
+                }
+            }
+        },
+        watch: {
+            subjectId: {
+                handler() {
+                    this.checkFirst()
+                }
             }
         }
     }

+ 1 - 3
TEAMModelOS/Controllers/Exam/ExamController.cs

@@ -61,9 +61,7 @@ namespace TEAMModelOS.Controllers
                 //新增
                 //string code = request.code;
                 var client = _azureCosmos.GetCosmosClient();
-                ExamInfo exam;                
-                request.pk = "Exam";
-                request.ttl = -1;
+                ExamInfo exam;
                 string code = request.code;
                 request.code = "Exam-" + request.code;
 

+ 19 - 7
TEAMModelOS/Controllers/Exam/ImportExerciseController.cs

@@ -32,7 +32,7 @@ using TEAMModelOS.Servicess.PowerPoint.Implement;
 
 namespace TEAMModelOS.Controllers
 {
-    [Route("api/import")]
+    [Route("common/import")]
     [ApiController]
     public class ImportExerciseController : BaseController
     {
@@ -82,7 +82,7 @@ namespace TEAMModelOS.Controllers
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
-        [HttpPost("parse-pptx")]
+        [HttpPost("parse-doc")]
         [RequestSizeLimit(102_400_000_00)] //最大10000m左右
         public async Task<IActionResult> ParsePPTX(JsonElement request)
         {
@@ -92,23 +92,35 @@ namespace TEAMModelOS.Controllers
             //if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
             //var id = jwt.Payload.Sub;
 
-            request.TryGetProperty("code", out JsonElement code);
+            request.TryGetProperty("file", out JsonElement code);
             string azureBlobSAS = System.Web.HttpUtility.UrlDecode(code.ToString(), Encoding.UTF8);
             (string, string) a = BlobUrlString(azureBlobSAS);
             string ContainerName = a.Item1;
             string BlobName = a.Item2;
             bool flg = IsBlobName(BlobName);
             var codes = azureBlobSAS.Split("/");
-            var FileName = codes[codes.Length - 1].Split(".")[0];
+            var file = codes[codes.Length - 1].Split(".");
+            var FileName = file[0];
+            var ext = file[1];
             if (flg)
             {
-                //TODO 需驗證
                 BlobAuth blobAuth = _azureStorage.GetBlobSasUriRead(ContainerName, BlobName);
                 var response = await _clientFactory.CreateClient().GetAsync(new Uri(blobAuth.url));
                 response.EnsureSuccessStatusCode();
                 Stream stream=  await response.Content.ReadAsStreamAsync();
-                string  index = await PPTXTranslator(ContainerName, FileName, stream);
-                return Ok(new { index=index });
+
+                if (ext.ToLower() == "pptx" || ext.ToLower() == "xml")
+                {
+                    string index = await PPTXTranslator(ContainerName, FileName, stream);
+                    return Ok(new { index = index });
+                }
+                else if (ext.ToLower() == "docx" || ext.ToLower() == "doc")
+                {
+                    return Ok(new { index = "" });
+                }
+                else {
+                    return BadRequest("不支持该文件类型的解析!");
+                }
             }
             else { return BadRequest("不是正确的Blob链接!"); }
         }

+ 0 - 1
TEAMModelOS/Controllers/Exam/PaperController.cs

@@ -196,7 +196,6 @@ namespace TEAMModelOS.Controllers
             if (!request.TryGetProperty("option", out JsonElement option)) return BadRequest();
             Paper paper;
             paper = papers.ToObject<Paper>();            
-            paper.pk = "Paper";
             paper.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             if (option.ToString().Equals("insert"))
             {               

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

@@ -45,7 +45,6 @@ namespace TEAMModelOS.Controllers
             try {
                 classroom = room.ToObject<Class>();
                 var client = _azureCosmos.GetCosmosClient();                
-                classroom.pk = "Class";
                 classroom.code = "Class-" + school_code.ToString();
                 //students = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "classroomCode", classroom.id } });
                 if (option.ToString().Equals("insert"))

+ 0 - 253
TEAMModelOS/Controllers/School/ClassStudentController.cs

@@ -1,253 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using TEAMModelOS.SDK.Context.Exception;
-using TEAMModelOS.SDK;
-using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.Helper.Common.ValidateHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Models;
-using System.Text.Json;
-using TEAMModelOS.SDK.Models;
-using Azure.Cosmos;
-using TEAMModelOS.SDK.Extension;
-
-namespace TEAMModelOS.Controllers
-{
-    [ProducesResponseType(StatusCodes.Status200OK)]
-    [ProducesResponseType(StatusCodes.Status400BadRequest)]
-    //[Authorize(Roles = "IES5")]
-    [Route("student/class")]
-    [ApiController]
-    public class ClassStudentController : ControllerBase
-    {
-
-        private AzureCosmosFactory _azureCosmos;
-
-        public ClassStudentController(AzureCosmosFactory azureCosmos)
-        {
-            _azureCosmos = azureCosmos;
-        }
-
-        /// <summary>
-        ///  获取实时的学生-班级关联信息
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        //[AuthToken(Roles = "Teacher")]
-        [HttpPost("find")]
-        public async Task<IActionResult> find(JsonElement request) {
-            //ResponseBuilder builder = ResponseBuilder.custom();
-            // 班级编码
-            /*            if (request.TryGetProperty("classroomCode", out JsonElement classroomCode)
-                             && request.TryGetProperty("schoolCode", out JsonElement schoolCode)
-                            )
-                        {*/
-            if (!request.TryGetProperty("classroomCode", out JsonElement classroomCode)) return BadRequest();
-            if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
-                //List<ClassStudent> classroomStudents = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", classroomCode } });
-                var client = _azureCosmos.GetCosmosClient();
-                List<object> classrooms = new List<object>();
-                string info = "";
-                for (int i = 0; i < classroomCode.GetArrayLength(); i++)
-                {
-                    //ids.Add(id[i].ToJsonString());
-                    info += classroomCode[i].ToJsonString() + ",";
-                }
-            var query = $"select c.name, c.students from c where c.id in ({info[0..^1]}) ";
-                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Classroom-{school_code}") }))
-                {
-                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
-                    {
-                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                        {
-                            classrooms.Add(obj.ToObject<object>());
-                        }
-                    }
-                }
-            //List<StudentSimple> students = new List<StudentSimple>();
-           /* classrooms.ForEach(c =>
-            {
-
-                c.students.ForEach(s =>
-                {
-                    StudentSimple student = new StudentSimple
-                    {
-                        id = s.id,
-                        name = s.name,
-                        no = s.no
-                    };
-                    students.Add(student);
-                });
-                //students = c.students;
-            });*/
-        
-
-            return Ok(new { classrooms });
-            /*List<Student> students = await _azureCosmos.FindByDict<Student>(
-                new Dictionary<string, object>() { { "classroomCode", classroomCode }, { "code", schoolCode } },
-                new List<string> { "id", "name", "code", "seatNo", "studentId", "classroomCode" });
-            List<dynamic> stus = new List<dynamic>();
-            List<ClassStudent> newClassStudents = new List<ClassStudent>();
-            ///新增的学生
-            if (students.IsNotEmpty())
-            {
-                students.ForEach(x =>
-                {
-                    if (!classroomStudents.Select(m => m.code).Contains(x.studentId))
-                    {
-                        newClassStudents.Add(new ClassStudent() { id = x.classroomCode, code = x.studentId });
-                    }
-                    var stu = new { x.id, x.name, x.code, x.seatNo, x.studentId, x.classroomCode };
-                    stus.Add(stu);
-                });
-            }
-            ///反射已存在的id信息
-            if (classroomStudents.IsNotEmpty())
-            {
-                ///处理冗余的id查询
-                List<string> ids = new List<string>();
-                if (students.IsNotEmpty()) {
-                    classroomStudents.ForEach(x =>
-                    {
-                        if (!students.Select(m => m.studentId).Contains(x.code))
-                        {
-                            ids.Add(x.code);
-                        }
-                    });
-                }
-
-                var sts = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "studentId", ids.ToArray() } });
-                if (sts.IsNotEmpty())
-                {
-                    sts.ForEach(x =>
-                    {
-                        var stu = new { x.id, x.name, x.code, x.seatNo, x.studentId, x.classroomCode };
-                        stus.Add(stu);
-                    });
-                }
-
-            }
-            //保存新增学生
-            if (newClassStudents.IsNotEmpty())
-            {
-                classroomStudents.AddRange(await _azureCosmos.SaveOrUpdateAll(newClassStudents));
-            }
-            return builder.Data(classroomStudents).Extend(new Dictionary<string, object> { { "students", stus }, { "count", stus.Count } }).build();
-        }
-        else
-        {
-            return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常classroomCode,code!").build();
-        }*/
-
-        }
-
-        /// <summary>
-        /// 保存或修改教室学生关联
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        //[AuthToken(Roles = "Teacher")]
-        [HttpPost("upsert")]
-        public async Task<BaseResponse> Upsert(List<ClassStudent> request)
-        {
-            ResponseBuilder builder = ResponseBuilder.custom();
-            List<ClassStudent> students = await _azureCosmos.SaveOrUpdateAll(request);
-            builder.Data(students);
-            return builder.build();
-        }
-
-
-        ///// <summary>
-        ///// 学生加入教室 
-        ///// </summary>
-        ///// <param name="request"></param>
-        ///// <returns></returns>
-        //[HttpPost("addStudent")]
-        //public async Task<BaseResponse> addStudent(JosnRPCRequest<List<ClassStudent>> request)
-        //{
-        //    JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
-
-        //    List<ClassStudent> students = await _cosmos.SaveOrUpdateAll(request.@params);
-        //    builder.Data(students);
-        //    return builder.build();
-        //}
-        /// <summary>
-        /// 学生退出教室,只能退出非原生班级的教室
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        //[AuthToken(Roles = "Teacher")]
-        [HttpPost("exit")]
-        public async Task<BaseResponse> Exit(List<ClassStudent> request)
-        {
-            ResponseBuilder builder = ResponseBuilder.custom();
-            if (ValidateHelper.IsValid(request) && request.Count>0)
-            {
-                List<ClassStudent> rm = new List<ClassStudent>();
-                List<OldStudent> students = await _azureCosmos.FindByDict<OldStudent>(new Dictionary<string, object> { { "studentId", request.GroupBy(x => x.code).ToList().Select(x => x.Key).ToArray() } });
-                students.ForEach(x => {
-                    if (!string.IsNullOrEmpty(x.classroomCode)) {
-                        request.ForEach(m =>
-                        {
-                            if (x.classroomCode.Equals(m.id) && x.studentId.Equals(m.code)) {
-                                rm.Add(m);
-                            }
-                        });
-                    }
-                });
-                rm.ForEach(x=> { request.Remove(x); });
-                List<IdPk> idPks = await _azureCosmos.DeleteAll<ClassStudent>(request.Select(x=> new IdPk { id=x.id,pk=x.code}).ToList());
-                builder.Data(idPks);
-            }
-            return builder.build();
-        }
-
-        /// <summary>
-        /// 查询教室学生关联 根据id
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        //[AuthToken(Roles = "Teacher")]
-        [HttpPost("find-by-id")]
-        public async Task<BaseResponse> FindById(IdPk request)
-        {
-            ResponseBuilder builder = ResponseBuilder.custom();
-            if (ValidateHelper.IsValid(request))
-            {
-                ClassStudent classStudent = await _azureCosmos.FindByIdPk<ClassStudent>(request.id,request.pk);
-                List<OldStudent> students = await _azureCosmos.FindByDict<OldStudent>(new Dictionary<string, object> { { "studentId",request.pk } }, new List<string> { "id", "name", "code", "seatNo", "studentId", "classroomCode" });
-                builder.Data(classStudent).Extend(new Dictionary<string, object> { { "student",students.IsNotEmpty()&& classStudent !=null? new { students[0].id, students[0].name, students[0].code, students[0].seatNo, students[0].studentId, students[0].classroomCode }:null } });
-            }
-            return builder.build();
-        }
-        /// <summary>
-        /// 查询学生在哪些教室
-        /// </summary>
-        /// <param name="studentId"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        //[AuthToken(Roles = "Teacher")]
-        [HttpPost("find-by-stu")]
-        public async Task<BaseResponse> FindByStu(JsonElement request)
-        {
-            ResponseBuilder builder = ResponseBuilder.custom();
-            if (request.TryGetProperty("code", out JsonElement studentId))
-            {
-                List<ClassStudent> sc = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "code",studentId.ToString()} });
-                List<Class> classrooms = await _azureCosmos.FindByDict<Class>(new Dictionary<string, object> { { "classroomCode", sc.GroupBy(x => x.id).Select(x => x.Key).ToArray() } });
-                builder.Data(classrooms).Extend(new Dictionary<string, object> { { "count", classrooms.Count } });
-            }
-            return builder.build();
-        }
-
-    }
-}

+ 16 - 2
TEAMModelOS/Controllers/School/CourseController.cs

@@ -414,9 +414,8 @@ namespace TEAMModelOS.Controllers
                 CourseManagement course = new CourseManagement();
                 //course = room.ToObject<CourseManagement>();
                 var client = _azureCosmos.GetCosmosClient();                
-                requert.pk = typeof(CourseManagement).Name;
                 string code = requert.code;
-                requert.code = typeof(CourseManagement).Name + "-" + requert.code;
+                requert.code = "CourseManagement-" + requert.code;
                 /*                if (requert.scope.Equals) { 
 
                                 }*/
@@ -683,6 +682,21 @@ namespace TEAMModelOS.Controllers
                 }
                 else
                 {
+                    if (course.classes.Count > 0) {
+                        foreach (ClassSimple classSimple in course.classes) {
+                            if (classSimple.scope.Equals("private",StringComparison.OrdinalIgnoreCase)) {
+                                Class cla = new Class();
+                                cla.id = classSimple.id;
+                                cla.code = cla.pk + "-" + code;
+                                cla.name = classSimple.name;
+                                cla.scope = classSimple.scope;
+                                cla.teacher.id = classSimple.teacher.id;
+                                cla.teacher.name = classSimple.teacher.name;
+
+                                await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(cla, new PartitionKey($"Class-{code}"));
+                            }                          
+                        }
+                    }
                     course = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(course,course.id, new PartitionKey($"Course-{code}"));
                 }
                 return Ok(new { course });

+ 0 - 1
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -51,7 +51,6 @@ namespace TEAMModelOS.Controllers
             {
                 School schoolInfo = new School();
                 var client = _azureCosmos.GetCosmosClient();                
-                requert.pk = typeof(School).Name;
                 var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(requert.id, new PartitionKey($"Base"));
                 if (response.Status == 200)
                 {

+ 0 - 2
TEAMModelOS/Controllers/Syllabus/ItemInfoController.cs

@@ -79,8 +79,6 @@ namespace TEAMModelOS.Controllers
             try {
                 ItemInfo itemInfo;
                 itemInfo = item.ToObject<ItemInfo>();                
-                itemInfo.pk = "Item";
-
                 if (option.ToString().Equals("insert"))
                 {
                     itemInfo.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

+ 2 - 1
TEAMModelOS/Controllers/Syllabus/VolumeController.cs

@@ -163,7 +163,8 @@ namespace TEAMModelOS.Controllers
                     request.id = key;
                     request.volumeCode = key;
                     string code = request.code;
-                    request.code = typeof(Volume).Name + "-" + request.code;
+                    //TODO 優化
+                    request.code = typeof(Volume).Name + "-" + request.code; 
                     volume = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(request, new PartitionKey($"Volume-{code}"));
                 }
                 else if (request.type == 1)

+ 12 - 13
TEAMModelOS/Controllers/Task/SurveyController.cs

@@ -46,17 +46,16 @@ namespace TEAMModelOS.Controllers
         /// <returns></returns>
         [ProducesDefaultResponseType]
         [HttpPost("upsert")]
-        public async Task<IActionResult> Upsert(SurveyDto request)
+        public async Task<IActionResult> Upsert(Survey request)
         {
             //ResponseBuilder builder = ResponseBuilder.custom();
             //新增
             //string code = request.survey.code;
             var client = _azureCosmos.GetCosmosClient();
             Survey survey;            
-            request.survey.pk = typeof(Survey).Name;
-            request.survey.school = request.survey.code;
-            request.survey.code = typeof(Survey).Name + "-" + request.survey.code;
-            request.survey.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            request.school = request.code;
+            request.code =  "Survey-" + request.code;
+            request.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             /*if (request.survey.publishModel.Equals("0"))
             {
                 //request.survey.startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
@@ -70,15 +69,15 @@ namespace TEAMModelOS.Controllers
                 request.survey.sequenceNumber = SequenceNumber;
 
             }*/
-            if (string.IsNullOrEmpty(request.survey.id))
+            if (string.IsNullOrEmpty(request.id))
             {
-                request.survey.id = Guid.NewGuid().ToString();
+                request.id = Guid.NewGuid().ToString();
                 //request.survey.status = 100;
-                request.survey.progress = "pending";
+                request.progress = "pending";
                 //await _serviceBus.GetServiceBusClient().cancelMessage(Constants.TopicName, info.sequenceNumber);
                /* long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.startTime);
                 request.survey.sequenceNumber = SequenceNumber;*/
-                survey = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request.survey, new PartitionKey($"{request.survey.code}"));
+                survey = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request, new PartitionKey($"{request.code}"));
                 /*if (request.survey.scope.Equals("school"))
                 {
                     survey = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(request.survey, new PartitionKey($"Survey-{code}"));
@@ -87,17 +86,17 @@ namespace TEAMModelOS.Controllers
                 {
                     survey = await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(request.survey, new PartitionKey($"Survey-{code}"));
                 }*/
-                await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.startTime);
+                await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.id, request.code, request.startTime);
 
             }
             else {
-                Survey info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Survey>(request.survey.id, new PartitionKey($"{request.survey.code}"));
+                Survey info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Survey>(request.id, new PartitionKey($"{request.code}"));
                 if (info.progress.Equals("going"))
                 {
                     return Ok(new { v = "活动正在进行中" });
                 }
                 //request.survey.code = info.code;
-                request.survey.progress = info.progress;
+                request.progress = info.progress;
                 /*try {
                     await _serviceBus.GetServiceBusClient().cancelMessage(Constants.TopicName, info.sequenceNumber);
                     long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.startTime);
@@ -107,7 +106,7 @@ namespace TEAMModelOS.Controllers
                     //await _dingDing.SendBotMsg($"ServiceBusㄛExamBus()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                 }        */       
                 
-                survey = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request.survey, info.id, new PartitionKey($"{info.code}"));
+                survey = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request, info.id, new PartitionKey($"{info.code}"));
                 //request.survey.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 /*if (request.survey.scope.Equals("school"))
                 {

+ 1 - 2
TEAMModelOS/Controllers/Task/VoteController.cs

@@ -76,9 +76,8 @@ namespace TEAMModelOS.Controllers.Learn
             //string code = request.vote.code;
             var client = _azureCosmos.GetCosmosClient();
             Vote vote = new Vote();            
-            request.vote.pk = typeof(Vote).Name;
             request.vote.school = request.vote.code;
-            request.vote.code = typeof(Vote).Name + "-" + request.vote.code;
+            request.vote.code = request.vote.pk+ "-" + request.vote.code;
             request.vote.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
             /*if (request.vote.publishModel.Equals("0"))
             {