CrazyIter_Bin 3 år sedan
förälder
incheckning
69a55836a0

+ 3 - 0
TEAMModelFunction/TriggerExam.cs

@@ -121,6 +121,7 @@ namespace TEAMModelFunction
                                         owner = info.owner,
                                         createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                         taskStatus = -1
+                                        classIds = classes
 
                                     });;
                                 });
@@ -145,6 +146,8 @@ namespace TEAMModelFunction
                                         subjects = sub,
                                         blob = null,
                                         owner = info.owner,
+                                        classIds = classes
+                                        
                                         createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                         taskStatus = -1
                                     });

+ 2 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/StuActivity.cs

@@ -56,6 +56,8 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
         public List<string> subjects { get; set; }
         public string blob { get; set; }
         public string recordUrl { get; set; }
+        public List<string> classIds { get; set; } = new List<string>();
+        
         public long createTime { get; set; }= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
         /// <summary>
         /// 任务完成状态,-1 未参与,0,未完成, 已完成

+ 302 - 3
TEAMModelOS/ClientApp/src/assets/iconfont/demo_index.html

@@ -54,6 +54,84 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+              <span class="icon iconfont">&#xe648;</span>
+                <div class="name">文档</div>
+                <div class="code-name">&amp;#xe648;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe78f;</span>
+                <div class="name">视频 播放 影片</div>
+                <div class="code-name">&amp;#xe78f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe64b;</span>
+                <div class="name">音频</div>
+                <div class="code-name">&amp;#xe64b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe64c;</span>
+                <div class="name">其他</div>
+                <div class="code-name">&amp;#xe64c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe70a;</span>
+                <div class="name">云盘</div>
+                <div class="code-name">&amp;#xe70a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe71c;</span>
+                <div class="name">选择</div>
+                <div class="code-name">&amp;#xe71c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63d;</span>
+                <div class="name">手指上</div>
+                <div class="code-name">&amp;#xe63d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6a6;</span>
+                <div class="name">线上</div>
+                <div class="code-name">&amp;#xe6a6;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe644;</span>
+                <div class="name">目标考核管理</div>
+                <div class="code-name">&amp;#xe644;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe645;</span>
+                <div class="name">诊断</div>
+                <div class="code-name">&amp;#xe645;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe646;</span>
+                <div class="name">3_3综合素养</div>
+                <div class="code-name">&amp;#xe646;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe7ae;</span>
+                <div class="name">精品课堂</div>
+                <div class="code-name">&amp;#xe7ae;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe63c;</span>
+                <div class="name">政策</div>
+                <div class="code-name">&amp;#xe63c;</div>
+              </li>
+          
             <li class="dib">
               <span class="icon iconfont">&#xe652;</span>
                 <div class="name">谷歌_google114</div>
@@ -828,9 +906,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1625740015353') format('woff2'),
-       url('iconfont.woff?t=1625740015353') format('woff'),
-       url('iconfont.ttf?t=1625740015353') format('truetype');
+  src: url('iconfont.woff2?t=1628756740623') format('woff2'),
+       url('iconfont.woff?t=1628756740623') format('woff'),
+       url('iconfont.ttf?t=1628756740623') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -856,6 +934,123 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
           
+          <li class="dib">
+            <span class="icon iconfont icon-document"></span>
+            <div class="name">
+              文档
+            </div>
+            <div class="code-name">.icon-document
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-video-outline"></span>
+            <div class="name">
+              视频 播放 影片
+            </div>
+            <div class="code-name">.icon-video-outline
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-audio-outline"></span>
+            <div class="name">
+              音频
+            </div>
+            <div class="code-name">.icon-audio-outline
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-other-grad"></span>
+            <div class="name">
+              其他
+            </div>
+            <div class="code-name">.icon-other-grad
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-yunpan"></span>
+            <div class="name">
+              云盘
+            </div>
+            <div class="code-name">.icon-yunpan
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-choose-arrow"></span>
+            <div class="name">
+              选择
+            </div>
+            <div class="code-name">.icon-choose-arrow
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-handle-down"></span>
+            <div class="name">
+              手指上
+            </div>
+            <div class="code-name">.icon-handle-down
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-online"></span>
+            <div class="name">
+              线上
+            </div>
+            <div class="code-name">.icon-online
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-assess"></span>
+            <div class="name">
+              目标考核管理
+            </div>
+            <div class="code-name">.icon-assess
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-diagnosis"></span>
+            <div class="name">
+              诊断
+            </div>
+            <div class="code-name">.icon-diagnosis
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-literacy"></span>
+            <div class="name">
+              3_3综合素养
+            </div>
+            <div class="code-name">.icon-literacy
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-cus-video"></span>
+            <div class="name">
+              精品课堂
+            </div>
+            <div class="code-name">.icon-cus-video
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-policy"></span>
+            <div class="name">
+              政策
+            </div>
+            <div class="code-name">.icon-policy
+            </div>
+          </li>
+          
           <li class="dib">
             <span class="icon iconfont icon-google"></span>
             <div class="name">
