index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <!--
  2. * @Descripttion: 数据表格组件
  3. * @version: 1.10
  4. -->
  5. <template>
  6. <el-main>
  7. <vxe-grid ref="xGrid" v-bind="gridOptions" @form-collapse="formCollapseEvent" @edit-activated="$emit('editActivated', $event)" @page-change="pageChangeEvent">
  8. <template #queryAction>
  9. <el-button type="primary" auto-insert-space @click="searchData">查询</el-button>
  10. <el-button auto-insert-space @click="resetData">重置</el-button>
  11. </template>
  12. <!-- table-column / 操作 -->
  13. <template v-for="(_, slotName) in $slots" #[slotName]="context">
  14. <slot :name="slotName" v-bind="{ ...context, row: XEUtils.get(context, '$grid', XEUtils.get(context, '$table'))?.getData(context.rowIndex) || context.row }"></slot>
  15. </template>
  16. </vxe-grid>
  17. </el-main>
  18. </template>
  19. <script setup>
  20. // 设置当前zIndex起始值
  21. import domZIndex from "dom-zindex";
  22. domZIndex.setCurrent(domZIndex.getMax() + 1);
  23. import VxeUI from "vxe-pc-ui";
  24. import XEUtils from "xe-utils";
  25. import store from "@/store";
  26. import config from "@/config/table";
  27. import pagerBatchDel from "./renderer/pager-batch-del";
  28. const props = defineProps({
  29. apiObj: { type: Object, default: () => {} },
  30. apiKey: { type: String, default: () => "get" },
  31. framework: { type: String, default: () => "common" },
  32. minHeight: { type: [String, Number], default: () => VxeUI.getConfig().table.minHeight },
  33. maxHeight: { type: [String, Number] },
  34. layouts: { type: Array, default: () => [["Top", "Form"], ["Toolbar", "Table", "Bottom", "Pager"]] },
  35. /* *************** query *************** */
  36. formConfig: { type: Object, default: () => {} },
  37. paramsColums: { type: Array, default: () => [] },
  38. /* *************** query *************** */
  39. toolbarConfig: { type: Object, default: () => {} },
  40. editConfig: { type: Object, default: () => {} },
  41. columns: { type: Array, default: () => [] },
  42. /* *************** pager *************** */
  43. pagerConfig: { type: Object, default: () => {} },
  44. batchDel: { type: Boolean, default: () => false },
  45. /* *************** pager *************** */
  46. options: { type: Object, default: () => {} }
  47. })
  48. const xGrid = ref();
  49. const selectedRows = ref([]);
  50. const gridOptions = ref({
  51. id: "xGride-table",
  52. loading: false,
  53. minHeight: props.minHeight,
  54. border: "full",
  55. size: "mini",
  56. data: [],
  57. columns: XEUtils.map(props.columns, item => ({ ...item, [item.type != "seq" && "exportMethod"]: ({ row, column }) => row[column?.field] || "" })),
  58. showOverflow: true,
  59. keepSource: true,
  60. layouts: [...props.layouts],
  61. formConfig: {
  62. enabled: true,
  63. className: "vxe-table-query",
  64. titleAlign: "right",
  65. collapseStatus: true,
  66. span: 6,
  67. items: [
  68. ...XEUtils.map(XEUtils.orderBy(XEUtils.get(props, "formConfig.items", []), "orderBy"), (formItem, formIndex) => {
  69. return {
  70. ...formItem,
  71. className: ({ $grid, item, data }) => {
  72. const showItems = XEUtils.filter(XEUtils.orderBy(XEUtils.get(props, "formConfig.items", []), "orderBy"), f_item => (XEUtils.isUndefined(f_item.visible) || f_item.visible) && (XEUtils.isUndefined(f_item.visibleMethod) || f_item.visibleMethod({ data })));
  73. const index = XEUtils.findIndexOf(showItems, f_item => f_item.field == item.field);
  74. item.folding = index > 2;
  75. XEUtils.set(formItem, "folding", index > 2);
  76. return "";
  77. }
  78. }
  79. }), {
  80. align: "right",
  81. slots: { default: "queryAction" },
  82. className: ({ $grid, item, data }) => {
  83. const showItems = XEUtils.filter(XEUtils.orderBy(XEUtils.get(props, "formConfig.items", []), "orderBy"), formItem => (XEUtils.isUndefined(formItem.visible) || formItem.visible) && (XEUtils.isUndefined(formItem.visibleMethod) || formItem.visibleMethod({ data })));
  84. const spanItems = (!gridOptions.value.formConfig.collapseStatus && showItems) || XEUtils.filter(showItems, f_item => !f_item.folding);
  85. const remainder = 24 - (XEUtils.sum(spanItems, s_item => s_item.span || 6) % 24);
  86. item.visible = showItems.length > 0;
  87. item.collapseNode = showItems.length > 3;
  88. item.span = remainder < 6 && 24 || remainder;
  89. return "query-action__item";
  90. }
  91. }
  92. ],
  93. ...XEUtils.omit(XEUtils.get(props, "formConfig", {}), "items")
  94. },
  95. toolbarConfig: {
  96. enabled: false,
  97. buttons: [
  98. { buttonRender: { name: "$table-search" } }
  99. ],
  100. print: true,
  101. zoom: true,
  102. custom: true,
  103. refresh: {
  104. queryMethod: () => getData(),
  105. },
  106. ...props.toolbarConfig
  107. },
  108. proxyConfig: {
  109. enabled: false
  110. },
  111. printConfig: {},
  112. importConfig: {
  113. // remote: true,
  114. types: ["xlsx", "xls"],
  115. mode: "insertBottom",
  116. modes: ["insertBottom", "insertTop", "covering"],
  117. // importMethod: ({ $grid, options }) => {},
  118. },
  119. exportConfig: {
  120. remote: true,
  121. types: ["xlsx"],
  122. modes: XEUtils.find(props.columns, item => XEUtils.includes(config.exportExcludeFields, item.type)) && ["current", "selected", "all"] || ["current", "all"],
  123. columns: XEUtils.filter(props.columns, item => !XEUtils.includes(config.exportExcludeFields, item.type)),
  124. exportMethod: ({ $grid, options }) => exportEvent($grid, options)
  125. },
  126. rowConfig: {
  127. keyField: "id",
  128. useKey: true,
  129. isHover: true
  130. },
  131. columnConfig: {
  132. useKey: true,
  133. resizable: true // 列宽拖动功能
  134. },
  135. headerCellConfig: {
  136. height: 36
  137. },
  138. cellConfig: {
  139. height: 36
  140. },
  141. checkboxConfig: {
  142. highlight: true,
  143. range: true // 鼠标在复选框的列内滑动选中或取消指定行
  144. },
  145. tooltipConfig: {
  146. enterable: true
  147. },
  148. expandConfig: {
  149. padding: true
  150. },
  151. editConfig: {
  152. enabled: false,
  153. mode: "cell",
  154. trigger: "click",
  155. showStatus: true,
  156. ...props.editConfig
  157. },
  158. pagerConfig: {
  159. queryType: "limit", // 页码筛选类型
  160. className: "vxe-table-pager",
  161. pageSizes: config.pageSizes,
  162. layouts: config.layouts,
  163. currentPage: 1,
  164. pageSize: config.pageSize,
  165. total: 0,
  166. slots: {
  167. left: params => props.batchDel && h(pagerBatchDel, { params })
  168. },
  169. ...props.pagerConfig
  170. }
  171. })
  172. watch(() => xGrid.value?.getCheckboxRecords(), val => selectedRows.value = val);
  173. addEventListener("resize", () => resizeTable());
  174. onMounted(() => {
  175. XEUtils.merge(gridOptions.value, props.options);
  176. resizeTable();
  177. getData();
  178. });
  179. const resizeTable = () => {
  180. nextTick(() => {
  181. if (store.state.global.ismobile) XEUtils.set(gridOptions.value, "maxHeight", 1048);
  182. else XEUtils.set(gridOptions.value, "maxHeight", (props.maxHeight || xGrid.value?.$el.parentElement.offsetHeight));
  183. });
  184. }
  185. // 获取数据
  186. const getData = () => {
  187. if (!props.apiObj) return;
  188. nextTick(() => {
  189. gridOptions.value.loading = true;
  190. const reqData = config.framework[props.framework].queryData(gridOptions.value, props.paramsColums);
  191. props.apiObj[props.apiKey](reqData).then(res => {
  192. const response = config.framework[props.framework].parseData(res);
  193. gridOptions.value.data = response.data || [];
  194. gridOptions.value.pagerConfig.total = response.total || 0;
  195. gridOptions.value.loading = false;
  196. }).catch(error => {
  197. gridOptions.value.loading = false;
  198. gridOptions.value.data = [];
  199. gridOptions.value.pagerConfig.total = 0;
  200. });
  201. });
  202. }
  203. const pageChangeEvent = ({ pageSize, currentPage }) => {
  204. gridOptions.value.pagerConfig.currentPage = currentPage;
  205. gridOptions.value.pagerConfig.pageSize = pageSize;
  206. getData();
  207. }
  208. const searchData = (mode = "add") => {
  209. if (mode == "add") gridOptions.value.pagerConfig.currentPage = 1;
  210. gridOptions.value.pagerConfig.pageSize = config.pageSize;
  211. getData();
  212. }
  213. const resetData = () => {
  214. gridOptions.value.pagerConfig.currentPage = 1;
  215. gridOptions.value.pagerConfig.pageSize = config.pageSize;
  216. XEUtils.arrayEach(gridOptions.value.formConfig.items, item => XEUtils.set(gridOptions.value.formConfig.data, item.field, XEUtils.get(item, "resetValue")));
  217. XEUtils.merge(gridOptions.value.formConfig.data, XEUtils.omit(gridOptions.value.formConfig.data, item => XEUtils.isEmpty(item) && !XEUtils.isNumber(item)));
  218. getData();
  219. }
  220. const formCollapseEvent = ({ collapse }) => gridOptions.value.formConfig.collapseStatus = collapse;
  221. const toggleFormEnabled = () => gridOptions.value.formConfig.enabled = !gridOptions.value.formConfig.enabled;
  222. const toggleToolbarProps = obj => XEUtils.objectEach(obj, (value, key) => XEUtils.set(gridOptions.value.toolbarConfig, key, value));
  223. const reloadColumn = columns => xGrid.value.reloadColumn(columns);
  224. const getTableData = () => xGrid.value.getTableData();
  225. const reloadData = data => xGrid.value.reloadData(data);
  226. const exportEvent = async ($grid, options) => {
  227. let data = XEUtils.clone(options.data);
  228. if (options.mode == "all") {
  229. const reqData = config.framework[props.framework].queryExport(gridOptions.value);
  230. const res = await props.apiObj[props.apiKey](reqData);
  231. const response = config.framework[props.framework].parseData(res);
  232. data = response.data || [];
  233. }
  234. $grid.exportData({
  235. ...options,
  236. remote: false,
  237. columns: XEUtils.map(options.columns, item => ({ ...item, [item.type != "seq" && "exportMethod"]: ({ row, column }) => row[column?.field] || "" })),
  238. data
  239. });
  240. }
  241. defineExpose({
  242. selectedRows,
  243. toggleFormEnabled,
  244. toggleToolbarProps,
  245. reloadColumn,
  246. getTableData,
  247. reloadData,
  248. searchData,
  249. resetData
  250. })
  251. </script>
  252. <style scoped>
  253. .el-main {padding: 0 12px 12px;background: var(--el-bg-color);}
  254. </style>