This commit is contained in:
2025-11-28 16:17:55 +08:00
commit 3b097b5f63
480 changed files with 117778 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
#数据源配置
spring:
data:
redis:
##redis 单机环境配置
host: 127.0.0.1
port: 6379
password: 123456
database: 8
ssl:
enabled: false
datasource:
# MySql
url: jdbc:mysql://127.0.0.1:3306/martial_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
username: root
password: 123456
#第三方登陆
social:
enabled: true
domain: http://127.0.0.1:1888
#blade配置
blade:
#分布式锁配置
lock:
##是否启用分布式锁
enabled: false
##redis服务地址
address: redis://127.0.0.1:6379
#本地文件上传
file:
remote-mode: true
upload-domain: http://localhost:8999
remote-path: /usr/share/nginx/html

View File

@@ -0,0 +1,42 @@
#数据源配置
spring:
data:
redis:
##redis 单机环境配置
##将docker脚本部署的redis服务映射为宿主机ip
##生产环境推荐使用阿里云高可用redis服务并设置密码
host: 127.0.0.1
port: 6379
password: 123456
database: 0
ssl:
enabled: false
##redis 集群环境配置
#cluster:
# nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
# commandTimeout: 5000
datasource:
url: jdbc:mysql://localhost:3306/martial_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
username: root
password: root
#第三方登陆
social:
enabled: true
domain: http://127.0.0.1:1888
#blade配置
blade:
#分布式锁配置
lock:
##是否启用分布式锁
enabled: false
##将docker脚本部署的redis服务映射为宿主机ip
##生产环境推荐使用阿里云高可用redis服务并设置密码
address: redis://127.0.0.1:6379
password: 123456
#本地文件上传
file:
remote-mode: true
upload-domain: http://localhost:8999
remote-path: /usr/share/nginx/html

View File

@@ -0,0 +1,42 @@
#数据源配置
spring:
data:
redis:
##redis 单机环境配置
##将docker脚本部署的redis服务映射为宿主机ip
##生产环境推荐使用阿里云高可用redis服务并设置密码
host: 127.0.0.1
port: 6379
password:
database: 0
ssl:
enabled: false
##redis 集群环境配置
#cluster:
# nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
# commandTimeout: 5000
datasource:
url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
username: root
password: root
#第三方登陆
social:
enabled: true
domain: http://127.0.0.1:1888
#blade配置
blade:
#分布式锁配置
lock:
##是否启用分布式锁
enabled: false
##将docker脚本部署的redis服务映射为宿主机ip
##生产环境推荐使用阿里云高可用redis服务并设置密码
address: redis://127.0.0.1:6379
password: 123456
#本地文件上传
file:
remote-mode: true
upload-domain: http://localhost:8999
remote-path: /usr/share/nginx/html

View File

