table多选右侧展示,反显,组件

<!--
 * @Description: 
 * @Version: 1.0
 * @Author: sunye
 * @Date: 2023-05-10 10:00:03
 * @LastEditors: sunye
 * @LastEditTime: 2023-10-18 10:56:55
-->
<script lang="ts" setup>
import { deptTreeByUser } from '@/api/logistics'
import { elTableMultiSelect } from '@/views/logistics/maintenance/hooks/shift'

const props = defineProps({
  maintenanceType: Number || String, //职务名称
  userId: [Number, String], //用户id
  maintainDeptIds: {
    //反显部门数组
    type: Array,
    default: [],
  },
  type: String, //组件类型(新增,修改)
})
const emit = defineEmits(['getCheckedList'])
const userProps = {
  label: 'deptName',
  value: 'id',
  multiple: true,
  filterable: true,
}
const state = reactive({
  deptName: '',
  deptLoading: false,
  tableDataLeft: [],
  defaultCheckist: [], //部门模糊搜索下拉树默认选中数组
  num: 0,
  pin: false, // 是否按住,默认不按住
  startPoint: undefined, // 连选多选起点
  endPoint: undefined, // 连选多选终点
  userList: [],
})
const userTree = ref([])
const options = ref([])
const leftTable = ref(null)
const userCascader = ref(null)
// 选中数据列表
const tableDataRight = ref([])


// 获取左侧部门table
const getDeptList = async (userId, type) => {
  const res = await deptTreeByUser(userId, type)
  state.tableDataLeft = res.data.deptTree
  state.num = res.data.total
  userTree.value = res.data.deptTree
  if (props.type === 'edit') {
    recursion(state.tableDataLeft, 'edit')
  } else {
    recursion(state.tableDataLeft, 'add')
  }
}

// 反显递归函数
const recursion = (arr, type) => {
  arr.forEach((i) => {
    // 新增根据列表flagMy字段判是否为自己选中,修改通过maintainDeptIds数组反显
    const judging =
      type === 'edit' ? props.maintainDeptIds.includes(i.id) : i.flagMy
    if (judging) {
      nextTick(() => {
        leftTable.value.toggleRowSelection(i, true)
      })
      i.children?.forEach((j) => {
        nextTick(() => {
          leftTable.value.toggleRowSelection(j, false)
        })
      })
    }
    if (i.children) {
      i.children.forEach((j) => {
        const childJudging =
          type === 'edit' ? props.maintainDeptIds.includes(j.id) : i.flagMy
        if (childJudging) {
          nextTick(() => {
            leftTable.value.toggleRowSelection(j, true)
          })
        } else {
          recursion(i.children)
        }
      })
    }
  })
}

// 禁选项
const selected = (row, index) => {
  // flagOther为其他人选中的不勾选
  if (row.flagOther) {
    return false //不可勾选
  } else {
    return true //可勾选
  }
}
// 搜索递归函数
const searchRec = (arr, query) => {
  let arrEnd = []
  arr.forEach((i) => {
    if (i.children) {
      i.children.forEach((j) => {
        if (j.deptName.indexOf(query) !== -1) {
          arrEnd.push(j)
        } else {
          searchRec(i.children, query)
        }
      })
    } else {
      if (i.deptName.indexOf(query) !== -1) {
        arrEnd.push(i)
      }
    }
  })
  return arrEnd
}
// 部门模糊搜索
const remoteMethod = (query: string) => {
  if (query) {
    state.deptLoading = true
    options.value = []
    setTimeout(() => {
      state.deptLoading = false
      options.value = searchRec(state.tableDataLeft, query)
      state.defaultCheckist = tableDataRight.value.map((i) => i.id)
    }, 200)
  } else {
    options.value = []
  }
}
// 部门模糊搜索选中
const treeChecked = (row) => {
  leftTable.value.toggleRowSelection(row, !row.checked)
}
// 获取左侧选中,展示到右侧
const handleSelectionChange = (rows) => {
  tableDataRight.value = rows
}
//
const handleTbSelect = (rows, row) => {
  console.log(' ~ file: Transfer.vue:145 ~ handleTbSelect ~ a, b:', row)
  if (row.children) {
    row.children.map((i) => {
      if (i.flagMaintain) leftTable.value.toggleRowSelection(i, false)
    })
  }
  tableDataRight.value = rows
}

// 右侧删除
const delectClick = (row) => {
  tableDataRight.value.forEach((i, index) => {
    if (i.id === row.id) {
      tableDataRight.value.splice(index, 1)
    }
  })
  leftTable.value.toggleRowSelection(row, false)
}

// 获取搜索项
const userChange = (e) => {
  const checkList = userCascader.value.getCheckedNodes()
  state.defaultCheckist = e
  checkList.forEach((i) => {
    // 根据选中数据高亮
    leftTable.value.toggleRowSelection(i.data, true)
  })
}

// 监听右侧选中数并传给父级
watch(
  () => tableDataRight.value,
  (nVal) => {
    const arr = nVal.map((i) => i.id)
    emit('getCheckedList', arr, nVal)
  },
)

watch(
  () => [props.maintenanceType, props.userId],
  (nVal) => {
    console.log('watch', nVal)
    getDeptList(nVal[1], nVal[0])
  },
)
//修改反显
if (props.type === 'edit') getDeptList(props.userId, props.maintenanceType)

const modelValue = ref()
</script>
<template>
  <el-row>
    <el-col :span="10">
      <div class="left-top">
        <span>当前所有商户</span>
        <span>{{ state.num }}</span>
      </div>
      <el-cascader
        style="width: 100%"
        ref="userCascader"
        clearable
        v-model="state.userList"
        @change="userChange"
        :options="userTree"
        :props="userProps"
        filterable
      />
      <el-table
        class="left-table"
        ref="leftTable"
        :data="state.tableDataLeft"
        style="width: 100%; margin-bottom: 20px"
        row-key="id"
        default-expand-all
        border
        @selection-change="handleSelectionChange"
        @select="handleTbSelect"
      >
        <el-table-column type="selection" width="55" :selectable="selected" />
        <el-table-column prop="deptName" align="left" />
        <el-table-column prop="areaName" align="right" />
      </el-table>
    </el-col>

    <el-col :span="13" class="right-box">
      <div class="left-top">
        <span>维护部门</span>
        <span>{{ tableDataRight.length }}</span>
      </div>
      <el-table :data="tableDataRight">
        <el-table-column type="selection" width="55" />
        <el-table-column type="index" width="80" label="序号" />
        <el-table-column prop="deptName" label="维护部门" />
        <el-table-column prop="areaName" label="行政区" />
        <el-table-column #default="{ row }">
          <el-button link type="primary" @click="delectClick(row)"
            >删除</el-button
          >
        </el-table-column>
      </el-table>
    </el-col>
  </el-row>
</template>

<style scoped lang="scss">
.left-top {
  display: flex;
  justify-content: space-between;
  span:first-child {
    font-weight: bold;
  }
  margin-bottom: 15px;
}
.dept-select {
  width: 100%;
  margin-bottom: 10px;
}
.right-box {
  margin-left: 15px;
}
:deep(.left-table .el-table__header-wrapper) {
  display: none;
}
:deep(.el-scrollbar) {
  height: 400px;
  overflow-y: auto;
}
</style>

table多选右侧展示,反显,组件_第1张图片

你可能感兴趣的:(前端,javascript,java)