RuoYi框架二次开发系列(三)第三方功能集成实战(OSS、短信、登录、支付)生产级方案
在前两篇文章中我们搞定了RuoYi基础开发规范、CRUD高效开发、核心数据权限体系解决了框架基础开发、数据安全两大核心问题。但企业级后台系统想要落地商用必须依赖各类第三方服务文件存储、短信验证、快捷登录、在线支付等。RuoYi原生预留了完善的拓展接口支持无缝集成第三方服务无需改动框架源码。本文作为系列第三篇聚焦生产级可落地的四大高频第三方功能包含阿里云OSS文件上传、短信验证码登录、微信/QQ快捷登录、在线支付对接全程提供完整代码、配置步骤、坑点排查复制即可上线。一、集成前置通用规范统一开发标准所有第三方集成严格遵循RuoYi二次开发核心原则不修改源码、配置化接入、模块化隔离、统一异常处理统一规范如下所有第三方配置统一放入 application.yml通过自定义配置类读取硬编码归零第三方工具类、请求常量、枚举统一存放至 com.ruoyi.common.third 自定义模块所有第三方请求添加日志打印、超时重试、异常捕获避免服务雪崩集成功能独立封装按需启用不影响框架原生功能二、阿里云OSS对象存储集成替代本地文件上传RuoYi原生默认本地存储文件生产环境存在服务器磁盘爆满、文件丢失、无法分布式部署等问题企业项目统一使用OSS对象存储实现文件云端存储、CDN加速访问。2.1 引入依赖在项目 pom.xml 中引入阿里云OSS官方依赖无版本冲突适配所有RuoYi版本!-- 阿里云OSS对象存储 --dependencygroupIdcom.aliyun.oss/groupIdartifactIdaliyun-sdk-oss/artifactIdversion3.15.1/version/dependency2.2 自定义yml配置在 application.yml 末尾添加OSS配置将密钥、节点、桶名称全部配置化# 阿里云OSS配置oss: endpoint: oss-cn-hangzhou.aliyuncs.com access-key-id: 你的AccessKeyId access-key-secret: 你的AccessKeySecret bucket-name: 你的Bucket名称 domain: https://xxx.oss-cn-hangzhou.aliyuncs.com# 访问域名2.3 配置类绑定参数创建OSS配置类读取yml配置交由Spring容器管理Component ConfigurationProperties(prefixoss)public class OssConfig{private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;private String domain;// get、set方法省略}2.4 核心工具类封装上传、删除、获取链接封装通用OSS工具类支持文件上传、单文件删除、批量删除、获取外网访问地址全局可复用Component public class OssUtil{Autowired private OssConfig ossConfig;/** * 文件上传OSS */ public String upload(MultipartFilefile){// 生成唯一文件名避免重名覆盖 String originalFilenamefile.getOriginalFilename();String suffixoriginalFilename.substring(originalFilename.lastIndexOf(.));String fileNameUUID.randomUUID().toString(true) suffix;// 创建OSS客户端 OSS ossClientnew OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());try{// 上传文件流 ossClient.putObject(ossConfig.getBucketName(), fileName, file.getInputStream());// 返回完整访问路径returnossConfig.getDomain()/ fileName;}catch(Exception e){throw new RuntimeException(OSS文件上传失败, e);}finally{// 关闭客户端if(ossClient!null){ossClient.shutdown();}}}}2.5 替换原生文件上传接口重写RuoYi原生文件上传接口将本地上传替换为OSS上传前端无需改动无缝适配原有上传组件。2.6 OSS集成避坑要点禁止将AccessKey密钥硬编码在代码中统一配置yml并加入.gitignore忽略提交上传文件名必须生成唯一ID防止同名文件覆盖丢失生产环境配置OSS跨域规则解决前端预览跨域问题定时清理OSS冗余文件节省存储费用三、阿里云短信验证码集成登录、注册、找回密码原生RuoYi仅支持账号密码登录移动端、前台系统普遍需要短信验证码登录这里提供生产级短信集成方案支持验证码发送、60秒限流、过期失效、校验验证。3.1 引入短信依赖!-- 阿里云短信依赖 --dependencygroupIdcom.aliyun/groupIdartifactIddysmsapi20170525/artifactIdversion2.0.24/version/dependency3.2 yml配置参数# 阿里云短信配置sms: access-key-id: 你的AccessKeyId access-key-secret: 你的AccessKeySecret sign-name: 你的短信签名 template-code: 你的短信模板CODE3.3 验证码核心逻辑限流缓存过期基于Redis缓存验证码设置5分钟过期、60秒发送限流防止恶意刷取短信接口// 发送短信验证码接口核心逻辑 GetMapping(/sendSms)public AjaxResult sendSms(String phone){//1. 校验手机号格式if(!PhoneUtil.isPhone(phone)){returnAjaxResult.error(手机号格式错误);}//2. 限流校验60秒内只能发送一次 String limitKeysms:limit: phone;if(redisCache.hasKey(limitKey)){returnAjaxResult.error(发送过于频繁请稍后再试);}//3. 生成6位数字验证码 String codeRandomUtil.randomNumbers(6);//4. 缓存验证码5分钟过期 String codeKeysms:code: phone;redisCache.setCacheObject(codeKey, code,5, TimeUnit.MINUTES);//5. 设置限流60秒 redisCache.setCacheObject(limitKey,1,60, TimeUnit.SECONDS);//6. 调用阿里云短信发送工具 boolean resultsmsUtil.sendSms(phone, code);returnresult ? AjaxResult.success(发送成功):AjaxResult.error(发送失败);}3.4 验证码校验逻辑登录、注册接口校验缓存中的验证码校验成功后立即删除缓存防止重复使用。3.5 短信集成避坑点必须添加发送限流避免恶意刷取短信产生高额费用验证码使用Redis缓存不存数据库过期自动失效短信签名、模板必须完成阿里云审核否则发送失败生产环境开启短信发送日志便于排查发送失败问题四、第三方快捷登录集成微信公众号登录很多后台系统、前台H5需要微信快捷登录无需注册账号一键授权登录系统。基于RuoYi权限体系实现微信授权自动注册、绑定账号、自动登录。4.1 核心实现思路前端跳转微信授权地址获取用户授权code后端通过code换取openId、用户昵称、头像根据openId查询系统用户存在则直接登录无用户则自动注册账号绑定默认角色与部门生成RuoYi原生Token完成登录授权4.2 微信配置参数# 微信公众号配置wechat: app-id: 你的公众号APPID app-secret: 你的公众号APPSECRET redirect-url: 授权回调地址4.3 核心授权代码通过微信接口获取用户信息适配RuoYi登录逻辑复用原生认证体系无需改造登录拦截器// 微信一键登录核心逻辑 public AjaxResult wechatLogin(String code){//1. 通过code获取openId WechatUser userInfowechatUtil.getUserInfoByCode(code);String openIduserInfo.getOpenid();//2. 查询数据库是否存在该微信用户 SysUser sysUseruserService.selectUserByOpenId(openId);//3. 不存在则自动注册用户if(Objects.isNull(sysUser)){sysUsernew SysUser();sysUser.setUserName(wx_ openId.substring(0,10));sysUser.setNickName(userInfo.getNickname());sysUser.setAvatar(userInfo.getHeadimgurl());sysUser.setOpenId(openId);// 设置默认部门、默认角色 sysUser.setDeptId(默认部门ID);userService.insertUser(sysUser);}//4. 复用RuoYi原生登录逻辑生成Token LoginUser loginUsernew LoginUser(sysUser);String tokentokenService.createToken(loginUser);returnAjaxResult.success(登录成功, MapUtil.of(token, token));}4.4 微信登录避坑指南回调地址必须在微信公众号后台配置白名单否则授权失败openId为用户唯一标识作为账号唯一依据不可重复自动注册用户必须分配默认角色和部门避免无权限访问区分公众号、小程序、App微信登录不可混用接口五、在线支付集成微信/支付宝基础适配针对商城、缴费、订单类系统提供RuoYi支付集成通用方案基于官方SDK实现支付下单、回调验签、订单状态同步适配微信支付、支付宝支付。5.1 支付核心设计思想支付参数全部配置化密钥、商户号、证书路径写入yml支付、退款、回调逻辑独立封装工具类支付回调开启幂等性校验防止重复回调修改订单状态所有支付操作留存日志便于对账排查5.2 核心适配要点订单表新增支付状态、支付流水号、支付时间、退款状态字段下单时生成唯一商户订单号作为支付唯一标识支付回调优先校验签名、订单状态、金额一致性回调成功后修改订单状态、生成支付记录返回官方成功报文5.3 支付集成避坑重点幂等性必须实现支付回调会多次重试未做幂等会导致订单状态错乱、重复扣款禁止前端传参直接支付所有金额、订单信息后端校验支付密钥、证书文件禁止上传代码仓库生产环境单独配置超时订单自动关闭通过定时任务扫描未支付订单六、通用集成最佳实践总结配置隔离所有第三方密钥、参数统一配置化杜绝硬编码模块隔离第三方代码独立封装不侵入框架原生核心代码安全防护接口限流、参数校验、幂等性、日志留存缺一不可异常容错第三方接口请求失败做好重试、降级、异常捕获规范落地所有集成功能适配RuoYi权限、日志、Token体系保持系统统一性七、下篇预告下一篇为系列第四篇RuoYi定时任务、工作流Flowable深度集成与审批流开发实战讲解定时任务高阶用法、动态任务配置、完整审批流搭建、流程节点配置、审批驳回/抄送/会签落地方案。