如何发送邮箱、手机短信以及设置

1.邮件发送

1.1 邮件服务设置

1.1.1 方法一:通过yaml文件配置

pamirs:
  email:
    smtp:
      smtpHost: smtp.exmail.qq.com
      smtpUser: xxx@xxx.com
      smtpPassword: xxxxxx
      smtpPort: 465
      smtpSecurity: SSL
      #邮件模块可后续后台自行添加
      templates:
        - name: 邮箱注册邮件
          title: '${code}是你此次注册的验证码'
          body: '<div>Hi ${realname},</div><div>你正在使用验证码注册。</div>'

1.1.2 方法二:工程启动加入初始化设置方法

/**
     * 初始化邮件模板
     */
    private void initEmailTemplate(){
        EmailSenderSource emailSenderSource = new EmailSenderSource();
        emailSenderSource.setName("邮件发送服务");
        emailSenderSource.setType(MessageEngineTypeEnum.EMAIL_SEND);
        //优先级
        emailSenderSource.setSequence(10);
        //发送账号
        emailSenderSource.setSmtpUser("xxx@xxx.com");
        //发送密码
        emailSenderSource.setSmtpPassword("xxxxxx");
        //发送服务器地址和端口
        emailSenderSource.setSmtpHost("smtp.exmail.qq.com");
        emailSenderSource.setSmtpPort(465);
        //" None: SMTP 对话用明文完成。" +
        //" TLS (STARTTLS): SMTP对话的开始时要求TLS 加密 (建议)" +
        //" SSL/TLS: SMTP对话通过专用端口用 SSL/TLS 加密 (默认是: 465)")
        emailSenderSource.setSmtpSecurity(EmailSendSecurityEnum.SSL);
        emailSenderSource.setActive(true);
        emailSenderSource.createOrUpdate();

        List<EmailTemplate> templates = new ArrayList<>();
        templates.add(new EmailTemplate().setName("重置密码邮件模板").setTitle("请确认你的密码修改请求").setBody("<div>Hi ${realname},</div><div>你正在使用验证码注册。</div>").setModel(PamirsUser.MODEL_MODEL).setEmailSenderSource(emailSenderSource));
        new EmailTemplate().createOrUpdateBatch(templates);
    }

1.2 调用邮件发送组件发送邮件

/**
     * 代码中使用消息组件发送Email
     */
    public void sendEmailByTemplate(){
        try {
            EmailSender emailSender = (EmailSender) MessageEngine.get(MessageEngineTypeEnum.EMAIL_SEND).get(null);;
            EmailTemplate template = new EmailTemplate().setName("邮件模版名称").queryOne();
            //标题:${name}
            //内容:${fieldInt}次数
            String sendTo = "xxx@xxx.com";
            String copyTo = "yyy@yyy.com";

            Map<String, Object> objectData = new HashMap<>();
            objectData.put("name","张三");
            objectData.put("fieldInt",999);
            Boolean aBoolean = emailSender.send(template, objectData, sendTo, copyTo);
            if (null == aBoolean || !aBoolean) {
                log.error("发送邮件失败");
            }
        } catch (Exception e) {
            log.error("发送确认邮件失败:,异常:{}", e);
        }
    }

2.发送短信

2.1 短信通道设置

2.1.1 方法一:通过yaml文件配置

pamirs:
  sms:
    aliyun:
      signatureMethod: HMAC-SHA1
      endpoint: https://dysmsapi.aliyuncs.com
      version: '2017-05-25'
      accessKeyId: xxxxxxxxxxxxx
      signatureVersion: '1.0'
      accessKeySecret: xxxxxxxxxxxx
      regionId: cn-hangzhou
      timeZone: GMT
      signName: xxxxxx

2.1.2 方法二:工程启动加入初始化设置方法

