Преглед изворни кода

讲义需求调整+课程详情需求调整+监管平台需求调整

Tang пре 2 година
родитељ
комит
1d2a721b85
35 измењених фајлова са 2831 додато и 584 уклоњено
  1. 1 0
      .env.development
  2. 1 0
      .env.production
  3. 1 0
      .env.staging
  4. 2 0
      package.json
  5. BIN
      src/assets/images/docx.png
  6. BIN
      src/assets/images/xlsx.png
  7. BIN
      src/assets/images/zip.png
  8. 42 22
      src/components/testPaperPreview/index.vue
  9. 298 0
      src/mixin/fpFile.js
  10. 8 0
      src/newApi/classTab.js
  11. 44 2
      src/newApi/handout.js
  12. 0 2
      src/permission.js
  13. 15 0
      src/utils/methodsTool.js
  14. 2 2
      src/utils/request.js
  15. 5 5
      src/views/Marketing/goods/commodityManageMent/add/index.vue
  16. 1 1
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/handoutView.vue
  17. 1 1
      src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue
  18. 5 5
      src/views/Marketing/goods/commodityManageMent/edit/index.vue
  19. 7 5
      src/views/classHoursReview/component/ChapterTable.vue
  20. 118 19
      src/views/classHoursReview/component/LessonTable.vue
  21. 3 0
      src/views/classHoursReview/index.vue
  22. 39 14
      src/views/education/classManageMent/classHoursReview/component/LessonTable.vue
  23. 24 6
      src/views/resource/bankManagement/chapterVolumeManagement/addChapterjs.vue
  24. 1 1
      src/views/resource/bankManagement/testPaperManagement/index.vue
  25. 772 0
      src/views/resource/handoutManagement/handoutList/add/index copy 1.vue
  26. 209 84
      src/views/resource/handoutManagement/handoutList/add/index copy.vue
  27. 69 90
      src/views/resource/handoutManagement/handoutList/add/index.vue
  28. 684 0
      src/views/resource/handoutManagement/handoutList/edit/index copy.vue
  29. 170 109
      src/views/resource/handoutManagement/handoutList/edit/index.vue
  30. 26 4
      src/views/resource/handoutManagement/handoutList/index.vue
  31. 140 166
      src/views/resource/videoManagement/courseManagement/chapterContent/index.vue
  32. 56 22
      src/views/secondJian/completionList/index.vue
  33. 16 2
      src/views/secondJian/courseList/index.vue
  34. 56 22
      src/views/secondZao/completionList/index.vue
  35. 15 0
      src/views/secondZao/courseList/index.vue

+ 1 - 0
.env.development

@@ -6,6 +6,7 @@ ENV = 'development'
 
 # 中正云教育管理后台/开发环境
 VUE_APP_BASE_API = 'http://120.79.166.78:19013/'
+VUE_APP_BASE_API_QP = 'http://192.168.1.7:9090'
 # VUE_APP_BASE_API = 'http://192.168.1.24:5030/'
 VUE_APP_IMG_API = 'https://file-dev.xyyxt.net'
 

+ 1 - 0
.env.production

@@ -6,6 +6,7 @@ ENV = 'production'
 
 # 中正云教育管理后台/生产环境
 VUE_APP_BASE_API = 'https://cloud.xyyxt.net/'
+VUE_APP_BASE_API_QP = 'https://attach.xyyxt.net'
 VUE_APP_IMG_API = 'https://file.xyyxt.net'
 
 # 路由懒加载

+ 1 - 0
.env.staging

@@ -9,6 +9,7 @@ ENV = 'staging'
 # 中正云教育管理后台/预发布环境
 # 测试
 VUE_APP_BASE_API = 'http://120.79.166.78:19013/'
+VUE_APP_BASE_API_QP = 'http://192.168.1.7:9090'
 # 预发布
 VUE_APP_BASE_API1 = 'http://120.79.166.78:19007/'
 #图片

+ 2 - 0
package.json

@@ -49,6 +49,7 @@
     "gsap": "^3.11.4",
     "highlight.js": "9.18.5",
     "html2canvas": "^1.4.1",
+    "iconv-lite": "^0.6.3",
     "js-beautify": "1.13.0",
     "js-cookie": "2.2.1",
     "js-md5": "^0.7.3",
@@ -59,6 +60,7 @@
     "quill-image-resize-module": "^3.0.0",
     "screenfull": "5.0.2",
     "sortablejs": "1.10.2",
+    "spark-md5": "^3.0.2",
     "v-fit-columns": "^0.2.0",
     "vue": "2.6.12",
     "vue-canvas-poster": "^1.2.1",

BIN
src/assets/images/docx.png


BIN
src/assets/images/xlsx.png


BIN
src/assets/images/zip.png


+ 42 - 22
src/components/testPaperPreview/index.vue

@@ -13,6 +13,15 @@
         </div>
       </div>
       <div>
+        <div style="margin-bottom: 14px" v-if="activeIndex !== null">
+          <el-button
+            v-for="(item, index) in examTitleList"
+            :key="index"
+            @click="getData(item.examId, index)"
+            :type="activeIndex === index ? 'primary' : ''"
+            >{{ item.examName }}</el-button
+          >
+        </div>
         <table class="table_style" border>
           <tr>
             <td>当前总分</td>
