mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-24 07:19:46 +08:00
add common 依赖 spring-boot-properties-migrator ;
add 新增 modules 模块, 包含 demo, generator, job, system 模块 ; update 更新模块包名 rateLimiter => ratelimiter ; refactor 重构 ratelimiter 模块, 参考幂等模块加入自动装配相关配置 ; fix 修正 AsyncConfig 实现接口 ; fix 修正 SwaggerConfig 注解写法 ; fix 修正 ruoyi-common-doc pom 描述 ; delete LogAspect 去掉无用注解 ;
This commit is contained in:
@ -0,0 +1,52 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.mail.utils.MailUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
/**
|
||||
* 邮件发送案例
|
||||
*
|
||||
* @author Michelle.Chung
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/mail")
|
||||
public class MailController {
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
*
|
||||
* @param to 接收人
|
||||
* @param subject 标题
|
||||
* @param text 内容
|
||||
*/
|
||||
@GetMapping("/sendSimpleMessage")
|
||||
public R<Void> sendSimpleMessage(String to, String subject, String text) {
|
||||
MailUtils.sendText(to, subject, text);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件(带附件)
|
||||
*
|
||||
* @param to 接收人
|
||||
* @param subject 标题
|
||||
* @param text 内容
|
||||
* @param filePath 附件路径
|
||||
*/
|
||||
@GetMapping("/sendMessageWithAttachment")
|
||||
public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) {
|
||||
MailUtils.sendText(to, subject, text, new File(filePath));
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.constant.CacheNames;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.redis.utils.RedisUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* spring-cache 演示案例
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
// 类级别 缓存统一配置
|
||||
//@CacheConfig(cacheNames = CacheNames.DEMO_CACHE)
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/cache")
|
||||
public class RedisCacheController {
|
||||
|
||||
/**
|
||||
* 测试 @Cacheable
|
||||
* <p>
|
||||
* 表示这个方法有了缓存的功能,方法的返回值会被缓存下来
|
||||
* 下一次调用该方法前,会去检查是否缓存中已经有值
|
||||
* 如果有就直接返回,不调用方法
|
||||
* 如果没有,就调用方法,然后把结果缓存起来
|
||||
* 这个注解「一般用在查询方法上」
|
||||
* <p>
|
||||
* 重点说明: 缓存注解严谨与其他筛选数据功能一起使用
|
||||
* 例如: 数据权限注解 会造成 缓存击穿 与 数据不一致问题
|
||||
* <p>
|
||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||
*/
|
||||
@Cacheable(cacheNames = "demo:cache#60s#10m#20", key = "#key", condition = "#key != null")
|
||||
@GetMapping("/test1")
|
||||
public R<String> test1(String key, String value) {
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 @CachePut
|
||||
* <p>
|
||||
* 加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用
|
||||
* 它「通常用在新增或者实时更新方法上」
|
||||
* <p>
|
||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||
*/
|
||||
@CachePut(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
|
||||
@GetMapping("/test2")
|
||||
public R<String> test2(String key, String value) {
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 @CacheEvict
|
||||
* <p>
|
||||
* 使用了CacheEvict注解的方法,会清空指定缓存
|
||||
* 「一般用在删除的方法上」
|
||||
* <p>
|
||||
* cacheNames 命名规则 查看 {@link CacheNames} 注释 支持多参数
|
||||
*/
|
||||
@CacheEvict(cacheNames = CacheNames.DEMO_CACHE, key = "#key", condition = "#key != null")
|
||||
@GetMapping("/test3")
|
||||
public R<String> test3(String key, String value) {
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试设置过期时间
|
||||
* 手动设置过期时间10秒
|
||||
* 11秒后获取 判断是否相等
|
||||
*/
|
||||
@GetMapping("/test6")
|
||||
public R<Boolean> test6(String key, String value) {
|
||||
RedisUtils.setCacheObject(key, value);
|
||||
boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10));
|
||||
System.out.println("***********" + flag);
|
||||
try {
|
||||
Thread.sleep(11 * 1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Object obj = RedisUtils.getCacheObject(key);
|
||||
return R.ok(value.equals(obj));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import com.baomidou.lock.annotation.Lock4j;
|
||||
import com.baomidou.lock.executor.RedissonLockExecutor;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalTime;
|
||||
|
||||
|
||||
/**
|
||||
* 测试分布式锁的样例
|
||||
*
|
||||
* @author shenxinquan
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/demo/redisLock")
|
||||
public class RedisLockController {
|
||||
|
||||
@Autowired
|
||||
private LockTemplate lockTemplate;
|
||||
|
||||
/**
|
||||
* 测试lock4j 注解
|
||||
*/
|
||||
@Lock4j(keys = {"#key"})
|
||||
@GetMapping("/testLock4j")
|
||||
public R<String> testLock4j(String key, String value) {
|
||||
System.out.println("start:" + key + ",time:" + LocalTime.now().toString());
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("end :" + key + ",time:" + LocalTime.now().toString());
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试lock4j 工具
|
||||
*/
|
||||
@GetMapping("/testLock4jLockTemplate")
|
||||
public R<String> testLock4jLockTemplate(String key, String value) {
|
||||
final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
|
||||
if (null == lockInfo) {
|
||||
throw new RuntimeException("业务处理中,请稍后再试");
|
||||
}
|
||||
// 获取锁成功,处理业务
|
||||
try {
|
||||
try {
|
||||
Thread.sleep(8000);
|
||||
} catch (InterruptedException e) {
|
||||
//
|
||||
}
|
||||
System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName());
|
||||
} finally {
|
||||
//释放锁
|
||||
lockTemplate.releaseLock(lockInfo);
|
||||
}
|
||||
//结束
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.redis.utils.RedisUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Redis 发布订阅 演示案例
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/redis/pubsub")
|
||||
public class RedisPubSubController {
|
||||
|
||||
/**
|
||||
* 发布消息
|
||||
*
|
||||
* @param key 通道Key
|
||||
* @param value 发送内容
|
||||
*/
|
||||
@GetMapping("/pub")
|
||||
public R<Void> pub(String key, String value) {
|
||||
RedisUtils.publish(key, value, consumer -> {
|
||||
System.out.println("发布通道 => " + key + ", 发送值 => " + value);
|
||||
});
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅消息
|
||||
*
|
||||
* @param key 通道Key
|
||||
*/
|
||||
@GetMapping("/sub")
|
||||
public R<Void> sub(String key) {
|
||||
RedisUtils.subscribe(key, String.class, msg -> {
|
||||
System.out.println("订阅通道 => " + key + ", 接收值 => " + msg);
|
||||
});
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.ratelimiter.annotation.RateLimiter;
|
||||
import com.ruoyi.common.ratelimiter.enums.LimitType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
/**
|
||||
* 测试分布式限流样例
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/demo/rateLimiter")
|
||||
public class RedisRateLimiterController {
|
||||
|
||||
/**
|
||||
* 测试全局限流
|
||||
* 全局影响
|
||||
*/
|
||||
@RateLimiter(count = 2, time = 10)
|
||||
@GetMapping("/test")
|
||||
public R<String> test(String value) {
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试请求IP限流
|
||||
* 同一IP请求受影响
|
||||
*/
|
||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
|
||||
@GetMapping("/testip")
|
||||
public R<String> testip(String value) {
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试集群实例限流
|
||||
* 启动两个后端服务互不影响
|
||||
*/
|
||||
@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
|
||||
@GetMapping("/testcluster")
|
||||
public R<String> testcluster(String value) {
|
||||
return R.ok("操作成功", value);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.utils.SpringUtils;
|
||||
import com.ruoyi.common.sms.config.properties.SmsProperties;
|
||||
import com.ruoyi.common.sms.core.SmsTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 短信演示案例
|
||||
* 请先阅读文档 否则无法使用
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 4.2.0
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/sms")
|
||||
public class SmsController {
|
||||
|
||||
private final SmsProperties smsProperties;
|
||||
// private final SmsTemplate smsTemplate; // 可以使用spring注入
|
||||
// private final AliyunSmsTemplate smsTemplate; // 也可以注入某个厂家的模板工具
|
||||
|
||||
/**
|
||||
* 发送短信Aliyun
|
||||
*
|
||||
* @param phones 电话号
|
||||
* @param templateId 模板ID
|
||||
*/
|
||||
@GetMapping("/sendAliyun")
|
||||
public R<Object> sendAliyun(String phones, String templateId) {
|
||||
if (!smsProperties.getEnabled()) {
|
||||
return R.fail("当前系统没有开启短信功能!");
|
||||
}
|
||||
if (!SpringUtils.containsBean("aliyunSmsTemplate")) {
|
||||
return R.fail("阿里云依赖未引入!");
|
||||
}
|
||||
SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
|
||||
Map<String, String> map = new HashMap<>(1);
|
||||
map.put("code", "1234");
|
||||
Object send = smsTemplate.send(phones, templateId, map);
|
||||
return R.ok(send);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信Tencent
|
||||
*
|
||||
* @param phones 电话号
|
||||
* @param templateId 模板ID
|
||||
*/
|
||||
@GetMapping("/sendTencent")
|
||||
public R<Object> sendTencent(String phones, String templateId) {
|
||||
if (!smsProperties.getEnabled()) {
|
||||
return R.fail("当前系统没有开启短信功能!");
|
||||
}
|
||||
if (!SpringUtils.containsBean("tencentSmsTemplate")) {
|
||||
return R.fail("腾讯云依赖未引入!");
|
||||
}
|
||||
SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class);
|
||||
Map<String, String> map = new HashMap<>(1);
|
||||
// map.put("2", "测试测试");
|
||||
map.put("1", "1234");
|
||||
Object send = smsTemplate.send(phones, templateId, map);
|
||||
return R.ok(send);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* swagger3 用法示例
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/swagger/demo")
|
||||
public class Swagger3DemoController {
|
||||
|
||||
/**
|
||||
* 上传请求
|
||||
* 必须使用 @RequestPart 注解标注为文件
|
||||
*
|
||||
* @param file 文件
|
||||
*/
|
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<String> upload(@RequestPart("file") MultipartFile file) {
|
||||
return R.ok("操作成功", file.getOriginalFilename());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.web.controller.BaseController;
|
||||
import com.ruoyi.demo.domain.TestDemo;
|
||||
import com.ruoyi.demo.mapper.TestDemoMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试批量方法
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-05-30
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/batch")
|
||||
public class TestBatchController extends BaseController {
|
||||
|
||||
/**
|
||||
* 为了便于测试 直接引入mapper
|
||||
*/
|
||||
private final TestDemoMapper testDemoMapper;
|
||||
|
||||
/**
|
||||
* 新增批量方法 可完美替代 saveBatch 秒级插入上万数据 (对mysql负荷较大)
|
||||
* <p>
|
||||
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
// @DS("slave")
|
||||
public R<Void> add() {
|
||||
List<TestDemo> list = new ArrayList<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
TestDemo testDemo = new TestDemo();
|
||||
testDemo.setOrderNum(-1);
|
||||
testDemo.setTestKey("批量新增");
|
||||
testDemo.setValue("测试新增");
|
||||
list.add(testDemo);
|
||||
}
|
||||
return toAjax(testDemoMapper.insertBatch(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或更新 可完美替代 saveOrUpdateBatch 高性能
|
||||
* <p>
|
||||
* 3.5.0 版本 增加 rewriteBatchedStatements=true 批处理参数 使 MP 原生批处理可以达到同样的速度
|
||||
*/
|
||||
@PostMapping("/addOrUpdate")
|
||||
// @DS("slave")
|
||||
public R<Void> addOrUpdate() {
|
||||
List<TestDemo> list = new ArrayList<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
TestDemo testDemo = new TestDemo();
|
||||
testDemo.setOrderNum(-1);
|
||||
testDemo.setTestKey("批量新增");
|
||||
testDemo.setValue("测试新增");
|
||||
list.add(testDemo);
|
||||
}
|
||||
testDemoMapper.insertBatch(list);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
TestDemo testDemo = list.get(i);
|
||||
testDemo.setTestKey("批量新增或修改");
|
||||
testDemo.setValue("批量新增或修改");
|
||||
if (i % 2 == 0) {
|
||||
testDemo.setId(null);
|
||||
}
|
||||
}
|
||||
return toAjax(testDemoMapper.insertOrUpdateBatch(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除批量方法
|
||||
*/
|
||||
@DeleteMapping()
|
||||
// @DS("slave")
|
||||
public R<Void> remove() {
|
||||
return toAjax(testDemoMapper.delete(new LambdaQueryWrapper<TestDemo>()
|
||||
.eq(TestDemo::getOrderNum, -1L)));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.utils.ValidatorUtils;
|
||||
import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.core.validate.QueryGroup;
|
||||
import com.ruoyi.common.core.web.controller.BaseController;
|
||||
import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
|
||||
import com.ruoyi.common.mybatis.core.page.PageQuery;
|
||||
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.excel.core.ExcelResult;
|
||||
import com.ruoyi.common.excel.utils.ExcelUtil;
|
||||
import com.ruoyi.common.log.annotation.Log;
|
||||
import com.ruoyi.common.log.enums.BusinessType;
|
||||
import com.ruoyi.demo.domain.TestDemo;
|
||||
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
||||
import com.ruoyi.demo.domain.bo.TestDemoImportVo;
|
||||
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
||||
import com.ruoyi.demo.service.ITestDemoService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 测试单表Controller
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/demo")
|
||||
public class TestDemoController extends BaseController {
|
||||
|
||||
private final ITestDemoService iTestDemoService;
|
||||
|
||||
/**
|
||||
* 查询测试单表列表
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<TestDemoVo> list(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
|
||||
return iTestDemoService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义分页查询
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:list")
|
||||
@GetMapping("/page")
|
||||
public TableDataInfo<TestDemoVo> page(@Validated(QueryGroup.class) TestDemoBo bo, PageQuery pageQuery) {
|
||||
return iTestDemoService.customPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入数据
|
||||
*
|
||||
* @param file 导入文件
|
||||
*/
|
||||
@Log(title = "测试单表", businessType = BusinessType.IMPORT)
|
||||
@SaCheckPermission("demo:demo:import")
|
||||
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
|
||||
ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
|
||||
List<TestDemoImportVo> volist = excelResult.getList();
|
||||
List<TestDemo> list = BeanUtil.copyToList(volist, TestDemo.class);
|
||||
iTestDemoService.saveBatch(list);
|
||||
return R.ok(excelResult.getAnalysis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出测试单表列表
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:export")
|
||||
@Log(title = "测试单表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
|
||||
List<TestDemoVo> list = iTestDemoService.queryList(bo);
|
||||
// 测试雪花id导出
|
||||
// for (TestDemoVo vo : list) {
|
||||
// vo.setId(1234567891234567893L);
|
||||
// }
|
||||
ExcelUtil.exportExcel(list, "测试单表", TestDemoVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取测试单表详细信息
|
||||
*
|
||||
* @param id 测试ID
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<TestDemoVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable("id") Long id) {
|
||||
return R.ok(iTestDemoService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增测试单表
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:add")
|
||||
@Log(title = "测试单表", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "{repeat.submit.message}")
|
||||
@PostMapping()
|
||||
public R<Void> add(@RequestBody TestDemoBo bo) {
|
||||
// 使用校验工具对标 @Validated(AddGroup.class) 注解
|
||||
// 用于在非 Controller 的地方校验对象
|
||||
ValidatorUtils.validate(bo, AddGroup.class);
|
||||
return toAjax(iTestDemoService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改测试单表
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:edit")
|
||||
@Log(title = "测试单表", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestDemoBo bo) {
|
||||
return toAjax(iTestDemoService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除测试单表
|
||||
*
|
||||
* @param ids 测试ID串
|
||||
*/
|
||||
@SaCheckPermission("demo:demo:remove")
|
||||
@Log(title = "测试单表", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.common.excel.utils.ExcelUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测试Excel功能
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/demo/excel")
|
||||
public class TestExcelController {
|
||||
|
||||
/**
|
||||
* 单列表多数据
|
||||
*/
|
||||
@GetMapping("/exportTemplateOne")
|
||||
public void exportTemplateOne(HttpServletResponse response) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("title", "单列表多数据");
|
||||
map.put("test1", "数据测试1");
|
||||
map.put("test2", "数据测试2");
|
||||
map.put("test3", "数据测试3");
|
||||
map.put("test4", "数据测试4");
|
||||
map.put("testTest", "666");
|
||||
List<TestObj> list = new ArrayList<>();
|
||||
list.add(new TestObj("单列表测试1", "列表测试1", "列表测试2", "列表测试3", "列表测试4"));
|
||||
list.add(new TestObj("单列表测试2", "列表测试5", "列表测试6", "列表测试7", "列表测试8"));
|
||||
list.add(new TestObj("单列表测试3", "列表测试9", "列表测试10", "列表测试11", "列表测试12"));
|
||||
ExcelUtil.exportTemplate(CollUtil.newArrayList(map, list), "单列表.xlsx", "excel/单列表.xlsx", response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 多列表多数据
|
||||
*/
|
||||
@GetMapping("/exportTemplateMuliti")
|
||||
public void exportTemplateMuliti(HttpServletResponse response) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("title1", "标题1");
|
||||
map.put("title2", "标题2");
|
||||
map.put("title3", "标题3");
|
||||
map.put("title4", "标题4");
|
||||
map.put("author", "Lion Li");
|
||||
List<TestObj1> list1 = new ArrayList<>();
|
||||
list1.add(new TestObj1("list1测试1", "list1测试2", "list1测试3"));
|
||||
list1.add(new TestObj1("list1测试4", "list1测试5", "list1测试6"));
|
||||
list1.add(new TestObj1("list1测试7", "list1测试8", "list1测试9"));
|
||||
List<TestObj1> list2 = new ArrayList<>();
|
||||
list2.add(new TestObj1("list2测试1", "list2测试2", "list2测试3"));
|
||||
list2.add(new TestObj1("list2测试4", "list2测试5", "list2测试6"));
|
||||
List<TestObj1> list3 = new ArrayList<>();
|
||||
list3.add(new TestObj1("list3测试1", "list3测试2", "list3测试3"));
|
||||
List<TestObj1> list4 = new ArrayList<>();
|
||||
list4.add(new TestObj1("list4测试1", "list4测试2", "list4测试3"));
|
||||
list4.add(new TestObj1("list4测试4", "list4测试5", "list4测试6"));
|
||||
list4.add(new TestObj1("list4测试7", "list4测试8", "list4测试9"));
|
||||
list4.add(new TestObj1("list4测试10", "list4测试11", "list4测试12"));
|
||||
Map<String, Object> multiListMap = new HashMap<>();
|
||||
multiListMap.put("map", map);
|
||||
multiListMap.put("data1", list1);
|
||||
multiListMap.put("data2", list2);
|
||||
multiListMap.put("data3", list3);
|
||||
multiListMap.put("data4", list4);
|
||||
ExcelUtil.exportTemplateMultiList(multiListMap, "多列表.xlsx", "excel/多列表.xlsx", response);
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
static class TestObj1 {
|
||||
private String test1;
|
||||
private String test2;
|
||||
private String test3;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
static class TestObj {
|
||||
private String name;
|
||||
private String list1;
|
||||
private String list2;
|
||||
private String list3;
|
||||
private String list4;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.utils.MessageUtils;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Range;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
* 测试国际化
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/demo/i18n")
|
||||
public class TestI18nController {
|
||||
|
||||
/**
|
||||
* 通过code获取国际化内容
|
||||
* code为 messages.properties 中的 key
|
||||
* <p>
|
||||
* 测试使用 user.register.success
|
||||
*
|
||||
* @param code 国际化code
|
||||
*/
|
||||
@GetMapping()
|
||||
public R<Void> get(String code) {
|
||||
return R.ok(MessageUtils.message(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validator 校验国际化
|
||||
* 不传值 分别查看异常返回
|
||||
* <p>
|
||||
* 测试使用 not.null
|
||||
*/
|
||||
@GetMapping("/test1")
|
||||
public R<Void> test1(@NotBlank(message = "{not.null}") String str) {
|
||||
return R.ok(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean 校验国际化
|
||||
* 不传值 分别查看异常返回
|
||||
* <p>
|
||||
* 测试使用 not.null
|
||||
*/
|
||||
@GetMapping("/test2")
|
||||
public R<TestI18nBo> test2(@Validated TestI18nBo bo) {
|
||||
return R.ok(bo);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TestI18nBo {
|
||||
|
||||
@NotBlank(message = "{not.null}")
|
||||
private String name;
|
||||
|
||||
@NotNull(message = "{not.null}")
|
||||
@Range(min = 0, max = 100, message = "{length.not.valid}")
|
||||
private Integer age;
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import com.ruoyi.common.core.annotation.Sensitive;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.enums.SensitiveStrategy;
|
||||
import com.ruoyi.common.core.web.controller.BaseController;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 测试数据脱敏控制器
|
||||
* <p>
|
||||
* 默认管理员不过滤
|
||||
* 需自行根据业务重写实现
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
* @see com.ruoyi.common.core.service.SensitiveService
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/demo/sensitive")
|
||||
public class TestSensitiveController extends BaseController {
|
||||
|
||||
/**
|
||||
* 测试数据脱敏
|
||||
*/
|
||||
@GetMapping("/test")
|
||||
public R<TestSensitive> test() {
|
||||
TestSensitive testSensitive = new TestSensitive();
|
||||
testSensitive.setIdCard("210397198608215431");
|
||||
testSensitive.setPhone("17640125371");
|
||||
testSensitive.setAddress("北京市朝阳区某某四合院1203室");
|
||||
testSensitive.setEmail("17640125371@163.com");
|
||||
testSensitive.setBankCard("6226456952351452853");
|
||||
return R.ok(testSensitive);
|
||||
}
|
||||
|
||||
@Data
|
||||
static class TestSensitive {
|
||||
|
||||
/**
|
||||
* 身份证
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.ID_CARD)
|
||||
private String idCard;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.PHONE)
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.ADDRESS)
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.EMAIL)
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 银行卡
|
||||
*/
|
||||
@Sensitive(strategy = SensitiveStrategy.BANK_CARD)
|
||||
private String bankCard;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.ruoyi.demo.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.core.validate.QueryGroup;
|
||||
import com.ruoyi.common.core.web.controller.BaseController;
|
||||
import com.ruoyi.common.excel.utils.ExcelUtil;
|
||||
import com.ruoyi.common.idempotent.annotation.RepeatSubmit;
|
||||
import com.ruoyi.common.log.annotation.Log;
|
||||
import com.ruoyi.common.log.enums.BusinessType;
|
||||
import com.ruoyi.demo.domain.bo.TestTreeBo;
|
||||
import com.ruoyi.demo.domain.vo.TestTreeVo;
|
||||
import com.ruoyi.demo.service.ITestTreeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试树表Controller
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/tree")
|
||||
public class TestTreeController extends BaseController {
|
||||
|
||||
private final ITestTreeService iTestTreeService;
|
||||
|
||||
/**
|
||||
* 查询测试树表列表
|
||||
*/
|
||||
@SaCheckPermission("demo:tree:list")
|
||||
@GetMapping("/list")
|
||||
public R<List<TestTreeVo>> list(@Validated(QueryGroup.class) TestTreeBo bo) {
|
||||
List<TestTreeVo> list = iTestTreeService.queryList(bo);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出测试树表列表
|
||||
*/
|
||||
@SaCheckPermission("demo:tree:export")
|
||||
@Log(title = "测试树表", businessType = BusinessType.EXPORT)
|
||||
@GetMapping("/export")
|
||||
public void export(@Validated TestTreeBo bo, HttpServletResponse response) {
|
||||
List<TestTreeVo> list = iTestTreeService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "测试树表", TestTreeVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取测试树表详细信息
|
||||
*
|
||||
* @param id 测试树ID
|
||||
*/
|
||||
@SaCheckPermission("demo:tree:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<TestTreeVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable("id") Long id) {
|
||||
return R.ok(iTestTreeService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增测试树表
|
||||
*/
|
||||
@SaCheckPermission("demo:tree:add")
|
||||
@Log(title = "测试树表", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody TestTreeBo bo) {
|
||||
return toAjax(iTestTreeService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改测试树表
|
||||
*/
|
||||
@SaCheckPermission("demo:tree:edit")
|
||||
@Log(title = "测试树表", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TestTreeBo bo) {
|
||||
return toAjax(iTestTreeService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除测试树表
|
||||
*
|
||||
* @param ids 测试树ID串
|
||||
*/
|
||||
@SaCheckPermission("demo:tree:remove")
|
||||
@Log(title = "测试树表", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
package com.ruoyi.demo.controller;
|
@ -0,0 +1,90 @@
|
||||
package com.ruoyi.demo.controller.queue;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.redis.utils.QueueUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 有界队列 演示案例
|
||||
* <p>
|
||||
* 轻量级队列 重量级数据量 请使用 MQ
|
||||
* <p>
|
||||
* 集群测试通过 同一个数据只会被消费一次 做好事务补偿
|
||||
* 集群测试流程 在其中一台发送数据 两端分别调用获取接口 一次获取一条
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/queue/bounded")
|
||||
public class BoundedQueueController {
|
||||
|
||||
|
||||
/**
|
||||
* 添加队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
* @param capacity 容量
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public R<Void> add(String queueName, int capacity) {
|
||||
// 用完了一定要销毁 否则会一直存在
|
||||
boolean b = QueueUtils.destroyQueue(queueName);
|
||||
log.info("通道: {} , 删除: {}", queueName, b);
|
||||
// 初始化设置一次即可
|
||||
if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) {
|
||||
log.info("通道: {} , 设置容量: {}", queueName, capacity);
|
||||
} else {
|
||||
log.info("通道: {} , 设置容量失败", queueName);
|
||||
return R.fail("操作失败");
|
||||
}
|
||||
for (int i = 0; i < 11; i++) {
|
||||
String data = "data-" + i;
|
||||
boolean flag = QueueUtils.addBoundedQueueObject(queueName, data);
|
||||
if (flag == false) {
|
||||
log.info("通道: {} , 发送数据: {} 失败, 通道已满", queueName, data);
|
||||
} else {
|
||||
log.info("通道: {} , 发送数据: {}", queueName, data);
|
||||
}
|
||||
}
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
*/
|
||||
@GetMapping("/remove")
|
||||
public R<Void> remove(String queueName) {
|
||||
String data = "data-" + 5;
|
||||
if (QueueUtils.removeQueueObject(queueName, data)) {
|
||||
log.info("通道: {} , 删除数据: {}", queueName, data);
|
||||
} else {
|
||||
return R.fail("操作失败");
|
||||
}
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
public R<Void> get(String queueName) {
|
||||
String data;
|
||||
do {
|
||||
data = QueueUtils.getQueueObject(queueName);
|
||||
log.info("通道: {} , 获取数据: {}", queueName, data);
|
||||
} while (data != null);
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.ruoyi.demo.controller.queue;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.redis.utils.QueueUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 延迟队列 演示案例
|
||||
* <p>
|
||||
* 轻量级队列 重量级数据量 请使用 MQ
|
||||
* 例如: 创建订单30分钟后过期处理
|
||||
* <p>
|
||||
* 集群测试通过 同一个数据只会被消费一次 做好事务补偿
|
||||
* 集群测试流程 两台集群分别开启订阅 在其中一台发送数据 观察接收消息的规律
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/queue/delayed")
|
||||
public class DelayedQueueController {
|
||||
|
||||
/**
|
||||
* 订阅队列
|
||||
*
|
||||
* @param queueName 队列名
|
||||
*/
|
||||
@GetMapping("/subscribe")
|
||||
public R<Void> subscribe(String queueName) {
|
||||
log.info("通道: {} 监听中......", queueName);
|
||||
// 项目初始化设置一次即可
|
||||
QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> {
|
||||
// 观察接收时间
|
||||
log.info("通道: {}, 收到数据: {}", queueName, orderNum);
|
||||
});
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
* @param orderNum 订单号
|
||||
* @param time 延迟时间(秒)
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public R<Void> add(String queueName, String orderNum, Long time) {
|
||||
QueueUtils.addDelayedQueueObject(queueName, orderNum, time, TimeUnit.SECONDS);
|
||||
// 观察发送时间
|
||||
log.info("通道: {} , 发送数据: {}", queueName, orderNum);
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
* @param orderNum 订单号
|
||||
*/
|
||||
@GetMapping("/remove")
|
||||
public R<Void> remove(String queueName, String orderNum) {
|
||||
if (QueueUtils.removeDelayedQueueObject(queueName, orderNum)) {
|
||||
log.info("通道: {} , 删除数据: {}", queueName, orderNum);
|
||||
} else {
|
||||
return R.fail("操作失败");
|
||||
}
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁队列
|
||||
*
|
||||
* @param queueName 队列名
|
||||
*/
|
||||
@GetMapping("/destroy")
|
||||
public R<Void> destroy(String queueName) {
|
||||
// 用完了一定要销毁 否则会一直存在
|
||||
QueueUtils.destroyDelayedQueue(queueName);
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.ruoyi.demo.controller.queue;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 实体类 注意不允许使用内部类 否则会找不到类
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class PriorityDemo implements Comparable<PriorityDemo> {
|
||||
private String name;
|
||||
private Integer orderNum;
|
||||
|
||||
@Override
|
||||
public int compareTo(PriorityDemo other) {
|
||||
return Integer.compare(getOrderNum(), other.getOrderNum());
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.ruoyi.demo.controller.queue;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.redis.utils.QueueUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 优先队列 演示案例
|
||||
* <p>
|
||||
* 轻量级队列 重量级数据量 请使用 MQ
|
||||
* <p>
|
||||
* 集群测试通过 同一个消息只会被消费一次 做好事务补偿
|
||||
* 集群测试流程 在其中一台发送数据 两端分别调用获取接口 一次获取一条
|
||||
*
|
||||
* @author Lion Li
|
||||
* @version 3.6.0
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/demo/queue/priority")
|
||||
public class PriorityQueueController {
|
||||
|
||||
/**
|
||||
* 添加队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public R<Void> add(String queueName) {
|
||||
// 用完了一定要销毁 否则会一直存在
|
||||
boolean b = QueueUtils.destroyQueue(queueName);
|
||||
log.info("通道: {} , 删除: {}", queueName, b);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int randomNum = RandomUtil.randomInt(10);
|
||||
PriorityDemo data = new PriorityDemo();
|
||||
data.setName("data-" + i);
|
||||
data.setOrderNum(randomNum);
|
||||
if (QueueUtils.addPriorityQueueObject(queueName, data)) {
|
||||
log.info("通道: {} , 发送数据: {}", queueName, data);
|
||||
} else {
|
||||
log.info("通道: {} , 发送数据: {}, 发送失败", queueName, data);
|
||||
}
|
||||
}
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
* @param name 对象名
|
||||
* @param orderNum 排序号
|
||||
*/
|
||||
@GetMapping("/remove")
|
||||
public R<Void> remove(String queueName, String name, Integer orderNum) {
|
||||
PriorityDemo data = new PriorityDemo();
|
||||
data.setName(name);
|
||||
data.setOrderNum(orderNum);
|
||||
if (QueueUtils.removeQueueObject(queueName, data)) {
|
||||
log.info("通道: {} , 删除数据: {}", queueName, data);
|
||||
} else {
|
||||
return R.fail("操作失败");
|
||||
}
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列数据
|
||||
*
|
||||
* @param queueName 队列名
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
public R<Void> get(String queueName) {
|
||||
PriorityDemo data;
|
||||
do {
|
||||
data = QueueUtils.getQueueObject(queueName);
|
||||
log.info("通道: {} , 获取数据: {}", queueName, data);
|
||||
} while (data != null);
|
||||
return R.ok("操作成功");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.ruoyi.demo.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 测试单表对象 test_demo
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("test_demo")
|
||||
public class TestDemo extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 排序号
|
||||
*/
|
||||
@OrderBy(asc = false, sort = 1)
|
||||
private Integer orderNum;
|
||||
|
||||
/**
|
||||
* key键
|
||||
*/
|
||||
private String testKey;
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 版本
|
||||
*/
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
/**
|
||||
* 删除标志
|
||||
*/
|
||||
@TableLogic
|
||||
private Long delFlag;
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.ruoyi.demo.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.Version;
|
||||
import com.ruoyi.common.core.web.domain.TreeEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 测试树表对象 test_tree
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("test_tree")
|
||||
public class TestTree extends TreeEntity<TestTree> {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 树节点名
|
||||
*/
|
||||
private String treeName;
|
||||
|
||||
/**
|
||||
* 版本
|
||||
*/
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
/**
|
||||
* 删除标志
|
||||
*/
|
||||
@TableLogic
|
||||
private Long delFlag;
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.ruoyi.demo.domain.bo;
|
||||
|
||||
import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 测试单表业务对象 test_demo
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TestDemoBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@NotNull(message = "部门id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@NotNull(message = "用户id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 排序号
|
||||
*/
|
||||
@NotNull(message = "排序号不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Integer orderNum;
|
||||
|
||||
/**
|
||||
* key键
|
||||
*/
|
||||
@NotBlank(message = "key键不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String testKey;
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
@NotBlank(message = "值不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String value;
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.ruoyi.demo.domain.bo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 测试单表业务对象 test_demo
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Data
|
||||
public class TestDemoImportVo {
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@NotNull(message = "部门id不能为空")
|
||||
@ExcelProperty(value = "部门id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@NotNull(message = "用户id不能为空")
|
||||
@ExcelProperty(value = "用户id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 排序号
|
||||
*/
|
||||
@NotNull(message = "排序号不能为空")
|
||||
@ExcelProperty(value = "排序号")
|
||||
private Long orderNum;
|
||||
|
||||
/**
|
||||
* key键
|
||||
*/
|
||||
@NotBlank(message = "key键不能为空")
|
||||
@ExcelProperty(value = "key键")
|
||||
private String testKey;
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
@NotBlank(message = "值不能为空")
|
||||
@ExcelProperty(value = "值")
|
||||
private String value;
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.ruoyi.demo.domain.bo;
|
||||
|
||||
import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.core.web.domain.TreeEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 测试树表业务对象 test_tree
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TestTreeBo extends TreeEntity<TestTreeBo> {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@NotNull(message = "部门id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@NotNull(message = "用户id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 树节点名
|
||||
*/
|
||||
@NotBlank(message = "树节点名不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String treeName;
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
package com.ruoyi.demo.domain;
|
@ -0,0 +1,86 @@
|
||||
package com.ruoyi.demo.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 测试单表视图对象 test_demo
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class TestDemoVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@ExcelProperty(value = "部门id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ExcelProperty(value = "用户id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 排序号
|
||||
*/
|
||||
@ExcelProperty(value = "排序号")
|
||||
private Integer orderNum;
|
||||
|
||||
/**
|
||||
* key键
|
||||
*/
|
||||
@ExcelProperty(value = "key键")
|
||||
private String testKey;
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
@ExcelProperty(value = "值")
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@ExcelProperty(value = "创建人")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@ExcelProperty(value = "更新时间")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@ExcelProperty(value = "更新人")
|
||||
private String updateBy;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.ruoyi.demo.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 测试树表视图对象 test_tree
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class TestTreeVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
@ExcelProperty(value = "父id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@ExcelProperty(value = "部门id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ExcelProperty(value = "用户id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 树节点名
|
||||
*/
|
||||
@ExcelProperty(value = "树节点名")
|
||||
private String treeName;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.ruoyi.demo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.mybatis.annotation.DataColumn;
|
||||
import com.ruoyi.common.mybatis.annotation.DataPermission;
|
||||
import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import com.ruoyi.demo.domain.TestDemo;
|
||||
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试单表Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
public interface TestDemoMapper extends BaseMapperPlus<TestDemoMapper, TestDemo, TestDemoVo> {
|
||||
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "user_id")
|
||||
})
|
||||
Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper);
|
||||
|
||||
@Override
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "user_id")
|
||||
})
|
||||
<P extends IPage<TestDemo>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
|
||||
|
||||
@Override
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "user_id")
|
||||
})
|
||||
List<TestDemo> selectList(@Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper);
|
||||
|
||||
@Override
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "user_id")
|
||||
})
|
||||
int updateById(@Param(Constants.ENTITY) TestDemo entity);
|
||||
|
||||
@Override
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "user_id")
|
||||
})
|
||||
int deleteBatchIds(@Param(Constants.COLL) Collection<?> idList);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.ruoyi.demo.mapper;
|
||||
|
||||
import com.ruoyi.common.mybatis.annotation.DataColumn;
|
||||
import com.ruoyi.common.mybatis.annotation.DataPermission;
|
||||
import com.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import com.ruoyi.demo.domain.TestTree;
|
||||
import com.ruoyi.demo.domain.vo.TestTreeVo;
|
||||
|
||||
/**
|
||||
* 测试树表Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "user_id")
|
||||
})
|
||||
public interface TestTreeMapper extends BaseMapperPlus<TestTreeMapper, TestTree, TestTreeVo> {
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
package com.ruoyi.demo.mapper;
|
@ -0,0 +1,71 @@
|
||||
package com.ruoyi.demo.service;
|
||||
|
||||
import com.ruoyi.common.mybatis.core.page.PageQuery;
|
||||
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||
import com.ruoyi.demo.domain.TestDemo;
|
||||
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
||||
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试单表Service接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
public interface ITestDemoService {
|
||||
|
||||
/**
|
||||
* 查询单个
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TestDemoVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*/
|
||||
TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 自定义分页查询
|
||||
*/
|
||||
TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*/
|
||||
List<TestDemoVo> queryList(TestDemoBo bo);
|
||||
|
||||
/**
|
||||
* 根据新增业务对象插入测试单表
|
||||
*
|
||||
* @param bo 测试单表新增业务对象
|
||||
* @return
|
||||
*/
|
||||
Boolean insertByBo(TestDemoBo bo);
|
||||
|
||||
/**
|
||||
* 根据编辑业务对象修改测试单表
|
||||
*
|
||||
* @param bo 测试单表编辑业务对象
|
||||
* @return
|
||||
*/
|
||||
Boolean updateByBo(TestDemoBo bo);
|
||||
|
||||
/**
|
||||
* 校验并删除数据
|
||||
*
|
||||
* @param ids 主键集合
|
||||
* @param isValid 是否校验,true-删除前校验,false-不校验
|
||||
* @return
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 批量保存
|
||||
*/
|
||||
Boolean saveBatch(List<TestDemo> list);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.ruoyi.demo.service;
|
||||
|
||||
import com.ruoyi.demo.domain.bo.TestTreeBo;
|
||||
import com.ruoyi.demo.domain.vo.TestTreeVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试树表Service接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
public interface ITestTreeService {
|
||||
/**
|
||||
* 查询单个
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TestTreeVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*/
|
||||
List<TestTreeVo> queryList(TestTreeBo bo);
|
||||
|
||||
/**
|
||||
* 根据新增业务对象插入测试树表
|
||||
*
|
||||
* @param bo 测试树表新增业务对象
|
||||
* @return
|
||||
*/
|
||||
Boolean insertByBo(TestTreeBo bo);
|
||||
|
||||
/**
|
||||
* 根据编辑业务对象修改测试树表
|
||||
*
|
||||
* @param bo 测试树表编辑业务对象
|
||||
* @return
|
||||
*/
|
||||
Boolean updateByBo(TestTreeBo bo);
|
||||
|
||||
/**
|
||||
* 校验并删除数据
|
||||
*
|
||||
* @param ids 主键集合
|
||||
* @param isValid 是否校验,true-删除前校验,false-不校验
|
||||
* @return
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.ruoyi.demo.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.mybatis.core.page.PageQuery;
|
||||
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||
import com.ruoyi.demo.domain.TestDemo;
|
||||
import com.ruoyi.demo.domain.bo.TestDemoBo;
|
||||
import com.ruoyi.demo.domain.vo.TestDemoVo;
|
||||
import com.ruoyi.demo.mapper.TestDemoMapper;
|
||||
import com.ruoyi.demo.service.ITestDemoService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测试单表Service业务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class TestDemoServiceImpl implements ITestDemoService {
|
||||
|
||||
private final TestDemoMapper baseMapper;
|
||||
|
||||
@Override
|
||||
public TestDemoVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
|
||||
Page<TestDemoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义分页查询
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
|
||||
Page<TestDemoVo> result = baseMapper.customPageList(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TestDemoVo> queryList(TestDemoBo bo) {
|
||||
return baseMapper.selectVoList(buildQueryWrapper(bo));
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<TestDemo> buildQueryWrapper(TestDemoBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<TestDemo> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue());
|
||||
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
|
||||
TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean insertByBo(TestDemoBo bo) {
|
||||
TestDemo add = BeanUtil.toBean(bo, TestDemo.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateByBo(TestDemoBo bo) {
|
||||
TestDemo update = BeanUtil.toBean(bo, TestDemo.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*
|
||||
* @param entity 实体类数据
|
||||
*/
|
||||
private void validEntityBeforeSave(TestDemo entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean saveBatch(List<TestDemo> list) {
|
||||
return baseMapper.insertBatch(list);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.ruoyi.demo.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.demo.domain.TestTree;
|
||||
import com.ruoyi.demo.domain.bo.TestTreeBo;
|
||||
import com.ruoyi.demo.domain.vo.TestTreeVo;
|
||||
import com.ruoyi.demo.mapper.TestTreeMapper;
|
||||
import com.ruoyi.demo.service.ITestTreeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 测试树表Service业务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2021-07-26
|
||||
*/
|
||||
// @DS("slave") // 切换从库查询
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class TestTreeServiceImpl implements ITestTreeService {
|
||||
|
||||
private final TestTreeMapper baseMapper;
|
||||
|
||||
@Override
|
||||
public TestTreeVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
// @DS("slave") // 切换从库查询
|
||||
@Override
|
||||
public List<TestTreeVo> queryList(TestTreeBo bo) {
|
||||
LambdaQueryWrapper<TestTree> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<TestTree> buildQueryWrapper(TestTreeBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<TestTree> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTreeName()), TestTree::getTreeName, bo.getTreeName());
|
||||
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
|
||||
TestTree::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean insertByBo(TestTreeBo bo) {
|
||||
TestTree add = BeanUtil.toBean(bo, TestTree.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateByBo(TestTreeBo bo) {
|
||||
TestTree update = BeanUtil.toBean(bo, TestTree.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*
|
||||
* @param entity 实体类数据
|
||||
*/
|
||||
private void validEntityBeforeSave(TestTree entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
package com.ruoyi.demo.service.impl;
|
@ -0,0 +1 @@
|
||||
package com.ruoyi.demo.service;
|
BIN
ruoyi-modules/ruoyi-demo/src/main/resources/excel/单列表.xlsx
Normal file
BIN
ruoyi-modules/ruoyi-demo/src/main/resources/excel/单列表.xlsx
Normal file
Binary file not shown.
BIN
ruoyi-modules/ruoyi-demo/src/main/resources/excel/多列表.xlsx
Normal file
BIN
ruoyi-modules/ruoyi-demo/src/main/resources/excel/多列表.xlsx
Normal file
Binary file not shown.
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.demo.mapper.TestDemoMapper">
|
||||
|
||||
<select id="customPageList" resultType="com.ruoyi.demo.domain.vo.TestDemoVo">
|
||||
SELECT * FROM test_demo ${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.demo.mapper.TestTreeMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,3 @@
|
||||
java包使用 `.` 分割 resource 目录使用 `/` 分割
|
||||
<br>
|
||||
此文件目的 防止文件夹粘连找不到 `xml` 文件
|
Reference in New Issue
Block a user