From e130377e8c1c523536f80e9758670f75cdf1bf64 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 22 Jun 2022 09:56:52 +0800 Subject: [PATCH 01/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E7=99=BB=E5=BD=95=E7=8A=B6=E6=80=81=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/exception/LoginStatusException.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 ym-admin/src/main/java/com/cnbm/admin/exception/LoginStatusException.java diff --git a/ym-admin/src/main/java/com/cnbm/admin/exception/LoginStatusException.java b/ym-admin/src/main/java/com/cnbm/admin/exception/LoginStatusException.java new file mode 100644 index 0000000..8dd9d59 --- /dev/null +++ b/ym-admin/src/main/java/com/cnbm/admin/exception/LoginStatusException.java @@ -0,0 +1,66 @@ +package com.cnbm.admin.exception; + +import com.cnbm.common.exception.ErrorCode; +import com.cnbm.common.utils.MessageUtils; + +/** + * @Author weihongyang + * @Date 2022/6/22 9:44 AM + * @Version 1.0 + */ +public class LoginStatusException extends RuntimeException{ + private static final long serialVersionUID = 1L; + + private int code; + private String msg; + + public LoginStatusException(int code) { + this.code = code; + this.msg = MessageUtils.getMessage(code); + } + + public LoginStatusException(int code, String... params) { + this.code = code; + this.msg = MessageUtils.getMessage(code, params); + } + + public LoginStatusException(int code, Throwable e) { + super(e); + this.code = code; + this.msg = MessageUtils.getMessage(code); + } + + public LoginStatusException(int code, Throwable e, String... params) { + super(e); + this.code = code; + this.msg = MessageUtils.getMessage(code, params); + } + + public LoginStatusException(String msg) { + super(msg); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + + public LoginStatusException(String msg, Throwable e) { + super(msg, e); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } +} From 4fe4936dfdfd81a7d33d526cfe80ab4baffff768 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 22 Jun 2022 09:57:39 +0800 Subject: [PATCH 02/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=BC=82=E5=B8=B8=E6=8D=95=E8=8E=B7=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...onHandler.java => YmExceptionHandler.java} | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) rename ym-admin/src/main/java/com/cnbm/admin/exception/{RenExceptionHandler.java => YmExceptionHandler.java} (62%) diff --git a/ym-admin/src/main/java/com/cnbm/admin/exception/RenExceptionHandler.java b/ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java similarity index 62% rename from ym-admin/src/main/java/com/cnbm/admin/exception/RenExceptionHandler.java rename to ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java index 9d5f48b..c33d554 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/exception/RenExceptionHandler.java +++ b/ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java @@ -1,34 +1,30 @@ package com.cnbm.admin.exception; -import cn.hutool.core.map.MapUtil; -import com.cnbm.admin.entity.SysLogErrorEntity; import com.cnbm.admin.service.SysLogErrorService; import com.cnbm.common.exception.ErrorCode; -import com.cnbm.common.exception.ExceptionUtils; import com.cnbm.common.exception.RenException; -import com.cnbm.common.utils.HttpContextUtils; -import com.cnbm.common.utils.IpUtils; -import com.cnbm.common.utils.JsonUtils; import com.cnbm.common.utils.Result; +import lombok.extern.log4j.Log4j2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; -import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.InternalAuthenticationServiceException; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import javax.servlet.http.HttpServletRequest; -import java.util.Map; - /** * @Author weihongyang * @Date 2022/6/10 2:05 PM * @Version 1.0 */ @RestControllerAdvice -public class RenExceptionHandler { - private static final Logger logger = LoggerFactory.getLogger(RenExceptionHandler.class); +@Log4j2 +public class YmExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(YmExceptionHandler.class); @Autowired private SysLogErrorService sysLogErrorService; @@ -44,6 +40,35 @@ public class RenExceptionHandler { return result; } + @ExceptionHandler(BadCredentialsException.class) + public Result handleBadCredentialsException(BadCredentialsException ex){ + Result result = new Result(); + result.error("密码错误"); + return result; + } + + @ExceptionHandler(UsernameNotFoundException.class) + public Result handleUsernameNotFoundException(UsernameNotFoundException ex){ + Result result = new Result(); + result.error(ex.getMessage()); + return result; + } + + @ExceptionHandler(InternalAuthenticationServiceException.class) + public Result handleInternalAuthenticationServiceException(InternalAuthenticationServiceException ex){ + Result result = new Result(); + result.error(ex.getMessage()); + return result; + } + + + @ExceptionHandler(LoginStatusException.class) + public Result handleLoginStatusException(LoginStatusException ex){ + Result result = new Result(); + result.error(ex.getMessage()); + return result; + } + @ExceptionHandler(DuplicateKeyException.class) public Result handleDuplicateKeyException(DuplicateKeyException ex){ Result result = new Result(); From 3a30a2a34c25812125e4e17864b6e3ee5fed861a Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 22 Jun 2022 09:58:10 +0800 Subject: [PATCH 03/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9sercurity?= =?UTF-8?q?=E7=9A=84UserDetailsService=E7=9A=84=E5=AE=9E=E7=8E=B0=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cnbm/admin/service/impl/UserDetailsServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/impl/UserDetailsServiceImpl.java b/ym-admin/src/main/java/com/cnbm/admin/service/impl/UserDetailsServiceImpl.java index dcee45d..389c4c9 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/impl/UserDetailsServiceImpl.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/impl/UserDetailsServiceImpl.java @@ -7,6 +7,7 @@ import com.cnbm.admin.dto.SysUserDTO; import com.cnbm.admin.entity.LoginUser; import com.cnbm.admin.entity.SysMenuEntity; import com.cnbm.admin.entity.SysUserEntity; +import com.cnbm.admin.exception.LoginStatusException; import com.cnbm.admin.service.SysMenuService; import com.cnbm.common.utils.ConvertUtils; import lombok.extern.log4j.Log4j2; @@ -48,7 +49,7 @@ public class UserDetailsServiceImpl implements UserDetailsService { throw new UsernameNotFoundException("用户名不存在"); } if (sysUserEntity.getStatus() == 0) { - throw new DisabledException("该账户已被禁用,请联系管理员"); + throw new LoginStatusException("该账户已被禁用,请联系管理员"); } log.info("sysUserEntity的值是"+sysUserEntity.toString()); log.info("sysUserEntity.getSuperAdmin()=="+sysUserEntity.getSuperAdmin()); From e01cd0f7fdbf241d53f2b91c0f3062fbdc03b833 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 22 Jun 2022 14:00:18 +0800 Subject: [PATCH 04/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E4=B8=80?= =?UTF-8?q?=E4=B8=AAswagger=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E6=A8=A1=E6=9D=BF=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cnbm/generator/utils/IdWorker.java | 50 +++++ .../com/cnbm/generator/utils/Sequence.java | 187 ++++++++++++++++++ .../src/main/resources/templates/mysql.vm | 7 + 3 files changed, 244 insertions(+) create mode 100644 ym-generator/src/main/java/com/cnbm/generator/utils/IdWorker.java create mode 100644 ym-generator/src/main/java/com/cnbm/generator/utils/Sequence.java create mode 100644 ym-generator/src/main/resources/templates/mysql.vm diff --git a/ym-generator/src/main/java/com/cnbm/generator/utils/IdWorker.java b/ym-generator/src/main/java/com/cnbm/generator/utils/IdWorker.java new file mode 100644 index 0000000..bc069b0 --- /dev/null +++ b/ym-generator/src/main/java/com/cnbm/generator/utils/IdWorker.java @@ -0,0 +1,50 @@ +package com.cnbm.generator.utils; + +import com.baomidou.mybatisplus.core.toolkit.StringPool; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @Author weihongyang + * @Date 2022/6/22 10:52 AM + * @Version 1.0 + */ +public class IdWorker { + + /** + * 主机和进程的机器码 + */ + private static Sequence WORKER = new Sequence(); + + public static long getId() { + return WORKER.nextId(); + } + + public static String getIdStr() { + return String.valueOf(WORKER.nextId()); + } + + /** + *

+ * 有参构造器 + *

+ * + * @param workerId 工作机器 ID + * @param datacenterId 序列号 + */ + public static void initSequence(long workerId, long datacenterId) { + WORKER = new Sequence(workerId, datacenterId); + } + + /** + *

+ * 使用ThreadLocalRandom获取UUID获取更优的效果 去掉"-" + *

+ */ + public static String get32UUID() { + ThreadLocalRandom random = ThreadLocalRandom.current(); + return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY); + } + +} diff --git a/ym-generator/src/main/java/com/cnbm/generator/utils/Sequence.java b/ym-generator/src/main/java/com/cnbm/generator/utils/Sequence.java new file mode 100644 index 0000000..42e3b93 --- /dev/null +++ b/ym-generator/src/main/java/com/cnbm/generator/utils/Sequence.java @@ -0,0 +1,187 @@ +package com.cnbm.generator.utils; + +import cn.hutool.core.date.SystemClock; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @Author weihongyang + * @Date 2022/6/22 10:53 AM + * @Version 1.0 + */ +public class Sequence { + + private static final Log logger = LogFactory.getLog(Sequence.class); + /** + * 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) + */ + private final long twepoch = 1288834974657L; + /** + * 机器标识位数 + */ + private final long workerIdBits = 5L; + private final long datacenterIdBits = 5L; + private final long maxWorkerId = -1L ^ (-1L << workerIdBits); + private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + /** + * 毫秒内自增位 + */ + private final long sequenceBits = 12L; + private final long workerIdShift = sequenceBits; + private final long datacenterIdShift = sequenceBits + workerIdBits; + /** + * 时间戳左移动位 + */ + private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + private final long sequenceMask = -1L ^ (-1L << sequenceBits); + + private final long workerId; + + /** + * 数据标识 ID 部分 + */ + private final long datacenterId; + /** + * 并发控制 + */ + private long sequence = 0L; + /** + * 上次生产 ID 时间戳 + */ + private long lastTimestamp = -1L; + + public Sequence() { + this.datacenterId = getDatacenterId(maxDatacenterId); + this.workerId = getMaxWorkerId(datacenterId, maxWorkerId); + } + + /** + *

+ * 有参构造器 + *

+ * + * @param workerId 工作机器 ID + * @param datacenterId 序列号 + */ + public Sequence(long workerId, long datacenterId) { + Assert.isFalse(workerId > maxWorkerId || workerId < 0, + String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + Assert.isFalse(datacenterId > maxDatacenterId || datacenterId < 0, + String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + /** + *

+ * 获取 maxWorkerId + *

+ */ + protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) { + StringBuilder mpid = new StringBuilder(); + mpid.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (StringUtils.isNotEmpty(name)) { + /* + * GET jvmPid + */ + mpid.append(name.split(StringPool.AT)[0]); + } + /* + * MAC + PID 的 hashcode 获取16个低位 + */ + return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1); + } + + /** + *

+ * 数据标识id部分 + *

+ */ + protected static long getDatacenterId(long maxDatacenterId) { + long id = 0L; + try { + InetAddress ip = InetAddress.getLocalHost(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + id = 1L; + } else { + byte[] mac = network.getHardwareAddress(); + if (null != mac) { + id = ((0x000000FF & (long) mac[mac.length - 1]) | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; + id = id % (maxDatacenterId + 1); + } + } + } catch (Exception e) { + logger.warn(" getDatacenterId: " + e.getMessage()); + } + return id; + } + + /** + * 获取下一个ID + * + * @return + */ + public synchronized long nextId() { + long timestamp = timeGen(); + //闰秒 + if (timestamp < lastTimestamp) { + long offset = lastTimestamp - timestamp; + if (offset <= 5) { + try { + wait(offset << 1); + timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset)); + } + } + + if (lastTimestamp == timestamp) { + // 相同毫秒内,序列号自增 + sequence = (sequence + 1) & sequenceMask; + if (sequence == 0) { + // 同一毫秒的序列数已经达到最大 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + // 不同毫秒内,序列号置为 1 - 3 随机数 + sequence = ThreadLocalRandom.current().nextLong(1, 3); + } + + lastTimestamp = timestamp; + + // 时间戳部分 | 数据中心部分 | 机器标识部分 | 序列号部分 + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + protected long timeGen() { + return SystemClock.now(); + } + +} diff --git a/ym-generator/src/main/resources/templates/mysql.vm b/ym-generator/src/main/resources/templates/mysql.vm new file mode 100644 index 0000000..effaa1f --- /dev/null +++ b/ym-generator/src/main/resources/templates/mysql.vm @@ -0,0 +1,7 @@ +-- 菜单初始SQL +INSERT INTO sys_menu(id, pid, name, url, permissions, type, icon, sort, creator, create_date, updater, update_date)VALUES (${id0}, 1067246875800000035, '${table.comment}', '${package.ModuleName}/${table.entityPath}', NULL, 0, 'icon-desktop', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, type, icon, sort, creator, create_date, updater, update_date) VALUES (${id1}, ${id0}, '查看', NULL, '${package.ModuleName}:${table.entityPath}:page,${package.ModuleName}:${table.entityPath}:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, type, icon, sort, creator, create_date, updater, update_date) VALUES (${id2}, ${id0}, '新增', NULL, '${package.ModuleName}:${table.entityPath}:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, type, icon, sort, creator, create_date, updater, update_date) VALUES (${id3}, ${id0}, '修改', NULL, '${package.ModuleName}:${table.entityPath}:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, type, icon, sort, creator, create_date, updater, update_date) VALUES (${id4}, ${id0}, '删除', NULL, '${package.ModuleName}:${table.entityPath}:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, type, icon, sort, creator, create_date, updater, update_date) VALUES (${id5}, ${id0}, '导出', NULL, '${package.ModuleName}:${table.entityPath}:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); From 89bf5bf10a88cdf0ef0758f5725a0c7eae7f5de1 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 22 Jun 2022 14:02:11 +0800 Subject: [PATCH 05/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E4=B8=80?= =?UTF-8?q?=E4=B8=AAswagger=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E6=A8=A1=E6=9D=BF=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnbm/generator/build/CodeGenerator.java | 84 ++----------------- .../engine/EnhanceVelocityTemplateEngine.java | 7 ++ 2 files changed, 13 insertions(+), 78 deletions(-) diff --git a/ym-generator/src/main/java/com/cnbm/generator/build/CodeGenerator.java b/ym-generator/src/main/java/com/cnbm/generator/build/CodeGenerator.java index 747018b..a133634 100644 --- a/ym-generator/src/main/java/com/cnbm/generator/build/CodeGenerator.java +++ b/ym-generator/src/main/java/com/cnbm/generator/build/CodeGenerator.java @@ -9,11 +9,13 @@ import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine; import com.baomidou.mybatisplus.generator.function.ConverterFileName; import com.cnbm.generator.config.DataConfig; import com.cnbm.generator.engine.EnhanceVelocityTemplateEngine; +import com.cnbm.generator.utils.IdWorker; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import java.io.File; import java.util.*; +import java.util.function.BiConsumer; import static com.baomidou.mybatisplus.generator.config.ConstVal.MODULE_NAME; @@ -27,7 +29,7 @@ public class CodeGenerator { @Test public void test(){ - mybatisPlusGenerator(new String[]{"sys_user"}); + mybatisPlusGenerator(new String[]{"sys_user","sys_role"}); } public static void mybatisPlusGenerator(String[] include){ @@ -36,9 +38,9 @@ public class CodeGenerator { Map customFile = new HashMap<>(); customFile.put("DTO","/templates/DTO.java.vm"); customFile.put("Excel","/templates/Excel.java.vm"); + customFile.put("mysql","/templates/mysql.vm"); + -// customFile.put("Excel","/templates/excel.java.vm"); -// new TemplateConfig.Builder().serviceImpl("/templates/serviceImpl.java"); FastAutoGenerator.create(DataConfig.url,DataConfig.username,DataConfig.password) .globalConfig(builder -> { builder.author("why") @@ -61,87 +63,13 @@ public class CodeGenerator { //设置需要生成的表名 builder.addInclude(include) //设置过滤表前缀 - .addTablePrefix("sys_") -// .entityBuilder().formatFileName("%sEntity") -// .mapperBuilder().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper") -// .controllerBuilder().formatFileName("%sController").enableRestStyle() -// .serviceBuilder().formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImpl") - ; + .addTablePrefix("sys_"); }) .injectionConfig(consumer -> { consumer.customFile(customFile); }) .templateEngine(new EnhanceVelocityTemplateEngine()) -// .templateEngine(new VelocityTemplateEngine(){ -// @Override -// protected void outputCustomFile(@NotNull Map customFile, @NotNull TableInfo tableInfo, @NotNull Map objectMap) { -// //存放取出的实体名称,用于生成路由 -// List entityNames = new ArrayList<>(); -// -// if (!entityNames.contains(tableInfo.getEntityName())) { -// entityNames.add(tableInfo.getEntityName()); -// } -// -// customFile.forEach((key, value) -> { -// String fileName = String.format(path + "/src/main/resources/static/" + tableInfo.getEntityName() + File.separator + tableInfo.getEntityName() + "%s", key); -// this.outputFile(new File(fileName), objectMap, ""); -// }); -// -// // 生成路由部分 -// Map routers = new HashMap<>(); -// routers.put("author", "why"); -// routers.put("date", new Date()); -// routers.put("entities", entityNames); -// -// // 使用 freemarker 模板引擎,路由页面路径 -// String templateRoutesPath = "/templates/DTO.java.vm"; -// -// // 生成的路由页面路径 -// File templateRoutesOutFile = new File(path + "/src/main/java/com/cnbm/generator/engine/"+tableInfo.getEntityName() +"DTO.java"); -// try { -// this.writer(routers, templateRoutesPath, templateRoutesOutFile); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// } -// }) - - -// .templateEngine(new FreemarkerTemplateEngine(){ -// @Override -// protected void outputCustomFile(@NotNull Map customFile, @NotNull TableInfo tableInfo, @NotNull Map objectMap) { -// //存放取出的实体名称,用于生成路由 -// List entityNames = new ArrayList<>(); -// -// if (!entityNames.contains(tableInfo.getEntityName())) { -// entityNames.add(tableInfo.getEntityName()); -// } -// -// customFile.forEach((key, value) -> { -// String fileName = String.format(path + "/src/main/resources/static/" + tableInfo.getEntityName() + File.separator + tableInfo.getEntityName() + "%s", key); -// this.outputFile(new File(fileName), objectMap, ""); -// }); -// -// // 生成路由部分 -// Map routers = new HashMap<>(); -// routers.put("author", "why"); -// routers.put("date", new Date()); -// routers.put("entities", entityNames); -// -// // 使用 freemarker 模板引擎,路由页面路径 -// String templateRoutesPath = "/templates/excel.java.ftl"; -// -// // 生成的路由页面路径 -// File templateRoutesOutFile = new File(path + "/src/main/java/com/cnbm/generator/engine/excel.java"); -// try { -// this.writer(routers, templateRoutesPath, templateRoutesOutFile); -// } catch (Exception e) { -// throw new RuntimeException(e); -// } -// } -// -// }) .execute(); } diff --git a/ym-generator/src/main/java/com/cnbm/generator/engine/EnhanceVelocityTemplateEngine.java b/ym-generator/src/main/java/com/cnbm/generator/engine/EnhanceVelocityTemplateEngine.java index 7d79c0f..bf0f12f 100644 --- a/ym-generator/src/main/java/com/cnbm/generator/engine/EnhanceVelocityTemplateEngine.java +++ b/ym-generator/src/main/java/com/cnbm/generator/engine/EnhanceVelocityTemplateEngine.java @@ -3,6 +3,7 @@ package com.cnbm.generator.engine; import com.baomidou.mybatisplus.generator.config.OutputFile; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine; +import com.cnbm.generator.utils.IdWorker; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -21,6 +22,9 @@ public class EnhanceVelocityTemplateEngine extends VelocityTemplateEngine { // String otherPath = this.getPathInfo(OutputFile.other); File file = new File(""); String path = file.getAbsolutePath(); + for (int i = 0; i < 6; i++) { + objectMap.put("id"+ i, IdWorker.getId()); + } customFile.forEach((key, value) -> { String fileName = ""; if ("DTO".equals(key)) { @@ -29,6 +33,9 @@ public class EnhanceVelocityTemplateEngine extends VelocityTemplateEngine { if ("Excel".equals(key)) { fileName = String.format((path+ File.separator +"src/main/java/com/cnbm/generator/code"+ File.separator + "excel" + File.separator + entityName + "%s" + ".java"), key); } + if ("mysql".equals(key)) { + fileName = String.format((path+ File.separator +"src/main/java/com/cnbm/generator/code"+ File.separator + "mysql" + File.separator + entityName + "%s" + ".sql"), key); + } this.outputFile(new File(fileName), objectMap, value); }); } From 3c4cd948d4a2c28dd37299572b85dd9c78ae78d0 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 22 Jun 2022 14:03:01 +0800 Subject: [PATCH 06/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9jackson=E5=AF=B9?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E7=9A=84=E5=BA=8F=E5=88=97=E5=8C=96=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-gateway/src/main/resources/application.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ym-gateway/src/main/resources/application.yml b/ym-gateway/src/main/resources/application.yml index 7fd704b..8c9bb5d 100644 --- a/ym-gateway/src/main/resources/application.yml +++ b/ym-gateway/src/main/resources/application.yml @@ -24,6 +24,8 @@ spring: mvc: pathmatch: matching-strategy: ANT_PATH_MATCHER + format: + date-time: yyyy-MM-dd HH:mm:ss servlet: multipart: max-file-size: 100MB @@ -41,6 +43,9 @@ spring: max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 10 # 连接池中的最大空闲连接 min-idle: 5 # 连接池中的最小空闲连接 + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss # 是否开启redis缓存 true开启 false关闭 renren: From 7fe617df56157baaa665c2e7c7e25c2160798415 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 09:47:51 +0800 Subject: [PATCH 07/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9jackson=E5=AF=B9?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E7=9A=84=E5=BA=8F=E5=88=97=E5=8C=96=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/cnbm/admin/config/CorsConfig.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/config/CorsConfig.java b/ym-admin/src/main/java/com/cnbm/admin/config/CorsConfig.java index 5999022..19c79e7 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/config/CorsConfig.java +++ b/ym-admin/src/main/java/com/cnbm/admin/config/CorsConfig.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.JSR310Module; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.ByteArrayHttpMessageConverter; @@ -59,17 +60,16 @@ public class CorsConfig implements WebMvcConfigurer { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); - //日期格式转换 - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN)); - mapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); - //Long类型转String类型 SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); mapper.registerModule(simpleModule); - + mapper.registerModules(new JSR310Module()); + //反序列化的时候如果多了其他属性,不抛出异常 + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + //日期格式处理 + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); converter.setObjectMapper(mapper); return converter; } From 47409787a4073a913095434c168aabf595ffbbde Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:51:19 +0800 Subject: [PATCH 08/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Esercurity?= =?UTF-8?q?=E7=9A=84LogoutHandler=E7=9A=84=E5=AE=9E=E7=8E=B0=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnbm/admin/handler/LogoutHandlerImpl.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 ym-admin/src/main/java/com/cnbm/admin/handler/LogoutHandlerImpl.java diff --git a/ym-admin/src/main/java/com/cnbm/admin/handler/LogoutHandlerImpl.java b/ym-admin/src/main/java/com/cnbm/admin/handler/LogoutHandlerImpl.java new file mode 100644 index 0000000..d41ac20 --- /dev/null +++ b/ym-admin/src/main/java/com/cnbm/admin/handler/LogoutHandlerImpl.java @@ -0,0 +1,32 @@ +package com.cnbm.admin.handler; + +import com.cnbm.admin.entity.LoginUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Author weihongyang + * @Date 2022/6/23 11:24 AM + * @Version 1.0 + */ +@Component +public class LogoutHandlerImpl implements LogoutHandler { + + @Autowired + private RedisTemplate redisTemplate; + + @Override + public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { + //获取SecurityContextHolder中的用户id + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + String userid = loginUser.getSysUserEntity().getId().toString(); + //删除redis中的值 + redisTemplate.delete("login:"+userid); + } +} From 4d57b45a02b54f9c4aabf22b3cd6e74e857ea31d Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:51:36 +0800 Subject: [PATCH 09/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Esercurity?= =?UTF-8?q?=E7=9A=84LogoutSuccessHandler=E7=9A=84=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handler/LogoutSuccessHandlerImpl.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 ym-admin/src/main/java/com/cnbm/admin/handler/LogoutSuccessHandlerImpl.java diff --git a/ym-admin/src/main/java/com/cnbm/admin/handler/LogoutSuccessHandlerImpl.java b/ym-admin/src/main/java/com/cnbm/admin/handler/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..82bcb8d --- /dev/null +++ b/ym-admin/src/main/java/com/cnbm/admin/handler/LogoutSuccessHandlerImpl.java @@ -0,0 +1,38 @@ +package com.cnbm.admin.handler; + +import com.cnbm.admin.entity.LoginUser; +import com.cnbm.admin.utils.ResponseResult; +import com.cnbm.admin.utils.WebUtils; +import com.cnbm.common.utils.JsonUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @Author weihongyang + * @Date 2022/6/23 10:44 AM + * @Version 1.0 + */ +@Component +public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { + + @Autowired + private RedisTemplate redisTemplate; + + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + ResponseResult result = new ResponseResult(HttpStatus.OK.value(),"退出成功"); + String json = JsonUtils.toJsonString(result); + WebUtils.renderString(response,json); + } +} From 45435f1cb41762ee80a813549ba540873c7a2490 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:52:54 +0800 Subject: [PATCH 10/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Esercurity?= =?UTF-8?q?=E7=9A=84=E9=80=80=E5=87=BA=E8=B4=A6=E5=8F=B7=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/cnbm/admin/config/SecurityConfig.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java index d6fb33b..fbbd13b 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java +++ b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java @@ -1,6 +1,7 @@ package com.cnbm.admin.config; import com.cnbm.admin.filter.JwtAuthenticationTokenFilter; +import com.cnbm.admin.handler.LogoutSuccessHandlerImpl; import com.cnbm.admin.service.impl.UserDetailsServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -45,6 +46,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsServiceImpl userDetailsService; + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; + @Override protected void configure(HttpSecurity http) throws Exception { @@ -56,14 +60,19 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .and() .authorizeRequests() // 对于登录接口 允许匿名访问 - .antMatchers("/login","/swagger/**","/v2/**", + .antMatchers("/login","/doLogout","/swagger/**","/v2/**", "/doc.html", "/swagger-resources/**", "/swagger-ui/**", "/webjars/**").anonymous() // .antMatchers("/testCors").hasAuthority("system:dept:list222") // 除上面外的所有请求全部需要鉴权认证 - .anyRequest().authenticated(); + .anyRequest() + .authenticated() + // 退出登录,默认为/logout,这里修改接口地址为 /doLogout + .and().logout().logoutUrl("/doLogout") + // 设置退出登录成功处理程序,退出成功后返回JSON字符串 + .logoutSuccessHandler(logoutSuccessHandler); //添加过滤器 http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); From 01863b53445bfef048a6acfcfd54ee1d457a6ca9 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:54:46 +0800 Subject: [PATCH 11/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Ejackson-datatyp?= =?UTF-8?q?e-jsr310=E7=9A=84maven?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 5cb407c..170fc5d 100644 --- a/pom.xml +++ b/pom.xml @@ -197,6 +197,10 @@ lombok ${lombok.version} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + From 681b5fbe63238b735840171fcc7b1fd393221ef7 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:55:08 +0800 Subject: [PATCH 12/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Ejackson?= =?UTF-8?q?=E6=9C=89=E5=85=B3=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-gateway/src/main/resources/application.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ym-gateway/src/main/resources/application.yml b/ym-gateway/src/main/resources/application.yml index 8c9bb5d..511d59d 100644 --- a/ym-gateway/src/main/resources/application.yml +++ b/ym-gateway/src/main/resources/application.yml @@ -44,8 +44,9 @@ spring: max-idle: 10 # 连接池中的最大空闲连接 min-idle: 5 # 连接池中的最小空闲连接 jackson: - time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + default-property-inclusion: non_null # 是否开启redis缓存 true开启 false关闭 renren: From 40c7df817b22fef0118297998a3c90ecdd74f058 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:55:44 +0800 Subject: [PATCH 13/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=80=80?= =?UTF-8?q?=E5=87=BA=E8=B4=A6=E5=8F=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/LoginController.java | 26 ++++++++++++------- .../com/cnbm/admin/service/LoginService.java | 2 ++ .../admin/service/impl/LoginServiceImpl.java | 12 +++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java index 39e020b..64cc902 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java +++ b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java @@ -1,5 +1,6 @@ package com.cnbm.admin.controller; +import com.cnbm.admin.handler.LogoutSuccessHandlerImpl; import com.cnbm.admin.params.LoginParam; import com.cnbm.admin.service.LoginService; import com.cnbm.admin.utils.ResponseResult; @@ -8,12 +9,14 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; -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 org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** * @Author weihongyang @@ -28,16 +31,19 @@ public class LoginController { @Autowired private LoginService loginService; - @RequestMapping("/hello") - @PreAuthorize("@ex.hasAuthority('sys:user:page')") - public String hello(){ - log.info("hello"); - return "hello"; - } + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; @PostMapping("/login") @ApiOperation(value = "登录") public ResponseResult login(HttpServletRequest request, @RequestBody LoginParam loginParam) { return loginService.login(request,loginParam); } + + @PostMapping("/doLogout") + @ApiOperation(value = "退出") + public void logout(){ + } + + } diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java b/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java index 2dfce88..c3f3cff 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java @@ -13,4 +13,6 @@ import javax.servlet.http.HttpServletRequest; public interface LoginService { ResponseResult login(HttpServletRequest request, LoginParam loginParam); + + ResponseResult logout(); } diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java b/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java index 8425e2e..cee7f12 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java @@ -10,6 +10,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; @@ -48,4 +49,15 @@ public class LoginServiceImpl implements LoginService { redisTemplate.opsForValue().set("login:"+userid,loginUser); return new ResponseResult(200,"登录成功",map); } + + @Override + public ResponseResult logout() { + //获取SecurityContextHolder中的用户id + UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + String userid = loginUser.getSysUserEntity().getId().toString(); + //删除redis中的值 + redisTemplate.delete("login:"+userid); + return new ResponseResult(200,"注销成功"); + } } From 3b6496773d05337ecfe8b3022feb7d8722974c08 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 11:56:20 +0800 Subject: [PATCH 14/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E5=AF=86=E7=A0=81=E5=9C=A8swagger=E6=9C=89=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-admin/src/main/java/com/cnbm/admin/params/LoginParam.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/params/LoginParam.java b/ym-admin/src/main/java/com/cnbm/admin/params/LoginParam.java index 9f6ad5f..aa2a651 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/params/LoginParam.java +++ b/ym-admin/src/main/java/com/cnbm/admin/params/LoginParam.java @@ -17,11 +17,11 @@ import java.io.Serializable; public class LoginParam implements Serializable { private static final long serialVersionUID = 1L; - @ApiModelProperty(value = "用户名", required = true) + @ApiModelProperty(value = "用户名", required = true, example = "admin") @NotBlank(message="用户名不能为空") private String username; - @ApiModelProperty(value = "密码" , required = true) + @ApiModelProperty(value = "密码" , required = true, example = "admin") @NotBlank(message="密码不能为空") private String password; From 42de3bd79c9b8e1afd95737c7308dc9ea5238568 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 12:09:55 +0800 Subject: [PATCH 15/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E9=80=80?= =?UTF-8?q?=E5=87=BA=E8=B4=A6=E5=8F=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cnbm/admin/controller/LoginController.java | 3 --- .../main/java/com/cnbm/admin/service/LoginService.java | 1 - .../com/cnbm/admin/service/impl/LoginServiceImpl.java | 10 ---------- 3 files changed, 14 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java index 64cc902..66bc7a8 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java +++ b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java @@ -31,9 +31,6 @@ public class LoginController { @Autowired private LoginService loginService; - @Autowired - private LogoutSuccessHandlerImpl logoutSuccessHandler; - @PostMapping("/login") @ApiOperation(value = "登录") public ResponseResult login(HttpServletRequest request, @RequestBody LoginParam loginParam) { diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java b/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java index c3f3cff..9f93524 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/LoginService.java @@ -14,5 +14,4 @@ public interface LoginService { ResponseResult login(HttpServletRequest request, LoginParam loginParam); - ResponseResult logout(); } diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java b/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java index cee7f12..1c8fdbb 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java @@ -50,14 +50,4 @@ public class LoginServiceImpl implements LoginService { return new ResponseResult(200,"登录成功",map); } - @Override - public ResponseResult logout() { - //获取SecurityContextHolder中的用户id - UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); - LoginUser loginUser = (LoginUser) authentication.getPrincipal(); - String userid = loginUser.getSysUserEntity().getId().toString(); - //删除redis中的值 - redisTemplate.delete("login:"+userid); - return new ResponseResult(200,"注销成功"); - } } From 04f1bb339e69dcff45b9431850f961f5bbbaae61 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 13:54:11 +0800 Subject: [PATCH 16/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9ECaptchaService?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/CaptchaServiceImpl.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 ym-admin/src/main/java/com/cnbm/admin/service/impl/CaptchaServiceImpl.java diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/impl/CaptchaServiceImpl.java b/ym-admin/src/main/java/com/cnbm/admin/service/impl/CaptchaServiceImpl.java new file mode 100644 index 0000000..ed12f51 --- /dev/null +++ b/ym-admin/src/main/java/com/cnbm/admin/service/impl/CaptchaServiceImpl.java @@ -0,0 +1,77 @@ +package com.cnbm.admin.service.impl; + +import com.cnbm.admin.service.CaptchaService; +import com.cnbm.common.redis.RedisKeys; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.wf.captcha.SpecCaptcha; +import com.wf.captcha.base.Captcha; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * @Author weihongyang + * @Date 2022/6/23 12:29 PM + * @Version 1.0 + */ +@Service +public class CaptchaServiceImpl implements CaptchaService { + @Autowired + private RedisTemplate redisTemplate; + + /** + * Local Cache 5分钟过期 + */ + Cache localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build(); + + @Override + public void create(HttpServletResponse response, String uuid) throws IOException { + response.setContentType("image/gif"); + response.setHeader("Pragma", "No-cache"); + response.setHeader("Cache-Control", "no-cache"); + response.setDateHeader("Expires", 0); + + //生成验证码 + SpecCaptcha captcha = new SpecCaptcha(150, 40); + captcha.setLen(5); + captcha.setCharType(Captcha.TYPE_DEFAULT); + captcha.out(response.getOutputStream()); + + //保存到缓存 + setCache(uuid, captcha.text()); + } + + @Override + public boolean validate(String uuid, String code) { + //获取验证码 + String captcha = getCache(uuid); + + //效验成功 + if(code.equalsIgnoreCase(captcha)){ + return true; + } + + return false; + } + + private void setCache(String key, String value){ + key = RedisKeys.getCaptchaKey(key); + redisTemplate.opsForValue().set(key, value, 300,TimeUnit.SECONDS); + } + + private String getCache(String key){ + key = RedisKeys.getCaptchaKey(key); + String captcha = (String)redisTemplate.opsForValue().get(key); + //删除验证码 + if(captcha != null){ + redisTemplate.delete(key); + } + return captcha; + } +} From 35812df81d66acc8279570ebb9afce3277313caf Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 13:54:49 +0800 Subject: [PATCH 17/37] =?UTF-8?q?fix:=20=E6=8A=8Aredis=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-gateway/src/main/resources/application.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ym-gateway/src/main/resources/application.yml b/ym-gateway/src/main/resources/application.yml index 511d59d..646ba7d 100644 --- a/ym-gateway/src/main/resources/application.yml +++ b/ym-gateway/src/main/resources/application.yml @@ -48,11 +48,6 @@ spring: time-zone: GMT+8 default-property-inclusion: non_null -# 是否开启redis缓存 true开启 false关闭 -renren: - redis: - open: false - #mybatis mybatis-plus: mapper-locations: classpath*:/mapper/*.xml From 204d758fcc05d2b9028624868da42c22e08526d1 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 13:55:17 +0800 Subject: [PATCH 18/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9ECaptchaService?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=B1=BB=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cnbm/admin/service/CaptchaService.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/CaptchaService.java b/ym-admin/src/main/java/com/cnbm/admin/service/CaptchaService.java index 5415ece..fc062e7 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/CaptchaService.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/CaptchaService.java @@ -1,9 +1,25 @@ package com.cnbm.admin.service; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + /** * @Author weihongyang * @Date 2022/6/8 8:55 AM * @Version 1.0 */ public interface CaptchaService { + + /** + * 图片验证码 + */ + void create(HttpServletResponse response, String uuid) throws IOException; + + /** + * 验证码效验 + * @param uuid uuid + * @param code 验证码 + * @return true:成功 false:失败 + */ + boolean validate(String uuid, String code); } From 6ba316299df43591aaf3028470e11fa0b0e02822 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 13:55:43 +0800 Subject: [PATCH 19/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Eeasy=20captcha?= =?UTF-8?q?=E7=9A=84maven=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-admin/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ym-admin/pom.xml b/ym-admin/pom.xml index c937493..132653d 100644 --- a/ym-admin/pom.xml +++ b/ym-admin/pom.xml @@ -33,6 +33,11 @@ jjwt 0.9.0 + + com.github.whvcse + easy-captcha + ${captcha.version} + com.cnbm ym-common From c7c397e92d0b55c3b53012dd44e5ed9a04cc5124 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 13:56:43 +0800 Subject: [PATCH 20/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Esercurity?= =?UTF-8?q?=E5=AF=B9=E4=BA=8E=E9=AA=8C=E8=AF=81=E7=A0=81=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E7=9A=84=E6=94=BE=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/cnbm/admin/config/SecurityConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java index fbbd13b..00a8a85 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java +++ b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java @@ -64,7 +64,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/doc.html", "/swagger-resources/**", "/swagger-ui/**", - "/webjars/**").anonymous() + "/webjars/**", + "/captcha").anonymous() // .antMatchers("/testCors").hasAuthority("system:dept:list222") // 除上面外的所有请求全部需要鉴权认证 .anyRequest() From 6be4ac7a62df26912f11b953217d2089d7af583e Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 13:57:30 +0800 Subject: [PATCH 21/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/LoginController.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java index 66bc7a8..c3f622e 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java +++ b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java @@ -2,9 +2,13 @@ package com.cnbm.admin.controller; import com.cnbm.admin.handler.LogoutSuccessHandlerImpl; import com.cnbm.admin.params.LoginParam; +import com.cnbm.admin.service.CaptchaService; import com.cnbm.admin.service.LoginService; import com.cnbm.admin.utils.ResponseResult; +import com.cnbm.common.exception.ErrorCode; +import com.cnbm.common.validator.AssertUtils; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; @@ -17,6 +21,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * @Author weihongyang @@ -31,6 +36,20 @@ public class LoginController { @Autowired private LoginService loginService; + @Autowired + private CaptchaService captchaService; + + @GetMapping("/captcha") + @ApiOperation(value = "验证码", produces="application/octet-stream") + @ApiImplicitParam(paramType = "query", dataTypeClass=String.class, name = "uuid", required = true) + public void captcha(HttpServletResponse response, String uuid)throws IOException { + //uuid不能为空 + AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); + + //生成验证码 + captchaService.create(response, uuid); + } + @PostMapping("/login") @ApiOperation(value = "登录") public ResponseResult login(HttpServletRequest request, @RequestBody LoginParam loginParam) { From 036cc1ac25a8e0bc80601b894f72334726c472f2 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 14:02:00 +0800 Subject: [PATCH 22/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=8E=A5=E5=8F=A3=E5=AE=9E=E7=8E=B0=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cnbm/admin/service/impl/LoginServiceImpl.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java b/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java index 1c8fdbb..ada95af 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java +++ b/ym-admin/src/main/java/com/cnbm/admin/service/impl/LoginServiceImpl.java @@ -2,9 +2,11 @@ package com.cnbm.admin.service.impl; import com.cnbm.admin.entity.LoginUser; import com.cnbm.admin.params.LoginParam; +import com.cnbm.admin.service.CaptchaService; import com.cnbm.admin.utils.JwtUtil; import com.cnbm.admin.service.LoginService; import com.cnbm.admin.utils.ResponseResult; +import com.cnbm.common.exception.ErrorCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; @@ -32,8 +34,16 @@ public class LoginServiceImpl implements LoginService { @Autowired private AuthenticationManager authenticationManager; + @Autowired + private CaptchaService captchaService; + @Override public ResponseResult login(HttpServletRequest request, LoginParam loginParam) { + //验证码是否正确 + boolean flag = captchaService.validate(loginParam.getUuid(), loginParam.getCaptcha()); + if(!flag){ + return new ResponseResult(ErrorCode.CAPTCHA_ERROR,"验证码错误"); + } UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginParam.getUsername(),loginParam.getPassword()); Authentication authenticate = authenticationManager.authenticate(authenticationToken); if (Objects.isNull(authenticate)) { From d3322639de1e8886e81ba5ff6751a477519b5ab3 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 14:21:44 +0800 Subject: [PATCH 23/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9swagger=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=96=B0=E7=9A=84=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/cnbm/config/SwaggerConfig.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/ym-gateway/src/main/java/com/cnbm/config/SwaggerConfig.java b/ym-gateway/src/main/java/com/cnbm/config/SwaggerConfig.java index 5ddb652..730a480 100644 --- a/ym-gateway/src/main/java/com/cnbm/config/SwaggerConfig.java +++ b/ym-gateway/src/main/java/com/cnbm/config/SwaggerConfig.java @@ -41,7 +41,7 @@ public class SwaggerConfig { @Bean public Docket restApi() { return new Docket(DocumentationType.SWAGGER_2) - .groupName("标准接口") + .groupName("全部接口") .apiInfo(apiInfo("Spring Boot中使用Swagger2构建RESTful APIs", "1.0")) .useDefaultResponseMessages(true) .forCodeGeneration(false) @@ -54,6 +54,22 @@ public class SwaggerConfig { .securitySchemes(Arrays.asList(new ApiKey("token", "token", "header"))); } + @Bean + public Docket adminApi() { + return new Docket(DocumentationType.SWAGGER_2) + .groupName("admin模块接口") + .apiInfo(apiInfo("Spring Boot中使用Swagger2构建RESTful APIs", "1.0")) + .useDefaultResponseMessages(true) + .forCodeGeneration(false) + .select() + .apis(RequestHandlerSelectors.basePackage("com.cnbm.admin")) + .paths(PathSelectors.any()) + .build() + .securityContexts(Arrays.asList(securityContext())) + // ApiKey的name需与SecurityReference的reference保持一致 + .securitySchemes(Arrays.asList(new ApiKey("token", "token", "header"))); + } + /** * 创建该API的基本信息(这些基本信息会展现在文档页面中) * 访问地址:http://ip:port/swagger-ui.html From aab0ea447939c09b8534f25c96bcbe0ae6de6e7f Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 15:31:55 +0800 Subject: [PATCH 24/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81uuid=E5=8F=82=E6=95=B0=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=98=AFstring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/cnbm/admin/controller/LoginController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java index c3f622e..85abb6a 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java +++ b/ym-admin/src/main/java/com/cnbm/admin/controller/LoginController.java @@ -41,7 +41,7 @@ public class LoginController { @GetMapping("/captcha") @ApiOperation(value = "验证码", produces="application/octet-stream") - @ApiImplicitParam(paramType = "query", dataTypeClass=String.class, name = "uuid", required = true) + @ApiImplicitParam(paramType = "query", dataTypeClass=String.class, name = "uuid", required = true,example = "string") public void captcha(HttpServletResponse response, String uuid)throws IOException { //uuid不能为空 AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); @@ -61,5 +61,4 @@ public class LoginController { public void logout(){ } - } From 093d6ee362998748afd924c61c68d8e0a75b06c2 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 15:39:49 +0800 Subject: [PATCH 25/37] =?UTF-8?q?feat:=20sercurity=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E6=96=B0=E5=A2=9E=E5=8A=A0LogoutHan?= =?UTF-8?q?dler=E7=9A=84=E5=AE=9E=E7=8E=B0=E7=B1=BB=20=E5=9C=A8LogoutFilte?= =?UTF-8?q?r=E4=B9=8B=E5=89=8D=E5=8A=A0=E5=85=A5jwtAuthenticationTokenFilt?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/cnbm/admin/config/SecurityConfig.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java index 00a8a85..f2dd2e8 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java +++ b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java @@ -1,6 +1,7 @@ package com.cnbm.admin.config; import com.cnbm.admin.filter.JwtAuthenticationTokenFilter; +import com.cnbm.admin.handler.LogoutHandlerImpl; import com.cnbm.admin.handler.LogoutSuccessHandlerImpl; import com.cnbm.admin.service.impl.UserDetailsServiceImpl; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +20,8 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; + /** * @Author weihongyang * @Date 2022/6/8 1:51 PM @@ -49,6 +52,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private LogoutSuccessHandlerImpl logoutSuccessHandler; + @Autowired + private LogoutHandlerImpl logoutHandler; + @Override protected void configure(HttpSecurity http) throws Exception { @@ -72,12 +78,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .authenticated() // 退出登录,默认为/logout,这里修改接口地址为 /doLogout .and().logout().logoutUrl("/doLogout") + .addLogoutHandler(logoutHandler) // 设置退出登录成功处理程序,退出成功后返回JSON字符串 .logoutSuccessHandler(logoutSuccessHandler); //添加过滤器 http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); - + http.addFilterBefore(jwtAuthenticationTokenFilter, LogoutFilter.class); //配置异常处理器 http.exceptionHandling() //配置认证失败处理器 From 1ac94e3d4cfb4771f9828ed43bbf39b38d37ccf9 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 23 Jun 2022 16:00:43 +0800 Subject: [PATCH 26/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnbm/admin/exception/YmExceptionHandler.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java b/ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java index c33d554..b3965f5 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java +++ b/ym-admin/src/main/java/com/cnbm/admin/exception/YmExceptionHandler.java @@ -77,14 +77,14 @@ public class YmExceptionHandler { return result; } - @ExceptionHandler(Exception.class) - public Result handleException(Exception ex){ - logger.error(ex.getMessage(), ex); - -// saveLog(ex); - - return new Result().error(); - } +// @ExceptionHandler(Exception.class) +// public Result handleException(Exception ex){ +// logger.error(ex.getMessage(), ex); +// +//// saveLog(ex); +// +// return new Result().error(); +// } // // /** // * 保存异常日志 From 645bafc28029db1d1a2850fe5fd2b529a1c8597b Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Fri, 24 Jun 2022 10:25:17 +0800 Subject: [PATCH 27/37] =?UTF-8?q?feat:=20init=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-schedule-task/pom.xml | 48 ++++++ .../scheduletask/config/ScheduleConfig.java | 58 +++++++ .../controller/ScheduleJobController.java | 125 ++++++++++++++ .../controller/ScheduleJobLogController.java | 55 +++++++ .../cnbm/scheduletask/dao/ScheduleJobDao.java | 21 +++ .../scheduletask/dao/ScheduleJobLogDao.java | 15 ++ .../cnbm/scheduletask/dto/ScheduleJobDTO.java | 56 +++++++ .../scheduletask/dto/ScheduleJobLogDTO.java | 45 +++++ .../entity/ScheduleJobEntity.java | 53 ++++++ .../entity/ScheduleJobLogEntity.java | 54 ++++++ .../init/JobCommandLineRunner.java | 39 +++++ .../service/ScheduleJobLogService.java | 20 +++ .../service/ScheduleJobService.java | 56 +++++++ .../impl/ScheduleJobLogServiceImpl.java | 51 ++++++ .../service/impl/ScheduleJobServiceImpl.java | 127 +++++++++++++++ .../com/cnbm/scheduletask/task/ITask.java | 16 ++ .../com/cnbm/scheduletask/task/TestTask.java | 20 +++ .../cnbm/scheduletask/utils/ScheduleJob.java | 70 ++++++++ .../scheduletask/utils/ScheduleUtils.java | 154 ++++++++++++++++++ 19 files changed, 1083 insertions(+) create mode 100644 ym-schedule-task/pom.xml create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/config/ScheduleConfig.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobController.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobLogController.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobDao.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobLogDao.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobDTO.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobLogDTO.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobEntity.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobLogEntity.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/init/JobCommandLineRunner.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobLogService.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobService.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobLogServiceImpl.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobServiceImpl.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/ITask.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java create mode 100644 ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleUtils.java diff --git a/ym-schedule-task/pom.xml b/ym-schedule-task/pom.xml new file mode 100644 index 0000000..9e491d0 --- /dev/null +++ b/ym-schedule-task/pom.xml @@ -0,0 +1,48 @@ + + + + ym-pass + com.cnbm + 1.0-SNAPSHOT + + 4.0.0 + + ym-schedule-task + + + 8 + 8 + 2.3.2 + + + + + com.cnbm + ym-common + 1.0-SNAPSHOT + + + com.cnbm + ym-admin + 1.0-SNAPSHOT + + + org.quartz-scheduler + quartz + ${quartz.version} + + + com.mchange + c3p0 + + + com.zaxxer + HikariCP-java6 + + + + + + \ No newline at end of file diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/config/ScheduleConfig.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/config/ScheduleConfig.java new file mode 100644 index 0000000..a2c7744 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/config/ScheduleConfig.java @@ -0,0 +1,58 @@ +package com.cnbm.scheduletask.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +import javax.sql.DataSource; +import java.util.Properties; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:30 PM + * @Version 1.0 + */ +@Configuration +public class ScheduleConfig { + + @Bean + public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { + SchedulerFactoryBean factory = new SchedulerFactoryBean(); + factory.setDataSource(dataSource); + + //quartz参数 + Properties prop = new Properties(); + prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler"); + prop.put("org.quartz.scheduler.instanceId", "AUTO"); + //线程池配置 + prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); + prop.put("org.quartz.threadPool.threadCount", "20"); + prop.put("org.quartz.threadPool.threadPriority", "5"); + //JobStore配置 + prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); + //集群配置 + prop.put("org.quartz.jobStore.isClustered", "true"); + prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); + prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); + + prop.put("org.quartz.jobStore.misfireThreshold", "12000"); + prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); + prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); + + //PostgreSQL数据库,需要打开此注释 + //prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"); + + factory.setQuartzProperties(prop); + + factory.setSchedulerName("RenrenScheduler"); + //延时启动 + factory.setStartupDelay(30); + factory.setApplicationContextSchedulerContextKey("applicationContextKey"); + //可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 + factory.setOverwriteExistingJobs(true); + //设置自动启动,默认为true + factory.setAutoStartup(true); + + return factory; + } +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobController.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobController.java new file mode 100644 index 0000000..31b0dbe --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobController.java @@ -0,0 +1,125 @@ +package com.cnbm.scheduletask.controller; + +import com.cnbm.admin.annotation.LogOperation; +import com.cnbm.common.constant.Constant; +import com.cnbm.common.page.PageData; +import com.cnbm.common.utils.Result; +import com.cnbm.common.validator.ValidatorUtils; +import com.cnbm.common.validator.group.AddGroup; +import com.cnbm.common.validator.group.DefaultGroup; +import com.cnbm.common.validator.group.UpdateGroup; +import com.cnbm.scheduletask.dto.ScheduleJobDTO; +import com.cnbm.scheduletask.service.ScheduleJobService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/24 8:57 AM + * @Version 1.0 + */ +@RestController +@RequestMapping("/sys/schedule") +@Api(tags="定时任务") +public class ScheduleJobController { + @Autowired + private ScheduleJobService scheduleJobService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataTypeClass=Integer.class) , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataTypeClass=Integer.class) , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataTypeClass=String.class) , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataTypeClass=String.class) , + @ApiImplicitParam(name = "beanName", value = "beanName", paramType = "query", dataTypeClass=String.class) + }) + @PreAuthorize("@ex.hasAuthority('sys:schedule:page')") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = scheduleJobService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @PreAuthorize("@ex.hasAuthority('sys:schedule:info')") + public Result info(@PathVariable("id") Long id){ + ScheduleJobDTO schedule = scheduleJobService.get(id); + + return new Result().ok(schedule); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @PreAuthorize("@ex.hasAuthority('sys:schedule:save')") + public Result save(@RequestBody ScheduleJobDTO dto){ + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + scheduleJobService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @PreAuthorize("@ex.hasAuthority('sys:schedule:update')") + public Result update(@RequestBody ScheduleJobDTO dto){ + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + scheduleJobService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @PreAuthorize("@ex.hasAuthority('sys:schedule:delete')") + public Result delete(@RequestBody Long[] ids){ + scheduleJobService.deleteBatch(ids); + + return new Result(); + } + + @PutMapping("/run") + @ApiOperation("立即执行") + @LogOperation("立即执行") + @PreAuthorize("@ex.hasAuthority('sys:schedule:run')") + public Result run(@RequestBody Long[] ids){ + scheduleJobService.run(ids); + + return new Result(); + } + + @PutMapping("/pause") + @ApiOperation("暂停") + @LogOperation("暂停") + @PreAuthorize("@ex.hasAuthority('sys:schedule:pause')") + public Result pause(@RequestBody Long[] ids){ + scheduleJobService.pause(ids); + + return new Result(); + } + + @PutMapping("/resume") + @ApiOperation("恢复") + @LogOperation("恢复") + @PreAuthorize("@ex.hasAuthority('sys:schedule:resume')") + public Result resume(@RequestBody Long[] ids){ + scheduleJobService.resume(ids); + + return new Result(); + } + +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobLogController.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobLogController.java new file mode 100644 index 0000000..073fb63 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/controller/ScheduleJobLogController.java @@ -0,0 +1,55 @@ +package com.cnbm.scheduletask.controller; + +import com.cnbm.common.constant.Constant; +import com.cnbm.common.page.PageData; +import com.cnbm.common.utils.Result; +import com.cnbm.scheduletask.dto.ScheduleJobLogDTO; +import com.cnbm.scheduletask.service.ScheduleJobLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/24 8:58 AM + * @Version 1.0 + */ +@RestController +@RequestMapping("/sys/scheduleLog") +@Api(tags="定时任务日志") +public class ScheduleJobLogController { + @Autowired + private ScheduleJobLogService scheduleJobLogService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataTypeClass=Integer.class) , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataTypeClass=Integer.class) , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataTypeClass=String.class) , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataTypeClass=String.class) , + @ApiImplicitParam(name = "jobId", value = "jobId", paramType = "query", dataType="String") + }) + @PreAuthorize("@ex.hasAuthority('sys:schedule:log')") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = scheduleJobLogService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @PreAuthorize("@ex.hasAuthority('sys:schedule:log')") + public Result info(@PathVariable("id") Long id){ + ScheduleJobLogDTO log = scheduleJobLogService.get(id); + + return new Result().ok(log); + } +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobDao.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobDao.java new file mode 100644 index 0000000..64cf74b --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobDao.java @@ -0,0 +1,21 @@ +package com.cnbm.scheduletask.dao; + +import com.cnbm.common.dao.BaseDao; +import com.cnbm.scheduletask.entity.ScheduleJobEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:48 PM + * @Version 1.0 + */ +@Mapper +public interface ScheduleJobDao extends BaseDao { + + /** + * 批量更新状态 + */ + int updateBatch(Map map); +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobLogDao.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobLogDao.java new file mode 100644 index 0000000..0fd5289 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dao/ScheduleJobLogDao.java @@ -0,0 +1,15 @@ +package com.cnbm.scheduletask.dao; + +import com.cnbm.common.dao.BaseDao; +import com.cnbm.scheduletask.entity.ScheduleJobLogEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:48 PM + * @Version 1.0 + */ +@Mapper +public interface ScheduleJobLogDao extends BaseDao { + +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobDTO.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobDTO.java new file mode 100644 index 0000000..d8e65b4 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobDTO.java @@ -0,0 +1,56 @@ +package com.cnbm.scheduletask.dto; + +import com.cnbm.common.validator.group.AddGroup; +import com.cnbm.common.validator.group.DefaultGroup; +import com.cnbm.common.validator.group.UpdateGroup; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:49 PM + * @Version 1.0 + */ +@Data +@ApiModel(value = "定时任务") +public class ScheduleJobDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "spring bean名称") + @NotBlank(message = "{schedule.bean.require}", groups = DefaultGroup.class) + private String beanName; + + @ApiModelProperty(value = "参数") + private String params; + + @ApiModelProperty(value = "cron表达式") + @NotBlank(message = "{schedule.cron.require}", groups = DefaultGroup.class) + private String cronExpression; + + @ApiModelProperty(value = "任务状态 0:暂停 1:正常") + @Range(min=0, max=1, message = "{schedule.status.range}", groups = DefaultGroup.class) + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + +} + diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobLogDTO.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobLogDTO.java new file mode 100644 index 0000000..d77859b --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/dto/ScheduleJobLogDTO.java @@ -0,0 +1,45 @@ +package com.cnbm.scheduletask.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:49 PM + * @Version 1.0 + */ +@Data +@ApiModel(value = "定时任务日志") +public class ScheduleJobLogDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "任务id") + private Long jobId; + + @ApiModelProperty(value = "spring bean名称") + private String beanName; + + @ApiModelProperty(value = "参数") + private String params; + + @ApiModelProperty(value = "任务状态 0:失败 1:成功") + private Integer status; + + @ApiModelProperty(value = "失败信息") + private String error; + + @ApiModelProperty(value = "耗时(单位:毫秒)") + private Integer times; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} + diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobEntity.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobEntity.java new file mode 100644 index 0000000..c624fe5 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobEntity.java @@ -0,0 +1,53 @@ +package com.cnbm.scheduletask.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.cnbm.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:47 PM + * @Version 1.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("schedule_job") +public class ScheduleJobEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * spring bean名称 + */ + private String beanName; + /** + * 参数 + */ + private String params; + /** + * cron表达式 + */ + private String cronExpression; + /** + * 任务状态 0:暂停 1:正常 + */ + private Integer status; + /** + * 备注 + */ + private String remark; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobLogEntity.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobLogEntity.java new file mode 100644 index 0000000..ff0e7ab --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/entity/ScheduleJobLogEntity.java @@ -0,0 +1,54 @@ +package com.cnbm.scheduletask.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:47 PM + * @Version 1.0 + */ +@Data +@TableName("schedule_job_log") +public class ScheduleJobLogEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * 任务id + */ + private Long jobId; + /** + * spring bean名称 + */ + private String beanName; + /** + * 参数 + */ + private String params; + /** + * 任务状态 0:失败 1:成功 + */ + private Integer status; + /** + * 失败信息 + */ + private String error; + /** + * 耗时(单位:毫秒) + */ + private Integer times; + /** + * 创建时间 + */ + private Date createDate; + +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/init/JobCommandLineRunner.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/init/JobCommandLineRunner.java new file mode 100644 index 0000000..38168a5 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/init/JobCommandLineRunner.java @@ -0,0 +1,39 @@ +package com.cnbm.scheduletask.init; + +import com.cnbm.scheduletask.dao.ScheduleJobDao; +import com.cnbm.scheduletask.entity.ScheduleJobEntity; +import com.cnbm.scheduletask.utils.ScheduleUtils; +import org.quartz.CronTrigger; +import org.quartz.Scheduler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:46 PM + * @Version 1.0 + */ +@Component +public class JobCommandLineRunner implements CommandLineRunner { + @Autowired + private Scheduler scheduler; + @Autowired + private ScheduleJobDao scheduleJobDao; + + @Override + public void run(String... args) { + List scheduleJobList = scheduleJobDao.selectList(null); + for(ScheduleJobEntity scheduleJob : scheduleJobList){ + CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getId()); + //如果不存在,则创建 + if(cronTrigger == null) { + ScheduleUtils.createScheduleJob(scheduler, scheduleJob); + }else { + ScheduleUtils.updateScheduleJob(scheduler, scheduleJob); + } + } + } +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobLogService.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobLogService.java new file mode 100644 index 0000000..4ff4ffd --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobLogService.java @@ -0,0 +1,20 @@ +package com.cnbm.scheduletask.service; + +import com.cnbm.common.page.PageData; +import com.cnbm.common.service.BaseService; +import com.cnbm.scheduletask.dto.ScheduleJobLogDTO; +import com.cnbm.scheduletask.entity.ScheduleJobLogEntity; + +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:44 PM + * @Version 1.0 + */ +public interface ScheduleJobLogService extends BaseService { + + PageData page(Map params); + + ScheduleJobLogDTO get(Long id); +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobService.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobService.java new file mode 100644 index 0000000..a8faea3 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/ScheduleJobService.java @@ -0,0 +1,56 @@ +package com.cnbm.scheduletask.service; + +import com.cnbm.common.page.PageData; +import com.cnbm.common.service.BaseService; +import com.cnbm.scheduletask.dto.ScheduleJobDTO; +import com.cnbm.scheduletask.entity.ScheduleJobEntity; + +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:43 PM + * @Version 1.0 + */ +public interface ScheduleJobService extends BaseService { + + PageData page(Map params); + + ScheduleJobDTO get(Long id); + + /** + * 保存定时任务 + */ + void save(ScheduleJobDTO dto); + + /** + * 更新定时任务 + */ + void update(ScheduleJobDTO dto); + + /** + * 批量删除定时任务 + */ + void deleteBatch(Long[] ids); + + /** + * 批量更新定时任务状态 + */ + int updateBatch(Long[] ids, int status); + + /** + * 立即执行 + */ + void run(Long[] ids); + + /** + * 暂停运行 + */ + void pause(Long[] ids); + + /** + * 恢复运行 + */ + void resume(Long[] ids); +} + diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobLogServiceImpl.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobLogServiceImpl.java new file mode 100644 index 0000000..0dedb9e --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobLogServiceImpl.java @@ -0,0 +1,51 @@ +package com.cnbm.scheduletask.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.cnbm.common.constant.Constant; +import com.cnbm.common.page.PageData; +import com.cnbm.common.service.impl.BaseServiceImpl; +import com.cnbm.common.utils.ConvertUtils; +import com.cnbm.scheduletask.dao.ScheduleJobLogDao; +import com.cnbm.scheduletask.dto.ScheduleJobLogDTO; +import com.cnbm.scheduletask.entity.ScheduleJobLogEntity; +import com.cnbm.scheduletask.service.ScheduleJobLogService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:46 PM + * @Version 1.0 + */ +@Service +public class ScheduleJobLogServiceImpl extends BaseServiceImpl implements ScheduleJobLogService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + return getPageData(page, ScheduleJobLogDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String jobId = (String)params.get("jobId"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(jobId), "job_id", jobId); + + return wrapper; + } + + @Override + public ScheduleJobLogDTO get(Long id) { + ScheduleJobLogEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, ScheduleJobLogDTO.class); + } + +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobServiceImpl.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobServiceImpl.java new file mode 100644 index 0000000..253f3e2 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/service/impl/ScheduleJobServiceImpl.java @@ -0,0 +1,127 @@ +package com.cnbm.scheduletask.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.cnbm.common.constant.Constant; +import com.cnbm.common.page.PageData; +import com.cnbm.common.service.impl.BaseServiceImpl; +import com.cnbm.common.utils.ConvertUtils; +import com.cnbm.scheduletask.dao.ScheduleJobDao; +import com.cnbm.scheduletask.dto.ScheduleJobDTO; +import com.cnbm.scheduletask.entity.ScheduleJobEntity; +import com.cnbm.scheduletask.service.ScheduleJobService; +import com.cnbm.scheduletask.utils.ScheduleUtils; +import org.apache.commons.lang3.StringUtils; +import org.quartz.Scheduler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:45 PM + * @Version 1.0 + */ +@Service +public class ScheduleJobServiceImpl extends BaseServiceImpl implements ScheduleJobService { + @Autowired + private Scheduler scheduler; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + return getPageData(page, ScheduleJobDTO.class); + } + + @Override + public ScheduleJobDTO get(Long id) { + ScheduleJobEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, ScheduleJobDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String beanName = (String)params.get("beanName"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(beanName), "bean_name", beanName); + + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(ScheduleJobDTO dto) { + ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class); + + entity.setStatus(Constant.ScheduleStatus.NORMAL.getValue()); + this.insert(entity); + + ScheduleUtils.createScheduleJob(scheduler, entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ScheduleJobDTO dto) { + ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class); + + ScheduleUtils.updateScheduleJob(scheduler, entity); + + this.updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteBatch(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.deleteScheduleJob(scheduler, id); + } + + //删除数据 + this.deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public int updateBatch(Long[] ids, int status){ + Map map = new HashMap<>(2); + map.put("ids", ids); + map.put("status", status); + return baseDao.updateBatch(map); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void run(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.run(scheduler, this.selectById(id)); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void pause(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.pauseJob(scheduler, id); + } + + updateBatch(ids, Constant.ScheduleStatus.PAUSE.getValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void resume(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.resumeJob(scheduler, id); + } + + updateBatch(ids, Constant.ScheduleStatus.NORMAL.getValue()); + } + +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/ITask.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/ITask.java new file mode 100644 index 0000000..c375dd9 --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/ITask.java @@ -0,0 +1,16 @@ +package com.cnbm.scheduletask.task; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:41 PM + * @Version 1.0 + */ +public interface ITask { + + /** + * 执行定时任务接口 + * + * @param params 参数,多参数使用JSON数据 + */ + void run(String params); +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java new file mode 100644 index 0000000..0eb2c1b --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java @@ -0,0 +1,20 @@ +package com.cnbm.scheduletask.task; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:41 PM + * @Version 1.0 + */ +@Component("testTask") +public class TestTask implements ITask{ + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void run(String params){ + logger.debug("TestTask定时任务正在执行,参数为:{}", params); + } +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java new file mode 100644 index 0000000..f7871ec --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java @@ -0,0 +1,70 @@ +package com.cnbm.scheduletask.utils; + +import com.cnbm.common.constant.Constant; +import com.cnbm.common.exception.ExceptionUtils; +import com.cnbm.common.utils.SpringContextUtils; +import com.cnbm.scheduletask.entity.ScheduleJobEntity; +import com.cnbm.scheduletask.entity.ScheduleJobLogEntity; +import com.cnbm.scheduletask.service.ScheduleJobLogService; +import org.quartz.JobExecutionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.lang.reflect.Method; +import java.util.Date; + +/** + * @Author weihongyang + * @Date 2022/6/23 4:38 PM + * @Version 1.0 + */ +public class ScheduleJob extends QuartzJobBean { + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + protected void executeInternal(JobExecutionContext context) { + ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap(). + get(ScheduleUtils.JOB_PARAM_KEY); + + //数据库保存执行记录 + ScheduleJobLogEntity log = new ScheduleJobLogEntity(); + log.setJobId(scheduleJob.getId()); + log.setBeanName(scheduleJob.getBeanName()); + log.setParams(scheduleJob.getParams()); + log.setCreateDate(new Date()); + + //任务开始时间 + long startTime = System.currentTimeMillis(); + + try { + //执行任务 + logger.info("任务准备执行,任务ID:{}", scheduleJob.getId()); + Object target = SpringContextUtils.getBean(scheduleJob.getBeanName()); + Method method = target.getClass().getDeclaredMethod("run", String.class); + method.invoke(target, scheduleJob.getParams()); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int)times); + //任务状态 + log.setStatus(Constant.SUCCESS); + + logger.info("任务执行完毕,任务ID:{} 总共耗时:{} 毫秒", scheduleJob.getId(), times); + } catch (Exception e) { + logger.error("任务执行失败,任务ID:{}", scheduleJob.getId(), e); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int)times); + + //任务状态 + log.setStatus(Constant.FAIL); + log.setError(ExceptionUtils.getErrorStackTrace(e)); + }finally { + //获取spring bean + ScheduleJobLogService scheduleJobLogService = SpringContextUtils.getBean(ScheduleJobLogService.class); + scheduleJobLogService.insert(log); + } + } +} diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleUtils.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleUtils.java new file mode 100644 index 0000000..00b57de --- /dev/null +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleUtils.java @@ -0,0 +1,154 @@ +package com.cnbm.scheduletask.utils; + +import com.cnbm.common.constant.Constant; +import com.cnbm.common.exception.ErrorCode; +import com.cnbm.common.exception.RenException; +import com.cnbm.scheduletask.entity.ScheduleJobEntity; +import org.quartz.*; + + +/** + * @Author weihongyang + * @Date 2022/6/23 4:40 PM + * @Version 1.0 + */ +public class ScheduleUtils { + private final static String JOB_NAME = "TASK_"; + /** + * 任务调度参数key + */ + public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY"; + + /** + * 获取触发器key + */ + public static TriggerKey getTriggerKey(Long jobId) { + return TriggerKey.triggerKey(JOB_NAME + jobId); + } + + /** + * 获取jobKey + */ + public static JobKey getJobKey(Long jobId) { + return JobKey.jobKey(JOB_NAME + jobId); + } + + /** + * 获取表达式触发器 + */ + public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) { + try { + return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + //构建job信息 + JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getId())).build(); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + //按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId())).withSchedule(scheduleBuilder).build(); + + //放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(JOB_PARAM_KEY, scheduleJob); + + scheduler.scheduleJob(jobDetail, trigger); + + //暂停任务 + if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ + pauseJob(scheduler, scheduleJob.getId()); + } + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 更新定时任务 + */ + public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + TriggerKey triggerKey = getTriggerKey(scheduleJob.getId()); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId()); + + //按新的cronExpression表达式重新构建trigger + trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + + //参数 + trigger.getJobDataMap().put(JOB_PARAM_KEY, scheduleJob); + + scheduler.rescheduleJob(triggerKey, trigger); + + //暂停任务 + if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ + pauseJob(scheduler, scheduleJob.getId()); + } + + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 立即执行任务 + */ + public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + //参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(JOB_PARAM_KEY, scheduleJob); + + scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 暂停任务 + */ + public static void pauseJob(Scheduler scheduler, Long jobId) { + try { + scheduler.pauseJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 恢复任务 + */ + public static void resumeJob(Scheduler scheduler, Long jobId) { + try { + scheduler.resumeJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 删除定时任务 + */ + public static void deleteScheduleJob(Scheduler scheduler, Long jobId) { + try { + scheduler.deleteJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } +} From 92a8e17f6e586787220f1df2069bd4651b48c3f7 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Fri, 24 Jun 2022 10:25:36 +0800 Subject: [PATCH 28/37] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0test=E7=9A=84ya?= =?UTF-8?q?ml=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-test.yml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 ym-gateway/src/main/resources/application-test.yml diff --git a/ym-gateway/src/main/resources/application-test.yml b/ym-gateway/src/main/resources/application-test.yml new file mode 100644 index 0000000..b443abc --- /dev/null +++ b/ym-gateway/src/main/resources/application-test.yml @@ -0,0 +1,40 @@ +spring: + datasource: + #MySQL + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://mysql.picaiba.com:30307/ym_pass?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: root + password: 1qaz@WSX3edc$RFV + # #Oracle + # driver-class-name: oracle.jdbc.OracleDriver + # url: jdbc:oracle:thin:@192.168.10.10:1521:xe + # username: renren_security + # password: 123456 + # #SQLServer + # driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver + # url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security + # username: sa + # password: 123456 + # #postgresql + # driver-class-name: org.postgresql.Driver + # url: jdbc:postgresql://192.168.10.10:5432/postgres + # username: postgres + # password: 123456 + hikari: + pool-name: GrowUpHikariCP + minimum-idle: 1 + maximum-pool-size: 10 + +##多数据源的配置,需要引用renren-dynamic-datasource +#dynamic: +# datasource: +# slave1: +# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +# url: jdbc:sqlserver://123456:1433;DatabaseName=renren_security +# username: sa +# password: 123456 +# slave2: +# driver-class-name: org.postgresql.Driver +# url: jdbc:postgresql://123456:5432/renren_security +# username: postgres +# password: 123456 \ No newline at end of file From 26fee6ac1c661d36b9478aedbce7e6e77085f880 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Fri, 24 Jun 2022 10:27:11 +0800 Subject: [PATCH 29/37] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E5=AE=9A=E4=BB=BB=E5=8A=A1=E6=A8=A1=E5=9D=97pom?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + ym-gateway/pom.xml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 170fc5d..50bd528 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,7 @@ ym-gateway ym-barcode ym-basic + ym-schedule-task pom diff --git a/ym-gateway/pom.xml b/ym-gateway/pom.xml index 9a4f017..383e4be 100644 --- a/ym-gateway/pom.xml +++ b/ym-gateway/pom.xml @@ -37,6 +37,11 @@ ym-basic 1.0-SNAPSHOT + + com.cnbm + ym-schedule-task + 1.0-SNAPSHOT + io.springfox springfox-boot-starter From 58c998afb0e99e1d0f259faef0686a0d1829790f Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Fri, 24 Jun 2022 16:07:31 +0800 Subject: [PATCH 30/37] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E5=AE=9A=E4=BB=BB=E5=8A=A1=E5=8A=9F=E8=83=BD=E7=9A=84?= =?UTF-8?q?xml=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/mapper/ScheduleJobDao.xml | 14 ++++++++++++++ .../main/resources/mapper/ScheduleJobLogDao.xml | 7 +++++++ 2 files changed, 21 insertions(+) create mode 100644 ym-schedule-task/src/main/resources/mapper/ScheduleJobDao.xml create mode 100644 ym-schedule-task/src/main/resources/mapper/ScheduleJobLogDao.xml diff --git a/ym-schedule-task/src/main/resources/mapper/ScheduleJobDao.xml b/ym-schedule-task/src/main/resources/mapper/ScheduleJobDao.xml new file mode 100644 index 0000000..4b89f72 --- /dev/null +++ b/ym-schedule-task/src/main/resources/mapper/ScheduleJobDao.xml @@ -0,0 +1,14 @@ + + + + + + + + update schedule_job set status = #{status} where id in + + #{id} + + + + \ No newline at end of file diff --git a/ym-schedule-task/src/main/resources/mapper/ScheduleJobLogDao.xml b/ym-schedule-task/src/main/resources/mapper/ScheduleJobLogDao.xml new file mode 100644 index 0000000..7d1b437 --- /dev/null +++ b/ym-schedule-task/src/main/resources/mapper/ScheduleJobLogDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 4712d0300acb4a9c13c74967960764f4bdd54ced Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 29 Jun 2022 16:27:00 +0800 Subject: [PATCH 31/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9redis=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-gateway/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ym-gateway/src/main/resources/application.yml b/ym-gateway/src/main/resources/application.yml index 646ba7d..3d651ce 100644 --- a/ym-gateway/src/main/resources/application.yml +++ b/ym-gateway/src/main/resources/application.yml @@ -32,7 +32,7 @@ spring: max-request-size: 100MB enabled: true redis: - database: 0 + database: 2 host: redis.picaiba.com port: 6380 password: '@WSXcde3' # 密码(默认为空) From fdf870c7794b9325f0f488000ba666273441934f Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 29 Jun 2022 16:27:40 +0800 Subject: [PATCH 32/37] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=9A=84log=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/cnbm/scheduletask/task/TestTask.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java index 0eb2c1b..b14fe2b 100644 --- a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/task/TestTask.java @@ -1,5 +1,6 @@ package com.cnbm.scheduletask.task; +import lombok.extern.log4j.Log4j2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -9,12 +10,12 @@ import org.springframework.stereotype.Component; * @Date 2022/6/23 4:41 PM * @Version 1.0 */ +@Log4j2 @Component("testTask") public class TestTask implements ITask{ - private Logger logger = LoggerFactory.getLogger(getClass()); @Override public void run(String params){ - logger.debug("TestTask定时任务正在执行,参数为:{}", params); + log.info("TestTask定时任务正在执行,参数为:{}", params); } } From 8d6cda8f90158d555faf98d17836265a82d7227f Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 29 Jun 2022 16:28:20 +0800 Subject: [PATCH 33/37] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Emaven=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-schedule-task/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ym-schedule-task/pom.xml b/ym-schedule-task/pom.xml index 9e491d0..42d22c5 100644 --- a/ym-schedule-task/pom.xml +++ b/ym-schedule-task/pom.xml @@ -28,6 +28,10 @@ ym-admin 1.0-SNAPSHOT + + org.springframework.boot + spring-boot-starter-jdbc + org.quartz-scheduler quartz From 6d792317dd2b084535d00d3c0257a081e493e57b Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 29 Jun 2022 16:29:25 +0800 Subject: [PATCH 34/37] =?UTF-8?q?feat:=20init=20websocket=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-websocket/pom.xml | 32 ++++++++ .../websocket/config/WebSocketConfig.java | 20 +++++ .../websocket/server/WebSocketServer.java | 79 +++++++++++++++++++ .../cnbm/websocket/task/SendMessageTask.java | 37 +++++++++ 4 files changed, 168 insertions(+) create mode 100644 ym-websocket/pom.xml create mode 100644 ym-websocket/src/main/java/com/cnbm/websocket/config/WebSocketConfig.java create mode 100644 ym-websocket/src/main/java/com/cnbm/websocket/server/WebSocketServer.java create mode 100644 ym-websocket/src/main/java/com/cnbm/websocket/task/SendMessageTask.java diff --git a/ym-websocket/pom.xml b/ym-websocket/pom.xml new file mode 100644 index 0000000..0f30458 --- /dev/null +++ b/ym-websocket/pom.xml @@ -0,0 +1,32 @@ + + + + ym-pass + com.cnbm + 1.0-SNAPSHOT + + 4.0.0 + + ym-websocket + + + 8 + 8 + + + + + + com.cnbm + ym-schedule-task + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-websocket + + + + \ No newline at end of file diff --git a/ym-websocket/src/main/java/com/cnbm/websocket/config/WebSocketConfig.java b/ym-websocket/src/main/java/com/cnbm/websocket/config/WebSocketConfig.java new file mode 100644 index 0000000..8180af6 --- /dev/null +++ b/ym-websocket/src/main/java/com/cnbm/websocket/config/WebSocketConfig.java @@ -0,0 +1,20 @@ +package com.cnbm.websocket.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @Author weihongyang + * @Date 2022/6/29 8:58 AM + * @Version 1.0 + */ +@Configuration +@EnableWebSocket +public class WebSocketConfig { + @Bean + public ServerEndpointExporter serverEndpoint(){ + return new ServerEndpointExporter(); + } +} diff --git a/ym-websocket/src/main/java/com/cnbm/websocket/server/WebSocketServer.java b/ym-websocket/src/main/java/com/cnbm/websocket/server/WebSocketServer.java new file mode 100644 index 0000000..3f381db --- /dev/null +++ b/ym-websocket/src/main/java/com/cnbm/websocket/server/WebSocketServer.java @@ -0,0 +1,79 @@ +package com.cnbm.websocket.server; + +import lombok.extern.log4j.Log4j2; +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @Author weihongyang + * @Date 2022/6/29 8:59 AM + * @Version 1.0 + */ +@Log4j2 +@Component +@ServerEndpoint("/websocket/info") // 指定websocket 连接的url +public class WebSocketServer { + + private static int onlineCount = 0; + + public static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>(); + + private Session session; + + private String sessionId; + + @OnOpen + public void onOpen(Session session) { + log.info("客户端:{}连接成功",session.getId()); + this.session = session; + this.sessionId = session.getId(); + if (webSocketMap.containsKey(session.getId())){ + webSocketMap.remove(sessionId); + webSocketMap.put(sessionId,this); + }else { + webSocketMap.put(sessionId,this); + addOnlineCount(); + } + } + + @OnClose + public void onClose(Session session) { + if (webSocketMap.containsKey(sessionId)) { + webSocketMap.remove(sessionId); + subOnlineCount(); + } + log.info("客户端:{}连接断开",session.getId()); + } + + @OnMessage + public String onMsg(String message,Session session) { + log.info("从客户端:{} 收到<--:{}", session.getId(),message); + + String send=message.toUpperCase(); + String result="客户:%s您好,来自server 的消息:%s"; + result = String.format(result, session.getId(), send); + return "来自server 的消息:" + result; + } + + public void sendMsg(String message) throws IOException{ + this.session.getBasicRemote().sendText(message); + } + + private static synchronized void addOnlineCount() { + WebSocketServer.onlineCount++; + } + + private static synchronized void subOnlineCount() { + WebSocketServer.onlineCount--; + } + + +} + diff --git a/ym-websocket/src/main/java/com/cnbm/websocket/task/SendMessageTask.java b/ym-websocket/src/main/java/com/cnbm/websocket/task/SendMessageTask.java new file mode 100644 index 0000000..0601de2 --- /dev/null +++ b/ym-websocket/src/main/java/com/cnbm/websocket/task/SendMessageTask.java @@ -0,0 +1,37 @@ +package com.cnbm.websocket.task; + +import com.cnbm.scheduletask.task.ITask; +import com.cnbm.websocket.server.WebSocketServer; +import lombok.extern.log4j.Log4j2; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @Author weihongyang + * @Date 2022/6/29 2:01 PM + * @Version 1.0 + */ +@Log4j2 +@Component("sendMessageTask") +public class SendMessageTask implements ITask { + public void run(String params) { + + Iterator> socketIt = WebSocketServer.webSocketMap.entrySet().iterator(); + + + while (socketIt.hasNext()) { + Map.Entry socketServerEntry = socketIt.next(); + try { + socketServerEntry.getValue().sendMsg("定时发送:"+new Date().toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + log.info("sendMessageTask定时任务正在执行,参数为:{}", params); + } +} From e277f2a32e3418565299a7fd5812608b19f64059 Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 29 Jun 2022 16:32:20 +0800 Subject: [PATCH 35/37] =?UTF-8?q?feat:=20=E7=BB=99websocket=E7=9A=84?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E6=94=BE=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java index f2dd2e8..2fff7b1 100644 --- a/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java +++ b/ym-admin/src/main/java/com/cnbm/admin/config/SecurityConfig.java @@ -71,6 +71,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/swagger-resources/**", "/swagger-ui/**", "/webjars/**", + "/websocket/**", "/captcha").anonymous() // .antMatchers("/testCors").hasAuthority("system:dept:list222") // 除上面外的所有请求全部需要鉴权认证 From 3a090fb584e4053a9f89dccb82e7d78055a6a78a Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Wed, 29 Jun 2022 16:33:10 +0800 Subject: [PATCH 36/37] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0websocket?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B9=8B=E5=90=8Emaven=E5=BF=85=E8=A6=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + ym-gateway/pom.xml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 50bd528..e30dc2c 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ ym-barcode ym-basic ym-schedule-task + ym-websocket pom diff --git a/ym-gateway/pom.xml b/ym-gateway/pom.xml index 383e4be..a47ed6c 100644 --- a/ym-gateway/pom.xml +++ b/ym-gateway/pom.xml @@ -42,6 +42,11 @@ ym-schedule-task 1.0-SNAPSHOT + + com.cnbm + ym-websocket + 1.0-SNAPSHOT + io.springfox springfox-boot-starter From e4bfce9df3b8dba55646c8c3f11d8ae493a0378f Mon Sep 17 00:00:00 2001 From: weihongyang <1075331873@qq.com> Date: Thu, 30 Jun 2022 08:40:59 +0800 Subject: [PATCH 37/37] fix: :wrench: --- .../src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java index f7871ec..d5dc22f 100644 --- a/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java +++ b/ym-schedule-task/src/main/java/com/cnbm/scheduletask/utils/ScheduleJob.java @@ -38,6 +38,7 @@ public class ScheduleJob extends QuartzJobBean { long startTime = System.currentTimeMillis(); try { + //执行任务 logger.info("任务准备执行,任务ID:{}", scheduleJob.getId()); Object target = SpringContextUtils.getBean(scheduleJob.getBeanName());