Tang il y a 2 ans
Parent
commit
7c5cd88a38

+ 168 - 18
package-lock.json

@@ -136,6 +136,16 @@
       "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==",
       "dev": true
     },
+    "@vue-office/excel": {
+      "version": "0.2.10",
+      "resolved": "https://registry.npmjs.org/@vue-office/excel/-/excel-0.2.10.tgz",
+      "integrity": "sha512-XuCkdl1+aRuF64U+cwhgizXciiR0IY3RkxCaaEGTmtbZu/ye2RAMUAgIxcf5/0/RC6ZJ+2wU5n+zryxNRjEwlQ=="
+    },
+    "@vue/composition-api": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/@vue/composition-api/-/composition-api-1.7.1.tgz",
+      "integrity": "sha512-xDWoEtxGXhH9Ku3ROYX/rzhcpt4v31hpPU5zF3UeVC/qxA3dChmqU8zvTUYoKh3j7rzpNsoFOwqsWG7XPMlaFA=="
+    },
     "abbrev": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -175,6 +185,11 @@
         }
       }
     },
+    "adler-32": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
+    },
     "agent-base": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -1858,6 +1873,15 @@
         "lazy-cache": "^1.0.3"
       }
     },
+    "cfb": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
+      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+      "requires": {
+        "adler-32": "~1.3.0",
+        "crc-32": "~1.2.0"
+      }
+    },
     "chalk": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2122,6 +2146,11 @@
       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
       "dev": true
     },
+    "codepage": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
+      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA=="
+    },
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -2388,8 +2417,7 @@
     "core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
-      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-      "dev": true
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
     },
     "cosmiconfig": {
       "version": "5.2.1",
@@ -2403,6 +2431,11 @@
         "parse-json": "^4.0.0"
       }
     },
+    "crc-32": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
+      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
+    },
     "create-ecdh": {
       "version": "4.0.4",
       "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
@@ -2448,6 +2481,58 @@
         "sha.js": "^2.4.8"
       }
     },
+    "cross-env": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+      "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^7.0.1"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
     "cross-spawn": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@@ -3595,6 +3680,14 @@
         "buffer-indexof": "^1.0.0"
       }
     },
+    "docx-preview": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/docx-preview/-/docx-preview-0.1.15.tgz",
+      "integrity": "sha512-qeYNwA+HF0e+GLxH/yltGdaBVQHoQrscfCwR2p7fRGCMjPBohdd36L7xDi1wdErS3ZnV/uh4kx5+tXOXgzq/dQ==",
+      "requires": {
+        "jszip": ">=3.0.0"
+      }
+    },
     "dom-converter": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -4523,6 +4616,11 @@
       "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
       "dev": true
     },
+    "frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
+    },
     "fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -5368,6 +5466,11 @@
       "resolved": "https://registry.npmjs.org/image-conversion/-/image-conversion-2.1.1.tgz",
       "integrity": "sha512-hnMOmP7q2jxA+52FZ+wHNhg3fdFRlgfngsQH2JQHEQkafY7tj/8F15e6Rv/RxDegc872jvyaRHwMbkTZK1Cjbg=="
     },
+    "immediate": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+    },
     "import-cwd": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
@@ -5446,8 +5549,7 @@
     "inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
     "internal-ip": {
       "version": "1.2.0",
@@ -5832,8 +5934,7 @@
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
     "isexe": {
       "version": "2.0.0",
@@ -5951,6 +6052,17 @@
         "verror": "1.10.0"
       }
     },
+    "jszip": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+      "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+      "requires": {
+        "lie": "~3.3.0",
+        "pako": "~1.0.2",
+        "readable-stream": "~2.3.6",
+        "setimmediate": "^1.0.5"
+      }
+    },
     "killable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -5988,6 +6100,14 @@
         "invert-kv": "^1.0.0"
       }
     },
+    "lie": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+      "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+      "requires": {
+        "immediate": "~3.0.5"
+      }
+    },
     "lines-and-columns": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -7760,8 +7880,7 @@
     "pako": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
-      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
-      "dev": true
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
     },
     "parallel-transform": {
       "version": "1.2.0",
@@ -10355,8 +10474,7 @@
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "dev": true
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
     "promise-inflight": {
       "version": "1.0.1",
@@ -10673,7 +10791,6 @@
       "version": "2.3.7",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
       "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-      "dev": true,
       "requires": {
         "core-util-is": "~1.0.0",
         "inherits": "~2.0.3",
@@ -11034,8 +11151,7 @@
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
     },
     "safe-regex": {
       "version": "1.1.0",
@@ -11406,8 +11522,7 @@
     "setimmediate": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
-      "dev": true
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
     },
     "setprototypeof": {
       "version": "1.2.0",
@@ -11885,6 +12000,14 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
+    "ssf": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
+      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+      "requires": {
+        "frac": "~1.1.2"
+      }
+    },
     "sshpk": {
       "version": "1.17.0",
       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
@@ -12117,7 +12240,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
       "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
       "requires": {
         "safe-buffer": "~5.1.0"
       }
@@ -12853,8 +12975,7 @@
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "dev": true
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
     },
     "util.promisify": {
       "version": "1.0.1",
@@ -12986,6 +13107,11 @@
         }
       }
     },
+    "vue-demi": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
+      "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg=="
+    },
     "vue-esign": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/vue-esign/-/vue-esign-1.1.0.tgz",
@@ -13896,6 +14022,16 @@
       "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
       "dev": true
     },
+    "wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
+    },
+    "word": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
+      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA=="
+    },
     "wordwrap": {
       "version": "0.0.2",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
@@ -14000,6 +14136,20 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "xlsx": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+      "requires": {
+        "adler-32": "~1.3.0",
+        "cfb": "~1.2.1",
+        "codepage": "~1.15.0",
+        "crc-32": "~1.2.1",
+        "ssf": "~0.11.2",
+        "wmf": "~1.0.1",
+        "word": "~0.3.0"
+      }
+    },
     "xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

+ 6 - 1
package.json

@@ -16,7 +16,10 @@
     "build:zz": "cross-env NODE_ENV=production ENV_ID=zz node build/build.js"
   },
   "dependencies": {
+    "@vue-office/excel": "^0.2.10",
+    "@vue/composition-api": "^1.7.1",
     "axios": "^0.26.1",
+    "docx-preview": "^0.1.15",
     "element-ui": "^2.15.6",
     "image-conversion": "^2.1.1",
     "js-base64": "^3.7.2",
@@ -27,10 +30,12 @@
     "v-distpicker": "^1.2.13",
     "vue": "^2.5.2",
     "vue-awesome-swiper": "^3.1.3",
+    "vue-demi": "^0.14.0",
     "vue-esign": "^1.1.0",
     "vue-pdf": "^4.3.0",
     "vue-router": "^3.0.1",
-    "vuex": "^3.6.2"
+    "vuex": "^3.6.2",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "autoprefixer": "^7.1.2",

+ 21 - 0
src/apis/course.js

@@ -28,6 +28,20 @@ export default {
 			params: data
 		})
 	},
