From c0b029b2447e381436b83a35a2dcdbac680baf62 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 26 Jan 2023 23:32:18 +0800 Subject: [PATCH] =?UTF-8?q?=E9=82=AE=E7=AE=B1=E6=A8=A1=E5=9D=97=EF=BC=9A?= =?UTF-8?q?=E5=AE=8C=E5=96=84=20template=20=E7=9A=84=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/date/LocalDateTimeUtils.java | 5 + .../service/mail/MailTemplateServiceImpl.java | 2 + .../mail/MailTemplateServiceImplTest.java | 163 ++++++++++++++++++ .../src/test/resources/sql/clean.sql | 1 + .../src/test/resources/sql/create_tables.sql | 45 +++-- .../src/api/system/mail/template.js | 9 + .../src/api/system/sms/smsTemplate.js | 2 +- .../src/views/system/mail/template/index.vue | 93 +++++++++- .../src/views/system/sms/smsTemplate.vue | 2 +- 9 files changed, 300 insertions(+), 22 deletions(-) create mode 100755 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index a29d5fb2e..62e0e4441 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -41,6 +41,11 @@ public class LocalDateTimeUtils { return LocalDateTime.of(year, mouth, day, 0, 0, 0); } + public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, + int year2, int mouth2, int day2) { + return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; + } + /** * 判断当前时间是否在该时间范围内 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImpl.java index c3e72f444..62baa7e83 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; import cn.iocoder.yudao.module.system.dal.mysql.mail.MailTemplateMapper; import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; import com.google.common.annotations.VisibleForTesting; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -55,6 +56,7 @@ public class MailTemplateServiceImpl implements MailTemplateService { * * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 */ + @Getter private volatile Map mailTemplateCache; @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java new file mode 100755 index 000000000..ab005822b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java @@ -0,0 +1,163 @@ +package cn.iocoder.yudao.module.system.service.mail; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateCreateReqVO; +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; +import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; +import cn.iocoder.yudao.module.system.dal.mysql.mail.MailTemplateMapper; +import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link MailTemplateServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(MailTemplateServiceImpl.class) +public class MailTemplateServiceImplTest extends BaseDbUnitTest { + + @Resource + private MailTemplateServiceImpl mailTemplateService; + + @Resource + private MailTemplateMapper mailTemplateMapper; + + @MockBean + private MailProducer mailProducer; + + @Test + public void testInitLocalCache() { + MailTemplateDO templateDO01 = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(templateDO01); + MailTemplateDO templateDO02 = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(templateDO02); + + // 调用 + mailTemplateService.initLocalCache(); + // 断言 mailTemplateCache 缓存 + Map mailTemplateCache = mailTemplateService.getMailTemplateCache(); + assertPojoEquals(templateDO01, mailTemplateCache.get(templateDO01.getCode())); + assertPojoEquals(templateDO02, mailTemplateCache.get(templateDO02.getCode())); + } + + @Test + public void testCreateMailTemplate_success() { + // 准备参数 + MailTemplateCreateReqVO reqVO = randomPojo(MailTemplateCreateReqVO.class); + + // 调用 + Long mailTemplateId = mailTemplateService.createMailTemplate(reqVO); + // 断言 + assertNotNull(mailTemplateId); + // 校验记录的属性是否正确 + MailTemplateDO mailTemplate = mailTemplateMapper.selectById(mailTemplateId); + assertPojoEquals(reqVO, mailTemplate); + } + + @Test + public void testUpdateMailTemplate_success() { + // mock 数据 + MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate);// @Sql: 先插入出一条存在的数据 + // 准备参数 + MailTemplateUpdateReqVO reqVO = randomPojo(MailTemplateUpdateReqVO.class, o -> { + o.setId(dbMailTemplate.getId()); // 设置更新的 ID + }); + + // 调用 + mailTemplateService.updateMailTemplate(reqVO); + // 校验是否更新正确 + MailTemplateDO mailTemplate = mailTemplateMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, mailTemplate); + } + + @Test + public void testUpdateMailTemplate_notExists() { + // 准备参数 + MailTemplateUpdateReqVO reqVO = randomPojo(MailTemplateUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> mailTemplateService.updateMailTemplate(reqVO), MAIL_TEMPLATE_NOT_EXISTS); + } + + @Test + public void testDeleteMailTemplate_success() { + // mock 数据 + MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbMailTemplate.getId(); + + // 调用 + mailTemplateService.deleteMailTemplate(id); + // 校验数据不存在了 + assertNull(mailTemplateMapper.selectById(id)); + } + + @Test + public void testDeleteMailTemplate_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> mailTemplateService.deleteMailTemplate(id), MAIL_TEMPLATE_NOT_EXISTS); + } + + @Test + public void testGetMailTemplatePage() { + // mock 数据 + MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class, o -> { // 等会查询到 + o.setName("源码"); + o.setCode("test_01"); + o.setAccountId(1L); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setCreateTime(buildTime(2023, 2, 3)); + }); + mailTemplateMapper.insert(dbMailTemplate); + // 测试 name 不匹配 + mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setName("芋道"))); + // 测试 code 不匹配 + mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setCode("test_02"))); + // 测试 accountId 不匹配 + mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setAccountId(2L))); + // 测试 status 不匹配 + mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 createTime 不匹配 + mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setCreateTime(buildTime(2023, 1, 5)))); + // 准备参数 + MailTemplatePageReqVO reqVO = new MailTemplatePageReqVO(); + reqVO.setName("源"); + reqVO.setCode("est_01"); + reqVO.setAccountId(1L); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 5)); + + // 调用 + PageResult pageResult = mailTemplateService.getMailTemplatePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbMailTemplate, pageResult.getList().get(0)); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql index b4181d16c..e3c2d2fdd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql @@ -26,3 +26,4 @@ DELETE FROM "system_oauth2_access_token"; DELETE FROM "system_oauth2_refresh_token"; DELETE FROM "system_oauth2_code"; DELETE FROM "system_mail_account"; +DELETE FROM "system_mail_template"; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql index 0ce2f0c2a..230f778dd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql @@ -568,17 +568,36 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_code" ( ) COMMENT 'OAuth2 刷新令牌'; CREATE TABLE IF NOT EXISTS "system_mail_account" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "mail" varchar NOT NULL, - "username" varchar NOT NULL, - "password" varchar NOT NULL, - "host" varchar NOT NULL, - "port" int NOT NULL, - "ssl_enable" bit NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "mail" varchar NOT NULL, + "username" varchar NOT NULL, + "password" varchar NOT NULL, + "host" varchar NOT NULL, + "port" int NOT NULL, + "ssl_enable" bit NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") ) COMMENT '邮箱账号表'; + +CREATE TABLE IF NOT EXISTS "system_mail_template" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar NOT NULL, + "code" varchar NOT NULL, + "account_id" bigint NOT NULL, + "nickname" varchar, + "title" varchar NOT NULL, + "content" varchar NOT NULL, + "params" varchar NOT NULL, + "status" varchar NOT NULL, + "remark" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '邮件模版表'; diff --git a/yudao-ui-admin/src/api/system/mail/template.js b/yudao-ui-admin/src/api/system/mail/template.js index ee5d8d454..4d6f12c48 100755 --- a/yudao-ui-admin/src/api/system/mail/template.js +++ b/yudao-ui-admin/src/api/system/mail/template.js @@ -42,3 +42,12 @@ export function getMailTemplatePage(query) { params: query }) } + +// 发送测试邮件 +export function sendMail(data) { + return request({ + url: '/system/mail-template/send-mail', + method: 'post', + data: data + }) +} diff --git a/yudao-ui-admin/src/api/system/sms/smsTemplate.js b/yudao-ui-admin/src/api/system/sms/smsTemplate.js index d6d933044..853784cd1 100644 --- a/yudao-ui-admin/src/api/system/sms/smsTemplate.js +++ b/yudao-ui-admin/src/api/system/sms/smsTemplate.js @@ -43,7 +43,7 @@ export function getSmsTemplatePage(query) { }) } -// 创建短信模板 +// 发送测试短信 export function sendSms(data) { return request({ url: '/system/sms-template/send-sms', diff --git a/yudao-ui-admin/src/views/system/mail/template/index.vue b/yudao-ui-admin/src/views/system/mail/template/index.vue index 10d71a9bd..a8825144e 100755 --- a/yudao-ui-admin/src/views/system/mail/template/index.vue +++ b/yudao-ui-admin/src/views/system/mail/template/index.vue @@ -44,6 +44,7 @@ + - - + diff --git a/yudao-ui-admin/src/views/system/sms/smsTemplate.vue b/yudao-ui-admin/src/views/system/sms/smsTemplate.vue index bf3e054a2..07fbd4beb 100644 --- a/yudao-ui-admin/src/views/system/sms/smsTemplate.vue +++ b/yudao-ui-admin/src/views/system/sms/smsTemplate.vue @@ -216,7 +216,7 @@ export default { }, sendSmsRules: { mobile: [{ required: true, message: "手机不能为空", trigger: "blur" }], - templateCode: [{ required: true, message: "手机不能为空", trigger: "blur" }], + templateCode: [{ required: true, message: "模版编码不能为空", trigger: "blur" }], templateParams: { } } };