Index.vue 15 KB

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