useVxeGrid.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 { useI18n } from '@/hooks/web/useI18n'
  6. import { useMessage } from '@/hooks/web/useMessage'
  7. import download from '@/utils/download'
  8. const { t } = useI18n()
  9. const message = useMessage() // 消息弹窗
  10. interface UseVxeGridConfig<T = any> {
  11. allSchemas: VxeAllSchemas
  12. topActionSlots?: boolean // 是否开启表格内顶部操作栏插槽
  13. treeConfig?: VxeTablePropTypes.TreeConfig // 树形表单配置
  14. isList?: boolean // 是否不带分页的list
  15. getListApi: (option: any) => Promise<T> // 获取列表接口
  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: 730, // 1080高度
  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. queryAll: ({ form }) => {
  86. const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form)))
  87. return new Promise(async (resolve) => {
  88. if (config?.exportListApi) {
  89. resolve(await config?.exportListApi(queryParams))
  90. } else {
  91. resolve(await config?.getListApi(queryParams))
  92. }
  93. })
  94. }
  95. }
  96. },
  97. exportConfig: {
  98. filename: config?.exportName,
  99. // 默认选中类型
  100. type: 'csv',
  101. // 自定义数据量列表
  102. modes: ['current', 'all'],
  103. columns: config?.allSchemas.printSchema
  104. }
  105. })
  106. if (config?.treeConfig) {
  107. gridOptions.treeConfig = config.treeConfig
  108. } else if (config?.isList) {
  109. gridOptions.proxyConfig = {
  110. seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
  111. form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
  112. props: { result: 'data' },
  113. ajax: {
  114. query: ({ form }) => {
  115. let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
  116. if (config?.queryParams) {
  117. queryParams = Object.assign(queryParams, config.queryParams)
  118. }
  119. gridOptions.loading = false
  120. return new Promise(async (resolve) => {
  121. resolve(await config?.getListApi(queryParams))
  122. })
  123. }
  124. }
  125. }
  126. } else {
  127. gridOptions.pagerConfig = {
  128. border: false, // 带边框
  129. background: true, // 带背景颜色
  130. perfect: false, // 配套的样式
  131. pageSize: 10, // 每页大小
  132. pagerCount: 7, // 显示页码按钮的数量
  133. autoHidden: false, // 当只有一页时自动隐藏
  134. pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
  135. layouts: [
  136. 'PrevJump',
  137. 'PrevPage',
  138. 'JumpNumber',
  139. 'NextPage',
  140. 'NextJump',
  141. 'Sizes',
  142. 'FullJump',
  143. 'Total'
  144. ]
  145. }
  146. }
  147. /**
  148. * 刷新列表
  149. * @param ref
  150. * @returns
  151. */
  152. const getList = async (ref) => {
  153. if (!ref) {
  154. console.error('未传入gridRef')
  155. return
  156. }
  157. await nextTick()
  158. ref.value.commitProxy('query')
  159. }
  160. // 获取查询参数
  161. const getSearchData = async (ref) => {
  162. if (!ref) {
  163. console.error('未传入gridRef')
  164. return
  165. }
  166. await nextTick()
  167. const queryParams = Object.assign(
  168. {},
  169. JSON.parse(JSON.stringify(ref.value.getProxyInfo()?.form))
  170. )
  171. return queryParams
  172. }
  173. /**
  174. * 删除
  175. * @param ref
  176. * @param ids rowid
  177. * @returns
  178. */
  179. const deleteData = async (ref, ids: string | number) => {
  180. if (!ref) {
  181. console.error('未传入gridRef')
  182. return
  183. }
  184. if (!config?.deleteApi) {
  185. console.error('未传入delListApi')
  186. return
  187. }
  188. await nextTick()
  189. return new Promise(async () => {
  190. message.delConfirm().then(async () => {
  191. await (config?.deleteApi && config?.deleteApi(ids))
  192. message.success(t('common.delSuccess'))
  193. // 刷新列表
  194. ref.value.commitProxy('query')
  195. })
  196. })
  197. }
  198. /**
  199. * 导出
  200. * @param ref
  201. * @param fileName 文件名,默认excel.xls
  202. * @returns
  203. */
  204. const exportList = async (ref, fileName?: string) => {
  205. if (!ref) {
  206. console.error('未传入gridRef')
  207. return
  208. }
  209. if (!config?.exportListApi) {
  210. console.error('未传入exportListApi')
  211. return
  212. }
  213. await nextTick()
  214. const queryParams = Object.assign(
  215. {},
  216. JSON.parse(JSON.stringify(ref.value?.getProxyInfo()?.form))
  217. )
  218. message.exportConfirm().then(async () => {
  219. const res = await (config?.exportListApi && config?.exportListApi(queryParams))
  220. download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls')
  221. })
  222. }
  223. /**
  224. * 表格最大/最小化
  225. * @param ref
  226. * @returns
  227. */
  228. const zoom = async (ref) => {
  229. if (!ref) {
  230. console.error('未传入gridRef')
  231. return
  232. }
  233. await nextTick()
  234. ref.value.zoom(!ref.value.isMaximized())
  235. }
  236. return {
  237. gridOptions,
  238. getList,
  239. getSearchData,
  240. deleteData,
  241. exportList,
  242. zoom
  243. }
  244. }