Commit 9af1aa03 authored by trumansdo's avatar trumansdo
Browse files

-- 功能点管理 完成80%,还差最后保存;完成功能点应该可以很快完成菜单管理

parent 5eea9632
# 功能列表
### 基础管理
用户管理 - 已完成
组织机构管理
角色管理
菜单项 - (需要功能点做前置)
功能点管理 - 进行中
字典数据管理
角色功能授权
角色数据授权
# 角色设计说明:关乎于路由表 # 角色设计说明:关乎于路由表
以集团为一个最大组织,可切换集团。 以集团为一个最大组织,可切换集团。
...@@ -7,4 +18,4 @@ ...@@ -7,4 +18,4 @@
# 开发规范 # 开发规范
- controller以ElController结尾 - controller以ElController结尾
- 以El开始的注解是前端视图类注解 - 以El开始的注解是前端视图类注解
- 所有的字典类型都从数据库中加载进缓存中,任何字典类型都应该以常量访问,任何的字典名称和值都应该以枚举访问。 - 所有的字典类型都从数据库中加载进缓存中,任何字典类型都应该以常量访问,任何的字典名称和值都应该以枚举访问。
\ No newline at end of file
package com.ibeetl.admin.console.service; package com.ibeetl.admin.console.service;
import java.util.ArrayList; import cn.hutool.core.collection.CollUtil;
import java.util.Date;
import java.util.List;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ibeetl.admin.console.dao.FunctionConsoleDao; import com.ibeetl.admin.console.dao.FunctionConsoleDao;
import com.ibeetl.admin.console.dao.RoleFunctionConsoleDao; import com.ibeetl.admin.console.dao.RoleFunctionConsoleDao;
import com.ibeetl.admin.console.web.dto.RoleDataAccessFunction; import com.ibeetl.admin.console.web.dto.RoleDataAccessFunction;
...@@ -22,23 +14,83 @@ import com.ibeetl.admin.core.rbac.tree.FunctionItem; ...@@ -22,23 +14,83 @@ import com.ibeetl.admin.core.rbac.tree.FunctionItem;
import com.ibeetl.admin.core.service.CoreBaseService; import com.ibeetl.admin.core.service.CoreBaseService;
import com.ibeetl.admin.core.service.CorePlatformService; import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.PlatformException; import com.ibeetl.admin.core.util.PlatformException;
/** @author lijiazhi */ import com.ibeetl.admin.core.util.enums.DelFlagEnum;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author lijiazhi
*/
@Service @Service
@Transactional @Transactional
public class FunctionConsoleService extends CoreBaseService<CoreFunction> { public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
@Autowired FunctionConsoleDao functionDao; @Autowired
@Autowired CoreMenuDao menuDao; FunctionConsoleDao functionConsoleDao;
@Autowired RoleFunctionConsoleDao roleFunctionConsoleDao;
@Autowired CoreRoleMenuDao sysRoleMenuDao; @Autowired
@Autowired CorePlatformService platformService; CoreMenuDao coreMenuDao;
@Autowired
RoleFunctionConsoleDao roleFunctionConsoleDao;
@Autowired
CoreRoleMenuDao coreRoleMenuDao;
@Autowired
CorePlatformService corePlatformService;
public List<CoreFunction> getFuncTree() {
List<CoreFunction> coreFunctionList = functionConsoleDao.getSQLManager()
.lambdaQuery(CoreFunction.class)
.andEq(CoreFunction::getDelFlag,
DelFlagEnum.NORMAL).select();
System.out.println(coreFunctionList);
CoreFunction root = new CoreFunction();
root.setId(-1L);
buildTree(root, coreFunctionList);
return root.getChildren();
}
/**
* 深度优先算法递归构建功能点树
*
* @param root
* @param allNodes
* @return
*/
private void buildTree(CoreFunction root, @NotNull List<CoreFunction> allNodes) {
if (CollUtil.isEmpty(allNodes)) {
return;
}
List<CoreFunction> childNodes =
allNodes.stream()
.filter(route -> route.getParentId().equals(root.getId()))
.collect(Collectors.toList());
root.setChildren(childNodes);
allNodes.removeAll(childNodes);
List<CoreFunction> rootChildrenList = root.getChildren();
for (CoreFunction coreFunction : rootChildrenList) {
buildTree(coreFunction, allNodes);
}
}
public void queryByCondtion(PageQuery<CoreFunction> query) { public void queryByCondtion(PageQuery<CoreFunction> query) {
functionDao.queryByCondtion(query);
functionConsoleDao.queryByCondtion(query);
List<CoreFunction> list = query.getList(); List<CoreFunction> list = query.getList();
this.queryListAfter(list); this.queryListAfter(list);
// 处理父功能名称显示 // 处理父功能名称显示
FunctionItem root = platformService.buildFunction(); FunctionItem root = corePlatformService.buildFunction();
for (CoreFunction function : list) { for (CoreFunction function : list) {
Long parentId = function.getParentId(); Long parentId = function.getParentId();
String name = ""; String name = "";
...@@ -52,70 +104,71 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> { ...@@ -52,70 +104,71 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
public Long saveFunction(CoreFunction function) { public Long saveFunction(CoreFunction function) {
functionDao.insert(function, true); functionConsoleDao.insert(function, true);
platformService.clearFunctionCache(); corePlatformService.clearFunctionCache();
return function.getId(); return function.getId();
} }
/** /**
* 删除功能点,跟菜单有关联的无法删除,删除功能点导致所有缓存都需要更新 * 删除功能点,跟菜单有关联的无法删除,删除功能点导致所有缓存都需要更新
*
* @param functionId
* @return
*/ */
public void deleteFunction(Long functionId) { public void deleteFunction(Long functionId) {
deleteFunctionId(functionId); deleteFunctionId(functionId);
platformService.clearFunctionCache(); corePlatformService.clearFunctionCache();
} }
public void batchDeleteFunction(List<Long> functionIds) { public void batchDeleteFunction(List<Long> functionIds) {
for (Long id : functionIds) { for (Long id : functionIds) {
deleteFunctionId(id); deleteFunctionId(id);
} }
platformService.clearFunctionCache(); corePlatformService.clearFunctionCache();
} }
public void updateFunction(CoreFunction function) { public void updateFunction(CoreFunction function) {
functionDao.updateById(function);
platformService.clearFunctionCache(); functionConsoleDao.updateById(function);
corePlatformService.clearFunctionCache();
} }
public CoreFunction getFunction(Long functionId) { public CoreFunction getFunction(Long functionId) {
return functionDao.unique(functionId);
return functionConsoleDao.unique(functionId);
} }
public CoreFunction getFunction(String code) { public CoreFunction getFunction(String code) {
CoreFunction query = new CoreFunction(); CoreFunction query = new CoreFunction();
query.setCode(code); query.setCode(code);
CoreFunction db = functionDao.templateOne(query); CoreFunction db = functionConsoleDao.templateOne(query);
return db; return db;
} }
/** /**
* 得到角色对应的所有功能点 * 得到角色对应的所有功能点
*
* @param roleId
* @return
*/ */
public List<Long> getFunctionByRole(Long roleId) { public List<Long> getFunctionByRole(Long roleId) {
return this.roleFunctionConsoleDao.getFunctionIdByRole(roleId); return this.roleFunctionConsoleDao.getFunctionIdByRole(roleId);
} }
/** /**
* 得到角色对应的所有数据权限功能点 * 得到角色对应的所有数据权限功能点
*
* @param roleId
* @return
*/ */
public List<RoleDataAccessFunction> getQueryFunctionByRole(Long roleId) { public List<RoleDataAccessFunction> getQueryFunctionByRole(Long roleId) {
return this.roleFunctionConsoleDao.getQueryFunctionAndRoleData(roleId); return this.roleFunctionConsoleDao.getQueryFunctionAndRoleData(roleId);
} }
/** /**
* 更新角色对应的功能点所有, * 更新角色对应的功能点所有,
* *
* @param data,必须包含id,和 dataAcerssType,采用模板更新 * @param data,必须包含id,和
* dataAcerssType,采用模板更新
*/ */
public void updateFunctionAccessByRole(List<RoleDataAccessFunction> data) { public void updateFunctionAccessByRole(List<RoleDataAccessFunction> data) {
for (RoleDataAccessFunction fun : data) { for (RoleDataAccessFunction fun : data) {
Long roleId = fun.getRoleId(); Long roleId = fun.getRoleId();
Long functionId = fun.getId(); Long functionId = fun.getId();
...@@ -139,11 +192,10 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> { ...@@ -139,11 +192,10 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
/** /**
* 给角色赋予功能同时,根据赋予的功能权限,更新能访问的菜单 * 给角色赋予功能同时,根据赋予的功能权限,更新能访问的菜单
* *
* @param adds
* @param dels
* @return 返回增加的项的id,用于前端 * @return 返回增加的项的id,用于前端
*/ */
public void updateSysRoleFunction(Long roleId, List<Long> adds, List<Long> dels) { public void updateSysRoleFunction(Long roleId, List<Long> adds, List<Long> dels) {
for (Long del : dels) { for (Long del : dels) {
// 获得功能关联的菜单 // 获得功能关联的菜单
CoreRoleFunction temp = new CoreRoleFunction(); CoreRoleFunction temp = new CoreRoleFunction();
...@@ -159,7 +211,7 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> { ...@@ -159,7 +211,7 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
// 同时,需要删除与此功能关联的菜单 // 同时,需要删除与此功能关联的菜单
CoreRoleMenu sysRoleMenu = querySysRoleMenu(roleFunction.getRoleId(), menu.getId()); CoreRoleMenu sysRoleMenu = querySysRoleMenu(roleFunction.getRoleId(), menu.getId());
if (sysRoleMenu != null) { if (sysRoleMenu != null) {
sysRoleMenuDao.deleteById(sysRoleMenu.getId()); coreRoleMenuDao.deleteById(sysRoleMenu.getId());
} }
} }
} }
...@@ -176,36 +228,37 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> { ...@@ -176,36 +228,37 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
CoreRoleMenu roleMenu = new CoreRoleMenu(); CoreRoleMenu roleMenu = new CoreRoleMenu();
roleMenu.setMenuId(menu.getId()); roleMenu.setMenuId(menu.getId());
roleMenu.setRoleId(roleId); roleMenu.setRoleId(roleId);
sysRoleMenuDao.insert(roleMenu); coreRoleMenuDao.insert(roleMenu);
} }
} }
// 清楚缓存 // 清楚缓存
platformService.clearFunctionCache(); corePlatformService.clearFunctionCache();
} }
private CoreMenu queryFunctionMenu(Long functionId) { private CoreMenu queryFunctionMenu(Long functionId) {
CoreMenu query = new CoreMenu(); CoreMenu query = new CoreMenu();
query.setFunctionId(functionId); query.setFunctionId(functionId);
List<CoreMenu> menus = menuDao.template(query); List<CoreMenu> menus = coreMenuDao.template(query);
return menus.isEmpty() ? null : menus.get(0); return menus.isEmpty() ? null : menus.get(0);
} }
private CoreRoleMenu querySysRoleMenu(Long roleId, Long menuId) { private CoreRoleMenu querySysRoleMenu(Long roleId, Long menuId) {
CoreRoleMenu query = new CoreRoleMenu(); CoreRoleMenu query = new CoreRoleMenu();
query.setMenuId(menuId); query.setMenuId(menuId);
query.setRoleId(roleId); query.setRoleId(roleId);
List<CoreRoleMenu> menus = sysRoleMenuDao.template(query); List<CoreRoleMenu> menus = coreRoleMenuDao.template(query);
return menus.isEmpty() ? null : menus.get(0); return menus.isEmpty() ? null : menus.get(0);
} }
/** /**
* 删除某一个功能点及其子功能,对应的role-function 需要删除,菜单对应的function需要设置成空 * 删除某一个功能点及其子功能,对应的role-function 需要删除,菜单对应的function需要设置成空
*
* @param functionId
*/ */
private void deleteFunctionId(Long functionId) { private void deleteFunctionId(Long functionId) {
FunctionItem root = platformService.buildFunction();
FunctionItem root = corePlatformService.buildFunction();
FunctionItem fun = root.findChild(functionId); FunctionItem fun = root.findChild(functionId);
List<FunctionItem> all = fun.findAllItem(); List<FunctionItem> all = fun.findAllItem();
// 也删除自身 // 也删除自身
...@@ -214,14 +267,16 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> { ...@@ -214,14 +267,16 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
} }
private void realDeleteFunction(List<FunctionItem> all) { private void realDeleteFunction(List<FunctionItem> all) {
List<Long> ids = new ArrayList<>(all.size()); List<Long> ids = new ArrayList<>(all.size());
for (FunctionItem item : all) { for (FunctionItem item : all) {
ids.add(item.getId()); ids.add(item.getId());
this.functionDao.deleteById(item.getId()); this.functionConsoleDao.deleteById(item.getId());
} }
// 删除角色和功能的关系 // 删除角色和功能的关系
this.roleFunctionConsoleDao.deleteRoleFunction(ids); this.roleFunctionConsoleDao.deleteRoleFunction(ids);
// 设置菜单对应的功能项为空 // 设置菜单对应的功能项为空
menuDao.clearMenuFunction(ids); coreMenuDao.clearMenuFunction(ids);
} }
} }
...@@ -138,7 +138,7 @@ public class FunctionController { ...@@ -138,7 +138,7 @@ public class FunctionController {
} }
// 删除功能和所有子功能 // 删除功能和所有子功能
functionConsoleService.deleteFunction(id); functionConsoleService.deleteFunction(id);
return new JsonResult().success(); return JsonResult.success();
} }
/** /**
......
package com.ibeetl.admin.console.web;
import com.ibeetl.admin.console.service.FunctionConsoleService;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.entity.CoreFunction;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.web.JsonResult;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 功能点管理
*
* @author 一日看尽长安花
*/
@Slf4j
@RestController
@RequestMapping("/functions")
public class FunctionElController {
@Autowired
CorePlatformService platformService;
@Autowired
private FunctionConsoleService functionConsoleService;
/**
* @return 功能点树
*/
@GetMapping
@Function("function.query")
@ResponseBody
public JsonResult<List<CoreFunction>> funcsTree() {
List<CoreFunction> functionTreeNodes = functionConsoleService.getFuncTree();
return JsonResult.success(functionTreeNodes);
}
}
...@@ -3,7 +3,7 @@ package com.ibeetl.admin.console.web; ...@@ -3,7 +3,7 @@ package com.ibeetl.admin.console.web;
import com.ibeetl.admin.console.service.UserConsoleService; import com.ibeetl.admin.console.service.UserConsoleService;
import com.ibeetl.admin.console.util.VOUtil; import com.ibeetl.admin.console.util.VOUtil;
import com.ibeetl.admin.console.web.dto.UserExcelExportData; import com.ibeetl.admin.console.web.dto.UserExcelExportData;
import com.ibeetl.admin.console.web.query.CoreUserElQuery; import com.ibeetl.admin.console.web.mo.CoreUserElMetadata;
import com.ibeetl.admin.console.web.query.UserRoleQuery; import com.ibeetl.admin.console.web.query.UserRoleQuery;
import com.ibeetl.admin.core.annotation.Function; import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.annotation.RequestBodyPlus; import com.ibeetl.admin.core.annotation.RequestBodyPlus;
...@@ -53,7 +53,7 @@ public class UserConsoleElController { ...@@ -53,7 +53,7 @@ public class UserConsoleElController {
@Function("user.query") @Function("user.query")
@GetMapping("/metadata") @GetMapping("/metadata")
public JsonResult<Map> usersMetedata() { public JsonResult<Map> usersMetedata() {
return JsonResult.success(VOUtil.resolveElColumn(CoreUserElQuery.class)); return JsonResult.success(VOUtil.resolveElColumn(CoreUserElMetadata.class));
} }
@Function("user.query") @Function("user.query")
......
package com.ibeetl.admin.console.web.query; package com.ibeetl.admin.console.web.mo;
import static com.ibeetl.admin.core.util.enums.ElColumnType.DATE; import static com.ibeetl.admin.core.util.enums.ElColumnType.DATE;
import static com.ibeetl.admin.core.util.enums.ElColumnType.DICT; import static com.ibeetl.admin.core.util.enums.ElColumnType.DICT;
...@@ -9,13 +9,13 @@ import java.util.Date; ...@@ -9,13 +9,13 @@ import java.util.Date;
import lombok.Data; import lombok.Data;
/** /**
* Class CoreUserElQuery : <br> * Class CoreUserElMetadata : <br>
* 描述:用户管理页面的metadata元数据 * 描述:用户管理页面的metadata元数据
* *
* @author 一日看尽长安花 Created on 2019/12/29 * @author 一日看尽长安花 Created on 2019/12/29
*/ */
@Data @Data
public class CoreUserElQuery { public class CoreUserElMetadata {
@ElColumn( @ElColumn(
name = "ID", name = "ID",
......
...@@ -3,7 +3,7 @@ queryByCondtion ...@@ -3,7 +3,7 @@ queryByCondtion
select select
@pageTag(){ @pageTag(){
f.* f.*
@} @}
from core_function f where 1=1 from core_function f where 1=1
@if(!isEmpty(functionIds)){ @if(!isEmpty(functionIds)){
...@@ -22,6 +22,6 @@ queryByCondtion ...@@ -22,6 +22,6 @@ queryByCondtion
and f.parent_id = #parentFunctionId# and f.parent_id = #parentFunctionId#
@} @}
@pageIgnoreTag(){ @pageIgnoreTag(){
order by id order by id
@} @}
import cn.hutool.core.collection.CollUtil;
import com.ibeetl.admin.ConsoleApplication; import com.ibeetl.admin.ConsoleApplication;
import com.ibeetl.admin.core.dao.CoreFunctionDao; import com.ibeetl.admin.core.dao.CoreFunctionDao;
import com.ibeetl.admin.core.entity.CoreRoute; import com.ibeetl.admin.core.entity.CoreRoute;
import entity.CmsBlog; import entity.CmsBlog;
import entity.CmsBlogTypeEnum; import entity.FunctionTypeEnum;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.beetl.sql.core.SQLManager; import org.beetl.sql.core.SQLManager;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -42,7 +31,7 @@ public class CustomBeanProcessorTest { ...@@ -42,7 +31,7 @@ public class CustomBeanProcessorTest {
CmsBlog blog = new CmsBlog(); CmsBlog blog = new CmsBlog();
blog.setTitle("test title"); blog.setTitle("test title");
blog.setContent("test content"); blog.setContent("test content");
blog.setType(CmsBlogTypeEnum.FN1); blog.setType(FunctionTypeEnum.FN1);
blog.setCreateUserId(1L); blog.setCreateUserId(1L);
sqlManager.lambdaQuery(CmsBlog.class).insert(blog); sqlManager.lambdaQuery(CmsBlog.class).insert(blog);
} }
......
...@@ -10,6 +10,6 @@ public class CmsBlog { ...@@ -10,6 +10,6 @@ public class CmsBlog {
private String title; private String title;
private String content; private String content;
private Long createUserId; private Long createUserId;
private CmsBlogTypeEnum type; private FunctionTypeEnum type;
private Long createTime; private Long createTime;
} }
package entity; package entity;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.ibeetl.admin.core.util.enums.DictTypeEnum;
import org.beetl.sql.core.annotatoin.EnumMapping; import org.beetl.sql.core.annotatoin.EnumMapping;
@EnumMapping("value") @EnumMapping("value")
public enum CmsBlogTypeEnum { public enum FunctionTypeEnum implements DictTypeEnum<FunctionTypeEnum> {
FN0("FN0", "普通功能", "function_type"), FN0("FN0", "导航访问", "function_type"),
FN1("FN1", "含数据权限", "function_type"), FN1("FN1", "功能访问", "function_type"),
FN2("FN2", "菜单功能", "function_type"); FN2("FN2", "菜单访问", "function_type");
private String value; private String value;
private String name; private String name;
private String type; private String type;
CmsBlogTypeEnum(String value, String name, String type) { FunctionTypeEnum(String value, String name, String type) {
this.value = value; this.value = value;
this.name = name; this.name = name;
this.type = type; this.type = type;
} }
@JsonValue
public String getValue() { public String getValue() {
return value; return value;
} }
public void setValue(String value) { public void setValue(String value) {
this.value = value; this.value = value;
} }
public String getName() { public String getName() {
return name; return name;
} }
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
public String getType() { public String getType() {
return type; return type;
} }
public void setType(String type) { public void setType(String type) {
this.type = type; this.type = type;
} }
@JsonCreator
@Override
public FunctionTypeEnum findEnum(String value) {
FunctionTypeEnum[] values = values();
for (FunctionTypeEnum typeEnum : values) {
if (typeEnum.value.equals(value)) {
return typeEnum;
}
}
return null;
}
} }
...@@ -2,9 +2,11 @@ package com.ibeetl.admin.core.entity; ...@@ -2,9 +2,11 @@ package com.ibeetl.admin.core.entity;
import java.util.Date; import java.util.Date;
import java.util.List;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.Data;
import org.beetl.sql.core.annotatoin.AutoID; import org.beetl.sql.core.annotatoin.AutoID;
import org.beetl.sql.core.annotatoin.SeqID; import org.beetl.sql.core.annotatoin.SeqID;
import org.beetl.sql.core.annotatoin.UpdateIgnore; import org.beetl.sql.core.annotatoin.UpdateIgnore;
...@@ -13,6 +15,7 @@ import com.ibeetl.admin.core.annotation.Dict; ...@@ -13,6 +15,7 @@ import com.ibeetl.admin.core.annotation.Dict;
import com.ibeetl.admin.core.util.ValidateConfig; import com.ibeetl.admin.core.util.ValidateConfig;
import com.ibeetl.admin.core.util.enums.CoreDictType; import com.ibeetl.admin.core.util.enums.CoreDictType;
@Data
public class CoreFunction extends BaseEntity { public class CoreFunction extends BaseEntity {
@NotNull(message = "ID不能为空", groups = ValidateConfig.UPDATE.class) @NotNull(message = "ID不能为空", groups = ValidateConfig.UPDATE.class)
...@@ -20,74 +23,33 @@ public class CoreFunction extends BaseEntity { ...@@ -20,74 +23,33 @@ public class CoreFunction extends BaseEntity {
@AutoID @AutoID
protected Long id; protected Long id;
// 创建时间
@UpdateIgnore protected Date createTime;
private String accessUrl;
@NotBlank private String code;
@NotBlank private String name;
@NotBlank private Long parentId;
@Dict(type = CoreDictType.FUNCTION_TYPE)
@NotBlank @NotBlank
private String type = null; // "FN0" ; private String code;
public String getAccessUrl() {
return accessUrl;
}
public void setAccessUrl(String accessUrl) {
this.accessUrl = accessUrl;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() { @NotBlank
return createTime; private String name;
}
public void setCreateTime(Date createTime) { private String accessUrl;
this.createTime = createTime;
}
public Long getParentId() { private String component;
return parentId;
}
public void setParentId(Long parentId) { @NotBlank
this.parentId = parentId; private Long parentId;
}
public Long getId() { @UpdateIgnore
return id; private Date createTime;
}
public void setId(Long id) { private short delFlag;
this.id = id;
}
public String getType() { @Dict(type = CoreDictType.FUNCTION_TYPE)
return type; @NotBlank
} private String type;
public void setType(String type) { private List<CoreFunction> children;
this.type = type;
}
public boolean hasParent() { public boolean hasParent() {
return this.parentId != null && this.parentId > 0; return this.parentId != null && this.parentId > 0;
} }
} }
...@@ -20,77 +20,84 @@ import java.util.Objects; ...@@ -20,77 +20,84 @@ import java.util.Objects;
@Data @Data
public class CoreRoute extends BaseEntity implements Comparable<CoreRoute> { public class CoreRoute extends BaseEntity implements Comparable<CoreRoute> {
private Long id; private Long id;
private Long parentId; private Long parentId;
/** /**
* 路由路径,完全参照vue router规范 * 路由路径,完全参照vue router规范
*/ */
private String path; private String path;
/** /**
* 路由名称,请确保唯一性 * 路由名称,请确保唯一性
*/ */
private String name; private String name;
/** /**
* 路由组件component * 路由组件component
*/ */
private String component; private String component;
/** /**
* 路由顺序 * 路由顺序
*/ */
private Long seq = -999L; private Long seq = -999L;
/** /**
* 路由元数据信息 * 路由元数据信息
*/ */
private CoreRouteMeta meta; private CoreRouteMeta meta;
/**
* 子路由项
*/
private List<CoreRoute> children = CollUtil.newArrayList();
public CoreRouteMeta getMeta() {
if (ObjectUtil.isNotEmpty(this.meta)) {
return this.meta;
}
Map<String, Object> metaMap = MapUtil.builder(getTails()).build();
this.meta = BeanUtil.mapToBean(metaMap, CoreRouteMeta.class, true);
return this.meta;
}
@Override /**
public boolean equals(Object o) { * 子路由项
if (o != null && o instanceof CoreRoute) { */
CoreRoute othRoute = (CoreRoute) o; private List<CoreRoute> children = CollUtil.newArrayList();
if (this.getId().equals(othRoute.getId())) {
return true; public CoreRouteMeta getMeta() {
}
if (this.getParentId().equals(othRoute.getParentId())) { if (ObjectUtil.isNotEmpty(this.meta)) {
return StrUtil.equals(this.getPath(), othRoute.getPath()) return this.meta;
&& StrUtil.equals(this.getName(), othRoute.getName());
} else {
return false;
}
} else {
return false;
}
} }
Map<String, Object> metaMap = MapUtil.builder(getTails()).build();
this.meta = BeanUtil.mapToBean(metaMap, CoreRouteMeta.class, true);
return this.meta;
}
@Override @Override
public int hashCode() { public boolean equals(Object o) {
return Objects.hash(id, parentId, path, name);
if (o != null && o instanceof CoreRoute) {
CoreRoute othRoute = (CoreRoute) o;
if (this.getId().equals(othRoute.getId())) {
return true;
}
if (this.getParentId().equals(othRoute.getParentId())) {
return StrUtil.equals(this.getPath(), othRoute.getPath())
&& StrUtil.equals(this.getName(), othRoute.getName());
} else {
return false;
}
} else {
return false;
} }
}
@Override
public int hashCode() {
@Override return Objects.hash(id, parentId, path, name);
public int compareTo(CoreRoute o) { }
if (null == o) return -1;
Long seq1 = this.getSeq() == null ? -999L : this.getSeq(); @Override
Long seq2 = o.getSeq() == null ? -999L : o.getSeq(); public int compareTo(CoreRoute o) {
return seq1.compareTo(seq2);
if (null == o) {
return -1;
} }
Long seq1 = this.getSeq() == null ? -999L : this.getSeq();
Long seq2 = o.getSeq() == null ? -999L : o.getSeq();
return seq1.compareTo(seq2);
}
} }
package com.ibeetl.admin.core.util.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import org.beetl.sql.core.annotatoin.EnumMapping;
@EnumMapping("value")
public enum FunctionTypeEnum implements DictTypeEnum<FunctionTypeEnum> {
FN0("FN0", "导航访问", "function_type"),
FN1("FN1", "功能访问", "function_type"),
FN2("FN2", "菜单访问", "function_type");
private String value;
private String name;
private String type;
FunctionTypeEnum(String value, String name, String type) {
this.value = value;
this.name = name;
this.type = type;
}
@JsonValue
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@JsonCreator
@Override
public FunctionTypeEnum findEnum(String value) {
FunctionTypeEnum[] values = values();
for (FunctionTypeEnum typeEnum : values) {
if (typeEnum.value.equals(value)) {
return typeEnum;
}
}
return null;
}
}
...@@ -27,6 +27,7 @@ public enum StateTypeEnum implements DictTypeEnum<StateTypeEnum> { ...@@ -27,6 +27,7 @@ public enum StateTypeEnum implements DictTypeEnum<StateTypeEnum> {
this.name = name; this.name = name;
} }
@Override
@JsonValue @JsonValue
public String getValue() { public String getValue() {
return value; return value;
......
...@@ -13,7 +13,7 @@ select menu.id, ...@@ -13,7 +13,7 @@ select menu.id,
func.COMPONENT component, func.COMPONENT component,
role_menu.ROLE_ID role_menu.ROLE_ID
from core_menu menu from core_menu menu
left join core_function func on func.ID = menu.FUNCTION_ID left join core_function func on func.ID = menu.FUNCTION_ID and menu.DEL_FLAG=0
left join core_role_menu role_menu on role_menu.MENU_ID = menu.id left join core_role_menu role_menu on role_menu.MENU_ID = menu.id
``` ```
......
/*
* @Author: 一日看尽长安花
* @since: 2020-05-31 14:38:23
* @LastEditTime: 2020-05-31 14:45:16
* @LastEditors: 一日看尽长安花
* @Description:
*/
import request from '@/utils/request';
/**
* 用户管理页的数据
* @param {*} params
*/
export function funcs(params) {
return request({
url: '/functions',
method: 'get',
params
});
}
...@@ -91,6 +91,7 @@ export function handleComponent(routes) { ...@@ -91,6 +91,7 @@ export function handleComponent(routes) {
* component = () => import(`@/${_route.component}`); * component = () => import(`@/${_route.component}`);
*/ */
//这一步多余的赋值遍历必须存在,import的bug //这一步多余的赋值遍历必须存在,import的bug
//无法直接使用模板字符
const name = _route.component; const name = _route.component;
_route.component = () => import(`@/${name}`); _route.component = () => import(`@/${name}`);
} }
......
<!--
* @Author: 一日看尽长安花
* @since: 2020-05-30 12:53:38
* @LastEditTime: 2020-05-31 21:13:33
* @LastEditors: 一日看尽长安花
* @Description:
-->
<template>
<!-- vue实例外创建 -->
<div id="func-manager" class="sp-transfer_editor--two">
<div class="sp-side_panel--left">
<el-input v-model="filterText" placeholder="输入关键字进行过滤">
</el-input>
<el-tree
key="treeKey"
ref="tree"
:data="treeData"
node-key="id"
default-expand-all
:expand-on-click-node="false"
:filter-node-method="filterNode"
>
<template v-slot="{ node: node, data: data }">
<div :class="['sp-tree_node', 'sp-tree_node_type--' + data.type]">
<span>{{ data.name }}</span>
<span>
<el-button
plain
type="primary"
size="mini"
@click="appendNode(node, data)"
>
添加
</el-button>
<el-button
v-if="data.id !== -1"
plain
type="primary"
size="mini"
@click="editNode(node, data)"
>
编辑
</el-button>
<el-button
v-if="data.id !== -1"
plain
type="primary"
size="mini"
@click="removeNode(node, data)"
>
删除
</el-button>
</span>
</div>
</template>
</el-tree>
</div>
<div class="sp-side_panel--right">
<el-form key="formKey" ref="form" :model="formModel" label-width="80px">
<el-form-item label="功能名">
<el-input v-model="formModel.name"></el-input>
</el-form-item>
<el-form-item label="功能代码">
<el-input v-model="formModel.code"></el-input>
</el-form-item>
<el-form-item label="功能地址">
<el-input
v-model="formModel.access_url"
:disabled="actType === 'editor'"
></el-input>
</el-form-item>
<el-form-item label="父功能">
<el-input
v-model="formModel.parent.name"
readonly
@focus="openSelectParentNodeLayer"
></el-input>
</el-form-item>
<el-form-item label="功能类型">
<el-select v-model="formModel.type" placeholder="请选择功能类型">
<el-option label="导航访问" value="FN0"></el-option>
<el-option label="功能点访问" value="FN1"></el-option>
<el-option label="菜单访问" value="FN2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="actType === 'create' ? createNode : updateNode"
>保存</el-button
>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
<sel-func-dialog :visible.sync="dialogVisible" :tree-data="treeData">
</sel-func-dialog>
</div>
</template>
<script>
/** 功能点管理 */
import { funcs } from '@/api/func';
import SelFuncDialog from './select_dialog';
export default {
name: 'FunctionMange',
components: { SelFuncDialog },
props: {},
data() {
return {
filterText: '',
treeData: [],
formModel: {
parent: {
id: undefined,
name: undefined
}
},
actType: 'create',
dialogVisible: false
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
mounted() {
funcs().then(res => {
const { code, message, data } = { ...res };
const vmNode = [
{
id: -1,
name: '平台',
children: data
}
];
this.treeData = vmNode;
});
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
appendNode(node, data) {
this.formModel = {};
this.formModel.parent = data;
this.actType = 'create';
},
editNode(node, data) {
this.formModel = data;
this.formModel.parent = node.parent.data;
this.actType = 'editor';
},
removeNode(node, data) {},
createNode() {},
updateNode() {},
openSelectParentNodeLayer() {
console.log(Math.random());
this.dialogVisible = true;
}
}
};
</script>
<style lang="scss" scoped>
.sp-transfer_editor--two {
display: flex;
justify-content: space-between;
align-items: stretch;
margin: 10px;
min-height: 84vh;
max-height: 84vh;
}
%sp-side_panel--common {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
box-shadow: 2px 2px 6px 1px #aaa;
padding: 10px;
margin: 0 10px;
}
.sp-side_panel--left {
@extend %sp-side_panel--common;
overflow-y: scroll;
}
.sp-side_panel--right {
@extend %sp-side_panel--common;
}
.sp-tree_node {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding-left: 6px;
border-radius: 5px;
}
%sp-tree_node_type {
box-shadow: 1px 1px 1px 1px #e8f4ff;
}
.sp-tree_node_type--FN0 {
@extend %sp-tree_node_type;
background: linear-gradient(to right, #ff03035e, transparent);
}
.sp-tree_node_type--FN1 {
@extend %sp-tree_node_type;
background: linear-gradient(to right, #fff5035e, transparent);
}
.sp-tree_node_type--FN2 {
@extend %sp-tree_node_type;
background: linear-gradient(to right, #033cff5e, transparent);
}
</style>
<style lang="scss">
.el-tree-node {
margin-top: 5px;
}
</style>
<!--
* @Author: 一日看尽长安花
* @since: 2020-05-30 12:53:38
* @LastEditTime: 2020-05-31 21:28:18
* @LastEditors: 一日看尽长安花
* @Description:
-->
<template>
<el-dialog
id="sel-func-dialog"
title="功能点选择"
:visible="visible"
@update:visible="$emit('update:visible', $event)"
>
<el-input v-model="filterText" placeholder="输入关键字进行过滤"> </el-input>
<el-tree
:key="Math.random()"
ref="tree"
:data="treeData"
node-key="id"
:show-checkbox="true"
default-expand-all
:expand-on-click-node="false"
:filter-node-method="filterNode"
>
<template v-slot="{ node: node, data: data }">
<div :class="['sp-tree_node', 'sp-tree_node_type--' + data.type]">
<span>{{ data.name }}</span>
</div>
</template>
</el-tree>
<div slot="footer" class="dialog-footer">
<el-button
type="primary"
@click="dialogFormVisible = false"
>确 定</el-button
>
</div>
</el-dialog>
</template>
<script>
/** 功能点管理 */
import { funcs } from '@/api/func';
export default {
name: 'SelFuncDialog',
components: {},
props: {
visible: {
type: Boolean,
default: false
},
treeData: {
type: Array,
default: function() {
return [];
}
}
},
data() {
return {
filterText: ''
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
}
}
};
</script>
<style lang="scss" scoped>
.sp-tree_node {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding-left: 6px;
border-radius: 5px;
}
%sp-tree_node_type {
box-shadow: 1px 1px 1px 1px #e8f4ff;
}
.sp-tree_node_type--FN0 {
@extend %sp-tree_node_type;
background: linear-gradient(to right, #ff03035e, transparent);
}
.sp-tree_node_type--FN1 {
@extend %sp-tree_node_type;
background: linear-gradient(to right, #fff5035e, transparent);
}
.sp-tree_node_type--FN2 {
@extend %sp-tree_node_type;
background: linear-gradient(to right, #033cff5e, transparent);
}
</style>
<style lang="scss">
.el-tree-node {
margin-top: 5px;
}
</style>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment