master
cai 1 week ago
commit 8bd1a9cf95

@ -0,0 +1,21 @@
# http://editorconfig.org
root = true
# 空格替代Tab缩进在各种编辑工具下效果一致
[*]
indent_style = space
indent_size = 4
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.java]
indent_style = tab
[*.{json,yml}]
indent_size = 2
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="nenghui-uat" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="17" />
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="nenghui-uat" options="-parameters" />
</option>
</component>
</project>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="bladex" />
<option name="name" value="BladeX Release Repository" />
<option name="url" value="https://center.javablade.com/api/packages/blade/maven" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="aliyun-repos" />
<option name="name" value="Aliyun Public Repository" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
</component>
</project>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

@ -0,0 +1,27 @@
## 一、调整内存max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]elasticsearch用户拥有的内存权限太小至少需要262144
#### 1.修改配置sysctl.conf
[root@localhost ~]# vi /etc/sysctl.conf
#### 2.添加下面配置:
vm.max_map_count=262144
#### 3.重新加载:
[root@localhost ~]# sysctl -p
#### 4.最后重新启动elasticsearch即可启动成功。
## 二、Docker 命令自动补全
#### 1.安装依赖工具bash-complete
[root@localhost ~]# yum install -y bash-completion
[root@localhost ~]# source /usr/share/bash-completion/completions/docker
[root@localhost ~]# source /usr/share/bash-completion/bash_completion
## 三、将本文件夹内的文件拷贝至服务器
#### 1.对sh脚本赋予执行权限
#### 2.执行 ./deploy.sh
#### 3.等待服务启动完毕即可
#### 4.卸载执行 ./undeploy.sh

@ -0,0 +1,88 @@
#./bin/bash
# 定义颜色
BLUE_COLOR="\033[36m"
RED_COLOR="\033[31m"
GREEN_COLOR="\033[32m"
VIOLET_COLOR="\033[35m"
RES="\033[0m"
echo -e "${BLUE_COLOR}# ######################################################################${RES}"
echo -e "${BLUE_COLOR}# Docker ELK Deploy Script #${RES}"
echo -e "${BLUE_COLOR}# ######################################################################${RES}"
# 创建目录
echo -e "${BLUE_COLOR}---> create [elasticsearch]directory start.${RES}"
if [ ! -d "./elasticsearch/" ]; then
mkdir -p ./elasticsearch/master/conf ./elasticsearch/master/data ./elasticsearch/master/logs \
./elasticsearch/slave1/conf ./elasticsearch/slave1/data ./elasticsearch/slave1/logs \
./elasticsearch/slave2/conf ./elasticsearch/slave2/data ./elasticsearch/slave2/logs
fi
echo -e "${RED_COLOR}---> create [kibana]directory start.${RES}"
if [ ! -d "./kibana/" ]; then
mkdir -p ./kibana/conf ./kibana/logs
fi
echo -e "${GREEN_COLOR}---> create [logstash]directory start.${RES}"
if [ ! -d "./logstash/" ]; then
mkdir -p ./logstash/conf ./logstash/logs
fi
echo -e "${GREEN_COLOR}---> create [filebeat]directory start.${RES}"
if [ ! -d "./filebeat/" ]; then
mkdir -p ./filebeat/conf ./filebeat/logs ./filebeat/data
fi
echo -e "${VIOLET_COLOR}---> create [nginx]directory start.${RES}"
if [ ! -d "./nginx/" ]; then
mkdir -p ./nginx/conf ./nginx/logs ./nginx/www
fi
echo -e "${BLUE_COLOR}===> create directory success.${RES}"
# 目录授权(data/logs 都要授读/写权限)
echo -e "${BLUE_COLOR}---> directory authorize start.${RES}"
if [ -d "./elasticsearch/" ]; then
chmod 777 ./elasticsearch/master/data/ ./elasticsearch/master/logs/ \
./elasticsearch/slave1/data/ ./elasticsearch/slave1/logs/ \
./elasticsearch/slave2/data/ ./elasticsearch/slave2/logs
fi
if [ -d "./filebeat/" ]; then
chmod 777 ./filebeat/data/ ./filebeat/logs/
fi
echo -e "${BLUE_COLOR}===> directory authorize success.${RES}"
# 移动配置文件
echo -e "${BLUE_COLOR}---> move [elasticsearch]config file start.${RES}"
if [ -f "./es-master.yml" ] && [ -f "./es-slave1.yml" ] && [ -f "./es-slave2.yml" ]; then
mv ./es-master.yml ./elasticsearch/master/conf
mv ./es-slave1.yml ./elasticsearch/slave1/conf
mv ./es-slave2.yml ./elasticsearch/slave2/conf
fi
echo -e "${RED_COLOR}---> move [kibana]config file start.${RES}"
if [ -f "./kibana.yml" ]; then
mv ./kibana.yml ./kibana/conf
fi
echo -e "${GREEN_COLOR}---> move [logstash]config file start.${RES}"
if [ -f "./logstash.yml" ] && [ -f "./logstash-filebeat.conf" ]; then
mv ./logstash-filebeat.conf ./logstash/conf
mv ./logstash.yml ./logstash/conf
fi
echo -e "${GREEN_COLOR}---> move [filebeat]config file start.${RES}"
if [ -f "./filebeat.yml" ]; then
mv ./filebeat.yml ./filebeat/conf
fi
echo -e "${VIOLET_COLOR}---> move [nginx]config file start.${RES}"
if [ -f "./nginx.conf" ]; then
mv ./nginx.conf ./nginx/conf
fi
echo -e "${BLUE_COLOR}===> move config files success.${RES}"
echo -e "${GREEN_COLOR}>>>>>>>>>>>>>>>>>> The End <<<<<<<<<<<<<<<<<<${RES}"
# 部署项目
echo -e "${BLUE_COLOR}==================> Docker deploy Start <==================${RES}"
docker-compose up --build -d

@ -0,0 +1,115 @@
version: "3"
services:
es-master:
container_name: es-master
hostname: es-master
image: elasticsearch:7.1.1
restart: always
ports:
- 9200:9200
- 9300:9300
volumes:
- ./elasticsearch/master/conf/es-master.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/master/data:/usr/share/elasticsearch/data
- ./elasticsearch/master/logs:/usr/share/elasticsearch/logs
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
es-slave1:
container_name: es-slave1
image: elasticsearch:7.1.1
restart: always
ports:
- 9201:9200
- 9301:9300
volumes:
- ./elasticsearch/slave1/conf/es-slave1.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/slave1/data:/usr/share/elasticsearch/data
- ./elasticsearch/slave1/logs:/usr/share/elasticsearch/logs
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
es-slave2:
container_name: es-slave2
image: elasticsearch:7.1.1
restart: always
ports:
- 9202:9200
- 9302:9300
volumes:
- ./elasticsearch/slave2/conf/es-slave2.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/slave2/data:/usr/share/elasticsearch/data
- ./elasticsearch/slave2/logs:/usr/share/elasticsearch/logs
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
es-head:
container_name: es-head
image: mobz/elasticsearch-head:5
restart: always
ports:
- 9100:9100
depends_on:
- es-master
- es-slave1
- es-slave2
kibana:
container_name: kibana
hostname: kibana
image: kibana:7.1.1
restart: always
ports:
- 5601:5601
volumes:
- ./kibana/conf/kibana.yml:/usr/share/kibana/config/kibana.yml
environment:
- elasticsearch.hosts=http://es-master:9200
depends_on:
- es-master
- es-slave1
- es-slave2
filebeat:
# 容器名称
container_name: filebeat
# 主机名称
hostname: filebeat
# 镜像
image: docker.elastic.co/beats/filebeat:7.1.1
# 重启机制
restart: always
# 持久化挂载
volumes:
- ./filebeat/conf/filebeat.yml:/usr/share/filebeat/filebeat.yml
# 映射到容器中[作为数据源]
- ./logs:/home/project/elk/logs
- ./filebeat/logs:/usr/share/filebeat/logs
- ./filebeat/data:/usr/share/filebeat/data
# 将指定容器连接到当前连接可以设置别名避免ip方式导致的容器重启动态改变的无法连接情况
links:
- logstash
ports:
- 9000:9000
# 依赖服务[可无]
depends_on:
- es-master
- es-slave1
- es-slave2
logstash:
container_name: logstash
hostname: logstash
image: logstash:7.1.1
command: logstash -f ./conf/logstash-filebeat.conf
restart: always
volumes:
# 映射到容器中
- ./logstash/conf/logstash-filebeat.conf:/usr/share/logstash/conf/logstash-filebeat.conf
- ./logstash/conf/logstash.yml:/usr/share/logstash/config/logstash.yml
ports:
- 5044:5044
depends_on:
- es-master
- es-slave1
- es-slave2

@ -0,0 +1,28 @@
# 集群名称
cluster.name: es-cluster
# 节点名称
node.name: es-master
# 是否可以成为master节点
node.master: true
# 是否允许该节点存储数据,默认开启
node.data: false
# 网络绑定
network.host: 0.0.0.0
# 设置对外服务的http端口
http.port: 9200
# 设置节点间交互的tcp端口
transport.port: 9300
# 集群发现
discovery.seed_hosts:
- es-master
- es-slave1
- es-slave2
# 手动指定可以成为 mater 的所有节点的 name 或者 ip这些配置将会在第一次选举中进行计算
cluster.initial_master_nodes:
- es-master
# 支持跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"
# 安全认证
xpack.security.enabled: false
#http.cors.allow-headers: "Authorization"

@ -0,0 +1,28 @@
# 集群名称
cluster.name: es-cluster
# 节点名称
node.name: es-slave1
# 是否可以成为master节点
node.master: true
# 是否允许该节点存储数据,默认开启
node.data: true
# 网络绑定
network.host: 0.0.0.0
# 设置对外服务的http端口
http.port: 9201
# 设置节点间交互的tcp端口
#transport.port: 9301
# 集群发现
discovery.seed_hosts:
- es-master
- es-slave1
- es-slave2
# 手动指定可以成为 mater 的所有节点的 name 或者 ip这些配置将会在第一次选举中进行计算
cluster.initial_master_nodes:
- es-master
# 支持跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"
# 安全认证
xpack.security.enabled: false
#http.cors.allow-headers: "Authorization"

@ -0,0 +1,28 @@
# 集群名称
cluster.name: es-cluster
# 节点名称
node.name: es-slave2
# 是否可以成为master节点
node.master: true
# 是否允许该节点存储数据,默认开启
node.data: true
# 网络绑定
network.host: 0.0.0.0
# 设置对外服务的http端口
http.port: 9202
# 设置节点间交互的tcp端口
#transport.port: 9302
# 集群发现
discovery.seed_hosts:
- es-master
- es-slave1
- es-slave2
# 手动指定可以成为 mater 的所有节点的 name 或者 ip这些配置将会在第一次选举中进行计算
cluster.initial_master_nodes:
- es-master
# 支持跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"
# 安全认证
xpack.security.enabled: false
#http.cors.allow-headers: "Authorization"

