Bläddra i källkod

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

OnePsycho 4 år sedan
förälder
incheckning
044aebd03d

+ 1 - 1
TEAMModelFunction/TriggerCorrect.cs

@@ -134,7 +134,7 @@ namespace TEAMModelFunction
                                     foreach (string stuId in examClass.studentIds)
                                     {
                                         int index = examClass.studentIds.IndexOf(stuId);
-                                        tasks.Add(redisClient.HashSetAsync($"Exam:Scoring:{eid}-{subjectId}", stuId, new { tmdId = "" , ans = examClass.studentAnswers[index][0], score = examClass.studentScores[index] }.ToJsonString()));
+                                        tasks.Add(redisClient.HashSetAsync($"Exam:Scoring:{eid}-{subjectId}", stuId, new { tmdId = "" , ans = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0] : "", score = examClass.studentScores[index] }.ToJsonString()));
                                     }
 
                                 }

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/Common/Inner/SyllabusTree.cs

@@ -12,7 +12,7 @@ namespace TEAMModelOS.SDK.Models
     }
     public class SyllabusTreeNode{
         public string id { get; set; }
-        public string code { get; set; }
+       // public string code { get; set; }
         public string scope { get; set; }
         public SyllabusTreeNode() {
             trees = new List<SyllabusTree>();

+ 3 - 2
TEAMModelOS.SDK/Models/Cosmos/Common/Syllabus.cs

@@ -9,9 +9,9 @@ using TEAMModelOS.SDK.Models.Cosmos.Common;
 namespace TEAMModelOS.SDK.Models
 {
     /// <summary>
-    /// Teaching materials 教学材料 ---课纲
+    /// Teaching materials 教学材料 ---课纲章节 数据结构
     /// </summary>
-    
+
     public class Syllabus : CosmosEntity
     {  
         /// <summary>
@@ -19,5 +19,6 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         [Required(ErrorMessage = "{0} 必须填写")]
         public List<Tnode> children { get; set; }
+        public string volumeId { get; set; }
     }
 }

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

@@ -23,6 +23,5 @@ namespace TEAMModelOS.SDK.Models
         //分组信息
         public string groupId { get; set; }
         public string groupName { get; set; }
-
     }
 }

+ 4 - 4
TEAMModelOS/ClientApp/src/view/learnactivity/markpaper/MarkSetting.vue

@@ -49,14 +49,14 @@
                             </FormItem>
                             </Col>
                             <!-- 启用异常处理 -->
-                            <Col :md="24" :lg="24" :xl="12" :xxl="8">
+                            <!-- <Col :md="24" :lg="24" :xl="12" :xxl="8">
                             <FormItem label="异常申报" class="setting-item-wrap" prop="isErr">
                                 <RadioGroup v-model="setting.isErr" style="color:white">
                                     <Radio :label="1">是</Radio>
                                     <Radio :label="0" style="margin-left:20px">否</Radio>
                                 </RadioGroup>
                             </FormItem>
-                            </Col>
+                            </Col> -->
                             <!-- 启用仲裁 -->
                             <Col :md="24" :lg="24" :xl="12" :xxl="8" v-show="setting.num > 1">
                             <FormItem label="启用仲裁" class="setting-item-wrap" prop="isArb">
@@ -86,11 +86,11 @@
                         <Row>
                             <Col :md="24" :lg="24" :xl="24" :xxl="24" v-if="setting.isErr">
                             <!-- 异常处理老师 -->
-                            <FormItem :label="$t('learnActivity.mark.errRole')" class="setting-item-wrap" prop="err">
+                            <!-- <FormItem :label="$t('learnActivity.mark.errRole')" class="setting-item-wrap" prop="err">
                                 <Select v-model="subsInfo.err" style="width:400px" multiple>
                                     <Option v-for="(item,index) in teacherList" :value="item.id" :key="index">{{item.name}}</Option>
                                 </Select>
-                            </FormItem>
+                            </FormItem> -->
                             </Col>
                             <Col :md="24" :lg="24" :xl="24" :xxl="24" v-if="setting.isArb">
                             <!-- 仲裁老师 -->

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

