useTable.ts 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * @Author: fxs bjnsfxs@163.com
  3. * @Date: 2024-08-20 17:15:49
  4. * @LastEditors: fxs bjnsfxs@163.com
  5. * @LastEditTime: 2024-12-07
  6. * @Description:
  7. *
  8. */
  9. import type { ResponseInfo } from '@/types/res'
  10. import type { TableFieldInfo, TablePaginationSetting } from '@/types/table'
  11. import { initLoadResource } from '@/utils/resource'
  12. import { reactive, toRaw } from 'vue'
  13. // import { downLoadData } from '@/utils/table/table'
  14. import { generateRandomFileName } from '@/utils/common'
  15. import * as xlsx from 'xlsx'
  16. import axiosInstance from '../utils/axios/axiosInstance'
  17. import type { ReqConfig } from '@/types/dataAnalysis'
  18. // 资源的加载路径
  19. const resourceInfo: Record<string, string> = {
  20. defaultHead: `/img/default/defaultHead.png`
  21. }
  22. // 使用blob的资源路径信息
  23. const blobUrlInfo = reactive<Record<string, string>>({})
  24. // 初始化资源
  25. initLoadResource(resourceInfo).then((data) => {
  26. Object.assign(blobUrlInfo, data)
  27. })
  28. export function useTable(
  29. tableData: Array<any>,
  30. paginationSetting: TablePaginationSetting,
  31. tableFieldsInfo: TableFieldInfo[]
  32. ) {
  33. /**
  34. * @description: 设置默认头像
  35. * @param data 请求回来的数据表格
  36. * @return 返回处理后的数据
  37. */
  38. const setDefaultHead = (data: Array<any>): Array<any> => {
  39. if (data) {
  40. data.map(async (item: any) => {
  41. if (!item.head) item.head = blobUrlInfo.defaultHead
  42. })
  43. }
  44. return data
  45. }
  46. /**
  47. * 将请求的数据写入tableData
  48. *
  49. * 对开启分页的数据做单独的处理
  50. *
  51. * @param dataList 数据列表
  52. * @param total 数据总量
  53. * @param openPagination 是否开启了分页查询
  54. * @param openRemoteReq 是否是远程请求
  55. * @return 成功返回true,反之false
  56. */
  57. const setTableData = (
  58. dataList: Array<any>,
  59. total: number,
  60. openPagination: boolean,
  61. openRemoteReq: boolean
  62. ): boolean => {
  63. try {
  64. if (!dataList || dataList.length === 0) {
  65. tableData.length = 0
  66. paginationSetting.total = 0
  67. } else {
  68. // 确保返回的数据中有total才赋值,否则直接使用长度
  69. if (total) {
  70. paginationSetting.total = total
  71. } else {
  72. paginationSetting.total = dataList.length
  73. }
  74. console.log(paginationSetting.total)
  75. // 处理有头像的字段
  76. dataList = setDefaultHead(dataList)
  77. // 如果开启了分页,设置 tableData 为二维数组,否则为一维数组
  78. const pageIndex = paginationSetting.currentPage ?? 0
  79. if (openPagination && openRemoteReq) {
  80. tableData[pageIndex] = dataList
  81. } else {
  82. tableData.splice(0, tableData.length, ...dataList)
  83. }
  84. }
  85. return true
  86. } catch (err) {
  87. console.error('数据处理错误:', err)
  88. return false
  89. }
  90. }
  91. /**
  92. * @description 获取表格数据
  93. * @param url 请求地址
  94. * @param option 请求参数
  95. * @return [表格数据,总数]
  96. */
  97. const getTableData = async (
  98. url: string,
  99. option: Record<string, any>
  100. ): Promise<[Array<any>, number]> => {
  101. try {
  102. const result = await axiosInstance.post<any, ResponseInfo>(url, option)
  103. return [result.data ?? [], result.count ?? 0]
  104. } catch (err) {
  105. console.error('请求数据错误:', err)
  106. return [[], 0]
  107. }
  108. }
  109. /**
  110. * 开启行号功能后,计算行号
  111. * @param index 当前行索引
  112. */
  113. const computedRowIndex = (index: number) => {
  114. return (paginationSetting.currentPage - 1) * paginationSetting.limit + index + 1
  115. }
  116. /**
  117. * @description: 改变页码
  118. * @param val
  119. */
  120. const handleCurrentChange = (val: number) => {
  121. paginationSetting.currentPage = val
  122. }
  123. /**
  124. * @description 改变每页大小
  125. * @param val
  126. */
  127. const handleSizeChange = (val: number) => {
  128. paginationSetting.limit = val
  129. }
  130. /**
  131. * 插入均值行
  132. *
  133. * @param needAverage 是否需要计算平均值
  134. * @param openRemoteReqData 是否是远程请求
  135. */
  136. const insertAverageRow = (needAverage: boolean, openRemoteReqData: boolean) => {
  137. if (needAverage) {
  138. const rowData: any = {}
  139. const oldList: Array<any> = JSON.parse(JSON.stringify(tableData))
  140. Object.values(tableFieldsInfo).map((item: TableFieldInfo, index: number) => {
  141. const sum = oldList
  142. .map((item) => item.count)
  143. .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
  144. const averageList = oldList
  145. .map((val) => val[item.name])
  146. .filter((item) => item !== undefined)
  147. if (index === 0) rowData[item.name] = '均值'
  148. else if (item.name === 'count') rowData[item.name] = sum
  149. else {
  150. const num =
  151. averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
  152. averageList.length
  153. rowData[item.name] = isNaN(num) ? 0 : num.toFixed(2)
  154. }
  155. })
  156. if (openRemoteReqData) {
  157. tableData[0].splice(0, 0, rowData)
  158. } else {
  159. tableData.splice(0, 0, rowData)
  160. }
  161. }
  162. }
  163. /**
  164. * 清空表格数据
  165. */
  166. const resetTableData = () => {
  167. tableData.splice(0, tableData.length)
  168. }
  169. /**
  170. * @description: 根据计算出来的值去返回对应的颜色深度
  171. * @param number 输入值
  172. */
  173. const getDecimalFromRange = (number: number) => {
  174. if (!number) return 0
  175. if (number < 25) return 0.25
  176. else if (number < 50) return 0.5
  177. else if (number < 75) return 0.75
  178. else return 1.0 // 如果number >= 75,则直接返回1.00
  179. }
  180. /**
  181. * @description: 初始化分页配置,把传入的配置拷贝一份
  182. */
  183. const initPageConfig = (propPageConfig?: TablePaginationSetting) => {
  184. if (propPageConfig) {
  185. Object.assign(paginationSetting, JSON.parse(JSON.stringify(propPageConfig)))
  186. }
  187. }
  188. /**
  189. * @description: 初始化请求配置,用于把拷贝一份新的数据
  190. */
  191. const initReqConfig = (reqConfig: ReqConfig, propReqConfig?: ReqConfig) => {
  192. if (propReqConfig) {
  193. Object.assign(reqConfig, propReqConfig)
  194. }
  195. }
  196. /**
  197. * @description: 创建row-key优化表格性能
  198. */
  199. const createRowKey = () => {
  200. return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`
  201. }
  202. /**
  203. * @description: 下载表格数据
  204. */
  205. const downLoadTable = (headerMap: Record<string, string> = {}) => {
  206. // downLoadData(generateRandomFileName(), JSON.parse(JSON.stringify(tableData)))
  207. const exportData = tableData
  208. .slice(1)
  209. .flat()
  210. .map((item) => {
  211. const rawData = toRaw(item)
  212. // 遍历对象的键,删除不在 validKeys 中的键
  213. Object.keys(item).forEach((key) => {
  214. if (!(key in headerMap)) {
  215. delete item[key]
  216. }
  217. })
  218. return rawData
  219. })
  220. // 表头设置
  221. // exportData.unshift(headerZh)
  222. const header = Object.keys(headerMap)
  223. const newData = [
  224. {
  225. actionId: '事件ID',
  226. actionName: '事件名称',
  227. actionCount: '操作次数',
  228. actionUserCount: '操作用户数',
  229. activeUserRate: '活跃设备发生率',
  230. loginActiveRate: '每次启动发生数'
  231. },
  232. ...exportData
  233. ]
  234. const workbook = xlsx.utils.book_new()
  235. const worksheet = xlsx.utils.json_to_sheet(newData, {
  236. header: header,
  237. skipHeader: true
  238. })
  239. xlsx.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
  240. return xlsx.writeFile(workbook, generateRandomFileName() + '.xlsx')
  241. }
  242. return {
  243. getTableData,
  244. setTableData,
  245. resetTableData,
  246. initPageConfig,
  247. initReqConfig,
  248. getDecimalFromRange,
  249. computedRowIndex,
  250. handleCurrentChange,
  251. handleSizeChange,
  252. insertAverageRow,
  253. createRowKey,
  254. downLoadTable
  255. }
  256. }