queryNew.vue 25 KB

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