|
|
@@ -1,464 +1,47 @@
|
|
|
-<script lang="ts" setup>
|
|
|
-import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
-import type Node from 'element-plus/es/components/tree/src/model/node'
|
|
|
-import Group from './components/Group.vue'
|
|
|
-import User from './components/User.vue'
|
|
|
-import { deleteGroupById, getGroupByList } from '@/api/system/groupApi'
|
|
|
-import { deleteUserById, getUserByPage, resetPassword, updateUserStatus } from '@/api/system/userApi'
|
|
|
-import { packageTreeData } from '@/utils/tool'
|
|
|
-import useUserStore from '@/store/modules/user'
|
|
|
-
|
|
|
-const userStore = useUserStore()
|
|
|
-const { pagination, getParams, onSizeChange, onCurrentChange } = usePagination()
|
|
|
-const userData = userStore.getUserData()
|
|
|
-
|
|
|
-interface TreeNode {
|
|
|
- label: string
|
|
|
- groupId: number
|
|
|
- children?: TreeNode[]
|
|
|
-}
|
|
|
-
|
|
|
-const state = reactive({
|
|
|
- loading: false,
|
|
|
- curGroupId: 0,
|
|
|
- groups: [] as TreeNode[],
|
|
|
- userList: [],
|
|
|
- search: {
|
|
|
- keywords: '',
|
|
|
- },
|
|
|
-})
|
|
|
+<route lang="yaml">
|
|
|
+meta:
|
|
|
+ enabled: false
|
|
|
+</route>
|
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
+import LeftGroupTreeComponent from './components/GroupTree.vue'
|
|
|
+import UserListComponent from './components/UserList.vue'
|
|
|
const groupTreeRef = ref()
|
|
|
+const userListRef = ref()
|
|
|
|
|
|
-// 查询帐号列表
|
|
|
-const getUserData = async () => {
|
|
|
- const params = getParams()
|
|
|
- const curGroupId = state.curGroupId
|
|
|
- if (curGroupId > 0) {
|
|
|
- params.groupId = curGroupId
|
|
|
- params.keywords = state.search.keywords
|
|
|
- state.loading = true
|
|
|
- const { data } = await getUserByPage(params)
|
|
|
- state.loading = false
|
|
|
- state.userList = data.data
|
|
|
- state.loading = false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 查询部门数据
|
|
|
-const getGroupData = async () => {
|
|
|
- const { data } = await getGroupByList()
|
|
|
-
|
|
|
- state.groups = packageTreeData({
|
|
|
- data,
|
|
|
- id: 'groupId',
|
|
|
- })
|
|
|
- if (data && data.length > 0) {
|
|
|
- state.curGroupId = data[0].groupId
|
|
|
- await getUserData()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- getGroupData()
|
|
|
-})
|
|
|
-
|
|
|
-// 每页数量切换
|
|
|
-function sizeChange(size: number) {
|
|
|
- onSizeChange(size).then(() => getUserData())
|
|
|
-}
|
|
|
-
|
|
|
-// 当前页码切换(翻页)
|
|
|
-function currentChange(page = 1) {
|
|
|
- onCurrentChange(page).then(() => getUserData())
|
|
|
-}
|
|
|
-
|
|
|
-// 部门点击
|
|
|
-const onTreeNodeClick = (node: TreeNode) => {
|
|
|
- state.curGroupId = node.groupId
|
|
|
- getUserData()
|
|
|
-}
|
|
|
-
|
|
|
-const groupRef = ref()
|
|
|
-
|
|
|
-// 新增部门
|
|
|
-const onGroupAdd = (data: any) => {
|
|
|
- const { groupId, groupName } = data
|
|
|
- groupRef.value.showAddModel(groupId, groupName)
|
|
|
-}
|
|
|
-
|
|
|
-// 编辑部门
|
|
|
-const onGroupEdit = (data?: any) => {
|
|
|
- const { groupId } = data
|
|
|
- groupRef.value.showEditModel(groupId)
|
|
|
-}
|
|
|
-
|
|
|
-// 删除部门
|
|
|
-const onGroupDelete = (node: Node, data: any) => {
|
|
|
- ElMessageBox.confirm(`确认删除「${data.label}」吗?`, '确认信息').then(async () => {
|
|
|
- const { msg } = await deleteGroupById(data.groupId)
|
|
|
- ElMessage.success(msg)
|
|
|
- await getGroupData()
|
|
|
- }).catch(() => {})
|
|
|
-}
|
|
|
-
|
|
|
-const accountTableRef = ref()
|
|
|
-const userRef = ref()
|
|
|
-
|
|
|
-// 查询
|
|
|
-const onSearch = () => {
|
|
|
- getUserData()
|
|
|
-}
|
|
|
-
|
|
|
-// 新增账号
|
|
|
-const onUserAdd = () => {
|
|
|
- userRef.value.showAddModel()
|
|
|
-}
|
|
|
-
|
|
|
-// 修改账号
|
|
|
-const onUserEdit = (row: any) => {
|
|
|
- userRef.value.showEditModel(row.groupId, row.accountId)
|
|
|
-}
|
|
|
-
|
|
|
-// 密码重置
|
|
|
-const onPasswordReset = (data?: any) => {
|
|
|
- ElMessageBox.confirm('温馨提示:系统默认重置密码为 888888?', '确认').then(async () => {
|
|
|
- const { msg } = await resetPassword(data.accountId)
|
|
|
- ElMessage.success(msg)
|
|
|
- }).catch(() => {})
|
|
|
-}
|
|
|
-
|
|
|
-// 修改状态
|
|
|
-const onChangeStatus = async (status: number, row: any) => {
|
|
|
- const { msg } = await updateUserStatus(row.accountId, status)
|
|
|
- ElMessage.success(msg)
|
|
|
-}
|
|
|
-
|
|
|
-// 删除用户账号
|
|
|
-const onUserDelete = (row: any) => {
|
|
|
- ElMessageBox.confirm('温馨提示:系统默认重置密码为 888888?', '确认').then(async () => {
|
|
|
- const { msg } = await deleteUserById(row.accountId)
|
|
|
- ElMessage.success(msg)
|
|
|
- }).catch(() => {})
|
|
|
-}
|
|
|
-
|
|
|
-// "更多"处理
|
|
|
-const onCommand = (command: string, row: any) => {
|
|
|
- switch (command) {
|
|
|
- case 'GrantGroupAdd':
|
|
|
- window.console.log(row)
|
|
|
- break
|
|
|
-
|
|
|
- case 'GrantGroupEdit':
|
|
|
- break
|
|
|
-
|
|
|
- case 'GrantGroupDelete':
|
|
|
- break
|
|
|
-
|
|
|
- case 'ResetPwd':
|
|
|
- onPasswordReset(row)
|
|
|
- break
|
|
|
-
|
|
|
- case 'Permit':
|
|
|
- break
|
|
|
- }
|
|
|
+const onItemSelect = (groupId: number) => {
|
|
|
+ userListRef.value.loadData(groupId)
|
|
|
}
|
|
|
-const getUserList = () => {}
|
|
|
-const getGroupList = () => {}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div class="absolute-container">
|
|
|
- <page-header title="帐号管理" content="维护组织部门及账号信息" />
|
|
|
+ <tool-header title="账号管理" />
|
|
|
|
|
|
<div class="page-main">
|
|
|
- <LayoutContainer left-side-width="300px" hide-left-side-toggle>
|
|
|
+ <LayoutContainer left-side-width="280px" hide-left-side-toggle>
|
|
|
<template #leftSide>
|
|
|
- <el-scrollbar class="tree">
|
|
|
- <ElTree ref="groupTreeRef" :data="state.groups" :current-node-key="state.curGroupId" default-expand-all @node-click="onTreeNodeClick">
|
|
|
- <template #default="{ node, data }">
|
|
|
- <div class="custom-tree-node">
|
|
|
- <div class="label" :title="node.label">
|
|
|
- <div class="text">
|
|
|
- {{ data.groupName }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="actions">
|
|
|
- <el-button-group>
|
|
|
- <el-button type="primary" plain size="small" @click.stop="onGroupAdd(data)">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:plus" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
-
|
|
|
- <el-button type="info" plain size="small" @click.stop="onGroupEdit(data)">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:edit" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
-
|
|
|
- <el-button v-if="data.groupId !== userData.ocId" type="danger" plain size="small" @click.stop="onGroupDelete(node, data)">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:delete" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
- </el-button-group>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </ElTree>
|
|
|
- </el-scrollbar>
|
|
|
+ <LeftGroupTreeComponent ref="groupTreeRef" @onItemSelect="onItemSelect" />
|
|
|
</template>
|
|
|
|
|
|
- <div class="container">
|
|
|
- <tool-bar>
|
|
|
- <template #left>
|
|
|
- <span />
|
|
|
- </template>
|
|
|
-
|
|
|
- <template #right>
|
|
|
- <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
|
|
|
- <el-button type="primary" @click="onSearch">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:search" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
-
|
|
|
- <el-button type="primary" @click="onUserAdd">
|
|
|
- 新增用户
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- </tool-bar>
|
|
|
-
|
|
|
- <el-table ref="accountTableRef" v-loading="state.loading" class="list-table" :data="state.userList" border stripe highlight-current-row>
|
|
|
- <el-table-column type="index" align="center" label="序号" width="60" />
|
|
|
-
|
|
|
- <el-table-column align="center" header-align="center" label="头像" width="60">
|
|
|
- <template #default="{ row }">
|
|
|
- <el-avatar :size="30" :src="row.accountAvatar" />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" width="100" label="账号">
|
|
|
- <template #default="{ row }">
|
|
|
- <span>{{ row.accountName }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" width="90" label="姓名">
|
|
|
- <template #default="{ row }">
|
|
|
- <span>{{ row.accountRealName }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" width="80" label="工号">
|
|
|
- <template #default="{ row }">
|
|
|
- <span>{{ row.accountStaffNo }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" width="125" label="联系方式">
|
|
|
- <template #default="{ row }">
|
|
|
- <span>{{ row.accountPhone }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" label="所在部门">
|
|
|
- <template #default="{ row }">
|
|
|
- <span>{{ row.groupName }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" width="100" label="岗位">
|
|
|
- <template #default="{ row }">
|
|
|
- <span>{{ row.positionName }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column align="center" label="状态" width="80">
|
|
|
- <template #default="scope">
|
|
|
- <div v-if="scope.row.isFixed !== 1">
|
|
|
- <el-switch
|
|
|
- v-model="scope.row.status"
|
|
|
- :active-value="1"
|
|
|
- :inactive-value="2"
|
|
|
- :loading="scope.row.loading"
|
|
|
- inline-prompt
|
|
|
- active-text="启用"
|
|
|
- inactive-text="禁用"
|
|
|
- @change="(status) => onChangeStatus(scope.row.status, scope.row)"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
-
|
|
|
- <el-table-column label="操作" header-align="center" align="center" width="220">
|
|
|
- <template #default="scope">
|
|
|
- <div>
|
|
|
- <el-button size="small" type="primary" @click="onUserEdit(scope.row)">
|
|
|
- 修改
|
|
|
- </el-button>
|
|
|
- <el-button v-if="scope.row.isFixed !== 1" size="small" type="danger" @click="onUserDelete(scope.row)">
|
|
|
- 删除
|
|
|
- </el-button>
|
|
|
- <el-dropdown v-if="scope.row.isFixed !== 1" @command="onCommand($event, scope.row)">
|
|
|
- <el-button size="small">
|
|
|
- 更多
|
|
|
- <el-icon class="el-icon--right">
|
|
|
- <svg-icon name="i-ep:arrow-down" />
|
|
|
- </el-icon>
|
|
|
- </el-button>
|
|
|
- <template #dropdown="{ row }">
|
|
|
- <el-dropdown-menu>
|
|
|
- <template v-if="row && row.grantGroupId > 0">
|
|
|
- <el-dropdown-item command="GrantGroupEdit">
|
|
|
- 编辑授权
|
|
|
- </el-dropdown-item>
|
|
|
- <el-dropdown-item command="GrantGroupDelete">
|
|
|
- 解除授权
|
|
|
- </el-dropdown-item>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <el-dropdown-item command="GrantGroupAdd">
|
|
|
- 添加授权
|
|
|
- </el-dropdown-item>
|
|
|
- </template>
|
|
|
- <el-dropdown-item command="ResetPwd">
|
|
|
- 重置密码
|
|
|
- </el-dropdown-item>
|
|
|
- <el-dropdown-item command="Permit">
|
|
|
- 权限配置
|
|
|
- </el-dropdown-item>
|
|
|
- </el-dropdown-menu>
|
|
|
- </template>
|
|
|
- </el-dropdown>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
-
|
|
|
- <el-pagination :current-page="pagination.page" :total="pagination.total" :page-size="pagination.size" :page-sizes="pagination.sizes" :layout="pagination.layout" :hide-on-single-page="false" class="pagination" background @current-change="currentChange" @size-change="sizeChange" />
|
|
|
- </div>
|
|
|
+ <UserListComponent ref="userListRef" />
|
|
|
</LayoutContainer>
|
|
|
</div>
|
|
|
- <Group ref="groupRef" @success="getGroupList" />
|
|
|
- <User ref="userRef" @success="getUserList" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.absolute-container {
|
|
|
- position: absolute;
|
|
|
- width: 100%;
|
|
|
+.container {
|
|
|
height: 100%;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
-
|
|
|
- .page-header {
|
|
|
- margin-bottom: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .page-main {
|
|
|
- flex: 1;
|
|
|
- overflow: auto;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
-.flex-container {
|
|
|
+.absolute-container {
|
|
|
:deep(.left-side) {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
height: 100%;
|
|
|
-
|
|
|
- .btns {
|
|
|
- display: inline-flex;
|
|
|
- width: 100%;
|
|
|
- margin-bottom: var(--container-padding);
|
|
|
-
|
|
|
- .add {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .tree {
|
|
|
- flex: 1;
|
|
|
- overflow-y: auto;
|
|
|
-
|
|
|
- .el-tree {
|
|
|
- .el-tree-node__content {
|
|
|
- height: 40px;
|
|
|
- }
|
|
|
-
|
|
|
- .is-current > .el-tree-node__content {
|
|
|
- background-color: var(--el-color-primary-light-9);
|
|
|
- }
|
|
|
-
|
|
|
- .custom-tree-node {
|
|
|
- flex: 1;
|
|
|
- position: relative;
|
|
|
- width: 0;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
-
|
|
|
- .label {
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- width: calc(100% - 10px);
|
|
|
- color: var(--el-text-color-primary);
|
|
|
-
|
|
|
- .text {
|
|
|
- @include text-overflow;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &:hover {
|
|
|
- .actions {
|
|
|
- display: block;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .actions {
|
|
|
- display: none;
|
|
|
- position: absolute;
|
|
|
- right: 10px;
|
|
|
- top: 50%;
|
|
|
- transform: translateY(-50%);
|
|
|
-
|
|
|
- .el-button {
|
|
|
- padding: 5px 8px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.main) {
|
|
|
- .main-container {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .empty {
|
|
|
- flex: 1;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- font-size: 32px;
|
|
|
- color: var(--el-text-color-placeholder);
|
|
|
}
|
|
|
}
|
|
|
</style>
|