@@ -371,7 +371,7 @@ export default {
             if (this.markList.length > 0) {
                 let total = this.markList[this.curTaskIndex].count
                 let marked = this.markData ? this.markData.attr.length : 0
-                return total - marked
+                
             } else {
                 return 0
             }

+ 3 - 3
TEAMModelOS/ClientApp/src/view/task/mark/ByQu.vue

@@ -20,12 +20,12 @@
             <div class="btn-wrap">
                 <span class="action-btn" @click="toggleStatus = !toggleStatus">
                     <Icon type="md-shuffle" class="action-btn-icon" />
-                    切换
+                    切换题目
                 </span>
-                <span class="action-btn">
+                <!-- <span class="action-btn">
                     <Icon type="md-refresh" class="action-btn-icon" />
                     回评
-                </span>
+                </span> -->
                 <span class="action-btn">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon" />
                     异常申报

+ 104 - 30
TEAMModelOS/ClientApp/src/view/task/mark/ByStu.vue

@@ -20,12 +20,12 @@
             <div class="btn-wrap">
                 <span class="action-btn" @click="toggleStatus = !toggleStatus">
                     <Icon type="md-shuffle" class="action-btn-icon" />
-                    切换
+                    切换学生
                 </span>
-                <span class="action-btn">
+                <!-- <span class="action-btn">
                     <Icon type="md-refresh" class="action-btn-icon" />
                     回评
-                </span>
+                </span> -->
                 <span class="action-btn">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon" />
                     异常申报
@@ -112,7 +112,7 @@
         <!-- 用来单独渲染学生作答数据,提高tocanvas 的效率 -->
         <iframe id="markIframe" :srcdoc="curAnswer"></iframe>
         <Modal v-model="toggleStatus" title="切换学生" :width="800" footer-hide>
-            <StuProg  @getStuId="toByStuView" class="light-stu-prog" :total="taskInfo.count" :stusData="stusData"></StuProg>
+            <StuProg @getStuId="toByStuView" class="light-stu-prog" :total="taskInfo.count" :stusData="stusData"></StuProg>
         </Modal>
     </div>
 </template>
@@ -155,12 +155,6 @@ export default {
         }
     },
     methods: {
-        /**
-         * 按人阅卷
-         */
-        toByStuView(stuId) {
-            this.$Message.warning('这里切换学生逻辑暂未处理!')    
-        },
         drawImg(imgIndex) {
             // this.activeIcon = imgIndex
             // this.curImg = new Image()
@@ -197,10 +191,6 @@ export default {
                 })
             }
         },
-        //将图片(答案)绘制到canvas
-        imgToCanvas(img) {
-            console.log('将图片(答案)绘制到canvas', img)
-        },
         /** 打分 */
         setScore(score) {
             this.score = score
@@ -237,7 +227,6 @@ export default {
                     }
                 }
             })
-            console.log('输出', realIndex)
             return --realIndex
         },
         //提交分数
@@ -269,6 +258,16 @@ export default {
             }
         },
         nextQuestion() {
+            //首先判断是都已阅完
+            if (!this.stuScore.includes(-1)) {
+                if (this.autoStu) {
+                    this.toggleStatus = true
+                } else {
+                    this.$Message.warning('当前完成当前学生评分,如果继续评分,请切换学生')
+                }
+                return
+            }
+
             // 当前不是最后一题
             if (this.quIndex < this.paperData.item.length - 1) {
                 //当前题目是综合题
@@ -352,6 +351,7 @@ export default {
                         this.$Message.success('已阅完')
                         if (this.autoStu) {
                             //TODE 随机获取下一位学生
+                            this.toggleStatus = true
                         }
                     }
 
@@ -366,11 +366,85 @@ export default {
                 name: sessionStorage.getItem('markFrom')
             })
         },
