init
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
FROM bladex/alpine-java:openjdk17_cn_slim
|
||||
|
||||
LABEL maintainer="bladejava@qq.com"
|
||||
|
||||
RUN mkdir -p /blade/desk
|
||||
|
||||
WORKDIR /blade/desk
|
||||
|
||||
EXPOSE 8105
|
||||
|
||||
COPY ./target/blade-demo.jar ./app.jar
|
||||
|
||||
ENTRYPOINT ["java", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
|
||||
@@ -0,0 +1,19 @@
|
||||
#自定义配置
|
||||
demo:
|
||||
name: demo-name
|
||||
|
||||
#放行配置
|
||||
blade:
|
||||
secure:
|
||||
skip-url:
|
||||
- /demo/**
|
||||
datasource:
|
||||
demo:
|
||||
master:
|
||||
url: jdbc:mysql://localhost:3306/bladex?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: root
|
||||
slave:
|
||||
url: jdbc:mysql://localhost:3306/bladex_slave?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: root
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-service</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>blade-demo</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- Boot核心依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-boot</artifactId>
|
||||
</dependency>
|
||||
<!-- 动态数据源依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-db-dynamic</artifactId>
|
||||
</dependency>
|
||||
<!-- Swagger依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-swagger</artifactId>
|
||||
</dependency>
|
||||
<!-- 对象存储依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-oss</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
</dependency>
|
||||
<!-- 业务编排依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-liteflow</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-literule</artifactId>
|
||||
</dependency>
|
||||
<!-- 工程自定义业务api -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-demo-api</artifactId>
|
||||
</dependency>
|
||||
<!-- 测试依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- 自动装配依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-auto</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>${docker.fabric.skip}</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo;
|
||||
|
||||
import org.springblade.core.cloud.client.BladeCloudApplication;
|
||||
import org.springblade.core.launch.BladeApplication;
|
||||
import org.springblade.core.launch.constant.AppConstant;
|
||||
|
||||
/**
|
||||
* Demo启动器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@BladeCloudApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BladeApplication.run(AppConstant.APPLICATION_DEMO_NAME, DemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.config;
|
||||
|
||||
|
||||
import com.example.demo.props.DemoProperties;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 配置feign、mybatis包名、properties
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ComponentScan({"org.springblade", "com.example"})
|
||||
@EnableFeignClients({"org.springblade", "com.example"})
|
||||
@MapperScan({"org.springblade.**.mapper.**", "com.example.**.mapper.**"})
|
||||
@EnableConfigurationProperties(DemoProperties.class)
|
||||
public class DemoConfiguration {
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.controller;
|
||||
|
||||
import com.example.demo.props.DemoProperties;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Demo控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RefreshScope
|
||||
@RestController
|
||||
@RequestMapping("demo")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "配置接口", description = "即时刷新配置")
|
||||
public class DemoController {
|
||||
|
||||
/**
|
||||
* 需要导入blade-demo-dev.yaml文件至nacos
|
||||
*/
|
||||
@Value("${demo.name:1}")
|
||||
private String name;
|
||||
|
||||
private final DemoProperties properties;
|
||||
|
||||
|
||||
@GetMapping("name")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@GetMapping("name-by-props")
|
||||
public String getNameByProps() {
|
||||
return properties.getName();
|
||||
}
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.controller;
|
||||
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
import com.example.demo.service.IDynamicService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 多数据源
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("dynamic")
|
||||
@Tag(name = "多数据源接口", description = "多数据源")
|
||||
public class DynamicController {
|
||||
|
||||
private final IDynamicService dynamicService;
|
||||
|
||||
/**
|
||||
* master列表
|
||||
*/
|
||||
@GetMapping("/master-list")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "master列表", description = "master列表")
|
||||
public R<List<Notice>> masterList() {
|
||||
List<Notice> list = dynamicService.masterList();
|
||||
return R.data(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* slave列表
|
||||
*/
|
||||
@GetMapping("/slave-list")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "slave列表", description = "slave列表")
|
||||
public R<List<Notice>> slaveList() {
|
||||
List<Notice> list = dynamicService.slaveList();
|
||||
return R.data(list);
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.example.demo.controller;
|
||||
|
||||
import com.example.demo.rule.liteflow.context.BizContext;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.tool.jackson.JsonUtil;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* LiteFlowController
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("liteflow")
|
||||
@Tag(name = "LiteFlow接口", description = "LiteFlow")
|
||||
public class LiteFlowController {
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
@GetMapping("/test")
|
||||
public String test() {
|
||||
// 构建上下文
|
||||
BizContext bizContext = new BizContext();
|
||||
bizContext.setId(1L);
|
||||
bizContext.setName("测试名称");
|
||||
bizContext.setCategory(1);
|
||||
bizContext.setIsPublish(Boolean.TRUE);
|
||||
// 启动 demoChain 的规则引擎
|
||||
LiteflowResponse resp = flowExecutor.execute2Resp("demoChain", null, bizContext);
|
||||
if (resp.isSuccess()) {
|
||||
BizContext contextBean = resp.getContextBean(BizContext.class);
|
||||
return JsonUtil.toJson(contextBean);
|
||||
} else {
|
||||
return "fail";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package com.example.demo.controller;
|
||||
|
||||
import com.example.demo.rule.literule.context.Address;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.engine.RuleEngineExecutor;
|
||||
import org.springblade.core.literule.provider.LiteRuleResponse;
|
||||
import org.springblade.core.literule.provider.RuleConfig;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* LiteRuleController
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("literule")
|
||||
@Tag(name = "LiteRule接口", description = "LiteRule")
|
||||
public class LiteRuleController {
|
||||
@Resource
|
||||
private RuleEngineExecutor ruleExecutor;
|
||||
|
||||
@GetMapping("/test")
|
||||
public String test() {
|
||||
// 测试成功场景
|
||||
testSuccessCase(ruleExecutor);
|
||||
|
||||
// 测试失败场景
|
||||
testFailureCase(ruleExecutor);
|
||||
|
||||
// 测试异步执行
|
||||
testAsyncExecution(ruleExecutor);
|
||||
|
||||
return "执行完毕请查看控制台输出";
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试成功场景
|
||||
*/
|
||||
private static void testSuccessCase(RuleEngineExecutor ruleExecutor) {
|
||||
log.info("=== [1] 开始测试:正常场景 ===");
|
||||
|
||||
// 构建上下文
|
||||
OrderContext context = OrderContext.builder()
|
||||
.orderId("ORD-001")
|
||||
.amount(new BigDecimal("1200"))
|
||||
.paymentType("ALIPAY")
|
||||
.shippingAddress(Address.builder()
|
||||
.country("China")
|
||||
.province("Guangdong")
|
||||
.city("Shenzhen")
|
||||
.detail("Nanshan District")
|
||||
.build())
|
||||
.build();
|
||||
|
||||
// 构建配置
|
||||
RuleConfig config = RuleConfig.builder()
|
||||
.enableTimeMonitor(true)
|
||||
.printExecutionTime(true)
|
||||
.enableLogging(true)
|
||||
.build();
|
||||
|
||||
// 执行规则链
|
||||
LiteRuleResponse<OrderContext> response = ruleExecutor.execute(
|
||||
"orderChain",
|
||||
context,
|
||||
config
|
||||
);
|
||||
|
||||
// 处理响应
|
||||
log.info("[1.1] 规则链执行结果:{}", response.isSuccess() ? "成功" : "失败");
|
||||
log.info("[1.2] 规则链执行耗时:{}毫秒", response.getExecutionTime());
|
||||
log.info("[1.3] 订单状态:{}", response.getContext().getStatus());
|
||||
log.info("[1.4] 最终金额:{}", response.getContext().getAmount());
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试失败场景
|
||||
*/
|
||||
private static void testFailureCase(RuleEngineExecutor ruleExecutor) {
|
||||
log.info("=== [2] 开始测试:失败场景 ===");
|
||||
|
||||
// 构建上下文(缺少必要字段)
|
||||
OrderContext context = OrderContext.builder()
|
||||
.orderId("") // 空订单ID
|
||||
.amount(new BigDecimal("-100")) // 负数金额
|
||||
.paymentType("UNKNOWN") // 未知支付方式
|
||||
.shippingAddress(Address.builder()
|
||||
.country("USA")
|
||||
.province("California")
|
||||
.city("San Francisco")
|
||||
.detail("Silicon Valley")
|
||||
.build())
|
||||
.build();
|
||||
|
||||
// 执行规则链
|
||||
LiteRuleResponse<OrderContext> response = ruleExecutor.execute(
|
||||
"orderChain",
|
||||
context
|
||||
);
|
||||
|
||||
// 处理响应
|
||||
log.info("[2.1] 规则链执行结果:{}", response.isSuccess() ? "成功" : "失败");
|
||||
log.info("[2.2] 错误信息:{}", response.getContext().getErrorMessages());
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试异步执行
|
||||
*/
|
||||
private static void testAsyncExecution(RuleEngineExecutor ruleExecutor) {
|
||||
log.info("=== [3] 开始测试:异步执行 ===");
|
||||
|
||||
// 构建上下文
|
||||
OrderContext context = OrderContext.builder()
|
||||
.orderId("ORD-002")
|
||||
.amount(new BigDecimal("800"))
|
||||
.paymentType("WECHAT")
|
||||
.shippingAddress(Address.builder()
|
||||
.country("USA")
|
||||
.province("California")
|
||||
.city("San Francisco")
|
||||
.detail("Silicon Valley")
|
||||
.build())
|
||||
.build();
|
||||
|
||||
// 异步执行规则链
|
||||
ruleExecutor.executeAsync(
|
||||
"orderChain",
|
||||
context,
|
||||
Executors.newSingleThreadExecutor()
|
||||
).thenAccept(response -> {
|
||||
log.info("[3.1] 异步规则链执行完成");
|
||||
log.info("[3.2] 规则链执行结果:{}", response.isSuccess() ? "成功" : "失败");
|
||||
log.info("[3.3] 规则链执行耗时:{}毫秒", response.getExecutionTime());
|
||||
log.info("[3.4] 订单状态:{}", response.getContext().getStatus());
|
||||
log.info("[3.5] 最终金额:{}", response.getContext().getAmount());
|
||||
});
|
||||
|
||||
// 等待异步执行完成
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
import com.example.demo.service.INoticeService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.common.cache.CacheNames;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("notice")
|
||||
@AllArgsConstructor
|
||||
@Tag(name = "用户博客", description = "博客接口")
|
||||
public class NoticeController extends BladeController implements CacheNames {
|
||||
|
||||
private final INoticeService noticeService;
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "详情", description = "传入notice")
|
||||
public R<Notice> detail(Notice notice) {
|
||||
Notice detail = noticeService.getOne(Condition.getQueryWrapper(notice));
|
||||
return R.data(detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@Parameters({
|
||||
@Parameter(name = "category", description = "公告类型", in = ParameterIn.QUERY, schema = @Schema(type = "integer")),
|
||||
@Parameter(name = "title", description = "公告标题", in = ParameterIn.QUERY, schema = @Schema(type = "string"))
|
||||
})
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "分页", description = "传入notice")
|
||||
public R<IPage<Notice>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> notice, Query query) {
|
||||
IPage<Notice> pages = noticeService.page(Condition.getPage(query), Condition.getQueryWrapper(notice, Notice.class));
|
||||
return R.data(pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
@PostMapping("/save")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "新增", description = "传入notice")
|
||||
public R save(@RequestBody Notice notice) {
|
||||
return R.status(noticeService.save(notice));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "修改", description = "传入notice")
|
||||
public R update(@RequestBody Notice notice) {
|
||||
return R.status(noticeService.updateById(notice));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "新增或修改", description = "传入notice")
|
||||
public R submit(@RequestBody Notice notice) {
|
||||
return R.status(noticeService.saveOrUpdate(notice));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "逻辑删除", description = "传入notice")
|
||||
public R remove(@ApiParam(value = "主键集合") @RequestParam String ids) {
|
||||
boolean temp = noticeService.deleteLogic(Func.toLongList(ids));
|
||||
return R.status(temp);
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.example.demo.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.boot.file.LocalFile;
|
||||
import org.springblade.core.oss.MinioTemplate;
|
||||
import org.springblade.core.oss.model.BladeFile;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* UploadController
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/notice/upload")
|
||||
@Tag(name = "对象存储接口", description = "oss上传测试")
|
||||
public class UploadController extends BladeController {
|
||||
|
||||
private final MinioTemplate minioTemplate;
|
||||
|
||||
/**
|
||||
* minio上传demo
|
||||
*
|
||||
* @param file 上传文件
|
||||
* @return BladeFile
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("put-object")
|
||||
public R<BladeFile> putMinioObject(@RequestParam MultipartFile file) {
|
||||
BladeFile bladeFile = minioTemplate.putFile(file);
|
||||
return R.data(bladeFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地文件
|
||||
*
|
||||
* @param file 上传文件
|
||||
* @return LocalFile
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("put-local-object")
|
||||
public R<LocalFile> putLocalObject(@RequestParam MultipartFile file) {
|
||||
LocalFile localFile = getFile(file);
|
||||
localFile.transfer();
|
||||
return R.data(localFile);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.feign;
|
||||
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
import com.example.demo.mapper.NoticeMapper;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Notice Feign
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Hidden
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
public class NoticeClient implements INoticeClient {
|
||||
|
||||
private final NoticeMapper mapper;
|
||||
|
||||
@Override
|
||||
@GetMapping(TOP)
|
||||
public R<List<Notice>> top(Integer number) {
|
||||
return R.data(mapper.topList(number));
|
||||
}
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.launcher;
|
||||
|
||||
import org.springblade.core.auto.service.AutoService;
|
||||
import org.springblade.core.launch.constant.NacosConstant;
|
||||
import org.springblade.core.launch.service.LauncherService;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 启动参数拓展
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@AutoService(LauncherService.class)
|
||||
public class DemoLauncherServiceImpl implements LauncherService {
|
||||
|
||||
@Override
|
||||
public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) {
|
||||
Properties props = System.getProperties();
|
||||
// 指定注册配置信息
|
||||
props.setProperty("spring.config.import", String.join(",",
|
||||
NacosConstant.dataId(),
|
||||
NacosConstant.dataId(profile),
|
||||
NacosConstant.dataId(appName, profile),
|
||||
NacosConstant.dataId("blade-example", profile))
|
||||
);
|
||||
// 指定注册IP
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.ip", "127.0.0.1");
|
||||
// 指定注册端口
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.port", "8200");
|
||||
// 自定义命名空间
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.config.namespace", LauncherConstant.NACOS_NAMESPACE);
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.namespace", LauncherConstant.NACOS_NAMESPACE);
|
||||
// 自定义分组
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.config.group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface NoticeMapper extends BaseMapper<Notice> {
|
||||
|
||||
/**
|
||||
* 前N条数据
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
List<Notice> topList(Integer number);
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
* @param page
|
||||
* @param notice
|
||||
* @return
|
||||
*/
|
||||
List<Notice> selectNoticePage(IPage page, Notice notice);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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.example.demo.mapper.NoticeMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="noticeResultMap" type="com.example.demo.pojo.entity.Notice">
|
||||
<result column="id" property="id"/>
|
||||
<result column="create_user" property="createUser"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_user" property="updateUser"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
<result column="release_time" property="releaseTime"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="content" property="content"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="baseColumnList">
|
||||
select id,
|
||||
create_user AS createUser,
|
||||
create_time AS createTime,
|
||||
update_user AS updateUser,
|
||||
update_time AS updateTime,
|
||||
status,
|
||||
is_deleted AS isDeleted,
|
||||
title, content
|
||||
</sql>
|
||||
|
||||
<select id="topList" resultMap="noticeResultMap">
|
||||
select * from blade_notice limit #{number}
|
||||
</select>
|
||||
|
||||
<select id="selectNoticePage" resultMap="noticeResultMap">
|
||||
select * from blade_notice where title like concat(concat('%', #{notice.title}), '%') and is_deleted = 0
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.example.demo.props;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* DemoProperties
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "demo")
|
||||
public class DemoProperties {
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.rule.liteflow;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
/**
|
||||
* A业务
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteflowComponent(id = "abizRule", name = "A业务")
|
||||
public class AbizRule extends NodeComponent {
|
||||
@Override
|
||||
public void process() throws Exception {
|
||||
|
||||
log.info("A业务执行完毕");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.rule.liteflow;
|
||||
|
||||
import com.example.demo.rule.liteflow.context.BizContext;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
/**
|
||||
* A业务
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteflowComponent(id = "bbizRule", name = "B业务")
|
||||
public class BbizRule extends NodeSwitchComponent {
|
||||
|
||||
@Override
|
||||
public String processSwitch() throws Exception {
|
||||
// 获取上下文
|
||||
BizContext contextBean = this.getContextBean(BizContext.class);
|
||||
// 获取条件
|
||||
Boolean isPublish = contextBean.getIsPublish();
|
||||
log.info("B业务执行判断");
|
||||
// 进行节点判断
|
||||
if (isPublish) {
|
||||
return "cbizRule";
|
||||
} else {
|
||||
return "dbizRule";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.rule.liteflow;
|
||||
|
||||
import com.example.demo.rule.liteflow.context.BizContext;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
/**
|
||||
* A业务
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteflowComponent(id = "cbizRule", name = "C业务")
|
||||
public class CbizRule extends NodeComponent {
|
||||
@Override
|
||||
public void process() throws Exception {
|
||||
// 获取上下文
|
||||
BizContext contextBean = this.getContextBean(BizContext.class);
|
||||
// 修改上下文
|
||||
contextBean.setName(contextBean.getName() + "-> C");
|
||||
|
||||
log.info("C业务执行完毕");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.rule.liteflow;
|
||||
|
||||
import com.example.demo.rule.liteflow.context.BizContext;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
/**
|
||||
* A业务
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteflowComponent(id = "dbizRule", name = "D业务")
|
||||
public class DbizRule extends NodeComponent {
|
||||
@Override
|
||||
public void process() throws Exception {
|
||||
// 获取上下文
|
||||
BizContext contextBean = this.getContextBean(BizContext.class);
|
||||
// 修改上下文
|
||||
contextBean.setName(contextBean.getName() + "-> D");
|
||||
|
||||
log.info("D业务执行完毕");
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.example.demo.rule.liteflow.context;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 上下文类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class BizContext {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer category;
|
||||
|
||||
private Boolean isPublish;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.example.demo.rule.literule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.annotation.LiteRuleComponent;
|
||||
import org.springblade.core.literule.core.RuleComponent;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
|
||||
/**
|
||||
* AlipayRule
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteRuleComponent(id = "alipayRule")
|
||||
public class AlipayRule extends RuleComponent {
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
OrderContext context = getContextBean(OrderContext.class);
|
||||
log.info("[规则4-支付宝] 处理支付宝支付:订单号={}, 金额={}",
|
||||
context.getOrderId(), context.getAmount());
|
||||
|
||||
// 模拟支付处理
|
||||
context.setStatus("PAID");
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.example.demo.rule.literule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.annotation.LiteRuleComponent;
|
||||
import org.springblade.core.literule.core.RuleComponent;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
|
||||
/**
|
||||
* BankPayRule
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteRuleComponent(id = "bankPayRule")
|
||||
public class BankPayRule extends RuleComponent {
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
OrderContext context = getContextBean(OrderContext.class);
|
||||
log.info("[规则4-银行] 处理银行卡支付:订单号={}, 金额={}",
|
||||
context.getOrderId(), context.getAmount());
|
||||
|
||||
// 模拟支付处理
|
||||
context.setStatus("PAID");
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.example.demo.rule.literule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.annotation.LiteRuleComponent;
|
||||
import org.springblade.core.literule.core.RuleComponent;
|
||||
import com.example.demo.rule.literule.context.Address;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* OrderAmountRule
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteRuleComponent(id = "orderAmountRule")
|
||||
public class OrderAmountRule extends RuleComponent {
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
OrderContext context = getContextBean(OrderContext.class);
|
||||
BigDecimal amount = context.getAmount();
|
||||
|
||||
// 计算折扣
|
||||
BigDecimal discount = calculateDiscount(amount);
|
||||
|
||||
// 计算运费
|
||||
BigDecimal shipping = calculateShipping(context.getShippingAddress());
|
||||
|
||||
// 更新订单金额
|
||||
BigDecimal finalAmount = amount.subtract(discount).add(shipping);
|
||||
context.setAmount(finalAmount);
|
||||
|
||||
log.info("[规则2] 订单金额计算完成:{} = {} - {} + {}", finalAmount, amount, discount, shipping);
|
||||
}
|
||||
|
||||
private BigDecimal calculateDiscount(BigDecimal amount) {
|
||||
// 折扣计算逻辑:金额大于1000打9折
|
||||
if (amount.compareTo(new BigDecimal("1000")) > 0) {
|
||||
return amount.multiply(new BigDecimal("0.1"));
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private BigDecimal calculateShipping(Address address) {
|
||||
// 运费计算逻辑:根据地址计算
|
||||
if ("China".equals(address.getCountry())) {
|
||||
return new BigDecimal("10");
|
||||
}
|
||||
return new BigDecimal("50");
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.example.demo.rule.literule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.annotation.LiteRuleComponent;
|
||||
import org.springblade.core.literule.core.RuleComponent;
|
||||
import com.example.demo.rule.literule.context.Address;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* OrderValidateRule
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteRuleComponent(id = "orderValidateRule")
|
||||
public class OrderValidateRule extends RuleComponent {
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
OrderContext context = getContextBean(OrderContext.class);
|
||||
|
||||
// 校验订单ID
|
||||
if (isEmpty(context.getOrderId())) {
|
||||
context.addError("订单ID不能为空");
|
||||
log.info("[规则1] 订单校验不通过:{}", context.getErrorMessages());
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验金额
|
||||
if (context.getAmount() == null || context.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
context.addError("订单金额无效");
|
||||
log.info("[规则1] 订单校验不通过:{}", context.getErrorMessages());
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验地址
|
||||
Address address = context.getShippingAddress();
|
||||
if (address == null) {
|
||||
context.addError("收货地址不能为空");
|
||||
log.info("[规则1] 订单校验不通过:{}", context.getErrorMessages());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("[规则1] 订单校验通过:{}", context.getOrderId());
|
||||
}
|
||||
|
||||
private boolean isEmpty(String str) {
|
||||
return str == null || str.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.example.demo.rule.literule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.annotation.LiteRuleComponent;
|
||||
import org.springblade.core.literule.core.RuleSwitchComponent;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PaymentRouteRule
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteRuleComponent(id = "paymentSwitchRule")
|
||||
public class PaymentSwitchRule extends RuleSwitchComponent {
|
||||
|
||||
private static final Map<String, String> PAYMENT_RULE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
PAYMENT_RULE_MAP.put("ALIPAY", "alipayRule");
|
||||
PAYMENT_RULE_MAP.put("WECHAT", "wechatPayRule");
|
||||
PAYMENT_RULE_MAP.put("BANK", "bankPayRule");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> process() {
|
||||
OrderContext context = getContextBean(OrderContext.class);
|
||||
String paymentType = context.getPaymentType();
|
||||
|
||||
log.info("[规则3] 支付路由选择:{}", paymentType);
|
||||
|
||||
String payName = PAYMENT_RULE_MAP.get(paymentType);
|
||||
if (payName != null) {
|
||||
return Collections.singletonList(payName);
|
||||
} else {
|
||||
context.addError("不支持的支付方式:" + paymentType);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.example.demo.rule.literule;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.literule.annotation.LiteRuleComponent;
|
||||
import org.springblade.core.literule.core.RuleComponent;
|
||||
import com.example.demo.rule.literule.context.OrderContext;
|
||||
|
||||
/**
|
||||
* WechatPayRule
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Slf4j
|
||||
@LiteRuleComponent(id = "wechatPayRule")
|
||||
public class WechatPayRule extends RuleComponent {
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
OrderContext context = getContextBean(OrderContext.class);
|
||||
log.info("[规则4-微信] 处理微信支付:订单号={}, 金额={}",
|
||||
context.getOrderId(), context.getAmount());
|
||||
|
||||
// 模拟支付处理
|
||||
context.setStatus("PAID");
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.example.demo.rule.literule.builder;
|
||||
|
||||
import org.springblade.core.literule.annotation.RuleEngineComponent;
|
||||
import org.springblade.core.literule.builder.LiteRule;
|
||||
import org.springblade.core.literule.builder.RuleBuilder;
|
||||
import org.springblade.core.literule.builder.chain.RuleChain;
|
||||
|
||||
/**
|
||||
* 订单处理规则链构建器
|
||||
*/
|
||||
@RuleEngineComponent(id = "orderChain")
|
||||
public class OrderRuleBuilder implements RuleBuilder {
|
||||
@Override
|
||||
public RuleChain build() {
|
||||
// 创建支付处理分支规则
|
||||
RuleChain paymentRule = LiteRule.SWITCH("paymentSwitchRule")
|
||||
.TO("alipayRule", "wechatPayRule", "bankPayRule")
|
||||
.build();
|
||||
|
||||
// 创建完整规则链
|
||||
return LiteRule.THEN("orderValidateRule", "orderAmountRule")
|
||||
.THEN(paymentRule)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.example.demo.rule.literule.context;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 地址实体
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Address {
|
||||
private String country;
|
||||
private String province;
|
||||
private String city;
|
||||
private String detail;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.example.demo.rule.literule.context;
|
||||
|
||||
import lombok.*;
|
||||
import org.springblade.core.literule.core.RuleContextComponent;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 订单上下文
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class OrderContext extends RuleContextComponent {
|
||||
private String orderId;
|
||||
private BigDecimal amount;
|
||||
private String paymentType;
|
||||
private String status;
|
||||
private Address shippingAddress;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.service;
|
||||
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IDynamicService extends BaseService<Notice> {
|
||||
|
||||
/**
|
||||
* master数据源的列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Notice> masterList();
|
||||
|
||||
/**
|
||||
* slave数据源的列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Notice> slaveList();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface INoticeService extends BaseService<Notice> {
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
* @param page
|
||||
* @param notice
|
||||
* @return
|
||||
*/
|
||||
IPage<Notice> selectNoticePage(IPage<Notice> page, Notice notice);
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.example.demo.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
import com.example.demo.mapper.NoticeMapper;
|
||||
import com.example.demo.service.IDynamicService;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DynamicServiceImpl
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
public class DynamicServiceImpl extends BaseServiceImpl<NoticeMapper, Notice> implements IDynamicService {
|
||||
|
||||
@Override
|
||||
public List<Notice> masterList() {
|
||||
return this.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
@DS("slave")
|
||||
public List<Notice> slaveList() {
|
||||
return this.list();
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package com.example.demo.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.example.demo.mapper.NoticeMapper;
|
||||
import com.example.demo.service.INoticeService;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import com.example.demo.pojo.entity.Notice;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
public class NoticeServiceImpl extends BaseServiceImpl<NoticeMapper, Notice> implements INoticeService {
|
||||
|
||||
@Override
|
||||
public IPage<Notice> selectNoticePage(IPage<Notice> page, Notice notice) {
|
||||
return page.setRecords(baseMapper.selectNoticePage(page, notice));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#服务器端口
|
||||
server:
|
||||
port: 8200
|
||||
|
||||
#Spring配置
|
||||
spring:
|
||||
datasource:
|
||||
#主数据源信息
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: ${blade.datasource.demo.master.url}
|
||||
username: ${blade.datasource.demo.master.username}
|
||||
password: ${blade.datasource.demo.master.password}
|
||||
#动态数据源信息
|
||||
dynamic:
|
||||
druid:
|
||||
#通用校验配置
|
||||
validation-query: select 1
|
||||
#设置默认的数据源或者数据源组,默认值即为master
|
||||
primary: master
|
||||
datasource:
|
||||
slave:
|
||||
druid:
|
||||
#独立校验配置
|
||||
validation-query: select 1
|
||||
#oracle校验
|
||||
#validation-query: select 1 from dual
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: ${blade.datasource.demo.slave.url}
|
||||
username: ${blade.datasource.demo.slave.username}
|
||||
password: ${blade.datasource.demo.slave.password}
|
||||
@@ -0,0 +1,31 @@
|
||||
#服务器端口
|
||||
server:
|
||||
port: 8200
|
||||
|
||||
#数据源配置
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: ${blade.datasource.prod.url}
|
||||
# username: ${blade.datasource.prod.username}
|
||||
# password: ${blade.datasource.prod.password}
|
||||
|
||||
spring:
|
||||
#排除DruidDataSourceAutoConfigure
|
||||
autoconfigure:
|
||||
exclude: com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure
|
||||
datasource:
|
||||
dynamic:
|
||||
druid:
|
||||
proxy-filters:
|
||||
- sqlLogInterceptor
|
||||
#设置默认的数据源或者数据源组,默认值即为master
|
||||
primary: master
|
||||
datasource:
|
||||
master:
|
||||
url: ${blade.datasource.demo.master.url}
|
||||
username: ${blade.datasource.demo.master.username}
|
||||
password: ${blade.datasource.demo.master.password}
|
||||
slave:
|
||||
url: ${blade.datasource.demo.slave.url}
|
||||
username: ${blade.datasource.demo.slave.username}
|
||||
password: ${blade.datasource.demo.slave.password}
|
||||
@@ -0,0 +1,31 @@
|
||||
#服务器端口
|
||||
server:
|
||||
port: 8200
|
||||
|
||||
#数据源配置
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: ${blade.datasource.test.url}
|
||||
# username: ${blade.datasource.test.username}
|
||||
# password: ${blade.datasource.test.password}
|
||||
|
||||
spring:
|
||||
#排除DruidDataSourceAutoConfigure
|
||||
autoconfigure:
|
||||
exclude: com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure
|
||||
datasource:
|
||||
url: ${blade.datasource.test.url}
|
||||
username: ${blade.datasource.test.username}
|
||||
password: ${blade.datasource.test.password}
|
||||
dynamic:
|
||||
druid:
|
||||
proxy-filters:
|
||||
- sqlLogInterceptor
|
||||
#设置默认的数据源或者数据源组,默认值即为master
|
||||
primary: master
|
||||
# datasource:
|
||||
# master:
|
||||
# slave:
|
||||
# url: ${blade.datasource.test.slave.url}
|
||||
# username: ${blade.datasource.test.slave.username}
|
||||
# password: ${blade.datasource.test.slave.password}
|
||||
@@ -0,0 +1,29 @@
|
||||
#mybatis-plus配置
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:com/example/**/mapper/*Mapper.xml
|
||||
#实体扫描,多个package用逗号或者分号分隔
|
||||
typeAliasesPackage: com.example.**.entity
|
||||
|
||||
#swagger扫描路径配置
|
||||
swagger:
|
||||
base-packages:
|
||||
- org.springblade
|
||||
- com.example
|
||||
|
||||
#oss配置
|
||||
oss:
|
||||
enabled: true
|
||||
name: minio
|
||||
tenant-mode: false
|
||||
endpoint: http://127.0.0.1:9000
|
||||
access-key: D99KGE6ZTQXSATTJWU24
|
||||
secret-key: QyVqGnhIQQE734UYSUFlGOZViE6+ZlDEfUG3NjhJ
|
||||
bucket-name: bladex
|
||||
|
||||
#blade配置
|
||||
blade:
|
||||
#本地文件上传
|
||||
file:
|
||||
remote-mode: true
|
||||
upload-domain: http://localhost:8999
|
||||
remote-path: /usr/share/nginx/html
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="demoChain">
|
||||
THEN(
|
||||
abizRule,
|
||||
SWITCH(bbizRule).TO(cbizRule, dbizRule)
|
||||
);
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.springblade.test;
|
||||
|
||||
import com.example.demo.DemoApplication;
|
||||
import com.example.demo.service.INoticeService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springblade.core.test.BladeBootTest;
|
||||
import org.springblade.core.test.BladeSpringExtension;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
/**
|
||||
* Blade单元测试
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@ExtendWith(BladeSpringExtension.class)
|
||||
@SpringBootTest(classes = DemoApplication.class)
|
||||
@BladeBootTest(appName = "blade-demo", profile = "test", enableLoader = true)
|
||||
public class BladeDemoTest {
|
||||
|
||||
@Autowired
|
||||
private INoticeService noticeService;
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
long count = noticeService.count();
|
||||
System.out.println("notice数量:[" + count + "] 个");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
package org.springblade.test;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springblade.core.tool.jackson.JsonUtil;
|
||||
import org.springblade.core.tool.jackson.Sensitive;
|
||||
import org.springblade.core.tool.sensitive.SensitiveConfig;
|
||||
import org.springblade.core.tool.sensitive.SensitiveType;
|
||||
import org.springblade.core.tool.sensitive.SensitiveUtil;
|
||||
import org.springblade.core.tool.sensitive.SensitiveWord;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* SensitiveUtil使用示例
|
||||
* 展示各种使用场景和数据脱敏效果
|
||||
*
|
||||
* @author BladeX
|
||||
*/
|
||||
public class SensitiveTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 演示所有使用场景
|
||||
demonstrateBasicUsage();
|
||||
demonstrateCustomConfig();
|
||||
demonstrateSingleType();
|
||||
demonstrateMultipleTypes();
|
||||
demonstrateCustomRegex();
|
||||
demonstrateSensitiveWords();
|
||||
demonstrateComplexExample();
|
||||
demonstrateJacksonSerializer();
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. 基础用法演示 - 使用默认配置
|
||||
*/
|
||||
private static void demonstrateBasicUsage() {
|
||||
System.out.println("\n=== 1.基础用法演示 ===");
|
||||
|
||||
String content = "客户信息:\n" +
|
||||
"手机号: 13812345678\n" +
|
||||
"邮箱: test@example.com\n" +
|
||||
"身份证: 310123199001011234\n" +
|
||||
"银行卡: 6222021234567890123";
|
||||
|
||||
String result = SensitiveUtil.process(content);
|
||||
System.out.println("原始内容:\n" + content);
|
||||
System.out.println("\n处理后:\n" + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. 自定义配置演示
|
||||
*/
|
||||
private static void demonstrateCustomConfig() {
|
||||
System.out.println("\n=== 2.自定义配置演示 ===");
|
||||
|
||||
// 创建自定义配置
|
||||
SensitiveConfig config = SensitiveConfig.builder()
|
||||
.sensitiveTypes(EnumSet.of(
|
||||
SensitiveType.MOBILE,
|
||||
SensitiveType.EMAIL
|
||||
))
|
||||
.sensitiveWords(EnumSet.of(
|
||||
SensitiveWord.SECURE,
|
||||
SensitiveWord.AUTHENTICATION
|
||||
))
|
||||
.customPatterns(Map.of(
|
||||
"CustomerId", Pattern.compile("(?<=CustomerID:)\\s*\\w+"),
|
||||
"ProjectCode", Pattern.compile("(?<=ProjectCode:)\\s*\\w+")
|
||||
))
|
||||
.processLineByLine(true)
|
||||
.replacement("***已隐藏***")
|
||||
.build();
|
||||
|
||||
String content = "用户数据:\n" +
|
||||
"手机: 13812345678\n" +
|
||||
"CustomerID: USER123456\n" +
|
||||
"ProjectCode: PRJ789\n" +
|
||||
"password=admin123\n" +
|
||||
"token=abcdef";
|
||||
|
||||
// 转换为LogVO示例
|
||||
LogVO logVO = SensitiveUtil.process(content, config, data -> {
|
||||
LogVO dto = new LogVO();
|
||||
dto.setContent(data);
|
||||
dto.setTimestamp(System.currentTimeMillis());
|
||||
return dto;
|
||||
});
|
||||
|
||||
System.out.println("原始内容:\n" + content);
|
||||
System.out.println("\n处理后:\n" + logVO.getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. 单个敏感类型处理演示
|
||||
*/
|
||||
private static void demonstrateSingleType() {
|
||||
System.out.println("\n=== 3.单个敏感类型处理演示 ===");
|
||||
|
||||
String content = "联系方式:13812345678,邮箱:test@example.com";
|
||||
String result = SensitiveUtil.process(content, SensitiveType.MOBILE);
|
||||
|
||||
System.out.println("原始内容:" + content);
|
||||
System.out.println("处理后:" + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 4. 多个敏感类型处理演示
|
||||
*/
|
||||
private static void demonstrateMultipleTypes() {
|
||||
System.out.println("\n=== 4.多个敏感类型处理演示 ===");
|
||||
|
||||
String content = "用户资料:\n" +
|
||||
"手机:13812345678\n" +
|
||||
"银行卡:6222021234567890123";
|
||||
|
||||
UserVO userVO = SensitiveUtil.process(content, EnumSet.of(
|
||||
SensitiveType.MOBILE,
|
||||
SensitiveType.BANK_CARD
|
||||
), data -> {
|
||||
UserVO vo = new UserVO();
|
||||
vo.setUserInfo(data);
|
||||
return vo;
|
||||
});
|
||||
|
||||
System.out.println("原始内容:\n" + content);
|
||||
System.out.println("\n处理后:\n" + userVO.getUserInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* 5. 自定义正则处理演示
|
||||
*/
|
||||
private static void demonstrateCustomRegex() {
|
||||
System.out.println("\n=== 5.自定义正则处理演示 ===");
|
||||
|
||||
// 简单版本
|
||||
String simpleContent = "订单号:ORDER20250101001";
|
||||
String simpleResult = SensitiveUtil.processWithRegex(
|
||||
simpleContent,
|
||||
"ORDER\\d{8}\\d{3}"
|
||||
);
|
||||
|
||||
System.out.println("简单版本:");
|
||||
System.out.println("原始内容:" + simpleContent);
|
||||
System.out.println("处理后:" + simpleResult);
|
||||
|
||||
// 自定义替换符版本
|
||||
String customContent = "项目编号:PRJ20250101";
|
||||
String customResult = SensitiveUtil.processWithRegex(
|
||||
customContent,
|
||||
"PRJ\\d{8}",
|
||||
"PRJ********"
|
||||
);
|
||||
|
||||
System.out.println("\n自定义替换符版本:");
|
||||
System.out.println("原始内容:" + customContent);
|
||||
System.out.println("处理后:" + customResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 6. 敏感词处理演示
|
||||
*/
|
||||
private static void demonstrateSensitiveWords() {
|
||||
System.out.println("\n=== 6.敏感词处理演示 ===");
|
||||
|
||||
String content = "系统配置:\n" +
|
||||
"password=admin123\n" +
|
||||
"api_key=sk_test_123456\n" +
|
||||
"secret=my_secret_key\n" +
|
||||
"test=my_test_key";
|
||||
|
||||
List<String> sensitiveWords = Arrays.asList("password", "api_key", "secret");
|
||||
|
||||
// 完整版本的敏感词处理
|
||||
String result = SensitiveUtil.processWithWords(
|
||||
content,
|
||||
sensitiveWords,
|
||||
"***",// 可不填
|
||||
true // 可不填
|
||||
);
|
||||
|
||||
System.out.println("原始内容:\n" + content);
|
||||
System.out.println("\n处理后:\n" + result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 7. 复杂场景示例
|
||||
*/
|
||||
private static void demonstrateComplexExample() {
|
||||
System.out.println("\n=== 7.复杂场景示例 ===");
|
||||
|
||||
String content = "API调用日志:\n" +
|
||||
"时间:2024-01-01 10:30:00\n" +
|
||||
"请求头:\n" +
|
||||
"Authorization: Bearer sk_test_123456\n" +
|
||||
"请求体:\n" +
|
||||
"{\n" +
|
||||
" \"user\": {\n" +
|
||||
" \"mobile\": \"13812345678\",\n" +
|
||||
" \"email\": \"test@example.com\",\n" +
|
||||
" \"idCard\": \"310123199001011234\",\n" +
|
||||
" \"test\": \"2333333333\"\n" +
|
||||
" },\n" +
|
||||
" \"payment\": {\n" +
|
||||
" \"cardNo\": \"6222021234567890123\",\n" +
|
||||
" \"secretKey\": \"payment_secret_123\"\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
// 创建复杂配置
|
||||
SensitiveConfig complexConfig = SensitiveConfig.builder()
|
||||
.sensitiveTypes(EnumSet.of(
|
||||
SensitiveType.MOBILE,
|
||||
SensitiveType.EMAIL,
|
||||
SensitiveType.ID_CARD
|
||||
))
|
||||
.sensitiveWords(EnumSet.allOf(SensitiveWord.class))
|
||||
.customPatterns(Map.of(
|
||||
"Bearer", Pattern.compile("Bearer\\s+[\\w-]+"),
|
||||
"SecretKey", Pattern.compile("(?<=secretKey\":\\s*\")[^\"]+")
|
||||
))
|
||||
.processLineByLine(true)
|
||||
.replacement("***")
|
||||
.build();
|
||||
|
||||
ApiLogVO apiLogVO = SensitiveUtil.process(content, complexConfig, data -> {
|
||||
ApiLogVO vo = new ApiLogVO();
|
||||
vo.setRequestLog(data);
|
||||
vo.setTimestamp(System.currentTimeMillis());
|
||||
return vo;
|
||||
});
|
||||
|
||||
System.out.println("原始内容:\n" + content);
|
||||
System.out.println("\n处理后:\n" + apiLogVO.getRequestLog());
|
||||
}
|
||||
|
||||
/**
|
||||
* 8. jackson序列化场景
|
||||
*/
|
||||
private static void demonstrateJacksonSerializer() {
|
||||
System.out.println("\n=== 8.jackson序列化场景 ===");
|
||||
|
||||
AccountVO accountVO = new AccountVO();
|
||||
accountVO.setMobile("13812345678");
|
||||
accountVO.setEmail("test@example.com");
|
||||
accountVO.setCredential("系统配置:\n" +
|
||||
"password=admin123\n" +
|
||||
"api_key=sk_test_123456\n" +
|
||||
"secret=my_secret_key\n" +
|
||||
"test=my_test");
|
||||
accountVO.setToken("Bearer password 123456");
|
||||
accountVO.setOrderId("订单号:ORDER20250101001");
|
||||
|
||||
System.out.println("原始内容:\n" + accountVO);
|
||||
System.out.println("\n处理后:\n" + JsonUtil.toJson(accountVO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据传输对象
|
||||
*/
|
||||
@Data
|
||||
static class LogVO {
|
||||
private String content;
|
||||
private long timestamp;
|
||||
}
|
||||
|
||||
@Data
|
||||
static class UserVO {
|
||||
private String userInfo;
|
||||
}
|
||||
|
||||
@Data
|
||||
static class ApiLogVO {
|
||||
private String requestLog;
|
||||
private long timestamp;
|
||||
}
|
||||
|
||||
@Data
|
||||
static class AccountVO {
|
||||
@Sensitive(type = SensitiveType.MOBILE)
|
||||
private String mobile;
|
||||
|
||||
@Sensitive(type = SensitiveType.EMAIL)
|
||||
private String email;
|
||||
|
||||
@Sensitive(word = SensitiveWord.SECURE)
|
||||
private String credential;
|
||||
|
||||
@Sensitive(words = {"password", "secret"})
|
||||
private String token;
|
||||
|
||||
@Sensitive(regex = "ORDER(.{2}).*(.{2})", replacement = "ORDER$1****$2")
|
||||
private String orderId;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.test.launcher;
|
||||
|
||||
import org.springblade.common.constant.LauncherConstant;
|
||||
import org.springblade.core.auto.service.AutoService;
|
||||
import org.springblade.core.launch.constant.NacosConstant;
|
||||
import org.springblade.core.launch.service.LauncherService;
|
||||
import org.springblade.core.launch.utils.PropsUtil;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 启动参数拓展
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@AutoService(LauncherService.class)
|
||||
public class DemoTestLauncherServiceImpl implements LauncherService {
|
||||
|
||||
@Override
|
||||
public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) {
|
||||
Properties props = System.getProperties();
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].data-id", NacosConstant.dataId("example", profile));
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].refresh", NacosConstant.NACOS_CONFIG_REFRESH);
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.server-addr", LauncherConstant.NACOS_DEV_ADDR);
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.server-addr", LauncherConstant.NACOS_DEV_ADDR);
|
||||
PropsUtil.setProperty(props, "spring.cloud.sentinel.transport.dashboard", LauncherConstant.SENTINEL_DEV_ADDR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#服务器端口
|
||||
server:
|
||||
port: 8200
|
||||
|
||||
#数据源配置
|
||||
#spring:
|
||||
# datasource:
|
||||
# url: ${blade.datasource.dev.url}
|
||||
# username: ${blade.datasource.dev.username}
|
||||
# password: ${blade.datasource.dev.password}
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
dynamic:
|
||||
druid:
|
||||
#通用校验配置
|
||||
validation-query: select 1
|
||||
#启用sql日志拦截器
|
||||
proxy-filters:
|
||||
- sqlLogInterceptor
|
||||
#设置默认的数据源或者数据源组,默认值即为master
|
||||
primary: master
|
||||
datasource:
|
||||
master:
|
||||
druid:
|
||||
#独立校验配置
|
||||
validation-query: select 1
|
||||
#oracle校验
|
||||
#validation-query: select 1 from dual
|
||||
url: ${blade.datasource.demo.master.url}
|
||||
username: ${blade.datasource.demo.master.username}
|
||||
password: ${blade.datasource.demo.master.password}
|
||||
slave:
|
||||
druid:
|
||||
#独立校验配置
|
||||
validation-query: select 1
|
||||
#oracle校验
|
||||
#validation-query: select 1 from dual
|
||||
url: ${blade.datasource.demo.slave.url}
|
||||
username: ${blade.datasource.demo.slave.username}
|
||||
password: ${blade.datasource.demo.slave.password}
|
||||
@@ -0,0 +1,10 @@
|
||||
#服务器端口
|
||||
server:
|
||||
port: 8200
|
||||
|
||||
#数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
url: ${blade.datasource.test.url}
|
||||
username: ${blade.datasource.test.username}
|
||||
password: ${blade.datasource.test.password}
|
||||
@@ -0,0 +1,21 @@
|
||||
#mybatis-plus配置
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:com/example/**/mapper/*Mapper.xml
|
||||
#实体扫描,多个package用逗号或者分号分隔
|
||||
typeAliasesPackage: com.example.**.entity
|
||||
|
||||
#swagger扫描路径配置
|
||||
swagger:
|
||||
base-packages:
|
||||
- org.springbalde
|
||||
- com.example
|
||||
|
||||
#oss配置
|
||||
oss:
|
||||
enabled: true
|
||||
name: minio
|
||||
tenant-mode: false
|
||||
endpoint: http://127.0.0.1:9000
|
||||
access-key: D99KGE6ZTQXSATTJWU24
|
||||
secret-key: QyVqGnhIQQE734UYSUFlGOZViE6+ZlDEfUG3NjhJ
|
||||
bucket-name: bladex
|
||||
Reference in New Issue
Block a user