提交
This commit is contained in:
1 parent
b9ff9c9d67
commit
44749ae716
87 files changed
+35089
-21918
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -45,7 +45,11 @@
|
||||
<el-button class="btn-ghost" :loading="loading" @click="handleReset"
|
||||
><el-icon><RefreshLeft /></el-icon>重置</el-button
|
||||
>
|
||||
<el-button class="btn-main" type="primary" :loading="loading" @click="handleSearch"
|
||||
<el-button
|
||||
class="btn-main"
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
@click="handleSearch"
|
||||
><el-icon><Search /></el-icon>搜索</el-button
|
||||
>
|
||||
</div>
|
||||
@@ -55,7 +59,7 @@
|
||||
|
||||
<div class="list-toolbar">
|
||||
<div class="list-toolbar-row">
|
||||
<ListQuickSearchInput
|
||||
<ListQuickSearchInput
|
||||
v-model="quickSearchKeyword"
|
||||
placeholder="账号/姓名/手机号"
|
||||
@search="handleQuickSearch"
|
||||
@@ -105,7 +109,8 @@
|
||||
</div>
|
||||
|
||||
<div class="list-body list-wrap">
|
||||
<ListTable table-key="system-user"
|
||||
<ListTable
|
||||
table-key="system-user"
|
||||
class="list-table"
|
||||
:data="tableData"
|
||||
v-loading="loading"
|
||||
@@ -114,7 +119,12 @@
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-dblclick="handleView"
|
||||
>
|
||||
<el-table-column type="selection" min-width="55" align="center" header-align="center" />
|
||||
<el-table-column
|
||||
type="selection"
|
||||
min-width="55"
|
||||
align="center"
|
||||
header-align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="序号"
|
||||
@@ -151,7 +161,27 @@
|
||||
header-align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatUserDeptDisplay(row) }}
|
||||
{{ row.deptName || '—' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="isColumnVisible('roles')"
|
||||
prop="roles"
|
||||
label="角色"
|
||||
min-width="180"
|
||||
align="center"
|
||||
header-align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template v-if="resolveUserRoles(row).length">
|
||||
<template v-for="(role, idx) in resolveUserRoles(row)" :key="role.id">
|
||||
<span v-if="idx > 0" class="user-role-sep">、</span>
|
||||
<el-link type="primary" @click.stop="handleOpenRole(role.id)">{{
|
||||
role.label
|
||||
}}</el-link>
|
||||
</template>
|
||||
</template>
|
||||
<span v-else>—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -191,9 +221,9 @@
|
||||
</ListTable>
|
||||
|
||||
<div class="pagination list-pager-bar">
|
||||
<div class="list-pager-selected">
|
||||
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
|
||||
</div>
|
||||
<div class="list-pager-selected">
|
||||
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
|
||||
</div>
|
||||
|
||||
<el-pagination
|
||||
:current-page="pagination.page"
|
||||
@@ -324,14 +354,38 @@
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
<template #userRoles>
|
||||
<div class="user-view-roles">
|
||||
<template v-if="viewRow && resolveUserRoles(viewRow).length">
|
||||
<el-tag
|
||||
v-for="role in resolveUserRoles(viewRow)"
|
||||
:key="role.id"
|
||||
type="info"
|
||||
size="small"
|
||||
class="user-role-tag"
|
||||
@click="handleOpenRole(role.id)"
|
||||
>
|
||||
{{ role.label }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<span v-else>—</span>
|
||||
</div>
|
||||
</template>
|
||||
</SystemViewDialog>
|
||||
|
||||
<RoleManageDialogs ref="roleDialogsRef" />
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, onMounted, watch } from 'vue'
|
||||
import { canDeleteByCreator, filterDeletableByCreator, allRowsDeletableByCreator, CREATOR_DELETE_TIP } from '@/utils/creator-delete'
|
||||
import {
|
||||
canDeleteByCreator,
|
||||
filterDeletableByCreator,
|
||||
allRowsDeletableByCreator,
|
||||
CREATOR_DELETE_TIP
|
||||
} from '@/utils/creator-delete'
|
||||
import { syncViewRowFromFlatList } from '@/utils/view-dialog-refresh'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import {
|
||||
@@ -346,6 +400,7 @@
|
||||
Delete
|
||||
} from '@element-plus/icons-vue'
|
||||
import SystemViewDialog from '@/components/business/system-view-dialog/index.vue'
|
||||
import RoleManageDialogs from '@/components/business/role-manage-dialogs/index.vue'
|
||||
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
|
||||
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
|
||||
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
|
||||
@@ -359,12 +414,12 @@
|
||||
fetchDeptTree,
|
||||
fetchRoleOptions
|
||||
} from '@/api/admin'
|
||||
import { buildPathLabelMapFromTreeRoots } from '@/utils/tree-path'
|
||||
import { useDictStore } from '@/store/modules/dict'
|
||||
import { buildPathLabelMapFromTreeRoots } from '@/utils/tree-path'
|
||||
import { useDictStore } from '@/store/modules/dict'
|
||||
|
||||
defineOptions({ name: 'SystemUser' })
|
||||
defineOptions({ name: 'SystemUser' })
|
||||
|
||||
const dictStore = useDictStore()
|
||||
const dictStore = useDictStore()
|
||||
|
||||
const roleOptions = ref<Array<{ label: string; value: string }>>([])
|
||||
|
||||
@@ -396,13 +451,20 @@ const dictStore = useDictStore()
|
||||
return deptPathLabelMap.value.get(id) || row.deptName || '—'
|
||||
}
|
||||
|
||||
function formatUserRoleDisplay(row: Api.User.UserItem) {
|
||||
function resolveUserRoles(row: Api.User.UserItem) {
|
||||
const ids = row.roleIds || []
|
||||
if (!ids.length) return '—'
|
||||
const labels = ids
|
||||
.map((id) => roleOptions.value.find((o) => o.value === id)?.label)
|
||||
.filter((name): name is string => Boolean(name))
|
||||
return labels.length ? labels.join('、') : '—'
|
||||
return ids
|
||||
.map((id) => {
|
||||
const label = roleOptions.value.find((o) => o.value === id)?.label
|
||||
return label ? { id, label } : null
|
||||
})
|
||||
.filter((item): item is { id: string; label: string } => Boolean(item))
|
||||
}
|
||||
|
||||
const roleDialogsRef = ref<InstanceType<typeof RoleManageDialogs> | null>(null)
|
||||
|
||||
function handleOpenRole(roleId: string) {
|
||||
roleDialogsRef.value?.openView(roleId)
|
||||
}
|
||||
|
||||
const searchForm = reactive<{ keyword: string; status: string }>({ keyword: '', status: '' })
|
||||
@@ -415,18 +477,14 @@ const dictStore = useDictStore()
|
||||
const listColumnDefs = [
|
||||
{ prop: 'userNo', label: '用户账号' },
|
||||
{ prop: 'deptName', label: '所属组织' },
|
||||
{ prop: 'roles', label: '角色' },
|
||||
{ prop: 'phoneNo', label: '手机号' },
|
||||
{ prop: 'status', label: '状态' },
|
||||
{ prop: 'createTime', label: '创建时间', defaultVisible: false }
|
||||
]
|
||||
|
||||
const {
|
||||
visibleColumns,
|
||||
checkAll,
|
||||
isIndeterminate,
|
||||
isColumnVisible,
|
||||
resetToDefault
|
||||
} = usePersistedListColumns('system-user-list-columns', listColumnDefs)
|
||||
const { visibleColumns, checkAll, isIndeterminate, isColumnVisible, resetToDefault } =
|
||||
usePersistedListColumns('system-user-list-columns', listColumnDefs)
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('新增用户')
|
||||
@@ -722,9 +780,14 @@ const dictStore = useDictStore()
|
||||
long: false
|
||||
},
|
||||
{ label: '创建时间', value: row.createTime, long: false },
|
||||
{ label: '角色', value: formatUserRoleDisplay(row), long: false },
|
||||
{ label: '备注', value: row.remark, long: false }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
titleStyle: 'field' as const,
|
||||
fields: [],
|
||||
slot: 'userRoles'
|
||||
}
|
||||
]
|
||||
})
|
||||
@@ -823,4 +886,20 @@ const dictStore = useDictStore()
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.user-role-tag {
|
||||
margin: 2px 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-role-sep {
|
||||
color: var(--mint-text-muted, var(--el-text-color-secondary));
|
||||
}
|
||||
|
||||
.user-view-roles {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user