private void initSmsConfig() {
        SmsChannelConfig smsChannelConfig = new SmsChannelConfig();
        SmsChannelConfig smsChannelConfigs = smsChannelConfig.setChannel(SMSChannelEnum.ALIYUN)
                .setAccessKeyId("xxxxxx")
                .setSignName("xxxxxx")
                .queryOne();
        if (null == smsChannelConfigs) {
            smsChannelConfig.setChannel(SMSChannelEnum.ALIYUN);
            smsChannelConfig.setType(MessageEngineTypeEnum.SMS_SEND);
            smsChannelConfig.setSignatureMethod("HMAC-SHA1");
            smsChannelConfig.setEndpoint("https://dysmsapi.aliyuncs.com");
            smsChannelConfig.setVersion("2017-05-25");
            smsChannelConfig.setAccessKeyId("xxxxxx");
            smsChannelConfig.setAccessKeySecret("xxxxxx");
            smsChannelConfig.setSignatureVersion("1.0");
            smsChannelConfig.setRegionId("cn-hangzhou");
            smsChannelConfig.setTimeZone("GMT");
            smsChannelConfig.setSignName("xxxxxx");
            smsChannelConfig.setActive(Boolean.TRUE);
            smsChannelConfig.create();
        } else {
            smsChannelConfigs.updateById();
        }

        //初始化短信模版,需要先到阿里云申请短信模版
        SmsTemplate smsTemplate = new SmsTemplate();
        smsTemplate.setChannel(SMSChannelEnum.ALIYUN);
        smsTemplate.setTemplateType(SMSTemplateTypeEnum.SIGN_IN);
        smsTemplate.setTemplateCode("SMS_252710149");//阿里云短信模版的Code
        smsTemplate.setTemplateContent("验证码: ${code},您正在登录。10分钟内有效,请注意保密,请勿向他人泄露您的验证码。");//阿里云短信模版

        List<SmsTemplate> smsTemplates = new ArrayList<>();
        smsTemplates.add(smsTemplate);
        new SmsTemplate().createOrUpdateBatch(smsTemplates);
    }

2.2 调用邮件发送组件发送邮件

public void sendSms(){
        try {

            List<String> receivePhoneNumbers = new ArrayList<>();
            receivePhoneNumbers.add("13800000000");
            // 占位符处理
            Map<String, String> vars = new HashMap<>();
            vars.put("code", "123456");

            SmsTemplate smsTemplate = new SmsTemplate().setChannel(SMSChannelEnum.ALIYUN);
            smsTemplate.setTemplateType(SMSTemplateTypeEnum.SIGN_IN);
            smsTemplate.setTemplateCode("SMS_252710149").queryOne();
            SMSSender smsSender = (SMSSender) MessageEngine.get(MessageEngineTypeEnum.SMS_SEND).get(null);
            receivePhoneNumbers.stream().distinct().forEach(it -> {
                try {
                    if (!smsSender.smsSend(smsTemplate, it, vars)) {
                        //todo 错误处理
                    }
                } catch (Exception e) {
                    //todo 错误处理
                }
            });
        } catch (Exception e) {
            //todo 错误处理
        }
    }

Oinone社区 作者:数式-海波原创文章,如若转载,请注明出处:https://doc.oinone.top/backend/4346.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
数式-海波的头像数式-海波数式管理员
上一篇 2023年11月6日 pm4:48
下一篇 2023年11月7日 am11:35

