Index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. <template>
  2. <el-affix :offset="0">
  3. <div style="height: 44px; width: 100vw; background: #00002a"></div>
  4. </el-affix>
  5. <el-affix :offset="44">
  6. <div class="blue-background">
  7. <div style="padding: 0px 20px;margin: 0px 15px;">
  8. <div class="left-row">
  9. <div>
  10. <span>状态:</span>
  11. <el-tag
  12. size="large"
  13. :effect="focusTaskStatus.includes('all') ? 'dark' : ''"
  14. type="primary"
  15. @click="changeTaskStatus()"
  16. style="cursor: pointer; margin: 10px 5px"
  17. >
  18. 全部
  19. </el-tag>
  20. <template v-for="status in taskStatus" :key="status.index">
  21. <el-tag
  22. size="large"
  23. :effect="focusTaskStatus.includes(status.index) ? 'dark' : ''"
  24. type="primary"
  25. @click="changeTaskStatus(status)"
  26. style="cursor: pointer; margin: 10px 5px"
  27. >
  28. {{ status.name }}
  29. </el-tag>
  30. </template>
  31. </div>
  32. <div>
  33. <span>类别:</span>
  34. <el-tag
  35. size="large"
  36. :effect="focusTaskType.includes('all') ? 'dark' : ''"
  37. type="primary"
  38. @click="changeTaskType()"
  39. style="cursor: pointer; margin: 10px 5px"
  40. >
  41. 全部
  42. </el-tag>
  43. <template v-for="type in taskType" :key="type.index">
  44. <el-tag
  45. size="large"
  46. :effect="focusTaskType.includes(type.index) ? 'dark' : ''"
  47. type="primary"
  48. @click="changeTaskType(type)"
  49. style="cursor: pointer; margin: 10px 5px"
  50. >
  51. {{ type.name }}
  52. </el-tag>
  53. </template>
  54. </div>
  55. <div class="row-search">
  56. <el-input
  57. size="mini"
  58. class="searcher"
  59. v-model="searcher"
  60. placeholder="请输入任务名称相关关键字"
  61. />
  62. <el-button type="primary" @click="pullTaskData(1)">搜索</el-button>
  63. <el-button class="reset-btn" @click="reset(), pullTaskData(1)">重置</el-button>
  64. </div>
  65. </div>
  66. <!-- <div class="row">
  67. <el-input
  68. class="searcher"
  69. v-model="searcher"
  70. placeholder="请输入任务名称相关关键字"
  71. />
  72. <el-button type="primary" @click="pullTaskData(1)">搜索</el-button>
  73. <el-button type="primary" @click="reset(), pullTaskData(1)">重置</el-button>
  74. </div> -->
  75. </div>
  76. <div class="lighter-container">
  77. <!-- <div style="padding-bottom: 10px">检索出{{ taskNum }}条任务</div> -->
  78. <el-table table-layout="fixed" row-key="main_id" :data="taskData" class="table"
  79. :header-cell-style="headerCellStyle"
  80. :row-style="rowStyle"
  81. :cell-style="cellStyle"
  82. stripe
  83. border>
  84. <el-table-column prop="main_c_name" label="名称" />
  85. <el-table-column prop="main_c_user_name" label="用户" />
  86. <el-table-column prop="main_c_state" label="类型">
  87. <template #default="scope">
  88. <el-tag
  89. effect="dark"
  90. v-show="getType(scope.row.main_c_type) != null"
  91. disable-transitions
  92. >{{ getType(scope.row.main_c_type)?.name ?? "" }}
  93. </el-tag>
  94. </template>
  95. </el-table-column>
  96. <el-table-column prop="main_c_state" label="状态">
  97. <template #default="scope">
  98. <el-tag
  99. effect="dark"
  100. v-show="getStatus(scope.row.main_c_state) != null"
  101. :type="statusStaticInfo[scope.row.main_c_state]?.tagType ?? ''"
  102. disable-transitions
  103. >{{ getStatus(scope.row.main_c_state)?.name ?? "" }}</el-tag
  104. >
  105. </template>
  106. </el-table-column>
  107. <el-table-column prop="main_c_start_time" label="任务开始时间">
  108. <template #default="scope">
  109. {{ timeFormatter(scope.row.main_c_start_time) }}
  110. </template>
  111. </el-table-column>
  112. <el-table-column prop="main_c_end_time" label="任务结束时间">
  113. <template #default="scope">
  114. {{ timeFormatter(scope.row.main_c_end_time) }}
  115. </template>
  116. </el-table-column>
  117. <el-table-column prop="main_c_file_name" label="结果">
  118. <template #default="scope">
  119. <span
  120. class="link"
  121. v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
  122. @click="
  123. downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)
  124. "
  125. >
  126. {{ scope.row.main_c_file_name }}
  127. </span>
  128. </template>
  129. </el-table-column>
  130. <el-table-column label="操作" width="420">
  131. <template #default="scope">
  132. <el-button
  133. type="primary"
  134. @click="
  135. () => {
  136. dialog = true;
  137. focusTask = scope.row;
  138. }
  139. "
  140. >
  141. 查看详情
  142. </el-button>
  143. <el-button
  144. v-if="scope.row.main_c_state == 0"
  145. type="success"
  146. @click="runTask(scope.row.main_id)"
  147. >
  148. 运行
  149. </el-button>
  150. <el-button
  151. v-if="scope.row.main_c_state == 3"
  152. type="warning"
  153. @click="runTask(scope.row.main_id)"
  154. >
  155. 重试
  156. </el-button>
  157. <template
  158. v-if="scope.row.main_c_file != null && scope.row.main_c_file_name != null"
  159. >
  160. <el-button
  161. type="primary"
  162. @click="
  163. downloadWithBlob(scope.row.main_c_file, scope.row.main_c_file_name)
  164. "
  165. >
  166. 下载结果
  167. </el-button>
  168. <el-button type="primary" v-if="scope.row.main_c_file.includes('.json') || scope.row.main_c_file.includes('.geojson') || scope.row.main_c_file.includes('.xlsx') || scope.row.main_c_file.includes('.xls')" @click="preView(scope.row.main_c_file)">
  169. 预览结果
  170. </el-button>
  171. </template>
  172. </template>
  173. </el-table-column>
  174. </el-table>
  175. <!-- <div class="between-row pagination-container">
  176. <div></div>
  177. <el-pagination
  178. layout="prev, pager, next"
  179. :total="taskNum"
  180. @change="(page) => pullTaskData(page)"
  181. />
  182. </div> -->
  183. <div class="between-row pagination-container">
  184. <span class="total-text">检索出{{ taskNum }}条任务</span>
  185. <el-pagination
  186. layout="prev, pager, next, jumper, total"
  187. :total="taskNum"
  188. :current-page="page"
  189. :page-size="pageSize"
  190. @current-change="pullTaskData"
  191. >
  192. </el-pagination>
  193. </div>
  194. </div>
  195. <el-dialog v-model="dialog" :show-close="true" width="750">
  196. <template #header>
  197. <div class="my-header">
  198. <span class="second-title">{{ focusTask.main_c_name }}</span>
  199. </div>
  200. </template>
  201. <el-descriptions class="margin-top" label-width="128" :column="1" border>
  202. <el-descriptions-item label="任务名称">
  203. {{ focusTask.main_c_name }}
  204. </el-descriptions-item>
  205. <el-descriptions-item label="任务描述">
  206. {{ focusTask.main_c_comment }}
  207. </el-descriptions-item>
  208. <el-descriptions-item label="任务类型">
  209. <el-tag
  210. effect="dark"
  211. v-show="getType(focusTask.main_c_type) != null"
  212. disable-transitions
  213. >{{ getType(focusTask.main_c_type)?.name ?? "" }}
  214. </el-tag>
  215. </el-descriptions-item>
  216. <el-descriptions-item label="用户名">
  217. {{ focusTask.main_c_user_name }}
  218. </el-descriptions-item>
  219. <el-descriptions-item label="用户id">
  220. {{ focusTask.main_c_user_id }}
  221. </el-descriptions-item>
  222. <el-descriptions-item label="状态">
  223. <el-tag
  224. effect="dark"
  225. :type="statusStaticInfo[focusTask.main_c_state]?.tagType ?? ''"
  226. disable-transitions
  227. >{{ getStatus(focusTask.main_c_state)?.name ?? "" }}
  228. </el-tag>
  229. </el-descriptions-item>
  230. <el-descriptions-item label="任务开始时间">
  231. {{ timeFormatter(focusTask.main_c_start_time) }}
  232. </el-descriptions-item>
  233. <el-descriptions-item label="任务结束时间">
  234. {{ timeFormatter(focusTask.main_c_end_time) }}
  235. </el-descriptions-item>
  236. <el-descriptions-item label="结果文件">
  237. {{ focusTask.main_c_file_name }}
  238. <template
  239. v-if="focusTask.main_c_file != null && focusTask.main_c_file_name != null"
  240. >
  241. <el-button
  242. type="primary"
  243. size="small"
  244. @click="
  245. downloadWithBlob(focusTask.main_c_file, focusTask.main_c_file_name)
  246. "
  247. >
  248. 下载结果
  249. </el-button>
  250. <el-button
  251. type="primary"
  252. size="small"
  253. @click="preView(focusTask.main_c_file)"
  254. >
  255. 预览结果
  256. </el-button>
  257. </template>
  258. <el-button
  259. v-if="focusTask.main_c_state == 3"
  260. type="warning"
  261. size="small"
  262. style="margin-left: 8px"
  263. @click="runTask(focusTask.main_id)"
  264. >
  265. 重新执行
  266. </el-button>
  267. </el-descriptions-item>
  268. <el-descriptions-item label="原始数据">
  269. <template
  270. v-if="
  271. focusTask.main_c_source_file_name != null &&
  272. focusTask.main_c_source_file != null
  273. "
  274. >
  275. {{ focusTask.main_c_source_file_name }}
  276. <br />
  277. </template>
  278. <template v-if="focusTask.main_c_source_data != null">
  279. <div class="hide-scrollbar long-text">
  280. {{ truncateText(focusTask.main_c_source_data, 10000) }}
  281. </div>
  282. </template>
  283. </el-descriptions-item>
  284. </el-descriptions>
  285. </el-dialog>
  286. </div>
  287. </el-affix>
  288. </template>
  289. <script>
  290. import { getTasks, getCName, executeTask } from "@/api/rwgl";
  291. export default {
  292. data() {
  293. return {
  294. searcher: "",
  295. taskStatus: [],
  296. focusTaskStatus: ["all"],
  297. statusStaticInfo: {
  298. 0: {
  299. tagType: "primary",
  300. },
  301. 1: {
  302. tagType: "primary",
  303. },
  304. 2: {
  305. tagType: "success",
  306. },
  307. 3: {
  308. tagType: "danger",
  309. },
  310. },
  311. taskType: [],
  312. focusTaskType: ["all"],
  313. taskData: [],
  314. taskNum: 0,
  315. focusTask: {},
  316. dialog: false,
  317. page: 1,
  318. pageSize: 10,
  319. tableHeight: 0,
  320. };
  321. },
  322. computed: {
  323. headerCellStyle() {
  324. return {
  325. // backgroundColor: "rgba(24, 144, 255, 0.25)",
  326. color: "#fff",
  327. fontWeight: "bold",
  328. // borderBottom: "2px solid rgba(24, 144, 255, 0.3)",
  329. padding: "12px 8px",
  330. };
  331. },
  332. rowStyle() {
  333. return {
  334. // 调整行背景色为更浅的黑色,增加透明度
  335. backgroundColor: "rgba(0, 0, 0, 0.05)",
  336. borderBottom: "1px solid rgba(255, 255, 255, 0.05)",
  337. transition: "all 0.3s ease",
  338. };
  339. },
  340. cellStyle() {
  341. return {
  342. color: "#e0e0e0",
  343. padding: "12px 8px",
  344. borderRight: "1px solid rgba(255, 255, 255, 0.05)",
  345. };
  346. },
  347. },
  348. mounted() {
  349. this.pullTaskStatus();
  350. this.pullTaskType();
  351. this.pullTaskData(1);
  352. this.calculateTableHeight();
  353. window.addEventListener("resize", this.calculateTableHeight);
  354. },
  355. beforeUnmount() {
  356. window.removeEventListener("resize", this.calculateTableHeight);
  357. },
  358. methods: {
  359. async pullTaskStatus() {
  360. let oData = this.$getDmsTypes("task_status");
  361. let newData = [];
  362. for (const key of Object.keys(oData)) {
  363. newData.push({
  364. index: Number(key),
  365. name: oData[key],
  366. });
  367. }
  368. this.taskStatus = newData.sort((a, b) => a.index - b.index);
  369. },
  370. changeTaskStatus(status) {
  371. if (status == null) {
  372. this.focusTaskStatus = ["all"];
  373. } else {
  374. let set = new Set(this.focusTaskStatus);
  375. set.delete("all");
  376. let index = status.index;
  377. if (this.focusTaskStatus.includes(index)) {
  378. set.delete(index);
  379. } else {
  380. set.add(index);
  381. }
  382. this.focusTaskStatus = Array.from(set);
  383. }
  384. // if(this.taskStatus.length==this.focusTaskStatus.length){
  385. // this.focusTaskStatus = ["all"]
  386. // }
  387. },
  388. getCheckedStatus() {
  389. if (this.focusTaskStatus.includes("all")) {
  390. return null;
  391. } else {
  392. return this.focusTaskStatus;
  393. }
  394. },
  395. getStatus(index) {
  396. for (let i = 0; i < this.taskStatus.length; i++) {
  397. const e = this.taskStatus[i];
  398. if (e.index == index) {
  399. return e;
  400. }
  401. }
  402. },
  403. async pullTaskType() {
  404. let oData = this.$getDmsTypes("yzt_task_type");
  405. let newData = [];
  406. for (const key of Object.keys(oData)) {
  407. newData.push({
  408. index: Number(key),
  409. name: oData[key],
  410. });
  411. }
  412. let taskType = newData.sort((a, b) => a.index - b.index);
  413. for (let i = 0; i < taskType.length; i++) {
  414. const e = taskType[i];
  415. if (e.index === 100) {
  416. const otherItem = taskType.splice(i, 1)[0];
  417. taskType.push(otherItem);
  418. break;
  419. }
  420. }
  421. this.taskType = taskType;
  422. },
  423. changeTaskType(types) {
  424. if (types == null) {
  425. this.focusTaskType = ["all"];
  426. } else {
  427. let set = new Set(this.focusTaskType);
  428. set.delete("all");
  429. let index = types.index;
  430. if (this.focusTaskType.includes(index)) {
  431. set.delete(index);
  432. } else {
  433. set.add(index);
  434. }
  435. this.focusTaskType = Array.from(set);
  436. }
  437. },
  438. getCheckedType() {
  439. if (this.focusTaskType.includes("all")) {
  440. return null;
  441. } else {
  442. return this.focusTaskType;
  443. }
  444. },
  445. getType(index) {
  446. for (let i = 0; i < this.taskType.length; i++) {
  447. const e = this.taskType[i];
  448. if (e.index == index) {
  449. return e;
  450. }
  451. }
  452. },
  453. async pullTaskData(page) {
  454. if (page != null) this.page = page;
  455. let res = await getTasks(
  456. this.page,
  457. this.pageSize,
  458. this.searcher,
  459. this.getCheckedStatus(),
  460. this.getCheckedType()
  461. );
  462. this.taskNum = res.count;
  463. this.taskData = res.data;
  464. },
  465. timeFormatter(time) {
  466. if (time == null) return "";
  467. let date = new Date(time);
  468. return date.toLocaleString();
  469. },
  470. async downloadWithBlob(url, filename) {
  471. try {
  472. const response = await fetch(systemConfig.dmsDataProxy + url);
  473. const blob = await response.blob();
  474. const blobUrl = window.URL.createObjectURL(blob);
  475. const link = document.createElement("a");
  476. link.href = blobUrl;
  477. link.download = filename || "file";
  478. link.click();
  479. // 清理URL对象
  480. window.URL.revokeObjectURL(blobUrl);
  481. } catch (error) {
  482. console.error("下载失败:", error);
  483. }
  484. },
  485. reset() {
  486. this.focusTaskStatus = ["all"];
  487. this.searcher = "";
  488. },
  489. preView(url) {
  490. window.open("fileView?url=" + systemConfig.dmsDataProxy + url, "_blank");
  491. },
  492. async runTask(taskId) {
  493. try {
  494. const res = await executeTask(taskId);
  495. if (res.code === 200) {
  496. this.$message({
  497. type: "success",
  498. message: res.content || "任务已提交,正在后台执行",
  499. });
  500. // 先禁用按钮,防止重复点击
  501. this.$refs.runTaskBtn.disabled = true;
  502. // 刷新任务列表
  503. setTimeout(() => {
  504. // 执行成功后,刷新任务列表
  505. this.pullTaskData(this.page);
  506. }, 300);
  507. } else {
  508. this.$message({
  509. type: "error",
  510. message: res.message || "执行任务失败",
  511. });
  512. }
  513. } catch (error) {
  514. console.error("执行任务失败:", error);
  515. this.$message({
  516. type: "error",
  517. message: "执行任务失败,请稍后重试",
  518. });
  519. }
  520. },
  521. truncateText(text, maxLength = 40) {
  522. if (typeof text !== "string" || text.length <= maxLength) {
  523. return text;
  524. }
  525. return text.substring(0, maxLength) + "…";
  526. },
  527. calculateTableHeight() {
  528. // 计算表格高度:窗口高度 - header高度 - footer高度 - 页面padding - 其他元素高度
  529. const windowHeight = window.innerHeight;
  530. const headerHeight = 70; // Header组件高度
  531. const footerHeight = 50; // Footer组件高度
  532. const pagePadding = 40 * 2; // 页面上下padding
  533. const filterAreaHeight = 120; // 筛选条件区域高度
  534. const taskCountHeight = 30; // 任务数量文字高度
  535. const paginationHeight = 50; // 分页区域高度
  536. const containerMargin = 15 * 2; // 容器上下margin
  537. this.tableHeight =
  538. windowHeight -
  539. headerHeight -
  540. footerHeight -
  541. pagePadding -
  542. filterAreaHeight -
  543. taskCountHeight -
  544. paginationHeight -
  545. containerMargin;
  546. },
  547. },
  548. };
  549. </script>
  550. <style lang="less" scoped>
  551. // * {
  552. // --el-table-bg-color: #eeeeee0b;
  553. // /* 表格背景 */
  554. // --el-table-header-bg-color: #eeeeee0b;
  555. // /* 表头背景 */
  556. // --el-table-tr-bg-color: #eeeeee0b;
  557. // /* 行背景 */
  558. // --el-table-row-hover-bg-color: #eeeeee0b;
  559. // /* 行悬浮背景 */
  560. // --el-table-header-text-color: #ededed;
  561. // /* 表头文字颜色 */
  562. // }
  563. // 美化表格行悬停效果
  564. :deep(.el-table__body tr:hover > td) {
  565. background-color: rgba(24, 144, 255, 0.1) !important;
  566. }
  567. // 美化表格边框
  568. :deep(.el-table__inner-wrapper) {
  569. border-radius: 6px;
  570. overflow: hidden;
  571. }
  572. :deep(.el-table__cell) {
  573. border-right: 1px solid rgba(255, 255, 255, 0.05);
  574. }
  575. :deep(.el-table__row) {
  576. border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  577. }
  578. // 调整奇偶行背景色,使其更明亮
  579. :deep(.el-table--striped .el-table__body tr.el-table__row--striped) {
  580. background-color: rgba(255, 255, 255, 0.02) !important;
  581. }
  582. // 调整表格主体背景色
  583. :deep(.el-table__body) {
  584. background-color: rgba(0, 0, 0, 0.05);
  585. }
  586. :deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
  587. background-color: rgba(255, 255, 255, 0.02);
  588. }
  589. :deep(.el-tag--primary){
  590. background-color: rgba(0, 0, 0, 0);
  591. color: #fff;
  592. }
  593. :deep(.el-tag--dark){
  594. background-color: var(--el-color-primary);
  595. }
  596. .font,
  597. .title,
  598. .super-title,
  599. .title-sub,
  600. .second-title,
  601. .third-title,
  602. .strong-data,
  603. link {
  604. color: #fff;
  605. }
  606. .hide-scrollbar {
  607. -ms-overflow-style: none;
  608. /* IE和Edge */
  609. scrollbar-width: none;
  610. /* Firefox */
  611. }
  612. .hide-scrollbar::-webkit-scrollbar {
  613. display: none;
  614. /* Chrome, Safari和Opera */
  615. }
  616. .long-text {
  617. width: 100%;
  618. height: 200px;
  619. overflow: scroll;
  620. }
  621. .icon {
  622. color: #fff;
  623. fill: currentColor;
  624. }
  625. .middle {
  626. text-align: center;
  627. }
  628. .darkblue-background,
  629. .dark-background,
  630. .bluedark-background,
  631. .blue-background,
  632. .image-background {
  633. padding-top: 40px;
  634. padding-bottom: 40px;
  635. margin-left: 0;
  636. padding-left: 90px;
  637. padding-right: 90px;
  638. // min-height: 80vh
  639. height: 100vh;
  640. }
  641. .darkblue-background {
  642. background: linear-gradient(to bottom, #02060c 0%, #0f3460 40%, #0f3460 100%);
  643. }
  644. .dark-background {
  645. background: #0a0a08;
  646. }
  647. .blue-background,
  648. body {
  649. background: #00002a;
  650. }
  651. .bluedark-background {
  652. background: linear-gradient(to bottom, #0f3460 0%, #0f3460 60%, #02060c 100%);
  653. }
  654. .image-background {
  655. background-repeat: no-repeat;
  656. background-position: center;
  657. background-size: 100% auto;
  658. }
  659. .lighter-container {
  660. background-color: #eeeeee0b;
  661. padding: 20px;
  662. margin: 15px;
  663. vertical-align: middle;
  664. border-radius: 10px;
  665. }
  666. .task-count {
  667. margin-bottom: 10px;
  668. color: #fff;
  669. }
  670. .pagination-container {
  671. margin-top: 15px;
  672. }
  673. .lightblue-container {
  674. border-radius: 3%;
  675. padding: 20px;
  676. margin: 15px;
  677. background: linear-gradient(to bottom, #215476 0%, #28638b 66%, #337aac 100%);
  678. font-size: 20px;
  679. .third-title {
  680. font-size: 28px;
  681. padding: 0;
  682. }
  683. }
  684. .middle-container {
  685. display: flex !important;
  686. justify-content: center;
  687. flex-direction: column;
  688. padding: 0;
  689. align-items: stretch;
  690. }
  691. .row,
  692. .warp-row,
  693. .between-row,
  694. .left-row {
  695. display: flex !important;
  696. justify-content: space-between;
  697. padding: 0;
  698. align-items: stretch;
  699. }
  700. .row-search{
  701. display: flex !important;
  702. justify-content: space-between;
  703. align-items: center;
  704. }
  705. .warp-row {
  706. flex-wrap: wrap;
  707. }
  708. .between-row {
  709. justify-content: space-between;
  710. }
  711. .left-row {
  712. justify-content: space-between;
  713. }
  714. .left-row > * {
  715. // margin-right: 15px;
  716. }
  717. .col {
  718. display: flex !important;
  719. justify-content: space-around;
  720. flex-direction: column;
  721. }
  722. .dense-col {
  723. display: flex !important;
  724. justify-content: center;
  725. flex-direction: column;
  726. }
  727. .start-reverse-col {
  728. display: flex !important;
  729. justify-content: start;
  730. flex-direction: column-reverse;
  731. }
  732. .dense-col > *,
  733. .start-reverse-col > * {
  734. margin: 10px;
  735. }
  736. .grid-2x2 {
  737. display: grid !important;
  738. grid-template-columns: 1fr 1fr;
  739. gap: 12px;
  740. width: 100%;
  741. height: 80%;
  742. }
  743. .strong-data {
  744. font-size: 32px;
  745. font-weight: bold;
  746. text-align: center;
  747. }
  748. .title {
  749. font-size: 36px;
  750. margin-top: 10px;
  751. text-align: center;
  752. font-weight: bold;
  753. }
  754. .super-title {
  755. font-size: 44px;
  756. margin-top: 10px;
  757. text-align: center;
  758. font-weight: bold;
  759. }
  760. .title-sub {
  761. font-size: 16px;
  762. margin-top: 10px;
  763. color: rgb(192, 192, 192);
  764. text-align: center;
  765. }
  766. .second-title {
  767. font-size: 20px;
  768. margin-top: 10px;
  769. padding-left: 10px;
  770. border-left: 2px solid #3498db;
  771. font-weight: bold;
  772. }
  773. .third-title {
  774. font-size: 18px;
  775. margin-top: 10px;
  776. padding-left: 10px;
  777. display: flex;
  778. font-weight: bold;
  779. }
  780. .link {
  781. font-weight: bold;
  782. /* 字体加粗 */
  783. text-decoration: underline;
  784. /* 下划线 */
  785. cursor: pointer;
  786. /* 鼠标悬浮时变为手型(可点击形式) */
  787. }
  788. .searcher {
  789. background-color: #00002a;
  790. margin-right: 15px;
  791. width: 500px;
  792. height: 34px;
  793. }
  794. .blue {
  795. color: #3498db;
  796. }
  797. .grey {
  798. color: rgb(192, 192, 192);
  799. }
  800. .lightgrey {
  801. color: rgb(229, 229, 229);
  802. }
  803. #echart1 {
  804. width: 100%;
  805. height: 450px;
  806. }
  807. .container {
  808. width: 1920px;
  809. margin: 0 auto;
  810. }
  811. </style>