大屏页面初始化

This commit is contained in:
2026-03-06 15:43:05 +08:00
parent 4c62e80407
commit b9d209f7ef
12 changed files with 395 additions and 29 deletions

View File

@@ -10,3 +10,27 @@ export function getHomeRoleList(params) {
params: params
})
}
/**
* 获取角色授权的菜单
*/
export function getHomeRoleMenus(params) {
return request({
url: '/biz/homeRole/roleMenus',
method: 'get',
params: params
})
}
/**
* 给角色授权菜单
*/
export function getHomeRoleAssign(data) {
return request({
url: '/biz/homeRole/assign',
method: 'post',
data
})
}

View File

@@ -15,12 +15,14 @@
icon="Refresh"
@click="handleReset"
v-if="showReset"
:disabled="loading"
>
重置
</el-button>
<el-button
icon="Close"
@click="handleCancel"
:disabled="loading"
>
取消
</el-button>
@@ -29,6 +31,8 @@
icon="Check"
@click="handleConfirm"
class="save-btn"
:loading="loading"
:disabled="loading"
>
{{ confirmText }}
</el-button>
@@ -57,6 +61,10 @@ const props = defineProps({
confirmText: {
type: String,
default: '保存'
},
loading: {
type: Boolean,
default: false
}
})
@@ -90,6 +98,7 @@ const handleConfirm = () => {
emit('confirm')
}
</script>
<style>
.uni-custom-dialog .el-dialog__header {
border-bottom: 1px solid #1989fa !important;
@@ -132,4 +141,8 @@ const handleConfirm = () => {
border-color: #0d82e0 !important;
color: #ffffff !important;
}
.uni-custom-dialog .el-button--loading {
pointer-events: none;
}
</style>

View File

@@ -74,13 +74,19 @@ const routes = [
name: 'Dashboard',
component: Dashboard
},
...generateRoutes()
...generateRoutes(),
{
path: '/:pathMatch(.*)*',
name: 'Layout404',
component: Page404
}
]
},
{
path: '/:pathMatch(.*)*',
name: 'Page404',
component: Page404
component: () => import('@/views/error/404.vue'),
meta: { requiresAuth: true }
}
]

View File

@@ -26,7 +26,7 @@
<script lang="ts" setup>
import { ref, watch, onMounted, onUnmounted } from 'vue'
import ResizablePage from '@/components/Layout/proResizable.vue'
import ResizablePage from '@/components/Table/proResizable.vue'
import FilterTree, { type FilterTreeNode } from '@/components/Table/proFilterTree.vue'
import { getTreeMenuList } from '@/api/bizMenu'
import vMeun from './list.vue'

View File

@@ -7,45 +7,62 @@
>
<template #sidebar>
<div class="sidebar-content">
<FilterSelect
:list-data="listData"
node-key="roleId"
label-key="roleName"
@item-click="handleItemClick"
@edit="handleEdit"
@delete="handleDelete"
@view="handleView"
/>
<FilterSelect
:list-data="listData"
node-key="roleId"
label-key="roleName"
@item-click="handleItemClick"
@edit="handleEdit"
@delete="handleDelete"
@view="handleView"
/>
</div>
</template>
<template #main>
<div class="main-content">
<vUser />
<vUser />
</div>
</template>
</ResizablePage>
<PDialog
v-model="dialogVisible"
title="角色授权"
:loading="saveLoading"
@close="handleDialogClose"
@reset="handleDialogReset"
@confirm="handleSave"
>
<vRole ref="formComponentRef" :form-data="roleForm" />
</PDialog>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import ResizablePage from '@/components/Layout/proResizable.vue'
import { ElMessage } from 'element-plus'
import ResizablePage from '@/components/Table/proResizable.vue'
import FilterSelect from '@/components/Table/proFilterSelect.vue'
import { getHomeRoleList } from '@/api/bizRole'
import PDialog from '@/components/Dialog/proDialog.vue'
import { getHomeRoleList, getHomeRoleAssign } from '@/api/bizRole'
import vUser from './list.vue'
import vRole from './role.vue'
const FormValues = ref({
menuId: ''
});
const listData = ref([]);
const saveLoading = ref(false)
const dialogVisible = ref(false)
const roleForm = ref({})
const formComponentRef = ref(null)
const getListData = async () => {
try {
const res = await getHomeRoleList();
listData.value = res || []
listData.value = res || []
} catch (error) {
console.log(error);
console.log(error);
}
}
@@ -53,9 +70,9 @@ const handleItemClick = (item) => {
console.log('选中了:', item)
}
// 操作事件处理
const handleEdit = (item) => {
console.log('编辑', item)
roleForm.value = { ...item }
dialogVisible.value = true
}
const handleDelete = (item) => {
@@ -66,8 +83,42 @@ const handleView = (item) => {
console.log('查看', item)
}
const handleDialogClose = () => {
roleForm.value = {}
dialogVisible.value = false
}
const handleDialogReset = () => {
if (formComponentRef.value) {
formComponentRef.value.resetForm()
ElMessage.info('表单已重置')
}
}
const handleSave = async () => {
if (formComponentRef.value) {
const isValid = await formComponentRef.value.validate()
if (!isValid) {
return
}
const selectedMenuIds = formComponentRef.value.getSelectedMenuIds()
roleForm.value.menuIds = selectedMenuIds
}
const reqParams = {
... roleForm.value
}
saveLoading.value = true
const res = await getHomeRoleAssign(reqParams);
setTimeout(() => {
ElMessage.success(res.msg)
saveLoading.value = false
dialogVisible.value = false
getListData()
}, 500)
}
onMounted(() => {
getListData();
getListData();
})
</script>

View File

@@ -52,7 +52,7 @@
@current-change="handleCurrentChange"
>
<template #columns>
<el-table-column prop="createTime" label="记录日期" />
<el-table-column prop="createTime" label="记录日期" width="180" />
<el-table-column prop="userName" label="登录账户" />
<el-table-column prop="uname" label="用户名称" />
<el-table-column prop="sex" label="性别" />

View File

@@ -0,0 +1,223 @@
<template>
<div class="role-auth-container">
<el-form
:model="formData"
class="role-info-form"
label-width="80px"
inline
>
<el-form-item label="角色编号:" class="form-col">
<el-input
v-model="formData.roleId"
disabled
class="info-input"
/>
</el-form-item>
<el-form-item label="角色名称:" class="form-col">
<el-input
v-model="formData.roleName"
class="info-input"
/>
</el-form-item>
</el-form>
<div class="menu-tree-wrapper">
<div class="tree-content">
<el-skeleton v-if="loading" :rows="10" animated />
<el-tree
v-else
ref="menuTreeRef"
:data="menuTreeData"
:props="treeProps"
:show-checkbox="true"
:default-expand-all="false"
node-key="id"
@check-change="handleCheckChange"
@check="handleCheck"
/>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, defineProps, defineExpose, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { getTreeMenuList } from '@/api/bizMenu'
import { getHomeRoleMenus } from '@/api/bizRole'
const props = defineProps({
formData: {
type: Object,
required: true,
default: () => ({
roleId: '',
roleName: '',
menuIds: []
})
}
})
const menuTreeData = ref([])
const loading = ref(false)
const menuTreeRef = ref(null)
const selectedMenuIds = ref([])
const getTreeListData = async () => {
try {
const res = await getTreeMenuList()
menuTreeData.value = res ?? []
} catch (error) {
console.error('加载菜单树失败:', error)
menuTreeData.value = []
}
}
const getRoleMenuIds = async () => {
try {
const reqParams = { roleId: props.formData.roleId }
const res = await getHomeRoleMenus(reqParams)
return (res ?? []).map(item => String(item?.menuId)).filter(id => id)
} catch (error) {
console.error('加载角色菜单权限失败:', error)
return []
}
}
const treeProps = reactive({
label: 'label',
children: 'children',
disabled: 'disabled'
})
onMounted(async () => {
loading.value = true
try {
const [_, roleMenuIds] = await Promise.all([
getTreeListData(),
getRoleMenuIds()
])
const propsMenuIds = (props.formData?.menuIds ?? []).map(id => String(id)).filter(id => id)
const defaultCheckedIds = roleMenuIds.length > 0 ? roleMenuIds : propsMenuIds
if (defaultCheckedIds.length > 0) {
selectedMenuIds.value = [...defaultCheckedIds]
setTimeout(() => {
if (menuTreeRef.value && menuTreeData.value.length) {
menuTreeRef.value.setCheckedKeys(defaultCheckedIds, false)
}
}, 300)
}
} catch (error) {
console.error('初始化权限数据失败:', error)
} finally {
loading.value = false
}
})
watch(() => props.formData.menuIds, (newVal) => {
if (!newVal || !newVal.length || !menuTreeRef.value) return
const menuIds = newVal.map(id => String(id)).filter(id => id)
if (menuIds.length) {
selectedMenuIds.value = [...menuIds]
menuTreeRef.value.setCheckedKeys(menuIds, false)
}
}, { deep: true })
const handleCheck = () => {
if (!menuTreeRef.value) return
selectedMenuIds.value = menuTreeRef.value.getCheckedKeys(false)
}
const handleCheckChange = (data, checked, indeterminate) => {
handleCheck()
}
const validate = async () => {
if (selectedMenuIds.value.length === 0) {
ElMessage.warning('请至少选择一个菜单权限!')
return false
}
return true
}
const resetForm = () => {
if (menuTreeRef.value) {
menuTreeRef.value.setCheckedKeys([])
selectedMenuIds.value = []
}
}
defineExpose({
validate,
resetForm,
getSelectedMenuIds: () => selectedMenuIds.value,
getLeafMenuIds: () => menuTreeRef.value ? menuTreeRef.value.getCheckedKeys(true) : []
})
</script>
<style scoped>
.role-auth-container {
width: 100%;
padding: 16px;
border: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 8px;
box-sizing: border-box;
background: #fff;
}
.role-info-form {
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #e5e7eb;
width: 100%;
display: flex;
gap: 20px;
}
.form-col {
flex: 1;
min-width: 200px;
}
.info-input {
width: 100%;
}
:deep(.role-info-form .el-form-item) {
margin-bottom: 0;
width: 100%;
}
:deep(.role-info-form .el-input.is-disabled .el-input__inner) {
background-color: #f5f7fa;
color: #666;
}
.menu-tree-wrapper {
width: 100%;
}
.tree-content {
width: 100%;
height: 400px;
overflow-y: auto;
border: 1px solid #e5e7eb;
border-radius: 4px;
padding: 8px;
box-sizing: border-box;
}
:deep(.el-tree) {
--el-tree-node-content-hover-bg-color: #f5f7fa;
}
:deep(.el-tree-node__content) {
height: 36px;
line-height: 36px;
}
.tree-content::-webkit-scrollbar {
width: 6px;
}
.tree-content::-webkit-scrollbar-thumb {
background-color: #dcdfe6;
border-radius: 3px;
}
</style>

View File

@@ -52,7 +52,7 @@
@current-change="handleCurrentChange"
>
<template #columns>
<el-table-column prop="createTime" label="记录日期" sortable fixed="left" />
<el-table-column prop="createTime" label="记录日期" width="180" sortable fixed="left" />
<el-table-column prop="userName" label="登录账户" />
<el-table-column prop="uname" label="用户名称" />
<el-table-column prop="sex" label="性别" sortable />

View File

@@ -9,5 +9,8 @@ import java.util.List;
public class RoleAssignPerm implements Serializable {
private String roleId;
private List<String> permissionIds;
private String roleName;
private List<String> menuIds;
}

View File

@@ -1,12 +1,20 @@
package com.mini.mybigscreen.biz.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mini.mybigscreen.Model.Message;
import com.mini.mybigscreen.Model.Result;
import com.mini.mybigscreen.Model.RoleAssignPerm;
import com.mini.mybigscreen.biz.domain.ErpCategory;
import com.mini.mybigscreen.biz.domain.HomeRole;
import com.mini.mybigscreen.biz.domain.HomeRoleMenu;
import com.mini.mybigscreen.biz.service.HomeRoleMenuService;
import com.mini.mybigscreen.biz.service.HomeRoleService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
@@ -20,16 +28,54 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/biz/homeRole")
public class HomeRoleController {
@Resource
private HomeRoleMenuService roleMenuService;
@Resource
private HomeRoleService roleService;
@GetMapping("list")
public Result<?> getList(){
public Result<?> getList() {
return Result.success(roleService.list());
}
/**
* 角色授权
*/
@PostMapping("assign")
public Result<Message> getRoleAssign(@RequestBody RoleAssignPerm assignPerm) {
HomeRole role = roleService.getById(assignPerm.getRoleId());
role.setRoleName(assignPerm.getRoleName());
roleService.updateById(role);
roleMenuService.remove(new LambdaQueryWrapper<HomeRoleMenu>()
.eq(HomeRoleMenu::getRoleId, assignPerm.getRoleId()));
List<HomeRoleMenu> newRoleMenus = assignPerm.getMenuIds().stream()
.map(menuId -> {
HomeRoleMenu roleMenu = new HomeRoleMenu();
roleMenu.setRoleId(assignPerm.getRoleId());
roleMenu.setMenuId(menuId);
roleMenu.setUstatus("1");
return roleMenu;
})
.collect(Collectors.toList());
roleMenuService.saveBatch(newRoleMenus);
return Result.success(new Message("角色菜单分配成功", 200));
}
@GetMapping("userMenus")
public Result<Message> getUserMenus() {
return Result.success();
}
@GetMapping("roleMenus")
public Result<List<HomeRoleMenu>> getRoleMenus(String roleId) {
LambdaQueryWrapper<HomeRoleMenu> query = new LambdaQueryWrapper<HomeRoleMenu>()
.eq(StrUtil.isNotBlank(roleId), HomeRoleMenu::getRoleId, roleId)
.orderByDesc(HomeRoleMenu::getCreateTime);
return Result.success(roleMenuService.list(query));
}
public Result<Message> save() {

View File

@@ -48,5 +48,5 @@ public class HomeRoleMenu extends BaseEntity implements Serializable {
private String menuId;
@TableField("ustatus")
private Integer ustatus;
private String ustatus;
}