# 花蕾-server
**Repository Path**: sprouting/bud-server
## Basic Information
- **Project Name**: 花蕾-server
- **Description**: 一个综合了非常多系统的开源工具,比如权限、人脸识别、车牌识别、目标检查、opencv、mq、es,这个系统的目标是建立一个最初始的模块化应用,通过配置,可以随时应用到主机的系统中,不同组件提供多个接入方式。注意,本项目是基于单机应用,不完全考虑分布式的问题,系统的目标是轻量级快速接入的开发组件
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 25
- **Forks**: 16
- **Created**: 2023-02-20
- **Last Updated**: 2025-05-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#
项目前端:https://gitee.com/sprouting/bud-web
项目后端:https://gitee.com/sprouting/bud-server
## 1、综述
一个综合了非常多系统的开源工具,比如权限、人脸识别、opencv、mq、es,这个系统的目标是建立一个最初始的模块化应用,通过配置,可以随时应用到自己的系统中,不同组件提供多个接入方式。注意,本项目是基于单机应用,不完全考虑分布式的问题,系统的目标是轻量级快速接入的开发组件。本来想做成一个一个的模块,要使用redis,就开启redis模块,后面感觉没必要,其实都是分层,搞简单点。
### 注意事项
原本设计之初只是放一些简单的功能,但一段时间对onnx模型非常感兴趣,加了不少了onnx模型内容,导致现在运行需要消耗非常大的内存,截止人脸模块识别的加入,单次启动内存已经在1G左右,所以运行本项目需要注意下这一块内容。
### 设计目标
2023年3月10日17:54:28
简单点说,这个项目力争在单机单节点下,尽量少的依赖完成各种任务,其中也包含了各种写法,比如kafka的消息发送,整合了所有发送类型,方便以后随时可以调用复制就可以使用。
比如本地视频播放,可能会直接让springboot就实现了推流,不使用nginx。
本项目的有两个目标
- 各种好玩的、有意思的项目进行整合,可以方便以后随时进行复制使用,也类似做一个后台管理项目。
- 尽量少的依赖
### 约定
所有的请求基本都是以 `form-data` 的方式提交,即form表单的形式提交。
## 2、已实现功能截图
### onnx 分类检测
#### 图像分类检测
入口 `OnnxController`



物体识别,支持中文


#### 视频分类检测


#### 头盔检测


头盔检测支持中文

#### 车牌识别

#### 本地离线人脸检测
返回的结果比较大,只能截个图,

返回的结果有相似度,人脸年龄、性别,坐标位置,还有识别到的人脸截图base64的图片信息。

#### 人脸关键点

#### 年龄和性别



### 数据库文档导出
#### word文档
效果如下。

#### html文档


## 3、已完成功能
### 3.1 功能项说明
1、单机幂等性验证逻辑 `@IdempotentSingle` 注解 和 `IdempotentSingleAop`
2、自定义 validation 注解, `@CheckNotNullValidator`
3、项目启动打印版本号和编译时间 `BeanPostConfig`
4、字符画,项目启动的字符画,直接在 banner.txt 文件修改即可。其他参考 `2.2.1`
5、git代码有些不提交,编辑这个文件即可 `.gitignore`
6、开启跨域配置,`CorsConfig` ,启用在配置文件 `bud.customize.cors.enabled`
7、增加 logbak 日志,只要添加 `logback-spring.xml` 文件,同时在配置文件中指定文件路径即可,`logging.config`