相关推荐

  • 重写QueryPage时,增加额外的条件

    在需要对QueryPage增加额外的查询条件,比如DemoItem增加只展示创建人为当前用户的数据 @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表") @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API}) public Pagination<DemoItem> queryPage(Pagination<DemoItem> page, IWrapper<DemoItem> queryWrapper) { LambdaQueryWrapper<DemoItem> qw = ((QueryWrapper<DemoItem>) queryWrapper).lambda(); qw.eq(DemoItem::getCreateUid, PamirsSession.getUserId()); return demoItemService.queryPage(page, qw); }

    2023年11月1日
    87200
  • 自定义数据权限拦截处理

    业务场景 公司给员工对哪些模块有访问权限,这个时候就需要在员工访问模块表的时候做数据过滤, 解决方案 我们可以通过平台提供的数据过滤占位符解决这个问题,新建一条数据行权限,过滤语句条件是占位符,再编写占位符的解析逻辑 1.初始化权限基础数据 package pro.shushi.pamirs.demo.core.init; import com.google.common.collect.Lists; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import pro.shushi.pamirs.auth.api.constants.AuthConstants; import pro.shushi.pamirs.auth.api.enmu.AuthGroupTypeEnum; import pro.shushi.pamirs.auth.api.enmu.PermissionDataSourceEnum; import pro.shushi.pamirs.auth.api.enmu.PermissionTypeEnum; import pro.shushi.pamirs.auth.api.model.AuthGroup; import pro.shushi.pamirs.auth.api.model.AuthRole; import pro.shushi.pamirs.auth.api.model.ResourcePermission; import pro.shushi.pamirs.boot.base.model.UeModule; import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCommand; import pro.shushi.pamirs.boot.common.api.init.InstallDataInit; import pro.shushi.pamirs.boot.common.api.init.UpgradeDataInit; import pro.shushi.pamirs.demo.api.DemoModule; import pro.shushi.pamirs.demo.core.placeholder.EmployeeModulePlaceholder; import pro.shushi.pamirs.framework.common.utils.ObjectUtils; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.domain.module.ModuleDefinition; import java.util.Collections; import java.util.List; @Slf4j @Component @Order(0) public class DemoModuleBizInit implements InstallDataInit, UpgradeDataInit { @Override public List<String> modules() { return Collections.singletonList(DemoModule.MODULE_MODULE); } @Override public int priority() { return 0; } @Override public boolean init(AppLifecycleCommand command, String version) { this.initAuth(); return true; } @Override public boolean upgrade(AppLifecycleCommand command, String version, String existVersion) { this.initAuth(); return true; } private void initAuth() { AuthGroup authGroup = new AuthGroup(); authGroup.setName("测试权限组") .setDisplayName("测试权限组") .setType(AuthGroupTypeEnum.RUNTIME) .setActive(true); authGroup.createOrUpdate(); AuthRole authRole = new AuthRole(); authRole.setCode("TEST_ROLE_1") .setName("测试角色") .setRoleTypeCode(AuthConstants.ROLE_SYSTEM_TYPE_CODE) .setPermissionDataSource(PermissionDataSourceEnum.CUSTOM) .setActive(true); authRole.createOrUpdate(); authRole.setGroups(Lists.newArrayList(authGroup)); authRole.fieldSave(AuthRole::getGroups); ResourcePermission authPermission = new ResourcePermission(); authPermission.setName("测试模块权限过滤") .setDomainExp(EmployeeModulePlaceholder.PLACEHOLDER) .setModel(ModuleDefinition.MODEL_MODEL) .setPermRead(true) .setPermRun(true) .setPermissionType(PermissionTypeEnum.ROW) .setPermissionDataSource(PermissionDataSourceEnum.CUSTOM) .setCanShow(true) .setActive(true); ResourcePermission authPermission2 = ObjectUtils.clone(authPermission); authPermission2.setName("测试ue模块权限过滤").setModel(UeModule.MODEL_MODEL); authGroup.setPermissions(Lists.newArrayList(authPermission, authPermission2)); authGroup.fieldSave(AuthGroup::getPermissions); } } 这里演示的module表比较特殊,需要同时设置ModuleDefinition和UeModule这2个模型做数据过滤 2.编写占位符拦截替换逻辑 package pro.shushi.pamirs.demo.core.placeholder; import org.springframework.stereotype.Component; import pro.shushi.pamirs.user.api.AbstractPlaceHolderParser; @Component public class EmployeeModulePlaceholder extends AbstractPlaceHolderParser { public static final String PLACEHOLDER = "${employeeModulePlaceholder}"; protected String value() { // TODO…

    2023年11月24日
    1.1K00
  • 引入搜索(增强模型Channel)常见问题解决办法

    总体描述 引入Oinone的搜索(即Channel模块)后,因错误的配置、缺少配置或者少引入一些Jar包,会出现一些报错。 问题1:启动报类JCTree找不到 具体现象 启动过程可能会出现报错:java.lang.NoClassDefFoundError: com/sun/tools/javac/tree/JCTree$JCExpression 产生原因 引入Channel模块后,启动过程中会扫描Class包找寻Enhance的注解,Pamirs底层有使用到jdk的tools中的类, com/sun/tools/javac/tree/JCTree$JCExpression 特定版本的jdk可能会缺少tools.jar导致启动失败 具体报错 at org.springframework.boot.loader.Launcher.launch(Launcher.java:107) [pamirs-venus-boot.jar:na] at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [pamirs-venus-boot.jar:na] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) [pamirs-venus-boot.jar:na] Caused by: java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: com/sun/tools/javac/tree/JCTree$JCExpression at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357) ~[na:1.8.0_381] at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908) ~[na:1.8.0_381] at pro.shushi.pamirs.boot.common.initial.PamirsBootMainInitial.init(PamirsBootMainInitial.java:66) ~[pamirs-boot-api-4.6.10.jar!/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_381] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_381] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_381] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_381] at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:305) ~[spring-context-5.2.12.RELEASE.jar!/:5.2.12.RELEASE] … 20 common frames omitted Caused by: java.lang.NoClassDefFoundError: com/sun/tools/javac/tree/JCTree$JCExpression at java.lang.Class.forName0(Native Method) ~[na:1.8.0_381] at java.lang.Class.forName(Class.java:264) ~[na:1.8.0_381] at pro.shushi.pamirs.meta.util.ClassUtils.getClasses(ClassUtils.java:157) ~[pamirs-meta-model-4.6.8.jar!/:na] at pro.shushi.pamirs.meta.util.ClassUtils.getClassesByPacks(ClassUtils.java:73) ~[pamirs-meta-model-4.6.8.jar!/:na] at pro.shushi.pamirs.channel.core.manager.EnhanceModelScanner.enhanceModel(EnhanceModelScanner.java:51) ~[pamirs-channel-core-4.6.15.jar!/:na] at pro.shushi.pamirs.channel.core.init.ChannelSystemBootAfterInit.init(ChannelSystemBootAfterInit.java:31) 解决办法 方式一【推荐】、配置channel的扫描路径 pamirs: channel: packages: – com.pamirs.ic 方式二、使用Oracle版本的jdk,确保jdk的lib目录,tools.jar有com/sun/tools/javac/tree/JCTree对应的类 问题2:启动报类JsonProvider找不到 具体报错 如果启动报错信息如下: Caused by: java.lang.NoClassDefFoundError: jakarta/json/spi/JsonProvider at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_181] at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_181] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_181] at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_181] 产生原因 项目中只引入了pamirs-channel-core,但未引入elasticsearch相关的包 解决办法 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>8.4.1</version> </dependency> <dependency> <groupId>jakarta.json</groupId> <artifactId>jakarta.json-api</artifactId> <version>2.1.1</version> </dependency> 其他参考: Oinone引入搜索引擎步骤:https://doc.oinone.top/backend/7235.html

    2024年5月17日
    1.3K00
  • 工作流-流程代办等页面自定义

    1. 审批/填写节点的视图页面 在界面设计器中创建对应模型的表单视图,可根据业务场景需要自定义所需流程待办的审批页面 2. 在审批/填写节点中选择刚创建的视图 在工作流待办数据权限可在节点数据权限中可对字段设置查看、编辑、隐藏

    2024年5月14日
    1.6K00
  • 框架之MessageHub(信息提示)

    框架之信息概述 后端除了可以返回错误信息以外,还可以返回调试、告警、成功、信息等级别的信息给前端。但是默认情况下前端只提示错误信息,可以通过前端的统一配置放开提示级别,有点类似后端的日志级别。 框架之MessageHub 在oinone平台中,我们怎么做到友好的错误提示呢?接下来介绍我们的MessageHub,它为自定义错误提示提供无限的可能。 何时使用 错误提示是用户体验中特别重要的组成部分,大部分的错误体现在整页级别,字段级别,按钮级别。友好的错误提示应该是怎么样的呢?我们假设他是这样的 与用户操作精密契合 当字段输入异常时,错误展示在错误框底部 按钮触发服务时异常,错误展示在按钮底部 区分不同的类型 错误 成功 警告 提示 调试 简洁易懂的错误信息 不同信息类型的举例 package pro.shushi.pamirs.demo.core.action; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.model.PetCatItem; import pro.shushi.pamirs.demo.api.model.PetType; import pro.shushi.pamirs.meta.annotation.Action; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.dto.common.Message; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.enmu.ActionContextTypeEnum; import pro.shushi.pamirs.meta.enmu.InformationLevelEnum; import pro.shushi.pamirs.meta.enmu.ViewTypeEnum; @Model.model(PetType.MODEL_MODEL) @Component public class PetTypeAction { @Action(displayName = "消息",bindingType = ViewTypeEnum.TABLE,contextType = ActionContextTypeEnum.CONTEXT_FREE) public PetType message(PetType data){ PamirsSession.getMessageHub().info("info1"); PamirsSession.getMessageHub().info("info2"); PamirsSession.getMessageHub().error("error1"); PamirsSession.getMessageHub().error("error2"); PamirsSession.getMessageHub().msg(new Message().msg("success1").setLevel(InformationLevelEnum.SUCCESS)); PamirsSession.getMessageHub().msg(new Message().msg("success2").setLevel(InformationLevelEnum.SUCCESS)); PamirsSession.getMessageHub().msg(new Message().msg("debug1").setLevel(InformationLevelEnum.DEBUG)); PamirsSession.getMessageHub().msg(new Message().msg("debug2").setLevel(InformationLevelEnum.DEBUG)); PamirsSession.getMessageHub().msg(new Message().msg("warn1").setLevel(InformationLevelEnum.WARN)); PamirsSession.getMessageHub().msg(new Message().msg("warn2").setLevel(InformationLevelEnum.WARN)); return data; } } 查询运行返回和效果 1)系统提示的返回结果 2)系统提示示例效果

    2024年5月14日
    1.4K00

Leave a Reply

登录后才能评论