瀏覽代碼

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

CrazyIter 5 年之前
父節點
當前提交
aaf512b279
共有 30 個文件被更改,包括 1449 次插入617 次删除
  1. 3 2
      TEAMModelOS.Service/Models/Learn/HomeWork.cs
  2. 10 2
      TEAMModelOS.Service/Models/Learn/HomeWorkStudent.cs
  3. 7 2
      TEAMModelOS.Service/TEAMModelOS.Model.xml
  4. 18 2
      TEAMModelOS/ClientApp/src/api/learnActivity.js
  5. 1 1
      TEAMModelOS/ClientApp/src/common/CollapseMenuLayout.vue
  6. 287 269
      TEAMModelOS/ClientApp/src/common/UploadFile.vue
  7. 19 1
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.less
  8. 118 20
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.vue
  9. 17 51
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwTable.vue
  10. 0 1
      TEAMModelOS/ClientApp/src/components/learnactivity/SelectLearnUnit.less
  11. 67 67
      TEAMModelOS/ClientApp/src/components/learnactivity/SelectLearnUnit.vue
  12. 75 0
      TEAMModelOS/ClientApp/src/components/learnactivity/SelectOrderLearn.less
  13. 83 0
      TEAMModelOS/ClientApp/src/components/learnactivity/SelectOrderLearn.vue
  14. 1 1
      TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.less
  15. 211 97
      TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.vue
  16. 5 3
      TEAMModelOS/ClientApp/src/view/selflearning/LearnProgress.vue
  17. 1 5
      TEAMModelOS/ClientApp/src/view/selflearning/ManageHomeWork.less
  18. 70 11
      TEAMModelOS/ClientApp/src/view/selflearning/ManageHomeWork.vue
  19. 105 5
      TEAMModelOS/ClientApp/src/view/selflearning/ManageSelfLearn.less
  20. 191 22
      TEAMModelOS/ClientApp/src/view/selflearning/ManageSelfLearn.vue
  21. 0 1
      TEAMModelOS/ClientApp/src/view/teachcontent/CreateLearnUnit.vue
  22. 2 1
      TEAMModelOS/ClientApp/src/view/teachcontent/CreateOrderLearn.vue
  23. 1 1
      TEAMModelOS/ClientApp/src/view/teachcontent/ManageOrderLearn.less
  24. 93 35
      TEAMModelOS/ClientApp/src/view/teachcontent/ManageOrderLearn.vue
  25. 0 1
      TEAMModelOS/ClientApp/src/view/teachcontent/ManageUnit.vue
  26. 37 2
      TEAMModelOS/Controllers/Analysis/AchievementController.cs
  27. 7 4
      TEAMModelOS/Controllers/Core/FileController.cs
  28. 4 2
      TEAMModelOS/Controllers/Learn/HomeWorkController.cs
  29. 11 6
      TEAMModelOS/Controllers/Learn/LearnController.cs
  30. 5 2
      TEAMModelOS/Controllers/Syllabus/SyllabusController.cs

+ 3 - 2
TEAMModelOS.Service/Models/Learn/HomeWork.cs

@@ -79,9 +79,9 @@ namespace TEAMModelOS.Service.Models.Learn
         //public Subdto subdto { get; set; }
 
         /// <summary>
-        /// 通知方式 0电子纸条 1 学生Email 2 家长Email
+        /// 
         /// </summary>
-        //public string noticeMode { get; set; }
+        public List<string> other { get; set; }
 
         //public class Subdto {
         //    /// <summary>
@@ -105,6 +105,7 @@ namespace TEAMModelOS.Service.Models.Learn
             public string classroomCode { get; set; }
             [Required(ErrorMessage = "{0} 必须填写")]
             public string scopeCode { get; set; }
+            public string classroomName { get; set; }
         }
 
         /// <summary>

+ 10 - 2
TEAMModelOS.Service/Models/Learn/HomeWorkStudent.cs

@@ -17,6 +17,8 @@ namespace TEAMModelOS.Service.Models.Learn
         public HomeWorkStudent() {
             content = new List<HomeWorkContent>();
             comments = new List<HomeWorkComment>();
+            classroom = new ClassroomItem();
+            nativeroom = new ClassroomItem();
         }
         public string id { get; set; }
 
@@ -38,12 +40,12 @@ namespace TEAMModelOS.Service.Models.Learn
         /// <summary>
         /// 上课班级
         /// </summary>
-        public string classroomCode { get; set; }
+        public ClassroomItem classroom { get; set; }
 
         /// <summary>
         /// 原生班级
         /// </summary>
-        public string nativeroomCode { get; set; }
+        public ClassroomItem nativeroom{ get; set; }
 
 
         /// <summary>
@@ -79,6 +81,12 @@ namespace TEAMModelOS.Service.Models.Learn
         //public Dictionary<string,HomeWorkComment> comments { get; set; }
     }
 
+    public class ClassroomItem {
+        public string name { get; set; }
+        public string code { get; set; }
+
+    }
+
     /// <summary>
     /// 作业内容
     /// </summary>

+ 7 - 2
TEAMModelOS.Service/TEAMModelOS.Model.xml

@@ -314,6 +314,11 @@
             作业附件
             </summary>
         </member>
+        <member name="P:TEAMModelOS.Service.Models.Learn.HomeWork.other">
+            <summary>
+            
+            </summary>
+        </member>
         <member name="T:TEAMModelOS.Service.Models.Learn.HomeWork.Target">
             <summary>
             发布对象
@@ -364,12 +369,12 @@
             醍摩豆id
             </summary>
         </member>
-        <member name="P:TEAMModelOS.Service.Models.Learn.HomeWorkStudent.classroomCode">
+        <member name="P:TEAMModelOS.Service.Models.Learn.HomeWorkStudent.classroom">
             <summary>
             上课班级
             </summary>
         </member>
-        <member name="P:TEAMModelOS.Service.Models.Learn.HomeWorkStudent.nativeroomCode">
+        <member name="P:TEAMModelOS.Service.Models.Learn.HomeWorkStudent.nativeroom">
             <summary>
             原生班级
             </summary>

+ 18 - 2
TEAMModelOS/ClientApp/src/api/learnActivity.js

@@ -89,7 +89,23 @@ export default {
     */
     FindHomeWork: function (data) {
         return post('/api/HomeWork/FindHomeWork', data)
+    },
+    /*
+    * 查询老师课程下的所有班级
+    */
+    FindClassroomByTeacherId: function (data) {
+        return post('/api/HomeWork/FindClassroom', data)
+    },
+    /*
+    *新增或者编辑自主学子活动
+    */
+    SaveSelfLearn: function (data) {
+        return post('/api/Learn/SaveorUpdataLearningAutonomous', data)
+    },
+    /*
+    *查询自主学子活动
+    */
+    FindSelfLearn: function (data) {
+        return post('/api/Learn/FindLearningAutonomous', data)
     }
-
-
 }

+ 1 - 1
TEAMModelOS/ClientApp/src/common/CollapseMenuLayout.vue

@@ -201,7 +201,7 @@
                                 icon: '',
                                 name: '投票活动',
                                 router: '/home/manageVote',
