commod = new ArrayList<>();
+ commod.add(ffmpegEXEPath);
+ commod.add("-ss");
+ commod.add("00:00:01");// 默认截图视频 01 秒的一帧
+ commod.add("-y");
+ commod.add("-i");
+ commod.add(videoPath);
+ commod.add("-vframes");
+ commod.add("1");// 默认截图一帧
+ commod.add(videoCoverOutputPath);
+
+ // 执行 cmd 命令
+ ProcessBuilder processBuilder = new ProcessBuilder(commod);
+ Process process = processBuilder.start();
+ // ffmpeg 进行音频与视频整合或转码时或产生很多流与碎片文件,为了防止占用主线程卡主,所以使用流的方式
+ InputStream inputStream = process.getErrorStream();// 获取字节流
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream);// 字节流转字符流
+ BufferedReader bufferedReader = new BufferedReader(inputStreamReader);// 吧字符流放到字符流缓冲流中读取
+ String line = "";
+ while ((line = bufferedReader.readLine()) != null){};
+ // 关闭流
+ if (bufferedReader != null){
+ bufferedReader.close();
+ }
+ if (inputStreamReader != null){
+ inputStreamReader.close();
+ }
+ if (inputStream != null){
+ inputStream.close();
+ }
+ }
+
+ public static void main(String[] args) {
+ // 测试
+ String ffmpegEXE = "G:\\ffmpeg\\bin\\ffmpeg.exe";
+ String videoInputPath = "G:\\ffmpeg\\bin\\01.mp4";
+ String videoOutputPath = "G:\\ffmpeg\\bin\\01.avi";
+ String mp3InputPath = "G:\\ffmpeg\\bin\\bgm.mp3";
+ String videoCoverPath = "G:\\ffmpeg\\bin\\001\\0001.jpg";
+ String conver = "G:/video-upload/1230681055802642432/cover/wx993172f7da9acf1f.jpg";
+ try {
+ //converVideo(ffmpegEXE,videoInputPath,videoOutputPath);// 视频格式转换
+ //converMergreVideoMp3(ffmpegEXE,videoInputPath,mp3InputPath,7,videoOutputPath);// 视频与音频整合
+ converVideoCover(ffmpegEXE,videoInputPath,conver);// 截图视频封面
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/suelec/permission/utils/IdWorker.java b/src/main/java/com/suelec/permission/utils/IdWorker.java
new file mode 100644
index 0000000..4752370
--- /dev/null
+++ b/src/main/java/com/suelec/permission/utils/IdWorker.java
@@ -0,0 +1,161 @@
+package com.suelec.permission.utils;
+
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+
+/**
+ * 名称:IdWorker.java
+ * 描述:分布式自增长ID
+ *
+ * Twitter的 Snowflake JAVA实现方案
+ *
+ * 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
+ * 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
+ * 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
+ * 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
+ * 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
+ * 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
+ * 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
+ *
+ * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
+ *
+ * @author Polim
+ */
+public class IdWorker {
+ // 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
+ private final static long twepoch = 1288834974657L;
+ // 机器标识位数
+ private final static long workerIdBits = 5L;
+ // 数据中心标识位数
+ private final static long datacenterIdBits = 5L;
+ // 机器ID最大值
+ private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
+ // 数据中心ID最大值
+ private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+ // 毫秒内自增位
+ private final static long sequenceBits = 12L;
+ // 机器ID偏左移12位
+ private final static long workerIdShift = sequenceBits;
+ // 数据中心ID左移17位
+ private final static long datacenterIdShift = sequenceBits + workerIdBits;
+ // 时间毫秒左移22位
+ private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+ private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
+ /* 上次生产id时间戳 */
+ private static long lastTimestamp = -1L;
+ // 0,并发控制
+ private long sequence = 0L;
+
+ private final long workerId;
+ // 数据标识id部分
+ private final long datacenterId;
+
+ public IdWorker(){
+ this.datacenterId = getDatacenterId(maxDatacenterId);
+ this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
+ }
+ /**
+ * @param workerId
+ * 工作机器ID
+ * @param datacenterId
+ * 序列号
+ */
+ public IdWorker(long workerId, long datacenterId) {
+ if (workerId > maxWorkerId || workerId < 0) {
+ throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+ }
+ if (datacenterId > maxDatacenterId || datacenterId < 0) {
+ throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+ }
+ this.workerId = workerId;
+ this.datacenterId = datacenterId;
+ }
+ /**
+ * 获取下一个ID
+ *
+ * @return
+ */
+ public synchronized long nextId() {
+ long timestamp = timeGen();
+ if (timestamp < lastTimestamp) {
+ throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+ }
+
+ if (lastTimestamp == timestamp) {
+ // 当前毫秒内,则+1
+ sequence = (sequence + 1) & sequenceMask;
+ if (sequence == 0) {
+ // 当前毫秒内计数满了,则等待下一秒
+ timestamp = tilNextMillis(lastTimestamp);
+ }
+ } else {
+ sequence = 0L;
+ }
+ lastTimestamp = timestamp;
+ // ID偏移组合生成最终的ID,并返回ID
+ long nextId = ((timestamp - twepoch) << timestampLeftShift)
+ | (datacenterId << datacenterIdShift)
+ | (workerId << workerIdShift) | sequence;
+
+ return nextId;
+ }
+
+ private long tilNextMillis(final long lastTimestamp) {
+ long timestamp = this.timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = this.timeGen();
+ }
+ return timestamp;
+ }
+
+ private long timeGen() {
+ return System.currentTimeMillis();
+ }
+
+ /**
+ *
+ * 获取 maxWorkerId
+ *
+ */
+ protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
+ StringBuffer mpid = new StringBuffer();
+ mpid.append(datacenterId);
+ String name = ManagementFactory.getRuntimeMXBean().getName();
+ if (!name.isEmpty()) {
+ /*
+ * GET jvmPid
+ */
+ mpid.append(name.split("@")[0]);
+ }
+ /*
+ * MAC + PID 的 hashcode 获取16个低位
+ */
+ return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
+ }
+
+ /**
+ *
+ * 数据标识id部分
+ *
+ */
+ protected static long getDatacenterId(long maxDatacenterId) {
+ long id = 0L;
+ try {
+ InetAddress ip = InetAddress.getLocalHost();
+ NetworkInterface network = NetworkInterface.getByInetAddress(ip);
+ if (network == null) {
+ id = 1L;
+ } else {
+ byte[] mac = network.getHardwareAddress();
+ id = ((0x000000FF & (long) mac[mac.length - 1])
+ | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
+ id = id % (maxDatacenterId + 1);
+ }
+ } catch (Exception e) {
+ System.out.println(" getDatacenterId: " + e.getMessage());
+ }
+ return id;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/suelec/permission/utils/JwtTokenUtil.java b/src/main/java/com/suelec/permission/utils/JwtTokenUtil.java
new file mode 100644
index 0000000..842f1b9
--- /dev/null
+++ b/src/main/java/com/suelec/permission/utils/JwtTokenUtil.java
@@ -0,0 +1,199 @@
+package com.suelec.permission.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.CompressionCodecs;
+import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+
+import java.util.Date;
+
+/**
+ * jwt token 工具类
+ */
+public class JwtTokenUtil {
+ /**
+ * 实例
+ */
+ private static JwtTokenUtil instance;
+
+ /**
+ * 发行者
+ */
+ private String issuer;
+
+ /**
+ * 主体(subject 代表这个JWT的主体,即它的所有人 一般是用户id)
+ */
+ private String subObject;
+
+ /**
+ * 过期时间,默认7天
+ */
+ private long expired = 1000 * 60 * 60 * 24 * 7;
+
+ /**
+ * jwt构造
+ */
+ private static JwtBuilder jwtBuilder;
+
+ /**
+ * 密钥
+ */
+ private String secret;// 密钥
+
+ /**
+ * 获取实例
+ * @return
+ */
+ public static JwtTokenUtil getInstance(){
+ if (instance == null){
+ instance = new JwtTokenUtil();
+ }
+ jwtBuilder = Jwts.builder();
+ return instance;
+ }
+
+ /**
+ * 荷载信息(通常是一个User信息,还包括一些其他的元数据)
+ * @param key
+ * @param val
+ * @return
+ */
+ public JwtTokenUtil setClaim(String key, Object val){
+ jwtBuilder.claim(key,val);
+ return this;
+ }
+
+ /**
+ * 生成 jwt token
+ * @return
+ */
+ public String generateToken(){
+ String token = jwtBuilder
+ .setIssuer(issuer)// 发行者
+ .setSubject(subObject) // 主体
+ //.claim("id","121") // 参数
+ .setIssuedAt(new Date()) // 发行时间
+ .setExpiration(new Date(System.currentTimeMillis() + expired))
+ .signWith(SignatureAlgorithm.HS256,secret) // 签名类型 与 密钥
+ .compressWith(CompressionCodecs.DEFLATE)// 对载荷进行压缩
+ .compact(); // 压缩一下
+ return token;
+ }
+
+ /**
+ * 解析 token
+ * @param token
+ * @return
+ */
+ public Claims parseToken(String token){
+ try{
+ final Claims claims = Jwts.parser()
+ .setSigningKey(secret)
+ .parseClaimsJws(token)
+ .getBody();
+ return claims;
+ }catch (Exception e){}
+ return null;
+ }
+
+ /**
+ * 验证是否过期
+ * @param token
+ * @return
+ */
+ public boolean isTokenExpired(String token){
+ try{
+ Claims claims = parseToken(token);
+ return claims != null && !claims.getExpiration().before(new Date());
+ }catch (Exception e){
+ return true;
+ }
+ }
+
+ /**
+ * 验证token是否验证通过
+ * @param token
+ * @return
+ */
+ public boolean checkToken(String token){
+ try{
+ return isTokenExpired(token);
+ }catch (Exception e){
+ return false;
+ }
+ }
+
+ /**
+ * 获取用户id
+ * @param token
+ * @return
+ */
+ public String getUserId(String token){
+ try{
+ Claims claims = parseToken(token);
+ return claims != null ? claims.getSubject() : null;
+ }catch (Exception e){
+ return null;
+ }
+ }
+
+ /**
+ * 获取token的剩余过期时间
+ * @param token
+ * @return
+ */
+ public long getRemainingTime(String token){
+ long time = 0;
+ try{
+ Claims claims = parseToken(token);
+ time = claims.getExpiration().getTime() - System.currentTimeMillis();
+ }catch (Exception e){}
+ return time;
+ }
+
+ /**
+ * 设置发行者
+ * @param issuer
+ * @return
+ */
+ public JwtTokenUtil setIssuer(String issuer) {
+ this.issuer = issuer;
+ return this;
+ }
+
+ /**
+ * 设置主题
+ * @param subObject
+ * @return
+ */
+ public JwtTokenUtil setSubObject(String subObject) {
+ this.subObject = subObject;
+ return this;
+ }
+
+ public long getExpired() {
+ return expired;
+ }
+
+ /**
+ * 设置过期时间
+ * @param expired
+ * @return
+ */
+ public JwtTokenUtil setExpired(long expired) {
+ this.expired = expired;
+ return this;
+ }
+
+ /**
+ * 设置密钥
+ * @param secret
+ * @return
+ */
+ public JwtTokenUtil setSecret(String secret) {
+ this.secret = secret;
+ return this;
+ }
+}
diff --git a/src/main/java/com/suelec/permission/utils/PageUtil.java b/src/main/java/com/suelec/permission/utils/PageUtil.java
new file mode 100644
index 0000000..745d6e9
--- /dev/null
+++ b/src/main/java/com/suelec/permission/utils/PageUtil.java
@@ -0,0 +1,28 @@
+package com.suelec.permission.utils;
+
+import com.github.pagehelper.PageInfo;
+import com.suelec.permission.vo.resp.PageVo;
+
+
+/**
+ * 分页工具类
+ */
+public class PageUtil {
+
+ /**
+ * 分页数据组装
+ * @param pageInfo
+ * @param
+ * @return
+ */
+ public static PageVo getPageVo(PageInfo pageInfo){
+ PageVo pageInfoPageVo = new PageVo();
+ pageInfoPageVo.setTotalRows(pageInfo.getTotal());//总记录数
+ pageInfoPageVo.setTotalPages(pageInfo.getPages());//总页数
+ pageInfoPageVo.setPageNum(pageInfo.getPageNum());//当前第几页
+ pageInfoPageVo.setPageSize(pageInfo.getPageSize());//每页记录数
+ pageInfoPageVo.setCurPageSize(pageInfo.getSize());//当前页记录数
+ pageInfoPageVo.setRows(pageInfo.getList());//结果集
+ return pageInfoPageVo;
+ }
+}
diff --git a/src/main/java/com/suelec/permission/utils/Response.java b/src/main/java/com/suelec/permission/utils/Response.java
new file mode 100644
index 0000000..9834de0
--- /dev/null
+++ b/src/main/java/com/suelec/permission/utils/Response.java
@@ -0,0 +1,76 @@
+package com.suelec.permission.utils;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.io.Serializable;
+
+/**
+ * 返回数据类
+ * @param
+ */
+//保证序列化json的时候,如果是null的对象,key也会消失
+//@JsonInclude(Include.NON_NULL)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Response implements Serializable {
+ // 成功值
+ private static final int SUCCESS_CODE = 1;
+ // 失败值
+ private static final int ERROR_CODE = 0;
+
+ //状态码
+ private int code;
+ //消息
+ private String msg;
+ //返回数据
+ private T data;
+
+ private Response(int code){
+ this.code = code;
+ }
+ private Response(int code,T data){
+ this.code = code;
+ this.data = data;
+ }
+ private Response(int code,String msg){
+ this.code = code;
+ this.msg = msg;
+ }
+ private Response(int code,String msg,T data){
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public static Response success(){
+ return new Response(SUCCESS_CODE,"success");
+ }
+ public static Response success(String msg){
+ return new Response(SUCCESS_CODE,msg);
+ }
+ public static Response success(T data){
+ return new Response(SUCCESS_CODE,data);
+ }
+ public static Response success(String msg,T data){
+ return new Response(SUCCESS_CODE,msg,data);
+ }
+
+ public static Response error(){
+ return new Response(ERROR_CODE,"error");
+ }
+ public static Response error(String msg){
+ return new Response(ERROR_CODE,msg);
+ }
+ public static Response error(int code,String msg){
+ return new Response(code,msg);
+ }
+
+ public int getCode(){
+ return code;
+ }
+ public String getMsg(){
+ return msg;
+ }
+ public T getData(){
+ return data;
+ }
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/LogPageReqVo.java b/src/main/java/com/suelec/permission/vo/req/LogPageReqVo.java
new file mode 100644
index 0000000..017afb0
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/LogPageReqVo.java
@@ -0,0 +1,26 @@
+package com.suelec.permission.vo.req;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class LogPageReqVo {
+
+ @ApiModelProperty("当前页数")
+ private Integer pageNum=1;
+
+ @ApiModelProperty(value = "当前页的数量")
+ private int pageSize=10;
+
+ @ApiModelProperty(value = "用户操作动作")
+ private String operation;
+
+ @ApiModelProperty(value = "账号")
+ private String username;
+
+ @ApiModelProperty(value = "开始时间")
+ private String startTime;
+
+ @ApiModelProperty(value = "结束时间")
+ private String endTime;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/LoginReqVo.java b/src/main/java/com/suelec/permission/vo/req/LoginReqVo.java
new file mode 100644
index 0000000..c25ec72
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/LoginReqVo.java
@@ -0,0 +1,26 @@
+package com.suelec.permission.vo.req;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel(value = "登陆对象",description = "用户登陆的参数对象")
+public class LoginReqVo {
+
+ @ApiModelProperty(value = "账号")
+ @NotBlank(message = "账号不能为空")
+ @Length(min = 3,max = 16,message = "账号名称长度需要在3~16个字之间")
+ private String username;
+
+ @ApiModelProperty(value = "密码")
+ @NotBlank(message = "密码不能为空")
+ private String password;
+
+ @ApiModelProperty(value = "登录类型 1:pc;2:App")
+ @NotBlank(message = "用户登录类型不能为空")
+ private String type;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/PermissionAddReqVo.java b/src/main/java/com/suelec/permission/vo/req/PermissionAddReqVo.java
new file mode 100644
index 0000000..8ebfda9
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/PermissionAddReqVo.java
@@ -0,0 +1,48 @@
+package com.suelec.permission.vo.req;
+
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class PermissionAddReqVo {
+
+ @ApiModelProperty(value = "菜单权限名称")
+ @NotBlank(message = "菜单权限名称不能为空")
+ private String title;
+
+ @ApiModelProperty(value = "菜单图标icon")
+ private String icon;
+
+ @ApiModelProperty(value = "菜单权限标识,shiro 适配restful")
+ private String perms;
+
+ @ApiModelProperty(value = "接口地址")
+ private String url;
+
+ @ApiModelProperty(value = "请求方式 和url 配合使用 (我们用 路径匹配的方式做权限管理的时候用到)")
+ private String method;
+
+ @ApiModelProperty(value = "name与前端vue路由name约定一致")
+ private String name;
+
+ @ApiModelProperty(value = "父级id")
+ @NotNull(message = "所属菜单不能为空")
+ private String pid;
+
+ @ApiModelProperty(value = "排序码")
+ private Integer orderNum;
+
+ @ApiModelProperty(value = "菜单权限类型(1:目录;2:菜单;3:按钮)")
+ @NotNull(message = "菜单权限类型不能为空")
+ private Integer type;
+
+ @ApiModelProperty(value = "状态1:正常 0:禁用")
+ private Integer status;
+
+ @ApiModelProperty(value = "编码(前后端分离 前段对按钮显示隐藏控制 btn-permission-search 代表 菜单权限管理的列表查询按钮)")
+ private String code;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/PermissionUpdateReqVo.java b/src/main/java/com/suelec/permission/vo/req/PermissionUpdateReqVo.java
new file mode 100644
index 0000000..dd19edb
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/PermissionUpdateReqVo.java
@@ -0,0 +1,47 @@
+package com.suelec.permission.vo.req;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class PermissionUpdateReqVo {
+ @ApiModelProperty(value = "id")
+ @NotBlank(message = "id 不能为空")
+ private String id;
+
+ @ApiModelProperty(value = "状态1:正常 0:禁用")
+ private Integer status;
+
+ @ApiModelProperty(value = "菜单权限名称")
+ private String title;
+
+ @ApiModelProperty(value = "菜单图标icon")
+ private String icon;
+
+ @ApiModelProperty(value = "菜单权限标识,shiro 适配restful")
+ private String perms;
+
+ @ApiModelProperty(value = "接口地址")
+ private String url;
+
+ @ApiModelProperty(value = "请求方式 和url 配合使用 (我们用 路径匹配的方式做权限管理的时候用到)")
+ private String method;
+
+ @ApiModelProperty(value = "name与前端vue路由name约定一致")
+ private String name;
+
+ @ApiModelProperty(value = "父级id")
+ private String pid;
+
+ @ApiModelProperty(value = "排序码")
+ private Integer orderNum;
+
+ @ApiModelProperty(value = "菜单权限类型(1:目录;2:菜单;3:按钮)")
+
+ private Integer type;
+
+ @ApiModelProperty(value = "编码(前后端分离 前段对按钮显示隐藏控制 btn-permission-search 代表 菜单权限管理的列表查询按钮)")
+ private String code;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/RolePageReqVo.java b/src/main/java/com/suelec/permission/vo/req/RolePageReqVo.java
new file mode 100644
index 0000000..a45b8a8
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/RolePageReqVo.java
@@ -0,0 +1,25 @@
+package com.suelec.permission.vo.req;
+
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class RolePageReqVo {
+
+ @ApiModelProperty(value = "第几页")
+ private int pageNum=1;
+ @ApiModelProperty(value = "当前页的数量")
+ private int pageSize=10;
+
+ @ApiModelProperty(value = "角色id")
+ private String roleId;
+ @ApiModelProperty(value = "角色名称")
+ private String roleName;
+ @ApiModelProperty(value = "角色状态")
+ private Integer status;
+ @ApiModelProperty(value = "开始时间")
+ private String startTime;
+ @ApiModelProperty(value = "结束时间")
+ private String endTime;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/RolePermissionOperationReqVo.java b/src/main/java/com/suelec/permission/vo/req/RolePermissionOperationReqVo.java
new file mode 100644
index 0000000..db383e2
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/RolePermissionOperationReqVo.java
@@ -0,0 +1,20 @@
+package com.suelec.permission.vo.req;
+
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+@Data
+public class RolePermissionOperationReqVo {
+
+ @ApiModelProperty(value = "角色id")
+ @NotBlank(message = "角色id不能为空")
+ private String roleId;
+
+ @ApiModelProperty(value = "菜单权限集合id")
+ @NotBlank(message = "菜单权限集合不能为空")
+ private List permissionIds;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/RoleReqVo.java b/src/main/java/com/suelec/permission/vo/req/RoleReqVo.java
new file mode 100644
index 0000000..45514b6
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/RoleReqVo.java
@@ -0,0 +1,26 @@
+package com.suelec.permission.vo.req;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+@Data
+public class RoleReqVo {
+
+ @ApiModelProperty(value = "角色名称")
+ @NotBlank(message = "角色名称不能为空")
+ @Length(min = 2,max = 15,message = "角色名称长度为2 ~ 15个字符")
+ private String name;
+
+ @ApiModelProperty(value = "角色描述")
+ private String description;
+
+ @ApiModelProperty(value = "角色状态:1:正常0:弃用")
+ private Integer status;
+
+ @ApiModelProperty(value = "选择的菜单id集合")
+ private List permissionsIds;
+}
diff --git a/src/main/java/com/suelec/permission/vo/req/RoleUpdateReqVo.java b/src/main/java/com/suelec/permission/vo/req/RoleUpdateReqVo.java
new file mode 100644
index 0000000..ff702a8
--- /dev/null
+++ b/src/main/java/com/suelec/permission/vo/req/RoleUpdateReqVo.java
@@ -0,0 +1,27 @@
+package com.suelec.permission.vo.req;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+@Data
+public class RoleUpdateReqVo {
+
+ @ApiModelProperty(value = "角色id")
+ @NotBlank(message = "角色 id 不能为空")
+ private String id;
+
+ @ApiModelProperty(value = "角色名称")
+ private String name;
+
+ @ApiModelProperty(value = "角色描述")
+ private String description;
+
+ @ApiModelProperty(value = "状态(1:正常0:弃用)")
+ private Integer status;
+
+ @ApiModelProperty(value = "所拥有的菜单权限")
+ private List