123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- import { ref, computed, watch, nextTick, unref, onMounted, onBeforeUnmount } from 'vue'
- import { isDefine, toggleClass } from '@/utils/common'
- import type { Ref, ShallowRef, UnwrapRef } from 'vue'
- import type { InstanceTable } from 'global-type'
- import type { MultipleResult } from '@/api/api'
- import { throttle } from 'lodash-es'
- import useMainStore from '@/store/main'
- import bus from '@/utils/bus'
- import { ElMessage } from 'element-plus'
- type ArrayObjectType = Array<Record<string, any>>
- type MultipleResultType<T = Record<string, any>> = MultipleResult<T>
- type InputDataType = MultipleResultType | ArrayObjectType
- type TableDataType<T> = Ref<T> | ShallowRef<T>
- type ArrayData<T extends InputDataType> = T extends MultipleResultType<infer D> ? D : ExtractArrayValue<T>
- type RowType<T extends TableDataType<InputDataType>> = ArrayData<UnwrapRef<T>> & {
- index: number
- }
- const mainStore = useMainStore()
- function isMultipleData(data: any): data is MultipleResultType {
- return isDefine(data?.result) && isDefine(data?.totalCount)
- }
- const useTableCheck = <T extends TableDataType<InputDataType>>(data: T, auto = true) => {
- const tableRef = ref<InstanceTable>()
- const elTableRef = computed(() => {
- return tableRef?.value?.tableRef
- })
- const totalCount = ref<any>(null)
- const pageSize = ref<any>(null)
- const pageNumber = ref<any>(null)
- const initPaginationParams = () => {
- const _data: any = unref(data)
- if (isMultipleData(_data)) {
- totalCount.value = _data.totalCount
- pageSize.value = _data.pageSize
- pageNumber.value = _data.pageNumber
- }
- }
- initPaginationParams()
- watch(data, () => {
- initPaginationParams()
- })
- const tableData = computed(() => {
- const d = unref(data)
- // let result: RowType<T>[] = []
- let result: any[] = []
- if (d) {
- if (isMultipleData(d)) {
- result = d?.result?.map((d, index) => ({ ...d, index: d.index ?? index }))
- } else {
- result = d?.map((d, index) => ({ ...d, index: d.index ?? index }))
- }
- }
- return result
- })
- // const current = ref<RowType<T>>()
- const current = ref<any>()
- // const currentView = ref<RowType<T>>()
- const currentView = ref<any>()
- const visibleHistory = ref<boolean>(false)
- watch(
- tableData,
- () => {
- current.value = void 0
- currentView.value = void 0
- if (tableData?.value?.length && auto) {
- nextTick(() => {
- elTableRef?.value?.setCurrentRow(tableData.value[0])
- })
- }
- },
- { immediate: true }
- )
- /** 表格选中 */
- // const onCurrentChange = (row: RowType<T>) => {
- const onCurrentChange = (row: any) => {
- current.value = row
- }
- /** 表格行双击 */
- // const onDbClick = (row: RowType<T>) => {
- const onDbClick = (row: any) => {
- currentView.value = row
- visibleHistory.value = true
- }
- /** 下一份 */
- const next = () => {
- // elTableRef?.value?.setCurrentRow(tableData.value[((current.value?.index || 0) + 1) % tableData.value.length])
- const rightTableViewDom = document.querySelector('.table-view')
- if (rightTableViewDom) {
- toggleClass(rightTableViewDom, 'collapse')
- }
- }
- const nextRow = throttle(() => {
- console.log('current.value?.index:', current.value?.index)
- console.log('tableData.value.length:', tableData.value.length)
- if (current.value?.index == tableData.value.length - 1) {
- //说明高亮正处于最后一行了,需要提示用户是否需要翻到下一页。
- if (totalCount.value !== null && pageSize.value !== null) {
- // 说明页面只使用了useTableCheck,而未使用useTable。
- //注意:这里只处理只使用了useTableCheck而未使用useTable的情况。另外一种情况在useTable里处理。避免重复
- //只使用了useTableCheck,而未使用useTable的情况,基本上是pageSize传了99999这种情况,所以一页就是全部的数据,最后一行就是到底了
- if (pageNumber.value * pageSize.value + 1 > totalCount.value) {
- ElMessage.warning('当前页已是最后一页')
- } else {
- //该情况应该不可能出现,因为只使用了useTableCheck而未使用useTable的情况,是只有一页的,即pageSize传的999999之类
- // mainStore.setRowNextBottomDialogStatus(true)
- }
- } else {
- //在useTable里才能拿到分页相关信息,所以要对useTable进行通信,告诉它到了最后一行了,是否需要弹框诱导到下一页
- bus.emit('atBottomRowFromUseTableCheck')
- }
- return
- }
- const index = (current.value?.index || 0) + 1
- elTableRef?.value?.setCurrentRow(tableData.value[index % tableData.value.length])
- const tBodyDomWrap: any = elTableRef?.value?.$refs.bodyWrapper
- if (tBodyDomWrap) {
- if (index % tableData.value.length == 0) {
- elTableRef?.value?.scrollTo({ left: 0, top: 0, behavior: 'smooth' })
- } else {
- const wrap = tBodyDomWrap.getElementsByClassName('el-scrollbar__wrap')[0]
- const oHeight = wrap.offsetHeight
- const sTop = wrap.scrollTop
- const sHeight = wrap.scrollHeight
- const targetRowAsHeight = 36 * ((current.value?.index || 0) + 1)
- if (sHeight > oHeight && targetRowAsHeight - sTop > oHeight) {
- const t = sHeight - targetRowAsHeight
- elTableRef?.value?.scrollTo({ left: 0, top: sTop + 36, behavior: 'smooth' })
- }
- }
- }
- // elTableRef?.value?.scrollTo(0, (current.value?.index || 0) * 36)
- }, 300)
- const prevRow = throttle(() => {
- console.log('current.value?.index:', current.value?.index)
- if (current.value?.index > 0) {
- const index = current.value?.index
- elTableRef?.value?.setCurrentRow(tableData.value[index - 1])
- const tBodyDomWrap: any = elTableRef?.value?.$refs.bodyWrapper
- if (tBodyDomWrap) {
- if (index % tableData.value.length == 0) {
- elTableRef?.value?.scrollTo({ left: 0, top: 0, behavior: 'smooth' })
- } else {
- const wrap = tBodyDomWrap.getElementsByClassName('el-scrollbar__wrap')[0]
- const oHeight = wrap.offsetHeight
- const sTop = wrap.scrollTop
- const sHeight = wrap.scrollHeight
- const targetRowAsHeight = 36 * (current.value?.index || 0)
- if (targetRowAsHeight - 36 < sTop) {
- elTableRef?.value?.scrollTo({ left: 0, top: targetRowAsHeight - 36, behavior: 'smooth' })
- }
- }
- }
- }
- }, 300)
- const arrowDownToNextRow = (e: any) => {
- // if (e.target.tagName === 'INPUT' || (e.target.className || '').includes('contenteditable-ele')) {
- // return false
- // }
- if ((e.target.className || '').includes('contenteditable-ele')) {
- return false
- }
- // e.preventDefault()
- if (e.key === 'ArrowDown') {
- e.preventDefault()
- nextRow()
- } else if (e.key === 'ArrowUp') {
- e.preventDefault()
- prevRow()
- }
- }
- onMounted(() => {
- document.addEventListener('keydown', arrowDownToNextRow)
- })
- onBeforeUnmount(() => {
- document.removeEventListener('keydown', arrowDownToNextRow)
- })
- return {
- tableRef,
- elTableRef,
- tableData,
- current,
- currentView,
- visibleHistory,
- onCurrentChange,
- onDbClick,
- next,
- nextRow,
- }
- }
- export default useTableCheck
|