diff --git a/Pinnacle/src/main/java/com/cfive/pinnacle/controller/GroupController.java b/Pinnacle/src/main/java/com/cfive/pinnacle/controller/GroupController.java
index 3a096d8..48cf758 100644
--- a/Pinnacle/src/main/java/com/cfive/pinnacle/controller/GroupController.java
+++ b/Pinnacle/src/main/java/com/cfive/pinnacle/controller/GroupController.java
@@ -1,7 +1,15 @@
package com.cfive.pinnacle.controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.cfive.pinnacle.entity.Group;
+import com.cfive.pinnacle.entity.common.ResponseCode;
+import com.cfive.pinnacle.entity.common.ResponseResult;
+import com.cfive.pinnacle.service.IGroupService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
/**
*
@@ -14,5 +22,51 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/group")
public class GroupController {
+ private IGroupService groupService;
+ @Autowired
+ public void setGroupService(IGroupService groupService) {
+ this.groupService = groupService;
+ }
+
+ @GetMapping
+ public ResponseResult getAllGroup() {
+ List groups = groupService.getAllGroup();
+ return ResponseResult.build(ResponseCode.DATABASE_SELECT_OK, "success", groups);
+ }
+
+ @PostMapping
+ public ResponseResult addGroup(@RequestBody Group group) {
+ if (!StringUtils.hasText(group.getName())) {
+ return ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "Name cannot be empty", null);
+ }
+ if (groupService.addGroup(group)) {
+ return ResponseResult.build(ResponseCode.DATABASE_SAVE_OK, "success", null);
+ } else {
+ return ResponseResult.build(ResponseCode.DATABASE_SAVE_ERROR, "error", null);
+ }
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseResult deleteGroup(@PathVariable Long id) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(Group::getId, id);
+ if (groupService.remove(wrapper)) {
+ return ResponseResult.build(ResponseCode.DATABASE_DELETE_OK, "success", null);
+ } else {
+ return ResponseResult.build(ResponseCode.DATABASE_DELETE_ERROR, "error", null);
+ }
+ }
+
+ @PutMapping
+ public ResponseResult modifyGroup(@RequestBody Group group) {
+ if (!StringUtils.hasText(group.getName())) {
+ return ResponseResult.build(ResponseCode.DATABASE_UPDATE_ERROR, "Name cannot be empty", null);
+ }
+ if (groupService.modifyGroup(group)) {
+ return ResponseResult.build(ResponseCode.DATABASE_UPDATE_OK, "success", null);
+ } else {
+ return ResponseResult.build(ResponseCode.DATABASE_UPDATE_ERROR, "error", null);
+ }
+ }
}
diff --git a/Pinnacle/src/main/java/com/cfive/pinnacle/entity/Group.java b/Pinnacle/src/main/java/com/cfive/pinnacle/entity/Group.java
index 1c64298..2b4ada3 100644
--- a/Pinnacle/src/main/java/com/cfive/pinnacle/entity/Group.java
+++ b/Pinnacle/src/main/java/com/cfive/pinnacle/entity/Group.java
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.Version;
import java.io.Serial;
import java.io.Serializable;
+import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -47,4 +48,7 @@ public class Group implements Serializable {
@TableField("version")
@Version
private Integer version;
+
+ @TableField(exist = false)
+ private List roles;
}
diff --git a/Pinnacle/src/main/java/com/cfive/pinnacle/mapper/GroupMapper.java b/Pinnacle/src/main/java/com/cfive/pinnacle/mapper/GroupMapper.java
index 0811e1c..938594c 100644
--- a/Pinnacle/src/main/java/com/cfive/pinnacle/mapper/GroupMapper.java
+++ b/Pinnacle/src/main/java/com/cfive/pinnacle/mapper/GroupMapper.java
@@ -3,6 +3,9 @@ package com.cfive.pinnacle.mapper;
import com.cfive.pinnacle.entity.Group;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
/**
*
@@ -14,5 +17,7 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface GroupMapper extends BaseMapper {
+ List getAll();
+ Group getOneById(@Param("id") long id);
}
diff --git a/Pinnacle/src/main/java/com/cfive/pinnacle/service/IGroupService.java b/Pinnacle/src/main/java/com/cfive/pinnacle/service/IGroupService.java
index 93f7e01..f4e47e3 100644
--- a/Pinnacle/src/main/java/com/cfive/pinnacle/service/IGroupService.java
+++ b/Pinnacle/src/main/java/com/cfive/pinnacle/service/IGroupService.java
@@ -3,6 +3,8 @@ package com.cfive.pinnacle.service;
import com.cfive.pinnacle.entity.Group;
import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
/**
*
* 用户组 服务类
@@ -12,5 +14,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @since 2023-04-30
*/
public interface IGroupService extends IService {
+ List getAllGroup();
+ Group getGroup(Long id);
+
+ boolean addGroup(Group group);
+
+ boolean modifyGroup(Group group);
}
diff --git a/Pinnacle/src/main/java/com/cfive/pinnacle/service/impl/GroupServiceImpl.java b/Pinnacle/src/main/java/com/cfive/pinnacle/service/impl/GroupServiceImpl.java
index 75a3cb5..7d16fdb 100644
--- a/Pinnacle/src/main/java/com/cfive/pinnacle/service/impl/GroupServiceImpl.java
+++ b/Pinnacle/src/main/java/com/cfive/pinnacle/service/impl/GroupServiceImpl.java
@@ -1,11 +1,18 @@
package com.cfive.pinnacle.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cfive.pinnacle.entity.Group;
+import com.cfive.pinnacle.entity.RoleGroup;
import com.cfive.pinnacle.mapper.GroupMapper;
+import com.cfive.pinnacle.mapper.RoleGroupMapper;
import com.cfive.pinnacle.service.IGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.util.HashSet;
+import java.util.List;
+
/**
*
* 用户组 服务实现类
@@ -16,5 +23,73 @@ import org.springframework.stereotype.Service;
*/
@Service
public class GroupServiceImpl extends ServiceImpl implements IGroupService {
+ private GroupMapper groupMapper;
+ private RoleGroupMapper roleGroupMapper;
+ @Autowired
+ public void setGroupMapper(GroupMapper groupMapper) {
+ this.groupMapper = groupMapper;
+ }
+
+ @Autowired
+ public void setRoleGroupMapper(RoleGroupMapper roleGroupMapper) {
+ this.roleGroupMapper = roleGroupMapper;
+ }
+
+ @Override
+ public List getAllGroup() {
+ return groupMapper.getAll();
+ }
+
+ @Override
+ public Group getGroup(Long id) {
+ return groupMapper.getOneById(id);
+ }
+
+ @Override
+ public boolean addGroup(Group group) {
+ if (groupMapper.insert(group) == 1) {
+ group.getRoles().forEach(role -> {
+ RoleGroup roleGroup = new RoleGroup();
+ roleGroup.setGroupId(group.getId());
+ roleGroup.setRoleId(role.getId());
+ if (roleGroupMapper.insert(roleGroup) != 1) {
+ throw new RuntimeException("Add role_group failure");
+ }
+ });
+ return true;
+ } else {
+ throw new RuntimeException("Add group failure");
+ }
+ }
+
+ @Override
+ public boolean modifyGroup(Group group) {
+ groupMapper.updateById(group);
+ Group originalGroup = getGroup(group.getId());
+ HashSet newRoleIds = new HashSet<>();
+ group.getRoles().forEach(role -> newRoleIds.add(role.getId()));
+ HashSet addRoleIds = new HashSet<>(newRoleIds);
+ if (originalGroup != null) {
+ HashSet originalRoleIds = new HashSet<>();
+ originalGroup.getRoles().forEach(role -> originalRoleIds.add(role.getId()));
+ HashSet deleteRoleIds = new HashSet<>(originalRoleIds);
+ deleteRoleIds.removeAll(newRoleIds);
+ addRoleIds.removeAll(originalRoleIds);
+ deleteRoleIds.forEach(deleteRoleId -> {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(RoleGroup::getGroupId, group.getId())
+ .eq(RoleGroup::getRoleId, deleteRoleId);
+ roleGroupMapper.delete(wrapper);
+ });
+ }
+ addRoleIds.forEach(addRoleId -> {
+ RoleGroup roleGroup = new RoleGroup();
+ roleGroup.setGroupId(group.getId());
+ roleGroup.setRoleId(addRoleId);
+ roleGroupMapper.insert(roleGroup);
+ });
+
+ return true;
+ }
}
diff --git a/Pinnacle/src/main/resources/mapper/GroupMapper.xml b/Pinnacle/src/main/resources/mapper/GroupMapper.xml
index d199bf2..de297e8 100644
--- a/Pinnacle/src/main/resources/mapper/GroupMapper.xml
+++ b/Pinnacle/src/main/resources/mapper/GroupMapper.xml
@@ -2,4 +2,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pinnacle/src/main/resources/mapper/RoleMapper.xml b/Pinnacle/src/main/resources/mapper/RoleMapper.xml
index fd967c7..b1545b4 100644
--- a/Pinnacle/src/main/resources/mapper/RoleMapper.xml
+++ b/Pinnacle/src/main/resources/mapper/RoleMapper.xml
@@ -3,32 +3,33 @@
diff --git a/sql/Insert.sql b/sql/Insert.sql
index 218baa6..4ebc8e2 100644
--- a/sql/Insert.sql
+++ b/sql/Insert.sql
@@ -95,6 +95,8 @@ VALUES (1656219345971326978, 1, 1655784840189972481),
(1656219345971326985, 8, 1655785102375940098),
(1656219345971326986, 9, 1655785102375940098);
+SET FOREIGN_KEY_CHECKS = 1;
+
select * from t_role
left join t_power_role tpr on t_role.id = tpr.role_id
left join t_power tp on tp.id = tpr.power_id
@@ -102,4 +104,6 @@ left join t_menu tm on tp.id = tm.power_id
left join t_element te on tp.id = te.power_id
left join t_operation t on tp.id = t.power_id;
-SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
+select * from t_group
+left join t_role_group trg on t_group.id = trg.group_id
+left join t_role tr on tr.id = trg.role_id
\ No newline at end of file
diff --git a/ui/src/assets/css/common.css b/ui/src/assets/css/common.css
index 4e266c1..9d68ead 100644
--- a/ui/src/assets/css/common.css
+++ b/ui/src/assets/css/common.css
@@ -115,4 +115,8 @@ body {
.el-popconfirm__action button:last-child {
margin-left: 0;
-}
\ No newline at end of file
+}
+
+.el-table__cell .el-tag:not(:first-child) {
+ margin-left: 5px;
+}
diff --git a/ui/src/components/power/CommonTable.vue b/ui/src/components/power/CommonTable.vue
new file mode 100644
index 0000000..5f9ccfa
--- /dev/null
+++ b/ui/src/components/power/CommonTable.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+ 无
+ {{
+ column
+ }}
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
diff --git a/ui/src/pages/power/GroupManagement.vue b/ui/src/pages/power/GroupManagement.vue
new file mode 100644
index 0000000..ca43691
--- /dev/null
+++ b/ui/src/pages/power/GroupManagement.vue
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+ 取消
+
+
+
+
+
+
+
diff --git a/ui/src/pages/power/RoleManagement.vue b/ui/src/pages/power/RoleManagement.vue
index 8ef92e1..b833f2b 100644
--- a/ui/src/pages/power/RoleManagement.vue
+++ b/ui/src/pages/power/RoleManagement.vue
@@ -14,32 +14,13 @@
添加
-
-
-
-
-
-
- 无
- {{ power }}
-
-
-
-
- 编辑
-
- 删除
-
-
-
-
+
+ />
+
@@ -129,7 +111,7 @@ export default {
if (response.code === DATABASE_SELECT_OK) {
const roles = response.data
for (const role of roles) {
- role.powers = []
+ role.customColumn = []
const menus = role.menus
const elements = role.elements
const operations = role.operations
@@ -151,7 +133,9 @@ export default {
_.forEach(element.operations, (value) => {
operas.push(value.name)
})
- role.powers.push(`${menu.name}/${element.name}/${_.join(operas, ';')}`)
+ role.customColumn.push(
+ `${menu.name}/${element.name}/${_.join(operas, ';')}`
+ )
}
}
this.roleTable = roles
@@ -264,9 +248,9 @@ export default {
if (valid) {
this.dialogLoading = true
const roleObject = {
+ id: '',
name: this.roleForm.inputRoleName,
- powers: [],
- id: ''
+ powers: []
}
for (const powerId of this.roleForm.selectedPower) {
const power = {
diff --git a/ui/src/router/index.ts b/ui/src/router/index.ts
index 441e874..b7ce8f4 100644
--- a/ui/src/router/index.ts
+++ b/ui/src/router/index.ts
@@ -186,13 +186,24 @@ const router = createRouter({
children: [
{
path: 'role',
- name: 'systemRole',
+ name: 'roleManagement',
component: async () => await import('@/pages/power/RoleManagement.vue'),
meta: {
title: '角色管理',
requiresScrollbar: false,
requiresPadding: true
}
+ },
+ {
+ path: 'group',
+ name: 'groupManagement',
+ component: async () =>
+ await import('@/pages/power/GroupManagement.vue'),
+ meta: {
+ title: '用户组管理',
+ requiresScrollbar: false,
+ requiresPadding: true
+ }
}
],
meta: {