@ -0,0 +1,37 @@
filebeat.inputs:
- type: log
enabled: true
paths:
# 当前目录下的所有.log文件
- /home/project/elk/logs/*.log
multiline.pattern: ^\[
multiline.negate: true
multiline.match: after
- type: tcp
enabled: true
max_message_size: 10MiB
host: "0.0.0.0:9000"
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.template.settings:
index.number_of_shards: 1
setup.dashboards.enabled: false
setup.kibana:
host: "http://kibana:5601"
# 不直接传输至ES
#output.elasticsearch:
# hosts: ["http://es-master:9200"]
# index: "filebeat-%{[beat.version]}-%{+yyyy.MM.dd}"
output.logstash:
hosts: ["logstash:5044"]
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~

@ -0,0 +1,8 @@
# 服务端口
server.port: 5601
# 服务IP
server.host: "0.0.0.0"
# ES
elasticsearch.hosts: ["http://es-master:9200"]
# 汉化
i18n.locale: "zh-CN"

@ -0,0 +1,23 @@
input {
# 来源beats
beats {
# 端口
port => "5044"
}
}
# 分析、过滤插件,可以多个
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}"}
}
geoip {
source => "clientip"
}
}
output {
# 选择elasticsearch
elasticsearch {
hosts => ["http://es-master:9200"]
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
}
}

@ -0,0 +1,8 @@
# 服务IP
http.host: "0.0.0.0"
# ES
xpack.monitoring.elasticsearch.hosts: [ "http://es-master:9200" ]
xpack.monitoring.enabled: true
xpack.management.enabled: false

@ -0,0 +1,16 @@
#./bin/bash
# 定义颜色
BLUE_COLOR="\033[36m"
RED_COLOR="\033[31m"
GREEN_COLOR="\033[32m"
VIOLET_COLOR="\033[35m"
RES="\033[0m"
echo -e "${BLUE_COLOR}# ######################################################################${RES}"
echo -e "${BLUE_COLOR}# Docker ELK UnDeploy Script #${RES}"
echo -e "${BLUE_COLOR}# ######################################################################${RES}"
# 部署项目
echo -e "${BLUE_COLOR}==================> Docker UnDeploy Start <==================${RES}"
docker-compose stop
docker-compose rm

@ -0,0 +1 @@
java -Xms1024m -Xmx1024m -jar app.jar

@ -0,0 +1,76 @@
#!/bin/bash
#设置jar文件名
APP_NAME=app.jar
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
exit 1
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
#如果不存在返回1存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#启动方法
start(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is already running. pid=${pid} ."
else
nohup java -Xms1024m -Xmx1024m -jar $APP_NAME > /dev/null 2>&1 &
fi
}
#停止方法
stop(){
is_exist
if [ $? -eq "0" ]; then
kill -9 $pid
else
echo "${APP_NAME} is not running"
fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is running. Pid is ${pid}"
else
echo "${APP_NAME} is NOT running."
fi
}
#重启
restart(){
stop
start
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac

@ -0,0 +1,687 @@
Table: blade_attach附件表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| link | VARCHAR(1000) | YES | | | 附件地址 |
| domain_url | VARCHAR(500) | YES | | | 附件域名 |
| name | VARCHAR(500) | YES | | | 附件名称 |
| original_name | VARCHAR(500) | YES | | | 附件原名 |
| extension | VARCHAR(12) | YES | | | 附件拓展名 |
| attach_size | BIGINT(20) | YES | | | 附件大小 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_client客户端表
| Field | Type | Null | Key | Default | Remarks |
| ----------------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| client_id | VARCHAR(48) | NO | | | 客户端id |
| client_secret | VARCHAR(256) | NO | | | 客户端密钥 |
| resource_ids | VARCHAR(256) | YES | | | 资源集合 |
| scope | VARCHAR(256) | NO | | | 授权范围 |
| authorized_grant_types | VARCHAR(256) | NO | | | 授权类型 |
| web_server_redirect_uri | VARCHAR(256) | YES | | | 回调地址 |
| authorities | VARCHAR(256) | YES | | | 权限 |
| access_token_validity | INT(10) | NO | | | 令牌过期秒数 |
| refresh_token_validity | INT(10) | NO | | | 刷新令牌过期秒数|
| additional_information | VARCHAR(4096) | YES | | | 附加说明 |
| autoapprove | VARCHAR(256) | YES | | | 自动授权 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | NO | | | 状态 |
| is_deleted | INT(10) | NO | | | 是否已删除 |
Table: blade_code代码生成表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| model_id | BIGINT(20) | YES | | | 数据模型主键 |
| service_name | VARCHAR(64) | YES | | | 服务名称 |
| code_name | VARCHAR(64) | YES | | | 模块名称 |
| table_name | VARCHAR(64) | YES | | | 表名 |
| table_prefix | VARCHAR(64) | YES | | | 表前缀 |
| pk_name | VARCHAR(32) | YES | | | 主键名 |
| package_name | VARCHAR(500) | YES | | | 后端包名 |
| template_type | VARCHAR(32) | YES | | | 模版类型 |
| author | VARCHAR(32) | YES | | | 作者信息 |
| sub_model_id | VARCHAR(32) | YES | | | 子表模型主键 |
| sub_fk_id | VARCHAR(32) | YES | | | 子表绑定外键 |
| tree_id | VARCHAR(32) | YES | | | 树主键字段 |
| tree_pid | VARCHAR(32) | YES | | | 树父主键字段 |
| tree_name | VARCHAR(64) | YES | | | 树名称字段 |
| base_mode | INT(10) | YES | | | 基础业务模式 |
| wrap_mode | INT(10) | YES | | | 包装器模式 |
| feign_mode | INT(10) | YES | | | 远程调用模式 |
| code_style | VARCHAR(32) | YES | | | 代码风格 |
| api_path | VARCHAR(2000) | YES | | | 后端路径 |
| web_path | VARCHAR(2000) | YES | | | 前端路径 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_datasource数据源配置表
| Field | Type | Null | Key | Default | Remarks |
|-----------------|--------------| ---- | --- | ------- |------------|
| id | BIGINT(20) | NO | PRI | | 主键 |
| category | INT(2) | YES | | | 数据源类型 |
| name | VARCHAR(100) | YES | | | 名称 |
| driver_class | VARCHAR(100) | YES | | | 驱动类 |
| url | VARCHAR(500) | YES | | | 连接地址 |
| username | VARCHAR(50) | YES | | | 用户名 |
| password | VARCHAR(50) | YES | | | 密码 |
| sharding_config | LONGTEXT | YES | | | 分库分表配置 |
| remark | VARCHAR(255) | YES | | | 备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_dept机构表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| parent_id | BIGINT(20) | YES | | 0 | 父主键 |
| ancestors | VARCHAR(2000) | YES | | | 祖级列表 |
| dept_category | INT(10) | YES | | | 部门类型 |
| dept_name | VARCHAR(45) | YES | | | 部门名 |
| full_name | VARCHAR(45) | YES | | | 部门全称 |
| sort | INT(10) | YES | | | 排序 |
| remark | VARCHAR(255) | YES | | | 备注 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_dict字典表
| Field | Type | Null | Key | Default | Remarks |
| ---------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| parent_id | BIGINT(20) | YES | | 0 | 父主键 |
| code | VARCHAR(255) | YES | | | 字典码 |
| dict_key | VARCHAR(255) | YES | | | 字典值 |
| dict_value | VARCHAR(255) | YES | | | 字典名称 |
| sort | INT(10) | YES | | | 排序 |
| remark | VARCHAR(255) | YES | | | 字典备注 |
| is_sealed | INT(10) | YES | | 0 | 是否已封存 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_dict_biz业务字典表
| Field | Type | Null | Key | Default | Remarks |
| ---------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | | 租户ID |
| parent_id | BIGINT(20) | YES | | 0 | 父主键 |
| code | VARCHAR(255) | YES | | | 字典码 |
| dict_key | VARCHAR(255) | YES | | | 字典值 |
| dict_value | VARCHAR(255) | YES | | | 字典名称 |
| sort | INT(10) | YES | | | 排序 |
| remark | VARCHAR(255) | YES | | | 字典备注 |
| is_sealed | INT(10) | YES | | 0 | 是否已封存 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_log_api接口日志表
| Field | Type | Null | Key | Default | Remarks |
| ------------ | ------------- | ---- | --- | ----------------- | ------- |
| id | BIGINT(20) | NO | PRI | | 编号 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| service_id | VARCHAR(32) | YES | | | 服务ID |
| server_host | VARCHAR(255) | YES | | | 服务器名 |
| server_ip | VARCHAR(255) | YES | | | 服务器IP地址 |
| env | VARCHAR(255) | YES | | | 服务器环境 |
| type | CHAR(1) | YES | | 1 | 日志类型 |
| title | VARCHAR(255) | YES | | | 日志标题 |
| method | VARCHAR(10) | YES | | | 操作方式 |
| request_uri | VARCHAR(255) | YES | | | 请求URI |
| user_agent | VARCHAR(1000) | YES | | | 用户代理 |
| remote_ip | VARCHAR(255) | YES | | | 操作IP地址 |
| method_class | VARCHAR(255) | YES | | | 方法类 |
| method_name | VARCHAR(255) | YES | | | 方法名 |
| params | TEXT(65535) | YES | | | 操作提交的数据 |
| time | VARCHAR(64) | YES | | | 执行时间 |
| create_by | VARCHAR(64) | YES | | | 创建者 |
| create_time | DATETIME(19) | YES | | CURRENT_TIMESTAMP | 创建时间 |
Table: blade_log_error错误日志表
| Field | Type | Null | Key | Default | Remarks |
| -------------- | ------------- | ---- | --- | ----------------- | ------- |
| id | BIGINT(20) | NO | PRI | | 编号 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| service_id | VARCHAR(32) | YES | | | 服务ID |
| server_host | VARCHAR(255) | YES | | | 服务器名 |
| server_ip | VARCHAR(255) | YES | | | 服务器IP地址 |
| env | VARCHAR(255) | YES | | | 系统环境 |
| method | VARCHAR(10) | YES | | | 操作方式 |
| request_uri | VARCHAR(255) | YES | | | 请求URI |
| user_agent | VARCHAR(1000) | YES | | | 用户代理 |
| stack_trace | TEXT(65535) | YES | | | 堆栈 |
| exception_name | VARCHAR(255) | YES | | | 异常名 |
| message | TEXT(65535) | YES | | | 异常信息 |
| line_number | INT(10) | YES | | | 错误行数 |
| remote_ip | VARCHAR(255) | YES | | | 操作IP地址 |
| method_class | VARCHAR(255) | YES | | | 方法类 |
| file_name | VARCHAR(1000) | YES | | | 文件名 |
| method_name | VARCHAR(255) | YES | | | 方法名 |
| params | TEXT(65535) | YES | | | 操作提交的数据 |
| create_by | VARCHAR(64) | YES | | | 创建者 |
| create_time | DATETIME(19) | YES | | CURRENT_TIMESTAMP | 创建时间 |
Table: blade_log_usual通用日志表
| Field | Type | Null | Key | Default | Remarks |
| ------------ | ------------- | ---- | --- | ----------------- | ------- |
| id | BIGINT(20) | NO | PRI | | 编号 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| service_id | VARCHAR(32) | YES | | | 服务ID |
| server_host | VARCHAR(255) | YES | | | 服务器名 |
| server_ip | VARCHAR(255) | YES | | | 服务器IP地址 |
| env | VARCHAR(255) | YES | | | 系统环境 |
| log_level | VARCHAR(10) | YES | | | 日志级别 |
| log_id | VARCHAR(100) | YES | | | 日志业务id |
| log_data | TEXT(65535) | YES | | | 日志数据 |
| method | VARCHAR(10) | YES | | | 操作方式 |
| request_uri | VARCHAR(255) | YES | | | 请求URI |
| remote_ip | VARCHAR(255) | YES | | | 操作IP地址 |
| method_class | VARCHAR(255) | YES | | | 方法类 |
| method_name | VARCHAR(255) | YES | | | 方法名 |
| user_agent | VARCHAR(1000) | YES | | | 用户代理 |
| params | TEXT(65535) | YES | | | 操作提交的数据 |
| create_by | VARCHAR(64) | YES | | | 创建者 |
| create_time | DATETIME(19) | YES | | CURRENT_TIMESTAMP | 创建时间 |
Table: blade_menu菜单表
| Field | Type | Null | Key | Default | Remarks |
| ---------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| parent_id | BIGINT(20) | YES | | 0 | 父级菜单 |
| code | VARCHAR(255) | YES | | | 菜单编号 |
| name | VARCHAR(255) | YES | | | 菜单名称 |
| alias | VARCHAR(255) | YES | | | 菜单别名 |
| path | VARCHAR(255) | YES | | | 请求地址 |
| source | VARCHAR(255) | YES | | | 菜单资源 |
| sort | INT(10) | YES | | | 排序 |
| category | INT(10) | YES | | | 菜单类型 |
| action | INT(10) | YES | | 0 | 操作按钮类型 |
| is_open | INT(10) | YES | | 1 | 是否打开新页面 |
| remark | VARCHAR(255) | YES | | | 备注 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_model数据模型表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| datasource_id | BIGINT(20) | YES | | | 数据源主键 |
| model_name | VARCHAR(50) | YES | | | 模型名称 |
| model_code | VARCHAR(50) | YES | | | 模型编号 |
| model_table | VARCHAR(100) | YES | | | 物理表名 |
| model_class | VARCHAR(100) | YES | | | 模型类名 |
| model_remark | VARCHAR(500) | YES | | | 模型备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_model_prototype数据原型表
| Field | Type | Null | Key | Default | Remarks |
| -------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| model_id | BIGINT(20) | YES | | | 模型主键 |
| jdbc_name | VARCHAR(50) | YES | | | 物理列名 |
| jdbc_type | VARCHAR(20) | YES | | | 物理类型 |
| jdbc_comment | VARCHAR(500) | YES | | | 注释说明 |
| property_type | VARCHAR(20) | YES | | | 实体类型 |
| property_entity| VARCHAR(500) | YES | | | 实体类型引用|
| property_name | VARCHAR(50) | YES | | | 实体列名 |
| is_list | INT(10) | YES | | | 列表显示 |
| is_form | INT(10) | YES | | | 表单显示 |
| is_row | INT(10) | YES | | | 独占一行 |
| component_type | VARCHAR(50) | YES | | | 组件类型 |
| dict_code | VARCHAR(50) | YES | | | 字典编码 |
| is_required | INT(10) | YES | | | 是否必填 |
| is_query | INT(10) | YES | | | 查询配置 |
| query_type | VARCHAR(50) | YES | | | 查询配置 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_notice通知公告表
| Field | Type | Null | Key | Default | Remarks |
| ------------ | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| title | VARCHAR(255) | YES | | | 标题 |
| category | INT(10) | YES | | | 类型 |
| release_time | DATETIME(19) | YES | | | 发布时间 |
| content | VARCHAR(2000) | YES | | | 内容 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_oss对象存储表
| Field | Type | Null | Key | Default | Remarks |
|--------------------| ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| category | INT(10) | YES | | | 分类 |
| oss_code | VARCHAR(32) | YES | | | 资源编号 |
| endpoint | VARCHAR(255) | YES | | | 资源地址 |
| transform_endpoint | VARCHAR(255) | YES | | | 外网资源地址 |
| access_key | VARCHAR(255) | YES | | | accessKey|
| secret_key | VARCHAR(255) | YES | | | secretKey|
| bucket_name | VARCHAR(255) | YES | | | 空间名 |
| app_id | VARCHAR(255) | YES | | | 应用ID |
| region | VARCHAR(255) | YES | | | 地域简称 |
| remark | VARCHAR(255) | YES | | | 备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_param参数表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| param_name | VARCHAR(255) | YES | | | 参数名 |
| param_key | VARCHAR(255) | YES | | | 参数键 |
| param_value | VARCHAR(255) | YES | | | 参数值 |
| remark | VARCHAR(255) | YES | | | 备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_post岗位表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| category | INT(10) | YES | | | 岗位类型 |
| post_code | VARCHAR(12) | YES | | | 岗位编号 |
| post_name | VARCHAR(64) | YES | | | 岗位名称 |
| sort | INT(10) | YES | | | 岗位排序 |
| remark | VARCHAR(255) | YES | | | 岗位描述 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_process_leave流程请假业务表
| Field | Type | Null | Key | Default | Remarks |
| --------------------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 编号 |
| process_definition_id | VARCHAR(64) | YES | | | 流程定义主键 |
| process_instance_id | VARCHAR(64) | YES | | | 流程实例主键 |
| start_time | DATETIME(19) | YES | | | 开始时间 |
| end_time | DATETIME(19) | YES | | | 结束时间 |
| reason | VARCHAR(255) | YES | | | 请假理由 |
| task_user | VARCHAR(255) | YES | | | 第一级审批人 |
| apply_time | DATETIME(19) | YES | | | 申请时间 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_region行政区划表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------ | ---- | --- | ------- | ------- |
| code | VARCHAR(12) | NO | PRI | | 区划编号 |
| parent_code | VARCHAR(12) | YES | | | 父区划编号 |
| ancestors | VARCHAR(255) | YES | | | 祖区划编号 |
| name | VARCHAR(32) | YES | | | 区划名称 |
| province_code | VARCHAR(12) | YES | | | 省级区划编号 |
| province_name | VARCHAR(32) | YES | | | 省级名称 |
| city_code | VARCHAR(12) | YES | | | 市级区划编号 |
| city_name | VARCHAR(32) | YES | | | 市级名称 |
| district_code | VARCHAR(12) | YES | | | 区级区划编号 |
| district_name | VARCHAR(32) | YES | | | 区级名称 |
| town_code | VARCHAR(12) | YES | | | 镇级区划编号 |
| town_name | VARCHAR(32) | YES | | | 镇级名称 |
| village_code | VARCHAR(12) | YES | | | 村级区划编号 |
| village_name | VARCHAR(32) | YES | | | 村级名称 |
| region_level | INT(10) | YES | | | 层级 |
| sort | INT(10) | YES | | | 排序 |
| remark | VARCHAR(255) | YES | | | 备注 |
Table: blade_report_file报表文件表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | -------------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| name | VARCHAR(100) | NO | | | 文件名 |
| content | MEDIUMBLOB(16777215) | YES | | | 文件内容 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_time | DATETIME(19) | YES | | | 更新时间 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_role角色表
| Field | Type | Null | Key | Default | Remarks |
| ---------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| parent_id | BIGINT(20) | YES | | 0 | 父主键 |
| role_name | VARCHAR(255) | YES | | | 角色名 |
| sort | INT(10) | YES | | | 排序 |
| role_alias | VARCHAR(255) | YES | | | 角色别名 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_role_menu角色菜单关联表
| Field | Type | Null | Key | Default | Remarks |
| ------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| menu_id | BIGINT(20) | YES | | | 菜单id |
| role_id | BIGINT(20) | YES | | | 角色id |
Table: blade_role_scope角色数据权限关联表
| Field | Type | Null | Key | Default | Remarks |
| -------------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| scope_category | INT(10) | YES | | | 权限类型(1:数据权限、2:接口权限)|
| scope_id | BIGINT(20) | YES | | | 权限id |
| role_id | BIGINT(20) | YES | | | 角色id |
Table: blade_scope_api接口权限表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| menu_id | BIGINT(20) | YES | | | 菜单主键 |
| resource_code | VARCHAR(255) | YES | | | 资源编号 |
| scope_name | VARCHAR(255) | YES | | | 接口权限名 |
| scope_path | VARCHAR(255) | YES | | | 接口权限地址 |
| scope_type | INT(10) | YES | | | 接口权限类型 |
| remark | VARCHAR(255) | YES | | | 接口权限备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_scope_data数据权限表
| Field | Type | Null | Key | Default | Remarks |
| ------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| menu_id | BIGINT(20) | YES | | | 菜单主键 |
| resource_code | VARCHAR(255) | YES | | | 资源编号 |
| scope_name | VARCHAR(255) | YES | | | 数据权限名称 |
| scope_field | VARCHAR(255) | YES | | | 数据权限字段 |
| scope_class | VARCHAR(500) | YES | | | 数据权限类名 |
| scope_column | VARCHAR(255) | YES | | | 数据权限字段 |
| scope_type | INT(10) | YES | | | 数据权限类型 |
| scope_value | VARCHAR(2000) | YES | | | 数据权限值域 |
| remark | VARCHAR(255) | YES | | | 数据权限备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_sms短信配置表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| category | INT(10) | YES | | | 分类 |
| sms_code | VARCHAR(32) | YES | | | 资源编号 |
| template_id | VARCHAR(64) | YES | | | 模板ID |
| access_key | VARCHAR(255) | YES | | | accessKey|
| secret_key | VARCHAR(255) | YES | | | secretKey|
| region_id | VARCHAR(255) | YES | | | regionId|
| sign_name | VARCHAR(64) | YES | | | 短信签名 |
| remark | VARCHAR(255) | YES | | | 备注 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_tenant租户表
| Field | Type | Null | Key | Default | Remarks |
| -------------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| tenant_name | VARCHAR(50) | NO | | | 租户名称 |
| domain_url | VARCHAR(255) | YES | | | 域名地址 |
| background_url | VARCHAR(1000) | YES | | | 系统背景 |
| linkman | VARCHAR(20) | YES | | | 联系人 |
| contact_number | VARCHAR(20) | YES | | | 联系电话 |
| address | VARCHAR(255) | YES | | | 联系地址 |
| account_number | INT(10) | YES | | -1 | 账号额度 |
| expire_time | DATETIME(19) | YES | | | 过期时间 |
| datasource | BIGINT(20) | YES | | | 数据源ID |
| license_key | VARCHAR(1000) | YES | | | 授权码 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_top_menu顶部菜单表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | ------------ | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | | 租户id |
| code | VARCHAR(255) | YES | | | 顶部菜单编号 |
| name | VARCHAR(255) | YES | | | 顶部菜单名 |
| source | VARCHAR(255) | YES | | | 顶部菜单资源 |
| sort | INT(10) | YES | | | 顶部菜单排序 |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | | 是否已删除 |
Table: blade_top_menu_setting顶部菜单配置表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| top_menu_id | BIGINT(20) | YES | | | 顶部菜单主键 |
| menu_id | BIGINT(20) | YES | | | 菜单主键 |
Table: blade_user用户表
| Field | Type | Null | Key | Default | Remarks |
| ----------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | 000000 | 租户ID |
| code | VARCHAR(12) | YES | | | 用户编号 |
| user_type | SMALLINT(5) | YES | | | 用户平台 |
| account | VARCHAR(45) | YES | | | 账号 |
| password | VARCHAR(45) | YES | | | 密码 |
| name | VARCHAR(20) | YES | | | 昵称 |
| real_name | VARCHAR(10) | YES | | | 真名 |
| avatar | VARCHAR(500) | YES | | | 头像 |
| email | VARCHAR(45) | YES | | | 邮箱 |
| phone | VARCHAR(45) | YES | | | 手机 |
| birthday | DATETIME(19) | YES | | | 生日 |
| sex | SMALLINT(5) | YES | | | 性别 |
| role_id | VARCHAR(1000) | YES | | | 角色id |
| dept_id | VARCHAR(1000) | YES | | | 部门id |
| post_id | VARCHAR(1000) | YES | | | 岗位id |
| create_user | BIGINT(20) | YES | | | 创建人 |
| create_dept | BIGINT(20) | YES | | | 创建部门 |
| create_time | DATETIME(19) | YES | | | 创建时间 |
| update_user | BIGINT(20) | YES | | | 修改人 |
| update_time | DATETIME(19) | YES | | | 修改时间 |
| status | INT(10) | YES | | | 状态 |
| is_deleted | INT(10) | YES | | 0 | 是否已删除 |
Table: blade_user_dept用户部门表
| Field | Type | Null | Key | Default | Remarks |
| ------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| user_id | BIGINT(20) | YES | | 0 | 用户ID |
| dept_id | BIGINT(20) | YES | | 0 | 部门ID |
Table: blade_user_oauth用户第三方认证表
| Field | Type | Null | Key | Default | Remarks |
| --------- | ------------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| tenant_id | VARCHAR(12) | YES | | | 租户ID |
| uuid | VARCHAR(64) | YES | | | 第三方系统用户ID|
| user_id | BIGINT(20) | YES | | | 用户ID |
| username | VARCHAR(32) | YES | | | 账号 |
| nickname | VARCHAR(64) | YES | | | 用户名 |
| avatar | VARCHAR(1000) | YES | | | 头像 |
| blog | VARCHAR(50) | YES | | | 应用主页 |
| company | VARCHAR(255) | YES | | | 公司名 |
| location | VARCHAR(255) | YES | | | 地址 |
| email | VARCHAR(255) | YES | | | 邮件 |
| remark | VARCHAR(255) | YES | | | 备注 |
| gender | VARCHAR(16) | YES | | | 性别 |
| source | VARCHAR(16) | YES | | | 来源 |
Table: blade_user_web用户平台拓展表
| Field | Type | Null | Key | Default | Remarks |
| ------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| user_id | BIGINT(20) | YES | | 0 | 用户ID |
| user_ext | VARCHAR(255) | YES | | | 用户拓展信息 |
Table: blade_user_app用户平台拓展表
| Field | Type | Null | Key | Default | Remarks |
| ------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| user_id | BIGINT(20) | YES | | 0 | 用户ID |
| user_ext | VARCHAR(255) | YES | | | 用户拓展信息 |
Table: blade_user_other用户平台拓展表
| Field | Type | Null | Key | Default | Remarks |
| ------- | ---------- | ---- | --- | ------- | ------- |
| id | BIGINT(20) | NO | PRI | | 主键 |
| user_id | BIGINT(19) | YES | | 0 | 用户ID |
| user_ext | VARCHAR(255) | YES | | | 用户拓展信息 |
Table: blade_job_server (任务服务表)
| Field | Type | Null | Key | Default | Remarks |
|-------------------|--------------|------|-----|---------|----------------------|
| id | BIGINT(20) | NO | PRI | | 主键 |
| job_server_name | VARCHAR(50) | YES | | NULL | 任务服务名称 |
| job_server_url | VARCHAR(255) | YES | | NULL | 任务服务器地址 |
| job_app_name | VARCHAR(20) | YES | | NULL | 任务应用名称 |
| job_app_password | VARCHAR(100) | YES | | NULL | 任务应用密码 |
| job_remark | VARCHAR(255) | YES | | NULL | 任务备注 |
| create_user | BIGINT(20) | YES | | NULL | 创建人 |
| create_dept | BIGINT(20) | YES | | NULL | 创建部门 |
| create_time | DATETIME | YES | | NULL | 创建时间 |
| update_user | BIGINT(20) | YES | | NULL | 修改人 |
| update_time | DATETIME | YES | | NULL | 修改时间 |
| status | INT(2) | YES | | NULL | 状态 |
| is_deleted | INT(2) | YES | | 0 | 是否已删除 |
Table: blade_job_info (任务信息表)
| Field | Type | Null | Key | Default | Remarks |
|------------------------|------------------------|------|-----|---------|-----------------------------------|
| id | BIGINT(20) | NO | PRI | | 主键 |
| job_server_id | BIGINT(20) | YES | | NULL | 任务服务ID |
| job_id | BIGINT(20) | YES | | NULL | 任务 ID |
| job_name | VARCHAR(50) | YES | | NULL | 任务名称 |
| job_description | VARCHAR(255) | YES | | NULL | 任务描述 |
| job_params | TEXT | YES | | | 任务参数 |
| time_expression_type | INT(2) | YES | | NULL | 时间表达式类型 |
| time_expression | VARCHAR(255) | YES | | NULL | 时间表达式 |
| execute_type | INT(2) | YES | | NULL | 执行类型 |
| processor_type | INT(2) | YES | | NULL | 处理器类型 |
| processor_info | VARCHAR(255) | YES | | NULL | 处理器参数 |
| max_instance_num | INT(11) | YES | | NULL | 最大实例数 |
| concurrency | INT(11) | YES | | NULL | 单机线程并发数 |
| instance_time_limit | BIGINT(20) | YES | | NULL | 任务实例运行时间限制 |
| instance_retry_num | INT(11) | YES | | NULL | 任务实例重试次数 |
| task_retry_num | INT(11) | YES | | NULL | Task 重试次数 |
| min_cpu_cores | DOUBLE | YES | | NULL | 最小可用 CPU 核心数 |
| min_memory_space | DOUBLE | YES | | NULL | 最小内存大小GB |
| min_disk_space | DOUBLE | YES | | NULL | 最小磁盘大小GB |
| designated_workers | VARCHAR(255) | YES | | NULL | 指定机器执行 |
| max_worker_count | INT(2) | YES | | NULL | 最大执行机器数量 |
| notify_user_ids | VARCHAR(2000) | YES | | NULL | 接收报警的用户 ID 列表 |
| enable | INT(2) | YES | | NULL | 是否启用该任务 |
| dispatch_strategy | INT(2) | YES | | NULL | 调度策略 |
| lifecycle | VARCHAR(255) | YES | | NULL | 生命周期 |
| alert_threshold | INT(2) | YES | | NULL | 错误阈值 |
| statistic_window_len | INT(2) | YES | | NULL | 统计的窗口长度(s) |
| silence_window_len | INT(2) | YES | | NULL | 沉默时间窗口(s) |
| log_type | INT(2) | YES | | NULL | 日志配置 |
| log_level | INT(2) | YES | | NULL | 日志级别 |
| extra | VARCHAR(255) | YES | | NULL | 扩展字段 |
| create_user | BIGINT(20) | YES | | NULL | 创建人 |
| create_dept | BIGINT(20) | YES | | NULL | 创建部门 |
| create_time | DATETIME | YES | | NULL | 创建时间 |
| update_user | BIGINT(20) | YES | | NULL | 修改人 |
| update_time | DATETIME | YES | | NULL | 修改时间 |
| status | INT(2) | YES | | NULL | 状态 |
| is_deleted | INT(2) | YES | | 0 | 是否已删除 |

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,16 @@
-- -----------------------------------
-- 修改应用表的授权集合
-- -----------------------------------
UPDATE "BLADEX"."BLADE_CLIENT" SET AUTHORIZED_GRANT_TYPES = 'authorization_code,password,refresh_token,captcha,social,register' where ID < 1123598811738675203;
-- -----------------------------------
-- 删除可能重复的菜单
-- -----------------------------------
DELETE FROM "BLADEX"."BLADE_CLIENT" WHERE "CLIENT_ID" = 'saber3';
DELETE FROM "BLADEX"."BLADE_CLIENT" WHERE "CLIENT_ID" = 'rider';
-- -----------------------------------
-- 新增客户端记录
-- -----------------------------------
INSERT INTO "BLADEX"."BLADE_CLIENT" ("ID", "CLIENT_ID", "CLIENT_SECRET", "RESOURCE_IDS", "SCOPE", "AUTHORIZED_GRANT_TYPES", "WEB_SERVER_REDIRECT_URI", "AUTHORITIES", "ACCESS_TOKEN_VALIDITY", "REFRESH_TOKEN_VALIDITY", "ADDITIONAL_INFORMATION", "AUTOAPPROVE", "CREATE_USER", "CREATE_DEPT", "CREATE_TIME", "UPDATE_USER", "UPDATE_TIME", "STATUS", "IS_DELETED") VALUES ('1123598811738675203', 'saber3', 'saber3_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:2888/login', NULL, '3600', '604800', NULL, NULL, '1123598815738675201', '1123598813738675201', '2024-04-01 00:00:00', '1123598815738675201', '2024-04-01 00:00:00', '1', '0');
INSERT INTO "BLADEX"."BLADE_CLIENT" ("ID", "CLIENT_ID", "CLIENT_SECRET", "RESOURCE_IDS", "SCOPE", "AUTHORIZED_GRANT_TYPES", "WEB_SERVER_REDIRECT_URI", "AUTHORITIES", "ACCESS_TOKEN_VALIDITY", "REFRESH_TOKEN_VALIDITY", "ADDITIONAL_INFORMATION", "AUTOAPPROVE", "CREATE_USER", "CREATE_DEPT", "CREATE_TIME", "UPDATE_USER", "UPDATE_TIME", "STATUS", "IS_DELETED") VALUES ('1123598811738675204', 'rider', 'rider_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:88', NULL, '3600', '604800', NULL, NULL, '1123598815738675201', '1123598813738675201', '2024-04-01 00:00:00', '1123598815738675201', '2024-04-01 00:00:00', '1', '0');

@ -0,0 +1,16 @@
-- -----------------------------------
-- 修改应用表saber的访问地址
-- -----------------------------------
UPDATE `blade_client` SET authorized_grant_types = 'authorization_code,password,refresh_token,captcha,social,register' where id < 1123598811738675203;
-- -----------------------------------
-- 删除可能重复的菜单
-- -----------------------------------
DELETE FROM `blade_client` WHERE client_id = 'saber3';
DELETE FROM `blade_client` WHERE client_id = 'rider';
-- -----------------------------------
-- 新增模型设计菜单
-- -----------------------------------
INSERT INTO `blade_client` (`id`, `client_id`, `client_secret`, `resource_ids`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `autoapprove`, `create_user`, `create_dept`, `create_time`, `update_user`, `update_time`, `status`, `is_deleted`) VALUES (1123598811738675203, 'saber3', 'saber3_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:2888/login', NULL, 3600, 604800, NULL, NULL, 1123598815738675201, 1123598813738675201, '2024-04-01 00:00:00', 1123598815738675201, '2024-04-01 00:00:00', 1, 0);
INSERT INTO `blade_client` (`id`, `client_id`, `client_secret`, `resource_ids`, `scope`, `authorized_grant_types`, `web_server_redirect_uri`, `authorities`, `access_token_validity`, `refresh_token_validity`, `additional_information`, `autoapprove`, `create_user`, `create_dept`, `create_time`, `update_user`, `update_time`, `status`, `is_deleted`) VALUES (1123598811738675204, 'rider', 'rider_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:88', NULL, 3600, 604800, NULL, NULL, 1123598815738675201, 1123598813738675201, '2024-04-01 00:00:00', 1123598815738675201, '2024-04-01 00:00:00', 1, 0);

@ -0,0 +1,16 @@
-- -----------------------------------
-- 修改应用表的授权集合
-- -----------------------------------
UPDATE "BLADEX"."BLADE_CLIENT" SET AUTHORIZED_GRANT_TYPES = 'authorization_code,password,refresh_token,captcha,social,register' where ID < 1123598811738675203;
-- -----------------------------------
-- 删除可能重复的菜单
-- -----------------------------------
DELETE FROM "BLADEX"."BLADE_CLIENT" WHERE "CLIENT_ID" = 'saber3';
DELETE FROM "BLADEX"."BLADE_CLIENT" WHERE "CLIENT_ID" = 'rider';
-- -----------------------------------
-- 新增客户端记录
-- -----------------------------------
INSERT INTO "BLADEX"."BLADE_CLIENT" ("ID", "CLIENT_ID", "CLIENT_SECRET", "RESOURCE_IDS", "SCOPE", "AUTHORIZED_GRANT_TYPES", "WEB_SERVER_REDIRECT_URI", "AUTHORITIES", "ACCESS_TOKEN_VALIDITY", "REFRESH_TOKEN_VALIDITY", "ADDITIONAL_INFORMATION", "AUTOAPPROVE", "CREATE_USER", "CREATE_DEPT", "CREATE_TIME", "UPDATE_USER", "UPDATE_TIME", "STATUS", "IS_DELETED") VALUES ('1123598811738675203', 'saber3', 'saber3_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:2888/login', NULL, '3600', '604800', NULL, NULL, '1123598815738675201', '1123598813738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1123598815738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1', '0');
INSERT INTO "BLADEX"."BLADE_CLIENT" ("ID", "CLIENT_ID", "CLIENT_SECRET", "RESOURCE_IDS", "SCOPE", "AUTHORIZED_GRANT_TYPES", "WEB_SERVER_REDIRECT_URI", "AUTHORITIES", "ACCESS_TOKEN_VALIDITY", "REFRESH_TOKEN_VALIDITY", "ADDITIONAL_INFORMATION", "AUTOAPPROVE", "CREATE_USER", "CREATE_DEPT", "CREATE_TIME", "UPDATE_USER", "UPDATE_TIME", "STATUS", "IS_DELETED") VALUES ('1123598811738675204', 'rider', 'rider_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:88', NULL, '3600', '604800', NULL, NULL, '1123598815738675201', '1123598813738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1123598815738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1', '0');

@ -0,0 +1,16 @@
-- -----------------------------------
-- 修改应用表的授权集合
-- -----------------------------------
UPDATE blade_client SET authorized_grant_types = 'authorization_code,password,refresh_token,captcha,social,register' WHERE client_id = 'saber';
-- -----------------------------------
-- 删除可能重复的菜单
-- -----------------------------------
DELETE FROM "blade_client" WHERE "client_id" = 'saber3';
DELETE FROM "blade_client" WHERE "client_id" = 'rider';
-- -----------------------------------
-- 新增客户端记录
-- -----------------------------------
INSERT INTO "blade_client" ("id", "client_id", "client_secret", "resource_ids", "scope", "authorized_grant_types", "web_server_redirect_uri", "authorities", "access_token_validity", "refresh_token_validity", "additional_information", "autoapprove", "create_user", "create_dept", "create_time", "update_user", "update_time", "status", "is_deleted") VALUES (1123598811738675203, 'saber3', 'saber3_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:2888/login', NULL, 3600, 604800, NULL, NULL, 1123598815738675201, 1123598813738675201, '2024-04-01 00:00:00', 1123598815738675201, '2024-04-01 00:00:00', 1, 0);
INSERT INTO "blade_client" ("id", "client_id", "client_secret", "resource_ids", "scope", "authorized_grant_types", "web_server_redirect_uri", "authorities", "access_token_validity", "refresh_token_validity", "additional_information", "autoapprove", "create_user", "create_dept", "create_time", "update_user", "update_time", "status", "is_deleted") VALUES (1123598811738675204, 'rider', 'rider_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:88', NULL, 3600, 604800, NULL, NULL, 1123598815738675201, 1123598813738675201, '2024-04-01 00:00:00', 1123598815738675201, '2024-04-01 00:00:00', 1, 0);

@ -0,0 +1,16 @@
-- -----------------------------------
-- 修改应用表saber的访问地址
-- -----------------------------------
UPDATE [dbo].[blade_client] SET [authorized_grant_types] = 'authorization_code,password,refresh_token,captcha,social,register' WHERE id < '1123598811738675203';
-- -----------------------------------
-- 删除可能重复的菜单
-- -----------------------------------
DELETE FROM [dbo].[blade_client] WHERE client_id = 'saber3';
DELETE FROM [dbo].[blade_client] WHERE client_id = 'rider';
-- -----------------------------------
-- 新增模型设计菜单
-- -----------------------------------
INSERT INTO [dbo].[blade_client] ([id], [client_id], [client_secret], [resource_ids], [scope], [authorized_grant_types], [web_server_redirect_uri], [authorities], [access_token_validity], [refresh_token_validity], [additional_information], [autoapprove], [create_user], [create_dept], [create_time], [update_user], [update_time], [status], [is_deleted]) VALUES (1123598811738675203, N'saber3', N'saber3_secret', NULL, N'all', N'authorization_code,password,refresh_token,captcha,social,register', N'http://localhost:2888/login', NULL, 3600, 604800, NULL, NULL, 1123598815738675201, 1123598813738675201, '2024-04-01 00:00:00', 1123598815738675201, '2024-04-01 00:00:00', 1, 0);
INSERT INTO [dbo].[blade_client] ([id], [client_id], [client_secret], [resource_ids], [scope], [authorized_grant_types], [web_server_redirect_uri], [authorities], [access_token_validity], [refresh_token_validity], [additional_information], [autoapprove], [create_user], [create_dept], [create_time], [update_user], [update_time], [status], [is_deleted]) VALUES (1123598811738675204, N'rider', N'rider_secret', NULL, N'all', N'authorization_code,password,refresh_token,captcha,social,register', N'http://localhost:88', NULL, 3600, 604800, NULL, NULL, 1123598815738675201, 1123598813738675201, '2024-04-01 00:00:00', 1123598815738675201, '2024-04-01 00:00:00', 1, 0);

@ -0,0 +1,16 @@
-- -----------------------------------
-- 修改应用表的授权集合
-- -----------------------------------
UPDATE "BLADE_CLIENT" SET AUTHORIZED_GRANT_TYPES = 'authorization_code,password,refresh_token,captcha,social,register' where ID < 1123598811738675203;
-- -----------------------------------
-- 删除可能重复的菜单
-- -----------------------------------
DELETE FROM "BLADE_CLIENT" WHERE "CLIENT_ID" = 'saber3';
DELETE FROM "BLADE_CLIENT" WHERE "CLIENT_ID" = 'rider';
-- -----------------------------------
-- 新增客户端记录
-- -----------------------------------
INSERT INTO "BLADE_CLIENT" ("ID", "CLIENT_ID", "CLIENT_SECRET", "RESOURCE_IDS", "SCOPE", "AUTHORIZED_GRANT_TYPES", "WEB_SERVER_REDIRECT_URI", "AUTHORITIES", "ACCESS_TOKEN_VALIDITY", "REFRESH_TOKEN_VALIDITY", "ADDITIONAL_INFORMATION", "AUTOAPPROVE", "CREATE_USER", "CREATE_DEPT", "CREATE_TIME", "UPDATE_USER", "UPDATE_TIME", "STATUS", "IS_DELETED") VALUES ('1123598811738675203', 'saber3', 'saber3_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:2888/login', NULL, '3600', '604800', NULL, NULL, '1123598815738675201', '1123598813738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1123598815738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1', '0');
INSERT INTO "BLADE_CLIENT" ("ID", "CLIENT_ID", "CLIENT_SECRET", "RESOURCE_IDS", "SCOPE", "AUTHORIZED_GRANT_TYPES", "WEB_SERVER_REDIRECT_URI", "AUTHORITIES", "ACCESS_TOKEN_VALIDITY", "REFRESH_TOKEN_VALIDITY", "ADDITIONAL_INFORMATION", "AUTOAPPROVE", "CREATE_USER", "CREATE_DEPT", "CREATE_TIME", "UPDATE_USER", "UPDATE_TIME", "STATUS", "IS_DELETED") VALUES ('1123598811738675204', 'rider', 'rider_secret', NULL, 'all', 'authorization_code,password,refresh_token,captcha,social,register', 'http://localhost:88', NULL, '3600', '604800', NULL, NULL, '1123598815738675201', '1123598813738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1123598815738675201', TO_DATE('2024-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1', '0');

@ -0,0 +1,359 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springblade</groupId>
<artifactId>nenghui-uat</artifactId>
<packaging>jar</packaging>
<version>4.0.1.RELEASE</version>
<properties>
<bladex.project.id>nenghui-uat</bladex.project.id>
<bladex.project.version>4.0.1.RELEASE</bladex.project.version>
<java.version>17</java.version>
<maven.plugin.version>3.11.0</maven.plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Docker仓库服务配置 -->
<docker.registry.url>192.168.0.188</docker.registry.url>
<docker.username>admin</docker.username>
<docker.password>admin12345</docker.password>
<docker.namespace>blade</docker.namespace>
<docker.fabric.version>0.42.0</docker.fabric.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springblade.platform</groupId>
<artifactId>blade-bom</artifactId>
<version>${bladex.project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Blade -->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-boot</artifactId>
<exclusions>
<exclusion>
<groupId>org.springblade</groupId>
<artifactId>blade-core-cloud</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-oauth2</artifactId>
</dependency>
<!-- 多租户字段隔离模式 -->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-tenant</artifactId>
</dependency>
<!-- 多租户数据库隔离模式则引入此配置 -->
<!--<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-tenant-dynamic</artifactId>
</dependency>-->
<!-- 集成sharding功能则引入此配置 -->
<!--<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-sharding</artifactId>
</dependency>-->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-http</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-api-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-datascope</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-develop</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-swagger</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-social</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-powerjob</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-auto</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 报表 -->
<!-- <dependency>-->
<!-- <groupId>org.springblade</groupId>-->
<!-- <artifactId>blade-starter-report</artifactId>-->
<!-- </dependency>-->
<!-- 工作流 -->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-flowable</artifactId>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
</dependency>
<!-- Mybatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<!--Oss-->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-oss</artifactId>
</dependency>
<!--Sms-->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-sms</artifactId>
</dependency>
<!--Aws S3-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
<!--MinIO-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
<!--Alioss-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
<!--AliSms-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<!--华为云Obs-->
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java</artifactId>
</dependency>
<!--腾讯COS-->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
</dependency>
<!--腾讯SMS-->
<dependency>
<groupId>com.github.qcloudsms</groupId>
<artifactId>qcloudsms</artifactId>
</dependency>
<!--QiNiu-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<!--YunPian-->
<dependency>
<groupId>com.yunpian.sdk</groupId>
<artifactId>yunpian-java-sdk</artifactId>
</dependency>
<!-- liteflow -->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-starter-liteflow</artifactId>
</dependency>
<!-- Oracle -->
<!--<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
</dependency>-->
<!-- PostgreSql -->
<!--<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>-->
<!-- SqlServer -->
<!--<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>-->
<!-- DaMeng -->
<!--<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
</dependency>-->
<!--YashanDB-->
<!--<dependency>
<groupId>com.yashandb.jdbc</groupId>
<artifactId>yasdb-jdbc</artifactId>
</dependency>-->
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.httpcomponents.client5</groupId>-->
<!-- <artifactId>httpclient5</artifactId>-->
<!-- <version>5.1.3</version> &lt;!&ndash; 请使用最新的版本号 &ndash;&gt;-->
<!-- </dependency>-->
</dependencies>
<build>
<finalName>${bladex.project.id}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<finalName>${project.build.finalName}</finalName>
<excludes>
<!-- 打包的 jar 中排除 lombok -->
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.fabric.version}</version>
<configuration>
<authConfig>
<username>${docker.username}</username>
<password>${docker.password}</password>
</authConfig>
<registry>${docker.registry.url}</registry>
<images>
<image>
<name>${docker.namespace}/${project.build.finalName}:${project.version}</name>
<alias>${project.name}</alias>
<build>
<dockerFile>${project.basedir}/Dockerfile</dockerFile>
</build>
</image>
</images>
<buildArgs>
<JAR_FILE>${basedir}/target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyun-repos</id>
<name>Aliyun Public Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>bladex</id>
<name>BladeX Release Repository</name>
<url>https://center.javablade.com/api/packages/blade/maven</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<name>Aliyun Public Plugin</name>
<url>https://maven.aliyun.com/repository/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<distributionManagement>
<repository>
<id>bladex</id>
<name>BladeX Release Repository</name>
<url>https://center.javablade.com/api/packages/blade/maven</url>
</repository>
<snapshotRepository>
<id>bladex</id>
<name>BladeX Snapshot Repository</name>
<url>https://center.javablade.com/api/packages/blade/maven</url>
</snapshotRepository>
</distributionManagement>
</project>

@ -0,0 +1,49 @@
/**
* 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;
import org.springblade.common.constant.CommonConstant;
import org.springblade.core.launch.BladeApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
*
*
* @author Chill
*/
@EnableScheduling
@EnableRedisHttpSession
@SpringBootApplication
public class Application {
public static void main(String[] args) {
BladeApplication.run(CommonConstant.APPLICATION_NAME, Application.class, args);
}
}

