👔 feat: 计算税额和修复包引入错误

This commit is contained in:
bunny 2025-05-18 17:33:55 +08:00
parent fb4134cc27
commit 3ce9c81757
19 changed files with 311 additions and 274 deletions

View File

@ -1,256 +0,0 @@
# Gitlab安装
完全笔记《安装GitLabel》 https://www.yuque.com/bunny-6ixda/bgxtva/wtw4x4r8kbvxwgac?singleDoc#
## Docker安装
- docker镜像
- https://hub.docker.com/r/gitlab/gitlab-ee/tags?name=17.9.6
- https://hub.docker.com/r/gitlab/gitlab-runner/tags?name=17.11.0
```bash
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt update
sudo apt upgrade
sudo apt-get install ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
sudo curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 安装docker
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 默认情况下只有root用户和docker组的用户才能运行Docker命令。我们可以将当前用户添加到docker组以避免每次使用Docker时都需要使用sudo设置完成后退出当前用户之后再进入既可
sudo usermod -aG docker $USER
# 运行docker
sudo systemctl start docker
# 安装工具
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# 重启docker
sudo service docker restart
# 重启终端生效
exit
```
配置镜像源
```bash
# 创建目录
sudo mkdir -p /etc/docker
# 写入配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker-0.unsee.tech",
"https://docker-cf.registry.cyou",
"https://docker.1panel.live"
]
}
EOF
# 重启docker服务
sudo systemctl daemon-reload && sudo systemctl restart docker
```
## 环境搭建
### 安装JDK21
```bash
# 安装JDK21
wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.deb
sudo dpkg -i jdk-21_linux-x64_bin.deb
java --version
```
### Maven 3.8.8安装
#### 安装
```bash
# 安装maven
wget https://archive.apache.org/dist/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz
sudo mkdir -p /opt/maven
sudo tar -xzf apache-maven-3.8.8-bin.tar.gz -C /opt/maven
sudo mv /opt/maven/apache-maven-3.8.8 /opt/maven/maven-3.8.8
# 修改镜像配置
cd /opt/maven/maven-3.8.8/conf
# 赋予权限修改
sudo chmod 666 settings.xml
# 编写配置
sudo vim /etc/profile
# 添加以下内容
# export PATH=$PATH:/opt/maven/maven-3.8.8/bin
# 刷新配置
source /etc/profile
mvn -V
```
#### maven的镜像
```xml
<mirror>
<id>aliyun</id>
<name>Aliyun Maven Mirror</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
```
## 安装Gitlab
```bash
# Ubuntu
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/focal/main/g/gitlab-ce/gitlab-ce_18.0.0-ce.0_amd64.deb
# dpkg
sudo dpkg -i gitlab-ce_18.0.0-ce.0_amd64.deb
```
### 编辑配置
```bash
# 编辑站点
sudo vim /etc/gitlab/gitlab.rb
```
修改下面内容
```bash
external_url 'http://192.168.95.134:3001'
```
应用配置
```bash
# 应用配置
sudo gitlab-ctl reconfigure
```
### 常用命令
```bash
# 服务控制
sudo gitlab-ctl start
sudo gitlab-ctl status
sudo gitlab-ctl stop
# 应用配置
sudo gitlab-ctl reconfigure
# 重启
sudo gitlab-ctl restart
```
### 查看密码
```bash
# 24 小时后自动删除
sudo cat /etc/gitlab/initial_root_password
```
## 安装Gitlab-Runner
```bash
# 需要 gitlab-runner-helper-images
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/focal/main/g/gitlab-runner-helper-images/gitlab-runner-helper-images_18.0.1-1_all.deb
sudo dpkg -i gitlab-runner-helper-images_18.0.1-1_all.deb
# 之后安装 gitlab-runner
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/focal/main/g/gitlab-runner/gitlab-runner_18.0.1-1_amd64.deb
sudo dpkg -i gitlab-runner_18.0.1-1_amd64.deb
```
### 先下载后安装
```bash
# Ubuntu
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/focal/main/g/gitlab-runner-helper-images/gitlab-runner-helper-images_18.0.1-1_all.deb
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/focal/main/g/gitlab-runner/gitlab-runner_18.0.1-1_amd64.deb
# dpkg
sudo dpkg -i gitlab-runner-helper-images_18.0.1-1_all.deb
sudo dpkg -i gitlab-runner_18.0.1-1_amd64.deb
```
### 配置Gitlab-Runner用户
> [!NOTE]
>
> 如果有需要清理缓存:`sudo rm -rf /opt/maven/maven-3.8.8/conf/builds/**`**
>
> gitlab-cehttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/focal/main/g/gitlab-ce/
>
> gitlab-runner-helper-imageshttps://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/focal/main/g/gitlab-runner-helper-images/
>
> gitlab-runnerhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/focal/main/g/gitlab-runner/
```bash
sudo gitlab-runner uninstall
sudo gitlab-runner install --working-directory /home/gitlab-runner --user root
sudo systemctl restart gitlab-runner
```
### 检查 GitLab Runner 配置
```bash
sudo vim /etc/gitlab-runner/config.toml
```
修改文件
```bash
[[runners]]
name = "my-runner"
executor = "shell"
shell = "bash"
user = "gitlab-runner" # 确保用户有权限
working_directory = "/home/gitlab-runner"
```
### 检查 Maven 安装目录权限
```bash
sudo chmod 777 -R /opt/maven/maven-3.8.8
sudo chmod 777 -R /opt/maven/maven-3.8.8/
sudo chown -R gitlab-runner:gitlab-runner /opt/maven/maven-3.8.8/
```
## CI/CD脚本示例
如果构建出现`pending`情况大部分情况下,是文件写错了,要么是`Gitlab-Runner`标签没写对
```yml
stages:
- build
- build-docker
- deploy
variables:
CONTAINER_NAME: "bunny-auth-server"
DOCKER_TAG: "4.0.0"
build-job:
stage: build
script:
- echo "Compiling the code..."
- mvn clean package -DskipTests
- echo "Compile complete."
- docker pull openjdk:24-ea-17-jdk-oraclelinux9
- echo "docker pull complete."
- docker build -f Dockerfile -t $CONTAINER_NAME:$DOCKER_TAG .
- echo "Application successfully deployed."
deploy-job:
stage: deploy
environment: production
script:
- echo "Deploying application..."
- docker stop $CONTAINER_NAME || true
- docker rm $CONTAINER_NAME || true
- docker run -d -p 7070:7070 -p 8000:8000 --name $CONTAINER_NAME --restart always $CONTAINER_NAME:$DOCKER_TAG
- echo "Application successfully deployed."
```

