useVxeGrid.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import { computed, nextTick, reactive } from 'vue'
  2. import { SizeType, VxeGridProps, VxeTablePropTypes } from 'vxe-table'
  3. import { useAppStore } from '@/store/modules/app'
  4. import { VxeAllSchemas } from './useVxeCrudSchemas'
  5. import download from '@/utils/download'
  6. const { t } = useI18n()
  7. const message = useMessage() // 消息弹窗
  8. interface UseVxeGridConfig<T = any> {
  9. allSchemas: VxeAllSchemas
  10. height?: number // 高度 默认730
  11. topActionSlots?: boolean // 是否开启表格内顶部操作栏插槽
  12. treeConfig?: VxeTablePropTypes.TreeConfig // 树形表单配置
  13. isList?: boolean // 是否不带分页的list
  14. getListApi: (option: any) => Promise<T> // 获取列表接口
  15. getAllListApi?: (option: any) => Promise<T> // 获取全部数据接口 用于VXE导出
  16. deleteApi?: (option: any) => Promise<T> // 删除接口
  17. exportListApi?: (option: any) => Promise<T> // 导出接口
  18. exportName?: string // 导出文件夹名称
  19. queryParams?: any // 其他查询参数
  20. }
  21. const appStore = useAppStore()
  22. const currentSize = computed(() => {
  23. let resSize: SizeType = 'small'
  24. const appsize = appStore.getCurrentSize
  25. switch (appsize) {
  26. case 'large':
  27. resSize = 'medium'
  28. break
  29. case 'default':
  30. resSize = 'small'
  31. break
  32. case 'small':
  33. resSize = 'mini'
  34. break
  35. }
  36. return resSize
  37. })
  38. export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => {
  39. /**
  40. * grid options 初始化
  41. */
  42. const gridOptions = reactive<VxeGridProps<any>>({
  43. loading: true,
  44. size: currentSize as any,
  45. height: config?.height ? config.height : 730,
  46. rowConfig: {
  47. isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
  48. isHover: true // 当鼠标移到行时,是否要高亮当前行
  49. },
  50. toolbarConfig: {
  51. slots:
  52. !config?.topActionSlots && config?.topActionSlots != false
  53. ? { buttons: 'toolbar_buttons' }
  54. : {}
  55. },
  56. printConfig: {
  57. columns: config?.allSchemas.printSchema
  58. },
  59. formConfig: {
  60. enabled: true,
  61. titleWidth: 100,
  62. titleAlign: 'right',
  63. items: config?.allSchemas.searchSchema
  64. },
  65. columns: config?.allSchemas.tableSchema,
  66. proxyConfig: {
  67. seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
  68. form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
  69. props: { result: 'list', total: 'total' },
  70. ajax: {
  71. query: ({ page, form }) => {
  72. let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
  73. if (config?.queryParams) {
  74. queryParams = Object.assign(queryParams, config.queryParams)
  75. }
  76. if (!config?.treeConfig) {
  77. queryParams.pageSize = page.pageSize
  78. queryParams.pageNo = page.currentPage
  79. }
  80. gridOptions.loading = false
  81. return new Promise(async (resolve) => {
  82. resolve(await config?.getListApi(queryParams))
  83. })
  84. },
  85. delete: ({ body }) => {
  86. return new Promise(async (resolve) => {
  87. if (config?.deleteApi) {
  88. resolve(await config?.deleteApi(JSON.stringify(body)))
  89. } else {
  90. Promise.reject('未设置deleteApi')
  91. }
  92. })
  93. },
  94. queryAll: ({ form }) => {
  95. const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form)))
  96. return new Promise(async (resolve) => {
  97. if (config?.getAllListApi) {
  98. resolve(await config?.getAllListApi(queryParams))
  99. } else {
  100. resolve(await config?.getListApi(queryParams))
  101. }
  102. })
  103. }
  104. }
  105. },
  106. exportConfig: {
  107. filename: config?.exportName,
  108. // 默认选中类型
  109. type: 'csv',
  110. // 自定义数据量列表
  111. modes: config?.getAllListApi ? ['current', 'all'] : ['current'],
  112. columns: config?.allSchemas.printSchema
  113. }
  114. })
  115. if (config?.treeConfig) {
  116. gridOptions.treeConfig = config.treeConfig
  117. } else if (config?.isList) {
  118. gridOptions.proxyConfig = {
  119. seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
  120. form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
  121. props: { result: 'data' },
  122. ajax: {
  123. query: ({ form }) => {
  124. let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
  125. if (config?.queryParams) {
  126. queryParams = Object.assign(queryParams, config.queryParams)
  127. }
  128. gridOptions.loading = false
  129. return new Promise(async (resolve) => {
  130. resolve(await config?.getListApi(queryParams))
  131. })
  132. }
  133. }
  134. }
  135. } else {
  136. gridOptions.pagerConfig = {
  137. border: false, // 带边框
  138. background: true, // 带背景颜色
  139. perfect: false, // 配套的样式
  140. pageSize: 10, // 每页大小
  141. pagerCount: 7, // 显示页码按钮的数量
  142. autoHidden: false, // 当只有一页时自动隐藏
  143. pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
  144. layouts: [
  145. 'PrevJump',
  146. 'PrevPage',
  147. 'JumpNumber',
  148. 'NextPage',
  149. 'NextJump',
  150. 'Sizes',
  151. 'FullJump',
  152. 'Total'
  153. ]
  154. }
  155. }
  156. /**
  157. * 刷新列表
  158. * @param ref
  159. * @returns
  160. */
  161. const getList = async (ref) => {
  162. if (!ref) {
  163. console.error('未传入gridRef')
  164. return
  165. }
  166. await nextTick()
  167. ref.value.commitProxy('query')
  168. }
  169. // 获取查询参数
  170. const getSearchData = async (ref) => {
  171. if (!ref) {
  172. console.error('未传入gridRef')
  173. return
  174. }
  175. await nextTick()
  176. const queryParams = Object.assign(
  177. {},
  178. JSON.parse(JSON.stringify(ref.value.getProxyInfo()?.form))
  179. )
  180. return queryParams
  181. }
  182. /**
  183. * 删除
  184. * @param ref
  185. * @param ids rowid
  186. * @returns
  187. */
  188. const deleteData = async (ref, ids: string | number) => {
  189. if (!ref) {
  190. console.error('未传入gridRef')
  191. return
  192. }
  193. if (!config?.deleteApi) {
  194. console.error('未传入delListApi')
  195. return
  196. }
  197. await nextTick()
  198. return new Promise(async () => {
  199. message.delConfirm().then(async () => {
  200. await (config?.deleteApi && config?.deleteApi(ids))
  201. message.success(t('common.delSuccess'))
  202. // 刷新列表
  203. ref.value.commitProxy('query')
  204. })
  205. })
  206. }
  207. /**
  208. * 导出
  209. * @param ref
  210. * @param fileName 文件名,默认excel.xls
  211. * @returns
  212. */
  213. const exportList = async (ref, fileName?: string) => {
  214. if (!ref) {
  215. console.error('未传入gridRef')
  216. return
  217. }
  218. if (!config?.exportListApi) {
  219. console.error('未传入exportListApi')
  220. return
  221. }
  222. await nextTick()
  223. const queryParams = Object.assign(
  224. {},
  225. JSON.parse(JSON.stringify(ref.value?.getProxyInfo()?.form))
  226. )
  227. message.exportConfirm().then(async () => {
  228. const res = await (config?.exportListApi && config?.exportListApi(queryParams))
  229. download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls')
  230. })
  231. }
  232. /**
  233. * 表格最大/最小化
  234. * @param ref
  235. * @returns
  236. */
  237. const zoom = async (ref) => {
  238. if (!ref) {
  239. console.error('未传入gridRef')
  240. return
  241. }
  242. await nextTick()
  243. ref.value.zoom(!ref.value.isMaximized())
  244. }
  245. return {
  246. gridOptions,
  247. getList,
  248. getSearchData,
  249. deleteData,
  250. exportList,
  251. zoom
  252. }
  253. }