8、增加了自动初始化创建sqlite的数据库 `AutoDatabaseCreate` ,控制开关:`bud.customize.db.create.enabled`
9、集成了 liquibase ,自动创建数据库。引入maven依赖,在配置文件中指定了脚本路径即可。
10、xss白名单,`XssFilter`,白名单在配置中 `bud.customize.xss.whites`
11、支持拖动的视频播放,不需要其他的工具。 `NonStaticResourceHttpRequestHandler` 、`PlayController` 。==需要配合前端才能展示效果==
12、自定义异常和通用异常处理 `GlobalExceptionHandler` 与 `ServiceException`
13、农历信息,`DateTool#toLunar`
14、真实IP工具 `NetTool`
15、==重要==资源拦截、不用nginx的配置资源映射、静态资源访问实现, `ResourcesAndSaTokenInterceptor.addResourceHandlers` ,直接可以访问指定的资源书籍
16、controller 的请求配置指定前缀,`ResourcesAndSaTokenInterceptor.configurePathMatch` ,主要解决,前端访问不想加前缀访问资源,后端因为同一拦截了,需要对controller的进行特殊处理,添加指定前缀访问
17、启动脚本 `startup.bat`
18、权限获取,sa-token 中 session 获取,`StpInterfaceCore`
19、备份sqlite数据库,`DatabaseBackupTask`
20、定时清理文件 `ClearFileTask`
21、代码生成工具 `GenerateTool`
22、增加验证码工具 `CaptchaTool`
23、文件存储服务,找到 `com.sprouting.bud.strategy` 下就是minio和亚马逊S3对象存储的2个实现
24、excel的导入导出工具。[2023年8月23日18:19:06 升级版本,并且支持 导出带下拉框,`ExcelTool`]
25、完成站内信,完成缓存消息
26、批量插入支持,只需要关注,`MybatisPlusConfig.mybatisPlusInsertBatchInjector` 和 `BaseDaoMapper` 即可,这个只支持mysql和sqlite
27、整合es,加入了easy-es
28、引入swarm2 参考:https://blog.csdn.net/A2254536570/article/details/121767271
> Swagger2和Swagger3是两个不同版本的API文档生成工具。
>
> 其中,Swagger2是OpenAPI规范的前身,Swagger3是OpenAPI规范的官方版本,相较于Swagger2,Swagger3在以下几个方面有所改进:
>
> \1. OpenAPI规范的支持:Swagger3采用OpenAPI规范来定义API,这使得API定义更加规范化和标准化;
>
> \2. 引入YAML语法:Swagger3除了支持JSON格式,还支持YAML格式,可以减少文本长度;
>
> \3. 支持响应式API:Swagger3支持异步API、Webhook等特性;
>
> \4. 组件化:Swagger3采用了组件化的方式来定义API元素,更加模块化和可扩展。
>
> 总体来说,Swagger3在支持标准化、规范化方面比Swagger2更加出色,同时也支持更多新的特性,使得开发人员能够更好地设计和维护API文档。
主要代码,引入maven依赖后,配置 `SwaggerConfig`,对拦截器进行处理 `ResourcesAndSaTokenInterceptor`
还需要注意,配置文件中的 `spring.mvc.pathmatch.matching-strategy` ,不设置会导致springboot2.6以上版本无法启动swagger。
29、整合 knife4j,基本不需要加什么,只要添加依赖,然后在权限部分排除掉路径即可
30、数据权限过滤,注解 `DataScope.java` 和 `UnitDataPermissionIntercept.java`
31、虹软人脸识别,核心文件:`CoreEngine` 和 `ArcSoftController`
32、bean自动注入,自定义start的时候最有用了,`AutoInjection` 和 `org.springframework.boot.autoconfigure.AutoConfiguration.imports`
33、离线IP获取工具 `IpTool` ,注意拷贝二进制的时候,如果文件变大了,说明文件被动了

