123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /*
- * @Author: fxs bjnsfxs@163.com
- * @Date: 2024-08-20 17:15:49
- * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-12-07
- * @Description:
- *
- */
- import type { ResponseInfo } from '@/types/res'
- import type { TableFieldInfo, TablePaginationSetting } from '@/types/table'
- import { initLoadResource } from '@/utils/resource'
- import { reactive, toRaw } from 'vue'
- // import { downLoadData } from '@/utils/table/table'
- import { generateRandomFileName } from '@/utils/common'
- import * as xlsx from 'xlsx'
- import axiosInstance from '../utils/axios/axiosInstance'
- import type { ReqConfig } from '@/types/dataAnalysis'
- // 资源的加载路径
- const resourceInfo: Record<string, string> = {
- defaultHead: `/img/default/defaultHead.png`
- }
- // 使用blob的资源路径信息
- const blobUrlInfo = reactive<Record<string, string>>({})
- // 初始化资源
- initLoadResource(resourceInfo).then((data) => {
- Object.assign(blobUrlInfo, data)
- })
- export function useTable(
- tableData: Array<any>,
- paginationSetting: TablePaginationSetting,
- tableFieldsInfo: TableFieldInfo[]
- ) {
- /**
- * @description: 设置默认头像
- * @param data 请求回来的数据表格
- * @return 返回处理后的数据
- */
- const setDefaultHead = (data: Array<any>): Array<any> => {
- if (data) {
- data.map(async (item: any) => {
- if (!item.head) item.head = blobUrlInfo.defaultHead
- })
- }
- return data
- }
- /**
- * 将请求的数据写入tableData
- *
- * 对开启分页的数据做单独的处理
- *
- * @param dataList 数据列表
- * @param total 数据总量
- * @param openPagination 是否开启了分页查询
- * @param openRemoteReq 是否是远程请求
- * @return 成功返回true,反之false
- */
- const setTableData = (
- dataList: Array<any>,
- total: number,
- openPagination: boolean,
- openRemoteReq: boolean
- ): boolean => {
- try {
- if (!dataList || dataList.length === 0) {
- tableData.length = 0
- paginationSetting.total = 0
- } else {
- // 确保返回的数据中有total才赋值,否则直接使用长度
- if (total) {
- paginationSetting.total = total
- } else {
- paginationSetting.total = dataList.length
- }
- console.log(paginationSetting.total)
- // 处理有头像的字段
- dataList = setDefaultHead(dataList)
- // 如果开启了分页,设置 tableData 为二维数组,否则为一维数组
- const pageIndex = paginationSetting.currentPage ?? 0
- if (openPagination && openRemoteReq) {
- tableData[pageIndex] = dataList
- } else {
- tableData.splice(0, tableData.length, ...dataList)
- }
- }
- return true
- } catch (err) {
- console.error('数据处理错误:', err)
- return false
- }
- }
- /**
- * @description 获取表格数据
- * @param url 请求地址
- * @param option 请求参数
- * @return [表格数据,总数]
- */
- const getTableData = async (
- url: string,
- option: Record<string, any>
- ): Promise<[Array<any>, number]> => {
- try {
- const result = await axiosInstance.post<any, ResponseInfo>(url, option)
- return [result.data ?? [], result.count ?? 0]
- } catch (err) {
- console.error('请求数据错误:', err)
- return [[], 0]
- }
- }
- /**
- * 开启行号功能后,计算行号
- * @param index 当前行索引
- */
- const computedRowIndex = (index: number) => {
- return (paginationSetting.currentPage - 1) * paginationSetting.limit + index + 1
- }
- /**
- * @description: 改变页码
- * @param val
- */
- const handleCurrentChange = (val: number) => {
- paginationSetting.currentPage = val
- }
- /**
- * @description 改变每页大小
- * @param val
- */
- const handleSizeChange = (val: number) => {
- paginationSetting.limit = val
- }
- /**
- * 插入均值行
- *
- * @param needAverage 是否需要计算平均值
- * @param openRemoteReqData 是否是远程请求
- */
- const insertAverageRow = (needAverage: boolean, openRemoteReqData: boolean) => {
- if (needAverage) {
- const rowData: any = {}
- const oldList: Array<any> = JSON.parse(JSON.stringify(tableData))
- Object.values(tableFieldsInfo).map((item: TableFieldInfo, index: number) => {
- const sum = oldList
- .map((item) => item.count)
- .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
- const averageList = oldList
- .map((val) => val[item.name])
- .filter((item) => item !== undefined)
- if (index === 0) rowData[item.name] = '均值'
- else if (item.name === 'count') rowData[item.name] = sum
- else {
- const num =
- averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
- averageList.length
- rowData[item.name] = isNaN(num) ? 0 : num.toFixed(2)
- }
- })
- if (openRemoteReqData) {
- tableData[0].splice(0, 0, rowData)
- } else {
- tableData.splice(0, 0, rowData)
- }
- }
- }
- /**
- * 清空表格数据
- */
- const resetTableData = () => {
- tableData.splice(0, tableData.length)
- }
- /**
- * @description: 根据计算出来的值去返回对应的颜色深度
- * @param number 输入值
- */
- const getDecimalFromRange = (number: number) => {
- if (!number) return 0
- if (number < 25) return 0.25
- else if (number < 50) return 0.5
- else if (number < 75) return 0.75
- else return 1.0 // 如果number >= 75,则直接返回1.00
- }
- /**
- * @description: 初始化分页配置,把传入的配置拷贝一份
- */
- const initPageConfig = (propPageConfig?: TablePaginationSetting) => {
- if (propPageConfig) {
- Object.assign(paginationSetting, JSON.parse(JSON.stringify(propPageConfig)))
- }
- }
- /**
- * @description: 初始化请求配置,用于把拷贝一份新的数据
- */
- const initReqConfig = (reqConfig: ReqConfig, propReqConfig?: ReqConfig) => {
- if (propReqConfig) {
- Object.assign(reqConfig, propReqConfig)
- }
- }
- /**
- * @description: 创建row-key优化表格性能
- */
- const createRowKey = () => {
- return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`
- }
- /**
- * @description: 下载表格数据
- */
- const downLoadTable = (headerMap: Record<string, string> = {}) => {
- // downLoadData(generateRandomFileName(), JSON.parse(JSON.stringify(tableData)))
- const exportData = tableData
- .slice(1)
- .flat()
- .map((item) => {
- const rawData = toRaw(item)
- // 遍历对象的键,删除不在 validKeys 中的键
- Object.keys(item).forEach((key) => {
- if (!(key in headerMap)) {
- delete item[key]
- }
- })
- return rawData
- })
- // 表头设置
- // exportData.unshift(headerZh)
- const header = Object.keys(headerMap)
- const newData = [
- {
- actionId: '事件ID',
- actionName: '事件名称',
- actionCount: '操作次数',
- actionUserCount: '操作用户数',
- activeUserRate: '活跃设备发生率',
- loginActiveRate: '每次启动发生数'
- },
- ...exportData
- ]
- const workbook = xlsx.utils.book_new()
- const worksheet = xlsx.utils.json_to_sheet(newData, {
- header: header,
- skipHeader: true
- })
- xlsx.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
- return xlsx.writeFile(workbook, generateRandomFileName() + '.xlsx')
- }
- return {
- getTableData,
- setTableData,
- resetTableData,
- initPageConfig,
- initReqConfig,
- getDecimalFromRange,
- computedRowIndex,
- handleCurrentChange,
- handleSizeChange,
- insertAverageRow,
- createRowKey,
- downLoadTable
- }
- }
|