@@ -0,0 +1,306 @@
#服务器配置
server:
port: 82
undertow:
threads:
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
io: 16
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
worker: 400
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
buffer-size: 1024
# 是否分配的直接内存
direct-buffers: true
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
#driver-class-name: org.postgresql.Driver
#driver-class-name: oracle.jdbc.OracleDriver
#driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
#driver-class-name: dm.jdbc.driver.DmDriver
#driver-class-name: com.yashandb.jdbc.Driver
druid:
# MySql、PostgreSQL、SqlServer、DaMeng校验
validation-query: select 1
# Oracle、YashanDB校验
#oracle: true
#validation-query: select 1 from dual
validation-query-timeout: 2000
initial-size: 5
max-active: 20
min-idle: 5
max-wait: 60000
test-on-borrow: false
test-on-return: false
test-while-idle: true
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
stat-view-servlet:
enabled: true
login-username: blade
login-password: 1qaz@WSX
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
session-stat-enable: true
session-stat-max-count: 10
# mybatis
mybatis-plus:
mapper-locations: classpath:org/springblade/**/mapper/*Mapper.xml
#实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: org.springblade.**.entity
#typeEnumsPackage: org.springblade.dashboard.entity.enums
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
#主键类型 0:"数据库ID自增", 1:"不操作", 2:"用户输入ID",3:"数字型snowflake", 4:"全局唯一ID UUID", 5:"字符串型snowflake";
id-type: assign_id
#字段策略
insert-strategy: not_null
update-strategy: not_null
where-strategy: not_null
#驼峰下划线转换
table-underline: true
# 逻辑删除配置
# 逻辑删除全局值1表示已删除这也是Mybatis Plus的默认配置
logic-delete-value: 1
# 逻辑未删除全局值0表示未删除这也是Mybatis Plus的默认配置
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
jdbc-type-for-null: 'null'
#springdoc-openapi配置
springdoc:
default-flat-param-object: true
#knife4j配置
knife4j:
#启用
enable: true
#基础认证
basic:
enable: false
username: blade
password: blade
#增强配置
setting:
enable-swagger-models: true
enable-document-manage: true
enable-host: false
enable-host-text: http://localhost
enable-request-cache: true
enable-filter-multipart-apis: false
enable-filter-multipart-api-method-type: POST
enable-footer: false
enable-footer-custom: true
language: zh_cn
footer-custom-content: Copyright © 2024 BladeX All Rights Reserved
#swagger公共信息
swagger:
title: BladeX 接口文档系统
description: BladeX 接口文档系统
version: 4.0.1.RELEASE
license: Powered By BladeX
license-url: https://license.bladex.cn
contact:
name: 翼宿
email: bladejava@qq.com
url: https://gitee.com/smallc
#oss默认配置
oss:
#开启oss配置
enabled: true
#开启oss类型
#minio、s3、qiniu、alioss、huaweiobs、tencentcos
name: minio
#租户模式
tenant-mode: true
#oss服务地址
endpoint: http://120.197.149.12:9000
#oss转换服务地址用于内网上传后将返回地址改为转换的外网地址
transform-endpoint: http://localhost:9000
#访问key
access-key: AKIAIOSFODNN7EXAMPLE
#密钥key
secret-key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
#存储桶
bucket-name: equipment
#第三方登陆配置
social:
oauth:
GITHUB:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/github
GITEE:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/gitee
WECHAT_OPEN:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/wechat
QQ:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/qq
DINGTALK:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/dingtalk
#flowable配置
flowable:
activity-font-name: \u5B8B\u4F53
label-font-name: \u5B8B\u4F53
annotation-font-name: \u5B8B\u4F53
check-process-definitions: false
database-schema-update: true
async-executor-activate: false
async-history-executor-activate: false
#报表配置
report:
enabled: false
database:
provider:
prefix: blade-
#job服务配置
powerjob:
worker:
enabled: false
app-name: blade-job
port: 27777
server-address: 127.0.0.1:7700
#blade配置
blade:
#token配置
token:
#是否有状态
state: false
#是否单用户登录
single: false
#单用户登录范围
single-level: all
#token签名 使用 @org.springblade.test.SignKeyGenerator 获取
sign-key: G5aqwBQUBJ3XMkAApoY6p6QNg0sVaH6A
#token加密 使用 @org.springblade.test.CryptoKeyGenerator 获取
crypto-key: FS6GeY1v2nVkX1S85MGuqvpEsMOZaHPO
#接口配置
api:
#报文加密配置
crypto:
#启用报文加密配置
enabled: false
#使用 @org.springblade.test.CryptoKeyGenerator 获取,需和前端保持一致
aes-key: ff8scTBKeZLua3dA8rmaKnnCqEGsxJsB
#使用 @org.springblade.test.CryptoKeyGenerator 获取,需和前端保持一致
des-key: 4NPogpO3NHrB8i0x
#jackson配置
jackson:
#null自动转空值
null-to-empty: true
#大数字自动转字符串
big-num-to-string: true
#支持text文本请求,与报文加密同时开启
support-text-plain: false
#redis序列化方式
redis:
serializer-type: protostuff
#日志配置
log:
request:
#开启控制台请求日志
enabled: true
#控制台请求日志忽略
skip-url:
- /blade-desk/notice/list
- /blade-chat/weixin/**
#开启错误日志入库
error-log: true
#xss配置
xss:
enabled: true
skip-url:
- /blade-chat/weixin
- /blade-desk/notice/submit
- /blade-flow/model/submit
- /blade-develop/datasource/submit
#安全框架配置
secure:
#严格模式
#缺失令牌字段则取消授权
strict-token: true
#缺失请求头则取消授权
strict-header: true
#接口放行
skip-url:
- /blade-test/**
- /blade-spare/**
- /blade-device/**
- /**
#授权认证配置
auth:
- method: ALL
pattern: /blade-chat/wechat/**
expression: "hasAuth()"
- method: ALL
pattern: /blade-chat/qq/**
expression: "hasStrictToken()"
- method: ALL
pattern: /blade-chat/ding/**
expression: "hasStrictHeader()"
- method: POST
pattern: /blade-desk/dashboard/upload
expression: "hasTimeAuth(9, 17)"
- method: POST
pattern: /blade-desk/dashboard/submit
expression: "hasAnyRole('administrator', 'admin', 'user')"
#基础认证配置
basic:
- method: ALL
pattern: /blade-desk/dashboard/info
username: "blade"
password: "blade"
#动态签名认证配置
sign:
- method: ALL
pattern: /blade-desk/dashboard/sign
crypto: "sha1"
#多终端认证配置
client:
- client-id: sword
path-patterns:
- /blade-sword/**
- client-id: saber
path-patterns:
- /blade-saber/**
#多租户配置
tenant:
#多租户增强
enhance: true
#多租户授权保护
license: false
#动态数据库隔离功能
dynamic-datasource: false
#动态数据库隔离全局扫描
dynamic-global: false
#多租户字段名
column: tenant_id
#排除多租户逻辑
exclude-tables:
- blade_user
#分库分表配置
sharding:
enabled: false

View File

@@ -0,0 +1,8 @@
${AnsiColor.BLUE} ______ _ _ ___ ___
${AnsiColor.BLUE} | ___ \| | | | \ \ / /
${AnsiColor.BLUE} | |_/ /| | __ _ __| | ___ \ V /
${AnsiColor.BLUE} | ___ \| | / _` | / _` | / _ \ > <
${AnsiColor.BLUE} | |_/ /| || (_| || (_| || __/ / . \
${AnsiColor.BLUE} \____/ |_| \__,_| \__,_| \___|/__/ \__\
${AnsiColor.BLUE}:: BladeX ${blade.service.version} :: ${spring.application.name}:${AnsiColor.RED}${blade.env}${AnsiColor.BLUE} :: Running SpringBoot ${spring-boot.version} :: ${AnsiColor.BRIGHT_BLACK}

View File

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" dynamicConfig="false">
<diskStore path="java.io.tmpdir"/>
<cache name="retry:limit:cache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
statistics="true">
</cache>
<!-- =================业务缓存================= -->
<!-- 缓存半小时 -->
<cache name="blade:biz"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存半小时 -->
<cache name="blade:dict"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存半小时 -->
<cache name="blade:menu"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存半小时 -->
<cache name="blade:user"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存半小时 -->
<cache name="blade:sys"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存半小时 -->
<cache name="blade:flow"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- =================系统缓存================= -->
<!-- 缓存半小时 -->
<cache name="half:hour"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存一小时 -->
<cache name="hour"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false"
diskPersistent="false"/>
<!-- 缓存一天 -->
<cache name="one:day"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="false"
diskPersistent="false"/>
<!--
name:缓存名称。
maxElementsInMemory缓存最大个数。
eternal:对象是否永久有效一但设置了timeout将不起作用。
timeToIdleSeconds设置对象在失效前的允许闲置时间单位。仅当eternal=false对象不是永久有效时使用可选属性默认值是0也就是可闲置时间无穷大。
timeToLiveSeconds设置对象在失效前允许存活时间单位。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用默认是0.,也就是对象存活时间无穷大。
overflowToDisk当内存中对象数量达到maxElementsInMemory时Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB这个参数设置DiskStore磁盘缓存的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk硬盘最大缓存个数。
diskPersistent是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds磁盘失效线程运行时间间隔默认是120秒。
memoryStoreEvictionPolicy当达到maxElementsInMemory限制时Ehcache将会根据指定的策略去清理内存。默认策略是LRU最近最少使用。你可以设置为FIFO先进先出或是LFU较少使用
clearOnFlush内存数量最大时是否清除。
-->
<defaultCache name="default:cache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
maxElementsOnDisk="100000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="ossChain">
THEN(
preOssRule,
SWITCH(ossCacheRule).TO(
ossReadRule,
THEN(
ossDataRule,
SWITCH(ossBuildRule).TO(
aliOssRule,
amazonS3Rule,
huaweiObsRule,
minioRule,
qiniuOssRule,
tencentCosRule
),
ossTemplateRule
).id("ossNewRule")
),
finallyOssRule
);
</chain>
</flow>

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="smsChain">
THEN(
preSmsRule,
SWITCH(smsBuildRule).TO(
aliSmsRule,
qiniuSmsRule,
tencentSmsRule,
yunpianSmsRule,
cacheSmsRule
),
finallySmsRule
);
</chain>
</flow>

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="tenantChain">
THEN(
tenantRule,
WHEN(
tenantRoleRule,
tenantRoleMenuRule,
tenantDeptRule,
tenantPostRule,
tenantDictBizRule,
tenantUserRule
)
);
</chain>
</flow>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<!-- 自定义参数监听 -->
<contextListener class="org.springblade.core.log.listener.LoggerStartupListener"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<if condition='property("ELK_MODE").toUpperCase().contains("TRUE")'>
<then>
<!-- 推送日志至elk -->
<appender name="STDOUT_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${DESTINATION}</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"traceId": "%X{traceId}",
"requestId": "%X{requestId}",
"accountId": "%X{accountId}",
"tenantId": "%X{tenantId}",
"logLevel": "%level",
"serviceName": "${springAppName:-SpringApp}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"line":"%L",
"message": "%message"
}
</pattern>
</pattern>
<mdc/>
<stackTrace/>
</providers>
</encoder>
</appender>
</then>
</if>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="${STDOUT_APPENDER}"/>
</root>
<logger name="net.sf.ehcache" level="INFO"/>
<logger name="druid.sql" level="INFO"/>
<!-- MyBatis log configure -->
<logger name="com.apache.ibatis" level="INFO"/>
<logger name="org.mybatis.spring" level="INFO"/>
<logger name="java.sql.Connection" level="INFO"/>
<logger name="java.sql.Statement" level="INFO"/>
<logger name="java.sql.PreparedStatement" level="INFO"/>
<!-- 减少部分debug日志 -->
<logger name="druid.sql" level="INFO"/>
<logger name="org.apache.shiro" level="INFO"/>
<logger name="org.mybatis.spring" level="INFO"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.springframework.context" level="WARN"/>
<logger name="org.springframework.beans" level="WARN"/>
<logger name="com.baomidou.mybatisplus" level="INFO"/>
<logger name="org.apache.ibatis.io" level="INFO"/>
<logger name="org.apache.velocity" level="INFO"/>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="io.undertow" level="INFO"/>
<logger name="org.xnio.nio" level="INFO"/>
<logger name="org.thymeleaf" level="INFO"/>
<logger name="springfox.documentation" level="INFO"/>
<logger name="org.hibernate.validator" level="INFO"/>
<logger name="com.netflix.loadbalancer" level="INFO"/>
<logger name="com.netflix.hystrix" level="INFO"/>
<logger name="com.netflix.zuul" level="INFO"/>
<logger name="de.codecentric" level="INFO"/>
<!-- cache INFO -->
<logger name="net.sf.ehcache" level="INFO"/>
<logger name="org.springframework.cache" level="INFO"/>
<!-- cloud -->
<logger name="org.apache.http" level="INFO"/>
<logger name="com.netflix.discovery" level="INFO"/>
<logger name="com.netflix.eureka" level="INFO"/>
<!-- 业务日志 -->
<Logger name="org.springblade" level="INFO"/>
<Logger name="org.springblade.core.tenant" level="INFO"/>
<Logger name="org.springblade.core.version" level="INFO"/>
<!-- 减少nacos日志 -->
<logger name="com.alibaba.nacos" level="ERROR"/>
</configuration>

View File

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<!-- 自定义参数监听 -->
<contextListener class="org.springblade.core.log.listener.LoggerStartupListener"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- 生成日志文件 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件输出的文件名 -->
<FileNamePattern>target/blade/log/info-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%logger{50}] %n%-5level: %msg%n</pattern>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 生成日志文件 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件输出的文件名 -->
<FileNamePattern>target/blade/log/error-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%logger{50}] %n%-5level: %msg%n</pattern>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<if condition='property("ELK_MODE").toUpperCase().contains("TRUE")'>
<then>
<!-- 推送日志至elk -->
<appender name="INFO_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${DESTINATION}</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"traceId": "%X{traceId}",
"requestId": "%X{requestId}",
"accountId": "%X{accountId}",
"tenantId": "%X{tenantId}",
"logLevel": "%level",
"serviceName": "${springAppName:-SpringApp}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"line":"%L",
"message": "%message"
}
</pattern>
</pattern>
<mdc/>
<stackTrace/>
</providers>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 推送日志至elk -->
<appender name="ERROR_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${DESTINATION}</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"traceId": "%X{traceId}",
"requestId": "%X{requestId}",
"accountId": "%X{accountId}",
"tenantId": "%X{tenantId}",
"logLevel": "%level",
"serviceName": "${springAppName:-SpringApp}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"line":"%L",
"message": "%message"
}
</pattern>
</pattern>
<mdc/>
<stackTrace/>
</providers>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
</then>
</if>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="${INFO_APPENDER}"/>
<appender-ref ref="${ERROR_APPENDER}"/>
</root>
<logger name="net.sf.ehcache" level="INFO"/>
<logger name="druid.sql" level="INFO"/>
<!-- 减少nacos日志 -->
<logger name="com.alibaba.nacos" level="ERROR"/>
</configuration>

View File

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<!-- 自定义参数监听 -->
<contextListener class="org.springblade.core.log.listener.LoggerStartupListener"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- 生成日志文件 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件输出的文件名 -->
<FileNamePattern>target/blade/log/info-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%logger{50}] %n%-5level: %msg%n</pattern>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 生成日志文件 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件输出的文件名 -->
<FileNamePattern>target/blade/log/error-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%n%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%logger{50}] %n%-5level: %msg%n</pattern>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<if condition='property("ELK_MODE").toUpperCase().contains("TRUE")'>
<then>
<!-- 推送日志至elk -->
<appender name="INFO_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${DESTINATION}</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"traceId": "%X{traceId}",
"requestId": "%X{requestId}",
"accountId": "%X{accountId}",
"tenantId": "%X{tenantId}",
"logLevel": "%level",
"serviceName": "${springAppName:-SpringApp}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"line":"%L",
"message": "%message"
}
</pattern>
</pattern>
<mdc/>
<stackTrace/>
</providers>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 推送日志至elk -->
<appender name="ERROR_LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${DESTINATION}</destination>
<!-- 日志输出编码 -->
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"traceId": "%X{traceId}",
"requestId": "%X{requestId}",
"accountId": "%X{accountId}",
"tenantId": "%X{tenantId}",
"logLevel": "%level",
"serviceName": "${springAppName:-SpringApp}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"line":"%L",
"message": "%message"
}
</pattern>
</pattern>
<mdc/>
<stackTrace/>
</providers>
</encoder>
<!-- 打印日志级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
</then>
</if>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="${INFO_APPENDER}"/>
<appender-ref ref="${ERROR_APPENDER}"/>
</root>
<logger name="net.sf.ehcache" level="INFO"/>
<logger name="druid.sql" level="INFO"/>
<!-- 减少nacos日志 -->
<logger name="com.alibaba.nacos" level="ERROR"/>
</configuration>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="Leave" name="请假流程" isExecutable="true">
<documentation>请假流程</documentation>
<startEvent id="start" name="开始" flowable:initiator="applyUser"></startEvent>
<userTask id="hrTask" name="人事审批" flowable:assignee="${taskUser}">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<exclusiveGateway id="judgeTask"></exclusiveGateway>
<userTask id="managerTak" name="经理审批" flowable:candidateGroups="manager"></userTask>
<userTask id="bossTask" name="老板审批" flowable:candidateGroups="boss"></userTask>
<endEvent id="end" name="结束"></endEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="hrTask"></sequenceFlow>
<sequenceFlow id="managerPassFlow" name="通过" sourceRef="managerTak" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pass}]]></conditionExpression>
</sequenceFlow>
<userTask id="userTask" name="调整申请" flowable:assignee="${applyUser}">
<extensionElements>
<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pass}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="judgeMore" name="大于3天" sourceRef="judgeTask" targetRef="bossTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${days > 3}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="managerNotPassFlow" name="驳回" sourceRef="managerTak" targetRef="userTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!pass}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="bossNotPassFlow" name="驳回" sourceRef="bossTask" targetRef="userTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!pass}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="hrPassFlow" name="同意" sourceRef="hrTask" targetRef="judgeTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pass}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="hrNotPassFlow" name="驳回" sourceRef="hrTask" targetRef="userTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!pass}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="judgeLess" name="小于3天" sourceRef="judgeTask" targetRef="managerTak">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${days <= 3}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="userPassFlow" name="重新申请" sourceRef="userTask" targetRef="hrTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pass}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="userNotPassFlow" name="关闭申请" sourceRef="userTask" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!pass}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_Leave">
<bpmndi:BPMNPlane bpmnElement="Leave" id="BPMNPlane_Leave">
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="30.0" width="30.0" x="300.0" y="135.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="hrTask" id="BPMNShape_hrTask">
<omgdc:Bounds height="80.0" width="100.0" x="360.0" y="165.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask">
<omgdc:Bounds height="40.0" width="40.0" x="255.0" y="300.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="managerTak" id="BPMNShape_managerTak">
<omgdc:Bounds height="80.0" width="100.0" x="555.0" y="75.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="bossTask" id="BPMNShape_bossTask">
<omgdc:Bounds height="80.0" width="100.0" x="450.0" y="420.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="28.0" width="28.0" x="705.0" y="390.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="userTask" id="BPMNShape_userTask">
<omgdc:Bounds height="80.0" width="100.0" x="510.0" y="270.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="327.9390183144677" y="157.4917313275668"></omgdi:waypoint>
<omgdi:waypoint x="360.0" y="176.05263157894737"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="hrPassFlow" id="BPMNEdge_hrPassFlow">
<omgdi:waypoint x="363.04347826086956" y="244.95000000000002"></omgdi:waypoint>
<omgdi:waypoint x="285.77299999999997" y="310.79999999999995"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="hrNotPassFlow" id="BPMNEdge_hrNotPassFlow">
<omgdi:waypoint x="459.95" y="236.21875000000006"></omgdi:waypoint>
<omgdi:waypoint x="513.9794844818516" y="270.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess">
<omgdi:waypoint x="274.3359375" y="300.66397214564284"></omgdi:waypoint>
<omgdi:waypoint x="274.3359375" y="115.0"></omgdi:waypoint>
<omgdi:waypoint x="554.9999999999982" y="115.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="userPassFlow" id="BPMNEdge_userPassFlow">
<omgdi:waypoint x="510.0" y="310.0"></omgdi:waypoint>
<omgdi:waypoint x="411.0" y="310.0"></omgdi:waypoint>
<omgdi:waypoint x="411.0" y="244.95000000000002"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="bossPassFlow" id="BPMNEdge_bossPassFlow">
<omgdi:waypoint x="549.9499999999998" y="447.2146118721461"></omgdi:waypoint>
<omgdi:waypoint x="705.4331577666419" y="407.4567570622598"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore">
<omgdi:waypoint x="287.29730895645025" y="327.65205479452055"></omgdi:waypoint>
<omgdi:waypoint x="450.0" y="428.8888888888889"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="managerPassFlow" id="BPMNEdge_managerPassFlow">
<omgdi:waypoint x="620.7588235294118" y="154.95"></omgdi:waypoint>
<omgdi:waypoint x="713.8613704477151" y="390.96328050279476"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="userNotPassFlow" id="BPMNEdge_userNotPassFlow">
<omgdi:waypoint x="609.95" y="339.5301886792453"></omgdi:waypoint>
<omgdi:waypoint x="706.9383699359797" y="396.87411962686997"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="bossNotPassFlow" id="BPMNEdge_bossNotPassFlow">
<omgdi:waypoint x="515.98" y="420.0"></omgdi:waypoint>
<omgdi:waypoint x="544.0" y="349.95000000000005"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="managerNotPassFlow" id="BPMNEdge_managerNotPassFlow">
<omgdi:waypoint x="595.438344721373" y="154.95"></omgdi:waypoint>
<omgdi:waypoint x="567.9366337262223" y="270.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB