大屏项目初始化
This commit is contained in:
@@ -33,6 +33,17 @@ export function getHomeRoleAssign(data) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存角色信息列表
|
||||
*/
|
||||
export function getHomeRoleSave(data) {
|
||||
return request({
|
||||
url: '/biz/homeRole/save',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除角色信息
|
||||
|
||||
@@ -191,7 +191,10 @@ const openedSubMenuKeys = ref([])
|
||||
const getMenuList = async () => {
|
||||
if (!isMounted.value) return
|
||||
try {
|
||||
const res = await getUserMenuList();
|
||||
const reqParams = {
|
||||
roleId: userStore.loginUser.roleId,
|
||||
}
|
||||
const res = await getUserMenuList(reqParams);
|
||||
menuList.value = res || [];
|
||||
const setMenuNameMap = (menus) => {
|
||||
menus.forEach(menu => {
|
||||
|
||||
@@ -1,8 +1,99 @@
|
||||
<template>
|
||||
<el-form
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
ref="formRef"
|
||||
label-width="100px"
|
||||
class="dialog-form-container"
|
||||
>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<el-form-item label="角色名称" prop="roleName">
|
||||
<el-input
|
||||
v-model="formData.roleName"
|
||||
placeholder="请输入角色名称"
|
||||
clearable
|
||||
:disabled="isEdit"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="form-col">
|
||||
<el-form-item label="角色状态" prop="ustatus">
|
||||
<el-select
|
||||
v-model="formData.ustatus"
|
||||
placeholder="请选择角色状态"
|
||||
clearable
|
||||
>
|
||||
<el-option label="停用" value="0" />
|
||||
<el-option label="在用" value="1" />
|
||||
<el-option label="锁定" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({
|
||||
roleName: '',
|
||||
ustatus: '1',
|
||||
})
|
||||
},
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
const formRules = {
|
||||
roleName: [ { required: true, message: '请输入角色名称', trigger: 'blur' } ],
|
||||
ustatus: [ { required: true, message: '请选择角色状态', trigger: 'change' } ],
|
||||
}
|
||||
|
||||
const validate = async () => {
|
||||
if (!formRef.value) return false
|
||||
try {
|
||||
const valid = await formRef.value.validate()
|
||||
return valid
|
||||
} catch (error) {
|
||||
console.error('表单验证失败:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
if (formRef.value) formRef.value.resetFields()
|
||||
}
|
||||
|
||||
defineExpose({ validate, resetForm })
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style scoped>
|
||||
.dialog-form-container {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
margin: 0;
|
||||
border: 1px solid rgba(64, 158, 255, 0.15);
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
margin: 0 0 16px 0;
|
||||
gap: 20px;
|
||||
}
|
||||
.form-row:last-child { margin-bottom: 0; }
|
||||
.form-col { flex: 1; min-width: 180px; }
|
||||
</style>
|
||||
@@ -20,7 +20,7 @@
|
||||
</template>
|
||||
<template #main>
|
||||
<div class="main-content">
|
||||
<vUser />
|
||||
<vUser @refresh-role-list="getListData" />
|
||||
</div>
|
||||
</template>
|
||||
</ResizablePage>
|
||||
|
||||
@@ -67,18 +67,6 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="260" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" @click="handleEdit(scope.row)">
|
||||
<el-icon><Edit /></el-icon>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</STable>
|
||||
</div>
|
||||
@@ -86,6 +74,7 @@
|
||||
|
||||
<PDialog
|
||||
v-model="dialogVisible"
|
||||
:loading="saveLoading"
|
||||
:title="isEdit ? '编辑数据' : '新增数据'"
|
||||
@close="handleDialogClose"
|
||||
@reset="handleDialogReset"
|
||||
@@ -101,6 +90,7 @@ import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Plus, Download, Edit, Delete } from '@element-plus/icons-vue'
|
||||
import { getHomeUserList } from '@/api/bizUser'
|
||||
import { getHomeRoleSave } from '@/api/bizRole'
|
||||
|
||||
import CSearch from '@/components/Search/proSearch.vue'
|
||||
import STable from '@/components/Table/proTable.vue'
|
||||
@@ -108,8 +98,10 @@ import PDialog from '@/components/Dialog/proDialog.vue'
|
||||
import VForm from './form.vue'
|
||||
|
||||
const formComponentRef = ref(null)
|
||||
const emit = defineEmits(['refresh-role-list'])
|
||||
|
||||
const loading = ref(false)
|
||||
const saveLoading = ref(false)
|
||||
const searchForm = reactive({
|
||||
uname: '',
|
||||
ustatus: '',
|
||||
@@ -187,10 +179,6 @@ const handleExport = () => {
|
||||
ElMessage.success('开始导出数据...')
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
ElMessage.warning(`删除ID为 ${row.id} 的数据`)
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pagination.pageSize = val
|
||||
getDataList()
|
||||
@@ -223,11 +211,20 @@ const handleSave = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
ElMessage.success(isEdit.value ? '编辑成功' : '新增成功')
|
||||
dialogVisible.value = false
|
||||
getDataList()
|
||||
}, 500)
|
||||
try {
|
||||
saveLoading.value = true;
|
||||
const reqParams = {
|
||||
...formData.value
|
||||
}
|
||||
const res = await getHomeRoleSave(reqParams);
|
||||
ElMessage.success(res.msg)
|
||||
dialogVisible.value = false
|
||||
emit('refresh-role-list')
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
} finally {
|
||||
saveLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -63,13 +63,31 @@ const loading = ref(false)
|
||||
const menuTreeRef = ref(null)
|
||||
const selectedMenuIds = ref([])
|
||||
|
||||
const getLeafNodeIds = (treeData, leafIds = []) => {
|
||||
treeData.forEach(node => {
|
||||
if (!node.children || node.children.length === 0) {
|
||||
leafIds.push(String(node.id))
|
||||
} else {
|
||||
getLeafNodeIds(node.children, leafIds)
|
||||
}
|
||||
})
|
||||
return leafIds
|
||||
}
|
||||
|
||||
const filterOnlyLeafIds = (allIds, treeData) => {
|
||||
const allLeafIds = getLeafNodeIds(treeData)
|
||||
return allIds.filter(id => allLeafIds.includes(id))
|
||||
}
|
||||
|
||||
const getTreeListData = async () => {
|
||||
try {
|
||||
const res = await getTreeMenuList()
|
||||
menuTreeData.value = res ?? []
|
||||
return menuTreeData.value
|
||||
} catch (error) {
|
||||
console.error('加载菜单树失败:', error)
|
||||
menuTreeData.value = []
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,21 +108,38 @@ const treeProps = reactive({
|
||||
disabled: 'disabled'
|
||||
})
|
||||
|
||||
function getIndeterminateKeys(node) {
|
||||
let keys = []
|
||||
if (node.indeterminate) {
|
||||
keys.push(node.key)
|
||||
}
|
||||
if (node.childNodes) {
|
||||
node.childNodes.forEach(c => keys.push(...getIndeterminateKeys(c)))
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
function getCheckedAndIndeterminateKeys() {
|
||||
if (!menuTreeRef.value) return []
|
||||
const checked = menuTreeRef.value.getCheckedKeys(false)
|
||||
const indeterminate = getIndeterminateKeys(menuTreeRef.value.root)
|
||||
return [...new Set([...checked, ...indeterminate])]
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const [_, roleMenuIds] = await Promise.all([
|
||||
getTreeListData(),
|
||||
getRoleMenuIds()
|
||||
])
|
||||
|
||||
const treeData = await getTreeListData()
|
||||
const roleMenuIds = await 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]
|
||||
const allMenuIds = roleMenuIds.length > 0 ? roleMenuIds : propsMenuIds
|
||||
const leafMenuIds = filterOnlyLeafIds(allMenuIds, treeData)
|
||||
|
||||
if (leafMenuIds.length > 0) {
|
||||
selectedMenuIds.value = [...leafMenuIds]
|
||||
setTimeout(() => {
|
||||
if (menuTreeRef.value && menuTreeData.value.length) {
|
||||
menuTreeRef.value.setCheckedKeys(defaultCheckedIds, false)
|
||||
if (menuTreeRef.value && treeData.length) {
|
||||
menuTreeRef.value.setCheckedKeys(leafMenuIds, false)
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
@@ -116,12 +151,14 @@ onMounted(async () => {
|
||||
})
|
||||
|
||||
watch(() => props.formData.menuIds, (newVal) => {
|
||||
if (!newVal || !newVal.length || !menuTreeRef.value) return
|
||||
if (!newVal || !newVal.length || !menuTreeRef.value || !menuTreeData.value.length) return
|
||||
|
||||
const menuIds = newVal.map(id => String(id)).filter(id => id)
|
||||
if (menuIds.length) {
|
||||
selectedMenuIds.value = [...menuIds]
|
||||
menuTreeRef.value.setCheckedKeys(menuIds, false)
|
||||
const allMenuIds = newVal.map(id => String(id)).filter(id => id)
|
||||
const leafMenuIds = filterOnlyLeafIds(allMenuIds, menuTreeData.value)
|
||||
|
||||
if (leafMenuIds.length) {
|
||||
selectedMenuIds.value = [...leafMenuIds]
|
||||
menuTreeRef.value.setCheckedKeys(leafMenuIds, false)
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
@@ -130,7 +167,7 @@ const handleCheck = () => {
|
||||
selectedMenuIds.value = menuTreeRef.value.getCheckedKeys(false)
|
||||
}
|
||||
|
||||
const handleCheckChange = (data, checked, indeterminate) => {
|
||||
const handleCheckChange = () => {
|
||||
handleCheck()
|
||||
}
|
||||
|
||||
@@ -152,7 +189,7 @@ const resetForm = () => {
|
||||
defineExpose({
|
||||
validate,
|
||||
resetForm,
|
||||
getSelectedMenuIds: () => selectedMenuIds.value,
|
||||
getSelectedMenuIds: () => getCheckedAndIndeterminateKeys(),
|
||||
getLeafMenuIds: () => menuTreeRef.value ? menuTreeRef.value.getCheckedKeys(true) : []
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -138,12 +138,12 @@ const dialogVisible = ref(false)
|
||||
async function getDataList() {
|
||||
loading.value = true
|
||||
try {
|
||||
const reqParmas = {
|
||||
const reqParams = {
|
||||
... searchForm,
|
||||
pageNum: pagination.pageNum,
|
||||
pageSize: pagination.pageSize,
|
||||
}
|
||||
const res = await getHomeUserList(reqParmas);
|
||||
const res = await getHomeUserList(reqParams);
|
||||
pagination.total = res.total;
|
||||
tableData.value = res.list || [];
|
||||
} catch (error) {
|
||||
|
||||
@@ -3,11 +3,15 @@ package com.mini.mybigscreen.biz.controller;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.mini.mybigscreen.Model.Menu;
|
||||
import com.mini.mybigscreen.Model.Message;
|
||||
import com.mini.mybigscreen.Model.Result;
|
||||
import com.mini.mybigscreen.Model.TreeMenu;
|
||||
import com.mini.mybigscreen.biz.domain.HomeMenu;
|
||||
import com.mini.mybigscreen.biz.domain.HomeModule;
|
||||
import com.mini.mybigscreen.biz.domain.HomeRoleMenu;
|
||||
import com.mini.mybigscreen.biz.mapper.HomeMenuMapper;
|
||||
import com.mini.mybigscreen.biz.service.HomeMenuService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -28,6 +32,9 @@ import java.util.stream.Collectors;
|
||||
public class HomeMenuController {
|
||||
|
||||
|
||||
@Resource
|
||||
private HomeMenuMapper homeMenuMapper;
|
||||
|
||||
@Resource
|
||||
private HomeMenuService menuService;
|
||||
|
||||
@@ -124,7 +131,6 @@ public class HomeMenuController {
|
||||
return treeMenu;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
menuList.add(new TreeMenu(menu.getMenuId(), menu.getMenuName(), treeMenus));
|
||||
}
|
||||
return Result.success(menuList);
|
||||
@@ -135,33 +141,38 @@ public class HomeMenuController {
|
||||
* 用户角色菜单
|
||||
*/
|
||||
@GetMapping("userList")
|
||||
public Result<?> getUserList() {
|
||||
List<Menu> menuList = new ArrayList<>();
|
||||
LambdaQueryWrapper<HomeMenu> parentQuery = new LambdaQueryWrapper<HomeMenu>()
|
||||
.eq(HomeMenu::getUstatus, "1")
|
||||
.eq(HomeMenu::getParentId, "0")
|
||||
public Result<?> getUserList(String roleId) {
|
||||
MPJLambdaWrapper<HomeMenu> wrapper = new MPJLambdaWrapper<HomeMenu>()
|
||||
.selectAll(HomeMenu.class)
|
||||
.leftJoin(HomeRoleMenu.class,
|
||||
HomeRoleMenu::getMenuId,
|
||||
HomeMenu::getMenuId)
|
||||
.eq(HomeRoleMenu::getRoleId, roleId)
|
||||
.eq(HomeRoleMenu::getUstatus, "1")
|
||||
.isNotNull(HomeMenu::getMenuId)
|
||||
.orderByAsc(HomeMenu::getSort);
|
||||
List<HomeMenu> pMenus = menuService.list(parentQuery);
|
||||
for (HomeMenu menu : pMenus) {
|
||||
LambdaQueryWrapper<HomeMenu> childQuery = new LambdaQueryWrapper<HomeMenu>()
|
||||
.eq(HomeMenu::getParentId, menu.getMenuId());
|
||||
List<HomeMenu> childMenus = menuService.list(childQuery);
|
||||
menuList.add(new Menu(
|
||||
menu.getMenuId(),
|
||||
menu.getParentId(),
|
||||
menu.getMenuName(),
|
||||
menu.getMenuType(),
|
||||
menu.getPath(),
|
||||
menu.getMenuIcon(),
|
||||
menu.getSort(),
|
||||
menu.getIsIframe(),
|
||||
menu.getUstatus(),
|
||||
childMenus
|
||||
));
|
||||
}
|
||||
List<HomeMenu> allMenus = homeMenuMapper.selectJoinList(HomeMenu.class, wrapper);
|
||||
Map<String, List<HomeMenu>> parentIdMap = allMenus.stream()
|
||||
.collect(Collectors.groupingBy(HomeMenu::getParentId));
|
||||
List<Menu> menuList = allMenus.stream()
|
||||
.filter(menu -> menu.getParentId().equals("0"))
|
||||
.map(homeMenu -> new Menu(
|
||||
homeMenu.getMenuId(),
|
||||
homeMenu.getParentId(),
|
||||
homeMenu.getMenuName(),
|
||||
homeMenu.getMenuType(),
|
||||
homeMenu.getPath(),
|
||||
homeMenu.getMenuIcon(),
|
||||
homeMenu.getSort(),
|
||||
homeMenu.getIsIframe(),
|
||||
homeMenu.getUstatus(),
|
||||
parentIdMap.getOrDefault(homeMenu.getMenuId(), new ArrayList<>())
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
return Result.success(menuList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增/修改
|
||||
*/
|
||||
|
||||
@@ -77,8 +77,9 @@ public class HomeRoleController {
|
||||
return Result.success(roleMenuService.list(query));
|
||||
}
|
||||
|
||||
|
||||
public Result<Message> save() {
|
||||
@PostMapping("save")
|
||||
public Result<Message> save(@RequestBody HomeRole homeRole) {
|
||||
roleService.save(homeRole);
|
||||
return Result.success(new Message("数据新增成功", 200));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user