-                                tag:'×'
+                                tag:'T'
                             },
                             {
                                 icon: '',

+ 287 - 269
TEAMModelOS/ClientApp/src/common/UploadFile.vue

@@ -1,284 +1,302 @@
 <template>
-  <div>
-    <Upload type="drag" action="" multiple :before-upload="beforeUpload" class="upload-wrap">
-      <p style="margin:20px 0px; margin-top:80px;font-size:30px;">{{$t('teachContent.uploadText')}}</p>
-      <Icon type="ios-cloud-upload" size="80" style="margin-bottom:80px;" />
-    </Upload>
-    <div class="upload-file-box">
-      <div class="upload-file-item" v-for="(item,index) in uploadedList">
-        <Icon type="ios-folder" />
-        <p class="upload-file-name">{{item.fileName}}</p>
-        <img width="25" style="float:right;" src="@/assets/loading/loading3.svg" v-if="item.status == 0"/>
-        <Icon type="md-checkmark" style="float:right;" color="aqua" size="20" v-else-if="item.status == 1"/>
-        <Icon type="md-close" style="float:right;" color="red" size="20" v-else-if="item.status == 2"/>
-      </div>
+    <div>
+        <Upload type="drag" action="" multiple :before-upload="beforeUpload" class="upload-wrap" :format="format" :max-size="maxSize" :on-format-error="onFormatError" :on-exceeded-size="sizeError">
+            <p style="margin:20px 0px; margin-top:80px;font-size:30px;">{{$t('teachContent.uploadText')}}</p>
+            <Icon type="ios-cloud-upload" size="80" style="margin-bottom:80px;" />
+        </Upload>
+        <div class="upload-file-box">
+            <div class="upload-file-item" v-for="(item,index) in uploadedList">
+                <Icon type="ios-folder" />
+                <p class="upload-file-name">{{item.fileName}}</p>
+                <img width="25" style="float:right;" src="@/assets/loading/loading3.svg" v-if="item.status == 0" />
+                <Icon type="md-checkmark" style="float:right;" color="aqua" size="20" v-else-if="item.status == 1" />
+                <Icon type="md-close" style="float:right;" color="red" size="20" v-else-if="item.status == 2" />
+            </div>
+        </div>
     </div>
-  </div>
 </template>
 <script>
-  import sha1 from 'js-sha1'
-  require('@/utils/azure-storage-blob.js')
-  export default {
-    data() {
-      return {
-        urlString: '',
-        containerURL: undefined,
-        sasString: '',
-        uploadedList: [],
-        contentTypes: [
-          ['JPG', 'JPEG', 'PNG', 'GIF'],
-          ['AVI', 'MP4'],
-          ['PPT', 'PPTX', 'DOC', 'DOCX', 'PDF', 'XLS', 'XLSX', 'HTE', 'HETX']
-        ]
-      }
-    },
-    props: {
-      accountName: {
-        default: 'teammodelostest',
-        type: String
-      },
-      containerName: {
-        default: 'teammodelos',
-        type: String
-      },
-      pathName: {
-        default: '',
-        type: String
-      },
-      quality: {
-        default: 0.2,
-        type: Number
-      }
+    import sha1 from 'js-sha1'
+    require('@/utils/azure-storage-blob.js')
+    export default {
+        data() {
+            return {
+                urlString: '',
+                containerURL: undefined,
+                sasString: '',
+                uploadedList: [],
+                contentTypes: [
+                    ['JPG', 'JPEG', 'PNG', 'GIF'],
+                    ['AVI', 'MP4'],
+                    ['PPT', 'PPTX', 'DOC', 'DOCX', 'PDF', 'XLS', 'XLSX', 'HTE', 'HETX']
+                ],
 
-    },
-    methods: {
-      checkSize() {
-
-      },
-      initBlob() {
-        this.containerURL = new window.azblob.ContainerURL(
-          // `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}?${this.sasString}`,
-          this.urlString + '/' + this.pathName + this.sasString,
-          window.azblob.StorageURL.newPipeline(new window.azblob.AnonymousCredential())
-        )
-      },
-      dataURLtoFile(dataurl, filename) {
-        var arr = dataurl.split(','); var mime = arr[0].match(/:(.*?);/)[1]
-          var bstr = atob(arr[1]); var n = bstr.length; var u8arr = new Uint8Array(n)
-        while (n--) {
-          u8arr[n] = bstr.charCodeAt(n)
-        }
-        return new File([u8arr], filename, { type: mime })
-      },
-      compressFile(file, fileInfo) {
-        if (fileInfo.type == 'picture') {
-          let reader = new FileReader()
-          reader.readAsDataURL(file)
-          reader.onload = (e) => {
-            let dataUrl = e.target.result
-            let img = new Image()
-            img.src = dataUrl
-            img.onload = () => {
-              let canvas = document.createElement('canvas')
-              canvas.width = 300
-              canvas.height = 300 * img.height / img.width
-              let ctx = canvas.getContext('2d')
-              ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height)
-              let newImgData = canvas.toDataURL(file.type, this.quality)
-              var resultFile = this.dataURLtoFile(newImgData, file.name)
-              this.initBlob()
-              const compressBlobURL = window.azblob.BlockBlobURL.fromContainerURL(
-                this.containerURL,
-                'compress' + file.name
-              )
-              let options = {
-                blockSize: 10 * 1024 * 1024
-              }
-              window.azblob.uploadBrowserDataToBlockBlob(
-                window.azblob.Aborter.none,
-                resultFile,
-                compressBlobURL,
-                options
-              ).then(
-                res => {
-                  // fileInfo['compressUrl'] = `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}/compress${file.name}`
-                  fileInfo['compressUrl'] = this.urlString + '/' + this.pathName + '/compress' + file.name
-                  this.$emit('successData', fileInfo)
-                },
-                err => {
-                  fileInfo['status'] = 2
-                  console.log(err)
-                }
-              )
             }
-          }
-        } else {
-          let video = document.createElement('video')
-          video.setAttribute('width', '300')
-          video.setAttribute('controls', 'controls')
-          video.setAttribute('crossOrigin', '*')
-          video.setAttribute('src', fileInfo.blobUrl + this.sasString)
-          video.addEventListener('loadeddata', () => {
-            let canvas = document.createElement('canvas')
-            canvas.width = 300
-            canvas.height = 300 * video.videoHeight / video.videoWidth
-            let ctx = canvas.getContext('2d')
-            ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.height)
-            let newVideoData = canvas.toDataURL('image/png', this.quality)
-            let resultFile = this.dataURLtoFile(newVideoData, file.name)
-            this.initBlob()
-            let posterName = 'compress' + file.name.replace(fileInfo.extension, 'png')
-            const compressBlobURL = window.azblob.BlockBlobURL.fromContainerURL(
-              this.containerURL,
-              posterName
-            )
-            window.azblob.uploadBrowserDataToBlockBlob(
-              window.azblob.Aborter.none,
-              resultFile,
-              compressBlobURL
-            ).then(
-              res => {
-                // fileInfo['compressUrl'] = `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}/${posterName}`
-                fileInfo['compressUrl'] = this.urlString + '/' + this.pathName + '/' + posterName
-                this.$emit('successData', fileInfo)
-              },
-              err => {
-                fileInfo['status'] = 2
-                console.log(err)
-              }
-            )
-          })
-        }
-      },
-      uploadToBlob(file) {
-        const blockBlobURL = window.azblob.BlockBlobURL.fromContainerURL(
-          this.containerURL,
-          file.name
-        )
-        let fileItem = {}
-        fileItem['fileName'] = file.name
-        // fileItem['blobUrl'] = `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}/${file.name}`
-        fileItem['blobUrl'] = this.urlString + '/' + this.pathName + '/' + file.name
-        fileItem['extension'] = file.name.substring(file.name.lastIndexOf('.') + 1)
-        fileItem['size'] = file.size
-        fileItem['status'] = 0
-        fileItem['contentType'] = file.type
-        let type = 'other'
-        for (let item in this.contentTypes) {
-          if (this.contentTypes[item].indexOf(fileItem.extension.toUpperCase()) !== -1) {
-            switch (true) {
-              case item == 0:
-                type = 'picture'
-                break
-              case item == 1:
-                type = 'video'
-                break
-              case item == 2:
-                type = 'document'
-                break
-              default:
-                break
+        },
+        props: {
+            accountName: {
+                default: 'teammodelostest',
+                type: String
+            },
+            containerName: {
+                default: 'teammodelos',
+                type: String
+            },
+            pathName: {
+                default: '',
+                type: String
+            },
+            quality: {
+                default: 0.2,
+                type: Number
+            },
+            maxSize: {
+                default: 4,
+                type: Number
+            },
+            format: {
+                default: () => {
+                    return []
+                },
+                type: Array
             }
-            break
-          }
-        }
-        fileItem['type'] = type
-        this.uploadedList.push(fileItem)
-        window.azblob.uploadBrowserDataToBlockBlob(
-          window.azblob.Aborter.none,
-          file,
-          blockBlobURL
-        ).then(
-          res => {
-            let reader = new FileReader()
-            reader.readAsArrayBuffer(file)
-            // reader.readAsArrayBuffer(file)
-            reader.onload = (ev) => {
-              try {
-                let fileRes = ev.target.result
-                let str = sha1(fileRes)
-                let index = this.getIndex(this.uploadedList, fileItem)
-                this.uploadedList[index].status = 1
-                this.uploadedList[index]['createTime'] = Date.parse(res.lastModified)
-                this.uploadedList[index]['sha1Code'] = str
-                if (this.uploadedList[index].type == 'picture' || this.uploadedList[index].type == 'video') {
-                  this.compressFile(file, this.uploadedList[index])
+        },
+        methods: {
+            onFormatError() {
+                this.$Message.error("含不支持的文件类型")
+            },
+            sizeError() {
+                this.$Message.error("文件大小超出限制")
+            },
+            checkSize() {
+
+            },
+            initBlob() {
+                this.containerURL = new window.azblob.ContainerURL(
+                    // `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}?${this.sasString}`,
+                    this.urlString + '/' + this.pathName + this.sasString,
+                    window.azblob.StorageURL.newPipeline(new window.azblob.AnonymousCredential())
+                )
+            },
+            dataURLtoFile(dataurl, filename) {
+                var arr = dataurl.split(','); var mime = arr[0].match(/:(.*?);/)[1]
+                var bstr = atob(arr[1]); var n = bstr.length; var u8arr = new Uint8Array(n)
+                while (n--) {
+                    u8arr[n] = bstr.charCodeAt(n)
+                }
+                return new File([u8arr], filename, { type: mime })
+            },
+            compressFile(file, fileInfo) {
+                if (fileInfo.type == 'picture') {
+                    let reader = new FileReader()
+                    reader.readAsDataURL(file)
+                    reader.onload = (e) => {
+                        let dataUrl = e.target.result
+                        let img = new Image()
+                        img.src = dataUrl
+                        img.onload = () => {
+                            let canvas = document.createElement('canvas')
+                            canvas.width = 300
+                            canvas.height = 300 * img.height / img.width
+                            let ctx = canvas.getContext('2d')
+                            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height)
+                            let newImgData = canvas.toDataURL(file.type, this.quality)
+                            var resultFile = this.dataURLtoFile(newImgData, file.name)
+                            this.initBlob()
+                            const compressBlobURL = window.azblob.BlockBlobURL.fromContainerURL(
+                                this.containerURL,
+                                'compress' + file.name
+                            )
+                            let options = {
+                                blockSize: 10 * 1024 * 1024
+                            }
+                            window.azblob.uploadBrowserDataToBlockBlob(
+                                window.azblob.Aborter.none,
+                                resultFile,
+                                compressBlobURL,
+                                options
+                            ).then(
+                                res => {
+                                    // fileInfo['compressUrl'] = `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}/compress${file.name}`
+                                    fileInfo['compressUrl'] = this.urlString + '/' + this.pathName + '/compress' + file.name
+                                    this.$emit('successData', fileInfo)
+                                },
+                                err => {
+                                    fileInfo['status'] = 2
+                                    console.log(err)
+                                }
+                            )
+                        }
+                    }
                 } else {
-                  this.$emit('successData', this.uploadedList[index])
+                    let video = document.createElement('video')
+                    video.setAttribute('width', '300')
+                    video.setAttribute('controls', 'controls')
+                    video.setAttribute('crossOrigin', '*')
+                    video.setAttribute('src', fileInfo.blobUrl + this.sasString)
+                    video.addEventListener('loadeddata', () => {
+                        let canvas = document.createElement('canvas')
+                        canvas.width = 300
+                        canvas.height = 300 * video.videoHeight / video.videoWidth
+                        let ctx = canvas.getContext('2d')
+                        ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.height)
+                        let newVideoData = canvas.toDataURL('image/png', this.quality)
+                        let resultFile = this.dataURLtoFile(newVideoData, file.name)
+                        this.initBlob()
+                        let posterName = 'compress' + file.name.replace(fileInfo.extension, 'png')
+                        const compressBlobURL = window.azblob.BlockBlobURL.fromContainerURL(
+                            this.containerURL,
+                            posterName
+                        )
+                        window.azblob.uploadBrowserDataToBlockBlob(
+                            window.azblob.Aborter.none,
+                            resultFile,
+                            compressBlobURL
+                        ).then(
+                            res => {
+                                // fileInfo['compressUrl'] = `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}/${posterName}`
+                                fileInfo['compressUrl'] = this.urlString + '/' + this.pathName + '/' + posterName
+                                this.$emit('successData', fileInfo)
+                            },
+                            err => {
+                                fileInfo['status'] = 2
+                                console.log(err)
+                            }
+                        )
+                    })
                 }
-              } catch (e) {
-                console.log(e)
-              }
-            }
-          },
-          err => {
-            fileItem['status'] = 2
-            console.log(err)
-          }
-        )
-        return false
-      },
-      beforeUpload(file) {
-        let url = file.name
-        this.$api.uploadFile.getContainerSAS().then(
-          (res) => {
-            if (res.error == null) {
-              this.sasString = res.result.data.SAS
-              this.urlString = res.result.data.Url
-              this.initBlob()
-              this.uploadToBlob(file)
-            } else {
-              alert('API error!')
+            },
+            uploadToBlob(file) {
+                const blockBlobURL = window.azblob.BlockBlobURL.fromContainerURL(
+                    this.containerURL,
+                    file.name
+                )
+                let fileItem = {}
+                fileItem['fileName'] = file.name
+                // fileItem['blobUrl'] = `https://${this.accountName}.blob.core.chinacloudapi.cn/${this.containerName}/${this.pathName}/${file.name}`
+                fileItem['blobUrl'] = this.urlString + '/' + this.pathName + '/' + file.name
+                fileItem['extension'] = file.name.substring(file.name.lastIndexOf('.') + 1)
+                fileItem['size'] = file.size
+                fileItem['status'] = 0
+                fileItem['contentType'] = file.type
+                let type = 'other'
+                for (let item in this.contentTypes) {
+                    if (this.contentTypes[item].indexOf(fileItem.extension.toUpperCase()) !== -1) {
+                        switch (true) {
+                            case item == 0:
+                                type = 'picture'
+                                break
+                            case item == 1:
+                                type = 'video'
+                                break
+                            case item == 2:
+                                type = 'document'
+                                break
+                            default:
+                                break
+                        }
+                        break
+                    }
+                }
+                fileItem['type'] = type
+                this.uploadedList.push(fileItem)
+                window.azblob.uploadBrowserDataToBlockBlob(
+                    window.azblob.Aborter.none,
+                    file,
+                    blockBlobURL
+                ).then(
+                    res => {
+                        let reader = new FileReader()
+                        reader.readAsArrayBuffer(file)
+                        // reader.readAsArrayBuffer(file)
+                        reader.onload = (ev) => {
+                            try {
+                                let fileRes = ev.target.result
+                                let str = sha1(fileRes)
+                                let index = this.getIndex(this.uploadedList, fileItem)
+                                this.uploadedList[index].status = 1
+                                this.uploadedList[index]['createTime'] = Date.parse(res.lastModified)
+                                this.uploadedList[index]['sha1Code'] = str
+                                if (this.uploadedList[index].type == 'picture' || this.uploadedList[index].type == 'video') {
+                                    this.compressFile(file, this.uploadedList[index])
+                                } else {
+                                    this.$emit('successData', this.uploadedList[index])
+                                }
+                            } catch (e) {
+                                console.log(e)
+                            }
+                        }
+                    },
+                    err => {
+                        fileItem['status'] = 2
+                        console.log(err)
+                    }
+                )
+                return false
+            },
+            beforeUpload(file) {
+                let url = file.name
+                this.$api.uploadFile.getContainerSAS().then(
+                    (res) => {
+                        if (res.error == null) {
+                            this.sasString = res.result.data.SAS
+                            this.urlString = res.result.data.Url
+                            this.initBlob()
+                            this.uploadToBlob(file)
+                        } else {
+                            alert('API error!')
+                        }
+                    },
+                    (err) => {
+                        alert('API error!')
+                    }
+                )
+                return false
+            },
+            getIndex(_arr, _obj) {
+                var len = _arr.length
+                for (let i = 0; i < len; i++) {
+                    if (this.isObjEqual(_arr[i], _obj)) {
+                        return parseInt(i)
+                    }
+                }
+                return -1
+            },
+            isObjEqual(o1, o2) {
+                var props1 = Object.keys(o1)
+                var props2 = Object.keys(o2)
+                if (props1.length != props2.length) {
+                    return false
+                }
+                for (var i = 0, max = props1.length; i < max; i++) {
+                    var propName = props1[i]
+                    if (o1[propName] !== o2[propName]) {
+                        return false
+                    }
+                }
+                return true
             }
-          },
-          (err) => {
-            alert('API error!')
-          }
-        )
-        return false
-      },
-      getIndex(_arr, _obj) {
-        var len = _arr.length
-        for (let i = 0; i < len; i++) {
-          if (this.isObjEqual(_arr[i], _obj)) {
-            return parseInt(i)
-          }
-        }
-        return -1
-      },
-      isObjEqual(o1, o2) {
-        var props1 = Object.keys(o1)
-        var props2 = Object.keys(o2)
-        if (props1.length != props2.length) {
-          return false
-        }
-        for (var i = 0, max = props1.length; i < max; i++) {
-          var propName = props1[i]
-          if (o1[propName] !== o2[propName]) {
-            return false
-          }
-        }
-        return true
-      }
-    },
-    mounted() {
-      this.uploadedList = []
-    },
-    created() {}
-  }
+        },
+        mounted() {
+            this.uploadedList = []
+        },
+        created() { }
+    }
 
 </script>
 <style scoped>
-  .upload-file-item {
-    cursor:pointer;
-    color:#909090;
-    margin-top:5px;
-  }
-    .upload-file-item:hover {
-      color:white;
+    .upload-file-item {
+        cursor: pointer;
+        color: #909090;
+        margin-top: 5px;
+    }
+
+        .upload-file-item:hover {
+            color: white;
+        }
+
+    .upload-file-name {
+        display: inline-block;
+        margin-left: 10px;
     }
-  .upload-file-name {
-    display:inline-block;
-    margin-left:10px;
-  }
 </style>

+ 19 - 1
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.less

@@ -34,7 +34,8 @@
         color: #939393;
     }
 
-    .ivu-input, .ivu-select-single .ivu-select-selection {
+    .ivu-input, .ivu-select-single .ivu-select-selection,
+    .ivu-select-multiple .ivu-select-selection {
         background: #353535;
         border: none;
         margin-top: 10px;
@@ -43,6 +44,22 @@
         color: @primary-textColor;
     }
 
+    .ivu-tag {
+        border: none;
+        background: @primary-color;
+        height: 28px;
+        line-height: 28px;
+
+        i{
+            top:8px;
+            color:#fff;
+        }
+
+        .ivu-tag-text {
+            color: #fff;
+        }
+    }
+
     .ivu-select {
         color: @second-textColor;
     }
@@ -52,6 +69,7 @@
     }
 
     .ivu-select-single .ivu-select-selection .ivu-select-placeholder,
+    .ivu-select-multiple .ivu-select-selection .ivu-select-placeholder,
     .ivu-select-single .ivu-select-selection .ivu-select-selected-value {
         height: 40px;
         line-height: 40px;

+ 118 - 20
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.vue

@@ -1,12 +1,12 @@
 <template>
     <div class="component-hw-form">
-        <Form ref="hwForm" :model="hwForm" label-position="top" :rules="ruleValidate">
+        <Form ref="hwForm" :model="hwForm" label-position="top" :rules="ruleValidate" :disabled="!editable">
             <FormItem label="作业名称" prop="name">
                 <Input v-model="hwForm.name" placeholder="请输入作业名称"></Input>
             </FormItem>
             <FormItem label="作业对象" prop="target">
-                <Select v-model="hwForm.target" placeholder="请选择作业发布对象">
-                    <Option value="beijing">New York</Option>
+                <Select multiple v-model="hwForm.target" placeholder="请选择作业发布对象">
+                    <Option v-for="item in classRooms" :value="item.classroomCode" :key="item.classroomCode">{{ item.classroomName }}</Option>
                 </Select>
             </FormItem>
 
@@ -52,9 +52,9 @@
                 </CheckboxGroup>
             </FormItem>
 
-            <FormItem>
-                <Button type="primary" class="btn-save" @click="handleSubmit('hwForm')">保存</Button>
-                <Button @click="handleReset('formValidate')" class="btn-reset" style="margin-left: 8px">重置</Button>
+            <FormItem v-if="editable">
+                <Button type="primary" class="btn-save" @click="handleSubmit('hwForm')" :loading="isBtnLoading">保存</Button>
+                <Button @click="handleReset('hwForm')" class="btn-reset" style="margin-left: 8px">重置</Button>
             </FormItem>
         </Form>
     </div>
@@ -62,10 +62,24 @@
 <script>
     import E from 'wangeditor'
     export default {
+        props: {
+            editItem: {
+                default: null,
+                type: Object
+            },
+            editable: {
+                default: false,
+                type: Boolean
+            }
+        },
         data() {
             return {
+                isEdit: false,
+                isBtnLoading:false,
+                editInfo: null,
                 userInfo:this.$store.state.userInfo,
                 descriptionEditor: null,
+                classRooms:[],
                 defaultConfig: {
                   uploadImgServer: '/api/file/uploadWangEditor', // 图片上传地址
                   showLinkImg: false, // 是否展示网络图片链接上传
@@ -75,7 +89,7 @@
                 },
                 hwForm: {
                     name: '',
-                    target: '',
+                    target: [],
                     endTime: '',
                     publishModel:'0',
                     startTime:'',
@@ -103,7 +117,7 @@
                         { required: true, message: '作业描述不能为空', trigger: 'blur' }
                     ],
                     target: [
-                        { required: true, message: '作业对象不能为空', trigger: 'change' }
+                        { required: true, message: '作业对象不能为空' }
                     ],
                     endTime: [
                         { required: true, type: 'date', message: '请设置结束时间', trigger: 'change' }
@@ -119,27 +133,67 @@
              */
             handleSubmit(name) {
                 this.$refs[name].validate((valid) => {
-                    if (valid) {
-                        console.log(this.hwForm)
+                    if (valid && this.getSimpleText(this.hwForm.description)) {
                         let params = Object.assign({}, this.defaultParams)
+                        let target = []
                         params.scopeCode = this.userInfo.TEAMModelId
                         params.name = this.hwForm.name
                         params.publishModel = this.hwForm.publishModel
-                        params.startTime = this.hwForm.publishModel === '1' ? Math.round(this.hwForm.startTime.getTime()) : null
+                        params.startTime = this.hwForm.publishModel === '1' ? Math.round(this.hwForm.startTime.getTime()) : 0
                         params.endTime = Math.round(this.hwForm.endTime.getTime())
                         params.description = this.hwForm.description
+                        params.other = this.hwForm.other
                         params.resource = []
-                        params.target = []
+                        if (this.isEdit) {
+                            params.id = this.editInfo.id
+                        }
+
+                        /** 替换作业对象格式 */
+                        this.hwForm.target.forEach(item => {
+                            target.push({
+                                classroomCode: item,
+                                classroomName: this.classRooms.filter(i => i.classroomCode === item)[0].classroomName,
+                                scopeCode: this.classRooms.filter(i => i.classroomCode === item)[0].scopeCode
+                            })
+                        })
 
-                        console.log(params)
-                        console.log(this.defaultParams)
-                        this.$Message.success('操作成功')
+                        params.target = target
+                        this.isBtnLoading = true
+                        this.saveorUpdataHw(params).then(res => {
+                            this.$Message.success(this.isEdit ? '修改成功!' : '添加成功!')
+                            this.$emit('onAddSuccess')
+                            this.isBtnLoading = false
+                        })
                     } else {
                         this.$Message.error('请将信息填写完整')
                     }
                 })
             },
 
+            /**
+             * 获取当前教师的所有教室数据
+             * @param teacherId 老师的醍摩豆ID
+             */
+            getClassrooms(teacherId) {
+                return new Promise((r, j) => {
+                    this.$api.learnActivity.FindClassroomByTeacherId(teacherId).then(res => {
+                        if (!res.error && res.result.data) {
+                            r(res.result.data)
+                        } else {
+                            j(500)
+                            this.$Message.error('获取数据失败')
+                        }
+                    })
+                })
+                
+            },
+
+            // 提取富文本内容中的文本
+            getSimpleText(html) {
+                var msg = html.replace(/<(?!img|video).*?>/g, '')// 执行替换成空字符
+                return msg.replace(/&nbsp;/ig, '')
+            },
+
             /**
              * 重置表单
              * @param name
@@ -164,22 +218,66 @@
              * @param data
              */
             saveorUpdataHw(data) {
-                this.$api.learnActivity.SaveorUpdataHomeWork(data).then(res => {
-                    console.log(res)
+                return new Promise((r, j) => {
+                    this.$api.learnActivity.SaveorUpdataHomeWork(data).then(res => {
+                        if (!res.error) {
+                            r(res.result.data)
+                        } else {
+                            j(res.error)
+                        }
+                    })
                 })
+                
+            },
+
+            /**
+             * 回显作业详情
+             * @param item
+             */
+            doRender(item) {
+                this.hwForm = {
+                    name: item.name,
+                    target: item.target.map(item => item.classroomCode),
+                    publishModel: item.publishModel,
+                    startTime: item.publishModel === '0' ? '' : new Date(item.startTime),
+                    endTime: new Date(item.endTime),
+                    description: item.description,
+                    other:item.other
+                }
+                this.descriptionEditor.txt.html(item.description)
             }
         },
         mounted() {
 
+            /** 获取可选教室列表 */
+            this.getClassrooms(this.userInfo.TEAMModelId).then(res => this.classRooms = res)
+
+            /** 初始化文件列表 */
             this.uploadList = this.$refs.upload.fileList;
 
+            /** 初始化作业详情的富文本编辑器 */
             let descriptionEditor = new E(this.$refs.descriptionEditor)
             descriptionEditor.customConfig = this.defaultConfig
-            descriptionEditor.customConfig.onchange = (html) => {
-                this.hwForm.description = html
-            }
+            descriptionEditor.customConfig.onchange = (html) => { this.hwForm.description = html }
             descriptionEditor.create()
             this.descriptionEditor = descriptionEditor
+        },
+        watch: {
+            editItem: {
+                handler(newValue) {
+                    /** 编辑回显 */
+                    if (newValue) {
+                        this.doRender(newValue)
+                        this.isEdit = true
+                        this.editInfo = newValue
+                    } else {
+                        /** 新增重置 */
+                        this.handleReset('hwForm')
+                        this.descriptionEditor.txt.clear()
+                    }
+                },
+                deep: true
+            }
         }
     }
 </script>

+ 17 - 51
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwTable.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="component-hw-table">
-        <Table border size='small' ref="selection" :columns="columns" :data="tableData.concat(tableData.concat(tableData))" stripe></Table>
+        <Table border size='small' ref="selection" :columns="columns" :data="tableData" stripe></Table>
 
         <!-- 评分以及评价弹窗 -->
         <Modal v-model="setScoreModal"
@@ -42,6 +42,7 @@
 </template>
 <script>
     export default {
+        props:['studentsList'],
         data() {
             return {
                 setScoreModal: false,
@@ -136,56 +137,7 @@
                         }
                     }
                 ],
-                tableData: [
-                    {
-                        name: '张三',
-                        className: '初一1班',
-                        id: '140015511001',
-                        isSubmit: '否',
-                        submitTime: '-',
-                        score:'-'
-                    },
-                    {
-                        name: '张三',
-                        className: '初一1班',
-                        id: '140015511001',
-                        isSubmit: '否',
-                        submitTime: '-',
-                        score:'-'
-                    },
-                    {
-                        name: '张三',
-                        className: '初一1班',
-                        id: '140015511001',
-                        isSubmit: '否',
-                        submitTime: '-',
-                        score:'-'
-                    },
-                    {
-                        name: '张三',
-                        className: '初一1班',
-                        id: '140015511001',
-                        isSubmit: '否',
-                        submitTime: '-',
-                        score:'-'
-                    },
-                    {
-                        name: '张三',
-                        className: '初一1班',
-                        id: '140015511001',
-                        isSubmit: '否',
-                        submitTime: '-',
-                        score:'-'
-                    },
-                    {
-                        name: '张三',
-                        className: '初一1班',
-                        id: '140015511001',
-                        isSubmit: '否',
-                        submitTime: '-',
-                        score:'-'
-                    }
-                ]
+                tableData: []
             }
         },
         methods: {
@@ -205,6 +157,20 @@
                     this.setScoreModal = false
                 }
             }
+        },
+        watch: {
+            studentsList: {
+                handler(newValue) {
+                    /** 编辑回显 */
+                    if (newValue) {
+                        console.log(newValue)
+                        this.tableData = newValue
+                    } else {
+                        /** 新增重置 */
+                    }
+                },
+                deep: true
+            }
         }
     }
 </script>

+ 0 - 1
TEAMModelOS/ClientApp/src/components/learnactivity/SelectLearnUnit.less

@@ -2,7 +2,6 @@
     background: #666666;
     margin-bottom: 10px;
     border-radius: 5px;
-    color: red;
 }
 
 .unit-list-wrap {

+ 67 - 67
TEAMModelOS/ClientApp/src/components/learnactivity/SelectLearnUnit.vue

@@ -57,73 +57,73 @@
             /**
              * 通过id查询题目信息
              * */
-            findQuestionById() {
-                if (this.unitList.length > 0) {
-                    this.isLoading = true
-                    if (!this.unitList[this.currentUnitIndex].requestedI) {
-                        this.$api.learnActivity.FindQuestionById(this.unitList[this.currentUnitIndex].item).then(
-                            res => {
-                                if (res.error == null) {
-                                    this.unitList[this.currentUnitIndex].item.length = 0
-                                    this.$set(this.unitList[this.currentUnitIndex], 'item', res.result.data)
-                                    this.unitList[this.currentUnitIndex].requestedI = true
-                                    console.log(this.unitList)
-                                } else {
-                                    this.$Message.error("API ERROR!")
-                                    setTimeout(() => {
-                                        this.isLoading = false
-                                    }, 500)
-                                }
-                            },
-                            err => {
-                                this.$Message.error("API ERROR!")
-                                setTimeout(() => {
-                                    this.isLoading = false
-                                }, 500)
-                            }
-                        )
-                    } else {
-                        setTimeout(() => {
-                            this.isLoading = false
-                        }, 200)
-                    }
-                }
-            },
+            //findQuestionById() {
+            //    if (this.unitList.length > 0) {
+            //        this.isLoading = true
+            //        if (!this.unitList[this.currentUnitIndex].requestedI) {
+            //            this.$api.learnActivity.FindQuestionById(this.unitList[this.currentUnitIndex].item).then(
+            //                res => {
+            //                    if (res.error == null) {
+            //                        this.unitList[this.currentUnitIndex].item.length = 0
+            //                        this.$set(this.unitList[this.currentUnitIndex], 'item', res.result.data)
+            //                        this.unitList[this.currentUnitIndex].requestedI = true
+            //                        console.log(this.unitList)
+            //                    } else {
+            //                        this.$Message.error("API ERROR!")
+            //                        setTimeout(() => {
+            //                            this.isLoading = false
+            //                        }, 500)
+            //                    }
+            //                },
+            //                err => {
+            //                    this.$Message.error("API ERROR!")
+            //                    setTimeout(() => {
+            //                        this.isLoading = false
+            //                    }, 500)
+            //                }
+            //            )
+            //        } else {
+            //            setTimeout(() => {
+            //                this.isLoading = false
+            //            }, 200)
+            //        }
+            //    }
+            //},
             /**
              * 通过id查询内容信息
              * */
-            findResourceById() {
-                if (this.unitList.length > 0) {
-                    this.isLoading = true
-                    if (!this.unitList[this.currentUnitIndex].requestedR) {
+            //findResourceById() {
+            //    if (this.unitList.length > 0) {
+            //        this.isLoading = true
+            //        if (!this.unitList[this.currentUnitIndex].requestedR) {
 
-                        this.$api.learnActivity.FindSyllabusResourceById(this.unitList[this.currentUnitIndex].resource).then(
-                            res => {
-                                if (res.error == null) {
-                                    this.unitList[this.currentUnitIndex].resource.length = 0
-                                    this.unitList[this.currentUnitIndex].resource = res.result.data
-                                    this.unitList[this.currentUnitIndex].requestedR = true
-                                } else {
-                                    this.$Message.error("API ERROR!")
-                                }
-                                setTimeout(() => {
-                                    this.isLoading = false
-                                }, 500)
-                            },
-                            err => {
-                                this.$Message.error("API ERROR!")
-                                setTimeout(() => {
-                                    this.isLoading = false
-                                }, 500)
-                            }
-                        )
-                    } else {
-                        setTimeout(() => {
-                            this.isLoading = false
-                        }, 200)
-                    }
-                }
-            },
+            //            this.$api.learnActivity.FindSyllabusResourceById(this.unitList[this.currentUnitIndex].resource).then(
+            //                res => {
+            //                    if (res.error == null) {
+            //                        this.unitList[this.currentUnitIndex].resource.length = 0
+            //                        this.unitList[this.currentUnitIndex].resource = res.result.data
+            //                        this.unitList[this.currentUnitIndex].requestedR = true
+            //                    } else {
+            //                        this.$Message.error("API ERROR!")
+            //                    }
+            //                    setTimeout(() => {
+            //                        this.isLoading = false
+            //                    }, 500)
+            //                },
+            //                err => {
+            //                    this.$Message.error("API ERROR!")
+            //                    setTimeout(() => {
+            //                        this.isLoading = false
+            //                    }, 500)
+            //                }
+            //            )
+            //        } else {
+            //            setTimeout(() => {
+            //                this.isLoading = false
+            //            }, 200)
+            //        }
+            //    }
+            //},
             /**
              * 获取最小单元列表
              * */
@@ -136,10 +136,10 @@
                     res => {
                         if (res.error == null) {
                             this.unitList = res.result.data
-                            if (this.unitList.length > 0) {
-                                this.findResourceById()
-                                this.findQuestionById()
-                            }
+                            //if (this.unitList.length > 0) {
+                            //    this.findResourceById()
+                            //    this.findQuestionById()
+                            //}
                         } else {
                             this.$Message.error('API ERROR!')
                         }

+ 75 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/SelectOrderLearn.less

@@ -0,0 +1,75 @@
+.unit-filter-wrap {
+    background: #666666;
+    margin-bottom: 10px;
+    border-radius: 5px;
+}
+
+.unit-list-wrap {
+    width: 100%;
+    height: 400px;
+    overflow: hidden;
+
+    &:before {
+        content: '';
+    }
+
+    .unit-list-item {
+        position: relative;
+        background: #484848;
+        margin-bottom: 2px;
+        margin-top: 6px;
+        border-radius: 2px;
+        padding: 10px 10px;
+        width: ~"calc(100% - 8px)";
+        height: fit-content;
+
+        &:hover {
+            background: #525252;
+            margin-bottom: 10px;
+            margin-top: 0px;
+            box-shadow: 1px 4px 5px #191919;
+        }
+
+        &:hover .unit-detail-action-icon {
+            display: inline-block !important;
+        }
+
+        .unit-name {
+            font-size: 16px;
+        }
+
+        .devid-line {
+            margin: 0 15px;
+            color: #AAAAAA;
+        }
+
+        .unit-detail-info {
+            font-size: 12px;
+            margin-top: 15px;
+            color: #AAAAAA;
+
+            .unit-detail-count {
+                color: white;
+            }
+        }
+
+        .unit-detail-action {
+            position: absolute;
+            right: 10px;
+            top: 0px;
+            line-height: 80px;
+
+            .unit-detail-action-icon {
+                color: white;
+                cursor: pointer;
+                font-size: 18px;
+                margin-right: 15px;
+                display: none;
+            }
+
+            .unit-detail-action-icon:hover {
+                color: aqua;
+            }
+        }
+    }
+}

+ 83 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/SelectOrderLearn.vue

@@ -0,0 +1,83 @@
+<template>
+    <div>
+        <div class="unit-filter-wrap dark-iview-input">
+            <Input search clearable placeholder="关键字搜索..." style="width: 100%" />
+        </div>
+        <div class="unit-list-wrap">
+            <vuescroll>
+                <div class="unit-list-item" v-for="(item,index) in orderLearnList" @click="selectOrder(item)" >
+                    <p class="unit-name">
+                        {{item.name}}
+                    </p>
+                    <div class="unit-detail-info">
+                        <span class="unit-datail-label">
+                            学习阶段数量:
+                        </span>
+                        <span class="unit-detail-count">
+                            {{item.steps.length}}
+                        </span>
+                    </div>
+                    <div class="unit-detail-action">
+                        <Icon class="unit-detail-action-icon" type="ios-folder-open" />
+                        <Icon class="unit-detail-action-icon" type="md-checkmark" size="20" @click="selectOrder(item)" :style="{color:selectedOrderId.indexOf(item.id) == -1 ? 'white':'aqua','display':selectedOrderId.indexOf(item.id) == -1 ? 'none':'inline-block'}" />
+                    </div>
+                    <!--<div class="order-step-content">
+
+                    </div>-->
+                </div>
+            </vuescroll>
+        </div>
+    </div>
+</template>
+<script>
+    export default {
+        data() {
+            return {
+                orderLearnList: [],
+                selectedOrderId: [],
+                selectedOrderItem: [],
+            }
+        }, 
+        methods: {
+            /**
+             * 查询编序式教材列表
+             * */
+            findOrderLearn() {
+                let requestData = {
+                    creator: this.$store.state.userInfo.TEAMModelId
+                }
+                this.$api.learnActivity.FindOrderLearn(requestData).then(
+                    res => {
+                        if (res.error == null) {
+                            this.orderLearnList = res.result.data
+                        } else {
+                            this.$Message.error('API ERROR!')
+                        }
+                    },
+                    err => {
+                        this.$Message.error('API ERROR!')
+                    }
+                )
+            },
+            selectOrder(item) {
+                let index = this.selectedOrderId.indexOf(item.id)
+                if (index == -1) {
+                    this.selectedOrderId.push(item.id)
+                    this.selectedOrderItem.push(item)
+                } else {
+                    this.selectedOrderId.splice(index, 1)
+                    this.selectedOrderItem.splice(index, 1)
+                }
+                this.$emit('selectOrderLearn', this.selectedOrderItem)
+            }
+        },
+        created() {
+            this.findOrderLearn()
+        }
+    }
+</script>
+<style scoped lang="less">
+    @import "./SelectOrderLearn.less";
+</style>
+<style>
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.less

@@ -123,7 +123,7 @@
 
 .content-file-wrap {
     height: fit-content;
-    padding: 10px 0px 20px 0px;
+    padding-bottom: 20px;
     color: white;
     margin-bottom: 10px;
 }

+ 211 - 97
TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.vue

@@ -30,8 +30,8 @@
                                 <Option v-for="(item,index) in classroomList" :value="item" :key="index">{{ item }}</Option>
                             </Select>
                         </FormItem>
-                        <FormItem label="截止时间" prop="endTime">
-                            <DatePicker v-model="selfLearnInfo.endTime" type="date" placeholder="设置截止时间" style="width:100%;"></DatePicker>
+                        <FormItem label="截止时间" prop="expire">
+                            <DatePicker type="date" placeholder="设置截止时间" style="width:100%;"></DatePicker>
                         </FormItem>
                         <FormItem label="闯关模式" prop="isOrder">
                             <div slot="label" style="display:inline-block;">
@@ -89,8 +89,7 @@
                             <vuescroll>
                                 <p class="content-type-label">内容:{{selfLearnInfo.steps[stepIndex].resource.length}}个</p>
                                 <div class="content-file-wrap">
-                                    <NoData style="margin-top:30px;" v-if="selfLearnInfo.steps[stepIndex].resource.length == 0"></NoData>
-                                    <p v-for="(item,index) in selfLearnInfo.steps[stepIndex].resource" class="content-file-item">{{item.fileName}}</p>
+                                    <ContentFileList :resources="selfLearnInfo.steps[stepIndex].resource"></ContentFileList>
                                 </div>
                                 <p class="content-type-label">题目:{{selfLearnInfo.steps[stepIndex].item.length}}道</p>
                                 <div class="content-question-wrap">
@@ -109,40 +108,14 @@
                class="dark-iview-modal"
                width="960"
                @on-ok="confirmSelectUnit">
-            <SelectLearnUnit></SelectLearnUnit>
+            <SelectLearnUnit @selectUnit="getSelectedUnit"></SelectLearnUnit>
         </Modal>
         <Modal v-model="selectOrderStatus"
                title="选择编序式教材"
                width="960"
                class="dark-iview-modal"
                @on-ok="confirmSelectOrder">
-            <div class="unit-filter-wrap dark-iview-input">
-                <Input search clearable placeholder="关键字搜索..." style="width: 100%" />
-            </div>
-            <div class="unit-list-wrap">
-                <vuescroll>
-                    <div class="unit-list-item" v-for="(item,index) in orderLearnList">
-                        <p class="unit-name">
-                            {{item.name}}
-                        </p>
-                        <div class="unit-detail-info">
-                            <span class="unit-datail-label">
-                                学习阶段数量:
-                            </span>
-                            <span class="unit-detail-count">
-                                {{item.steps.length}}
-                            </span>
-                        </div>
-                        <div class="unit-detail-action">
-                            <Icon class="unit-detail-action-icon" type="ios-folder-open" />
-                            <Icon class="unit-detail-action-icon" type="md-checkmark" size="20" @click="selectOrder(item)" :style="{color:selectedOrderId.indexOf(item.id) == -1 ? 'white':'aqua','display':selectedOrderId.indexOf(item.id) == -1 ? 'none':'inline-block'}" />
-                        </div>
-                        <div class="order-step-content">
-
-                        </div>
-                    </div>
-                </vuescroll>
-            </div>
+            <SelectOrderLearn @selectOrderLearn="getSelectdOrderLearn"></SelectOrderLearn>
         </Modal>
         <Modal v-model="addCustomStatus"
                title="自定义选择内容"
@@ -162,23 +135,36 @@
             <span>名称:</span>
             <Input v-model="editStepName" placeholder="请输入名称..." style="width: calc(100% - 50px);" />
         </Modal>
+        <Modal v-model="goToManageStatus"
+               title="管理自学活动"
+               ok-text="是"
+               cancel-text="否"
+               @on-ok="confirmToManage">
+            <p>自学活动保存成功,是否跳转到管理页面查看?</p>
+        </Modal>
     </div>
 </template>
 <script>
     import ChooseContent from '@/components/learnactivity/ChooseContent.vue'
     import QuestionList from '@/components/learnactivity/QuestionList.vue'
     import SelectLearnUnit from '@/components/learnactivity/SelectLearnUnit.vue'
+    import SelectOrderLearn from '@/components/learnactivity/SelectOrderLearn.vue'
     import NoData from '@/common/NoData.vue'
+    import ContentFileList from '@/components/learnactivity/ContentFileList.vue'
     export default {
         components: {
-            ChooseContent,NoData,QuestionList,SelectLearnUnit
+            ChooseContent,
+            NoData,
+            QuestionList,
+            SelectLearnUnit,
+            SelectOrderLearn,
+            ContentFileList
         },
         data() {
             return {
-                
-                
-                selectedOrderId: [],
-                selectedOrderItem: [],
+                goToManageStatus: false,
+                selectedOrderLearn: [],
+                selectedUnit:[],
                 editStepName: '',
                 stepIndex: 0,
                 demoLoginInfo: {
@@ -201,9 +187,9 @@
                     isOrder: [
                         { required: true, message: '请选择模式', trigger: 'change' }
                     ],
-                    target: [
-                        { required: true, message: '请选择发布对象', trigger: 'change' }
-                    ],
+                    //target: [
+                    //    { required: true, message: '请选择发布对象', trigger: 'change' }
+                    //],
                     introduce: [
                         { required: true, message: '请完善说明信息', trigger: 'change' }
                     ]
@@ -222,15 +208,12 @@
                     isOrder: '',
                     creator: '',
                     introduce: '',
-                    endTime: '',
+                    expire: 0,
                     steps: []
                 },
                 addStepStatus: false,
                 classroomList: [],
-                
-                orderLearnList: [],
                 isLoading: false,
-                
                 columns: [
                     {
                         title: '',
@@ -247,6 +230,154 @@
             }
         },
         methods: {
+            confirmToManage() {
+                this.$router.push({
+                    name: 'manageSelfLearn'
+                })
+            },
+            /**
+             * 处理SelectLearnUnit组件选择事件
+             * @param data
+             */
+            getSelectedUnit(data) {
+                this.selectedUnit = data
+            },
+            confirmSelectUnit() {
+                let itemPromise = []
+                let resourcePromise = []
+                for (let i = 0; i < this.selectedUnit.length; i++) {
+                    itemPromise.push(this.$api.learnActivity.FindQuestionById(this.selectedUnit[i].item))
+                    resourcePromise.push(this.$api.learnActivity.FindSyllabusResourceById(this.selectedUnit[i].resource))
+                }
+                Promise.all(itemPromise).then(
+                    itemRes => {
+                        console.log('itemRes')
+                        console.log(itemRes)
+                        Promise.all(resourcePromise).then(
+                            resourceRes => {
+                                console.log('resourceRes')
+                                console.log(resourceRes)
+                                for (let i = 0; i < this.selectedUnit.length; i++) {
+                                    this.selectedUnit[i].item = itemRes[i].result.data
+                                    this.selectedUnit[i].resource = resourceRes[i].result.data
+                                }
+                                this.selfLearnInfo.steps.push(...this.selectedUnit)
+                                console.log(this.selfLearnInfo)
+                                this.selectedUnit.length = 0
+                            },
+                            err => {
+                                console.log('err')
+                                console.log(err)
+                            }
+                        )
+                    },
+                    err => {
+                        console.log('err')
+                        console.log(err)
+                    }
+                )
+            },
+            /**
+             * 处理SelectOrderLearn组件选择事件
+             * @param data
+             */
+            getSelectdOrderLearn(data) {
+                this.selectedOrderLearn = data
+            },
+            confirmSelectOrder() {
+                let itemPromise = []
+                let resourcePromise = []
+                console.log(this.selectedOrderLearn)
+                for (let i = 0; i < this.selectedOrderLearn.length; i++) {
+                    for (let j = 0; j < this.selectedOrderLearn[i].steps.length; j++) {
+                        itemPromise.push(this.$api.learnActivity.FindQuestionById(this.selectedOrderLearn[i].steps[j].item))
+                        resourcePromise.push(this.$api.learnActivity.FindSyllabusResourceById(this.selectedOrderLearn[i].steps[j].resource))
+                    }
+                }
+                Promise.all(itemPromise).then(
+                    itemRes => {
+                        console.log('itemRes')
+                        console.log(itemRes)
+                        Promise.all(resourcePromise).then(
+                            resourceRes => {
+                                console.log('resourceRes')
+                                console.log(resourceRes)
+                                for (let i = 0; i < this.selectedOrderLearn.length; i++) {
+                                    for (let j = 0; j < this.selectedOrderLearn[i].steps.length; j++) {
+                                        let index = i * this.selectedOrderLearn.length + j
+                                        console.log(index)
+                                        this.selectedOrderLearn[i].steps[j].item = itemRes[index].result.data
+                                        this.selectedOrderLearn[i].steps[j].resource = resourceRes[index].result.data
+                                    }
+                                    this.selfLearnInfo.steps.push(...this.selectedOrderLearn[i].steps)
+                                }
+                                this.selectedOrderLearn.length = 0
+                            },
+                            err => {
+                                console.log('err')
+                                console.log(err)
+                            }
+                        )
+                    },
+                    err => {
+                        console.log('err')
+                        console.log(err)
+                    }
+                )
+                
+            },
+            /**
+             * 通过id查询题目信息
+             * */
+            findQuestionById(ids) {
+                if (ids.length > 0) {
+                    this.listLoading = true
+                    this.$api.learnActivity.FindQuestionById(ids).then(
+                        res => {
+                            if (res.error == null) {
+                                return res.result.data
+                            } else {
+                                this.$Message.error("API ERROR!")
+                            }
+                            setTimeout(() => {
+                                this.listLoading = false
+                            }, 500)
+                        },
+                        err => {
+                            this.$Message.error("API ERROR!")
+                            setTimeout(() => {
+                                this.listLoading = false
+                            }, 1000)
+                        }
+                    )
+                }
+            },
+            /**
+             * 通过id查询内容信息
+             * */
+            findResourceById(ids) {
+                if (ids.length > 0) {
+                    this.listLoading = true
+                    this.$api.learnActivity.FindSyllabusResourceById(ids).then(
+                        res => {
+                            if (res.error == null) {
+                                return res.result.data
+                            } else {
+                                this.$Message.error("API ERROR!")
+                            }
+                            setTimeout(() => {
+                                this.listLoading = false
+                            }, 500)
+                        },
+                        err => {
+                            this.$Message.error("API ERROR!")
+                            setTimeout(() => {
+                                this.listLoading = false
+                            }, 500)
+                        }
+                    )
+                }
+            },
             deleteStep(index) {
                 this.$Modal.confirm({
                     title: '删除',
@@ -258,29 +389,6 @@
                     }
                 })
             },
-            /**
-             * 查询编序式教材列表
-             * */
-            findOrderLearn() {
-                let requestData = {
-                    creator: this.demoLoginInfo.TEAMModelId
-                }
-                this.$api.learnActivity.FindOrderLearn(requestData).then(
-                    res => {
-                        if (res.error == null) {
-                            this.orderLearnList = res.result.data
-                        } else {
-                            this.$Message.error('API ERROR!')
-                        }
-                    },
-                    err => {
-                        this.$Message.error('API ERROR!')
-                    }
-                )
-            },
-            
-            
-            
             confirmEditStep() {
                 this.selfLearnInfo.steps[this.stepIndex].name = this.editStepName
             },
@@ -312,30 +420,8 @@
                     this.selfLearnInfo.steps.splice(index1, 1);
                 }
             },
-            confirmSelectUnit() {
-                this.selfLearnInfo.steps.push(...this.selectedUnitItem)
-                this.selectedUnitItem.length = 0
-                console.log(this.selfLearnInfo)
-            },
             
-            selectOrder(item) {
-                let index = this.selectedOrderId.indexOf(item.id)
-                if (index == -1) {
-                    this.selectedOrderId.push(item.id)
-                    this.selectedOrderItem.push(item)
-                } else {
-                    this.selectedOrderId.splice(index, 1)
-                    this.selectedOrderItem.splice(index, 1)
-                }
-                console.log(this.selectedOrderId)
-            },
-            confirmSelectOrder() {
-                for (let i = 0; i < this.selectedOrderItem.length; i++) {
-                    this.selfLearnInfo.steps.push(...this.selectedOrderItem[i].steps)
-                }
-                this.selectedOrderItem.length = 0
-                console.log(this.selfLearnInfo)
-            },
+            
             confirmAddCustom() {
                 this.selfLearnInfo.steps.push(
                     {
@@ -352,17 +438,45 @@
             toggleSelectOrder() {
                 this.selectOrderStatus = true
             },
+            checkData() {
+                let flag = true
+                this.$refs.selfLearnInfo.validate((valid) => {
+                    if (!valid) {
+                        flag = false
+                    }
+                })
+                return flag
+            },
             saveData() {
-                console.log(this.selfLearnInfo)
-                this.isLoading = true
-                setTimeout(() => {
-                    this.isLoading = false
-                }, 2000)
+                let check = this.checkData()
+                if (check) {
+                    this.isLoading = true
+                    this.selfLearnInfo.scopeCode = this.$store.state.userInfo.TEAMModelId
+                    this.selfLearnInfo.creator = this.$store.state.userInfo.TEAMModelId
+                    this.$api.learnActivity.SaveSelfLearn([this.selfLearnInfo]).then(
+                        res => {
+                            if (res.error == null) {
+                                this.selfLearnInfo.id = res.result.data.id
+                                this.goToManageStatus = true
+                            } else {
+                                this.$Message.error("API ERROR!")
+                            }
+                            this.isLoading = false
+                        },
+                        err => {
+                            this.isLoading = false
+                        }
+                    )   
+                } else {
+                    this.$Message.error("请先完成必填信息")
+                }
             }
         },
         created() {
-            
-            this.findOrderLearn()
+            let routerData = this.$route.params.selfLearnInfo
+            if (routerData != undefined) {
+                this.selfLearnInfo = routerData
+            }
         }
     }
 </script>

+ 5 - 3
TEAMModelOS/ClientApp/src/view/selflearning/LearnProgress.vue

@@ -3,11 +3,11 @@
         <div class="learn-progress-filter dark-iview-select">
             <span class="filter-label">搜学生:</span>
             <Select v-model="model11" filterable style="display:inline-block;width:200px;" size="small">
-                <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+                <Option v-for="item in studentList" :value="item.value" :key="item.value">{{ item.label }}</Option>
             </Select>
             <span  class="filter-label" style="margin-left:30px;">选班级:</span>
             <Select v-model="model11" filterable style="display:inline-block;width:200px;" size="small">
-                <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+                <Option v-for="item in classroomList" :value="item.value" :key="item.value">{{ item.label }}</Option>
             </Select>
             <div class="right-filter-wrap">
                 <div class="radio-box-wrap">
@@ -18,7 +18,7 @@
                     </div>
                     <div :class="currentView == 1 ? 'radio-box-item active-radio-box-item':'radio-box-item'" @click="setCurrentView(1)">
                         <Tooltip content="学习自学概况" placement="bottom" theme="light">
-                            <Icon type="md-people" size="15" />
+                            <Icon type="md-person" size="15" />
                         </Tooltip>
                     </div>
                 </div>
@@ -41,6 +41,8 @@
         data() {
             return {
                 currentView: 0,
+                studentList: [],
+                classroomList: [],
                 columns: [
                     {
                         title: '学习阶段',

+ 1 - 5
TEAMModelOS/ClientApp/src/view/selflearning/ManageHomeWork.less

@@ -59,15 +59,11 @@
 
             .hw-item {
                 width: 100%;
-                height: 90px;
+                min-height: 90px;
                 padding: 15px;
                 border-bottom: 1px solid #2c2c2c;
                 cursor: pointer;
 
-                &:first-child {
-                    .item-active;
-                }
-
                 &:hover {
                     .item-active;
                 }

+ 70 - 11
TEAMModelOS/ClientApp/src/view/selflearning/ManageHomeWork.vue

@@ -8,11 +8,19 @@
             </div>
             <vuescroll>
                 <div class="hw-item-wrap">
-                    <div class="hw-item" v-for="(item,index) in hwList" :key="index">
-                        <p class="hw-item-name">测试作业名称</p>
-                        <div class="hw-item-info">
-                            <span class="hw-item-nums">提交人数: 10 / 20</span>
-                            <span class="hw-item-status">进行中</span>
+                    <div v-if="hwList.length === 0">
+                        <EmptyBox :top="50"></EmptyBox>
+                    </div>
+                    <div style="width:100%" v-else>
+                        <div :class='["hw-item",index === activeHwIndex ? "item-active":""]'
+                             v-for="(item,index) in hwList"
+                             :key="index"
+                             @click="onHwClick(item,index)">
+                            <p class="hw-item-name">{{ item.name }}</p>
+                            <div class="hw-item-info">
+                                <span class="hw-item-nums">提交人数: 10 / 20</span>
+                                <span class="hw-item-status">进行中</span>
+                            </div>
                         </div>
                     </div>
 
@@ -25,12 +33,12 @@
             <div class="hw-box-header">
                 <span>作业详情</span>
                 <div class="hw-box-header-tools">
-                    <span class="hw-box-header-tools-tool"><Icon type="md-create" size="18" title="编辑" /></span>
+                    <span class="hw-box-header-tools-tool"><Icon type="md-create" size="18" title="编辑" @click="onEditHw"/></span>
                 </div>
             </div>
             <vuescroll>
                 <div class="hw-info-wrap">
-                    <BaseHwForm></BaseHwForm>
+                    <BaseHwForm :editItem="currentHw"></BaseHwForm>
                 </div>
             </vuescroll>
         </div>
@@ -45,7 +53,7 @@
             </div>
             <vuescroll>
                 <div class="hw-data-wrap">
-                    <BaseHwTable></BaseHwTable>
+                    <BaseHwTable :studentsList="studentsList"></BaseHwTable>
                 </div>
             </vuescroll>
         </div>
@@ -58,27 +66,78 @@
                width="600px">
             <div class="hw-modal-box">
                 <vuescroll>
-                    <BaseHwForm></BaseHwForm>
+                    <BaseHwForm @onAddSuccess="onAddSuccess" :editItem="editItem" editable></BaseHwForm>
                 </vuescroll>
             </div>
         </Modal>
     </div>
 </template>
 <script>
+    import EmptyBox from '@/common/EmptyData'
     import BaseHwForm from '@/components/learnactivity/BaseHwForm'
     import BaseHwTable from '@/components/learnactivity/BaseHwTable'
     export default {
-        components: { BaseHwForm, BaseHwTable },
+        components: { BaseHwForm, BaseHwTable, EmptyBox },
         data() {
             return {
+                hwList: [],
+                studentsList:[],
+                currentHw: {},
+                editItem: {},
+                activeHwIndex:0,
                 addHwModal:false,
-                hwList: new Array(5).fill('1')
             }
         },
         methods: {
             goToCreate() {
+                this.editItem = null
+                this.addHwModal = true
+
+            },
+
+            getHomeWorkList() {
+                let params = { scopeCode:this.$store.state.userInfo.TEAMModelId }
+                this.$api.learnActivity.FindHomeWork(params).then(res => {
+                    if (!res.error && res.result.data) {
+                        this.hwList = res.result.data
+                        this.onHwClick(res.result.data[0],0)
+                    } else {
+                        this.$Message.error('获取数据失败')
+                    }
+                })
+            },
+
+            onHwClick(item,index) {
+                this.currentHw = item
+                this.activeHwIndex = index
+                this.getHwStudents(item.id)
+            },
+
+
+            getHwStudents(hwId) {
+                this.$api.learnActivity.FindStudentByHwId({ homeWorkId: hwId }).then(res => {
+                    if (!res.error && res.result.data) {
+                        this.studentsList = res.result.data
+                    } else {
+                        this.$Message.error('获取数据失败')
+                    }
+                })
+            },
+
+            onEditHw() {
+                this.editItem = this.currentHw
                 this.addHwModal = true
+            },
+
+
+
+            onAddSuccess() {
+                this.addHwModal = false
+                this.getHomeWorkList()
             }
+        },
+        mounted() {
+            this.getHomeWorkList()
         }
     }
 </script>

+ 105 - 5
TEAMModelOS/ClientApp/src/view/selflearning/ManageSelfLearn.less

@@ -66,16 +66,33 @@
 .self-learn-main {
     width: 100%;
     height: 100%;
-    .self-learn-main-body{
-        width:100%;
-        height:~"calc(100% - 45px)";
-    } 
+
+    .self-learn-main-body {
+        width: 100%;
+        height: ~"calc(100% - 45px)";
+    }
+
     .self-learn-main-header {
         height: 45px;
         width: 100%;
         line-height: 45px;
         border-bottom: 1px solid @borderColor;
 
+        .self-learn-header-right {
+            float: right;
+
+            .main-bar-action-btn {
+                color: white;
+                float: right;
+                margin-right: 50px;
+                cursor: pointer;
+
+                &:hover {
+                    color: aqua;
+                }
+            }
+        }
+
         .main-header-tab {
             color: @second-textColor;
             margin-right: 35px;
@@ -85,4 +102,87 @@
             line-height: 25px;
         }
     }
-}
+}
+
+.box-heaher {
+    height: 40px;
+    line-height: 40px;
+    color: @second-textColor;
+    border-bottom: 1px solid @borderColor;
+}
+
+.self-learn-main-body {
+    .base-info-box {
+        color: white;
+
+        .base-info-box-header {
+            .box-heaher;
+        }
+
+        .base-info-detail {
+            padding-top: 10px;
+
+            .base-info-item {
+                margin-bottom: 20px;
+            }
+
+            .base-info-label {
+                color: @second-textColor;
+                display: inline-block;
+                width: 80px;
+                font-size: 15px;
+            }
+
+            .base-info-value {
+                color: white;
+                font-size: 16px;
+                border-bottom: 1px solid #202020;
+                padding-bottom: 4px;
+            }
+        }
+    }
+
+    .learn-steps-box {
+        color: white;
+        padding-left: 15px;
+
+        .learn-steps-box-header {
+            .box-heaher;
+        }
+
+        .learn-steps-detail {
+            .self-learn-step-item {
+                padding: 10px 0px;
+                font-size: 16px;
+                cursor: pointer;
+                border-bottom: 1px solid @borderColor;
+            }
+        }
+    }
+
+    .learn-content-box {
+        color: white;
+        padding-left: 15px;
+        width: 100%;
+        height: 100%;
+
+        .learn-content-box-header {
+            .box-heaher;
+        }
+
+        .learn-content-detail {
+            width: 100%;
+            height: ~"calc(100% - 40px)";
+            padding-top: 15px;
+
+            .self-learn-content-label {
+                color: white;
+                line-height: 13px;
+                padding: 5px;
+                padding-left: 8px;
+                border-left: 2px solid white;
+                background: #333333;
+            }
+        }
+    }
+}

+ 191 - 22
TEAMModelOS/ClientApp/src/view/selflearning/ManageSelfLearn.vue

@@ -6,58 +6,205 @@
                     <span>自学活动列表</span>
                     <Icon type="md-add" class="to-create-icon" @click="goToCreate" />
                 </div>
-                <div :class="currentLearnIndex == index ? 'order-learn-item block-bg block-bg-active':'order-learn-item block-bg' " v-for="(item,index) in selfLearnList" @click="selectOrderLearn(index)">
+                <div v-for="(item,index) in selfLearnList" @click="selectOrderLearn(index)" :class="currentLearnIndex == index ? 'order-learn-item block-bg block-bg-active':'order-learn-item block-bg' ">
                     <p class="order-learn-name">{{item.name}}</p>
-                    <div class="order-learn-steps">
-                        <span><Icon type="md-filing" style="margin-right:8px;" />闯关模式:</span>
-                        <span>{{item.isOrder == 1 ? '是':'否'}}</span>
-                    </div>
                     <div class="order-learn-steps">
                         <span><Icon type="ios-cube" style="margin-right:8px;" />学习阶段:</span>
                         <span>{{item.steps.length}}</span>
                     </div>
+                    <div class="order-learn-steps">
+                        <span><Icon type="ios-cube" style="margin-right:8px;" />活动状态:</span>
+                        <span style="color:aqua;">{{index % 3 == 0 ? '未发布': index % 3 == 1 ? '进行中':'已结束' }}</span>
+                    </div>
                 </div>
                 <NoData v-if="selfLearnList.length == 0"></NoData>
             </vuescroll>
         </div>
         <div class="self-learn-main">
             <div class="self-learn-main-header">
-                <span :class="currentTabIndex == 0 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(0)">基础信息</span>
+                <span :class="currentTabIndex == 0 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(0)">活动信息</span>
                 <span :class="currentTabIndex == 1 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(1)">学习进度</span>
                 <span :class="currentTabIndex == 2 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(2)">学习数据</span>
+                <div class="self-learn-header-right">
+                    <span class="main-bar-action-btn" @click="editInfo()">
+                        <Icon type="ios-create-outline" size="20" />
+                        编辑内容
+                    </span>
+                </div>
             </div>
             <div class="self-learn-main-body">
+                <div v-if="currentTabIndex == 0" class="dark-iview-split" style="width:100%;height:100%;">
+                    <Split v-model="split1">
+                        <div slot="left" class="base-info-box">
+                            <div class="base-info-box-header">
+                                <span>基础信息</span>
+                            </div>
+                            <div class="base-info-detail">
+                                <div class="base-info-item">
+                                    <span class="base-info-label">
+                                        名称:
+                                    </span>
+                                    <p class="base-info-value">
+                                        {{selfLearnList[currentLearnIndex].name}}
+                                    </p>
+                                </div>
+                                <div class="base-info-item">
+                                    <span class="base-info-label">
+                                        学段:
+                                    </span>
+
+                                    <p class="base-info-value">
+                                        <!--{{selfLearnList[currentLearnIndex].periodCode}}-->
+                                        小学
+                                    </p>
+                                </div>
+                                <div class="base-info-item">
+                                    <span class="base-info-label">
+                                        学科:
+                                        
+
+                                        
+
+                                    </span>
+                                    
+
+                                    
+                                    <p class="base-info-value">
+                                        {{selfLearnList[currentLearnIndex].subjectCode}}
+                                    </p>
+                                </div>
+                                <div class="base-info-item">
+                                    <span class="base-info-label">
+                                        学习对象:
+                                    </span>
+                                    <p class="base-info-value">
+                                        {{selfLearnList[currentLearnIndex].target.join(',')}}
+                                    </p>
+                                </div>
+                                <div class="base-info-item">
+                                    <span class="base-info-label">
+                                        闯关模式:
+                                    </span>
+                                    <p class="base-info-value">
+                                        {{selfLearnList[currentLearnIndex].isOrder == 1 ? '是':'否'}}
+                                    </p>
+                                </div>
+                                <div class="base-info-item">
+                                    <span class="base-info-label">
+                                        结束时间:
+                                    </span>
+                                    <p class="base-info-value">
+                                        暂未设置
+                                    </p>
+                                </div>
+                                <div class="base-info-item">
+                                    <p class="base-info-label">
+                                        备注说明:
+                                    </p>
+                                    <p class="base-info-value">
+                                        {{selfLearnList[currentLearnIndex].introduce}}
+                                    </p>
+                                </div>
+                            </div>
+                        </div>
+                        <div slot="right" class="demo-split-pane" style="width:100%;height:100%;">
+                            <Split v-model="split2">
+                                <div slot="left" class="learn-steps-box">
+                                    <div class="learn-steps-box-header">
+                                        <span>
+                                            学习阶段
+                                        </span>
+                                    </div>
+                                    <div class="learn-steps-detail">
+                                        <div v-for="(item,index) in selfLearnList[currentLearnIndex].steps" @click="selectStep(index)" :class="currentStepIndex == index ? 'self-learn-step-item block-bg block-bg-active':'self-learn-step-item block-bg'">
+                                            <span>
+                                                {{item.name}}
+                                            </span>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div slot="right" class="learn-content-box">
+                                    <div class="learn-content-box-header">
+                                        <span>
+                                            学习内容
+                                        </span>
+                                    </div>
+                                    <div class="learn-content-detail">
+                                        <vuescroll>
+                                            <p class="self-learn-content-label">
+                                                内容:{{selfLearnList.length == 0 ? 0 : selfLearnList[currentLearnIndex].steps[currentStepIndex].resource.length}}
+                                            </p>
+                                            <div style="min-height:220px;">
+                                                <Loading v-show="isLoading"></Loading>
+                                                <ContentFileList v-show="!isLoading" :class="isLoading ? '':'animated fadeIn'" :resources="selfLearnList[currentLearnIndex].steps[currentStepIndex].resource"></ContentFileList>
+                                            </div>
+                                            <p class="self-learn-content-label" style="margin-bottom:15px;">
+                                                题目:{{selfLearnList.length == 0 ? 0 : selfLearnList[currentLearnIndex].steps[currentStepIndex].item.length}}
+                                            </p>
+                                            <div>
+                                                <NoData v-if="selfLearnList.length == 0" style="margin-top:120px;"></NoData>
+                                                <Loading v-show="isLoading"></Loading>
+                                                <QuestionList v-show="!isLoading" :class="isLoading ? '':'animated fadeIn'" :questions="selfLearnList[currentLearnIndex].steps[currentStepIndex].item" style="margin-top:12px;"></QuestionList>
+                                            </div>
+                                        </vuescroll>
+                                    </div>
+                                </div>
+                            </Split>
+                        </div>
+                    </Split>
+                </div>
                 <LearnProgress v-if="currentTabIndex == 1"></LearnProgress>
             </div>
         </div>
+        <Modal v-model="editStatus"
+               title="编辑内容"
+               @on-ok="confirmEdit">
+            <p>确认跳转到自主学习活动编辑页面?</p>
+        </Modal>
     </div>
 </template>
 <script>
     import NoData from '@/common/NoData.vue'
     import LearnProgress from './LearnProgress.vue'
+    import Loading from '@/common/Loading.vue'
+    import QuestionList from '@/components/learnactivity/QuestionList.vue'
+    import ContentFileList from '@/components/learnactivity/ContentFileList.vue'
     export default {
         components: {
-            NoData,LearnProgress
+            NoData, LearnProgress, Loading, QuestionList, ContentFileList
         },
         data() {
             return {
-                currentTabIndex:0,
+                isLoading: false,
+                editStatus: false,
+                split1: 0.18,
+                split2: 0.2,
+                currentTabIndex: 0,
                 currentLearnIndex: 0,
-                selfLearnList: [
-                    {
-                        name: '自主学习活动名称',
-                        isOrder: 1,
-                        steps: []
-                    },
-                    {
-                        name: '自主学习活动名称',
-                        isOrder: 1,
-                        steps: []
-                    }
-                ]
+                currentStepIndex: 0,
+                selfLearnList: []
             }
         },
         methods: {
+            confirmEdit() {
+                let selfLearnInfo = this.selfLearnList[this.currentLearnIndex]
+                this.$router.push({
+                    name: 'createSelfLearn',
+                    params: {
+                        selfLearnInfo
+                    }
+                })
+            },
+            editInfo() {
+                this.editStatus = true
+            },
+            selectStep(index) {
+                this.currentStepIndex = index
+                this.isLoading = true
+                setTimeout(() => {
+                    this.isLoading = false
+                },300)
+            },
             selectTab(index) {
                 this.currentTabIndex = index
             },
@@ -68,13 +215,35 @@
             },
             selectOrderLearn(index) {
                 this.currentLearnIndex = index
+            },
+            findSelfLearn() {
+                let requestData = {
+                    creator: this.$store.state.userInfo.TEAMModelId
+                }
+                this.$api.learnActivity.FindSelfLearn(requestData).then(
+                    res => {
+                        if (res.error == null) {
+                            this.selfLearnList = res.result.data
+                        } else {
+                            this.$Message.error("API ERROR!")
+                        }
+                    },
+                    err => {
+
+                    }
+                )
             }
+        },
+        created() {
+            this.findSelfLearn()
         }
     }
 </script>
 <style lang="less" scoped>
-@import "./ManageSelfLearn.less";
+    @import "./ManageSelfLearn.less";
 </style>
 <style>
-
+    .learn-content-detail #loadingBox {
+        margin-top: 70px !important;
+    }
 </style>

+ 0 - 1
TEAMModelOS/ClientApp/src/view/teachcontent/CreateLearnUnit.vue

@@ -142,7 +142,6 @@
             },
             getSelectFile(data) {
                 console.log(data)
-                //this.learnUnit.resource.push(data.file)
                 this.learnUnit.resource = data.files
             }
         },

+ 2 - 1
TEAMModelOS/ClientApp/src/view/teachcontent/CreateOrderLearn.vue

@@ -385,7 +385,6 @@
              * @param data
              */
             getSelectedUnit(data) {
-                console.log(data)
                 this.selectedUnit = data
             },
             confirmSelectUnit() {
@@ -406,6 +405,8 @@
                 this.orderLearnInfo.steps.push(
                     {
                         name: this.newStepName,
+                        requestedI: true,
+                        requestedR: true,
                         resource: [],
                         item: []
                     }

+ 1 - 1
TEAMModelOS/ClientApp/src/view/teachcontent/ManageOrderLearn.less

@@ -121,7 +121,7 @@
             .order-learn-content-label {
                 color: white;
                 line-height: 13px;
-                margin: 15px 0px;
+                margin-top: 15px;
                 padding: 5px;
                 padding-left: 8px;
                 border-left: 2px solid white;

+ 93 - 35
TEAMModelOS/ClientApp/src/view/teachcontent/ManageOrderLearn.vue

@@ -29,7 +29,7 @@
                     编辑内容
                 </span>
             </div>
-            <div :class="currentBarIndex == 0 ? 'animated fadeIn order-learn-main-body dark-iview-split':'order-learn-main-body'" v-show="currentBarIndex == 0">
+            <div class="order-learn-main-body dark-iview-split">
                 <Split v-model="split1">
                     <div slot="left">
                         <div class="order-learn-main-label">
@@ -113,30 +113,17 @@
                                             <p class="order-learn-content-label">
                                                 内容:{{orderLearnList.length == 0 ? 0 : orderLearnList[currentLearnIndex].steps[currentStepIndex].resource.length}}
                                             </p>
-                                            <div style="margin-bottom:30px;">
-                                                <NoData v-if="orderLearnList.length == 0"></NoData>
-                                                <div v-if="orderLearnList.length > 0" class="order-learn-file-wrap">
-                                                    <NoData v-if="orderLearnList[currentLearnIndex].steps[currentStepIndex].resource.length == 0"></NoData>
-                                                    <div class="order-learn-file-item" v-for="(item,index) in orderLearnList[currentLearnIndex].steps[currentStepIndex].resource">
-                                                        <span>{{item.fileName}}</span>
-                                                        <span class="file-item-action">
-                                                            <Icon type="md-download" class="action-icon" title="下载"  @click="downloadFile(item)"/>
-                                                            <Icon v-if="item.type == 'video' || item.type == 'picture' || item.extension == 'pdf'" type="md-eye" class="action-icon" title="预览" @click="clickToPreview(item)" />
-                                                            <!--<Icon type="md-close" class="action-icon" title="删除" />-->
-                                                        </span>
-                                                    </div>
-                                                </div>
-
+                                            <div style="min-height:220px;">
+                                                <Loading v-show="isLoading"></Loading>
+                                                <ContentFileList v-show="!isLoading" :class="isLoading ? '':'animated fadeIn'" :resources="orderLearnList[currentLearnIndex].steps[currentStepIndex].resource"></ContentFileList>
                                             </div>
-                                            <p class="order-learn-content-label">
+                                            <p class="order-learn-content-label" style="margin-bottom:15px;">
                                                 题目:{{orderLearnList.length == 0 ? 0 : orderLearnList[currentLearnIndex].steps[currentStepIndex].item.length}}
                                             </p>
-                                            <div>
-                                                <NoData v-if="orderLearnList.length == 0"></NoData>
-                                                <div v-if="orderLearnList.length > 0" class="order-learn-file-item">
-                                                    <NoData v-if="orderLearnList[currentLearnIndex].steps[currentStepIndex].item.length == 0"></NoData>
-                                                    <QuestionList :questions="orderLearnList[currentLearnIndex].steps[currentStepIndex].item"></QuestionList>
-                                                </div>
+                                            <div class="unit-content-detail">
+                                                <NoData v-if="orderLearnList.length == 0" style="margin-top:120px;"></NoData>
+                                                <Loading v-show="isLoading"></Loading>
+                                                <QuestionList v-show="!isLoading" :class="isLoading ? '':'animated fadeIn'" :questions="orderLearnList[currentLearnIndex].steps[currentStepIndex].item" style="margin-top:12px;"></QuestionList>
                                             </div>
                                         </vuescroll>
                                     </div>
@@ -147,29 +134,27 @@
                     </div>
                 </Split>
             </div>
-            <div :class="currentBarIndex == 1 ? 'animated fadeIn order-learn-main-body':'order-learn-main-body'" v-show="currentBarIndex == 1">
-                <h1 style="text-align:center;color: rgb(170, 170, 170);padding-top:200px;">功能正在开发中,敬请期待!</h1>
-            </div>
-            <div :class="currentBarIndex == 2 ? 'animated fadeIn order-learn-main-body':'order-learn-main-body'" v-show="currentBarIndex == 2">
-                <h1 style="text-align:center;color: rgb(170, 170, 170);padding-top:200px;">功能正在开发中,敬请期待!</h1>
-            </div>
         </div>
         <Modal v-model="editStatus"
                title="编辑内容"
                @on-ok="confirmEdit">
-            <p>确认跳转到编序式自主学习活动编辑页面?</p>
+            <p>确认跳转到编序式教材编辑页面?</p>
         </Modal>
     </div>
 </template>
 <script>
     import NoData from '@/common/NoData.vue'
+    import Loading from '@/common/Loading.vue'
     import QuestionList from '@/components/learnactivity/QuestionList.vue'
+    import ContentFileList from '@/components/learnactivity/ContentFileList.vue'
     export default {
         components: {
-            NoData,QuestionList
+            NoData, QuestionList, ContentFileList, Loading
+
         },
         data() {
             return {
+                isLoading: false,
                 sasString:'',
                 editStatus: false,
                 split1: 0.2,
@@ -182,11 +167,79 @@
                 },
                 orderLearnList: [],
                 currentLearnIndex: 0,
-                currentBarIndex: 0,
                 currentStepIndex: 0,
             }
         },
         methods: {
+            /**
+             * 通过id查询内容信息
+             * */
+            findResourceById() {
+                if (this.orderLearnList.length > 0) {
+                    this.isLoading = true
+                    if (!this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].requestedR) {
+                        this.$api.learnActivity.FindSyllabusResourceById(this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].resource).then(
+                            res => {
+                                if (res.error == null) {
+                                    this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].resource.length = 0
+                                    this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].resource = res.result.data
+                                    this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].requestedR = true
+                                } else {
+                                    this.$Message.error("API ERROR!")
+                                }
+                                setTimeout(() => {
+                                    this.isLoading = false
+                                }, 500)
+                            },
+                            err => {
+                                this.$Message.error("API ERROR!")
+                                setTimeout(() => {
+                                    this.isLoading = false
+                                }, 500)
+                            }
+                        )
+                    } else {
+                        setTimeout(() => {
+                            this.isLoading = false
+                        }, 200)
+                    }
+                }
+            },
+            /**
+             * 通过id查询题目信息
+             * */
+            findQuestionById() {
+                if (this.orderLearnList.length > 0) {
+                    this.isLoading = true
+                    if (!this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].requestedI) {
+                        this.$api.learnActivity.FindQuestionById(this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].item).then(
+                            res => {
+                                if (res.error == null) {
+                                    this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].item.length = 0
+                                    this.$set(this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex],'item',res.result.data)
+                                    this.orderLearnList[this.currentLearnIndex].steps[this.currentStepIndex].requestedI = true
+                                    console.log(this.orderLearnList[this.currentLearnIndex])
+                                } else {
+                                    this.$Message.error("API ERROR!")
+                                    setTimeout(() => {
+                                        this.isLoading = false
+                                    }, 500)
+                                }
+                            },
+                            err => {
+                                this.$Message.error("API ERROR!")
+                                setTimeout(() => {
+                                    this.isLoading = false
+                                },500)
+                            }
+                        )
+                    }else {
+                        setTimeout(() => {
+                            this.isLoading = false
+                        }, 200)
+                    }
+                }
+            },
             goToCreate() {
                 this.$router.push({
                     name: 'createOrderLearn'
@@ -210,14 +263,14 @@
             },
             selectStep(index) {
                 this.currentStepIndex = index
-            },
-            selectBar(index) {
-                this.currentBarIndex = index
+                this.findQuestionById()
+                this.findResourceById()
             },
             selectOrderLearn(index) {
                 this.currentStepIndex = 0
                 this.currentLearnIndex = index
-                
+                this.findQuestionById()
+                this.findResourceById()
             },
             findOrderLearn() {
                 let requestData = {
@@ -227,6 +280,8 @@
                     res => {
                         if (res.error == null) {
                             this.orderLearnList = res.result.data
+                            this.findResourceById()
+                            this.findQuestionById()
                         } else {
                             this.$Message.error('API ERROR!')
                         }
@@ -246,4 +301,7 @@
     @import "./ManageOrderLearn.less";
 </style>
 <style>
+    .order-learn-content-wrap #loadingBox {
+        margin-top: 88px !important;
+    }
 </style>

+ 0 - 1
TEAMModelOS/ClientApp/src/view/teachcontent/ManageUnit.vue

@@ -34,7 +34,6 @@
                         <NoData v-if="unitList[currentUnitIndex].length == 0" style="margin-top:120px;"></NoData>
                         <Loading v-show="isLoading"></Loading>
                         <QuestionList v-show="!isLoading" :class="isLoading ? '':'animated fadeIn'" :questions="unitList[currentUnitIndex].item" style="margin-top:12px;"></QuestionList>
-
                     </div>
                 </vuescroll>
             </div>

+ 37 - 2
TEAMModelOS/Controllers/Analysis/AchievementController.cs

@@ -1320,12 +1320,47 @@ namespace TEAMModelOS.Controllers.Analysis
         public async Task<BaseJosnRPCResponse> FindExamAnswer(JosnRPCRequest<Dictionary<string, object>> request)
         {
             JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            if (RedisHelper.Instance != null)
+            {
 
-            List<ExamAnswer> info = await azureCosmosDBRepository.FindByDict<ExamAnswer>(request.@params);
-            builder.Data(info);
+                List<ExamAnswer> info = await RedisHelper.CacheShellAsync(CacheCosmosPrefix + request.method,
+                    ShaHashHelper.GetSHA1(JsonNetHelper.ToJson(request.@params)), timeoutSeconds, () => { return FindExamAnswerRedis(request.@params, request.method); });
+                builder.Data(info);
+
+            }
+            else
+            {
+                List<ExamAnswer> info = await FindExamAnswerRedis(request.@params, request.method);
+                builder.Data(info);
+            }
 
             return builder.build();
         }
+        public async Task<List<ExamAnswer>> FindExamAnswerRedis(Dictionary<string, object> dict, string method)
+        {
+            try
+            {
+                List<ExamAnswer> info = await azureCosmosDBRepository.FindByDict<ExamAnswer>(dict);
+                if (RedisHelper.Instance != null)
+                {
+                    if (!RedisHelper.Exists(CacheCosmosPrefix + method))
+                    {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + method, ShaHashHelper.GetSHA1(JsonNetHelper.ToJson(dict)), info);
+                    }
+                    else
+                    {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + method, ShaHashHelper.GetSHA1(JsonNetHelper.ToJson(dict)), info);
+                        await RedisHelper.ExpireAsync(CacheCosmosPrefix + method, timeoutSeconds);
+                    }
+                }
+                return info;
+            }
+            catch (Exception e)
+            {
+                throw new BizException(e.Message);
+
+            }
+        }
 
         public async Task<List<ExamAnswer>> FindExamAnswerRedis(Dictionary<string, object> dict)
         {

+ 7 - 4
TEAMModelOS/Controllers/Core/FileController.cs

@@ -185,8 +185,9 @@ namespace TEAMModelOS.Controllers.Syllabus
         public BaseJosnRPCResponse GetContainerSAS(JosnRPCRequest<string> azureBlobSASDto)
         {
             JsonRPCResponseBuilder responseBuilder = new JsonRPCResponseBuilder();
-            string Url = _azureBlobDBRepository.GetContainerSasUri().Item1;
-            string SAS = _azureBlobDBRepository.GetContainerSasUri().Item2;
+            (string, string) aaa = _azureBlobDBRepository.GetContainerSasUri();
+            string Url = aaa.Item1;
+            string SAS = aaa.Item2;
             return responseBuilder.Data(new Dictionary<string,object> { 
                 { "Url",Url },
                 { "SAS",SAS}
@@ -204,8 +205,10 @@ namespace TEAMModelOS.Controllers.Syllabus
             JsonRPCResponseBuilder responseBuilder = new JsonRPCResponseBuilder();
             string azureBlobSAS = azureBlobSASDto.@params;
             string ContainerName = ContainerUrlString(azureBlobSAS);
-            string Url = _azureBlobDBRepository.GetContainerSasUriRead(ContainerName).Item1;
-            string SAS = _azureBlobDBRepository.GetContainerSasUriRead(ContainerName).Item2;
+            (string, string) aaa = _azureBlobDBRepository.GetContainerSasUriRead(ContainerName);
+
+            string Url = aaa.Item1;
+            string SAS = aaa.Item2;
 
             return responseBuilder.Data(new Dictionary<string, object> {
                 { "Url",Url },

+ 4 - 2
TEAMModelOS/Controllers/Learn/HomeWorkController.cs

@@ -73,7 +73,8 @@ namespace TEAMModelOS.Controllers.Learn
                             homeWorkStudent.id = Guid.NewGuid().ToString();
                             homeWorkStudent.homeWorkId = request.@params.id;
                             homeWorkStudent.studentId = studentid;
-                            homeWorkStudent.classroomCode = target.classroomCode;
+                            homeWorkStudent.classroom.code = target.classroomCode;
+                            homeWorkStudent.classroom.name = target.classroomName;
                             homeWorkStudents.Add(homeWorkStudent);
                         }
                     }
@@ -88,7 +89,8 @@ namespace TEAMModelOS.Controllers.Learn
                         {
                             homeWorkStudents1.name = student.name;
                             homeWorkStudents1.TEAMModelId = student.TEAMModelId;
-                            homeWorkStudents1.nativeroomCode = student.classroomCode;
+                            homeWorkStudents1.nativeroom.code = student.classroomCode;
+                            //homeWorkStudents1.nativeroomCode.code = student
                         }
                     }
                     await _cosmos.SaveOrUpdateAll<HomeWorkStudent>(homeWorkStudents);

+ 11 - 6
TEAMModelOS/Controllers/Learn/LearnController.cs

@@ -195,14 +195,19 @@ namespace TEAMModelOS.Controllers.Learn
             JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
             if (ValidateHelper.IsValid(request.@params))
             {
-                request.@params.ForEach(x =>
-                {
-                    if (string.IsNullOrEmpty(x.id))
+
+                foreach (LearningAutonomous learningAutonomous1 in request.@params) {
+
+                    if (string.IsNullOrEmpty(learningAutonomous1.id))
                     {
-                        x.id = new Guid().ToString();
-                        x.createTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
+                        learningAutonomous1.id = Guid.NewGuid().ToString();
+                        learningAutonomous1.createTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
                     }
-                });
+                }
+                //request.@params.ForEach(x =>
+                //{
+                    
+                //});
                 List<LearningAutonomous> learningAutonomous = await cosmosDBV3Repository.SaveOrUpdateAll<LearningAutonomous>(request.@params);
                 builder.Data(learningAutonomous);
             }

+ 5 - 2
TEAMModelOS/Controllers/Syllabus/SyllabusController.cs

@@ -26,10 +26,13 @@ namespace TEAMModelOS.Controllers.Syllabus
         private IAzureCosmosDBV3Repository azureCosmosDBRepository;
         private ISyllabusService syllabusService;
 
-        public SyllabusController(IAzureCosmosDBV3Repository _azureCosmosDBRepository)
+        public SyllabusController(IAzureCosmosDBV3Repository azureCosmosDBRepository, ISyllabusService syllabusService)
         {
-            azureCosmosDBRepository = _azureCosmosDBRepository;
+            this.azureCosmosDBRepository = azureCosmosDBRepository;
+            this.syllabusService = syllabusService;
         }
+
+
         /// <summary>
         /// 批量保存或更新课纲
         /// </summary>