@ -0,0 +1,70 @@
/**
* 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.common.cache;
import org.springblade.core.tool.utils.StringPool;
/**
*
*
* @author Chill
*/
public interface CacheNames {
/**
* key
*
* @param cacheKey key
* @param cacheKeyValue key
* @return tenantKey
*/
static String cacheKey(String cacheKey, String cacheKeyValue) {
return cacheKey.concat(cacheKeyValue);
}
/**
* key
*
* @param tenantId
* @param cacheKey key
* @param cacheKeyValue key
* @return tenantKey
*/
static String tenantKey(String tenantId, String cacheKey, String cacheKeyValue) {
return tenantId.concat(StringPool.COLON).concat(cacheKey).concat(cacheKeyValue);
}
/**
* key
*/
String CAPTCHA_KEY = "blade:auth::blade:captcha:";
/**
* key
*/
String USER_FAIL_KEY = "blade:user::blade:fail:";
}

@ -0,0 +1,125 @@
/**
* 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.common.cache;
import org.springblade.common.enums.DictBizEnum;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.modules.system.pojo.entity.DictBiz;
import org.springblade.modules.system.service.IDictBizService;
import java.util.List;
import static org.springblade.core.cache.constant.CacheConstant.DICT_CACHE;
/**
*
*
* @author Chill
*/
public class DictBizCache {
private static final String DICT_ID = "dictBiz:id";
private static final String DICT_VALUE = "dictBiz:value";
private static final String DICT_LIST = "dictBiz:list";
private static final IDictBizService dictService;
static {
dictService = SpringUtil.getBean(IDictBizService.class);
}
/**
*
*
* @param id
* @return DictBiz
*/
public static DictBiz getById(Long id) {
String keyPrefix = DICT_ID.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
return CacheUtil.get(DICT_CACHE, keyPrefix, id, () -> dictService.getById(id));
}
/**
*
*
* @param code
* @param dictKey Integer
* @return String
*/
public static String getValue(DictBizEnum code, Integer dictKey) {
return getValue(code.getName(), dictKey);
}
/**
*
*
* @param code
* @param dictKey Integer
* @return String
*/
public static String getValue(String code, Integer dictKey) {
String keyPrefix = DICT_VALUE.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
return CacheUtil.get(DICT_CACHE, keyPrefix + code + StringPool.COLON, String.valueOf(dictKey), () -> dictService.getValue(code, String.valueOf(dictKey)));
}
/**
*
*
* @param code
* @param dictKey String
* @return String
*/
public static String getValue(DictBizEnum code, String dictKey) {
return getValue(code.getName(), dictKey);
}
/**
*
*
* @param code
* @param dictKey String
* @return String
*/
public static String getValue(String code, String dictKey) {
String keyPrefix = DICT_VALUE.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
return CacheUtil.get(DICT_CACHE, keyPrefix + code + StringPool.COLON, dictKey, () -> dictService.getValue(code, dictKey));
}
/**
*
*
* @param code
* @return List<DictBiz>
*/
public static List<DictBiz> getList(String code) {
String keyPrefix = DICT_LIST.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
return CacheUtil.get(DICT_CACHE, keyPrefix, code, () -> dictService.getList(code));
}
}