34、日志注解 `LogRecord` 和 `LogRecordAop`
35、集群的幂等性注解,`IdempotentCluster`
36、增加xss代码校验注解,`CheckXss` ,不过由于项目做了整体的xss代码过滤,一般不需要考虑这个注解
37、增加了动态sms服务 `com.sprouting.bud.sms` 包下现有2个实现,一个是腾讯云的,一个是阿里云的sms服务实现
38、全局线程池 `ThreadPoolConfig`
39、增加了websocket,支持单机和集群模式,`WebSocketServer` ,新增支持IP检测。如果配置了nginx,还要关注,`3.3.6 websocket的nginx配置`
40、流式查询的例子 `SelectFlowTest` (这是mybatis支持的),增加了mp的流式查询,也在`SelectFlowTest` 中
41、增加了Spire的例子,对word家族文档进行处理,`SpireDemo`
42、mq这一块暂时不打算加入,可以参考 dubbo-test 项目,里面集成了kafka、rocketMQ
43、深度优先搜索算法,防止树死循环,`CamelServerNodeController.checkDeadCycle`
44、javacv推送摄像头数据的几个处理,路径在 `com.sprouting.bud.video.javacv.camera`, 入口在 `CameraController.start()`
45、rtspToFlv,这个是rtsp 转flv的例子,还不能用,但流程和思路是可以参考的,代码中定义了 `FlvConverterInterface ` 接口,几个要做的事情,然后定义了抽象类 `FlvConverterInterfaceAbstract` ,将其中公共的方法写在里面,最后,有2个实现,一个是标准的不需要转码的 h264 和 acc 的音频的,直接转 flv。
46、整合添加了 quartz, 这个代码要看就看 `JobController` 的保存,其实springboot2.0已经默认添加了 quartz,已经简化非常多,我们的改造多了日志,多了可配置的选项,能马上执行,定时执行,暂停、恢复等等。
使用的话,涉及到2张表,日志 `bud_job` 和日志记录表 `bud_job_log` ,参考 TestTask 类,只要继承 `TaskJobExecInterfaces` 接口即可,然后录入的bean将放到spring中管理,将要执行的代码放到exec方法中。需要注意一点,bean的名字应该第一个是小写,其实就是类的名字,假设一个项目中有多个这样的类名,估计会有一定的问题。但应该是通不过检测的。
47、**javacv相关的几个可以参考下 package com.sprouting.bud.video; 下的 package-info.java 。**
48、封装了ffmpeg,增加了一些工具信息,`FfmpegTool`
49、注解支持el表达式,`LogRecord` 注解的 `remark` 开始支持EL表达式,使用上请看,如果没有使用el表达式,则如下,
```java
@LogRecord(remark = "sdasddfd")
public ResultJson loginPc(LoginDTO loginDTO){}
结果,会抛出一个异常,获取不到EL1007E: Property or field 'sdasddfd' cannot be found on null的错误,但现在做了处理,只有 # 才会进入到el
```
实在el表达式
```java
@LogRecord(remark = "#loginDTO.key")
public ResultJson loginPc(LoginDTO loginDTO){}
结果:正常获取到参数:1231dssd三大
```
直接使用对象也可以
```
@LogRecord(remark = "#loginDTO")
public ResultJson loginPc(LoginDTO loginDTO){}
结果:{"key":"1231dssd三大"}
```
放入了一个找不到的
```java
@LogRecord(remark = "#loginDTObak")
public ResultJson loginPc(LoginDTO loginDTO){}
这里会得到一个空
```
如果给一个未知的属性去获取
```java
@LogRecord(remark = "#loginDTO.ss")
public ResultJson loginPc(LoginDTO loginDTO){}
结果:会抛出获取不到的异常
```
50、~~科大讯飞语音识别~~,本来写完,发现限制太多,而且要收费,算了,不集成了
51、集成了英文tts工具marytts,不支持中文 `VoiceController`
52、增加了Tika,可以识别各种文档类型,不在需要从后缀判断,毕竟后缀判断是不准确的,同时可以读取文档的内容,但不保证一定成功。`TikaController`
53、集成了短信发送功能,支持主流的短信发送平台,`TextMessageTool`,更多文档看 `https://wind.kim/doc/start/`
54、根据对象获取属性名称,`EntityTool.getFieldName` ,比如 `EntityTool.getFieldName(IndicatorTreeDTO::getId)` 得到id
55、统一文件存储,官网:`https://spring-file-storage.xuyanwu.cn/` 。支持各种云存储等,`of`方法支持 File、MultipartFile、byte[]、InputStream、URL、URI、String,大文件会自动分片上传。
2023年11月16日16:48:35 原本的 `UploadFileController` 做的太简陋了,但这一块又有点不太好用,打算将这一块封装到 `UnifiedFileStorageController` 中。
56、支持onnx模型在Java中的运行,具体代码在 onnx 包下面,注意,这里需要去 `application.properties` 配置文件,否则可能会出现后处理有异常,配置为:`bud.customize.onnx.type` ,常用的调用方法在 `OnnxController` 中。项目参考:https://gitee.com/agricultureiot/yolo-onnx-java
57、车牌检测,可实际项目使用的,参考的:https://gitee.com/open-visual/open-anpr
58、数据库表结构导出和表信息获取。本来想将我另外一个项目集成进来的,但考虑到该项目需要一些依赖,很多同学可能没有去注意,到时候启动反而麻烦,另外,开源的另外一个项目实际已经封装的很好了,只要配置一下即可使用,无需处理如此麻烦。故而考虑再三,不进行集成,但记录下来,https://gitee.com/sprouting/database-metadata 通过该项目可以随时导出文档和表结构。
2023年11月16日11:30:20 还是集成了进来,打包为jar,然后maven依赖进去。
测试:访问接口 `http://127.0.0.1:8086/bud/export/exportMysql` 注意,要导入其他的文档,要将对应的数据库驱动导入。
59、增加了人脸识别模块,基于Onnx模型,参考项目:https://gitee.com/open-visual/face-search/tree/master/face-search-core
入口controller:`FaceController`。
60、vosk的声音识别demo,vosk语音转文字,入口:`VoskController`
61、excel,基于模版的导出功能,遇到复杂的excel的时候,需要使用模版,直接填充数据导出,做了一个示例,和增加了工具类,示例方法:`ExcelController.testTemplateImport`
效果:

填充后

62、MQTT集成,集成了Mica的MQTT,项目地址:https://gitee.com/596392912/mica-mqtt
开启后会有类似这种日志

代码位置如下

集成完成,如果想开启,需要在配置文件中打开


62、openstack的核心api功能完成。`com.sprouting.bud.openstack` ,需要验证。核心api还存在 `ceilometer` 以及 云硬盘挂载相关的接口缺少。
63、平均分配数量,完美版本:`com.sprouting.bud.example.controller.TestController#assign()`
64、增加Java操作docker示例,`com/sprouting/bud/docker/service/DockerOperateService.java` ,示例:`com/sprouting/bud/example/controller/DockerController.java`
65、实现pdf生成,创建工具类`PdfTool`,示例 `com/sprouting/bud/example/controller/TestController.java # testPdf`
66、基于后台的模糊查询树 全局搜索 `recursiveQuery` 即可,在权限查询中有这种相关的查询
#### 暂时不进行集成模块
1、支付模块暂不加入,因为无法测试,但记录下可以参考的代码。
- https://javen205.gitee.io/ijpay/
- https://gitee.com/52itstyle/spring-boot-pay/tree/master
2、暂不集成消息推送模块,https://gitee.com/zhongfucheng/austin#https://gitee.com/link?target=http%3A%2F%2F139.9.66.219%3A3000%2F 这种大型推送的还没必要,其实上面集成了定时任务,已经可以完成这种简单的消息推送了。
3、t-io暂时不考虑集成,可以参考 `t-io-test ` 项目,已经非常棒了。
4、mqtt 这一块的技术选项较多,是netty,还是 tio,还是这个,都不确定,但代码其实很简单 https://smartboot.gitee.io/smart-mqtt/bridge.html#mqtt-bridge
5、后续可以参考的一些优秀项目
- rtsp转rtmp https://gitee.com/banmajio/RTSPtoHTTP-FLV?_from=gitee_search
- java版天网人脸识别系统,获取视频流 进行人脸识别后推送到流媒体服务器实时展示 https://gitee.com/endlesshh/red5-rtmp-push?_from=gitee_search
- Springboot、netty实现的http-flv、websocket-flv直播点播,支持rtsp、h264、h265、rtmp等多种源,h5纯js播放(不依赖flash),不需要nginx等第三方拉流服务 https://toscode.gitee.com/52jian/EasyMedia
下一步计划
- 讯飞
- EasyMedia
- video 要加配置
- ClearFileTask 定时任务开启,数据清理超过多长时间的,都从配置中来。
- `DatabaseBackupTask` 要设置可配置的定时任务,设置保留的文件数量
- 多节点雪花算法
- 参考 camle 在 usp系统
### 3.2 子功能说明
#### 3.2.1 字符画
生成字符画的网站:https://www.bootschool.net/ascii
颜色可以在这里配置:`${AnsiColor:BLUE}` 字符画可选的颜色有如下
```properties
DEFAULT("49"),
BLACK("40"),
RED("41"),
GREEN("42"),
YELLOW("43"),
BLUE("44"),
MAGENTA("45"),
CYAN("46"),
WHITE("47"),
BRIGHT_BLACK("100"),
BRIGHT_RED("101"),
BRIGHT_GREEN("102"),
BRIGHT_YELLOW("103"),
BRIGHT_BLUE("104"),
BRIGHT_MAGENTA("105"),
BRIGHT_CYAN("106"),
BRIGHT_WHITE("107");
```
不开启字符画只要将这一行代码放开注释即可

#### 3.2.2 Quartz框架封装后结构

