usePopBiz.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. import { reactive, ref, unref, defineAsyncComponent, toRaw, markRaw } from 'vue';
  2. import { httpGroupRequest } from '/@/components/Form/src/utils/GroupRequest';
  3. import { defHttp } from '/@/utils/http/axios';
  4. import { filterMultiDictText } from '/@/utils/dict/JDictSelectUtil.js';
  5. import { useMessage } from '/@/hooks/web/useMessage';
  6. import { OnlineColumn } from '/@/components/jeecg/OnLine/types/onlineConfig';
  7. import { h } from 'vue';
  8. import { useRouter } from 'vue-router';
  9. import { useMethods } from '/@/hooks/system/useMethods';
  10. import { importViewsFile } from '/@/utils';
  11. export function usePopBiz(props, tableRef?) {
  12. const { createMessage } = useMessage();
  13. //弹窗可视状态
  14. const visible = ref(false);
  15. //表格加载
  16. const loading = ref(false);
  17. //cgRpConfigId
  18. const cgRpConfigId = ref('');
  19. //标题
  20. const title = ref('列表');
  21. // 排序字段,默认无排序
  22. const iSorter = ref<any>('');
  23. // 查询对象
  24. const queryInfo = ref([]);
  25. // 查询参数
  26. const queryParam = ref<any>({});
  27. // 动态参数
  28. const dynamicParam = ref<any>({});
  29. //字典配置项
  30. const dictOptions = ref({});
  31. //数据集
  32. const dataSource = ref<Array<object>>([]);
  33. //定义表格信息
  34. const columns = ref<Array<object>>([]);
  35. //定义请求url信息
  36. const configUrl = reactive({
  37. //列表页加载column和data
  38. getColumnsAndData: '/online/cgreport/api/getColumnsAndData/',
  39. getColumns: '/online/cgreport/api/getRpColumns/',
  40. getData: '/online/cgreport/api/getData/',
  41. getQueryInfo: '/online/cgreport/api/getQueryInfo/',
  42. export: '/online/cgreport/api/exportManySheetXls/',
  43. });
  44. //已选择的值
  45. const checkedKeys = ref<Array<string | number>>([]);
  46. //选择的行记录
  47. const selectRows = ref<Array<any>>([]);
  48. // 点击单元格选中行 popup需要 但是报表预览不需要
  49. let clickThenCheckFlag = true;
  50. if (props.clickToRowSelect === false) {
  51. clickThenCheckFlag = false;
  52. }
  53. /**
  54. * 选择列配置
  55. */
  56. const rowSelection = {
  57. fixed: true,
  58. selectedRowKeys: checkedKeys,
  59. selectionRows: selectRows,
  60. onChange: onSelectChange,
  61. };
  62. /**
  63. * 序号列配置
  64. */
  65. const indexColumnProps = {
  66. dataIndex: 'index',
  67. width: '15px',
  68. };
  69. /**
  70. * 分页配置
  71. */
  72. const pagination = reactive({
  73. current: 1,
  74. pageSize: 10,
  75. pageSizeOptions: ['10', '20', '30'],
  76. // showTotal: (total, range) => {
  77. // return range[0] + '-' + range[1] + ' 共' + total + '条'
  78. // },
  79. showQuickJumper: true,
  80. showSizeChanger: true,
  81. total: 0,
  82. // 合计逻辑 [待优化 3.0]
  83. showTotal: (total) => onShowTotal(total),
  84. realPageSize: 10,
  85. realTotal: 0,
  86. // 是否有合计列,默认为"",在第一次获取到数据之后会设计为ture或者false
  87. isTotal: <string | boolean>'',
  88. onShowSizeChange: (current, pageSize) => onSizeChange(current, pageSize),
  89. });
  90. /**
  91. * 表格选择事件
  92. * @param selectedRowKeys
  93. * @param selectRow
  94. */
  95. function onSelectChange(selectedRowKeys: (string | number)[]) {
  96. if (!selectedRowKeys || selectedRowKeys.length == 0) {
  97. selectRows.value = [];
  98. } else {
  99. for (let i = 0; i < selectedRowKeys.length; i++) {
  100. let combineKey = combineRowKey(getRowByKey(selectedRowKeys[i]));
  101. let keys = unref(checkedKeys);
  102. if (combineKey && keys.indexOf(combineKey) < 0) {
  103. let row = getRowByKey(selectedRowKeys[i]);
  104. row && selectRows.value.push(row);
  105. }
  106. }
  107. }
  108. checkedKeys.value = selectedRowKeys;
  109. }
  110. /**
  111. * 过滤没用选项
  112. * @param selectedRowKeys
  113. */
  114. function filterUnuseSelect() {
  115. selectRows.value = unref(selectRows).filter((item) => {
  116. let combineKey = combineRowKey(item);
  117. return unref(checkedKeys).indexOf(combineKey) >= 0;
  118. });
  119. }
  120. /**
  121. * 根据key获取row信息
  122. * @param key
  123. */
  124. function getRowByKey(key) {
  125. let row = unref(dataSource).filter((record) => combineRowKey(record) === key);
  126. return row && row.length > 0 ? row[0] : '';
  127. }
  128. /**
  129. * 加载rowKey
  130. */
  131. function combineRowKey(record) {
  132. let res = record?.id || '';
  133. Object.keys(record).forEach((key) => {
  134. res = key == 'rowIndex' ? record[key] + res : res + record[key];
  135. });
  136. res = res.length > 50 ? res.substring(0, 50) : res;
  137. return res;
  138. }
  139. /**
  140. * 加载列信息
  141. */
  142. function loadColumnsInfo() {
  143. let url = `${configUrl.getColumns}${props.code}`;
  144. //缓存key
  145. let groupIdKey = props.groupId ? `${props.groupId}${url}` : '';
  146. httpGroupRequest(() => defHttp.get({ url }, { isTransformResponse: false, successMessageMode: 'none' }), groupIdKey).then((res) => {
  147. if (res.success) {
  148. initDictOptionData(res.result.dictOptions);
  149. cgRpConfigId.value = res.result.cgRpConfigId;
  150. title.value = res.result.cgRpConfigName;
  151. let currColumns = res.result.columns;
  152. for (let a = 0; a < currColumns.length; a++) {
  153. if (currColumns[a].customRender) {
  154. let dictCode = currColumns[a].customRender;
  155. currColumns[a].customRender = ({ text }) => {
  156. return filterMultiDictText(unref(dictOptions)[dictCode], text + '');
  157. };
  158. }
  159. // 排序字段受控
  160. if (unref(iSorter) && currColumns[a].dataIndex === unref(iSorter).column) {
  161. currColumns[a].sortOrder = unref(iSorter).order === 'asc' ? 'ascend' : 'descend';
  162. }
  163. }
  164. if (currColumns[0].key !== 'rowIndex') {
  165. currColumns.unshift({
  166. title: '序号',
  167. dataIndex: 'rowIndex',
  168. key: 'rowIndex',
  169. width: 60,
  170. align: 'center',
  171. customRender: function ({ text }) {
  172. return parseInt(text) + 1;
  173. },
  174. });
  175. }
  176. columns.value = [...currColumns];
  177. initQueryInfo(null);
  178. }
  179. });
  180. }
  181. /**
  182. * 加载列和数据[列表专用]
  183. */
  184. function loadColumnsAndData() {
  185. // 第一次加载 置空isTotal 在这里调用确保 该方法只是进入页面后 加载一次 其余查询不走该方法
  186. pagination.isTotal = '';
  187. let url = `${configUrl.getColumnsAndData}${props.id}`;
  188. //缓存key
  189. let groupIdKey = props.groupId ? `${props.groupId}${url}` : '';
  190. httpGroupRequest(() => defHttp.get({ url }, { isTransformResponse: false, successMessageMode: 'none' }), groupIdKey).then((res) => {
  191. if (res.success) {
  192. initDictOptionData(res.result.dictOptions);
  193. cgRpConfigId.value = props.id;
  194. let { columns: metaColumnList, cgreportHeadName, fieldHrefSlots, isGroupTitle } = res.result;
  195. title.value = cgreportHeadName;
  196. // href 跳转
  197. const fieldHrefSlotKeysMap = {};
  198. fieldHrefSlots.forEach((item) => (fieldHrefSlotKeysMap[item.slotName] = item));
  199. let currColumns = handleColumnHrefAndDict(metaColumnList, fieldHrefSlotKeysMap);
  200. // popup需要序号, 普通列表不需要
  201. if (clickThenCheckFlag === true) {
  202. currColumns.unshift({
  203. title: '序号',
  204. dataIndex: 'rowIndex',
  205. key: 'rowIndex',
  206. width: 60,
  207. align: 'center',
  208. customRender: function ({ text }) {
  209. return parseInt(text) + 1;
  210. },
  211. });
  212. }
  213. // 合并表头
  214. if (isGroupTitle === true) {
  215. currColumns = handleGroupTitle(currColumns);
  216. }
  217. columns.value = [...currColumns];
  218. initQueryInfo(res.result.data);
  219. } else {
  220. //update-begin-author:taoyan date:20220401 for: VUEN-583【vue3】JeecgBootException: sql黑名单校验不通过,请联系管理员!,前台无提示
  221. createMessage.warning(res.message);
  222. //update-end-author:taoyan date:20220401 for: VUEN-583【vue3】JeecgBootException: sql黑名单校验不通过,请联系管理员!,前台无提示
  223. }
  224. });
  225. }
  226. /**
  227. * 处理求和的列 合计逻辑 [待优化 3.0]
  228. */
  229. function handleSumColumn(metaColumnList: OnlineColumn[], dataTotal: number): void {
  230. // 获取需要合计列的dataIndex
  231. let sumColumnList = getNeedSumColumns(metaColumnList);
  232. // 判断是否为第一次获取数据,如果是的话,则需要重新设置pageSize
  233. if (pagination.isTotal == '') {
  234. if (sumColumnList.length > 0) {
  235. pagination.isTotal = true;
  236. // 有合计字段时,每次最多查询原pageSize-1条记录,另外需要第一次时将查询的10条中删除最后一条
  237. // 删除最后一条数据 如果第一次得到的数据长度等于pageSize的话,则删除最后一条
  238. if (dataSource.value.length == pagination.pageSize) {
  239. let remove_data = dataSource.value.pop();
  240. }
  241. pagination.realPageSize = pagination.pageSize - 1;
  242. } else {
  243. pagination.isTotal = false;
  244. }
  245. }
  246. // 需要添加合计字段
  247. if (pagination.isTotal) {
  248. let totalRow = {};
  249. sumColumnList.forEach((dataIndex) => {
  250. let count = 0;
  251. dataSource.value.forEach((row) => {
  252. // 统计去除null及空数据
  253. if (row[dataIndex] != null && row[dataIndex] != '') {
  254. count += parseFloat(row[dataIndex]);
  255. }
  256. });
  257. totalRow[dataIndex] = isNaN(count) ? '包含非数字内容' : count.toFixed(2);
  258. // 长整形时合计不显示.00后缀
  259. let v = metaColumnList.find((v) => v.dataIndex == dataIndex);
  260. if (v && v.fieldType == 'Long') {
  261. totalRow[dataIndex] = parseInt(totalRow[dataIndex]);
  262. }
  263. });
  264. dataSource.value.push(totalRow);
  265. pagination.realTotal = dataTotal;
  266. pagination.total = Number(dataTotal) + Number(Math.floor(dataTotal / pagination.realPageSize));
  267. }
  268. }
  269. /**
  270. * 获取需要求和的列 dataIndex
  271. * @param columns
  272. */
  273. function getNeedSumColumns(columns: OnlineColumn[]): string[] {
  274. let arr: string[] = [];
  275. for (let column of columns) {
  276. if (column.isTotal === '1') {
  277. arr.push(column.dataIndex!);
  278. }
  279. // 【VUEN-1569】【online报表】合计无效
  280. if (column.children && column.children.length > 0) {
  281. let subArray = getNeedSumColumns(column.children);
  282. if (subArray.length > 0) {
  283. arr.push(...subArray);
  284. }
  285. }
  286. }
  287. return arr;
  288. }
  289. /**
  290. * 处理列的href和字典翻译
  291. */
  292. function handleColumnHrefAndDict(columns: OnlineColumn[], fieldHrefSlotKeysMap: {}): OnlineColumn[] {
  293. for (let column of columns) {
  294. let { customRender, hrefSlotName, fieldType } = column;
  295. // online 报表中类型配置为日期(yyyy-MM-dd ),但是实际展示为日期时间格式(yyyy-MM-dd HH:mm:ss) issues/3042
  296. if (fieldType == 'Date') {
  297. column.customRender = ({ text }) => {
  298. if (!text) {
  299. return '';
  300. }
  301. if (text.length > 10) {
  302. return text.substring(0, 10);
  303. }
  304. return text;
  305. };
  306. } else {
  307. if (!hrefSlotName && column.scopedSlots && column.scopedSlots.customRender) {
  308. //【Online报表】字典和href互斥 这里通过fieldHrefSlotKeysMap 先找到是href的列
  309. if (fieldHrefSlotKeysMap.hasOwnProperty(column.scopedSlots.customRender)) {
  310. hrefSlotName = column.scopedSlots.customRender;
  311. }
  312. }
  313. // 如果 customRender 有值则代表使用了字典
  314. // 如果 hrefSlotName 有值则代表使用了href跳转
  315. // 两者可以兼容。兼容的具体思路为:先获取到字典替换的值,再添加href链接跳转
  316. if (customRender || hrefSlotName) {
  317. let dictCode = customRender as string;
  318. let replaceFlag = '_replace_text_';
  319. column.customRender = ({ text, record }) => {
  320. let value = text;
  321. // 如果 dictCode 有值,就进行字典转换
  322. if (dictCode) {
  323. if (dictCode.startsWith(replaceFlag)) {
  324. let textFieldName = dictCode.replace(replaceFlag, '');
  325. value = record[textFieldName];
  326. } else {
  327. value = filterMultiDictText(unref(dictOptions)[dictCode], text + '');
  328. }
  329. }
  330. // 扩展参数设置列的内容长度
  331. if (column.showLength) {
  332. if (value && value.length > column.showLength) {
  333. value = value.substr(0, column.showLength) + '...';
  334. }
  335. }
  336. // 如果 hrefSlotName 有值,就生成一个 a 标签,包裹住字典替换后(或原生)的值
  337. if (hrefSlotName) {
  338. let field = fieldHrefSlotKeysMap[hrefSlotName];
  339. if (field) {
  340. return h(
  341. 'a',
  342. {
  343. onClick: () => handleClickFieldHref(field, record),
  344. },
  345. value
  346. );
  347. }
  348. }
  349. return value;
  350. };
  351. }
  352. }
  353. }
  354. return columns;
  355. }
  356. /**
  357. * 处理合并表头
  358. * @param columns
  359. */
  360. function handleGroupTitle(columns: OnlineColumn[]): OnlineColumn[] {
  361. let newColumns: OnlineColumn[] = [];
  362. for (let column of columns) {
  363. //排序字段受控 ---- 此逻辑为新增逻辑 待
  364. if (unref(iSorter) && column.dataIndex === unref(iSorter).column) {
  365. column.sortOrder = unref(iSorter).order === 'asc' ? 'ascend' : 'descend';
  366. }
  367. //判断字段是否需要合并表头
  368. if (column.groupTitle) {
  369. let clIndex = newColumns.findIndex((im) => im.title === column.groupTitle);
  370. if (clIndex !== -1) {
  371. //表头已存在直接push children
  372. newColumns[clIndex].children!.push(column);
  373. } else {
  374. //表头不存在组装表头信息
  375. let clGroup: OnlineColumn = {},
  376. child: OnlineColumn[] = [];
  377. child.push(column);
  378. clGroup.title = column.groupTitle;
  379. clGroup.align = 'center';
  380. clGroup.children = child;
  381. newColumns.push(clGroup);
  382. }
  383. } else {
  384. newColumns.push(column);
  385. }
  386. }
  387. return newColumns;
  388. }
  389. // 获取路由器对象 href跳转用到
  390. let router = useRouter();
  391. /**
  392. * href 点击事件
  393. * @param field
  394. * @param record
  395. */
  396. function handleClickFieldHref(field, record) {
  397. let href = field.href;
  398. let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?/;
  399. let compPattern = /\.vue(\?.*)?$/;
  400. let jsPattern = /{{([^}]+)}}/g; // {{ xxx }}
  401. if (typeof href === 'string') {
  402. href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2]);
  403. // 执行 {{...}} JS增强语句
  404. if (jsPattern.test(href)) {
  405. href = href.replace(jsPattern, function (text, s0) {
  406. try {
  407. return eval(s0);
  408. } catch (e) {
  409. console.error(e);
  410. return text;
  411. }
  412. });
  413. }
  414. if (urlPattern.test(href)) {
  415. window.open(href, '_blank');
  416. } else if (compPattern.test(href)) {
  417. // 处理弹框
  418. openHrefCompModal(href);
  419. } else {
  420. router.push(href);
  421. }
  422. }
  423. }
  424. /**
  425. * 导出
  426. */
  427. function handleExport() {
  428. const { handleExportXls } = useMethods();
  429. let url = `${configUrl.export}${cgRpConfigId.value}`;
  430. let params = getQueryParams(); //查询条件
  431. // 【VUEN-1568】如果选中了某些行,就只导出选中的行
  432. let keys = unref(checkedKeys);
  433. if (keys.length > 0) {
  434. params['force_id'] = keys
  435. .map((i) => (getRowByKey(i) as any)?.id)
  436. .filter((i) => i != null && i !== '')
  437. .join(',');
  438. }
  439. handleExportXls(title.value, url, params);
  440. }
  441. /**
  442. * 合计逻辑 [待优化 3.0]
  443. * 分页 大小改变事件
  444. * @param _current
  445. * @param size
  446. */
  447. function onSizeChange(_current, size) {
  448. pagination.isTotal = '';
  449. pagination.pageSize = size;
  450. if (pagination.isTotal) {
  451. pagination.realPageSize = size - 1;
  452. } else {
  453. pagination.realPageSize = size;
  454. }
  455. pagination.current = 1;
  456. }
  457. /**
  458. * 合计逻辑 [待优化 3.0]
  459. * 显示总条数
  460. * @param total
  461. */
  462. function onShowTotal(total) {
  463. // 重新根据是否有合计计算每页显示的数据
  464. let start = (pagination.current - 1) * pagination.realPageSize + 1;
  465. let end = start + (pagination.isTotal ? dataSource.value.length - 1 : dataSource.value.length) - 1;
  466. let realTotal = pagination.isTotal ? pagination.realTotal : total;
  467. return start + '-' + end + ' 共' + realTotal + '条';
  468. }
  469. /**
  470. * 弹出框显示隐藏触发事件
  471. */
  472. async function visibleChange($event) {
  473. visible.value = $event;
  474. $event && loadColumnsInfo();
  475. }
  476. /**
  477. * 初始化查询条件
  478. * @param data 数据结果集
  479. */
  480. function initQueryInfo(data) {
  481. let url = `${configUrl.getQueryInfo}${unref(cgRpConfigId)}`;
  482. //缓存key
  483. let groupIdKey = props.groupId ? `${props.groupId}${url}` : '';
  484. httpGroupRequest(() => defHttp.get({ url }, { isTransformResponse: false, successMessageMode: 'none' }), groupIdKey).then((res) => {
  485. // console.log("获取查询条件", res);
  486. if (res.success) {
  487. dynamicParamHandler(res.result);
  488. queryInfo.value = res.result;
  489. console.log('queryInfo==>', queryInfo.value);
  490. //查询条件加载后再请求数据
  491. if (data) {
  492. setDataSource(data);
  493. } else {
  494. //没有传递data时查询数据
  495. loadData(1);
  496. }
  497. } else {
  498. createMessage.warning(res.message);
  499. }
  500. });
  501. }
  502. /**
  503. * 加载表格数据
  504. * @param arg
  505. */
  506. function loadData(arg?) {
  507. if (arg == 1) {
  508. pagination.current = 1;
  509. }
  510. let params = getQueryParams(); //查询条件
  511. loading.value = true;
  512. let url = `${configUrl.getData}${unref(cgRpConfigId)}`;
  513. //缓存key
  514. let groupIdKey = props.groupId ? `${props.groupId}${url}${JSON.stringify(params)}` : '';
  515. httpGroupRequest(() => defHttp.get({ url, params }, { isTransformResponse: false, successMessageMode: 'none' }), groupIdKey).then((res) => {
  516. loading.value = false;
  517. let data = res.result;
  518. console.log('表格信息:', data);
  519. setDataSource(data);
  520. });
  521. }
  522. /**
  523. * 设置dataSource
  524. */
  525. function setDataSource(data) {
  526. if (data) {
  527. pagination.total = Number(data.total);
  528. let currentPage = pagination?.current ?? 1;
  529. for (let a = 0; a < data.records.length; a++) {
  530. if (!data.records[a].rowIndex) {
  531. data.records[a].rowIndex = a + (currentPage - 1) * 10;
  532. }
  533. }
  534. dataSource.value = data.records;
  535. } else {
  536. pagination.total = 0;
  537. dataSource.value = [];
  538. }
  539. // 合计逻辑 [待优化 3.0]
  540. handleSumColumn(columns.value, pagination.total);
  541. }
  542. /**
  543. * 获取查询参数
  544. */
  545. function getQueryParams() {
  546. let paramTarget = {};
  547. if (unref(dynamicParam)) {
  548. //处理自定义参数
  549. Object.keys(unref(dynamicParam)).map((key) => {
  550. paramTarget['self_' + key] = unref(dynamicParam)[key];
  551. });
  552. }
  553. let param = Object.assign(paramTarget, unref(queryParam), unref(iSorter));
  554. param.pageNo = pagination.current;
  555. // 合计逻辑 [待优化 3.0]
  556. // 实际查询时不使用table组件的pageSize,而使用自定义的realPageSize,realPageSize会在第一次获取到数据后变化
  557. param.pageSize = pagination.realPageSize;
  558. return filterObj(param);
  559. }
  560. /**
  561. * 处理动态参数
  562. */
  563. function dynamicParamHandler(arr?) {
  564. if (arr && arr.length > 0) {
  565. //第一次加载查询条件前 初始化queryParam为空对象
  566. let queryTemp = {};
  567. for (let item of arr) {
  568. if (item.mode === 'single') {
  569. queryTemp[item.field] = '';
  570. }
  571. }
  572. queryParam.value = { ...queryTemp };
  573. }
  574. let dynamicTemp = {};
  575. if (props.param) {
  576. Object.keys(props.param).map((key) => {
  577. let str = props.param[key];
  578. if (key in queryParam) {
  579. if (str && str.startsWith("'") && str.endsWith("'")) {
  580. str = str.substring(1, str.length - 1);
  581. }
  582. //如果查询条件包含参数 设置值
  583. unref(queryParam)[key] = str;
  584. }
  585. dynamicTemp[key] = props.param[key];
  586. });
  587. }
  588. dynamicParam.value = { ...dynamicTemp };
  589. }
  590. /**
  591. * 分页
  592. * @param page
  593. * @param filters
  594. * @param sorter
  595. */
  596. function handleChangeInTable(page, filters, sorter) {
  597. console.log(page, filters, sorter);
  598. //分页、排序、筛选变化时触发
  599. if (Object.keys(sorter).length > 0) {
  600. iSorter.value = {
  601. column: sorter.field,
  602. order: 'ascend' === sorter.order ? 'asc' : 'desc',
  603. };
  604. // 排序字段受控
  605. unref(columns).forEach((col) => {
  606. if (col['dataIndex'] === sorter.field) {
  607. col['sortOrder'] = sorter.order;
  608. }
  609. });
  610. }
  611. pagination.current = page.current;
  612. pagination.pageSize = page.pageSize;
  613. loadData();
  614. }
  615. /**
  616. * 行点击事件
  617. * @param record
  618. */
  619. function clickThenCheck(record) {
  620. if (clickThenCheckFlag === true) {
  621. let rowKey = combineRowKey(record);
  622. if (!unref(checkedKeys) || unref(checkedKeys).length == 0) {
  623. let arr1: any[] = [],
  624. arr2: any[] = [];
  625. arr1.push(record);
  626. arr2.push(rowKey);
  627. checkedKeys.value = arr2;
  628. selectRows.value = arr1;
  629. } else {
  630. if (unref(checkedKeys).indexOf(rowKey) < 0) {
  631. //不存在就选中
  632. checkedKeys.value.push(rowKey);
  633. selectRows.value.push(record);
  634. } else {
  635. //已选中就取消
  636. let rowKey_index = unref(checkedKeys).indexOf(rowKey);
  637. checkedKeys.value.splice(rowKey_index, 1);
  638. selectRows.value.splice(rowKey_index, 1);
  639. }
  640. }
  641. }
  642. }
  643. //防止字典中有垃圾数据
  644. function initDictOptionData(arr) {
  645. let obj = {};
  646. Object.keys(arr).map((k) => {
  647. obj[k] = arr[k].filter((item) => {
  648. return item != null;
  649. });
  650. });
  651. dictOptions.value = obj;
  652. }
  653. /**
  654. * 过滤对象中为空的属性
  655. * @param obj
  656. * @returns {*}
  657. */
  658. function filterObj(obj) {
  659. if (!(typeof obj == 'object')) {
  660. return;
  661. }
  662. for (let key in obj) {
  663. if (obj.hasOwnProperty(key) && (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
  664. delete obj[key];
  665. }
  666. }
  667. return obj;
  668. }
  669. // 样式
  670. const dialogStyle = {
  671. top: 0,
  672. left: 0,
  673. height: '100%',
  674. margin: 0,
  675. padding: 0,
  676. };
  677. // 弹窗属性配置
  678. const hrefComponent = ref({
  679. model: {
  680. title: '',
  681. okText: '关闭',
  682. width: '100%',
  683. visible: false,
  684. destroyOnClose: true,
  685. style: dialogStyle,
  686. // dialogStyle: dialogStyle,
  687. bodyStyle: {
  688. padding: '8px',
  689. height: 'calc(100vh - 108px)',
  690. overflow: 'auto',
  691. overflowX: 'hidden',
  692. },
  693. // 隐藏掉取消按钮
  694. cancelButtonProps: { style: { display: 'none' } },
  695. },
  696. on: {
  697. ok: () => (hrefComponent.value.model.visible = false),
  698. cancel: () => (hrefComponent.value.model.visible = false),
  699. },
  700. is: <any>null,
  701. params: {},
  702. });
  703. // 超链点击事件--> 打开一个modal窗口
  704. function openHrefCompModal(href) {
  705. // 解析 href 参数
  706. let index = href.indexOf('?');
  707. let path = href;
  708. if (index !== -1) {
  709. path = href.substring(0, index);
  710. let paramString = href.substring(index + 1, href.length);
  711. let paramArray = paramString.split('&');
  712. let params = {};
  713. paramArray.forEach((paramObject) => {
  714. let paramItem = paramObject.split('=');
  715. params[paramItem[0]] = paramItem[1];
  716. });
  717. hrefComponent.value.params = params;
  718. } else {
  719. hrefComponent.value.params = {};
  720. }
  721. hrefComponent.value.model.visible = true;
  722. hrefComponent.value.model.title = '操作';
  723. hrefComponent.value.is = markRaw(defineAsyncComponent(() => importViewsFile(path)));
  724. }
  725. //update-begin-author:taoyan date:2022-5-31 for: VUEN-1155 popup 选择数据时,会选择多条重复数据
  726. /**
  727. * emit事件 获取选中的行数据
  728. */
  729. function getOkSelectRows(): any[] {
  730. let arr = unref(selectRows);
  731. let selectedRowKeys = checkedKeys.value;
  732. console.log('arr', arr);
  733. if (!selectedRowKeys || selectedRowKeys.length <= 0) {
  734. return [];
  735. }
  736. if (!arr || arr.length <= 0) {
  737. return [];
  738. }
  739. let rows: any = [];
  740. for (let key of selectedRowKeys) {
  741. for (let i = 0; i < arr.length; i++) {
  742. let combineKey = combineRowKey(arr[i]);
  743. if (key === combineKey) {
  744. rows.push(toRaw(arr[i]));
  745. break;
  746. }
  747. }
  748. }
  749. return rows;
  750. }
  751. //update-end-author:taoyan date:2022-5-31 for: VUEN-1155 popup 选择数据时,会选择多条重复数据
  752. return [
  753. {
  754. visibleChange,
  755. loadColumnsInfo,
  756. loadColumnsAndData,
  757. dynamicParamHandler,
  758. loadData,
  759. handleChangeInTable,
  760. combineRowKey,
  761. clickThenCheck,
  762. filterUnuseSelect,
  763. handleExport,
  764. getOkSelectRows,
  765. },
  766. {
  767. hrefComponent,
  768. visible,
  769. rowSelection,
  770. checkedKeys,
  771. selectRows,
  772. pagination,
  773. dataSource,
  774. columns,
  775. indexColumnProps,
  776. loading,
  777. title,
  778. iSorter,
  779. queryInfo,
  780. queryParam,
  781. dictOptions,
  782. },
  783. ];
  784. }