View File

@ -24,6 +24,7 @@
<properties>
<java.version>17</java.version>
<drools.version>10.0.0</drools.version>
<knife4j.version>4.5.0</knife4j.version>
</properties>
<dependencies>
<dependency>
@ -51,6 +52,14 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- knife 4 j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!-- drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-ruleunits-engine</artifactId>

View File

@ -5,9 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DroolsApplication {
public static void main(String[] args) {
SpringApplication.run(DroolsApplication.class, args);
}
}

View File

@ -0,0 +1,32 @@
package cn.bunny.drools.bean.exercise;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class CalculateTax {
/* 税前工资 */
private double wage;
/* 应纳税所得额 */
private double wagemore;
/* 税率 */
private double cess;
/* 速算扣除数 */
private double preminus;
/* 扣税额 */
private double wageminus;
/* 税后工资 */
private double actualwage;
}

View File

@ -1,14 +1,28 @@
package cn.bunny.drools.config;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException;
@Configuration
public class DroolsConfiguration {
// 指定规则文件存放的目录
private static final String RULES_PATH = "rules/exercise/";
private final KieServices kieServices = KieServices.Factory.get();
/**
* 读取单个文件内容
@ -27,4 +41,36 @@ public class DroolsConfiguration {
return container.newKieSession();
}
@Bean
@ConditionalOnMissingBean
public KieFileSystem kieFileSystem() throws IOException {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] files = resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
String path;
for (Resource file : files) {
path = RULES_PATH + file.getFilename();
kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
}
return kieFileSystem;
}
@Bean
@ConditionalOnMissingBean
public KieContainer kieContainer() throws IOException {
KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
}
@Bean
@ConditionalOnMissingBean
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
}

View File

@ -0,0 +1,40 @@
package cn.bunny.drools.controller;
import cn.bunny.drools.bean.exercise.CalculateTax;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.SneakyThrows;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = "计算税额")
@RequestMapping("/api/calculate-tax")
public class CalculateTaxController {
// @Autowired
// private DroolsConfiguration droolsConfiguration;
@SneakyThrows
@GetMapping("")
@Operation(summary = "计算税后工资")
public CalculateTax getCalculateTax(double amount) {
// KieBase kieBase = droolsConfiguration.kieBase();
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("ExerciseTax");
KieSession session = kieBase.newKieSession();
CalculateTax calculateTax = CalculateTax.builder().wage(amount).build();
session.insert(calculateTax);
session.fireAllRules();
session.dispose();
session.close();
return calculateTax;
}
}

View File

@ -0,0 +1,15 @@
package cn.bunny.drools.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("")
public class IndexController {
@GetMapping("")
public String index() {
return "index";
}
}

View File

@ -1,13 +1,15 @@
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<!-- 练习 -->
<kbase name="Exercise" packages="rules.exercise" default="false">
<kbase name="Exercise" packages="rules.exercise" default="true">
</kbase>
<!-- 练习 -->
<kbase name="ExerciseTax" packages="rules.exercise.tax" default="true">
</kbase>
<!-- demo 练习 -->
<kbase name="BookDisCount" packages="rules.demo" default="true">
</kbase>
</kmodule>

View File

@ -1,9 +1,9 @@
package rules;
package rules.demo;
import cn.bunny.drools.bean.demo2.User;
import cn.bunny.drools.bean.demo2.AccessRequest;
import cn.bunny.drools.bean.demo2.Content;
import cn.bunny.drools.bean.demo2.ContentType;
import cn.bunny.drools.bean.demo.demo2.User;
import cn.bunny.drools.bean.demo.demo2.AccessRequest;
import cn.bunny.drools.bean.demo.demo2.Content;
import cn.bunny.drools.bean.demo.demo2.ContentType;
/**
场景:年龄限制内容访问控制

View File

@ -1,4 +1,4 @@
package rules;
package rules.demo;
import cn.bunny.drools.bean.demo.BookDisCount
/*

View File

@ -1,7 +1,7 @@
package rules;
package rules.demo;
import cn.bunny.drools.bean.demo3.ApprovalDecision
import cn.bunny.drools.bean.demo3.CreditCardApplication
import cn.bunny.drools.bean.demo.demo3.ApprovalDecision
import cn.bunny.drools.bean.demo.demo3.CreditCardApplication
import cn.bunny.drools.bean.demo.demo3.ApprovalDecision;
/**

View File

@ -1,6 +1,6 @@
package rules;
package rules.demo;
import cn.bunny.drools.bean.demo1.Order;
import cn.bunny.drools.bean.demo.demo1.Order;
/**
* 当订单金额超过100元时给予5%折扣

View File

@ -0,0 +1,133 @@
package rules.exercise.tax;
import cn.bunny.drools.bean.exercise.CalculateTax
rule "个人所得税:计算应纳税所得额 应纳税所得额为税前工资减去3500"
// 需要优先执行
salience 100
// 设置生效日期
date-effective "2011-09-01"
// 防止循环
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wage > 0)
then
// 计算应纳税所得额
double wageMore = $cal.getWage() - 3500;
$cal.setWagemore(wageMore);
// 更新规则,之后重新计算
update($cal);
end
rule "个人所得税:设置税率-->>应纳税所得额 <= 1500 税率为0.03速算扣除数为0"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore <= 1500)
then
$cal.setCess(0.03);
$cal.setPreminus(0);
update($cal);
end
rule "设置税率,应纳税所得额在 1500 ~ 4500 之间 税率为0.1速算扣除数为105"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore > 1500 && wagemore <= 4000)
then
$cal.setCess(0.1);
$cal.setPreminus(105);
update($cal);
end
rule "设置税率,应纳税所得额在 4500 ~ 9000 之间 税率为0.2速算扣除数为555"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore > 4500 && wagemore <= 9000)
then
$cal.setCess(0.2);
$cal.setPreminus(555);
update($cal);
end
rule "设置税率,应纳税所得额在 9000 ~ 35000 之间 税率为0.25速算扣除数为1005"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore > 9000 && wagemore <= 35000)
then
$cal.setCess(0.25);
$cal.setPreminus(1005);
update($cal);
end
rule "设置税率,应纳税所得额在 35000 ~ 55000 之间 税率为0.3速算扣除数为2755"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore > 35000 && wagemore <= 55000)
then
$cal.setCess(0.3);
$cal.setPreminus(2755);
update($cal);
end
rule "设置税率,应纳税所得额在 55000 ~ 80000 之间 税率为0.35速算扣除数为5505"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore > 55000 && wagemore < 80000)
then
$cal.setCess(0.35);
$cal.setPreminus(5505);
update($cal);
end
rule "设置税率应纳税所得额在80000以上 税率为0.45速算扣除数为13505"
salience 90
no-loop true
activation-group "exercise-calculate-tax"
when
$cal:CalculateTax(wagemore > 80000)
then
$cal.setCess(0.45);
$cal.setPreminus(13505);
update($cal);
end
rule "计算税后工资"
salience 1
when
$cal:CalculateTax(wage > 0 && wagemore > 0 && cess > 0)
then
// 扣税额=应纳税所得额*税率-速算扣除数
double wageMore = ($cal.getWagemore() * $cal.getCess()) - $cal.getPreminus();
$cal.setWagemore(wageMore);
// 税后工资=税前工资-扣税额
double actualWage = $cal.getWage() - wageMore;
$cal.setActualwage(actualWage);
System.out.println("-----税前工资:"+$cal.getWage());
System.out.println("-----应纳税所得额:"+$cal.getWagemore());
System.out.println("-----税率:" + $cal.getCess());
System.out.println("-----速算扣除数:" + $cal.getPreminus());
System.out.println("-----扣税额:" + $cal.getWageminus());
System.out.println("-----税后工资:" + $cal.getActualwage());
end

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Drools学习教程</title>
</head>
<body>
<h1>Drools学习教程</h1>
</body>
</html>

View File

@ -8,7 +8,7 @@ import java.math.BigDecimal;
class _01OrderTest {
public static void main(String[] args) {
try (KieSession kieSession = DroolsConfiguration.createKieSession("order.drl")) {
try (KieSession kieSession = DroolsConfiguration.createKieSession("demo/order.drl")) {
Order order = new Order();
order.setAmount(new BigDecimal(99));

View File

@ -14,7 +14,7 @@ public class _02AgeVerifyTest {
// 默认允许
request.setGranted(true);
try (KieSession kieSession = DroolsConfiguration.createKieSession("age-verify.drl")) {
try (KieSession kieSession = DroolsConfiguration.createKieSession("demo/age-verify.drl")) {
kieSession.insert(request);
kieSession.insert(adult);

View File

@ -63,7 +63,7 @@ public class _03CreditCardApplicationTest {
}
public static CreditCardApplication processApplication(CreditCardApplication application) {
try (KieSession kieSession = DroolsConfiguration.createKieSession("credit-card-approval.drl")) {
try (KieSession kieSession = DroolsConfiguration.createKieSession("demo/credit-card-approval.drl")) {
kieSession.insert(application);
kieSession.fireAllRules();
return application;

View File

@ -17,6 +17,7 @@ public class Exercise01ComparisonOperationTest {
/* contains */
@Test
void test1() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");
@ -36,6 +37,7 @@ public class Exercise01ComparisonOperationTest {
/* not contains */
@Test
void test2() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");
@ -55,6 +57,8 @@ public class Exercise01ComparisonOperationTest {
/* memberOf */
@Test
void test3() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");
@ -74,6 +78,7 @@ public class Exercise01ComparisonOperationTest {
/* matches & not matches */
@Test
void test4() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");
@ -93,6 +98,7 @@ public class Exercise01ComparisonOperationTest {
/* 指定规则后缀进行匹配 */
@Test
void test5() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");
@ -112,6 +118,7 @@ public class Exercise01ComparisonOperationTest {
/* 以什么前缀匹配 */
@Test
void test6() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");
@ -130,6 +137,7 @@ public class Exercise01ComparisonOperationTest {
/* 以正则匹配regexp */
@Test
void test7() {
System.setProperty("drools.dateformat", "yyyy-MM-dd");
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
KieBase kieBase = container.getKieBase("Exercise");