qiniuTransfer.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. <template>
  2. <div>
  3. <div>
  4. <div class="gva-search-box">
  5. <div>
  6. <el-form ref="searchForm" :inline="true" :model="searchInfo">
  7. <el-form-item label="归属任务">
  8. <el-select v-model="searchInfo.name" size="small" filterable>
  9. <el-option
  10. v-for="item in taskOptions"
  11. :key="item.value"
  12. :label="item.label"
  13. :value="item.value"
  14. />
  15. </el-select>
  16. </el-form-item>
  17. <el-form-item label="负责人">
  18. <el-select v-model="searchInfo.director_name" size="small">
  19. <el-option
  20. v-for="item in directorOptions"
  21. :key="item.value"
  22. :label="item.label"
  23. :value="item.value"
  24. />
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item>
  28. <el-button
  29. size="small"
  30. type="primary"
  31. icon="search"
  32. @click="onSubmit"
  33. >查询</el-button
  34. >
  35. <el-button size="small" icon="refresh" @click="onReset"
  36. >重置</el-button
  37. >
  38. </el-form-item>
  39. </el-form>
  40. </div>
  41. </div>
  42. <div class="gva-search-box" style="padding-bottom: 25px">
  43. <div>
  44. <el-button
  45. size="small"
  46. type="primary"
  47. icon="upload"
  48. @click="navToScript()"
  49. >上传文件</el-button
  50. >
  51. <el-button
  52. v-if="createButtonVisible"
  53. class="excel-btn"
  54. size="small"
  55. type="success"
  56. icon="plus"
  57. @click="switchCreateFolder()"
  58. >新建文件夹</el-button
  59. >
  60. </div>
  61. </div>
  62. <div class="gva-btn-list">
  63. <div class="row center">
  64. <el-breadcrumb :separator-icon="ArrowRight">
  65. <el-breadcrumb-item
  66. v-for="(breadcrumb, index) in breadcrumbList"
  67. :key="index"
  68. >
  69. <a @click="clickBreadcrumb(breadcrumb, index)">{{
  70. breadcrumb.name
  71. }}</a>
  72. </el-breadcrumb-item>
  73. </el-breadcrumb>
  74. </div>
  75. </div>
  76. <div class="gva-table-box">
  77. <div class="video-container">
  78. <el-card shadow="hover">
  79. <div class="video-main">
  80. <ul class="list">
  81. <li
  82. v-for="(file, index) in files"
  83. :key="index"
  84. :class="{ active: file.active }"
  85. class="list-item"
  86. @dblclick="dbClickOpenFile(file)"
  87. >
  88. <el-dropdown
  89. trigger="contextmenu"
  90. :id="String(file.id)"
  91. placement="bottom"
  92. @command="handleCommand"
  93. @visible-change="handleChange($event, String(file.id))"
  94. ref="dropdownRef"
  95. >
  96. <div class="inner">
  97. <img
  98. :src="file.thumUrl ? file.thumUrl : defultThumUrl"
  99. class="icon-thumb"
  100. />
  101. <div class="inner-info" v-if="file.isFile">
  102. <p>
  103. 版本:<span style="font-size: 14px">{{
  104. file.file_version
  105. }}</span>
  106. </p>
  107. </div>
  108. <!-- <i v-else class="icon-folder"></i> -->
  109. <!-- <div v-show="file.resType > 0" class="hover-cover">
  110. <span style="color: #fff">{{
  111. file.size | sizeFilter
  112. }}</span>
  113. </div> -->
  114. </div>
  115. <template #dropdown>
  116. <el-dropdown-menu>
  117. <el-dropdown-item
  118. v-if="file.isFile == false"
  119. :command="beforeHandleCommand('open', file)"
  120. ><el-icon><Open /></el-icon>打开</el-dropdown-item
  121. >
  122. <el-dropdown-item
  123. v-if="file.isFile"
  124. :command="beforeHandleCommand('rename', file)"
  125. ><el-icon><InfoFilled /></el-icon
  126. >重命名</el-dropdown-item
  127. >
  128. <el-dropdown-item
  129. v-if="file.isFile"
  130. :command="beforeHandleCommand('getUrl', file)"
  131. ><el-icon><Share /></el-icon
  132. >获取链接</el-dropdown-item
  133. >
  134. <el-dropdown-item
  135. v-if="file.isFile"
  136. :command="beforeHandleCommand('download', file)"
  137. ><el-icon><Download /></el-icon>下载</el-dropdown-item
  138. >
  139. <el-dropdown-item
  140. v-if="file.isFile"
  141. :command="beforeHandleCommand('delete', file)"
  142. ><el-icon><DeleteFilled /></el-icon
  143. >删除</el-dropdown-item
  144. >
  145. </el-dropdown-menu>
  146. </template>
  147. </el-dropdown>
  148. <!-- <i
  149. class="icon-file-selected"
  150. @click="toggleSelect(file, file.id)"
  151. ></i> -->
  152. <div class="file-name">
  153. <span :title="file.name">{{ file.name }}</span>
  154. </div>
  155. </li>
  156. </ul>
  157. </div>
  158. </el-card>
  159. </div>
  160. </div>
  161. </div>
  162. <el-dialog
  163. title="文件上传界面"
  164. v-model="uploadVisible"
  165. :center="true"
  166. :close-on-click-modal="false"
  167. :close-on-press-escape="false"
  168. >
  169. <el-form
  170. ref="elForm2"
  171. :model="uploadForm"
  172. size="medium"
  173. label-width="100px"
  174. >
  175. <el-form-item label="上传目录" prop="way">
  176. <el-col :span="20">
  177. <el-input
  178. v-model="uploadForm.way"
  179. placeholder="根目录"
  180. disabled
  181. ></el-input>
  182. </el-col>
  183. </el-form-item>
  184. <el-form-item label="关联任务" prop="id">
  185. <el-col :span="20">
  186. <el-input
  187. v-model="uploadForm.task_id"
  188. placeholder="关联任务"
  189. disabled
  190. ></el-input>
  191. </el-col>
  192. </el-form-item>
  193. <el-form-item label="任务名称" prop="name">
  194. <el-col :span="20">
  195. <el-input
  196. v-model="uploadForm.task_name"
  197. placeholder="任务名称"
  198. disabled
  199. ></el-input>
  200. </el-col>
  201. </el-form-item>
  202. <el-form-item label="文件类型" prop="type">
  203. <el-col :span="20">
  204. <el-select
  205. v-model="uploadForm.type"
  206. placeholder="文件类型"
  207. :style="{ width: '100%' }"
  208. @change="selectChanged(uploadForm)"
  209. >
  210. <el-option
  211. v-for="item in fileTypeOptions"
  212. :key="item.value"
  213. :label="item.label"
  214. :value="item.value"
  215. />
  216. </el-select>
  217. </el-col>
  218. </el-form-item>
  219. <el-form-item label="文件名称" prop="qiniuVersion">
  220. <el-col :span="20">
  221. <el-input
  222. v-model="uploadForm.fileName"
  223. placeholder="文件名称,选择文件后自动生成"
  224. disabled
  225. :style="{ width: '100%' }"
  226. ></el-input>
  227. </el-col>
  228. </el-form-item>
  229. <el-form-item v-if="showVersion" label="更新版本" prop="qiniuVersion">
  230. <el-col :span="20">
  231. <el-input
  232. v-model="uploadForm.qiniuVersion"
  233. placeholder="版本号"
  234. disabled
  235. :style="{ width: '100%' }"
  236. ></el-input>
  237. </el-col>
  238. </el-form-item>
  239. <el-form-item v-if="showUpload" label="选择文件" prop="qiniuAddress">
  240. <el-col :span="20">
  241. <el-upload
  242. :limit="1"
  243. action="http://upload-z2.qiniup.com"
  244. :data="qiniuData"
  245. drag
  246. :disabled="disabledUpload"
  247. :show-file-list="false"
  248. :http-request="uploadHttpRequest"
  249. :on-success="handleAvatarSuccess"
  250. :before-upload="beforeAvatarUpload"
  251. :on-progress="onProgress"
  252. >
  253. <div class="el-default" v-if="!progressFlag">
  254. <i class="el-icon-upload"></i>
  255. <div class="el-upload__text">
  256. 将文件拖到此处,或<em> 点击上传 </em>
  257. </div>
  258. </div>
  259. <el-progress
  260. type="circle"
  261. :percentage="progress"
  262. :stroke-width="15"
  263. style="margin-top: 20px"
  264. v-if="progressFlag"
  265. >
  266. </el-progress>
  267. </el-upload>
  268. <!-- 进度条 -->
  269. <!-- <el-progress
  270. v-if="progressFlag"
  271. :text-inside="true"
  272. :percentage="progress"
  273. :stroke-width="15"
  274. :status="status"
  275. ></el-progress> -->
  276. </el-col>
  277. </el-form-item>
  278. <el-form-item>
  279. <el-button size="small" @click="cancelUp(uploadForm)"
  280. >取消上传</el-button
  281. >
  282. <!-- <el-button type="primary" size="small" @click="recordFile(uploadForm)"
  283. >确定上传</el-button
  284. > -->
  285. </el-form-item>
  286. </el-form>
  287. </el-dialog>
  288. <el-dialog
  289. v-model="fileFolderVisible"
  290. title="新建文件夹"
  291. width="50%"
  292. :close-on-press-escape="false"
  293. :show-close="false"
  294. :close-on-click-modal="false"
  295. >
  296. <el-form
  297. v-if="fileFolderVisible"
  298. :inline="true"
  299. :model="formFolder"
  300. :rules="rules"
  301. label-position="left"
  302. label-width="100px"
  303. >
  304. <el-row :gutter="2">
  305. <el-col :span="24">
  306. <el-form-item label="文件夹类型" prop="folder_type">
  307. <!-- <el-select
  308. v-model="formFolder.folder_type"
  309. size="small"
  310. @change="changeFolderType"
  311. >
  312. <el-option label="游戏任务" value="0" />
  313. <el-option label="其他文件" value="1" />
  314. </el-select> -->
  315. <el-select
  316. v-model="formFolder.folder_type"
  317. placeholder="文件夹类型"
  318. :style="{ width: '100%' }"
  319. size="small"
  320. @change="changeFolderType"
  321. >
  322. <el-option
  323. v-for="item in folderTypeOptions"
  324. :key="item.value"
  325. :label="item.label"
  326. :value="item.value"
  327. />
  328. </el-select>
  329. </el-form-item>
  330. </el-col>
  331. </el-row>
  332. <el-row :gutter="2" v-if="taskFolderVisible">
  333. <el-col :span="24">
  334. <el-form-item label="任务名称" prop="task">
  335. <el-select
  336. v-model="formFolder.task"
  337. size="small"
  338. filterable
  339. @change="changeTask"
  340. >
  341. <el-option
  342. v-for="item in taskOptions"
  343. :key="item.value"
  344. :label="item.label"
  345. :value="item.value"
  346. />
  347. </el-select>
  348. </el-form-item>
  349. </el-col>
  350. </el-row>
  351. <el-row :gutter="2">
  352. <el-col :span="24">
  353. <el-form-item label="文件夹名" prop="folder_name">
  354. <el-input
  355. v-model="formFolder.folder_name"
  356. :disabled="disabledFolderName"
  357. />
  358. </el-form-item>
  359. </el-col>
  360. </el-row>
  361. </el-form>
  362. <template #footer>
  363. <div class="dialog-footer">
  364. <el-button size="small" @click="fileFolderVisible = false"
  365. >取 消</el-button
  366. >
  367. <el-button size="small" type="primary" @click="createFolder()"
  368. >确 定</el-button
  369. >
  370. </div>
  371. </template>
  372. </el-dialog>
  373. </div>
  374. </template>
  375. <script>
  376. export default {
  377. name: "qiniuTransfer",
  378. };
  379. </script>
  380. <script setup>
  381. import {
  382. getAllTaskSimple,
  383. addFileFolder,
  384. getFolderFileList,
  385. getQiniuToken,
  386. getAllFileType,
  387. selectFolderMsg,
  388. queryVersionByType,
  389. addQiniuFile,
  390. deleteQiniuFile,
  391. deleteQiniuFileAndRecord,
  392. renameQiniuFileAndRecord,
  393. queryFolder,
  394. } from "@/api/fileManager";
  395. import { getDirectorList } from "@/api/responsiblePerson";
  396. import { ref } from "vue";
  397. import { ElMessage, ElMessageBox } from "element-plus";
  398. import { ArrowRight } from "@element-plus/icons-vue";
  399. // import { number } from "echarts";
  400. import * as qiniu from "qiniu-js";
  401. import { switchCase } from "@babel/types";
  402. //===================
  403. const fileFolderVisible = ref(false);
  404. const taskFolderVisible = ref(false);
  405. const createButtonVisible = ref(true);
  406. const disabledFolderName = ref(false);
  407. const formFolder = ref({
  408. folder_type: "0",
  409. folder_name: "",
  410. task: "",
  411. parentId: 0,
  412. });
  413. const taskOptions = ref();
  414. const fileTypeOptions = ref([]);
  415. const directorOptions = ref();
  416. const currentParentId = ref(0);
  417. const uploadVisible = ref(false);
  418. const progressFlag = ref(false);
  419. const progress = ref(0);
  420. const cance = ref(false);
  421. const disabledUpload = ref(false);
  422. const uploadForm = ref({
  423. way: "",
  424. parentId: 0,
  425. parentName: "",
  426. task_id: 0,
  427. task_name: "",
  428. fileName: "",
  429. type: null,
  430. type_name: "",
  431. qiniuVersion: "",
  432. key: "",
  433. qiniuAddress: "",
  434. qiniuHash: "",
  435. });
  436. const folderTypeOptions = ref([]);
  437. const dropdownRef = ref();
  438. const activeItems = ref([]); // 选中激活的文件列表
  439. const qiniuData = ref({
  440. key: "",
  441. token: "",
  442. cName: "",
  443. }); //七牛上传时获取的服务器信息
  444. const showVersion = ref(false);
  445. const showUpload = ref(false);
  446. const status = ref("exception");
  447. //
  448. async function switchCreateFolder() {
  449. if (breadcrumbList.value.length == 1) {
  450. folderTypeOptions.value = [
  451. { value: "0", label: "游戏任务" },
  452. // { value: "1", label: "其他文件" },
  453. ];
  454. formFolder.value.folder_type = "0";
  455. taskFolderVisible.value = true;
  456. disabledFolderName.value = true;
  457. formFolder.value.folder_name = "";
  458. formFolder.value.task = "";
  459. } else {
  460. folderTypeOptions.value = [
  461. // { value: "0", label: "游戏任务" },
  462. { value: "1", label: "其他文件" },
  463. ];
  464. formFolder.value.folder_type = "1";
  465. taskFolderVisible.value = false;
  466. disabledFolderName.value = false;
  467. formFolder.value.folder_name = "";
  468. formFolder.value.task = "";
  469. }
  470. formFolder.value.parentId =
  471. breadcrumbList.value[breadcrumbList.value.length - 1].id;
  472. if (fileFolderVisible.value == false) {
  473. fileFolderVisible.value = true;
  474. }
  475. if (formFolder.value.folder_type === "0") {
  476. taskFolderVisible.value = true;
  477. disabledFolderName.value = true;
  478. }
  479. const taskListRes = await getAllTaskSimple({
  480. page: 1,
  481. pageSize: 999,
  482. });
  483. let taskList = [];
  484. const data = taskListRes.data.list;
  485. data.forEach((e) => {
  486. taskList.push({
  487. value: e.task_id + "|" + e.task_name,
  488. label: e.task_id + "_" + e.task_name,
  489. });
  490. });
  491. taskOptions.value = taskList;
  492. }
  493. function changeFolderType(e) {
  494. if (e === "0") {
  495. taskFolderVisible.value = true;
  496. disabledFolderName.value = true;
  497. formFolder.value.folder_name = "";
  498. formFolder.value.task = "";
  499. } else {
  500. taskFolderVisible.value = false;
  501. disabledFolderName.value = false;
  502. formFolder.value.folder_name = "";
  503. formFolder.value.task = "";
  504. }
  505. }
  506. function changeTask(e) {
  507. formFolder.value.folder_name = e;
  508. }
  509. const createFolder = async () => {
  510. var task = formFolder.value.task;
  511. var taskArr = task.split("|");
  512. const addFormFolder = {
  513. name: formFolder.value.folder_name,
  514. task_id: Number(taskArr[0]),
  515. parent_id: Number(formFolder.value.parentId),
  516. };
  517. let res = await addFileFolder(addFormFolder);
  518. // console.log(res);
  519. if (res.code === 0) {
  520. ElMessage({
  521. type: "success",
  522. message: "文件夹创建成功!",
  523. });
  524. fileFolderVisible.value = false;
  525. currentParentId.value = res.data.id;
  526. breadcrumbList.value.push({ id: res.data.id, name: res.data.name });
  527. initMaterialPage(currentParentId.value);
  528. } else {
  529. ElMessage({
  530. type: "error",
  531. message: res.message,
  532. });
  533. }
  534. };
  535. //
  536. // 跳转上传界面
  537. async function navToScript() {
  538. if (breadcrumbList.value.length == 1) {
  539. ElMessage.warning("根目录不允许直接上传文件,请先选择进入文件夹!!");
  540. return;
  541. }
  542. uploadForm.value.parentId =
  543. breadcrumbList.value[breadcrumbList.value.length - 1].id;
  544. uploadForm.value.parentName =
  545. breadcrumbList.value[breadcrumbList.value.length - 1].name;
  546. uploadForm.value.way = "";
  547. breadcrumbList.value.forEach((e) => {
  548. uploadForm.value.way += e.name + ">";
  549. });
  550. // console.log(uploadForm.value.parentId);
  551. const folderInfo = await getParentTaskMsg(uploadForm.value.parentId);
  552. // console.log(folderInfo);
  553. if (folderInfo == "") {
  554. uploadForm.value.task_id = "";
  555. uploadForm.value.task_name = "";
  556. } else {
  557. uploadForm.value.task_id = folderInfo.task_id;
  558. uploadForm.value.task_name = folderInfo.task_name;
  559. }
  560. uploadVisible.value = true;
  561. cance.value = false;
  562. showVersion.value = false;
  563. showUpload.value = false;
  564. uploadForm.value.fileName = "";
  565. uploadForm.value.type = null;
  566. uploadForm.value.qiniuVersion = "";
  567. uploadForm.value.qiniuAddress = "";
  568. progressFlag.value = false;
  569. await getFileTypeOptions();
  570. disabledUpload.value = false;
  571. await getToken();
  572. }
  573. // 查询所有文件类型
  574. async function getFileTypeOptions() {
  575. fileTypeOptions.value = [];
  576. const res = await getAllFileType();
  577. if (res.code === 0) {
  578. for (let i = 0; i < res.data.list.length; i++) {
  579. var temp = {
  580. typeId: res.data.list[i].id,
  581. value: i,
  582. label: res.data.list[i].name + res.data.list[i].describe,
  583. name: res.data.list[i].name,
  584. type: res.data.list[i].describe,
  585. };
  586. fileTypeOptions.value.push(temp);
  587. }
  588. }
  589. }
  590. //查询上传目录是否关联任务id并返回
  591. async function getParentTaskMsg(id) {
  592. const res = await selectFolderMsg({ id: Number(id) });
  593. // console.log(res);
  594. if (res.msg == "获取成功") {
  595. return res.data.data;
  596. }
  597. return "";
  598. }
  599. const handleChange = (visible, id) => {
  600. if (!visible) return;
  601. dropdownRef.value.forEach((item) => {
  602. if (item.id == id) return;
  603. item.handleClose();
  604. });
  605. };
  606. /**
  607. * 动态设置Dropdown的command
  608. */
  609. function beforeHandleCommand(flag, command) {
  610. // flag为传递的参数
  611. return {
  612. flag: flag,
  613. command: command,
  614. };
  615. }
  616. const handleCommand = (val) => {
  617. switch (val.flag) {
  618. case "open":
  619. dbClickOpenFile(val.command);
  620. break;
  621. case "download":
  622. downloadFile(val.command);
  623. break;
  624. case "delete":
  625. deleteFile(val.command);
  626. break;
  627. case "getUrl":
  628. getUrl(val.command);
  629. break;
  630. case "rename":
  631. rename(val.command);
  632. break;
  633. default:
  634. break;
  635. }
  636. };
  637. //文件重命名
  638. async function rename(file) {
  639. ElMessageBox.prompt("请输入新的文件名", "重命名", {
  640. confirmButtonText: "确认",
  641. cancelButtonText: "取消",
  642. inputPattern:
  643. /(?!((^(con)$)|^(con)\..*|(^(prn)$)|^(prn)\..*|(^(aux)$)|^(aux)\..*|(^(nul)$)|^(nul)\..*|(^(com)[1-9]$)|^(com)[1-9]\..*|(^(lpt)[1-9]$)|^(lpt)[1-9]\..*)|^\s+|.*\s$)(^[^\\\/\:\*\?\"\<\>\|]{1,255}$)/,
  644. inputErrorMessage: "不允许这样命名",
  645. inputValue: file.name,
  646. })
  647. .then(async ({ value }) => {
  648. const res = await renameQiniuFileAndRecord({
  649. id: file.id,
  650. file_name: file.name,
  651. file_name_new: value,
  652. qiniu_key: file.qiniu_key,
  653. });
  654. // console.log(res);
  655. if (res.code == 0) {
  656. ElMessage.success(res.msg);
  657. initMaterialPage(currentParentId.value);
  658. }
  659. })
  660. .catch(() => {
  661. // ElMessage({
  662. // type: "info",
  663. // message: "Input canceled",
  664. // });
  665. });
  666. }
  667. //获取下载链接
  668. async function getUrl(file) {
  669. ElMessageBox.alert(
  670. "<strong>" + file.qiniu_address + "</strong>",
  671. "下载链接",
  672. {
  673. dangerouslyUseHTMLString: true,
  674. showClose: false,
  675. }
  676. );
  677. }
  678. //从七牛云删除文件并且清除数据库记录
  679. async function deleteFile(file) {
  680. // console.log(file);
  681. ElMessageBox.confirm("确定删除此文件?", "警告", {
  682. type: "warning",
  683. })
  684. .then(async () => {
  685. const res = await deleteQiniuFileAndRecord({
  686. id: file.id,
  687. qiniu_key: file.qiniu_key,
  688. });
  689. if (res.code == 0) {
  690. ElMessage.success(res.msg);
  691. initMaterialPage(currentParentId.value);
  692. }
  693. })
  694. .catch(() => null);
  695. }
  696. //下载文件
  697. async function downloadFile(file) {
  698. // console.log(file);
  699. // console.log(file.qiniu_address);
  700. // let url = window.URL.createObjectURL(new Blob([file.qiniu_address]));
  701. // let link = document.createElement("a");
  702. // link.style.display = "none";
  703. // link.href = url;
  704. // link.setAttribute("download", file.name); //指定下载后的文件名,防跳转
  705. // document.body.appendChild(link);
  706. // link.click();
  707. // // 释放内存
  708. // window.URL.revokeObjectURL(link.href);
  709. // 创建 a 标签
  710. const a = document.createElement("a");
  711. // 创建一个点击事件
  712. const event = new MouseEvent("click");
  713. // 将 a 的 download 属性设置为想要下载的名称
  714. a.download = file.name || "文件名称";
  715. // 将生成的 url 设置为 a.href 属性
  716. a.href = file.qiniu_address;
  717. // 打开新的窗口(如果是一个图片类型的文件,在浏览器打开新的标签页打开)
  718. // a.target = "_blank";
  719. // 实现触发生成的 a 标签
  720. a.dispatchEvent(event);
  721. }
  722. //获取七牛token
  723. async function getToken() {
  724. const res = await getQiniuToken();
  725. if (res.code === 0) {
  726. qiniuData.value.token = res.data.token;
  727. qiniuData.value.cName = res.data.cName;
  728. // console.log(qiniuData);
  729. } else {
  730. ElMessageBox.alert(err, "提示", {
  731. confirmButtonText: "关闭",
  732. });
  733. }
  734. }
  735. async function selectChanged(aaa) {
  736. // 查询该类型对应最新版本号并+1
  737. const res = await queryVersionByType({
  738. task_id: aaa.task_id,
  739. file_type: fileTypeOptions.value[uploadForm.value.type].typeId,
  740. });
  741. // console.log(res);
  742. if (res.code == 0) {
  743. uploadForm.value.qiniuVersion = parseInt(res.data.fileVersion) + 1;
  744. } else {
  745. }
  746. showVersion.value = true;
  747. showUpload.value = true;
  748. }
  749. // 取消上传文件
  750. async function cancelUp(aaa) {
  751. //中断文件传输
  752. cance.value = true;
  753. uploadVisible.value = false;
  754. // console.log(qiniuData.value.key);
  755. var qiniu_key = qiniuData.value.key;
  756. if (qiniu_key == "") {
  757. return;
  758. }
  759. //取消上传时从七牛云删除已上传的文件
  760. const res = await deleteQiniuFile({
  761. qiniu_key: qiniu_key,
  762. });
  763. // console.log(res);
  764. if (res.code == 0) {
  765. ElMessage.success(res.msg);
  766. }
  767. }
  768. //上传前处理
  769. function beforeAvatarUpload(file) {
  770. progressFlag.value = false;
  771. const fileFirst = file.name.substring(0, file.name.lastIndexOf("."));
  772. const fileLast = file.name.substring(file.name.lastIndexOf(".") + 1);
  773. //
  774. const limitType = fileTypeOptions.value[uploadForm.value.type].type;
  775. let isALL = limitType.substring(limitType.lastIndexOf(".") + 1);
  776. if (isALL == "*") {
  777. } else if (fileLast == "" || isALL != fileLast) {
  778. ElMessageBox.alert("只能上传" + isALL + "格式的文件", "提示", {
  779. confirmButtonText: "关闭",
  780. });
  781. return false;
  782. }
  783. let folder =
  784. "shuyou/" +
  785. uploadForm.value.task_id +
  786. "|" +
  787. uploadForm.value.task_name +
  788. "/" +
  789. fileTypeOptions.value[uploadForm.value.type].name +
  790. "/" +
  791. fileFirst +
  792. "_" +
  793. new Date().getTime() +
  794. "." +
  795. fileLast;
  796. uploadForm.value.fileName =
  797. fileFirst + "_" + new Date().getTime() + "." + fileLast;
  798. qiniuData.value.key = folder;
  799. // console.log(folder);
  800. disabledUpload.value = true;
  801. }
  802. //确定上传,记录文件信息在数据库中
  803. async function recordFile(aaa) {
  804. console.log(aaa);
  805. const params = {
  806. parent_id: aaa.parentId,
  807. task_id: aaa.task_id,
  808. file_version: aaa.qiniuVersion,
  809. qiniu_address: aaa.qiniuAddress,
  810. file_name: aaa.fileName,
  811. file_type: aaa.type,
  812. file_type_name: aaa.type_name,
  813. qiniu_hash: aaa.qiniuHash,
  814. qiniu_key: aaa.key,
  815. };
  816. let res = await addQiniuFile(params);
  817. if (res.code === 0) {
  818. uploadVisible.value = false;
  819. ElMessage.success("文件记录成功!!!");
  820. }
  821. cance.value = false;
  822. initMaterialPage(currentParentId.value);
  823. }
  824. //上传成功
  825. function handleAvatarSuccess(res) {
  826. // console.log(res);
  827. // 七牛云对外域名qiniuData.value.cName
  828. const fileUrl = qiniuData.value.cName + res.key;
  829. const fileHash = res.hash;
  830. // console.log(fileUrl);
  831. uploadForm.value.key = res.key;
  832. uploadForm.value.qiniuAddress = fileUrl;
  833. uploadForm.value.qiniuHash = fileHash;
  834. uploadForm.value.type_name =
  835. fileTypeOptions.value[uploadForm.value.type].name;
  836. uploadForm.value.type = fileTypeOptions.value[uploadForm.value.type].typeId;
  837. setTimeout(() => {
  838. recordFile(uploadForm.value);
  839. }, 1000); // 一秒后执行保存
  840. }
  841. //进度条显示
  842. function onProgress(event, file, fileList) {
  843. progressFlag.value = true; // 显示进度条
  844. progress.value = parseInt(event.percent); // 动态获取文件上传进度
  845. status.value = "exception";
  846. if (progress.value >= 100) {
  847. status.value = "success";
  848. // setTimeout(() => {
  849. // progressFlag.value = false;
  850. // }, 1000); // 一秒后关闭进度条
  851. } else if (progress.value >= 50) {
  852. status.value = "warning";
  853. }
  854. }
  855. //自定义上传操作
  856. function uploadHttpRequest(option) {
  857. // 开始上传,token从后端获取, key自定义也可从后端获取(key可以说是文件名)
  858. const putExtra = {};
  859. const config = {
  860. checkByServer: false,
  861. checkByMD5: false,
  862. forceDirect: false,
  863. useCdnDomain: true,
  864. disableStatisticsReport: false,
  865. concurrentRequestLimit: 10,
  866. retryCount: 4,
  867. chunkSize: 100, //分片时每片大小
  868. // region: qiniu.region.z2,
  869. debugLogLevel: "OFF",
  870. };
  871. const observable = qiniu.upload(
  872. option.file,
  873. qiniuData.value.key,
  874. qiniuData.value.token,
  875. putExtra,
  876. config
  877. );
  878. let subscription = observable.subscribe({
  879. // 以下相关代码就是将七牛云的回调函数给el-upload
  880. //让el-upload能够展示进度条
  881. next(res) {
  882. option.onProgress({ percent: res.total.percent });
  883. if (cance.value == true) {
  884. console.log("上传取消");
  885. ElMessage.error("上传取消");
  886. subscription.unsubscribe(); // 上传取消
  887. }
  888. },
  889. error(err) {
  890. option.onError(err);
  891. },
  892. complete(res) {
  893. option.onSuccess(res);
  894. },
  895. });
  896. return subscription;
  897. }
  898. function toggleSelect(item, id) {
  899. // 切换选择文件或文件夹的激活样式
  900. // this.id = id;
  901. // if (item.active) {
  902. // Vue.set(item, "active", false); // 为item添加不存在的属性,需要使用vue提供的Vue.set( object, key, value )方法
  903. // const index = this.activeItems.indexOf(id);
  904. // if (index > -1) {
  905. // this.activeItems.splice(index, 1);
  906. // }
  907. // } else {
  908. // Vue.set(item, "active", true);
  909. // this.activeItems.push(id);
  910. // }
  911. // if (this.activeItems.length > 0) {
  912. // // 当有文件被激活时,显示重命名,删除,移动操作按钮
  913. // this.activeFlag = true;
  914. // } else {
  915. // this.activeFlag = false;
  916. // }
  917. // if (this.activeItems.length > 1) {
  918. // // 当有两个以上的文件被选中的时候,重命名,移动操作按钮不可用
  919. // this.activeFlagNotReame = true;
  920. // } else {
  921. // this.activeFlagNotReame = false;
  922. // }
  923. // this.activeFlagMoveble = true;
  924. // this.files.forEach((item) => {
  925. // if (item.active) {
  926. // if (item.resType !== 0) {
  927. // // 只要有一个不是文件夹的被选中,就可以移动
  928. // this.activeFlagMoveble = false;
  929. // }
  930. // }
  931. // });
  932. }
  933. //===================
  934. const rules = ref({
  935. folder_type: [
  936. { required: true, message: "请选择文件夹类型", trigger: "blur" },
  937. ],
  938. folder_name: [{ required: true, message: "请输入文件夹名", trigger: "blur" }],
  939. });
  940. const page = ref(1);
  941. const pageSize = ref(20);
  942. const searchInfo = ref({});
  943. let breadcrumbList = ref([
  944. {
  945. id: 0,
  946. name: "根目录",
  947. },
  948. ]); // 面包屑
  949. let files = ref([]); // 文件数据列表
  950. const defultThumUrl = ref("src/assets/defultThumUrl.png"); // 默认文件夹的样式图片
  951. function clickBreadcrumb(breadcrumb, index) {
  952. breadcrumbList.value = breadcrumbList.value.slice(0, index + 1);
  953. currentParentId.value = breadcrumb.id;
  954. this.initMaterialPage(currentParentId.value);
  955. if (breadcrumbList.value.length == 1) {
  956. createButtonVisible.value = true;
  957. } else {
  958. createButtonVisible.value = false;
  959. }
  960. }
  961. function dbClickOpenFile(file) {
  962. // 双击文件操作
  963. if (file.isFile) {
  964. return;
  965. }
  966. // 打开的是文件夹
  967. breadcrumbList.value.push({ id: file.id, name: file.name });
  968. currentParentId.value = file.id;
  969. // console.log(file);
  970. // console.log(currentParentId.value);
  971. initMaterialPage(currentParentId.value);
  972. if (breadcrumbList.value.length == 1) {
  973. createButtonVisible.value = true;
  974. } else {
  975. createButtonVisible.value = false;
  976. }
  977. }
  978. async function initMaterialPage(id = 0) {
  979. searchInfo.value.parent_id = id;
  980. files.value = [];
  981. // 初始化获取
  982. const table = await getFolderFileList({
  983. // page: page.value,
  984. // pageSize: pageSize.value,
  985. ...searchInfo.value,
  986. });
  987. if (table.code === 0) {
  988. // console.log(table);
  989. const folderList = table.data.folderList;
  990. const fileList = table.data.fileList;
  991. if (folderList != null) {
  992. for (let i = 0; i < table.data.folderList.length; i++) {
  993. var temp = {
  994. id: table.data.folderList[i].id,
  995. name: table.data.folderList[i].name,
  996. isFile: false,
  997. };
  998. files.value.push(temp);
  999. }
  1000. }
  1001. if (fileList != null) {
  1002. for (let i = 0; i < table.data.fileList.length; i++) {
  1003. var temp = {
  1004. id: table.data.fileList[i].id,
  1005. name: table.data.fileList[i].file_name,
  1006. isFile: true,
  1007. update_time: table.data.fileList[i].update_time,
  1008. file_version: table.data.fileList[i].file_version,
  1009. qiniu_address: table.data.fileList[i].qiniu_address,
  1010. qiniu_key: table.data.fileList[i].qiniu_key,
  1011. qiniu_hash: table.data.fileList[i].qiniu_hash,
  1012. thumUrl: "",
  1013. };
  1014. switch (table.data.fileList[i].file_type) {
  1015. case 1:
  1016. temp.thumUrl = "src/assets/file_type_dll.svg";
  1017. break;
  1018. case 2:
  1019. temp.thumUrl = "src/assets/file_type_ld.svg";
  1020. break;
  1021. case 3:
  1022. temp.thumUrl = "src/assets/file_type_apk.svg";
  1023. break;
  1024. case 4:
  1025. temp.thumUrl = "src/assets/file_type_yeshen.webp";
  1026. break;
  1027. default:
  1028. temp.thumUrl = "src/assets/file_type_other.svg";
  1029. break;
  1030. }
  1031. files.value.push(temp);
  1032. }
  1033. }
  1034. }
  1035. }
  1036. //获取下拉框list
  1037. const getSelectList = async () => {
  1038. const taskListRes = await getAllTaskSimple({
  1039. page: 1,
  1040. pageSize: 999,
  1041. });
  1042. let taskList = [];
  1043. const data = taskListRes.data.list;
  1044. data.forEach((e) => {
  1045. taskList.push({
  1046. value: e.task_id + "|" + e.task_name,
  1047. label: e.task_id + "_" + e.task_name,
  1048. });
  1049. });
  1050. taskOptions.value = taskList;
  1051. //游戏负责人列表===============================
  1052. const directorRes = await getDirectorList();
  1053. let directorList = [];
  1054. const data3 = directorRes.data.list;
  1055. data3.forEach((e) => {
  1056. if (e.name != "备用") {
  1057. directorList.push({ value: e.name, label: e.name });
  1058. }
  1059. });
  1060. directorOptions.value = directorList;
  1061. };
  1062. const onReset = () => {
  1063. searchInfo.value = {};
  1064. };
  1065. const onSubmit = async () => {
  1066. // console.log(searchInfo.value)
  1067. files.value = [];
  1068. const table = await queryFolder({
  1069. ...searchInfo.value,
  1070. });
  1071. if (table.code === 0) {
  1072. // // console.log(table);
  1073. const folderList = table.data.folderList;
  1074. if (folderList != null) {
  1075. for (let i = 0; i < table.data.folderList.length; i++) {
  1076. var temp = {
  1077. id: table.data.folderList[i].id,
  1078. name: table.data.folderList[i].name,
  1079. isFile: false,
  1080. };
  1081. files.value.push(temp);
  1082. }
  1083. }
  1084. }
  1085. };
  1086. getSelectList();
  1087. initMaterialPage();
  1088. </script>
  1089. <style scoped lang="scss">
  1090. .button-box {
  1091. padding: 10px 20px;
  1092. .el-button {
  1093. float: right;
  1094. }
  1095. }
  1096. .warning {
  1097. color: #dc143c;
  1098. }
  1099. .clearfix:after {
  1100. content: "";
  1101. display: block;
  1102. clear: both;
  1103. }
  1104. .video-container {
  1105. min-width: 630px;
  1106. margin: 10px;
  1107. .video-header {
  1108. padding: 0 0 5px 0;
  1109. border-bottom: 1px solid #dbdbdb;
  1110. .breadcrumb {
  1111. // float: left;
  1112. height: 20px;
  1113. margin-top: 10px;
  1114. .breadcrumb-link {
  1115. cursor: pointer;
  1116. //font-size: 16px;
  1117. }
  1118. .breadcrumb-link:hover {
  1119. color: #409eff;
  1120. text-decoration: underline;
  1121. }
  1122. .breadcrumb-link-active {
  1123. // 面包屑当前激活文件夹的样式
  1124. font-weight: 700;
  1125. }
  1126. }
  1127. .header-top {
  1128. // float: right;
  1129. height: 40px;
  1130. line-height: 40px;
  1131. position: relative;
  1132. }
  1133. }
  1134. .video-main {
  1135. .list-item {
  1136. border: 1px solid rgb(241, 241, 241);
  1137. border-radius: 5%;
  1138. box-sizing: border-box;
  1139. position: relative;
  1140. height: 125px;
  1141. width: 160px;
  1142. background-color: rgb(241, 241, 241);
  1143. margin: 5px;
  1144. display: inline-block;
  1145. cursor: pointer;
  1146. .inner {
  1147. height: 85px;
  1148. width: 140px;
  1149. // background-color: red;
  1150. margin: 5px 10px;
  1151. // padding: 10px 15px 10px 15px;
  1152. .icon-folder {
  1153. // 文件夹的样式
  1154. display: inline-block;
  1155. width: 80px;
  1156. height: 80px;
  1157. background-image: url(../../assets/defultThumUrl.png);
  1158. background-size: 100% 100%;
  1159. }
  1160. .icon-thumb {
  1161. // 文件的样式
  1162. width: 80px;
  1163. height: 80px;
  1164. }
  1165. .inner-info {
  1166. float: right;
  1167. // border: 1px solid #409eff;
  1168. width: 45px;
  1169. height: 20px;
  1170. margin-top: 30px;
  1171. }
  1172. }
  1173. .file-name {
  1174. // 文件夹name样式
  1175. padding-left: 10px;
  1176. overflow: hidden;
  1177. text-overflow: ellipsis;
  1178. white-space: nowrap;
  1179. color: #424e67;
  1180. font-size: 12px;
  1181. }
  1182. .file-name:hover {
  1183. color: rgb(0, 123, 255);
  1184. }
  1185. }
  1186. .hover-cover {
  1187. width: 100px;
  1188. height: 100px;
  1189. position: absolute;
  1190. left: 10px;
  1191. top: 5px;
  1192. background-color: rgb(0, 0, 0);
  1193. opacity: 0;
  1194. text-align: center;
  1195. line-height: 100px;
  1196. font-size: 12px;
  1197. }
  1198. .list-item:hover {
  1199. background-color: rgb(212, 212, 212);
  1200. .icon-file-selected {
  1201. opacity: 0.5;
  1202. }
  1203. .hover-cover {
  1204. opacity: 0.6;
  1205. }
  1206. }
  1207. .icon-file-selected {
  1208. // 小圆点默认样式
  1209. position: absolute;
  1210. right: 5px;
  1211. top: 5px;
  1212. display: inline-block;
  1213. width: 20px;
  1214. height: 20px;
  1215. background-size: 100% 100%;
  1216. background-image: url(../../assets/selected.svg);
  1217. opacity: 0;
  1218. }
  1219. .icon-file-selected:hover {
  1220. // 小圆点hover
  1221. opacity: 1 !important;
  1222. }
  1223. .active {
  1224. // 选择文件触发激活样式
  1225. border: 1px solid #409eff;
  1226. border-radius: 8px;
  1227. .icon-file-selected {
  1228. position: absolute;
  1229. right: 5px;
  1230. top: 5px;
  1231. display: inline-block;
  1232. width: 20px;
  1233. height: 20px;
  1234. background-size: 100% 100%;
  1235. background-image: url(../../assets/selected.svg);
  1236. opacity: 1;
  1237. }
  1238. }
  1239. .active:hover {
  1240. // 激活状态小圆点透明度1
  1241. .icon-file-selected {
  1242. opacity: 1 !important;
  1243. }
  1244. }
  1245. // .loadding-message {
  1246. // // 加载loading的文字样式
  1247. // color: #424e67;
  1248. // font-size: 12px;
  1249. // text-align: center;
  1250. // }
  1251. }
  1252. }
  1253. </style>