@@ -205,6 +214,8 @@ export default {
       tableData: [], //题目内容
       topData: {}, //顶部表格数据
       type: "",
+      examTitleList: [],
+      activeIndex: null,
     };
   },
   computed: {
@@ -255,31 +266,12 @@ export default {
      * type = 1时Id获取数据row = ID, 2时直接获取数据row = 数据
      */
     openBox(type, row) {
+      this.activeIndex = null;
       const ROWS = JSON.parse(JSON.stringify(row));
       this.type = type;
       if (type === 1) {
-        //搜索Id处理数据
-        this.$api.obtainbankexam(row).then((res) => {
-          this.topData = {
-            answerTime: res.data.answerTime,
-            answerNum: res.data.answerNum,
-            doType: res.data.doType,
-            passScore: res.data.passScore,
-          };
-          this.$api.inquirebankexamquestionList({ examId: row }).then((res) => {
-            res.data.map((item) => {
-              item.optionsList = JSON.parse(item.jsonStr);
-            });
-            this.tableData = res.data;
-            var num = 0;
-            res.data.forEach((item) => {
-              num += item.score;
-            });
-            this.topData.getAllpocis = num;
-
-            this.diavos = true;
-          });
-        });
+        this.examTitleList = row;
+        this.getData(row[0].examId, 0);
       }
       if (type === 2) {
         this.topData = ROWS.topData;
@@ -287,6 +279,34 @@ export default {
         this.diavos = true;
       }
     },
+    getData(id, index) {
+      if (this.activeIndex === index) return;
+      //搜索Id处理数据
+      this.$api.obtainbankexam(id).then((res) => {
+        this.topData = {
+          answerTime: res.data.answerTime,
+          answerNum: res.data.answerNum,
+          doType: res.data.doType,
+          passScore: res.data.passScore,
+        };
+        this.$api.inquirebankexamquestionList({ examId: id }).then((res) => {
+          this.activeIndex = index;
+          res.data.map((item) => {
+            item.optionsList = JSON.parse(item.jsonStr);
+          });
+          this.tableData = res.data;
+          var num = 0;
+          res.data.forEach((item) => {
+            num += item.score;
+          });
+          this.topData.getAllpocis = num;
+          this.diavos = true;
+          this.$nextTick(() => {
+            document.getElementsByClassName("bank_style")[0].scrollTop = 0;
+          });
+        });
+      });
+    },
     changeDatas(row) {
       this.$parent.addClick(row, 0, row.index, true);
     },

+ 298 - 0
src/mixin/fpFile.js

@@ -0,0 +1,298 @@
+/*
+ * @Description: 大文件上传、分片上传、断点续传、文件秒传
+ * @Author: zhangy
+ * @Date: 2022-05-16 13:10:13
+ * @LastEditors: zhangy
+ * @LastEditTime: 2022-05-19 10:14:33
+ */
+
+const SparkMD5 = require('spark-md5')
+import handoutApi from '@/newApi/handout'
+import axios from 'axios'
+// 切片大小(单位:B)
+const CHUNK_SIZE = 50 * 1024 * 1024
+// const CHUNK_SIZE = 24 * 1024
+
+/**
+ * @description: 分块计算文件的md5值
+ * @param {*} file 文件
+ * @param {*} chunkSize 分片大小
+ * @returns {*}
+ */
+function calculateFileMd5(file, chunkSize) {
+    return new Promise((resolve, reject) => {
+        const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
+        const chunks = Math.ceil(file.size / chunkSize)
+        let currentChunk = 0
+        const spark = new SparkMD5.ArrayBuffer()
+        const fileReader = new FileReader()
+
+        fileReader.onload = function (e) {
+            spark.append(e.target.result)
+            currentChunk++
+            if (currentChunk < chunks) {
+                loadNext()
+            } else {
+                const md5 = spark.end()
+                resolve(md5)
+            }
+        }
+
+        fileReader.onerror = function (e) {
+            reject(e)
+        }
+
+        function loadNext() {
+            const start = currentChunk * chunkSize
+            let end = start + chunkSize
+            if (end > file.size) {
+                end = file.size
+            }
+            fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
+        }
+
+        loadNext()
+    })
+}
+
+/**
+ * @description: 分块计算文件的md5值
+ * @param {*} file 文件
+ * @returns {Promise}
+ */
+function calculateFileMd5ByDefaultChunkSize(file) {
+    return calculateFileMd5(file, CHUNK_SIZE)
+}
+
+/**
+ * @description: 文件切片
+ * @param {*} file
+ * @param {*} size 切片大小
+ * @returns [{file}]
+ */
+function createFileChunk(file, size = CHUNK_SIZE) {
+    const chunks = []
+    let cur = 0
+    while (cur < file.size) {
+        chunks.push({ file: file.slice(cur, cur + size) })
+        cur += size
+    }
+    return chunks
+}
+
+/**
+ * @description: 获取文件的后缀名
+ */
+function getFileType(fileName) {
+    return fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase()
+}
+
+/**
+ * @description: 根据文件的md5值判断文件是否已经上传过了
+ * @param {*} md5 文件的md5
+ * @param {*} 准备上传的文件
+ * @returns {Promise}
+ */
+function checkMd5(md5, file) {
+    return new Promise(resolve => {
+        getUploadStatus({ md5 })
+            .then(res => {
+                if (res.data.code === 20000) {
+                    // 文件已经存在了,秒传(后端直接返回已上传的文件)
+                    resolve({
+                        uploaded: true,
+                        url: res.data.msg,
+                        code: res.data.code
+                    })
+                } else if (res.data.code === 40004) {
+                    // 文件不存在需要上传
+                    resolve({ uploaded: false, url: '', code: res.data.code })
+                } else {
+                    resolve({ uploaded: false, url: '', code: 500 })
+                }
+            })
+            .catch(() => {
+                resolve({ uploaded: false, url: '', code: 500 })
+            })
+    })
+}
+
+/**
+ * @description: 执行分片上传
+ * @param {*} file 上传的文件
+ * @param {*} i 第几分片,从0开始
+ * @param {*} md5 文件的md5值
+ * @param {*} vm 虚拟 dom 指向组件 this
+ * @returns {Promise}
+ */
+function PostFile(file, i, md5, vm) {
+    const name = file.name // 文件名
+    const size = file.size // 总大小
+    const shardCount = Math.ceil(size / CHUNK_SIZE) // 总片数
+    if (i >= shardCount) {
+        return
+    }
+
+    const start = i * CHUNK_SIZE
+    const end = start + CHUNK_SIZE
+    const packet = file.slice(start, end) // 将文件进行切片
+    const param = { "shardCount": shardCount, "name": name, "index": i + 1, "fileSign": md5, "fileMd5": md5 }
+    /*  构建form表单进行提交  */
+    const form = new FormData()
+    form.append('file', packet) // slice方法用于切出文件的一部分
+    form.append('param', JSON.stringify(param)) // slice方法用于切出文件的一部分
+    return new Promise((resolve, reject) => {
+        handoutApi.commondecompression(form)
+            .then(res => {
+                if (res.code === 200) {
+                    // 拿到已上传过的切片
+                    resolve({
+                        uploadedList: res.data ? res.data.map(item => {
+                            return item.slice(0, item.lastIndexOf('.'))
+                        }) : []
+                    })
+                } else {
+                    resolve({ uploadedList: [], code: 500 })
+                    // reject()
+                }
+            })
+            .catch(() => {
+                // reject()
+                resolve({ uploadedList: [], code: 500 })
+            })
+    })
+}
+
+/**
+ * @description: 合并文件
+ * @param {*} shardCount 分片数
+ * @param {*} fileName 文件名
+ * @param {*} md5 文件md值
+ * @param {*} fileType 文件类型
+ * @param {*} fileSize 文件大小
+ * @returns {Promise}
+ */
+function merge(fileMd5, name) {
+    return new Promise((resolve,reject) => {
+        handoutApi.commonmergefile({ fileMd5, name}).then(res => {
+            if(res.code === 200){
+                resolve(true)
+            }else{
+                resolve(false)
+            }
+        }).catch(()=>{
+            resolve(false)
+        })
+    })
+}
+
+export default {
+    data() {
+        return {
+            chunks: [],
+            percent: 0,
+            percentCount: 0,
+            stopUpload: false // 在需要的时机或场合阻止上传
+        }
+    },
+    methods: {
+        /**
+         * @description: 上传文件
+         * @param {*} file 文件
+         * @returns {Object} 包含成功的文件地址、名称等
+        */
+        async chunksUpload(file) {
+            this.chunks = []
+            // step1 获取文件切片
+            const initChunks = createFileChunk(file)
+            console.log(initChunks, "initChunks")
+            // step2 获取文件 md5 值
+            const md5 = await calculateFileMd5ByDefaultChunkSize(file)
+
+            // step3 获取文件的上传状态
+            //   const { uploaded, url, code } = await checkMd5(md5, file)
+
+            //   if (uploaded) {
+            //     // step4 如果上传成功
+            //     this.percent = 100
+
+            //     // step5 拿到结果
+            //     return url
+            //   }
+
+            //   if (!uploaded && code === 500) {
+            //     return this.errorInfo()
+            //   }
+
+            // step4 如果文件未传成功,执行切片上传
+            const { uploadedList } = await PostFile(file, 0, md5, this)
+            // todo 方法1:逐次发送请求
+            // const requestList = [] // 请求集合
+            // initChunks.forEach(async (chunk, index) => {
+            //     // 过滤掉已上传的切片
+            //     if (uploadedList.indexOf(md5 + '_' + (index + 1)) < 0) {
+            //         const fn = () => {
+            //             return PostFile(file, index, md5, this)
+            //         }
+            //         requestList.push(fn)
+            //     }
+            // })
+
+            // let reqNum = 0 // 记录发送的请求个数
+            // const send = async () => {
+            //     if (reqNum >= requestList.length) {
+            //         // step5 如果所有切片已上传,执行合并
+            //         const res = await merge(initChunks.length, file.name, md5, getFileType(file.name), file.size)
+            //         if (res.data.code === 20000) {
+            //             return res.data.msg
+            //         } else {
+            //             this.errorInfo()
+            //             return {}
+            //         }
+            //     }
+
+            //     if (this.stopUpload) return {} // 阻止上传
+            //     const sliceRes = await requestList[reqNum]()
+            //     if (sliceRes.code && sliceRes.code === 500) {
+            //         return this.errorInfo()
+            //     }
+            //     // 计算当下所上传切片数
+            //     const count = initChunks.length - uploadedList.length
+            //     if (this.percentCount === 0) {
+            //         this.percentCount = 100 / count
+            //     }
+            //     this.percent += this.percentCount
+            //     reqNum++
+            //     return send()
+            // }
+
+            // const mergeResult = await send()
+            // return mergeResult
+
+            // todo 方法2:使用Promise.all 统一发送请求
+            const requestList = initChunks.map(async (chunk, index) => {
+                // 过滤掉已上传的切片
+                if (uploadedList.indexOf(md5 + '_' + (index + 1)) < 0) {
+                    return PostFile(file, index, md5, this)
+                }
+            })
+            return Promise.all(requestList)
+                .then(async() => {
+                    const res = await merge(md5, file.name, md5)
+                    console.log(res,"-------res")
+                    return {status:res,md5}
+                })
+                .catch(() => {
+                    this.$message.error('出错了,请稍后重试!')
+                    return {status:false,md5}
+                })
+        },
+
+        /**
+         * @description: 错误提示
+        */
+        errorInfo() {
+            this.$message.error('出错了,请稍后重试!')
+        }
+    }
+}

+ 8 - 0
src/newApi/classTab.js

@@ -16,6 +16,14 @@ export default {
             params: data
         })
     },
+    //导出商品的课程结构
+    inquireGradegradeexportGoodsMenuExcel(data) {
+        return request({
+            url: '/grade/grade/exportGoodsMenuExcel',
+            method: 'get',
+            params: data
+        })
+    },
     //选新班
     gradegradechangeGrade(data) {
         return request({

+ 44 - 2
src/newApi/handout.js

@@ -3,7 +3,7 @@ export default {
     //新增讲义列
     addCourseHandouts(data) {
         return request({
-            url: '/course/handouts',
+            url: '/course/handouts/save',
             method: 'post',
             data
         })
@@ -11,7 +11,7 @@ export default {
     //修改讲义列
     editCourseHandouts(data) {
         return request({
-            url: '/course/handouts/edit',
+            url: '/course/handouts/edit/handouts',
             method: 'post',
             data
         })
@@ -31,4 +31,46 @@ export default {
             method: 'get',
         })
     },
+    //获取讲义列详细信息s
+    inquireCourseHandoutsfiledetail(data) {
+        return request({
+            url: '/course/handouts/file/detail',
+            method: 'get',
+            params: data
+        })
+    },
+    //切片上传
+    commondecompression(data) {
+        return request({
+            url: process.env.VUE_APP_BASE_API_QP+'/common/decompression',
+            method: 'post',
+            headers: {
+              isToken: false
+            },
+            data
+        })
+    },
+    //判断完整性
+    commonmergefile(data) {
+        return request({
+            url: process.env.VUE_APP_BASE_API_QP+'/common/merge/file',
+            method: 'post',
+            headers: {
+              isToken: false
+            },
+            data
+        })
+    },
+    //删除后台切片缓存
+    commondeletefile(data) {
+        return request({
+            url: process.env.VUE_APP_BASE_API_QP+'/common/delete/file',
+            method: 'post',
+            headers: {
+              isToken: false
+            },
+            data
+        })
+    },
+    
 }

+ 0 - 2
src/permission.js

@@ -61,7 +61,6 @@ router.beforeEach(async (to, from, next) => {
         if (!to.path.includes('/user/profile')) {
           checkFunc()
         }
-        console.log("to:", to)
         next()
         // }
       }
@@ -75,7 +74,6 @@ router.beforeEach(async (to, from, next) => {
       if (sessionStorage.TenantId == undefined) {
         next(`/login`) // 否则全部重定向到登录页
       } else {
-        console.log("sessionStorage", sessionStorage.TenantId)
         next(`/login?TenantId=${sessionStorage.TenantId}`) // 否则全部重定向到登录页
       }
       NProgress.done()

+ 15 - 0
src/utils/methodsTool.js

@@ -87,6 +87,21 @@ export default {
 			return true;
 		}
 	},
+	exportData(msg) {
+		if (!msg) {
+			this.$message.warning("导出地址获取错误,请联系开发人员处理")
+			return
+		}
+		let url =
+			baseUrls.baseURL + "common/download?fileName=" + msg;
+		let link = document.createElement("a");
+		let fileName = "导入模板" + ".xlsx";
+		document.body.appendChild(link);
+		link.href = url;
+		link.dowmload = fileName;
+		link.click();
+		link.remove();
+	},
 	//判断是否为数组
 	isArrayFn(o) {
 		return Object.prototype.toString.call(o) === '[object Array]';

+ 2 - 2
src/utils/request.js

@@ -8,13 +8,13 @@ import methods from '@/utils/methodsTool';
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 // 创建axios实例
 export const baseURL = process.env.VUE_APP_BASE_API
-// export const baseURL = 'http://192.168.1.222:5030/'
+// export const baseURL = 'http://192.168.1.7:5030/'
 export const BASE_IMG_URL = process.env.VUE_APP_IMG_API
 const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分
   baseURL: baseURL,
   // 超时
-  timeout: 60000
+  timeout: 600000
 })
 // request拦截器
 service.interceptors.request.use(config => {

+ 5 - 5
src/views/Marketing/goods/commodityManageMent/add/index.vue

@@ -657,7 +657,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -678,7 +678,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -697,7 +697,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -716,7 +716,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -869,7 +869,7 @@ export default {
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
         this.$router.push({
-          path: "CommodityManageMent",
+          path: "commodityManageMent",
         });
       });
     },

+ 1 - 1
src/views/Marketing/goods/commodityManageMent/edit/courseContent/handoutView.vue

@@ -199,7 +199,7 @@ export default {
      */
     openBox(id) {
       if (id && !this.handoutsName) {
-        this.$api.obtainCourseHandouts(id).then((res) => {
+        this.$api.inquireCourseHandoutsfiledetail({handoutsId:id}).then((res) => {
           this.handoutsName = res.data.handoutsName;
         });
       }

+ 1 - 1
src/views/Marketing/goods/commodityManageMent/edit/courseContent/index.vue

@@ -566,7 +566,7 @@ export default {
      * 讲义回调数据
      */
     backHandoutView(id) {
-      this.$set(this.listData, "handoutsId", id);
+      this.$set(this.listData, "handoutsId", id || null);
     },
   },
 };

+ 5 - 5
src/views/Marketing/goods/commodityManageMent/edit/index.vue

@@ -877,7 +877,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -898,7 +898,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -917,7 +917,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -936,7 +936,7 @@ export default {
                 .dispatch("tagsView/exitView", this.$route)
                 .then((res) => {
                   this.$router.push({
-                    path: "CommodityManageMent",
+                    path: "commodityManageMent",
                   });
                 });
             }, 300);
@@ -1100,7 +1100,7 @@ export default {
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
         this.$router.push({
-          path: "CommodityManageMent",
+          path: "commodityManageMent",
         });
       });
     },

+ 7 - 5
src/views/classHoursReview/component/ChapterTable.vue

@@ -72,11 +72,13 @@ export default {
     chapterClassHours: function () {
       return function (arr) {
         var num = 0;
-        arr.classPeriodSectionList.forEach((item) => {
-          if (item.durationTime) {
-            num += parseInt(item.durationTime);
-          }
-        });
+        if (arr.classPeriodSectionList) {
+          arr.classPeriodSectionList.forEach((item) => {
+            if (item.durationTime) {
+              num += parseInt(item.durationTime);
+            }
+          });
+        }
         return num ? (parseInt(num) / 60 / 45).toFixed(1) : 0;
       };
     },

+ 118 - 19
src/views/classHoursReview/component/LessonTable.vue

@@ -127,7 +127,7 @@
               <el-option
                 v-for="(items, indexs) in scope2.row['numList']"
                 :key="indexs"
-                :label="'第' + items + '次审核记录'"
+                :label="`第${items}次审核记录${indexs > 0 ? '(重修)' : ''}`"
                 :value="items"
               >
               </el-option>
@@ -143,12 +143,14 @@
           <span v-else-if="item.scope === 'aTime'">
             {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
           </span>
-          <span v-else-if="item.scope === 'durationTime' && scope2.row.type !== 5">
-            <!-- {{ $methodsTools.secondToDate(scope2.row[item.prop], false) }} -->
+          <span
+            v-else-if="item.scope === 'durationTime' && scope2.row.type !== 5"
+          >
             {{ (scope2.row[item.prop] / 60 / 45).toFixed(2) }}
           </span>
           <span v-else-if="item.scope === 'durTime' && scope2.row.type !== 5">
-            {{ $methodsTools.secondToDate(scope2.row[item.prop], false) }}
+            <!-- {{ $methodsTools.secondToDate(scope2.row[item.prop], false) }} -->
+            {{ (scope2.row[item.prop] / 60).toFixed(0) || 0 }}分钟
             <!-- {{ (scope2.row[item.prop] / 60 / 45).toFixed(2) }} -->
           </span>
           <span
@@ -160,7 +162,7 @@
             {{ scope2.row[item.prop] }}
           </span>
           <div v-else-if="item.scope === 'aTimeSE'">
-            <span
+            <div
               v-if="
                 scope2.row['type'] === 3 &&
                 scope2.row['durationTime'] &&
@@ -169,11 +171,99 @@
               "
               :style="comput(scope2.row)"
             >
-              {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
-            </span>
-            <span v-else>
-              {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
-            </span>
+              <div
+                v-if="
+                  scope2.row['numIndex'] === scope2.row['numList'] &&
+                  scope2.row['numIndex'] !== 1
+                "
+              >
+                <div>
+                  上次时间:{{
+                    $methodsTools.onlyForma(scope2.row["preStartTime"]) +
+                    " - " +
+                    $methodsTools.onlyForma(scope2.row["preEndTime"])
+                  }}
+                </div>
+                <div>
+                  重学时间:{{
+                    $methodsTools.onlyForma(scope2.row[item.prop1]) +
+                    " - " +
+                    $methodsTools.onlyForma(scope2.row[item.prop2])
+                  }}
+                </div>
+              </div>
+              <div v-else>
+                学习时间:{{
+                  $methodsTools.onlyForma(scope2.row[item.prop1]) +
+                  " - " +
+                  $methodsTools.onlyForma(scope2.row[item.prop2])
+                }}
+              </div>
+              <!-- {{ $methodsTools.onlyForma(scope2.row[item.prop]) }} -->
+            </div>
+          </div>
+          <div v-else-if="item.scope === 'aTimeSEComputer'">
+            <div
+              v-if="
+                scope2.row['type'] === 3 &&
+                scope2.row['durationTime'] &&
+                scope2.row['studyStartTime'] &&
+                scope2.row['studyEndTime']
+              "
+            >
+              <div
+                v-if="
+                  scope2.row['numIndex'] === scope2.row['numList'] &&
+                  scope2.row['numIndex'] !== 1
+                "
+              >
+                <!-- <div>
+                  上次时间:{{
+                    $methodsTools.secondToDate(
+                      scope2.row["preEndTime"] - scope2.row["preStartTime"]
+                    )
+                  }}
+                </div>
+                <div>
+                  重学时间:{{
+                    $methodsTools.secondToDate(
+                      scope2.row[item.prop2] - scope2.row[item.prop1]
+                    )
+                  }}
+                </div> -->
+                <div>
+                  上次时间:{{
+                    (
+                      (scope2.row["preEndTime"] - scope2.row["preStartTime"]) /
+                      60
+                    ).toFixed(0) || 0
+                  }}分钟
+                </div>
+                <div>
+                  重学时间:
+                  {{
+                    (
+                      (scope2.row[item.prop2] - scope2.row[item.prop1]) /
+                      60
+                    ).toFixed(0) || 0
+                  }}分钟
+                </div>
+              </div>
+              <div v-else>
+                <!-- 学习时间:{{
+                  $methodsTools.secondToDate(
+                    scope2.row[item.prop2] - scope2.row[item.prop1]
+                  )
+                }} -->
+                学习时间:
+                {{
+                  (
+                    (scope2.row[item.prop2] - scope2.row[item.prop1]) /
+                    60
+                  ).toFixed(0) || 0
+                }}分钟
+              </div>
+            </div>
           </div>
           <span v-else> {{ scope2.row[item.prop] }} </span>
         </template>
@@ -205,7 +295,7 @@ export default {
           label: "选择",
           prop: "numIndex",
           scope: "activeNum",
-          width: "180px",
+          width: "210px",
         },
         {
           label: "姓名",
@@ -239,7 +329,7 @@ export default {
           label: "学时",
           prop: "durationTime",
           width: "120px",
-          scope:"durationTime"
+          scope: "durationTime",
         },
         {
           label: "时长",
@@ -254,16 +344,25 @@ export default {
           scope: "performance",
         },
         {
-          label: "开始时间",
-          prop: "studyStartTime",
+          label: "学习时间",
+          prop1: "studyStartTime",
+          prop2: "studyEndTime",
           scope: "aTimeSE",
+          width: "420px",
         },
         {
-          label: "结束时间",
-          prop: "studyEndTime",
-          scope: "aTimeSE",
+          label: "用时",
+          prop1: "studyStartTime",
+          prop2: "studyEndTime",
+          scope: "aTimeSEComputer",
+          width: "170px",
         },
         // {
+        //   label: "结束时间",
+        //   prop: "studyEndTime",
+        //   scope: "aTimeSE",
+        // },
+        // {
         //   label: "审核状态",
         //   prop: "status",
         //   scope: "select",
@@ -389,8 +488,8 @@ export default {
 <style lang="less" scoped>
 .liImgs {
   float: left;
-  width: 210px;
-  height: 280px;
+  width: 168px;
+  height: 224px;
   margin-right: 16px;
   margin-bottom: 16px;
   position: relative;

+ 3 - 0
src/views/classHoursReview/index.vue

@@ -86,4 +86,7 @@ export default {
 /deep/ .el-tabs__content{
   padding: 6px;
 }
+/deep/ .el-table .el-table__cell.is-center{
+  font-size: 16px;
+}
 </style>

+ 39 - 14
src/views/education/classManageMent/classHoursReview/component/LessonTable.vue

@@ -118,7 +118,7 @@
               <el-option
                 v-for="(items, indexs) in scope2.row['numList']"
                 :key="indexs"
-                :label="'第' + items + '次审核记录'"
+                :label="`第${items}次审核记录${indexs > 0 ? '(重修)' : ''}`"
                 :value="items"
               >
               </el-option>
@@ -138,7 +138,7 @@
             {{ $methodsTools.secondToDate(scope2.row[item.prop], false) }}
           </span>
           <div v-else-if="item.scope === 'aTimeSE'">
-            <span
+            <div
               v-if="
                 scope2.row['type'] === 3 &&
                 scope2.row['durationTime'] &&
@@ -147,8 +147,36 @@
               "
               :style="comput(scope2.row)"
             >
-              {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
-            </span>
+              <div
+                v-if="
+                  scope2.row['numIndex'] === scope2.row['numList'] &&
+                  scope2.row['numIndex'] !== 1
+                "
+              >
+                <div>
+                  上次时间:{{
+                    $methodsTools.onlyForma(scope2.row["preStartTime"]) +
+                    " - " +
+                    $methodsTools.onlyForma(scope2.row["preEndTime"])
+                  }}
+                </div>
+                <div>
+                  重学时间:{{
+                    $methodsTools.onlyForma(scope2.row[item.prop1]) +
+                    " - " +
+                    $methodsTools.onlyForma(scope2.row[item.prop2])
+                  }}
+                </div>
+              </div>
+              <div v-else>
+                学习时间:{{
+                  $methodsTools.onlyForma(scope2.row[item.prop1]) +
+                  " - " +
+                  $methodsTools.onlyForma(scope2.row[item.prop2])
+                }}
+              </div>
+              <!-- {{ $methodsTools.onlyForma(scope2.row[item.prop]) }} -->
+            </div>
             <span v-else>
               {{ $methodsTools.onlyForma(scope2.row[item.prop]) }}
             </span>
@@ -183,7 +211,7 @@ export default {
           label: "选择",
           prop: "numIndex",
           scope: "activeNum",
-          width: "180px",
+          width: "210px",
         },
         {
           label: "姓名",
@@ -220,14 +248,11 @@ export default {
           scope: "durTime",
         },
         {
-          label: "开始时间",
-          prop: "studyStartTime",
-          scope: "aTimeSE",
-        },
-        {
-          label: "结束时间",
-          prop: "studyEndTime",
+          label: "时间",
+          prop1: "studyStartTime",
+          prop2: "studyEndTime",
           scope: "aTimeSE",
+          width: "370px",
         },
         {
           label: "审核状态",
@@ -349,7 +374,7 @@ export default {
 };
 </script>
 
-<style  lang="less" scoped>
+<style lang="less" scoped>
 .liImgs {
   float: left;
   width: 210px;
@@ -395,4 +420,4 @@ export default {
   margin-left: 0px;
   margin-bottom: 10px;
 }
-</style>
+</style>

+ 24 - 6
src/views/resource/bankManagement/chapterVolumeManagement/addChapterjs.vue

@@ -35,6 +35,20 @@
                   注:请尽量规范易懂,方便在题卷目录表呈现给学员
                 </p>
               </el-form-item>
+              <el-form-item required label="试卷类型">
+                <el-select
+                  v-model="item.examPaperId"
+                  placeholder="请选择试卷类型"
+                >
+                  <el-option
+                    v-for="item in paperexam"
+                    :key="item.paperId"
+                    :label="item.paperName"
+                    :value="item.paperId"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
             </div>
             <div class="clear_style">
               <el-button :size="size" @click="list.splice(index, 1)"
@@ -55,6 +69,7 @@
 </template>
 
 <script>
+import { mapGetters } from "vuex";
 export default {
   data() {
     return {
@@ -63,25 +78,28 @@ export default {
       list: [],
     };
   },
+  computed: {
+    ...mapGetters(["paperexam"]),
+  },
   methods: {
     addChapterList() {
       this.list.push({});
     },
     openBoxs(arr) {
       this.businList = JSON.parse(JSON.stringify(arr));
-      this.list = [{}]
+      this.list = [{}];
       this.dialogVisible = true;
     },
     submitForm() {
       const arr = [];
       this.list.forEach((item, index) => {
-        if (!item.examName && item.examName !== 0) {
+        if ((!item.examName && item.examName !== 0) || !item.examPaperId) {
           arr.push(index + 1);
         }
       });
       if (arr.length) {
         this.$message.error(
-          `第${arr.join(",")}条数据没有填写试卷标题,请填写完整后提交`
+          `请检查第${arr.join(",")}条数据的试卷标题或试卷类型,请完成后提交`
         );
         return;
       }
@@ -116,9 +134,9 @@ export default {
     text-align: center;
   }
 }
-.elform_style{
-    max-height: 620px;
-    overflow: auto;
+.elform_style {
+  max-height: 620px;
+  overflow: auto;
 }
 .p_style {
   font-size: 12px;

+ 1 - 1
src/views/resource/bankManagement/testPaperManagement/index.vue

@@ -287,7 +287,7 @@ export default {
     addClick(v, int) {
       if (v === undefined) {
         this.$router.push({
-          path: "AddPaper",
+          path: "addPaper",
         });
         return;
       }

+ 772 - 0
src/views/resource/handoutManagement/handoutList/add/index copy 1.vue

@@ -0,0 +1,772 @@
+<template>
+  <div id="handoutListAdd">
+    <div class="boxWidth">
+      <el-form
+        label-position="right"
+        label-width="120px"
+        :model="listData"
+        :rules="rules"
+        ref="listData"
+      >
+        <el-form-item label="适用业务层级">
+          <el-select
+            v-model="eduType"
+            placeholder="请选择教育类型"
+            @change="changeEduType"
+          >
+            <el-option
+              v-for="(item, index) in eduTypeOptions"
+              :key="index"
+              :label="item.educationName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+          <el-select
+            v-model="courType"
+            placeholder="请选择业务层次"
+            @change="changecourseType"
+          >
+            <el-option
+              v-for="(item, index) in newCourTypeOptions"
+              :key="index"
+              :label="item.projectName + '-' + item.businessName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+          <el-popover
+            ref="popovers"
+            placement="bottom"
+            width="200"
+            trigger="click"
+            @show="showHandle"
+            @hide="hideHandle"
+            :disabled="courType ? false : true"
+          >
+            <el-checkbox
+              v-model="checkAll"
+              @change="handleCheckAllChange"
+              :indeterminate="isIndeterminate"
+              >全选</el-checkbox
+            >
+            <el-checkbox-group
+              v-model="sujectArray"
+              class="checkboxSty"
+              @change="handleCheckedCitiesChange"
+            >
+              <el-checkbox
+                v-for="(item, index) in newSujectOption"
+                :label="item.newId"
+                :key="index"
+                >{{ item.subjectName }}</el-checkbox
+              >
+            </el-checkbox-group>
+            <div style="display: block; text-align: center; margin-top: 10px">
+              <el-button size="mini" type="primary" @click="submitSujectArray"
+                >确定</el-button
+              >
+            </div>
+            <el-button slot="reference" style="margin-left: 12px"
+              >请选择科目</el-button
+            >
+          </el-popover>
+        </el-form-item>
+        <el-form-item label="">
+          <div :class="changeHeight ? 'ach' : 'clh'">
+            <div
+              v-for="(item, index) in newSujectApis"
+              :key="index"
+              class="listBoxStys"
+            >
+              {{
+                item.educationName +
+                " - " +
+                item.projectName +
+                " - " +
+                item.businessName +
+                " - " +
+                item.subjectName
+              }}
+              <i class="el-icon-error closeIcons" @click="closeType(index)"></i>
+            </div>
+          </div>
+          <el-popover
+            placement="bottom-start"
+            trigger="hover"
+            :close-delay="50"
+          >
+            <ul style="margin: 0; max-width: 600px">
+              <li
+                class="copyDataLi"
+                :class="changeSty(itemT)"
+                v-for="(itemT, indexT) in localData"
+                :key="indexT"
+                @click="unTime(itemT)"
+              >
+                {{
+                  `${itemT.educationName}-${itemT.projectName}-${itemT.businessName}-${itemT.subjectName}`
+                }}
+              </li>
+            </ul>
+            <el-button
+              v-show="localData.length"
+              type="danger"
+              slot="reference"
+              size="mini"
+              style="margin-right: 10px"
+              >最近选择</el-button
+            >
+          </el-popover>
+          <el-button
+            size="mini"
+            v-if="newSujectApis.length > 1"
+            @click="changeType"
+            >{{ changeHeight ? "展开" : "关闭" }}</el-button
+          ><el-button
+            size="mini"
+            v-if="newSujectApis.length > 0"
+            @click="sujectApis = []"
+            >清空</el-button
+          >
+          <!-- <span v-if="newSujectApis.length === 0">未选项目类型</span> -->
+        </el-form-item>
+        <el-form-item label="讲义标题" prop="handoutsName">
+          <el-input v-model="listData.handoutsName"></el-input>
+        </el-form-item>
+        <el-form-item label="是否可下载" prop="canDownload">
+          <el-radio-group v-model="listData.canDownload">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="是否发布" prop="status">
+          <el-radio-group v-model="listData.status">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="讲义文件">
+          <div class="handoutList">
+            <label for="uplose"><span class="primary_btn">添加</span></label>
+            <input
+              ref="file"
+              type="file"
+              style="display: none"
+              id="uplose"
+              @change="getImgFile"
+              multiple
+            />
+            <span style="margin-left: 10px">注:只能上传PDF/zip/rar文件</span>
+            <ul>
+              <li v-for="(item, index) in fileList" :key="index">
+                <el-input-number
+                  style="width: 60px; margin-right: 10px"
+                  size="mini"
+                  :precision="0"
+                  v-model="item.sort"
+                  :min="1"
+                  :max="127"
+                  label="排序"
+                  :controls="false"
+                  @blur="sortList"
+                ></el-input-number>
+                <a v-if="item.type === 'pdf'" :href="item.blob" target="_blank">
+                  <img src="@/assets/images/pdf@3x.png" alt="" />
+                </a>
+                <input class="input_text" v-model="item.urlName" />
+                <el-button
+                  type="danger"
+                  size="mini"
+                  style="margin-left: 10px"
+                  @click="fileList.splice(index, 1)"
+                  >删除</el-button
+                >
+              </li>
+            </ul>
+          </div>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="backPage" size="mini">取消</el-button>
+          <el-button
+            size="mini"
+            type="primary"
+            @click="submit('listData')"
+            :loading="disabledBtn"
+            >确定</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import JSZip from "jszip";
+export default {
+  name: "HandoutListAdd",
+  data() {
+    return {
+      fileList: [],
+      // --------------------------------------------
+      disabledBtn: false,
+      isIndeterminate: false,
+      checkAll: false,
+      //   弹窗数据
+      changeHeight: true,
+      listData: {
+        handoutsUrl: undefined,
+        urlName: undefined,
+      },
+      eduTypeOptions: [], //教育类型数据
+      projectTypeOptions: [], //项目类型数据
+      courTypeOptions: [], //业务层次数据
+      newCourTypeOptions: [], //当前业务层次数据
+      sujectOption: [], //科目数据
+      newSujectOption: [], //当前科目数据数据
+      eduType: "", //当前选中教育类型
+      courType: "", //当前选中业务层次
+      sujectApis: [], //当前存在的科目
+      newSujectApis: [],
+      sujectArray: [], //选中的科目
+      localData: [],
+      //表单验证
+      rules: {
+        handoutsName: [
+          { required: true, message: "请输入讲义标题", trigger: "blur" },
+        ],
+        canDownload: [
+          { required: true, message: "请选择是否可下载", trigger: "change" },
+        ],
+        status: [
+          { required: true, message: "请选择是否发布", trigger: "change" },
+        ],
+      },
+    };
+  },
+  watch: {
+    sujectApis: {
+      immediate: true,
+      handler(newName, oldName) {
+        this.changeTypes();
+      },
+    },
+  },
+  mounted() {
+    this.localData = this.$methodsTools.getBusinessList();
+    this.getDict();
+  },
+  methods: {
+    unTime(val) {
+      let a = `${val.businessId}-${val.subjectId}`;
+      if (this.sujectApis.includes(a)) {
+        this.sujectApis.splice(this.sujectApis.indexOf(a), 1);
+      } else {
+        this.sujectApis.push(a);
+      }
+    },
+    changeSty(val) {
+      var arr = "";
+      this.sujectApis.forEach((item) => {
+        let arr1 = item.split("-").map(Number);
+        if (val.businessId == arr1[0] && val.subjectId == arr1[1]) {
+          arr = "activeStyIcons";
+        }
+      });
+      return arr;
+    },
+    handleCheckedCitiesChange() {
+      let nid = this.newSujectOption.map((item) => {
+        return item.newId;
+      });
+      this.checkAll = this.sujectArray.length === nid.length;
+      this.isIndeterminate =
+        this.sujectArray.length > 0 && this.sujectArray.length < nid.length;
+    },
+    setFunc(arr) {
+      var arrays = [];
+      for (let i = 0; i < arr.length; i++) {
+        if (!arrays.includes(arr[i])) {
+          arrays.push(arr[i]);
+        }
+      }
+      return arrays;
+    },
+    handleCheckAllChange(val) {
+      if (val) {
+        let nid = this.newSujectOption.map((item) => {
+          return item.newId;
+        });
+        let arrays = this.sujectArray.concat(nid);
+        this.sujectArray = this.setFunc(arrays);
+        this.isIndeterminate = false;
+      } else {
+        let nid = this.newSujectOption.map((item) => {
+          return item.newId;
+        });
+        let newArr = [];
+        this.sujectArray.forEach((item) => {
+          if (!nid.includes(item)) {
+            newArr.push(item);
+          }
+        });
+        this.sujectArray = newArr;
+        this.isIndeterminate = false;
+      }
+    },
+    changeTypes() {
+      var self = this;
+      var arrays = [];
+      this.sujectApis.map((item, index) => {
+        this.courTypeOptions.map((items) => {
+          if (items.id === item.split("-").map(Number)[0]) {
+            var obj = {
+              educationId: items.educationId,
+              educationName: items.educationName,
+              projectId: items.projectId,
+              projectName: items.projectName,
+              businessId: items.id,
+              businessName: items.businessName,
+            };
+            self.sujectOption.map((i) => {
+              if (
+                i.id === item.split("-").map(Number)[1] &&
+                i.courseArrays.indexOf(items.projectId) !== -1
+              ) {
+                obj.subjectName = i.subjectName;
+                obj.subjectId = i.id;
+              }
+            });
+            arrays.push(obj);
+          }
+        });
+      });
+      this.newSujectApis = arrays;
+    },
+    changeType() {
+      this.changeHeight = !this.changeHeight;
+    },
+    submitSujectArray() {
+      var self = this;
+      this.sujectApis = this.sujectApis.filter((item, index) => {
+        return item.split("-").map(Number)[0] !== Number(self.courType);
+      });
+      for (let i = 0; i < this.sujectArray.length; i++) {
+        this.sujectApis.push(this.sujectArray[i]);
+      }
+      this.$refs.popovers.doClose();
+    },
+    showHandle() {
+      var array = [];
+      for (let i = 0; i < this.sujectApis.length; i++) {
+        if (
+          this.sujectApis[i].split("-").map(Number)[0] === Number(this.courType)
+        ) {
+          array.push(this.sujectApis[i]);
+        }
+      }
+      this.sujectArray = array;
+      if (!this.newSujectOption.length) {
+        this.$message.warning("该业务层次暂无关联科目");
+        this.$refs.popovers.doClose();
+        return;
+      }
+      this.newSujectOption.map((item) => {
+        item.newId = this.courType + "-" + item.id;
+      });
+      this.handleCheckedCitiesChange();
+    },
+    hideHandle() {},
+    getDict() {
+      this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
+        this.eduTypeOptions = res.rows;
+      });
+      this.$api.inquireCourseProjectType({ status: 1 }).then((res) => {
+        this.projectTypeOptions = res.rows;
+      });
+      this.$api.inquirebusinessList({ status: 1 }).then((res) => {
+        this.courTypeOptions = res.rows;
+        this.newCourTypeOptions = res.rows;
+      });
+      this.$api.inquireCourseSubject({ status: 1 }).then((res) => {
+        res.rows.map((item, index) => {
+          var array = [];
+          item.courseProjectTypes.map((items, indexs) => {
+            array.push(items.id);
+          });
+          item.courseArrays = array;
+        });
+        this.sujectOption = res.rows;
+      });
+    },
+    changeEduType() {
+      if (!(this.courType === undefined || this.courType === "")) {
+        this.courType = "";
+      }
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.eduType) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+    },
+    changecourseType() {
+      this.newCourTypeOptions.map((item, index) => {
+        if (item.id === this.courType) {
+          this.eduType = item.educationId;
+          var array = [];
+          this.sujectOption.map((items, indexs) => {
+            if (items.courseArrays.indexOf(item.projectId) !== -1) {
+              array.push(items);
+            }
+          });
+          this.newSujectOption = array;
+        }
+      });
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.eduType) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+      this.$refs.popovers.doClose();
+    },
+    clearImgs() {
+      this.listData.handoutsUrl = undefined;
+      this.listData.urlName = undefined;
+    },
+    async submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    async rulesTableSumbit() {
+      var dataInfos = {
+        handoutsName: this.listData.handoutsName,
+        courseHandoutsBusinessAddBos: this.newSujectApis,
+        status: this.listData.status,
+        canDownload: this.listData.canDownload,
+        coverUrl: this.listData.coverUrl,
+      };
+      if (this.fileList.length) {
+        const hasSort = this.fileList.every((item) => {
+          return item.sort >= 0 && item.urlName.length > 0;
+        });
+        if (hasSort) {
+          let array = [];
+          let stop = false; //控制上下文执行
+          for (let i = 0; i < this.fileList.length; i++) {
+            array.push(
+              new Promise((resolve, reject) => {
+                this.$upload
+                  .upload(this.fileList[i].file, 6)
+                  .then((res) => {
+                    this.$set(this.fileList[i], "url", res);
+                    resolve();
+                  })
+                  .catch((err) => {
+                    this.$message.error(`第${i}个文件上传失败`);
+                    reject();
+                  });
+              })
+            );
+          }
+          await Promise.all(array)
+            .then(() => {
+              stop = false;
+              console.log("成功");
+            })
+            .catch(() => {
+              stop = true;
+              console.log("失败");
+            });
+          if (stop) {
+            return;
+          }
+        } else {
+          this.$message.warning("排序与文件名不允许为空");
+          return;
+        }
+      }
+      dataInfos["fileList"] = this.fileList;
+      this.disabledBtn = true;
+      this.$api
+        .addCourseHandouts(dataInfos)
+        .then((res) => {
+          this.$methodsTools.cacheBusinessList(this.newSujectApis);
+          this.$message.success("新增成功");
+          setTimeout(() => {
+            this.$store
+              .dispatch("tagsView/exitView", this.$route)
+              .then((res) => {
+                this.$router.push({
+                  path: "handoutList",
+                });
+              });
+          }, 500);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "handoutList",
+        });
+      });
+    },
+    closeType(index) {
+      this.sujectApis.splice(index, 1);
+    },
+    getImgFile(e) {
+      console.log(e.target.files);
+      if (e.target.files.length > 0) {
+        for (let i = 0; i < e.target.files.length; i++) {
+          var type = e.target.files[i].name.toLowerCase().split(".").splice(-1);
+          console.log(["pdf", "zip", "rar"].includes(type[0]));
+          if (["pdf", "zip", "rar"].includes(type[0])) {
+            const imgURL = window.URL.createObjectURL(e.target.files[i]);
+            this.fileList.push({
+              type: type[0],
+              blob: imgURL,
+              url: "",
+              file: e.target.files[i],
+              status: 1,
+              urlName: e.target.files[i].name,
+              sort: this.backNowMathMax(),
+            });
+            if (type[0] === "zip") {
+              var new_zip = new JSZip();
+              var iconv = require("iconv-lite"); // 一个纯粹用javascript解码的模块iconv-lite,可以实现编码转换
+              new_zip
+                .loadAsync(e.target.files[i], {
+                  decodeFileName: function (bytes) {
+                    return iconv.decode(bytes, "gbk"); // 按中文编码
+                  },
+                })
+                .then((res) => {
+                  var array = [];
+                  res.forEach((val) => {
+                    //转换为file文件
+                    res.files[val].async("blob").then((con) => {
+                      const imgURLs = window.URL.createObjectURL(
+                        new window.File([con], val)
+                      );
+                      if (val.indexOf("/") !== -1) {
+                        console.log(val.indexOf("/") !== -1);
+                        var str = val.slice(0, val.indexOf("/"));
+                        if (array.findIndex((s) => s.urlName === str) === -1) {
+                          //查看暂存array是否有这个文件夹
+                          array.push({
+                            type: 1,
+                            blob: "",
+                            url: "",
+                            file: "",
+                            status: 1,
+                            urlName: str,
+                            children: [],
+                          });
+                        }
+                        array[
+                          array.findIndex((s) => s.urlName === str)
+                        ].children.push({
+                          type: 2,
+                          blob: imgURLs,
+                          url: "",
+                          file: new window.File(
+                            [con],
+                            val.slice(val.indexOf("/") + 1)
+                          ),
+                          status: 1,
+                          urlName: val.slice(val.indexOf("/") + 1),
+                        });
+                      } else {
+                        array.push({
+                          type: 2,
+                          blob: imgURLs,
+                          url: "",
+                          file: new window.File([con], val),
+                          status: 1,
+                          urlName: val,
+                        });
+                      }
+                    });
+                  });
+                  console.log("成功:", res, array);
+                })
+                .catch((err) => {
+                  console.log("错误:", err);
+                });
+            }
+          }
+        }
+      }
+      // console.log(this.fileList, e.target.files);
+      return;
+      var fileArry = [];
+      for (let i = 0; i < e.target.files.length; i++) {
+        fileArry.push(e.target.files[i]);
+      }
+      console.log(fileArry);
+      var self = this;
+      for (let i = 0; i < fileArry.length; i++) {
+        var file = fileArry[i];
+        if (file === undefined) {
+          // self.$set(self.listData, "handoutsUrl", "");
+          return;
+        }
+        if (file.size > 100 * 1024 * 1024) {
+          self.$message.error("pdf文件不得大于100MB");
+          return;
+        }
+        var type = file.name.toLowerCase().split(".").splice(-1);
+        if (type[0] != "pdf") {
+          self.$message.error("上传格式需为:.pdf");
+          // self.$refs.file.value = "";
+          return;
+        }
+        const imgURL = window.URL.createObjectURL(file);
+        self.fileList.push({
+          blob: imgURL,
+          url: "",
+          file: file,
+          status: 1,
+          urlName: file.name,
+          sort: self.backNowMathMax(),
+        });
+      }
+      e.target.value = "";
+    },
+    //返回当前数组sort最大值+1,用于自动sort排序
+    backNowMathMax() {
+      if (this.fileList.length) {
+        let list = this.fileList.map((item) => {
+          if (item.sort >= 0) {
+            return Number(item.sort);
+          } else {
+            return 0;
+          }
+        });
+        return Math.max(...list) + 1;
+      } else {
+        return 1;
+      }
+    },
+
+    //排序
+    sortList() {
+      this.fileList = this.fileList.sort((a, b) => {
+        if (a.sort >= 0 && b.sort >= 0) {
+          return a.sort - b.sort;
+        } else {
+          this.$message.warning("请完善排序号码");
+        }
+      }); //升序
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.boxWidth {
+  width: 700px;
+}
+.numInputs {
+  width: 150px;
+}
+.checkboxSty {
+  max-height: 210px;
+  overflow: auto;
+  display: flex;
+  flex-direction: column;
+}
+.listBoxStys {
+  flex-shrink: 0;
+  padding: 0px 10px;
+  border-radius: 8px;
+  border: 1px solid #eee;
+  margin-right: 10px;
+  margin-bottom: 6px;
+}
+.closeIcons {
+  color: red;
+  cursor: pointer;
+  margin-left: 6px;
+}
+.ach {
+  display: flex;
+  align-items: center;
+  overflow: hidden;
+}
+.clh {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.handoutList {
+  & > ul {
+    max-height: 500px;
+    overflow: auto;
+    & > li {
+      display: flex;
+      align-items: center;
+      margin-bottom: 6px;
+      a {
+        display: inherit;
+      }
+      img {
+        height: 28px;
+        width: 20px;
+        cursor: pointer;
+        transition: all 0.3s;
+        margin-right: 10px;
+        &:hover {
+          transform: scale(1.05);
+        }
+      }
+      .input_text {
+        height: 28px;
+      }
+    }
+  }
+}
+
+.primary_btn {
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  background: #ffffff;
+  border: 1px solid #dcdfe6;
+  border-color: #dcdfe6;
+  color: #606266;
+  -webkit-appearance: none;
+  text-align: center;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  outline: none;
+  margin: 0;
+  -webkit-transition: 0.1s;
+  transition: 0.1s;
+  font-weight: 400;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  padding: 12px 20px;
+  font-size: 14px;
+  border-radius: 4px;
+  padding: 7px 15px;
+  font-size: 12px;
+  border-radius: 3px;
+  color: #ffffff;
+  background-color: #1890ff;
+  border-color: #1890ff;
+}
+</style>

+ 209 - 84
src/views/resource/handoutManagement/handoutList/add/index copy.vue

@@ -147,39 +147,56 @@
           </el-radio-group>
         </el-form-item>
         <el-form-item label="讲义文件">
-          <div class="imgBoxins">
-            <div v-if="handoutsUrlLive" class="dis_stsy">
-              <a :href="blob" target="_blank">
-                <img src="@/assets/images/pdf@3x.png" alt="" />
-              </a>
-
-              <p>{{ listData.urlName }}</p>
-              <el-button
-                type="danger"
-                size="mini"
-                class="margin-top: 20px;"
-                @click="clearImgs"
-                >删除</el-button
-              >
-            </div>
-            <div class="posimg" v-else>
-              <label for="uplose">
-                <i class="el-icon-circle-plus-outline iconStsz"></i
-              ></label>
-              <input
-                ref="file"
-                type="file"
-                style="display: none"
-                id="uplose"
-                @change="getImgFile"
-              />
-              <p>注:只能上传PDF文件,且不超过100MB</p>
-            </div>
+          <div class="handoutList">
+            <label for="uplose"><span class="primary_btn">添加pdf</span></label>
+            <input
+              ref="file"
+              type="file"
+              style="display: none"
+              id="uplose"
+              @change="getImgFile"
+              multiple
+            />
+            <span style="margin-left: 10px"
+              >注:只能上传PDF文件,且不超过100MB</span
+            >
+            <ul>
+              <li v-for="(item, index) in fileList" :key="index">
+                <el-input-number
+                  style="width: 60px; margin-right: 10px"
+                  size="mini"
+                  :precision="0"
+                  v-model="item.sort"
+                  :min="1"
+                  :max="127"
+                  label="排序"
+                  :controls="false"
+                  @blur="sortList"
+                ></el-input-number>
+                <a :href="item.blob" target="_blank">
+                  <img src="@/assets/images/pdf@3x.png" alt="" />
+                </a>
+                <input class="input_text" v-model="item.urlName" />
+                <el-button
+                  type="danger"
+                  size="mini"
+                  style="margin-left: 10px"
+                  @click="fileList.splice(index, 1)"
+                  >删除</el-button
+                >
+              </li>
+            </ul>
           </div>
         </el-form-item>
         <el-form-item>
-          <el-button @click="backPage">取消</el-button>
-          <el-button type="primary" @click="submit('listData')" :loading="disabledBtn">确定</el-button>
+          <el-button @click="backPage" size="mini">取消</el-button>
+          <el-button
+            size="mini"
+            type="primary"
+            @click="submit('listData')"
+            :loading="disabledBtn"
+            >确定</el-button
+          >
         </el-form-item>
       </el-form>
     </div>
@@ -191,11 +208,11 @@ export default {
   name: "HandoutListAdd",
   data() {
     return {
+      fileList: [],
+      // --------------------------------------------
       disabledBtn: false,
       isIndeterminate: false,
       checkAll: false,
-      blob: "", //pdf本地路径
-      handoutsUrlLive: false, //是否存在PDF
       //   弹窗数据
       changeHeight: true,
       listData: {
@@ -235,15 +252,6 @@ export default {
         this.changeTypes();
       },
     },
-    "listData.handoutsUrl": {
-      handler(newValue, oldValue) {
-        if (newValue) {
-          this.handoutsUrlLive = true;
-        } else {
-          this.handoutsUrlLive = false;
-        }
-      },
-    },
   },
   mounted() {
     this.localData = this.$methodsTools.getBusinessList();
@@ -430,7 +438,7 @@ export default {
       this.listData.handoutsUrl = undefined;
       this.listData.urlName = undefined;
     },
-    submit(formName) {
+    async submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
           this.rulesTableSumbit();
@@ -447,25 +455,66 @@ export default {
         canDownload: this.listData.canDownload,
         coverUrl: this.listData.coverUrl,
       };
-      if (this.listData.handoutsUrl) {
-        const urls = await this.$upload.upload(this.listData.handoutsUrl, 6);
-        dataInfos.handoutsUrl = urls;
-        dataInfos.urlName = this.listData.urlName;
-      }
-      this.disabledBtn = true
-      this.$api.addCourseHandouts(dataInfos).then((res) => {
-        this.$methodsTools.cacheBusinessList(this.newSujectApis);
-        this.$message.success("新增成功");
-        setTimeout(() => {
-          this.$store.dispatch("tagsView/exitView", this.$route).then((res) => {
-            this.$router.push({
-              path: "handoutList",
+      if (this.fileList.length) {
+        const hasSort = this.fileList.every((item) => {
+          return item.sort >= 0 && item.urlName.length > 0;
+        });
+        if (hasSort) {
+          let array = [];
+          let stop = false; //控制上下文执行
+          for (let i = 0; i < this.fileList.length; i++) {
+            array.push(
+              new Promise((resolve, reject) => {
+                this.$upload
+                  .upload(this.fileList[i].file, 6)
+                  .then((res) => {
+                    this.$set(this.fileList[i], "url", res);
+                    resolve();
+                  })
+                  .catch((err) => {
+                    this.$message.error(`第${i}个文件上传失败`);
+                    reject();
+                  });
+              })
+            );
+          }
+          await Promise.all(array)
+            .then(() => {
+              stop = false;
+              console.log("成功");
+            })
+            .catch(() => {
+              stop = true;
+              console.log("失败");
             });
-          });
-        }, 500);
-      }).catch(()=>{
-          this.disabledBtn = false
+          if (stop) {
+            return;
+          }
+        } else {
+          this.$message.warning("排序与文件名不允许为空");
+          return;
+        }
+      }
+      dataInfos["fileList"] = this.fileList;
+      this.disabledBtn = true;
+      this.$api
+        .addCourseHandouts(dataInfos)
+        .then((res) => {
+          this.$methodsTools.cacheBusinessList(this.newSujectApis);
+          this.$message.success("新增成功");
+          setTimeout(() => {
+            this.$store
+              .dispatch("tagsView/exitView", this.$route)
+              .then((res) => {
+                this.$router.push({
+                  path: "handoutList",
+                });
+              });
+          }, 500);
         })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
     },
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
@@ -478,26 +527,66 @@ export default {
       this.sujectApis.splice(index, 1);
     },
     getImgFile(e) {
+      console.log(e.target.files)
+      var fileArry = [];
+      for (let i = 0; i < e.target.files.length; i++) {
+        fileArry.push(e.target.files[i]);
+      }
+      console.log(fileArry);
       var self = this;
-      var file = self.$refs.file.files[0];
+      for(let i = 0; i < fileArry.length;i++){
+      var file = fileArry[i]
       if (file === undefined) {
-        self.$set(self.listData, "handoutsUrl", "");
+        // self.$set(self.listData, "handoutsUrl", "");
         return;
       }
       if (file.size > 100 * 1024 * 1024) {
         self.$message.error("pdf文件不得大于100MB");
         return;
       }
-      var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
+      var type = file.name.toLowerCase().split(".").splice(-1);
       if (type[0] != "pdf") {
         self.$message.error("上传格式需为:.pdf");
-        self.$refs.file.value = "";
+        // self.$refs.file.value = "";
         return;
       }
       const imgURL = window.URL.createObjectURL(file);
-      self.blob = imgURL;
-      self.listData.handoutsUrl = file;
-      self.listData.urlName = file.name;
+      self.fileList.push({
+        blob: imgURL,
+        url: "",
+        file: file,
+        status: 1,
+        urlName: file.name,
+        sort: self.backNowMathMax(),
+      });
+      }
+      e.target.value = "";
+    },
+    //返回当前数组sort最大值+1,用于自动sort排序
+    backNowMathMax() {
+      if (this.fileList.length) {
+        let list = this.fileList.map((item) => {
+          if (item.sort >= 0) {
+            return Number(item.sort);
+          } else {
+            return 0;
+          }
+        });
+        return Math.max(...list) + 1;
+      } else {
+        return 1;
+      }
+    },
+
+    //排序
+    sortList() {
+      this.fileList = this.fileList.sort((a, b) => {
+        if (a.sort >= 0 && b.sort >= 0) {
+          return a.sort - b.sort;
+        } else {
+          this.$message.warning("请完善排序号码");
+        }
+      }); //升序
     },
   },
 };
@@ -539,27 +628,63 @@ export default {
   align-items: center;
   flex-wrap: wrap;
 }
-.imgBoxins {
-  width: 375px;
-  // height: 220px;
-  text-align: center;
-  img {
-    height: 100%;
-    width: 60px;
-    cursor: pointer;
-    transition: all 0.3s;
-    &:hover {
-      transform: scale(1.05);
+.handoutList {
+  & > ul {
+    max-height: 500px;
+    overflow: auto;
+    & > li {
+      display: flex;
+      align-items: center;
+      margin-bottom: 6px;
+      a {
+        display: inherit;
+      }
+      img {
+        height: 28px;
+        width: 20px;
+        cursor: pointer;
+        transition: all 0.3s;
+        margin-right: 10px;
+        &:hover {
+          transform: scale(1.05);
+        }
+      }
+      .input_text{
+        height: 28px;
+      }
     }
   }
-  .dis_stsy {
-    display: flex;
-    align-items: flex-end;
-  }
 }
-.iconStsz {
-  font-size: 40px;
-  color: #67c23a;
+
+.primary_btn {
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
   cursor: pointer;
+  background: #ffffff;
+  border: 1px solid #dcdfe6;
+  border-color: #dcdfe6;
+  color: #606266;
+  -webkit-appearance: none;
+  text-align: center;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  outline: none;
+  margin: 0;
+  -webkit-transition: 0.1s;
+  transition: 0.1s;
+  font-weight: 400;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  padding: 12px 20px;
+  font-size: 14px;
+  border-radius: 4px;
+  padding: 7px 15px;
+  font-size: 12px;
+  border-radius: 3px;
+  color: #ffffff;
+  background-color: #1890ff;
+  border-color: #1890ff;
 }
 </style>

+ 69 - 90
src/views/resource/handoutManagement/handoutList/add/index.vue

@@ -148,7 +148,13 @@
         </el-form-item>
         <el-form-item label="讲义文件">
           <div class="handoutList">
-            <label for="uplose"><span class="primary_btn">添加pdf</span></label>
+            <label for="uplose"
+              ><span
+                class="primary_btn"
+                :style="uploadStatus > 0 ? 'cursor: no-drop' : 'cursor:pointer'"
+                >添加</span
+              ></label
+            >
             <input
               ref="file"
               type="file"
@@ -156,32 +162,43 @@
               id="uplose"
               @change="getImgFile"
               multiple
+              :disabled="uploadStatus > 0 ? true : false"
             />
             <span style="margin-left: 10px"
-              >注:只能上传PDF文件,且不超过100MB</span
+              >注:只能上传DOCX/XLSX/PDF/ZIP文件</span
             >
             <ul>
               <li v-for="(item, index) in fileList" :key="index">
-                <el-input-number
-                  style="width: 60px; margin-right: 10px"
-                  size="mini"
-                  :precision="0"
-                  v-model="item.sort"
-                  :min="1"
-                  :max="127"
-                  label="排序"
-                  :controls="false"
-                  @blur="sortList"
-                ></el-input-number>
-                <a :href="item.blob" target="_blank">
+                <a
+                  v-if="
+                    item.name.toLowerCase().split('.').splice(-1)[0] === 'pdf'
+                  "
+                  :href="item.blob"
+                  target="_blank"
+                >
                   <img src="@/assets/images/pdf@3x.png" alt="" />
                 </a>
-                <input class="input_text" v-model="item.urlName" />
+                <img
+                  v-else-if="
+                    item.name.toLowerCase().split('.').splice(-1)[0] === 'xlsx'
+                  "
+                  src="@/assets/images/xlsx.png"
+                  alt=""
+                />
+                <img
+                  v-else-if="
+                    item.name.toLowerCase().split('.').splice(-1)[0] === 'docx'
+                  "
+                  src="@/assets/images/docx.png"
+                  alt=""
+                />
+                <img v-else src="@/assets/images/zip.png" alt="" />
+                <span>{{ item.name }}</span>
                 <el-button
                   type="danger"
                   size="mini"
                   style="margin-left: 10px"
-                  @click="fileList.splice(index, 1)"
+                  @click="delList(item)"
                   >删除</el-button
                 >
               </li>
@@ -193,9 +210,10 @@
           <el-button
             size="mini"
             type="primary"
+            :disabled="uploadStatus > 0"
             @click="submit('listData')"
             :loading="disabledBtn"
-            >确定</el-button
+            >{{ uploadStatus > 0 ? "上传中" : "确定" }}</el-button
           >
         </el-form-item>
       </el-form>
@@ -204,8 +222,11 @@
 </template>
 
 <script>
+import JSZip from "jszip";
+import fpFile from "@/mixin/fpFile";
 export default {
   name: "HandoutListAdd",
+  mixins: [fpFile],
   data() {
     return {
       fileList: [],
@@ -231,6 +252,7 @@ export default {
       newSujectApis: [],
       sujectArray: [], //选中的科目
       localData: [],
+      uploadStatus: 0, //为0代表文件全部上传完成
       //表单验证
       rules: {
         handoutsName: [
@@ -258,6 +280,12 @@ export default {
     this.getDict();
   },
   methods: {
+    delList(data) {
+      this.fileList = this.fileList.filter((d) => d.md5 !== data.md5);
+      this.$api
+        .commondeletefile({ name: data.name, fileMd5: data.md5 })
+        .then(() => {});
+    },
     unTime(val) {
       let a = `${val.businessId}-${val.subjectId}`;
       if (this.sujectApis.includes(a)) {
@@ -454,48 +482,11 @@ export default {
         status: this.listData.status,
         canDownload: this.listData.canDownload,
         coverUrl: this.listData.coverUrl,
+        fileList:
+          this.fileList.map((i) => {
+            return { urlName: i.name };
+          }) || [],
       };
-      if (this.fileList.length) {
-        const hasSort = this.fileList.every((item) => {
-          return item.sort >= 0 && item.urlName.length > 0;
-        });
-        if (hasSort) {
-          let array = [];
-          let stop = false; //控制上下文执行
-          for (let i = 0; i < this.fileList.length; i++) {
-            array.push(
-              new Promise((resolve, reject) => {
-                this.$upload
-                  .upload(this.fileList[i].file, 6)
-                  .then((res) => {
-                    this.$set(this.fileList[i], "url", res);
-                    resolve();
-                  })
-                  .catch((err) => {
-                    this.$message.error(`第${i}个文件上传失败`);
-                    reject();
-                  });
-              })
-            );
-          }
-          await Promise.all(array)
-            .then(() => {
-              stop = false;
-              console.log("成功");
-            })
-            .catch(() => {
-              stop = true;
-              console.log("失败");
-            });
-          if (stop) {
-            return;
-          }
-        } else {
-          this.$message.warning("排序与文件名不允许为空");
-          return;
-        }
-      }
-      dataInfos["fileList"] = this.fileList;
       this.disabledBtn = true;
       this.$api
         .addCourseHandouts(dataInfos)
@@ -526,38 +517,26 @@ export default {
     closeType(index) {
       this.sujectApis.splice(index, 1);
     },
-    getImgFile(e) {
-      var fileArry = [];
-      for (let i = 0; i < e.target.files.length; i++) {
-        fileArry.push(e.target.files[i]);
-      }
-      console.log(fileArry);
+    async getImgFile(e) {
       var self = this;
-      for(let i = 0; i < fileArry.length;i++){
-      var file = fileArry[i]
-      if (file === undefined) {
-        // self.$set(self.listData, "handoutsUrl", "");
-        return;
-      }
-      if (file.size > 100 * 1024 * 1024) {
-        self.$message.error("pdf文件不得大于100MB");
-        return;
-      }
-      var type = file.name.toLowerCase().split(".").splice(-1);
-      if (type[0] != "pdf") {
-        self.$message.error("上传格式需为:.pdf");
-        // self.$refs.file.value = "";
-        return;
-      }
-      const imgURL = window.URL.createObjectURL(file);
-      self.fileList.push({
-        blob: imgURL,
-        url: "",
-        file: file,
-        status: 1,
-        urlName: file.name,
-        sort: self.backNowMathMax(),
-      });
+      if (e.target.files.length > 0) {
+        this.uploadStatus += e.target.files.length;
+        for (let i = 0; i < e.target.files.length; i++) {
+          var type = e.target.files[i].name.toLowerCase().split(".").splice(-1);
+          if (["docx", "xlsx", "pdf", "zip"].includes(type[0])) {
+            const obj = await this.chunksUpload(e.target.files[i]);
+            e.target.files[i].blob = window.URL.createObjectURL(
+              e.target.files[i]
+            );
+            e.target.files[i].md5 = obj.md5;
+            if (obj.status) {
+              self.fileList.push(e.target.files[i]);
+              this.uploadStatus--;
+            }
+          } else {
+            this.uploadStatus--;
+          }
+        }
       }
       e.target.value = "";
     },
@@ -648,7 +627,7 @@ export default {
           transform: scale(1.05);
         }
       }
-      .input_text{
+      .input_text {
         height: 28px;
       }
     }

+ 684 - 0
src/views/resource/handoutManagement/handoutList/edit/index copy.vue

@@ -0,0 +1,684 @@
+<template>
+  <div id="handoutListEdit">
+    <div class="boxWidth">
+      <el-form
+        label-position="right"
+        label-width="120px"
+        :model="listData"
+        :rules="rules"
+        ref="listData"
+      >
+        <el-form-item label="适用业务层级">
+          <el-select
+            v-model="eduType"
+            placeholder="请选择教育类型"
+            @change="changeEduType"
+          >
+            <el-option
+              v-for="(item, index) in eduTypeOptions"
+              :key="index"
+              :label="item.educationName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+          <el-select
+            v-model="courType"
+            placeholder="请选择业务层次"
+            @change="changecourseType"
+          >
+            <el-option
+              v-for="(item, index) in newCourTypeOptions"
+              :key="index"
+              :label="item.projectName + '-' + item.businessName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+          <el-popover
+            ref="popovers"
+            placement="bottom"
+            trigger="click"
+            @show="showHandle"
+            @hide="hideHandle"
+            :disabled="courType ? false : true"
+          >
+            <el-checkbox
+              v-model="checkAll"
+              @change="handleCheckAllChange"
+              :indeterminate="isIndeterminate"
+              >全选</el-checkbox
+            >
+            <el-checkbox-group
+              v-model="sujectArray"
+              class="checkboxSty"
+              @change="handleCheckedCitiesChange"
+            >
+              <el-checkbox
+                v-for="(item, index) in newSujectOption"
+                :label="item.newId"
+                :key="index"
+                >{{ item.subjectName }}</el-checkbox
+              >
+            </el-checkbox-group>
+            <div style="display: block; text-align: center; margin-top: 10px">
+              <el-button size="mini" type="primary" @click="submitSujectArray"
+                >确定</el-button
+              >
+            </div>
+            <el-button slot="reference" style="margin-left: 12px"
+              >请选择科目</el-button
+            >
+          </el-popover>
+        </el-form-item>
+        <el-form-item label="">
+          <div :class="changeHeight ? 'ach' : 'clh'">
+            <div
+              v-for="(item, index) in newSujectApis"
+              :key="index"
+              class="listBoxStys"
+            >
+              {{
+                item.educationName +
+                " - " +
+                item.projectName +
+                " - " +
+                item.businessName +
+                " - " +
+                item.subjectName
+              }}
+              <i class="el-icon-error closeIcons" @click="closeType(index)"></i>
+            </div>
+          </div>
+          <el-button
+            size="mini"
+            v-if="newSujectApis.length > 1"
+            @click="changeType"
+            >{{ changeHeight ? "展开" : "关闭" }}</el-button
+          ><el-button
+            size="mini"
+            v-if="newSujectApis.length > 0"
+            @click="sujectApis = []"
+            >清空</el-button
+          >
+          <!-- <span v-if="newSujectApis.length === 0">未选项目类型</span> -->
+        </el-form-item>
+        <el-form-item label="讲义标题" prop="handoutsName">
+          <el-input v-model="listData.handoutsName"></el-input>
+        </el-form-item>
+        <el-form-item label="讲义文件">
+          <div class="handoutList">
+            <label for="uplose"><span class="primary_btn">添加pdf</span></label>
+            <input
+              ref="file"
+              type="file"
+              style="display: none"
+              id="uplose"
+              @change="getImgFile"
+              multiple
+            />
+            <span style="margin-left: 10px"
+              >注:只能上传PDF文件,且不超过100MB</span
+            >
+            <ul>
+              <li v-for="(item, index) in fileList" :key="index">
+                <el-input-number
+                  style="width: 60px; margin-right: 10px"
+                  size="mini"
+                  :precision="0"
+                  v-model="item.sort"
+                  :min="1"
+                  :max="127"
+                  label="排序"
+                  :controls="false"
+                  @blur="sortList"
+                ></el-input-number>
+                <a
+                  :href="
+                    item.blob ? item.blob : $methodsTools.splitImgHost(item.url)
+                  "
+                  target="_blank"
+                >
+                  <img src="@/assets/images/pdf@3x.png" alt="" />
+                </a>
+                <input class="input_text" v-model="item.urlName" />
+                <el-button
+                  type="danger"
+                  size="mini"
+                  style="margin-left: 10px"
+                  @click="fileList.splice(index, 1)"
+                  >删除</el-button
+                >
+              </li>
+            </ul>
+          </div>
+        </el-form-item>
+        <el-form-item label="是否可下载" prop="canDownload">
+          <el-radio-group v-model="listData.canDownload">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="是否发布" prop="status">
+          <el-radio-group v-model="listData.status">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="backPage" size="mini">取消</el-button>
+          <el-button
+            size="mini"
+            type="primary"
+            @click="submit('listData')"
+            :loading="disabledBtn"
+            >确定</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "HandoutListEdit",
+  data() {
+    return {
+      fileList: [],
+      disabledBtn: false,
+      isIndeterminate: false,
+      checkAll: false,
+      changeHeight: true,
+      //   弹窗数据
+      listData: {
+        handoutsUrl: undefined,
+        urlName: undefined,
+      },
+      bfImg: "",
+      eduTypeOptions: [], //教育类型数据
+      projectTypeOptions: [], //项目类型数据
+      courTypeOptions: [], //业务层次数据
+      newCourTypeOptions: [], //当前业务层次数据
+      sujectOption: [], //科目数据
+      newSujectOption: [], //当前科目数据数据
+      eduType: "", //当前选中教育类型
+      courType: "", //当前选中业务层次
+      sujectApis: [], //当前存在的科目
+      newSujectApis: [],
+      sujectArray: [], //选中的科目
+      //表单验证
+      rules: {
+        handoutsName: [
+          { required: true, message: "请输入讲义标题", trigger: "blur" },
+        ],
+        canDownload: [
+          { required: true, message: "请选择是否可下载", trigger: "change" },
+        ],
+        status: [
+          { required: true, message: "请选择是否发布", trigger: "change" },
+        ],
+      },
+    };
+  },
+  watch: {
+    sujectApis: {
+      immediate: true,
+      handler(newName, oldName) {
+        this.changeTypes();
+      },
+    },
+  },
+  async mounted() {
+    this.$modal.loading("正在导入数据,请稍后...");
+    await this.getDict();
+    this.search();
+  },
+  methods: {
+    handleCheckedCitiesChange() {
+      let nid = this.newSujectOption.map((item) => {
+        return item.newId;
+      });
+      this.checkAll = this.sujectArray.length === nid.length;
+      this.isIndeterminate =
+        this.sujectArray.length > 0 && this.sujectArray.length < nid.length;
+    },
+    setFunc(arr) {
+      var arrays = [];
+      for (let i = 0; i < arr.length; i++) {
+        if (!arrays.includes(arr[i])) {
+          arrays.push(arr[i]);
+        }
+      }
+      return arrays;
+    },
+    handleCheckAllChange(val) {
+      if (val) {
+        let nid = this.newSujectOption.map((item) => {
+          return item.newId;
+        });
+        let arrays = this.sujectArray.concat(nid);
+        this.sujectArray = this.setFunc(arrays);
+        this.isIndeterminate = false;
+      } else {
+        let nid = this.newSujectOption.map((item) => {
+          return item.newId;
+        });
+        let newArr = [];
+        this.sujectArray.forEach((item) => {
+          if (!nid.includes(item)) {
+            newArr.push(item);
+          }
+        });
+        this.sujectArray = newArr;
+        this.isIndeterminate = false;
+      }
+    },
+    search() {
+      this.$api
+        .obtainCourseHandouts(this.$route.query.id)
+        .then((res) => {
+          this.fileList = res.data.fileList || [];
+          this.listData = res.data;
+          if (res.data.courseHandoutsBusinessVo) {
+            var arrays = [];
+            res.data.courseHandoutsBusinessVo.map((item) => {
+              arrays.push(item.businessId + "-" + item.subjectId);
+            });
+            this.sujectApis = arrays;
+          }
+        })
+        .finally(() => {
+          this.$modal.closeLoading();
+        });
+    },
+    changeTypes() {
+      var self = this;
+      var arrays = [];
+      this.sujectApis.map((item, index) => {
+        this.courTypeOptions.map((items) => {
+          if (items.id === item.split("-").map(Number)[0]) {
+            var obj = {
+              educationId: items.educationId,
+              educationName: items.educationName,
+              projectId: items.projectId,
+              projectName: items.projectName,
+              businessId: items.id,
+              businessName: items.businessName,
+            };
+            self.sujectOption.map((i) => {
+              if (
+                i.id === item.split("-").map(Number)[1] &&
+                i.courseArrays.indexOf(items.projectId) !== -1
+              ) {
+                obj.subjectName = i.subjectName;
+                obj.subjectId = i.id;
+              }
+            });
+            arrays.push(obj);
+          }
+        });
+      });
+      this.newSujectApis = arrays;
+    },
+    changeType() {
+      this.changeHeight = !this.changeHeight;
+    },
+    submitSujectArray() {
+      var self = this;
+      this.sujectApis = this.sujectApis.filter((item, index) => {
+        return item.split("-").map(Number)[0] !== Number(self.courType);
+      });
+      for (let i = 0; i < this.sujectArray.length; i++) {
+        this.sujectApis.push(this.sujectArray[i]);
+      }
+      this.$refs.popovers.doClose();
+    },
+    showHandle() {
+      var array = [];
+      for (let i = 0; i < this.sujectApis.length; i++) {
+        if (
+          this.sujectApis[i].split("-").map(Number)[0] === Number(this.courType)
+        ) {
+          array.push(this.sujectApis[i]);
+        }
+      }
+      this.sujectArray = array;
+      if (!this.newSujectOption.length) {
+        this.$message.warning("该业务层次暂无关联科目");
+        this.$refs.popovers.doClose();
+        return;
+      }
+      this.newSujectOption.map((item) => {
+        item.newId = this.courType + "-" + item.id;
+      });
+      this.handleCheckedCitiesChange();
+    },
+    hideHandle() {},
+    getDict() {
+      return new Promise((resolve, reject) => {
+        this.$api.inquireCourseEducationType({ status: 1 }).then((res) => {
+          this.eduTypeOptions = res.rows;
+        });
+        this.$api.inquireCourseProjectType({ status: 1 }).then((res) => {
+          this.projectTypeOptions = res.rows;
+        });
+        this.$api.inquirebusinessList({ status: 1 }).then((res) => {
+          this.courTypeOptions = res.rows;
+          this.newCourTypeOptions = res.rows;
+        });
+        this.$api.inquireCourseSubject({ status: 1 }).then((res) => {
+          res.rows.map((item, index) => {
+            var array = [];
+            item.courseProjectTypes.map((items, indexs) => {
+              array.push(items.id);
+            });
+            item.courseArrays = array;
+          });
+          this.sujectOption = res.rows;
+          resolve();
+        });
+        this.$api.inquireCourseStreaming({ status: 1 }).then((res) => {
+          var arrays = [];
+          var newarrays1 = [];
+          var newarrays2 = [];
+          res.rows.map((item) => {
+            if (item.streamingType === 1) {
+              arrays.push(item);
+            }
+            if (item.streamingType === 2) {
+              newarrays1.push(item);
+            }
+            if (item.streamingType === 3) {
+              newarrays2.push(item);
+            }
+          });
+          this.newLiveUrl = arrays;
+          this.newSteamUrl1 = newarrays1;
+          this.newSteamUrl2 = newarrays2;
+        });
+      });
+    },
+    changeEduType() {
+      if (!(this.courType === undefined || this.courType === "")) {
+        this.courType = "";
+      }
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.eduType) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+    },
+    changecourseType() {
+      this.newCourTypeOptions.map((item, index) => {
+        if (item.id === this.courType) {
+          this.eduType = item.educationId;
+          var array = [];
+          this.sujectOption.map((items, indexs) => {
+            if (items.courseArrays.indexOf(item.projectId) !== -1) {
+              array.push(items);
+            }
+          });
+          this.newSujectOption = array;
+        }
+      });
+      var arrays = [];
+      this.courTypeOptions.map((item) => {
+        if (item.educationId === this.eduType) {
+          arrays.push(item);
+        }
+      });
+      this.newCourTypeOptions = arrays;
+      this.$refs.popovers.doClose();
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.rulesTableSumbit();
+        } else {
+          return false;
+        }
+      });
+    },
+    async rulesTableSumbit() {
+      var dataInfos = {
+        handoutsId: this.$route.query.id,
+        courseHandoutsBusinessAddBos: this.newSujectApis,
+        handoutsName: this.listData.handoutsName,
+        status: this.listData.status,
+        canDownload: this.listData.canDownload,
+      };
+      if (this.fileList.length) {
+        const hasSort = this.fileList.every((item) => {
+          return item.sort >= 0 && item.urlName.length > 0;
+        });
+        if (hasSort) {
+          let array = [];
+          let stop = false; //控制上下文执行
+          for (let i = 0; i < this.fileList.length; i++) {
+            if (this.fileList[i].blob) {
+              array.push(
+                new Promise((resolve, reject) => {
+                  this.$upload
+                    .upload(this.fileList[i].file, 6)
+                    .then((res) => {
+                      this.$set(this.fileList[i], "url", res);
+                      resolve();
+                    })
+                    .catch((err) => {
+                      this.$message.error(`第${i}个文件上传失败`);
+                      reject();
+                    });
+                })
+              );
+            }
+          }
+          await Promise.all(array)
+            .then(() => {
+              stop = false;
+              console.log("成功");
+            })
+            .catch(() => {
+              stop = true;
+              console.log("失败");
+            });
+          if (stop) {
+            return;
+          }
+        } else {
+          this.$message.warning("排序与文件名不允许为空");
+          return;
+        }
+      }
+      dataInfos["fileList"] = this.fileList;
+      this.disabledBtn = true;
+      this.$api
+        .editCourseHandouts(dataInfos)
+        .then((res) => {
+          this.$message.success("修改成功");
+          setTimeout(() => {
+            this.$store
+              .dispatch("tagsView/exitView", this.$route)
+              .then((res) => {
+                this.$router.push({
+                  path: "handoutList",
+                });
+              });
+          }, 500);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "handoutList",
+        });
+      });
+    },
+    closeType(index) {
+      this.sujectApis.splice(index, 1);
+    },
+    getImgFile(e) {
+      var fileArry = [];
+      for (let i = 0; i < e.target.files.length; i++) {
+        fileArry.push(e.target.files[i]);
+      }
+      console.log(fileArry);
+      var self = this;
+      for (let i = 0; i < fileArry.length; i++) {
+        var file = fileArry[i];
+        if (file === undefined) {
+          // self.$set(self.listData, "handoutsUrl", "");
+          return;
+        }
+        if (file.size > 100 * 1024 * 1024) {
+          self.$message.error("pdf文件不得大于100MB");
+          return;
+        }
+        var type = file.name.toLowerCase().split(".").splice(-1);
+        if (type[0] != "pdf") {
+          self.$message.error("上传格式需为:.pdf");
+          // self.$refs.file.value = "";
+          return;
+        }
+        const imgURL = window.URL.createObjectURL(file);
+        self.fileList.push({
+          blob: imgURL,
+          url: "",
+          file: file,
+          status: 1,
+          urlName: file.name,
+          sort: self.backNowMathMax(),
+        });
+      }
+      e.target.value = "";
+    },
+
+    //返回当前数组sort最大值+1,用于自动sort排序
+    backNowMathMax() {
+      if (this.fileList.length) {
+        let list = this.fileList.map((item) => {
+          if (item.sort >= 0) {
+            return Number(item.sort);
+          } else {
+            return 0;
+          }
+        });
+        return Math.max(...list) + 1;
+      } else {
+        return 1;
+      }
+    },
+    //排序
+    sortList() {
+      this.fileList = this.fileList.sort((a, b) => {
+        if (a.sort >= 0 && b.sort >= 0) {
+          return a.sort - b.sort;
+        } else {
+          this.$message.warning("请完善排序号码");
+        }
+      }); //升序
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.boxWidth {
+  width: 700px;
+}
+.numInputs {
+  width: 150px;
+}
+.checkboxSty {
+  max-height: 210px;
+  overflow: auto;
+  display: flex;
+  flex-direction: column;
+}
+.listBoxStys {
+  flex-shrink: 0;
+  padding: 0px 10px;
+  border-radius: 8px;
+  border: 1px solid #eee;
+  margin-right: 10px;
+  margin-bottom: 6px;
+}
+.closeIcons {
+  color: red;
+  cursor: pointer;
+  margin-left: 6px;
+}
+.ach {
+  display: flex;
+  align-items: center;
+  overflow: hidden;
+}
+.clh {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+.handoutList {
+  & > ul {
+    max-height: 500px;
+    overflow: auto;
+    & > li {
+      display: flex;
+      align-items: center;
+      margin-bottom: 6px;
+      a {
+        display: inherit;
+      }
+      img {
+        height: 28px;
+        width: 20px;
+        cursor: pointer;
+        transition: all 0.3s;
+        margin-right: 10px;
+        &:hover {
+          transform: scale(1.05);
+        }
+      }
+      .input_text {
+        height: 28px;
+      }
+    }
+  }
+}
+.primary_btn {
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  background: #ffffff;
+  border: 1px solid #dcdfe6;
+  border-color: #dcdfe6;
+  color: #606266;
+  -webkit-appearance: none;
+  text-align: center;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  outline: none;
+  margin: 0;
+  -webkit-transition: 0.1s;
+  transition: 0.1s;
+  font-weight: 400;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  padding: 12px 20px;
+  font-size: 14px;
+  border-radius: 4px;
+  padding: 7px 15px;
+  font-size: 12px;
+  border-radius: 3px;
+  color: #ffffff;
+  background-color: #1890ff;
+  border-color: #1890ff;
+}
+</style>

+ 170 - 109
src/views/resource/handoutManagement/handoutList/edit/index.vue

@@ -108,49 +108,82 @@
         </el-form-item>
         <el-form-item label="讲义文件">
           <div class="handoutList">
-            <label for="uplose"><span class="primary_btn">添加pdf</span></label>
+            <label @click="submitClickData = {}" for="uplose"
+              ><span
+                class="primary_btn"
+                :style="uploadStatus > 0 ? 'cursor: no-drop' : 'cursor:pointer'"
+                >添加</span
+              ></label
+            >
             <input
               ref="file"
               type="file"
               style="display: none"
               id="uplose"
               @change="getImgFile"
+              :disabled="uploadStatus > 0 ? true : false"
               multiple
             />
             <span style="margin-left: 10px"
-              >注:只能上传PDF文件,且不超过100MB</span
+              >注:只能上传DOCX/XLSX/PDF/ZIP文件</span
             >
-            <ul>
-              <li v-for="(item, index) in fileList" :key="index">
-                <el-input-number
-                  style="width: 60px; margin-right: 10px"
-                  size="mini"
-                  :precision="0"
-                  v-model="item.sort"
-                  :min="1"
-                  :max="127"
-                  label="排序"
-                  :controls="false"
-                  @blur="sortList"
-                ></el-input-number>
-                <a
-                  :href="
-                    item.blob ? item.blob : $methodsTools.splitImgHost(item.url)
-                  "
-                  target="_blank"
-                >
-                  <img src="@/assets/images/pdf@3x.png" alt="" />
-                </a>
-                <input class="input_text" v-model="item.urlName" />
-                <el-button
-                  type="danger"
-                  size="mini"
-                  style="margin-left: 10px"
-                  @click="fileList.splice(index, 1)"
-                  >删除</el-button
+            <!-- <el-input placeholder="输入关键字进行过滤" v-model="filterText">
+            </el-input> -->
+            <el-tree
+              ref="tree"
+              :data="listData.fileList"
+              node-key="fileId"
+              @node-drop="handleDrop"
+              draggable
+              :allow-drop="allowDrop"
+              :allow-drag="allowDrag"
+              :props="defaultProps"
+              :filter-node-method="filterNode"
+            >
+              <span class="custom-tree-node" slot-scope="{ node, data }">
+                <span>{{ node.label }}</span>
+                <span>
+                  <label
+                    style="margin-right: 6px;"
+                    @click.stop="submitClickData = data"
+                    for="uplose1"
+                    v-if="data.type === 2 && data.fileId"
+                    ><span
+                      :style="
+                        uploadStatus > 0 ? 'cursor: no-drop' : 'cursor:pointer'
+                      "
+                      >添加</span
+                    ></label
+                  >
+                  <input
+                    ref="file"
+                    type="file"
+                    style="display: none"
+                    id="uplose1"
+                    @change="getImgFile"
+                    :disabled="uploadStatus > 0 ? true : false"
+                    multiple
+                  />
+                  <el-button
+                    v-if="data.type === 1 && (data.url || data.blob)"
+                    type="text"
+                  >
+                    <a
+                      :href="
+                        data.blob
+                          ? data.blob
+                          : $methodsTools.splitImgHost(data.url)
+                      "
+                      target="_blank"
+                    >
+                      预览</a
+                    ></el-button
+                  ><el-button type="text" @click.stop="delList(node, data)"
+                    >删除</el-button
+                  ></span
                 >
-              </li>
-            </ul>
+              </span>
+            </el-tree>
           </div>
         </el-form-item>
         <el-form-item label="是否可下载" prop="canDownload">
@@ -170,9 +203,10 @@
           <el-button
             size="mini"
             type="primary"
+            :disabled="uploadStatus > 0"
             @click="submit('listData')"
             :loading="disabledBtn"
-            >确定</el-button
+            >{{ uploadStatus > 0 ? "上传中" : "确定" }}</el-button
           >
         </el-form-item>
       </el-form>
@@ -181,10 +215,14 @@
 </template>
 
 <script>
+import fpFile from "@/mixin/fpFile";
 export default {
   name: "HandoutListEdit",
+  mixins: [fpFile],
   data() {
     return {
+      filterText: "",
+      submitClickData: {},
       fileList: [],
       disabledBtn: false,
       isIndeterminate: false,
@@ -207,6 +245,7 @@ export default {
       sujectApis: [], //当前存在的科目
       newSujectApis: [],
       sujectArray: [], //选中的科目
+      uploadStatus: 0,
       //表单验证
       rules: {
         handoutsName: [
@@ -219,6 +258,10 @@ export default {
           { required: true, message: "请选择是否发布", trigger: "change" },
         ],
       },
+      defaultProps: {
+        children: "children",
+        label: "urlName",
+      },
     };
   },
   watch: {
@@ -228,6 +271,9 @@ export default {
         this.changeTypes();
       },
     },
+    filterText(val) {
+      this.$refs.tree.filter(val);
+    },
   },
   async mounted() {
     this.$modal.loading("正在导入数据,请稍后...");
@@ -235,6 +281,45 @@ export default {
     this.search();
   },
   methods: {
+    filterNode(value, data, node) {
+      let parentNode = node.parent; // 父级node
+      let labels = [node.label]; // 当前node的名字
+      let level = 1; // 层级
+      while (level < node.level) {
+        labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字
+        parentNode = parentNode.parent;
+        level++;
+      }
+      return labels.some((d) => d.indexOf(value) !== -1);
+    },
+    delList(node, data) {
+      const parent = node.parent;
+      const children = parent.data.children || parent.data;
+      if (data.fileId) {
+        var index = children.findIndex((d) => d.fileId === data.fileId);
+      } else {
+        var index = children.findIndex((d) => d.md5 === data.md5);
+        this.fileList = this.fileList.filter((d) => d.md5 !== data.md5);
+        this.$api
+          .commondeletefile({ name: data.urlName, fileMd5: data.md5 })
+          .then(() => {});
+      }
+      children.splice(index, 1);
+    },
+    handleDrop(draggingNode, dropNode, dropType, ev) {
+      console.log("tree drop: ", draggingNode, dropNode.label, dropType, ev);
+    },
+    //判断是否允许放置
+    allowDrop(draggingNode, dropNode, type) {
+      if (dropNode.data.type === 1) {
+        return type !== "inner";
+      } else {
+        return true;
+      }
+    },
+    allowDrag(draggingNode) {
+      return true;
+    },
     handleCheckedCitiesChange() {
       let nid = this.newSujectOption.map((item) => {
         return item.newId;
@@ -276,9 +361,11 @@ export default {
     },
     search() {
       this.$api
-        .obtainCourseHandouts(this.$route.query.id)
+        .inquireCourseHandoutsfiledetail({ handoutsId: this.$route.query.id })
         .then((res) => {
-          this.fileList = res.data.fileList || [];
+          if (!res.data.fileList) {
+            res.data.fileList = [];
+          }
           this.listData = res.data;
           if (res.data.courseHandoutsBusinessVo) {
             var arrays = [];
@@ -449,50 +536,13 @@ export default {
         handoutsName: this.listData.handoutsName,
         status: this.listData.status,
         canDownload: this.listData.canDownload,
+        fileList: this.listData.fileList,
       };
-      if (this.fileList.length) {
-        const hasSort = this.fileList.every((item) => {
-          return item.sort >= 0 && item.urlName.length > 0;
-        });
-        if (hasSort) {
-          let array = [];
-          let stop = false; //控制上下文执行
-          for (let i = 0; i < this.fileList.length; i++) {
-            if (this.fileList[i].blob) {
-              array.push(
-                new Promise((resolve, reject) => {
-                  this.$upload
-                    .upload(this.fileList[i].file, 6)
-                    .then((res) => {
-                      this.$set(this.fileList[i], "url", res);
-                      resolve();
-                    })
-                    .catch((err) => {
-                      this.$message.error(`第${i}个文件上传失败`);
-                      reject();
-                    });
-                })
-              );
-            }
-          }
-          await Promise.all(array)
-            .then(() => {
-              stop = false;
-              console.log("成功");
-            })
-            .catch(() => {
-              stop = true;
-              console.log("失败");
-            });
-          if (stop) {
-            return;
-          }
-        } else {
-          this.$message.warning("排序与文件名不允许为空");
-          return;
-        }
-      }
-      dataInfos["fileList"] = this.fileList;
+      // var formdata = new FormData();
+      // formdata.append("param", JSON.stringify(dataInfos));
+      // this.fileList.forEach((i) => {
+      //   formdata.append("files", i);
+      // });
       this.disabledBtn = true;
       this.$api
         .editCourseHandouts(dataInfos)
@@ -522,38 +572,42 @@ export default {
     closeType(index) {
       this.sujectApis.splice(index, 1);
     },
-    getImgFile(e) {
-      var fileArry = [];
-      for (let i = 0; i < e.target.files.length; i++) {
-        fileArry.push(e.target.files[i]);
-      }
-      console.log(fileArry);
-      var self = this;
-      for (let i = 0; i < fileArry.length; i++) {
-        var file = fileArry[i];
-        if (file === undefined) {
-          // self.$set(self.listData, "handoutsUrl", "");
-          return;
-        }
-        if (file.size > 100 * 1024 * 1024) {
-          self.$message.error("pdf文件不得大于100MB");
-          return;
-        }
-        var type = file.name.toLowerCase().split(".").splice(-1);
-        if (type[0] != "pdf") {
-          self.$message.error("上传格式需为:.pdf");
-          // self.$refs.file.value = "";
-          return;
+    async getImgFile(e) {
+      if (e.target.files.length > 0) {
+        this.uploadStatus += e.target.files.length;
+        for (let i = 0; i < e.target.files.length; i++) {
+          var type = e.target.files[i].name.toLowerCase().split(".").splice(-1);
+          if (["docx", "pdf", "zip", "xlsx"].includes(type[0])) {
+            // e.target.files[i].blob = window.URL.createObjectURL(
+            //   e.target.files[i]
+            // );
+            const obj = await this.chunksUpload(e.target.files[i]);
+            if (obj.status) {
+              e.target.files[i].md5 = obj.md5;
+              this.fileList.push(e.target.files[i]);
+              this.uploadStatus--;
+              const newChild = {
+                blob: window.URL.createObjectURL(e.target.files[i]),
+                handoutsId: this.$route.query.id,
+                status: 1,
+                type: type[0] === "zip" ? 2 : 1,
+                urlName: e.target.files[i].name,
+                children: null,
+                md5: obj.md5,
+              };
+              if (!this.submitClickData.urlName) {
+                this.listData.fileList.push(newChild);
+              } else {
+                if (!this.submitClickData.children) {
+                  this.$set(this.submitClickData, "children", []);
+                }
+                this.submitClickData.children.push(newChild);
+              }
+            }
+          } else {
+            this.uploadStatus--;
+          }
         }
-        const imgURL = window.URL.createObjectURL(file);
-        self.fileList.push({
-          blob: imgURL,
-          url: "",
-          file: file,
-          status: 1,
-          urlName: file.name,
-          sort: self.backNowMathMax(),
-        });
       }
       e.target.value = "";
     },
@@ -588,6 +642,13 @@ export default {
 </script>
 
 <style lang="less" scoped>
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding-right: 8px;
+}
 .boxWidth {
   width: 700px;
 }

+ 26 - 4
src/views/resource/handoutManagement/handoutList/index.vue

@@ -16,10 +16,17 @@
       @editInfo="editInfo"
     >
       <template slot="btn" slot-scope="props">
-        <el-button type="text" @click="addClick(props.scope.row, 0)"
+        <el-button
+          type="text"
+          @click="addClick(props.scope.row, 0)"
           >修改</el-button
         >
-        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+        <el-button
+          type="text"
+          :disabled="props.scope.row['updateStatus'] === 0"
+          @click="del(props.scope.row)"
+          >删除</el-button
+        >
       </template>
     </table-list>
     <pagination
@@ -114,7 +121,6 @@ export default {
           label: "讲义标题",
           prop: "handoutsName",
           hidden: true,
-          scope: "editInfo",
         },
         {
           label: "适用业务层级",
@@ -139,6 +145,23 @@ export default {
             },
           ],
         },
+        {
+          label: "状态",
+          prop: "updateStatus",
+          hidden: true,
+          scope: "isOptions",
+          width: "120px",
+          options: [
+            {
+              label: "正常",
+              value: 1,
+            },
+            {
+              label: "修改中",
+              value: 0,
+            },
+          ],
+        },
         {
           label: "发布状态",
           prop: "status",
@@ -350,4 +373,3 @@ export default {
   }
 }
 </style>
-

+ 140 - 166
src/views/resource/videoManagement/courseManagement/chapterContent/index.vue

@@ -48,16 +48,7 @@
             关联试卷
           </el-button>
           <el-button
-            v-if="data.type === 2 && getShowStatus(data)"
-            type="text"
-            size="mini"
-            style="color: orange"
-            @click.stop="preview(node, data)"
-          >
-            预览
-          </el-button>
-          <el-button
-            v-if="data.type === 3"
+            v-if="getShowStatus(data) || data.type === 3"
             type="text"
             size="mini"
             style="color: orange"
@@ -211,13 +202,12 @@
       </div>
       <div>
         <div><el-button @click="openExamBoxs">选择题卷</el-button></div>
-        <div>
-          <span>{{ goodsName }}</span>
+        <div v-for="(item, index) in activeArray" :key="index">
+          <span>{{ item.examName }}</span>
           <el-button
-            v-if="goodsName && templateRadio"
             type="text"
             style="margin-left: 10px"
-            @click="delExam"
+            @click="activeArray.splice(index, 1)"
             >删除</el-button
           >
         </div>
@@ -285,7 +275,7 @@
           <img src="@/assets/images/Close@2x.png" alt="" @click="closePZ" />
         </div>
       </div>
-      <div>
+      <div v-if="dialogVisiblePZDown">
         <search-box-new
           ref="searchBox"
           :formData="formData6"
@@ -294,6 +284,8 @@
           @init="init6"
         />
         <el-table
+          ref="tableExam"
+          row-key="examId"
           :data="tableDataExam"
           border
           :header-cell-style="{
@@ -301,18 +293,42 @@
             padding: '8px',
             color: '#333',
           }"
+          @selection-change="selectionChangeExam"
         >
-          <el-table-column label="" width="45" align="center">
+          <el-table-column
+            label=""
+            width="45"
+            align="center"
+            v-if="ActiveExamType === 3"
+          >
             <template scope="scope">
-              <el-radio
+              <!-- <el-radio
                 class="radioTables"
                 :label="scope.row.examId"
-                v-model="templateRadioLS"
+                v-model="nowActiveCheckObj.examId"
                 @change.native="getTemplateRow(scope.$index, scope.row)"
                 >{{ "" }}</el-radio
+              > -->
+              <div
+                class="radioTables"
+                @click="getTemplateRow(scope.$index, scope.row)"
               >
+                <div
+                  class="activeRadio"
+                  v-if="scope.row.examId === nowActiveCheckObj.examId"
+                ></div>
+              </div>
             </template>
           </el-table-column>
+          <el-table-column
+            type="selection"
+            width="55"
+            align="center"
+            reserve-selection
+            :selectable="checkboxExam"
+            v-else
+          >
+          </el-table-column>
           <template v-for="(item, index) in tableListExam">
             <el-table-column
               v-if="item.scope !== 'inputs'"
@@ -503,6 +519,10 @@ export default {
           return data.hasChildren ? false : true;
         },
       },
+      activeArray: [],
+      nowActiveCheck: [], //当前选中复选框
+      nowActiveCheckObj: {}, //当前选中单选框
+      ActiveExamType: null, //当前关联类型
     };
   },
   computed: {
@@ -512,35 +532,15 @@ export default {
     getShowStatus: function () {
       return function (item) {
         var ints = item.id.split("-").map(Number);
-        var arr = [];
         if (ints[0] === 1) {
-          arr.push(ints[1]);
-          if (ints[2]) {
-            arr.push(ints[2]);
-          } else {
-            arr.push(0);
-          }
-          if (ints[3]) {
-            arr.push(ints[3]);
-          } else {
-            arr.push(0);
-          }
+          var atys = `${ints[1]}-${ints[2] || 0}-${ints[3] || 0}`;
         }
         if (ints[0] === 2) {
-          arr.push(0);
-          arr.push(ints[1]);
-          if (ints[2]) {
-            arr.push(ints[2]);
-          } else {
-            arr.push(0);
-          }
+          var atys = `0-${ints[1]}-${ints[2] || 0}`;
         }
         if (ints[0] === 3) {
-          arr.push(0);
-          arr.push(0);
-          arr.push(ints[1]);
+          var atys = `0-0-${ints[1]}`;
         }
-        var atys = arr.join("-");
         var setTs = this.menuExamList.some((items) => {
           return items.onlyId == atys;
         });
@@ -560,47 +560,24 @@ export default {
     this.search();
   },
   methods: {
+    selectionChangeExam(a) {
+      this.nowActiveCheck = a;
+    },
     preview(node, data) {
-      if (data.type === 2) {
+      if (data.type === 1||data.type === 2) {
         var ints = data.id.split("-").map(Number);
-        var arr = [];
         if (ints[0] === 1) {
-          arr.push(ints[1]);
-          if (ints[2]) {
-            arr.push(ints[2]);
-          } else {
-            arr.push(0);
-          }
-          if (ints[3]) {
-            arr.push(ints[3]);
-          } else {
-            arr.push(0);
-          }
+          var atys = `${ints[1]}-${ints[2] || 0}-${ints[3] || 0}`;
         }
         if (ints[0] === 2) {
-          arr.push(0);
-          arr.push(ints[1]);
-          if (ints[2]) {
-            arr.push(ints[2]);
-          } else {
-            arr.push(0);
-          }
+          var atys = `0-${ints[1]}-${ints[2] || 0}`;
         }
         if (ints[0] === 3) {
-          arr.push(0);
-          arr.push(0);
-          arr.push(ints[1]);
+          var atys = `0-0-${ints[1]}`;
         }
-        var atys = arr.join("-");
-        var setTs = this.menuExamList.some((items) => {
-          return items.onlyId == atys;
-        });
-        if (setTs) {
-          this.menuExamList.map((items) => {
-            if (items.onlyId == atys) {
-              this.$refs.testPaperPreview.openBox(1, items.examId);
-            }
-          });
+        if (this.menuExamList.some((items) => items.onlyId == atys)) {
+          const array = this.menuExamList.filter(item => item.onlyId == atys)
+          this.$refs.testPaperPreview.openBox(1, array);
         }
       }
       if (data.type === 3) {
@@ -629,111 +606,86 @@ export default {
     },
     openExamBoxs() {
       this.getSJ(2);
-      this.templateRadioLS = this.templateRadio;
+      if (this.ActiveExamType === 3) {
+        if (this.activeArray.length === 0) {
+          this.nowActiveCheckObj = {};
+        } else {
+          this.nowActiveCheckObj = JSON.parse(
+            JSON.stringify(this.activeArray[0])
+          );
+        }
+      } else {
+        this.nowActiveCheck = [];
+      }
       this.dialogVisiblePZDown = true;
+      this.$nextTick(() => {
+        this.$refs.tableExam.clearSelection();
+      });
     },
     //单选触发
     getTemplateRow(index, row) {
-      this.templateRadioLS = row.examId;
-      this.goodsNameLS = row.examName;
+      this.nowActiveCheckObj = row;
+      console.log(row.examId, this.nowActiveCheckObj.examId);
     },
     //2确定变化选项
     submitPZ() {
-      this.templateRadio = this.templateRadioLS;
-      this.goodsName = this.goodsNameLS;
+      if (this.ActiveExamType !== 3) {
+        this.activeArray.push(...this.nowActiveCheck);
+      } else {
+        this.activeArray = [this.nowActiveCheckObj];
+      }
       this.dialogVisiblePZDown = false;
     },
     closePZ() {
       this.dialogVisiblePZDown = false;
     },
-    //删除题卷
-    delExam() {
-      this.templateRadio = "";
-      this.goodsName = "";
-    },
     //1确定关联试卷弹窗
     submitExam() {
-      if (!this.templateRadio && !this.goodsName) {
-        console.log(this.menuExamList, "this.menuExamList111111");
-        this.menuExamList = this.menuExamList.filter((item) => {
-          return item.onlyId != this.onlyId;
-        });
-      } else {
-        console.log(this.menuExamList, "this.menuExamList222222");
-        var arrays = {};
+      if (this.ActiveExamType === 3 && this.activeArray.length > 1) {
+        this.$message.error("只允许关联一张试卷");
+        return;
+      }
+      this.menuExamList = this.menuExamList.filter(
+        (item) => item.onlyId != this.onlyId
+      );
+      if (this.activeArray.length !== 0) {
         let ast = this.onlyId.split("-").map(Number);
-        arrays = {
-          onlyId: this.onlyId,
-          courseId: Number(this.$route.query.id),
-          moduleId: ast[0],
-          chapterId: ast[1],
-          sectionId: ast[2],
-          examId: this.templateRadio,
-          examName: this.goodsName,
-        };
-        var stu = this.menuExamList.some((item) => {
-          return item.onlyId == this.onlyId;
+        var newList = this.activeArray.map((item) => {
+          return {
+            onlyId: this.onlyId,
+            courseId: Number(this.$route.query.id),
+            moduleId: ast[0],
+            chapterId: ast[1],
+            sectionId: ast[2],
+            examId: item.examId,
+            examName: item.examName,
+          };
         });
-        if (stu) {
-          for (let i = 0; i < this.menuExamList.length; i++) {
-            if (this.menuExamList[i].onlyId == this.onlyId) {
-              this.menuExamList[i] = arrays;
-            }
-          }
-        } else {
-          this.menuExamList.push(arrays);
-        }
+        this.menuExamList.push(...newList);
       }
       this.aboutExamStatus = false;
     },
     //开启关联试卷盒子
     openExamBox(node, item) {
-      console.log(this.tableDataInfos, "this.tableDataInfos");
       var ints = item.id.split("-").map(Number);
-      var arr = [];
       if (ints[0] === 1) {
-        arr.push(ints[1]);
-        if (ints[2]) {
-          arr.push(ints[2]);
-        } else {
-          arr.push(0);
-        }
-        if (ints[3]) {
-          arr.push(ints[3]);
-        } else {
-          arr.push(0);
-        }
+        var atys = `${ints[1]}-${ints[2] || 0}-${ints[3] || 0}`;
       }
       if (ints[0] === 2) {
-        arr.push(0);
-        arr.push(ints[1]);
-        if (ints[2]) {
-          arr.push(ints[2]);
-        } else {
-          arr.push(0);
-        }
+        var atys = `0-${ints[1]}-${ints[2] || 0}`;
       }
       if (ints[0] === 3) {
-        arr.push(0);
-        arr.push(0);
-        arr.push(ints[1]);
+        var atys = `0-0-${ints[1]}`;
       }
-      var atys = arr.join("-");
-      var setTs = this.menuExamList.some((items) => {
-        return items.onlyId == atys;
-      });
-      if (setTs) {
-        this.menuExamList.map((items) => {
-          if (items.onlyId == atys) {
-            this.templateRadio = items.examId;
-            this.goodsName = items.examName;
-          }
-        });
+      if (this.menuExamList.some((i) => i.onlyId == atys)) {
+        this.activeArray = this.menuExamList.filter(
+          (items) => items.onlyId == atys
+        );
       } else {
-        this.templateRadio = "";
-        this.goodsName = "";
+        this.activeArray = [];
       }
       this.onlyId = atys;
+      this.ActiveExamType = item.type;
       this.aboutExamStatus = true;
     },
     //关闭关联试卷盒子
@@ -757,23 +709,9 @@ export default {
         .inquireCourseListSmenuexam({ courseId: this.$route.query.id })
         .then((res) => {
           res.rows.forEach((item) => {
-            var lets = [];
-            if (!item.moduleId) {
-              lets.push(0);
-            } else {
-              lets.push(item.moduleId);
-            }
-            if (!item.chapterId) {
-              lets.push(0);
-            } else {
-              lets.push(item.chapterId);
-            }
-            if (!item.sectionId) {
-              lets.push(0);
-            } else {
-              lets.push(item.sectionId);
-            }
-            item.onlyId = lets.join("-");
+            item.onlyId = `${item.moduleId || 0}-${item.chapterId || 0}-${
+              item.sectionId || 0
+            }`;
           });
           this.menuExamList = res.rows;
         });
@@ -1059,6 +997,12 @@ export default {
         return true;
       }
     },
+    checkboxExam(row, index) {
+      return this.activeArray.findIndex((item) => item.examId == row.examId) ===
+        -1
+        ? true
+        : false;
+    },
     submitForm() {
       if (this.activeLists.length === 0) {
         this.dialogVisible = false;
@@ -1293,6 +1237,36 @@ export default {
 </script>
 
 <style lang="less" scoped>
+.radioTables {
+  border-radius: 50%;
+  width: 18px;
+  height: 18px;
+  border: 1px solid #eee;
+  background-color: #fff;
+  cursor: pointer;
+  position: relative;
+  & > .activeRadio {
+    position: absolute;
+    transition: all 0.3s;
+    left: 50%;
+    top: 50%;
+    transform: translateX(-50%) translateY(-50%);
+    width: 12px;
+    height: 12px;
+    border-radius: 50%;
+    overflow: hidden;
+    background-color: rgb(24, 144, 255);
+    animation: radios 0.3s;
+  }
+}
+@keyframes radios {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
 .fatherSty {
   background-color: #eee;
   padding: 10px;
@@ -1368,4 +1342,4 @@ export default {
     }
   }
 }
-</style>
+</style>

+ 56 - 22
src/views/secondJian/completionList/index.vue

@@ -1,5 +1,12 @@
 <template>
   <div id="">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="search(2)"
+    />
     <table-list
       :tableSets="tableSet"
       :tableData="tableData"
@@ -23,11 +30,12 @@
 </template>
 
 <script>
+import searchBoxNew from "@/components/searchBoxNew";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 export default {
   name: "",
-  components: { tableList, pagination },
+  components: { searchBoxNew, tableList, pagination },
   data() {
     return {
       size: "small",
@@ -45,7 +53,19 @@ export default {
           title: "未定义",
         },
       },
+      formList: [
+        {
+          placeholder: "学员姓名",
+          prop: "searchKey",
+        },
+        {
+          placeholder: "身份证",
+          prop: "idCard",
+        },
+      ],
       formData: {
+        searchKey: "",
+        idCard: "",
         profileStatus: "",
         periodStatus: 1,
         status: 1,
@@ -201,27 +221,27 @@ export default {
       //       this.$message.warning(res.msg + "正在操作");
       //       return;
       //     } else {
-            let data = {
-              userId: v.userId,
-              realName: v.realName,
-              id: v.gradeId,
-              className: v.className,
-              goodsId: v.goodsId,
-              goodsName: v.goodsName,
-              keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
-            };
-            this.checkSession(data)
-              .then(() => {
-                //学员详情
-                this.$router.push({
-                  name: "ClassHoursReviews",
-                });
-              })
-              .catch(() => {
-                this.$message.error("存在异常,请联系开发人员");
-              });
-        //   }
-        // });
+      let data = {
+        userId: v.userId,
+        realName: v.realName,
+        id: v.gradeId,
+        className: v.className,
+        goodsId: v.goodsId,
+        goodsName: v.goodsName,
+        keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
+      };
+      this.checkSession(data)
+        .then(() => {
+          //学员详情
+          this.$router.push({
+            name: "ClassHoursReviews",
+          });
+        })
+        .catch(() => {
+          this.$message.error("存在异常,请联系开发人员");
+        });
+      //   }
+      // });
     },
     checkSession(row) {
       return new Promise((resolve, reject) => {
@@ -260,6 +280,20 @@ export default {
       if (int === 1) {
         this.formData.pageNum = 1;
       }
+      if (int === 2) {
+        this.formData = {
+          educationId: this.formData.educationId,
+          projectId: this.formData.projectId,
+          businessId: this.formData.businessId,
+          searchKey: "",
+          idCard: "",
+          profileStatus: "",
+          periodStatus: 1,
+          status: 1,
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
       var data = JSON.parse(JSON.stringify(this.formData));
       this.$api
         .inquireGradegradelistUserPeriods(data)

+ 16 - 2
src/views/secondJian/courseList/index.vue

@@ -9,6 +9,11 @@
       <template slot="btn" slot-scope="props">
         <el-button type="text" @click="msgInfo(props.scope.row)"
           >课程内容详情</el-button
+        ><el-button
+          type="text"
+          @click="exportBtn(props.scope.row)"
+          style="margin-left: 0px"
+          >导出课程结构</el-button
         >
       </template>
     </table-list>
@@ -176,7 +181,7 @@ export default {
         status: 1,
         pageSize: 10,
         pageNum: 1,
-        commitPeriodStatus:1
+        commitPeriodStatus: 1,
       },
       // 表单
       tableSet: [
@@ -227,7 +232,6 @@ export default {
           scope: "studentServicePeriod",
           hidden: false,
         },
-        
       ],
       tableData: [], //表单数据
       total: 0, //一共多少条
@@ -276,6 +280,16 @@ export default {
       }
       return ast;
     },
+    /**
+     * 导出商品的课程结构
+     */
+    exportBtn(item) {
+      this.$api
+        .inquireGradegradeexportGoodsMenuExcel({ goodsId: item.goodsId })
+        .then((res) => {
+          this.$methodsTools.exportData(res.msg);
+        });
+    },
     /**
      * 关闭详情触发事件
      */

+ 56 - 22
src/views/secondZao/completionList/index.vue

@@ -1,5 +1,12 @@
 <template>
   <div id="">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="search(2)"
+    />
     <table-list
       :tableSets="tableSet"
       :tableData="tableData"
@@ -23,11 +30,12 @@
 </template>
 
 <script>
+import searchBoxNew from "@/components/searchBoxNew";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 export default {
   name: "",
-  components: { tableList, pagination },
+  components: { searchBoxNew, tableList, pagination },
   data() {
     return {
       size: "small",
@@ -45,7 +53,19 @@ export default {
           title: "未定义",
         },
       },
+      formList: [
+        {
+          placeholder: "学员姓名",
+          prop: "searchKey",
+        },
+        {
+          placeholder: "身份证",
+          prop: "idCard",
+        },
+      ],
       formData: {
+        searchKey: "",
+        idCard: "",
         profileStatus: "",
         periodStatus: 1,
         status: 1,
@@ -201,27 +221,27 @@ export default {
       //       this.$message.warning(res.msg + "正在操作");
       //       return;
       //     } else {
-            let data = {
-              userId: v.userId,
-              realName: v.realName,
-              id: v.gradeId,
-              className: v.className,
-              goodsId: v.goodsId,
-              goodsName: v.goodsName,
-              keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
-            };
-            this.checkSession(data)
-              .then(() => {
-                //学员详情
-                this.$router.push({
-                  name: "ClassHoursReviews",
-                });
-              })
-              .catch(() => {
-                this.$message.error("存在异常,请联系开发人员");
-              });
-        //   }
-        // });
+      let data = {
+        userId: v.userId,
+        realName: v.realName,
+        id: v.gradeId,
+        className: v.className,
+        goodsId: v.goodsId,
+        goodsName: v.goodsName,
+        keyId: `${v.userId}-${v.goodsId}-${v.gradeId}`,
+      };
+      this.checkSession(data)
+        .then(() => {
+          //学员详情
+          this.$router.push({
+            name: "ClassHoursReviews",
+          });
+        })
+        .catch(() => {
+          this.$message.error("存在异常,请联系开发人员");
+        });
+      //   }
+      // });
     },
     checkSession(row) {
       return new Promise((resolve, reject) => {
@@ -260,6 +280,20 @@ export default {
       if (int === 1) {
         this.formData.pageNum = 1;
       }
+      if (int === 2) {
+        this.formData = {
+          educationId: this.formData.educationId,
+          projectId: this.formData.projectId,
+          businessId: this.formData.businessId,
+          searchKey: "",
+          idCard: "",
+          profileStatus: "",
+          periodStatus: 1,
+          status: 1,
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
       var data = JSON.parse(JSON.stringify(this.formData));
       this.$api
         .inquireGradegradelistUserPeriods(data)

+ 15 - 0
src/views/secondZao/courseList/index.vue

@@ -9,6 +9,11 @@
       <template slot="btn" slot-scope="props">
         <el-button type="text" @click="msgInfo(props.scope.row)"
           >课程内容详情</el-button
+        ><el-button
+          type="text"
+          @click="exportBtn(props.scope.row)"
+          style="margin-left: 0px"
+          >导出课程结构</el-button
         >
       </template>
     </table-list>
@@ -275,6 +280,16 @@ export default {
       }
       return ast;
     },
+    /**
+     * 导出商品的课程结构
+     */
+    exportBtn(item) {
+      this.$api
+        .inquireGradegradeexportGoodsMenuExcel({ goodsId: item.goodsId })
+        .then((res) => {
+          this.$methodsTools.exportData(res.msg);
+        });
+    },
     /**
      * 关闭详情触发事件
      */