-        uuid() {
-            function S4() {
-                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
+        /**
+         * 按人阅卷
+         */
+        async toByStuView(stuId) {
+            this.toggleStatus = false
+            // 如果挑选的是当前的学生
+            if (stuId) {
+                let stuInfo = this.stusData.find(item => {
+                    return item.stuId == stuId
+                })
+                if (stuInfo && !stuInfo.info.answer) {
+                    let sas = this.$store.state.user.schoolProfile.blob_sas //目前只有校本评测安排阅卷任务
+                    let blobUrl = JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri //目前只有校本评测安排阅卷任务
+                    stuInfo.info.answer = stuInfo.info.ans ? JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${stuInfo.info.ans}?${sas}`)) : []
+                }
+                this.stuAnswer = stuInfo.info.answer
+                this.stuScore = stuInfo.info.score
+                this.stuId = stuId
             }
-            return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
+            // 随机获取一名学生
+            else {
+                if (this.taskInfo.count == this.stusData.length) {
+                    let res = this.stusData.filter(item => {
+                        return item.info.score.includes(-1)
+                    })
+                    if (res.length) {
+                        this.$Message.warning('已无未阅学生,请挑选进行中的学生继续阅卷。')
+                        this.toggleStatus = true
+                    } else {
+                        this.$Message.success('您已完成阅卷任务')
+                    }
+
+                } else {
+                    this.getNextStu()
+                }
+
+            }
+        },
+        /**
+         * 批阅下个学生
+         * @param stuId 如果传了stuid则会获取对应学生的数据,否则随机获取一个学生
+         */
+        getNextStu(stuId) {
+            let requestData = {
+                code: this.markList[this.curTaskIndex].ecode.replace('Exam-', ''),
+                id: this.markList[this.curTaskIndex].id,
+                subjectId: this.markList[this.curTaskIndex].subject,
+                count: this.markList[this.curTaskIndex].count,
+                tmdId: this.$store.state.userInfo.TEAMModelId,
+                stuId
+            }
+            this.$api.mark.FindNextStu(requestData).then(
+                async res => {
+                    if (res) {
+                        let obj = {
+                            stuId: res.stuId,
+                            info: {
+                                ans: res.ans.ans,
+                                score: res.ans.score,
+                                mark: res.ans.mark
+                            }
+                        }
+                        let sas = this.$store.state.user.schoolProfile.blob_sas //目前只有校本评测安排阅卷任务
+                        let blobUrl = JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri //目前只有校本评测安排阅卷任务
+                        obj.info.answer = JSON.parse(await this.$tools.getFile(`${blobUrl}/exam/${obj.info.ans}?${sas}`))
+                        this.stusData.push(obj)
+
+                        this.stuId = res.stuId
+                        this.stuAnswer = obj.info.answer
+                        this.stuScore = obj.info.score
+                        this.toggleStatus = false
+                    } else {
+                        this.$Message.error('API ERROR')
+                    }
+                },
+                err => {
+                    this.$Message.error('API ERROR')
+                }
+            )
         },
     },
     mounted() {
@@ -429,7 +503,7 @@ export default {
 }
 </script>
 <style scoped lang="less">
-.light-stu-prog{
+.light-stu-prog {
     margin-bottom: 15px;
 }
 .score-setting-wrap {
@@ -736,29 +810,29 @@ export default {
     color: red;
     font-weight: 800;
 }
-.light-stu-prog .setting-content{
-    background: #FFF;
+.light-stu-prog .setting-content {
+    background: #fff;
     box-shadow: none;
     border-color: #e8eaec;
 }
-.light-stu-prog .filter-tab-item{
+.light-stu-prog .filter-tab-item {
     border-color: #e8eaec;
 }
-.light-stu-prog .filter-tab-item-active{
-    background: #FFF !important;
+.light-stu-prog .filter-tab-item-active {
+    background: #fff !important;
     color: black;
 }
-.light-stu-prog .filter-tab-item{
-    background: #EEE;
+.light-stu-prog .filter-tab-item {
+    background: #eee;
 }
-.light-stu-prog .no-mark-text .no-mark-count{
+.light-stu-prog .no-mark-text .no-mark-count {
     color: #515a6e;
 }
-.light-stu-prog .stu-name{
+.light-stu-prog .stu-name {
     background: #eee;
     color: #515a6e;
 }
-.light-stu-prog .stu-name:hover{
+.light-stu-prog .stu-name:hover {
     color: #515a6e;
     box-shadow: 0px 0px 5px 2px #ccc;
 }

+ 7 - 3
TEAMModelOS/ClientApp/src/view/task/mark/ProgPie.vue

@@ -100,13 +100,17 @@ export default {
         count: {
             handler(n, o) {
                 this.count.forEach((item, index) => {
-                    console.log(item,index)
+                    console.log(item, index)
                     this.option.series[0].data[index].value = item
                 })
                 if (!this.techScoreGau) {
-                    this.techScoreGau = this.$echarts.init(document.getElementById('mark-prog-pie'))
+                    this.$nextTick(() => {
+                        this.techScoreGau = this.$echarts.init(document.getElementById('mark-prog-pie'))
+                        this.techScoreGau.setOption(this.option)
+                    })
+                } else {
+                    this.techScoreGau.setOption(this.option)
                 }
-                this.techScoreGau.setOption(this.option)
             },
             immediate: true,
             deep: true

+ 11 - 3
TEAMModelOS/ClientApp/src/view/task/mark/StuProg.vue

@@ -66,14 +66,22 @@ export default {
         }
     },
     methods: {
-        toByStuView(stuId){
-            this.$emit('getStuId',stuId)
+        toByStuView(stuId) {
+            this.$emit('getStuId', stuId)
         }
     },
     computed: {
         //当前阅卷任务未阅数量
         unmarked() {
-            return this.total - this.marked.length - this.marking.length
+            let res = this.total - this.marked.length - this.marking.length
+            if (res == 0) {
+                if (this.marking.length == 0) {
+                    this.tabIndex = 2
+                } else {
+                    this.tabIndex = 1
+                }
+            }
+            return res
         },
         //当前阅卷任务已阅学生信息
         marked() {

+ 39 - 33
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -1573,7 +1573,7 @@ namespace TEAMModelOS.Controllers
                     {
                         recs.Add(new { stuId = rcd.Name.ToString(), ans = value });
                     }
-                    else
+                    if (string.IsNullOrEmpty(tmdId.ToString()))
                     {
                         all.Add(new { stuId = rcd.Name.ToString(), ans = value });
                     }
@@ -1594,10 +1594,14 @@ namespace TEAMModelOS.Controllers
                 {
                     if (recs.Count == count.GetInt32())
                     {
-                        return Ok( new { msg = "分配人数已到上限"});
+                        return Ok(new { msg = "分配人数已到上限" });
                     }
                     else
                     {
+                        if (all.Count == 0)
+                        {
+                            return Ok(new { msg = "暂无可选学生" });
+                        }
                         //随机选取一名学生打分
                         Random random = new Random();
                         int n = random.Next(all.Count);
@@ -1613,40 +1617,42 @@ namespace TEAMModelOS.Controllers
                         await redisClient.HashSetAsync($"Exam:Scoring:{id}-{subjectId}", sId.ToString(), new { ans = blob, score = sc, tmdId = tId }.ToJsonString());
                         return Ok(item);
                     }
-                   
+
                 }
 
                 //var json = JsonDocument.Parse(record);
-                /*if (info.scope.Equals("school"))
-				{
-
-					await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(
-					queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}'",
-					requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{info.school}") }))
-					{
-						classResults.Add(item);
-					}
-				}
-				else
-				{
-					await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(
-						queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}'",
-						requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{info.creatorId}") }))
-					{
-						classResults.Add(item);
-					}
-				}
-				List<Task<bool>> tasks = new List<Task<bool>>();
-				foreach (ExamClassResult examClass in classResults)
-				{
-					foreach (string stuId in examClass.studentIds)
-					{
-						int index = examClass.studentIds.IndexOf(stuId);
-						tasks.Add(redisClient.HashSetAsync($"Exam:Scoring:{id}-{subjectId}", stuId, new { ans = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0]: "", score = examClass.studentScores[index] }.ToJsonString()));
-					}
-
-				}
-				await Task.WhenAll(tasks);*/
+                /*ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new Azure.Cosmos.PartitionKey($"Exam-hbcn"));
+                if (info.scope.Equals("school"))
+                {
+
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(
+                    queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}'",
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{info.school}") }))
+                    {
+                        classResults.Add(item);
+                    }
+                }
+                else
+                {
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(
+                        queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}'",
+                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{info.creatorId}") }))
+                    {
+                        classResults.Add(item);
+                    }
+                }
+                List<Task<bool>> tasks = new List<Task<bool>>();
+                foreach (ExamClassResult examClass in classResults)
+                {
+                    foreach (string stuId in examClass.studentIds)
+                    {
+                        int index = examClass.studentIds.IndexOf(stuId);
+                        tasks.Add(redisClient.HashSetAsync($"Exam:Scoring:{id}-{subjectId}", stuId, new { ans = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0] : "", score = examClass.studentScores[index] }.ToJsonString()));
+                    }
+
+                }
+                await Task.WhenAll(tasks);
+                return Ok();*/
                 //info = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(info, info.id, new PartitionKey($"Exam-{code}"));                
             }
             catch (Exception ex)

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

@@ -79,7 +79,6 @@ namespace TEAMModelOS.Controllers
                             if (currStud.TryGetProperty("year", out var tmpYear)) year = tmpYear.GetInt32();
                             if (currStud.TryGetProperty("no", out var tmpNo)) no = tmpNo.GetString();
                             if (currStud.TryGetProperty("classId", out var tmpClassId)) classId = tmpClassId.GetString();
-
                             //要檢查座號使否已被使用
                             var existNo = await checkStudNo(schoolId.GetString(), classId, new List<string>() { id });
                             if (existNo.Count != 0) return this.Ok(new { code = $"Base-{schoolId.GetString()}", existNo = existNo.Select(o => o.id).ToList() });

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

@@ -283,7 +283,6 @@ namespace TEAMModelOS.Controllers
                     var treechd = SyllabusService.ListToTree(syllabus.children);
                     etree = new SyllabusTreeNode() {
                         id = syllabus.id,
-                        code = syllabus.code,
                         trees = treechd
                     };
                 }
@@ -292,7 +291,6 @@ namespace TEAMModelOS.Controllers
                     stree = new SyllabusTreeNode()
                     {
                         id = syllabus.id,
-                        code = syllabus.code
                     };
                     snodes.ForEach(x => {
                         SyllabusTree syllabusTree = null;

+ 193 - 125
TEAMModelOS/Controllers/Syllabus/SyllabusController.cs

@@ -37,88 +37,152 @@ namespace TEAMModelOS.Controllers
 
         /*
         {
-          "id": "hbcn108774752059002880",
-          "code": "Syllabus-hbcn",
-          "scope":"school/private",
-          "trees": [
-              {
-                  "id": "111111-111-44E7-8DD9-A6CB6D0D52F2",
-                  "pid": "hbcn108515325535981568",
-                  "title": "第一章",
-                  "order": 0,
-                  "type": tree,
-                  "rnodes":[
-                      {
-                            "type":"item/paper/image/video/pptx.../link"//试题 ,试卷,内容资源,外部链接(只有link,和name)
-                            "title":"显示名称",
-                            "id":"关联资源的id",
-                            "code":"关联资源的code",
-                            "link":["https;//www.xxx.com/xxx.json"],
-                            "cntr":"blob的容器名"
-                      }
-                   ],
-                  "children": [
-                      {
-                          "id": "22222-111-447E-8A52-BFCD63E61D33",
-                          "pid": "111111-111-44E7-8DD9-A6CB6D0D52F2",
-                          "title": "第一节333",
-                          "order": 0,
-                          "type": 1,
-                          "children": [
-                              {
-                                  "id": "3333-111-447E-8A52-BFCD63E61D33",
-                                  "pid": "22222-111-447E-8A52-BFCD63E61D33",
-                                  "title": "第一节333",
-                                  "order": 0,
-                                  "type": 1
-                              },
-                              {
-                                  "id": "4444-111-447E-8A52-BFCD63E61D33",
-                                  "pid": "22222-111-447E-8A52-BFCD63E61D33",
-                                  "title": "第一节333",
-                                  "order": 0,
-                                  "type": 1
-                              }
-                          ]
-                      }
-                  ]
-              },
-              {
-                  "id": "111111-222-44E7-8DD9-A6CB6D0D52F2",
-                  "pid": "hbcn108515325535981568",
-                  "title": "第一章",
-                  "order": 0,
-                  "type": 1,
-                  "children": [
-                      {
-                          "id": "22222-222-447E-8A52-BFCD63E61D33",
-                          "pid": "111111-222-44E7-8DD9-A6CB6D0D52F2",
-                          "title": "第一节333",
-                          "order": 0,
-                          "type": 1,
-                          "children": [
-                              {
-                                  "id": "3333-222-447E-8A52-BFCD63E61D33",
-                                  "pid": "22222-222-447E-8A52-BFCD63E61D33",
-                                  "title": "第一节333",
-                                  "order": 0,
-                                  "type": 1
-                              }
-                          ]
-                      },
-                      {
-                          "id": "5555-222-447E-8A52-BFCD63E61D33",
-                          "pid": "111111-222-44E7-8DD9-A6CB6D0D52F2",
-                          "title": "第一节333",
-                          "order": 0,
-                          "type": 1,
-                          "children": []
-                      }
-                  ]
-              }
-          ]
+    "id": "0baf00db-0768-4b62-a8f7-280f6bcebf71",
+    "scope": "school",
+    "trees": [
+        {
+            "children": [
+                {
+                    "children": [],
+                    "id": "AC4BA269-541B-4DFC-92A5-D773068A6439",
+                    "pid": "2dfcc62e-8eea-9881-dc79-384b2f0afbec",
+                    "order": 0,
+                    "rnodes": [
+                        {
+                            "type": "doc",
+                            "id": "a2bee388-5584-72cc-1d9a-d8a77d255364",
+                            "code": "hbcn",
+                            "scope": "private",
+                            "cntr": "1595321354",
+                            "link": [
+                                "https://teammodelstorage.blob.core.chinacloudapi.cn/1595321354/doc/2020智慧課堂與智慧教研.pptx"
+                            ],
+                            "title": "2020智慧課堂與智慧教研.pptx"
+                        }
+                    ],
+                    "cids": [],
+                    "creatorId": null,
+                    "updateTime": 0,
+                    "title": "1-1 新冠疫情小贴士"
+                }
+            ],
+            "id": "2dfcc62e-8eea-9881-dc79-384b2f0afbec",
+            "pid": "0baf00db-0768-4b62-a8f7-280f6bcebf71",
+            "order": 0,
+            "rnodes": [
+                {
+                    "type": "doc",
+                    "id": "cf1b4d21-66e1-e6c7-c944-30a03e419fa6",
+                    "code": "hbcn",
+                    "scope": "school",
+                    "cntr": "hbcn",
+                    "link": [
+                        "https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn/syllabus/IES5试卷模板制作说明(终).pdf"
+                    ],
+                    "title": "IES5试卷模板制作说明(终).pdf"
+                },
+                {
+                    "type": "doc",
+                    "id": "f3e82595-7340-a5fe-1004-04538ca09b86",
+                    "code": "hbcn",
+                    "scope": "school",
+                    "cntr": "hbcn",
+                    "link": [
+                        "https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn/syllabus/111.pdf"
+                    ],
+                    "title": "111.pdf"
+                },
+                {
+                    "type": "doc",
+                    "id": "e1b31639-dad9-9efb-020b-159dd045f238",
+                    "code": "hbcn",
+                    "scope": "school",
+                    "cntr": "hbcn",
+                    "link": [
+                        "https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn/doc/6789.pdf"
+                    ],
+                    "title": "6789.pdf"
+                },
+                {
+                    "type": "doc",
+                    "id": "aaeb4b5c-0450-cb4d-a1ac-244f3d115c4a",
+                    "code": "hbcn",
+                    "scope": "private",
+                    "cntr": "1595321354",
+                    "link": [
+                        "https://teammodelstorage.blob.core.chinacloudapi.cn/1595321354/doc/422北京培新活动邀请函.pdf"
+                    ],
+                    "title": "422北京培新活动邀请函.pdf"
+                },
+                {
+                    "type": "doc",
+                    "id": "c5f5838c-5c2f-5e9b-a734-a473cd2cad2e",
+                    "code": "hbcn",
+                    "scope": "school",
+                    "cntr": "hbcn",
+                    "link": [
+                        "https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn/doc/6666.pdf"
+                    ],
+                    "title": "6666.pdf"
+                },
+                {
+                    "type": "doc",
+                    "id": "4a106c8e-6831-5f4b-4ec3-3c18f778cab2",
+                    "code": "hbcn",
+                    "scope": "school",
+                    "cntr": "hbcn",
+                    "link": [
+                        "https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn/doc/6.pdf"
+                    ],
+                    "title": "6.pdf"
+                }
+            ],
+            "cids": [
+                "AC4BA269-541B-4DFC-92A5-D773068A6439"
+            ],
+            "creatorId": null,
+            "updateTime": 0,
+            "title": "第一单元 新冠疫情防控"
+        },
+        {
+            "children": [
+                {
+                    "children": [],
+                    "id": "FC5132E1-9723-4875-B3B5-D3DC98D194FA",
+                    "pid": "4f12752c-852f-6e90-a3df-1f1f710af23d",
+                    "order": 0,
+                    "rnodes": [],
+                    "cids": [],
+                    "creatorId": null,
+                    "updateTime": 0,
+                    "title": "2-1 全球醍摩豆智慧教育研究院"
+                },
+                {
+                    "children": [],
+                    "id": "3CAD52BE-67B6-4EDB-8EFB-9122960D816A",
+                    "pid": "4f12752c-852f-6e90-a3df-1f1f710af23d",
+                    "order": 1,
+                    "rnodes": [],
+                    "cids": [],
+                    "creatorId": null,
+                    "updateTime": 0,
+                    "title": "2-2 醍摩豆研究院课程体系"
+                }
+            ],
+            "id": "4f12752c-852f-6e90-a3df-1f1f710af23d",
+            "pid": "0baf00db-0768-4b62-a8f7-280f6bcebf71",
+            "order": 1,
+            "rnodes": [],
+            "cids": [
+                "FC5132E1-9723-4875-B3B5-D3DC98D194FA",
+                "3CAD52BE-67B6-4EDB-8EFB-9122960D816A"
+            ],
+            "creatorId": null,
+            "updateTime": 0,
+            "title": "第二单元 醍摩豆手册学习"
         }
-
+    ]
+}
               */
 
         /// <summary>
@@ -131,42 +195,35 @@ namespace TEAMModelOS.Controllers
         [HttpPost("upsert-tree")]
         public async Task<IActionResult> SaveOrUpdateAsTree(SyllabusTreeNode request)
         {
-            List<Tnode> nodes = new List<Tnode>();
-            Syllabus syllabus = new Syllabus();
-            SyllabusService.TreeToList(request.trees, nodes);
-            syllabus.children = nodes;
-            syllabus.id = !string.IsNullOrEmpty(request.id) ? request.id : Guid.NewGuid().ToString();
-            syllabus.code = $"Syllabus-{request.code}";
-            syllabus.pk = "Syllabus";
-            syllabus.ttl = -1;
-            if (request.scope == "school")
-            {
-                await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey(syllabus.code));
-            }
-            else {
-                await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey(syllabus.code));
+            List<List<SyllabusTree>> tts = new List<List<SyllabusTree>>();
+            foreach (var tree in request.trees) {
+                Syllabus syllabus = new Syllabus();
+                List<Tnode> nodes = new List<Tnode>();
+                SyllabusService.TreeToList(new List<SyllabusTree> { tree }, nodes);
+                syllabus.children = nodes;
+                syllabus.id = !string.IsNullOrEmpty(tree.id) ? tree.id : Guid.NewGuid().ToString();
+                syllabus.code = $"Syllabus-{request.id}";
+                syllabus.pk = "Syllabus";
+                syllabus.ttl = -1;
+                syllabus.volumeId = request.id;
+                if (request.scope == "school")
+                {
+                    await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{request.id}"));
+                }
+                else
+                {
+                    await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{request.id}"));
+                }
+                List<SyllabusTree> trees = SyllabusService.ListToTree(nodes);
+                tts.Add(trees);
             }
-            List<SyllabusTree> trees = SyllabusService.ListToTree(nodes);
-            request.trees = trees;
-            return Ok(request);
-        }
 
-
-        /// <summary>
-        /// 按节点新增课纲
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [HttpPost("upsert-nodes")]
-        public async Task<IActionResult> SaveOrUpdateAsNodes(List<Tnode> request)
-        {
-            return Ok();
-            // List<Syllabus> syllabuses = await SaveOrUpdateToNodes(request);
-            //if (syllabuses.IsNotEmpty()) return Ok(request);
-            //else return Ok(syllabuses);
+            request.trees = new List<SyllabusTree>() ;
+            tts.ForEach(x => request.trees.AddRange(x));
+            return Ok(request);
         }
 
+ 
 
         /// <summary>
         /// 查找课纲 
@@ -178,32 +235,43 @@ namespace TEAMModelOS.Controllers
         public async Task<IActionResult> Find(JsonElement request)
         {
             var client = _azureCosmos.GetCosmosClient();
-            if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
             if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
             if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
             SyllabusTreeNode tree = null;
+            string vcode = null;
+            List<List<SyllabusTree>> tts = new List<List<SyllabusTree>>();
             try {
                 if (scope.ToString().Equals("school"))
                 {
-                    Syllabus syllabus = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(id.ToString(), new PartitionKey($"Syllabus-{code}"));
-                    List<SyllabusTree> trees = SyllabusService.ListToTree(syllabus.children);
-                    tree = new SyllabusTreeNode() { id = syllabus.id, code = syllabus.code, scope = "school", trees= trees };
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c ",
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{code}") }))
+                    {
+                        vcode = item.volumeId;
+                        List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
+                        tts.Add(trees);
+                    }
+                    tree = new SyllabusTreeNode() { id = vcode,  scope = "school", trees= new List<SyllabusTree>() };
+                    tts.ForEach(x => tree.trees.AddRange(x));
                 }
                 else
                 {
-                    Syllabus syllabus = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(id.ToString(), new PartitionKey($"Syllabus-{code}"));
-                    List<SyllabusTree> trees = SyllabusService.ListToTree(syllabus.children);
-                    tree = new SyllabusTreeNode() { id = syllabus.id, code = syllabus.code, scope = "private", trees = trees };
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c ",
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{code}") }))
+                    {
+                        vcode = item.volumeId;
+                        List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
+                        tts.Add(trees);
+                    }
+                    tree = new SyllabusTreeNode() { id = vcode, scope = "school", trees = new List<SyllabusTree>() };
+                    tts.ForEach(x => tree.trees.AddRange(x)); 
                 }
-                 
                 return Ok(new { tree });
             } catch (Exception ex) {
                 return Ok(new { tree});
             }
         }
-
         /// <summary>
-        /// 删除课纲
+        /// 删除章节
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
@@ -217,12 +285,12 @@ namespace TEAMModelOS.Controllers
             var client = _azureCosmos.GetCosmosClient();
             if (scope.ToString().Equals("school"))
             {
-                var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Volume-{code}"));
+                var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
                 return Ok(new { code = response.Status });
             }
             else
             {
-                var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Volume-{code}"));
+                var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
                 return Ok(new { code = response.Status });
             }
         }

+ 3 - 1
TEAMModelOS/Services/Common/SyllabusService.cs

@@ -63,7 +63,9 @@ namespace TEAMModelOS.Services.Common
                     pid = x.pid,
                     order = x.order,
                     rnodes = x.rnodes,
-                    cids= cids
+                    cids= cids,
+                    creatorId=x.creatorId,
+                    updateTime=x.updateTime
                 };
                 list.Add(node);
             });