templates = getTemplates();
+ for (String template : templates) {
+ //渲染模板
+ StringWriter sw = new StringWriter();
+ Template tpl = Velocity.getTemplate(template, "UTF-8");
+ tpl.merge(context, sw);
+
+ try {
+ //添加到zip
+ zip.putNextEntry(new ZipEntry(Objects.requireNonNull(getFileName(template, tableEntity.getClassName(), config.getString("package")))));
+ IOUtils.write(sw.toString(), zip, "UTF-8");
+ IOUtils.closeQuietly(sw);
+ zip.closeEntry();
+ } catch (IOException e) {
+ throw new BusinessException("渲染模板失败,表名:" + tableEntity.getTableName());
+ }
+ }
+ }
+
+
+ /**
+ * 列名转换成Java属性名
+ */
+ public static String columnToJava(String field) {
+ String[] fields = field.split("_");
+ StringBuilder sbuilder = new StringBuilder(fields[0]);
+ for (int i = 1; i < fields.length; i++) {
+ char[] cs = fields[i].toCharArray();
+ if(cs[0]>='a') {
+ cs[0] -= 32;
+ }
+ sbuilder.append(String.valueOf(cs));
+ }
+ return sbuilder.toString().substring(0, 1).toUpperCase() + sbuilder.toString().substring(1);
+ }
+
+
+ /**
+ * 表名转换成Java类名
+ */
+ public static String tableToJava(String tableName, String[] tablePrefixArray) {
+ tableName = tableName.toLowerCase();
+ if (null != tablePrefixArray && tablePrefixArray.length > 0) {
+ for (String tablePrefix : tablePrefixArray) {
+ tablePrefix = tablePrefix.toLowerCase();
+ tableName = tableName.replace(tablePrefix, "");
+ }
+ }
+ return columnToJava(tableName);
+ }
+
+ /**
+ * 获取配置信息
+ */
+ public static Configuration getConfig() {
+ try {
+ return new PropertiesConfiguration("generator.properties");
+ } catch (ConfigurationException e) {
+ throw new BusinessException("获取配置文件失败");
+ }
+ }
+
+ /**
+ * 获取文件名
+ */
+ public static String getFileName(String template, String className, String packageName) {
+ String packagePath = "main" + File.separator + "java" + File.separator;
+ if (StringUtils.isNotBlank(packageName)) {
+ packagePath += packageName.replace(".", File.separator) + File.separator;
+ }
+
+ if (template.contains("Entity.java.vm")) {
+ return packagePath + "entity" + File.separator + className + "Entity.java";
+ }
+
+ if (template.contains("Dao.java.vm")) {
+ return packagePath + "mapper" + File.separator + className + "Mapper.java";
+ }
+
+ if (template.contains("Service.java.vm")) {
+ return packagePath + "service" + File.separator + className + "Service.java";
+ }
+
+ if (template.contains("ServiceImpl.java.vm")) {
+ return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
+ }
+
+ if (template.contains("Controller.java.vm")) {
+ return packagePath + "controller" + File.separator + className + "Controller.java";
+ }
+
+ if (template.contains("Dao.xml.vm")) {
+ return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator + className + "Mapper.xml";
+ }
+
+ if (template.contains("menu.sql.vm")) {
+ return className.toLowerCase() + "_menu.sql";
+ }
+
+ if (template.contains("list.html.vm")) {
+ return "main" + File.separator + "resources" + File.separator + "templates" + File.separator + className.toLowerCase() + File.separator + "list" + ".html";
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/common/utils/HttpContextUtils.java b/src/main/java/com/huoran/iasf/common/utils/HttpContextUtils.java
new file mode 100644
index 0000000..dae9e64
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/HttpContextUtils.java
@@ -0,0 +1,32 @@
+package com.huoran.iasf.common.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+/**
+ * HttpContextUtils
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public class HttpContextUtils {
+
+ public static HttpServletRequest getHttpServletRequest() {
+ return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+ }
+
+ public static boolean isAjaxRequest(HttpServletRequest request) {
+
+ String accept = request.getHeader("accept");
+ String xRequestedWith = request.getHeader("X-Requested-With");
+
+ // 如果是异步请求或是手机端,则直接返回信息
+ return ((accept != null && accept.contains("application/json")
+ || (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
+ ));
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/common/utils/IPUtils.java b/src/main/java/com/huoran/iasf/common/utils/IPUtils.java
new file mode 100644
index 0000000..f0d0f48
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/IPUtils.java
@@ -0,0 +1,73 @@
+package com.huoran.iasf.common.utils;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * IPUtils
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public class IPUtils {
+
+ private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
+
+ /**
+ * 获取IP地址
+ *
+ * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
+ * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
+ */
+ public static String getIpAddr(HttpServletRequest request) {
+ String ip = null;
+ try {
+ ip = request.getHeader("x-forwarded-for");
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ }
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ } catch (Exception e) {
+ logger.error("IPUtils ERROR ", e);
+ }
+
+ // 使用代理,则获取第一个IP地址
+ if (!StringUtils.isEmpty(ip) && ip.length() > 15) {
+ if (ip.indexOf(",") > 0) {
+ ip = ip.substring(0, ip.indexOf(","));
+ }
+ }
+
+ return ip;
+ }
+
+ /**
+ * 获取客户端主机名称
+ */
+ public static String getHostName() {
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ logger.error(e.getMessage(), e);
+ }
+ return "未知";
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/common/utils/OkHttpUtils.java b/src/main/java/com/huoran/iasf/common/utils/OkHttpUtils.java
new file mode 100644
index 0000000..ded155d
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/OkHttpUtils.java
@@ -0,0 +1,299 @@
+package com.huoran.iasf.common.utils;
+
+import com.alibaba.fastjson.JSON;
+import okhttp3.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Ok http utils
+ * @author cheney.li
+ */
+public class OkHttpUtils {
+ private static OkHttpClient okHttpClient;
+ private static Semaphore semaphore;
+ private Map headerMap;
+ private Map paramMap;
+ private String url;
+ private Request.Builder request;
+ private static final String ERROR_MESSAGE = "OkHttpUtils error:{}";
+ private static final Logger logger = LoggerFactory.getLogger(OkHttpUtils.class);
+ /**
+ * 初始化okHttpClient,并且允许https访问
+ */
+ private OkHttpUtils() {
+ if (okHttpClient == null) {
+ synchronized (OkHttpUtils.class) {
+ okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(20, TimeUnit.SECONDS)
+ .retryOnConnectionFailure(true)
+ .build();
+ addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
+ }
+ }
+ }
+
+ /**
+ * 用于异步请求时,控制访问线程数,返回结果
+ *
+ * @return
+ */
+ private static Semaphore getSemaphoreInstance() {
+ //只能1个线程同时访问
+ synchronized (OkHttpUtils.class) {
+ if (semaphore == null) {
+ semaphore = new Semaphore(0);
+ }
+ }
+ return semaphore;
+ }
+
+ /**
+ * 创建OkHttpUtils
+ *
+ * @return ok http utils
+ */
+ public static OkHttpUtils builder() {
+ return new OkHttpUtils();
+ }
+
+ /**
+ * 添加url
+ *
+ * @param url url
+ * @return ok http utils
+ */
+ public OkHttpUtils url(String url) {
+ this.url = url;
+ return this;
+ }
+
+ /**
+ * 添加参数
+ *
+ * @param key 参数名
+ * @param value 参数值
+ * @return ok http utils
+ */
+ public OkHttpUtils addParam(String key, String value) {
+ if (paramMap == null) {
+ paramMap = new LinkedHashMap<>(16);
+ }
+ paramMap.put(key, value);
+ return this;
+ }
+ /**
+ * 添加参数
+ *
+ * @param map map
+ * @return ok http utils
+ */
+ public OkHttpUtils addMap(Map map) {
+ if (paramMap == null) {
+ paramMap = new LinkedHashMap<>(16);
+ }
+ paramMap.putAll(map);
+ return this;
+ }
+ /**
+ * 添加请求头
+ *
+ * @param key 参数名
+ * @param value 参数值
+ * @return ok addHeader utils
+ */
+ public OkHttpUtils addHeader(String key, String value) {
+ if (headerMap == null) {
+ headerMap = new LinkedHashMap<>(16);
+ }
+ headerMap.put(key, value);
+ return this;
+ }
+
+ /**
+ * 初始化get方法
+ *
+ * @return ok http utils
+ */
+ public OkHttpUtils get() {
+ request = new Request.Builder().get();
+ StringBuilder urlBuilder = new StringBuilder(url);
+ if (paramMap != null) {
+ urlBuilder.append("?");
+ try {
+ for (Map.Entry entry : paramMap.entrySet()) {
+ urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")).
+ append("=").
+ append(URLEncoder.encode(entry.getValue(), "utf-8")).
+ append("&");
+ }
+ } catch (Exception e) {
+ logger.error(ERROR_MESSAGE, e.getMessage());
+ }
+ urlBuilder.deleteCharAt(urlBuilder.length() - 1);
+ }
+ request.url(urlBuilder.toString());
+ return this;
+ }
+
+ /**
+ * 初始化post方法
+ *
+ * @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw false等于普通的表单提交
+ * @return ok http utils
+ */
+ public OkHttpUtils post(boolean isJsonPost) {
+ RequestBody requestBody;
+ if (isJsonPost) {
+ String json = "";
+ if (paramMap != null) {
+ json = JSON.toJSONString(paramMap);
+ }
+ requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
+ } else {
+ FormBody.Builder formBody = new FormBody.Builder();
+ if (paramMap != null) {
+ paramMap.forEach(formBody::add);
+ }
+ requestBody = formBody.build();
+ }
+ request = new Request.Builder().post(requestBody).url(url);
+ return this;
+ }
+
+ /**
+ * 同步请求
+ *
+ * @return string
+ */
+ public String sync() {
+ setHeader(request);
+ try {
+ Response response = okHttpClient.newCall(request.build()).execute();
+ assert response.body() != null;
+ return response.body().string();
+ } catch (IOException e) {
+ return "请求失败:" + e.getMessage();
+ }
+ }
+
+ /**
+ * 异步请求,有返回值
+ *
+ * @return the string
+ */
+ public String async() {
+ StringBuilder buffer = new StringBuilder("");
+ setHeader(request);
+ okHttpClient.newCall(request.build()).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ buffer.append("请求出错:").append(e.getMessage());
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (response.body() != null) {
+ buffer.append(response.body().string());
+ getSemaphoreInstance().release();
+ }
+ }
+ });
+ try {
+ getSemaphoreInstance().acquire();
+ } catch (Exception e) {
+ logger.error(ERROR_MESSAGE, e.getMessage());
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * 异步请求,带有接口回调
+ *
+ * @param callBack call back
+ */
+ public void async(ICallBack callBack) {
+ setHeader(request);
+ okHttpClient.newCall(request.build()).enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ callBack.onFailure(call, e.getMessage());
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (response.body() != null) {
+ callBack.onSuccessful(call, response.body().string());
+ }
+ }
+ });
+ }
+
+ /**
+ * 为request添加请求头
+ *
+ * @param request
+ */
+ private void setHeader(Request.Builder request) {
+ if (headerMap != null) {
+ try {
+ for (Map.Entry entry : headerMap.entrySet()) {
+ request.addHeader(entry.getKey(), entry.getValue());
+ }
+ } catch (Exception e) {
+ logger.error(ERROR_MESSAGE, e.getMessage());
+ }
+ }
+ }
+
+
+ /**
+ * 自定义一个接口回调
+ */
+ public interface ICallBack {
+
+ /**
+ * On successful *
+ *
+ * @param call call
+ * @param data data
+ */
+ void onSuccessful(Call call, String data);
+
+ /**
+ * On failure *
+ *
+ * @param call call
+ * @param errorMsg error msg
+ */
+ void onFailure(Call call, String errorMsg);
+
+ }
+
+ /**
+ * Main
+ *
+ * @param args args
+ */
+ public static void main(String[] args) {
+ String tokenJson = OkHttpUtils.builder()
+ .url("https://10.1.50.198")
+ .addParam("client_id", "pbase_account")
+ .addParam("client_secret", "bed0bfd22d87b7bbab9b1d43191ddd57")
+ .addParam("grant_type", "client_credentials")
+ .post(false)
+ .sync();
+ logger.info(tokenJson);
+ }
+}
+
+
diff --git a/src/main/java/com/huoran/iasf/common/utils/PasswordEncoder.java b/src/main/java/com/huoran/iasf/common/utils/PasswordEncoder.java
new file mode 100644
index 0000000..0d5a677
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/PasswordEncoder.java
@@ -0,0 +1,117 @@
+package com.huoran.iasf.common.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+
+/**
+ * 密码加密
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public class PasswordEncoder {
+
+ private static Logger logger = LoggerFactory.getLogger(PasswordEncoder.class);
+
+
+ private final static String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
+ "e", "f"};
+
+ private final static String MD5 = "MD5";
+
+ private Object salt;
+ private String algorithm;
+
+ public PasswordEncoder(Object salt) {
+ this(salt, MD5);
+ }
+
+ public PasswordEncoder(Object salt, String algorithm) {
+ this.salt = salt;
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * 密码加密
+ *
+ * @param rawPass 密码
+ * @return 加密后
+ */
+ public String encode(String rawPass) {
+ String result = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance(algorithm);
+ // 加密后的字符串
+ result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes(StandardCharsets.UTF_8)));
+ } catch (Exception e) {
+ logger.error(e.toString(), e);
+ }
+ return result;
+ }
+
+ /**
+ * 密码匹配验证
+ *
+ * @param encPass 密文
+ * @param rawPass 明文
+ * @return 是否匹配
+ */
+ public boolean matches(String encPass, String rawPass) {
+ String pass1 = "" + encPass;
+ String pass2 = encode(rawPass);
+
+ return pass1.equals(pass2);
+ }
+
+ private String mergePasswordAndSalt(String password) {
+ if (password == null) {
+ password = "";
+ }
+
+ if ((salt == null) || "".equals(salt)) {
+ return password;
+ } else {
+ return password + "{" + salt.toString() + "}";
+ }
+ }
+
+ /**
+ * 转换字节数组为16进制字串
+ *
+ * @param b 字节数组
+ * @return 16进制字串
+ */
+ private String byteArrayToHexString(byte[] b) {
+ StringBuilder resultSb = new StringBuilder();
+ for (byte value : b) {
+ resultSb.append(byteToHexString(value));
+ }
+ return resultSb.toString();
+ }
+
+ /**
+ * 将字节转换为16进制
+ *
+ * @param b 字节
+ * @return 16进制
+ */
+ private static String byteToHexString(byte b) {
+ int n = b;
+ if (n < 0) {
+ n = 256 + n;
+ }
+ int d1 = n / 16;
+ int d2 = n % 16;
+ return HEX_DIGITS[d1] + HEX_DIGITS[d2];
+ }
+
+ public static void main(String[] args) {
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/common/utils/PasswordUtils.java b/src/main/java/com/huoran/iasf/common/utils/PasswordUtils.java
new file mode 100644
index 0000000..6c358e6
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/PasswordUtils.java
@@ -0,0 +1,47 @@
+package com.huoran.iasf.common.utils;
+
+import java.util.UUID;
+
+
+/**
+ * 密码工具类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public class PasswordUtils {
+
+ /**
+ * 匹配密码
+ *
+ * @param salt 盐
+ * @param rawPass 明文
+ * @param encPass 密文
+ * @return 是否匹配
+ */
+ public static boolean matches(String salt, String rawPass, String encPass) {
+ return new PasswordEncoder(salt).matches(encPass, rawPass);
+ }
+
+ /**
+ * 明文密码加密
+ *
+ * @param rawPass 明文
+ * @param salt 盐
+ * @reture 加密后
+ */
+ public static String encode(String rawPass, String salt) {
+ return new PasswordEncoder(salt).encode(rawPass);
+ }
+
+ /**
+ * 获取加密盐
+ *
+ * @return 盐值
+ */
+ public static String getSalt() {
+ return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/common/utils/R.java b/src/main/java/com/huoran/iasf/common/utils/R.java
new file mode 100644
index 0000000..85ce28b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/R.java
@@ -0,0 +1,113 @@
+package com.huoran.iasf.common.utils;
+
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.common.exception.code.ResponseCodeInterface;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 返回值R
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class R {
+
+
+
+ /**
+ * 请求响应code,0为成功 其他为失败
+ */
+ @ApiModelProperty(value = "请求响应code,200为成功 其他为失败", name = "code")
+ private int code;
+
+ /**
+ * 响应异常码详细信息
+ */
+ @ApiModelProperty(value = "响应异常码详细信息", name = "msg")
+ private String msg;
+
+ @ApiModelProperty(value = "需要返回的数据", name = "data")
+ private Object data;
+
+ public R(int code, Object data) {
+ this.code = code;
+ this.data = data;
+ this.msg = null;
+ }
+
+ public R(int code, String msg, Object data) {
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public R(int code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ this.data = null;
+ }
+
+ public R() {
+ this.code = BaseResponseCode.SUCCESS.getCode();
+ this.msg = BaseResponseCode.SUCCESS.getMsg();
+ this.data = null;
+ }
+
+ public R(Object data) {
+ this.data = data;
+ this.code = BaseResponseCode.SUCCESS.getCode();
+ this.msg = BaseResponseCode.SUCCESS.getMsg();
+ }
+
+ public R(ResponseCodeInterface responseCodeInterface) {
+ this.data = null;
+ this.code = responseCodeInterface.getCode();
+ this.msg = responseCodeInterface.getMsg();
+ }
+
+ public R(ResponseCodeInterface responseCodeInterface, Object data) {
+ this.data = data;
+ this.code = responseCodeInterface.getCode();
+ this.msg = responseCodeInterface.getMsg();
+ }
+
+ /**
+ * 操作成功 data为null
+ */
+ public static R success() {
+ return new R();
+ }
+
+ /**
+ * 操作成功 data 不为null
+ */
+ public static R success(Object data) {
+ return new R(data);
+ }
+
+ /**
+ * 操作失败 data 不为null
+ */
+ public static R fail(String msg) {
+ return new R(BaseResponseCode.OPERATION_ERROR.getCode(), msg);
+ }
+
+ /**
+ * 自定义返回 data为null
+ */
+ public static R getResult(int code, String msg) {
+ return new R(code, msg);
+ }
+
+ /**
+ * 自定义返回 入参一般是异常code枚举 data为空
+ */
+ public static R getResult(BaseResponseCode responseCode) {
+ return new R(responseCode);
+ }
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/common/utils/SpringContextUtils.java b/src/main/java/com/huoran/iasf/common/utils/SpringContextUtils.java
new file mode 100644
index 0000000..fe5c931
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/SpringContextUtils.java
@@ -0,0 +1,33 @@
+package com.huoran.iasf.common.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * SpringContextUtils
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+ private static ApplicationContext applicationContext;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ SpringContextUtils.applicationContext = applicationContext;
+ }
+
+ public static Object getBean(String name) {
+ try {
+ return applicationContext.getBean(name);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/common/utils/ValidatorUtils.java b/src/main/java/com/huoran/iasf/common/utils/ValidatorUtils.java
new file mode 100644
index 0000000..c485355
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/common/utils/ValidatorUtils.java
@@ -0,0 +1,53 @@
+package com.huoran.iasf.common.utils;
+
+
+import com.huoran.iasf.common.exception.BusinessException;
+import org.apache.commons.lang.StringUtils;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Set;
+
+/**
+ * hibernate-validator校验工具类
+ *
+ */
+public class ValidatorUtils {
+ private static Validator validator;
+
+ static {
+ validator = Validation.buildDefaultValidatorFactory().getValidator();
+ }
+
+ /**
+ * 校验对象
+ * @param object 待校验对象
+ * @param groups 待校验的组
+ * @throws BusinessException 校验不通过,则报RRException异常
+ */
+ public static void validateEntity(Object object, Class>... groups)
+ throws BusinessException {
+ Set> constraintViolations = validator.validate(object, groups);
+ if (!constraintViolations.isEmpty()) {
+ ConstraintViolation constraint = (ConstraintViolation)constraintViolations.iterator().next();
+ throw new BusinessException(constraint.getMessage());
+ }
+ }
+
+ /**
+ * 空判断处理
+ * @param str
+ * @param message
+ */
+ public static void isBlank(Object str, String message) {
+ if (str == null) {
+ throw new BusinessException(message);
+ }
+ if (str instanceof String) {
+ if (StringUtils.isBlank(String.valueOf(str))) {
+ throw new BusinessException(message);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/CaptchaController.java b/src/main/java/com/huoran/iasf/controller/CaptchaController.java
new file mode 100644
index 0000000..f02fc59
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/CaptchaController.java
@@ -0,0 +1,41 @@
+package com.huoran.iasf.controller;
+
+import com.wf.captcha.ArithmeticCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 验证码相关
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Api(tags = "验证码相关")
+@RestController
+@Slf4j
+@RequestMapping("/sys")
+public class CaptchaController {
+ /**
+ * 获取验证码图片
+ * Gets captcha code.
+ *
+ * @param request the request
+ * @param response the response
+ * @throws IOException the io exception
+ */
+ @RequestMapping("/getVerify")
+ public void getCaptchaCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48);
+ captcha.setLen(2);
+ CaptchaUtil.out(captcha, request, response);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/DeptController.java b/src/main/java/com/huoran/iasf/controller/DeptController.java
new file mode 100644
index 0000000..eaff5e8
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/DeptController.java
@@ -0,0 +1,93 @@
+package com.huoran.iasf.controller;
+
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysDept;
+import com.huoran.iasf.service.DeptService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 部门管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RequestMapping("/sys")
+@RestController
+@Api(tags = "组织模块-机构管理")
+public class DeptController {
+ @Resource
+ private DeptService deptService;
+
+ @PostMapping("/dept")
+ @ApiOperation(value = "新增组织接口")
+ @LogAnnotation(title = "机构管理", action = "新增组织")
+ @RequiresPermissions("sys:dept:add")
+ public R addDept(@RequestBody @Valid SysDept vo) {
+ deptService.addDept(vo);
+ return R.success();
+ }
+
+ @DeleteMapping("/dept/{id}")
+ @ApiOperation(value = "删除组织接口")
+ @LogAnnotation(title = "机构管理", action = "删除组织")
+ @RequiresPermissions("sys:dept:deleted")
+ public R deleted(@PathVariable("id") String id) {
+ deptService.deleted(id);
+ return R.success();
+ }
+
+ @PutMapping("/dept")
+ @ApiOperation(value = "更新组织信息接口")
+ @LogAnnotation(title = "机构管理", action = "更新组织信息")
+ @RequiresPermissions("sys:dept:update")
+ public R updateDept(@RequestBody SysDept vo) {
+ if (StringUtils.isEmpty(vo.getId())) {
+ return R.fail("id不能为空");
+ }
+ deptService.updateDept(vo);
+ return R.success();
+ }
+
+ @GetMapping("/dept/{id}")
+ @ApiOperation(value = "查询组织详情接口")
+ @LogAnnotation(title = "机构管理", action = "查询组织详情")
+ @RequiresPermissions("sys:dept:detail")
+ public R detailInfo(@PathVariable("id") String id) {
+ return R.success(deptService.getById(id));
+ }
+
+ @GetMapping("/dept/tree")
+ @ApiOperation(value = "树型组织列表接口")
+ @LogAnnotation(title = "机构管理", action = "树型组织列表")
+ @RequiresPermissions(value = {"sys:user:list", "sys:user:update", "sys:user:add", "sys:dept:add", "sys:dept:update"}, logical = Logical.OR)
+ public R getTree(@RequestParam(required = false) String deptId) {
+ return R.success(deptService.deptTreeList(deptId, false));
+ }
+
+ @GetMapping("/depts")
+ @ApiOperation(value = "获取机构列表接口")
+ @LogAnnotation(title = "机构管理", action = "获取所有组织机构")
+ @RequiresPermissions("sys:dept:list")
+ public R getDeptAll() {
+ List deptList = deptService.list();
+ deptList.parallelStream().forEach(entity -> {
+ SysDept parentDept = deptService.getById(entity.getPid());
+ if (parentDept != null) {
+ entity.setPidName(parentDept.getName());
+ }
+ });
+ return R.success(deptList);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/HomeController.java b/src/main/java/com/huoran/iasf/controller/HomeController.java
new file mode 100644
index 0000000..51d15b2
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/HomeController.java
@@ -0,0 +1,40 @@
+package com.huoran.iasf.controller;
+
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.service.HomeService;
+import com.huoran.iasf.service.HttpSessionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+
+/**
+ * 首页
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RestController
+@RequestMapping("/sys")
+@Api(tags = "首页数据")
+public class HomeController {
+ @Resource
+ private HomeService homeService;
+ @Resource
+ private HttpSessionService httpSessionService;
+
+ @GetMapping("/home")
+ @ApiOperation(value = "获取首页数据接口")
+ public R getHomeInfo() {
+ //通过access_token拿userId
+ String userId = httpSessionService.getCurrentUserId();
+ R result = R.success();
+ result.setData(homeService.getHomeInfo(userId));
+ return result;
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/PermissionController.java b/src/main/java/com/huoran/iasf/controller/PermissionController.java
new file mode 100644
index 0000000..dace6ff
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/PermissionController.java
@@ -0,0 +1,148 @@
+package com.huoran.iasf.controller;
+
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.exception.BusinessException;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysPermission;
+import com.huoran.iasf.service.PermissionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * 菜单权限管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RequestMapping("/sys")
+@RestController
+@Api(tags = "组织模块-菜单权限管理")
+public class PermissionController {
+
+ @Resource
+ private PermissionService permissionService;
+
+ @PostMapping("/permission")
+ @ApiOperation(value = "新增菜单权限接口")
+ @LogAnnotation(title = "菜单权限管理", action = "新增菜单权限")
+ @RequiresPermissions("sys:permission:add")
+ public R addPermission(@RequestBody @Valid SysPermission vo) {
+ verifyFormPid(vo);
+ vo.setStatus(1);
+ permissionService.save(vo);
+ return R.success();
+ }
+
+ @DeleteMapping("/permission/{id}")
+ @ApiOperation(value = "删除菜单权限接口")
+ @LogAnnotation(title = "菜单权限管理", action = "删除菜单权限")
+ @RequiresPermissions("sys:permission:deleted")
+ public R deleted(@PathVariable("id") String id) {
+ permissionService.deleted(id);
+ return R.success();
+ }
+
+ @PutMapping("/permission")
+ @ApiOperation(value = "更新菜单权限接口")
+ @LogAnnotation(title = "菜单权限管理", action = "更新菜单权限")
+ @RequiresPermissions("sys:permission:update")
+ public R updatePermission(@RequestBody @Valid SysPermission vo) {
+ if (StringUtils.isEmpty(vo.getId())) {
+ return R.fail("id不能为空");
+ }
+ SysPermission sysPermission = permissionService.getById(vo.getId());
+ if (null == sysPermission) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ // 只有类型变更或者所属菜单变更
+ if (sysPermission.getType().equals(vo.getType()) || !sysPermission.getPid().equals(vo.getPid())) {
+ verifyFormPid(vo);
+ }
+ permissionService.updatePermission(vo);
+ return R.success();
+ }
+
+ @GetMapping("/permission/{id}")
+ @ApiOperation(value = "查询菜单权限接口")
+ @LogAnnotation(title = "菜单权限管理", action = "查询菜单权限")
+ @RequiresPermissions("sys:permission:detail")
+ public R detailInfo(@PathVariable("id") String id) {
+ return R.success(permissionService.getById(id));
+
+ }
+
+ @GetMapping("/permissions")
+ @ApiOperation(value = "获取所有菜单权限接口")
+ @LogAnnotation(title = "菜单权限管理", action = "获取所有菜单权限")
+ @RequiresPermissions("sys:permission:list")
+ public R getAllMenusPermission() {
+ return R.success(permissionService.selectAll());
+ }
+
+ @GetMapping("/permission/tree")
+ @ApiOperation(value = "获取所有目录菜单树接口")
+ @LogAnnotation(title = "菜单权限管理", action = "获取所有目录菜单树")
+ @RequiresPermissions(value = {"sys:permission:update", "sys:permission:add"}, logical = Logical.OR)
+ public R getAllMenusPermissionTree(@RequestParam(required = false) String permissionId) {
+ return R.success(permissionService.selectAllMenuByTree(permissionId));
+ }
+
+ @GetMapping("/permission/tree/all")
+ @ApiOperation(value = "获取所有目录菜单树接口")
+ @LogAnnotation(title = "菜单权限管理", action = "获取所有目录菜单树")
+ @RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR)
+ public R getAllPermissionTree() {
+ return R.success(permissionService.selectAllByTree());
+ }
+
+ /**
+ * 操作后的菜单类型是目录的时候 父级必须为目录
+ * 操作后的菜单类型是菜单的时候,父类必须为目录类型
+ * 操作后的菜单类型是按钮的时候 父类必须为菜单类型
+ */
+ private void verifyFormPid(SysPermission sysPermission) {
+ SysPermission parent;
+ parent = permissionService.getById(sysPermission.getPid());
+ switch (sysPermission.getType()) {
+ case 1:
+ if (parent != null) {
+ if (parent.getType() != 1) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_CATALOG_ERROR);
+ }
+ } else if (!"0".equals(sysPermission.getPid())) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_CATALOG_ERROR);
+ }
+ break;
+ case 2:
+ if (parent == null || parent.getType() != 1) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_MENU_ERROR);
+ }
+ if (StringUtils.isEmpty(sysPermission.getUrl())) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_URL_NOT_NULL);
+ }
+
+ break;
+ case 3:
+ if (parent == null || parent.getType() != 2) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_BTN_ERROR);
+ }
+ if (StringUtils.isEmpty(sysPermission.getPerms())) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_URL_PERMS_NULL);
+ }
+ if (StringUtils.isEmpty(sysPermission.getUrl())) {
+ throw new BusinessException(BaseResponseCode.OPERATION_MENU_PERMISSION_URL_NOT_NULL);
+ }
+ break;
+ default:
+ }
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/RoleController.java b/src/main/java/com/huoran/iasf/controller/RoleController.java
new file mode 100644
index 0000000..5cdfbd2
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/RoleController.java
@@ -0,0 +1,132 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysRole;
+import com.huoran.iasf.entity.SysRoleDeptEntity;
+import com.huoran.iasf.service.RoleService;
+import com.huoran.iasf.service.SysRoleDeptService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 角色管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RequestMapping("/sys")
+@RestController
+@Api(tags = "组织模块-角色管理")
+public class RoleController {
+ @Resource
+ private RoleService roleService;
+ @Resource
+ private SysRoleDeptService sysRoleDeptService;
+
+ @PostMapping("/role")
+ @ApiOperation(value = "新增角色接口")
+ @LogAnnotation(title = "角色管理", action = "新增角色")
+ @RequiresPermissions("sys:role:add")
+ public R addRole(@RequestBody @Valid SysRole vo) {
+ roleService.addRole(vo);
+ return R.success();
+ }
+
+ @DeleteMapping("/role/{id}")
+ @ApiOperation(value = "删除角色接口")
+ @LogAnnotation(title = "角色管理", action = "删除角色")
+ @RequiresPermissions("sys:role:deleted")
+ public R deleted(@PathVariable("id") String id) {
+ roleService.deletedRole(id);
+ return R.success();
+ }
+
+ @PutMapping("/role")
+ @ApiOperation(value = "更新角色信息接口")
+ @LogAnnotation(title = "角色管理", action = "更新角色信息")
+ @RequiresPermissions("sys:role:update")
+ public R updateDept(@RequestBody SysRole vo) {
+ if (StringUtils.isEmpty(vo.getId())) {
+ return R.fail("id不能为空");
+ }
+ roleService.updateRole(vo);
+ return R.success();
+ }
+
+ @PostMapping("/role/bindDept")
+ @ApiOperation(value = "绑定角色部门接口")
+ @LogAnnotation(title = "角色管理", action = "绑定角色部门信息")
+ @RequiresPermissions("sys:role:bindDept")
+ public R bindDept(@RequestBody SysRole vo) {
+ if (StringUtils.isEmpty(vo.getId())) {
+ return R.fail("id不能为空");
+ }
+ if (roleService.getById(vo.getId()) == null) {
+ return R.fail("获取角色失败");
+ }
+
+ //先删除所有绑定
+ sysRoleDeptService.remove(Wrappers.lambdaQuery().eq(SysRoleDeptEntity::getRoleId, vo.getId()));
+ //如果不是自定义
+ if (vo.getDataScope() != 2) {
+ vo.setDepts(null);
+ }
+ if (!CollectionUtils.isEmpty(vo.getDepts())) {
+ List list = new ArrayList<>();
+ for (String deptId : vo.getDepts()) {
+ SysRoleDeptEntity sysRoleDeptEntity = new SysRoleDeptEntity();
+ sysRoleDeptEntity.setDeptId(deptId);
+ sysRoleDeptEntity.setRoleId(vo.getId());
+ list.add(sysRoleDeptEntity);
+ }
+ sysRoleDeptService.saveBatch(list);
+ }
+ roleService.updateById(new SysRole().setId(vo.getId()).setDataScope(vo.getDataScope()));
+ return R.success();
+ }
+
+ @GetMapping("/role/{id}")
+ @ApiOperation(value = "查询角色详情接口")
+ @LogAnnotation(title = "角色管理", action = "查询角色详情")
+ @RequiresPermissions("sys:role:detail")
+ public R detailInfo(@PathVariable("id") String id) {
+ return R.success(roleService.detailInfo(id));
+ }
+
+ @PostMapping("/roles")
+ @ApiOperation(value = "分页获取角色信息接口")
+ @LogAnnotation(title = "角色管理", action = "分页获取角色信息")
+ @RequiresPermissions("sys:role:list")
+ @SuppressWarnings("unchecked")
+ public R pageInfo(@RequestBody SysRole vo) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ if (!StringUtils.isEmpty(vo.getName())) {
+ queryWrapper.like(SysRole::getName, vo.getName());
+ }
+ if (!StringUtils.isEmpty(vo.getStartTime())) {
+ queryWrapper.gt(SysRole::getCreateTime, vo.getStartTime());
+ }
+ if (!StringUtils.isEmpty(vo.getEndTime())) {
+ queryWrapper.lt(SysRole::getCreateTime, vo.getEndTime());
+ }
+ if (!StringUtils.isEmpty(vo.getStatus())) {
+ queryWrapper.eq(SysRole::getStatus, vo.getStatus());
+ }
+ queryWrapper.orderByDesc(SysRole::getCreateTime);
+ return R.success(roleService.page(vo.getQueryPage(), queryWrapper));
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/RolePermissionController.java b/src/main/java/com/huoran/iasf/controller/RolePermissionController.java
new file mode 100644
index 0000000..a3ad721
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/RolePermissionController.java
@@ -0,0 +1,41 @@
+package com.huoran.iasf.controller;
+
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.service.RolePermissionService;
+import com.huoran.iasf.vo.req.RolePermissionOperationReqVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * 角色和菜单关联
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RequestMapping("/sys")
+@RestController
+@Api(tags = "组织管理-角色和菜单关联接口")
+public class RolePermissionController {
+ @Resource
+ private RolePermissionService rolePermissionService;
+
+ @PostMapping("/role/permission")
+ @ApiOperation(value = "修改或者新增角色菜单权限接口")
+ @LogAnnotation(title = "角色和菜单关联接口", action = "修改或者新增角色菜单权限")
+ @RequiresPermissions(value = {"sys:role:update", "sys:role:add"}, logical = Logical.OR)
+ public R operationRolePermission(@RequestBody @Valid RolePermissionOperationReqVO vo) {
+ rolePermissionService.addRolePermission(vo);
+ return R.success();
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysContentController.java b/src/main/java/com/huoran/iasf/controller/SysContentController.java
new file mode 100644
index 0000000..310770b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysContentController.java
@@ -0,0 +1,79 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.aop.annotation.DataScope;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysContentEntity;
+import com.huoran.iasf.service.SysContentService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * 文章管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Api(tags = "文章管理")
+@RestController
+@RequestMapping("/sysContent")
+public class SysContentController {
+ @Resource
+ private SysContentService sysContentService;
+
+
+ @ApiOperation(value = "新增")
+ @PostMapping("/add")
+ @RequiresPermissions("sysContent:add")
+ public R add(@RequestBody SysContentEntity sysContent) {
+ sysContentService.save(sysContent);
+ return R.success();
+ }
+
+ @ApiOperation(value = "删除")
+ @DeleteMapping("/delete")
+ @RequiresPermissions("sysContent:delete")
+ public R delete(@RequestBody @ApiParam(value = "id集合") List ids) {
+ sysContentService.removeByIds(ids);
+ return R.success();
+ }
+
+ @ApiOperation(value = "更新")
+ @PutMapping("/update")
+ @RequiresPermissions("sysContent:update")
+ public R update(@RequestBody SysContentEntity sysContent) {
+ sysContentService.updateById(sysContent);
+ return R.success();
+ }
+
+ @ApiOperation(value = "查询分页数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysContent:list")
+ @DataScope
+ public R findListByPage(@RequestBody SysContentEntity sysContent) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ //查询条件示例
+ if (!StringUtils.isEmpty(sysContent.getTitle())) {
+ queryWrapper.like(SysContentEntity::getTitle, sysContent.getTitle());
+ }
+ //数据权限示例, 需手动添加此条件 begin
+ if (!CollectionUtils.isEmpty(sysContent.getCreateIds())) {
+ queryWrapper.in(SysContentEntity::getCreateId, sysContent.getCreateIds());
+ }
+ //数据权限示例, 需手动添加此条件 end
+ IPage iPage = sysContentService.page(sysContent.getQueryPage(), queryWrapper);
+ return R.success(iPage);
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysDictController.java b/src/main/java/com/huoran/iasf/controller/SysDictController.java
new file mode 100644
index 0000000..3d10db1
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysDictController.java
@@ -0,0 +1,96 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysDictDetailEntity;
+import com.huoran.iasf.entity.SysDictEntity;
+import com.huoran.iasf.service.SysDictDetailService;
+import com.huoran.iasf.service.SysDictService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * 字典管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+// @Api(tags = "字典管理")
+// @RestController
+// @RequestMapping("/sysDict")
+public class SysDictController {
+ @Resource
+ private SysDictService sysDictService;
+ @Resource
+ private SysDictDetailService sysDictDetailService;
+
+
+ @ApiOperation(value = "新增")
+ @PostMapping("/add")
+ @RequiresPermissions("sysDict:add")
+ public R add(@RequestBody SysDictEntity sysDict) {
+ if (StringUtils.isEmpty(sysDict.getName())) {
+ return R.fail("字典名称不能为空");
+ }
+ SysDictEntity q = sysDictService.getOne(Wrappers.lambdaQuery().eq(SysDictEntity::getName, sysDict.getName()));
+ if (q != null) {
+ return R.fail("字典名称已存在");
+ }
+ sysDictService.save(sysDict);
+ return R.success();
+ }
+
+ @ApiOperation(value = "删除")
+ @DeleteMapping("/delete")
+ @RequiresPermissions("sysDict:delete")
+ public R delete(@RequestBody @ApiParam(value = "id集合") List ids) {
+ sysDictService.removeByIds(ids);
+ //删除detail
+ sysDictDetailService.remove(Wrappers.lambdaQuery().in(SysDictDetailEntity::getDictId, ids));
+ return R.success();
+ }
+
+ @ApiOperation(value = "更新")
+ @PutMapping("/update")
+ @RequiresPermissions("sysDict:update")
+ public R update(@RequestBody SysDictEntity sysDict) {
+ if (StringUtils.isEmpty(sysDict.getName())) {
+ return R.fail("字典名称不能为空");
+ }
+
+ SysDictEntity q = sysDictService.getOne(Wrappers.lambdaQuery().eq(SysDictEntity::getName, sysDict.getName()));
+ if (q != null && !q.getId().equals(sysDict.getId())) {
+ return R.fail("字典名称已存在");
+ }
+
+ sysDictService.updateById(sysDict);
+ return R.success();
+ }
+
+ @ApiOperation(value = "查询分页数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysDict:list")
+ public R findListByPage(@RequestBody SysDictEntity sysDict) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ //查询条件示例
+ if (!StringUtils.isEmpty(sysDict.getName())) {
+ queryWrapper.like(SysDictEntity::getName, sysDict.getName());
+ queryWrapper.or();
+ queryWrapper.like(SysDictEntity::getRemark, sysDict.getName());
+ }
+ queryWrapper.orderByAsc(SysDictEntity::getName);
+ IPage iPage = sysDictService.page(sysDict.getQueryPage(), queryWrapper);
+ return R.success(iPage);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysDictDetailController.java b/src/main/java/com/huoran/iasf/controller/SysDictDetailController.java
new file mode 100644
index 0000000..fe39b26
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysDictDetailController.java
@@ -0,0 +1,90 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysDictDetailEntity;
+import com.huoran.iasf.service.SysDictDetailService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * 字典明细管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+// @Api(tags = "字典明细管理")
+// @RestController
+// @RequestMapping("/sysDictDetail")
+public class SysDictDetailController {
+ @Resource
+ private SysDictDetailService sysDictDetailService;
+
+ @ApiOperation(value = "新增")
+ @PostMapping("/add")
+ @RequiresPermissions("sysDict:add")
+ public R add(@RequestBody SysDictDetailEntity sysDictDetail) {
+ if (StringUtils.isEmpty(sysDictDetail.getValue())) {
+ return R.fail("字典值不能为空");
+ }
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ queryWrapper.eq(SysDictDetailEntity::getValue, sysDictDetail.getValue());
+ queryWrapper.eq(SysDictDetailEntity::getDictId, sysDictDetail.getDictId());
+ SysDictDetailEntity q = sysDictDetailService.getOne(queryWrapper);
+ if (q != null) {
+ return R.fail("字典名称-字典值已存在");
+ }
+ sysDictDetailService.save(sysDictDetail);
+ return R.success();
+ }
+
+ @ApiOperation(value = "删除")
+ @DeleteMapping("/delete")
+ @RequiresPermissions("sysDict:delete")
+ public R delete(@RequestBody @ApiParam(value = "id集合") List ids) {
+ sysDictDetailService.removeByIds(ids);
+ return R.success();
+ }
+
+ @ApiOperation(value = "更新")
+ @PutMapping("/update")
+ @RequiresPermissions("sysDict:update")
+ public R update(@RequestBody SysDictDetailEntity sysDictDetail) {
+ if (StringUtils.isEmpty(sysDictDetail.getValue())) {
+ return R.fail("字典值不能为空");
+ }
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ queryWrapper.eq(SysDictDetailEntity::getValue, sysDictDetail.getValue());
+ queryWrapper.eq(SysDictDetailEntity::getDictId, sysDictDetail.getDictId());
+ SysDictDetailEntity q = sysDictDetailService.getOne(queryWrapper);
+ if (q != null && !q.getId().equals(sysDictDetail.getId())) {
+ return R.fail("字典名称-字典值已存在");
+ }
+
+ sysDictDetailService.updateById(sysDictDetail);
+ return R.success();
+ }
+
+
+ @ApiOperation(value = "查询列表数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysDict:list")
+ public R findListByPage(@RequestBody SysDictDetailEntity sysDictDetail) {
+ if (StringUtils.isEmpty(sysDictDetail.getDictId())) {
+ return R.success();
+ }
+ IPage iPage = sysDictDetailService.listByPage(sysDictDetail.getQueryPage(), sysDictDetail.getDictId());
+ return R.success(iPage);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysFilesController.java b/src/main/java/com/huoran/iasf/controller/SysFilesController.java
new file mode 100644
index 0000000..5e25340
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysFilesController.java
@@ -0,0 +1,62 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysFilesEntity;
+import com.huoran.iasf.service.SysFilesService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * 文件上传
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RestController
+@RequestMapping("/sysFiles")
+@Api(tags = "文件管理")
+public class SysFilesController {
+ @Resource
+ private SysFilesService sysFilesService;
+
+ @ApiOperation(value = "新增")
+ @PostMapping("/upload")
+ @RequiresPermissions(value = {"sysFiles:add", "sysContent:update", "sysContent:add"}, logical = Logical.OR)
+ public R add(@RequestParam(value = "file") MultipartFile file) {
+ //判断文件是否空
+ if (file == null || file.getOriginalFilename() == null || "".equalsIgnoreCase(file.getOriginalFilename().trim())) {
+ return R.fail("文件为空");
+ }
+ return sysFilesService.saveFile(file);
+ }
+
+ @ApiOperation(value = "删除")
+ @DeleteMapping("/delete")
+ @RequiresPermissions("sysFiles:delete")
+ public R delete(@RequestBody @ApiParam(value = "id集合") List ids) {
+ sysFilesService.removeByIdsAndFiles(ids);
+ return R.success();
+ }
+
+ @ApiOperation(value = "查询分页数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysFiles:list")
+ public R findListByPage(@RequestBody SysFilesEntity sysFiles) {
+ IPage iPage = sysFilesService.page(sysFiles.getQueryPage(), Wrappers.lambdaQuery().orderByDesc(SysFilesEntity::getCreateDate));
+ return R.success(iPage);
+ }
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysGeneratorController.java b/src/main/java/com/huoran/iasf/controller/SysGeneratorController.java
new file mode 100644
index 0000000..553ffa9
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysGeneratorController.java
@@ -0,0 +1,57 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysGenerator;
+import com.huoran.iasf.service.ISysGeneratorService;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.io.IOUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 代码生成
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+// @Api(tags = "系统模块-代码生成")
+// @Slf4j
+// @RestController
+// @RequestMapping("/sysGenerator")
+public class SysGeneratorController {
+ @Resource
+ private ISysGeneratorService sysGeneratorService;
+
+ /**
+ * 生成代码
+ */
+ @ApiOperation(value = "生成")
+ @GetMapping("/gen")
+ @RequiresPermissions("sysGenerator:add")
+ public void code(String tables, HttpServletResponse response) throws IOException {
+ byte[] data = sysGeneratorService.generatorCode(tables.split(","));
+
+ response.reset();
+ response.setHeader("Content-Disposition", "attachment; filename=\"manager.zip\"");
+ response.addHeader("Content-Length", "" + data.length);
+ response.setContentType("application/octet-stream; charset=UTF-8");
+
+ IOUtils.write(data, response.getOutputStream());
+ }
+
+ @ApiOperation(value = "查询分页数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysGenerator:list")
+ public R findListByPage(@RequestBody SysGenerator vo) {
+ IPage iPage = sysGeneratorService.selectAllTables(vo.getQueryPage(), vo);
+ return R.success(iPage);
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysJobController.java b/src/main/java/com/huoran/iasf/controller/SysJobController.java
new file mode 100644
index 0000000..5da08c2
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysJobController.java
@@ -0,0 +1,178 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.common.job.utils.ScheduleJob;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysJobEntity;
+import com.huoran.iasf.service.SysJobService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.quartz.TriggerUtils;
+import org.quartz.impl.triggers.CronTriggerImpl;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 定时任务
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+// @Api(tags = "定时任务")
+// @RestController
+// @RequestMapping("/sysJob")
+public class SysJobController {
+ @Resource
+ private SysJobService sysJobService;
+
+ @ApiOperation(value = "新增")
+ @LogAnnotation(title = "新增")
+ @PostMapping("/add")
+ @RequiresPermissions("sysJob:add")
+ public R add(@RequestBody SysJobEntity sysJob) {
+ if (isValidExpression(sysJob.getCronExpression())) {
+ return R.fail("cron表达式有误");
+ }
+ R R = ScheduleJob.judgeBean(sysJob.getBeanName());
+ if (BaseResponseCode.SUCCESS.getCode() != R.getCode()) {
+ return R;
+ }
+
+ sysJobService.saveJob(sysJob);
+ return R.success();
+ }
+
+ @ApiOperation(value = "删除")
+ @DeleteMapping("/delete")
+ @RequiresPermissions("sysJob:delete")
+ @LogAnnotation(title = "删除")
+ public R delete(@RequestBody @ApiParam(value = "id集合") List ids) {
+ sysJobService.delete(ids);
+ return R.success();
+ }
+
+ @ApiOperation(value = "更新")
+ @PutMapping("/update")
+ @RequiresPermissions("sysJob:update")
+ @LogAnnotation(title = "更新")
+ public R update(@RequestBody SysJobEntity sysJob) {
+ if (isValidExpression(sysJob.getCronExpression())) {
+ return R.fail("cron表达式有误");
+ }
+ R R = ScheduleJob.judgeBean(sysJob.getBeanName());
+ if (BaseResponseCode.SUCCESS.getCode() != R.getCode()) {
+ return R;
+ }
+
+ sysJobService.updateJobById(sysJob);
+ return R.success();
+ }
+
+ @ApiOperation(value = "查询分页数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysJob:list")
+ public R findListByPage(@RequestBody SysJobEntity sysJob) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ //查询条件示例
+ if (!StringUtils.isEmpty(sysJob.getBeanName())) {
+ queryWrapper.like(SysJobEntity::getBeanName, sysJob.getBeanName());
+ }
+ IPage iPage = sysJobService.page(sysJob.getQueryPage(), queryWrapper);
+ return R.success(iPage);
+ }
+
+
+ /**
+ * 立即执行任务
+ */
+ @ApiOperation(value = "立即执行任务")
+ @LogAnnotation(title = "立即执行任务")
+ @PostMapping("/run")
+ @RequiresPermissions("sysJob:run")
+ public R run(@RequestBody List ids) {
+ sysJobService.run(ids);
+
+ return R.success();
+ }
+
+ /**
+ * 暂停定时任务
+ */
+ @ApiOperation(value = "暂停定时任务")
+ @LogAnnotation(title = "暂停定时任务")
+ @PostMapping("/pause")
+ @RequiresPermissions("sysJob:pause")
+ public R pause(@RequestBody List ids) {
+ sysJobService.pause(ids);
+
+ return R.success();
+ }
+
+ /**
+ * 恢复定时任务
+ */
+ @ApiOperation(value = "恢复定时任务")
+ @LogAnnotation(title = "恢复定时任务")
+ @PostMapping("/resume")
+ @RequiresPermissions("sysJob:resume")
+ public R resume(@RequestBody List ids) {
+ sysJobService.resume(ids);
+ return R.success();
+ }
+
+ /**
+ * 判断cron表达式
+ *
+ * @param cronExpression cron表达式
+ * @return 是否有误
+ */
+ public static boolean isValidExpression(String cronExpression) {
+ CronTriggerImpl trigger = new CronTriggerImpl();
+ try {
+ trigger.setCronExpression(cronExpression);
+ Date date = trigger.computeFirstFireTime(null);
+ return date == null || !date.after(new Date());
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
+
+ @ApiOperation(value = "获取运行时间")
+ @LogAnnotation(title = "获取运行时间")
+ @PostMapping("/getRecentTriggerTime")
+ @RequiresPermissions("sysJob:add")
+ public R getRecentTriggerTime(String cron) {
+ List list = new ArrayList<>();
+ try {
+ CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
+ cronTriggerImpl.setCronExpression(cron);
+ // 这个是重点,一行代码搞定
+ List dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 5);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ for (Date date : dates) {
+ list.add(dateFormat.format(date));
+ }
+
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return R.success(list);
+ }
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysJobLogController.java b/src/main/java/com/huoran/iasf/controller/SysJobLogController.java
new file mode 100644
index 0000000..9d6345c
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysJobLogController.java
@@ -0,0 +1,55 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysJobLogEntity;
+import com.huoran.iasf.service.SysJobLogService;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+
+/**
+ * 定时任务日志
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+// @Api(tags = "定时任务日志")
+// @RestController
+// @RequestMapping("/sysJobLog")
+public class SysJobLogController {
+ @Resource
+ private SysJobLogService sysJobLogService;
+
+ @ApiOperation(value = "查询分页数据")
+ @PostMapping("/listByPage")
+ @RequiresPermissions("sysJob:list")
+ public R findListByPage(@RequestBody SysJobLogEntity sysJobLog) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ //查询条件示例
+ if (!StringUtils.isEmpty(sysJobLog.getJobId())) {
+ queryWrapper.like(SysJobLogEntity::getJobId, sysJobLog.getJobId());
+ }
+ queryWrapper.orderByDesc(SysJobLogEntity::getCreateTime);
+ IPage iPage = sysJobLogService.page(sysJobLog.getQueryPage(), queryWrapper);
+ return R.success(iPage);
+ }
+
+ @ApiOperation(value = "清空定时任务日志")
+ @DeleteMapping("/delete")
+ @RequiresPermissions("sysJob:delete")
+ @LogAnnotation(title = "清空")
+ public R delete() {
+ sysJobLogService.remove(Wrappers.emptyWrapper());
+ return R.success();
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/controller/SysLogController.java b/src/main/java/com/huoran/iasf/controller/SysLogController.java
new file mode 100644
index 0000000..113b5e4
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/SysLogController.java
@@ -0,0 +1,62 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysLog;
+import com.huoran.iasf.service.LogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 系统操作日志
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RequestMapping("/sys")
+@Api(tags = "系统模块-系统操作日志管理")
+@RestController
+public class SysLogController {
+ @Resource
+ private LogService logService;
+
+ @PostMapping("/logs")
+ @ApiOperation(value = "分页查询系统操作日志接口")
+ @LogAnnotation(title = "系统操作日志管理", action = "分页查询系统操作日志")
+ @RequiresPermissions("sys:log:list")
+ public R pageInfo(@RequestBody SysLog vo) {
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ if (!StringUtils.isEmpty(vo.getUsername())) {
+ queryWrapper.like(SysLog::getUsername, vo.getUsername());
+ }
+ if (!StringUtils.isEmpty(vo.getOperation())) {
+ queryWrapper.like(SysLog::getOperation, vo.getOperation());
+ }
+ if (!StringUtils.isEmpty(vo.getStartTime())) {
+ queryWrapper.gt(SysLog::getCreateTime, vo.getStartTime());
+ }
+ if (!StringUtils.isEmpty(vo.getEndTime())) {
+ queryWrapper.lt(SysLog::getCreateTime, vo.getEndTime());
+ }
+ queryWrapper.orderByDesc(SysLog::getCreateTime);
+ return R.success(logService.page(vo.getQueryPage(), queryWrapper));
+ }
+
+ @DeleteMapping("/logs")
+ @ApiOperation(value = "删除日志接口")
+ @LogAnnotation(title = "系统操作日志管理", action = "删除系统操作日志")
+ @RequiresPermissions("sys:log:deleted")
+ public R deleted(@RequestBody List logIds) {
+ logService.removeByIds(logIds);
+ return R.success();
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/UserController.java b/src/main/java/com/huoran/iasf/controller/UserController.java
new file mode 100644
index 0000000..a5a0d4b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/UserController.java
@@ -0,0 +1,194 @@
+package com.huoran.iasf.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysUser;
+import com.huoran.iasf.entity.SysUserRole;
+import com.huoran.iasf.service.HttpSessionService;
+import com.huoran.iasf.service.UserRoleService;
+import com.huoran.iasf.service.UserService;
+import com.huoran.iasf.vo.req.UserRoleOperationReqVO;
+import com.wf.captcha.utils.CaptchaUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.subject.Subject;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 用户管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RestController
+@Api(tags = "组织模块-用户管理")
+@RequestMapping("/sys")
+@Slf4j
+public class UserController {
+ @Resource
+ private UserService userService;
+ @Resource
+ private UserRoleService userRoleService;
+ @Resource
+ private HttpSessionService httpSessionService;
+
+ @PostMapping(value = "/user/login")
+ @ApiOperation(value = "用户登录接口")
+ public R login(@RequestBody @Valid SysUser vo, HttpServletRequest request) {
+ //判断验证码
+ if (!CaptchaUtil.ver(vo.getCaptcha(), request)) {
+ // 清除session中的验证码
+ CaptchaUtil.clear(request);
+ return R.fail("验证码错误!");
+ }
+ return R.success(userService.login(vo));
+ }
+
+ @PostMapping("/user/register")
+ @ApiOperation(value = "用户注册接口")
+ public R register(@RequestBody @Valid SysUser vo) {
+ userService.register(vo);
+ return R.success();
+ }
+
+ @GetMapping("/user/unLogin")
+ @ApiOperation(value = "引导客户端去登录")
+ public R unLogin() {
+ return R.getResult(BaseResponseCode.TOKEN_ERROR);
+ }
+
+ @PutMapping("/user")
+ @ApiOperation(value = "更新用户信息接口")
+ @LogAnnotation(title = "用户管理", action = "更新用户信息")
+ @RequiresPermissions("sys:user:update")
+ public R updateUserInfo(@RequestBody SysUser vo) {
+ if (StringUtils.isEmpty(vo.getId())) {
+ return R.fail("id不能为空");
+ }
+
+ userService.updateUserInfo(vo);
+ return R.success();
+ }
+
+ @PutMapping("/user/info")
+ @ApiOperation(value = "更新用户信息接口")
+ @LogAnnotation(title = "用户管理", action = "更新用户信息")
+ public R updateUserInfoById(@RequestBody SysUser vo) {
+ userService.updateUserInfoMy(vo);
+ return R.success();
+ }
+
+ @GetMapping("/user/{id}")
+ @ApiOperation(value = "查询用户详情接口")
+ @LogAnnotation(title = "用户管理", action = "查询用户详情")
+ @RequiresPermissions("sys:user:detail")
+ public R detailInfo(@PathVariable("id") String id) {
+ return R.success(userService.getById(id));
+ }
+
+ @GetMapping("/user")
+ @ApiOperation(value = "查询用户详情接口")
+ @LogAnnotation(title = "用户管理", action = "查询用户详情")
+ public R youSelfInfo() {
+ String userId = httpSessionService.getCurrentUserId();
+ return R.success(userService.getById(userId));
+ }
+
+ @PostMapping("/users")
+ @ApiOperation(value = "分页获取用户列表接口")
+ @RequiresPermissions("sys:user:list")
+ @LogAnnotation(title = "用户管理", action = "分页获取用户列表")
+ public R pageInfo(@RequestBody SysUser vo) {
+ return R.success(userService.pageInfo(vo));
+ }
+
+ @PostMapping("/user")
+ @ApiOperation(value = "新增用户接口")
+ @RequiresPermissions("sys:user:add")
+ @LogAnnotation(title = "用户管理", action = "新增用户")
+ public R addUser(@RequestBody @Valid SysUser vo) {
+ userService.addUser(vo);
+ return R.success();
+ }
+
+ @GetMapping("/user/logout")
+ @ApiOperation(value = "退出接口")
+ @LogAnnotation(title = "用户管理", action = "退出")
+ public R logout() {
+ httpSessionService.abortUserByToken();
+ Subject subject = SecurityUtils.getSubject();
+ subject.logout();
+ return R.success();
+ }
+
+ @PutMapping("/user/pwd")
+ @ApiOperation(value = "修改密码接口")
+ @LogAnnotation(title = "用户管理", action = "更新密码")
+ public R updatePwd(@RequestBody SysUser vo) {
+ if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) {
+ return R.fail("旧密码与新密码不能为空");
+ }
+ String userId = httpSessionService.getCurrentUserId();
+ vo.setId(userId);
+ userService.updatePwd(vo);
+ return R.success();
+ }
+
+ @DeleteMapping("/user")
+ @ApiOperation(value = "删除用户接口")
+ @LogAnnotation(title = "用户管理", action = "删除用户")
+ @RequiresPermissions("sys:user:deleted")
+ public R deletedUser(@RequestBody @ApiParam(value = "用户id集合") List userIds) {
+ //删除用户, 删除redis的绑定的角色跟权限
+ httpSessionService.abortUserByUserIds(userIds);
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ queryWrapper.in(SysUser::getId, userIds);
+ userService.remove(queryWrapper);
+ return R.success();
+ }
+
+ @GetMapping("/user/roles/{userId}")
+ @ApiOperation(value = "赋予角色-获取所有角色接口")
+ @LogAnnotation(title = "用户管理", action = "赋予角色-获取所有角色接口")
+ @RequiresPermissions("sys:user:role:detail")
+ public R getUserOwnRole(@PathVariable("userId") String userId) {
+ R result = R.success();
+ result.setData(userService.getUserOwnRole(userId));
+ return result;
+ }
+
+ @PutMapping("/user/roles/{userId}")
+ @ApiOperation(value = "赋予角色-用户赋予角色接口")
+ @LogAnnotation(title = "用户管理", action = "赋予角色-用户赋予角色接口")
+ @RequiresPermissions("sys:user:update:role")
+ public R setUserOwnRole(@PathVariable("userId") String userId, @RequestBody List roleIds) {
+
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
+ queryWrapper.eq(SysUserRole::getUserId, userId);
+ userRoleService.remove(queryWrapper);
+ if (!CollectionUtils.isEmpty(roleIds)) {
+ UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO();
+ reqVO.setUserId(userId);
+ reqVO.setRoleIds(roleIds);
+ userRoleService.addUserRoleInfo(reqVO);
+ }
+ //刷新权限
+ httpSessionService.refreshUerId(userId);
+ return R.success();
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/UserRoleController.java b/src/main/java/com/huoran/iasf/controller/UserRoleController.java
new file mode 100644
index 0000000..7225825
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/UserRoleController.java
@@ -0,0 +1,38 @@
+package com.huoran.iasf.controller;
+
+import com.huoran.iasf.common.aop.annotation.LogAnnotation;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.service.UserRoleService;
+import com.huoran.iasf.vo.req.UserRoleOperationReqVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * 用户和角色关联
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@RequestMapping("/sys")
+@RestController
+@Api(tags = "组织管理-用户和角色关联接口")
+public class UserRoleController {
+ @Resource
+ private UserRoleService userRoleService;
+
+ @PostMapping("/user/role")
+ @ApiOperation(value = "修改或者新增用户角色接口")
+ @LogAnnotation(title = "用户和角色关联接口", action = "修改或者新增用户角色")
+ public R operationUserRole(@RequestBody @Valid UserRoleOperationReqVO vo) {
+ userRoleService.addUserRoleInfo(vo);
+ return R.success();
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/controller/api/TestController.java b/src/main/java/com/huoran/iasf/controller/api/TestController.java
new file mode 100644
index 0000000..d0b46da
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/controller/api/TestController.java
@@ -0,0 +1,49 @@
+package com.huoran.iasf.controller.api;
+
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.service.HttpApiSessionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+
+/**
+ * api test示例
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2020年5月11日
+ */
+@RestController
+@RequestMapping("/app/api")
+@Api(tags = "test")
+public class TestController {
+
+ @Resource
+ HttpApiSessionService httpApiSessionService;
+
+ @PostMapping("/login")
+ @ApiOperation(value = "登录接口")
+ public R login() {
+ //TODO 登录
+
+ //生成token
+ String token = httpApiSessionService.geneJsonWebToken("123", "测试用户名");
+ return R.success(token);
+ }
+
+
+ @GetMapping("/getCurUserInfo")
+ @ApiOperation(value = "获取当前登录人信息示例")
+ public R getAppUserInfo() {
+ //拿userId与userName
+ String userId = httpApiSessionService.getCurrentUserId();
+ String username = httpApiSessionService.getCurrentUsername();
+ return R.success();
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/entity/BaseEntity.java b/src/main/java/com/huoran/iasf/entity/BaseEntity.java
new file mode 100644
index 0000000..7c084c9
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/BaseEntity.java
@@ -0,0 +1,42 @@
+package com.huoran.iasf.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * BaseEntity
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class BaseEntity {
+
+ @JSONField(serialize = false)
+ @TableField(exist = false)
+ private int page = 1;
+
+ @JSONField(serialize = false)
+ @TableField(exist = false)
+ private int limit = 10;
+
+ /**
+ * 数据权限:用户id
+ */
+ @TableField(exist = false)
+ private List createIds;
+
+ /**
+ * page条件
+ * @param
+ * @return
+ */
+ public Page getQueryPage() {
+ return new Page(page, limit);
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/entity/ColumnEntity.java b/src/main/java/com/huoran/iasf/entity/ColumnEntity.java
new file mode 100644
index 0000000..829b67f
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/ColumnEntity.java
@@ -0,0 +1,104 @@
+package com.huoran.iasf.entity;
+
+import lombok.Data;
+
+/**
+ * 代码生成 列属性
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class ColumnEntity {
+ /**
+ * 列名
+ */
+ private String columnName;
+
+ /**
+ * 列名类型
+ */
+ private String dataType;
+
+ /**
+ * 列名备注
+ */
+ private String comments;
+
+ /**
+ * 属性名称(第一个字母大写),如:user_name => UserName
+ */
+ private String attrName;
+
+ /**
+ * 属性名称(第一个字母小写),如:user_name => userName
+ */
+ private String attrname;
+
+ /**
+ * 属性类型
+ */
+ private String attrType;
+
+ /**
+ * auto_increment
+ */
+ private String extra;
+
+ public String getColumnName() {
+ return columnName;
+ }
+
+ public void setColumnName(String columnName) {
+ this.columnName = columnName;
+ }
+
+ public String getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(String dataType) {
+ this.dataType = dataType;
+ }
+
+ public String getComments() {
+ return comments;
+ }
+
+ public void setComments(String comments) {
+ this.comments = comments;
+ }
+
+ public String getAttrname() {
+ return attrname;
+ }
+
+ public void setAttrname(String attrname) {
+ this.attrname = attrname;
+ }
+
+ public String getAttrName() {
+ return attrName;
+ }
+
+ public void setAttrName(String attrName) {
+ this.attrName = attrName;
+ }
+
+ public String getAttrType() {
+ return attrType;
+ }
+
+ public void setAttrType(String attrType) {
+ this.attrType = attrType;
+ }
+
+ public String getExtra() {
+ return extra;
+ }
+
+ public void setExtra(String extra) {
+ this.extra = extra;
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysContentEntity.java b/src/main/java/com/huoran/iasf/entity/SysContentEntity.java
new file mode 100644
index 0000000..7a4db1d
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysContentEntity.java
@@ -0,0 +1,78 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 内容管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("sys_content")
+public class SysContentEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键id
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * 主题
+ */
+ @TableField("title")
+ private String title;
+
+ /**
+ * 内容
+ */
+ @TableField("content")
+ private String content;
+
+ /**
+ * 单个图片url
+ */
+ private String oneImg;
+
+ /**
+ * 多个图片url
+ */
+ private String multipleImg;
+
+ /**
+ * 关键字
+ */
+ private String keywords;
+
+ /**
+ * 类型(数据字典)
+ */
+ @TableField("type")
+ private String type;
+
+ /**
+ * 创建人
+ */
+ @TableField(value = "create_id", fill = FieldFill.INSERT)
+ private String createId;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Date createTime;
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysDept.java b/src/main/java/com/huoran/iasf/entity/SysDept.java
new file mode 100644
index 0000000..f2ffe20
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysDept.java
@@ -0,0 +1,54 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 部门
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class SysDept implements Serializable {
+ @TableId
+ private String id;
+
+ private String deptNo;
+
+ @NotBlank(message = "机构名称不能为空")
+ private String name;
+
+ @NotBlank(message = "父级不能为空")
+ private String pid;
+
+ @TableField(exist = false)
+ private String pidName;
+
+ private Integer status;
+
+ private String relationCode;
+
+ private String deptManagerId;
+
+ private String managerName;
+
+ private String phone;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Date updateTime;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Integer deleted;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/SysDictDetailEntity.java b/src/main/java/com/huoran/iasf/entity/SysDictDetailEntity.java
new file mode 100644
index 0000000..14b1767
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysDictDetailEntity.java
@@ -0,0 +1,68 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 字典明细
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("sys_dict_detail")
+public class SysDictDetailEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * 字典标签
+ */
+ @TableField("label")
+ private String label;
+
+ /**
+ * 字典值
+ */
+ @TableField("value")
+ private String value;
+
+ /**
+ * 排序
+ */
+ @TableField("sort")
+ private Integer sort;
+
+ /**
+ * 字典id
+ */
+ @TableField("dict_id")
+ private String dictId;
+
+ /**
+ * 创建日期
+ */
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Date createTime;
+
+ /**
+ * 字典name
+ */
+ @TableField(exist = false)
+ private String dictName;
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysDictEntity.java b/src/main/java/com/huoran/iasf/entity/SysDictEntity.java
new file mode 100644
index 0000000..b4e05b0
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysDictEntity.java
@@ -0,0 +1,51 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 字典管理
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("sys_dict")
+public class SysDictEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * 字典名称
+ */
+ @TableField("name")
+ private String name;
+
+ /**
+ * 备注
+ */
+ @TableField("remark")
+ private String remark;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Date createTime;
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysFilesEntity.java b/src/main/java/com/huoran/iasf/entity/SysFilesEntity.java
new file mode 100644
index 0000000..eeb3e5d
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysFilesEntity.java
@@ -0,0 +1,51 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 文件上传
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("sys_files")
+public class SysFilesEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * URL地址
+ */
+ @TableField("url")
+ private String url;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_date", fill = FieldFill.INSERT)
+ private Date createDate;
+
+ @TableField("file_name")
+ private String fileName;
+
+ @TableField("file_path")
+ private String filePath;
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysGenerator.java b/src/main/java/com/huoran/iasf/entity/SysGenerator.java
new file mode 100644
index 0000000..f52f515
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysGenerator.java
@@ -0,0 +1,30 @@
+package com.huoran.iasf.entity;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 代码生成
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysGenerator extends BaseEntity implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String tableName;
+
+ private Date createTime;
+
+ private String tableComment;
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysJobEntity.java b/src/main/java/com/huoran/iasf/entity/SysJobEntity.java
new file mode 100644
index 0000000..8650736
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysJobEntity.java
@@ -0,0 +1,72 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 定时任务
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("sys_job")
+public class SysJobEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+ /**
+ * 任务调度参数key
+ */
+ public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
+ /**
+ * 任务id
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * spring bean名称
+ */
+ @TableField("bean_name")
+ private String beanName;
+
+ /**
+ * 参数
+ */
+ @TableField("params")
+ private String params;
+
+ /**
+ * cron表达式
+ */
+ @TableField("cron_expression")
+ private String cronExpression;
+
+ /**
+ * 任务状态 0:正常 1:暂停
+ */
+ @TableField("status")
+ private Integer status;
+
+ /**
+ * 备注
+ */
+ @TableField("remark")
+ private String remark;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Date createTime;
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysJobLogEntity.java b/src/main/java/com/huoran/iasf/entity/SysJobLogEntity.java
new file mode 100644
index 0000000..0cd494b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysJobLogEntity.java
@@ -0,0 +1,75 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 定时任务日志
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("sys_job_log")
+public class SysJobLogEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 任务日志id
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * 任务id
+ */
+ @TableField("job_id")
+ private String jobId;
+
+ /**
+ * spring bean名称
+ */
+ @TableField("bean_name")
+ private String beanName;
+
+ /**
+ * 参数
+ */
+ @TableField("params")
+ private String params;
+
+ /**
+ * 任务状态 0:成功 1:失败
+ */
+ @TableField("status")
+ private Integer status;
+
+ /**
+ * 失败信息
+ */
+ @TableField("error")
+ private String error;
+
+ /**
+ * 耗时(单位:毫秒)
+ */
+ @TableField("times")
+ private Integer times;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Date createTime;
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysLog.java b/src/main/java/com/huoran/iasf/entity/SysLog.java
new file mode 100644
index 0000000..7725668
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysLog.java
@@ -0,0 +1,48 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 操作日志
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SysLog extends BaseEntity implements Serializable {
+ @TableId
+ private String id;
+
+ private String userId;
+
+ private String username;
+
+ private String operation;
+
+ private Integer time;
+
+ private String method;
+
+ private String params;
+
+ private String ip;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+ @TableField(exist = false)
+ private String startTime;
+
+ @TableField(exist = false)
+ private String endTime;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/SysPermission.java b/src/main/java/com/huoran/iasf/entity/SysPermission.java
new file mode 100644
index 0000000..70561b8
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysPermission.java
@@ -0,0 +1,63 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 权限菜单
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class SysPermission implements Serializable {
+
+
+ @TableId
+ private String id;
+
+ @NotBlank(message = "菜单权限名称不能为空")
+ private String name;
+
+ private String perms;
+
+ private String url;
+
+ private String icon;
+
+ private String target;
+
+ @NotNull(message = "所属菜单不能为空")
+ private String pid;
+
+ private Integer orderNum;
+
+ @NotNull(message = "菜单权限类型不能为空")
+ private Integer type;
+
+ /**
+ * 1正常 2禁用
+ */
+ private Integer status;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Date updateTime;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Integer deleted;
+
+ @TableField(exist = false)
+ private String pidName;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/SysRole.java b/src/main/java/com/huoran/iasf/entity/SysRole.java
new file mode 100644
index 0000000..978aa8f
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysRole.java
@@ -0,0 +1,66 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.huoran.iasf.vo.resp.DeptRespNodeVO;
+import com.huoran.iasf.vo.resp.PermissionRespNode;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 角色
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+public class SysRole extends BaseEntity implements Serializable {
+ @TableId
+ private String id;
+
+ @NotBlank(message = "名称不能为空")
+ private String name;
+
+ private String description;
+
+ private Integer status;
+
+ private Integer dataScope;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Date updateTime;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Integer deleted;
+
+ @TableField(exist = false)
+ private List permissionRespNodes;
+ @TableField(exist = false)
+ private List deptRespNodes;
+
+ @TableField(exist = false)
+ private String startTime;
+
+ @TableField(exist = false)
+ private String endTime;
+
+ @TableField(exist = false)
+ private List permissions;
+
+ @TableField(exist = false)
+ private List depts;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/SysRoleDeptEntity.java b/src/main/java/com/huoran/iasf/entity/SysRoleDeptEntity.java
new file mode 100644
index 0000000..daa7d81
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysRoleDeptEntity.java
@@ -0,0 +1,49 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 角色部门
+ *
+ * @author cheney
+ * @email *****@mail.com
+ * @date 2020-09-27 17:30:15
+ */
+@Data
+@TableName("sys_role_dept")
+public class SysRoleDeptEntity extends BaseEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId("id")
+ private String id;
+
+ /**
+ * 角色id
+ */
+ @TableField("role_id")
+ private String roleId;
+
+ /**
+ * 菜单权限id
+ */
+ @TableField("dept_id")
+ private String deptId;
+
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time", fill = FieldFill.INSERT)
+ private Date createTime;
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/entity/SysRolePermission.java b/src/main/java/com/huoran/iasf/entity/SysRolePermission.java
new file mode 100644
index 0000000..2c9fe26
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysRolePermission.java
@@ -0,0 +1,30 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 角色权限
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class SysRolePermission implements Serializable {
+ @TableId
+ private String id;
+
+ private String roleId;
+
+ private String permissionId;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/SysUser.java b/src/main/java/com/huoran/iasf/entity/SysUser.java
new file mode 100644
index 0000000..0ed2156
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysUser.java
@@ -0,0 +1,88 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 用户
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SysUser extends BaseEntity implements Serializable {
+ @TableId
+ private String id;
+
+ @NotBlank(message = "账号不能为空")
+ private String username;
+
+ private String salt;
+
+ @NotBlank(message = "密码不能为空")
+ private String password;
+
+ @TableField(exist = false)
+ private String oldPwd;
+
+ @TableField(exist = false)
+ private String newPwd;
+
+ private String phone;
+
+ private String deptId;
+
+ @TableField(exist = false)
+ private String deptName;
+
+ @TableField(exist = false)
+ private String deptNo;
+
+
+ private String realName;
+
+ private String nickName;
+
+ private String email;
+
+ private Integer status;
+
+ private Integer sex;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Integer deleted;
+
+ private String createId;
+
+ private String updateId;
+
+ private Integer createWhere;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Date updateTime;
+
+ @TableField(exist = false)
+ private String startTime;
+
+ @TableField(exist = false)
+ private String endTime;
+
+ @TableField(exist = false)
+ private List roleIds;
+
+ @TableField(exist = false)
+ private String captcha;
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/SysUserRole.java b/src/main/java/com/huoran/iasf/entity/SysUserRole.java
new file mode 100644
index 0000000..7764975
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/SysUserRole.java
@@ -0,0 +1,31 @@
+package com.huoran.iasf.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户角色
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Data
+public class SysUserRole implements Serializable {
+ @TableId
+ private String id;
+
+ private String userId;
+
+ private String roleId;
+
+ @TableField(fill = FieldFill.INSERT)
+ private Date createTime;
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/entity/TableEntity.java b/src/main/java/com/huoran/iasf/entity/TableEntity.java
new file mode 100644
index 0000000..2449dc0
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/entity/TableEntity.java
@@ -0,0 +1,84 @@
+package com.huoran.iasf.entity;
+
+import java.util.List;
+
+/**
+ * 代码生成 表数据
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public class TableEntity {
+ //表的名称
+ private String tableName;
+ //表的备注
+ private String comments;
+ //表的主键
+ private ColumnEntity pk;
+ //表的列名(不包含主键)
+ private List columns;
+
+ //类名(第一个字母大写),如:sys_user => SysUser
+ private String className;
+ //类名(第一个字母小写),如:sys_user => sysUser
+ private String classname;
+ //类名(都小写),如:sys_user => sysuser
+ private String classNameLower;
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getComments() {
+ return comments;
+ }
+
+ public void setComments(String comments) {
+ this.comments = comments;
+ }
+
+ public ColumnEntity getPk() {
+ return pk;
+ }
+
+ public void setPk(ColumnEntity pk) {
+ this.pk = pk;
+ }
+
+ public List getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List columns) {
+ this.columns = columns;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public String getClassname() {
+ return classname;
+ }
+
+ public void setClassname(String classname) {
+ this.classname = classname;
+ }
+
+ public String getClassNameLower() {
+ return classNameLower;
+ }
+
+ public void setClassNameLower(String classNameLower) {
+ this.classNameLower = classNameLower;
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/GeneratorMapper.java b/src/main/java/com/huoran/iasf/mapper/GeneratorMapper.java
new file mode 100644
index 0000000..942fec4
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/GeneratorMapper.java
@@ -0,0 +1,26 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.huoran.iasf.entity.SysGenerator;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 代码生成 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface GeneratorMapper extends BaseMapper {
+
+ IPage selectAllTables(Page page, @Param(value = "vo") SysGenerator vo);
+
+ Map queryTable(String tableName);
+
+ List> queryColumns(String tableName);
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysContentMapper.java b/src/main/java/com/huoran/iasf/mapper/SysContentMapper.java
new file mode 100644
index 0000000..684ea54
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysContentMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysContentEntity;
+
+/**
+ * 内容管理 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysContentMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java b/src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java
new file mode 100644
index 0000000..4b98776
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysDeptMapper.java
@@ -0,0 +1,14 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysDept;
+
+/**
+ * 部门 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysDeptMapper extends BaseMapper {
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/mapper/SysDictDetailMapper.java b/src/main/java/com/huoran/iasf/mapper/SysDictDetailMapper.java
new file mode 100644
index 0000000..c5806d3
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysDictDetailMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysDictDetailEntity;
+
+/**
+ * 字典详情 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysDictDetailMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysDictMapper.java b/src/main/java/com/huoran/iasf/mapper/SysDictMapper.java
new file mode 100644
index 0000000..b188a7d
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysDictMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysDictEntity;
+
+/**
+ * 字典 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysDictMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java b/src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java
new file mode 100644
index 0000000..cdff573
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysFilesMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysFilesEntity;
+
+/**
+ * 文件上传 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysFilesMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysJobLogMapper.java b/src/main/java/com/huoran/iasf/mapper/SysJobLogMapper.java
new file mode 100644
index 0000000..4b17b2c
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysJobLogMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysJobLogEntity;
+
+/**
+ * 定时任务日志、 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysJobLogMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysJobMapper.java b/src/main/java/com/huoran/iasf/mapper/SysJobMapper.java
new file mode 100644
index 0000000..692a83a
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysJobMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysJobEntity;
+
+/**
+ * 定时任务 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysJobMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysLogMapper.java b/src/main/java/com/huoran/iasf/mapper/SysLogMapper.java
new file mode 100644
index 0000000..fa16d58
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysLogMapper.java
@@ -0,0 +1,14 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysLog;
+
+/**
+ * 操作日志 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysLogMapper extends BaseMapper {
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/mapper/SysPermissionMapper.java b/src/main/java/com/huoran/iasf/mapper/SysPermissionMapper.java
new file mode 100644
index 0000000..b2f7701
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysPermissionMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysPermission;
+
+/**
+ * 菜单权限 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysPermissionMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/mapper/SysRoleDeptMapper.java b/src/main/java/com/huoran/iasf/mapper/SysRoleDeptMapper.java
new file mode 100644
index 0000000..e55414c
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysRoleDeptMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysRoleDeptEntity;
+
+/**
+ * 角色部门
+ *
+ * @author cheney
+ * @email *****@mail.com
+ * @date 2020-09-27 17:30:15
+ */
+public interface SysRoleDeptMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/huoran/iasf/mapper/SysRoleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysRoleMapper.java
new file mode 100644
index 0000000..bea4d2d
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysRoleMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysRole;
+
+/**
+ * 角色 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysRoleMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/mapper/SysRolePermissionMapper.java b/src/main/java/com/huoran/iasf/mapper/SysRolePermissionMapper.java
new file mode 100644
index 0000000..0c4bd50
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysRolePermissionMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysRolePermission;
+
+/**
+ * 角色权限 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysRolePermissionMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/mapper/SysUserMapper.java b/src/main/java/com/huoran/iasf/mapper/SysUserMapper.java
new file mode 100644
index 0000000..608aba2
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysUserMapper.java
@@ -0,0 +1,14 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysUser;
+
+/**
+ * 用户 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysUserMapper extends BaseMapper {
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/mapper/SysUserRoleMapper.java b/src/main/java/com/huoran/iasf/mapper/SysUserRoleMapper.java
new file mode 100644
index 0000000..f4244d2
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/mapper/SysUserRoleMapper.java
@@ -0,0 +1,15 @@
+package com.huoran.iasf.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.huoran.iasf.entity.SysUserRole;
+
+/**
+ * 用户角色 Mapper
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysUserRoleMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/service/DeptService.java b/src/main/java/com/huoran/iasf/service/DeptService.java
new file mode 100644
index 0000000..7a86e24
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/DeptService.java
@@ -0,0 +1,47 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysDept;
+import com.huoran.iasf.vo.resp.DeptRespNodeVO;
+
+import java.util.List;
+
+/**
+ * 部门
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface DeptService extends IService {
+
+ /**
+ * 添加部门
+ *
+ * @param vo vo
+ */
+ void addDept(SysDept vo);
+
+ /**
+ * 更新部门
+ *
+ * @param vo vo
+ */
+ void updateDept(SysDept vo);
+
+ /**
+ * 删除部门
+ *
+ * @param id id
+ */
+ void deleted(String id);
+
+ /**
+ * 部门树形列表
+ *
+ * @param deptId deptId
+ * @param disabled 最顶级是否可用
+ * @return 树形列表
+ */
+ List deptTreeList(String deptId, Boolean disabled);
+}
diff --git a/src/main/java/com/huoran/iasf/service/HomeService.java b/src/main/java/com/huoran/iasf/service/HomeService.java
new file mode 100644
index 0000000..ae54d0a
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/HomeService.java
@@ -0,0 +1,21 @@
+package com.huoran.iasf.service;
+
+import com.huoran.iasf.vo.resp.HomeRespVO;
+
+/**
+ * 首页
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface HomeService {
+
+ /**
+ * 获取首页信息
+ *
+ * @param userId userId
+ * @return HomeRespVO
+ */
+ HomeRespVO getHomeInfo(String userId);
+}
diff --git a/src/main/java/com/huoran/iasf/service/HttpApiSessionService.java b/src/main/java/com/huoran/iasf/service/HttpApiSessionService.java
new file mode 100644
index 0000000..e8b6a9d
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/HttpApiSessionService.java
@@ -0,0 +1,97 @@
+package com.huoran.iasf.service;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+/**
+ * session管理器
+ * @author cheney
+ * @version V1.0
+ * @date 2020年5月11日
+ */
+@Service
+public class HttpApiSessionService {
+
+
+ public static final String USER_ID_KEY = "user_id_key";
+
+ public static final String USER_USERNAME_KEY = "user_username_key";
+
+ public static final String SUBJECT = "HuoRan_SUBJECT";
+
+ public static final long EXPIRE = 1000 * 60 * 60 * 24 * 2; //过期时间,毫秒,一天
+
+ //秘钥
+ public static final String APP_SECRET = "HuoRan_SYMMETRIC_ENCRYPTION_HS256";
+
+ @Resource
+ private HttpServletRequest request;
+
+ /**
+ * 生成jwt
+ * @param userId username
+ * @return token
+ */
+ public String geneJsonWebToken(String userId, String userName) {
+ String token = Jwts.builder().setSubject(SUBJECT)
+ .claim(USER_ID_KEY, userId)
+ .claim(USER_USERNAME_KEY, userName)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
+ .signWith(SignatureAlgorithm.HS256, APP_SECRET).compact();
+ return token;
+ }
+
+
+ /**
+ * 校验token
+ *
+ * @param token
+ * @return
+ */
+ public Claims checkJWT(String token) {
+
+ try {
+ final Claims claims = Jwts.parser().setSigningKey(APP_SECRET).
+ parseClaimsJws(token).getBody();
+ return claims;
+ } catch (Exception e) {
+ }
+ return null;
+
+ }
+
+ /**
+ * 获取当前session信息 username
+ *
+ * @return username
+ */
+ public String getCurrentUsername() {
+ if (request.getAttribute(USER_USERNAME_KEY) != null) {
+ return request.getAttribute(USER_USERNAME_KEY).toString();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 获取当前session信息 UserId
+ *
+ * @return UserId
+ */
+ public String getCurrentUserId() {
+ if (request.getAttribute(USER_ID_KEY) != null) {
+ return request.getAttribute(USER_ID_KEY).toString();
+ } else {
+ return null;
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/service/HttpSessionService.java b/src/main/java/com/huoran/iasf/service/HttpSessionService.java
new file mode 100644
index 0000000..97b6f08
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/HttpSessionService.java
@@ -0,0 +1,265 @@
+package com.huoran.iasf.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.huoran.iasf.common.utils.Constant;
+import com.huoran.iasf.entity.SysUser;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * session管理器
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+public class HttpSessionService {
+ @Resource
+ private com.huoran.iasf.service.RedisService redisService;
+ @Resource
+ private com.huoran.iasf.service.UserRoleService userRoleService;
+ @Resource
+ private com.huoran.iasf.service.RolePermissionService rolePermissionService;
+ @Resource
+ private HttpServletRequest request;
+ @Resource
+ private com.huoran.iasf.service.PermissionService permissionService;
+ @Resource
+ private com.huoran.iasf.service.RoleService roleService;
+
+ @Value("${spring.redis.key.prefix.userToken}")
+ private String userTokenPrefix;
+
+ @Value("${spring.redis.key.expire.userToken}")
+ private int exire;
+
+ @Value("${spring.redis.key.prefix.permissionRefresh}")
+ private String redisPermissionRefreshKey;
+ @Value("${spring.redis.key.expire.permissionRefresh}")
+ private Long redisPermissionRefreshExpire;
+
+ public String createTokenAndUser(SysUser user, List roles, Set permissions) {
+ //方便根据id找到redis的key, 修改密码/退出登陆 方便使用
+ String token = getRandomToken() + "#" + user.getId();
+ JSONObject sessionInfo = new JSONObject();
+ sessionInfo.put(Constant.USERID_KEY, user.getId());
+ sessionInfo.put(Constant.USERNAME_KEY, user.getUsername());
+ sessionInfo.put(Constant.ROLES_KEY, roles);
+ sessionInfo.put(Constant.PERMISSIONS_KEY, permissions);
+ String key = userTokenPrefix + token;
+ //设置该用户已登录的token
+ redisService.setAndExpire(key, sessionInfo.toJSONString(), exire);
+
+ //登陆后删除权限刷新标志
+ redisService.del(redisPermissionRefreshKey + user.getId());
+ return token;
+ }
+
+ /**
+ * 根据token获取userid
+ *
+ * @param token token
+ * @return userid
+ */
+ public static String getUserIdByToken(String token) {
+ if (StringUtils.isBlank(token) || !token.contains("#")) {
+ return "";
+ } else {
+ return token.substring(token.indexOf("#") + 1);
+ }
+ }
+
+ /**
+ * 获取参数中的token
+ *
+ * @return token
+ */
+ public String getTokenFromHeader() {
+ String token = request.getHeader(Constant.ACCESS_TOKEN);
+ //如果header中不存在token,则从参数中获取token
+ if (StringUtils.isBlank(token)) {
+ token = request.getParameter(Constant.ACCESS_TOKEN);
+ }
+ return token;
+ }
+
+ /**
+ * 获取当前session信息
+ *
+ * @return session信息
+ */
+ public JSONObject getCurrentSession() {
+ String token = getTokenFromHeader();
+ if (null != token) {
+ if (redisService.exists(userTokenPrefix + token)) {
+ String sessionInfoStr = redisService.get(userTokenPrefix + token);
+ return JSON.parseObject(sessionInfoStr);
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 获取当前session信息 username
+ *
+ * @return username
+ */
+ public String getCurrentUsername() {
+ if (getCurrentSession() != null) {
+ return getCurrentSession().getString(Constant.USERNAME_KEY);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * 获取当前session信息 UserId
+ *
+ * @return UserId
+ */
+ public String getCurrentUserId() {
+ if (getCurrentSession() != null) {
+ return getCurrentSession().getString(Constant.USERID_KEY);
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * 使当前用户的token失效
+ */
+ public void abortUserByToken() {
+ String token = getTokenFromHeader();
+ redisService.del(userTokenPrefix + token);
+ }
+
+ /**
+ * 使所有用户的token失效
+ */
+ public void abortAllUserByToken() {
+ String token = getTokenFromHeader();
+ String userId = getUserIdByToken(token);
+ redisService.delKeys(userTokenPrefix + "*#" + userId);
+ }
+
+ /**
+ * 使用户的token失效
+ */
+ public void abortUserById(String userId) {
+ redisService.delKeys(userTokenPrefix + "*#" + userId);
+ }
+
+ /**
+ * 使多个用户的token失效
+ */
+ public void abortUserByUserIds(List userIds) {
+ if (CollectionUtils.isNotEmpty(userIds)) {
+ for (String id : userIds) {
+ redisService.delKeys(userTokenPrefix + "*#" + id);
+ }
+
+ }
+ }
+
+ /**
+ * 根据用户id, 刷新redis用户权限
+ *
+ * @param userId userId
+ */
+ public void refreshUerId(String userId) {
+// redisService.delKeys(userTokenPrefix + "*#" + userId);
+
+
+// Set keys = redisService.keys("#" + userId);
+// //如果修改了角色/权限, 那么刷新权限
+// for (String key : keys) {
+// JSONObject redisSession = JSON.parseObject(redisService.get(key));
+//
+// List roleNames = getRolesByUserId(userId);
+// if (!CollectionUtils.isEmpty(roleNames)) {
+// redisSession.put(Constant.ROLES_KEY, roleNames);
+// }
+// Set permissions = getPermissionsByUserId(userId);
+// redisSession.put(Constant.PERMISSIONS_KEY, permissions);
+// Long redisTokenKeyExpire = redisService.getExpire(key);
+// //刷新token绑定的角色权限
+// redisService.setAndExpire(key, redisSession.toJSONString(), redisTokenKeyExpire);
+//
+// }
+ }
+
+ /**
+ * 根据角色id, 刷新redis用户权限
+ *
+ * @param roleId roleId
+ */
+ public void refreshRolePermission(String roleId) {
+// List userIds = userRoleService.getUserIdsByRoleId(roleId);
+// if (!CollectionUtils.isEmpty(userIds)) {
+// userIds.parallelStream().forEach(this::refreshUerId);
+// }
+ }
+
+ /**
+ * 根据权限id, 刷新redis用户权限
+ *
+ * @param permissionId permissionId
+ */
+ public void refreshPermission(String permissionId) {
+// List userIds = permissionService.getUserIdsById(permissionId);
+// if (!CollectionUtils.isEmpty(userIds)) {
+// userIds.parallelStream().forEach(this::refreshUerId);
+// }
+ }
+
+
+ /**
+ * 生成随机的token
+ *
+ * @return token
+ */
+ private String getRandomToken() {
+ Random random = new Random();
+ StringBuilder randomStr = new StringBuilder();
+
+ // 根据length生成相应长度的随机字符串
+ for (int i = 0; i < 32; i++) {
+ String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
+
+ //输出字母还是数字
+ if ("char".equalsIgnoreCase(charOrNum)) {
+ //输出是大写字母还是小写字母
+ int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
+ randomStr.append((char) (random.nextInt(26) + temp));
+ } else {
+ randomStr.append(random.nextInt(10));
+ }
+ }
+
+ return randomStr.toString();
+ }
+
+
+ private List getRolesByUserId(String userId) {
+ return roleService.getRoleNames(userId);
+ }
+
+ private Set getPermissionsByUserId(String userId) {
+ return permissionService.getPermissionsByUserId(userId);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/service/ISysGeneratorService.java b/src/main/java/com/huoran/iasf/service/ISysGeneratorService.java
new file mode 100644
index 0000000..83ae42b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/ISysGeneratorService.java
@@ -0,0 +1,32 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.huoran.iasf.entity.SysGenerator;
+
+/**
+ * 代码生成
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface ISysGeneratorService {
+
+ /**
+ * 获取所有表
+ *
+ * @param page page
+ * @param vo vo
+ * @return IPage
+ */
+ IPage selectAllTables(Page page, SysGenerator vo);
+
+ /**
+ * 生成代码
+ *
+ * @param tables tables
+ * @return byte[]
+ */
+ byte[] generatorCode(String[] tables);
+}
diff --git a/src/main/java/com/huoran/iasf/service/LogService.java b/src/main/java/com/huoran/iasf/service/LogService.java
new file mode 100644
index 0000000..f2b426a
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/LogService.java
@@ -0,0 +1,14 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysLog;
+
+/**
+ * 系统日志
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface LogService extends IService {
+}
diff --git a/src/main/java/com/huoran/iasf/service/PermissionService.java b/src/main/java/com/huoran/iasf/service/PermissionService.java
new file mode 100644
index 0000000..6a5d4bf
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/PermissionService.java
@@ -0,0 +1,87 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysPermission;
+import com.huoran.iasf.vo.resp.PermissionRespNode;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 菜单权限
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface PermissionService extends IService {
+
+ /**
+ * 根据userId获取权限
+ *
+ * @param userId userId
+ * @return 权限
+ */
+ List getPermission(String userId);
+
+ /**
+ * 删除权限
+ *
+ * @param permissionId 权限id
+ */
+ void deleted(String permissionId);
+
+ /**
+ * 获取所有
+ *
+ * @return List
+ */
+ List selectAll();
+
+ /**
+ * 根据userId获取权限标志
+ *
+ * @param userId userId
+ * @return Set
+ */
+ Set getPermissionsByUserId(String userId);
+
+ /**
+ * 根据userId获取权限树
+ *
+ * @param userId
+ * @return List
+ */
+ List permissionTreeList(String userId);
+
+ /**
+ * 根据权限树
+ *
+ * @return List
+ */
+ List selectAllByTree();
+
+ /**
+ * 根据目录树
+ *
+ * @param permissionId permissionId
+ * @return List
+ */
+ List selectAllMenuByTree(String permissionId);
+
+
+ /**
+ * 根据权限id获取绑定的userId
+ *
+ * @param permissionId permissionId
+ * @return List
+ */
+ List getUserIdsById(String permissionId);
+
+ /**
+ * 更新
+ *
+ * @param vo vo
+ */
+ void updatePermission(SysPermission vo);
+}
diff --git a/src/main/java/com/huoran/iasf/service/RedisService.java b/src/main/java/com/huoran/iasf/service/RedisService.java
new file mode 100644
index 0000000..fbe002c
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/RedisService.java
@@ -0,0 +1,74 @@
+package com.huoran.iasf.service;
+
+import com.huoran.iasf.common.exception.BusinessException;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * redis
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+public class RedisService {
+ private final StringRedisTemplate redisTemplate;
+
+ public RedisService(StringRedisTemplate redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
+
+ public boolean exists(String key) {
+ return this.redisTemplate.hasKey(key);
+ }
+
+ public Long getExpire(String key) {
+ if (null == key) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR.getCode(), "key or TomeUnit 不能为空");
+ }
+ return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+ }
+
+
+ public void set(String key, String value) {
+ this.redisTemplate.opsForValue().set(key, value);
+ }
+
+
+ public String get(String key) {
+ return this.redisTemplate.opsForValue().get(key);
+ }
+
+ public void del(String key) {
+ if (this.exists(key)) {
+ this.redisTemplate.delete(key);
+ }
+
+ }
+
+ public void setAndExpire(String key, String value, long seconds) {
+ this.redisTemplate.opsForValue().set(key, value);
+ this.redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
+ }
+
+
+ public Set keys(String pattern) {
+ return redisTemplate.keys("*" + pattern);
+ }
+
+ public void delKeys(String pattern) {
+ Set keys = redisTemplate.keys(pattern);
+ if (!CollectionUtils.isEmpty(keys)) {
+ this.redisTemplate.delete(keys);
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/service/RolePermissionService.java b/src/main/java/com/huoran/iasf/service/RolePermissionService.java
new file mode 100644
index 0000000..65efdad
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/RolePermissionService.java
@@ -0,0 +1,22 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysRolePermission;
+import com.huoran.iasf.vo.req.RolePermissionOperationReqVO;
+
+/**
+ * 角色权限关联
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface RolePermissionService extends IService {
+
+ /**
+ * 角色绑定权限
+ *
+ * @param vo vo
+ */
+ void addRolePermission(RolePermissionOperationReqVO vo);
+}
diff --git a/src/main/java/com/huoran/iasf/service/RoleService.java b/src/main/java/com/huoran/iasf/service/RoleService.java
new file mode 100644
index 0000000..0904c29
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/RoleService.java
@@ -0,0 +1,61 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysRole;
+
+import java.util.List;
+
+/**
+ * 角色
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface RoleService extends IService {
+
+ /**
+ * 添加角色
+ *
+ * @param vo SysRole
+ */
+ void addRole(SysRole vo);
+
+ /**
+ * 更新角色
+ *
+ * @param vo SysRole
+ */
+ void updateRole(SysRole vo);
+
+ /**
+ * 根据id获取角色详情
+ *
+ * @param id id
+ * @return SysRole
+ */
+ SysRole detailInfo(String id);
+
+ /**
+ * 根据id删除
+ *
+ * @param id id
+ */
+ void deletedRole(String id);
+
+ /**
+ * 根据userId获取绑定的角色
+ *
+ * @param userId userId
+ * @return List
+ */
+ List getRoleInfoByUserId(String userId);
+
+ /**
+ * 根据userId获取绑定的角色名
+ *
+ * @param userId userId
+ * @return List
+ */
+ List getRoleNames(String userId);
+}
diff --git a/src/main/java/com/huoran/iasf/service/SysContentService.java b/src/main/java/com/huoran/iasf/service/SysContentService.java
new file mode 100644
index 0000000..bc986d4
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysContentService.java
@@ -0,0 +1,16 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysContentEntity;
+
+/**
+ * 内容 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysContentService extends IService {
+
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/SysDictDetailService.java b/src/main/java/com/huoran/iasf/service/SysDictDetailService.java
new file mode 100644
index 0000000..9c9864a
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysDictDetailService.java
@@ -0,0 +1,26 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysDictDetailEntity;
+
+/**
+ * 数据字典 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysDictDetailService extends IService {
+
+ /**
+ * 分页
+ *
+ * @param page page
+ * @param dictId dictId
+ * @return IPage
+ */
+ IPage listByPage(Page page, String dictId);
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/SysDictService.java b/src/main/java/com/huoran/iasf/service/SysDictService.java
new file mode 100644
index 0000000..c21b446
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysDictService.java
@@ -0,0 +1,16 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysDictEntity;
+
+/**
+ * 数据字典 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysDictService extends IService {
+
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/SysFilesService.java b/src/main/java/com/huoran/iasf/service/SysFilesService.java
new file mode 100644
index 0000000..286f0f1
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysFilesService.java
@@ -0,0 +1,23 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.common.utils.R;
+import com.huoran.iasf.entity.SysFilesEntity;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * 文件上传 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysFilesService extends IService {
+
+ R saveFile(MultipartFile file);
+
+ void removeByIdsAndFiles(List ids);
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/SysJobLogService.java b/src/main/java/com/huoran/iasf/service/SysJobLogService.java
new file mode 100644
index 0000000..4928112
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysJobLogService.java
@@ -0,0 +1,16 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysJobLogEntity;
+
+/**
+ * 定时任务 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysJobLogService extends IService {
+
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/SysJobService.java b/src/main/java/com/huoran/iasf/service/SysJobService.java
new file mode 100644
index 0000000..d0bb02b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysJobService.java
@@ -0,0 +1,67 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysJobEntity;
+
+import java.util.List;
+
+/**
+ * 定时任务 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface SysJobService extends IService {
+
+ /**
+ * 保存job
+ *
+ * @param sysJob sysJob
+ */
+ void saveJob(SysJobEntity sysJob);
+
+ /**
+ * 更新job
+ *
+ * @param sysJob sysJob
+ */
+ void updateJobById(SysJobEntity sysJob);
+
+ /**
+ * 删除job
+ *
+ * @param ids ids
+ */
+ void delete(List ids);
+
+ /**
+ * 运行一次job
+ *
+ * @param ids ids
+ */
+ void run(List ids);
+
+ /**
+ * 暂停job
+ *
+ * @param ids ids
+ */
+ void pause(List ids);
+
+ /**
+ * 恢复job
+ *
+ * @param ids ids
+ */
+ void resume(List ids);
+
+ /**
+ * 批量更新状态
+ *
+ * @param ids ids
+ * @param status status
+ */
+ void updateBatch(List ids, int status);
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/SysRoleDeptService.java b/src/main/java/com/huoran/iasf/service/SysRoleDeptService.java
new file mode 100644
index 0000000..07b1f53
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/SysRoleDeptService.java
@@ -0,0 +1,16 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysRoleDeptEntity;
+
+/**
+ * 角色部门
+ *
+ * @author cheney
+ * @email *****@mail.com
+ * @date 2020-09-27 17:30:15
+ */
+public interface SysRoleDeptService extends IService {
+
+}
+
diff --git a/src/main/java/com/huoran/iasf/service/UserRoleService.java b/src/main/java/com/huoran/iasf/service/UserRoleService.java
new file mode 100644
index 0000000..5a8dfca
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/UserRoleService.java
@@ -0,0 +1,40 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysUserRole;
+import com.huoran.iasf.vo.req.UserRoleOperationReqVO;
+
+import java.util.List;
+
+/**
+ * 用户角色 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface UserRoleService extends IService {
+
+ /**
+ * 根据userId获取绑定的角色id
+ *
+ * @param userId userId
+ * @return List
+ */
+ List getRoleIdsByUserId(String userId);
+
+ /**
+ * 用户绑定角色
+ *
+ * @param vo vo
+ */
+ void addUserRoleInfo(UserRoleOperationReqVO vo);
+
+ /**
+ * 根据角色id获取绑定的人
+ *
+ * @param roleId roleId
+ * @return List
+ */
+ List getUserIdsByRoleId(String roleId);
+}
diff --git a/src/main/java/com/huoran/iasf/service/UserService.java b/src/main/java/com/huoran/iasf/service/UserService.java
new file mode 100644
index 0000000..5949061
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/UserService.java
@@ -0,0 +1,76 @@
+package com.huoran.iasf.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huoran.iasf.entity.SysUser;
+import com.huoran.iasf.vo.resp.LoginRespVO;
+import com.huoran.iasf.vo.resp.UserOwnRoleRespVO;
+
+/**
+ * 用户 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+public interface UserService extends IService {
+
+ /**
+ * 注册
+ *
+ * @param vo vo
+ */
+ void register(SysUser vo);
+
+ /**
+ * 登陆
+ *
+ * @param vo vo
+ * @return LoginRespVO
+ */
+ LoginRespVO login(SysUser vo);
+
+ /**
+ * 更新用户信息
+ *
+ * @param vo vo
+ */
+ void updateUserInfo(SysUser vo);
+
+ /**
+ * 分页
+ *
+ * @param vo vo
+ * @return IPage
+ */
+ IPage pageInfo(SysUser vo);
+
+ /**
+ * 添加用户
+ *
+ * @param vo vo
+ */
+ void addUser(SysUser vo);
+
+ /**
+ * 修改密码
+ *
+ * @param vo vo
+ */
+ void updatePwd(SysUser vo);
+
+ /**
+ * 根据userid获取绑定角色
+ *
+ * @param userId userId
+ * @return UserOwnRoleRespVO
+ */
+ UserOwnRoleRespVO getUserOwnRole(String userId);
+
+ /**
+ * 修改自己信息
+ *
+ * @param vo vo
+ */
+ void updateUserInfoMy(SysUser vo);
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/DeptServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/DeptServiceImpl.java
new file mode 100644
index 0000000..4fc26a3
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/DeptServiceImpl.java
@@ -0,0 +1,212 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.common.exception.BusinessException;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.entity.SysDept;
+import com.huoran.iasf.entity.SysUser;
+import com.huoran.iasf.mapper.SysDeptMapper;
+import com.huoran.iasf.mapper.SysUserMapper;
+import com.huoran.iasf.service.DeptService;
+import com.huoran.iasf.vo.resp.DeptRespNodeVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * 部门
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+@Slf4j
+public class DeptServiceImpl extends ServiceImpl implements DeptService {
+
+ @Resource
+ private SysDeptMapper sysDeptMapper;
+ @Resource
+ private SysUserMapper sysUserMapper;
+
+ @Override
+ public void addDept(SysDept vo) {
+ String relationCode;
+ String deptCode = this.getNewDeptCode();
+ SysDept parent = sysDeptMapper.selectById(vo.getPid());
+ if ("0".equals(vo.getPid())) {
+ relationCode = deptCode;
+ } else if (null == parent) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ } else {
+ relationCode = parent.getRelationCode() + deptCode;
+ }
+ vo.setDeptNo(deptCode);
+ vo.setRelationCode(relationCode);
+ vo.setStatus(1);
+ sysDeptMapper.insert(vo);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateDept(SysDept vo) {
+
+ SysDept sysDept = sysDeptMapper.selectById(vo.getId());
+ if (null == sysDept) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ sysDeptMapper.updateById(vo);
+ //说明层级发生了变化
+ if (!StringUtils.isEmpty(vo.getPid()) && !vo.getPid().equals(sysDept.getPid())) {
+ SysDept parent = sysDeptMapper.selectById(vo.getPid());
+ if (!"0".equals(vo.getPid()) && null == parent) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ SysDept oldParent = sysDeptMapper.selectById(sysDept.getPid());
+ String oldRelationCode;
+ String newRelationCode;
+ //根目录降到其他目录
+ if ("0".equals(sysDept.getPid())) {
+ oldRelationCode = sysDept.getDeptNo();
+ newRelationCode = parent.getRelationCode() + sysDept.getDeptNo();
+ } else if ("0".equals(vo.getPid())) { // 其他目录升级到跟目录
+ oldRelationCode = sysDept.getRelationCode();
+ newRelationCode = sysDept.getDeptNo();
+ } else {
+ oldRelationCode = oldParent.getRelationCode();
+ newRelationCode = parent.getRelationCode();
+ }
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.likeLeft(SysDept::getDeptNo, sysDept.getDeptNo());
+ List list = sysDeptMapper.selectList(wrapper);
+ list.parallelStream().forEach(entity -> {
+ String relationCode = entity.getRelationCode().replace(oldRelationCode, newRelationCode);
+ entity.setRelationCode(relationCode);
+ sysDeptMapper.updateById(entity);
+ });
+ }
+ }
+
+ @Override
+ public void deleted(String id) {
+ SysDept sysDept = sysDeptMapper.selectById(id);
+ if (null == sysDept) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ List deptIds = sysDeptMapper.selectObjs(Wrappers.lambdaQuery().select(SysDept::getId).likeRight(SysDept::getRelationCode, sysDept.getRelationCode()));
+ List list = sysUserMapper.selectList(Wrappers.lambdaQuery().in(SysUser::getDeptId, deptIds));
+ if (!CollectionUtils.isEmpty(list)) {
+ throw new BusinessException(BaseResponseCode.NOT_PERMISSION_DELETED_DEPT);
+ }
+ sysDeptMapper.deleteById(id);
+ }
+
+ @Override
+ public List deptTreeList(String deptId, Boolean disabled) {
+ List list;
+ if (StringUtils.isEmpty(deptId)) {
+ list = sysDeptMapper.selectList(Wrappers.emptyWrapper());
+ } else {
+ SysDept sysDept = sysDeptMapper.selectById(deptId);
+ if (sysDept == null) {
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().likeRight(SysDept::getRelationCode, sysDept.getRelationCode());
+ List childIds = sysDeptMapper.selectObjs(queryWrapper);
+ list = sysDeptMapper.selectList(Wrappers.lambdaQuery().notIn(SysDept::getId, childIds));
+ }
+ // 默认加一个顶级方便新增顶级部门
+ DeptRespNodeVO respNodeVO = new DeptRespNodeVO();
+ respNodeVO.setTitle("默认顶级部门");
+ respNodeVO.setId("0");
+ respNodeVO.setSpread(true);
+ respNodeVO.setDisabled(disabled);
+ respNodeVO.setChildren(getTree(list));
+ List result = new ArrayList<>();
+ result.add(respNodeVO);
+ return result;
+ }
+
+ private List getTree(List all) {
+ List list = new ArrayList<>();
+ for (SysDept sysDept : all) {
+ if ("0".equals(sysDept.getPid())) {
+ DeptRespNodeVO deptTree = new DeptRespNodeVO();
+ BeanUtils.copyProperties(sysDept, deptTree);
+ deptTree.setTitle(sysDept.getName());
+ deptTree.setSpread(true);
+ deptTree.setChildren(getChild(sysDept.getId(), all));
+ list.add(deptTree);
+ }
+ }
+ return list;
+ }
+
+ private List getChild(String id, List all) {
+ List list = new ArrayList<>();
+ for (SysDept sysDept : all) {
+ if (sysDept.getPid().equals(id)) {
+ DeptRespNodeVO deptTree = new DeptRespNodeVO();
+ BeanUtils.copyProperties(sysDept, deptTree);
+ deptTree.setTitle(sysDept.getName());
+ deptTree.setChildren(getChild(sysDept.getId(), all));
+ list.add(deptTree);
+ }
+ }
+ return list;
+ }
+
+ //获取新的部门编码
+ public String getNewDeptCode() {
+ LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery();
+ lambdaQueryWrapper.select(SysDept::getDeptNo);
+ //获取所有的deptCode
+ List deptCodes = sysDeptMapper.selectObjs(lambdaQueryWrapper);
+ AtomicReference maxDeptCode = new AtomicReference<>(0);
+
+ //遍历获取最大的DeptCode
+ deptCodes.forEach(o -> {
+ String str = String.valueOf(o);
+ if (str.length() >= 7) {
+ Integer one = Integer.parseInt(str.substring(str.length() - 5));
+ if (one > maxDeptCode.get()) {
+ maxDeptCode.set(one);
+ }
+ }
+ });
+
+ return padRight(maxDeptCode.get() + 1, 6, "0");
+ }
+
+
+ /**
+ * 右补位,左对齐
+ *
+ * @param len 目标字符串长度
+ * @param alexi 补位字符
+ * @param oriStr 原字符串
+ * @return 目标字符串
+ * 以alexin 做为补位
+ */
+ public static String padRight(int oriStr, int len, String alexi) {
+ StringBuilder str = new StringBuilder();
+ int strlen = String.valueOf(oriStr).length();
+ if (strlen < len) {
+ for (int i = 0; i < len - strlen; i++) {
+ str.append(alexi);
+ }
+ }
+ str.append(oriStr);
+ return "D" + str.toString();
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/HomeServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/HomeServiceImpl.java
new file mode 100644
index 0000000..cb5ba9b
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/HomeServiceImpl.java
@@ -0,0 +1,58 @@
+package com.huoran.iasf.service.impl;
+
+import com.huoran.iasf.entity.SysDept;
+import com.huoran.iasf.entity.SysUser;
+import com.huoran.iasf.service.DeptService;
+import com.huoran.iasf.service.HomeService;
+import com.huoran.iasf.service.PermissionService;
+import com.huoran.iasf.service.UserService;
+import com.huoran.iasf.vo.resp.HomeRespVO;
+import com.huoran.iasf.vo.resp.PermissionRespNode;
+import com.huoran.iasf.vo.resp.UserInfoRespVO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 首页
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+public class HomeServiceImpl implements HomeService {
+ @Resource
+ private UserService userService;
+ @Resource
+ private DeptService deptService;
+ @Resource
+ private PermissionService permissionService;
+
+ @Override
+ public HomeRespVO getHomeInfo(String userId) {
+
+
+ SysUser sysUser = userService.getById(userId);
+ UserInfoRespVO vo = new UserInfoRespVO();
+
+ if (sysUser != null) {
+ BeanUtils.copyProperties(sysUser, vo);
+ SysDept sysDept = deptService.getById(sysUser.getDeptId());
+ if (sysDept != null) {
+ vo.setDeptId(sysDept.getId());
+ vo.setDeptName(sysDept.getName());
+ }
+ }
+
+ List menus = permissionService.permissionTreeList(userId);
+
+ HomeRespVO respVO = new HomeRespVO();
+ respVO.setMenus(menus);
+ respVO.setUserInfo(vo);
+
+ return respVO;
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/LogServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/LogServiceImpl.java
new file mode 100644
index 0000000..bb61562
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/LogServiceImpl.java
@@ -0,0 +1,18 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.entity.SysLog;
+import com.huoran.iasf.mapper.SysLogMapper;
+import com.huoran.iasf.service.LogService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 系统日志
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+public class LogServiceImpl extends ServiceImpl implements LogService {
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/PermissionServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/PermissionServiceImpl.java
new file mode 100644
index 0000000..7c4024f
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/PermissionServiceImpl.java
@@ -0,0 +1,269 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.common.exception.BusinessException;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.entity.SysPermission;
+import com.huoran.iasf.entity.SysRolePermission;
+import com.huoran.iasf.entity.SysUserRole;
+import com.huoran.iasf.mapper.SysPermissionMapper;
+import com.huoran.iasf.service.HttpSessionService;
+import com.huoran.iasf.service.PermissionService;
+import com.huoran.iasf.service.RolePermissionService;
+import com.huoran.iasf.service.UserRoleService;
+import com.huoran.iasf.vo.resp.PermissionRespNode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 菜单权限
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+@Slf4j
+public class PermissionServiceImpl extends ServiceImpl implements PermissionService {
+ @Resource
+ private UserRoleService userRoleService;
+ @Resource
+ private RolePermissionService rolePermissionService;
+ @Resource
+ private SysPermissionMapper sysPermissionMapper;
+ @Resource
+ private HttpSessionService httpSessionService;
+
+ /**
+ * 根据用户查询拥有的权限
+ * 先查出用户拥有的角色
+ * 再去差用户拥有的权限
+ * 也可以多表关联查询
+ */
+ @Override
+ public List getPermission(String userId) {
+ List roleIds = userRoleService.getRoleIdsByUserId(userId);
+ if (CollectionUtils.isEmpty(roleIds)) {
+ return null;
+ }
+ List permissionIds = rolePermissionService.listObjs(Wrappers.lambdaQuery().select(SysRolePermission::getPermissionId).in(SysRolePermission::getRoleId, roleIds));
+ if (CollectionUtils.isEmpty(permissionIds)) {
+ return null;
+ }
+
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().in(SysPermission::getId, permissionIds).eq(SysPermission::getStatus, 1).orderByAsc(SysPermission::getOrderNum);
+ return sysPermissionMapper.selectList(queryWrapper);
+ }
+
+ /**
+ * 删除菜单权限
+ * 判断是否 有角色关联
+ * 判断是否有子集
+ */
+ @Transactional(rollbackFor = Exception.class)
+ @Override
+ public void deleted(String permissionId) {
+ //获取关联userId
+ List userIds = getUserIdsById(permissionId);
+ SysPermission sysPermission = sysPermissionMapper.selectById(permissionId);
+ if (null == sysPermission) {
+ log.error("传入 的 id:{}不合法", permissionId);
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ //获取下一级
+ List childs = sysPermissionMapper.selectList(Wrappers.lambdaQuery().eq(SysPermission::getPid, permissionId));
+ if (!CollectionUtils.isEmpty(childs)) {
+ throw new BusinessException(BaseResponseCode.ROLE_PERMISSION_RELATION);
+ }
+ sysPermissionMapper.deleteById(permissionId);
+ //删除和角色关联
+ rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getPermissionId, permissionId));
+
+ if (!CollectionUtils.isEmpty(userIds)) {
+ //刷新权限
+ userIds.parallelStream().forEach(httpSessionService::refreshUerId);
+ }
+
+ }
+
+ @Override
+ public void updatePermission(SysPermission vo) {
+ sysPermissionMapper.updateById(vo);
+ httpSessionService.refreshPermission(vo.getId());
+ }
+
+ /**
+ * 获取所有菜单权限
+ */
+ @Override
+ public List selectAll() {
+ List result = sysPermissionMapper.selectList(Wrappers.lambdaQuery().orderByAsc(SysPermission::getOrderNum));
+ if (!CollectionUtils.isEmpty(result)) {
+ for (SysPermission sysPermission : result) {
+ SysPermission parent = sysPermissionMapper.selectById(sysPermission.getPid());
+ if (parent != null) {
+ sysPermission.setPidName(parent.getName());
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 获取权限标识
+ */
+ @Override
+ public Set getPermissionsByUserId(String userId) {
+
+ List list = getPermission(userId);
+ Set permissions = new HashSet<>();
+ if (CollectionUtils.isEmpty(list)) {
+ return null;
+ }
+ for (SysPermission sysPermission : list) {
+ if (!StringUtils.isEmpty(sysPermission.getPerms())) {
+ permissions.add(sysPermission.getPerms());
+ }
+
+ }
+ return permissions;
+ }
+
+ /**
+ * 以树型的形式把用户拥有的菜单权限返回给客户端
+ */
+ @Override
+ public List permissionTreeList(String userId) {
+ List list = getPermission(userId);
+ return getTree(list, true);
+ }
+
+ /**
+ * 递归获取菜单树
+ */
+ private List getTree(List all, boolean type) {
+
+ List list = new ArrayList<>();
+ if (CollectionUtils.isEmpty(all)) {
+ return list;
+ }
+ for (SysPermission sysPermission : all) {
+ if ("0".equals(sysPermission.getPid())) {
+ PermissionRespNode permissionRespNode = new PermissionRespNode();
+ BeanUtils.copyProperties(sysPermission, permissionRespNode);
+ permissionRespNode.setTitle(sysPermission.getName());
+
+ if (type) {
+ permissionRespNode.setChildren(getChildExcBtn(sysPermission.getId(), all));
+ } else {
+ permissionRespNode.setChildren(getChildAll(sysPermission.getId(), all));
+ }
+ list.add(permissionRespNode);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * 递归遍历所有
+ */
+ private List getChildAll(String id, List all) {
+
+ List list = new ArrayList<>();
+ for (SysPermission sysPermission : all) {
+ if (sysPermission.getPid().equals(id)) {
+ PermissionRespNode permissionRespNode = new PermissionRespNode();
+ BeanUtils.copyProperties(sysPermission, permissionRespNode);
+ permissionRespNode.setTitle(sysPermission.getName());
+ permissionRespNode.setChildren(getChildAll(sysPermission.getId(), all));
+ list.add(permissionRespNode);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * 只递归获取目录和菜单
+ */
+ private List getChildExcBtn(String id, List all) {
+
+ List list = new ArrayList<>();
+ for (SysPermission sysPermission : all) {
+ if (sysPermission.getPid().equals(id) && sysPermission.getType() != 3) {
+ PermissionRespNode permissionRespNode = new PermissionRespNode();
+ BeanUtils.copyProperties(sysPermission, permissionRespNode);
+ permissionRespNode.setTitle(sysPermission.getName());
+ permissionRespNode.setChildren(getChildExcBtn(sysPermission.getId(), all));
+ list.add(permissionRespNode);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * 获取所有菜单权限按钮
+ */
+ @Override
+ public List selectAllByTree() {
+
+ List list = selectAll();
+ return getTree(list, false);
+ }
+
+ /**
+ * 获取所有的目录菜单树排除按钮
+ * 因为不管是新增或者修改
+ * 选择所属菜单目录的时候
+ * 都不可能选择到按钮
+ * 而且编辑的时候 所属目录不能
+ * 选择自己和它的子类
+ */
+ @Override
+ public List selectAllMenuByTree(String permissionId) {
+
+ List list = selectAll();
+ if (!CollectionUtils.isEmpty(list) && !StringUtils.isEmpty(permissionId)) {
+ for (SysPermission sysPermission : list) {
+ if (sysPermission.getId().equals(permissionId)) {
+ list.remove(sysPermission);
+ break;
+ }
+ }
+ }
+ List result = new ArrayList<>();
+ //新增顶级目录是为了方便添加一级目录
+ PermissionRespNode respNode = new PermissionRespNode();
+ respNode.setId("0");
+ respNode.setTitle("默认顶级菜单");
+ respNode.setSpread(true);
+ respNode.setChildren(getTree(list, true));
+ result.add(respNode);
+ return result;
+ }
+
+ @Override
+ public List getUserIdsById(String id) {
+ //根据权限id,获取所有角色id
+ //根据权限id,获取所有角色id
+ List roleIds = rolePermissionService.listObjs(Wrappers.lambdaQuery().select(SysRolePermission::getRoleId).eq(SysRolePermission::getPermissionId, id));
+ if (!CollectionUtils.isEmpty(roleIds)) {
+ //根据角色id, 获取关联用户
+ return userRoleService.listObjs(Wrappers.lambdaQuery().select(SysUserRole::getUserId).in(SysUserRole::getRoleId, roleIds));
+ }
+ return null;
+ }
+
+
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/RolePermissionServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/RolePermissionServiceImpl.java
new file mode 100644
index 0000000..99697d2
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/RolePermissionServiceImpl.java
@@ -0,0 +1,36 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.entity.SysRolePermission;
+import com.huoran.iasf.mapper.SysRolePermissionMapper;
+import com.huoran.iasf.service.RolePermissionService;
+import com.huoran.iasf.vo.req.RolePermissionOperationReqVO;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 角色权限关联
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+public class RolePermissionServiceImpl extends ServiceImpl implements RolePermissionService {
+ @Override
+ public void addRolePermission(RolePermissionOperationReqVO vo) {
+ List list = new ArrayList<>();
+ for (String permissionId : vo.getPermissionIds()) {
+ SysRolePermission sysRolePermission = new SysRolePermission();
+ sysRolePermission.setPermissionId(permissionId);
+ sysRolePermission.setRoleId(vo.getRoleId());
+ list.add(sysRolePermission);
+ }
+ this.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, vo.getRoleId()));
+ this.saveBatch(list);
+ }
+
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/RoleServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/RoleServiceImpl.java
new file mode 100644
index 0000000..f53b76a
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/RoleServiceImpl.java
@@ -0,0 +1,166 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.common.exception.BusinessException;
+import com.huoran.iasf.common.exception.code.BaseResponseCode;
+import com.huoran.iasf.entity.SysRole;
+import com.huoran.iasf.entity.SysRoleDeptEntity;
+import com.huoran.iasf.entity.SysRolePermission;
+import com.huoran.iasf.entity.SysUserRole;
+import com.huoran.iasf.mapper.SysRoleMapper;
+import com.huoran.iasf.service.*;
+import com.huoran.iasf.vo.req.RolePermissionOperationReqVO;
+import com.huoran.iasf.vo.resp.DeptRespNodeVO;
+import com.huoran.iasf.vo.resp.PermissionRespNode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 角色
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service
+@Slf4j
+public class RoleServiceImpl extends ServiceImpl implements RoleService {
+ @Resource
+ private SysRoleMapper sysRoleMapper;
+ @Resource
+ private UserRoleService userRoleService;
+ @Resource
+ private RolePermissionService rolePermissionService;
+ @Resource
+ private PermissionService permissionService;
+ @Resource
+ private HttpSessionService httpSessionService;
+ @Resource
+ private DeptService deptService;
+ @Resource
+ private SysRoleDeptService sysRoleDeptService;
+
+ @Transactional(rollbackFor = Exception.class)
+ @Override
+ public void addRole(SysRole vo) {
+
+ vo.setStatus(1);
+ sysRoleMapper.insert(vo);
+ if (!CollectionUtils.isEmpty(vo.getPermissions())) {
+ RolePermissionOperationReqVO reqVO = new RolePermissionOperationReqVO();
+ reqVO.setRoleId(vo.getId());
+ reqVO.setPermissionIds(vo.getPermissions());
+ rolePermissionService.addRolePermission(reqVO);
+ }
+ }
+
+ @Transactional(rollbackFor = Exception.class)
+ @Override
+ public void updateRole(SysRole vo) {
+ SysRole sysRole = sysRoleMapper.selectById(vo.getId());
+ if (null == sysRole) {
+ log.error("传入 的 id:{}不合法", vo.getId());
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ sysRoleMapper.updateById(vo);
+ //删除角色权限关联
+ rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, sysRole.getId()));
+ if (!CollectionUtils.isEmpty(vo.getPermissions())) {
+ RolePermissionOperationReqVO reqVO = new RolePermissionOperationReqVO();
+ reqVO.setRoleId(sysRole.getId());
+ reqVO.setPermissionIds(vo.getPermissions());
+ rolePermissionService.addRolePermission(reqVO);
+ // 刷新权限
+ httpSessionService.refreshRolePermission(sysRole.getId());
+ }
+ }
+
+ @Override
+ public SysRole detailInfo(String id) {
+ SysRole sysRole = sysRoleMapper.selectById(id);
+ if (sysRole == null) {
+ log.error("传入 的 id:{}不合法", id);
+ throw new BusinessException(BaseResponseCode.DATA_ERROR);
+ }
+ List permissionRespNodes = permissionService.selectAllByTree();
+ LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().select(SysRolePermission::getPermissionId).eq(SysRolePermission::getRoleId, sysRole.getId());
+ Set checkList =
+ new HashSet<>(rolePermissionService.listObjs(queryWrapper));
+ setChecked(permissionRespNodes, checkList);
+ sysRole.setPermissionRespNodes(permissionRespNodes);
+
+ LambdaQueryWrapper queryWrapperDept = Wrappers.lambdaQuery().select(SysRoleDeptEntity::getDeptId).eq(SysRoleDeptEntity::getRoleId, sysRole.getId());
+ List deptRespNodes = deptService.deptTreeList(null, true);
+ Set checkDeptList =
+ new HashSet<>(sysRoleDeptService.listObjs(queryWrapperDept));
+ setCheckedDept(deptRespNodes, checkDeptList);
+ sysRole.setDeptRespNodes(deptRespNodes);
+ return sysRole;
+ }
+
+ private void setCheckedDept(List deptRespNodes, Set checkDeptList) {
+ for (DeptRespNodeVO node : deptRespNodes) {
+ if (checkDeptList.contains(node.getId())) {
+ node.setChecked(true);
+ }
+ setCheckedDept((List) node.getChildren(), checkDeptList);
+ }
+ }
+
+
+ private void setChecked(List list, Set checkList) {
+ for (PermissionRespNode node : list) {
+ if (checkList.contains(node.getId())
+ && CollectionUtils.isEmpty(node.getChildren())) {
+ node.setChecked(true);
+ }
+ setChecked((List) node.getChildren(), checkList);
+ }
+ }
+
+ @Transactional(rollbackFor = Exception.class)
+ @Override
+ public void deletedRole(String id) {
+ //获取关联userId
+ List userIds = userRoleService.getUserIdsByRoleId(id);
+ //删除角色
+ sysRoleMapper.deleteById(id);
+ //删除角色权限关联
+ rolePermissionService.remove(Wrappers.lambdaQuery().eq(SysRolePermission::getRoleId, id));
+ //删除角色用户关联
+ userRoleService.remove(Wrappers.lambdaQuery().eq(SysUserRole::getRoleId, id));
+ if (!CollectionUtils.isEmpty(userIds)) {
+ // 刷新权限
+ userIds.parallelStream().forEach(httpSessionService::refreshUerId);
+ }
+ }
+
+ @Override
+ public List getRoleInfoByUserId(String userId) {
+
+ List roleIds = userRoleService.getRoleIdsByUserId(userId);
+ if (CollectionUtils.isEmpty(roleIds)) {
+ return null;
+ }
+ return sysRoleMapper.selectBatchIds(roleIds);
+ }
+
+ @Override
+ public List getRoleNames(String userId) {
+ List sysRoles = getRoleInfoByUserId(userId);
+ if (CollectionUtils.isEmpty(sysRoles)) {
+ return null;
+ }
+ return sysRoles.stream().map(SysRole::getName).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java
new file mode 100644
index 0000000..991dc6a
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/SysContentServiceImpl.java
@@ -0,0 +1,20 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.entity.SysContentEntity;
+import com.huoran.iasf.mapper.SysContentMapper;
+import com.huoran.iasf.service.SysContentService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 内容 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service("sysContentService")
+public class SysContentServiceImpl extends ServiceImpl implements SysContentService {
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/service/impl/SysDictDetailServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysDictDetailServiceImpl.java
new file mode 100644
index 0000000..ab539b1
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/SysDictDetailServiceImpl.java
@@ -0,0 +1,51 @@
+package com.huoran.iasf.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.common.exception.BusinessException;
+import com.huoran.iasf.entity.SysDictDetailEntity;
+import com.huoran.iasf.entity.SysDictEntity;
+import com.huoran.iasf.mapper.SysDictDetailMapper;
+import com.huoran.iasf.mapper.SysDictMapper;
+import com.huoran.iasf.service.SysDictDetailService;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+
+/**
+ * 数据字典 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service("sysDictDetailService")
+public class SysDictDetailServiceImpl extends ServiceImpl implements SysDictDetailService {
+ @Resource
+ private SysDictDetailMapper sysDictDetailMapper;
+ @Resource
+ private SysDictMapper sysDictMapper;
+
+
+ @Override
+ public IPage listByPage(Page page, String dictId) {
+
+ SysDictEntity sysDictEntity = sysDictMapper.selectById(dictId);
+ if (sysDictEntity == null) {
+ throw new BusinessException("获取字典数据失败!");
+ }
+
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.eq(SysDictDetailEntity::getDictId, dictId);
+ wrapper.orderByAsc(SysDictDetailEntity::getSort);
+ IPage result = sysDictDetailMapper.selectPage(page, wrapper);
+ if (!CollectionUtils.isEmpty(result.getRecords())) {
+ result.getRecords().parallelStream().forEach(entity -> entity.setDictName(sysDictEntity.getName()));
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/huoran/iasf/service/impl/SysDictServiceImpl.java b/src/main/java/com/huoran/iasf/service/impl/SysDictServiceImpl.java
new file mode 100644
index 0000000..e3e20ed
--- /dev/null
+++ b/src/main/java/com/huoran/iasf/service/impl/SysDictServiceImpl.java
@@ -0,0 +1,51 @@
+package com.huoran.iasf.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huoran.iasf.entity.SysDictDetailEntity;
+import com.huoran.iasf.entity.SysDictEntity;
+import com.huoran.iasf.mapper.SysDictDetailMapper;
+import com.huoran.iasf.mapper.SysDictMapper;
+import com.huoran.iasf.service.SysDictService;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 数据字典 服务类
+ *
+ * @author cheney
+ * @version V1.0
+ * @date 2022年7月28日
+ */
+@Service("sysDictService")
+public class SysDictServiceImpl extends ServiceImpl implements SysDictService {
+
+ @Resource
+ private SysDictDetailMapper sysDictDetailMapper;
+
+ /**
+ * 根据字典类型查询字典数据信息
+ *
+ * @param name 字典名称
+ * @return 参数键值
+ **/
+ public JSONArray getType(String name) {
+ if (StringUtils.isEmpty(name)) {
+ return new JSONArray();
+ }
+ //根据名称获取字典
+ SysDictEntity dict = this.getOne(Wrappers.