chore: 🔨 用户列表左侧部门树形菜单

This commit is contained in:
tk 2024-12-18 15:24:27 +08:00 committed by nsnail
parent ef17a8bd79
commit f7c91252cd
3 changed files with 115 additions and 79 deletions

View File

@ -86,12 +86,12 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('部门编号')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('部门名称')" min-width="150" prop="name" sortable="custom" /> <el-table-column :label="$t('部门名称')" min-width="150" prop="name" sortable="custom" />
<na-col-id :label="$t('部门编号')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('用户数量')" align="right" width="100"> <el-table-column :label="$t('用户数量')" align="right" width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-link @click.native="dialog.save = { mode: 'view', row, tabId: 'user' }" <el-link @click.native="dialog.save = { mode: 'view', row, tabId: 'user' }"
>{{ statistics.deptId?.find((x) => x.key.deptId === row.id.toString())?.value ?? '...' }} >{{ statistics.deptId?.find((x) => x.key.deptId === row.id.toString())?.value ?? '0' }}
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>

View File

@ -38,19 +38,23 @@
<div class="treeMain"> <div class="treeMain">
<el-tree <el-tree
:data="trees.api" :data="trees.api"
:props="{ label: (data) => data.summary }" :props="{ label: (data) => `${data.summary} - ${data.id}` }"
default-expand-all default-expand-all
node-key="id" node-key="id"
ref="api" ref="api"
show-checkbox></el-tree> show-checkbox></el-tree>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('数据范围')"> <el-tab-pane :label="$t('数据权限')">
<el-form label-width="10rem"> <el-form label-width="10rem">
<el-form-item :label="$t('规则类型')"> <el-form-item :label="$t('数据权限')">
<el-select v-model="form.dataScope" :disabled="mode === 'view'"> <el-radio-group v-model="form.dataScope" :disabled="mode === 'view'">
<el-option v-for="(item, i) in this.$GLOBAL.enums.dataScopes" :key="i" :label="item[1]" :value="i"></el-option> <el-radio-button
</el-select> v-for="(item, i) in this.$GLOBAL.enums.dataScopes"
:key="i"
:label="item[1]"
:value="i"></el-radio-button>
</el-radio-group>
</el-form-item> </el-form-item>
<el-form-item v-show="form.dataScope === 'specificDept'" :label="$t('选择部门')"> <el-form-item v-show="form.dataScope === 'specificDept'" :label="$t('选择部门')">
<div class="treeMain" style="width: 100%"> <div class="treeMain" style="width: 100%">
@ -63,16 +67,11 @@
show-checkbox></el-tree> show-checkbox></el-tree>
</div> </div>
</el-form-item> </el-form-item>
</el-form> <el-form-item :label="$t('首页视图')">
</el-tab-pane> <el-radio-group v-model="form.displayDashboard" :disabled="mode === 'view'">
<el-tab-pane :label="$t('控制台')"> <el-radio-button :label="$t('仪表板')" :value="true"></el-radio-button>
<el-form label-width="10rem"> <el-radio-button :label="$t('工作台')" :value="false"></el-radio-button>
<el-form-item :label="$t('控制台视图')"> </el-radio-group>
<el-select v-model="form.displayDashboard" :disabled="mode === 'view'">
<el-option :label="$t('仪表板')" :value="true"></el-option>
<el-option :label="$t('工作台')" :value="false"></el-option>
</el-select>
<div class="el-form-item-msg">{{ $t('用于控制角色登录后控制台的视图') }}</div>
</el-form-item> </el-form-item>
<el-form-item v-if="form.displayDashboard" :label="$t('仪表板布局')"> <el-form-item v-if="form.displayDashboard" :label="$t('仪表板布局')">
<v-ace-editor <v-ace-editor
@ -80,9 +79,9 @@
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json" lang="json"
style="height: 30rem; width: 100%" /> style="height: 30rem; width: 100%" />
<el-button @click="form.dashboardLayout = jsonFormat(form.dashboardLayout)" type="text">{{ <el-button @click="form.dashboardLayout = jsonFormat(form.dashboardLayout)" type="text"
$t('JSON 格式化') >{{ $t('JSON 格式化') }}
}}</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>

View File