+	
+	/**
+	 * 
+	 * @param {*} data 
+	 * @returns 
+	 * 检查二建二造用户是否学完必修
+	 */
+	 goodsGradeCheckFinishRequiredCourse(data) {
+		return request({
+			url: '/grade/grade/checkFinishRequiredCourse',
+			method: 'get',
+			params: data
+		})
+	},
 	/**
 	  * 
 	  * @param {*} data 
@@ -110,6 +124,13 @@ export default {
 			method: 'get'
 		})
 	},
+	courseHandoutsdetail(data) {
+		return request({
+			url: '/course/handouts/file/detail',
+			method: 'get',
+			params: data
+		})
+	},
 
 	reMenuList(data) {
 		return request({

+ 8 - 1
src/apis/user.js

@@ -269,7 +269,14 @@ export default {
 			data: data
 		})
 	},
-
+	//file-文件流
+	commonreturnStream(data) {
+		return request({
+			url: '/app/common/returnStream',
+			method: 'post',
+			data: data
+		})
+	},
   studyRecord(data) {
 		return request({
 			url: '/study/record',

+ 765 - 0
src/assets/css/xlsx.css

@@ -0,0 +1,765 @@
+body {
+  margin: 0;
+}
+.x-spreadsheet {
+  font-size: 13px;
+  line-height: normal;
+  user-select: none;
+  -moz-user-select: none;
+  font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
+  box-sizing: content-box;
+  background: #fff;
+  -webkit-font-smoothing: antialiased;
+}
+.x-spreadsheet textarea {
+  font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
+}
+.x-spreadsheet-sheet {
+  position: relative;
+  overflow: hidden;
+}
+.x-spreadsheet-table {
+  vertical-align: bottom;
+}
+.x-spreadsheet-tooltip {
+  font-family: inherit;
+  position: absolute;
+  padding: 5px 10px;
+  color: #fff;
+  border-radius: 1px;
+  background: #000000;
+  font-size: 12px;
+  z-index: 201;
+}
+.x-spreadsheet-tooltip:before {
+  pointer-events: none;
+  position: absolute;
+  left: calc(50% - 4px);
+  top: -4px;
+  content: "";
+  width: 8px;
+  height: 8px;
+  background: inherit;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  z-index: 1;
+  box-shadow: 1px 1px 3px -1px rgba(0, 0, 0, 0.3);
+}
+.x-spreadsheet-color-palette {
+  padding: 5px;
+}
+.x-spreadsheet-color-palette table {
+  margin: 0;
+  padding: 0;
+  border-collapse: separate;
+  border-spacing: 2;
+  background: #fff;
+}
+.x-spreadsheet-color-palette table td {
+  margin: 0;
+  cursor: pointer;
+  border: 1px solid transparent;
+}
+.x-spreadsheet-color-palette table td:hover {
+  border-color: #ddd;
+}
+.x-spreadsheet-color-palette table td .x-spreadsheet-color-palette-cell {
+  width: 16px;
+  height: 16px;
+}
+.x-spreadsheet-border-palette {
+  padding: 6px;
+}
+.x-spreadsheet-border-palette table {
+  margin: 0;
+  padding: 0;
+  border-collapse: separate;
+  border-spacing: 0;
+  background: #fff;
+  table-layout: fixed;
+}
+.x-spreadsheet-border-palette table td {
+  margin: 0;
+}
+.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left {
+  border-right: 1px solid #eee;
+  padding-right: 6px;
+}
+.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell {
+  width: 30px;
+  height: 30px;
+  cursor: pointer;
+  text-align: center;
+}
+.x-spreadsheet-border-palette .x-spreadsheet-border-palette-left .x-spreadsheet-border-palette-cell:hover {
+  background-color: #eee;
+}
+.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right {
+  padding-left: 6px;
+}
+.x-spreadsheet-border-palette .x-spreadsheet-border-palette-right .x-spreadsheet-line-type {
+  position: relative;
+  left: 0;
+  top: -3px;
+}
+.x-spreadsheet-dropdown {
+  position: relative;
+}
+.x-spreadsheet-dropdown .x-spreadsheet-dropdown-content {
+  position: absolute;
+  z-index: 200;
+  background: #fff;
+  box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
+}
+.x-spreadsheet-dropdown.bottom-left .x-spreadsheet-dropdown-content {
+  top: calc(100% + 5px);
+  left: 0;
+}
+.x-spreadsheet-dropdown.bottom-right .x-spreadsheet-dropdown-content {
+  top: calc(100% + 5px);
+  right: 0;
+}
+.x-spreadsheet-dropdown.top-left .x-spreadsheet-dropdown-content {
+  bottom: calc(100% + 5px);
+  left: 0;
+}
+.x-spreadsheet-dropdown.top-right .x-spreadsheet-dropdown-content {
+  bottom: calc(100% + 5px);
+  right: 0;
+}
+.x-spreadsheet-dropdown .x-spreadsheet-dropdown-title {
+  padding: 0 5px;
+  display: inline-block;
+}
+/* resizer **/
+.x-spreadsheet-resizer {
+  position: absolute;
+  z-index: 11;
+}
+.x-spreadsheet-resizer .x-spreadsheet-resizer-hover {
+  background-color: rgba(75, 137, 255, 0.25);
+}
+.x-spreadsheet-resizer .x-spreadsheet-resizer-line {
+  position: absolute;
+}
+.x-spreadsheet-resizer.horizontal {
+  cursor: row-resize;
+}
+.x-spreadsheet-resizer.horizontal .x-spreadsheet-resizer-line {
+  border-bottom: 2px dashed #4b89ff;
+  left: 0;
+  bottom: 0;
+}
+.x-spreadsheet-resizer.vertical {
+  cursor: col-resize;
+}
+.x-spreadsheet-resizer.vertical .x-spreadsheet-resizer-line {
+  border-right: 2px dashed #4b89ff;
+  top: 0;
+  right: 0;
+}
+/* scrollbar */
+.x-spreadsheet-scrollbar {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  background-color: #f4f5f8;
+  opacity: 0.9;
+  z-index: 12;
+}
+.x-spreadsheet-scrollbar.horizontal {
+  right: 15px;
+  overflow-x: scroll;
+  overflow-y: hidden;
+}
+.x-spreadsheet-scrollbar.horizontal > div {
+  height: 1px;
+  background: #ddd;
+}
+.x-spreadsheet-scrollbar.vertical {
+  bottom: 15px;
+  overflow-x: hidden;
+  overflow-y: scroll;
+}
+.x-spreadsheet-scrollbar.vertical > div {
+  width: 1px;
+  background: #ddd;
+}
+/* @{css-prefix}-overlayer */
+.x-spreadsheet-overlayer {
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: 10;
+}
+.x-spreadsheet-overlayer .x-spreadsheet-overlayer-content {
+  position: absolute;
+  overflow: hidden;
+  pointer-events: none;
+  width: 100%;
+  height: 100%;
+}
+.x-spreadsheet-editor,
+.x-spreadsheet-selector {
+  box-sizing: content-box;
+  position: absolute;
+  overflow: hidden;
+  pointer-events: none;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+/* @{css-prefix}-selector */
+.x-spreadsheet-selector .hide-input {
+  position: absolute;
+  z-index: 0;
+}
+.x-spreadsheet-selector .hide-input input {
+  padding: 0;
+  width: 0;
+  border: none!important;
+}
+.x-spreadsheet-selector .x-spreadsheet-selector-area {
+  position: absolute;
+  border: 2px solid #4b89ff;
+  background: rgba(75, 137, 255, 0.1);
+  z-index: 5;
+}
+.x-spreadsheet-selector .x-spreadsheet-selector-clipboard,
+.x-spreadsheet-selector .x-spreadsheet-selector-autofill {
+  position: absolute;
+  background: transparent;
+  z-index: 100;
+}
+.x-spreadsheet-selector .x-spreadsheet-selector-clipboard {
+  border: 2px dashed #4b89ff;
+}
+.x-spreadsheet-selector .x-spreadsheet-selector-autofill {
+  border: 1px dashed rgba(0, 0, 0, 0.45);
+}
+.x-spreadsheet-selector .x-spreadsheet-selector-corner {
+  pointer-events: auto;
+  position: absolute;
+  cursor: crosshair;
+  font-size: 0;
+  height: 5px;
+  width: 5px;
+  right: -5px;
+  bottom: -5px;
+  border: 2px solid #ffffff;
+  background: #4b89ff;
+}
+.x-spreadsheet-editor {
+  z-index: 20;
+}
+.x-spreadsheet-editor .x-spreadsheet-editor-area {
+  position: absolute;
+  text-align: left;
+  border: 2px solid #4b89ff;
+  line-height: 0;
+  z-index: 100;
+  pointer-events: auto;
+}
+.x-spreadsheet-editor .x-spreadsheet-editor-area textarea {
+  box-sizing: content-box;
+  border: none;
+  padding: 0 3px;
+  outline: none;
+  resize: none;
+  text-align: start;
+  overflow-y: hidden;
+  font: 400 13px Arial, 'Lato', 'Source Sans Pro', Roboto, Helvetica, sans-serif;
+  color: inherit;
+  white-space: normal;
+  word-wrap: break-word;
+  line-height: 22px;
+  margin: 0;
+}
+.x-spreadsheet-editor .x-spreadsheet-editor-area .textline {
+  overflow: hidden;
+  visibility: hidden;
+  position: fixed;
+  top: 0;
+  left: 0;
+}
+.x-spreadsheet-item {
+  user-select: none;
+  background: 0;
+  border: 1px solid transparent;
+  outline: none;
+  height: 26px;
+  color: rgba(0, 0, 0, 0.9);
+  line-height: 26px;
+  list-style: none;
+  padding: 2px 10px;
+  cursor: default;
+  text-align: left;
+  overflow: hidden;
+}
+.x-spreadsheet-item.disabled {
+  pointer-events: none;
+  opacity: 0.5;
+}
+.x-spreadsheet-item:hover,
+.x-spreadsheet-item.active {
+  background: rgba(0, 0, 0, 0.05);
+}
+.x-spreadsheet-item.divider {
+  height: 0;
+  padding: 0;
+  margin: 5px 0;
+  border: none;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+}
+.x-spreadsheet-item .label {
+  float: right;
+  opacity: 0.65;
+  font-size: 1em;
+}
+.x-spreadsheet-item.state,
+.x-spreadsheet-header.state {
+  padding-left: 35px!important;
+  position: relative;
+}
+.x-spreadsheet-item.state:before,
+.x-spreadsheet-header.state:before {
+  content: '';
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  left: 12px;
+  top: calc(50% - 5px);
+  background: rgba(0, 0, 0, 0.08);
+  border-radius: 2px;
+}
+.x-spreadsheet-item.state.checked:before,
+.x-spreadsheet-header.state.checked:before {
+  background: #4b89ff;
+}
+.x-spreadsheet-checkbox {
+  position: relative;
+  display: inline-block;
+  backface-visibility: hidden;
+  outline: 0;
+  vertical-align: baseline;
+  font-style: normal;
+  font-size: 1rem;
+  line-height: 1em;
+}
+.x-spreadsheet-checkbox > input {
+  position: absolute;
+  top: 0;
+  left: 0;
+  opacity: 0!important;
+  outline: 0;
+  z-index: -1;
+}
+.x-spreadsheet-suggest,
+.x-spreadsheet-contextmenu,
+.x-spreadsheet-sort-filter {
+  position: absolute;
+  box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
+  background: #fff;
+  z-index: 100;
+  width: 260px;
+  pointer-events: auto;
+  overflow: auto;
+}
+.x-spreadsheet-suggest {
+  width: 200px;
+}
+.x-spreadsheet-filter {
+  border: 1px solid #e9e9e9;
+  font-size: 12px;
+  margin: 10px;
+}
+.x-spreadsheet-filter .x-spreadsheet-header {
+  padding: 0.5em 0.75em;
+  background: #f8f8f9;
+  border-bottom: 1px solid #e9e9e9;
+  border-left: 1px solid transparent;
+}
+.x-spreadsheet-filter .x-spreadsheet-body {
+  height: 200px;
+  overflow-y: auto;
+}
+.x-spreadsheet-filter .x-spreadsheet-body .x-spreadsheet-item {
+  height: 20px;
+  line-height: 20px;
+}
+.x-spreadsheet-sort-filter .x-spreadsheet-buttons {
+  margin: 10px;
+}
+.x-spreadsheet-bottombar {
+  height: 40px;
+  padding: 0 30px;
+  text-align: left;
+  background: #f5f6f7;
+  display: flex;
+}
+.x-spreadsheet-bottombar {
+  position: relative;
+  border-top: 1px solid #e0e2e4;
+}
+.x-spreadsheet-bottombar .x-spreadsheet-menu > li {
+  line-height: 40px;
+  height: 40px;
+  padding-top: 0;
+  padding-bottom: 0;
+  vertical-align: middle;
+  border-right: 1px solid #e8eaed;
+}
+.x-spreadsheet-menu {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  user-select: none;
+}
+.x-spreadsheet-menu > li {
+  float: left;
+  line-height: 1.25em;
+  padding: 0.785em 1em;
+  margin: 0;
+  vertical-align: middle;
+  text-align: left;
+  font-weight: 400;
+  color: #80868b;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: all 0.3s;
+  font-weight: bold;
+}
+.x-spreadsheet-menu > li.active {
+  background-color: #fff;
+  color: rgba(0, 0, 0, 0.65);
+}
+.x-spreadsheet-menu > li .x-spreadsheet-dropdown {
+  display: inline-block;
+}
+.x-spreadsheet-print {
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: 100;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+.x-spreadsheet-print-bar {
+  background: #424242;
+  height: 60px;
+  line-height: 60px;
+  padding: 0 30px;
+}
+.x-spreadsheet-print-bar .-title {
+  color: #fff;
+  font-weight: bold;
+  font-size: 1.2em;
+  float: left;
+}
+.x-spreadsheet-print-bar .-right {
+  float: right;
+  margin-top: 12px;
+}
+.x-spreadsheet-print-content {
+  display: flex;
+  flex: auto;
+  flex-direction: row;
+  background: #d0d0d0;
+  height: calc(100% - 60px);
+}
+.x-spreadsheet-print-content .-sider {
+  flex: 0 0 300px;
+  width: 300px;
+  border-left: 2px solid #ccc;
+  background: #fff;
+}
+.x-spreadsheet-print-content .-content {
+  flex: auto;
+  overflow-x: auto;
+  overflow-y: scroll;
+  height: 100%;
+}
+.x-spreadsheet-canvas-card-wraper {
+  margin: 40px 20px;
+}
+.x-spreadsheet-canvas-card {
+  background: #fff;
+  margin: auto;
+  page-break-before: auto;
+  page-break-after: always;
+  box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 3px rgba(0, 0, 0, 0.12), 0 4px 5px 0 rgba(0, 0, 0, 0.2);
+}
+.x-spreadsheet-calendar {
+  color: rgba(0, 0, 0, 0.65);
+  background: #ffffff;
+  user-select: none;
+}
+.x-spreadsheet-calendar .calendar-header {
+  font-weight: 700;
+  line-height: 30px;
+  text-align: center;
+  width: 100%;
+  float: left;
+  background: #f9fafb;
+}
+.x-spreadsheet-calendar .calendar-header .calendar-header-left {
+  padding-left: 5px;
+  float: left;
+}
+.x-spreadsheet-calendar .calendar-header .calendar-header-right {
+  float: right;
+}
+.x-spreadsheet-calendar .calendar-header .calendar-header-right a {
+  padding: 3px 0;
+  margin-right: 2px;
+  border-radius: 2px;
+}
+.x-spreadsheet-calendar .calendar-header .calendar-header-right a:hover {
+  background: rgba(0, 0, 0, 0.08);
+}
+.x-spreadsheet-calendar .calendar-body {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+.x-spreadsheet-calendar .calendar-body th,
+.x-spreadsheet-calendar .calendar-body td {
+  width: 14.28571429%;
+  min-width: 32px;
+  text-align: center;
+  font-weight: 700;
+  line-height: 30px;
+  padding: 0;
+}
+.x-spreadsheet-calendar .calendar-body td > .cell:hover {
+  background: #ecf6fd;
+}
+.x-spreadsheet-calendar .calendar-body td > .cell.active,
+.x-spreadsheet-calendar .calendar-body td > .cell.active:hover {
+  background: #ecf6fd;
+  color: #2185D0;
+}
+.x-spreadsheet-calendar .calendar-body td > .cell.disabled {
+  pointer-events: none;
+  opacity: 0.5;
+}
+.x-spreadsheet-datepicker {
+  box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2);
+  position: absolute;
+  left: 0;
+  top: calc(100% + 5px);
+  z-index: 10;
+  width: auto;
+}
+.x-spreadsheet-buttons {
+  display: flex;
+  justify-content: flex-end;
+}
+.x-spreadsheet-buttons .x-spreadsheet-button {
+  margin-left: 8px;
+}
+.x-spreadsheet-button {
+  display: inline-block;
+  border-radius: 3px;
+  line-height: 1em;
+  min-height: 1em;
+  white-space: nowrap;
+  text-align: center;
+  cursor: pointer;
+  font-size: 1em;
+  font-weight: 700;
+  padding: 0.75em 1em;
+  color: rgba(0, 0, 0, 0.6);
+  background: #E0E1E2;
+  text-decoration: none;
+  font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif;
+  outline: none;
+  vertical-align: baseline;
+  zoom: 1;
+  user-select: none;
+  transition: all 0.1s linear;
+}
+.x-spreadsheet-button.active,
+.x-spreadsheet-button:hover {
+  background-color: #C0C1C2;
+  color: rgba(0, 0, 0, 0.8);
+}
+.x-spreadsheet-button.primary {
+  color: #fff;
+  background-color: #2185D0;
+}
+.x-spreadsheet-button.primary:hover,
+.x-spreadsheet-button.primary.active {
+  color: #fff;
+  background-color: #1678c2;
+}
+.x-spreadsheet-form-input {
+  font-size: 1em;
+  position: relative;
+  font-weight: 400;
+  display: inline-flex;
+  color: rgba(0, 0, 0, 0.87);
+}
+.x-spreadsheet-form-input input {
+  z-index: 1;
+  margin: 0;
+  max-width: 100%;
+  flex: 1 0 auto;
+  outline: 0;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  text-align: left;
+  line-height: 30px;
+  height: 30px;
+  padding: 0 8px;
+  background: #fff;
+  border: 1px solid #e9e9e9;
+  border-radius: 3px;
+  transition: box-shadow 0.1s ease, border-color 0.1s ease;
+  box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
+}
+.x-spreadsheet-form-input input:focus {
+  border-color: #4b89ff;
+  box-shadow: inset 0 1px 2px rgba(75, 137, 255, 0.2);
+}
+.x-spreadsheet-form-select {
+  position: relative;
+  display: inline-block;
+  background: #fff;
+  border: 1px solid #e9e9e9;
+  border-radius: 2px;
+  cursor: pointer;
+  color: rgba(0, 0, 0, 0.87);
+  user-select: none;
+  box-shadow: inset 0 1px 2px hsla(0, 0%, 4%, 0.06);
+}
+.x-spreadsheet-form-select .input-text {
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  min-width: 60px;
+  width: auto;
+  height: 30px;
+  line-height: 30px;
+  padding: 0 8px;
+}
+.x-spreadsheet-form-fields {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+}
+.x-spreadsheet-form-fields .x-spreadsheet-form-field {
+  flex: 0 1 auto;
+}
+.x-spreadsheet-form-fields .x-spreadsheet-form-field .label {
+  display: inline-block;
+  margin: 0 10px 0 0;
+}
+.x-spreadsheet-form-field {
+  display: block;
+  vertical-align: middle;
+  margin-left: 10px;
+  margin-bottom: 10px;
+}
+.x-spreadsheet-form-field:first-child {
+  margin-left: 0;
+}
+.x-spreadsheet-form-field.error .x-spreadsheet-form-select,
+.x-spreadsheet-form-field.error input {
+  border-color: #f04134;
+}
+.x-spreadsheet-form-field .tip {
+  color: #f04134;
+  font-size: 0.9em;
+}
+.x-spreadsheet-dimmer {
+  display: none;
+  position: absolute;
+  top: 0 !important;
+  left: 0 !important;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  vertical-align: middle;
+  background-color: rgba(0, 0, 0, 0.6);
+  opacity: 0;
+  -webkit-animation-fill-mode: both;
+  animation-fill-mode: both;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  transition: background-color 0.5s linear;
+  user-select: none;
+  z-index: 1000;
+}
+.x-spreadsheet-dimmer.active {
+  display: block;
+  opacity: 1;
+}
+form fieldset {
+  border: none;
+}
+form fieldset label {
+  display: block;
+  margin-bottom: 0.5em;
+  font-size: 1em;
+  color: #666;
+}
+form fieldset select {
+  font-size: 1.1em;
+  width: 100%;
+  background-color: #fff;
+  border: none;
+  border-bottom: 2px solid #ddd;
+  padding: 0.5em 0.85em;
+  border-radius: 2px;
+}
+.x-spreadsheet-modal,
+.x-spreadsheet-toast {
+  font-size: 13px;
+  position: fixed;
+  z-index: 1001;
+  text-align: left;
+  line-height: 1.25em;
+  min-width: 360px;
+  color: rgba(0, 0, 0, 0.87);
+  font-family: 'Lato', 'Source Sans Pro', Roboto, Helvetica, Arial, sans-serif;
+  border-radius: 4px;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  background-color: #fff;
+  background-clip: padding-box;
+  box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px;
+}
+.x-spreadsheet-toast {
+  background-color: rgba(255, 255, 255, 0.85);
+}
+.x-spreadsheet-modal-header,
+.x-spreadsheet-toast-header {
+  font-weight: 600;
+  background-clip: padding-box;
+  background-color: rgba(255, 255, 255, 0.85);
+  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+  border-radius: 4px 4px 0 0;
+}
+
+.x-spreadsheet-toast-header {
+  color: #F2711C;
+}
+.x-spreadsheet-modal-header {
+  border-bottom: 1px solid #e0e2e4;
+  background: rgba(0, 0, 0, 0.08);
+  font-size: 1.0785em;
+}
+.x-spreadsheet-modal-header,
+.x-spreadsheet-modal-content,
+.x-spreadsheet-toast-header,
+.x-spreadsheet-toast-content {
+  padding: 0.75em 1em;
+}
+
+.x-spreadsheet-menu li:first-child {
+  display: none;
+}
+
+.vue-office-excel {
+  height: 100%;
+}

+ 1 - 0
src/axios.js

@@ -1,6 +1,7 @@
 import axios from 'axios'
 import store from './store'
 export const BASE_URL = process.env.BASE_URL    //测试-外网
+// export const BASE_URL = "http://192.168.1.7:5055"    //测试-外网
 export const tenantId = process.env.TENANT_ID
 import tools from './common/tools'
 import router from './router'

+ 267 - 0
src/pages/course-detail/components/HandOut copy.vue

@@ -0,0 +1,267 @@
+<template>
+  <div class="lecture-notesjy">
+    <div class="header">
+      <div class="header__name">{{ showId != null ? activeItem.urlName : courseHandoutsData.handoutsName }}</div>
+      <el-button
+        class="header__btn"
+        size="mini"
+        v-if="showId"
+        @click="showId = null"
+        >收起当前PDF</el-button
+      >
+    </div>
+    <ul
+      class="center"
+      v-if="
+        courseHandoutsData.fileList &&
+        courseHandoutsData.fileList.length > 0 &&
+        showId == null
+      "
+    >
+      <li
+        class="centerLi"
+        v-for="(item, index) in courseHandoutsData.fileList"
+        :key="index"
+      >
+        <div class="centerLibox">
+          <div class="centerLiboxName">{{ item.urlName }}</div>
+          <div class="centerLiboxBtnBox">
+            <el-button
+              v-if="showId !== item.fileId"
+              type="text"
+              @click="loadSeePdf(item)"
+              >预览</el-button
+            >
+            <el-button
+              type="text"
+              v-if="courseHandoutsData.canDownload == 1 ? true : false"
+              @click="printView($tools.splitImgHost(item.url))"
+              >打印</el-button
+            >
+            <el-button
+              type="text"
+              v-if="courseHandoutsData.canDownload == 1 ? true : false"
+              @click="download($tools.splitImgHost(item.url), item.urlName)"
+              >下载</el-button
+            >
+          </div>
+        </div>
+      </li>
+    </ul>
+    <div
+      class="pdf_box"
+      v-else-if="showId != null"
+      v-infinite-scroll="loadscroll"
+      :infinite-scroll-delay="200"
+      :infinite-scroll-distance="50"
+    >
+      <pdf
+        class="iframe"
+        :src="$tools.splitImgHost(activeItem.url)"
+        v-for="i in pdfCounts"
+        :key="i"
+        :page="i"
+        ref="pdf"
+      ></pdf>
+      <iframe
+        id="printIframe"
+        :src="$tools.splitImgHost(activeItem.url)"
+        frameborder="0"
+        style="display: none"
+      ></iframe>
+    </div>
+    <p class="no_center" v-else>暂无讲义列表</p>
+  </div>
+</template>
+
+<script>
+import pdf from "vue-pdf";
+import Print from "print-js";
+export default {
+  components: { pdf },
+  props: {
+    goodsData: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      courseHandoutsData: {},
+      showId: null, //当前显示pdfID号
+      activeItem: {},
+      pdfCounts: 0,
+    };
+  },
+  watch: {
+    goodsData: {
+      handler(newVal, oldVal) {
+        if (newVal.handoutsId != oldVal.handoutsId) {
+          this.courseHandouts();
+        }
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    /**
+     * 打印
+     */
+    printView(url) {
+      console.log("触发打印", url);
+      Print({
+        printable: url,
+        type: "pdf",
+        header: null,
+        targetStyles: ["*"],
+        style: "@page {margin:0 10mm}",
+      });
+    },
+    //下载
+    download(url, fileName) {
+      let xhr = new XMLHttpRequest();
+      xhr.open("get", url, true);
+      xhr.setRequestHeader("Content-Type", `application/pdf`);
+      xhr.responseType = "blob";
+      let that = this;
+      xhr.onload = function () {
+        if (this.status == 200) {
+          //接受二进制文件流
+          var blob = this.response;
+          that.downloadExportFile(blob, fileName);
+        }
+      };
+      xhr.send();
+    },
+
+    downloadExportFile(blob, tagFileName) {
+      let downloadElement = document.createElement("a");
+      let href = "";
+      if (typeof blob == "string") {
+        downloadElement.target = "_blank";
+      } else {
+        href = window.URL.createObjectURL(blob); //创建下载的链接
+      }
+      downloadElement.href = href;
+      downloadElement.download = tagFileName;
+      //下载后文件名
+      document.body.appendChild(downloadElement);
+      downloadElement.click(); //点击下载
+      document.body.removeChild(downloadElement); //下载完成移除元素
+      if (typeof blob != "string") {
+        window.URL.revokeObjectURL(href); //释放掉blob对象
+      }
+    },
+    /**
+     * 获取讲义权限
+     */
+    courseHandouts() {
+      if (this.goodsData.handoutsId) {
+        this.$request
+          .courseHandoutsdetail({handoutsId:this.goodsData.handoutsId})
+          .then((res) => {
+            this.courseHandoutsData = res.data || {};
+            if (res.data.fileList && res.data.fileList.length > 0) {
+              this.loadSeePdf(res.data.fileList[0]);
+            }
+          })
+          .catch((err) => {});
+      }
+    },
+
+    loadscroll() {
+      if (!this.pdfCounts && this.activeItem.pdf) {
+        if (this.activeItem.pdf >= 4) {
+          this.pdfCounts = 4;
+        } else {
+          this.pdfCounts = this.activeItem.pdf;
+        }
+      }
+      if (this.pdfCounts < this.activeItem.pdf) {
+        this.pdfCounts++;
+      } else {
+        return;
+      }
+    },
+    //点击预览加载
+    loadSeePdf(item) {
+      if (item.pdf) {
+        this.showId = item.fileId;
+        this.activeItem = item;
+        if (item.pdf >= 4) {
+          this.pdfCounts = 4;
+        } else {
+          this.pdfCounts = item.pdf;
+        }
+        this.$emit("backSwitchPdfData", item);
+        return;
+      }
+      const loadingTask = pdf.createLoadingTask(
+        this.$tools.splitImgHost(item.url)
+      );
+      loadingTask.promise
+        .then((pdf) => {
+          item.pdf = pdf.numPages;
+          this.showId = item.fileId;
+          this.activeItem = item;
+          if (item.pdf >= 4) {
+            this.pdfCounts = 4;
+          } else {
+            this.pdfCounts = item.pdf;
+          }
+          this.$emit("backSwitchPdfData", item);
+        })
+        .catch((err) => {});
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.lecture-notesjy {
+  max-height: 416px;
+  .header {
+    display: flex;
+    align-items: center;
+    border-bottom: 1px solid #fff;
+    &__name {
+      flex: 1;
+      color: #fff;
+      padding: 10px;
+    }
+    &__btn {
+      flex-shrink: 0;
+      margin: 0px 10px;
+    }
+  }
+  .no_center {
+    text-align: center;
+    color: #fff;
+    padding: 10px;
+  }
+  .center {
+    flex: 1;
+    overflow: auto;
+    .centerLi {
+      padding: 4px 10px;
+      & > .centerLibox {
+        display: flex;
+        align-items: center;
+        color: #fff;
+        & > .centerLiboxName {
+          flex: 1;
+        }
+        & > .centerLiboxBtnBox {
+          flex-shrink: 0;
+        }
+      }
+    }
+  }
+  .pdf_box {
+    flex: 1;
+    overflow: auto;
+  }
+}
+</style>

+ 280 - 60
src/pages/course-detail/components/HandOut.vue

@@ -1,7 +1,11 @@
 <template>
   <div class="lecture-notesjy">
     <div class="header">
-      <div class="header__name">{{ showId != null ? activeItem.urlName : courseHandoutsData.handoutsName }}</div>
+      <div class="header__name">
+        {{
+          showId != null ? activeItem.urlName : courseHandoutsData.handoutsName
+        }}
+      </div>
       <el-button
         class="header__btn"
         size="mini"
@@ -10,113 +14,239 @@
         >收起当前PDF</el-button
       >
     </div>
-    <ul
-      class="center"
-      v-if="
+    <div
+      v-show="
         courseHandoutsData.fileList &&
-        courseHandoutsData.fileList.length > 0 &&
-        showId == null
+          courseHandoutsData.fileList.length > 0 &&
+          showId == null
       "
+      class="content_flex"
     >
-      <li
-        class="centerLi"
-        v-for="(item, index) in courseHandoutsData.fileList"
-        :key="index"
+      <el-input placeholder="输入关键字进行过滤" v-model="filterText" clearable>
+      </el-input>
+      <el-tree
+        ref="tree"
+        :data="courseHandoutsData.fileList"
+        node-key="fileId"
+        draggable
+        :props="defaultProps"
+        :filter-node-method="filterNode"
       >
-        <div class="centerLibox">
-          <div class="centerLiboxName">{{ item.urlName }}</div>
-          <div class="centerLiboxBtnBox">
+        <span class="custom-tree-node" slot-scope="{ node, data }">
+          <span :class="data.type === 1 ? 'node_label1' : 'node_label2'">{{
+            node.label
+          }}</span>
+          <div>
             <el-button
-              v-if="showId !== item.fileId"
+              v-if="data.type === 1 && data.url"
               type="text"
-              @click="loadSeePdf(item)"
+              @click="loadSeePdf(data)"
               >预览</el-button
             >
             <el-button
               type="text"
-              v-if="courseHandoutsData.canDownload == 1 ? true : false"
-              @click="printView($tools.splitImgHost(item.url))"
+              v-if="
+                data.type === 1 &&
+                data.url &&
+                courseHandoutsData.canDownload == 1
+                  ? true
+                  : false
+              "
+              @click="printView($tools.splitImgHost(data.url), data.urlName)"
               >打印</el-button
             >
             <el-button
               type="text"
-              v-if="courseHandoutsData.canDownload == 1 ? true : false"
-              @click="download($tools.splitImgHost(item.url), item.urlName)"
+              v-if="
+                data.type === 1 &&
+                data.url &&
+                courseHandoutsData.canDownload == 1
+                  ? true
+                  : false
+              "
+              @click="download($tools.splitImgHost(data.url), data.urlName)"
               >下载</el-button
             >
           </div>
-        </div>
-      </li>
-    </ul>
+        </span>
+      </el-tree>
+    </div>
     <div
       class="pdf_box"
-      v-else-if="showId != null"
+      v-show="showId != null"
       v-infinite-scroll="loadscroll"
       :infinite-scroll-delay="200"
       :infinite-scroll-distance="50"
     >
-      <pdf
-        class="iframe"
-        :src="$tools.splitImgHost(activeItem.url)"
-        v-for="i in pdfCounts"
-        :key="i"
-        :page="i"
-        ref="pdf"
-      ></pdf>
-      <iframe
-        id="printIframe"
-        :src="$tools.splitImgHost(activeItem.url)"
-        frameborder="0"
-        style="display: none"
-      ></iframe>
+      <div id="bodyContainer" v-if="ShowAlist === 'docx'"></div>
+      <vue-office-excel
+        style="height: 376px;overflow: hidden;"
+        v-else-if="ShowAlist === 'xlsx'"
+        :src="readerResult"
+        @rendered="rendered"
+        @error="errorHandler"
+        :key="12"
+      />
+      <template v-else>
+        <pdf
+          class="iframe"
+          :src="$tools.splitImgHost(activeItem.url)"
+          v-for="i in pdfCounts"
+          :key="i"
+          :page="i"
+          ref="pdf"
+        ></pdf>
+        <iframe
+          id="printIframe"
+          :src="$tools.splitImgHost(activeItem.url)"
+          frameborder="0"
+          style="display: none"
+        ></iframe>
+      </template>
     </div>
-    <p class="no_center" v-else>暂无讲义列表</p>
+    <p
+      class="no_center"
+      v-show="
+        !courseHandoutsData.fileList || courseHandoutsData.fileList.length === 0
+      "
+    >
+      暂无讲义列表
+    </p>
   </div>
 </template>
 
 <script>
+import axios from "axios";
+import { renderAsync } from "docx-preview";
+import VueOfficeExcel from "@vue-office/excel";
+import "@vue-office/excel/lib/index.css";
 import pdf from "vue-pdf";
+import CMapReaderFactory from "vue-pdf/src/CMapReaderFactory.js";
 import Print from "print-js";
 export default {
-  components: { pdf },
+  components: { pdf, VueOfficeExcel },
   props: {
     goodsData: {
       type: Object,
       default: () => {
         return {};
-      },
-    },
+      }
+    }
   },
   data() {
     return {
+      readerResult: null,
+      filterText: "",
+      defaultProps: {
+        children: "children",
+        label: "urlName"
+      },
       courseHandoutsData: {},
       showId: null, //当前显示pdfID号
       activeItem: {},
-      pdfCounts: 0,
+      pdfCounts: 0
     };
   },
+  computed: {
+    ShowAlist() {
+      if (this.activeItem.urlName) {
+        return this.activeItem.urlName.slice(
+          this.activeItem.urlName.indexOf(".") + 1
+        );
+      }
+      return "";
+    }
+  },
   watch: {
+    filterText(val) {
+      this.$refs.tree.filter(val);
+    },
     goodsData: {
       handler(newVal, oldVal) {
         if (newVal.handoutsId != oldVal.handoutsId) {
           this.courseHandouts();
         }
       },
-      deep: true,
-    },
+      deep: true
+    }
   },
   methods: {
+    //渲染docx
+    docxRender(url, fileName) {
+      axios({
+        method: "get",
+        responseType: "blob", // 设置响应文件格式
+        url: url
+      }).then(({ data }) => {
+        let array = [
+          document.getElementById("bodyContainer"),
+          document.getElementById("bodyContainers")
+        ];
+        for (let i = 0; i < array.length; i++) {
+          renderAsync(data, array[i]); // 渲染到页面预览
+        }
+      });
+    },
+    rendered() {},
+    errorHandler(e) {
+      this.$message.error("表格内容不支持预览");
+      console.log("错误", e);
+      return;
+    },
+    //渲染xlsx
+    xlsxRender(url, fileName) {
+      axios({
+        method: "get",
+        responseType: "blob", // 设置响应文件格式
+        url: url
+      }).then(({ data }) => {
+        var file = new File([data], fileName, {
+          type: "application/json",
+          lastModified: Date.now()
+        });
+        this.beforeUpload(file);
+      });
+    },
+    beforeUpload(file) {
+      let reader = new FileReader();
+      reader.readAsArrayBuffer(file);
+      reader.onload = loadEvent => {
+        let arrayBuffer = loadEvent.target.result;
+        this.readerResult = arrayBuffer;
+      };
+      return false;
+    },
+    getTable(sheetName) {
+      var worksheet = this.workbook.Sheets[sheetName];
+      this.excelData = xlsxs.utils.sheet_to_json(worksheet);
+    },
+    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);
+    },
     /**
      * 打印
      */
-    printView(url) {
+    printView(url, name) {
       console.log("触发打印", url);
+      var a = name.slice(name.indexOf(".") + 1);
+      if (a !== "pdf") {
+        this.$message.error("当前类型不支持打印功能");
+        return;
+      }
       Print({
         printable: url,
-        type: "pdf",
+        type: a,
         header: null,
         targetStyles: ["*"],
-        style: "@page {margin:0 10mm}",
+        style: "@page {margin:0 10mm}"
       });
     },
     //下载
@@ -126,7 +256,7 @@ export default {
       xhr.setRequestHeader("Content-Type", `application/pdf`);
       xhr.responseType = "blob";
       let that = this;
-      xhr.onload = function () {
+      xhr.onload = function() {
         if (this.status == 200) {
           //接受二进制文件流
           var blob = this.response;
@@ -160,17 +290,33 @@ export default {
     courseHandouts() {
       if (this.goodsData.handoutsId) {
         this.$request
-          .courseHandouts(this.goodsData.handoutsId)
-          .then((res) => {
+          .courseHandoutsdetail({ handoutsId: this.goodsData.handoutsId })
+          .then(res => {
             this.courseHandoutsData = res.data || {};
             if (res.data.fileList && res.data.fileList.length > 0) {
-              this.loadSeePdf(res.data.fileList[0]);
+              this.loadSeePdf(this.getFirstPdf(res.data.fileList));
             }
           })
-          .catch((err) => {});
+          .catch(err => {});
       }
     },
-
+    //递归查询第一个PDF
+    getFirstPdf(array) {
+      let obj = {};
+      for (let i = 0; i < array.length; i++) {
+        if (array[i].type === 1 && array[i].url) {
+          obj = array[i];
+          break;
+        }
+        if (array[i].type === 2) {
+          obj = this.getFirstPdf(array[i].children || []);
+          if (Object.keys(obj).length != 0) {
+            break;
+          }
+        }
+      }
+      return obj;
+    },
     loadscroll() {
       if (!this.pdfCounts && this.activeItem.pdf) {
         if (this.activeItem.pdf >= 4) {
@@ -187,6 +333,25 @@ export default {
     },
     //点击预览加载
     loadSeePdf(item) {
+      console.log(item, "item");
+      if (Object.keys(item).length == 0) {
+        this.$message.error("当前选择文件不存在");
+        return;
+      }
+      if (item.urlName.slice(item.urlName.indexOf(".") + 1) === "docx") {
+        this.showId = item.fileId;
+        this.activeItem = item;
+        this.$emit("backSwitchPdfData", item);
+        this.docxRender(this.$tools.splitImgHost(item.url));
+        return;
+      }
+      if (item.urlName.slice(item.urlName.indexOf(".") + 1) === "xlsx") {
+        this.showId = item.fileId;
+        this.activeItem = item;
+        this.$emit("backSwitchPdfData", item);
+        this.xlsxRender(this.$tools.splitImgHost(item.url));
+        return;
+      }
       if (item.pdf) {
         this.showId = item.fileId;
         this.activeItem = item;
@@ -198,11 +363,13 @@ export default {
         this.$emit("backSwitchPdfData", item);
         return;
       }
-      const loadingTask = pdf.createLoadingTask(
-        this.$tools.splitImgHost(item.url)
-      );
+      const loadingTask = pdf.createLoadingTask({
+        url: this.$tools.splitImgHost(item.url),
+        CMapReaderFactory,
+        cMapPacked: true
+      });
       loadingTask.promise
-        .then((pdf) => {
+        .then(pdf => {
           item.pdf = pdf.numPages;
           this.showId = item.fileId;
           this.activeItem = item;
@@ -213,19 +380,56 @@ export default {
           }
           this.$emit("backSwitchPdfData", item);
         })
-        .catch((err) => {});
-    },
-  },
+        .catch(err => {});
+    }
+  }
 };
 </script>
 
 <style lang="scss" scoped>
+.el-tree {
+  background-color: #3f4449;
+  color: #fff;
+}
+/deep/ .el-input__inner {
+  background-color: #3f4449;
+  color: #fff;
+  border-radius: 0px;
+  border: none;
+  border-bottom: 1px solid #dcdfe6;
+}
+/deep/ .el-tree-node__content:hover,
+/deep/ .el-tree-node:focus > .el-tree-node__content {
+  background-color: #0005;
+}
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding-right: 8px;
+  
+  & > .node_label1 {
+    flex: 1;
+    width: 1px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  & > .node_label2 {
+    width: 408px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+}
 .lecture-notesjy {
   max-height: 416px;
   .header {
     display: flex;
     align-items: center;
     border-bottom: 1px solid #fff;
+    height: 40px;
     &__name {
       flex: 1;
       color: #fff;
@@ -236,6 +440,22 @@ export default {
       margin: 0px 10px;
     }
   }
+  .content_flex {
+    flex: 1;
+    height: 1px;
+    display: flex;
+    flex-direction: column;
+    & > .el-input {
+      height: 40px;
+    }
+    & > .el-tree {
+      background-color: #3f4449;
+      color: #fff;
+      flex: 1;
+      /* height: 1px; */
+      overflow: auto;
+    }
+  }
   .no_center {
     text-align: center;
     color: #fff;

+ 117 - 36
src/pages/course-detail/index.vue

@@ -36,40 +36,53 @@
                     id="player"
                   ></div>
                   <div
-                    v-if="switchPdf.pdf"
+                    v-if="switchPdf.pdf || ShowAlist !== ''"
                     :class="!switchBox ? 'smallBox overStyle' : 'switchPdf'"
                     :style="!switchBox && hideBox ? 'display:none;' : ''"
                   >
                     <div
-                      v-if="switchPdf.pdf && switchPdf.pdf > 0"
+                      v-if="
+                        (switchPdf.pdf && switchPdf.pdf > 0) || ShowAlist !== ''
+                      "
                       v-infinite-scroll="loadscroll"
                       :infinite-scroll-delay="200"
                       :infinite-scroll-distance="50"
                     >
-                      <pdf
-                        class="iframe"
-                        :src="$tools.splitImgHost(switchPdf.url)"
-                        v-for="i in counts"
-                        :key="i"
-                        :page="i"
-                        ref="pdf"
-                        @page-loaded="pageLoaded"
-                      ></pdf>
-                      <iframe
-                        id="printIframe"
-                        :src="$tools.splitImgHost(switchPdf.url)"
-                        frameborder="0"
-                        style="display: none"
-                      ></iframe>
+                      <div
+                        id="bodyContainers"
+                        v-if="ShowAlist === 'docx'"
+                      ></div>
+                      <vue-office-excel
+                        style="width:808px;height: 452px!important;overflow: hidden;"
+                        v-else-if="ShowAlist === 'xlsx'"
+                        :src="readerResult"
+                      />
+                      <template v-else>
+                        <pdf
+                          class="iframe"
+                          :src="$tools.splitImgHost(switchPdf.url)"
+                          v-for="i in counts"
+                          :key="i"
+                          :page="i"
+                          ref="pdf"
+                          @page-loaded="pageLoaded"
+                        ></pdf>
+                        <iframe
+                          id="printIframe"
+                          :src="$tools.splitImgHost(switchPdf.url)"
+                          frameborder="0"
+                          style="display: none"
+                        ></iframe>
+                      </template>
                     </div>
                   </div>
                   <i
-                    v-if="!hideBox && switchPdf.pdf"
+                    v-if="!hideBox && (switchPdf.pdf || ShowAlist !== '')"
                     class="switch el-icon-monitor"
                     @click="switchBoxFunc"
                   ></i>
                   <i
-                    v-if="switchPdf.pdf"
+                    v-if="switchPdf.pdf || ShowAlist !== ''"
                     class="hideSwitchBox el-icon-view"
                     @click="hideBox = !hideBox"
                   ></i>
@@ -874,6 +887,7 @@
 </template>
 
 <script>
+import axios from "axios";
 import Footer from "@/components/footer/index";
 import Header from "@/components/header/index";
 import ToolBar from "@/components/toolbar/index";
@@ -885,6 +899,8 @@ import CourseTree from "./components/CourseTree.vue";
 import AnswerQuestions from "./components/AnswerQuestions.vue";
 import Notes from "./components/Notes.vue";
 import HandOut from "./components/HandOut.vue";
+import VueOfficeExcel from "@vue-office/excel";
+import "@vue-office/excel/lib/index.css";
 export default {
   name: "CourseDetail",
   components: {
@@ -896,7 +912,8 @@ export default {
     CourseTree,
     AnswerQuestions,
     Notes,
-    HandOut
+    HandOut,
+    VueOfficeExcel
   },
   data() {
     return {
@@ -1232,7 +1249,9 @@ export default {
       playTabIndex: "",
       takeSetInt: null,
       videoPause: null,
-      confirmStatus: false
+      confirmStatus: false,
+      openPhotoStatus: 0,
+      readerResult: null
     };
   },
   watch: {
@@ -1280,6 +1299,17 @@ export default {
         return ary;
       };
     },
+    ShowAlist() {
+      if (this.switchPdf.urlName) {
+        console.log(
+          this.switchPdf.urlName.slice(this.switchPdf.urlName.indexOf(".") + 1)
+        );
+        return this.switchPdf.urlName.slice(
+          this.switchPdf.urlName.indexOf(".") + 1
+        );
+      }
+      return "";
+    },
     menuTab() {
       let menuTab = [
         {
@@ -1424,7 +1454,35 @@ export default {
     backSwitchPdfData(item) {
       this.counts = 0;
       this.switchPdf = item;
-      this.loadscroll();
+      if (this.ShowAlist === "xlsx") {
+        this.xlsxRender(this.$tools.splitImgHost(item.url));
+      } else if (this.ShowAlist === "pdf") {
+        this.loadscroll();
+      }
+    },
+    //渲染xlsx
+    xlsxRender(url, fileName) {
+      axios({
+        method: "get",
+        responseType: "blob", // 设置响应文件格式
+        url: url
+      }).then(({ data }) => {
+        var file = new File([data], fileName, {
+          type: "application/json",
+          lastModified: Date.now()
+        });
+        this.beforeUpload(file);
+      });
+    },
+    beforeUpload(file) {
+      let reader = new FileReader();
+      reader.readAsArrayBuffer(file);
+      reader.onload = loadEvent => {
+        let arrayBuffer = loadEvent.target.result;
+        this.readerResult = arrayBuffer;
+        console.log("readerResult:", this.readerResult);
+      };
+      return false;
     },
     pauseVideo() {
       if (this.takePhotoModal || this.confirmStatus) {
@@ -1564,7 +1622,7 @@ export default {
             this.isTaking = false;
             this.loading = false;
             var polyvPlayerContext = this.player;
-            if (polyvPlayerContext) {
+            if (polyvPlayerContext && this.openPhotoStatus !== 1) {
               polyvPlayerContext.j2s_resumeVideo();
             }
             var polyvPlayerContext = this.playerzb;
@@ -3415,6 +3473,7 @@ export default {
           );
         //播放视频
         this.showRecordStatus = false; //隐藏播放记录提示
+        this.openPhotoStatus = 0;
         this.sectionItem = option;
         this.isPlayRebuild = option.rebuild;
         this.moduleId = option.moduleId || 0;
@@ -3635,12 +3694,6 @@ export default {
             type: "success",
             message: "播放完毕"
           });
-          if (this.playTabIndex == this.courseTabIndex - 1) {
-            this.$refs["courseTree"][
-              this.playTabIndex
-            ].dialogPalyVisible = true;
-            clearTimeout(this.videoPause);
-          }
 
           if (this.isFullScreen()) {
             this.exitFullscreen();
@@ -3822,7 +3875,7 @@ export default {
         this.photoConfig = true;
         if (this.goodsData.erJianErZao) {
           this.photoList = this.randomConfig(totalVideoTime, duration);
-        console.log("拍摄时间组:(秒)",this.photoList)
+          console.log("拍摄时间组:(秒)", this.photoList);
           return;
         }
         //没有历史拍照间隔数据
@@ -3864,7 +3917,7 @@ export default {
               this.photoList.push(endTakeTime);
             }
           }
-        console.log("拍摄时间组:(秒)",this.photoList)
+          console.log("拍摄时间组:(秒)", this.photoList);
           this.postCoursePhotoRecord(true); //提交随机拍照时间数组
         }
         console.log(this.photoList, "随机拍照时间数组");
@@ -4036,15 +4089,35 @@ export default {
         .studyRecord(data)
         .then(res => {
           if (status > 0) {
+            this.openPhotoStatus = 0;
+            if (this.playTabIndex == this.courseTabIndex - 1) {
+              this.$refs["courseTree"][
+                this.playTabIndex
+              ].dialogPalyVisible = true;
+              clearTimeout(this.videoPause);
+            }
             //看完视频刷新父级列表
             // let rebuildObj = this.getSameObj(this.sectionItem);
             // this.refreshParentList(this.sectionItem, rebuildObj);
             this.$refs["courseTree"][0].refreshList();
           }
-
           self.ossAvatarUrl = "";
+          if (this.openPhotoStatus === 1) {
+            this.postStudyRecord(1);
+          }
         })
-        .catch(err => {});
+        .catch(err => {
+          if (err.code === 559) {
+            this.$message.error(err.msg);
+            console.log("拍照不够触发");
+            this.openPhotoStatus = 1;
+            this.openPhoto();
+          }
+          if (err.code === 558) {
+            this.$message.error(err.msg);
+            return;
+          }
+        });
     },
     /**
      * 获取重修列表中是否有相同对象
@@ -4642,6 +4715,14 @@ export default {
 
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
+/deep/ .docx-wrapper {
+  padding: 0px;
+}
+/deep/ .docx-wrapper > section.docx {
+  padding: 4px !important;
+  width: auto !important;
+  min-height: auto !important;
+}
 .course-detail {
   .section {
     padding-bottom: 30px;
@@ -4694,7 +4775,7 @@ export default {
               background: #fff;
               right: 20px;
               bottom: 75px;
-              z-index: 1;
+              z-index: 1998;
               overflow: hidden;
               /deep/ .pv-video-player {
                 // width: 100%!important;
@@ -4710,7 +4791,7 @@ export default {
               position: absolute;
               right: 22px;
               bottom: 77px;
-              z-index: 2;
+              z-index: 1999;
               font-size: 30px;
               transition: all 0.3;
               border-radius: 50%;
@@ -4726,7 +4807,7 @@ export default {
               position: absolute;
               right: 22px;
               bottom: 126px;
-              z-index: 2;
+              z-index: 1999;
               font-size: 30px;
               transition: all 0.3;
               border-radius: 50%;

+ 16 - 1
src/pages/home/index.vue

@@ -2265,6 +2265,7 @@ export default {
         font-weight: 400;
         color: #333333;
         text-shadow: 0px 6px 6px rgba(249, 113, 13, 0.08);
+        flex-shrink: 0;
       }
     }
 
@@ -2278,6 +2279,12 @@ export default {
         color: #888888;
         font-size: 14px;
         margin-right: 32px;
+        overflow: hidden;
+        word-break: break-all;
+        text-overflow: ellipsis;
+        display: -webkit-box;
+        -webkit-line-clamp: 1;
+        -webkit-box-orient: vertical;
 
         &.active {
           font-weight: 600;
@@ -2303,6 +2310,7 @@ export default {
 
     &__footer {
       overflow: hidden;
+      flex-shrink: 0;
 
       .btn {
         cursor: pointer;
@@ -2348,6 +2356,7 @@ export default {
         font-weight: 400;
         color: #333333;
         text-shadow: 0px 6px 6px rgba(249, 113, 13, 0.08);
+        flex-shrink: 0;
       }
     }
     .tabs {
@@ -2360,6 +2369,12 @@ export default {
         color: #888888;
         font-size: 14px;
         margin-right: 32px;
+        overflow: hidden;
+        word-break: break-all;
+        text-overflow: ellipsis;
+        display: -webkit-box;
+        -webkit-line-clamp: 1;
+        -webkit-box-orient: vertical;
         &.active {
           font-weight: 600;
           color: #222222;
@@ -2383,7 +2398,7 @@ export default {
 
     &__footer {
       overflow: hidden;
-
+      flex-shrink: 0;
       .btn {
         cursor: pointer;
         width: 72px;

+ 1 - 1
src/pages/live-detail/index.vue

@@ -6383,7 +6383,7 @@ export default {
      */
     courseHandouts() {
       this.$request
-        .courseHandouts(this.goodsData.handoutsId)
+        .courseHandoutsdetail({handoutsId:this.goodsData.handoutsId})
         .then((res) => {
           this.courseHandoutsData = res.data;
           const loadingTask = pdf.createLoadingTask(

+ 134 - 114
src/pages/person-center/my-course/index.vue

@@ -1033,137 +1033,134 @@ export default {
     getRecord(item) {
       this.$request.studyrecordgetUserStudyLast().then(async res => {
         if (res.data && res.data.sectionId) {
-        await this.getGoodsData(res);
-        var stop = false;
-        for (let y = 0; y < this.goodsTeacher.length; y++) {
-          for (let i = 0; i < this.goodsTeacher[y].courseList.length; i++) {
-            if (stop) {
-              break;
-            }
-            if (
-              this.goodsTeacher[y].courseList[i].courseId == res.data.courseId
-            ) {
-              await this.changeStatus(this.goodsTeacher[y].courseList[i]);
-              for (
-                let k = 0;
-                k < this.goodsTeacher[y].courseList[i].children.length;
-                k++
+          await this.getGoodsData(res);
+          var stop = false;
+          for (let y = 0; y < this.goodsTeacher.length; y++) {
+            for (let i = 0; i < this.goodsTeacher[y].courseList.length; i++) {
+              if (stop) {
+                break;
+              }
+              if (
+                this.goodsTeacher[y].courseList[i].courseId == res.data.courseId
               ) {
-                if (res.data.moduleId) {
-                  console.log(1);
-                  if (
-                    this.goodsTeacher[y].courseList[i].children[k].menuId ==
-                    res.data.moduleId
-                  ) {
-                    await this.changeModuleStatus(
-                      this.goodsTeacher[y].courseList[i].children[k],
-                      i,
-                      k,
-                      y
-                    );
-                    for (
-                      let j = 0;
-                      j <
-                      this.goodsTeacher[y].courseList[i].children[k].children
-                        .length;
-                      j++
+                await this.changeStatus(this.goodsTeacher[y].courseList[i]);
+                for (
+                  let k = 0;
+                  k < this.goodsTeacher[y].courseList[i].children.length;
+                  k++
+                ) {
+                  if (res.data.moduleId) {
+                    console.log(1);
+                    if (
+                      this.goodsTeacher[y].courseList[i].children[k].menuId ==
+                      res.data.moduleId
                     ) {
-                      if (
-                        this.goodsTeacher[y].courseList[i].children[k].children[
-                          j
-                        ].chapterId == res.data.chapterId
+                      await this.changeModuleStatus(
+                        this.goodsTeacher[y].courseList[i].children[k],
+                        i,
+                        k,
+                        y
+                      );
+                      for (
+                        let j = 0;
+                        j <
+                        this.goodsTeacher[y].courseList[i].children[k].children
+                          .length;
+                        j++
                       ) {
-                        await this.changeChapterStatus(
-                          y,
-                          2,
-                          this.goodsTeacher[y].courseList[i].children[k]
-                            .children[j],
-                          i,
-                          k,
-                          j
-                        );
-
-                        for (
-                          let m = 0;
-                          m <
+                        if (
                           this.goodsTeacher[y].courseList[i].children[k]
-                            .children[j].children.length;
-                          m++
+                            .children[j].chapterId == res.data.chapterId
                         ) {
-                          if (
+                          await this.changeChapterStatus(
+                            y,
+                            2,
+                            this.goodsTeacher[y].courseList[i].children[k]
+                              .children[j],
+                            i,
+                            k,
+                            j
+                          );
+
+                          for (
+                            let m = 0;
+                            m <
                             this.goodsTeacher[y].courseList[i].children[k]
-                              .children[j].children[m].sectionId ==
-                            res.data.sectionId
+                              .children[j].children.length;
+                            m++
                           ) {
-                            this.$set(
+                            if (
                               this.goodsTeacher[y].courseList[i].children[k]
-                                .children[j].children[m],
-                              "recordStatus",
-                              true
-                            );
-                            stop = true;
-                            break;
+                                .children[j].children[m].sectionId ==
+                              res.data.sectionId
+                            ) {
+                              this.$set(
+                                this.goodsTeacher[y].courseList[i].children[k]
+                                  .children[j].children[m],
+                                "recordStatus",
+                                true
+                              );
+                              stop = true;
+                              break;
+                            }
                           }
                         }
                       }
                     }
-                  }
-                } else if (res.data.chapterId) {
-                  console.log(2);
-                  if (
-                    this.goodsTeacher[y].courseList[i].children[k].menuId ==
-                    res.data.chapterId
-                  ) {
-                    await this.changeChapterStatus(
-                      y,
-                      1,
-                      this.goodsTeacher[y].courseList[i].children[k],
-                      i,
-                      k
-                    );
-                    for (
-                      let j = 0;
-                      j <
-                      this.goodsTeacher[y].courseList[i].children[k].children
-                        .length;
-                      j++
+                  } else if (res.data.chapterId) {
+                    console.log(2);
+                    if (
+                      this.goodsTeacher[y].courseList[i].children[k].menuId ==
+                      res.data.chapterId
                     ) {
-                      if (
-                        this.goodsTeacher[y].courseList[i].children[k].children[
-                          j
-                        ].sectionId == res.data.sectionId
+                      await this.changeChapterStatus(
+                        y,
+                        1,
+                        this.goodsTeacher[y].courseList[i].children[k],
+                        i,
+                        k
+                      );
+                      for (
+                        let j = 0;
+                        j <
+                        this.goodsTeacher[y].courseList[i].children[k].children
+                          .length;
+                        j++
                       ) {
-                        this.$set(
+                        if (
                           this.goodsTeacher[y].courseList[i].children[k]
-                            .children[j],
-                          "recordStatus",
-                          true
-                        );
-                        stop = true;
-                        break;
+                            .children[j].sectionId == res.data.sectionId
+                        ) {
+                          this.$set(
+                            this.goodsTeacher[y].courseList[i].children[k]
+                              .children[j],
+                            "recordStatus",
+                            true
+                          );
+                          stop = true;
+                          break;
+                        }
                       }
                     }
-                  }
-                } else {
-                  console.log(3);
-                  if (
-                    this.goodsTeacher[y].courseList[i].children[k].menuId ==
-                    res.data.sectionId
-                  ) {
-                    this.$set(
-                      this.goodsTeacher[y].courseList[i].children[k],
-                      "recordStatus",
-                      true
-                    );
-                    stop = true;
-                    break;
+                  } else {
+                    console.log(3);
+                    if (
+                      this.goodsTeacher[y].courseList[i].children[k].menuId ==
+                      res.data.sectionId
+                    ) {
+                      this.$set(
+                        this.goodsTeacher[y].courseList[i].children[k],
+                        "recordStatus",
+                        true
+                      );
+                      stop = true;
+                      break;
+                    }
                   }
                 }
               }
             }
           }
-        }
-
         } else {
           this.resultCourseGoodsList();
         }
@@ -1389,12 +1386,14 @@ export default {
         if (
           item.officialName &&
           item.businessName == "二级" &&
-          item.projectName == "建造师"
+          (item.projectName == "建造师" || item.projectName == "造价师")
         ) {
+          if (!(await this.RequiredCourse())) {
+            return;
+          }
           confirmDetail = await this.userConfirmInfoDetail();
         }
       }
-
       // //内部系统
       // if (item.interfacePushId > 0 && item.officialStatus != 1) {
       //   this.$message({
@@ -1590,8 +1589,11 @@ export default {
         if (
           item.officialName &&
           item.businessName == "二级" &&
-          item.projectName == "建造师"
+          (item.projectName == "建造师" || item.projectName == "造价师")
         ) {
+          if (!(await this.RequiredCourse())) {
+            return;
+          }
           confirmDetail = await this.userConfirmInfoDetail();
         }
       }
@@ -1612,7 +1614,7 @@ export default {
       if (!(await this.orderTopTobottom(courseLists, section, type))) {
         this.$message({
           type: "warning",
-          message: "请学完视频课程再进行练习和测试",
+          message: "请学完视频课程再进行练习和测试"
         });
         return false;
       }
@@ -1759,7 +1761,25 @@ export default {
           });
       });
     },
-
+    RequiredCourse() {
+      return new Promise(resolve => {
+        if (this.goodsData.categoryName !== "必修") {
+          this.$request
+            .goodsGradeCheckFinishRequiredCourse({
+              businessId: this.goodsData.businessId,
+              goodsId:this.goodsData.goodsId
+            })
+            .then(res => {
+              if (res.data > 0) {
+                resolve(true);
+              } else {
+                this.$message.warning("请先学习必修商品");
+                resolve(false);
+              }
+            });
+        }
+      });
+    },
     userConfirmInfoDetail() {
       return new Promise(resolve => {
         this.$request