Compare commits
14 Commits
master
...
online-for
| Author | SHA1 | Date |
|---|---|---|
|
|
792a8cc96f | 4 weeks ago |
|
|
8d491ff216 | 1 month ago |
|
|
446eeba6be | 1 month ago |
|
|
d26d2b14a5 | 1 month ago |
|
|
ed03e2a488 | 1 month ago |
|
|
3104f1b026 | 2 months ago |
|
|
6fc400ab77 | 2 months ago |
|
|
e9c3b36512 | 2 months ago |
|
|
7dcb3bb5c9 | 2 months ago |
|
|
f405113552 | 2 months ago |
|
|
15dd345744 | 2 months ago |
|
|
1d42dfc702 | 2 months ago |
|
|
c665cde835 | 2 months ago |
|
|
610a4d10ed | 2 months ago |
36 changed files with 1645 additions and 2943 deletions
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
server: |
||||
tomcat: |
||||
uri-encoding: UTF-8 |
||||
threads: |
||||
max: 100 |
||||
min-spare: 10 |
||||
servlet: |
||||
encoding: |
||||
force: true |
||||
charset: UTF-8 |
||||
enabled: true |
||||
|
||||
logging: |
||||
config: classpath:logback-spring.xml |
||||
|
||||
spring: |
||||
servlet: |
||||
multipart: |
||||
max-file-size: 50MB |
||||
max-request-size: 50MB |
||||
mvc: |
||||
converters: |
||||
preferred-json-mapper: fastjson |
||||
freemarker: |
||||
template-loader-path: classpath:/template/ |
||||
cache: false |
||||
charset: UTF-8 |
||||
check-template-location: true |
||||
content-type: text/html |
||||
expose-request-attributes: false |
||||
expose-session-attributes: false |
||||
request-context-attribute: request |
||||
suffix: .ftl |
||||
cloud: |
||||
sentinel: |
||||
transport: |
||||
# sentinel控制台地址。 |
||||
# 由于8080端口容易与其他服务端口冲突,可以在启动sentinel控制台时动态修改,如: |
||||
# java -Dserver.port=8858 -jar sentinel-dashboard-$VERSION.jar |
||||
# 改为8858后,下面的配置端口也需要改为:localhost:8858。 |
||||
dashboard: localhost:8858 |
||||
|
||||
# feign 配置 |
||||
feign: |
||||
sentinel: |
||||
enabled: false |
||||
httpclient: |
||||
enabled: true |
||||
max-connections: 200 |
||||
max-connections-per-route: 50 |
||||
client: |
||||
config: |
||||
default: |
||||
# 输出feignclient的日志,缺省值为none,可选值为none/basic/headers/full |
||||
# 注意:需要把feignclient类所在包的日志级别设置为debug时才生效。如: |
||||
# logging: |
||||
# level: |
||||
# com.demo.multi: info |
||||
# com.demo.multi.coursepaperinterface.client: debug |
||||
loggerLevel: full |
||||
connectTimeout: 5000 |
||||
readTimeout: 10000 |
||||
compression: |
||||
request: |
||||
enabled: true |
||||
response: |
||||
enabled: true |
||||
|
||||
common-core: |
||||
# 可选值为 mysql / postgresql / oracle / dm8 / kingbase |
||||
databaseType: mysql |
||||
|
||||
swagger: |
||||
# 当enabled为false的时候,则可禁用swagger。 |
||||
enabled: true |
||||
# 工程的基础包名。 |
||||
basePackage: apelet |
||||
# 工程服务的基础包名。 |
||||
serviceBasePackage: |
||||
title: 小猿微服务工程 |
||||
description: 小猿微服务工程详情 |
||||
version: 1.0 |
||||
knife4j: |
||||
# 打开knife4j增强模式。 |
||||
enable: true |
||||
|
||||
aliyun: |
||||
oss: |
||||
enabled: false |
||||
expireSeconds: 1000 |
||||
# 下面几项均需在申请阿里云OSS后,根据自己的实际情况进行配置。 |
||||
endpoint: |
||||
accessKey: |
||||
secretKey: |
||||
bucketName: |
||||
|
||||
minio: |
||||
enabled: false |
||||
endpoint: |
||||
accessKey: |
||||
secretKey: |
||||
bucketName: |
||||
|
||||
# 暴露监控端点 |
||||
management: |
||||
metrics: |
||||
tags: |
||||
application: ${spring.application.name} |
||||
endpoints: |
||||
web: |
||||
exposure: |
||||
include: '*' |
||||
jmx: |
||||
exposure: |
||||
include: '*' |
||||
endpoint: |
||||
# 与中间件相关的健康详情也会被展示 |
||||
health: |
||||
show-details: always |
||||
configprops: |
||||
# 在/actuator/configprops中,所有包含password的配置,将用 * 隐藏。 |
||||
# 如果不想隐藏任何配置项的值,可以直接使用如下被注释的空值。 |
||||
# keys-to-sanitize: |
||||
keys-to-sanitize: password |
||||
server: |
||||
base-path: "/" |
||||
|
||||
# 存储session数据的Redis,所有服务均需要,因此放到公共配置中。 |
||||
# 根据实际情况,该Redis也可以用于存储其他数据。 |
||||
common-redis: |
||||
# redisson的配置。每个服务可以自己的配置文件中覆盖此选项。 |
||||
redisson: |
||||
# 如果该值为false,系统将不会创建RedissionClient的bean。 |
||||
enabled: true |
||||
# mode的可用值为,single/cluster/sentinel/master-slave |
||||
mode: single |
||||
# single: 单机模式 |
||||
# address: redis://localhost:6379 |
||||
# cluster: 集群模式 |
||||
# 每个节点逗号分隔,同时每个节点前必须以redis://开头。 |
||||
# address: redis://localhost:6379,redis://localhost:6378,... |
||||
# sentinel: |
||||
# 每个节点逗号分隔,同时每个节点前必须以redis://开头。 |
||||
# address: redis://localhost:6379,redis://localhost:6378,... |
||||
# master-slave: |
||||
# 每个节点逗号分隔,第一个为主节点,其余为从节点。同时每个节点前必须以redis://开头。 |
||||
# address: redis://localhost:6379,redis://localhost:6378,... |
||||
address: redis://192.168.100.25:6379 |
||||
# 链接超时,单位毫秒。 |
||||
timeout: 6000 |
||||
# 单位毫秒。分布式锁的超时检测时长。 |
||||
# 如果一次锁内操作超该毫秒数,或在释放锁之前异常退出,Redis会在该时长之后主动删除该锁使用的key。 |
||||
lockWatchdogTimeout: 60000 |
||||
# redis 密码,空可以不填。 |
||||
password: |
||||
database: 0 |
||||
pool: |
||||
# 连接池数量。 |
||||
poolSize: 20 |
||||
# 连接池中最小空闲数量。 |
||||
minIdle: 5 |
||||
@ -0,0 +1,355 @@
@@ -0,0 +1,355 @@
|
||||
logging: |
||||
level: |
||||
# 这里设置的日志级别优先于logback-spring.xml文件Loggers中的日志级别。 |
||||
apelet: info |
||||
config: classpath:logback-spring.xml |
||||
|
||||
server: |
||||
port: 8075 |
||||
|
||||
application: |
||||
# Jwt令牌加密的签名值。该值的长度要超过10个字符(过短会报错)。 |
||||
tokenSigningKey: tenantadmin-signing-key-signing-key |
||||
# Jwt令牌在Http Header中的键名称。 |
||||
tokenHeaderKey: Authorization |
||||
# Jwt令牌刷新后在Http Header中的键名称。 |
||||
refreshedTokenHeaderKey: RefreshedToken |
||||
# Jwt令牌过期时间(毫秒)。 |
||||
expiration: 72000000 |
||||
# 初始化密码。 |
||||
defaultUserPassword: 123456 |
||||
# 缺省的文件上传根目录。 |
||||
uploadFileBaseDir: ./zz-resource/upload-files/tenant-admin |
||||
# 跨域的IP(http://192.168.10.10:8086)白名单列表,多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。 |
||||
credentialIpList: "*" |
||||
# 同步租户公共管理数据到消息队列的主题,再由同步消费者服务将数据同步到目标数据库中。 |
||||
tenantSyncTopic: TenantSync |
||||
# Session会话和用户和权限在Redis中的过期时间(秒)。 |
||||
sessionExpiredSeconds: 86400 |
||||
# Session的数据权限信息在Redis中的过期时间(秒)。 |
||||
dataPermExpiredSeconds: 86460 |
||||
# 是否排他登录。 |
||||
excludeLogin: false |
||||
common-eas: |
||||
urlPrefix: /tenantadmin/eas |
||||
common-ext: |
||||
urlPrefix: /tenantadmin/commonext |
||||
common-mobile: |
||||
# 注意不要以反斜杠(/)结尾。 |
||||
urlPrefix: /tenantadmin/mobile |
||||
# 在线表单业务数据上传资源路径 |
||||
uploadFileBaseDir: ./zz-resource/upload-files/mobile |
||||
common-online: |
||||
# 注意不要以反斜杠(/)结尾。 |
||||
urlPrefix: /tenantadmin/online |
||||
# 打印接口的路径,不要以反斜杠(/)结尾。 |
||||
printUrlPath: /tenantadmin/report/reportPrint/print |
||||
# 在线表单业务数据上传资源路径 |
||||
uploadFileBaseDir: ./zz-resource/upload-files/online |
||||
# 如果为false,在线表单模块中所有Controller接口将不能使用。 |
||||
operationEnabled: true |
||||
# 1: minio 2: aliyun-oss 3: qcloud-cos。 |
||||
distributeStoreType: 2 |
||||
# 调用render接口时候,是否打开一级缓存加速。 |
||||
enableRenderCache: false |
||||
# 脱敏字段的掩码字符,只能为单个字符。 |
||||
maskChar: '*' |
||||
# 下面的url列表,请保持反斜杠(/)结尾。 |
||||
viewUrlList: |
||||
- ${common-online.urlPrefix}/onlineOperation/viewByDatasourceId/ |
||||
- ${common-online.urlPrefix}/onlineOperation/viewByOneToManyRelationId/ |
||||
- ${common-online.urlPrefix}/onlineOperation/listByDatasourceId/ |
||||
- ${common-online.urlPrefix}/onlineOperation/listByOneToManyRelationId/ |
||||
- ${common-online.urlPrefix}/onlineOperation/exportByDatasourceId/ |
||||
- ${common-online.urlPrefix}/onlineOperation/exportByOneToManyRelationId/ |
||||
- ${common-online.urlPrefix}/onlineOperation/downloadDatasource/ |
||||
- ${common-online.urlPrefix}/onlineOperation/downloadOneToManyRelation/ |
||||
- ${common-online.urlPrefix}/onlineOperation/print/ |
||||
editUrlList: |
||||
- ${common-online.urlPrefix}/onlineOperation/addDatasource/ |
||||
- ${common-online.urlPrefix}/onlineOperation/addOneToManyRelation/ |
||||
- ${common-online.urlPrefix}/onlineOperation/updateDatasource/ |
||||
- ${common-online.urlPrefix}/onlineOperation/updateOneToManyRelation/ |
||||
- ${common-online.urlPrefix}/onlineOperation/deleteDatasource/ |
||||
- ${common-online.urlPrefix}/onlineOperation/deleteOneToManyRelation/ |
||||
- ${common-online.urlPrefix}/onlineOperation/deleteBatchDatasource/ |
||||
- ${common-online.urlPrefix}/onlineOperation/deleteBatchOneToManyRelation/ |
||||
- ${common-online.urlPrefix}/onlineOperation/uploadDatasource/ |
||||
- ${common-online.urlPrefix}/onlineOperation/uploadOneToManyRelation/ |
||||
|
||||
common-flow: |
||||
# 请慎重修改urlPrefix的缺省配置,注意不要以反斜杠(/)结尾。如必须修改其他路径,请同步修改数据库脚本。 |
||||
urlPrefix: /tenantadmin/flow |
||||
# 如果为false,流程模块的所有Controller中的接口将不能使用。 |
||||
operationEnabled: true |
||||
|
||||
common-report: |
||||
# 注意不要以反斜杠(/)结尾。 |
||||
urlPrefix: /tenantadmin/report |
||||
# 如果为false,报表模块的所有Controller中的接口将不能使用。 |
||||
operationEnabled: true |
||||
# 该配置项仅当打印模板中,打印图片字段时,才会需要。 |
||||
# 这里的url配置只是一个示例,并不能保证开箱即用,代码示例和说明可参考common-report模块 |
||||
# example包内的ReportExampleController中的代码和详细说明。 |
||||
imageDownloadUrl: "http://localhost:8083/tenantadmin/report/example/downloadDirectly" |
||||
# 该配置用于报表部分的数据权限过滤功能。 |
||||
# 当前数据权限需要获取指定部门Ids的所有下级子部门Ids的时候,会调用该接口。 |
||||
dataPermAllChildrenDeptIdUrl: "http://localhost:8083/tenantadmin/upms/sysDept/listAllChildDeptIdByParentIds" |
||||
# 当前服务是否为可视化后台服务。 |
||||
isVisualization: false |
||||
# 下面的url列表,请保持反斜杠(/)结尾。 |
||||
viewUrlList: |
||||
- ${common-report.urlPrefix}/reportOperation/listData/ |
||||
|
||||
datasync: |
||||
producer: |
||||
# upms服务作为生产者,需要打开该选项。 |
||||
enabled: true |
||||
# Redisson 分布式锁的名称。 |
||||
# 当存在多个发送者实例时,需要分布式锁控制只有一个实例可以执行消息流水读取并发送到MQ的操作。 |
||||
distributeLockName: tenant-datasync |
||||
# 每次读取生产者消息流水的等待时间间隔,单位分钟。 |
||||
fetchTransIntervalMins: 2 |
||||
# 每次读取生产者消息流水的记录数量。 |
||||
fetchCount: 10 |
||||
|
||||
rocketmq: |
||||
name-server: 127.0.0.1:9876 |
||||
producer: |
||||
group: apelet_saas |
||||
|
||||
datafilter: |
||||
tenant: |
||||
enabled: false |
||||
dataperm: |
||||
enabled: true |
||||
# 在拼接数据权限过滤的SQL时,我们会用到sys_dept_relation表,该表的前缀由此配置项指定。 |
||||
# 如果没有前缀,请使用 "" 。 |
||||
deptRelationTablePrefix: xy_ |
||||
# 是否在每次执行数据权限查询过滤时,都要进行菜单Id和URL之间的越权验证。 |
||||
enableMenuPermVerify: true |
||||
|
||||
sequence: |
||||
# 是否使用基于美团Leaf的分布式Id生成器。 |
||||
advanceIdGenerator: true |
||||
# 多个zk服务之间逗号分隔。 |
||||
zkAddress: localhost:2181 |
||||
# 与本机的ip一起构成zk中标识不同服务实例的key值。 |
||||
idPort: 18083 |
||||
# zk中生成WorkNode的路径。不同的业务可以使用不同的路径,以免冲突。 |
||||
zkPath: apelet |
||||
|
||||
common-log: |
||||
# 操作日志配置,对应配置文件common-log/OperationLogProperties.java |
||||
operation-log: |
||||
enabled: false |
||||
kafkaTopic: SysOperationLog-TenantAdmin |
||||
|
||||
mybatis-plus: |
||||
mapper-locations: classpath:apelet/tenantadmin/tenant/dao/mapper/*Mapper.xml,apelet/tenantadmin/upms/dao/mapper/*Mapper.xml,apelet/common/report/dao/mapper/*Mapper.xml,apelet/common/datasync/dao/mapper/*Mapper.xml,apelet/common/log/dao/mapper/*Mapper.xml,apelet/common/flow/dao/mapper/*Mapper.xml,apelet/common/online/dao/mapper/*Mapper.xml,apelet/common/generator/dao/mapper/*Mapper.xml,apelet/common/botp/dao/mapper/*Mapper.xml,apelet/tenantadmin/app/dao/mapper/*Mapper.xml,apelet/common/mobile/dao/mapper/*Mapper.xml,apelet/common/eas/dao/mapper/*Mapper.xml,classpath:mapper/*Mapper.xml |
||||
type-aliases-package: apelet.tenantadmin.*.model,apelet.common.report.model,apelet.common.datasync.model,apelet.common.log.model,apelet.common.flow.model,apelet.common.online.model,apelet.common.mobile.model,apelet.common.eas.model |
||||
global-config: |
||||
db-config: |
||||
logic-delete-value: -1 |
||||
logic-not-delete-value: 1 |
||||
|
||||
# 自动分页的配置 |
||||
pagehelper: |
||||
helperDialect: mysql |
||||
reasonable: true |
||||
supportMethodsArguments: false |
||||
params: count=countSql |
||||
|
||||
aj: |
||||
captcha: |
||||
# 缓存local/redis.. |
||||
cache-type: redis |
||||
# 验证码类型default两种都实例化。 |
||||
type: default |
||||
# 右下角水印文字(我的水印) |
||||
water-mark: 我的水印 |
||||
#点选字体样式 默认Font.BOLD |
||||
font-style: 1 |
||||
#点选字体字体大小 |
||||
font-size: 25 |
||||
# 支持项目路径,以classpath:开头,取resource目录下路径,例:classpath:images/jigsaw |
||||
jigsaw: classpath:images/jigsaw |
||||
# 支持项目路径,以classpath:开头,取resource目录下路径,例:classpath:images/pic-click |
||||
pic-click: classpath:images/pic-click |
||||
history-data-clear-enable: false |
||||
# 接口请求次数一分钟限制是否开启 true|false |
||||
req-frequency-limit-enable: false |
||||
# 验证失败5次,get接口锁定 |
||||
req-get-lock-limit: 5 |
||||
# 验证失败后,锁定时间间隔,s |
||||
req-get-lock-seconds: 360 |
||||
# get接口一分钟内请求数限制 |
||||
req-get-minute-limit: 30 |
||||
# check接口一分钟内请求数限制 |
||||
req-check-minute-limit: 30 |
||||
# verify接口一分钟内请求数限制 |
||||
req-verify-minute-limit: 60 |
||||
# 校验滑动拼图允许误差偏移量(默认5像素) |
||||
slip-offset: 5 |
||||
# aes加密坐标开启或者禁用(true|false) |
||||
aes-status: true |
||||
# 滑动干扰项(0/1/2) |
||||
interference-options: 2 |
||||
|
||||
# 开发数据库相关配置 |
||||
spring: |
||||
datasource: |
||||
type: com.alibaba.druid.pool.DruidDataSource |
||||
druid: |
||||
# 租户管理数据源。 |
||||
tenant-admin: |
||||
url: jdbc:mysql://192.168.100.18:3306/apelet_admin_xk?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai |
||||
username: root |
||||
password: X7&9p8L2@6z4K7!8 |
||||
# 租户业务平台的通用业务数据,如字典、在线表单、流程、报表的定义等数据。 |
||||
tenant-common: |
||||
url: jdbc:mysql://192.168.100.18:3306/apelet_admin_xk?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai |
||||
username: root |
||||
password: X7&9p8L2@6z4K7!8 |
||||
# 默认生成的操作日志数据源配置。 |
||||
operation-log: |
||||
url: jdbc:mysql://192.168.100.18:3306/apelet_admin_xk?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai |
||||
username: root |
||||
password: X7&9p8L2@6z4K7!8 |
||||
driverClassName: com.mysql.cj.jdbc.Driver |
||||
name: tenant-admin |
||||
initialSize: 10 |
||||
minIdle: 10 |
||||
maxActive: 50 |
||||
maxWait: 60000 |
||||
timeBetweenEvictionRunsMillis: 60000 |
||||
minEvictableIdleTimeMillis: 300000 |
||||
poolPreparedStatements: true |
||||
maxPoolPreparedStatementPerConnectionSize: 20 |
||||
maxOpenPreparedStatements: 20 |
||||
validationQuery: SELECT 'x' |
||||
testWhileIdle: true |
||||
testOnBorrow: false |
||||
testOnReturn: false |
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 |
||||
filters: stat,wall |
||||
useGlobalDataSourceStat: true |
||||
web-stat-filter: |
||||
enabled: true |
||||
url-pattern: "/*" |
||||
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*,/actuator/*,/ai/*" |
||||
stat-view-servlet: |
||||
enabled: true |
||||
urlPattern: /druid/* |
||||
resetEnable: true |
||||
eas: |
||||
config: |
||||
easurl: |
||||
userName: |
||||
password: 1 |
||||
dcName: |
||||
dbType: 2 |
||||
ltpaToken: C:\work\company\project\plat\orm\apelet_saas\common\common-eas\src\main\resources\LtpaToken.properties |
||||
#easurl: https://ehr.jztweb.com |
||||
#userName: SSQadmin |
||||
#password: SSQadmin |
||||
#dcName: EHR_001 |
||||
#dbType: 2 |
||||
#ltpaToken: C:\work\company\project\plat\orm\apelet_saas\common\common-eas\src\main\resources\LtpaToken_zs.properties |
||||
hubCloud: |
||||
#测试 |
||||
#secret: RXmdRE0lf5ngGfLJSSj4 |
||||
#appId: 501019058 |
||||
secret: |
||||
appId: |
||||
dingTalk: |
||||
secret: 95gAMy_7nWGqRwFbt_kLzRpI9BqKhB7LM3SPgpcvV8Q7s0Az_PMei_yRxWE6LmhV |
||||
project: |
||||
server: |
||||
url: https://jgzy-api.nbjgcloud.com |
||||
sync: |
||||
url: http://10.22.98.37:9999 |
||||
loginUrl: /sys/login |
||||
loginName: nbjg |
||||
loginPassword: NBjj123456 |
||||
userUrl: |
||||
projectUrl: |
||||
ai: |
||||
dify: |
||||
baseUrl: |
||||
datasetKey: |
||||
appKey: |
||||
appUrl: |
||||
pandoc: |
||||
panurl: pandoc |
||||
genurl: |
||||
templateFileName: sample-orgin-change.docx |
||||
luaFileName: parse-html.lua |
||||
preUrl: |
||||
mineru: |
||||
workspace: |
||||
batchfile: |
||||
timeout: 10000 |
||||
baseurl: http://192.168.77.6:8000 |
||||
pdfurl: /file_parse |
||||
mdSaveDir: /app/work/pdf |
||||
cqurl: |
||||
config: |
||||
url: |
||||
gys: |
||||
#client_id: xy_mobile |
||||
#client_secret: asdasdnsandlkadnlkas!@#@!3WWW |
||||
#username: sunquan |
||||
client_id: |
||||
client_secret: |
||||
username: |
||||
accountId: |
||||
|
||||
msg: |
||||
notice: |
||||
# 是否启用定时消息提醒(true启用,false禁用) |
||||
enabled: true |
||||
|
||||
# 定时任务cron表达式,控制提醒执行频率 |
||||
# 默认值:0 0 * * * ? (每小时整点执行) |
||||
# 常用示例: |
||||
# 0 0 * * * ? - 每小时执行一次 |
||||
# 0 0 */2 * * ? - 每2小时执行一次 |
||||
# 0 0 9 * * ? - 每天上午9点执行 |
||||
# 0 0 9,18 * * ? - 每天上午9点和下午6点执行 |
||||
# 0 */30 * * * ? - 每30分钟执行一次 |
||||
cron: "0 0 * * * ?" |
||||
|
||||
# 默认提醒消息内容 |
||||
default-message: hello |
||||
|
||||
# ==================================== |
||||
# 短信通知配置 |
||||
# ==================================== |
||||
sms: |
||||
# 是否启用短信通知 |
||||
enabled: false |
||||
# 短信API地址(根据实际短信服务商配置) |
||||
api-url: https://sms.example.com/send |
||||
# 短信API密钥 |
||||
api-key: your-sms-api-key |
||||
# 短信签名 |
||||
sign: "【您的签名】" |
||||
|
||||
# ==================================== |
||||
# 邮箱通知配置 |
||||
# ==================================== |
||||
email: |
||||
# 是否启用邮箱通知 |
||||
enabled: true |
||||
# SMTP服务器地址 |
||||
smtp-host: smtp.qq.com |
||||
# SMTP端口(25或465或587) |
||||
smtp-port: 465 |
||||
# 发件人邮箱地址 |
||||
from-email: 287962685@qq.com |
||||
# 发件人密码或授权码 |
||||
password: evccxezdmdnpbhbh |
||||
# 是否启用SSL(如果使用465端口,建议启用SSL) |
||||
ssl-enabled: true |
||||
|
||||
@ -1,34 +0,0 @@
@@ -1,34 +0,0 @@
|
||||
<?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"> |
||||
<parent> |
||||
<artifactId>common</artifactId> |
||||
<groupId>apelet</groupId> |
||||
<version>1.0.0</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>common-flow-online</artifactId> |
||||
<version>1.0.0</version> |
||||
<name>common-flow-online</name> |
||||
<packaging>jar</packaging> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>apelet</groupId> |
||||
<artifactId>common-flow</artifactId> |
||||
<version>1.0.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>apelet</groupId> |
||||
<artifactId>common-online</artifactId> |
||||
<version>1.0.0</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>apelet</groupId> |
||||
<artifactId>common-orm</artifactId> |
||||
<version>1.0.0</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -1,88 +0,0 @@
@@ -1,88 +0,0 @@
|
||||
package apelet.common.flow.online.aop; |
||||
|
||||
import apelet.common.core.object.TokenData; |
||||
import apelet.common.core.util.AopTargetUtil; |
||||
import apelet.common.core.util.MyDateUtil; |
||||
import apelet.common.flow.dao.FlowTransProducerMapper; |
||||
import apelet.common.flow.model.FlowTaskComment; |
||||
import apelet.common.flow.model.FlowTransProducer; |
||||
import apelet.common.flow.online.object.TransactionalFlowBusinessData; |
||||
import cn.hutool.core.bean.BeanUtil; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.annotation.Pointcut; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.ApplicationEventPublisher; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* 拦截流程业务多数据库数据写入的AOP对象。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Aspect |
||||
@Component |
||||
@Slf4j |
||||
public class FlowMultiDatabaseWriteAspect { |
||||
|
||||
@Autowired |
||||
private ApplicationEventPublisher eventPublisher; |
||||
@Autowired |
||||
private FlowTransProducerMapper flowTransProducerMapper; |
||||
|
||||
@Pointcut("execution(public * apelet.common.flow..service.impl..*(..)) " + |
||||
"&& @annotation(apelet.common.core.annotation.MultiDatabaseWriteMethod)") |
||||
public void multiDatabaseWriteMethodPointCut() { |
||||
// 空注释,避免sonar警告
|
||||
} |
||||
|
||||
@Around("multiDatabaseWriteMethodPointCut()") |
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
String initMethod = AopTargetUtil.getFullMethodName(joinPoint); |
||||
TransactionalFlowBusinessData data = TransactionalFlowBusinessData.getOrCreateFromRequestAttribute(); |
||||
if (data.getInitMethod() == null) { |
||||
data.setInitMethod(initMethod); |
||||
} |
||||
try { |
||||
// 调用原来的方法
|
||||
Object result = joinPoint.proceed(); |
||||
if (StrUtil.equals(initMethod, data.getInitMethod()) && CollUtil.isNotEmpty(data.getSqlDataList())) { |
||||
this.fillupTransactionalBusinessData(); |
||||
FlowTransProducer producerData = BeanUtil.copyProperties(data, FlowTransProducer.class); |
||||
producerData.setAppCode(TokenData.takeFromRequest().getAppCode()); |
||||
producerData.setTryTimes(1); |
||||
String sqlData = JSON.toJSONStringWithDateFormat( |
||||
data.getSqlDataList(), MyDateUtil.COMMON_SHORT_DATETIME_FORMAT); |
||||
producerData.setSqlData(sqlData); |
||||
flowTransProducerMapper.insert(producerData); |
||||
eventPublisher.publishEvent(data); |
||||
} |
||||
return result; |
||||
} catch (Exception e) { |
||||
TransactionalFlowBusinessData.removeFromRequestAttribute(); |
||||
throw e; |
||||
} finally { |
||||
if (StrUtil.equals(initMethod, data.getInitMethod())) { |
||||
TransactionalFlowBusinessData.removeFromRequestAttribute(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void fillupTransactionalBusinessData() { |
||||
FlowTaskComment comment = FlowTaskComment.getFromRequest(); |
||||
TransactionalFlowBusinessData data = TransactionalFlowBusinessData.getFromRequestAttribute(); |
||||
if (comment != null) { |
||||
data.setProcessInstanceId(comment.getProcessInstanceId()); |
||||
data.setTaskId(comment.getTaskId()); |
||||
data.setTaskKey(comment.getTaskKey()); |
||||
data.setTaskName(comment.getTaskName()); |
||||
data.setTaskComment(comment.getTaskComment()); |
||||
} |
||||
} |
||||
} |
||||
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
package apelet.common.flow.online.aop; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.annotation.Pointcut; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* 主要用于拦截FlowTransactionBusinessDataListener监听器类抛出的异常。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Aspect |
||||
@Component |
||||
@Order(1) |
||||
@Slf4j |
||||
public class FlowMultiDatabaseWriteExAspect { |
||||
|
||||
@Pointcut("execution(public * apelet.common.flow.online.service.impl..*(..)) " + |
||||
"&& @annotation(apelet.common.core.annotation.MultiDatabaseWriteMethod)") |
||||
public void multiDatabaseWriteMethodPointCut() { |
||||
// 空注释,避免sonar警告
|
||||
} |
||||
|
||||
@Around("multiDatabaseWriteMethodPointCut()") |
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
try { |
||||
return joinPoint.proceed(); |
||||
} catch (Exception e) { |
||||
log.error("FlowMultiDatabaseWriteExAspect throw", e); |
||||
throw e; |
||||
} |
||||
} |
||||
} |
||||
@ -1,13 +0,0 @@
@@ -1,13 +0,0 @@
|
||||
package apelet.common.flow.online.config; |
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
|
||||
/** |
||||
* common-flow-online模块的自动配置引导类。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@EnableConfigurationProperties({FlowOnlineProperties.class}) |
||||
public class FlowOnlineAutoConfig { |
||||
} |
||||
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
package apelet.common.flow.online.config; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
||||
/** |
||||
* 在线表单工作流模块的配置对象。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Data |
||||
@ConfigurationProperties(prefix = "common-flow-online") |
||||
public class FlowOnlineProperties { |
||||
|
||||
/** |
||||
* 在线表单的URL前缀。 |
||||
*/ |
||||
private String urlPrefix; |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -1,94 +0,0 @@
@@ -1,94 +0,0 @@
|
||||
package apelet.common.flow.online.listener; |
||||
|
||||
import apelet.common.core.util.ApplicationContextHolder; |
||||
import apelet.common.flow.model.FlowEntry; |
||||
import apelet.common.flow.model.FlowNodeTasks; |
||||
import apelet.common.flow.model.FlowWorkOrder; |
||||
import apelet.common.flow.service.FlowEntryService; |
||||
import apelet.common.flow.service.FlowNodeTasksService; |
||||
import apelet.common.flow.service.FlowWorkOrderService; |
||||
import apelet.common.online.dto.OnlinePluginExecuteDto; |
||||
import apelet.common.online.model.OnlineForm; |
||||
import apelet.common.online.service.OnlineFormService; |
||||
import apelet.common.online.service.OnlineOperationService; |
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import org.flowable.engine.RuntimeService; |
||||
import org.flowable.engine.delegate.TaskListener; |
||||
import org.flowable.engine.runtime.ProcessInstance; |
||||
import org.flowable.task.service.delegate.DelegateTask; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 审批设置插件by创建事件 |
||||
*/ |
||||
public class ApprovalSettingsByCreateListener implements TaskListener { |
||||
|
||||
private final transient FlowNodeTasksService flowNodeTasksService = |
||||
ApplicationContextHolder.getBean(FlowNodeTasksService.class); |
||||
private final transient FlowEntryService flowEntryService = |
||||
ApplicationContextHolder.getBean(FlowEntryService.class); |
||||
private final transient OnlineFormService onlineFormService = |
||||
ApplicationContextHolder.getBean(OnlineFormService.class); |
||||
private final transient FlowWorkOrderService flowWorkOrderService = |
||||
ApplicationContextHolder.getBean(FlowWorkOrderService.class); |
||||
private final transient OnlineOperationService onlineOperationService = |
||||
ApplicationContextHolder.getBean(OnlineOperationService.class); |
||||
|
||||
private final transient RuntimeService runtimeService = |
||||
ApplicationContextHolder.getBean(RuntimeService.class); |
||||
@Override |
||||
public void notify(DelegateTask delegateTask) { |
||||
|
||||
String eventName = delegateTask.getEventName(); |
||||
List<Integer> setList = new ArrayList<>(); |
||||
if (eventName.equals("create")) { |
||||
setList.add(1); |
||||
} else if (eventName.equals("assignment")) { |
||||
setList.add(2); |
||||
} else if (eventName.equals("complete")) { |
||||
String operationType = (String)delegateTask.getVariable("operationType"); |
||||
if(operationType != null){ |
||||
if(operationType.equals("agree")){ |
||||
setList.add(5); |
||||
}else if(operationType.equals("reject")) { |
||||
setList.add(6); |
||||
}else if(operationType.equals("refuse")){ |
||||
} |
||||
} |
||||
setList.add(3); |
||||
} else if (eventName.equals("delete")) { |
||||
setList.add(4); |
||||
} |
||||
String taskKey = delegateTask.getTaskDefinitionKey(); |
||||
String processDefinitionId = delegateTask.getProcessDefinitionId(); |
||||
LambdaQueryWrapper<FlowNodeTasks> wrapper = new LambdaQueryWrapper<>(); |
||||
// wrapper.eq(FlowNodeTasks::getFlowId, processDefinitionId);
|
||||
wrapper.eq(FlowNodeTasks::getTaskKey, taskKey); |
||||
wrapper.in(FlowNodeTasks::getExecutionTiming, setList); |
||||
List<FlowNodeTasks> list = flowNodeTasksService.list(wrapper); |
||||
if (list != null && list.size() > 0) { |
||||
for (FlowNodeTasks flowNodeTasks : list) { |
||||
LambdaQueryWrapper<FlowEntry> wrapperFlowEntry = new LambdaQueryWrapper<>(); |
||||
wrapperFlowEntry.eq(FlowEntry::getEntryId, flowNodeTasks.getFlowId()); |
||||
FlowEntry flowEntry = flowEntryService.getById(flowNodeTasks.getFlowId()); |
||||
OnlineForm form = onlineFormService.getOnlineFormFromCache(flowEntry.getDefaultFormId()); |
||||
Long formId = form.getFormId(); |
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() |
||||
.processInstanceId(delegateTask.getProcessInstanceId()) |
||||
.singleResult(); |
||||
String billId = processInstance.getBusinessKey(); |
||||
if (billId != null && formId > 0) { |
||||
OnlinePluginExecuteDto onlinePluginExecuteDto = new OnlinePluginExecuteDto(); |
||||
onlinePluginExecuteDto.setBillId(String.valueOf(billId)); |
||||
onlinePluginExecuteDto.setFormId(formId); |
||||
onlinePluginExecuteDto.setButtonName(flowNodeTasks.getOperation()); |
||||
onlineOperationService.executePlugin(onlinePluginExecuteDto, null, null); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -1,101 +0,0 @@
@@ -1,101 +0,0 @@
|
||||
package apelet.common.flow.online.object; |
||||
|
||||
import apelet.common.core.util.ContextUtil; |
||||
import apelet.common.online.object.TransactionalBusinessData; |
||||
import lombok.Data; |
||||
import lombok.EqualsAndHashCode; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
/** |
||||
* 跨库存储工作流的业务数据的事物性事件数据。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@EqualsAndHashCode(callSuper = true) |
||||
@Data |
||||
public class TransactionalFlowBusinessData extends TransactionalBusinessData { |
||||
|
||||
/** |
||||
* 流程实例Id。 |
||||
*/ |
||||
private String processInstanceId; |
||||
/** |
||||
* 流程任务Id。 |
||||
*/ |
||||
private String taskId; |
||||
/** |
||||
* 流程任务定义标识。 |
||||
*/ |
||||
private String taskKey; |
||||
/** |
||||
* 流程任务定义名称。 |
||||
*/ |
||||
private String taskName; |
||||
/** |
||||
* 审批注释。 |
||||
*/ |
||||
private String taskComment; |
||||
|
||||
private static final ThreadLocal<TransactionalFlowBusinessData> FLOW_BUSINESS_DATA_THREAD_LOCAL = new ThreadLocal<>(); |
||||
|
||||
public TransactionalFlowBusinessData() { |
||||
super(); |
||||
} |
||||
|
||||
public TransactionalFlowBusinessData(HttpServletRequest request) { |
||||
super(request); |
||||
} |
||||
|
||||
/** |
||||
* 获取HttpServletRequest属性中的事物性时间对象。如果没有情趣对象,则从线程本地存储中获取。 |
||||
* |
||||
* @return 返回设置在当前请求属性中的事务性时间对象。如果不存在则返回NULL。 |
||||
*/ |
||||
public static TransactionalFlowBusinessData getFromRequestAttribute() { |
||||
HttpServletRequest request = ContextUtil.getHttpRequest(); |
||||
if (request != null) { |
||||
return (TransactionalFlowBusinessData) request.getAttribute(BUSINESS_DATA_ATTR_KEY); |
||||
} |
||||
return FLOW_BUSINESS_DATA_THREAD_LOCAL.get(); |
||||
} |
||||
|
||||
/** |
||||
* 获取HttpServletRequest属性中的事物性时间对象。如果存在直接返回,否则创建新对象,并设置到当前请求的指定属性中。 |
||||
* 如果没有情趣对象,则从线程本地存储中创建。 |
||||
* |
||||
* @return 返回设置在当前请求属性中的事务性时间对象。 |
||||
*/ |
||||
public static TransactionalFlowBusinessData getOrCreateFromRequestAttribute() { |
||||
HttpServletRequest request = ContextUtil.getHttpRequest(); |
||||
TransactionalFlowBusinessData data; |
||||
if (request != null) { |
||||
data = (TransactionalFlowBusinessData) request.getAttribute(BUSINESS_DATA_ATTR_KEY); |
||||
if (data != null) { |
||||
return data; |
||||
} |
||||
data = new TransactionalFlowBusinessData(request); |
||||
request.setAttribute(BUSINESS_DATA_ATTR_KEY, data); |
||||
} else { |
||||
data = FLOW_BUSINESS_DATA_THREAD_LOCAL.get(); |
||||
if (data != null) { |
||||
return data; |
||||
} |
||||
data = new TransactionalFlowBusinessData(); |
||||
FLOW_BUSINESS_DATA_THREAD_LOCAL.set(data); |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
/** |
||||
* 移除该对象。 |
||||
*/ |
||||
public static void removeFromRequestAttribute() { |
||||
if (ContextUtil.hasRequestContext()) { |
||||
ContextUtil.getHttpRequest().removeAttribute(BUSINESS_DATA_ATTR_KEY); |
||||
} else { |
||||
FLOW_BUSINESS_DATA_THREAD_LOCAL.remove(); |
||||
} |
||||
} |
||||
} |
||||
@ -1,13 +0,0 @@
@@ -1,13 +0,0 @@
|
||||
package apelet.common.flow.online.service; |
||||
|
||||
import apelet.common.flow.model.FlowEntry; |
||||
|
||||
import javax.xml.stream.XMLStreamException; |
||||
|
||||
public interface FlowEntryOnlineService { |
||||
|
||||
void publish(FlowEntry flowEntry, String initTaskInfo) throws XMLStreamException; |
||||
|
||||
|
||||
void processFlowTaskExtList(FlowEntry flowEntry, String taskInfo) throws XMLStreamException; |
||||
} |
||||
@ -1,163 +0,0 @@
@@ -1,163 +0,0 @@
|
||||
package apelet.common.flow.online.service; |
||||
|
||||
import apelet.common.flow.model.FlowTaskComment; |
||||
import apelet.common.flow.model.FlowTransProducer; |
||||
import apelet.common.flow.model.FlowWorkOrder; |
||||
import apelet.common.online.model.OnlineDatasource; |
||||
import apelet.common.online.model.OnlineDatasourceRelation; |
||||
import apelet.common.online.model.OnlineTable; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import org.flowable.engine.runtime.ProcessInstance; |
||||
import org.flowable.task.api.Task; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 流程操作服务接口。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
public interface FlowOnlineOperationService { |
||||
|
||||
/** |
||||
* 启动流程实例,并将业务主键Id传给新启动的流程实例。 |
||||
* |
||||
* @param processDefinitionId 流程实例Id。 |
||||
* @param dataId 业务主键Id。 |
||||
*/ |
||||
ProcessInstance startWithBusinessKey(String processDefinitionId, String dataId); |
||||
|
||||
|
||||
/** |
||||
* 启动流程实例,并将业务主键Id传给新启动的流程实例。 |
||||
* |
||||
* @param processDefinitionId 流程实例Id。 |
||||
* @param dataId 业务主键Id。 |
||||
*/ |
||||
void startWithBusinessKeyExt(String processDefinitionId, String dataId,Long formId); |
||||
|
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时启动流程。如果当前用户是第一个用户任务的Assignee, |
||||
* 或者第一个用户任务的Assignee是流程发起人变量,该方法还会自动Take第一个任务。 |
||||
* |
||||
* @param processDefinitionId 流程定义Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param table 表对象。 |
||||
* @param data 表数据。 |
||||
*/ |
||||
void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data); |
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时启动流程。如果当前用户是第一个用户任务的Assignee, |
||||
* 或者第一个用户任务的Assignee是流程发起人变量,该方法还会自动Take第一个任务。 |
||||
* |
||||
* @param processDefinitionId 流程定义Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param masterTable 主表对象。 |
||||
* @param masterData 主表数据。 |
||||
* @param slaveDataListMap 关联从表数据Map。 |
||||
*/ |
||||
void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap); |
||||
|
||||
/** |
||||
* 保存在线表单的草稿数据,同时启动一个流程实例。 |
||||
* |
||||
* @param processDefinitionId 流程定义Id。 |
||||
* @param tableId 在线表单主表Id。 |
||||
* @param masterData 主表数据。 |
||||
* @param slaveData 所有关联从表数据。 |
||||
* @return 流程工单对象。 |
||||
*/ |
||||
FlowWorkOrder saveNewDraftAndStartProcess( |
||||
String processDefinitionId, Long tableId, JSONObject masterData, JSONObject slaveData); |
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时Take用户任务。 |
||||
* |
||||
* @param processInstanceId 流程实例Id。 |
||||
* @param taskId 流程任务Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param table 表对象。 |
||||
* @param data 表数据。 |
||||
*/ |
||||
void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data); |
||||
|
||||
/** |
||||
* 保存在线表单的数据,同时Take用户任务。 |
||||
* |
||||
* @param processInstanceId 流程实例Id。 |
||||
* @param taskId 流程任务Id。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param masterTable 主表对象。 |
||||
* @param masterData 主表数据。 |
||||
* @param slaveDataListMap 关联从表数据Map。 |
||||
*/ |
||||
void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap); |
||||
|
||||
/** |
||||
* 保存业务表数据,同时接收流程任务。 |
||||
* |
||||
* @param task 流程任务。 |
||||
* @param flowTaskComment 流程审批批注对象。 |
||||
* @param taskVariableData 流程任务的变量数据。 |
||||
* @param datasource 主表所在数据源。 |
||||
* @param masterData 主表数据。 |
||||
* @param masterDataId 主表数据主键。 |
||||
* @param slaveDataListMap 从表数据。 |
||||
*/ |
||||
void updateAndTakeTask( |
||||
Task task, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineDatasource datasource, |
||||
JSONObject masterData, |
||||
String masterDataId, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap); |
||||
|
||||
/** |
||||
* 修复业务数据。 |
||||
* |
||||
* @param flowTransProducer 流程操作流水生产者对象。 |
||||
*/ |
||||
void fixBusinessData(FlowTransProducer flowTransProducer); |
||||
|
||||
/** |
||||
* 获取在线表单工作流Id所关联的权限数据,包括权限字列表和权限资源列表。 |
||||
* |
||||
* @param onlineFormEntryIds 在线表单工作流Id集合。 |
||||
* @return 参数中在线表单工作流Id集合所关联的权限数据。 |
||||
*/ |
||||
List<Map<String, Object>> calculatePermData(Set<Long> onlineFormEntryIds); |
||||
} |
||||
@ -1,319 +0,0 @@
@@ -1,319 +0,0 @@
|
||||
package apelet.common.flow.online.service.impl; |
||||
|
||||
import apelet.common.core.object.TokenData; |
||||
import apelet.common.core.util.MyModelUtil; |
||||
import apelet.common.flow.constant.FlowConstant; |
||||
import apelet.common.flow.dao.FlowEntryMapper; |
||||
import apelet.common.flow.dao.FlowEntryPublishMapper; |
||||
import apelet.common.flow.dao.FlowEntryPublishVariableMapper; |
||||
import apelet.common.flow.listener.*; |
||||
import apelet.common.flow.model.*; |
||||
import apelet.common.flow.model.constant.FlowEntryStatus; |
||||
import apelet.common.flow.object.*; |
||||
import apelet.common.flow.online.listener.ApprovalSettingsByCreateListener; |
||||
import apelet.common.flow.online.service.FlowEntryOnlineService; |
||||
import apelet.common.flow.service.*; |
||||
import apelet.common.flow.util.BaseFlowIdentityExtHelper; |
||||
import apelet.common.flow.util.FlowCustomExtFactory; |
||||
import apelet.common.flow.util.FlowRedisKeyUtil; |
||||
import apelet.common.redis.util.CommonRedisUtil; |
||||
import apelet.common.sequence.wrapper.IdGeneratorWrapper; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.lang.Assert; |
||||
import cn.hutool.core.util.BooleanUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.Cleanup; |
||||
import org.flowable.bpmn.converter.BpmnXMLConverter; |
||||
import org.flowable.bpmn.model.*; |
||||
import org.flowable.engine.RepositoryService; |
||||
import org.flowable.engine.repository.Deployment; |
||||
import org.flowable.engine.repository.ProcessDefinition; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import javax.xml.stream.XMLInputFactory; |
||||
import javax.xml.stream.XMLStreamException; |
||||
import javax.xml.stream.XMLStreamReader; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
@Service("flowEntryOnlineService") |
||||
public class FlowEntryOnlineServiceImpl implements FlowEntryOnlineService { |
||||
|
||||
@Autowired |
||||
private FlowEntryMapper flowEntryMapper; |
||||
@Autowired |
||||
private FlowEntryPublishMapper flowEntryPublishMapper; |
||||
@Autowired |
||||
private FlowEntryPublishVariableMapper flowEntryPublishVariableMapper; |
||||
@Autowired |
||||
private FlowEntryVariableService flowEntryVariableService; |
||||
@Autowired |
||||
private FlowCategoryService flowCategoryService; |
||||
@Autowired |
||||
private FlowTaskExtService flowTaskExtService; |
||||
@Autowired |
||||
private FlowApiService flowApiService; |
||||
@Autowired |
||||
private FlowCustomExtFactory flowCustomExtFactory; |
||||
@Autowired |
||||
private RepositoryService repositoryService; |
||||
@Autowired |
||||
private IdGeneratorWrapper idGenerator; |
||||
@Autowired |
||||
private CommonRedisUtil commonRedisUtil; |
||||
|
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void publish(FlowEntry flowEntry, String initTaskInfo) throws XMLStreamException { |
||||
commonRedisUtil.evictFormCache( |
||||
FlowRedisKeyUtil.makeFlowEntryKey(flowEntry.getProcessDefinitionKey())); |
||||
FlowCategory flowCategory = flowCategoryService.getById(flowEntry.getCategoryId()); |
||||
InputStream xmlStream = new ByteArrayInputStream( |
||||
flowEntry.getBpmnXml().getBytes(StandardCharsets.UTF_8)); |
||||
@Cleanup XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(xmlStream); |
||||
BpmnXMLConverter converter = new BpmnXMLConverter(); |
||||
BpmnModel bpmnModel = converter.convertToBpmnModel(reader); |
||||
bpmnModel.getMainProcess().setName(flowEntry.getProcessDefinitionName()); |
||||
bpmnModel.getMainProcess().setId(flowEntry.getProcessDefinitionKey()); |
||||
flowApiService.addProcessInstanceEndListener(bpmnModel, FlowFinishedListener.class); |
||||
List<FlowTaskExt> flowTaskExtList = flowTaskExtService.buildTaskExtList(bpmnModel); |
||||
if (StrUtil.isNotBlank(flowEntry.getExtensionData())) { |
||||
FlowEntryExtensionData flowEntryExtensionData = |
||||
JSON.parseObject(flowEntry.getExtensionData(), FlowEntryExtensionData.class); |
||||
this.mergeTaskNotifyData(flowEntryExtensionData, flowTaskExtList); |
||||
this.processFlowTaskRevive(flowEntryExtensionData, bpmnModel); |
||||
} |
||||
this.processFlowTaskExtList(flowTaskExtList, bpmnModel); |
||||
TokenData tokenData = TokenData.takeFromRequest(); |
||||
Deployment deploy = repositoryService.createDeployment() |
||||
.addBpmnModel(flowEntry.getProcessDefinitionKey() + ".bpmn", bpmnModel) |
||||
.tenantId(tokenData.getTenantId() != null ? tokenData.getTenantId().toString() : tokenData.getAppCode()) |
||||
.name(flowEntry.getProcessDefinitionName()) |
||||
.key(flowEntry.getProcessDefinitionKey()) |
||||
.category(flowCategory.getCode()) |
||||
.deploy(); |
||||
ProcessDefinition processDefinition = flowApiService.getProcessDefinitionByDeployId(deploy.getId()); |
||||
FlowEntryPublish flowEntryPublish = new FlowEntryPublish(); |
||||
flowEntryPublish.setEntryPublishId(idGenerator.nextLongId()); |
||||
flowEntryPublish.setEntryId(flowEntry.getEntryId()); |
||||
flowEntryPublish.setProcessDefinitionId(processDefinition.getId()); |
||||
flowEntryPublish.setDeployId(processDefinition.getDeploymentId()); |
||||
flowEntryPublish.setPublishVersion(processDefinition.getVersion()); |
||||
flowEntryPublish.setActiveStatus(true); |
||||
flowEntryPublish.setMainVersion(flowEntry.getStatus().equals(FlowEntryStatus.UNPUBLISHED)); |
||||
flowEntryPublish.setCreateUserId(TokenData.takeFromRequest().getUserId()); |
||||
flowEntryPublish.setPublishTime(new Date()); |
||||
flowEntryPublish.setInitTaskInfo(initTaskInfo); |
||||
flowEntryPublish.setExtensionData(flowEntry.getExtensionData()); |
||||
flowEntryPublish.setStartConditions(flowEntry.getStartConditions()); |
||||
AnalyzedNode rootNode = flowApiService.analyzeBpmnRoads(processDefinition.getId()); |
||||
flowEntryPublish.setAnalyzedNodeJson(JSON.toJSONString(rootNode)); |
||||
flowEntryPublishMapper.insert(flowEntryPublish); |
||||
FlowEntry updatedFlowEntry = new FlowEntry(); |
||||
updatedFlowEntry.setEntryId(flowEntry.getEntryId()); |
||||
updatedFlowEntry.setStatus(FlowEntryStatus.PUBLISHED); |
||||
updatedFlowEntry.setLatestPublishTime(new Date()); |
||||
// 对于从未发布过的工作,第一次发布的时候会将本地发布置位主版本。
|
||||
if (flowEntry.getStatus().equals(FlowEntryStatus.UNPUBLISHED)) { |
||||
updatedFlowEntry.setMainEntryPublishId(flowEntryPublish.getEntryPublishId()); |
||||
} |
||||
flowEntryMapper.updateById(updatedFlowEntry); |
||||
FlowEntryVariable flowEntryVariableFilter = new FlowEntryVariable(); |
||||
flowEntryVariableFilter.setEntryId(flowEntry.getEntryId()); |
||||
List<FlowEntryVariable> flowEntryVariableList = |
||||
flowEntryVariableService.getFlowEntryVariableList(flowEntryVariableFilter, null); |
||||
if (CollUtil.isNotEmpty(flowTaskExtList)) { |
||||
flowTaskExtList.forEach(t -> t.setProcessDefinitionId(processDefinition.getId())); |
||||
flowTaskExtService.saveBatch(flowTaskExtList); |
||||
} |
||||
this.insertEntryPublishVariables(flowEntryVariableList, flowEntryPublish.getEntryPublishId()); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void processFlowTaskExtList(FlowEntry flowEntry,String taskInfo) throws XMLStreamException { |
||||
|
||||
InputStream xmlStream = new ByteArrayInputStream( |
||||
flowEntry.getBpmnXml().getBytes(StandardCharsets.UTF_8)); |
||||
@Cleanup XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(xmlStream); |
||||
BpmnXMLConverter converter = new BpmnXMLConverter(); |
||||
BpmnModel bpmnModel = converter.convertToBpmnModel(reader); |
||||
bpmnModel.getMainProcess().setName(flowEntry.getProcessDefinitionName()); |
||||
bpmnModel.getMainProcess().setId(flowEntry.getProcessDefinitionKey()); |
||||
|
||||
List<FlowTaskExt> flowTaskExtList = flowTaskExtService.buildTaskExtList(bpmnModel); |
||||
|
||||
List<FlowElement> elementList = new LinkedList<>(); |
||||
this.calculateAllElementList(bpmnModel.getMainProcess().getFlowElements(), elementList); |
||||
|
||||
Map<String, FlowElement> elementMap = elementList.stream() |
||||
.filter(UserTask.class::isInstance).collect(Collectors.toMap(FlowElement::getId, c -> c)); |
||||
for (FlowTaskExt t : flowTaskExtList) { |
||||
UserTask userTask = (UserTask) elementMap.get(t.getTaskId()); |
||||
// create 创建
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "create"); |
||||
// assignment 分配/指派
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "assignment"); |
||||
// complete 完成
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "complete"); |
||||
// delete 删除
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "delete"); |
||||
} |
||||
} |
||||
|
||||
private void calculateAllElementList(Collection<FlowElement> elements, List<FlowElement> resultList) { |
||||
resultList.addAll(elements); |
||||
for (FlowElement element : elements) { |
||||
if (element instanceof SubProcess) { |
||||
this.calculateAllElementList(((SubProcess) element).getFlowElements(), resultList); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void mergeTaskNotifyData(FlowEntryExtensionData flowEntryExtensionData, List<FlowTaskExt> flowTaskExtList) { |
||||
if (CollUtil.isEmpty(flowEntryExtensionData.getNotifyTypes())) { |
||||
return; |
||||
} |
||||
List<String> flowTaskNotifyTypes = |
||||
flowEntryExtensionData.getNotifyTypes().stream().filter(StrUtil::isNotBlank).collect(Collectors.toList()); |
||||
if (CollUtil.isEmpty(flowTaskNotifyTypes)) { |
||||
return; |
||||
} |
||||
for (FlowTaskExt flowTaskExt : flowTaskExtList) { |
||||
if (flowTaskExt.getExtraDataJson() == null) { |
||||
JSONObject o = new JSONObject(); |
||||
o.put(FlowConstant.USER_TASK_NOTIFY_TYPES_KEY, flowTaskNotifyTypes); |
||||
flowTaskExt.setExtraDataJson(o.toJSONString()); |
||||
} else { |
||||
FlowUserTaskExtData taskExtData = |
||||
JSON.parseObject(flowTaskExt.getExtraDataJson(), FlowUserTaskExtData.class); |
||||
if (CollUtil.isEmpty(taskExtData.getFlowNotifyTypeList())) { |
||||
taskExtData.setFlowNotifyTypeList(flowTaskNotifyTypes); |
||||
} else { |
||||
Set<String> notifyTypesSet = taskExtData.getFlowNotifyTypeList() |
||||
.stream().filter(StrUtil::isNotBlank).collect(Collectors.toSet()); |
||||
notifyTypesSet.addAll(flowTaskNotifyTypes); |
||||
taskExtData.setFlowNotifyTypeList(new LinkedList<>(notifyTypesSet)); |
||||
} |
||||
flowTaskExt.setExtraDataJson(JSON.toJSONString(taskExtData)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void processFlowTaskRevive(FlowEntryExtensionData flowEntryExtensionData, BpmnModel bpmnModel) { |
||||
if (BooleanUtil.isTrue(flowEntryExtensionData.getSupportRevive())) { |
||||
List<UserTask> mainProcessUserTasks = bpmnModel.getMainProcess().getFlowElements() |
||||
.stream().filter(UserTask.class::isInstance).map(t -> (UserTask) t).collect(Collectors.toList()); |
||||
mainProcessUserTasks.forEach(t -> flowApiService.addTaskCreateListener(t, FlowTaskReviveListener.class)); |
||||
} |
||||
} |
||||
|
||||
private void processFlowTaskExtList(List<FlowTaskExt> flowTaskExtList, BpmnModel bpmnModel) { |
||||
List<FlowElement> elementList = new LinkedList<>(); |
||||
this.calculateAllElementList(bpmnModel.getMainProcess().getFlowElements(), elementList); |
||||
this.doAddLatestApprovalStatusListener(elementList); |
||||
Map<String, FlowElement> elementMap = elementList.stream() |
||||
.filter(UserTask.class::isInstance).collect(Collectors.toMap(FlowElement::getId, c -> c)); |
||||
BaseFlowIdentityExtHelper flowIdentityExtHelper = flowCustomExtFactory.getFlowIdentityExtHelper(); |
||||
for (FlowTaskExt t : flowTaskExtList) { |
||||
UserTask userTask = (UserTask) elementMap.get(t.getTaskId()); |
||||
flowApiService.addTaskCreateListener(userTask, FlowUserTaskListener.class); |
||||
// create 创建
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "create"); |
||||
// assignment 分配/指派
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "assignment"); |
||||
// complete 完成
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "complete"); |
||||
// delete 删除
|
||||
flowApiService.addTaskListenerByEvent(userTask, ApprovalSettingsByCreateListener.class, "delete"); |
||||
|
||||
Map<String, List<ExtensionAttribute>> attributes = userTask.getAttributes(); |
||||
if (CollUtil.isNotEmpty(attributes.get(FlowConstant.USER_TASK_AUTO_SKIP_KEY))) { |
||||
flowApiService.addTaskCreateListener(userTask, AutoSkipTaskListener.class); |
||||
} |
||||
// 如果流程图中包含部门领导审批和上级部门领导审批的选项,就需要注册 FlowCustomExtFactory 工厂中的
|
||||
// BaseFlowIdentityExtHelper 对象,该注册操作需要业务模块中实现。
|
||||
if (StrUtil.equals(t.getGroupType(), FlowConstant.GROUP_TYPE_UP_DEPT_POST_LEADER)) { |
||||
userTask.setCandidateGroups( |
||||
CollUtil.newArrayList("${" + FlowConstant.GROUP_TYPE_UP_DEPT_POST_LEADER_VAR + "}")); |
||||
Assert.notNull(flowIdentityExtHelper); |
||||
flowApiService.addTaskCreateListener(userTask, flowIdentityExtHelper.getUpDeptPostLeaderListener()); |
||||
} else if (StrUtil.equals(t.getGroupType(), FlowConstant.GROUP_TYPE_DEPT_POST_LEADER)) { |
||||
userTask.setCandidateGroups( |
||||
CollUtil.newArrayList("${" + FlowConstant.GROUP_TYPE_DEPT_POST_LEADER_VAR + "}")); |
||||
Assert.notNull(flowIdentityExtHelper); |
||||
flowApiService.addTaskCreateListener(userTask, flowIdentityExtHelper.getDeptPostLeaderListener()); |
||||
} else if (StrUtil.equals(t.getGroupType(), FlowConstant.GROUP_TYPE_POST)) { |
||||
Assert.notNull(t.getDeptPostListJson()); |
||||
List<FlowTaskPostCandidateGroup> groupDataList = |
||||
JSON.parseArray(t.getDeptPostListJson(), FlowTaskPostCandidateGroup.class); |
||||
List<String> candidateGroupList = |
||||
FlowTaskPostCandidateGroup.buildCandidateGroupList(groupDataList); |
||||
userTask.setCandidateGroups(candidateGroupList); |
||||
} |
||||
this.processFlowTaskExtListener(userTask, t); |
||||
} |
||||
} |
||||
|
||||
private void insertEntryPublishVariables(List<FlowEntryVariable> entryVariableList, Long entryPublishId) { |
||||
if (CollUtil.isEmpty(entryVariableList)) { |
||||
return; |
||||
} |
||||
List<FlowEntryPublishVariable> entryPublishVariableList = |
||||
MyModelUtil.copyCollectionTo(entryVariableList, FlowEntryPublishVariable.class); |
||||
for (FlowEntryPublishVariable variable : entryPublishVariableList) { |
||||
variable.setVariableId(idGenerator.nextLongId()); |
||||
variable.setEntryPublishId(entryPublishId); |
||||
} |
||||
flowEntryPublishVariableMapper.insertList(entryPublishVariableList); |
||||
} |
||||
|
||||
private void doAddLatestApprovalStatusListener(Collection<FlowElement> elementList) { |
||||
List<FlowElement> sequenceFlowList = |
||||
elementList.stream().filter(SequenceFlow.class::isInstance).collect(Collectors.toList()); |
||||
for (FlowElement sequenceFlow : sequenceFlowList) { |
||||
FlowElementExtProperty extProperty = flowTaskExtService.buildFlowElementExt(sequenceFlow); |
||||
if (extProperty != null && extProperty.getLatestApprovalStatus() != null) { |
||||
List<FieldExtension> fieldExtensions = new LinkedList<>(); |
||||
FieldExtension fieldExtension = new FieldExtension(); |
||||
fieldExtension.setFieldName(FlowConstant.LATEST_APPROVAL_STATUS_KEY); |
||||
fieldExtension.setStringValue(extProperty.getLatestApprovalStatus().toString()); |
||||
fieldExtensions.add(fieldExtension); |
||||
flowApiService.addExecutionListener( |
||||
sequenceFlow, UpdateLatestApprovalStatusListener.class, "start", fieldExtensions); |
||||
} |
||||
} |
||||
List<SubProcess> subProcesseList = elementList.stream() |
||||
.filter(SubProcess.class::isInstance).map(SubProcess.class::cast).collect(Collectors.toList()); |
||||
for (SubProcess subProcess : subProcesseList) { |
||||
this.doAddLatestApprovalStatusListener(subProcess.getFlowElements()); |
||||
} |
||||
} |
||||
|
||||
private void processFlowTaskExtListener(UserTask userTask, FlowTaskExt taskExt) { |
||||
if (StrUtil.isBlank(taskExt.getExtraDataJson())) { |
||||
return; |
||||
} |
||||
FlowUserTaskExtData userTaskExtData = |
||||
JSON.parseObject(taskExt.getExtraDataJson(), FlowUserTaskExtData.class); |
||||
if (CollUtil.isNotEmpty(userTaskExtData.getFlowNotifyTypeList())) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowTaskNotifyListener.class); |
||||
} |
||||
if (userTaskExtData.getRejectType().equals(FlowUserTaskExtData.REJECT_TYPE_BACK_TO_SOURCE)) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowTaskRejectBackListener.class); |
||||
} |
||||
if (StrUtil.isNotBlank(userTaskExtData.getTimeoutHandleWay())) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowTaskTimeoutListener.class); |
||||
} |
||||
if (StrUtil.isNotBlank(userTaskExtData.getEmptyUserHandleWay())) { |
||||
flowApiService.addTaskCreateListener(userTask, FlowEmptyUserHandleListener.class); |
||||
} |
||||
} |
||||
} |
||||
@ -1,102 +0,0 @@
@@ -1,102 +0,0 @@
|
||||
package apelet.common.flow.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MyDataSource; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.flow.base.service.BaseFlowOnlineService; |
||||
import apelet.common.flow.model.FlowWorkOrder; |
||||
import apelet.common.flow.online.object.TransactionalFlowBusinessData; |
||||
import apelet.common.flow.util.FlowCustomExtFactory; |
||||
import apelet.common.online.exception.OnlineRuntimeException; |
||||
import apelet.common.online.model.*; |
||||
import apelet.common.online.model.constant.FieldKind; |
||||
import apelet.common.online.service.*; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import javax.annotation.PostConstruct; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 在线表单和流程监听器进行数据对接时的服务实现类。 |
||||
* |
||||
* @author guifc |
||||
* @date 2023-08-04 |
||||
*/ |
||||
@Slf4j |
||||
@MyDataSource(ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("flowOnlineBusinessService") |
||||
public class FlowOnlineBusinessServiceImpl implements BaseFlowOnlineService { |
||||
|
||||
@Autowired |
||||
private FlowCustomExtFactory flowCustomExtFactory; |
||||
@Autowired |
||||
private OnlineTableService onlineTableService; |
||||
@Autowired |
||||
private OnlineDatasourceService onlineDatasourceService; |
||||
@Autowired |
||||
private OnlineDatasourceRelationService onlineDatasourceRelationService; |
||||
@Autowired |
||||
private OnlineOperationService onlineOperationService; |
||||
|
||||
@PostConstruct |
||||
public void doRegister() { |
||||
flowCustomExtFactory.getOnlineBusinessDataExtHelper().setOnlineBusinessService(this); |
||||
} |
||||
|
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void updateFlowStatus(FlowWorkOrder workOrder) { |
||||
OnlineTable onlineTable = onlineTableService.getOnlineTableFromCache(workOrder.getOnlineTableId()); |
||||
if (onlineTable == null) { |
||||
log.error("OnlineTableId [{}] doesn't exist while calling FlowOnlineBusinessServiceImpl.updateFlowStatus", |
||||
workOrder.getOnlineTableId()); |
||||
return; |
||||
} |
||||
String dataId = workOrder.getBusinessKey(); |
||||
this.handleTransactionalFlowBusinessData(workOrder, "FlowOnlineBusinessServiceImpl.updateFlowStatus"); |
||||
for (OnlineColumn column : onlineTable.getColumnMap().values()) { |
||||
if (ObjectUtil.equals(column.getFieldKind(), FieldKind.FLOW_FINISHED_STATUS)) { |
||||
onlineOperationService.updateColumn(onlineTable, dataId, column, workOrder.getFlowStatus()); |
||||
} |
||||
if (ObjectUtil.equals(column.getFieldKind(), FieldKind.FLOW_APPROVAL_STATUS)) { |
||||
onlineOperationService.updateColumn(onlineTable, dataId, column, workOrder.getLatestApprovalStatus()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void deleteBusinessData(FlowWorkOrder workOrder) { |
||||
OnlineTable onlineTable = onlineTableService.getOnlineTableFromCache(workOrder.getOnlineTableId()); |
||||
if (onlineTable == null) { |
||||
log.error("OnlineTableId [{}] doesn't exist while calling FlowOnlineBusinessServiceImpl.deleteBusinessData", |
||||
workOrder.getOnlineTableId()); |
||||
return; |
||||
} |
||||
OnlineDatasource datasource = |
||||
onlineDatasourceService.getOnlineDatasourceByMasterTableId(onlineTable.getTableId()); |
||||
List<OnlineDatasourceRelation> relationList = |
||||
onlineDatasourceRelationService.getOnlineDatasourceRelationListFromCache(CollUtil.newHashSet(datasource.getDatasourceId())); |
||||
String dataId = workOrder.getBusinessKey(); |
||||
for (OnlineDatasourceRelation relation : relationList) { |
||||
OnlineTable slaveTable = onlineTableService.getOnlineTableFromCache(relation.getSlaveTableId()); |
||||
if (slaveTable == null) { |
||||
throw new OnlineRuntimeException("数据验证失败,数据源关联 [" + relation.getRelationName() + "] 的从表Id不存在!"); |
||||
} |
||||
relation.setSlaveTable(slaveTable); |
||||
} |
||||
this.handleTransactionalFlowBusinessData(workOrder, "FlowOnlineBusinessServiceImpl.deleteBusinessData"); |
||||
onlineOperationService.delete(onlineTable, relationList, dataId); |
||||
} |
||||
|
||||
private void handleTransactionalFlowBusinessData(FlowWorkOrder workOrder, String desc) { |
||||
TransactionalFlowBusinessData eventData = TransactionalFlowBusinessData.getFromRequestAttribute(); |
||||
if (eventData != null) { |
||||
eventData.setProcessInstanceId(workOrder.getProcessInstanceId()); |
||||
eventData.setOperationDesc(desc); |
||||
} |
||||
} |
||||
} |
||||
@ -1,434 +0,0 @@
@@ -1,434 +0,0 @@
|
||||
package apelet.common.flow.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MultiDatabaseWriteMethod; |
||||
import apelet.common.core.annotation.MyDataSource; |
||||
import apelet.common.core.config.CoreProperties; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.core.object.CallResult; |
||||
import apelet.common.core.object.ObjectValue; |
||||
import apelet.common.dbutil.provider.DataSourceProvider; |
||||
import apelet.common.dbutil.provider.PostgreSqlProvider; |
||||
import apelet.common.flow.config.FlowProperties; |
||||
import apelet.common.flow.constant.FlowApprovalType; |
||||
import apelet.common.flow.constant.FlowConstant; |
||||
import apelet.common.flow.constant.FlowTaskStatus; |
||||
import apelet.common.flow.dao.FlowTransProducerMapper; |
||||
import apelet.common.flow.exception.FlowOperationException; |
||||
import apelet.common.flow.model.*; |
||||
import apelet.common.flow.online.object.TransactionalFlowBusinessData; |
||||
import apelet.common.flow.online.service.FlowOnlineOperationService; |
||||
import apelet.common.flow.service.FlowApiService; |
||||
import apelet.common.flow.service.FlowEntryService; |
||||
import apelet.common.flow.service.FlowWorkOrderService; |
||||
import apelet.common.generator.utils.OrmGenDataSourceUtil; |
||||
import apelet.common.online.config.OnlineProperties; |
||||
import apelet.common.online.exception.OnlineRuntimeException; |
||||
import apelet.common.online.model.*; |
||||
import apelet.common.online.object.TransactionalBusinessData; |
||||
import apelet.common.online.service.*; |
||||
import apelet.common.online.util.OnlineDataSourceUtil; |
||||
import apelet.common.orm.impl.Selector; |
||||
import apelet.common.orm.impl.SelectorItem; |
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.lang.Assert; |
||||
import cn.hutool.core.map.MapUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.flowable.engine.runtime.ProcessInstance; |
||||
import org.flowable.task.api.Task; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
import org.springframework.transaction.event.TransactionPhase; |
||||
import org.springframework.transaction.event.TransactionalEventListener; |
||||
|
||||
import java.sql.Connection; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
@Slf4j |
||||
@MyDataSource(ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("flowOnlineOperationService") |
||||
public class FlowOnlineOperationServiceImpl implements FlowOnlineOperationService { |
||||
|
||||
@Autowired |
||||
private FlowApiService flowApiService; |
||||
@Autowired |
||||
private FlowWorkOrderService flowWorkOrderService; |
||||
@Autowired |
||||
private FlowEntryService flowEntryService; |
||||
@Autowired |
||||
private OnlineOperationService onlineOperationService; |
||||
@Autowired |
||||
private OnlineDatasourceService onlineDatasourceService; |
||||
@Autowired |
||||
private OnlineProperties onlineProperties; |
||||
@Autowired |
||||
private FlowProperties flowProperties; |
||||
@Autowired |
||||
private CoreProperties coreProperties; |
||||
@Autowired |
||||
private OnlineDataSourceUtil dataSourceUtil; |
||||
@Autowired |
||||
private FlowTransProducerMapper flowTransProducerMapper; |
||||
@Autowired |
||||
private OnlineFormService onlineFormService; |
||||
@Autowired |
||||
private OnlineTableService onlineTableService; |
||||
|
||||
@Autowired |
||||
private OrmGenDataSourceUtil ormGenDataSourceUtil; |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public ProcessInstance startWithBusinessKey(String processDefinitionId, String dataId) { |
||||
ProcessInstance instance = flowApiService.start(processDefinitionId, dataId); |
||||
flowWorkOrderService.saveNew(instance, dataId, null, null); |
||||
return instance; |
||||
} |
||||
|
||||
@Override |
||||
public void startWithBusinessKeyExt(String processDefinitionId, String dataId, Long formId) { |
||||
OnlineForm OnlineForm = onlineFormService.getOnlineFormFromCache(formId); |
||||
OnlineTable onlineTable = onlineTableService.getOnlineTableFromCache(OnlineForm.getMasterTableId()); |
||||
Selector selector = new Selector(); |
||||
selector.getList().add(new SelectorItem("billstatus")); |
||||
ObjectValue objectValue = ormGenDataSourceUtil.queryOne(onlineTable.getTableName(),Long.valueOf(dataId),selector); |
||||
if(objectValue == null){ |
||||
String errorMessage = "无效数据!"; |
||||
throw new RuntimeException(errorMessage); |
||||
} |
||||
if(!objectValue.get("billstatus").equals("A")){ |
||||
throw new RuntimeException("只有保存状态才能提交"); |
||||
} |
||||
objectValue.put("billstatus","B"); |
||||
try { |
||||
ormGenDataSourceUtil.update(onlineTable.getTableName(),objectValue,selector); |
||||
}catch (Exception e){ |
||||
e.printStackTrace(); |
||||
String errorMessage = "更新失败!错误信息:"+e.getMessage(); |
||||
throw new RuntimeException(errorMessage); |
||||
} |
||||
if(processDefinitionId != null){ |
||||
JSONObject taskVariableData = new JSONObject(); |
||||
ProcessInstance instance = this.startWithBusinessKey(processDefinitionId,dataId); |
||||
FlowTaskComment flowTaskComment = new FlowTaskComment(); |
||||
flowTaskComment.setApprovalType("agree"); |
||||
flowTaskComment.setTaskComment("发起人"); |
||||
flowApiService.takeFirstTask(instance.getProcessInstanceId(), flowTaskComment, taskVariableData); |
||||
} |
||||
|
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data) { |
||||
this.saveNewAndStartProcess(processDefinitionId, flowTaskComment, taskVariableData, table, data, null); |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndStartProcess( |
||||
String processDefinitionId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
Object dataId = onlineOperationService.saveNewWithRelation(masterTable, masterData, slaveDataListMap); |
||||
Assert.notNull(dataId); |
||||
if (taskVariableData == null) { |
||||
taskVariableData = new JSONObject(); |
||||
} |
||||
taskVariableData.put(FlowConstant.MASTER_DATA_KEY, masterData); |
||||
taskVariableData.put(FlowConstant.SLAVE_DATA_KEY, this.normailizeSlaveDataListMap(slaveDataListMap)); |
||||
taskVariableData.put(FlowConstant.MASTER_TABLE_KEY, masterTable); |
||||
ProcessInstance instance = flowApiService.start(processDefinitionId, dataId); |
||||
flowWorkOrderService.saveNew(instance, dataId, masterTable.getTableId(), null); |
||||
flowApiService.takeFirstTask(instance.getProcessInstanceId(), flowTaskComment, taskVariableData); |
||||
// 这里需要在创建工单后再次更新一下工单状态,在flowApiService.completeTask中的更新,
|
||||
// 因为当时没有创建工单对象,更新会不起任何作用,所以这里要补偿一下。
|
||||
Integer approvalStatus = MapUtil.getInt(taskVariableData, FlowConstant.LATEST_APPROVAL_STATUS_KEY); |
||||
flowWorkOrderService.updateLatestApprovalStatusByProcessInstanceId(instance.getId(), approvalStatus); |
||||
} |
||||
|
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public FlowWorkOrder saveNewDraftAndStartProcess( |
||||
String processDefinitionId, Long tableId, JSONObject masterData, JSONObject slaveData) { |
||||
ProcessInstance instance = flowApiService.start(processDefinitionId, null); |
||||
return flowWorkOrderService.saveNewWithDraft( |
||||
instance, tableId, null, JSON.toJSONString(masterData), JSON.toJSONString(slaveData)); |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable table, |
||||
JSONObject data) { |
||||
this.saveNewAndTakeTask( |
||||
processInstanceId, taskId, flowTaskComment, taskVariableData, table, data, null); |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void saveNewAndTakeTask( |
||||
String processInstanceId, |
||||
String taskId, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineTable masterTable, |
||||
JSONObject masterData, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
Object dataId = onlineOperationService.saveNewWithRelation(masterTable, masterData, slaveDataListMap); |
||||
Assert.notNull(dataId); |
||||
Task task = flowApiService.getProcessInstanceActiveTask(processInstanceId, taskId); |
||||
flowApiService.setBusinessKeyForProcessInstance(processInstanceId, dataId); |
||||
Map<String, Object> variables = |
||||
flowApiService.initAndGetProcessInstanceVariables(task.getProcessDefinitionId()); |
||||
if (taskVariableData == null) { |
||||
taskVariableData = new JSONObject(); |
||||
} |
||||
taskVariableData.putAll(variables); |
||||
taskVariableData.put(FlowConstant.MASTER_DATA_KEY, masterData); |
||||
taskVariableData.put(FlowConstant.SLAVE_DATA_KEY, this.normailizeSlaveDataListMap(slaveDataListMap)); |
||||
taskVariableData.put(FlowConstant.MASTER_TABLE_KEY, masterTable); |
||||
flowApiService.completeTask(task, flowTaskComment, taskVariableData, null); |
||||
ProcessInstance instance = flowApiService.getProcessInstance(processInstanceId); |
||||
FlowWorkOrder flowWorkOrder = |
||||
flowWorkOrderService.getFlowWorkOrderByProcessInstanceId(instance.getProcessInstanceId()); |
||||
if (flowWorkOrder == null) { |
||||
flowWorkOrderService.saveNew(instance, dataId, masterTable.getTableId(), null); |
||||
} else { |
||||
flowWorkOrder.setBusinessKey(dataId.toString()); |
||||
flowWorkOrder.setUpdateTime(new Date()); |
||||
flowWorkOrder.setFlowStatus(FlowTaskStatus.SUBMITTED); |
||||
flowWorkOrderService.updateById(flowWorkOrder); |
||||
} |
||||
} |
||||
|
||||
@MultiDatabaseWriteMethod |
||||
@Transactional(rollbackFor = Exception.class) |
||||
@Override |
||||
public void updateAndTakeTask( |
||||
Task task, |
||||
FlowTaskComment flowTaskComment, |
||||
JSONObject taskVariableData, |
||||
OnlineDatasource datasource, |
||||
JSONObject masterData, |
||||
String masterDataId, |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
int flowStatus = FlowTaskStatus.APPROVING; |
||||
if (flowTaskComment.getApprovalType().equals(FlowApprovalType.REFUSE)) { |
||||
flowStatus = FlowTaskStatus.REFUSED; |
||||
} else if (flowTaskComment.getApprovalType().equals(FlowApprovalType.STOP)) { |
||||
flowStatus = FlowTaskStatus.FINISHED; |
||||
} |
||||
OnlineTable masterTable = datasource.getMasterTable(); |
||||
Long datasourceId = datasource.getDatasourceId(); |
||||
flowWorkOrderService.updateFlowStatusByProcessInstanceId(task.getProcessInstanceId(), flowStatus); |
||||
this.updateMasterData(masterTable, masterData, masterDataId); |
||||
if (slaveDataListMap != null) { |
||||
for (Map.Entry<OnlineDatasourceRelation, List<JSONObject>> relationEntry : slaveDataListMap.entrySet()) { |
||||
Long relationId = relationEntry.getKey().getRelationId(); |
||||
onlineOperationService.updateRelationData( |
||||
masterTable, masterData, masterDataId, datasourceId, relationId, relationEntry.getValue()); |
||||
} |
||||
} |
||||
if (flowTaskComment.getApprovalType().equals(FlowApprovalType.STOP)) { |
||||
Integer s = MapUtil.getInt(taskVariableData, FlowConstant.LATEST_APPROVAL_STATUS_KEY); |
||||
flowWorkOrderService.updateLatestApprovalStatusByProcessInstanceId(task.getProcessInstanceId(), s); |
||||
CallResult stopResult = flowApiService.stopProcessInstance( |
||||
task.getProcessInstanceId(), flowTaskComment.getTaskComment(), flowStatus); |
||||
if (!stopResult.isSuccess()) { |
||||
throw new FlowOperationException(stopResult.getErrorMessage()); |
||||
} |
||||
} else { |
||||
if (taskVariableData == null) { |
||||
taskVariableData = new JSONObject(); |
||||
} |
||||
taskVariableData.put(FlowConstant.MASTER_DATA_KEY, masterData); |
||||
taskVariableData.put(FlowConstant.SLAVE_DATA_KEY, this.normailizeSlaveDataListMap(slaveDataListMap)); |
||||
taskVariableData.put(FlowConstant.MASTER_TABLE_KEY, masterTable); |
||||
flowApiService.completeTask(task, flowTaskComment, taskVariableData, null); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void fixBusinessData(FlowTransProducer flowTransProducer) { |
||||
try { |
||||
String sql = "SELECT * FROM zz_flow_trans_consumer WHERE trans_id = " + flowTransProducer.getTransId(); |
||||
List<Map<String, Object>> dataList = dataSourceUtil.query(flowTransProducer.getDblinkId(), sql); |
||||
if (CollUtil.isNotEmpty(dataList)) { |
||||
return; |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("Failed to call dataSourceUtil.query", e); |
||||
throw new OnlineRuntimeException(e.getMessage()); |
||||
} |
||||
TransactionalFlowBusinessData businessData = new TransactionalFlowBusinessData(); |
||||
businessData.setTransId(flowTransProducer.getTransId()); |
||||
businessData.setDblinkId(flowTransProducer.getDblinkId()); |
||||
List<TransactionalBusinessData.BusinessSqlData> sqlDataList = |
||||
JSON.parseArray(flowTransProducer.getSqlData(), TransactionalBusinessData.BusinessSqlData.class); |
||||
businessData.setSqlDataList(sqlDataList); |
||||
try { |
||||
this.doHandle(businessData); |
||||
} catch (Exception e) { |
||||
log.error(e.getMessage(), e); |
||||
throw new OnlineRuntimeException(e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public List<Map<String, Object>> calculatePermData(Set<Long> onlineFormEntryIds) { |
||||
if (CollUtil.isEmpty(onlineFormEntryIds)) { |
||||
return new LinkedList<>(); |
||||
} |
||||
List<Map<String, Object>> permDataList = new LinkedList<>(); |
||||
List<FlowEntry> flowEntries = flowEntryService.getInList(onlineFormEntryIds); |
||||
Set<Long> pageIds = flowEntries.stream().map(FlowEntry::getPageId).collect(Collectors.toSet()); |
||||
Map<Long, String> pageAndVariableNameMap = |
||||
onlineDatasourceService.getPageIdAndVariableNameMapByPageIds(pageIds); |
||||
for (FlowEntry flowEntry : flowEntries) { |
||||
JSONObject permData = new JSONObject(); |
||||
permData.put("entryId", flowEntry.getEntryId()); |
||||
String key = StrUtil.upperFirst(flowEntry.getProcessDefinitionKey()); |
||||
List<String> permCodeList = new LinkedList<>(); |
||||
String formPermCode = "form" + key; |
||||
permCodeList.add(formPermCode); |
||||
permCodeList.add(formPermCode + ":fragment" + key); |
||||
permData.put("permCodeList", permCodeList); |
||||
String flowUrlPrefix = flowProperties.getUrlPrefix(); |
||||
String onlineUrlPrefix = onlineProperties.getUrlPrefix(); |
||||
List<String> permList = CollUtil.newLinkedList( |
||||
onlineUrlPrefix + "/onlineForm/view", |
||||
onlineUrlPrefix + "/onlineForm/render", |
||||
onlineUrlPrefix + "/onlineOperation/listByOneToManyRelationId/" + pageAndVariableNameMap.get(flowEntry.getPageId()), |
||||
flowUrlPrefix + "/flowOperation/viewInitialHistoricTaskInfo", |
||||
flowUrlPrefix + "/flowOperation/startOnly", |
||||
flowUrlPrefix + "/flowOperation/viewInitialTaskInfo", |
||||
flowUrlPrefix + "/flowOperation/viewRuntimeTaskInfo", |
||||
flowUrlPrefix + "/flowOperation/viewProcessBpmn", |
||||
flowUrlPrefix + "/flowOperation/viewHighlightFlowData", |
||||
flowUrlPrefix + "/flowOperation/listFlowTaskComment", |
||||
flowUrlPrefix + "/flowOperation/cancelWorkOrder", |
||||
flowUrlPrefix + "/flowOperation/listRuntimeTask", |
||||
flowUrlPrefix + "/flowOperation/listHistoricProcessInstance", |
||||
flowUrlPrefix + "/flowOperation/listHistoricTask", |
||||
flowUrlPrefix + "/flowOperation/freeJumpTo", |
||||
flowUrlPrefix + "/flowOnlineOperation/startPreview", |
||||
flowUrlPrefix + "/flowOnlineOperation/viewUserTask", |
||||
flowUrlPrefix + "/flowOnlineOperation/viewHistoricProcessInstance", |
||||
flowUrlPrefix + "/flowOnlineOperation/submitUserTask", |
||||
flowUrlPrefix + "/flowOnlineOperation/upload", |
||||
flowUrlPrefix + "/flowOnlineOperation/download", |
||||
flowUrlPrefix + "/flowOperation/submitConsign", |
||||
flowUrlPrefix + "/flowOnlineOperation/startAndTakeUserTask/" + flowEntry.getProcessDefinitionKey(), |
||||
flowUrlPrefix + "/flowOnlineOperation/startAndSaveDraft/" + flowEntry.getProcessDefinitionKey(), |
||||
flowUrlPrefix + "/flowOnlineOperation/listWorkOrder/" + flowEntry.getProcessDefinitionKey(), |
||||
flowUrlPrefix + "/flowOnlineOperation/printWorkOrder/" + flowEntry.getProcessDefinitionKey() |
||||
); |
||||
permData.put("permList", permList); |
||||
permDataList.add(permData); |
||||
} |
||||
return permDataList; |
||||
} |
||||
|
||||
// @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
|
||||
// public void bulkHandleBusinessData(TransactionalFlowBusinessData businessData) {
|
||||
// try {
|
||||
// this.doHandle(businessData);
|
||||
// // 这里会切换回原有的在线表单表所在的数据库上线文。
|
||||
// flowTransProducerMapper.deleteById(businessData.getTransId());
|
||||
// } catch (Exception e) {
|
||||
// log.error("Failed to commit online business data [** " + JSON.toJSONString(businessData) + " **]", e);
|
||||
// FlowTransProducer transProducer = flowTransProducerMapper.selectById(businessData.getTransId());
|
||||
// transProducer.setErrorReason(e.getMessage());
|
||||
// flowTransProducerMapper.updateById(transProducer);
|
||||
// businessData.setErrorReason(e.getMessage());
|
||||
// throw new OnlineRuntimeException(e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
private void doHandle(TransactionalFlowBusinessData businessData) throws Exception { |
||||
Connection conn = null; |
||||
try { |
||||
conn = dataSourceUtil.getConnection(businessData.getDblinkId()); |
||||
conn.setAutoCommit(false); |
||||
for (TransactionalBusinessData.BusinessSqlData s : businessData.getSqlDataList()) { |
||||
List<Object> paramList = null; |
||||
if (CollUtil.isNotEmpty(s.getColumnValueList())) { |
||||
paramList = s.getColumnValueList().stream().map(Object.class::cast).collect(Collectors.toList()); |
||||
} |
||||
dataSourceUtil.execute(conn, s.getSql(), paramList); |
||||
} |
||||
this.insertFlowConsumerTrans(conn, businessData); |
||||
conn.commit(); |
||||
} catch (Exception e) { |
||||
if (conn != null) { |
||||
conn.rollback(); |
||||
} |
||||
log.error(e.getMessage(), e); |
||||
throw new OnlineRuntimeException(e.getMessage()); |
||||
} finally { |
||||
if (conn != null) { |
||||
conn.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void insertFlowConsumerTrans(Connection conn, TransactionalFlowBusinessData businessData) { |
||||
DataSourceProvider provider = dataSourceUtil.getProvider(businessData.getDblinkId()); |
||||
Long transId = businessData.getTransId(); |
||||
String sql = "INSERT INTO zz_flow_trans_consumer VALUES(?,?)"; |
||||
if (provider instanceof PostgreSqlProvider) { |
||||
dataSourceUtil.execute(conn, sql, CollUtil.newArrayList(transId, new java.sql.Date(System.currentTimeMillis()))); |
||||
} else { |
||||
dataSourceUtil.execute(conn, sql, CollUtil.newArrayList(transId, new Date())); |
||||
} |
||||
} |
||||
|
||||
private void updateMasterData(OnlineTable masterTable, JSONObject masterData, String dataId) { |
||||
if (masterData == null) { |
||||
return; |
||||
} |
||||
// 如果存在主表数据,就执行主表数据的更新。
|
||||
Map<String, Object> originalMasterData = |
||||
onlineOperationService.getMasterData(masterTable, null, null, dataId); |
||||
for (Map.Entry<String, Object> entry : originalMasterData.entrySet()) { |
||||
masterData.putIfAbsent(entry.getKey(), entry.getValue()); |
||||
} |
||||
if (!onlineOperationService.update(masterTable, masterData)) { |
||||
throw new FlowOperationException("主表数据不存在!"); |
||||
} |
||||
} |
||||
|
||||
private Map<String, List<JSONObject>> normailizeSlaveDataListMap( |
||||
Map<OnlineDatasourceRelation, List<JSONObject>> slaveDataListMap) { |
||||
if (slaveDataListMap == null || slaveDataListMap.size() == 0) { |
||||
return null; |
||||
} |
||||
Map<String, List<JSONObject>> resultMap = new HashMap<>(slaveDataListMap.size()); |
||||
for (Map.Entry<OnlineDatasourceRelation, List<JSONObject>> entry : slaveDataListMap.entrySet()) { |
||||
resultMap.put(entry.getKey().getSlaveTable().getTableName(), entry.getValue()); |
||||
} |
||||
return resultMap; |
||||
} |
||||
} |
||||
@ -1,2 +0,0 @@
@@ -1,2 +0,0 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
||||
apelet.common.flow.online.config.FlowOnlineAutoConfig |
||||
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
package apelet.common.online.util; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public class WidgetFieldTypeMapping { |
||||
|
||||
private WidgetFieldTypeMapping() { |
||||
} |
||||
|
||||
private static final Map<Integer, String> WIDGET_TO_FIELD_TYPE = new HashMap<>(); |
||||
private static final Map<Integer, Integer> DEFAULT_LENGTH = new HashMap<>(); |
||||
|
||||
static { |
||||
// 文本输入框 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(1, "0"); |
||||
DEFAULT_LENGTH.put(1, 255); |
||||
// 数字输入框 → int
|
||||
WIDGET_TO_FIELD_TYPE.put(3, "1"); |
||||
// 开关组件 → int
|
||||
WIDGET_TO_FIELD_TYPE.put(5, "1"); |
||||
// 滑块组件 → decimal
|
||||
WIDGET_TO_FIELD_TYPE.put(6, "4"); |
||||
// 单选组件 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(7, "0"); |
||||
DEFAULT_LENGTH.put(7, 255); |
||||
// 复选框 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(8, "0"); |
||||
DEFAULT_LENGTH.put(8, 255); |
||||
// 下拉选择框 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(10, "0"); |
||||
DEFAULT_LENGTH.put(10, 255); |
||||
// 级联选择框 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(12, "0"); |
||||
DEFAULT_LENGTH.put(12, 255); |
||||
// 树形选择 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(13, "0"); |
||||
DEFAULT_LENGTH.put(13, 255); |
||||
// 评分组件 → int
|
||||
WIDGET_TO_FIELD_TYPE.put(14, "1"); |
||||
DEFAULT_LENGTH.put(14, 5); |
||||
// 日期选择框 → datetime
|
||||
WIDGET_TO_FIELD_TYPE.put(20, "3"); |
||||
// 颜色选择 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(30, "0"); |
||||
DEFAULT_LENGTH.put(30, 50); |
||||
// 附件上传 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(31, "0"); |
||||
DEFAULT_LENGTH.put(31, 255); |
||||
// 图片上传 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(653, "0"); |
||||
DEFAULT_LENGTH.put(653, 255); |
||||
// 富文本编辑 → varchar(2000)
|
||||
WIDGET_TO_FIELD_TYPE.put(32, "0"); |
||||
DEFAULT_LENGTH.put(32, 2000); |
||||
// MD编辑器 → varchar(2000)
|
||||
WIDGET_TO_FIELD_TYPE.put(760, "0"); |
||||
DEFAULT_LENGTH.put(760, 2000); |
||||
// 用户选择 → bigint
|
||||
WIDGET_TO_FIELD_TYPE.put(400, "2"); |
||||
// 部门选择 → bigint
|
||||
WIDGET_TO_FIELD_TYPE.put(401, "2"); |
||||
// 关联选择 → bigint
|
||||
WIDGET_TO_FIELD_TYPE.put(402, "2"); |
||||
// 时间选择器 → datetime
|
||||
WIDGET_TO_FIELD_TYPE.put(652, "3"); |
||||
// 文件上传 → varchar
|
||||
WIDGET_TO_FIELD_TYPE.put(750, "0"); |
||||
DEFAULT_LENGTH.put(750, 255); |
||||
} |
||||
|
||||
public static String getFieldTypeId(Integer widgetType) { |
||||
String type = WIDGET_TO_FIELD_TYPE.get(widgetType); |
||||
if (type == null) { |
||||
throw new IllegalArgumentException("不支持的控件类型: " + widgetType); |
||||
} |
||||
return type; |
||||
} |
||||
|
||||
public static Integer getDefaultLength(Integer widgetType) { |
||||
return DEFAULT_LENGTH.get(widgetType); |
||||
} |
||||
|
||||
public static boolean isDataWidget(Integer widgetType) { |
||||
return WIDGET_TO_FIELD_TYPE.containsKey(widgetType); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue