queryNew.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. <template>
  2. <!-- 唯一根节点:el-card -->
  3. <el-card class="el-content-wrap mb-3px" shadow="never">
  4. <!-- 标题 + 提示 -->
  5. <template v-if="title" slot="header">
  6. <div class="flex items-center">
  7. <span class="text-16px font-700">{{ title }}</span>
  8. <el-tooltip v-if="message" effect="dark" placement="right">
  9. <template slot="content">
  10. <div class="max-w-200px">{{ message }}</div>
  11. </template>
  12. <i class="el-icon-question ml-5px" style="font-size: 14px" />
  13. </el-tooltip>
  14. </div>
  15. </template>
  16. <!-- 原 content-wrap 的 slot 内容 -->
  17. <el-row class="mb-10px">
  18. <template v-for="btn in dynamicButtons">
  19. <el-button
  20. v-if="!btn.ifHide"
  21. :key="btn.id"
  22. type="primary"
  23. size="small"
  24. @click="handleDynamicButtonClick(btn)"
  25. >
  26. {{ btn.buttonName }}
  27. </el-button>
  28. </template>
  29. <el-button size="small" type="danger" @click="AllConditionReset">
  30. <i class="el-icon-refresh mr-5px" style="font-size: 14px" />
  31. 全条件重置
  32. </el-button>
  33. <el-button size="small" type="primary" @click="Export">
  34. <i class="el-icon-download mr-5px" style="font-size: 14px" />
  35. 导出
  36. </el-button>
  37. <el-button
  38. size="small"
  39. type="success"
  40. :loading="exportLoading"
  41. @click="ExportAll"
  42. >
  43. <i class="el-icon-download mr-5px" style="font-size: 14px" />
  44. 导出全部
  45. </el-button>
  46. <el-button size="small" @click="handleBack">
  47. <i class="el-icon-arrow-left mr-5px" style="font-size: 14px" />
  48. 返回
  49. </el-button>
  50. </el-row>
  51. <!-- 表格 -->
  52. <el-table
  53. id="table_excel"
  54. ref="tableRef"
  55. v-loading="loading"
  56. :data="list"
  57. stripe
  58. border
  59. size="small"
  60. show-overflow-tooltip
  61. @selection-change="handleSelectionChange"
  62. @header-dragend="handleResize"
  63. >
  64. <el-table-column
  65. v-if="showMultipleList.length"
  66. type="selection"
  67. width="55"
  68. />
  69. <el-table-column type="index" width="55" align="center" />
  70. <template v-for="(item, i) in queryData">
  71. <el-table-column
  72. v-if="!item.ifHide"
  73. :key="i"
  74. :label="item.columnComment"
  75. :prop="item.columnComment"
  76. align="center"
  77. :min-width="item.javaField || ''"
  78. :sortable="false"
  79. show-overflow-tooltip
  80. >
  81. <template slot="header">
  82. <div class="mr-5px flex items-center">
  83. <!-- 排序图标 -->
  84. <div v-show="item.ifSort" class="mr-5px flex flex-col gap-0">
  85. <i
  86. class="el-icon-caret-top"
  87. style="font-size: 15px; cursor: pointer"
  88. :class="{
  89. 'is-sort':
  90. currentSortField === item.columnComment &&
  91. currentSortDirection === 'asc',
  92. }"
  93. @click="handleSort(item.columnComment, 'asc')"
  94. />
  95. <i
  96. ref=""
  97. class="el-icon-caret-bottom -mt-1.2"
  98. style="font-size: 15px; cursor: pointer"
  99. :class="{
  100. 'is-sort':
  101. currentSortField === item.columnComment &&
  102. currentSortDirection === 'desc',
  103. }"
  104. @click="handleSort(item.columnComment, 'desc')"
  105. />
  106. </div>
  107. <span>{{ item.columnComment }}</span>
  108. <!-- 列过滤 -->
  109. <FilterColumnInQuery
  110. v-if="item.listOperationResult"
  111. :label="item.columnComment"
  112. :prop="item.columnName"
  113. :filter-list="queryData"
  114. :query-id="$route.query.id"
  115. :filter-list-key="item.columnName"
  116. order-type="queryManage"
  117. :param-list="queryParamList"
  118. :active-filters="customFilters"
  119. :html-type="item.htmlType"
  120. :dict-type="item.dictType"
  121. :is-clear="isClear"
  122. @select-data="
  123. (data, field, htmlType) =>
  124. filterData(data, field, htmlType, item)
  125. "
  126. >
  127. <template slot="reference">
  128. <div
  129. class="flex items-center justify-center text-gray-600"
  130. :class="{ 'has-filter': hasFilter(item.columnName) }"
  131. >
  132. <svg-icon
  133. icon-class="search"
  134. class="ml-2px"
  135. style="font-size: 14px; cursor: pointer"
  136. />
  137. </div>
  138. </template>
  139. </FilterColumnInQuery>
  140. </div>
  141. </template>
  142. <template slot-scope="{ row }">
  143. <div
  144. :class="{ active: item.example }"
  145. @click="
  146. pathChange(item.example, row[item.columnComment], item, row)
  147. "
  148. >
  149. <dict-tag
  150. v-if="
  151. isDict(item.columnComment) &&
  152. ![undefined, null].includes(row[item.columnComment])
  153. "
  154. :type="isDict(item.columnComment)"
  155. :value="row[item.columnComment]"
  156. />
  157. <span
  158. v-else-if="
  159. row[item.columnComment] && isDateTime(item.columnComment)
  160. "
  161. >
  162. {{ formatToDateTime(row[item.columnComment]) }}
  163. </span>
  164. <span v-else>{{ row[item.columnComment] }}</span>
  165. </div>
  166. </template>
  167. </el-table-column>
  168. </template>
  169. </el-table>
  170. <!-- 分页 -->
  171. <pagination
  172. v-show="total > 0"
  173. :total="total"
  174. :page.sync="pageNo"
  175. :limit.sync="pageSize"
  176. @pagination="handleSearch"
  177. />
  178. <!-- 弹窗 -->
  179. <ReportPrint ref="reportPrint" />
  180. <ParameterDetail ref="parameterDetailRef" @success="getQueryData" />
  181. </el-card>
  182. </template>
  183. <script>
  184. import * as QueryManageApi from "@/api/mes/queryManage";
  185. import { getQueryManageButtonPage } from "@/api/mes/queryManage/button";
  186. import { saveAs } from "file-saver";
  187. import * as XLSX from "xlsx";
  188. import FilterColumnInQuery from "./components/FilterColumnInQuery.vue";
  189. import DictTag from "./components/DictTag.vue";
  190. import ParameterDetail from "./components/ParameterDetail.vue";
  191. import ReportPrint from "./components/ReportPrint.vue";
  192. import request from "@/utils/request";
  193. import { getAccessToken, getTenantId } from "@/utils/auth";
  194. import axios from "axios";
  195. export default {
  196. name: "QueryForm",
  197. components: {
  198. FilterColumnInQuery,
  199. ParameterDetail,
  200. ReportPrint,
  201. DictTag,
  202. },
  203. data() {
  204. return {
  205. title: "", // ContentWrap 的 title
  206. message: "", // ContentWrap 的 message
  207. queryList: [],
  208. searchData: [],
  209. queryData: [],
  210. list: [],
  211. originalList: [],
  212. pageNo: 1,
  213. pageSize: 20,
  214. total: 0,
  215. loading: false,
  216. form: {},
  217. visible: false,
  218. customFilters: {},
  219. currentSortField: null,
  220. currentSortDirection: null,
  221. dynamicButtons: [],
  222. queryParamList: [],
  223. exportLoading: false,
  224. showMultipleList: [],
  225. isClear: false,
  226. multipleSelection: [],
  227. headerWidthChange: false,
  228. };
  229. },
  230. mounted() {
  231. this.init();
  232. },
  233. activated() {
  234. this.init();
  235. },
  236. beforeDestroy() {
  237. this.saveColumnWidth();
  238. },
  239. methods: {
  240. /* 生命周期 */
  241. async init() {
  242. this.title =
  243. this.$route.query?.name ||
  244. this.$route.redirectedFrom?.meta?.title ||
  245. "查询";
  246. // 需要提示文字时,再写 this.message = 'xxx'
  247. if (this.$route.query.infraQueryId) {
  248. await this.getFilterData();
  249. } else {
  250. this.buildQueryParamFromRoute();
  251. await this.getQueryData();
  252. }
  253. },
  254. /* 以下所有方法保持与原文件一致,不再赘述 */
  255. async getQueryData() {
  256. try {
  257. this.loading = true;
  258. const data = await QueryManageApi.getQueryManageColumnListByMasterId(
  259. this.$route.query.id
  260. );
  261. // 确保queryData是数组
  262. this.queryData = Array.isArray(data.data) ? data.data || [] : [];
  263. console.log("queryData长度", this.queryData.length);
  264. this.searchData = this.queryData.filter(
  265. (item) => item.listOperationResult && item.ifHide === false
  266. );
  267. this.showMultipleList = this.queryData.filter(
  268. (item) => item.listOperationCondition === "1"
  269. );
  270. this.queryList = [];
  271. for (let i = 0; i < this.searchData.length; i++) {
  272. const { dataType, htmlType, dictType, columnName } =
  273. this.searchData[i];
  274. this.queryList.push({
  275. dataType,
  276. htmlType,
  277. dictType,
  278. key: columnName,
  279. operate: dataType === "ym_string_query_type" ? "like" : "",
  280. });
  281. }
  282. await this.getManageButtons(this.$route.query?.id);
  283. await this.getList();
  284. } finally {
  285. this.loading = false;
  286. }
  287. },
  288. async getList() {
  289. console.log("getList被调用,queryParamList:", this.queryParamList);
  290. try {
  291. this.loading = true;
  292. console.log("调用QueryManageApi.loadTableData,参数:", {
  293. pageNo: this.pageNo,
  294. pageSize: this.pageSize,
  295. paramList: this.queryParamList,
  296. id: this.$route.query?.id,
  297. });
  298. const data = await QueryManageApi.loadTableData({
  299. pageNo: this.pageNo,
  300. pageSize: this.pageSize,
  301. paramList: this.queryParamList,
  302. id: this.$route.query?.id,
  303. });
  304. console.log("后端返回", data);
  305. this.list = data?.data?.list || [];
  306. console.log("赋值后 list =", this.list);
  307. console.log("list.length =", this.list.length);
  308. console.log("list 第一条 =", this.list[0]);
  309. this.originalList = JSON.parse(JSON.stringify(data?.data?.list || []));
  310. this.total = data?.data?.total || 0;
  311. } catch (error) {
  312. console.error("getList错误:", error);
  313. } finally {
  314. this.loading = false;
  315. }
  316. },
  317. async getManageButtons(masterId) {
  318. const data = await getQueryManageButtonPage({ masterId });
  319. this.dynamicButtons = data?.data?.list || [];
  320. },
  321. async handleDynamicButtonClick(btn = {}) {
  322. const {
  323. ifJimu,
  324. interfaceUrl,
  325. printSoft,
  326. operateType,
  327. paramList = [],
  328. } = btn;
  329. if (ifJimu) {
  330. this.handlePrintByJimu(btn);
  331. } else if (this.isFullUrl(interfaceUrl) && printSoft) {
  332. this.handlePrintByOtherSoft(btn);
  333. } else if (operateType === 2) {
  334. this.$refs.parameterDetailRef.open(
  335. "create",
  336. btn,
  337. this.$route.query?.id,
  338. [],
  339. this.queryData
  340. );
  341. } else if (operateType === 3) {
  342. if (this.multipleSelection.length === 0) {
  343. return this.$message.warning("请先选择行数据!");
  344. }
  345. if (this.multipleSelection.length > 1) {
  346. return this.$message.warning("只能选择单条数据修改!");
  347. }
  348. this.$refs.parameterDetailRef.open(
  349. "update",
  350. btn,
  351. this.$route.query?.id,
  352. this.multipleSelection,
  353. this.queryData
  354. );
  355. } else if (operateType === 7) {
  356. this.$router.push({ path: `${interfaceUrl}` });
  357. } else {
  358. this.handleDynamic(btn);
  359. }
  360. },
  361. formatToDateTime(val) {
  362. const d = val ? new Date(val) : new Date();
  363. if (isNaN(d.getTime())) return "";
  364. const pad = (n) => String(n).padStart(2, "0");
  365. return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(
  366. d.getDate()
  367. )} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
  368. },
  369. handlePrintByJimu(params) {
  370. if (this.multipleSelection.length === 0) {
  371. return this.$message.warning("请先选择数据!");
  372. }
  373. const baseUrl = process.env.VITE_BASE_URL;
  374. const token = getAccessToken();
  375. const tenantId = getTenantId();
  376. const { paramList = [], interfaceUrl, reportId } = params;
  377. const fieldValues = this.paramsToConver(paramList);
  378. const printParams = new URLSearchParams({
  379. token,
  380. tenantId,
  381. ...fieldValues,
  382. });
  383. const src = `${baseUrl}${interfaceUrl}${reportId}?${printParams.toString()}`;
  384. this.$refs.reportPrint.open(
  385. src,
  386. this.$route.query?.name ||
  387. this.$route.redirectedFrom?.meta?.title ||
  388. "报表打印"
  389. );
  390. },
  391. async handlePrintByOtherSoft(params) {
  392. if (this.multipleSelection.length === 0) {
  393. return this.$message.warning("请先选择数据!");
  394. }
  395. const { interfaceUrl, paramList, restMethod, templet } = params;
  396. if (!templet) return this.$message.warning("未配置打印模板!");
  397. const fieldValues = this.paramsToConver(paramList);
  398. const printParams = { ...fieldValues, fileUrl: templet };
  399. const config = {
  400. method: restMethod,
  401. url: interfaceUrl,
  402. [restMethod === "get" || restMethod === "delete" ? "params" : "data"]:
  403. printParams,
  404. };
  405. await axios(config);
  406. this.$message.success("操作成功!");
  407. this.getList();
  408. },
  409. async handleDynamic(params) {
  410. if (this.multipleSelection.length === 0) {
  411. return this.$message.warning("请先选择数据!");
  412. }
  413. const {
  414. interfaceUrl,
  415. restMethod = "get",
  416. paramList = [],
  417. requestParameter = "0",
  418. } = params;
  419. const fieldValues = this.paramsToConver(paramList);
  420. const config = { method: restMethod, url: interfaceUrl };
  421. this.handleGetDelete(config, fieldValues, requestParameter);
  422. await request[restMethod]?.(config);
  423. this.$message.success("操作成功");
  424. this.getList();
  425. },
  426. handleGetDelete(config, fieldValues, requestParameter) {
  427. switch (requestParameter) {
  428. case "1":
  429. config.params = fieldValues;
  430. break;
  431. case "3":
  432. config.url = new URLSearchParams(fieldValues).toString()
  433. ? `${config.url}?${new URLSearchParams(fieldValues).toString()}`
  434. : config.url;
  435. break;
  436. case "4":
  437. config.headers = { ...config.headers, ...fieldValues };
  438. break;
  439. default:
  440. config.data = fieldValues;
  441. }
  442. },
  443. paramsToConver(paramList) {
  444. const matchListWithParam = paramList
  445. ?.filter((item) =>
  446. this.queryData.some((query) => item.columnId === query?.id)
  447. )
  448. .map((item) => {
  449. const paramItem = this.queryData.find(
  450. (query) => item.columnId === query?.id
  451. );
  452. return { ...item, columnComment: paramItem?.columnComment };
  453. });
  454. const result = this.generateMappedData(
  455. this.multipleSelection,
  456. matchListWithParam
  457. );
  458. const allFields = [...new Set(result.flatMap(Object.keys))];
  459. return allFields.reduce((acc, field) => {
  460. acc[field] = result.map((item) => item[field]).join(",");
  461. return acc;
  462. }, {});
  463. },
  464. generateMappedData(selectList, keys) {
  465. return selectList.map((item) =>
  466. keys.reduce((res, key) => {
  467. const { columnComment, paramName } = key;
  468. if (item.hasOwnProperty(columnComment)) {
  469. const field = paramName.split(".").pop();
  470. res[field] = item[columnComment];
  471. }
  472. return res;
  473. }, {})
  474. );
  475. },
  476. isFullUrl(url) {
  477. try {
  478. const parsed = new URL(url);
  479. return parsed.protocol === "http:" || parsed.protocol === "https:";
  480. } catch {
  481. return false;
  482. }
  483. },
  484. isDict(key) {
  485. if (!Array.isArray(this.queryData)) return false;
  486. const item = this.queryData.find((item) => item.columnComment === key);
  487. return item ? item.dictType : false;
  488. },
  489. isNumber(key) {
  490. if (!Array.isArray(this.queryData)) return false;
  491. const item = this.queryData.find((item) => item.columnComment === key);
  492. return item && item.dataType === "ym_int_query_type";
  493. },
  494. isDateTime(key) {
  495. if (!Array.isArray(this.queryData)) return false;
  496. const item = this.queryData.find((item) => item.columnComment === key);
  497. return item && item.javaType === "LocalDateTime";
  498. },
  499. hasFilter(field) {
  500. return !!(this.customFilters[field] && this.customFilters[field].length);
  501. },
  502. handleSort(field, direction) {
  503. if (
  504. this.currentSortField === field &&
  505. this.currentSortDirection === direction
  506. ) {
  507. this.currentSortField = "";
  508. this.currentSortDirection = "";
  509. this.list = JSON.parse(JSON.stringify(this.originalList));
  510. return;
  511. }
  512. this.currentSortField = field;
  513. this.currentSortDirection = direction;
  514. this.list = [...this.originalList].sort((a, b) => {
  515. let valA = a[field];
  516. let valB = b[field];
  517. valA =
  518. typeof valA === "string" ? parseFloat(valA.replace(/,/g, "")) : valA;
  519. valB =
  520. typeof valB === "string" ? parseFloat(valB.replace(/,/g, "")) : valB;
  521. if (isNaN(valA)) {
  522. return direction === "asc"
  523. ? valA > valB
  524. ? 1
  525. : -1
  526. : valA < valB
  527. ? 1
  528. : -1;
  529. }
  530. if (isNaN(valB)) {
  531. return direction === "asc"
  532. ? valA > valB
  533. ? 1
  534. : -1
  535. : valA < valB
  536. ? 1
  537. : -1;
  538. }
  539. return direction === "asc" ? valA - valB : valB - valA;
  540. });
  541. },
  542. filterData(data, field, type, row) {
  543. console.log("filterData被调用:", { data, field, type, row });
  544. const { dataType } = row;
  545. this.$set(this.customFilters, field, data);
  546. const isDateRange = data[0]?.isRange;
  547. if (isDateRange) {
  548. const valueList = data.flatMap((item) => item.column).join(",");
  549. const idx = this.queryParamList.findIndex((item) => item.key === field);
  550. if (idx > -1) {
  551. this.queryParamList[idx].value = valueList;
  552. } else {
  553. this.queryParamList.push({
  554. key: field,
  555. operate: "like",
  556. htmlType: type,
  557. value: valueList,
  558. });
  559. }
  560. console.log(
  561. "filterData - 日期范围筛选后queryParamList:",
  562. this.queryParamList
  563. );
  564. this.getList();
  565. return;
  566. }
  567. let valueStr;
  568. if (data.length) {
  569. valueStr =
  570. dataType === "ym_int_query_type"
  571. ? data.map((item) => item.column).join(",")
  572. : data.map((item) => `'${item.column}'`).join(",");
  573. const idx = this.queryParamList.findIndex((item) => item.key === field);
  574. if (idx > -1) {
  575. this.queryParamList[idx].value = valueStr;
  576. } else {
  577. this.queryParamList.push({
  578. key: field,
  579. operate: "like",
  580. htmlType: type,
  581. value: valueStr,
  582. });
  583. }
  584. } else {
  585. const idx = this.queryParamList.findIndex((item) => item.key === field);
  586. if (idx > -1) this.queryParamList.splice(idx, 1);
  587. }
  588. console.log("filterData - 筛选后queryParamList:", this.queryParamList);
  589. this.getList();
  590. },
  591. AllConditionReset() {
  592. this.queryParamList = [];
  593. this.customFilters = {};
  594. this.isClear = true;
  595. setTimeout(() => (this.isClear = false), 1000);
  596. this.getList();
  597. },
  598. handleSearch() {
  599. this.list = [];
  600. this.getList();
  601. },
  602. async Export() {
  603. try {
  604. await this.$confirm("确定导出当前页?", "提示", { type: "warning" });
  605. setTimeout(() => {
  606. const xlsxParam = { raw: true };
  607. const tables = document.getElementById("table_excel");
  608. const table_book = XLSX.utils.table_to_book(tables, xlsxParam);
  609. const tableWrite = XLSX.write(table_book, {
  610. bookType: "xlsx",
  611. bookSST: true,
  612. type: "array",
  613. });
  614. saveAs(
  615. new Blob([tableWrite], { type: "application/octet-stream" }),
  616. `${this.title}.xlsx`
  617. );
  618. }, 1000);
  619. } catch {}
  620. },
  621. async ExportAll() {
  622. try {
  623. await this.$confirm("确定导出全部?", "提示", { type: "warning" });
  624. this.exportLoading = true;
  625. const data = await QueryManageApi.exportExcel({
  626. id: this.$route.query?.id,
  627. paramList: this.queryParamList,
  628. });
  629. this.$download.excel(data, this.title + ".xls");
  630. } finally {
  631. this.exportLoading = false;
  632. }
  633. },
  634. getHandleNumber(val) {
  635. return Math.round(parseFloat(val) * 100000000) / 100000000;
  636. },
  637. getSummaries({ columns }) {
  638. const sums = [];
  639. columns.forEach((column, index) => {
  640. if (index === 0) {
  641. sums[index] = "总计";
  642. return;
  643. }
  644. const values = this.list.map((item) => Number(item[column.property]));
  645. if (this.isNumber(column.property)) {
  646. sums[index] = values.reduce((acc, cur) => {
  647. const value = Number(cur);
  648. return !isNaN(value) ? this.getHandleNumber(acc + cur) : acc;
  649. }, 0);
  650. }
  651. });
  652. return sums;
  653. },
  654. handleSelectionChange(val) {
  655. this.multipleSelection = val;
  656. },
  657. pathChange(path, val, item, row) {
  658. if (path === "sameRouter") return;
  659. if (!path) return;
  660. const data = {};
  661. this.dynamicButtons
  662. .filter((v) => v.ifHide && v.paramList.length)
  663. .forEach((v) =>
  664. v.paramList.forEach((val) => {
  665. data[val.paramName] = val.value || row[val.paramComment];
  666. })
  667. );
  668. this.$router.push({ path: `${path}`, query: { id: val, ...data } });
  669. },
  670. handleBack() {
  671. this.$router.push({ path: "/querymanage/queryManageIndex" });
  672. },
  673. handleResize() {
  674. this.headerWidthChange = true;
  675. },
  676. async saveColumnWidth() {
  677. if (!this.headerWidthChange) return;
  678. this.headerWidthChange = false;
  679. const widthList = [];
  680. // 确保queryData是数组
  681. if (!Array.isArray(this.queryData)) return;
  682. const headers = this.$refs.tableRef.$el.querySelectorAll(
  683. ".el-table__header-wrapper tr th"
  684. );
  685. const visibleColumns = this.queryData.filter((item) => !item.ifHide);
  686. const validHeaders = [...headers].filter(
  687. (th) =>
  688. !th.classList.contains("el-table-column--selection") &&
  689. th.innerText.trim() !== ""
  690. );
  691. validHeaders.forEach((header, i) => {
  692. const correspondingItem = visibleColumns[i];
  693. if (correspondingItem) {
  694. widthList.push({
  695. id: correspondingItem.id,
  696. javaField: header.offsetWidth,
  697. });
  698. }
  699. });
  700. await QueryManageApi.updateWidth(widthList);
  701. },
  702. buildQueryParamFromRoute() {
  703. const queryParam = [];
  704. for (const i in this.$route.query) {
  705. if (i !== "id" && i !== "name") {
  706. queryParam.push({
  707. key: i,
  708. operate: "like",
  709. htmlType: "input",
  710. value: "'" + this.$route.query[i] + "'",
  711. });
  712. }
  713. }
  714. this.queryParamList = queryParam;
  715. },
  716. async getFilterData() {
  717. const data = await getQueryManageButtonPage({
  718. masterId: this.$route.query?.infraQueryId,
  719. });
  720. const arr = [];
  721. data.list
  722. .filter((v) => v.ifHide && v.paramList.length)
  723. .forEach((v) =>
  724. v.paramList.forEach((val) => {
  725. if (val.filter) arr.push(val.paramName);
  726. })
  727. );
  728. const queryParam = [];
  729. for (const i in this.$route.query) {
  730. if (arr.indexOf(i) > -1) {
  731. queryParam.push({
  732. key: i,
  733. operate: "like",
  734. htmlType: "input",
  735. value: "'" + this.$route.query[i] + "'",
  736. });
  737. }
  738. }
  739. this.queryParamList = queryParam;
  740. await this.getQueryData();
  741. },
  742. },
  743. };
  744. </script>
  745. <style scoped lang="scss">
  746. /* ---------- ContentWrap 原样式 ---------- */
  747. .el-content-wrap {
  748. /* 自定义 */
  749. height: 100vh;
  750. overflow-y: auto;
  751. }
  752. .text-16px {
  753. font-size: 16px;
  754. }
  755. .font-700 {
  756. font-weight: 700;
  757. }
  758. .ml-5px {
  759. margin-left: 5px;
  760. }
  761. .max-w-200px {
  762. max-width: 200px;
  763. }
  764. .mb-3px {
  765. margin-bottom: 3px;
  766. }
  767. /* ---------- 原来的表格样式 ---------- */
  768. :deep(.el-table__row) {
  769. height: 15px !important;
  770. }
  771. .el-table--medium .el-table__cell,
  772. .el-table--small .el-table__cell {
  773. padding: 1px 0 !important;
  774. }
  775. .active:hover {
  776. cursor: pointer;
  777. }
  778. .has-filter,
  779. .is-sort,
  780. .active {
  781. color: #1890ff !important;
  782. }
  783. </style>