@ -0,0 +1,152 @@
/**
* 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.common.cache;
import org.springblade.common.enums.DictEnum;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.modules.system.pojo.entity.Dict;
import org.springblade.modules.system.service.IDictService;
import java.util.List;
import java.util.Optional;
import static org.springblade.core.cache.constant.CacheConstant.DICT_CACHE;
/**
*
*
* @author Chill
*/
public class DictCache {
private static final String DICT_ID = "dict:id:";
private static final String DICT_KEY = "dict:key:";
private static final String DICT_VALUE = "dict:value:";
private static final String DICT_LIST = "dict:list:";
private static final Boolean TENANT_MODE = Boolean.FALSE;
private static final IDictService dictService;
static {
dictService = SpringUtil.getBean(IDictService.class);
}
/**
*
*
* @param id
* @return Dict
*/
public static Dict getById(Long id) {
return CacheUtil.get(DICT_CACHE, DICT_ID, id, () -> dictService.getById(id), TENANT_MODE);
}
/**
*
*
* @param code
* @param dictValue
* @return String
*/
public static String getKey(DictEnum code, String dictValue) {
return getKey(code.getName(), dictValue);
}
/**
*
*
* @param code
* @param dictValue
* @return String
*/
public static String getKey(String code, String dictValue) {
return CacheUtil.get(DICT_CACHE, DICT_KEY + code + StringPool.COLON, dictValue, () -> {
List<Dict> list = getList(code);
Optional<String> key = list.stream().filter(
dict -> dict.getDictValue().equalsIgnoreCase(dictValue)
).map(Dict::getDictKey).findFirst();
return key.orElse(StringPool.EMPTY);
}, TENANT_MODE);
}
/**
*
*
* @param code
* @param dictKey Integer
* @return String
*/
public static String getValue(DictEnum code, Integer dictKey) {
return getValue(code.getName(), dictKey);
}
/**
*
*
* @param code
* @param dictKey Integer
* @return String
*/
public static String getValue(String code, Integer dictKey) {
return CacheUtil.get(DICT_CACHE, DICT_VALUE + code + StringPool.COLON, String.valueOf(dictKey), () -> dictService.getValue(code, String.valueOf(dictKey)), TENANT_MODE);
}
/**
*
*
* @param code
* @param dictKey String
* @return String
*/
public static String getValue(DictEnum code, String dictKey) {
return getValue(code.getName(), dictKey);
}
/**
*
*
* @param code
* @param dictKey String
* @return String
*/
public static String getValue(String code, String dictKey) {
return CacheUtil.get(DICT_CACHE, DICT_VALUE + code + StringPool.COLON, dictKey, () -> dictService.getValue(code, dictKey), TENANT_MODE);
}
/**
*
*
* @param code
* @return List<Dict>
*/
public static List<Dict> getList(String code) {
return CacheUtil.get(DICT_CACHE, DICT_LIST, code, () -> dictService.getList(code), TENANT_MODE);
}
}

@ -0,0 +1,71 @@
/**
* 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.common.cache;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.modules.system.pojo.entity.Param;
import org.springblade.modules.system.service.IParamService;
import static org.springblade.core.cache.constant.CacheConstant.PARAM_CACHE;
/**
*
*
* @author Chill
*/
public class ParamCache {
private static final String PARAM_ID = "param:id:";
private static final String PARAM_VALUE = "param:value:";
private static final IParamService paramService;
static {
paramService = SpringUtil.getBean(IParamService.class);
}
/**
*
*
* @param id
* @return Param
*/
public static Param getById(Long id) {
return CacheUtil.get(PARAM_CACHE, PARAM_ID, id, () -> paramService.getById(id));
}
/**
*
*
* @param paramKey
* @return String
*/
public static String getValue(String paramKey) {
return CacheUtil.get(PARAM_CACHE, PARAM_VALUE, paramKey, () -> paramService.getValue(paramKey));
}
}

@ -0,0 +1,66 @@
/**
* 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.common.cache;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.modules.system.pojo.entity.Region;
import org.springblade.modules.system.service.IRegionService;
import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
/**
*
*
* @author Chill
*/
public class RegionCache {
public static final String MAIN_CODE = "00";
public static final int PROVINCE_LEVEL = 1;
public static final int CITY_LEVEL = 2;
public static final int DISTRICT_LEVEL = 3;
public static final int TOWN_LEVEL = 4;
public static final int VILLAGE_LEVEL = 5;
private static final String REGION_CODE = "region:code:";
private static final IRegionService regionService;
static {
regionService = SpringUtil.getBean(IRegionService.class);
}
/**
*
*
* @param code
* @return Param
*/
public static Region getByCode(String code) {
return CacheUtil.get(SYS_CACHE, REGION_CODE, code, () -> regionService.getById(code));
}
}

@ -0,0 +1,326 @@
/**
* 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.common.cache;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.modules.system.pojo.entity.*;
import org.springblade.modules.system.service.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
/**
*
*
* @author Chill
*/
public class SysCache {
private static final String MENU_ID = "menu:id:";
private static final String DEPT_ID = "dept:id:";
private static final String DEPT_NAME = "dept:name:";
private static final String DEPT_NAME_FUZZY = "dept:nameFuzzy:";
private static final String DEPT_NAME_ID = "deptName:id:";
private static final String DEPT_NAMES_ID = "deptNames:id:";
private static final String DEPT_CHILD_ID = "deptChild:id:";
private static final String DEPT_CHILDIDS_ID = "deptChildIds:id:";
private static final String POST_ID = "post:id:";
private static final String POST_NAME = "post:name:";
private static final String POST_NAME_FUZZY = "post:nameFuzzy:";
private static final String POST_NAME_ID = "postName:id:";
private static final String POST_NAMES_ID = "postNames:id:";
private static final String ROLE_ID = "role:id:";
private static final String ROLE_NAME = "role:name:";
private static final String ROLE_NAME_ID = "roleName:id:";
private static final String ROLE_NAMES_ID = "roleNames:id:";
private static final String ROLE_ALIAS_ID = "roleAlias:id:";
private static final String ROLE_ALIASES_ID = "roleAliases:id:";
public static final String TENANT_ID = "tenant:id:";
public static final String TENANT_TENANT_ID = "tenant:tenantId:";
public static final String TENANT_PACKAGE_ID = "tenant:packageId:";
private static final IMenuService menuService;
private static final IDeptService deptService;
private static final IPostService postService;
private static final IRoleService roleService;
private static final ITenantService tenantService;
private static final ITenantPackageService tenantPackageService;
static {
menuService = SpringUtil.getBean(IMenuService.class);
deptService = SpringUtil.getBean(IDeptService.class);
postService = SpringUtil.getBean(IPostService.class);
roleService = SpringUtil.getBean(IRoleService.class);
tenantService = SpringUtil.getBean(ITenantService.class);
tenantPackageService = SpringUtil.getBean(ITenantPackageService.class);
}
/**
*
*
* @param id
* @return
*/
public static Menu getMenu(Long id) {
return CacheUtil.get(SYS_CACHE, MENU_ID, id, () -> menuService.getById(id));
}
/**
*
*
* @param id
* @return
*/
public static Dept getDept(Long id) {
return CacheUtil.get(SYS_CACHE, DEPT_ID, id, () -> deptService.getById(id));
}
/**
* id
*
* @param tenantId id
* @param deptNames
* @return id
*/
public static String getDeptIds(String tenantId, String deptNames) {
return CacheUtil.get(SYS_CACHE, DEPT_NAME, tenantId + StringPool.DASH + deptNames, () -> deptService.getDeptIds(tenantId, deptNames));
}
/**
* id
*
* @param tenantId id
* @param deptNames
* @return id
*/
public static String getDeptIdsByFuzzy(String tenantId, String deptNames) {
return CacheUtil.get(SYS_CACHE, DEPT_NAME_FUZZY, tenantId + StringPool.DASH + deptNames, () -> deptService.getDeptIdsByFuzzy(tenantId, deptNames));
}
/**
*
*
* @param id
* @return
*/
public static String getDeptName(Long id) {
return CacheUtil.get(SYS_CACHE, DEPT_NAME_ID, id, () -> deptService.getById(id).getDeptName());
}
/**
*
*
* @param deptIds
* @return
*/
public static List<String> getDeptNames(String deptIds) {
return CacheUtil.get(SYS_CACHE, DEPT_NAMES_ID, deptIds, () -> deptService.getDeptNames(deptIds));
}
/**
*
*
* @param deptId
* @return
*/
public static List<Dept> getDeptChild(Long deptId) {
return CacheUtil.get(SYS_CACHE, DEPT_CHILD_ID, deptId, () -> deptService.getDeptChild(deptId));
}
/**
* ID
*
* @param deptId
* @return ID
*/
public static List<Long> getDeptChildIds(Long deptId) {
if (deptId == null) {
return null;
}
List<Long> deptIdList = CacheUtil.get(SYS_CACHE, DEPT_CHILDIDS_ID, deptId, List.class);
if (deptIdList == null) {
deptIdList = new ArrayList<>();
List<Dept> deptChild = getDeptChild(deptId);
if (deptChild != null) {
List<Long> collect = deptChild.stream().map(Dept::getId).collect(Collectors.toList());
deptIdList.addAll(collect);
}
deptIdList.add(deptId);
CacheUtil.put(SYS_CACHE, DEPT_CHILDIDS_ID, deptId, deptIdList);
}
return deptIdList;
}
/**
*
*
* @param id
* @return
*/
public static Post getPost(Long id) {
return CacheUtil.get(SYS_CACHE, POST_ID, id, () -> postService.getById(id));
}
/**
* id
*
* @param tenantId id
* @param postNames
* @return
*/
public static String getPostIds(String tenantId, String postNames) {
return CacheUtil.get(SYS_CACHE, POST_NAME, tenantId + StringPool.DASH + postNames, () -> postService.getPostIds(tenantId, postNames));
}
/**
* id
*
* @param tenantId id
* @param postNames
* @return
*/
public static String getPostIdsByFuzzy(String tenantId, String postNames) {
return CacheUtil.get(SYS_CACHE, POST_NAME_FUZZY, tenantId + StringPool.DASH + postNames, () -> postService.getPostIdsByFuzzy(tenantId, postNames));
}
/**
*
*
* @param id
* @return
*/
public static String getPostName(Long id) {
return CacheUtil.get(SYS_CACHE, POST_NAME_ID, id, () -> postService.getById(id).getPostName());
}
/**
*
*
* @param postIds
* @return
*/
public static List<String> getPostNames(String postIds) {
return CacheUtil.get(SYS_CACHE, POST_NAMES_ID, postIds, () -> postService.getPostNames(postIds));
}
/**
*
*
* @param id
* @return Role
*/
public static Role getRole(Long id) {
return CacheUtil.get(SYS_CACHE, ROLE_ID, id, () -> roleService.getById(id));
}
/**
* id
*
* @param tenantId id
* @param roleNames
* @return
*/
public static String getRoleIds(String tenantId, String roleNames) {
return CacheUtil.get(SYS_CACHE, ROLE_NAME, tenantId + StringPool.DASH + roleNames, () -> roleService.getRoleIds(tenantId, roleNames));
}
/**
*
*
* @param id
* @return
*/
public static String getRoleName(Long id) {
return CacheUtil.get(SYS_CACHE, ROLE_NAME_ID, id, () -> roleService.getById(id).getRoleName());
}
/**
*
*
* @param roleIds
* @return
*/
public static List<String> getRoleNames(String roleIds) {
return CacheUtil.get(SYS_CACHE, ROLE_NAMES_ID, roleIds, () -> roleService.getRoleNames(roleIds));
}
/**
*
*
* @param id
* @return
*/
public static String getRoleAlias(Long id) {
return CacheUtil.get(SYS_CACHE, ROLE_ALIAS_ID, id, () -> roleService.getById(id).getRoleAlias());
}
/**
*
*
* @param roleIds
* @return
*/
public static List<String> getRoleAliases(String roleIds) {
return CacheUtil.get(SYS_CACHE, ROLE_ALIASES_ID, roleIds, () -> roleService.getRoleAliases(roleIds));
}
/**
*
*
* @param id
* @return Tenant
*/
public static Tenant getTenant(Long id) {
return CacheUtil.get(SYS_CACHE, TENANT_ID, id, () -> tenantService.getById(id), Boolean.FALSE);
}
/**
*
*
* @param tenantId id
* @return Tenant
*/
public static Tenant getTenant(String tenantId) {
return CacheUtil.get(SYS_CACHE, TENANT_TENANT_ID, tenantId, () -> tenantService.getByTenantId(tenantId), Boolean.FALSE);
}
/**
*
*
* @param tenantId id
* @return Tenant
*/
public static TenantPackage getTenantPackage(String tenantId) {
Tenant tenant = getTenant(tenantId);
return CacheUtil.get(SYS_CACHE, TENANT_PACKAGE_ID, tenantId, () -> tenantPackageService.getById(tenant.getPackageId()), Boolean.FALSE);
}
}

@ -0,0 +1,86 @@
/**
* 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.common.cache;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.system.pojo.entity.User;
import org.springblade.modules.system.service.IUserService;
import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
import static org.springblade.core.launch.constant.FlowConstant.TASK_USR_PREFIX;
/**
*
*
* @author Chill
*/
public class UserCache {
private static final String USER_CACHE_ID = "user:id:";
private static final String USER_CACHE_ACCOUNT = "user:account:";
private static final IUserService userService;
static {
userService = SpringUtil.getBean(IUserService.class);
}
/**
* id
*
* @param taskUserId id
* @return
*/
public static User getUserByTaskUser(String taskUserId) {
Long userId = Func.toLong(StringUtil.removePrefix(taskUserId, TASK_USR_PREFIX));
return getUser(userId);
}
/**
*
*
* @param userId id
* @return
*/
public static User getUser(Long userId) {
return CacheUtil.get(USER_CACHE, USER_CACHE_ID, userId, () -> userService.getById(userId));
}
/**
*
*
* @param tenantId id
* @param account
* @return
*/
public static User getUser(String tenantId, String account) {
return CacheUtil.get(USER_CACHE, USER_CACHE_ACCOUNT, tenantId + StringPool.DASH + account, () -> userService.userByAccount(tenantId, account));
}
}

@ -0,0 +1,95 @@
/**
* 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.common.config;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.oauth2.endpoint.OAuth2SocialEndpoint;
import org.springblade.core.oauth2.endpoint.OAuth2TokenEndPoint;
import org.springblade.core.secure.registry.SecureRegistry;
import org.springblade.core.tool.utils.StringPool;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Blade
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
public class BladeConfiguration implements WebMvcConfigurer {
/**
*
*/
@Bean
public SecureRegistry secureRegistry() {
SecureRegistry secureRegistry = new SecureRegistry();
secureRegistry.setEnabled(true);
secureRegistry.excludePathPatterns("/blade-auth/**");
secureRegistry.excludePathPatterns("/blade-system/tenant/info");
secureRegistry.excludePathPatterns("/blade-flow/process/resource-view");
secureRegistry.excludePathPatterns("/blade-flow/process/diagram-view");
secureRegistry.excludePathPatterns("/blade-flow/manager/check-upload");
secureRegistry.excludePathPatterns("/doc.html");
secureRegistry.excludePathPatterns("/swagger-ui.html");
secureRegistry.excludePathPatterns("/static/**");
secureRegistry.excludePathPatterns("/blade-auth/**");
secureRegistry.excludePathPatterns("/open/**");
secureRegistry.excludePathPatterns("/swagger-resources/**");
secureRegistry.excludePathPatterns("/druid/**");
return secureRegistry;
}
/**
*
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedHeaders("*")
.allowedMethods("*")
.maxAge(3600)
.allowCredentials(true);
}
/**
* OAuth2
*/
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix(StringPool.SLASH + AppConstant.APPLICATION_AUTH_NAME,
c -> c.isAnnotationPresent(RestController.class) && (
OAuth2TokenEndPoint.class.equals(c) || OAuth2SocialEndpoint.class.equals(c))
);
}
}

@ -0,0 +1,52 @@
/**
* 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.common.config;
import lombok.AllArgsConstructor;
import org.springblade.common.handler.BladeScopeModelHandler;
import org.springblade.core.datascope.handler.ScopeModelHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Blade
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@AllArgsConstructor
public class BladeHandlerConfiguration {
private final JdbcTemplate jdbcTemplate;
@Bean
public ScopeModelHandler scopeModelHandler() {
return new BladeScopeModelHandler(jdbcTemplate);
}
}

@ -0,0 +1,67 @@
/**
* 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.common.config;
import lombok.AllArgsConstructor;
import org.springblade.common.event.ApiLogListener;
import org.springblade.common.event.ErrorLogListener;
import org.springblade.common.event.UsualLogListener;
import org.springblade.core.launch.props.BladeProperties;
import org.springblade.core.launch.server.ServerInfo;
import org.springblade.modules.system.service.ILogService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@AllArgsConstructor
public class BladeLogConfiguration {
private final ILogService logService;
private final ServerInfo serverInfo;
private final BladeProperties bladeProperties;
@Bean(name = "apiLogListener")
public ApiLogListener apiLogListener() {
return new ApiLogListener(logService, serverInfo, bladeProperties);
}
@Bean(name = "errorEventListener")
public ErrorLogListener errorEventListener() {
return new ErrorLogListener(logService, serverInfo, bladeProperties);
}
@Bean(name = "usualEventListener")
public UsualLogListener usualEventListener() {
return new UsualLogListener(logService, serverInfo, bladeProperties);
}
}

@ -0,0 +1,26 @@
package org.springblade.common.config;
import org.springblade.common.filter.PreviewFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "blade.preview.enabled", havingValue = "true")
public class BladePreviewConfiguration {
/**
*
*/
@Bean
public PreviewFilter previewFilter() {
return new PreviewFilter();
}
}

@ -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 org.springblade.common.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "report.enabled", havingValue = "true", matchIfMissing = true)
public class BladeReportConfiguration {
/**
*
*/
// @Bean
// public ReportDataSource reportDataSource(DataSource dataSource) {
// return new ReportDataSource(dataSource);
// }
}

