file.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. <template>
  2. <div class="c_box">
  3. <!-- <div class="mask"></div> -->
  4. <!-- <div v-if="!checkJson">暂未设置题目</div> -->
  5. <!-- <div v-if="!cJson">暂未设置题目</div> -->
  6. <div class="choices" v-if="!cJson">
  7. <div class="binfo_input">
  8. <div><span>填写者上传区</span></div>
  9. </div>
  10. </div>
  11. <div v-else class="choice_box">
  12. <!-- <div class="title"><div>{{ `(${option[checkJson.type].name})` }}</div><div v-html="checkJson.title"></div></div> -->
  13. <div class="title" style="display: flex;">
  14. <!-- + `(${option[checkJson.type].name})` -->
  15. <span style="min-width: fit-content;">{{ tindex + 1 + "、" }}</span>
  16. <span>{{ checkJson.title }}</span>
  17. <span style="color: #efa030;min-width: fit-content;" v-if="checkJson.score">({{ '分值:' + checkJson.score
  18. +
  19. '分' }})</span>
  20. <!-- </div><div v-html="checkJson.title"></div> -->
  21. </div>
  22. <div class="detail" v-if="checkJson.detail" v-html="checkJson.detail"
  23. style="color: #00000099;margin-top: 5px;">
  24. </div>
  25. <div class="choices">
  26. <div class="uploadBtn" v-if="checktype == 1">
  27. <div class="btn" @click.stop="addImg($event)">
  28. <span>添加本地文件</span>
  29. <input type="file" accept="*" style="display: none" multiple="multiple"
  30. @change="beforeUpload($event)" />
  31. </div>
  32. <div class="btn" @click="openFileBox()">
  33. <span>从资源库添加</span>
  34. </div>
  35. <div class="switch">
  36. <el-switch
  37. active-color="#3681fc"
  38. v-model="isTong">
  39. </el-switch>
  40. <span @click="isTong = !isTong">同步至资源库</span>
  41. </div>
  42. </div>
  43. <div class="binfo_input">
  44. <div class="fileBox" v-if="checkJson.file && checkJson.file.length">
  45. <div class="fileC">
  46. <div class="file" v-for="(item, index) in checkJson.file" :key="index"
  47. @click.stop="checkFile(item)">
  48. <img class="del" src="../../../../../../assets/icon/fileIcon/deleteworks.png"
  49. @click.stop="delFile(index)" />
  50. <img class="download" src="../../../../../../assets/icon/fileIcon/download.png"
  51. @click.stop="downloadFile(item)"
  52. :style="{ right: checktype != 1 ? '10px' : '45px' }" />
  53. <img class="img" :src="wordIcon" alt="" v-if="item.type == 1" />
  54. <img class="img" :src="videoIcon" alt="" v-if="item.type == 2" />
  55. <img class="img" :src="item.url" alt="" v-if="item.type == 3" />
  56. <img class="img" :src="wordIcon" alt="" v-if="item.type == 4" />
  57. <img class="img" :src="fileIcon" alt="" v-if="item.type == 5" />
  58. <div class="name">
  59. <el-tooltip :content="item.name" placement="top" effect="dark">
  60. <span>{{ item.name }}</span>
  61. </el-tooltip>
  62. </div>
  63. </div>
  64. </div>
  65. <!-- @click.stop="addImg($event)" -->
  66. <!-- <div class="btn" @click.stop="openFileBox()">
  67. <span>点击添加文件</span>
  68. <input type="file" accept="*" style="display: none" multiple="multiple" @change="beforeUpload($event)" />
  69. </div> -->
  70. </div>
  71. <!-- @click.stop="addImg($event)" @click.stop="addImg($event)" -->
  72. <div class="uploadQ" v-else>
  73. <span>填写者上传区</span>
  74. <!-- <input type="file" accept="*" style="display: none" multiple="multiple" @change="beforeUpload($event)" /> -->
  75. </div>
  76. <div v-if="proVisible" class="mask">
  77. <div class="progressBox">
  78. <div class="lbox">
  79. <img src="../../../../../../assets/loading.gif" />上传中,请稍后
  80. </div>
  81. <!-- <div style="margin-bottom: 10px">
  82. <span>{{
  83. isFinishSize
  84. }}M</span>
  85. /
  86. <span>{{
  87. isAllSize
  88. }}M</span>
  89. </div> -->
  90. <!-- <el-progress :text-inside="true" :stroke-width="20" :percentage="progress
  91. ? progress
  92. : 0
  93. " style="width: 80%"></el-progress> -->
  94. </div>
  95. </div>
  96. </div>
  97. <!-- <textarea :readonly="checktype == 2" rows="2" v-autoHeight="68" class="binfo_input binfo_textarea" cols v-model="checkJson.answer2"
  98. placeholder=""></textarea> -->
  99. </div>
  100. </div>
  101. <wpdf :dialogVisiblePdf.sync="dialogVisiblePdf" :url="wurl"></wpdf>
  102. <wVideo :dialogVisibleVideo.sync="dialogVisibleVideo" :url="wurl"></wVideo>
  103. <wOffice :dialogVisibleOffice.sync="dialogVisibleOffice" :url="wurl"></wOffice>
  104. <checkfile :dialogVisiblefile.sync="dialogVisiblefile" @setCheckJson="setCheckJson"></checkfile>
  105. </div>
  106. </template>
  107. <script>
  108. import "../../../../../../common/aws-sdk-2.235.1.min.js";
  109. import videoIcon from '../../../../../../assets/icon/fileIcon/isVideo.png'
  110. import wordIcon from '../../../../../../assets/icon/fileIcon/isWord.png'
  111. import fileIcon from '../../../../../../assets/icon/fileIcon/word2.png'
  112. import wVideo from "../../../file/wVideo.vue";
  113. import wpdf from "../../../file/wPdf2.vue";
  114. import wOffice from "../../../file/wOffice.vue";
  115. import checkfile from "../../../file/checkfile.vue";
  116. export default {
  117. components: {
  118. wpdf,
  119. wVideo,
  120. wOffice,
  121. checkfile
  122. },
  123. props: {
  124. tindex: {
  125. type: Number
  126. },
  127. cJson: {
  128. type: Object,
  129. },
  130. checktype: {
  131. type: Number,
  132. default: 1
  133. },
  134. see: {
  135. type: Boolean,
  136. default: false
  137. }
  138. },
  139. data() {
  140. return {
  141. option: {
  142. 1: { name: '附件' },
  143. },
  144. userid: this.$route.query.userid,
  145. checkJson: undefined,
  146. progress: 0,
  147. isFinishSize: 0,
  148. proVisible: false,
  149. isAllSize: 0,
  150. videoIcon: videoIcon,
  151. wordIcon: wordIcon,
  152. fileIcon: fileIcon,
  153. dialogVisiblePdf: false,
  154. dialogVisibleVideo: false,
  155. dialogVisibleOffice: false,
  156. dialogVisiblefile: false,
  157. wurl: "",
  158. isTong: false
  159. }
  160. },
  161. watch: {
  162. checkJson: {
  163. handler(newValue) {
  164. this.$emit('update:cJson', newValue)
  165. },
  166. deep: true
  167. },
  168. },
  169. methods: {
  170. depthCopy(s) {
  171. return JSON.parse(JSON.stringify(s));
  172. },
  173. openFileBox() {
  174. this.dialogVisiblefile = true
  175. },
  176. addImg(e) {
  177. var el = e.currentTarget;
  178. el.getElementsByTagName("input")[0].click();
  179. e.target.value = "";
  180. },
  181. beforeUpload(event, type) {
  182. // const loading = this.openLoading();
  183. let file = "";
  184. let cfindex2 = 0;
  185. for (var cfindex = 0; cfindex < event.target.files.length; cfindex++) {
  186. file = event.target.files[cfindex];
  187. var credentials = {
  188. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  189. secretAccessKey: "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",
  190. }; //秘钥形式的登录上传
  191. window.AWS.config.update(credentials);
  192. window.AWS.config.region = "cn-northwest-1"; //设置区域
  193. var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
  194. var _this = this;
  195. // _this.progress = 0;
  196. _this.proVisible = true;
  197. // _this.isFinishSize = 0;
  198. // _this.isAllSize = (file.size / 1024 / 1024).toFixed(2);
  199. let _name = file.name
  200. let size = file.size;
  201. _this.$forceUpdate();
  202. if (file) {
  203. var params = {
  204. Key:
  205. file.name.split(".")[0] +
  206. new Date().getTime() +
  207. "." +
  208. file.name.split(".")[file.name.split(".").length - 1],
  209. ContentType: file.type,
  210. Body: file,
  211. "Access-Control-Allow-Credentials": "*",
  212. ACL: "public-read",
  213. }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
  214. var options = {
  215. partSize: 2048 * 1024 * 1024,
  216. queueSize: 2,
  217. leavePartsOnError: true,
  218. };
  219. bucket
  220. .upload(params, options)
  221. .on("httpUploadProgress", function (evt) {
  222. //这里可以写进度条
  223. // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
  224. // _this.progress = parseInt((evt.loaded / evt.total) * 100);
  225. // _this.isFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
  226. // _this.$forceUpdate();
  227. })
  228. .send(function (err, data) {
  229. cfindex2++;
  230. // _this.progress = 100;
  231. // _this.isFinishSize = _this.isAllSize;
  232. // _this.$forceUpdate();
  233. // setTimeout(() => {
  234. // _this.proVisible = false;
  235. // _this.$forceUpdate();
  236. // }, 1000);
  237. setTimeout(() => {
  238. if (
  239. cfindex2 == event.target.files.length ||
  240. cfindex2 > event.target.files.length
  241. ) {
  242. _this.proVisible = false;
  243. }
  244. }, 1000);
  245. // loading.close();
  246. if (err) {
  247. _this.$message.error("上传失败");
  248. } else {
  249. let _type = 2;
  250. var imgA = [
  251. "png",
  252. "jpg",
  253. "jpeg",
  254. "bmp",
  255. "gif",
  256. "webp",
  257. "psd",
  258. "svg",
  259. "tiff",
  260. ];
  261. var fileA = [
  262. "DOC",
  263. "DOCX",
  264. "DOCM",
  265. "DOTM",
  266. "DOTX",
  267. "PPTX",
  268. "PPSX",
  269. "PPT",
  270. "PPS",
  271. "PPTM",
  272. "POTM",
  273. "PPAM",
  274. "POTX",
  275. "PPSM",
  276. "XLSX",
  277. "XLS",
  278. ];
  279. var videoA = [
  280. "AVI",
  281. "NAVI",
  282. "MPEG",
  283. "ASF",
  284. "MOV",
  285. "WMV",
  286. "3GP",
  287. "RM",
  288. "RMVB",
  289. "FLV",
  290. "F4V",
  291. "H.264",
  292. "H.265",
  293. "REAL VIDEO",
  294. "MKV",
  295. "WebM",
  296. "HDDVD",
  297. "MP4",
  298. "MPG",
  299. "M4V",
  300. "MGV",
  301. "OGV",
  302. "QTM",
  303. "STR",
  304. "AMC",
  305. "DVX",
  306. "EVO",
  307. "DAT",
  308. "OGG",
  309. "OGM",
  310. ];
  311. if (
  312. fileA.indexOf(
  313. data.Location.split(".")[
  314. data.Location.split(".").length - 1
  315. ].toLocaleUpperCase()
  316. ) != -1
  317. ) {
  318. _type = 1; //word 文件
  319. } else if (
  320. videoA.indexOf(
  321. data.Location.split(".")[
  322. data.Location.split(".").length - 1
  323. ].toLocaleUpperCase()
  324. ) != -1
  325. ) {
  326. _type = 2; //视频
  327. } else if (
  328. imgA.indexOf(
  329. data.Location.split(".")[
  330. data.Location.split(".").length - 1
  331. ].toLocaleLowerCase()
  332. ) != -1
  333. ) {
  334. _type = 3; //图片
  335. } else if (
  336. 'pdf'.indexOf(
  337. data.Location.split(".")[
  338. data.Location.split(".").length - 1
  339. ].toLocaleLowerCase()
  340. ) != -1
  341. ) {
  342. _type = 4; //pdf
  343. } else {
  344. _type = 5; //文件
  345. }
  346. if (_this.checkJson.file) {
  347. _this.checkJson.file.push({
  348. name: _name,
  349. url: data.Location,
  350. type: _type,
  351. });
  352. } else {
  353. _this.checkJson.file = []
  354. _this.checkJson.file.push({
  355. name: _name,
  356. url: data.Location,
  357. type: _type,
  358. });
  359. }
  360. if(_this.isTong){
  361. let _file = {
  362. name: _name,
  363. url: data.Location,
  364. type: _type,
  365. size: _this.formatFileSize(size)
  366. }
  367. _this.addSource(_file)
  368. }
  369. _this.$forceUpdate();
  370. console.log(_this.checkJson);
  371. console.log(data.Location);
  372. }
  373. });
  374. }
  375. }
  376. },
  377. addSource(file) {
  378. let params = [{
  379. n: file.name,
  380. file: file.url,
  381. type: file.type,
  382. pid: '0',
  383. uid: this.userid,
  384. size: file.size,
  385. }];
  386. this.ajax
  387. .post(this.$store.state.api + "addSourceFile", params)
  388. .then((res) => {
  389. // if (_ctype == 2) {
  390. // this.$message.success('上传成功');
  391. // }
  392. })
  393. .catch((err) => {
  394. console.error(err);
  395. });
  396. },
  397. formatFileSize(bytes) {
  398. if (bytes < 1024) {
  399. return bytes + "B";
  400. } else if (bytes < 1048576) {
  401. return (bytes / 1024).toFixed(2) + "KB";
  402. } else if (bytes < 1073741824) {
  403. return (bytes / 1048576).toFixed(2) + "MB";
  404. } else {
  405. return (bytes / 1073741824).toFixed(2) + "GB";
  406. }
  407. },
  408. setCheckJson(name, url, type) {
  409. if (this.checkJson.file) {
  410. this.checkJson.file.push({
  411. name: name,
  412. url: url,
  413. type: type,
  414. });
  415. } else {
  416. this.checkJson.file = []
  417. this.checkJson.file.push({
  418. name: name,
  419. url: url,
  420. type: type,
  421. });
  422. }
  423. this.$forceUpdate();
  424. },
  425. checkFile(item) {
  426. if (item.type == 3) {
  427. this.$hevueImgPreview(item.url);
  428. } else if (item.type == 5) {
  429. this.downloadFile(item);
  430. } else if (item.type == 1) {
  431. this.dialogVisibleOffice = true
  432. this.wurl = item.url
  433. } else if (item.type == 2) {
  434. this.dialogVisibleVideo = true
  435. this.wurl = item.url
  436. } else if (item.type == 4) {
  437. this.dialogVisiblePdf = true
  438. this.wurl = item.url
  439. }
  440. },
  441. downloadFile(f) {
  442. var credentials = {
  443. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  444. secretAccessKey: "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",
  445. }; //秘钥形式的登录上传
  446. window.AWS.config.update(credentials);
  447. window.AWS.config.region = "cn-northwest-1"; //设置区域
  448. let url2 = f.url;
  449. let _url2 = "";
  450. if (
  451. url2.indexOf("https://view.officeapps.live.com/op/view.aspx?src=") != -1
  452. ) {
  453. _url2 = url2.split(
  454. "https://view.officeapps.live.com/op/view.aspx?src="
  455. )[1];
  456. } else {
  457. _url2 = url2;
  458. }
  459. let _this = this;
  460. _this.downLoading = _url2
  461. var s3 = new window.AWS.S3({ params: { Bucket: "ccrb" } });
  462. let name = decodeURIComponent(_url2.split("https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/")[1])
  463. var params = {
  464. Bucket: "ccrb",
  465. Key: name
  466. };
  467. s3.getObject(params, function (err, data) {
  468. _this.downLoading = ''
  469. if (err) console.log(err, err.stack); // an error occurred
  470. else {
  471. let url = window.URL.createObjectURL(new Blob([data.Body]));
  472. let a = document.createElement("a");
  473. a.name = f.name;
  474. a.href = url;
  475. a.download = f.name;
  476. a.click();
  477. console.log(data);
  478. } // sxuccessful response
  479. });
  480. },
  481. delFile(index) {
  482. this.checkJson.file.splice(index, 1)
  483. this.$forceUpdate();
  484. }
  485. },
  486. mounted() {
  487. this.checkJson = this.cJson ? this.depthCopy(this.cJson) : undefined
  488. }
  489. }
  490. </script>
  491. <style scoped>
  492. .c_box {
  493. width: 100%;
  494. position: relative;
  495. }
  496. /* .mask {
  497. position: absolute;
  498. height: 100%;
  499. width: 100%;
  500. z-index: 2;
  501. } */
  502. .choice_box {
  503. white-space: pre-line;
  504. }
  505. .choice_box>.title {
  506. font-weight: bold;
  507. width: 100%;
  508. word-break: break-all;
  509. }
  510. .choice_box>.choices {
  511. margin-top: 10px;
  512. }
  513. .binfo_input {
  514. width: 100%;
  515. margin: 0;
  516. padding: 10px;
  517. display: block;
  518. min-width: 0;
  519. outline: none;
  520. box-sizing: border-box;
  521. background: none;
  522. border: none;
  523. border-radius: 5px;
  524. background: #fff;
  525. font-size: 16px;
  526. resize: none;
  527. font-family: 'Microsoft YaHei';
  528. min-height: 120px;
  529. /* border: 1px solid #3682fc00; */
  530. border: 1.5px solid #e0e0e0;
  531. position: relative;
  532. }
  533. .binfo_input>.uploadQ {
  534. /* border: 1.5px dashed #dfdfdf; */
  535. height: 120px;
  536. width: 100%;
  537. display: flex;
  538. align-items: center;
  539. justify-content: center;
  540. background: #f9fafb;
  541. color: rgb(124, 124, 124);
  542. border-radius: 5px;
  543. cursor: pointer;
  544. }
  545. .mask {
  546. background-color: rgb(0 0 0 / 30%);
  547. /* position: fixed; */
  548. position: absolute;
  549. top: 0;
  550. left: 0;
  551. width: 100%;
  552. height: 100%;
  553. z-index: 90;
  554. display: flex;
  555. align-items: center;
  556. justify-content: center;
  557. }
  558. .progressBox {
  559. width: 300px;
  560. height: 150px;
  561. background: #fff;
  562. border-radius: 10px;
  563. box-shadow: 0 0 6px 1px #bfbfbf;
  564. display: flex;
  565. align-items: center;
  566. justify-content: center;
  567. flex-direction: column;
  568. position: relative;
  569. color: #6c6c6c;
  570. }
  571. .progressBox>>>.el-progress-bar__outer {
  572. background-color: #d1dfff !important;
  573. }
  574. .progressBox .lbox {
  575. height: 50px;
  576. font-size: 19px;
  577. display: flex;
  578. align-items: center;
  579. color: #747474;
  580. }
  581. .progressBox .lbox img {
  582. width: 40px;
  583. margin-right: 20px;
  584. }
  585. .closeCss {
  586. position: absolute;
  587. top: 8px;
  588. right: 8px;
  589. cursor: pointer;
  590. width: 20px;
  591. height: 20px;
  592. }
  593. .closeCss>img {
  594. width: 100%;
  595. height: 100%;
  596. }
  597. .binfo_input>.fileBox {}
  598. .binfo_input>.fileBox .fileC {
  599. display: flex;
  600. flex-wrap: wrap;
  601. width: 100%;
  602. cursor: pointer;
  603. }
  604. .binfo_input>.fileBox .fileC>.file {
  605. width: 200px;
  606. height: 140px;
  607. margin: 10px 10px 10px 0px;
  608. border-radius: 15px;
  609. box-shadow: rgb(223, 218, 218) 0px 0px 6px 1px;
  610. overflow: hidden;
  611. margin-right: 15px;
  612. position: relative;
  613. display: flex;
  614. flex-direction: column;
  615. }
  616. .binfo_input>.fileBox .fileC>.file>.img {
  617. width: 100%;
  618. height: calc(100% - 35px);
  619. object-fit: cover;
  620. }
  621. .binfo_input>.fileBox .fileC>.file>.del {
  622. position: absolute;
  623. width: 25px;
  624. top: 10px;
  625. right: 10px;
  626. cursor: pointer;
  627. }
  628. .binfo_input>.fileBox .fileC>.file>.download {
  629. position: absolute;
  630. width: 25px;
  631. top: 10px;
  632. right: 35px;
  633. cursor: pointer;
  634. opacity: .8;
  635. }
  636. .binfo_input>.fileBox .fileC>.file>.name {
  637. height: 35px;
  638. width: 100%;
  639. background: #f9f9f9;
  640. display: flex;
  641. align-items: center;
  642. padding: 0 10px;
  643. box-sizing: border-box;
  644. }
  645. .binfo_input>.fileBox .fileC>.file>.name>span {
  646. display: block;
  647. text-overflow: ellipsis;
  648. max-width: 100%;
  649. white-space: nowrap;
  650. overflow: hidden;
  651. }
  652. .binfo_input>.fileBox .btn {
  653. width: 100%;
  654. height: 40px;
  655. background: #007bff;
  656. color: #fff;
  657. border-radius: 15px;
  658. margin-top: 10px;
  659. display: flex;
  660. align-items: center;
  661. justify-content: center;
  662. cursor: pointer;
  663. }
  664. .uploadBtn {
  665. display: flex;
  666. margin-bottom: 10px;
  667. align-items: center;
  668. width: 100%;
  669. justify-content: flex-end;
  670. }
  671. .uploadBtn .btn {
  672. display: flex;
  673. cursor: pointer;
  674. align-items: center;
  675. height: 30px;
  676. padding: 0 8px;
  677. background: #fff;
  678. color: #3681FC;
  679. border: 1px solid #3681FC;
  680. box-sizing: border-box;
  681. border-radius: 4px;
  682. font-size: 14px;
  683. align-items: center;
  684. margin-right: 10px;
  685. }
  686. .uploadBtn .switch{
  687. display: flex;
  688. align-items: center;
  689. cursor: pointer;
  690. }
  691. .uploadBtn .switch > span{
  692. margin-left: 5px;
  693. }
  694. </style>