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