@ -0,0 +1,104 @@
/**
* 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.common.config;
import lombok.AllArgsConstructor;
import org.springblade.core.launch.constant.AppConstant;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Swagger
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@AllArgsConstructor
@ConditionalOnProperty(value = "swagger.enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerConfiguration {
@Bean
public GroupedOpenApi authApi() {
return GroupedOpenApi.builder()
.group("授权模块")
.packagesToScan(AppConstant.BASE_PACKAGES + ".core.oauth2", AppConstant.BASE_PACKAGES + ".modules.auth")
.build();
}
@Bean
public GroupedOpenApi sysApi() {
return GroupedOpenApi.builder()
.group("系统模块")
.packagesToScan(AppConstant.BASE_PACKAGES + ".modules.system", AppConstant.BASE_PACKAGES + ".modules.resource")
.build();
}
@Bean
public GroupedOpenApi operationApi() {
return GroupedOpenApi.builder()
.group("运维模块")
.packagesToScan(AppConstant.BASE_PACKAGES + ".modules.operation", AppConstant.BASE_PACKAGES + ".modules.partner")
.build();
}
@Bean
public GroupedOpenApi orderApi() {
return GroupedOpenApi.builder()
.group("工单管理")
.packagesToScan(AppConstant.BASE_PACKAGES + ".modules.order")
.build();
}
@Bean
public GroupedOpenApi fittingApplyApi() {
return GroupedOpenApi.builder()
.group("物料申请模块")
.packagesToScan(AppConstant.BASE_PACKAGES + ".modules.fitting", AppConstant.BASE_PACKAGES + ".modules.material")
.build();
}
@Bean
public GroupedOpenApi nhApi() {
return GroupedOpenApi.builder()
.group("监控模块")
.packagesToScan(AppConstant.BASE_PACKAGES + ".modules.nh")
.build();
}
@Bean
public GroupedOpenApi flowApi() {
// 创建并返回GroupedOpenApi对象
return GroupedOpenApi.builder()
.group("工作流模块")
.packagesToScan(AppConstant.BASE_PACKAGES + ".modules.flowable", AppConstant.BASE_PACKAGES + ".modules.apply")
.build();
}
}

@ -0,0 +1,93 @@
/**
* 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.common.constant;
import org.springblade.core.launch.constant.AppConstant;
/**
*
*
* @author Chill
*/
public interface CommonConstant {
/**
* app name
*/
String APPLICATION_NAME = AppConstant.APPLICATION_NAME_PREFIX + "api";
/**
* sword
*/
String SWORD_NAME = "sword";
/**
* saber
*/
String SABER_NAME = "saber";
/**
* id
*/
Long TOP_PARENT_ID = 0L;
/**
*
*/
String TOP_PARENT_NAME = "顶级";
/**
*
*/
Integer NOT_SEALED_ID = 0;
/**
*
*/
String DEFAULT_PASSWORD = "123456";
/**
*
*/
String DEFAULT_PARAM_PASSWORD = "account.initPassword";
/**
*
*/
String SORT_FIELD = "sort";
/**
*
*/
Integer DATA_SCOPE_CATEGORY = 1;
/**
*
*/
Integer API_SCOPE_CATEGORY = 2;
}

@ -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 org.springblade.common.constant;
/**
* .
*
* @author zhuangqian
*/
public interface DictConstant {
String SEX_CODE = "sex";
String NOTICE_CODE = "notice";
String MENU_CATEGORY_CODE = "menu_category";
String BUTTON_FUNC_CODE = "button_func";
String YES_NO_CODE = "yes_no";
String FLOW_CATEGORY_CODE = "flow_category";
}

@ -0,0 +1,102 @@
/**
* 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.common.constant;
import org.springblade.core.launch.constant.AppConstant;
/**
*
*
* @author Chill
*/
public interface LauncherConstant {
/**
* sentinel dev
*/
String SENTINEL_DEV_ADDR = "127.0.0.1:8858";
/**
* sentinel prod
*/
String SENTINEL_PROD_ADDR = "10.211.55.5:8858";
/**
* sentinel test
*/
String SENTINEL_TEST_ADDR = "172.30.0.58:8858";
/**
* elk dev
*/
String ELK_DEV_ADDR = "127.0.0.1:9000";
/**
* elk prod
*/
String ELK_PROD_ADDR = "172.30.0.58:9000";
/**
* elk test
*/
String ELK_TEST_ADDR = "172.30.0.58:9000";
/**
* sentinel
*
* @param profile
* @return addr
*/
static String sentinelAddr(String profile) {
switch (profile) {
case (AppConstant.PROD_CODE):
return SENTINEL_PROD_ADDR;
case (AppConstant.TEST_CODE):
return SENTINEL_TEST_ADDR;
default:
return SENTINEL_DEV_ADDR;
}
}
/**
* elk
*
* @param profile
* @return addr
*/
static String elkAddr(String profile) {
switch (profile) {
case (AppConstant.PROD_CODE):
return ELK_PROD_ADDR;
case (AppConstant.TEST_CODE):
return ELK_TEST_ADDR;
default:
return ELK_DEV_ADDR;
}
}
}

@ -0,0 +1,39 @@
package org.springblade.common.constant;
public class MonitorConstants {
/**
* 0 1 2 3
*/
public static String NORMAL = "0";
public static String CLOSE = "1";
public static String SHIELD = "2";
public static String DELETE = "3";
public static String ALARM_ST_NOT_CONFIRMED = "1";
public static String ALARM_ST_UNHANDLED = "2";
public static String ALARM_ST_HANDLING = "3";
public static String ALARM_ST_SOLVED = "4";
/**
*
*/
public static String ALARM_CLOSE_NO = "1";
/**
*
*/
public static String ALARM_CLOSE_YES = "2";
/**
* :1234 level';
*/
public static String ALARM_TYPE_FAULT = "1";
public static String ALARM_TYPE_WARN = "2";
public static String ALARM_TYPE_TIPS = "3";
public static String ALARM_TYPE_ADVICE = "4";
}

@ -0,0 +1,38 @@
package org.springblade.common.constant;
/**
*
* sadasd
* @author ruoyi
*/
public class NhConstants
{
public static final String HQ_ID = "101";
public static final String SYS_TYPE_GINLONG = "0";
public static final String SYS_TYPE_AISWEI = "1";
public static final String SYS_TYPE_GOODWE = "2";
public static final String SYS_TYPE_SAJ = "5";
public static final int STATION_STATUS_NORMAL = 1;
public static final int STATION_STATUS_WARN = 2;
public static final int STATION_STATUS_ONLINE = 3;
//低效电站状态
public static final int INEFFICIENT_STATION_STATION_TODO = 0;
//已转运维
public static final int INEFFICIENT_STATION_STATION_DONE = 0;
/**
*
*/
public static final String UAP_TYPE_DC = "1";
/**
*
*/
public static final String UAP_TYPE_AC = "2";
public static final String UAP_LIST_TEMP_KEY = "UAP_LIST_TEMP_KEY";
}

@ -0,0 +1,75 @@
/**
* 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.common.constant;
import java.util.Arrays;
import java.util.List;
/**
*
*
* @author Chill
*/
public interface TenantConstant {
/**
* KEY
*/
String PASSWORD_KEY = "tenant.default.password";
/**
* KEY
*/
String ACCOUNT_NUMBER_KEY = "tenant.default.accountNumber";
/**
* KEY
*/
String ACCOUNT_MENU_CODE_KEY = "tenant.default.menuCode";
/**
*
*/
String DEFAULT_PASSWORD = "123456";
/**
* 16
*/
String DES_KEY = "0000000000000000";
/**
*
*/
Integer DEFAULT_ACCOUNT_NUMBER = -1;
/**
*
*/
List<String> MENU_CODES = Arrays.asList(
"desk", "flow", "work", "monitor", "resource", "role", "user", "dept", "dictbiz", "topmenu"
);
}

@ -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 org.springblade.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author Chill
*/
@Getter
@AllArgsConstructor
public enum DictBizEnum {
/**
*
*/
TEST("test"),
;
final String name;
}

@ -0,0 +1,133 @@
/**
* 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.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author Chill
*/
@Getter
@AllArgsConstructor
public enum DictEnum {
/**
*
*/
WL_TYPE("wl_type"),
BRAND("device_brand"),
/**
*
*/
ORDER_STATUS("order_status"),
ORDER_TYPE("order_type"),
/**
*
*/
SETTING_PLAN_TYPE("setting_plan_type"),
/**
*
*/
SETTING_RECORD_TYPE("setting_record_type"),
/**
*
*/
SETTING_CUSTOMER_TYPE("setting_customer_type"),
/**
*
*/
POWER_STATION_STATUS("power_station_status"),
/**
*
*/
SEX("sex"),
/**
*
*/
NOTICE("notice"),
/**
*
*/
MENU_CATEGORY("menu_category"),
/**
*
*/
BUTTON_FUNC("button_func"),
/**
*
*/
YES_NO("yes_no"),
/**
*
*/
FLOW("flow"),
/**
*
*/
ORG_CATEGORY("org_category"),
/**
*
*/
DATA_SCOPE_TYPE("data_scope_type"),
/**
*
*/
API_SCOPE_TYPE("api_scope_type"),
/**
*
*/
SCOPE_CATEGORY("scope_category"),
/**
*
*/
OSS("oss"),
/**
*
*/
SMS("sms"),
/**
*
*/
POST_CATEGORY("post_category"),
/**
*
*/
REGION("region"),
/**
*
*/
USER_TYPE("user_type"),
DEVICE_BRAND("device_brand"),
;
final String name;
}

@ -0,0 +1,29 @@
package org.springblade.common.enums;
import org.springblade.common.constant.NhConstants;
public class SysType {
private final String sysType;
public SysType(String sysType) {
this.sysType = sysType;
}
public String getName() {
switch (sysType) {
case NhConstants.SYS_TYPE_GINLONG:
return "锦浪";
case NhConstants.SYS_TYPE_GOODWE:
return "固德威";
case NhConstants.SYS_TYPE_AISWEI:
return "爱士惟";
}
return "X";
}
@Override
public String toString() {
return getName();
}
}

@ -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 org.springblade.common.event;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.launch.props.BladeProperties;
import org.springblade.core.launch.server.ServerInfo;
import org.springblade.core.log.constant.EventConstant;
import org.springblade.core.log.event.ApiLogEvent;
import org.springblade.core.log.model.LogApi;
import org.springblade.core.log.utils.LogAbstractUtil;
import org.springblade.modules.system.service.ILogService;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import java.util.Map;
/**
*
*
* @author Chill
*/
@Slf4j
@AllArgsConstructor
public class ApiLogListener {
private final ILogService logService;
private final ServerInfo serverInfo;
private final BladeProperties bladeProperties;
@Async
@Order
@EventListener(ApiLogEvent.class)
public void saveApiLog(ApiLogEvent event) {
Map<String, Object> source = (Map<String, Object>) event.getSource();
LogApi logApi = (LogApi) source.get(EventConstant.EVENT_LOG);
LogAbstractUtil.addOtherInfoToLog(logApi, bladeProperties, serverInfo);
logService.saveApiLog(logApi);
}
}

@ -0,0 +1,71 @@
/**
* 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.common.event;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.launch.props.BladeProperties;
import org.springblade.core.launch.server.ServerInfo;
import org.springblade.core.log.constant.EventConstant;
import org.springblade.core.log.event.ErrorLogEvent;
import org.springblade.core.log.model.LogError;
import org.springblade.core.log.utils.LogAbstractUtil;
import org.springblade.modules.system.service.ILogService;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import java.util.Map;
/**
*
*
* @author Chill
*/
@Slf4j
@AllArgsConstructor
public class ErrorLogListener {
private final ILogService logService;
private final ServerInfo serverInfo;
private final BladeProperties bladeProperties;
@Async
@Order
@EventListener(ErrorLogEvent.class)
public void saveErrorLog(ErrorLogEvent event) {
try {
Map<String, Object> source = (Map<String, Object>) event.getSource();
LogError logError = (LogError) source.get(EventConstant.EVENT_LOG);
LogAbstractUtil.addOtherInfoToLog(logError, bladeProperties, serverInfo);
logService.saveErrorLog(logError);
} catch (Exception e) {
// 可以根据需要进行更多的异常处理,例如发送警报等
log.error("保存错误日志时发生异常", e);
}
}
}

@ -0,0 +1,67 @@
/**
* 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.common.event;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.launch.props.BladeProperties;
import org.springblade.core.launch.server.ServerInfo;
import org.springblade.core.log.constant.EventConstant;
import org.springblade.core.log.event.UsualLogEvent;
import org.springblade.core.log.model.LogUsual;
import org.springblade.core.log.utils.LogAbstractUtil;
import org.springblade.modules.system.service.ILogService;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import java.util.Map;
/**
*
*
* @author Chill
*/
@Slf4j
@AllArgsConstructor
public class UsualLogListener {
private final ILogService logService;
private final ServerInfo serverInfo;
private final BladeProperties bladeProperties;
@Async
@Order
@EventListener(UsualLogEvent.class)
public void saveUsualLog(UsualLogEvent event) {
Map<String, Object> source = (Map<String, Object>) event.getSource();
LogUsual logUsual = (LogUsual) source.get(EventConstant.EVENT_LOG);
LogAbstractUtil.addOtherInfoToLog(logUsual, bladeProperties, serverInfo);
logService.saveUsualLog(logUsual);
}
}

@ -0,0 +1,34 @@
package org.springblade.common.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
static Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);
private static final boolean debug = false;
@Override
public ClientHttpResponse intercept(HttpRequest req, byte[] reqBody, ClientHttpRequestExecution ex) throws IOException {
if (debug) {
LOGGER.debug("Request body: {}", new String(reqBody, StandardCharsets.UTF_8));
}
ClientHttpResponse response = ex.execute(req, reqBody);
InputStreamReader isr = new InputStreamReader(response.getBody(), StandardCharsets.UTF_8);
String body = new BufferedReader(isr).lines().collect(Collectors.joining("\n"));
if (debug) {
LOGGER.debug("Response body: {}", body);
}
return response;
}
}

@ -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 org.springblade.common.filter;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
*
* @author Chill
*/
public class PreviewFilter implements Filter {
private static final List<String> KEYS = new ArrayList<>();
static {
KEYS.add("notice");
KEYS.add("process");
KEYS.add("work");
KEYS.add("token");
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String path = httpServletRequest.getServletPath();
String method = httpServletRequest.getMethod();
String get = "GET";
if (method.equals(get) || KEYS.stream().anyMatch(path::contains)) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
throw new RuntimeException("演示环境暂时无法操作!");
}
}
@Override
public void destroy() {
}
}

@ -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 org.springblade.common.handler;
import lombok.RequiredArgsConstructor;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.datascope.constant.DataScopeConstant;
import org.springblade.core.datascope.handler.ScopeModelHandler;
import org.springblade.core.datascope.model.DataScopeModel;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
/**
* BladeScopeModelHandler
*
* @author Chill
*/
//若开启动态数据源功能,则加上@Master注解指定权限数据库为主库
//@Master
@RequiredArgsConstructor
public class BladeScopeModelHandler implements ScopeModelHandler {
private static final String SCOPE_CACHE_CODE = "dataScope:code:";
private static final String SCOPE_CACHE_CLASS = "dataScope:class:";
private static final String DEPT_CACHE_ANCESTORS = "dept:ancestors:";
private static final DataScopeModel SEARCHED_DATA_SCOPE_MODEL = new DataScopeModel(Boolean.TRUE);
private final JdbcTemplate jdbcTemplate;
/**
*
*
* @param mapperId mapperId
* @param roleId
* @return DataScopeModel
*/
@Override
public DataScopeModel getDataScopeByMapper(String mapperId, String roleId) {
List<Object> args = new ArrayList<>(Collections.singletonList(mapperId));
List<Long> roleIds = Func.toLongList(roleId);
args.addAll(roleIds);
// 增加searched字段防止未配置的参数重复读库导致缓存击穿
// 后续若有新增配置则会清空缓存重新加载
DataScopeModel dataScope = CacheUtil.get(SYS_CACHE, SCOPE_CACHE_CLASS, mapperId + StringPool.COLON + roleId, DataScopeModel.class, Boolean.FALSE);
if (dataScope == null || !dataScope.getSearched()) {
List<DataScopeModel> list = jdbcTemplate.query(DataScopeConstant.dataByMapper(roleIds.size()), args.toArray(), new BeanPropertyRowMapper<>(DataScopeModel.class));
if (CollectionUtil.isNotEmpty(list)) {
dataScope = list.iterator().next();
dataScope.setSearched(Boolean.TRUE);
} else {
dataScope = SEARCHED_DATA_SCOPE_MODEL;
}
CacheUtil.put(SYS_CACHE, SCOPE_CACHE_CLASS, mapperId + StringPool.COLON + roleId, dataScope, Boolean.FALSE);
}
return StringUtil.isNotBlank(dataScope.getResourceCode()) ? dataScope : null;
}
/**
*
*
* @param code
* @return DataScopeModel
*/
@Override
public DataScopeModel getDataScopeByCode(String code) {
DataScopeModel dataScope = CacheUtil.get(SYS_CACHE, SCOPE_CACHE_CODE, code, DataScopeModel.class, Boolean.FALSE);
// 增加searched字段防止未配置的参数重复读库导致缓存击穿
// 后续若有新增配置则会清空缓存重新加载
if (dataScope == null || !dataScope.getSearched()) {
List<DataScopeModel> list = jdbcTemplate.query(DataScopeConstant.DATA_BY_CODE, new Object[]{code}, new BeanPropertyRowMapper<>(DataScopeModel.class));
if (CollectionUtil.isNotEmpty(list)) {
dataScope = list.iterator().next();
dataScope.setSearched(Boolean.TRUE);
} else {
dataScope = SEARCHED_DATA_SCOPE_MODEL;
}
CacheUtil.put(SYS_CACHE, SCOPE_CACHE_CODE, code, dataScope, Boolean.FALSE);
}
return StringUtil.isNotBlank(dataScope.getResourceCode()) ? dataScope : null;
}
/**
*
*
* @param deptId id
* @return deptIds
*/
@Override
public List<Long> getDeptAncestors(Long deptId) {
List ancestors = CacheUtil.get(SYS_CACHE, DEPT_CACHE_ANCESTORS, deptId, List.class);
if (CollectionUtil.isEmpty(ancestors)) {
ancestors = jdbcTemplate.queryForList(DataScopeConstant.DATA_BY_DEPT, new Object[]{deptId}, Long.class);
CacheUtil.put(SYS_CACHE, DEPT_CACHE_ANCESTORS, deptId, ancestors);
}
return ancestors;
}
}

@ -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 org.springblade.common.launch;
import org.springblade.common.constant.LauncherConstant;
import org.springblade.core.auto.service.AutoService;
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 smallchil
*/
@AutoService(LauncherService.class)
public class LauncherServiceImpl implements LauncherService {
@Override
public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) {
Properties props = System.getProperties();
PropsUtil.setProperty(props, "spring.cloud.sentinel.transport.dashboard", LauncherConstant.sentinelAddr(profile));
PropsUtil.setProperty(props, "spring.datasource.dynamic.enabled", "false");
// 开启elk日志
//PropsUtil.setProperty(props, "blade.log.elk.destination", LauncherConstant.elkAddr(profile));
}
}

@ -0,0 +1,9 @@
package org.springblade.common.utils;
import java.util.List;
public interface AsyncTaskRunner {
void run(List<Runnable> runnables);
}

