Newer
Older
vue3-front / src / views / system / user / list.user.vue
liyaguang on 29 Nov 2022 9 KB feat: 用户管理相关功能
<script lang="ts" setup name="SystemDictListDict">
import { ElMessage, ElMessageBox } from 'element-plus'
import type { IlistQueryType, TreeStructure, userType } from './user_interface'
import { getDeptTreeList } from '@/api/system/dept'
import { delUser, freezeUserApi, getUserList, unfreezeUser } from '@/api/system/user'
import { toTreeList } from '@/utils/structure'
// 逻辑代码
interface Tree {
  name: string
  children?: Tree[]
  id: string
}
const select = ref()
const { proxy } = getCurrentInstance() as any
const tagNames = { 已冻结: 'danger', 启用: 'success' }
const btnNames = { 已冻结: '解冻', 启用: '冻结' }
const btnStatus = { 已冻结: '', 启用: 'primary' }
const columns = [
  { text: '账号', value: 'account' },
  { text: '所在组织机构', value: 'deptName', width: 150 },
  { text: '真实姓名', value: 'name' },
  { text: '角色', value: 'roleName' },
  { text: '手机号', value: 'phone' },
  { text: '注册时间', value: 'createtime' },
]
const list = ref([])
const total = ref(20)
const loadingTable = ref<boolean>(false)
const loadingTree = ref<boolean>(false)

const logTypeList = ref(null)
const listLoading = ref(true)
const defaultProps = {
  children: 'children',
  label: 'name',
}
// 查询参数
const listQuery: IlistQueryType = reactive({
  keywords: '',
  beginTime: '',
  endTime: '',
  deptId: '',
  offset: 1,
  limit: 20,
  sort: 'id',
  deptType: '',
})
const treeData = ref<TreeStructure[]>([])
// 获取列表数据
const fetchData = (flag: string) => {
  loadingTable.value = true
  if (flag === 'search') {
    listQuery.deptId = ''
  }
  else if (flag === 'click') {
    listQuery.keywords = ''
    listQuery.beginTime = ''
    listQuery.endTime = ''
  }
  getUserList(listQuery).then((res) => {
    list.value = res.data.rows
    total.value = res.data.total
    loadingTable.value = false
  }).catch(() => {
    loadingTable.value = false
  })
}
// 点击树形结构
const handleNodeClick = (data: Tree) => {
  listQuery.deptId = data.id as string
  fetchData('click')
}

// 获取组织列表树数据
const fetchTreeData = () => {
  loadingTree.value = true
  getDeptTreeList(listQuery).then((res) => {
    treeData.value = toTreeList<TreeStructure>(res.data, '0', true)
    loadingTree.value = false
  }).catch(() => {
    loadingTree.value = false
  })
}
// 查询数据
const search = () => {
  fetchData('search')
}
// 删除用户
const deleteUser = () => {
  if (select.value) {
    const user: userType = list.value[select.value - 1]
    ElMessageBox.confirm(
      `确定要删除${user.name}吗?`,
      'Warning',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      },
    ).then(() => {
      delUser({ id: user.id }).then(() => {
        ElMessage.success('操作成功')
        fetchData('')
      })
    }).catch(() => { })
  }
  else {
    ElMessage.error('必须选中一项')
  }
}
// 冻结/解冻用户
const frozenUser = (row: userType) => {
  ElMessageBox.confirm(
    `确定要${(btnNames as any)[row.statusName]}${row.name}吗?`,
    'Warning',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    },
  ).then(() => {
    if ((btnNames as any)[row.statusName] === '冻结') {
      // 发送请求
      freezeUserApi({ id: row.id }).then((res) => {
        ElMessage.success('操作成功')
        fetchData('')
      })
    }
    else {
      unfreezeUser({ id: row.id }).then((res) => {
        ElMessage.success('操作成功')
        fetchData('')
      })
    }
  }).catch(() => { })
}
// 改变每页条数
const handleSizeChange = (val: number) => {
  listQuery.limit = val
  fetchData('')
}
// 改变当前页数
const handleCurrentChange = (val: number) => {
  listQuery.offset = val
  fetchData('')
}
// 挂载
onMounted(() => {
  // 获取树形结构数据
  fetchTreeData()
  // 获取列表数据
  fetchData('click')
})
</script>