@@ -2017,6 +2212,110 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-document"></use>
+                </svg>
+                <div class="name">文档</div>
+                <div class="code-name">#icon-document</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-video-outline"></use>
+                </svg>
+                <div class="name">视频 播放 影片</div>
+                <div class="code-name">#icon-video-outline</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-audio-outline"></use>
+                </svg>
+                <div class="name">音频</div>
+                <div class="code-name">#icon-audio-outline</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-other-grad"></use>
+                </svg>
+                <div class="name">其他</div>
+                <div class="code-name">#icon-other-grad</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-yunpan"></use>
+                </svg>
+                <div class="name">云盘</div>
+                <div class="code-name">#icon-yunpan</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-choose-arrow"></use>
+                </svg>
+                <div class="name">选择</div>
+                <div class="code-name">#icon-choose-arrow</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-handle-down"></use>
+                </svg>
+                <div class="name">手指上</div>
+                <div class="code-name">#icon-handle-down</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-online"></use>
+                </svg>
+                <div class="name">线上</div>
+                <div class="code-name">#icon-online</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-assess"></use>
+                </svg>
+                <div class="name">目标考核管理</div>
+                <div class="code-name">#icon-assess</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-diagnosis"></use>
+                </svg>
+                <div class="name">诊断</div>
+                <div class="code-name">#icon-diagnosis</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-literacy"></use>
+                </svg>
+                <div class="name">3_3综合素养</div>
+                <div class="code-name">#icon-literacy</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-cus-video"></use>
+                </svg>
+                <div class="name">精品课堂</div>
+                <div class="code-name">#icon-cus-video</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-policy"></use>
+                </svg>
+                <div class="name">政策</div>
+                <div class="code-name">#icon-policy</div>
+            </li>
+          
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-google"></use>

+ 55 - 3
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2000444 */
-  src: url('iconfont.woff2?t=1625740015353') format('woff2'),
-       url('iconfont.woff?t=1625740015353') format('woff'),
-       url('iconfont.ttf?t=1625740015353') format('truetype');
+  src: url('iconfont.woff2?t=1628756740623') format('woff2'),
+       url('iconfont.woff?t=1628756740623') format('woff'),
+       url('iconfont.ttf?t=1628756740623') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,58 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-document:before {
+  content: "\e648";
+}
+
+.icon-video-outline:before {
+  content: "\e78f";
+}
+
+.icon-audio-outline:before {
+  content: "\e64b";
+}
+
+.icon-other-grad:before {
+  content: "\e64c";
+}
+
+.icon-yunpan:before {
+  content: "\e70a";
+}
+
+.icon-choose-arrow:before {
+  content: "\e71c";
+}
+
+.icon-handle-down:before {
+  content: "\e63d";
+}
+
+.icon-online:before {
+  content: "\e6a6";
+}
+
+.icon-assess:before {
+  content: "\e644";
+}
+
+.icon-diagnosis:before {
+  content: "\e645";
+}
+
+.icon-literacy:before {
+  content: "\e646";
+}
+
+.icon-cus-video:before {
+  content: "\e7ae";
+}
+
+.icon-policy:before {
+  content: "\e63c";
+}
+
 .icon-google:before {
   content: "\e652";
 }

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.js


+ 91 - 0
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.json

@@ -5,6 +5,97 @@
   "css_prefix_text": "icon-",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "554016",
+      "name": "文档",
+      "font_class": "document",
+      "unicode": "e648",
+      "unicode_decimal": 58952
+    },
+    {
+      "icon_id": "688102",
+      "name": "视频 播放 影片",
+      "font_class": "video-outline",
+      "unicode": "e78f",
+      "unicode_decimal": 59279
+    },
+    {
+      "icon_id": "1391286",
+      "name": "音频",
+      "font_class": "audio-outline",
+      "unicode": "e64b",
+      "unicode_decimal": 58955
+    },
+    {
+      "icon_id": "9697596",
+      "name": "其他",
+      "font_class": "other-grad",
+      "unicode": "e64c",
+      "unicode_decimal": 58956
+    },
+    {
+      "icon_id": "13479229",
+      "name": "云盘",
+      "font_class": "yunpan",
+      "unicode": "e70a",
+      "unicode_decimal": 59146
+    },
+    {
+      "icon_id": "20567897",
+      "name": "选择",
+      "font_class": "choose-arrow",
+      "unicode": "e71c",
+      "unicode_decimal": 59164
+    },
+    {
+      "icon_id": "2226561",
+      "name": "手指上",
+      "font_class": "handle-down",
+      "unicode": "e63d",
+      "unicode_decimal": 58941
+    },
+    {
+      "icon_id": "2552606",
+      "name": "线上",
+      "font_class": "online",
+      "unicode": "e6a6",
+      "unicode_decimal": 59046
+    },
+    {
+      "icon_id": "7171140",
+      "name": "目标考核管理",
+      "font_class": "assess",
+      "unicode": "e644",
+      "unicode_decimal": 58948
+    },
+    {
+      "icon_id": "8780649",
+      "name": "诊断",
+      "font_class": "diagnosis",
+      "unicode": "e645",
+      "unicode_decimal": 58949
+    },
+    {
+      "icon_id": "9074037",
+      "name": "3_3综合素养",
+      "font_class": "literacy",
+      "unicode": "e646",
+      "unicode_decimal": 58950
+    },
+    {
+      "icon_id": "18486382",
+      "name": "精品课堂",
+      "font_class": "cus-video",
+      "unicode": "e7ae",
+      "unicode_decimal": 59310
+    },
+    {
+      "icon_id": "18043205",
+      "name": "政策",
+      "font_class": "policy",
+      "unicode": "e63c",
+      "unicode_decimal": 58940
+    },
     {
       "icon_id": "634377",
       "name": "谷歌_google114",

BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.ttf


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff2


+ 8 - 3
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -595,11 +595,16 @@ import { mapGetters, mapState } from 'vuex';
 </style>
 
 <style lang="less" scoped>
+.icon-selector{
+    .ivu-radio-wrapper{
+        overflow: hidden;
+    }
+}
 .dev-top{
     .develop{
         position: absolute;
-        bottom: 10px;
-        right: -11px;
+        top: 1px;
+        right: -13px;
         font-size: xx-small;
         color: #fff;
         padding: 2px 5px;
@@ -612,7 +617,7 @@ import { mapGetters, mapState } from 'vuex';
         content: " ";
         right: 0px;
         top: -4px;
-        z-index: -1;
+        z-index: 0;
         width: 33px;
         height: 20px;
         background-color: #64AE16;

+ 19 - 1
TEAMModelOS/ClientApp/src/components/student-web/HomeView/MissionListCard.vue

@@ -5,7 +5,17 @@
             <span class="title">{{ $t("studentWeb.missionListCardTitle") }}</span>
         </div>
         <Card class="list">
-            <Scroll class="list-block"
+            <div class="no-data-text" v-if="!testData.length">
+                <img
+                    src="@/assets/icon/no_data_evaluation.png"
+                    width="120"
+                />
+                <span style="margin-top: 15px; color: #808080">{{
+                    $t("studentWeb.public.noData")
+                }}</span>
+            </div>
+            <Scroll v-else
+                    class="list-block"
                     :style="{'max-height':listblockHeight+'px'}"
                     :on-reach-bottom="handleReachBottom"
                     :loading-text=" testData.length == 5  ? $t('studentWeb.missionListCardReachBottom') : $t('studentWeb.missionListCardLoading') "
@@ -210,3 +220,11 @@
     @import "~@/assets/student-web/component_styles/mission-list-card.css";
     @import "~@/assets/student-web/component_styles/mission-list-card-new.css";
 </style>
+
+<style lang="less" scoped>
+.list{
+    .no-data-text{
+        margin-top: 100px;
+    }
+}
+</style>

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/cusMgt.js

@@ -107,6 +107,7 @@ export default {
     qrCodeText:'Invitation Code:',
     inviteUrl:'Invitation Link:',
     copyUrl:'Copy Link',
+    createTips:'溫馨提示:您(已加入學校)可以挑選學校學生加入課程 或者 讓學生通過邀請碼、二維碼、鏈接加入名單。 ',
     //ManageClass.vue
     classLabel:'Class:',
     stuCount:'Student Number: ',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/cusMgt.js

@@ -107,6 +107,7 @@ export default {
     qrCodeText:'邀请码:',
     inviteUrl:'邀请链接:',
     copyUrl:'复制链接',
+    createTips:'温馨提示:您(已加入学校)可以挑选学校学生加入课程 或者 让学生通过邀请码、二维码、链接加入名单。',
     //ManageClass.vue
     classLabel:'班级:',
     stuCount:'学生人数:',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/cusMgt.js

@@ -107,6 +107,7 @@ export default {
     qrCodeText:'邀請碼:',
     inviteUrl:'邀請鏈接:',
     copyUrl:'複製鏈接',
+    createTips:'溫馨提示:您(已加入學校)可以挑選學校學生加入課程 或者 讓學生通過邀請碼、二維碼、鏈接加入名單。 ',
     //ManageClass.vue
     classLabel: '班級:',
     stuCount: '學生人數:',

+ 3 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/CreatePrivEva.vue

@@ -36,7 +36,7 @@
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.courseType')" prop="course">
                                 <Select v-model="evaluationInfo.scope" @on-change="resetCourse">
-                                    <Option value="school">{{$t('learnActivity.createEv.cusLabel1')}}</Option>
+                                    <Option value="school" v-show="$store.state.userInfo.hasSchool">{{$t('learnActivity.createEv.cusLabel1')}}</Option>
                                     <Option value="private">{{$t('learnActivity.createEv.cusLabel2')}}</Option>
                                 </Select>
                             </FormItem>
@@ -167,7 +167,7 @@ export default {
                 name: '',
                 targets: [],
                 classes: [],
-                scope: 'school',
+                scope: '',
                 type: '',  //测试类别
                 source: '',
                 publish: '0',
@@ -589,7 +589,7 @@ export default {
         } else {
             this.mode = 'private'
         }
-
+        this.evaluationInfo.scope = this.$store.state.userInfo.hasSchool ? 'school' : 'private'
         //编辑评测逻辑
         let routerData = this.$route.params.evaluationInfo
         if (routerData !== undefined) {

+ 6 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue

@@ -27,6 +27,10 @@
                     <Icon :type="showQu ? 'md-eye-off':'md-eye'" />
                     {{ showQu ? $t('learnActivity.score.hideQu') : $t('learnActivity.score.showQu')}}
                 </span>
+                <span class="base-info-btn" @click="markByQu">
+                    <Icon type="ios-create" />
+                    按题批阅
+                </span>
             </div>
             <!-- 题号 -->
             <div class="question-index-box" v-if="studentAnswer.scores">
@@ -377,7 +381,9 @@ export default {
         }
     },
     methods: {
+        markByQu(){
 
+        },
         closeModal() {
             this.markStatus = false
             this.curAnIndex = -1

+ 1 - 1
TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue

@@ -667,7 +667,7 @@ export default {
 
                         },
                         err => {
-                            this.$Message.error('教学班数据获取失败')
+                            this.$Message.error('API error')
                         }
                     )
                     return []

+ 11 - 2
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.less

@@ -336,7 +336,7 @@
     position: absolute;
     right: 15px;
     top: 50%;
-    margin-top: -10px;
+    margin-top: -15px;
 }
 .no-school-tips{
     color: #ff9900;
@@ -390,4 +390,13 @@
     user-select: none;
     line-height: 45px;
     display: inline-block;
-}
+}
+.create-list-title{
+    font-size: 16px;
+    font-weight: 500;
+    margin-right: 20px;
+}
+.create-list-tips{
+    color: #ff9900;
+    font-size: 12px;
+}

+ 9 - 5
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -59,7 +59,7 @@
                                         <span class="attr-label">{{$t('cusMgt.stuCount')}}:</span>
                                         <span class="class-name">{{item.allStu ? item.allStu.length : 0}}{{$t('unit.text7')}}</span>
                                     </p>
-                                    <Icon size="20" custom="iconfont icon-qr-code" class="qr-code-icon" @click="showQrCode(index)" v-if="listType == 'private'" />
+                                    <Icon size="30" custom="iconfont icon-qr-code" class="qr-code-icon" @click="showQrCode(index)" v-if="listType == 'private'" title="扫码加入名单"/>
                                 </div>
                                 <EmptyData v-if="teaClassList.length == 0" :top="160" :textContent="$t('cusMgt.noClassList')"></EmptyData>
                             </vuescroll>
@@ -67,8 +67,8 @@
                     </div>
                     <div class="course-classroom-info" id="table-height" slot="right">
                         <div class="course-classroom-info-header" style="padding-right:30px;">
-                            <span @click="selectTab('record')" :class="tabName == 'record' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">{{$t('cusMgt.cusRecord')}}</span>
                             <span @click="selectTab('activity')" :class="tabName == 'activity' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">{{$t('cusMgt.acRecord')}}</span>
+                            <span @click="selectTab('record')" :class="tabName == 'record' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">{{$t('cusMgt.cusRecord')}}</span>
                             <span @click="selectTab('stus')" :class="tabName == 'stus' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">{{$t('courseManage.classroom.studentList')}}</span>
                             <span v-show="tabName == 'stus' && listType == 'school'" class="group-tips">{{$t('cusMgt.groupTips')}}</span>
                             <!-- 个人课程时段设置暂不实做 -->
@@ -278,9 +278,13 @@
             </div>
         </Drawer>
         <!-- 创建名单 -->
-        <Modal v-model="newSlStatus" :title="$t('cusMgt.createList')" width="1200" @on-ok="confirmCreateList" class-name="dark-iview-modal" :loading="modalLoading">
+        <Modal v-model="newSlStatus" width="1200" @on-ok="confirmCreateList" class-name="dark-iview-modal" :loading="modalLoading">
+            <div slot="header">
+                <span class="create-list-title">{{$t('cusMgt.createList')}}</span>
+                <span class="create-list-tips">{{$t('cusMgt.createTips')}}</span>
+            </div>
             <div class="dark-iview-input list-name-box">
-                <span>{{$t('cusMgt.name')}}</span>
+                <span>{{$t('cusMgt.name')}}</span>
                 <Input v-model="listName" :placeholder="$t('cusMgt.nameHolder')" style="width: 300px" />
             </div>
             <StudentList v-if="$store.state.userInfo.hasSchool" @getSelectInfo="(selction)=>{createStuList = selction}"></StudentList>
@@ -475,7 +479,7 @@ export default {
             newSlStatus: false,
             stuLoading: false,
             listType: 'private',
-            tabName: 'record',
+            tabName: 'activity',
             addCusStatus: false,
             addStuStatus: false,
             joinQRcode: undefined,

+ 116 - 229
TEAMModelOS/ClientApp/src/view/teachcontent/index.vue

@@ -166,7 +166,7 @@
                                     <span class="table-file-name" v-show="editIndex !== index">{{row.name}}</span>
                                     <Input v-model="fileListShow[index].name" v-show="editIndex == index" style="width: 300px;" @on-change="checkName" />
                                     <span style="color:#ed4014" v-show="editIndex == index && formatErr">{{$t('teachContent.specialChart')}}(?*:"<>\/|)</span>
-                                    <Icon type="md-checkmark" v-show="editIndex == index && !formatErr" @click="confirmRename" class="rename-action-icon" />
+                                    <Icon type="md-checkmark" v-show="editIndex == index && !formatErr" @click="confirmRename('list')" class="rename-action-icon" />
                                     <Icon type="md-close" v-show="editIndex == index" @click="cancelRename" class="rename-action-icon" />
                                 </div>
                             </template>
@@ -178,7 +178,7 @@
                                     <Icon type="md-download" size="18" color="white" :title="$t('teachContent.tips3')" @click="downloadFile(index)" />
                                     <Icon v-if="activeType !== 'other' && (activeType == 'res' && row.extension != 'HTE')" type="md-eye" size="18" color="white" :title="$t('teachContent.tips4')" @click="openPreviewFile(index)" />
                                     <Icon v-if="$access.can('admin.*|content-upd') || routerScope == 'private'" type="md-trash" size="18" color="white" :title="$t('teachContent.tips7')" @click="delFile(row,index)" />
-                                    <Icon v-if="$access.can('admin.*|content-upd') || routerScope == 'private'" type="md-create" size="18" color="white" :title="$t('teachContent.tips6')" @click="rename(row,index)" />
+                                    <Icon v-if="$access.can('admin.*|content-upd') || routerScope == 'private'" type="md-create" size="18" color="white" :title="$t('teachContent.tips6')" @click="rename(row,index,'list')" />
                                 </div>
                             </template>
                         </Table>
@@ -192,6 +192,7 @@
                                     <Icon type="md-download" size="18" color="white" :title="$t('teachContent.tips3')" @click.stop="downloadFile(props.index)" />
                                     <Icon type="md-eye" size="18" color="white" :title="$t('teachContent.tips4')" @click.stop="openPreviewFile(props.index)" />
                                     <Icon v-if="$access.can('admin.*|content-upd') || routerScope == 'private'" type="md-trash" size="18" color="white" :title="$t('teachContent.tips7')" @click.stop="delFile(props.value, props.index)" />
+                                    <Icon v-if="$access.can('admin.*|content-upd') || routerScope == 'private'" type="md-create" size="18" color="white" :title="$t('teachContent.tips6')" @click.stop="rename(props.value, props.index, 'card')" />
                                     <span style="color:white; float:right;margin-right:10px;">{{$jsFn.formatBytes(props.value.size)}}</span>
                                 </div>
                             </div>
@@ -222,6 +223,10 @@
                 <MyHTEXRender v-else-if="previewFile.extension == 'HTEX'" :url="previewFile.url"></MyHTEXRender>
             </div>
         </div>
+        <Modal v-model="edidNameStatus" title="重命名" @on-ok="confirmRename('card')" @on-cancel="cancelRename">
+            <span style="margin-right:10px">文件名:</span>
+            <Input v-model="edName" :placeholder="renameBefore" style="width: 300px" />
+        </Modal>
     </div>
 </template>
 <script>
@@ -239,6 +244,9 @@ export default {
     },
     data() {
         return {
+            renameBefore: '',
+            edName: '',
+            edidNameStatus: false,
             teachSpace: 0,
             schoolBase: {
                 period: []
@@ -363,7 +371,18 @@ export default {
                 this.formatErr = false
             }
         },
-        rename(row, index) {
+        /**
+         * type list:列表模式 card:图片模式
+         */
+        rename(row, index, type) {
+            if (type == 'list') {
+
+            } else if (type == 'card') {
+                this.edidNameStatus = true
+                this.edName = row.name
+            } else {
+                return
+            }
             this.editIndex = index
             this.renameBefore = row.name
         },
@@ -374,11 +393,18 @@ export default {
             this.fileListShow = JSON.parse(dataTemp);
             this.editIndex = -1
         },
-        confirmRename() {
+        /**
+         * type list | card
+         */
+        confirmRename(mode) {
             let editIndex = this.editIndex
-            console.log(this.fileListShow[editIndex])
-            let newName = this.fileListShow[editIndex].name
-
+            let newName = mode == 'list' ? this.fileListShow[editIndex].name : this.edName
+            // 检查文件后缀
+            let oldEx = this.renameBefore.substring(this.renameBefore.lastIndexOf('.'), this.renameBefore.length)
+            let newEx = newName.substring(newName.lastIndexOf('.'), newName.length)
+            if (oldEx != newEx) {
+                this.$Message('不能修改文件后缀名')
+            }
             let params = {
                 scope: this.routerScope,
                 cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
@@ -388,6 +414,9 @@ export default {
             this.$api.blob.blobRename(params).then(
                 res => {
                     this.$Message.success(this.$t('teachContent.nameOk'))
+                    if (mode == 'card') {
+                        this.$set(this.fileListShow[editIndex], 'name', newName)
+                    }
                     let orginUrl = this.fileListShow[editIndex].url
                     let thum = this.fileListShow[editIndex].url
                     this.fileListShow[editIndex].blob = '/' + params.newName
@@ -410,52 +439,6 @@ export default {
             ).finally(() => {
                 this.editIndex = -1
             })
-            // if (this.fileListShow[this.editIndex].extension == 'HTEX') {
-            //     let newName = this.fileListShow[editIndex].name
-            //     this.containerClient.copyFolder(`res/${newName.replace('.HTEX', '/')}`, `res/${this.renameBefore.replace('.HTEX', '')}`).then(
-            //         res => {
-            //             this.$api.blob.deletePrefix({
-            //                 cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-            //                 prefix: `res/${this.renameBefore.replace('.HTEX', '')}`
-            //             }).then(
-            //                 res => {
-            //                     this.$Message.success(this.$t('teachContent.nameOk'))
-            //                     let orginUrl = this.fileListShow[editIndex].url
-            //                     this.fileListShow[editIndex].blob = `/res/${this.newName}/index.json`
-            //                     this.fileListShow[editIndex].url = orginUrl.replace(this.renameBefore, this.fileListShow[editIndex].name)
-            //                 }
-            //             )
-            //         },
-            //         err => {
-            //             this.$Message.error(this.$t('teachContent.nameErr'))
-            //         }
-            //     ).finally(() => {
-            //         this.editIndex = -1
-            //     })
-            // } else {
-            //     let sourceUrl = this.fileListShow[this.editIndex].url.substring(0, this.fileListShow[this.editIndex].url.lastIndexOf('?')) //截取授权之前的,授权不能encode
-            //     let targetUrl = this.fileListShow[this.editIndex].blob
-            //     targetUrl = targetUrl.replace(this.renameBefore, this.fileListShow[this.editIndex].name)
-            //     targetUrl = targetUrl.substring(1)
-            //     this.containerClient.copyBlob(targetUrl, sourceUrl, this.sasString).then(
-            //         res => {
-            //             //这里虽然是复制,但是是重命名操作,所以空间不会变化,就设置为0
-            //             this.containerClient.deleteBlob(this.fileListShow[editIndex].blob, 0).then(
-            //                 res => {
-            //                     this.$Message.success(this.$t('teachContent.nameOk'))
-            //                     let orginUrl = this.fileListShow[editIndex].url
-            //                     this.fileListShow[editIndex].blob = '/' + targetUrl
-            //                     this.fileListShow[editIndex].url = orginUrl.replace(this.renameBefore, this.fileListShow[editIndex].name)
-            //                 }
-            //             )
-            //         },
-            //         err => {
-            //             this.$Message.error(this.$t('teachContent.nameErr'))
-            //         }
-            //     ).finally(() => {
-            //         this.editIndex = -1
-            //     })
-            // }
         },
         getFileUrl(files) { // 获取文件地址
             this.preUpdFiles.push(...files)
@@ -741,23 +724,23 @@ export default {
                 {
                     label: this.$t('teachContent.filterVideo'),
                     type: 'video',
-                    icon: 'logo-youtube'
+                    icon: 'iconfont icon-video-outline'
                 },
                 {
                     label: this.$t('teachContent.filterAudio'),
                     type: 'audio',
-                    icon: 'iconfont icon-audio2'
+                    icon: 'iconfont icon-audio-outline'
                 },
                 {
                     label: this.$t('teachContent.filterDoc'),
                     type: 'doc',
-                    icon: 'logo-wordpress'
+                    icon: 'iconfont icon-document'
                 },
 
                 {
                     label: this.$t('teachContent.filterOther'),
                     type: 'other',
-                    icon: 'md-filing'
+                    icon: 'iconfont icon-other-grad'
                 }
             ]
         },
@@ -875,107 +858,6 @@ export default {
                             this.$Message.error(this.$t('teachContent.props3'))
                         }
                     )
-                    // if (this.activeType == 'res') {
-                    //     //批量删除HTEX需要循环删除每个文件夹下面的文件
-                    //     this.selections.forEach((item, index) => {
-                    //         this.$api.blob.deletePrefix({
-                    //             cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-                    //             prefix: `res/${item.name.replace('.HTEX', '')}`,
-                    //             scope: this.routerScope
-                    //         }).then(
-                    //             res => {
-                    //                 let fileNames = this.selections.map((item) => { return item.name })
-                    //                 for (let i = 0; i < this.fileList[this.activeType].length; i++) {
-                    //                     let index = fileNames.indexOf(this.fileList[this.activeType][i].name)
-                    //                     if (index > -1) {
-                    //                         this.sizeInfo[this.activeType] -= this.fileList[this.activeType][i].size
-                    //                         this.sizeInfo.total -= this.fileList[this.activeType][i].size
-                    //                         this.fileList[this.activeType].splice(i, 1)
-                    //                         i--
-                    //                     }
-                    //                 }
-                    //                 let fs = this.fileList[this.activeType] ? this.fileList[this.activeType] : []
-                    //                 this.fileListShow = this._.cloneDeep(fs)
-                    //                 this.$Message.success(this.$t('teachContent.props2'))
-                    //             },
-                    //             err => {
-                    //                 this.$Message.error(this.$t('teachContent.props3'))
-                    //             }
-                    //         ).finally(() => {
-                    //             this.isLoading = false
-                    //         })
-                    //     })
-                    //     //删除本地最近上传数据
-                    //     let ids = this.selections.map(item => {
-                    //         return item.id
-                    //     })
-                    //     this.delCacheFiles(ids)
-                    // } else {
-                    //     let blobs = this.selections.map((item) => {
-                    //         return item.url.substring(0, item.url.lastIndexOf('?'))
-                    //     })
-                    //     let ids = this.selections.map((item) => {
-                    //         return item.id
-                    //     })
-                    //     this.$api.blob.deleteBlobs({
-                    //         cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-                    //         urls: blobs,
-                    //         scope: this.routerScope,
-                    //         ids
-                    //     }).then(
-                    //         res => {
-                    //             let thums = this.selections.map((item) => {
-                    //                 if (item.type == 'image') {
-                    //                     return item.url.substring(0, item.url.lastIndexOf('?')).replace('/image/', '/thum/')
-                    //                 } else if (item.extension == 'MP4') {
-                    //                     let n = item.url.substring(0, item.url.lastIndexOf('?')).replace('/video/', '/thum/')
-                    //                     return n.slice(0, n.lastIndexOf('.')) + '.png'
-                    //                 }
-
-                    //             })
-                    //             if (thums.length) {
-                    //                 this.$api.blob.deleteBlobs({
-                    //                     cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-                    //                     urls: thums,
-                    //                     scope: this.routerScope,
-                    //                     ids: []
-                    //                 })
-                    //             }
-
-                    //             let files = this.selections.map((item) => { return item.blob })
-                    //             for (let i = 0; i < this.fileList[this.activeType].length; i++) {
-                    //                 let index = files.indexOf(this.fileList[this.activeType][i].blob)
-                    //                 if (index != -1) {
-                    //                     this.sizeInfo[this.activeType] -= this.fileList[this.activeType][i].size
-                    //                     this.sizeInfo.total -= this.fileList[this.activeType][i].size
-                    //                     this.fileList[this.activeType].splice(i, 1)
-                    //                     i--
-                    //                 }
-                    //             }
-                    //             let fs = this.fileList[this.activeType] ? this.fileList[this.activeType] : []
-                    //             this.fileListShow = this._.cloneDeep(fs)
-                    //             this.$Message.success(this.$t('teachContent.props2'))
-
-                    //             if (this.activeType == 'recent') {
-                    //                 this.selections.forEach(item => {
-                    //                     let type = item.type
-                    //                     if (this.fileList[type]) {
-                    //                         for (let i = 0; i < this.fileList[type].length; i++) {
-                    //                             if (item.id == this.fileList[type][i].id) {
-                    //                                 this.fileList[type].splice(i, 1)
-                    //                             }
-                    //                         }
-                    //                     }
-                    //                 })
-                    //             }
-                    //             //删除本地最近上传数据
-                    //             this.delCacheFiles(ids)
-                    //         },
-                    //         err => {
-                    //             this.$Message.success(this.$t('teachContent.props3'))
-                    //         }
-                    //     )
-                    // }
                 }
             })
         },
@@ -992,87 +874,92 @@ export default {
                     //需要先删除CosmosDB记录的Blob信息
                     let params = {
                         scope: this.routerScope,
-                        name: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-                        opt: 'del',
-                        id: [file.id]
+                        cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
+                        blobs: []
                     }
-                    this.$api.blob.BlobInfoMgt(params).then(
+                    params.blobs.push({
+                        path: file.blob.substring(1),
+                        id: file.id
+                    })
+                    this.$api.blob.deleteBlobs(params).then(
                         res => {
-                            //这里开始真正的删除Blob
+                            this.$Message.success(this.$t('teachContent.props2'))
+                            //这里开始真正的删除Blob,后端处理,前端不用处理blob
                             //删除HTEX需要批量删除
-                            if (file.extension == 'HTEX') {
-                                this.sizeInfo[this.activeType] -= file.size
-                                this.sizeInfo.total -= file.size
-                                this.fileListShow.splice(index, 1)
-                                for (let i in this.fileList[this.activeType]) {
-                                    if (this.fileList[this.activeType][i].url == file.url) {
-                                        this.fileList[this.activeType].splice(i, 1)
-                                    }
-                                }
-                                this.$api.blob.deletePrefix({
-                                    cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-                                    prefix: `res/${file.name.replace('.HTEX', '')}`
-                                }).then(
-                                    res => {
-                                        this.$Message.success(this.$t('teachContent.props2'))
-                                    },
-                                    err => {
-                                        // this.$Message.error(this.$t('teachContent.props3'))
-                                        console.log('delete blob error')
-                                    }
-                                ).finally(() => {
-                                    this.isLoading = false
-                                })
-                            } else {
-                                this.sizeInfo[this.activeType] -= file.size
-                                this.sizeInfo.total -= file.size
-                                this.fileListShow.splice(index, 1)
-                                for (let i in this.fileList[this.activeType]) {
-                                    if (this.fileList[this.activeType][i].url == file.url) this.fileList[this.activeType].splice(i, 1)
-                                }
-                                this.$Message.success(this.$t('teachContent.props2'))
-                                this.containerClient.deleteBlob(file.blob, file.size).then(
-                                    (res) => {
-                                        //删除缩略图或封面
-                                        if (file.type == 'image') {
-                                            let thum = file.blob.replace('/image/', '/thum/')
-                                            //这里暂时预设缩略图大小为60KB
-                                            this.containerClient.deleteBlob(thum, 60 * 1024)
-                                        } else if (file.type == 'video' && file.extension == 'MP4') {
-                                            let thum = file.blob.replace('/video/', '/thum/')
-                                            thum = thum.slice(0, thum.lastIndexOf('.')) + '.png'
-                                            //这里暂时预封面大小为60KB
-                                            this.containerClient.deleteBlob(thum, 60 * 1024)
-                                        }
-                                        //如果是从最近上传删除,则需要判断是否已经请求对接类型的数据,如果有则需要删除对应的数据
-                                        if (this.activeType == 'recent') {
-                                            let type = file.type
-                                            if (this.fileList[type]) {
-                                                for (let i = 0; i < this.fileList[type].length; i++) {
-                                                    if (file.id == this.fileList[type][i].id) {
-                                                        this.fileList[type].splice(i, 1)
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    },
-                                    (err) => {
-                                        // this.$Message.error(this.$t('teachContent.props3'))
-                                        console.log('delete blob error')
-                                    }
-                                ).finally(() => {
-                                    this.isLoading = false
-                                })
+                            // if (file.extension == 'HTEX') {
+                            //     this.sizeInfo[this.activeType] -= file.size
+                            //     this.sizeInfo.total -= file.size
+                            //     this.fileListShow.splice(index, 1)
+                            //     for (let i in this.fileList[this.activeType]) {
+                            //         if (this.fileList[this.activeType][i].url == file.url) {
+                            //             this.fileList[this.activeType].splice(i, 1)
+                            //         }
+                            //     }
+                            //     this.$api.blob.deletePrefix({
+                            //         cntr: this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
+                            //         prefix: `res/${file.name.replace('.HTEX', '')}`
+                            //     }).then(
+                            //         res => {
+                            //             this.$Message.success(this.$t('teachContent.props2'))
+                            //         },
+                            //         err => {
+                            //             // this.$Message.error(this.$t('teachContent.props3'))
+                            //             console.log('delete blob error')
+                            //         }
+                            //     ).finally(() => {
+                            //         this.isLoading = false
+                            //     })
+                            // } else {
+                            //     this.sizeInfo[this.activeType] -= file.size
+                            //     this.sizeInfo.total -= file.size
+                            //     this.fileListShow.splice(index, 1)
+                            //     for (let i in this.fileList[this.activeType]) {
+                            //         if (this.fileList[this.activeType][i].url == file.url) this.fileList[this.activeType].splice(i, 1)
+                            //     }
+                            //     this.$Message.success(this.$t('teachContent.props2'))
+                            //     this.containerClient.deleteBlob(file.blob, file.size).then(
+                            //         (res) => {
+                            //             //删除缩略图或封面
+                            //             if (file.type == 'image') {
+                            //                 let thum = file.blob.replace('/image/', '/thum/')
+                            //                 //这里暂时预设缩略图大小为60KB
+                            //                 this.containerClient.deleteBlob(thum, 60 * 1024)
+                            //             } else if (file.type == 'video' && file.extension == 'MP4') {
+                            //                 let thum = file.blob.replace('/video/', '/thum/')
+                            //                 thum = thum.slice(0, thum.lastIndexOf('.')) + '.png'
+                            //                 //这里暂时预封面大小为60KB
+                            //                 this.containerClient.deleteBlob(thum, 60 * 1024)
+                            //             }
+                            //             //如果是从最近上传删除,则需要判断是否已经请求对接类型的数据,如果有则需要删除对应的数据
+                            //             if (this.activeType == 'recent') {
+                            //                 let type = file.type
+                            //                 if (this.fileList[type]) {
+                            //                     for (let i = 0; i < this.fileList[type].length; i++) {
+                            //                         if (file.id == this.fileList[type][i].id) {
+                            //                             this.fileList[type].splice(i, 1)
+                            //                         }
+                            //                     }
+                            //                 }
+                            //             }
+                            //         },
+                            //         (err) => {
+                            //             // this.$Message.error(this.$t('teachContent.props3'))
+                            //             console.log('delete blob error')
+                            //         }
+                            //     ).finally(() => {
+                            //         this.isLoading = false
+                            //     })
 
-                            }
+                            // }
                             //删除本地最近上传数据
                             this.delCacheFiles([file.id])
                         },
                         err => {
                             this.$Message.error(this.$t('teachContent.props3'))
                         }
-                    )
-
+                    ).finally(() => {
+                        this.isLoading = false
+                    })
                 }
             })
         },

+ 4 - 4
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -616,7 +616,7 @@ namespace TEAMModelOS.Controllers
             if (!request.TryGetProperty("answer", out JsonElement answer)) return BadRequest();
             if (!request.TryGetProperty("studentId", out JsonElement studentId)) return BadRequest();
             if (!request.TryGetProperty("subjectId", out JsonElement subjectId)) return BadRequest();
-            //if (!request.TryGetProperty("classId", out JsonElement classId)) return BadRequest();
+            if (!request.TryGetProperty("classIds", out JsonElement classId)) return BadRequest();
             if (!request.TryGetProperty("multipleRule", out JsonElement multipleRule)) return BadRequest();
             //if (!request.TryGetProperty("answers ", out JsonElement tandardAnswer)) return BadRequest();
             if (!request.TryGetProperty("paperId", out JsonElement paperId)) return BadRequest();
@@ -625,12 +625,12 @@ namespace TEAMModelOS.Controllers
             if (!request.TryGetProperty("scode", out JsonElement scode)) return BadRequest();
             try
             {
-                //List<string> ids = new List<string>();
-                //ids = classId.ToObject<List<string>>();
+                List<string> ids = new List<string>();
+                ids = classId.ToObject<List<string>>();
                 var client = _azureCosmos.GetCosmosClient();
                 List<ExamClassResult> examClassResults = new List<ExamClassResult>();
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
-                    queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}' and array_contains(c.studentIds,'{studentId}')",
+                    queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}' and c.info.id in ({string.Join(",", ids.Select(o => $"'{o}'"))})",
                     requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{school}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);