@ -0,0 +1,374 @@
package org.springblade.common.utils;
import cn.hutool.core.math.MathUtil;
import com.google.common.collect.Maps;
import org.apache.commons.compress.utils.Lists;
import org.springblade.core.http.util.HttpUtil;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.nh.pojo.entity.MonitorInverterDailyStatEntity;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
/**
*
*
* @author Chill
*/
public class CommonUtil {
public static Double sum(Double num1, Double num2) {
Double sum = 0D;
if(num1!=null){
sum = sum+num1;
}
if(num2!=null){
sum = sum+num2;
}
return sum;
}
public static int getDaysInCurrentMonth() {
// 获取当前日期
LocalDate currentDate = LocalDate.now();
// 获取当前月的最后一天
LocalDate lastDayOfMonth = currentDate.with(TemporalAdjusters.lastDayOfMonth());
// 返回当前月的天数
return lastDayOfMonth.getDayOfMonth();
}
public static List<String> splitOutStationIds(String outStationIds) {
if(StringUtil.isBlank(outStationIds)) return null;
String[] arr = outStationIds.split(",");
return Arrays.asList(arr);
}
public static List<Object> retainNum(List<Object> list, int num) {
List<Object> result = Lists.newArrayList();
if(CollectionUtil.isEmpty(list)){
return list;
}
for(Object item : list){
if(item instanceof Double){
String formattedValue = String.format("%."+num+"f", item);
result.add(formattedValue);
}else{
result.add(item);
}
};
return result;
}
public static Double retainDoubleNum(Double e, int num) {
String formattedValue = String.format("%."+num+"f", e);
return Double.parseDouble(formattedValue);
}
public static boolean monthBeginLessThanDays(int days, Date baseDate) {
int date = baseDate.getDate();
return date <= days;
}
public static boolean yearBeginLessThanDays(int days, Date baseDate) {
Calendar c = Calendar.getInstance();
c.setTime(baseDate);
return c.get(Calendar.DAY_OF_YEAR) <= days;
}
public static List<String> hourListFrom0() {
List<String> ret = new ArrayList<>();
for (int i = 0; i < 24; i++) {
ret.add(String.format("%d:00", i));
}
return ret;
}
public static List<String> hourListFrom1() {
List<String> ret = new ArrayList<>();
for (int i = 0; i < 24; i++) {
ret.add(String.format("%02d", i + 1));
}
return ret;
}
public static Double getDoubleByFile(Class<?> clazz, MonitorInverterDailyStatEntity entity, String key) {
Double ret=null;
try{
Field field = clazz.getDeclaredField(key);
field.setAccessible(true);
Object value = field.get(entity);
return (Double) value;
}catch (Exception e){
e.printStackTrace();
}
return ret;
}
public static List<Double> repeatNum(int ticks, Double val) {
List<Double> ret = new ArrayList<>();
for (int i = 0; i < ticks; i++) {
ret.add(val);
}
return ret;
}
public static String queryWeather(String area){
String host = "https://weather01.market.alicloudapi.com";
String path = "/area-to-weather";
String method = "GET";
String appcode = "84f9472ee67349189cd5f61c1805a430";
Map<String, String> headers = Maps.newHashMap();
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
headers.put("Authorization", "APPCODE " + appcode);
Map<String, Object> querys = Maps.newHashMap();
querys.put("area", area);
querys.put("need3HourForcast", "0");
querys.put("needAlarm", "0");
querys.put("needHourData", "0");
querys.put("needIndex", "0");
querys.put("needMoreDay", "0");
return HttpUtil.get(host+path,headers,querys);
}
public static String queryWeatherByMonth(String area,String month){
String host = "https://weather01.market.alicloudapi.com";
String path = "/weatherhistory";
String method = "GET";
String appcode = "84f9472ee67349189cd5f61c1805a430";
Map<String, String> headers = Maps.newHashMap();
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
headers.put("Authorization", "APPCODE " + appcode);
Map<String, Object> querys = Maps.newHashMap();
querys.put("area", area);
querys.put("month", month);
return HttpUtil.get(host+path,headers,querys);
}
public static void reflectSetField(Object r, String fieldName, Object value) {
try{
Field field= r.getClass().getDeclaredField(fieldName);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, r,value);
}catch (Exception e){
e.printStackTrace();
}
}
public static Object reflectGetField(Object r, String fieldName) {
try{
Field field= r.getClass().getDeclaredField(fieldName);
ReflectionUtils.makeAccessible(field);
return ReflectionUtils.getField(field, r);
}catch (Exception e){
}
return null;
}
public static BigDecimal getPreHourMax(Map<String, Object> resMap, int hour) {
BigDecimal max = BigDecimal.ZERO;
for(int i=(hour-1); i>0; i--){
BigDecimal bigDecimal = new BigDecimal(resMap.get("h" + i).toString());
if(bigDecimal!=null && bigDecimal.compareTo(max) > 0){
max = bigDecimal;
}
}
return max;
}
public static String assembleIUData(String ukey,String iKey,int max,Object detail){
List<String> list = Lists.newArrayList();
for(int i=1;i<=max;i++){
Object iPvObj = CommonUtil.reflectGetField(detail,iKey+i);
Object uPvObj = CommonUtil.reflectGetField(detail,ukey+i);
if(iPvObj==null||uPvObj==null){
break;
}
if(iPvObj.equals(0d) && uPvObj.equals(0d)){
break;
}
list.add(uPvObj+":"+iPvObj);
}
return String.join("|", list);
}
public static void copyFieldToOther(Object sourceObj,String sourceField,Object toObj,String toField){
Object sourceVal = CommonUtil.reflectGetField(sourceObj,sourceField);
CommonUtil.reflectSetField(toObj,toField,sourceVal);
}
/**
* @param start
* @return
*/
public static String calDuringToNow(Date start){
String today = DateUtil.format(new Date(),"yyyyMMdd");
Date startDate = DateUtil.parse(today+"080000","yyyyMMddHHmmss");
if(start==null){
start = startDate;
}
if(start.after(startDate)){
startDate = start;
}
Long now = System.currentTimeMillis();
Long startTime = startDate.getTime();
long during = (now - startTime)/1000;
return convertDuring(during);
}
public static String convertDuring(Long during){
if(during==null){
return "";
}
long day = during/(24*3600);
during = during%(24*3600);
long hour = during/3600;
during = during%(3600);
long min = during/60;
StringBuilder sb = new StringBuilder();
if(day>0){
sb.append(day+"天");
}
if(hour>0){
sb.append(hour+"时");
}
if(min>0){
sb.append(min+"分");
}
return sb.toString();
}
public static int getVendorIndex(Map<String, Object> ctx){
if(ctx.containsKey("index")){
int index = (int) ctx.get("index");
return index;
}else{
return 1;
}
}
public static Map<String,Object> getCtx(int i){
Map<String, Object> ctx = Maps.newHashMap();
ctx.put("index",i);
return ctx;
}
public static List<String> assembleIdsList(List<String> list,int size) {
List<String> result = Lists.newArrayList();
int page = list.size()/size;
if(list.size()%size>0){
page++;
}
for(int i=0;i<page;i++){
int last = (i+1)*size;
if(last>=list.size()){
last = list.size();
}
List<String> sublist = list.subList(i*size,last);
result.add(StringUtil.join(sublist,","));
}
return result;
}
public static Double round(Double number,int precision) {
BigDecimal bigDecimal = new BigDecimal(number);
// 四舍五入到两位有效数字
bigDecimal = bigDecimal.round(new java.math.MathContext(precision, RoundingMode.HALF_UP));
// 转换回double类型
return bigDecimal.doubleValue();
}
public static Double setScale(Double number,int precision) {
BigDecimal bigDecimal = new BigDecimal(number);
// 四舍五入到两位有效数字
bigDecimal = bigDecimal.setScale(precision,RoundingMode.HALF_UP);
// 转换回double类型
return bigDecimal.doubleValue();
}
public static boolean isOutTime(Long time,int min){
if(time==null) return true;
long during = System.currentTimeMillis() - time;
//超过15分钟
if(during>min*60*1000){
return true;
}
return false;
}
public static Date getNowHour(){
// 获取当前日期和时间
LocalDateTime now = LocalDateTime.now();
int c = now.getMinute()/15;
// 获取当前小时的整点时间
LocalTime currentHour = LocalTime.of(now.getHour(), c*15);
LocalDateTime currentHourDateTime = LocalDateTime.of(now.toLocalDate(), currentHour);
// 将LocalDateTime转换为ZonedDateTime
ZonedDateTime zonedDateTime = currentHourDateTime.atZone(ZoneId.systemDefault());
Instant instant = zonedDateTime.toInstant();
// 将Instant转换为Date
Date date = Date.from(instant);
return date;
}
public static String genSign(Map<String, ?> paramMap){
TreeMap<String, Object> treeMap = Maps.newTreeMap();
paramMap.forEach((key, value) -> {
treeMap.put(key, value);
});
return genSign(treeMap);
}
/**
* Generate Sign
* @return String
*/
public static String genSign(TreeMap<String, Object> paramMap) {
StringBuilder data = new StringBuilder();
paramMap.forEach((key, value) -> {
if (StringUtil.isNotBlank(data.toString())) {
data.append(",");
}
data.append(key).append("=").append(value);
});
try {
return DigestUtil.sha256Hex(data.toString());
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) {
// {
// "aqiLevel": "1",
// "wind_direction": "无持续风向",
// "aqi": "40",
// "wind_power": "微风",
// "area": "丽江",
// "time": "20160101",
// "min_temperature": "1",
// "max_temperature": "15",
// "aqiInfo": "优",
// "weather": "多云"
// },
// System.out.println(queryWeatherByMonth("合肥","202405"));
// System.out.println(DateUtil.formatDateTime(getNowHour()));
TreeMap<String, Object> paramMap = Maps.newTreeMap();
paramMap.put("appId", "123456789");
System.out.println(genSign(paramMap));
}
}

@ -0,0 +1,47 @@
package org.springblade.common.utils;
import cn.hutool.core.collection.CollectionUtil;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class ListUtils {
public static boolean isEqualList(final Collection list1, final Collection list2) {
if (list1 == list2) {
return true;
}
if (list1 == null || list2 == null || list1.size() != list2.size()) {
return false;
}
Iterator it1 = list1.iterator();
Iterator it2 = list2.iterator();
Object obj1, obj2;
while (it1.hasNext() && it2.hasNext()) {
obj1 = it1.next();
obj2 = it2.next();
if (!(obj1 == null ? obj2 == null : obj1.equals(obj2))) {
return false;
}
}
return !(it1.hasNext() || it2.hasNext());
}
public static <T> List<List<T>> maxParts(List<T> all, int maxParts) {
int partSize = all.size() / maxParts;
if (partSize == 0) {
partSize = 1;
}
return CollectionUtil.split(all ,partSize);
}
public static <T> List<List<T>> split(List<T> all, int size) {
return org.apache.commons.collections4.ListUtils.partition(all, size);
}
}

@ -0,0 +1,35 @@
package org.springblade.common.utils;
import java.util.Date;
import java.util.Objects;
public class MonitorTask {
private final String taskId;
private final Date requestTime;
public MonitorTask(String taskId) {
this.taskId = taskId;
this.requestTime = new Date();
}
public String getTaskId() {
return taskId;
}
public Date getRequestTime() {
return requestTime;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MonitorTask that = (MonitorTask) o;
return Objects.equals(taskId, that.taskId);
}
@Override
public int hashCode() {
return Objects.hash(taskId);
}
}

@ -0,0 +1,60 @@
package org.springblade.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
public class MultiAsyncTaskRunner implements AsyncTaskRunner {
private final Runnable taskCleaner;
private volatile boolean run;
private static final Logger log = LoggerFactory.getLogger(MultiAsyncTaskRunner.class);
public MultiAsyncTaskRunner(String taskId, Runnable taskCleaner) {
this.taskCleaner = taskCleaner;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!run) {
log.error("task might hang, task.id: {}", taskId, new Exception());
taskCleaner.run();
}
}
}, 30 * 1000);
}
@Override
public void run(List<Runnable> runnableList) {
run = true;
if (CollectionUtils.isEmpty(runnableList)) {
taskCleaner.run();
return;
}
CountDownLatch latch = new CountDownLatch(runnableList.size());
for (Runnable runnable : runnableList) {
new Thread(new Runnable() {
@Override
public void run() {
try {
runnable.run();
} finally {
latch.countDown();
}
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
// ignore
} finally {
taskCleaner.run();
}
}
}

@ -0,0 +1,9 @@
package org.springblade.common.utils;
import java.util.List;
public class NopTaskRunner implements AsyncTaskRunner {
@Override
public void run(List<Runnable> runnables) {
}
}

@ -0,0 +1,97 @@
package org.springblade.common.utils;
import cn.hutool.core.util.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.tool.utils.DateUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TaskControl {
private static final Map<String, MonitorTask> tasks = new HashMap<>();
private static final Map<String, MonitorTask> asyncTasks = new HashMap<>();
private static final Logger log = LoggerFactory.getLogger(TaskControl.class);
private static final Object singleTaskLock = new Object();
private static final Object asyncSingleTaskLock = new Object();
// 创建一个固定大小的线程池
public static final ExecutorService executor = Executors.newFixedThreadPool(10);
public static void runTask(String taskId, Runnable runnable) {
executor.submit(runnable);
}
public static void newSingleInstanceTask(String taskId, Runnable runnable) {
synchronized (singleTaskLock) {
MonitorTask monitorTask = tasks.get(taskId);
if (monitorTask != null) {
log.info("task is still running, id:{}, req.time:{}", taskId, DateUtil.format(monitorTask.getRequestTime(), "yyyy-MM-dd HH:mm"));
} else {
tasks.put(taskId, new MonitorTask(taskId));
}
}
try {
runnable.run();
} finally {
synchronized (singleTaskLock) {
tasks.remove(taskId);
}
}
}
public static AsyncTaskRunner newSingleInstanceTask(String taskId) {
synchronized (asyncSingleTaskLock) {
MonitorTask task = asyncTasks.get(taskId);
if (task != null) {
return new NopTaskRunner();
}
asyncTasks.put(taskId, new MonitorTask(taskId));
return new MultiAsyncTaskRunner(taskId, new Runnable() {
@Override
public void run() {
synchronized (asyncSingleTaskLock) {
asyncTasks.remove(taskId);
}
}
});
}
}
// public static void main(String[] args) {
// // 创建一个固定大小为4的线程池
// ExecutorService executor = Executors.newFixedThreadPool(10);
//
// // 提交任务到线程池
// for (int i = 0; i < 100; i++) {
// int finalI = i; // 用于在lambda表达式中捕获变量
// executor.submit(() -> {
// try {
// Thread.sleep(RandomUtil.randomInt(500,3000));
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// System.out.println("Task " + finalI + " executed by " + Thread.currentThread().getName());
// });
// }
//
// // 关闭线程池,不再接受新任务,等待现有任务完成
// executor.shutdown();
// try {
// // 等待线程池关闭最多等待1分钟
// if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
// // 超时后,尝试立即关闭所有正在执行的任务
// executor.shutdownNow();
// }
// } catch (InterruptedException e) {
// // 线程被中断时的处理
// executor.shutdownNow();
// }
// }
}

@ -0,0 +1,88 @@
package org.springblade.common.utils;
public class UnitUtil {
public static Double convEnergy(Double val, String unit) {
if (unit == null || val == null) {
return null;
}
String s = unit.toLowerCase();
switch (s) {
case "kwh":
return val;
case "mwh":
return val * 1000;
case "gwh":
return val * 1000 * 1000;
case "twh":
return val * 1000 * 1000 * 1000;
case "pwh":
return val * 1000 * 1000 * 1000 * 1000;
}
throw new RuntimeException("invalid unit: " + unit);
}
public static Double convPower(Double val, String unit) {
if (unit == null || val == null) {
return null;
}
String s = unit.toLowerCase();
if (s.endsWith("p")) {
s = s.substring(0, s.length() - 1);
}
switch (s) {
case "w":
return val / 1000;
case "kw":
return val;
case "mw":
return val * 1000;
case "gw":
return val * 1000 * 1000;
case "tw":
return val * 1000 * 1000 * 1000;
case "pw":
return val * 1000 * 1000 * 1000 * 1000;
}
throw new RuntimeException("invalid unit: " + unit);
}
public static Double convVa(Double v, String unit) {
if (unit == null || v == null) {
return null;
}
String s = unit.toLowerCase();
if (s.endsWith("w")) {
return convPower(v, unit);
}
switch (s) {
case "va":
return v;
case "kva":
return v * 1000;
case "mva":
return v * 1000 * 1000;
case "gva":
return v * 1000 * 1000 * 1000;
}
throw new RuntimeException("invalid unit: " + unit);
}
public static Double convHz(Double fac, String facStr) {
if (facStr == null || fac == null) {
return null;
}
String s = facStr.toLowerCase();
switch (s) {
case "hz":
return fac;
case "khz":
return fac * 1000;
case "mhz":
return fac * 1000 * 1000;
case "ghz":
return fac * 1000 * 1000 * 1000;
}
throw new RuntimeException("invalid unit: " + facStr);
}
}

@ -0,0 +1,155 @@
/**
* 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.flow.business.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.flowable.engine.TaskService;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.flow.business.service.FlowBusinessService;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.engine.entity.FlowProcess;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springframework.web.bind.annotation.*;
/**
*
*
* @author Chill
*/
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/work")
@Tag(name = "流程事务通用接口", description = "流程事务通用接口")
public class WorkController {
private final TaskService taskService;
private final FlowEngineService flowEngineService;
private final FlowBusinessService flowBusinessService;
/**
*
*/
@GetMapping("start-list")
@ApiOperationSupport(order = 1)
@Operation(summary = "发起事务列表页", description = "传入流程类型")
public R<IPage<FlowProcess>> startList(@Parameter(description = "流程类型") String category, Query query, @RequestParam(required = false, defaultValue = "1") Integer mode) {
IPage<FlowProcess> pages = flowEngineService.selectProcessPage(Condition.getPage(query), category, mode);
return R.data(pages);
}
/**
*
*/
@GetMapping("claim-list")
@ApiOperationSupport(order = 2)
@Operation(summary = "待签事务列表页", description = "传入流程信息")
public R<IPage<BladeFlow>> claimList(@Parameter(description = "流程信息") BladeFlow bladeFlow, Query query) {
IPage<BladeFlow> pages = flowBusinessService.selectClaimPage(Condition.getPage(query), bladeFlow);
return R.data(pages);
}
/**
*
*/
@GetMapping("todo-list")
@ApiOperationSupport(order = 3)
@Operation(summary = "待办事务列表页", description = "传入流程信息")
public R<IPage<BladeFlow>> todoList(@Parameter(description = "流程信息") BladeFlow bladeFlow, Query query) {
IPage<BladeFlow> pages = flowBusinessService.selectTodoPage(Condition.getPage(query), bladeFlow);
return R.data(pages);
}
/**
*
*/
@GetMapping("send-list")
@ApiOperationSupport(order = 4)
@Operation(summary = "已发事务列表页", description = "传入流程信息")
public R<IPage<BladeFlow>> sendList(@Parameter(description = "流程信息") BladeFlow bladeFlow, Query query) {
IPage<BladeFlow> pages = flowBusinessService.selectSendPage(Condition.getPage(query), bladeFlow);
return R.data(pages);
}
/**
*
*/
@GetMapping("done-list")
@ApiOperationSupport(order = 5)
@Operation(summary = "办结事务列表页", description = "传入流程信息")
public R<IPage<BladeFlow>> doneList(@Parameter(description = "流程信息") BladeFlow bladeFlow, Query query) {
IPage<BladeFlow> pages = flowBusinessService.selectDonePage(Condition.getPage(query), bladeFlow);
return R.data(pages);
}
/**
*
*
* @param taskId id
*/
@PostMapping("claim-task")
@ApiOperationSupport(order = 6)
@Operation(summary = "签收事务", description = "传入流程信息")
public R claimTask(@Parameter(description = "任务id") String taskId) {
taskService.claim(taskId, TaskUtil.getTaskUser());
return R.success("签收事务成功");
}
/**
*
*
* @param flow
*/
@PostMapping("complete-task")
@ApiOperationSupport(order = 7)
@Operation(summary = "完成任务", description = "传入流程信息")
public R completeTask(@Parameter(description = "任务信息") @RequestBody BladeFlow flow) {
return R.status(flowBusinessService.completeTask(flow));
}
/**
*
*
* @param taskId id
* @param reason
*/
@PostMapping("delete-task")
@ApiOperationSupport(order = 8)
@Operation(summary = "删除任务", description = "传入流程信息")
public R deleteTask(@Parameter(description = "任务id") String taskId, @Parameter(description = "删除原因") String reason) {
taskService.deleteTask(taskId, reason);
return R.success("删除任务成功");
}
}

@ -0,0 +1,89 @@
/**
* 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.flow.business.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.flow.core.entity.BladeFlow;
import java.util.List;
/**
*
*
* @author Chill
*/
public interface FlowBusinessService {
/**
*
*
* @param page
* @param bladeFlow
* @return
*/
IPage<BladeFlow> selectClaimPage(IPage<BladeFlow> page, BladeFlow bladeFlow);
/**
*
*
* @param page
* @param bladeFlow
* @return
*/
IPage<BladeFlow> selectTodoPage(IPage<BladeFlow> page, BladeFlow bladeFlow);
/**
*
*
* @param page
* @param bladeFlow
* @return
*/
IPage<BladeFlow> selectSendPage(IPage<BladeFlow> page, BladeFlow bladeFlow);
/**
*
*
* @param page
* @param bladeFlow
* @return
*/
IPage<BladeFlow> selectDonePage(IPage<BladeFlow> page, BladeFlow bladeFlow);
/**
*
*
* @param leave
* @return boolean
*/
boolean completeTask(BladeFlow leave);
/**
*
*/
// List<BladeFlow> findHidTask(String processInstanceId);
}

@ -0,0 +1,86 @@
/**
* 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.flow.business.service;
import org.springblade.flow.core.entity.BladeFlow;
import java.util.Map;
/**
* .
*
* @author Chill
*/
public interface IFlowService {
/**
*
*
* @param processDefinitionId id
* @param businessKey key
* @param variables
* @return BladeFlow
*/
BladeFlow startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables);
/**
*
*
* @param processDefinitionKey
* @param businessKey key
* @param variables
* @return BladeFlow
*/
BladeFlow startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables);
/**
*
*
* @param taskId id
* @param processInstanceId id
* @param comment
* @param variables
* @return R
*/
boolean completeTask(String taskId, String processInstanceId, String comment, Map<String, Object> variables);
/**
*
*
* @param taskId id
* @param variableName
* @return R
*/
Object taskVariable(String taskId, String variableName);
/**
*
*
* @param taskId id
* @return R
*/
Map<String, Object> taskVariables(String taskId);
}

