From 8683401c802e1e98d9de8f5427a8f1cdf4b0c4a5 Mon Sep 17 00:00:00 2001 From: dxyx <5676377+dxyx@user.noreply.gitee.com> Date: Fri, 12 Mar 2021 09:31:15 +0800 Subject: [PATCH 01/27] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=94=B1=E4=BA=8Emybat?= =?UTF-8?q?is-plus=E6=97=A0=E6=B3=95=E8=BF=87=E6=BB=A4=E8=BD=AF=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AF=BC=E8=87=B4=E8=A7=92=E8=89=B2=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=BC=93=E5=AD=98=E6=9C=AA=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E8=8F=9C=E5=8D=95=E7=BC=93=E5=AD=98=E6=9C=AA?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/dal/mysql/permission/SysRoleMenuMapper.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/permission/SysRoleMenuMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/permission/SysRoleMenuMapper.java index b93bb5917..e6bdc56cd 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/permission/SysRoleMenuMapper.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/permission/SysRoleMenuMapper.java @@ -33,9 +33,7 @@ public interface SysRoleMenuMapper extends BaseMapperX { .in("menu_id", menuIds)); } - default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) { - return selectOne(new QueryWrapper().select("id") - .gt("update_time", maxUpdateTime).last("LIMIT 1")) != null; - } + @Select("select id from sys_role_menu where update_time > #{maxUpdateTime} limit 1") + List selectExistsByUpdateTimeAfter(Date maxUpdateTime); } From bbea33e72efc6612597e6beac0260d3b140164d0 Mon Sep 17 00:00:00 2001 From: dxyx <5676377+dxyx@user.noreply.gitee.com> Date: Fri, 12 Mar 2021 09:34:01 +0800 Subject: [PATCH 02/27] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=94=B1=E4=BA=8Emybat?= =?UTF-8?q?is-plus=E6=97=A0=E6=B3=95=E8=BF=87=E6=BB=A4=E8=BD=AF=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AF=BC=E8=87=B4=E8=A7=92=E8=89=B2=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=BC=93=E5=AD=98=E6=9C=AA=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E7=94=B1=E4=BA=8Emybatis-plus=E6=97=A0=E6=B3=95=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E8=BD=AF=E5=88=A0=E9=99=A4=E5=AF=BC=E8=87=B4=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E5=8E=BB=E6=8E=89=E8=8F=9C=E5=8D=95=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=9C=AA=E5=88=B7=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/permission/impl/SysPermissionServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java index 9f48af9f5..835fb8961 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java @@ -123,7 +123,7 @@ public class SysPermissionServiceImpl implements SysPermissionService { if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 log.info("[loadRoleMenuIfUpdate][首次加载全量角色与菜单的关联]"); } else { // 判断数据库中是否有更新的角色与菜单的关联 - if (!roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime)) { + if (roleMenuMapper.selectExistsByUpdateTimeAfter(maxUpdateTime).size() == 0) { return null; } log.info("[loadRoleMenuIfUpdate][增量加载全量角色与菜单的关联]"); From fe31d61de9e80543a493e15d57dfd08e6d69af30 Mon Sep 17 00:00:00 2001 From: hexiaowu Date: Fri, 12 Mar 2021 18:07:53 +0800 Subject: [PATCH 03/27] =?UTF-8?q?=E5=9B=A0JS=E7=B2=BE=E5=87=86=E5=BA=A6?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E6=9C=80=E5=A4=9A=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?2^53-1=E7=9A=84=E6=95=B0=E5=80=BC=E3=80=82=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?Long=E7=B1=BB=E5=9E=8B=E5=BA=8F=E5=88=97=E5=8C=96=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E5=80=99=EF=BC=8C=E8=87=AA=E5=8A=A8=E4=BC=9A=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E4=B8=BA=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jackson/config/JacksonConfig.java | 11 +++++++- .../framework/jackson/ser/LongSerializer.java | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java diff --git a/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java b/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java index 27d199a2d..323b447ce 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java +++ b/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java @@ -1,7 +1,9 @@ package cn.iocoder.dashboard.framework.jackson.config; +import cn.iocoder.dashboard.framework.jackson.ser.LongSerializer; import cn.iocoder.dashboard.util.json.JsonUtils; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -11,8 +13,15 @@ public class JacksonConfig { @Bean @SuppressWarnings("InstantiationOfUtilityClass") public JsonUtils jsonUtils(ObjectMapper objectMapper) { + SimpleModule simpleModule = new SimpleModule(); + /* + * 新增Long类型序列化规则,数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型 + */ + simpleModule.addSerializer(Long.class,LongSerializer.getInstance()) + .addSerializer(Long.TYPE,LongSerializer.getInstance()); + objectMapper.registerModule(simpleModule); + JsonUtils.init(objectMapper); return new JsonUtils(); } - } diff --git a/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java b/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java new file mode 100644 index 000000000..6c0561d23 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java @@ -0,0 +1,26 @@ +package cn.iocoder.dashboard.framework.jackson.ser; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * Long类型序列化规则 + *

+ * 数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型 + */ +public class LongSerializer extends JsonSerializer { + + private static final LongSerializer LONG_SERIALIZER = new LongSerializer(); + + @Override + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.toString()); + } + + public static LongSerializer getInstance() { + return LONG_SERIALIZER; + } +} From 3b6359caa04dd7a9483306d0539fc055dadf829b Mon Sep 17 00:00:00 2001 From: neilz Date: Sat, 13 Mar 2021 16:38:07 +0800 Subject: [PATCH 04/27] =?UTF-8?q?job=20=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=20Demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/job/vo/job/InfJobBaseVO.java | 3 + .../service/job/impl/InfJobServiceImpl.java | 2 + .../infra/service/job/InfJobServiceTest.java | 78 +++++++++++++++++++ src/test/resources/sql/clean.sql | 1 + src/test/resources/sql/create_tables.sql | 18 +++++ 5 files changed, 102 insertions(+) create mode 100644 src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java index 2df3ad823..352c490fc 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java @@ -34,4 +34,7 @@ public class InfJobBaseVO { @ApiModelProperty(value = "监控超时时间", example = "1000") private Integer monitorTimeout; + public void setCronExpression(String cronExpression) { + this.cronExpression = cronExpression; + } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java index d82207de1..eab60051c 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java @@ -13,6 +13,7 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper; import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; import cn.iocoder.dashboard.modules.infra.service.job.InfJobService; import org.quartz.SchedulerException; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -37,6 +38,7 @@ public class InfJobServiceImpl implements InfJobService { @Resource private InfJobMapper jobMapper; + @MockBean @Resource private SchedulerManager schedulerManager; diff --git a/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java new file mode 100644 index 000000000..e8ed0dfc7 --- /dev/null +++ b/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java @@ -0,0 +1,78 @@ +package cn.iocoder.dashboard.modules.infra.service.job; + +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import javax.annotation.Resource; + +import org.junit.jupiter.api.Test; +import org.quartz.SchedulerException; +import org.springframework.context.annotation.Import; +import cn.iocoder.dashboard.BaseDbUnitTest; +import cn.iocoder.dashboard.framework.quartz.core.scheduler.SchedulerManager; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO; +import cn.iocoder.dashboard.modules.infra.convert.job.InfJobConvert; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; +import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper; +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; +import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobServiceImpl; + +/** + * {@link InfJobServiceImpl} 的单元测试 + * + * @author neilz + */ +@Import(InfJobServiceImpl.class) +public class InfJobServiceTest extends BaseDbUnitTest { + @Resource + private InfJobServiceImpl jobService; + + @Resource + private InfJobMapper jobMapper; + @Resource + private SchedulerManager schedulerManager; + + @Test + public void testCreateJob_success() throws SchedulerException { + // 准备参数 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class); + reqVO.setCronExpression("0 0/1 * * * ? *"); + + // 调用 + Long jobId = jobService.createJob(reqVO); + + // 断言 + assertNotNull(jobId); + + // 校验记录的属性是否正确 + InfJobDO job = jobMapper.selectById(jobId); + assertPojoEquals(reqVO, job); + assertEquals(InfJobStatusEnum.NORMAL.getStatus(), job.getStatus()); + + // 校验调用 + verify(jobMapper, times(1)).selectByHandlerName(reqVO.getHandlerName()); + + InfJobDO insertJob = InfJobConvert.INSTANCE.convert(reqVO); + insertJob.setStatus(InfJobStatusEnum.INIT.getStatus()); + fillJobMonitorTimeoutEmpty(insertJob); + verify(jobMapper, times(1)).insert(insertJob); + + verify(schedulerManager, times(1)).addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(), + job.getRetryCount(), job.getRetryInterval()); + + InfJobDO updateObj = InfJobDO.builder().id(insertJob.getId()).status(InfJobStatusEnum.NORMAL.getStatus()).build(); + verify(jobMapper, times(1)).updateById(updateObj); + + } + + private static void fillJobMonitorTimeoutEmpty(InfJobDO job) { + if (job.getMonitorTimeout() == null) { + job.setMonitorTimeout(0); + } + } + +} diff --git a/src/test/resources/sql/clean.sql b/src/test/resources/sql/clean.sql index 75372fd1a..329a94064 100644 --- a/src/test/resources/sql/clean.sql +++ b/src/test/resources/sql/clean.sql @@ -1,6 +1,7 @@ -- inf 开头的 DB DELETE FROM "inf_config"; DELETE FROM "inf_file"; +DELETE FROM "inf_job"; -- sys 开头的 DB DELETE FROM "sys_dept"; diff --git a/src/test/resources/sql/create_tables.sql b/src/test/resources/sql/create_tables.sql index 36c573dd9..f4908a710 100644 --- a/src/test/resources/sql/create_tables.sql +++ b/src/test/resources/sql/create_tables.sql @@ -29,6 +29,24 @@ CREATE TABLE IF NOT EXISTS "inf_file" ( PRIMARY KEY ("id") ) COMMENT '文件表'; +CREATE TABLE "inf_job" ( + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号', + "name" varchar(32) NOT NULL COMMENT '任务名称', + "status" tinyint(4) NOT NULL COMMENT '任务状态', + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数', + "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式', + "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数', + "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔', + "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间', + "creator" varchar(64) DEFAULT '' COMMENT '创建者', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + "updater" varchar(64) DEFAULT '' COMMENT '更新者', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + "deleted" bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + PRIMARY KEY ("id") +) COMMENT='定时任务表'; + -- sys 开头的 DB CREATE TABLE IF NOT EXISTS "sys_dept" ( From dd8b6cc94a460e5780c8029e9a920cece8bb0036 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 13 Mar 2021 19:58:11 +0800 Subject: [PATCH 05/27] =?UTF-8?q?1.=20=E5=A2=9E=E5=8A=A0=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=99=A8=E7=9A=84=E8=87=AA=E5=8A=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java | 2 ++ src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java b/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java index 59bacb052..aadf47bda 100644 --- a/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java +++ b/src/test/java/cn/iocoder/dashboard/BaseDbAndRedisUnitTest.java @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; import org.redisson.spring.starter.RedissonAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; import org.springframework.test.context.ActiveProfiles; @@ -30,6 +31,7 @@ public class BaseDbAndRedisUnitTest { // DB 配置类 DataSourceConfiguration.class, // 自己的 DB 配置类 DataSourceAutoConfiguration.class, // Spring DB 自动配置类 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 DruidDataSourceAutoConfigure.class, // Druid 自动配置类 // MyBatis 配置类 MybatisConfiguration.class, // 自己的 MyBatis 配置类 diff --git a/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java b/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java index 821118279..19e930f1a 100644 --- a/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java +++ b/src/test/java/cn/iocoder/dashboard/BaseDbUnitTest.java @@ -5,6 +5,7 @@ import cn.iocoder.dashboard.framework.mybatis.config.MybatisConfiguration; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; import org.springframework.test.context.ActiveProfiles; @@ -26,6 +27,7 @@ public class BaseDbUnitTest { // DB 配置类 DataSourceConfiguration.class, // 自己的 DB 配置类 DataSourceAutoConfiguration.class, // Spring DB 自动配置类 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 DruidDataSourceAutoConfigure.class, // Druid 自动配置类 // MyBatis 配置类 MybatisConfiguration.class, // 自己的 MyBatis 配置类 From 0775e85aacf544343b608ea889b5e5da149bd572 Mon Sep 17 00:00:00 2001 From: neilz Date: Sun, 14 Mar 2021 15:35:42 +0800 Subject: [PATCH 06/27] =?UTF-8?q?Quartz=20=E7=9B=B8=E5=85=B3=E8=A1=A8?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=88=9D=E5=A7=8B=E5=8C=96=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?sql=20sysUserSessionTimeoutJob?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/quartz.sql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/quartz.sql b/sql/quartz.sql index dca0859e1..cf5ee70d7 100644 --- a/sql/quartz.sql +++ b/sql/quartz.sql @@ -178,3 +178,11 @@ CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIG CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); commit; + +-- 初始化默认任务 用户 Session 超时 Job +INSERT INTO QRTZ_JOB_DETAILS VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', NULL, 'cn.iocoder.dashboard.framework.quartz.core.handler.JobHandlerInvoker', '0', '1', '1', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000027400064A4F425F49447372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000047400104A4F425F48414E444C45525F4E414D457400187379735573657253657373696F6E54696D656F75744A6F627800); +commit; +INSERT INTO QRTZ_TRIGGERS VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', 'sysUserSessionTimeoutJob', 'DEFAULT', NULL, 1615706340000, 1615706280000, 5, 'WAITING', 'CRON', 1615706125000, 0, NULL, 0, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C770800000010000000037400114A4F425F48414E444C45525F504152414D707400124A4F425F52455452595F494E54455256414C737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B0200007870000007D074000F4A4F425F52455452595F434F554E547371007E0009000000037800); +commit; +INSERT INTO QRTZ_CRON_TRIGGERS VALUES ('schedulerName', 'sysUserSessionTimeoutJob', 'DEFAULT', '0 * * * * ? *', 'Asia/Shanghai'); +commit; From 4067087da6f8615ef3ad07ed03c8332be18e1c90 Mon Sep 17 00:00:00 2001 From: hexiaowu Date: Sun, 14 Mar 2021 18:56:06 +0800 Subject: [PATCH 07/27] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=9A=84Long=E5=BA=8F=E5=88=97=E5=8C=96=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E7=B1=BB=E5=9E=8B=E8=A7=84=E5=88=99=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9ELocalDateTime=E7=9A=84=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E3=80=81=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E8=A7=84?= =?UTF-8?q?=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jackson/config/JacksonConfig.java | 20 +++++++++----- .../deser/LocalDateTimeDeserializer.java | 26 +++++++++++++++++++ .../jackson/ser/LocalDateTimeSerializer.java | 24 +++++++++++++++++ .../framework/jackson/ser/LongSerializer.java | 26 ------------------- 4 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 src/main/java/cn/iocoder/dashboard/framework/jackson/deser/LocalDateTimeDeserializer.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LocalDateTimeSerializer.java delete mode 100644 src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java diff --git a/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java b/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java index 323b447ce..483d956f8 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java +++ b/src/main/java/cn/iocoder/dashboard/framework/jackson/config/JacksonConfig.java @@ -1,12 +1,16 @@ package cn.iocoder.dashboard.framework.jackson.config; -import cn.iocoder.dashboard.framework.jackson.ser.LongSerializer; +import cn.iocoder.dashboard.framework.jackson.deser.LocalDateTimeDeserializer; +import cn.iocoder.dashboard.framework.jackson.ser.LocalDateTimeSerializer; import cn.iocoder.dashboard.util.json.JsonUtils; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.time.LocalDateTime; + @Configuration public class JacksonConfig { @@ -15,11 +19,15 @@ public class JacksonConfig { public JsonUtils jsonUtils(ObjectMapper objectMapper) { SimpleModule simpleModule = new SimpleModule(); /* - * 新增Long类型序列化规则,数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型 - */ - simpleModule.addSerializer(Long.class,LongSerializer.getInstance()) - .addSerializer(Long.TYPE,LongSerializer.getInstance()); - objectMapper.registerModule(simpleModule); + * 1. 新增Long类型序列化规则,数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型 + * 2. 新增LocalDateTime序列化、反序列化规则 + */ + simpleModule.addSerializer(Long.class, ToStringSerializer.instance) + .addSerializer(Long.TYPE, ToStringSerializer.instance) + .addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE) + .addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE); + + objectMapper.registerModules(simpleModule); JsonUtils.init(objectMapper); return new JsonUtils(); diff --git a/src/main/java/cn/iocoder/dashboard/framework/jackson/deser/LocalDateTimeDeserializer.java b/src/main/java/cn/iocoder/dashboard/framework/jackson/deser/LocalDateTimeDeserializer.java new file mode 100644 index 000000000..122f461a4 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/jackson/deser/LocalDateTimeDeserializer.java @@ -0,0 +1,26 @@ +package cn.iocoder.dashboard.framework.jackson.deser; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * LocalDateTime反序列化规则 + *

+ * 会将毫秒级时间戳反序列化为LocalDateTime + */ +public class LocalDateTimeDeserializer extends JsonDeserializer { + + public static final LocalDateTimeDeserializer INSTANCE = new LocalDateTimeDeserializer(); + + @Override + public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + return LocalDateTime.ofInstant(Instant.ofEpochMilli(p.getValueAsLong()), ZoneId.systemDefault()); + } +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LocalDateTimeSerializer.java b/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LocalDateTimeSerializer.java new file mode 100644 index 000000000..d7230eadd --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LocalDateTimeSerializer.java @@ -0,0 +1,24 @@ +package cn.iocoder.dashboard.framework.jackson.ser; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * LocalDateTime序列化规则 + *

+ * 会将LocalDateTime序列化为毫秒级时间戳 + */ +public class LocalDateTimeSerializer extends JsonSerializer { + + public static final LocalDateTimeSerializer INSTANCE = new LocalDateTimeSerializer(); + + @Override + public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + } +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java b/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java deleted file mode 100644 index 6c0561d23..000000000 --- a/src/main/java/cn/iocoder/dashboard/framework/jackson/ser/LongSerializer.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.dashboard.framework.jackson.ser; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import java.io.IOException; - -/** - * Long类型序列化规则 - *

- * 数值超过2^53-1,在JS会出现精度丢失问题,因此Long自动序列化为字符串类型 - */ -public class LongSerializer extends JsonSerializer { - - private static final LongSerializer LONG_SERIALIZER = new LongSerializer(); - - @Override - public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(value.toString()); - } - - public static LongSerializer getInstance() { - return LONG_SERIALIZER; - } -} From 78e847a81adb0a267f4fc94e1522d08f1b6aa78f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 Mar 2021 20:46:26 +0800 Subject: [PATCH 08/27] =?UTF-8?q?=E6=95=B4=E7=90=86=20dept=E3=80=81post=20?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=20url=20=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-ui/src/api/system/dept.js | 4 +- ruoyi-ui/src/api/system/post.js | 4 +- ruoyi-ui/src/views/system/dept/index.vue | 67 +++---------- ruoyi-ui/src/views/system/post/index.vue | 75 +++------------ .../controller/auth/SysAuthController.java | 14 +-- .../auth/SysUserSessionController.java | 8 +- .../controller/dept/SysDeptController.java | 71 +++++++------- .../controller/dept/SysPostController.java | 73 +++++++------- .../system/service/dept/SysDeptService.java | 94 +++++++++---------- .../system/service/dept/SysPostService.java | 66 ++++++------- .../service/dept/impl/SysDeptServiceImpl.java | 93 +++++++++--------- .../service/dept/impl/SysPostServiceImpl.java | 58 ++++++------ .../permission/SysPermissionService.java | 4 +- .../impl/SysPermissionServiceImpl.java | 4 +- .../service/user/SysUserServiceImpl.java | 4 +- .../service/dept/SysDeptServiceTest.java | 2 +- .../service/dept/SysPostServiceTest.java | 4 +- 17 files changed, 281 insertions(+), 364 deletions(-) diff --git a/ruoyi-ui/src/api/system/dept.js b/ruoyi-ui/src/api/system/dept.js index c22f0f4a8..d8c59cf9a 100644 --- a/ruoyi-ui/src/api/system/dept.js +++ b/ruoyi-ui/src/api/system/dept.js @@ -46,7 +46,7 @@ export function addDept(data) { export function updateDept(data) { return request({ url: '/system/dept/update', - method: 'post', + method: 'put', data: data }) } @@ -55,6 +55,6 @@ export function updateDept(data) { export function delDept(id) { return request({ url: '/system/dept/delete?id=' + id, - method: 'post' + method: 'delete' }) } diff --git a/ruoyi-ui/src/api/system/post.js b/ruoyi-ui/src/api/system/post.js index cb1dfc3e5..3ef4a9906 100644 --- a/ruoyi-ui/src/api/system/post.js +++ b/ruoyi-ui/src/api/system/post.js @@ -38,7 +38,7 @@ export function addPost(data) { export function updatePost(data) { return request({ url: '/system/post/update', - method: 'post', + method: 'put', data: data }) } @@ -47,7 +47,7 @@ export function updatePost(data) { export function delPost(postId) { return request({ url: '/system/post/delete?id=' + postId, - method: 'post' + method: 'delete' }) } diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/dept/index.vue index 5485703ac..0fc5a8733 100644 --- a/ruoyi-ui/src/views/system/dept/index.vue +++ b/ruoyi-ui/src/views/system/dept/index.vue @@ -2,22 +2,11 @@

- + - + @@ -28,24 +17,13 @@ - 新增 + 新增 - + @@ -56,28 +34,12 @@ @@ -119,11 +81,8 @@ - {{dict.label}} + + {{dict.label}} diff --git a/ruoyi-ui/src/views/system/post/index.vue b/ruoyi-ui/src/views/system/post/index.vue index 9a66f964c..80cab5d49 100644 --- a/ruoyi-ui/src/views/system/post/index.vue +++ b/ruoyi-ui/src/views/system/post/index.vue @@ -2,31 +2,14 @@
- + - + - + @@ -37,22 +20,12 @@ - 新增 + 新增 - 导出 + 导出 @@ -70,31 +43,16 @@ - + @@ -110,11 +68,8 @@ - {{dict.label}} + + {{dict.label}} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java index ea7dbfd76..f6ea81e1d 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java @@ -19,6 +19,7 @@ import cn.iocoder.dashboard.modules.system.service.user.SysUserService; import cn.iocoder.dashboard.util.collection.SetUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -34,6 +35,7 @@ import static cn.iocoder.dashboard.util.servlet.ServletUtils.getUserAgent; @Api(tags = "认证") @RestController @RequestMapping("/") +@Validated public class SysAuthController { @Resource @@ -45,8 +47,8 @@ public class SysAuthController { @Resource private SysPermissionService permissionService; - @ApiOperation("使用账号密码登录") @PostMapping("/login") + @ApiOperation("使用账号密码登录") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { String token = authService.login(reqVO, getClientIP(), getUserAgent()); @@ -54,8 +56,8 @@ public class SysAuthController { return success(SysAuthLoginRespVO.builder().token(token).build()); } - @ApiOperation("获取登陆用户的权限信息") @GetMapping("/get-permission-info") + @ApiOperation("获取登陆用户的权限信息") public CommonResult getPermissionInfo() { // 获得用户信息 SysUserDO user = userService.getUser(getLoginUserId()); @@ -65,7 +67,7 @@ public class SysAuthController { // 获得角色列表 List roleList = roleService.listRolesFromCache(getLoginUserRoleIds()); // 获得菜单列表 - List menuList = permissionService.listRoleMenusFromCache( + List menuList = permissionService.getRoleMenusFromCache( getLoginUserRoleIds(), // 注意,基于登陆的角色,因为后续的权限判断也是基于它 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()), SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); @@ -73,11 +75,11 @@ public class SysAuthController { return success(SysAuthConvert.INSTANCE.convert(user, roleList, menuList)); } - @ApiOperation("获得登陆用户的菜单列表") @GetMapping("list-menus") - public CommonResult> listMenus() { + @ApiOperation("获得登陆用户的菜单列表") + public CommonResult> getMenus() { // 获得用户拥有的菜单列表 - List menuList = permissionService.listRoleMenusFromCache( + List menuList = permissionService.getRoleMenusFromCache( getLoginUserRoleIds(), // 注意,基于登陆的角色,因为后续的权限判断也是基于它 SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型 SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的 diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysUserSessionController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysUserSessionController.java index 570ebb6be..7ffd6318a 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysUserSessionController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysUserSessionController.java @@ -39,9 +39,9 @@ public class SysUserSessionController { @Resource private SysDeptService deptService; + @GetMapping("/page") @ApiOperation("获得 Session 分页列表") @PreAuthorize("@ss.hasPermission('system:user-session:page')") - @GetMapping("/page") public CommonResult> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) { // 获得 Session 分页 PageResult pageResult = userSessionService.getUserSessionPage(reqVO); @@ -66,12 +66,12 @@ public class SysUserSessionController { return success(new PageResult<>(sessionList, pageResult.getTotal())); } - @ApiOperation("删除 Session") - @PreAuthorize("@ss.hasPermission('system:user-session:delete')") @DeleteMapping("/delete") + @ApiOperation("删除 Session") @ApiImplicitParam(name = "id", value = "Session 编号", required = true, dataTypeClass = String.class, example = "fe50b9f6-d177-44b1-8da9-72ea34f63db7") - public CommonResult delete(@RequestParam("id") String id) { + @PreAuthorize("@ss.hasPermission('system:user-session:delete')") + public CommonResult deleteUserSession(@RequestParam("id") String id) { userSessionService.deleteUserSession(id); return success(true); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysDeptController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysDeptController.java index 77ebdcad3..9651275c1 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysDeptController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysDeptController.java @@ -9,10 +9,12 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.validation.Valid; import java.util.Comparator; import java.util.List; @@ -21,65 +23,64 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success; @Api(tags = "部门") @RestController @RequestMapping("/system/dept") +@Validated public class SysDeptController { @Resource private SysDeptService deptService; - @ApiOperation("获取部门列表") -// @PreAuthorize("@ss.hasPermi('system:dept:list')") + @PostMapping("create") + @ApiOperation("创建部门") + @PreAuthorize("@ss.hasPermission('system:dept:create')") + public CommonResult createDept(@Valid @RequestBody SysDeptCreateReqVO reqVO) { + Long deptId = deptService.createDept(reqVO); + return success(deptId); + } + + @PutMapping("update") + @ApiOperation("更新部门") + @PreAuthorize("@ss.hasPermission('system:dept:update')") + public CommonResult updateDept(@Valid @RequestBody SysDeptUpdateReqVO reqVO) { + deptService.updateDept(reqVO); + return success(true); + } + + @DeleteMapping("delete") + @ApiOperation("删除部门") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('system:dept:delete')") + public CommonResult deleteDept(@RequestParam("id") Long id) { + deptService.deleteDept(id); + return success(true); + } + @GetMapping("/list") + @ApiOperation("获取部门列表") + @PreAuthorize("@ss.hasPermission('system:dept:query')") public CommonResult> listDepts(SysDeptListReqVO reqVO) { - List list = deptService.listDepts(reqVO); + List list = deptService.getSimpleDepts(reqVO); list.sort(Comparator.comparing(SysDeptDO::getSort)); return success(SysDeptConvert.INSTANCE.convertList(list)); } - @ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项") @GetMapping("/list-all-simple") - public CommonResult> listSimpleDepts() { + @ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项") + public CommonResult> getSimpleDepts() { // 获得部门列表,只要开启状态的 SysDeptListReqVO reqVO = new SysDeptListReqVO(); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - List list = deptService.listDepts(reqVO); + List list = deptService.getSimpleDepts(reqVO); // 排序后,返回给前端 list.sort(Comparator.comparing(SysDeptDO::getSort)); return success(SysDeptConvert.INSTANCE.convertList02(list)); } + @GetMapping("/get") @ApiOperation("获得部门信息") @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) -// @PreAuthorize("@ss.hasPermi('system:dept:query')") - @GetMapping("/get") + @PreAuthorize("@ss.hasPermission('system:dept:query')") public CommonResult getDept(@RequestParam("id") Long id) { return success(SysDeptConvert.INSTANCE.convert(deptService.getDept(id))); } - @ApiOperation("新增部门") - @PostMapping("create") -// @PreAuthorize("@ss.hasPermi('system:dept:add')") -// @Log(title = "部门管理", businessType = BusinessType.INSERT) - public CommonResult createDept(@Validated @RequestBody SysDeptCreateReqVO reqVO) { - Long deptId = deptService.createDept(reqVO); - return success(deptId); - } - - @ApiOperation("修改部门") - @PostMapping("update") -// @PreAuthorize("@ss.hasPermi('system:dept:edit')") -// @Log(title = "部门管理", businessType = BusinessType.UPDATE) - public CommonResult updateDept(@Validated @RequestBody SysDeptUpdateReqVO reqVO) { - deptService.updateDept(reqVO); - return success(true); - } - - @ApiOperation("删除部门") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PostMapping("delete") -// @PreAuthorize("@ss.hasPermi('system:dept:remove')") -// @Log(title = "部门管理", businessType = BusinessType.DELETE) - public CommonResult deleteDept(@RequestParam("id") Long id) { - deptService.deleteDept(id); - return success(true); - } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysPostController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysPostController.java index 65f6c6994..125cd5d61 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysPostController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dept/SysPostController.java @@ -4,6 +4,7 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum; import cn.iocoder.dashboard.common.pojo.CommonResult; import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils; +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.*; import cn.iocoder.dashboard.modules.system.convert.dept.SysPostConvert; import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO; @@ -11,88 +12,88 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysPostService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.List; import static cn.iocoder.dashboard.common.pojo.CommonResult.success; +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT; @Api(tags = "岗位") @RestController @RequestMapping("/system/post") +@Valid public class SysPostController { @Resource private SysPostService postService; - @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项") - @GetMapping("/list-all-simple") - public CommonResult> listSimplePosts() { - // 获得岗位列表,只要开启状态的 - List list = postService.listPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); - // 排序后,返回给前端 - list.sort(Comparator.comparing(SysPostDO::getSort)); - return success(SysPostConvert.INSTANCE.convertList02(list)); - } - - @ApiOperation("获得岗位分页列表") - @GetMapping("/page") -// @PreAuthorize("@ss.hasPermi('system:post:list')") - public CommonResult> pagePosts(@Validated SysPostPageReqVO reqVO) { - return success(SysPostConvert.INSTANCE.convertPage(postService.pagePosts(reqVO))); - } - - @ApiOperation("新增岗位") @PostMapping("/create") -// @PreAuthorize("@ss.hasPermi('system:post:add')") -// @Log(title = "岗位管理", businessType = BusinessType.INSERT) - public CommonResult createPost(@Validated @RequestBody SysPostCreateReqVO reqVO) { + @ApiOperation("创建岗位") + @PreAuthorize("@ss.hasPermission('system:post:create')") + public CommonResult createPost(@Valid @RequestBody SysPostCreateReqVO reqVO) { Long postId = postService.createPost(reqVO); return success(postId); } + @PutMapping("/update") @ApiOperation("修改岗位") - @PostMapping("/update") -// @PreAuthorize("@ss.hasPermi('system:post:edit')") -// @Log(title = "岗位管理", businessType = BusinessType.UPDATE) - public CommonResult updatePost(@Validated @RequestBody SysPostUpdateReqVO reqVO) { + @PreAuthorize("@ss.hasPermission('system:post:update')") + public CommonResult updatePost(@Valid @RequestBody SysPostUpdateReqVO reqVO) { postService.updatePost(reqVO); return success(true); } + @DeleteMapping("/delete") @ApiOperation("删除岗位") - @PostMapping("/delete") -// @PreAuthorize("@ss.hasPermi('system:post:remove')") -// @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @PreAuthorize("@ss.hasPermission('system:post:delete')") public CommonResult deletePost(@RequestParam("id") Long id) { postService.deletePost(id); return success(true); } + @GetMapping(value = "/get") @ApiOperation("获得岗位信息") @ApiImplicitParam(name = "id", value = "岗位编号", required = true, example = "1024", dataTypeClass = Long.class) -// @PreAuthorize("@ss.hasPermi('system:post:query')") - @GetMapping(value = "/get") + @PreAuthorize("@ss.hasPermission('system:post:query')") public CommonResult getPost(@RequestParam("id") Long id) { return success(SysPostConvert.INSTANCE.convert(postService.getPost(id))); } + @GetMapping("/list-all-simple") + @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项") + public CommonResult> getSimplePosts() { + // 获得岗位列表,只要开启状态的 + List list = postService.getPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); + // 排序后,返回给前端 + list.sort(Comparator.comparing(SysPostDO::getSort)); + return success(SysPostConvert.INSTANCE.convertList02(list)); + } + + @GetMapping("/page") + @ApiOperation("获得岗位分页列表") + @PreAuthorize("@ss.hasPermission('system:post:query')") + public CommonResult> getPostPage(@Validated SysPostPageReqVO reqVO) { + return success(SysPostConvert.INSTANCE.convertPage(postService.getPostPage(reqVO))); + } + @GetMapping("/export") @ApiOperation("岗位管理") -// @Log(title = "岗位管理", businessType = BusinessType.EXPORT) -// @PreAuthorize("@ss.hasPermi('system:post:export')") + @PreAuthorize("@ss.hasPermission('system:post:export')") + @OperateLog(type = EXPORT) public void export(HttpServletResponse response, @Validated SysPostExportReqVO reqVO) throws IOException { - List posts = postService.listPosts(reqVO); - List excelDataList = SysPostConvert.INSTANCE.convertList03(posts); + List posts = postService.getPosts(reqVO); + List data = SysPostConvert.INSTANCE.convertList03(posts); // 输出 - ExcelUtils.write(response, "岗位数据.xls", "岗位列表", - SysPostExcelVO.class, excelDataList); + ExcelUtils.write(response, "岗位数据.xls", "岗位列表", SysPostExcelVO.class, data); } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptService.java index b41dc7871..b378fd18d 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptService.java @@ -24,53 +24,6 @@ public interface SysDeptService { */ void initLocalCache(); - /** - * 获得指定编号的部门列表 - * - * @param ids 部门编号数组 - * @return 部门列表 - */ - List listDepts(Collection ids); - - /** - * 获得指定编号的部门 Map - * - * @param ids 部门编号数组 - * @return 部门 Map - */ - default Map getDeptMap(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return Collections.emptyMap(); - } - List list = listDepts(ids); - return CollectionUtils.convertMap(list, SysDeptDO::getId); - } - - /** - * 筛选部门列表 - * - * @param reqVO 筛选条件请求 VO - * @return 部门列表 - */ - List listDepts(SysDeptListReqVO reqVO); - - /** - * 获得所有子部门,从缓存中 - * - * @param parentId 部门编号 - * @param recursive 是否递归获取所有 - * @return 子部门列表 - */ - List listDeptsByParentIdFromCache(Long parentId, boolean recursive); - - /** - * 获得部门信息 - * - * @param id 部门编号 - * @return 部门信息 - */ - SysDeptDO getDept(Long id); - /** * 创建部门 * @@ -93,4 +46,51 @@ public interface SysDeptService { */ void deleteDept(Long id); + /** + * 获得指定编号的部门列表 + * + * @param ids 部门编号数组 + * @return 部门列表 + */ + List getSimpleDepts(Collection ids); + + /** + * 获得指定编号的部门 Map + * + * @param ids 部门编号数组 + * @return 部门 Map + */ + default Map getDeptMap(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyMap(); + } + List list = getSimpleDepts(ids); + return CollectionUtils.convertMap(list, SysDeptDO::getId); + } + + /** + * 筛选部门列表 + * + * @param reqVO 筛选条件请求 VO + * @return 部门列表 + */ + List getSimpleDepts(SysDeptListReqVO reqVO); + + /** + * 获得部门信息 + * + * @param id 部门编号 + * @return 部门信息 + */ + SysDeptDO getDept(Long id); + + /** + * 获得所有子部门,从缓存中 + * + * @param parentId 部门编号 + * @param recursive 是否递归获取所有 + * @return 子部门列表 + */ + List getDeptsByParentIdFromCache(Long parentId, boolean recursive); + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java index 76992e681..b4cca1ab1 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java @@ -18,39 +18,6 @@ import java.util.List; */ public interface SysPostService { - /** - * 获得符合条件的岗位列表 - * - * @param ids 岗位编号数组。如果为空,不进行筛选 - * @param statuses 状态数组。如果为空,不进行筛选 - * @return 部门列表 - */ - List listPosts(@Nullable Collection ids, @Nullable Collection statuses); - - /** - * 获得岗位分页列表 - * - * @param reqVO 分页条件 - * @return 部门分页列表 - */ - PageResult pagePosts(SysPostPageReqVO reqVO); - - /** - * 获得岗位列表 - * - * @param reqVO 查询条件 - * @return 部门列表 - */ - List listPosts(SysPostExportReqVO reqVO); - - /** - * 获得岗位信息 - * - * @param id 岗位编号 - * @return 岗位信息 - */ - SysPostDO getPost(Long id); - /** * 创建岗位 * @@ -73,4 +40,37 @@ public interface SysPostService { */ void deletePost(Long id); + /** + * 获得符合条件的岗位列表 + * + * @param ids 岗位编号数组。如果为空,不进行筛选 + * @param statuses 状态数组。如果为空,不进行筛选 + * @return 部门列表 + */ + List getPosts(@Nullable Collection ids, @Nullable Collection statuses); + + /** + * 获得岗位分页列表 + * + * @param reqVO 分页条件 + * @return 部门分页列表 + */ + PageResult getPostPage(SysPostPageReqVO reqVO); + + /** + * 获得岗位列表 + * + * @param reqVO 查询条件 + * @return 部门列表 + */ + List getPosts(SysPostExportReqVO reqVO); + + /** + * 获得岗位信息 + * + * @param id 岗位编号 + * @return 岗位信息 + */ + SysPostDO getPost(Long id); + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java index 1f3682bc6..65777ef06 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java @@ -19,6 +19,7 @@ import com.google.common.collect.Multimap; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; import javax.annotation.PostConstruct; import javax.annotation.Resource; @@ -32,6 +33,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; * @author 芋道源码 */ @Service +@Validated @Slf4j public class SysDeptServiceImpl implements SysDeptService { @@ -47,6 +49,7 @@ public class SysDeptServiceImpl implements SysDeptService { * * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 */ + @SuppressWarnings("FieldCanBeLocal") private volatile Map deptCache; /** * 父部门缓存 @@ -118,17 +121,55 @@ public class SysDeptServiceImpl implements SysDeptService { } @Override - public List listDepts(Collection ids) { + public Long createDept(SysDeptCreateReqVO reqVO) { + // 校验正确性 + checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName()); + // 插入部门 + SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO); + deptMapper.insert(dept); + // 发送刷新消息 + deptProducer.sendDeptRefreshMessage(); + return dept.getId(); + } + + @Override + public void updateDept(SysDeptUpdateReqVO reqVO) { + // 校验正确性 + checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName()); + // 更新部门 + SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO); + deptMapper.updateById(updateObj); + // 发送刷新消息 + deptProducer.sendDeptRefreshMessage(); + } + + @Override + public void deleteDept(Long id) { + // 校验是否存在 + checkDeptExists(id); + // 校验是否有子部门 + if (deptMapper.selectCountByParentId(id) > 0) { + throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN); + } + // 删除部门 + deptMapper.deleteById(id); + // TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下 + // 发送刷新消息 + deptProducer.sendDeptRefreshMessage(); + } + + @Override + public List getSimpleDepts(Collection ids) { return deptMapper.selectBatchIds(ids); } @Override - public List listDepts(SysDeptListReqVO reqVO) { + public List getSimpleDepts(SysDeptListReqVO reqVO) { return deptMapper.selectList(reqVO); } @Override - public List listDeptsByParentIdFromCache(Long parentId, boolean recursive) { + public List getDeptsByParentIdFromCache(Long parentId, boolean recursive) { List result = new ArrayList<>(); // 递归,简单粗暴 this.listDeptsByParentIdFromCache(result, parentId, @@ -167,44 +208,6 @@ public class SysDeptServiceImpl implements SysDeptService { return deptMapper.selectById(id); } - @Override - public Long createDept(SysDeptCreateReqVO reqVO) { - // 校验正确性 - checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName()); - // 插入部门 - SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO); - deptMapper.insert(dept); - // 发送刷新消息 - deptProducer.sendDeptRefreshMessage(); - return dept.getId(); - } - - @Override - public void updateDept(SysDeptUpdateReqVO reqVO) { - // 校验正确性 - checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName()); - // 更新部门 - SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO); - deptMapper.updateById(updateObj); - // 发送刷新消息 - deptProducer.sendDeptRefreshMessage(); - } - - @Override - public void deleteDept(Long id) { - // 校验是否存在 - checkDeptExists(id); - // 校验是否有子部门 - if (deptMapper.selectCountByParentId(id) > 0) { - throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN); - } - // 删除部门 - deptMapper.deleteById(id); - // TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下 - // 发送刷新消息 - deptProducer.sendDeptRefreshMessage(); - } - private void checkCreateOrUpdate(Long id, Long parentId, String name) { // 校验自己存在 checkDeptExists(id); @@ -232,7 +235,7 @@ public class SysDeptServiceImpl implements SysDeptService { throw ServiceExceptionUtil.exception(DEPT_NOT_ENABLE); } // 父部门不能是原来的子部门 - List children = this.listDeptsByParentIdFromCache(id, true); + List children = this.getDeptsByParentIdFromCache(id, true); if (children.stream().anyMatch(dept1 -> dept1.getId().equals(parentId))) { throw ServiceExceptionUtil.exception(DEPT_PARENT_IS_CHILD); } @@ -262,12 +265,6 @@ public class SysDeptServiceImpl implements SysDeptService { } } -// /** -// * 查询部门管理数据 -// * -// * @param dept 部门信息 -// * @return 部门信息集合 -// */ // @Override // @DataScope(deptAlias = "d") // public List selectDeptList(SysDept dept) diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysPostServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysPostServiceImpl.java index 0036fb8d7..36bb95cb2 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysPostServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysPostServiceImpl.java @@ -11,6 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dept.SysPostMapper; import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO; import cn.iocoder.dashboard.modules.system.service.dept.SysPostService; import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Collection; @@ -24,31 +25,12 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; * @author 芋道源码 */ @Service +@Validated public class SysPostServiceImpl implements SysPostService { @Resource private SysPostMapper postMapper; - @Override - public List listPosts(Collection ids, Collection statuses) { - return postMapper.selectList(ids, statuses); - } - - @Override - public PageResult pagePosts(SysPostPageReqVO reqVO) { - return postMapper.selectPage(reqVO); - } - - @Override - public List listPosts(SysPostExportReqVO reqVO) { - return postMapper.selectList(reqVO); - } - - @Override - public SysPostDO getPost(Long id) { - return postMapper.selectById(id); - } - @Override public Long createPost(SysPostCreateReqVO reqVO) { // 校验正确性 @@ -68,6 +50,34 @@ public class SysPostServiceImpl implements SysPostService { postMapper.updateById(updateObj); } + @Override + public void deletePost(Long id) { + // 校验是否存在 + this.checkPostExists(id); + // 删除部门 + postMapper.deleteById(id); + } + + @Override + public List getPosts(Collection ids, Collection statuses) { + return postMapper.selectList(ids, statuses); + } + + @Override + public PageResult getPostPage(SysPostPageReqVO reqVO) { + return postMapper.selectPage(reqVO); + } + + @Override + public List getPosts(SysPostExportReqVO reqVO) { + return postMapper.selectList(reqVO); + } + + @Override + public SysPostDO getPost(Long id) { + return postMapper.selectById(id); + } + private void checkCreateOrUpdate(Long id, String name, String code) { // 校验自己存在 checkPostExists(id); @@ -105,14 +115,6 @@ public class SysPostServiceImpl implements SysPostService { } } - @Override - public void deletePost(Long id) { - // 校验是否存在 - this.checkPostExists(id); - // 删除部门 - postMapper.deleteById(id); - } - private void checkPostExists(Long id) { if (id == null) { return; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java index cfbf205d1..5390d3294 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java @@ -32,8 +32,8 @@ public interface SysPermissionService extends SecurityPermissionFrameworkService * @param menusStatuses 菜单状态数组 * @return 菜单列表 */ - List listRoleMenusFromCache(Collection roleIds, Collection menuTypes, - Collection menusStatuses); + List getRoleMenusFromCache(Collection roleIds, Collection menuTypes, + Collection menusStatuses); /** * 获得用户拥有的角色编号集合 diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java index ceb1d6d83..5ac32419b 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java @@ -133,8 +133,8 @@ public class SysPermissionServiceImpl implements SysPermissionService { } @Override - public List listRoleMenusFromCache(Collection roleIds, Collection menuTypes, - Collection menusStatuses) { + public List getRoleMenusFromCache(Collection roleIds, Collection menuTypes, + Collection menusStatuses) { // 任一一个参数为空时,不返回任何菜单 if (CollectionUtils.isAnyEmpty(roleIds, menusStatuses, menusStatuses)) { return Collections.emptyList(); diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java index acffcb7d1..2e792d24c 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java @@ -113,7 +113,7 @@ public class SysUserServiceImpl implements SysUserService { if (deptId == null) { return Collections.emptySet(); } - Set deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache( + Set deptIds = CollectionUtils.convertSet(deptService.getDeptsByParentIdFromCache( deptId, true), SysDeptDO::getId); deptIds.add(deptId); // 包括自身 return deptIds; @@ -287,7 +287,7 @@ public class SysUserServiceImpl implements SysUserService { if (CollUtil.isEmpty(postIds)) { // 允许不选择 return; } - List posts = postService.listPosts(postIds, null); + List posts = postService.getPosts(postIds, null); if (CollUtil.isEmpty(posts)) { throw ServiceExceptionUtil.exception(POST_NOT_FOUND); } diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java index ca0165c0f..727d08f78 100644 --- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java @@ -92,7 +92,7 @@ class SysDeptServiceTest extends BaseDbUnitTest { reqVO.setName("开"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 - List sysDeptDOS = deptService.listDepts(reqVO); + List sysDeptDOS = deptService.getSimpleDepts(reqVO); // 断言 assertEquals(1, sysDeptDOS.size()); assertPojoEquals(dept, sysDeptDOS.get(0)); diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostServiceTest.java index bf3478989..be8b3225d 100644 --- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostServiceTest.java +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostServiceTest.java @@ -59,7 +59,7 @@ class SysPostServiceTest extends BaseDbUnitTest { reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 - PageResult pageResult = postService.pagePosts(reqVO); + PageResult pageResult = postService.getPostPage(reqVO); // 断言 assertEquals(1, pageResult.getTotal()); @@ -85,7 +85,7 @@ class SysPostServiceTest extends BaseDbUnitTest { reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 - List list = postService.listPosts(reqVO); + List list = postService.getPosts(reqVO); // 断言 assertEquals(1, list.size()); assertPojoEquals(postDO, list.get(0)); From ca1132f2df07a1c9e04379f75a7cb21f0e243cdc Mon Sep 17 00:00:00 2001 From: neilz Date: Sun, 14 Mar 2021 20:59:40 +0800 Subject: [PATCH 09/27] =?UTF-8?q?job=20=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/job/impl/InfJobServiceImpl.java | 2 - .../service/job/InfJobLogServiceTest.java | 173 ++++++++++++ .../infra/service/job/InfJobServiceTest.java | 249 ++++++++++++++++-- src/test/resources/sql/clean.sql | 1 + src/test/resources/sql/create_tables.sql | 52 ++-- 5 files changed, 439 insertions(+), 38 deletions(-) create mode 100644 src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobLogServiceTest.java diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java index 3cdbbf1c9..156c423c6 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java @@ -13,7 +13,6 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper; import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; import cn.iocoder.dashboard.modules.infra.service.job.InfJobService; import org.quartz.SchedulerException; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -38,7 +37,6 @@ public class InfJobServiceImpl implements InfJobService { @Resource private InfJobMapper jobMapper; - @MockBean @Resource private SchedulerManager schedulerManager; diff --git a/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobLogServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobLogServiceTest.java new file mode 100644 index 000000000..d6caa2a54 --- /dev/null +++ b/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobLogServiceTest.java @@ -0,0 +1,173 @@ +package cn.iocoder.dashboard.modules.infra.service.job; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.dashboard.util.RandomUtils.randomLongId; +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo; +import static cn.iocoder.dashboard.util.RandomUtils.randomString; +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Resource; + +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import cn.iocoder.dashboard.BaseDbUnitTest; +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.log.InfJobLogExportReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.log.InfJobLogPageReqVO; +import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobLogDO; +import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobLogMapper; +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobLogStatusEnum; +import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobLogServiceImpl; +import cn.iocoder.dashboard.util.object.ObjectUtils; + +/** + * {@link InfJobLogServiceImpl} 的单元测试 + * + * @author neilz + */ +@Import(InfJobLogServiceImpl.class) +public class InfJobLogServiceTest extends BaseDbUnitTest { + + @Resource + private InfJobLogServiceImpl jobLogService; + @Resource + private InfJobLogMapper jobLogMapper; + + @Test + public void testCreateJobLog_success() { + // 准备参数 + InfJobLogDO reqVO = randomPojo(InfJobLogDO.class, o -> { + o.setExecuteIndex(1); + }); + // 调用 + Long jobLogId = jobLogService.createJobLog(reqVO.getJobId(), reqVO.getBeginTime(), reqVO.getHandlerName(), reqVO.getHandlerParam(), reqVO.getExecuteIndex()); + // 断言 + assertNotNull(jobLogId); + // 校验记录的属性是否正确 + InfJobLogDO job = jobLogMapper.selectById(jobLogId); + assertEquals(InfJobLogStatusEnum.RUNNING.getStatus(), job.getStatus()); + } + + @Test + public void testUpdateJobLogResultAsync_success() { + // 准备参数 + InfJobLogDO reqVO = randomPojo(InfJobLogDO.class, o -> { + o.setExecuteIndex(1); + }); + InfJobLogDO log = InfJobLogDO.builder().jobId(reqVO.getJobId()).handlerName(reqVO.getHandlerName()).handlerParam(reqVO.getHandlerParam()).executeIndex(reqVO.getExecuteIndex()) + .beginTime(reqVO.getBeginTime()).status(InfJobLogStatusEnum.RUNNING.getStatus()).build(); + jobLogMapper.insert(log); + // 调用 + jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), true,reqVO.getResult()); + // 校验记录的属性是否正确 + InfJobLogDO job = jobLogMapper.selectById(log.getId()); + assertEquals(InfJobLogStatusEnum.SUCCESS.getStatus(), job.getStatus()); + + // 调用 + jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), false,reqVO.getResult()); + // 校验记录的属性是否正确 + InfJobLogDO job2 = jobLogMapper.selectById(log.getId()); + assertEquals(InfJobLogStatusEnum.FAILURE.getStatus(), job2.getStatus()); + } + + @Test + public void testGetJobLogListByIds_success() { + // mock 数据 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> { + o.setExecuteIndex(1); + o.setStatus(randomEle(InfJobLogStatusEnum.values()).getStatus()); // 保证 status 的范围 + }); + InfJobLogDO cloneJobLog = ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())); + jobLogMapper.insert(dbJobLog); + // 测试 handlerName 不匹配 + jobLogMapper.insert(cloneJobLog); + // 准备参数 + ArrayList ids = new ArrayList<>(); + ids.add(dbJobLog.getId()); + ids.add(cloneJobLog.getId()); + // 调用 + List list = jobLogService.getJobLogList(ids); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(dbJobLog, list.get(0)); + } + + @Test + public void testGetJobPage_success() { + // mock 数据 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> { + o.setExecuteIndex(1); + o.setHandlerName("handlerName 单元测试"); + o.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus()); + o.setBeginTime(buildTime(2021, 1, 8)); + o.setEndTime(buildTime(2021, 1, 8)); + }); + jobLogMapper.insert(dbJobLog); + // 测试 jobId 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId()))); + // 测试 handlerName 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString()))); + // 测试 beginTime 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7)))); + // 测试 endTime 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9)))); + // 测试 status 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus()))); + // 准备参数 + InfJobLogPageReqVO reqVo = new InfJobLogPageReqVO(); + reqVo.setJobId(dbJobLog.getJobId()); + reqVo.setHandlerName("单元"); + reqVo.setBeginTime(dbJobLog.getBeginTime()); + reqVo.setEndTime(dbJobLog.getEndTime()); + reqVo.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus()); + // 调用 + PageResult pageResult = jobLogService.getJobLogPage(reqVo); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbJobLog, pageResult.getList().get(0)); + } + + @Test + public void testGetJobListForExport_success() { + // mock 数据 + InfJobLogDO dbJobLog = randomPojo(InfJobLogDO.class, o -> { + o.setExecuteIndex(1); + o.setHandlerName("handlerName 单元测试"); + o.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus()); + o.setBeginTime(buildTime(2021, 1, 8)); + o.setEndTime(buildTime(2021, 1, 8)); + }); + jobLogMapper.insert(dbJobLog); + // 测试 jobId 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId()))); + // 测试 handlerName 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString()))); + // 测试 beginTime 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7)))); + // 测试 endTime 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9)))); + // 测试 status 不匹配 + jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus()))); + // 准备参数 + InfJobLogExportReqVO reqVo = new InfJobLogExportReqVO(); + reqVo.setJobId(dbJobLog.getJobId()); + reqVo.setHandlerName("单元"); + reqVo.setBeginTime(dbJobLog.getBeginTime()); + reqVo.setEndTime(dbJobLog.getEndTime()); + reqVo.setStatus(InfJobLogStatusEnum.SUCCESS.getStatus()); + // 调用 + List list = jobLogService.getJobLogList(reqVo); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbJobLog, list.get(0)); + } + +} diff --git a/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java index e8ed0dfc7..10a2dba7a 100644 --- a/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java +++ b/src/test/java/cn/iocoder/dashboard/modules/infra/service/job/InfJobServiceTest.java @@ -1,25 +1,43 @@ package cn.iocoder.dashboard.modules.infra.service.job; +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CHANGE_STATUS_EQUALS; +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CHANGE_STATUS_INVALID; +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_CRON_EXPRESSION_VALID; +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_HANDLER_EXISTS; +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_NOT_EXISTS; +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.JOB_UPDATE_ONLY_NORMAL_STATUS; import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException; import static cn.iocoder.dashboard.util.RandomUtils.randomPojo; +import static cn.iocoder.dashboard.util.RandomUtils.randomString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.ArrayList; +import java.util.List; import javax.annotation.Resource; import org.junit.jupiter.api.Test; import org.quartz.SchedulerException; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; + import cn.iocoder.dashboard.BaseDbUnitTest; +import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.framework.quartz.core.scheduler.SchedulerManager; import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobCreateReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobExportReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO; +import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobUpdateReqVO; import cn.iocoder.dashboard.modules.infra.convert.job.InfJobConvert; import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO; import cn.iocoder.dashboard.modules.infra.dal.mysql.job.InfJobMapper; import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobServiceImpl; +import cn.iocoder.dashboard.util.object.ObjectUtils; /** * {@link InfJobServiceImpl} 的单元测试 @@ -28,45 +46,236 @@ import cn.iocoder.dashboard.modules.infra.service.job.impl.InfJobServiceImpl; */ @Import(InfJobServiceImpl.class) public class InfJobServiceTest extends BaseDbUnitTest { - @Resource - private InfJobServiceImpl jobService; @Resource - private InfJobMapper jobMapper; + private InfJobServiceImpl jobService; @Resource + private InfJobMapper jobMapper; + @MockBean private SchedulerManager schedulerManager; @Test - public void testCreateJob_success() throws SchedulerException { - // 准备参数 + public void testCreateJob_cronExpressionValid() { + // 准备参数。Cron 表达式为 String 类型,默认随机字符串。 InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class); - reqVO.setCronExpression("0 0/1 * * * ? *"); + // 调用,并断言异常 + assertServiceException(() -> jobService.createJob(reqVO), JOB_CRON_EXPRESSION_VALID); + } + @Test + public void testCreateJob_jobHandlerExists() throws SchedulerException { + // 准备参数 指定 Cron 表达式 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + // 调用 + jobService.createJob(reqVO); + // 调用,并断言异常 + assertServiceException(() -> jobService.createJob(reqVO), JOB_HANDLER_EXISTS); + } + + @Test + public void testCreateJob_success() throws SchedulerException { + // 准备参数 指定 Cron 表达式 + InfJobCreateReqVO reqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); // 调用 Long jobId = jobService.createJob(reqVO); - // 断言 assertNotNull(jobId); - // 校验记录的属性是否正确 InfJobDO job = jobMapper.selectById(jobId); assertPojoEquals(reqVO, job); assertEquals(InfJobStatusEnum.NORMAL.getStatus(), job.getStatus()); + } - // 校验调用 - verify(jobMapper, times(1)).selectByHandlerName(reqVO.getHandlerName()); + @Test + public void testUpdateJob_jobNotExists(){ + // 准备参数 + InfJobUpdateReqVO reqVO = randomPojo(InfJobUpdateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + // 调用,并断言异常 + assertServiceException(() -> jobService.updateJob(reqVO), JOB_NOT_EXISTS); + } - InfJobDO insertJob = InfJobConvert.INSTANCE.convert(reqVO); - insertJob.setStatus(InfJobStatusEnum.INIT.getStatus()); - fillJobMonitorTimeoutEmpty(insertJob); - verify(jobMapper, times(1)).insert(insertJob); + @Test + public void testUpdateJob_onlyNormalStatus(){ + // mock 数据 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO); + job.setStatus(InfJobStatusEnum.INIT.getStatus()); + fillJobMonitorTimeoutEmpty(job); + jobMapper.insert(job); + // 准备参数 + InfJobUpdateReqVO updateReqVO = randomPojo(InfJobUpdateReqVO.class, o -> { + o.setId(job.getId()); + o.setName(createReqVO.getName()); + o.setCronExpression(createReqVO.getCronExpression()); + }); + // 调用,并断言异常 + assertServiceException(() -> jobService.updateJob(updateReqVO), JOB_UPDATE_ONLY_NORMAL_STATUS); + } - verify(schedulerManager, times(1)).addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(), - job.getRetryCount(), job.getRetryInterval()); + @Test + public void testUpdateJob_success() throws SchedulerException { + // mock 数据 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO); + job.setStatus(InfJobStatusEnum.NORMAL.getStatus()); + fillJobMonitorTimeoutEmpty(job); + jobMapper.insert(job); + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(), + createReqVO.getRetryCount(), createReqVO.getRetryInterval()); + // 准备参数 + InfJobUpdateReqVO updateReqVO = randomPojo(InfJobUpdateReqVO.class, o -> { + o.setId(job.getId()); + o.setName(createReqVO.getName()); + o.setCronExpression(createReqVO.getCronExpression()); + }); + // 调用 + jobService.updateJob(updateReqVO); + // 校验记录的属性是否正确 + InfJobDO updateJob = jobMapper.selectById(updateReqVO.getId()); + assertPojoEquals(updateReqVO, updateJob); + } - InfJobDO updateObj = InfJobDO.builder().id(insertJob.getId()).status(InfJobStatusEnum.NORMAL.getStatus()).build(); - verify(jobMapper, times(1)).updateById(updateObj); + @Test + public void testUpdateJobStatus_changeStatusInvalid() { + // 调用,并断言异常 + assertServiceException(() -> jobService.updateJobStatus(1l, InfJobStatusEnum.INIT.getStatus()), JOB_CHANGE_STATUS_INVALID); + } + @Test + public void testUpdateJobStatus_changeStatusEquals() { + // mock 数据 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO); + job.setStatus(InfJobStatusEnum.NORMAL.getStatus()); + fillJobMonitorTimeoutEmpty(job); + jobMapper.insert(job); + // 调用,并断言异常 + assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), JOB_CHANGE_STATUS_EQUALS); + } + + @Test + public void testUpdateJobStatus_success() throws SchedulerException { + // mock 数据 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO); + job.setStatus(InfJobStatusEnum.NORMAL.getStatus()); + fillJobMonitorTimeoutEmpty(job); + jobMapper.insert(job); + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(), + createReqVO.getRetryCount(), createReqVO.getRetryInterval()); + // 调用 + jobService.updateJobStatus(job.getId(), InfJobStatusEnum.STOP.getStatus()); + // 校验记录的属性是否正确 + InfJobDO updateJob = jobMapper.selectById(job.getId()); + assertEquals(InfJobStatusEnum.STOP.getStatus(), updateJob.getStatus()); + } + + /** + * 页面"执行一次"按钮功能集成测试发现问题: + * inf_job 表初始化任务 sysUserSessionTimeoutJob 点击报错,是因为 Job 并没有添加到 Quartz 中; + * 没有走 createJob 中 scheduler.scheduleJob() 这一步,报错任务找不到。 + * // FINISHED Quartz 相关表新增初始化任务 sysUserSessionTimeoutJob sql + */ + @Test + public void testTriggerJob_success() throws SchedulerException { + /** + * TODO 不知道是否要将 Quartz 相关 SQL 引入来做单元测试 + * 1、schedulerManager.addJob sysUserSessionTimeoutJob + * 2、schedulerManager.triggerJob + * 3、check inf_job_log + */ + } + + @Test + public void testDeleteJob_success() throws SchedulerException { + // mock 数据 + InfJobCreateReqVO createReqVO = randomPojo(InfJobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + InfJobDO job = InfJobConvert.INSTANCE.convert(createReqVO); + job.setStatus(InfJobStatusEnum.NORMAL.getStatus()); + fillJobMonitorTimeoutEmpty(job); + jobMapper.insert(job); + schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(), + createReqVO.getRetryCount(), createReqVO.getRetryInterval()); + // 调用 UPDATE inf_job SET deleted=1 WHERE id=? AND deleted=0 + jobService.deleteJob(job.getId()); + // 校验数据不存在了 WHERE id=? AND deleted=0 查询为空正常 + assertNull(jobMapper.selectById(job.getId())); + } + + @Test + public void testGetJobListByIds_success() { + // mock 数据 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> { + o.setStatus(randomEle(InfJobStatusEnum.values()).getStatus()); // 保证 status 的范围 + }); + InfJobDO cloneJob = ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())); + jobMapper.insert(dbJob); + // 测试 handlerName 不匹配 + jobMapper.insert(cloneJob); + // 准备参数 + ArrayList ids = new ArrayList<>(); + ids.add(dbJob.getId()); + ids.add(cloneJob.getId()); + // 调用 + List list = jobService.getJobList(ids); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(dbJob, list.get(0)); + } + + @Test + public void testGetJobPage_success() { + // mock 数据 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> { + o.setName("定时任务测试"); + o.setHandlerName("handlerName 单元测试"); + o.setStatus(InfJobStatusEnum.INIT.getStatus()); + }); + jobMapper.insert(dbJob); + // 测试 name 不匹配 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆"))); + // 测试 status 不匹配 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus()))); + // 测试 handlerName 不匹配 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString()))); + // 准备参数 + InfJobPageReqVO reqVo = new InfJobPageReqVO(); + reqVo.setName("定时"); + reqVo.setStatus(InfJobStatusEnum.INIT.getStatus()); + reqVo.setHandlerName("单元"); + // 调用 + PageResult pageResult = jobService.getJobPage(reqVo); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbJob, pageResult.getList().get(0)); + } + + @Test + public void testGetJobListForExport_success() { + // mock 数据 + InfJobDO dbJob = randomPojo(InfJobDO.class, o -> { + o.setName("定时任务测试"); + o.setHandlerName("handlerName 单元测试"); + o.setStatus(InfJobStatusEnum.INIT.getStatus()); + }); + jobMapper.insert(dbJob); + // 测试 name 不匹配 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆"))); + // 测试 status 不匹配 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus()))); + // 测试 handlerName 不匹配 + jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString()))); + // 准备参数 + InfJobExportReqVO reqVo = new InfJobExportReqVO(); + reqVo.setName("定时"); + reqVo.setStatus(InfJobStatusEnum.INIT.getStatus()); + reqVo.setHandlerName("单元"); + // 调用 + List list = jobService.getJobList(reqVo); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbJob, list.get(0)); } private static void fillJobMonitorTimeoutEmpty(InfJobDO job) { diff --git a/src/test/resources/sql/clean.sql b/src/test/resources/sql/clean.sql index 329a94064..4345fcb45 100644 --- a/src/test/resources/sql/clean.sql +++ b/src/test/resources/sql/clean.sql @@ -2,6 +2,7 @@ DELETE FROM "inf_config"; DELETE FROM "inf_file"; DELETE FROM "inf_job"; +DELETE FROM "inf_job_log"; -- sys 开头的 DB DELETE FROM "sys_dept"; diff --git a/src/test/resources/sql/create_tables.sql b/src/test/resources/sql/create_tables.sql index 795336435..7dadc2fba 100644 --- a/src/test/resources/sql/create_tables.sql +++ b/src/test/resources/sql/create_tables.sql @@ -29,24 +29,44 @@ CREATE TABLE IF NOT EXISTS "inf_file" ( PRIMARY KEY ("id") ) COMMENT '文件表'; -CREATE TABLE "inf_job" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号', - "name" varchar(32) NOT NULL COMMENT '任务名称', - "status" tinyint(4) NOT NULL COMMENT '任务状态', - "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', - "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数', - "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式', - "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数', - "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔', - "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间', - "creator" varchar(64) DEFAULT '' COMMENT '创建者', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - "updater" varchar(64) DEFAULT '' COMMENT '更新者', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - "deleted" bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - PRIMARY KEY ("id") +CREATE TABLE IF NOT EXISTS "inf_job" ( + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '任务编号', + "name" varchar(32) NOT NULL COMMENT '任务名称', + "status" tinyint(4) NOT NULL COMMENT '任务状态', + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数', + "cron_expression" varchar(32) NOT NULL COMMENT 'CRON 表达式', + "retry_count" int(11) NOT NULL DEFAULT '0' COMMENT '重试次数', + "retry_interval" int(11) NOT NULL DEFAULT '0' COMMENT '重试间隔', + "monitor_timeout" int(11) NOT NULL DEFAULT '0' COMMENT '监控超时时间', + "creator" varchar(64) DEFAULT '' COMMENT '创建者', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + "updater" varchar(64) DEFAULT '' COMMENT '更新者', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + "deleted" bit NOT NULL DEFAULT FALSE COMMENT '是否删除', + PRIMARY KEY ("id") ) COMMENT='定时任务表'; +DROP TABLE IF EXISTS "inf_job_log"; +CREATE TABLE "inf_job_log" ( + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号', + "job_id" bigint(20) NOT NULL COMMENT '任务编号', + "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', + "handler_param" varchar(255) DEFAULT NULL COMMENT '处理器的参数', + "execute_index" tinyint(4) NOT NULL DEFAULT '1' COMMENT '第几次执行', + "begin_time" datetime NOT NULL COMMENT '开始执行时间', + "end_time" datetime DEFAULT NULL COMMENT '结束执行时间', + "duration" int(11) DEFAULT NULL COMMENT '执行时长', + "status" tinyint(4) NOT NULL COMMENT '任务状态', + "result" varchar(4000) DEFAULT '' COMMENT '结果数据', + "creator" varchar(64) DEFAULT '' COMMENT '创建者', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + "updater" varchar(64) DEFAULT '' COMMENT '更新者', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + "deleted" bit(1) NOT NULL DEFAULT FALSE COMMENT '是否删除', + PRIMARY KEY ("id") +)COMMENT='定时任务日志表'; + -- sys 开头的 DB CREATE TABLE IF NOT EXISTS "sys_dept" ( From a7a2725a87cea07231cfe7b6239127078553aa05 Mon Sep 17 00:00:00 2001 From: neilz Date: Sun, 14 Mar 2021 21:06:55 +0800 Subject: [PATCH 10/27] =?UTF-8?q?=E5=9B=9E=E9=80=80=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/infra/controller/job/vo/job/InfJobBaseVO.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java index 352c490fc..246f2a7a9 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/controller/job/vo/job/InfJobBaseVO.java @@ -34,7 +34,5 @@ public class InfJobBaseVO { @ApiModelProperty(value = "监控超时时间", example = "1000") private Integer monitorTimeout; - public void setCronExpression(String cronExpression) { - this.cronExpression = cronExpression; - } + } From 9f9c63a221ee0998530a40183e50b3f8b510459a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 Mar 2021 21:28:17 +0800 Subject: [PATCH 11/27] =?UTF-8?q?=E6=95=B4=E7=90=86=20dict=20data=20?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=20url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-ui/src/api/system/dict/data.js | 4 +- ruoyi-ui/src/api/system/dict/type.js | 4 +- ruoyi-ui/src/views/system/dict/data.vue | 73 +++----------- ruoyi-ui/src/views/system/dict/index.vue | 96 ++++--------------- .../dict/SysDictDataController.java | 84 ++++++++-------- .../dict/SysDictTypeController.java | 75 ++++++++------- .../service/dict/SysDictDataService.java | 62 ++++++------ .../service/dict/SysDictTypeService.java | 44 ++++----- .../dict/impl/SysDictDataServiceImpl.java | 4 +- .../service/dict/SysDictDataServiceTest.java | 2 +- 10 files changed, 172 insertions(+), 276 deletions(-) diff --git a/ruoyi-ui/src/api/system/dict/data.js b/ruoyi-ui/src/api/system/dict/data.js index c29b2f81f..00e614b15 100644 --- a/ruoyi-ui/src/api/system/dict/data.js +++ b/ruoyi-ui/src/api/system/dict/data.js @@ -38,7 +38,7 @@ export function addData(data) { export function updateData(data) { return request({ url: '/system/dict-data/update', - method: 'post', + method: 'put', data: data }) } @@ -47,7 +47,7 @@ export function updateData(data) { export function delData(dictCode) { return request({ url: '/system/dict-data/delete?id=' + dictCode, - method: 'post' + method: 'delete' }) } diff --git a/ruoyi-ui/src/api/system/dict/type.js b/ruoyi-ui/src/api/system/dict/type.js index a1423f1d6..9fe10d418 100644 --- a/ruoyi-ui/src/api/system/dict/type.js +++ b/ruoyi-ui/src/api/system/dict/type.js @@ -30,7 +30,7 @@ export function addType(data) { export function updateType(data) { return request({ url: '/system/dict-type/update', - method: 'post', + method: 'put', data: data }) } @@ -39,7 +39,7 @@ export function updateType(data) { export function delType(dictId) { return request({ url: '/system/dict-type/delete?id=' + dictId, - method: 'post' + method: 'delete' }) } diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue index 262ea31bb..13d262303 100644 --- a/ruoyi-ui/src/views/system/dict/data.vue +++ b/ruoyi-ui/src/views/system/dict/data.vue @@ -3,31 +3,15 @@ - + - + - + @@ -38,22 +22,12 @@ - 新增 + 新增 - 导出 + 导出 @@ -72,31 +46,16 @@ - + @@ -115,11 +74,7 @@ - {{dict.label}} + {{dict.label}} diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue index 4f92859a0..a730e61bf 100644 --- a/ruoyi-ui/src/views/system/dict/index.vue +++ b/ruoyi-ui/src/views/system/dict/index.vue @@ -2,52 +2,19 @@
- + - + - - + + - + 搜索 @@ -57,22 +24,12 @@ - 新增 + 新增 - 导出 + 导出 @@ -96,31 +53,16 @@ - + @@ -133,11 +75,7 @@ - {{dict.label}} + {{dict.label}} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictDataController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictDataController.java index baeb68342..cca874d7e 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictDataController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictDataController.java @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dict; import cn.iocoder.dashboard.common.pojo.CommonResult; import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils; +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; import cn.iocoder.dashboard.modules.system.controller.dict.vo.data.*; import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert; import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO; @@ -10,84 +11,85 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; import java.io.IOException; import java.util.List; import static cn.iocoder.dashboard.common.pojo.CommonResult.success; +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT; @Api(tags = "字典数据") @RestController @RequestMapping("/system/dict-data") +@Validated public class SysDictDataController { @Resource private SysDictDataService dictDataService; - @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地") - @GetMapping("/list-all-simple") - // 无需添加权限认证,因为前端全局都需要 - public CommonResult> listSimpleDictDatas() { - List list = dictDataService.getDictDataList(); - return success(SysDictDataConvert.INSTANCE.convertList(list)); - } - - @ApiOperation("/获得字典类型的分页列表") - @GetMapping("/page") -// @PreAuthorize("@ss.hasPermi('system:dict:list')") - public CommonResult> pageDictTypes(@Validated SysDictDataPageReqVO reqVO) { - return success(SysDictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO))); - } - - @ApiOperation("/查询字典数据详细") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @GetMapping(value = "/get") -// @PreAuthorize("@ss.hasPermi('system:dict:query')") - public CommonResult getDictData(@RequestParam("id") Long id) { - return success(SysDictDataConvert.INSTANCE.convert(dictDataService.getDictData(id))); - } - - @ApiOperation("新增字典数据") @PostMapping("/create") -// @PreAuthorize("@ss.hasPermi('system:dict:add')") -// @Log(title = "字典数据", businessData = BusinessData.INSERT) - public CommonResult createDictData(@Validated @RequestBody SysDictDataCreateReqVO reqVO) { + @ApiOperation("新增字典数据") + @PreAuthorize("@ss.hasPermission('system:dict:create')") + public CommonResult createDictData(@Valid @RequestBody SysDictDataCreateReqVO reqVO) { Long dictDataId = dictDataService.createDictData(reqVO); return success(dictDataId); } + @PutMapping("update") @ApiOperation("修改字典数据") - @PostMapping("update") -// @PreAuthorize("@ss.hasPermi('system:dict:edit')") -// @Log(title = "字典数据", businessData = BusinessData.UPDATE) - public CommonResult updateDictData(@Validated @RequestBody SysDictDataUpdateReqVO reqVO) { + @PreAuthorize("@ss.hasPermission('system:dict:update')") + public CommonResult updateDictData(@Valid @RequestBody SysDictDataUpdateReqVO reqVO) { dictDataService.updateDictData(reqVO); return success(true); } + @DeleteMapping("/delete") @ApiOperation("删除字典数据") @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PostMapping("/delete") -// @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @PreAuthorize("@ss.hasPermission('system:dict:delete')") public CommonResult deleteDictData(Long id) { dictDataService.deleteDictData(id); return success(true); } - @ApiOperation("导出字典数据") + @GetMapping("/list-all-simple") + @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地") + // 无需添加权限认证,因为前端全局都需要 + public CommonResult> getSimpleDictDatas() { + List list = dictDataService.getDictDatas(); + return success(SysDictDataConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @ApiOperation("/获得字典类型的分页列表") + @PreAuthorize("@ss.hasPermission('system:dict:query')") + public CommonResult> getDictTypePage(@Valid SysDictDataPageReqVO reqVO) { + return success(SysDictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO))); + } + + @GetMapping(value = "/get") + @ApiOperation("/查询字典数据详细") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('system:dict:query')") + public CommonResult getDictData(@RequestParam("id") Long id) { + return success(SysDictDataConvert.INSTANCE.convert(dictDataService.getDictData(id))); + } + @GetMapping("/export") -// @Log(title = "字典类型", businessType = BusinessType.EXPORT) -// @PreAuthorize("@ss.hasPermi('system:dict:export')") - public void export(HttpServletResponse response, @Validated SysDictDataExportReqVO reqVO) throws IOException { - List list = dictDataService.getDictDataList(reqVO); - List excelDataList = SysDictDataConvert.INSTANCE.convertList02(list); + @ApiOperation("导出字典数据") + @PreAuthorize("@ss.hasPermission('system:dict:export')") + @OperateLog(type = EXPORT) + public void export(HttpServletResponse response, @Valid SysDictDataExportReqVO reqVO) throws IOException { + List list = dictDataService.getDictDatas(reqVO); + List data = SysDictDataConvert.INSTANCE.convertList02(list); // 输出 - ExcelUtils.write(response, "字典数据.xls", "数据列表", - SysDictDataExcelVO.class, excelDataList); + ExcelUtils.write(response, "字典数据.xls", "数据列表", SysDictDataExcelVO.class, data); } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictTypeController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictTypeController.java index d75059fbc..cc53d7c5b 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictTypeController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/dict/SysDictTypeController.java @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.dict; import cn.iocoder.dashboard.common.pojo.CommonResult; import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.framework.excel.core.util.ExcelUtils; +import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog; import cn.iocoder.dashboard.modules.system.controller.dict.vo.type.*; import cn.iocoder.dashboard.modules.system.convert.dict.SysDictTypeConvert; import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictTypeDO; @@ -10,67 +11,68 @@ import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; import java.io.IOException; import java.util.List; import static cn.iocoder.dashboard.common.pojo.CommonResult.success; +import static cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum.EXPORT; @Api(tags = "字典类型") @RestController @RequestMapping("/system/dict-type") +@Validated public class SysDictTypeController { @Resource private SysDictTypeService dictTypeService; + @PostMapping("/create") + @ApiOperation("创建字典类型") + @PreAuthorize("@ss.hasPermission('system:dict:create')") + public CommonResult createDictType(@Valid @RequestBody SysDictTypeCreateReqVO reqVO) { + Long dictTypeId = dictTypeService.createDictType(reqVO); + return success(dictTypeId); + } + + @PostMapping("update") + @ApiOperation("修改字典类型") + @PreAuthorize("@ss.hasPermission('system:dict:update')") + public CommonResult updateDictType(@Valid @RequestBody SysDictTypeUpdateReqVO reqVO) { + dictTypeService.updateDictType(reqVO); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除字典类型") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('system:dict:delete')") + public CommonResult deleteDictType(Long id) { + dictTypeService.deleteDictType(id); + return success(true); + } + @ApiOperation("/获得字典类型的分页列表") @GetMapping("/page") -// @PreAuthorize("@ss.hasPermi('system:dict:list')") - public CommonResult> pageDictTypes(@Validated SysDictTypePageReqVO reqVO) { + @PreAuthorize("@ss.hasPermission('system:dict:quey')") + public CommonResult> pageDictTypes(@Valid SysDictTypePageReqVO reqVO) { return success(SysDictTypeConvert.INSTANCE.convertPage(dictTypeService.getDictTypePage(reqVO))); } @ApiOperation("/查询字典类型详细") @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) @GetMapping(value = "/get") -// @PreAuthorize("@ss.hasPermi('system:dict:query')") + @PreAuthorize("@ss.hasPermission('system:dict:quey')") public CommonResult getDictType(@RequestParam("id") Long id) { return success(SysDictTypeConvert.INSTANCE.convert(dictTypeService.getDictType(id))); } - @ApiOperation("新增字典类型") - @PostMapping("/create") -// @PreAuthorize("@ss.hasPermi('system:dict:add')") -// @Log(title = "字典类型", businessType = BusinessType.INSERT) - public CommonResult createDictType(@Validated @RequestBody SysDictTypeCreateReqVO reqVO) { - Long dictTypeId = dictTypeService.createDictType(reqVO); - return success(dictTypeId); - } - - @ApiOperation("修改字典类型") - @PostMapping("update") -// @PreAuthorize("@ss.hasPermi('system:dict:edit')") -// @Log(title = "字典类型", businessType = BusinessType.UPDATE) - public CommonResult updateDictType(@Validated @RequestBody SysDictTypeUpdateReqVO reqVO) { - dictTypeService.updateDictType(reqVO); - return success(true); - } - - @ApiOperation("删除字典类型") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PostMapping("/delete") -// @PreAuthorize("@ss.hasPermi('system:dict:remove')") - public CommonResult deleteDictType(Long id) { - dictTypeService.deleteDictType(id); - return success(true); - } - - @GetMapping("/list-all-simple") @ApiOperation(value = "获得全部字典类型列表", notes = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项") // 无需添加权限认证,因为前端全局都需要 @@ -81,14 +83,13 @@ public class SysDictTypeController { @ApiOperation("导出数据类型") @GetMapping("/export") -// @Log(title = "字典类型", businessType = BusinessType.EXPORT) -// @PreAuthorize("@ss.hasPermi('system:dict:export')") - public void export(HttpServletResponse response, @Validated SysDictTypeExportReqVO reqVO) throws IOException { + @PreAuthorize("@ss.hasPermission('system:dict:quey')") + @OperateLog(type = EXPORT) + public void export(HttpServletResponse response, @Valid SysDictTypeExportReqVO reqVO) throws IOException { List list = dictTypeService.getDictTypeList(reqVO); - List excelTypeList = SysDictTypeConvert.INSTANCE.convertList02(list); + List data = SysDictTypeConvert.INSTANCE.convertList02(list); // 输出 - ExcelUtils.write(response, "字典类型.xls", "类型列表", - SysDictTypeExcelVO.class, excelTypeList); + ExcelUtils.write(response, "字典类型.xls", "类型列表", SysDictTypeExcelVO.class, data); } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataService.java index 3969e420f..ffbd66d19 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataService.java @@ -22,37 +22,6 @@ public interface SysDictDataService extends DictDataFrameworkService { */ void initLocalCache(); - /** - * 获得字典数据列表 - * - * @return 字典数据全列表 - */ - List getDictDataList(); - - /** - * 获得字典数据分页列表 - * - * @param reqVO 分页请求 - * @return 字典数据分页列表 - */ - PageResult getDictDataPage(SysDictDataPageReqVO reqVO); - - /** - * 获得字典数据列表 - * - * @param reqVO 列表请求 - * @return 字典数据列表 - */ - List getDictDataList(SysDictDataExportReqVO reqVO); - - /** - * 获得字典数据详情 - * - * @param id 字典数据编号 - * @return 字典数据 - */ - SysDictDataDO getDictData(Long id); - /** * 创建字典数据 * @@ -75,6 +44,37 @@ public interface SysDictDataService extends DictDataFrameworkService { */ void deleteDictData(Long id); + /** + * 获得字典数据列表 + * + * @return 字典数据全列表 + */ + List getDictDatas(); + + /** + * 获得字典数据分页列表 + * + * @param reqVO 分页请求 + * @return 字典数据分页列表 + */ + PageResult getDictDataPage(SysDictDataPageReqVO reqVO); + + /** + * 获得字典数据列表 + * + * @param reqVO 列表请求 + * @return 字典数据列表 + */ + List getDictDatas(SysDictDataExportReqVO reqVO); + + /** + * 获得字典数据详情 + * + * @param id 字典数据编号 + * @return 字典数据 + */ + SysDictDataDO getDictData(Long id); + /** * 获得指定字典类型的数据数量 * diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeService.java index 14fe9f7cd..1d2fbe945 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictTypeService.java @@ -16,6 +16,28 @@ import java.util.List; */ public interface SysDictTypeService { + /** + * 创建字典类型 + * + * @param reqVO 字典类型信息 + * @return 字典类型编号 + */ + Long createDictType(SysDictTypeCreateReqVO reqVO); + + /** + * 更新字典类型 + * + * @param reqVO 字典类型信息 + */ + void updateDictType(SysDictTypeUpdateReqVO reqVO); + + /** + * 删除字典类型 + * + * @param id 字典类型编号 + */ + void deleteDictType(Long id); + /** * 获得字典类型分页列表 * @@ -48,28 +70,6 @@ public interface SysDictTypeService { */ SysDictTypeDO getDictType(String type); - /** - * 创建字典类型 - * - * @param reqVO 字典类型信息 - * @return 字典类型编号 - */ - Long createDictType(SysDictTypeCreateReqVO reqVO); - - /** - * 更新字典类型 - * - * @param reqVO 字典类型信息 - */ - void updateDictType(SysDictTypeUpdateReqVO reqVO); - - /** - * 删除字典类型 - * - * @param id 字典类型编号 - */ - void deleteDictType(Long id); - /** * 获得全部字典类型列表 * diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java index 603a9933e..7f24cbff4 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java @@ -131,7 +131,7 @@ public class SysDictDataServiceImpl implements SysDictDataService { } @Override - public List getDictDataList() { + public List getDictDatas() { List list = dictDataMapper.selectList(); list.sort(COMPARATOR_TYPE_AND_SORT); return list; @@ -143,7 +143,7 @@ public class SysDictDataServiceImpl implements SysDictDataService { } @Override - public List getDictDataList(SysDictDataExportReqVO reqVO) { + public List getDictDatas(SysDictDataExportReqVO reqVO) { List list = dictDataMapper.selectList(reqVO); list.sort(COMPARATOR_TYPE_AND_SORT); return list; diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java index 79c89518d..2874285e4 100644 --- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dict/SysDictDataServiceTest.java @@ -133,7 +133,7 @@ public class SysDictDataServiceTest extends BaseDbUnitTest { reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 - List list = dictDataService.getDictDataList(reqVO); + List list = dictDataService.getDictDatas(reqVO); // 断言 assertEquals(1, list.size()); assertPojoEquals(dbDictData, list.get(0)); From 378f5834ccc94e1fef23bc0d5d2e7d0b58c61dc5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 14 Mar 2021 21:54:23 +0800 Subject: [PATCH 12/27] =?UTF-8?q?=E6=95=B4=E7=90=86=20logger=E3=80=81notic?= =?UTF-8?q?e=20=E7=9A=84=20url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-ui/src/views/system/loginlog/index.vue | 72 ++++------------- ruoyi-ui/src/views/system/notice/index.vue | 81 +++---------------- .../src/views/system/operatelog/index.vue | 77 ++++-------------- .../jackson/config/JacksonConfig.java | 6 +- .../logger/SysLoginLogController.java | 25 +++--- .../logger/SysOperateLogController.java | 34 +++----- .../notice/SysNoticeController.java | 52 ++++++------ .../service/notice/SysNoticeService.java | 33 ++++---- .../notice/impl/SysNoticeServiceImpl.java | 20 ++--- 9 files changed, 121 insertions(+), 279 deletions(-) diff --git a/ruoyi-ui/src/views/system/loginlog/index.vue b/ruoyi-ui/src/views/system/loginlog/index.vue index 601c9420f..5e572aa94 100644 --- a/ruoyi-ui/src/views/system/loginlog/index.vue +++ b/ruoyi-ui/src/views/system/loginlog/index.vue @@ -2,56 +2,22 @@
- + - + - - - + + + - + 搜索 @@ -61,13 +27,8 @@ - 导出 + 导出 @@ -76,7 +37,7 @@ @@ -95,13 +56,8 @@ - +
diff --git a/ruoyi-ui/src/views/system/notice/index.vue b/ruoyi-ui/src/views/system/notice/index.vue index bc46b0d1b..30f17bcf2 100644 --- a/ruoyi-ui/src/views/system/notice/index.vue +++ b/ruoyi-ui/src/views/system/notice/index.vue @@ -2,31 +2,14 @@
- + - + - + @@ -37,39 +20,16 @@ - 新增 + 新增 - - - + + +