Index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. <template>
  2. <div class="blue-background">
  3. <div class="lighter-container">
  4. <div class="left-row">
  5. <div>
  6. <div>状态:</div>
  7. <el-tag
  8. size="large"
  9. :effect="focusTaskStatus.includes('all') ? 'dark' : ''"
  10. type="primary"
  11. @click="changeTaskStatus()"
  12. >
  13. 全部
  14. </el-tag>
  15. <template v-for="status in taskStatus" :key="status.index">
  16. <el-tag
  17. size="large"
  18. :effect="focusTaskStatus.includes(status.index) ? 'dark' : ''"
  19. type="primary"
  20. @click="changeTaskStatus(status)"
  21. >
  22. {{ status.name }}
  23. </el-tag>
  24. </template>
  25. </div>
  26. <div>
  27. <div>类别:</div>
  28. <el-tag
  29. size="large"
  30. :effect="focusTaskType.includes('all') ? 'dark' : ''"
  31. type="primary"
  32. @click="changeTaskType()"
  33. >
  34. 全部
  35. </el-tag>
  36. <template v-for="type in taskType" :key="type.index">
  37. <el-tag
  38. size="large"
  39. :effect="focusTaskType.includes(type.index) ? 'dark' : ''"
  40. type="primary"
  41. @click="changeTaskType(type)"
  42. >
  43. {{ type.name }}
  44. </el-tag>
  45. </template>
  46. </div>
  47. </div>
  48. <div class="row">
  49. <el-input
  50. class="searcher"
  51. v-model="searcher"
  52. placeholder="请输入任务名称相关关键字"
  53. />
  54. <el-button type="primary" @click="pullTaskData(1)">搜索</el-button>
  55. <el-button type="primary" @click="reset(), pullTaskData(1)">重置</el-button>
  56. </div>
  57. </div>
  58. <div class="lighter-container">
  59. 查询到{{ taskNum }}条任务
  60. <el-table table-layout="fixed" row-key="main_id" :data="taskData" class="table">
  61. <el-table-column prop="main_c_name" label="名称" />
  62. <el-table-column prop="main_c_user_name" label="用户" />
  63. <el-table-column prop="main_c_state" label="类型">
  64. <template #default="scope">
  65. <el-tag
  66. effect="dark"
  67. v-show="getType(scope.row.main_c_type) != null"
  68. disable-transitions
  69. >{{ getType(scope.row.main_c_type)?.name ?? "" }}
  70. </el-tag>
  71. </template>
  72. </el-table-column>
  73. <el-table-column prop="main_c_state" label="状态">
  74. <template #default="scope">
  75. <el-tag
  76. effect="dark"
  77. v-show="getStatus(scope.row.main_c_state) != null"
  78. :type="statusStaticInfo[scope.row.main_c_state]?.tagType ?? ''"
  79. disable-transitions
  80. >{{ getStatus(scope.row.main_c_state)?.name ?? "" }}</el-tag
  81. >
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="main_c_start_time" label="任务开始时间">
  85. <template #default="scope">
  86. {{ timeFormatter(scope.row.main_c_start_time) }}
  87. </template>
  88. </el-table-column>
  89. <el-table-column prop="main_c_end_time" label="任务结束时间">
  90. <template #default="scope">
  91. {{ timeFormatter(scope.row.main_c_end_time) }}
  92. </template>
  93. </el-table-column>
  94. <el-table-column prop="main_c_file_name" label="结果">
  95. <template #default="scope">
  96. <span
  97. class="link"
  98. v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
  99. @click="downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)"
  100. >
  101. {{ scope.row.main_c_file_name }}
  102. </span>
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="操作" width="360">
  106. <template #default="scope">
  107. <el-button
  108. type="primary"
  109. @click="
  110. () => {
  111. dialog = true;
  112. focusTask = scope.row;
  113. }
  114. "
  115. >
  116. 查看详情
  117. </el-button>
  118. <template
  119. v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
  120. >
  121. <el-button
  122. type="primary"
  123. @click="
  124. downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)
  125. "
  126. >
  127. 下载结果
  128. </el-button>
  129. <el-button type="primary" @click="preView(scope.row.main_c_file)">
  130. 预览结果
  131. </el-button>
  132. </template>
  133. </template>
  134. </el-table-column>
  135. </el-table>
  136. <div class="between-row">
  137. <div><!--empty div--></div>
  138. <el-pagination
  139. layout="prev, pager, next"
  140. :total="taskNum"
  141. @change="(page) => pullTaskData(page)"
  142. />
  143. </div>
  144. </div>
  145. <el-dialog v-model="dialog" :show-close="true" width="750">
  146. <template #header>
  147. <div class="my-header">
  148. <span class="second-title">{{ focusTask.main_c_name }}</span>
  149. </div>
  150. </template>
  151. <el-descriptions class="margin-top" label-width="128" :column="1" border>
  152. <el-descriptions-item label="任务名称">
  153. {{ focusTask.main_c_name }}
  154. </el-descriptions-item>
  155. <el-descriptions-item label="任务描述">
  156. {{ focusTask.main_c_comment }}
  157. </el-descriptions-item>
  158. <el-descriptions-item label="任务类型">
  159. <el-tag
  160. effect="dark"
  161. v-show="getType(focusTask.main_c_type) != null"
  162. disable-transitions
  163. >{{ getType(focusTask.main_c_type)?.name ?? "" }}
  164. </el-tag>
  165. </el-descriptions-item>
  166. <el-descriptions-item label="用户名">
  167. {{ focusTask.main_c_user_name }}
  168. </el-descriptions-item>
  169. <el-descriptions-item label="用户id">
  170. {{ focusTask.main_c_user_id }}
  171. </el-descriptions-item>
  172. <el-descriptions-item label="状态">
  173. <el-tag
  174. effect="dark"
  175. :type="statusStaticInfo[focusTask.main_c_state]?.tagType ?? ''"
  176. disable-transitions
  177. >{{ getStatus(focusTask.main_c_state)?.name ?? "" }}
  178. </el-tag>
  179. </el-descriptions-item>
  180. <el-descriptions-item label="任务开始时间">
  181. {{ timeFormatter(focusTask.main_c_start_time) }}
  182. </el-descriptions-item>
  183. <el-descriptions-item label="任务结束时间">
  184. {{ timeFormatter(focusTask.main_c_end_time) }}
  185. </el-descriptions-item>
  186. <el-descriptions-item label="结果文件">
  187. {{ focusTask.main_c_file_name }}
  188. <template
  189. v-if="focusTask.main_c_file != null && focusTask.main_c_file_name != null"
  190. >
  191. <el-button
  192. type="primary"
  193. size="small"
  194. @click="downloadWithBlob(focusTask.main_c_file, focusTask.main_c_file_name)"
  195. >
  196. 下载结果
  197. </el-button>
  198. <el-button
  199. type="primary"
  200. size="small"
  201. @click="preView(focusTask.main_c_file)"
  202. >
  203. 预览结果
  204. </el-button>
  205. </template>
  206. </el-descriptions-item>
  207. <el-descriptions-item label="原始数据">
  208. <template
  209. v-if="
  210. focusTask.main_c_source_file_name != null &&
  211. focusTask.main_c_source_file != null
  212. "
  213. >
  214. {{ focusTask.main_c_source_file_name }}
  215. <br />
  216. </template>
  217. <template v-if="focusTask.main_c_source_data != null">
  218. <div class="hide-scrollbar long-text">
  219. {{ truncateText(focusTask.main_c_source_data, 10000) }}
  220. </div>
  221. </template>
  222. </el-descriptions-item>
  223. </el-descriptions>
  224. </el-dialog>
  225. </div>
  226. </template>
  227. <script>
  228. import { getTasks, getCName } from "@/api/rwgl";
  229. export default {
  230. data() {
  231. return {
  232. searcher: "",
  233. taskStatus: [],
  234. focusTaskStatus: ["all"],
  235. statusStaticInfo: {
  236. 0: {
  237. tagType: "primary",
  238. },
  239. 1: {
  240. tagType: "primary",
  241. },
  242. 2: {
  243. tagType: "success",
  244. },
  245. 3: {
  246. tagType: "danger",
  247. },
  248. },
  249. taskType: [],
  250. focusTaskType: ["all"],
  251. taskData: [],
  252. taskNum: 0,
  253. focusTask: {},
  254. dialog: false,
  255. page: 1,
  256. };
  257. },
  258. mounted() {
  259. this.pullTaskStatus();
  260. this.pullTaskType();
  261. this.pullTaskData(1);
  262. },
  263. methods: {
  264. async pullTaskStatus() {
  265. this.taskStatus = (await getCName("task_status")).sort((a, b) => a.index - b.index);
  266. },
  267. changeTaskStatus(status) {
  268. if (status == null) {
  269. this.focusTaskStatus = ["all"];
  270. } else {
  271. let set = new Set(this.focusTaskStatus);
  272. set.delete("all");
  273. let index = status.index;
  274. if (this.focusTaskStatus.includes(index)) {
  275. set.delete(index);
  276. } else {
  277. set.add(index);
  278. }
  279. this.focusTaskStatus = Array.from(set);
  280. }
  281. // if(this.taskStatus.length==this.focusTaskStatus.length){
  282. // this.focusTaskStatus = ["all"]
  283. // }
  284. },
  285. getCheckedStatus() {
  286. if (this.focusTaskStatus.includes("all")) {
  287. return null;
  288. } else {
  289. return this.focusTaskStatus;
  290. }
  291. },
  292. getStatus(index) {
  293. for (let i = 0; i < this.taskStatus.length; i++) {
  294. const e = this.taskStatus[i];
  295. if (e.index == index) {
  296. return e;
  297. }
  298. }
  299. },
  300. async pullTaskType() {
  301. this.taskType = (await getCName("yzt_task_type")).sort((a, b) => a.index - b.index);
  302. },
  303. changeTaskType(types) {
  304. if (types == null) {
  305. this.focusTaskType = ["all"];
  306. } else {
  307. let set = new Set(this.focusTaskType);
  308. set.delete("all");
  309. let index = types.index;
  310. if (this.focusTaskType.includes(index)) {
  311. set.delete(index);
  312. } else {
  313. set.add(index);
  314. }
  315. this.focusTaskType = Array.from(set);
  316. }
  317. },
  318. getCheckedType() {
  319. if (this.focusTaskType.includes("all")) {
  320. return null;
  321. } else {
  322. return this.focusTaskType;
  323. }
  324. },
  325. getType(index) {
  326. for (let i = 0; i < this.taskType.length; i++) {
  327. const e = this.taskType[i];
  328. if (e.index == index) {
  329. return e;
  330. }
  331. }
  332. },
  333. async pullTaskData(page) {
  334. if (page != null) this.page = page;
  335. let res = await getTasks(
  336. this.page,
  337. 10,
  338. this.searcher,
  339. this.getCheckedStatus(),
  340. this.getCheckedType()
  341. );
  342. this.taskNum = res.count;
  343. this.taskData = res.data;
  344. },
  345. timeFormatter(time) {
  346. if (time == null) return;
  347. let date = new Date(time);
  348. return date.toLocaleString();
  349. },
  350. async downloadWithBlob(url, filename) {
  351. try {
  352. const response = await fetch(systemConfig.dmsDataProxy + url);
  353. const blob = await response.blob();
  354. const blobUrl = window.URL.createObjectURL(blob);
  355. const link = document.createElement("a");
  356. link.href = blobUrl;
  357. link.download = filename || "file";
  358. link.click();
  359. // 清理URL对象
  360. window.URL.revokeObjectURL(blobUrl);
  361. } catch (error) {
  362. console.error("下载失败:", error);
  363. }
  364. },
  365. reset() {
  366. this.focusTaskStatus = ["all"];
  367. this.searcher = "";
  368. },
  369. preView(url) {
  370. window.open("fileView?url=" + systemConfig.dmsDataProxy + url, "_blank");
  371. },
  372. truncateText(text, maxLength = 40) {
  373. if (typeof text !== "string" || text.length <= maxLength) {
  374. return text;
  375. }
  376. return text.substring(0, maxLength) + "…";
  377. },
  378. },
  379. };
  380. </script>
  381. <style lang="less" scoped>
  382. * {
  383. --el-table-bg-color: #eeeeee0b;
  384. /* 表格背景 */
  385. --el-table-header-bg-color: #eeeeee0b;
  386. /* 表头背景 */
  387. --el-table-tr-bg-color: #eeeeee0b;
  388. /* 行背景 */
  389. --el-table-row-hover-bg-color: #eeeeee0b;
  390. /* 行悬浮背景 */
  391. --el-table-header-text-color: #ededed;
  392. /* 表头文字颜色 */
  393. }
  394. .font,
  395. .title,
  396. .super-title,
  397. .title-sub,
  398. .second-title,
  399. .third-title,
  400. .strong-data,
  401. link {
  402. color: #fff;
  403. }
  404. .hide-scrollbar {
  405. -ms-overflow-style: none;
  406. /* IE和Edge */
  407. scrollbar-width: none;
  408. /* Firefox */
  409. }
  410. .hide-scrollbar::-webkit-scrollbar {
  411. display: none;
  412. /* Chrome, Safari和Opera */
  413. }
  414. .long-text {
  415. width: 100%;
  416. height: 200px;
  417. overflow: scroll;
  418. }
  419. .icon {
  420. color: #fff;
  421. fill: currentColor;
  422. }
  423. .middle {
  424. text-align: center;
  425. }
  426. .darkblue-background,
  427. .dark-background,
  428. .bluedark-background,
  429. .blue-background,
  430. .image-background {
  431. padding-top: 40px;
  432. padding-bottom: 40px;
  433. margin-left: 0;
  434. padding-left: 90px;
  435. padding-right: 90px;
  436. min-height: 600px;
  437. }
  438. .darkblue-background {
  439. background: linear-gradient(to bottom, #02060c 0%, #0f3460 40%, #0f3460 100%);
  440. }
  441. .dark-background {
  442. background: #0a0a08;
  443. }
  444. .blue-background,
  445. body {
  446. background: #0f3460;
  447. }
  448. .bluedark-background {
  449. background: linear-gradient(to bottom, #0f3460 0%, #0f3460 60%, #02060c 100%);
  450. }
  451. .image-background {
  452. background-repeat: no-repeat;
  453. background-position: center;
  454. background-size: 100% auto;
  455. }
  456. .lighter-container {
  457. background-color: #eeeeee0b;
  458. padding: 10px;
  459. margin: 15px;
  460. vertical-align: middle;
  461. border-radius: 3%;
  462. }
  463. .lightblue-container {
  464. border-radius: 3%;
  465. padding: 10px;
  466. margin: 15px;
  467. background: linear-gradient(to bottom, #215476 0%, #28638b 66%, #337aac 100%);
  468. font-size: 20px;
  469. .third-title {
  470. font-size: 28px;
  471. padding: 0;
  472. }
  473. }
  474. .middle-container {
  475. display: flex !important;
  476. justify-content: center;
  477. flex-direction: column;
  478. padding: 0;
  479. align-items: stretch;
  480. }
  481. .row,
  482. .warp-row,
  483. .between-row,
  484. .left-row {
  485. display: flex !important;
  486. justify-content: space-around;
  487. padding: 0;
  488. align-items: stretch;
  489. }
  490. .warp-row {
  491. flex-wrap: wrap;
  492. }
  493. .between-row {
  494. justify-content: space-between;
  495. }
  496. .left-row {
  497. justify-content: flex-start;
  498. }
  499. .left-row > * {
  500. margin-right: 15px;
  501. }
  502. .col {
  503. display: flex !important;
  504. justify-content: space-around;
  505. flex-direction: column;
  506. }
  507. .dense-col {
  508. display: flex !important;
  509. justify-content: center;
  510. flex-direction: column;
  511. }
  512. .start-reverse-col {
  513. display: flex !important;
  514. justify-content: start;
  515. flex-direction: column-reverse;
  516. }
  517. .dense-col > *,
  518. .start-reverse-col > * {
  519. margin: 10px;
  520. }
  521. .grid-2x2 {
  522. display: grid !important;
  523. grid-template-columns: 1fr 1fr;
  524. gap: 12px;
  525. width: 100%;
  526. height: 80%;
  527. }
  528. .strong-data {
  529. font-size: 32px;
  530. font-weight: bold;
  531. text-align: center;
  532. }
  533. .title {
  534. font-size: 36px;
  535. margin-top: 10px;
  536. text-align: center;
  537. font-weight: bold;
  538. }
  539. .super-title {
  540. font-size: 44px;
  541. margin-top: 10px;
  542. text-align: center;
  543. font-weight: bold;
  544. }
  545. .title-sub {
  546. font-size: 16px;
  547. margin-top: 10px;
  548. color: rgb(192, 192, 192);
  549. text-align: center;
  550. }
  551. .second-title {
  552. font-size: 20px;
  553. margin-top: 10px;
  554. padding-left: 10px;
  555. border-left: 2px solid #3498db;
  556. font-weight: bold;
  557. }
  558. .third-title {
  559. font-size: 18px;
  560. margin-top: 10px;
  561. padding-left: 10px;
  562. display: flex;
  563. font-weight: bold;
  564. }
  565. .link {
  566. font-weight: bold;
  567. /* 字体加粗 */
  568. text-decoration: underline;
  569. /* 下划线 */
  570. cursor: pointer;
  571. /* 鼠标悬浮时变为手型(可点击形式) */
  572. }
  573. .searcher {
  574. background-color: #334155;
  575. margin-right: 15px;
  576. }
  577. .blue {
  578. color: #3498db;
  579. }
  580. .grey {
  581. color: rgb(192, 192, 192);
  582. }
  583. .lightgrey {
  584. color: rgb(229, 229, 229);
  585. }
  586. #echart1 {
  587. width: 100%;
  588. height: 450px;
  589. }
  590. .container {
  591. width: 1920px;
  592. margin: 0 auto;
  593. }
  594. </style>