@ -0,0 +1,343 @@
/**
* 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.flow.business.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.flow.business.service.FlowBusinessService;
import org.springblade.flow.core.constant.ProcessConstant;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.engine.constant.FlowEngineConstant;
import org.springblade.flow.engine.entity.FlowProcess;
import org.springblade.flow.engine.utils.FlowCache;
import org.springframework.stereotype.Service;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
*
*
* @author Chill
*/
@Service
@AllArgsConstructor
public class FlowBusinessServiceImpl implements FlowBusinessService {
private final TaskService taskService;
private final HistoryService historyService;
@Override
public IPage<BladeFlow> selectClaimPage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
String taskUser = TaskUtil.getTaskUser();
String taskGroup = TaskUtil.getCandidateGroup();
List<BladeFlow> flowList = new LinkedList<>();
// 个人等待签收的任务
TaskQuery claimUserQuery = taskService.createTaskQuery().taskCandidateUser(taskUser)
.includeProcessVariables().active().orderByTaskCreateTime().desc();
// 定制流程等待签收的任务
TaskQuery claimRoleWithTenantIdQuery = taskService.createTaskQuery().taskTenantId(AuthUtil.getTenantId()).taskCandidateGroupIn(Func.toStrList(taskGroup))
.includeProcessVariables().active().orderByTaskCreateTime().desc();
// 通用流程等待签收的任务
TaskQuery claimRoleWithoutTenantIdQuery = taskService.createTaskQuery().taskWithoutTenantId().taskCandidateGroupIn(Func.toStrList(taskGroup))
.includeProcessVariables().active().orderByTaskCreateTime().desc();
// 构建列表数据
buildFlowTaskList(bladeFlow, flowList, claimUserQuery, FlowEngineConstant.STATUS_CLAIM);
buildFlowTaskList(bladeFlow, flowList, claimRoleWithTenantIdQuery, FlowEngineConstant.STATUS_CLAIM);
buildFlowTaskList(bladeFlow, flowList, claimRoleWithoutTenantIdQuery, FlowEngineConstant.STATUS_CLAIM);
// 计算总数
long count = claimUserQuery.count() + claimRoleWithTenantIdQuery.count() + claimRoleWithoutTenantIdQuery.count();
// 设置页数
page.setSize(count);
// 设置总数
page.setTotal(count);
// 设置数据
page.setRecords(flowList);
return page;
}
@Override
public IPage<BladeFlow> selectTodoPage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
String taskUser = TaskUtil.getTaskUser();
List<BladeFlow> flowList = new LinkedList<>();
// 已签收的任务
TaskQuery todoQuery = taskService.createTaskQuery().taskAssignee(taskUser).active()
.includeProcessVariables().orderByTaskCreateTime().desc();
// 构建列表数据
buildFlowTaskList(bladeFlow, flowList, todoQuery, FlowEngineConstant.STATUS_TODO);
// 计算总数
long count = todoQuery.count();
// 设置页数
page.setSize(count);
// 设置总数
page.setTotal(count);
// 设置数据
page.setRecords(flowList);
return page;
}
@Override
public IPage<BladeFlow> selectSendPage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
String taskUser = TaskUtil.getTaskUser();
List<BladeFlow> flowList = new LinkedList<>();
HistoricProcessInstanceQuery historyQuery = historyService.createHistoricProcessInstanceQuery().startedBy(taskUser).orderByProcessInstanceStartTime().desc();
if (bladeFlow.getCategory() != null) {
historyQuery.processDefinitionCategory(bladeFlow.getCategory());
}
if (bladeFlow.getProcessDefinitionName() != null) {
historyQuery.processDefinitionName(bladeFlow.getProcessDefinitionName());
}
if (bladeFlow.getBeginDate() != null) {
historyQuery.startedAfter(bladeFlow.getBeginDate());
}
if (bladeFlow.getEndDate() != null) {
historyQuery.startedBefore(bladeFlow.getEndDate());
}
// 查询列表
List<HistoricProcessInstance> historyList = historyQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize()));
historyList.forEach(historicProcessInstance -> {
BladeFlow flow = new BladeFlow();
// historicProcessInstance
flow.setCreateTime(historicProcessInstance.getStartTime());
flow.setEndTime(historicProcessInstance.getEndTime());
flow.setVariables(historicProcessInstance.getProcessVariables());
String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey());
if (businessKey.length > 1) {
flow.setBusinessTable(businessKey[0]);
flow.setBusinessId(businessKey[1]);
}
flow.setHistoryActivityName(historicProcessInstance.getName());
flow.setProcessInstanceId(historicProcessInstance.getId());
flow.setHistoryProcessInstanceId(historicProcessInstance.getId());
// ProcessDefinition
FlowProcess processDefinition = FlowCache.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
flow.setProcessDefinitionId(processDefinition.getId());
flow.setProcessDefinitionName(processDefinition.getName());
flow.setProcessDefinitionVersion(processDefinition.getVersion());
flow.setProcessDefinitionKey(processDefinition.getKey());
flow.setCategory(processDefinition.getCategory());
flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
flow.setProcessInstanceId(historicProcessInstance.getId());
// HistoricTaskInstance
List<HistoricTaskInstance> historyTasks = historyService.createHistoricTaskInstanceQuery().processInstanceId(historicProcessInstance.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
if (Func.isNotEmpty(historyTasks)) {
HistoricTaskInstance historyTask = historyTasks.iterator().next();
flow.setTaskId(historyTask.getId());
flow.setTaskName(historyTask.getName());
flow.setTaskDefinitionKey(historyTask.getTaskDefinitionKey());
}
// Status
if (historicProcessInstance.getEndActivityId() != null) {
flow.setProcessIsFinished(FlowEngineConstant.STATUS_FINISHED);
} else {
flow.setProcessIsFinished(FlowEngineConstant.STATUS_UNFINISHED);
}
flow.setStatus(FlowEngineConstant.STATUS_FINISH);
flowList.add(flow);
});
// 计算总数
long count = historyQuery.count();
// 设置总数
page.setTotal(count);
page.setRecords(flowList);
return page;
}
@Override
public IPage<BladeFlow> selectDonePage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
String taskUser = TaskUtil.getTaskUser();
List<BladeFlow> flowList = new LinkedList<>();
HistoricTaskInstanceQuery doneQuery = historyService.createHistoricTaskInstanceQuery().taskAssignee(taskUser).finished()
.includeProcessVariables().orderByHistoricTaskInstanceEndTime().desc();
if (bladeFlow.getCategory() != null) {
doneQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory()));
}
if (bladeFlow.getProcessDefinitionName() != null) {
doneQuery.processDefinitionName(bladeFlow.getProcessDefinitionName());
}
if (bladeFlow.getBeginDate() != null) {
doneQuery.taskCompletedAfter(bladeFlow.getBeginDate());
}
if (bladeFlow.getEndDate() != null) {
doneQuery.taskCompletedBefore(bladeFlow.getEndDate());
}
// 查询列表
List<HistoricTaskInstance> doneList = doneQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize()));
doneList.forEach(historicTaskInstance -> {
BladeFlow flow = new BladeFlow();
flow.setTaskId(historicTaskInstance.getId());
flow.setTaskDefinitionKey(historicTaskInstance.getTaskDefinitionKey());
flow.setTaskName(historicTaskInstance.getName());
flow.setAssignee(historicTaskInstance.getAssignee());
flow.setCreateTime(historicTaskInstance.getCreateTime());
flow.setExecutionId(historicTaskInstance.getExecutionId());
flow.setHistoryTaskEndTime(historicTaskInstance.getEndTime());
flow.setVariables(historicTaskInstance.getProcessVariables());
FlowProcess processDefinition = FlowCache.getProcessDefinition(historicTaskInstance.getProcessDefinitionId());
flow.setProcessDefinitionId(processDefinition.getId());
flow.setProcessDefinitionName(processDefinition.getName());
flow.setProcessDefinitionKey(processDefinition.getKey());
flow.setProcessDefinitionVersion(processDefinition.getVersion());
flow.setCategory(processDefinition.getCategory());
flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
flow.setProcessInstanceId(historicTaskInstance.getProcessInstanceId());
flow.setHistoryProcessInstanceId(historicTaskInstance.getProcessInstanceId());
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance((historicTaskInstance.getProcessInstanceId()));
if (Func.isNotEmpty(historicProcessInstance)) {
String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey());
flow.setBusinessTable(businessKey[0]);
flow.setBusinessId(businessKey[1]);
if (historicProcessInstance.getEndActivityId() != null) {
flow.setProcessIsFinished(FlowEngineConstant.STATUS_FINISHED);
} else {
flow.setProcessIsFinished(FlowEngineConstant.STATUS_UNFINISHED);
}
}
flow.setStatus(FlowEngineConstant.STATUS_FINISH);
flowList.add(flow);
});
// 计算总数
long count = doneQuery.count();
// 设置总数
page.setTotal(count);
page.setRecords(flowList);
return page;
}
@Override
public boolean completeTask(BladeFlow flow) {
String taskId = flow.getTaskId();
String processInstanceId = flow.getProcessInstanceId();
String comment = Func.toStr(flow.getComment(), ProcessConstant.PASS_COMMENT);
// 增加评论
if (StringUtil.isNoneBlank(processInstanceId, comment)) {
taskService.addComment(taskId, processInstanceId, comment);
}
// 创建变量
Map<String, Object> variables = flow.getVariables();
if (variables == null) {
variables = Kv.create();
}
variables.put(ProcessConstant.PASS_KEY, flow.isPass());
// 完成任务
taskService.complete(taskId, variables);
return true;
}
/**
*
*
* @param bladeFlow
* @param flowList
* @param taskQuery
* @param status
*/
private void buildFlowTaskList(BladeFlow bladeFlow, List<BladeFlow> flowList, TaskQuery taskQuery, String status) {
if (bladeFlow.getCategory() != null) {
taskQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory()));
}
if (bladeFlow.getProcessDefinitionName() != null) {
taskQuery.processDefinitionName(bladeFlow.getProcessDefinitionName());
}
if (bladeFlow.getBeginDate() != null) {
taskQuery.taskCreatedAfter(bladeFlow.getBeginDate());
}
if (bladeFlow.getEndDate() != null) {
taskQuery.taskCreatedBefore(bladeFlow.getEndDate());
}
taskQuery.list().forEach(task -> {
BladeFlow flow = new BladeFlow();
flow.setTaskId(task.getId());
flow.setTaskDefinitionKey(task.getTaskDefinitionKey());
flow.setTaskName(task.getName());
flow.setAssignee(task.getAssignee());
flow.setCreateTime(task.getCreateTime());
flow.setClaimTime(task.getClaimTime());
flow.setExecutionId(task.getExecutionId());
flow.setVariables(task.getProcessVariables());
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(task.getProcessInstanceId());
if (Func.isNotEmpty(historicProcessInstance)) {
String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey());
flow.setBusinessTable(businessKey[0]);
flow.setBusinessId(businessKey[1]);
}
FlowProcess processDefinition = FlowCache.getProcessDefinition(task.getProcessDefinitionId());
flow.setCategory(processDefinition.getCategory());
flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
flow.setProcessDefinitionId(processDefinition.getId());
flow.setProcessDefinitionName(processDefinition.getName());
flow.setProcessDefinitionKey(processDefinition.getKey());
flow.setProcessDefinitionVersion(processDefinition.getVersion());
flow.setProcessInstanceId(task.getProcessInstanceId());
flow.setStatus(status);
flowList.add(flow);
});
}
/**
*
*
* @param processInstanceId id
* @return HistoricProcessInstance
*/
private HistoricProcessInstance getHistoricProcessInstance(String processInstanceId) {
return historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
}
}

@ -0,0 +1,106 @@
/**
* 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.flow.business.service.impl;
import lombok.AllArgsConstructor;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.flow.business.service.IFlowService;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.TaskUtil;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
*
*
* @author Chill
*/
@RestController
@AllArgsConstructor
public class FlowServiceImpl implements IFlowService {
private final RuntimeService runtimeService;
private final IdentityService identityService;
private final TaskService taskService;
@Override
public BladeFlow startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables) {
// 设置流程启动用户
identityService.setAuthenticatedUserId(TaskUtil.getTaskUser());
// 开启流程
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, businessKey, variables);
// 组装流程通用类
BladeFlow flow = new BladeFlow();
flow.setProcessInstanceId(processInstance.getId());
return flow;
}
@Override
public BladeFlow startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables) {
// 设置流程启动用户
identityService.setAuthenticatedUserId(TaskUtil.getTaskUser());
// 开启流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
// 组装流程通用类
BladeFlow flow = new BladeFlow();
flow.setProcessInstanceId(processInstance.getId());
return flow;
}
@Override
public boolean completeTask(String taskId, String processInstanceId, String comment, Map<String, Object> variables) {
// 增加评论
if (StringUtil.isNoneBlank(processInstanceId, comment)) {
taskService.addComment(taskId, processInstanceId, comment);
}
// 非空判断
if (Func.isEmpty(variables)) {
variables = Kv.create();
}
// 完成任务
taskService.complete(taskId, variables);
return true;
}
@Override
public Object taskVariable(String taskId, String variableName) {
return R.data(taskService.getVariable(taskId, variableName));
}
@Override
public Map<String, Object> taskVariables(String taskId) {
return taskService.getVariables(taskId);
}
}

@ -0,0 +1,70 @@
/**
* 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.flow.core.constant;
/**
* .
*
* @author Chill
*/
public interface ProcessConstant {
/**
*
*/
String LEAVE_KEY = "Leave";
/**
*
*/
String EXPENSE_KEY = "Expense";
/**
*
*/
String PASS_KEY = "pass";
/**
*
*/
String PASS_ALIAS = "ok";
/**
*
*/
String PASS_COMMENT = "同意";
/**
*
*/
String NOT_PASS_COMMENT = "驳回";
/**
*
*/
String TASK_VARIABLE_CREATE_USER = "createUser";
}

@ -0,0 +1,190 @@
/**
* 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.flow.core.entity;
import lombok.Data;
import org.springblade.flow.core.constant.ProcessConstant;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
/**
*
*
* @author Chill
*/
@Data
public class BladeFlow implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
private String taskId;
/**
*
*/
private String taskName;
/**
* Key
*/
private String taskDefinitionKey;
/**
*
*/
private String assignee;
/**
*
*/
private String assigneeName;
/**
*
*/
private String category;
/**
*
*/
private String categoryName;
/**
*
*/
private Date createTime;
/**
*
*/
private Date endTime;
/**
*
*/
private Date claimTime;
/**
*
*/
private Date historyTaskEndTime;
/**
* ID
*/
private String executionId;
/**
* ID
*/
private String processInstanceId;
/**
* ID
*/
private String processDefinitionId;
/**
*
*/
private String processDefinitionKey;
/**
*
*/
private String processDefinitionName;
/**
*
*/
private int processDefinitionVersion;
/**
*
*/
private String processDefinitionDesc;
/**
*
*/
private String processDefinitionDiagramResName;
/**
*
*/
private String processDefinitionResName;
/**
* ID
*/
private String historyProcessInstanceId;
/**
*
*/
private String processIsFinished;
/**
* ID
*/
private String historyActivityId;
/**
*
*/
private String historyActivityName;
/**
*
*/
private String historyActivityDurationTime;
/**
* Table
*/
private String businessTable;
/**
* ID
*/
private String businessId;
/**
*
*/
private String status;
/**
*
*/
private String comment;
/**
*
*/
private boolean isPass;
/**
*
*/
private String flag;
/**
*
*/
private Date beginDate;
/**
*
*/
private Date endDate;
/**
*
*/
private Map<String, Object> variables;
/**
*
*/
public boolean isPass() {
return ProcessConstant.PASS_ALIAS.equals(flag) || ProcessConstant.PASS_COMMENT.equals(comment);
}
}

@ -0,0 +1,52 @@
/**
* 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.flow.core.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
/**
* FlowEntity
*
* @author Chill
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class FlowEntity extends BaseEntity {
@TableField(exist = false)
private BladeFlow flow;
public BladeFlow getFlow() {
if (flow == null) {
flow = new BladeFlow();
}
return flow;
}
}

@ -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 org.springblade.flow.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author Chill
*/
@Getter
@AllArgsConstructor
public enum FlowModeEnum {
/**
*
*/
COMMON("common", 1),
/**
*
*/
CUSTOM("custom", 2),
;
final String name;
final int mode;
}

@ -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 org.springblade.flow.core.utils;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.flow.core.constant.ProcessConstant;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author Chill
*/
public class FlowUtil {
/**
* key
*/
private final static Map<String, String> BUSINESS_TABLE = new HashMap<>();
static {
BUSINESS_TABLE.put(ProcessConstant.LEAVE_KEY, "blade_process_leave");
}
/**
* key
*
* @param key key
*/
public static String getBusinessTable(String key) {
String businessTable = BUSINESS_TABLE.get(key);
if (Func.isEmpty(businessTable)) {
return StringPool.EMPTY;
}
return businessTable;
}
/**
*
*
* @param businessTable
* @param businessId
* @return businessKey
*/
public static String getBusinessKey(String businessTable, String businessId) {
return StringUtil.format("{}:{}", businessTable, businessId);
}
}

