This commit is contained in:
闵炳辉 2024-06-26 18:04:44 +08:00
commit 65cb66de2d
25 changed files with 613 additions and 174 deletions

View File

@ -0,0 +1,8 @@
package com.das.common.config;
/**
* Session 变量定义
*/
public class SessionUtil {
public static final String SESSION_USER_KEY = "current_user";
}

View File

@ -0,0 +1,43 @@
package com.das.common.config;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.stereotype.Component;
import com.das.modules.auth.domain.vo.SysUserVo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* 自定义权限验证接口扩展
*/
@Component // 保证此类被springboot扫描完成sa-token的自定义权限验证扩展
public class StpInterfaceImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String s) {
SysUserVo currentUser = (SysUserVo) StpUtil.getTokenSession().get(SessionUtil.SESSION_USER_KEY);
if(currentUser==null){
return Collections.emptyList();
}else{
List<String> list = new ArrayList<>();
currentUser.getAuthorities().forEach(item->{
list.add(item.toString());
});
return list;
}
}
/**
* 权限判断这块 全部采用权限Permission 判断不采用角色Role判断
* @param loginId
* @param s
* @return
*/
@Override
public List<String> getRoleList(Object loginId, String s) {
return Collections.emptyList();
}
}

View File

@ -1,15 +1,21 @@
package com.das.modules.auth.controller; package com.das.modules.auth.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.das.common.config.SessionUtil;
import com.das.common.config.SysAuthorityIds;
import com.das.common.result.R; import com.das.common.result.R;
import com.das.common.utils.PageDataInfo; import com.das.common.utils.PageDataInfo;
import com.das.common.utils.PageQuery; import com.das.common.utils.PageQuery;
import com.das.modules.auth.domain.dto.DeleteDto; import com.das.modules.auth.domain.dto.DeleteDto;
import com.das.modules.auth.domain.dto.SysMenuDto; import com.das.modules.auth.domain.dto.SysMenuDto;
import com.das.modules.auth.domain.dto.SysMenuQueryDto; import com.das.modules.auth.domain.dto.SysMenuQueryDto;
import com.das.modules.auth.domain.vo.SysUserVo;
import com.das.modules.auth.entity.SysMenu; import com.das.modules.auth.entity.SysMenu;
import com.das.modules.auth.service.SysMenuService; import com.das.modules.auth.service.SysMenuService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -32,6 +38,12 @@ public class SysMenusController {
*/ */
@PostMapping("/add") @PostMapping("/add")
public R<?> createMenu(@RequestBody SysMenuDto sysMenuDto) { public R<?> createMenu(@RequestBody SysMenuDto sysMenuDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
return R.success(sysMenuService.createMenu(sysMenuDto)); return R.success(sysMenuService.createMenu(sysMenuDto));
} }
@ -41,6 +53,12 @@ public class SysMenusController {
*/ */
@PostMapping("/update") @PostMapping("/update")
public R<?> updateMenu(@RequestBody SysMenuDto sysMenuDto) { public R<?> updateMenu(@RequestBody SysMenuDto sysMenuDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysMenuService.updateMenu(sysMenuDto); sysMenuService.updateMenu(sysMenuDto);
return R.success(); return R.success();
} }
@ -51,6 +69,12 @@ public class SysMenusController {
*/ */
@PostMapping("/delete") @PostMapping("/delete")
public R<?> deleteMenu(@RequestBody DeleteDto deleteDto) { public R<?> deleteMenu(@RequestBody DeleteDto deleteDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysMenuService.deleteMenu(deleteDto); sysMenuService.deleteMenu(deleteDto);
return R.success(); return R.success();
} }

View File

@ -1,5 +1,7 @@
package com.das.modules.auth.controller; package com.das.modules.auth.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.das.common.config.SysAuthorityIds;
import com.das.common.result.R; import com.das.common.result.R;
import com.das.common.utils.PageDataInfo; import com.das.common.utils.PageDataInfo;
import com.das.common.utils.PageQuery; import com.das.common.utils.PageQuery;
@ -32,6 +34,12 @@ public class SysOrgController {
*/ */
@PostMapping("/add") @PostMapping("/add")
public R<?> createOrg(@RequestBody SysOrgDto sysOrgDto) { public R<?> createOrg(@RequestBody SysOrgDto sysOrgDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
return R.success(sysOrgService.createOrg(sysOrgDto)); return R.success(sysOrgService.createOrg(sysOrgDto));
} }
@ -41,6 +49,12 @@ public class SysOrgController {
*/ */
@PostMapping("/update") @PostMapping("/update")
public R<?> updateOrg(@RequestBody SysOrgDto sysOrgDto) { public R<?> updateOrg(@RequestBody SysOrgDto sysOrgDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysOrgService.updateOrg(sysOrgDto); sysOrgService.updateOrg(sysOrgDto);
return R.success(); return R.success();
} }
@ -51,6 +65,12 @@ public class SysOrgController {
*/ */
@PostMapping("/delete") @PostMapping("/delete")
public R<?> deleteOrg(@RequestBody DeleteDto deleteDto) { public R<?> deleteOrg(@RequestBody DeleteDto deleteDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysOrgService.deleteOrg(deleteDto); sysOrgService.deleteOrg(deleteDto);
return R.success(); return R.success();
} }

View File

@ -1,5 +1,7 @@
package com.das.modules.auth.controller; package com.das.modules.auth.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.das.common.config.SysAuthorityIds;
import com.das.common.result.R; import com.das.common.result.R;
import com.das.common.utils.PageDataInfo; import com.das.common.utils.PageDataInfo;
import com.das.common.utils.PageQuery; import com.das.common.utils.PageQuery;
@ -32,6 +34,12 @@ public class SysRoleController {
*/ */
@PostMapping("/add") @PostMapping("/add")
public R<?> createRole(@RequestBody SysRoleDto sysRoleDto) { public R<?> createRole(@RequestBody SysRoleDto sysRoleDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
return R.success(sysRoleService.createRole(sysRoleDto)); return R.success(sysRoleService.createRole(sysRoleDto));
} }
@ -41,6 +49,12 @@ public class SysRoleController {
*/ */
@PostMapping("/update") @PostMapping("/update")
public R<?> updateRole(@RequestBody SysRoleDto sysRoleDto) { public R<?> updateRole(@RequestBody SysRoleDto sysRoleDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
return R.success(sysRoleService.updateRole(sysRoleDto)); return R.success(sysRoleService.updateRole(sysRoleDto));
} }
@ -50,6 +64,12 @@ public class SysRoleController {
*/ */
@PostMapping("/delete") @PostMapping("/delete")
public R<?> deleteRole(@RequestBody DeleteDto deleteDto) { public R<?> deleteRole(@RequestBody DeleteDto deleteDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysRoleService.deleteRole(deleteDto); sysRoleService.deleteRole(deleteDto);
return R.success(); return R.success();
} }

View File

@ -1,5 +1,7 @@
package com.das.modules.auth.controller; package com.das.modules.auth.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.das.common.config.SysAuthorityIds;
import com.das.common.result.R; import com.das.common.result.R;
import com.das.common.utils.PageDataInfo; import com.das.common.utils.PageDataInfo;
import com.das.common.utils.PageQuery; import com.das.common.utils.PageQuery;
@ -33,6 +35,12 @@ public class SysUserController {
*/ */
@PostMapping("/add") @PostMapping("/add")
public R<?> createUser(@RequestBody SysUserDto sysUserDto) { public R<?> createUser(@RequestBody SysUserDto sysUserDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
return R.success(sysUserService.createUser(sysUserDto)); return R.success(sysUserService.createUser(sysUserDto));
} }
@ -42,6 +50,12 @@ public class SysUserController {
*/ */
@PostMapping("/update") @PostMapping("/update")
public R<?> updateUser(@RequestBody SysUserDto sysUserDto) { public R<?> updateUser(@RequestBody SysUserDto sysUserDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysUserService.updateUser(sysUserDto); sysUserService.updateUser(sysUserDto);
return R.success(); return R.success();
} }
@ -52,6 +66,12 @@ public class SysUserController {
*/ */
@PostMapping("/delete") @PostMapping("/delete")
public R<?> deleteUser(@RequestBody DeleteDto deleteDto) { public R<?> deleteUser(@RequestBody DeleteDto deleteDto) {
//判断是否有权限
// boolean hasPermission = StpUtil.hasPermission(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN.toString());
// if(!hasPermission){
// return R.fail("没有系统管理权限");
// }
sysUserService.deleteUser(deleteDto); sysUserService.deleteUser(deleteDto);
return R.success(); return R.success();
} }

View File

@ -1,7 +1,10 @@
package com.das.modules.auth.domain.dto; package com.das.modules.auth.domain.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -11,6 +14,7 @@ public class SysUserDto implements Serializable {
/** /**
* 角色ID * 角色ID
*/ */
@JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
/** /**
* 账号 * 账号

View File

@ -1,5 +1,7 @@
package com.das.modules.auth.domain.vo; package com.das.modules.auth.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.io.Serial; import java.io.Serial;
@ -13,6 +15,7 @@ public class SysMenuVo implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 菜单ID */ /** 菜单ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id ; private Long id ;
/** 菜单名称 */ /** 菜单名称 */
private String menuName ; private String menuName ;

View File

@ -0,0 +1,39 @@
package com.das.modules.auth.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class SysOrgVo implements Serializable {
/** 机构id */
@JsonSerialize(using = ToStringSerializer.class)
private Long id ;
/** 机构名称 */
private String name ;
/** 机构编码 */
private String mrid ;
/** 省份 */
private String province ;
/** 城市 */
private String city ;
/** 区县 */
private String county ;
/** 具体地址 */
private String address ;
/** 联系电话 */
private String contactPhone ;
/** 备注 */
private String remarks ;
/** 机构简称 */
private String aliasName;
/** 上级组织机构id */
private Long parentOrgId ;
private String parentOrgName ;
/** 乐观锁 */
private Integer revision ;
}

View File

@ -1,5 +1,7 @@
package com.das.modules.auth.domain.vo; package com.das.modules.auth.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.io.Serial; import java.io.Serial;
@ -17,6 +19,7 @@ public class SysRoleAuthVo implements Serializable {
/** /**
* 账号ID * 账号ID
*/ */
@JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
/** /**

View File

@ -2,6 +2,8 @@ package com.das.modules.auth.domain.vo;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.Version; import com.baomidou.mybatisplus.annotation.Version;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.io.Serial; import java.io.Serial;
@ -20,6 +22,7 @@ public class SysRoleVo implements Serializable {
/** /**
* 账号ID * 账号ID
*/ */
@JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
/** /**

View File

@ -1,5 +1,7 @@
package com.das.modules.auth.domain.vo; package com.das.modules.auth.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.io.Serial; import java.io.Serial;
@ -17,6 +19,7 @@ public class SysUserRoleVo implements Serializable {
/** /**
* 账号ID * 账号ID
*/ */
@JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
/** /**

View File

@ -1,9 +1,12 @@
package com.das.modules.auth.domain.vo; package com.das.modules.auth.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data; import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -18,6 +21,7 @@ public class SysUserVo implements Serializable {
/** /**
* 账号ID * 账号ID
*/ */
@JsonSerialize(using = ToStringSerializer.class)
private Long id; private Long id;
/** /**
@ -50,6 +54,7 @@ public class SysUserVo implements Serializable {
/** /**
* 所属机构 * 所属机构
*/ */
@JsonSerialize(using = ToStringSerializer.class)
private Long orgId; private Long orgId;
/** /**
@ -57,5 +62,8 @@ public class SysUserVo implements Serializable {
*/ */
private List<SysUserRoleVo> roleList; private List<SysUserRoleVo> roleList;
/**
*权限列表
*/
private List<Integer> authorities=new ArrayList<>();
} }

View File

@ -7,6 +7,8 @@ import com.das.modules.auth.entity.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* <p> * <p>
* 用户信息 Mapper 接口 * 用户信息 Mapper 接口
@ -26,4 +28,10 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
IPage<SysUserVo> queryUserList(IPage<SysUserVo> page, @Param("sysUser") SysUserQueryDto sysUserQueryDto); IPage<SysUserVo> queryUserList(IPage<SysUserVo> page, @Param("sysUser") SysUserQueryDto sysUserQueryDto);
long existUserByUserName(@Param("userName") String userName); long existUserByUserName(@Param("userName") String userName);
/**
* 根据用户id查询权限列表
* @param userId 用户id
* @return 该用户拥有的权限id列表
*/
List<Integer> queryAuthoritiesByUserId(@Param("userId") Long userId);
} }

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.das.common.captcha.CaptchaUtils; import com.das.common.captcha.CaptchaUtils;
import com.das.common.config.SaTokenProperties; import com.das.common.config.SaTokenProperties;
import com.das.common.config.SessionUtil;
import com.das.common.utils.AdminRedisTemplate; import com.das.common.utils.AdminRedisTemplate;
import com.das.modules.auth.domain.vo.LoginUserDetailsVo; import com.das.modules.auth.domain.vo.LoginUserDetailsVo;
import com.das.modules.auth.domain.dto.LoginDto; import com.das.modules.auth.domain.dto.LoginDto;
@ -75,10 +76,18 @@ public class LoginServiceImpl implements LoginService {
sysUserVo.setEmail(sysUser.getEmail()); sysUserVo.setEmail(sysUser.getEmail());
sysUserVo.setOrgId(sysUser.getOrgId()); sysUserVo.setOrgId(sysUser.getOrgId());
//查询用户权限列表
sysUserVo.setAuthorities(sysUserMapper.queryAuthoritiesByUserId(sysUser.getId()));
loginInfo.setSysUser(sysUserVo); // 存储用户信息到会话 loginInfo.setSysUser(sysUserVo); // 存储用户信息到会话
loginInfo.setToken(token); loginInfo.setToken(token);
loginInfo.setRefreshToken(refreshTokenUuid); loginInfo.setRefreshToken(refreshTokenUuid);
adminRedisTemplate.setEx(refreshToken, loginInfo, Duration.ofSeconds(saTokenProperties.getRefreshExpireTime())); adminRedisTemplate.setEx(refreshToken, loginInfo, Duration.ofSeconds(saTokenProperties.getRefreshExpireTime()));
//将登录用户信息存入 Session
StpUtil.getTokenSession().set(SessionUtil.SESSION_USER_KEY, sysUserVo);
return loginInfo; return loginInfo;
} }

View File

@ -30,9 +30,9 @@ public class SysAuthorityServiceImpl implements SysAuthorityService {
@PostConstruct @PostConstruct
public void init() { public void init() {
List<SysAuthority> list = new ArrayList<>(); List<SysAuthority> list = new ArrayList<>();
list.add(new SysAuthority(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN,"systemMgr","系统管理权限",1)); list.add(new SysAuthority(SysAuthorityIds.SYS_AUTHORITY_ID_ADMIN,"SYS_AUTHORITY_ID_ADMIN","系统管理权限",1));
list.add(new SysAuthority(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_MGR,"equipmentLedgerManagement","设备台账维护权限",1)); list.add(new SysAuthority(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_MGR,"SYS_AUTHORITY_ID_DEVICE_MGR","设备台账维护权限",1));
list.add(new SysAuthority(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_VIEW,"equipmentLedgerView","设备台账浏览权限",1)); list.add(new SysAuthority(SysAuthorityIds.SYS_AUTHORITY_ID_DEVICE_VIEW,"SYS_AUTHORITY_ID_DEVICE_VIEW","设备台账浏览权限",1));
try { try {
// 性能优化先查询所有需要的权限是否存在减少数据库访问次数 // 性能优化先查询所有需要的权限是否存在减少数据库访问次数

View File

@ -2,7 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.das.modules.auth.mapper.SysOrgMapper"> <mapper namespace="com.das.modules.auth.mapper.SysOrgMapper">
<resultMap type="com.das.modules.auth.entity.SysOrg" id="SysOrgMap"> <resultMap type="com.das.modules.auth.domain.vo.SysOrgVo" id="SysOrgMap">
<result property="id" column="id" jdbcType="BIGINT"/> <result property="id" column="id" jdbcType="BIGINT"/>
<result property="name" column="name" jdbcType="VARCHAR"/> <result property="name" column="name" jdbcType="VARCHAR"/>
<result property="mrid" column="mrid" jdbcType="VARCHAR"/> <result property="mrid" column="mrid" jdbcType="VARCHAR"/>
@ -13,42 +13,41 @@
<result property="contactPhone" column="contact_phone" jdbcType="VARCHAR"/> <result property="contactPhone" column="contact_phone" jdbcType="VARCHAR"/>
<result property="remarks" column="remarks" jdbcType="VARCHAR"/> <result property="remarks" column="remarks" jdbcType="VARCHAR"/>
<result property="parentOrgId" column="parent_org_id" jdbcType="VARCHAR"/> <result property="parentOrgId" column="parent_org_id" jdbcType="VARCHAR"/>
<result property="parentOrgName" column="parentOrgName" jdbcType="VARCHAR"/>
<result property="revision" column="revision" jdbcType="VARCHAR"/> <result property="revision" column="revision" jdbcType="VARCHAR"/>
<result property="createdBy" column="created_by" jdbcType="VARCHAR"/>
<result property="createdTime" column="created_time" jdbcType="VARCHAR"/>
<result property="updatedBy" column="updated_by" jdbcType="VARCHAR"/>
<result property="updatedTime" column="updated_time" jdbcType="VARCHAR"/>
</resultMap> </resultMap>
<select id="queryOrgList" resultMap="SysOrgMap"> <select id="queryOrgList" resultMap="SysOrgMap">
select * from sys_org select t.*, p.name as parentOrgName from sys_org t left join sys_org p on p.id = t.parent_org_id
<where> <where>
<if test="sysOrg.name != null and sysOrg.name != ''"> <if test="sysOrg.name != null and sysOrg.name != ''">
and name like concat('%',#{sysOrg.name},'%') and t.name like concat('%',#{sysOrg.name},'%')
</if> </if>
<if test="sysOrg.province != null and sysOrg.province != ''"> <if test="sysOrg.province != null and sysOrg.province != ''">
and province like concat('%',#{sysOrg.province},'%') and t.province like concat('%',#{sysOrg.province},'%')
</if> </if>
<if test="sysOrg.city != null and sysOrg.city != ''"> <if test="sysOrg.city != null and sysOrg.city != ''">
and city like concat('%',#{sysOrg.city},'%') and t.city like concat('%',#{sysOrg.city},'%')
</if> </if>
<if test="sysOrg.county != null and sysOrg.county != ''"> <if test="sysOrg.county != null and sysOrg.county != ''">
and county like concat('%',#{sysOrg.county},'%') and t.county like concat('%',#{sysOrg.county},'%')
</if> </if>
<if test="sysOrg.parentOrgId != null and sysOrg.parentOrgId != ''"> <if test="sysOrg.parentOrgId != null and sysOrg.parentOrgId != ''">
and parent_org_id = #{sysOrg.parentOrgId} and t.parent_org_id = #{sysOrg.parentOrgId}
</if> </if>
</where> </where>
</select> </select>
<select id="queryAllOrgTree" resultMap="SysOrgMap"> <select id="queryAllOrgTree" resultMap="SysOrgMap">
SELECT i.* FROM sys_org i WHERE i.id = #{id} select t.*, p.name as parentOrgName from sys_org t left join sys_org p on p.id = t.parent_org_id
WHERE t.id = #{id}
</select> </select>
<select id="queryAllChildOrgTree" resultMap="SysOrgMap"> <select id="queryAllChildOrgTree" resultMap="SysOrgMap">
SELECT i.* FROM sys_org i WHERE i.parent_org_id = #{id} select t.*, p.name as parentOrgName from sys_org t left join sys_org p on p.id = t.parent_org_id
WHERE t.parent_org_id = #{id}
</select> </select>
</mapper> </mapper>

View File

@ -64,4 +64,24 @@
</where> </where>
</select> </select>
<select id="queryAuthoritiesByUserId" resultType="java.lang.Integer" parameterType="java.lang.Long">
select
t2.id
from
sys_authority t2
where
t2.id in(
select
t1.authority_id
from
sys_r_role_authority t1
where
t1.role_id in(
select
t.role_id
from
sys_r_user_role t
where
t.user_id = #{userId}))
</select>
</mapper> </mapper>

View File

@ -316,6 +316,36 @@ const menu = [
}, },
], ],
}, },
{
id: 99,
pid: 98,
type: 'menu',
title: '角色管理',
name: 'auth\/RoleManagement',
path: 'auth\/RoleManagement',
icon: 'fa fa-group',
menu_type: 'tab',
url: '',
component: '\/src\/views\/backend\/RoleManagement\/RoleManagement.vue',
keepalive: 'auth\/RoleManagement',
extend: 'none',
children: [],
},
{
id: 97,
pid: 96,
type: 'menu',
title: '机构管理',
name: 'auth\/InstitutionalManagement',
path: 'auth\/InstitutionalManagement',
icon: 'fa fa-group',
menu_type: 'tab',
url: '',
component: '\/src\/views\/backend\/InstitutionalManagement\/InstitutionalManagement.vue',
keepalive: 'auth\/InstitutionalManagement',
extend: 'none',
children: [],
},
], ],
}, },
] ]

View File

@ -1,6 +1,6 @@
<template> <template>
<el-main class="layout-main"> <el-main class="layout-main">
<el-scrollbar class="layout-main-scrollbar" :style="layoutMainScrollbarStyle" ref="layoutMainScrollbarRef"> <el-scrollbar view-class="layout-main-scrollbar" :view-style="layoutMainScrollbarStyle" ref="layoutMainScrollbarRef">
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition :name="config.layout.mainAnimation" mode="out-in"> <transition :name="config.layout.mainAnimation" mode="out-in">
<keep-alive :include="state.keepAliveComponentNameList"> <keep-alive :include="state.keepAliveComponentNameList">

View File

@ -27,6 +27,16 @@
<el-select v-if="item.prop === 'city'" v-model="formModel[item.prop]" :placeholder="item.placeholder"> <el-select v-if="item.prop === 'city'" v-model="formModel[item.prop]" :placeholder="item.placeholder">
<el-option v-for="opt in cityOptions" :key="opt.value" :label="opt.label" :value="opt.value"></el-option> <el-option v-for="opt in cityOptions" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
</el-select> </el-select>
<el-tree-select
v-if="item.prop === 'parentOrgId'"
v-model="formModel[item.prop]"
:data="treeData"
lazy
:load="loadSelectTreeData"
check-strictly
:props="treeSelectReplaceProps"
:placeholder="item.placeholder"
></el-tree-select>
</template> </template>
</el-form-item> </el-form-item>
</template> </template>
@ -36,25 +46,34 @@
<el-button @click="closeAddForm">关闭</el-button> <el-button @click="closeAddForm">关闭</el-button>
</template> </template>
</el-dialog> </el-dialog>
<el-container> <el-container class="defaultContainer">
<el-aside class="defaultAside"> <el-aside class="defaultAside">
<el-header class="treeHeader"> <el-header class="treeHeader">
<el-input v-model="searchInputTreeValue" :placeholder="treeSearchInputPlaceholder" class="searchInput"></el-input> <el-input v-model="searchInputTreeValue" :placeholder="treeSearchInputPlaceholder" class="searchInput"></el-input>
</el-header> </el-header>
<el-main class="treeMain"> <el-main class="treeMain">
<el-tree :data="treeData" lazy node-key="id" :load="loadTreeData" :props="treeReplaceProps" @node-click="treeNodeClick"></el-tree> <el-tree
class="treePart"
ref="treeRef"
:data="treeData"
lazy
:load="loadTreeData"
node-key="id"
:props="treeReplaceProps"
@node-click="treeNodeClick"
></el-tree>
</el-main> </el-main>
</el-aside> </el-aside>
<el-container> <el-container class="defaultMainContainer">
<el-header class="defaultHeader"> <el-header class="defaultHeader">
<div class="searchPart"> <div class="searchPart">
<el-input v-model:value="searchTableInput" class="searchInput"></el-input> <el-input v-model="searchTableInput" class="searchInput"></el-input>
<el-button @click="searchTable" type="primary" :icon="Search" class="defaultBtn">{{ t('management.search') }}</el-button> <el-button @click="searchTable" type="primary" :icon="Search" class="defaultBtn">{{ t('management.search') }}</el-button>
</div> </div>
<el-button type="primary" :icon="Plus" class="defaultBtn" @click="addInstitutional">{{ t('management.add') }}</el-button> <el-button type="primary" :icon="Plus" class="defaultBtn" @click="addInstitutional">{{ t('management.add') }}</el-button>
</el-header> </el-header>
<el-main class="defaultMain"> <el-main class="defaultMain">
<el-table :data="tableData"> <el-table :data="tableData" class="tablePart">
<el-table-column <el-table-column
v-for="item in tableColumn" v-for="item in tableColumn"
:key="item.key" :key="item.key"
@ -77,6 +96,15 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="currentPageSize"
:total="pageTotal"
:page-sizes="pagePagination"
background
:pager-count="7"
layout="prev, pager, next, jumper,sizes,total"
></el-pagination>
</el-main> </el-main>
</el-container> </el-container>
</el-container> </el-container>
@ -84,7 +112,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue' import { onMounted, ref, computed } from 'vue'
import { import {
ElContainer, ElContainer,
ElAside, ElAside,
@ -101,8 +129,9 @@ import {
ElOption, ElOption,
ElPopconfirm, ElPopconfirm,
ElMessage, ElMessage,
ElPagination,
} from 'element-plus' } from 'element-plus'
import type { FormInstance } from 'element-plus' import type { FormInstance, TreeInstance } from 'element-plus'
import type Node from 'element-plus/es/components/tree/src/model/node' import type Node from 'element-plus/es/components/tree/src/model/node'
import { Plus, Search } from '@element-plus/icons-vue' import { Plus, Search } from '@element-plus/icons-vue'
import { import {
@ -113,6 +142,7 @@ import {
getInstitutionalTreeListReq, getInstitutionalTreeListReq,
} from './request' } from './request'
import { import {
getDataType,
addDataEnum, addDataEnum,
addDataType, addDataType,
formItemListType, formItemListType,
@ -121,6 +151,7 @@ import {
changeDataType, changeDataType,
selectDataType, selectDataType,
getTreeDataReturnType, getTreeDataReturnType,
allEnumType,
} from './type' } from './type'
import { pcaTextArr } from 'element-china-area-data' import { pcaTextArr } from 'element-china-area-data'
import { useAdminInfo } from '/@/stores/adminInfo' import { useAdminInfo } from '/@/stores/adminInfo'
@ -131,7 +162,8 @@ const treeSearchInputPlaceholder = '搜索机构'
const searchInputTreeValue = ref<string>('') const searchInputTreeValue = ref<string>('')
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const formModel = ref<addDataType | changeDataType>({
const defaultFormModel = {
mrid: '', mrid: '',
name: '', name: '',
aliasName: '', aliasName: '',
@ -143,8 +175,10 @@ const formModel = ref<addDataType | changeDataType>({
remarks: '', remarks: '',
parentOrgId: null, parentOrgId: null,
revision: 1, revision: 1,
}) }
const defaultFormModel = JSON.parse(JSON.stringify(formModel.value))
const formModel = ref<addDataType | changeDataType>(JSON.parse(JSON.stringify(defaultFormModel)))
const provinceOptions: selectDataType[] = pcaTextArr const provinceOptions: selectDataType[] = pcaTextArr
const countyOptions = ref<selectDataType[]>([]) const countyOptions = ref<selectDataType[]>([])
const cityOptions = ref<selectDataType[]>([]) const cityOptions = ref<selectDataType[]>([])
@ -229,7 +263,7 @@ const addFormItemList: formItemListType<addDataEnumKeyJointType>[] = [
rules: [{ required: true, validator: phoneRule, trigger: 'blur' }], rules: [{ required: true, validator: phoneRule, trigger: 'blur' }],
}, },
{ {
type: 'input', type: 'custom',
prop: 'parentOrgId', prop: 'parentOrgId',
label: addDataEnum['parentOrgId'], label: addDataEnum['parentOrgId'],
placeholder: `请选择${addDataEnum['parentOrgId']}`, placeholder: `请选择${addDataEnum['parentOrgId']}`,
@ -247,8 +281,10 @@ const dialogTitle = ref('新增机构')
const dialogVible = ref(false) const dialogVible = ref(false)
const addInstitutional = () => { const addInstitutional = () => {
dialogTitle.value = '新增机构' dialogTitle.value = '新增机构'
formRef.value && formRef.value.resetFields()
formModel.value = defaultFormModel formModel.value = defaultFormModel
formRef.value && formRef.value.clearValidate(Object.keys(defaultFormModel))
console.log(defaultFormModel, 'defaultFormModel')
dialogVible.value = true dialogVible.value = true
} }
@ -263,6 +299,7 @@ const submitAddForm = () => {
ElMessage.success('新增成功') ElMessage.success('新增成功')
getInstitutionList() getInstitutionList()
dialogVible.value = false dialogVible.value = false
refreshTreeData()
} }
}) })
} else if (dialogTitle.value === '编辑机构') { } else if (dialogTitle.value === '编辑机构') {
@ -271,6 +308,7 @@ const submitAddForm = () => {
ElMessage.success('编辑成功') ElMessage.success('编辑成功')
getInstitutionList() getInstitutionList()
dialogVible.value = false dialogVible.value = false
refreshTreeData()
} else { } else {
ElMessage.error('编辑失败') ElMessage.error('编辑失败')
} }
@ -283,18 +321,25 @@ const closeAddForm = () => {
dialogVible.value = false dialogVible.value = false
} }
const getInstitutionList = () => { const getInstitutionList = (data: getDataType = { name: null }) => {
getInstitutionalListReq({ getInstitutionalListReq(data).then((res) => {
name: null,
}).then((res) => {
console.log(res) console.log(res)
pageTotal.value = res.total
tableData.value = res.rows originData.value = res.rows
}) })
} }
const tableData = ref<getTreeDataReturnType[]>() const pagePagination = [5, 10, 20, 30]
const tableColumn: tableColumnType<addDataEnumKeyJointType>[] = [ const currentPage = ref(1)
const currentPageSize = ref(pagePagination[0])
const pageTotal = ref(0)
const originData = ref<getTreeDataReturnType[]>()
const tableData = computed(() => {
const start = (currentPage.value - 1) * currentPageSize.value
const end = start + currentPageSize.value
return originData.value?.slice(start, end)
})
const tableColumn: tableColumnType<allEnumType>[] = [
{ {
key: 'mridColumn', key: 'mridColumn',
prop: 'mrid', prop: 'mrid',
@ -341,16 +386,14 @@ const tableColumn: tableColumnType<addDataEnumKeyJointType>[] = [
label: addDataEnum['remarks'], label: addDataEnum['remarks'],
}, },
{ {
key: 'parentOrgIdColumn', key: 'parentOrgNameColumn',
prop: 'parentOrgId', prop: 'parentOrgName',
label: addDataEnum['parentOrgId'], label: addDataEnum['parentOrgName'],
}, },
] ]
const editForm = (column: changeDataType) => { const editForm = (column: changeDataType) => {
formModel.value = JSON.parse(JSON.stringify(column)) formModel.value = JSON.parse(JSON.stringify(column))
formModel.value.parentOrgId = 1
dialogTitle.value = '编辑机构' dialogTitle.value = '编辑机构'
dialogVible.value = true dialogVible.value = true
} }
@ -360,15 +403,21 @@ const delForm = (column: changeDataType) => {
if (res.success) { if (res.success) {
ElMessage.success('删除成功') ElMessage.success('删除成功')
getInstitutionList() getInstitutionList()
refreshTreeData()
} }
}) })
} }
const treeRef = ref<TreeInstance>()
const treeData = ref<getTreeDataReturnType[]>() const treeData = ref<getTreeDataReturnType[]>()
const treeReplaceProps = { const treeReplaceProps = {
children: 'children', children: 'children',
label: 'name', label: 'name',
} }
const treeSelectReplaceProps = {
label: 'name',
value: 'id',
}
const loadTreeData = (node: Node, resolve: any) => { const loadTreeData = (node: Node, resolve: any) => {
if (node.level === 0) { if (node.level === 0) {
return resolve([]) return resolve([])
@ -378,7 +427,32 @@ const loadTreeData = (node: Node, resolve: any) => {
if (!res.length) { if (!res.length) {
node.data.isLeaf = true node.data.isLeaf = true
} }
tableData.value = [...res] pageTotal.value = res.length
originData.value = [...res]
return resolve(res)
})
.catch((err) => {
console.log(err)
})
}
const loadSelectTreeData = (node: Node, resolve: any) => {
if (node.level === 0) {
getTreeData(adminInfo.orgid, true)
.then((res) => {
if (!res.length) {
node.data.isLeaf = true
}
return resolve(res)
})
.catch((err) => {
console.log(err)
})
}
getTreeData(node.data.id)
.then((res) => {
if (!res.length) {
node.data.isLeaf = true
}
return resolve(res) return resolve(res)
}) })
.catch((err) => { .catch((err) => {
@ -408,22 +482,30 @@ const initData = () => {
return getTreeData(adminInfo.orgid) return getTreeData(adminInfo.orgid)
}) })
.then((res) => { .then((res) => {
tableData.value = [...res] pageTotal.value = res.length
originData.value = [...res]
}) })
} }
const currentTreeId = ref<string | number>(adminInfo.orgid)
const refreshTreeData = () => {
getTreeData(currentTreeId.value).then((res) => {
treeRef.value?.updateKeyChildren(currentTreeId.value, res)
})
}
const treeNodeClick = (nodeData: getTreeDataReturnType, node: Node) => { const treeNodeClick = (nodeData: getTreeDataReturnType, node: Node) => {
console.log(node.childNodes, nodeData.isLeaf) console.log(node.childNodes, nodeData.isLeaf)
if (node.childNodes.length || nodeData.isLeaf) { if (node.childNodes.length || nodeData.isLeaf) {
getTreeData(nodeData.id).then((res) => { getTreeData(nodeData.id).then((res) => {
tableData.value = [...res] pageTotal.value = res.length
originData.value = [...res]
}) })
} }
currentTreeId.value = nodeData.id
} }
const searchTableInput = ref('') const searchTableInput = ref('')
const searchTable = () => { const searchTable = () => {
if (searchTableInput.value === '') return // if (searchTableInput.value === '') return
// table getInstitutionList({ name: searchTableInput.value, parentOrgId: currentTreeId.value })
} }
onMounted(() => { onMounted(() => {
initData() initData()
@ -436,47 +518,71 @@ onMounted(() => {
width: 220px; width: 220px;
height: 40px; height: 40px;
} }
$defaultHeaderHeight: 60px;
$defaultMainHeight: calc(100% - 60px);
$paginationHeight: 32px;
.institutionalManagement { .institutionalManagement {
.defaultAside { width: 100%;
width: 260px; height: 100%;
border-right: 1px solid #eaebed; .defaultContainer {
.treeHeader { height: 100%;
display: flex; .defaultAside {
align-items: center; width: 260px;
justify-content: center; height: 100%;
.searchInput { border-right: 1px solid #eaebed;
@include searchInput(0); .treeHeader {
display: flex;
align-items: center;
justify-content: center;
height: $defaultHeaderHeight;
.searchInput {
@include searchInput(0);
}
}
.treeMain {
height: $defaultMainHeight;
.treePart {
height: 100%;
}
} }
} }
} .defaultMainContainer {
.defaultHeader { height: 100%;
display: flex; .defaultHeader {
justify-content: space-between; display: flex;
align-items: center; justify-content: space-between;
.searchPart { align-items: center;
display: flex; height: $defaultHeaderHeight;
justify-content: space-between; .searchPart {
align-items: center; display: flex;
} justify-content: space-between;
.defaultBtn { align-items: center;
width: 88px; }
height: 40px; .defaultBtn {
} width: 88px;
.searchInput { height: 40px;
@include searchInput(10px); }
} .searchInput {
} @include searchInput(10px);
.defaultMain { }
.tableOperate { }
display: flex; .defaultMain {
justify-content: center; height: $defaultMainHeight;
align-items: center; .tablePart {
a { height: calc(100% - $paginationHeight);
margin: 5px; }
color: #0064aa; .tableOperate {
font-weight: 600; display: flex;
&:hover { justify-content: center;
cursor: pointer; align-items: center;
a {
margin: 5px;
color: #0064aa;
font-weight: 600;
&:hover {
cursor: pointer;
}
}
} }
} }
} }

View File

@ -2,7 +2,7 @@ import createAxios from '/@/utils/axios'
import { getDataType, addDataType, changeDataType, delDataType, getDataReturnType, operateDataReturnType, getTreeDataType,getTreeDataReturnType } from './type' import { getDataType, addDataType, changeDataType, delDataType, getDataReturnType, operateDataReturnType, getTreeDataType,getTreeDataReturnType } from './type'
export const getInstitutionalListReq = (data: getDataType) => { export const getInstitutionalListReq = (data: getDataType) => {
return createAxios<addDataType, getDataReturnType<changeDataType>>({ return createAxios<addDataType, getDataReturnType<getTreeDataReturnType>>({
url: '/api/org/query', url: '/api/org/query',
method: 'post', method: 'post',
data: data, data: data,

View File

@ -1,6 +1,6 @@
export type getDataType = { export type getDataType = {
name?: string | null name?: string | null
parentOrgId?: string parentOrgId?: string | number
province?: string province?: string
city?: string city?: string
county?: string county?: string
@ -23,8 +23,12 @@ export enum addDataEnum {
contactPhone = '联系电话', contactPhone = '联系电话',
remarks = '备注', remarks = '备注',
parentOrgId = '上级机构', parentOrgId = '上级机构',
parentOrgName = '上级机构名称',
} }
export type addDataEnumKeyJointType = keyof typeof addDataEnum export type allEnumType = keyof typeof addDataEnum
export type addDataEnumKeyJointType = Exclude<allEnumType, 'parentOrgName'>
export type formItemListType<T extends addDataEnumKeyJointType> = { export type formItemListType<T extends addDataEnumKeyJointType> = {
type: 'input' | 'select' | 'custom' type: 'input' | 'select' | 'custom'
prop: T prop: T
@ -55,18 +59,8 @@ export type addDataType = {
export type changeDataType = { export type changeDataType = {
id: string id: string
mrid: string } & addDataType
name: string
aliasName: string
province: string
city: string
county: string
address: string
contactPhone: string
remarks: string
parentOrgId: number
revision: number
}
export type operateDataReturnType<T = any> = Promise<{ export type operateDataReturnType<T = any> = Promise<{
code: number code: number
msg: string msg: string
@ -78,11 +72,11 @@ export type delDataType = {
id: string id: string
} }
export type getTreeDataType = { export type getTreeDataType = {
parentOrgId: number|string parentOrgId: number | string
recursive: boolean recursive: boolean
} }
export type tableColumnType<T extends addDataEnumKeyJointType> = { export type tableColumnType<T extends allEnumType> = {
key: string key: string
prop: T prop: T
label: (typeof addDataEnum)[T] label: (typeof addDataEnum)[T]
@ -100,8 +94,9 @@ export type getTreeDataReturnType = {
mrid: string mrid: string
name: string name: string
parentOrgId: number parentOrgId: number
parentOrgName: string
province: string province: string
remarks: string remarks: string
revision: number revision: number
isLeaf?:boolean isLeaf?: boolean
} }

View File

@ -27,16 +27,16 @@
<el-button @click="cancelSubmitForm">取消</el-button> <el-button @click="cancelSubmitForm">取消</el-button>
</template> </template>
</el-dialog> </el-dialog>
<el-container> <el-container class="container">
<el-header class="containerHeader"> <el-header class="containerHeader">
<div class="searchPart"> <div class="searchPart">
<el-input class="searchInput" v-model:value="searchInputValue" :placeholder="searchInputPlacehoder"></el-input> <el-input class="searchInput" v-model="searchInputValue" :placeholder="searchInputPlacehoder"></el-input>
<el-button type="primary" :icon="Search" class="defaultBtn" @click="searchClick">{{ t('management.search') }}</el-button> <el-button type="primary" :icon="Search" class="defaultBtn" @click="searchClick">{{ t('management.search') }}</el-button>
</div> </div>
<el-button type="primary" :icon="Plus" class="defaultBtn" @click="addClick">{{ t('management.add') }}</el-button> <el-button type="primary" :icon="Plus" class="defaultBtn" @click="addClick">{{ t('management.add') }}</el-button>
</el-header> </el-header>
<el-main class="containerMain"> <el-main class="containerMain">
<el-table :data="tableData"> <el-table :data="tableData" class="tablePart">
<el-table-column <el-table-column
v-for="item in tableColumn" v-for="item in tableColumn"
:key="item.key" :key="item.key"
@ -59,14 +59,37 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="currentPageSize"
:total="pageTotal"
:page-sizes="pagePagination"
background
:pager-count="7"
layout="prev, pager, next, jumper,sizes,total"
></el-pagination>
</el-main> </el-main>
</el-container> </el-container>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
import { ElContainer, ElHeader, ElMain, ElInput, ElButton, ElTable, ElTableColumn, ElDialog, ElForm, ElFormItem, ElMessage } from 'element-plus' import {
ElContainer,
ElHeader,
ElMain,
ElInput,
ElButton,
ElTable,
ElTableColumn,
ElDialog,
ElForm,
ElFormItem,
ElMessage,
ElPopconfirm,
ElPagination,
} from 'element-plus'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { Plus, Search } from '@element-plus/icons-vue' import { Plus, Search } from '@element-plus/icons-vue'
import { import {
@ -77,21 +100,22 @@ import {
formColumnListType, formColumnListType,
formDataType, formDataType,
authorityDataListType, authorityDataListType,
tableDataColumnTypeJointType,
tableDataEnum,
} from './type' } from './type'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { getRoleListReq, changeRoleListReq, addRoleListReq, delRoleListReq, getAllRoleListReq } from './request' import { getRoleListReq, changeRoleListReq, addRoleListReq, delRoleListReq, getAllRoleListReq } from './request'
import { placeholderSign } from 'element-plus/es/components/table-v2/src/private.mjs'
const { t } = useI18n() const { t } = useI18n()
const dialogTitle = ref('新增角色') const dialogTitle = ref('新增角色')
const dialogVisible = ref(false) const dialogVisible = ref(false)
const formModel = ref<formDataType>({ const defaultFormModel = {
id: '', id: '',
authList: [], authList: [],
roleName: '', roleName: '',
roleCode: '', roleCode: '',
}) }
const defaultFormModel = JSON.parse(JSON.stringify(formModel.value)) const formModel = ref<formDataType>(JSON.parse(JSON.stringify(defaultFormModel)))
const formColumnList: formColumnListType<formDataEnumKeyJointType>[] = [ const formColumnList: formColumnListType<formDataEnumKeyJointType>[] = [
{ type: 'input', label: formDataEnum['roleName'], prop: 'roleName', rule: [{ required: true, message: '请输入角色名称', trigger: 'blur' }] }, { type: 'input', label: formDataEnum['roleName'], prop: 'roleName', rule: [{ required: true, message: '请输入角色名称', trigger: 'blur' }] },
{ type: 'input', label: formDataEnum['roleCode'], prop: 'roleCode', rule: [{ required: true, message: '请输入角色编码', trigger: 'blur' }] }, { type: 'input', label: formDataEnum['roleCode'], prop: 'roleCode', rule: [{ required: true, message: '请输入角色编码', trigger: 'blur' }] },
@ -108,20 +132,20 @@ const formRef = ref<FormInstance>()
const submitForm = () => { const submitForm = () => {
if (!formRef.value) return if (!formRef.value) return
formRef.value.validate((valid) => { formRef.value.validate((valid) => {
console.log(valid);
if (valid) { if (valid) {
if (dialogTitle.value === '新增角色') { if (dialogTitle.value === '新增角色') {
console.log(formModel.value) console.log(formModel.value)
addRoleListReq(formModel.value).then((res) => { addRoleListReq(formModel.value)
if (res.success) { .then((res) => {
getRoleList() if (res.success) {
ElMessage.success('新增成功') getRoleList()
} ElMessage.success('新增成功')
}).catch(err=>{ }
ElMessage.error(err?.response?.data?.msg ?? '新增失败') })
}) .catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '新增失败')
})
dialogVisible.value = false dialogVisible.value = false
} else if (dialogTitle.value === '编辑角色') { } else if (dialogTitle.value === '编辑角色') {
changeRoleListReq(formModel.value) changeRoleListReq(formModel.value)
@ -135,7 +159,6 @@ const submitForm = () => {
}) })
.catch((err) => { .catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '编辑失败') ElMessage.error(err?.response?.data?.msg ?? '编辑失败')
}) })
} }
} }
@ -148,34 +171,43 @@ const cancelSubmitForm = () => {
const searchInputPlacehoder = t('management.Query roles by name') const searchInputPlacehoder = t('management.Query roles by name')
const searchInputValue = ref<string>('') const searchInputValue = ref<string>('')
const searchClick = () => { const searchClick = () => {
if (!searchInputValue.value) return currentPage.value = 1
getRoleList(searchInputValue.value)
} }
const tableColumn = ref<tableColumnType<formDataEnumKeyJointType>[]>([ const tableColumn = ref<tableColumnType<tableDataColumnTypeJointType>[]>([
{ {
key: 'roleName-table', key: 'roleName-table',
prop: 'roleName', prop: 'roleName',
label: formDataEnum['roleName'], label: tableDataEnum['roleName'],
}, },
{ {
key: 'roleCode_table', key: 'roleCode_table',
prop: 'roleCode', prop: 'roleCode',
label: formDataEnum['roleCode'], label: tableDataEnum['roleCode'],
}, },
{ {
label: formDataEnum['authList'], label: tableDataEnum['listName'],
prop: 'authList', prop: 'listName',
key: 'authList-table', key: 'authList-table',
}, },
]) ])
const tableData = ref<tableDataType[]>([]) const tableData = computed(() => {
const start = (currentPage.value - 1) * currentPageSize.value
const end = start + currentPageSize.value
return originData.value?.slice(start, end)
})
const pagePagination = [5, 10, 20, 30]
const currentPage = ref(1)
const currentPageSize = ref(pagePagination[0])
const pageTotal = ref(0)
const originData = ref<tableDataType<authorityDataListType>[]>()
const addClick = () => { const addClick = () => {
// //
dialogTitle.value = '新增角色' dialogTitle.value = '新增角色'
formRef.value && formRef.value.resetFields() formRef.value && formRef.value.clearValidate(Object.keys(defaultFormModel))
formModel.value = defaultFormModel formModel.value = defaultFormModel
dialogVisible.value = true dialogVisible.value = true
} }
const editForm = (formData: formDataType) => { const editForm = (formData: formDataType) => {
@ -185,19 +217,33 @@ const editForm = (formData: formDataType) => {
dialogVisible.value = true dialogVisible.value = true
} }
const delForm = (formData: formDataType) => { const delForm = (formData: formDataType) => {
delRoleListReq({ id: formData.id }).then((res) => { delRoleListReq({ id: formData.id })
if (res.success) { .then((res) => {
ElMessage.success('删除成功') if (res.success) {
getRoleList() ElMessage.success('删除成功')
} getRoleList()
}) }
})
.catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '删除失败')
})
} }
const getRoleList = (roleName = '') => { const getRoleList = (roleName = '') => {
getRoleListReq({ getRoleListReq({
roleName, roleName,
}).then((res) => { }).then((res) => {
tableData.value = res.rows pageTotal.value = res.total
originData.value = res.rows.map((item) => {
return {
roleCode: item.roleCode,
roleName: item.roleName,
listName: item.list.map((item) => item.authorityName).join(','),
authList: item.list.map((item) => item.id),
id: item.id,
revision: item.revision,
}
})
}) })
} }
onMounted(() => { onMounted(() => {
@ -209,35 +255,47 @@ onMounted(() => {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
$defaultHeaderHeight: 60px;
$defaultMainHeight: calc(100% - 60px);
$paginationHeight: 32px;
.roleManagement { .roleManagement {
width: 100%; width: 100%;
height: 100%; height: 100%;
.containerHeader { .container {
display: flex;
align-items: center;
justify-content: space-between;
.searchInput {
margin-right: 10px;
width: 220px;
height: 40px;
}
.defaultBtn {
width: 88px;
height: 40px;
}
}
.containerMain {
width: 100%; width: 100%;
.tableOperate { height: 100%;
.containerHeader {
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
a { justify-content: space-between;
margin: 5px; height: $defaultHeaderHeight;
color: #0064aa; .searchInput {
font-weight: 600; margin-right: 10px;
&:hover { width: 220px;
cursor: pointer; height: 40px;
}
.defaultBtn {
width: 88px;
height: 40px;
}
}
.containerMain {
width: 100%;
height: $defaultMainHeight;
.tablePart {
height: calc(100% - $paginationHeight);
.tableOperate {
display: flex;
justify-content: center;
align-items: center;
a {
margin: 5px;
color: #0064aa;
font-weight: 600;
&:hover {
cursor: pointer;
}
}
} }
} }
} }

View File

@ -7,10 +7,11 @@ export enum formDataEnum {
export type formDataType = { export type formDataType = {
id: string id: string
authList: number[] authList: string[]
roleName: string roleName: string
roleCode: string roleCode: string
} }
export type formDataEnumKeyJointType = keyof typeof formDataEnum export type formDataEnumKeyJointType = keyof typeof formDataEnum
export type formColumnListType<T extends formDataEnumKeyJointType> = { export type formColumnListType<T extends formDataEnumKeyJointType> = {
@ -25,19 +26,36 @@ export type formColumnListType<T extends formDataEnumKeyJointType> = {
| [{ validator: (rule: any, value: any, callback: any) => void; trigger: 'blur' | 'change' }] | [{ validator: (rule: any, value: any, callback: any) => void; trigger: 'blur' | 'change' }]
} }
export type tableDataType = { export enum tableDataEnum {
createdTime?: string id = '系统角色id',
listName = '角色权限',
roleName = '角色名称',
roleCode = '角色编码',
authList = '角色权限编码',
}
export type tableDataColumnType = {
id: string
authList: string[]
roleName: string
roleCode: string
listName: string
}
export type tableDataColumnTypeJointType = keyof typeof tableDataEnum
export type tableDataType<T extends authorityDataListType> = {
id: string id: string
revision: number revision: number
roleCode: number roleCode: number
roleName: string roleName: string
updatedTime?: string listName: T['authorityName']
authList: T['id'][]
} }
export type tableColumnType<T extends formDataEnumKeyJointType> = { export type tableColumnType<T extends tableDataColumnTypeJointType> = {
key: string key: string
prop: T prop: T
label: (typeof formDataEnum)[T] label: (typeof tableDataEnum)[T]
fixed?: boolean fixed?: boolean
align?: 'left' | 'center' | 'right' align?: 'left' | 'center' | 'right'
} }
@ -66,12 +84,11 @@ export type getDataType = {
} }
export type getDataReturnType = { export type getDataReturnType = {
createdTime: string
id: string id: string
revision: number revision: number
roleCode: number roleCode: number
roleName: string roleName: string
updatedTime: string list: authorityDataListType[]
} }
export type changeDataType = Omit<formDataType, 'roleCode'> export type changeDataType = Omit<formDataType, 'roleCode'>
@ -89,4 +106,3 @@ export type addDataReturnType = changeDataReturnType
export type delDataType = { export type delDataType = {
id: string id: string
} }