#### 3.3.3 缓存
所有的缓存相关暂时全部走的本地缓存。
模拟缓存使用
`private static TimedCache timedCache = CacheUtil.newTimedCache(30 * 1000);`
锁释放则使用如下方式
```java
// 通过再次设置这个值,并将过期时间设置为1毫秒,实现释放锁的功能
timedCache.put(key, "1", 1);
```
#### 3.3.4 MQTT
已集成 mica 的MQTT。
详情见上面的以实现功能项说明 - 62
这里主要补充常见问题:https://gitee.com/596392912/mica-mqtt/issues/I45GO7
项目地址:https://gitee.com/596392912/mica-mqtt
nginx配置:
`nginx tcp 负载均衡` 即可:
- [https://zhuanlan.zhihu.com/p/139275668](https://gitee.com/link?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F139275668)
- [http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html](https://gitee.com/link?target=http%3A%2F%2Fnginx.org%2Fen%2Fdocs%2Fstream%2Fngx_stream_proxy_module.html)
配置 /etc/nginx/nginx.conf
```properties
stream {
upstream stream_backend {
zone tcp_servers 64k;
hash $remote_addr;
server 192.168.0.2:1883 max_fails=2 fail_timeout=30s;
server 192.168.0.3:1883 max_fails=2 fail_timeout=30s;
}
server {
listen 8883 ssl;
status_zone tcp_server;
proxy_pass stream_backend;
proxy_buffer_size 4k;
proxy_protocol on; # 转发源ip信息, mica-mqtt 开源版不支持,私服版已经支持,可捐助获取
ssl_handshake_timeout 15s;
ssl_certificate /etc/emqx/certs/cert.pem;
ssl_certificate_key /etc/emqx/certs/key.pem;
}
}
```
#### 3.3.5 camle
系统中集成了camle,该工作量太大,原本的计划是可以根据页面自定义,就可以实现camel的各种转换,但前端并不是我擅长的地方,且camel还是比较深的,现在只是封装了一些方法在contrller等层。
但6月份又将部分camel的示例添加进来,现在只要关注 `com.sprouting.bud.camel.service` 下的几个文件夹,里面是各个主要的示例,足够一般使用了。
#### 3.3.6 websocket的nginx配置
nginx配置如下
```nginx
upstream ws {
#weigth参数表示权值,权值越高被分配到的几率越大
# 需要注意一点,这里配置服务端IP,不要配置 127.0.0.1(docker部署的情况下),部分服务器上有限制
server 192.168.0.21:端口 weight=1;
}
location /budWs/ {
proxy_pass http://ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 2000s;
keepalive_timeout 2000s;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
```
如果是docker部署的nginx,需要重启。
#### 3.3.7 docker相关
##### docker插件安装
前往官网下载插件, https://plugins.jetbrains.com/search?products=idea&search=docker
这里直接搜索到 docker插件:https://plugins.jetbrains.com/plugin/7724-docker
注意下载的时候选择适合你的IDEA版本,否则可能出现不兼容的问题。安装成功后就会有一个docker的选项。

##### 远程连接docker服务器

才表示成功,否则没有成功,如果docker服务器没开启远程访问,你是无法连接上去的。
##### 开启docker远程访问
编辑 `/usr/lib/systemd/system/docker.service`
修改ExecStart行为下面内容:
原始文件

修改为:
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

重新加载docker配置
systemctl daemon-reload // 1,加载docker守护线程
systemctl restart docker // 2,重启docker
#### 3.3.8 字体安装
为了解决pdf生成后的乱码问题,需要安装字体
建议安装微软雅黑和宋体
为了管理字体,先安装这个工具:`yum install -y fontconfig mkfontscale`
这样就可以看到字体列表了:`fc-list`
还需要安装字体管理工具:`yum -y install fontconfig mkfontscale`
创建文件:`sudo mkdir -p /usr/share/fonts/chinese`

拷贝这几个字体,最后刷新下缓存 `fc-cache -fv`
这样生成的文件就没有乱码了
## 4、常见问题
### 项目无法启动,参数太长
项目中一旦使用了 `javacv-platform` 的依赖,那么就会出现这个错误,项目无法起来。问题原因就是参数太长。但这个依赖不加入,调用ffmpeg就会出现依赖问题。
解决办法很简单,idea中配置下即可。

如下,将 shorten command line 旋转为上图这种,不要选 none ,即可。有些idea无法看到该选项,则在 modify options 中找到勾选即可。
## 软件架构
软件架构说明
## 安装教程
## 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request