@ -36,14 +36,6 @@
placeholder: $t('用户编号 / 用户名 / 手机号 / 邮箱 / 备注'), placeholder: $t('用户编号 / 用户名 / 手机号 / 邮箱 / 备注'),
style: 'width:25rem', style: 'width:25rem',
}, },
{
type: 'cascader',
field: ['filter', 'deptId'],
api: $API.sys_dept.query,
props: { label: 'name', value: 'id', checkStrictly: true, expandTrigger: 'hover', emitPath: false },
placeholder: $t('所属部门'),
style: 'width:15rem',
},
{ {
type: 'remote-select', type: 'remote-select',
field: ['filter', 'roleId'], field: ['filter', 'roleId'],
@ -80,54 +72,79 @@
</div> </div>
</el-header> </el-header>
<el-main class="nopadding"> <el-main class="nopadding">
<sc-table <el-row class="h100p">
:context-menus="['id', 'userName', 'mobile', 'email', 'enabled', 'createdTime', 'lastLoginTime']" <el-col :lg="4">
:context-opers="['view', 'edit']" <el-tree
:default-sort="{ prop: 'id', order: 'descending' }" v-loading="!deptTree"
:export-api="$API.sys_user.export" :data="deptTree"
:params="query" :default-expand-all="true"
:query-api="$API.sys_user.pagedQuery" :expand-on-click-node="false"
:vue="this" :props="{
@data-change="getStatistics" label: (data) => {
@selection-change=" return data.name
(items) => { },
selection = items }"
} @node-click="deptClick"
" highlight-current
ref="table" node-key="id"
remote-filter ref="tree">
remote-sort </el-tree>
row-key="id" </el-col>
stripe> <el-col :lg="20">
<el-table-column type="selection" width="50" /> <sc-table
<na-col-id :label="$t('用户编号')" prop="id" sortable="custom" width="170" /> :context-menus="['id', 'userName', 'mobile', 'email', 'enabled', 'createdTime', 'lastLoginTime']"
<na-col-avatar :label="$t('用户名')" prop="userName" width="170" /> :context-opers="['view', 'edit']"
<el-table-column :label="$t('手机号')" align="center" prop="mobile" sortable="custom" width="120" /> :default-sort="{ prop: 'id', order: 'descending' }"
<el-table-column :label="$t('邮箱')" align="right" prop="email" sortable="custom" width="250" /> :export-api="$API.sys_user.export"
<na-col-tags :params="query"
:label="$t('所属部门')" :query-api="$API.sys_user.pagedQuery"
@click="(item) => (this.dialog.deptSave = { row: item, mode: 'view' })" :vue="this"
field="name" @data-change="getStatistics"
prop="dept" @selection-change="
width="120" /> (items) => {
<na-col-tags selection = items
:label="$t('所属角色')" }
@click="(item) => (this.dialog.roleSave = { row: item, mode: 'view' })" "
field="name" ref="table"
min-width="200" remote-filter
prop="roles" /> remote-sort
<el-table-column :label="$t('最后登录')" align="right" prop="lastLoginTime" sortable="custom" width="120"> row-key="id"
<template #default="{ row }"> stripe>
<span v-time.tip="row.lastLoginTime" :title="row.lastLoginTime"></span> <el-table-column type="selection" width="50" />
</template> <na-col-id :label="$t('用户编号')" prop="id" sortable="custom" width="170" />
</el-table-column> <na-col-avatar :label="$t('用户名')" prop="userName" width="170" />
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="100"> <el-table-column :label="$t('手机号 / 邮箱')" align="right" prop="mobile" sortable="custom" width="250">
<template #default="{ row }"> <template #default="{ row }">
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <p>{{ row.mobile }}</p>
</template> <p>{{ row.email }}</p>
</el-table-column> </template>
<na-col-operation :vue="this" width="120" /> </el-table-column>
</sc-table> <na-col-tags
:label="$t('所属部门')"
@click="(item) => (this.dialog.deptSave = { row: item, mode: 'view' })"
field="name"
prop="dept"
width="120" />
<na-col-tags
:label="$t('所属角色')"
@click="(item) => (this.dialog.roleSave = { row: item, mode: 'view' })"
field="name"
min-width="200"
prop="roles" />
<el-table-column :label="$t('最后登录')" align="right" prop="lastLoginTime" sortable="custom" width="120">
<template #default="{ row }">
<span v-time.tip="row.lastLoginTime" :title="row.lastLoginTime"></span>
</template>
</el-table-column>
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="100">
<template #default="{ row }">
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template>
</el-table-column>
<na-col-operation :vue="this" width="120" />
</sc-table>
</el-col>
</el-row>
</el-main> </el-main>
</el-container> </el-container>
@ -167,7 +184,17 @@ export default {
return table return table
}, },
}, },
created() { async created() {
const res = await this.$API.sys_dept.query.post({})
this.deptTree = [
{
id: 0,
name: '所有部门',
children: res.data,
},
]
if (this.roleId) { if (this.roleId) {
this.query.filter.roleId = this.roleId this.query.filter.roleId = this.roleId
} }
@ -177,6 +204,7 @@ export default {
}, },
data() { data() {
return { return {
deptTree: null,
statistics: { statistics: {
total: '...', total: '...',
}, },
@ -200,6 +228,10 @@ export default {
}, },
inject: ['reload'], inject: ['reload'],
methods: { methods: {
deptClick(e) {
this.$refs.search.form.filter.deptId = e.id
this.$refs.search.search()
},
async getStatistics() { async getStatistics() {
this.statistics.total = this.$refs.table?.total this.statistics.total = this.$refs.table?.total
const res = await Promise.all([ const res = await Promise.all([
@ -260,6 +292,7 @@ export default {
onReset() { onReset() {
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = [''])) Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))
this.$refs.selectFilter.selected['enabled'] = [true] this.$refs.selectFilter.selected['enabled'] = [true]
this.$refs.tree.setCurrentKey(0)
}, },
// //
async onSearch(form) { async onSearch(form) {
@ -322,4 +355,8 @@ export default {
} }
</script> </script>
<style scoped></style> <style scoped>
::v-deep .el-tree-node__content {
height: 3rem;
}
</style>