<template>
  <!-- 布局 -->
  <app-container>
    <div class="container">
      <!-- 左侧组织机构 -->
      <div class="left-container">
        <div class="dept-div">
          <el-card class="box-card" shadow="always">
            <template #header>
              <div class="clearfix">
                <span>组织机构</span>
              </div>
            </template>
            <el-tree
              v-loading="loadingTree" :data="treeData" :props="defaultProps" default-expand-all
              :expand-on-click-node="false" @node-click="handleNodeClick"
            />
          </el-card>
        </div>
      </div>
      <!-- 右侧表格 -->
      <div ref="tableContainer" class="table">
        <!-- 筛选条件 -->
        <search-area @search="search">
          <search-item>
            <el-input v-model.trim="listQuery.keywords" placeholder="账户/真实姓名/手机号" clearable />
          </search-item>
          <search-item>
            <el-date-picker
              v-model="listQuery.beginTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
              placeholder="选择开始时间"
            />
          </search-item>
          <search-item>
            <el-date-picker
              v-model="listQuery.endTime" type="datetime" format="YYYY-MM-DD HH:mm:ss"
              placeholder="选择结束时间"
            />
          </search-item>
        </search-area>
        <!-- 操作 -->
        <div style="margin-bottom: 10px;">
          <el-button v-if="proxy.hasPerm('/sys/mgr/add')" size="small" type="primary" icon="el-icon-plus">
            新增
          </el-button>
          <el-button v-if="proxy.hasPerm('/sys/mgr/update')" size="small" type="primary" icon="el-icon-edit">
            修改
          </el-button>
          <el-button
            v-if="proxy.hasPerm('/sys/mgr/delete')" size="small" type="primary" icon="el-icon-delete"
            @click="deleteUser"
          >
            删除
          </el-button>
          <el-button v-if="proxy.hasPerm('/sys/mgr/reset')" size="small" type="primary" icon="el-icon-key">
            重置密码
          </el-button>
          <el-button v-if="proxy.hasPerm('/sys/mgr/roleAssign')" size="small" type="primary" icon="el-icon-magic-stick">
            角色分配
          </el-button>
        </div>
        <!-- 查询结果Table显示 -->
        <div clss="title">
          <div>
            数据列表
          </div>
        </div>
        <el-table v-loading="loadingTable" :data="list" style="width: 100%;" border>
          <el-table-column label="选择" width="60" header-align="center">
            <template #default="scope">
              <el-radio v-model="select" :label="scope.$index + 1" class="radio" />
            </template>
          </el-table-column>
          <el-table-column label="#" width="55" align="center">
            <template #default="scope">
              {{ (listQuery.offset - 1) * listQuery.limit + scope.$index + 1 }}
            </template>
          </el-table-column>
          <el-table-column prop="account" label="账号" align="center" show-overflow-tooltip />
          <el-table-column prop="deptName" label="所在机构组织" align="center" width="110" show-overflow-tooltip />
          <el-table-column prop="name" label="真实姓名" align="center" show-overflow-tooltip />
          <el-table-column prop="roleName" label="角色" align="center" show-overflow-tooltip />
          <el-table-column prop="phone" label="手机号" align="center" width="130" />
          <el-table-column prop="createtime" label="注册时间" align="center" width="130" />
          <el-table-column label="状态" align="center">
            <template #default="scope">
              <el-tag :type="(tagNames as any)[scope.row.statusName]">
                {{ scope.row.statusName }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <template #default="scope">
              <el-button :type="(btnStatus as any)[scope.row.statusName]" size="small" @click="frozenUser(scope.row)">
                {{ (btnNames as any)[scope.row.statusName] }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页 -->
        <div class="pagination">
          <el-pagination
            :current-page="listQuery.offset" :page-sizes="[20, 30, 40]" :page-size="listQuery.limit"
            :total="total" layout="total, sizes, prev, pager, next" @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
          <el-pagination />
        </div>
      </div>
    </div>
  </app-container>
</template>

<style lang="scss" scoped>
// 样式
.container {
  width: 100%;
  display: flex;

  .left-container {
    width: 22%;
  }

  .title {
    padding: 5px 10px;
    // background-color: ;
    font-size: 15px;
    line-height: 46px;
    color: #fff;
  }

  .table {
    width: 78%;

    .pagination {
      margin-top: 10px;
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
  }
}

.dept-div {
  padding-right: 12px;

  :deep(.el-card) {
    height: 100vh;
    background-color: #fff;
  }

  .box-card {
    width: 100%;

    .user-dept-scroll {
      width: 100%;
      height: calc(100vh - 265px);
    }
  }
}
</style>