qiniuTransfer.vue 37 KB

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