Table.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. <!--
  2. * @Author: fxs bjnsfxs@163.com
  3. * @Date: 2024-08-20 18:16:18
  4. * @LastEditors: fxs bjnsfxs@163.com
  5. * @LastEditTime: 2024-09-11 17:05:33
  6. * @FilePath: \Game-Backstage-Management-System\src\components\Table.vue
  7. * @Description:
  8. *
  9. -->
  10. <script setup lang="ts">
  11. import type { PropsParams, TablePaginationSetting } from '@/types/table'
  12. import type { ReqConfig } from '@/types/dataAnalysis'
  13. import { FilterType, FieldSpecialEffectType } from '@/types/table'
  14. import { initLoadResouce } from '@/utils/resource'
  15. import { computed, onMounted, reactive, ref, toRaw, watch } from 'vue'
  16. import { useTable } from '@/hooks/useTable'
  17. import FilterPopover from './toolsBtn/FilterPopover.vue'
  18. import RegreshBtn from './toolsBtn/RegreshBtn.vue'
  19. import { useRequest } from '@/hooks/useRequest'
  20. import type { FormInstance } from 'element-plus'
  21. import axiosInstance from '@/utils/axios/axiosInstance'
  22. import { clearReactiveData } from '@/utils/common'
  23. const { analysisResCode } = useRequest()
  24. // 表格工具图标大小
  25. const toolsIconSize = ref(25)
  26. // 查询表单
  27. const queryFormRef = ref<FormInstance>()
  28. // 传过来的配置
  29. const props = withDefaults(defineProps<PropsParams>(), {
  30. needRowindex: true,
  31. needAverage: false,
  32. needLeftTools: false,
  33. needRightTools: false,
  34. openFilterQuery: false,
  35. openPageQuery: false,
  36. needUpload: false,
  37. needDownLoad: false
  38. })
  39. // 父组件触发的方法
  40. const emits = defineEmits(['addNewItem', 'upload', 'downLoad', 'loadSuccess'])
  41. // 加载动画
  42. const loading = ref(false)
  43. // 表格数据
  44. const tableData: Array<any> = reactive([])
  45. // 查询表单的数据
  46. const queryFormData = reactive<any>({})
  47. // 分页数据
  48. const paginationConfig2 = reactive<TablePaginationSetting>({
  49. currentPage: 0,
  50. limit: 0,
  51. total: 0,
  52. pagesizeList: []
  53. })
  54. // 请求配置
  55. const reqconfig = reactive<ReqConfig>({
  56. url: '',
  57. otherOptions: {}
  58. })
  59. // 资源的加载路径
  60. const resourceInfo: Record<string, string> = {
  61. defaultHead: `/img/default/defaultHead.png`
  62. }
  63. // 使用blob的资源路径信息
  64. const blobUrlInfo = reactive<Record<string, string>>({})
  65. // 一些公用方法
  66. const { getTableData } = useTable(tableData, paginationConfig2)
  67. // 没有开启分页查询的时候使用的数据
  68. const tableDataNoPaging = computed(() => {
  69. let curPage = paginationConfig2.currentPage
  70. let limit = paginationConfig2.limit
  71. let begin = curPage * limit - limit
  72. //这里不减一是因为,slice方法裁切是左闭右开数组
  73. let end = curPage * limit
  74. return tableData.slice(begin, end)
  75. })
  76. // 所有类型为input的表单控件信息
  77. const inputFieldsList = computed(() => {
  78. return props.queryInfo?.filter((item) => item.type === FilterType.INPUT)
  79. })
  80. // 所有类型为select的表单控件信息
  81. const selectFieldsList = computed(() => {
  82. return props.queryInfo?.filter((item) => {
  83. return item.type === FilterType.SELECT
  84. })
  85. })
  86. // 所有类型为date的表单控件信息
  87. const dateFieldsList = computed(() => {
  88. return props.queryInfo?.filter((item) => item.type === FilterType.DATE)
  89. })
  90. // 计算行号
  91. const computedRowIndex = (index: number) => {
  92. return (paginationConfig2.currentPage - 1) * paginationConfig2.limit + index + 1
  93. }
  94. // 改变页码
  95. const handleCurrentChange = (val: number) => {
  96. paginationConfig2.currentPage = val
  97. }
  98. // 改变每页大小
  99. const handleSizeChange = (val: number) => {
  100. paginationConfig2.limit = val
  101. }
  102. /**
  103. * @description: 获取数据,如果没有直接传入数据,则去请求数据,有则直接用
  104. * @return {*}
  105. */
  106. const getData = () => {
  107. return new Promise((resolve, reject) => {
  108. if (props.dataList) {
  109. tableData.splice(0, tableData.length, ...props.dataList)
  110. paginationConfig2.total = props.paginationConfig.total
  111. loading.value = false
  112. emits('loadSuccess', tableData)
  113. resolve(true)
  114. } else {
  115. loading.value = true
  116. if (props.requestConfig) {
  117. if (props.openPageQuery) {
  118. // 如果开启了分页查询,那么要计算出需要展示的页码位置所对应的偏移量
  119. // 同时要将查询的条数改为对应的用户选择的展示条数
  120. reqconfig.otherOptions.offset =
  121. (paginationConfig2.currentPage - 1) * paginationConfig2.limit
  122. reqconfig.otherOptions.limit = paginationConfig2.limit
  123. }
  124. // 查询时要根据是否开启分页查询传入对应参数
  125. getTableData(reqconfig.url, reqconfig.otherOptions, props.openPageQuery)
  126. .then(() => {
  127. emits('loadSuccess', tableData)
  128. resolve(true)
  129. })
  130. .catch((err) => {
  131. console.log(err)
  132. reject(err)
  133. })
  134. .finally(() => {
  135. loading.value = false
  136. })
  137. } else {
  138. loading.value = false
  139. throw new Error('no match requestConfig')
  140. }
  141. }
  142. if (tableData.length) {
  143. if (props.needAverage) {
  144. let rowData: any = {}
  145. let oldList: Array<any> = JSON.parse(JSON.stringify(tableData))
  146. Object.values(props.tableFieldsInfo).map((item, index) => {
  147. let sum = oldList
  148. .map((item) => item.count)
  149. .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
  150. let averageList = oldList
  151. .map((val) => val[item.name])
  152. .filter((item) => item !== undefined)
  153. if (index === 0) rowData[item.name] = '均值'
  154. else if (item.name === 'count') rowData[item.name] = sum
  155. else {
  156. let num =
  157. averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
  158. averageList.length
  159. rowData[item.name] = isNaN(num) ? 0 : num.toFixed(2)
  160. }
  161. })
  162. insertRow(0, rowData)
  163. }
  164. }
  165. })
  166. }
  167. // 清空表格数据
  168. const resetTableData = () => {
  169. tableData.splice(0, tableData.length)
  170. }
  171. // 按条件查询
  172. const queryTableData = () => {
  173. if (props.requestConfig) {
  174. reqconfig.otherOptions = { ...props.requestConfig.otherOptions, ...queryFormData }
  175. getData()
  176. } else {
  177. throw new Error('no match requestConfig')
  178. }
  179. }
  180. /**
  181. * @description: 重置整个查询表单,重置后,再请求一次全部表格
  182. * @param {*} formEl 表单对象
  183. * @return {*}
  184. */
  185. const resetQueryForm = (formEl: FormInstance | undefined) => {
  186. if (!formEl) return
  187. clearReactiveData(queryFormData)
  188. queryTableData()
  189. }
  190. /**
  191. * @description: 在获取完数据后,插入均值行
  192. * @param {*} start 插入的位置
  193. * @param {*} rowData 插入的数据
  194. * @return {*}
  195. */
  196. const insertRow = (start: number, rowData: any) => {
  197. if (props.openPageQuery) {
  198. tableData[start].splice(0, 0, rowData)
  199. } else {
  200. tableData.splice(start, 0, rowData)
  201. }
  202. }
  203. /**
  204. * @description: 根据计算出来的值去返回对应的颜色深度
  205. * @return {*}
  206. */
  207. const getDecimalFromRange = (number: number) => {
  208. if (number === null || number === undefined) return 0
  209. if (number < 25) return 0.25
  210. else if (number < 50) return 0.5
  211. else if (number < 75) return 0.75
  212. else return 1.0 // 如果number >= 75,则直接返回1.00
  213. }
  214. /**
  215. * @description: 单独处理拥有均值行的表格每个单元格的样式,均值字段均加粗,其他需要比较的字段根据自身百分比显示颜色
  216. * 其中使用row-style无效,scope会导致无法覆盖样式
  217. * 同时由于我自定义了表格内容,哪里的样式会覆盖row的样式,所以只能单独对单元格设置
  218. * @param {*} info 每个单元格的信息
  219. * @return {*}
  220. */
  221. const tableCellStyle = (info: any) => {
  222. if (info.row.date === '均值')
  223. return {
  224. 'font-weight': 'bold'
  225. }
  226. else if (info.column.property != 'count' && info.column.property != 'date' && props.needAverage) {
  227. return {
  228. 'background-color': `rgba(59, 157, 247,${getDecimalFromRange(info.row[info.column.property])})`
  229. }
  230. } else return {}
  231. }
  232. // 根据分页大小的切换来更新数据
  233. // 这里将他赋值,用于根据传入的配置来选择是否开启该监听
  234. /**
  235. * @description: 监听litmit,currentpage,gid的变化,改变后去重新请求数据
  236. * 如果是limit的变化,则需要把当前页置为1
  237. *
  238. * 对于Gid需要去监听props的,而不是本地的,因为是外部的改变
  239. * @return {*}
  240. */
  241. const changePageLimit = watch(
  242. () => [
  243. paginationConfig2.limit,
  244. props.requestConfig?.otherOptions.gid,
  245. paginationConfig2.currentPage
  246. ],
  247. ([newLimit, newGid], [oldLimit, oldGid]) => {
  248. if (newLimit != oldLimit) {
  249. // 需要给分页按钮加上:current-page.sync="current_page" 配置,不然不生效
  250. // 当改变每页大小时把之前的缓存全部清除,重新开始
  251. paginationConfig2.currentPage = 1
  252. // resetTableData()
  253. }
  254. if (newGid != oldGid) reqconfig.otherOptions.gid = newGid
  255. if (newLimit != oldLimit || !tableData[paginationConfig2.currentPage] || newGid != oldGid) {
  256. getData()
  257. }
  258. },
  259. { deep: true }
  260. )
  261. // 监听传入的datalist的变化,然后去更新数据
  262. const changeDataList = watch(
  263. () => [props.dataList],
  264. () => {
  265. getData()
  266. },
  267. {
  268. deep: true
  269. }
  270. )
  271. // 监听日期的变化,
  272. const watchDateChange = watch(
  273. () => [props.requestConfig?.otherOptions.startTime, props.requestConfig?.otherOptions.endTime],
  274. () => {
  275. getData()
  276. },
  277. { deep: true }
  278. )
  279. /**
  280. * @description: 创建row-key优化表格性能
  281. * @return {*}
  282. */
  283. const createRowKey = () => {
  284. return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
  285. }
  286. //如果没有日期就取消掉
  287. if (!props.requestConfig?.otherOptions.startTime && !props.requestConfig?.otherOptions.endTime) {
  288. watchDateChange()
  289. }
  290. // 没传入datalist则取消该监听
  291. if (!props.dataList) {
  292. changeDataList()
  293. }
  294. // 没有开启分页查询就关闭掉这个监听
  295. if (!props.openPageQuery) {
  296. changePageLimit()
  297. }
  298. /**
  299. * @description: 拷贝一份配置文件
  300. * @return {*}
  301. */
  302. const initpageConfig = () => {
  303. Object.assign(paginationConfig2, props.paginationConfig)
  304. }
  305. /**
  306. * @description: 初始化请求配置,用于把拷贝一份新的数据
  307. * @return {*}
  308. */
  309. const initReqConfig = () => {
  310. Object.assign(reqconfig, props.requestConfig)
  311. }
  312. /**
  313. * @description: 表格排序
  314. * @param {*} data 获取到的数据
  315. * @return {*}
  316. */
  317. const tableSortChange = (data: { column: any; prop: string; order: any }) => {
  318. let { order } = { ...data }
  319. if (order === 'ascending') order = 'asc'
  320. else if (order === 'descending') order = 'desc'
  321. else order = ''
  322. reqconfig.otherOptions.order = order
  323. getData()
  324. }
  325. /**
  326. * @description: 删除行
  327. * @param {*} url 请求地址
  328. * @param {*} row 行数据
  329. * @return {*}
  330. */
  331. const deleteRow = (url: string, filedsInfo: any) => {
  332. axiosInstance
  333. .post(url, { ...filedsInfo })
  334. .then((data) => {
  335. analysisResCode(data).then(() => {
  336. getData()
  337. })
  338. })
  339. .catch((err) => {
  340. console.log(err)
  341. })
  342. }
  343. /**
  344. * @description: 下载表格数据
  345. * @return {*}
  346. */
  347. const downLoadTable = () => {
  348. emits('downLoad', JSON.parse(JSON.stringify(tableData)))
  349. }
  350. /**
  351. * @description: 外部获取数据
  352. * @return {*}
  353. */
  354. const outGetTableData = () => {
  355. return toRaw(tableData).flat()
  356. }
  357. // 定义暴露出去的方法
  358. defineExpose({
  359. getData,
  360. resetTableData,
  361. deleteRow,
  362. downLoadTable,
  363. outGetTableData
  364. })
  365. onMounted(() => {
  366. initpageConfig()
  367. initReqConfig()
  368. if (props.loadingState !== undefined) {
  369. loading.value = props.loadingState
  370. }
  371. if (!props.openPageQuery) {
  372. getData()
  373. }
  374. // 去加载所有需要的资源
  375. initLoadResouce(resourceInfo).then((data) => {
  376. Object.assign(blobUrlInfo, data)
  377. })
  378. })
  379. </script>
  380. <template>
  381. <div class="tableContent">
  382. <div class="filterBox" v-if="openFilterQuery">
  383. <!-- slot -->
  384. <div class="filterHeader">
  385. <span>查询条件</span>
  386. </div>
  387. <div class="filterBody">
  388. <el-form
  389. :inline="true"
  390. ref="queryFormRef"
  391. :model="queryFormData"
  392. class="queryForm"
  393. :label-position="'left'"
  394. >
  395. <!-- 所有的input查询框 -->
  396. <el-form-item :label="item.label" v-for="item in inputFieldsList" class="filterItem">
  397. <el-input
  398. v-model="queryFormData[item.name]"
  399. :placeholder="item.placeholder"
  400. clearable
  401. />
  402. </el-form-item>
  403. <!-- 所有选择框 -->
  404. <el-form-item :label="item.label" v-for="item in selectFieldsList" class="filterItem">
  405. <el-select v-model="queryFormData[item.name]" :placeholder="item.placeholder">
  406. <el-option v-for="val in item.otherOption" :label="val.cnName" :value="val.value" />
  407. </el-select>
  408. </el-form-item>
  409. <!-- 所有日期选择框 -->
  410. <el-form-item :label="item.label" v-for="item in dateFieldsList" class="filterItem">
  411. <el-date-picker
  412. v-model="queryFormData[item.name]"
  413. type="date"
  414. :placeholder="item.placeholder"
  415. clearable
  416. />
  417. </el-form-item>
  418. </el-form>
  419. <!-- 分割线 -->
  420. <!-- <el-divider class="queryPartition" content-position="center" direction="vertical" /> -->
  421. <div class="queryBox">
  422. <el-divider class="queryPartition" content-position="center" direction="vertical" />
  423. <div class="queryBtnBox">
  424. <el-button class="queryBtn" color="#165dff" @click="queryTableData">
  425. <el-icon><Search /></el-icon>查询
  426. </el-button>
  427. <el-button class="refreshBtn" color="#f2f3f5" @click="resetQueryForm(queryFormRef)">
  428. <el-icon><RefreshRight /></el-icon>重置
  429. </el-button>
  430. </div>
  431. </div>
  432. </div>
  433. </div>
  434. <!-- 分割线 -->
  435. <!-- <el-divider class="partition" content-position="center" /> -->
  436. <div class="tableTools">
  437. <div class="leftTools">
  438. <div class="leftToolsGroup" v-if="needLeftTools" style="display: flex">
  439. <el-button class="leftToolBtn" color="#165dff" @click="emits('addNewItem')">
  440. <el-icon><Plus /></el-icon>新增
  441. </el-button>
  442. <el-button
  443. class="leftToolBtn"
  444. color="#626aef"
  445. @click="emits('upload', outGetTableData())"
  446. v-if="needUpload"
  447. >
  448. <el-icon><Upload /></el-icon>上传
  449. </el-button>
  450. </div>
  451. </div>
  452. <div class="rightTools" v-if="needRightTools">
  453. <el-button
  454. v-if="needDownload"
  455. color="#f0f1f3"
  456. size="default"
  457. class="rightToolsItem"
  458. @click="downLoadTable"
  459. >
  460. <el-icon><Download /></el-icon>下载
  461. </el-button>
  462. <RegreshBtn @refresh-table="getData" :icon-size="toolsIconSize"></RegreshBtn>
  463. <FilterPopover
  464. :table-fields-info="tableFieldsInfo"
  465. :icon-size="toolsIconSize"
  466. ></FilterPopover>
  467. </div>
  468. </div>
  469. <div class="tableBox">
  470. <!-- 没有分页的时候需要重新计算一下data -->
  471. <el-table
  472. :data="openPageQuery ? tableData[paginationConfig2.currentPage] : tableDataNoPaging"
  473. style="width: 100%"
  474. class="tableBody"
  475. :cell-style="tableCellStyle"
  476. v-loading="loading"
  477. :row-key="createRowKey()"
  478. @sort-change="tableSortChange"
  479. >
  480. <el-table-column
  481. v-if="props.needRowindex"
  482. align="center"
  483. label="#"
  484. type="index"
  485. :index="computedRowIndex"
  486. />
  487. <template v-for="item in tableFieldsInfo">
  488. <el-table-column
  489. :prop="item.name"
  490. :label="item.cnName"
  491. :min-width="item.specialEffect?.type === FieldSpecialEffectType.DROPDOWN ? '170px' : ''"
  492. align="center"
  493. show-overflow-tooltip
  494. v-if="item.isShow"
  495. :sortable="item.needSort === true ? 'custorm' : false"
  496. >
  497. <template v-slot="scope">
  498. <!-- tag类 -->
  499. <el-tag
  500. v-if="item.specialEffect?.type === FieldSpecialEffectType.TAG"
  501. :type="scope.row[item.name] ? 'danger' : 'success'"
  502. >
  503. {{
  504. scope.row[item.name]
  505. ? item.specialEffect.othnerInfo.text[0]
  506. : item.specialEffect.othnerInfo.text[1]
  507. }}
  508. </el-tag>
  509. <!-- 头像类 -->
  510. <el-image
  511. v-else-if="item.specialEffect?.type === FieldSpecialEffectType.IMG"
  512. :preview-teleported="true"
  513. :src="scope.row[item.name]"
  514. :preview-src-list="[scope.row[item.name]]"
  515. style="width: 35px; height: 35px"
  516. :fit="'fill'"
  517. :hide-on-click-modal="true"
  518. >
  519. <template #error>
  520. <!-- -->
  521. <img style="width: 35px; height: 35px" :src="blobUrlInfo.defaultHead" />
  522. </template>
  523. </el-image>
  524. <!-- 文字类 -->
  525. <el-text
  526. v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TEXT"
  527. :type="
  528. scope.row[item.name]
  529. ? item.specialEffect.othnerInfo.color[0]
  530. : item.specialEffect.othnerInfo.color[1]
  531. "
  532. >
  533. {{ scope.row[item.name] }}
  534. </el-text>
  535. <!-- 翻译类 -->
  536. <el-text v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TRANSLATE">
  537. <el-icon
  538. v-if="item.specialEffect.othnerInfo.icon"
  539. style="padding-right: 8px"
  540. :color="scope.row[item.name] ? '#409EFF' : '#F56C6C'"
  541. ><icon-tabler-point-filled></icon-tabler-point-filled
  542. ></el-icon>
  543. {{
  544. item.specialEffect.othnerInfo.translateText[scope.row[item.name]]
  545. ? item.specialEffect.othnerInfo.translateText[scope.row[item.name]]
  546. : '未知'
  547. }}
  548. </el-text>
  549. <!-- 状态类 -->
  550. <el-text v-else-if="item.specialEffect?.type === FieldSpecialEffectType.STATE">
  551. <span>
  552. <el-icon
  553. style="padding-right: 8px"
  554. :color="scope.row[item.name] ? '#409EFF' : '#F56C6C'"
  555. ><icon-tabler-point-filled></icon-tabler-point-filled
  556. ></el-icon>
  557. {{
  558. scope.row[item.name]
  559. ? item.specialEffect.othnerInfo.text[0]
  560. : item.specialEffect.othnerInfo.text[1]
  561. }}</span
  562. >
  563. </el-text>
  564. <!-- 开关类 -->
  565. <el-switch
  566. :active-value="1"
  567. :inactive-value="0"
  568. v-else-if="item.specialEffect?.type === FieldSpecialEffectType.SWITCH"
  569. v-model="scope.row[item.name]"
  570. :data="scope.row[item.name]"
  571. size="default"
  572. >
  573. </el-switch>
  574. <!-- 下拉菜单类 -->
  575. <el-dropdown
  576. trigger="click"
  577. v-else-if="item.specialEffect?.type === FieldSpecialEffectType.DROPDOWN"
  578. >
  579. <span
  580. class="el-dropdown-link"
  581. style="display: flex; align-items: center; cursor: pointer"
  582. >
  583. <el-icon
  584. style="padding-right: 8px"
  585. :color="scope.row[item.name] ? '#409EFF' : '#F56C6C'"
  586. ><icon-tabler-point-filled></icon-tabler-point-filled
  587. ></el-icon>
  588. {{
  589. scope.row[item.name]
  590. ? item.specialEffect.othnerInfo.text[0]
  591. : item.specialEffect.othnerInfo.text[1]
  592. }}
  593. <el-icon class="el-icon--right"><arrow-down /></el-icon>
  594. </span>
  595. <template #dropdown>
  596. <el-dropdown-menu>
  597. <el-dropdown-item :command="{ value: true }">使用中</el-dropdown-item>
  598. <el-dropdown-item :command="{ value: false }">已弃用</el-dropdown-item>
  599. </el-dropdown-menu>
  600. </template>
  601. </el-dropdown>
  602. <el-text v-else>
  603. <!-- 其他列按默认方式显示 -->
  604. {{
  605. props.needAverage &&
  606. scope.row[item.name] !== undefined &&
  607. item.name !== 'count' &&
  608. item.name !== 'date'
  609. ? scope.row[item.name] + '%'
  610. : scope.row[item.name]
  611. }}
  612. </el-text>
  613. </template>
  614. </el-table-column>
  615. </template>
  616. <slot name="tableOperation"></slot>
  617. </el-table>
  618. <div class="userTablePaginationBox">
  619. <el-pagination
  620. class="userTablePagination"
  621. background
  622. :page-size="paginationConfig2.limit"
  623. :page-sizes="paginationConfig2.pagesizeList"
  624. table-layout="fixed"
  625. layout="prev, pager, next ,jumper ,sizes,total,"
  626. :total="paginationConfig2.total"
  627. :current-page.sync="paginationConfig2.currentPage"
  628. @current-change="handleCurrentChange"
  629. @size-change="handleSizeChange"
  630. />
  631. </div>
  632. </div>
  633. </div>
  634. </template>
  635. <style scoped>
  636. .tableContent {
  637. margin: 0 auto;
  638. width: 100%;
  639. /* height: 100%; */
  640. box-shadow:
  641. 0 4px 8px 0 rgba(0, 0, 0, 0.02),
  642. 0 1px 3px 0 rgba(0, 0, 0, 0.02);
  643. }
  644. .filterBox,
  645. .tableBox {
  646. width: 100%;
  647. }
  648. .filterBox {
  649. margin-top: 1%;
  650. min-height: 18%;
  651. display: flex;
  652. flex-direction: column;
  653. }
  654. .filterHeader,
  655. .filterBody {
  656. width: 98%;
  657. margin: 0 auto;
  658. }
  659. .filterHeader {
  660. display: flex;
  661. align-items: center;
  662. color: black;
  663. font-size: 16px;
  664. font-weight: bold;
  665. /* background-color: lightblue; */
  666. /* margin-bottom: 1%; */
  667. }
  668. .filterBody {
  669. display: flex;
  670. }
  671. .queryBox {
  672. width: 10%;
  673. display: flex;
  674. justify-content: space-around;
  675. }
  676. .queryBtnBox {
  677. width: 100%;
  678. display: flex;
  679. flex-direction: column;
  680. align-items: center;
  681. justify-content: center;
  682. }
  683. .refreshBtn {
  684. margin-top: 10%;
  685. margin-bottom: 10%;
  686. }
  687. .queryPartition {
  688. height: 90%;
  689. }
  690. .queryForm {
  691. width: 90%;
  692. display: flex;
  693. flex-wrap: wrap;
  694. /* justify-content: space-between; */
  695. }
  696. .filterItem {
  697. width: 20%;
  698. display: flex;
  699. align-items: center;
  700. }
  701. .partition {
  702. width: 98%;
  703. margin: 0 auto;
  704. }
  705. .tableTools {
  706. width: 98%;
  707. margin: 0 auto;
  708. display: flex;
  709. justify-content: space-between;
  710. margin-top: 1%;
  711. }
  712. .leftTools,
  713. .rightTools {
  714. width: 10%;
  715. display: flex;
  716. align-items: center;
  717. justify-content: space-between;
  718. }
  719. .rightTools {
  720. width: 5%;
  721. }
  722. .tableBox {
  723. width: 98%;
  724. /* height: 98%; */
  725. margin: 0 auto;
  726. /* margin-top: 0.5%;
  727. margin-bottom: 2%; */
  728. }
  729. .userTablePaginationBox {
  730. box-sizing: border-box;
  731. width: 98%;
  732. margin: 0% auto;
  733. padding: 1% 0;
  734. display: flex;
  735. justify-content: center;
  736. }
  737. .averageItem {
  738. font-size: 14px;
  739. color: #515b6f;
  740. }
  741. .normalItem {
  742. font-size: 14px;
  743. color: #515b6f;
  744. font-weight: 400;
  745. }
  746. .leftToolBtn {
  747. margin-right: 5px;
  748. }
  749. </style>