@ -0,0 +1,80 @@
/**
* 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.flow.core.utils;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import static org.springblade.core.launch.constant.FlowConstant.TASK_USR_PREFIX;
/**
*
*
* @author Chill
*/
public class TaskUtil {
/**
*
*
* @return taskUser
*/
public static String getTaskUser() {
return StringUtil.format("{}{}", TASK_USR_PREFIX, AuthUtil.getUserId());
}
/**
*
*
* @param userId id
* @return taskUser
*/
public static String getTaskUser(String userId) {
return StringUtil.format("{}{}", TASK_USR_PREFIX, userId);
}
/**
*
*
* @param taskUser
* @return userId
*/
public static Long getUserId(String taskUser) {
return Func.toLong(StringUtil.removePrefix(taskUser, TASK_USR_PREFIX));
}
/**
*
*
* @return candidateGroup
*/
public static String getCandidateGroup() {
return AuthUtil.getUserRole();
}
}

@ -0,0 +1,74 @@
/**
* 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.flow.demo.leave.controller;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.UserCache;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.flow.demo.leave.entity.ProcessLeave;
import org.springblade.flow.demo.leave.service.ILeaveService;
import org.springframework.web.bind.annotation.*;
/**
*
*
* @author Chill
*/
@NonDS
@Hidden
@RestController
@RequestMapping(AppConstant.APPLICATION_DESK_NAME + "/process/leave")
@AllArgsConstructor
public class LeaveController {
private final ILeaveService leaveService;
/**
*
*
* @param businessId
*/
@GetMapping("detail")
public R<ProcessLeave> detail(Long businessId) {
ProcessLeave detail = leaveService.getById(businessId);
detail.getFlow().setAssigneeName(UserCache.getUser(detail.getCreateUser()).getName());
return R.data(detail);
}
/**
*
*
* @param leave
*/
@PostMapping("start-process")
public R startProcess(@RequestBody ProcessLeave leave) {
return R.status(leaveService.startProcess(leave));
}
}

@ -0,0 +1,78 @@
/**
* 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.flow.demo.leave.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.flow.core.entity.FlowEntity;
import java.io.Serial;
import java.util.Date;
/**
*
*
* @author Chill
*/
@Data
@TableName("blade_process_leave")
@EqualsAndHashCode(callSuper = true)
public class ProcessLeave extends FlowEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
private String processDefinitionId;
/**
* id
*/
private String processInstanceId;
/**
*
*/
private Date startTime;
/**
*
*/
private Date endTime;
/**
*
*/
private String reason;
/**
*
*/
private String taskUser;
/**
*
*/
private Date applyTime;
}

@ -0,0 +1,38 @@
/**
* 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.flow.demo.leave.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.flow.demo.leave.entity.ProcessLeave;
/**
* Mapper
*
* @author Chill
*/
public interface LeaveMapper extends BaseMapper<ProcessLeave> {
}

@ -0,0 +1,6 @@
<?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="org.springblade.flow.demo.leave.mapper.LeaveMapper">
</mapper>

@ -0,0 +1,46 @@
/**
* 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.flow.demo.leave.service;
import org.springblade.core.mp.base.BaseService;
import org.springblade.flow.demo.leave.entity.ProcessLeave;
/**
*
*
* @author Chill
*/
public interface ILeaveService extends BaseService<ProcessLeave> {
/**
*
*
* @param leave
* @return boolean
*/
boolean startProcess(ProcessLeave leave);
}

@ -0,0 +1,256 @@
/**
* 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.flow.demo.leave.service.impl;
import com.google.gson.Gson;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.flow.business.service.IFlowService;
import org.springblade.flow.core.constant.ProcessConstant;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.FlowUtil;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.demo.leave.entity.ProcessLeave;
import org.springblade.flow.demo.leave.mapper.LeaveMapper;
import org.springblade.flow.demo.leave.service.ILeaveService;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springblade.modules.flowable.examineInfo.service.impl.ExamineInfoServiceImpl;
import org.springblade.modules.flowable.processForm.pojo.entity.ProcessDefAuditStepEntity;
import org.springblade.modules.flowable.processForm.pojo.vo.ProcessDefReq;
import org.springblade.modules.flowable.processForm.service.impl.ProcessDefAuditStepServiceImpl;
import org.springblade.modules.flowable.processForm.utils.FormUtils;
import org.springblade.modules.operation.service.impl.PlatformEmployeeServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
*
*
* @author Chill
*/
@Slf4j
@Service
@AllArgsConstructor
public class LeaveServiceImpl extends BaseServiceImpl<LeaveMapper, ProcessLeave> implements ILeaveService {
private final IFlowService flowService;
private final TaskService taskService;
private final FlowEngineService flowEngineService;
@Autowired
private ProcessDefAuditStepServiceImpl auditStepService;
@Autowired
private PlatformEmployeeServiceImpl employeeService;
@Autowired
private ExamineInfoServiceImpl examineInfoService;
@Override
@Transactional(rollbackFor = Exception.class)
public boolean startProcess(ProcessLeave leave) {
String businessTable = FlowUtil.getBusinessTable(ProcessConstant.LEAVE_KEY);
if (Func.isEmpty(businessTable)) {
throw new ServiceException("流程启动失败,未找到相关业务表");
}
if (Func.isEmpty(leave.getId())) {
// 保存leave
leave.setApplyTime(DateUtil.now());
save(leave);
// 启动流程
Kv variables = Kv.create()
.set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName())
.set("taskUser", TaskUtil.getTaskUser(leave.getTaskUser()))
.set("days", DateUtil.between(leave.getStartTime(), leave.getEndTime()).toDays());
BladeFlow flow = flowService.startProcessInstanceById(leave.getProcessDefinitionId(), FlowUtil.getBusinessKey(businessTable, String.valueOf(leave.getId())), variables);
if (Func.isNotEmpty(flow)) {
log.debug("流程已启动,流程ID:" + flow.getProcessInstanceId());
// 返回流程id写入leave
leave.setProcessInstanceId(flow.getProcessInstanceId());
updateById(leave);
} else {
throw new ServiceException("开启流程失败");
}
} else {
updateById(leave);
}
return true;
}
@Transactional(rollbackFor = Exception.class)
public String startProcessFlowable(String applicationId, ProcessDefReq processDef, String formId, Date submitTime, String UserName, String content, String processInsName, String province, String city){
log.info(" >>>>>>>>>>>>启动流程 startProcessFlowable {applicationId}:{},formId:{};" ,applicationId,formId);
Map<String,Object> map=new HashMap<>();
map.put("applicationId",applicationId);
map.put("formId",formId);
map.put("reject","1");
String processDefId= processDef.getId();
List<ProcessDefAuditStepEntity> auditItems = auditStepService.findListByDefId(processDefId);
Random rand = new Random();
String oneAuditUseId="";
for(ProcessDefAuditStepEntity r:auditItems){
List<String> emps=new ArrayList<>();
String userId="";
if("1".equals(r.getAuditType())){ // 1平台角色 2 平台员工
//根据角色,获取角色员工(要根据员工的数据权限分配)
emps=employeeService.findEmpUserId(r.getRoleId(),province,city,"");
}else{
String str=r.getEmpUserId();
//获取符合数据权限的员工id
String ifOrder="1";
if("3".equals(r.getAuditMethod())){ //3 依次审批 那么不需要排序
ifOrder="";
}
emps=employeeService.getFitUserEmpId(str,province,city,"",ifOrder);
}
if(emps==null || emps.size()==0){
throw new RuntimeException(r.getItemName()+" 该节点没有符合审批设置的员工审批,不能启动流程!");
}
if("1".equals(r.getAuditMethod())||"2".equals(r.getAuditMethod())||"3".equals(r.getAuditMethod())){ //1 或签 2会签 3 依次审批
map.put("assigneeList"+r.getSort(),emps);
}else{ //任意人
int i=rand.nextInt(emps.size());
userId=emps.get(i);
map.put("assignee"+r.getSort(),userId);
}
if(r.getSort()==1){
if(StringUtil.isNotBlank(userId)){
oneAuditUseId=userId;
}else {
oneAuditUseId=String.join(",",emps);
}
}
}
processDef.setOneAuditUseId(oneAuditUseId);
log.info(">>>>>>>>>>>>startProcessFlowable map:{}",new Gson().toJson(map));
BladeFlow flow= flowService.startProcessInstanceByKey("Process_"+processDefId,formId,map);
if (Func.isNotEmpty(flow)) {
log.debug("流程已启动,流程ID:" + flow.getProcessInstanceId());
//log.info( " >>>> 流程提交成功.流程Id为" + flow.getProcessInstanceId());
String str=UserName+",提交表单"+(StringUtil.isNotBlank(content)?""+content:"");
//保存流程的过程信息
examineInfoService.saveExamineInfo(applicationId,str,submitTime,UserName,formId);
// 返回流程id写入leave
return flow.getProcessInstanceId();
} else {
throw new ServiceException("开启流程失败");
}
//log.info(" >>>>>>>>>> 流程启动成功 startProcessFlowable service ");
//return "";
}
/**
*
* @param content
* @param applicationId id
* @param currentUser
*/
@Transactional(rollbackFor = Exception.class)
public void approveTask(Task task, String content, String applicationId, BladeUser currentUser, String formId){
Date date=new Date();
log.info(">>>>>>>>>>>>>>>>>applicationId:{},task:{}",applicationId,task);
String UserName = currentUser.getUserName();
String type="";
if (!"编辑后提交".equals(content)) {
type=",同意 ";
}
String str = UserName + type+ (StringUtil.isNotBlank(content) ?content : "");
//保存流程的过程信息
examineInfoService.saveExamineInfo(applicationId,str,date,UserName,formId);
if (task != null) {
taskService.claim(task.getId(),currentUser.getUserId().toString()); //领取任务
log.info(UserName+" >>>>>> 审批流程通过 {task} :" +task.getId());
taskService.setOwner(task.getId(),UserName);
Map<String, Object> map =new HashMap<>();
map.put("approve", true);
map.put("reject","1");
taskService.complete(task.getId(),map);
}
}
/**
*
* @param content
* @param applicationId id
* @param currentUser
*/
@Transactional(rollbackFor = Exception.class)
public void rejectTask(Task task, String content, String applicationId, BladeUser currentUser,String formId,String createBy){
log.info(">>>>>>>>>>>>>>>>rejectTask taskId:{},applicationId:{}",task.getId(),applicationId);
String UserName = currentUser.getNickName();
Date date=new Date();
String str=UserName+",驳回"+(StringUtil.isNotBlank(content)?""+content:"");
examineInfoService.saveExamineInfo(applicationId,str,date,UserName,formId);
taskService.claim(task.getId(),currentUser.getUserId().toString()); //领取任务
log.info(" >>>>>> 审批流程驳回 {task} :" +task);
Map<String, Object> map = new HashMap<>();
map.put("approve",false);
map.put("reject","2");
map.put("assigneeUserId",createBy);
taskService.complete(task.getId(), map);
}
public void deleteApplication(String applicationId,String processInstanceId,String UserName,String status,String formId){
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>删除申请 deleteApplication applicationId:{};processInstanceId:{}",applicationId,processInstanceId);
//删除任务
if("2".equals(status) || "3".equals(status)){ //处理中的申请 才删除流程
List<Task> taskList=taskService.createTaskQuery().processInstanceId(processInstanceId).list();
if(taskList.size()>0){
log.info(">>>>>>>>>>>>> 开始删除任务 {} ",processInstanceId);
//删除任务
flowEngineService.deleteProcessInstance(processInstanceId,"删除任务!");
log.info(">>>>>>>>>>> 删除任务成功 ");
}
}
//保存流程的过程信息
examineInfoService.saveExamineInfo(applicationId,UserName +" (撤销申请)",new Date(),UserName,formId);
}
}

@ -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 org.springblade.flow.engine.config;
import lombok.AllArgsConstructor;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.flowable.spring.boot.FlowableProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Flowable
*
* @author Chill
*/
@Configuration(proxyBeanMethods = false)
@AllArgsConstructor
@EnableConfigurationProperties(FlowableProperties.class)
public class FlowableConfiguration implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
private final FlowableProperties flowableProperties;
@Override
public void configure(SpringProcessEngineConfiguration engineConfiguration) {
engineConfiguration.setActivityFontName(flowableProperties.getActivityFontName());
engineConfiguration.setLabelFontName(flowableProperties.getLabelFontName());
engineConfiguration.setAnnotationFontName(flowableProperties.getAnnotationFontName());
}
}

@ -0,0 +1,23 @@
package org.springblade.flow.engine.constant;
public class BondApplyConstant {
public static String APPLYSTATUS_ZERO="0";//0.暂存
public static String APPLYSTATUS_ONE="1";//1.审核中
public static String APPLYSTATUS_TWO="2";//2.驳回
public static String APPLYSTATUS_THREE="3";//3.正常
public static String APPLYSTATUS_FOUR="4";//4 取消
public static final String TYPE_ONE = "1"; //审批
public static final String TYPE_TWO = "2"; //驳回
public static final String TYPE_THREE = "3"; //抄送
public static final String TYPE_FOUR = "4"; //转发
}

@ -0,0 +1,61 @@
/**
* 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.flow.engine.constant;
/**
* .
*
* @author zhuangqian
*/
public interface FlowEngineConstant {
String FLOWABLE_BASE_PACKAGES = "org.flowable.ui";
String SUFFIX = ".bpmn20.xml";
String ACTIVE = "active";
String SUSPEND = "suspend";
String STATUS_TODO = "todo";
String STATUS_CLAIM = "claim";
String STATUS_SEND = "send";
String STATUS_DONE = "done";
String STATUS_FINISHED = "finished";
String STATUS_UNFINISHED = "unfinished";
String STATUS_FINISH = "finish";
String START_EVENT = "startEvent";
String END_EVENT = "endEvent";
}

@ -0,0 +1,82 @@
/**
* 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.flow.engine.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.AllArgsConstructor;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.annotation.PreAuth;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.RoleConstant;
import org.springblade.flow.engine.entity.FlowExecution;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springframework.web.bind.annotation.*;
/**
*
*
* @author Chill
*/
@NonDS
@RestController
@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/follow")
@AllArgsConstructor
@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
@Hidden
public class FlowFollowController {
private final FlowEngineService flowEngineService;
/**
*
*/
@GetMapping("list")
@ApiOperationSupport(order = 1)
@Operation(summary = "分页", description = "传入notice")
public R<IPage<FlowExecution>> list(Query query, @Parameter(description = "流程实例id") String processInstanceId, @Parameter(description = "流程key") String processDefinitionKey) {
IPage<FlowExecution> pages = flowEngineService.selectFollowPage(Condition.getPage(query), processInstanceId, processDefinitionKey);
return R.data(pages);
}
/**
*
*/
@PostMapping("delete-process-instance")
@ApiOperationSupport(order = 2)
@Operation(summary = "删除", description = "传入主键集合")
public R deleteProcessInstance(@Parameter(description = "流程实例id") @RequestParam String processInstanceId, @Parameter(description = "删除原因") @RequestParam String deleteReason) {
boolean temp = flowEngineService.deleteProcessInstance(processInstanceId, deleteReason);
return R.status(temp);
}
}

@ -0,0 +1,134 @@
/**
* 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.flow.engine.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.annotation.PreAuth;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.RoleConstant;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.flow.engine.constant.FlowEngineConstant;
import org.springblade.flow.engine.entity.FlowProcess;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Objects;
/**
*
*
* @author Chill
*/
@NonDS
@RestController
@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/manager")
@AllArgsConstructor
@Tag(name = "流程管理接口", description = "流程管理接口")
@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
@Hidden
public class FlowManagerController {
private final FlowEngineService flowEngineService;
/**
*
*/
@GetMapping("list")
@ApiOperationSupport(order = 1)
@Operation(summary = "分页", description = "传入流程类型")
public R<IPage<FlowProcess>> list(@Parameter(description = "流程类型") String category, Query query, @RequestParam(required = false, defaultValue = "1") Integer mode) {
IPage<FlowProcess> pages = flowEngineService.selectProcessPage(Condition.getPage(query), category, mode);
return R.data(pages);
}
/**
*
*
* @param state
* @param processId id
*/
@PostMapping("change-state")
@ApiOperationSupport(order = 2)
@Operation(summary = "变更流程状态", description = "传入state,processId")
public R changeState(@RequestParam String state, @RequestParam String processId) {
String msg = flowEngineService.changeState(state, processId);
return R.success(msg);
}
/**
*
*
* @param deploymentIds id
*/
@PostMapping("delete-deployment")
@ApiOperationSupport(order = 3)
@Operation(summary = "删除部署流程", description = "部署流程id集合")
public R deleteDeployment(String deploymentIds) {
return R.status(flowEngineService.deleteDeployment(deploymentIds));
}
/**
*
*
* @param file
*/
@PostMapping("check-upload")
@ApiOperationSupport(order = 4)
@Operation(summary = "上传部署流程文件", description = "传入文件")
public R checkUpload(@RequestParam MultipartFile file) {
boolean temp = Objects.requireNonNull(file.getOriginalFilename()).endsWith(FlowEngineConstant.SUFFIX);
return R.data(Kv.create().set("name", file.getOriginalFilename()).set("success", temp));
}
/**
*
*
* @param files
* @param category
*/
@PostMapping("deploy-upload")
@ApiOperationSupport(order = 5)
@Operation(summary = "上传部署流程文件", description = "传入文件")
public R deployUpload(@RequestParam List<MultipartFile> files,
@RequestParam String category,
@RequestParam(required = false, defaultValue = "") String tenantIds) {
return R.status(flowEngineService.deployUpload(files, category, Func.toStrList(tenantIds)));
}
}

@ -0,0 +1,131 @@
/**
* 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.flow.engine.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Hidden;
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 lombok.AllArgsConstructor;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.annotation.PreAuth;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.RoleConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.flow.engine.entity.FlowModel;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
*
*
* @author Chill
*/
@NonDS
@RestController
@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/model")
@AllArgsConstructor
@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
@Hidden
public class FlowModelController {
private final FlowEngineService flowEngineService;
/**
*
*/
@GetMapping("/list")
@Parameters({
@Parameter(name = "modelKey", description = "模型标识", in = ParameterIn.QUERY, schema = @Schema(type = "string")),
@Parameter(name = "name", description = "模型名称", in = ParameterIn.QUERY, schema = @Schema(type = "string"))
})
@ApiOperationSupport(order = 1)
@Operation(summary = "分页", description = "传入notice")
public R<IPage<FlowModel>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> flow, Query query) {
IPage<FlowModel> pages = flowEngineService.page(Condition.getPage(query), Condition.getQueryWrapper(flow, FlowModel.class)
.select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated")
.orderByDesc("last_updated"));
return R.data(pages);
}
/**
*
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 2)
@Operation(summary = "删除", description = "传入主键集合")
public R remove(@Parameter(description = "主键集合") @RequestParam String ids) {
boolean temp = flowEngineService.removeByIds(Func.toStrList(ids));
return R.status(temp);
}
/**
*
*/
@PostMapping("/deploy")
@ApiOperationSupport(order = 3)
@Operation(summary = "部署", description = "传入模型id和分类")
public R deploy(@Parameter(description = "模型id") @RequestParam String modelId,
@Parameter(description = "工作流分类") @RequestParam String category,
@Parameter(description = "租户ID") @RequestParam(required = false, defaultValue = "") String tenantIds) {
boolean temp = flowEngineService.deployModel(modelId, category, Func.toStrList(tenantIds));
return R.status(temp);
}
@PostMapping("submit")
@ApiOperationSupport(order = 4)
@Operation(summary = "保存/编辑")
@Parameters({
@Parameter(name = "id", description = "模型id"),
@Parameter(name = "name", description = "模型名称", required = true),
@Parameter(name = "modelKey", description = "模型key", required = true),
@Parameter(name = "description", description = "模型描述"),
@Parameter(name = "xml", description = "模型xml", required = true),
})
public R<FlowModel> submit(@RequestBody @Parameter(hidden = true) FlowModel model) {
return R.data(flowEngineService.submitModel(model));
}
@GetMapping("detail")
@Operation(summary = "详情")
@ApiOperationSupport(order = 5)
@Parameters({
@Parameter(name = "id", description = "模型id", required = true),
})
public R<FlowModel> detail(String id) {
return R.data(flowEngineService.getById(id));
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save