实用指南:工作流引擎-16-开源审批流项目之 整合Flowable官方的Rest包

news/2025/10/5 16:27:59/文章来源:https://www.cnblogs.com/lxjshuju/p/19126687

工作流引擎系列

工作流引擎-00-流程引擎概览

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

工作流引擎-02-BPM OA ERP 区别和联系

工作流引擎-03-聊一聊流程引擎

工作流引擎-04-流程引擎 activiti 优秀开源项目

工作流引擎-05-流程引擎 Camunda 8 协调跨人、系统和设备的复杂业务流程

工作流引擎-06-流程引擎 Flowable、Activiti 与 Camunda 全维度对比分析

工作流引擎-07-流程引擎 flowable-engine 入门介绍

工作流引擎-08-流程引擎 flowable-engine 优秀开源项目

工作流引擎-09-XState 是一个 JavaScript 和 TypeScript 的状态管理库,它使用状态机和状态图来建模逻辑

工作流引擎-10-什么是 BPM?

工作流引擎-11-开源 BPM 项目 jbpm

工作流引擎-12-开源 BPM 项目 foxbpm

工作流引擎-13-开源 BPM 项目 UFLO2

工作流引擎-14-开源审批流项目之 RuoYi-vue + flowable 6.7.2 的工作流管理

工作流引擎-15-开源审批流项目之 RuoYi-Vue-Plus 进行二次开发扩展Flowable工作流功能

工作流引擎-16-开源审批流项目之 整合Flowable官方的Rest包

工作流引擎-17-开源审批流项目之 flowable workflow designer based on vue and bpmn.io

工作流引擎-18-开源审批流项目之 plumdo-work 工作流,表单,报表结合的多模块系统

flowable-ui

经过两周左右时间的学习,Flowable基础知识自认为学习完毕,简单构思设计之后,开始上手实践了。

由于Flowable官方已经提供了丰富的REST包(和Activiti差不多),基本功能已经满足我们的要求了,个别接口不适用的可自行重写稍作调整即可。

Flowable官方提供的五个war包

starter描述在线体验
flowable-modeler让具有建模权限的用户可以创建流程模型、表单、选择表与应用定义。https://t.cn/A6cjNwAj
flowable-idm身份管理应用。为所有Flowable UI应用提供单点登录认证功能,并且为拥有IDM管理员权限的用户提供了管理用户、组与权限的功能。https://t.cn/A6cjCFHc
flowable-task运行时任务应用。提供了启动流程实例、编辑任务表单、完成任务,以及查询流程实例与任务的功能。https://t.cn/A6cjNLWv
flowable-admin管理应用。让具有管理员权限的用户可以查询BPMN、DMN、Form及Content引擎,并提供了许多选项用于修改流程实例、任务、作业等。管理应用通过REST API连接至引擎,并与Flowable Task应用及Flowable REST应用一同部署。https://t.cn/A6cjN4uq
flowable-restFlowable页面包含的常用REST API

在线体验账号:admin/123 (个人服务器,配置较低,仅供体验,请勿对应用进行压测)

先访问idm,使用体验账号登录后,再去访问modeler,task,admin其他模块

以官方提供的war包为基准,集成以上四个默认页面对应的REST接口。

开始集成

后端集成
  • maven
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-rest</artifactId>
<version>${flowable.version}</version>
</dependency>
<!-- flowable UI集成 --><dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-modeler-conf</artifactId><version>${flowable.version}</version></dependency><dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-task-conf</artifactId><version>${flowable.version}</version></dependency><dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-admin-conf</artifactId><version>${flowable.version}</version></dependency><dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-idm-conf</artifactId><version>${flowable.version}</version></dependency>
  • gradle
compile group: 'org.flowable'
, name: 'flowable-spring-boot-starter-rest'
, version:'6.4.1'
compile group: 'org.flowable'
, name: 'flowable-ui-modeler-conf'
, version:'6.4.1'
compile group: 'org.flowable'
, name: 'flowable-ui-task-conf'
, version:'6.4.1'
compile group: 'org.flowable'
, name: 'flowable-ui-admin-conf'
, version:'6.4.1'
compile group: 'org.flowable'
, name: 'flowable-ui-idm-conf'
, version:'6.4.1'

注:

flowable-ui-xxx-conf: UI独立于业务外的配置
flowable-ui-xxx-logic: UI的业务逻辑
flowable-ui-xxx-rest: 提供常用的操作REST API

以上就是集成Flowable UI的基础包了。

由于flowable-ui-xxx-conf中包中,每个中都有对应自己的如ApplicationConfiguration等配置类,所以如果用默认配置会出现

conflicts with existing, non-compatible bean definition of same name and class

类似的错误信息,提示在Spring容器中存在两个相同名称的Bean。

所以不能使用默认的配置类,只能自己去编写配置类,完成flowable-ui-xxx-conf的配置。

  • AppDispatcherServletConfiguration
@Configuration
@ComponentScan
(value = {
"org.flowable.ui.admin.rest"
,
"org.flowable.ui.task.rest.runtime"
,
"org.flowable.ui.idm.rest.app"
,
"org.flowable.ui.common.rest.exception"
,
"org.flowable.ui.modeler.rest.app"
,
"org.flowable.ui.common.rest"
}
,
excludeFilters = {
@ComponentScan.Filter
(type = FilterType.ASSIGNABLE_TYPE
, value = RemoteAccountResource.
class
)
,
@ComponentScan.Filter
(type = FilterType.ASSIGNABLE_TYPE
, value = StencilSetResource.
class
)
,
@ComponentScan.Filter
(type = FilterType.ASSIGNABLE_TYPE
, value = EditorUsersResource.
class
)
,
@ComponentScan.Filter
(type = FilterType.ASSIGNABLE_TYPE
, value = EditorGroupsResource.
class
)
}
)
@EnableAsync
public
class AppDispatcherServletConfiguration
implements WebMvcRegistrations
// 下面类内容省略,可参考org.flowable.ui.xxx.servlet.AppDispatcherServletConfiguration类

注: 通过StencilSetResource类汉化流程设计器(其实没必要重写类,只需要将stencilset_bpmn.json文件内容汉化即可,重写的目的是以后可以通过此处兼容国际化)

  • ApplicationConfiguration
@Configuration
@EnableConfigurationProperties
({
FlowableIdmAppProperties.
class
, FlowableModelerAppProperties.
class
, FlowableAdminAppProperties.
class
}
)
@ComponentScan
(
basePackages = {
"org.flowable.ui.admin.repository"
,
"org.flowable.ui.admin.service"
,
"org.flowable.ui.task.model.component"
,
"org.flowable.ui.task.service.runtime"
,
"org.flowable.ui.task.service.debugger"
,
"org.flowable.ui.idm.conf"
,
"org.flowable.ui.idm.security"
,
"org.flowable.ui.idm.service"
,
"org.flowable.ui.modeler.repository"
,
"org.flowable.ui.modeler.service"
,
"org.flowable.ui.common.filter"
,
"org.flowable.ui.common.service"
,
"org.flowable.ui.common.repository"
,
"org.flowable.ui.common.security"
,
"org.flowable.ui.common.tenant"
}
,
excludeFilters = {
@ComponentScan.Filter
(type = FilterType.ASSIGNABLE_TYPE
, value = org.flowable.ui.idm.conf.ApplicationConfiguration.
class
)
}
)

注: 通过@ComponentScan注解,扫描需要的包及其接口。

  • DatabaseConfiguration
/**
* 重写flowable-ui-xxx-conf 中的 DatabaseConfiguration 类,
* 包括:flowable-ui-modeler-conf和flowable-ui-admin-conf 的DatabaseConfiguration
*/
@Configuration
@EnableTransactionManagement
public
class DatabaseConfiguration {
private
static
final Logger LOGGER = LoggerFactory.getLogger(DatabaseConfiguration.
class
)
;
@Bean
public Liquibase modelerLiquibase(DataSource dataSource) {
Liquibase liquibase =
null
;
try {
DatabaseConnection connection =
new JdbcConnection(dataSource.getConnection(
)
)
;
Database database = DatabaseFactory.getInstance(
).findCorrectDatabaseImplementation(connection)
;
database.setDatabaseChangeLogTableName("ACT_DE_" + database.getDatabaseChangeLogTableName(
)
)
;
database.setDatabaseChangeLogLockTableName("ACT_DE_" + database.getDatabaseChangeLogLockTableName(
)
)
;
liquibase =
new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml"
,
new ClassLoaderResourceAccessor(
)
, database)
;
liquibase.update("flowable"
)
;
return liquibase;
}
catch (Exception e) {
throw
new InternalServerErrorException("Error creating liquibase database"
, e)
;
}
finally {
closeDatabase(liquibase)
;
}
}
@Bean
public Liquibase adminLiquibase(DataSource dataSource) {
LOGGER.debug("Configuring Liquibase"
)
;
Liquibase liquibase =
null
;
try {
DatabaseConnection connection =
new JdbcConnection(dataSource.getConnection(
)
)
;
Database database = DatabaseFactory.getInstance(
).findCorrectDatabaseImplementation(connection)
;
database.setDatabaseChangeLogTableName("ACT_ADM_" + database.getDatabaseChangeLogTableName(
)
)
;
database.setDatabaseChangeLogLockTableName("ACT_ADM_" + database.getDatabaseChangeLogLockTableName(
)
)
;
liquibase =
new Liquibase("META-INF/liquibase/flowable-admin-app-db-changelog.xml"
,
new ClassLoaderResourceAccessor(
)
, database)
;
liquibase.update("flowable"
)
;
return liquibase;
}
catch (Exception e) {
throw
new InternalServerErrorException("Error creating liquibase database"
)
;
}
finally {
closeDatabase(liquibase)
;
}
}
private
void closeDatabase(Liquibase liquibase) {
if (liquibase !=
null
) {
Database database = liquibase.getDatabase(
)
;
if (database !=
null
) {
try {
database.close(
)
;
}
catch (DatabaseException e) {
LOGGER.warn("Error closing database"
, e)
;
}
}
}
}
}

注: 创建Modeler的模型存储表和Admin首页的服务配置表。

  • TaskUserCacheImpl
/**
* 重写 {@link org.flowable.ui.task.service.idm.UserCacheImpl} 类,避免启动时和 {@link org.flowable.ui.idm.service.UserCacheImpl} 命名冲突
* Cache containing User objects to prevent too much DB-traffic (users exist separately from the Flowable tables, they need to be fetched afterward one by one to join with those entities).
* <p>
*
* @author Frederik Heremans
* @author Joram Barrez
* @author Filip Hrisafov
*/
@Service
public
class TaskUserCacheImpl
implements UserCache

注: 重写 {@link org.flowable.ui.task.service.idm.UserCacheImpl} 类,避免启动时和 {@link org.flowable.ui.idm.service.UserCacheImpl} 命名冲突

  • org.flowable.ui.admin.service.engine.CmmnTaskService
package org.flowable.ui.admin.service.engine
;
/**
* 覆盖jar包中的CmmnTaskService的定义,修改Bean的定义名称,避免和org.flowable.cmmn.api.CmmnTaskService命名冲突
* Service for invoking Flowable REST services.
*/
@Service
("adminCmmnTaskService"
)
public
class CmmnTaskService

由于flowable官方提供的jar包导致的冲突问题解决完毕之后,以下是application.yml中需要对Flowable做的配置,其他如数据源相关配置省略,此处不再累述。

flowable:
labelFontName: 宋体
activityFontName: 宋体
annotationFontName: 宋体
rest:
app:
authentication-mode: verify-privilege
process:
definition-cache-limit: 1
idm:
app:
admin:
password: test
user-id: admin
first-name: admin
last-name: admin
common:
app:
role-prefix:
idm-url: http://localhost:${
server.port
}/${
spring.application.name
}/idm
xml:
encoding: UTF-8
modeler:
app:
rest-enabled: true
admin:
app:
security:
encryption:
credentials-secret-spec: 9FGl73ngxcOoJvmL
credentials-i-v-spec: j8kdO2hejA9lKmm6
server-config:
app:
context-root: ${
spring.application.name
}
password: test
server-address: http://localhost
user-name: admin
port: ${
server.port
}
rest-root: app-api
name: Flowable App app
description: Flowable App REST config
process:
context-root: ${
spring.application.name
}
server-address: http://localhost
password: test
user-name: admin
rest-root: process-api
port: ${
server.port
}
name: Flowable Process app
description: Flowable Process REST config
form:
context-root: ${
spring.application.name
}
server-address: http://localhost
password: test
user-name: admin
port: ${
server.port
}
rest-root: form-api
name: Flowable Form app
description: Flowable Form REST config
dmn:
context-root: ${
spring.application.name
}
server-address: http://localhost
password: test
user-name: admin
port: ${
server.port
}
rest-root: dmn-api
name: Flowable DMN app
description: Flowable DMN REST config
cmmn:
context-root: ${
spring.application.name
}
password: test
server-address: http://localhost
user-name: admin
port: ${
server.port
}
rest-root: cmmn-api
name: Flowable CMMN app
description: Flowable CMMN REST config
content:
context-root: ${
spring.application.name
}
server-address: http://localhost
password: test
user-name: admin
rest-root: content-api
port: ${
server.port
}
name: Flowable Content app
description: Flowable Content REST config
database-schema-update: true
management:
endpoint:
health:
roles: access-admin
show-details: when_authorized
endpoints:
jmx:
unique-names: true
# MyBatis配置比较重要,手动去扫描Flowable默认的Mapper.xml,以及设置字段类型
mybatis:
mapper-locations:
- classpath:/META-INF/admin-mybatis-mappings/*.xml
- classpath:/META-INF/modeler-mybatis-mappings/*.xml
configuration-properties:
prefix:
boolValue: TRUE
blobType: BLOB

至此后端集成完毕。

集成思路出现偏差

一开始准备将官方提供的页面集成到后端工程来,但是由于modeler页面我是直接放到static目录下的,而其他三个页面只能自己建目录存放(idm, admin, task),导致访问modeler时是以后端项目请求路径为根访问路径的,在modeler请求后端接口时,请求路径没有问题;可访问idm、admin、task时,则必须加上idm/路径,导致请求后端接口时,不管将前端请求后端的路径改为相对路径还是绝对路径,最终请求路径都存在问题。此处花费时间较多。下面会讲讲新的页面集成方式。

Flowable与SpringBoot版本坑

flowable-ui-modeler-confAppDispatcherServletConfiguration配置类,实现了WebMvcRegistrations接口,SpringBoot1.x中,WebMvcRegistrations在spring-boot-autoconfigure中的web包下,而在SpringBoot2.x中,WebMvcRegistrations被移到web.servlet下了,所以在使用默认类时,SpringBoot版本必须是2.x。

Flowable官方包冲突

由于是根据flowable-modeler、flowable-idm、flowable-task、flowable-admin来集成的,所以后端基础包也是需要这对应的四个,故直接集成了flowable-ui-modeler-conf、flowable-ui-idm-conf、flowable-ui-task-conf、flowable-ui-admin-conf,但是由于这四个包中存在各自的自动配置类,而且在modeler和admin中,自动配置类又和他自己的业务逻辑有关联,而且存在多个类命名相同的Spring Bean,导致Spring上下文由于出现相同名称的Bean而初始化失败,但是默认配置有些又不能不用,最终的解决办法就是去除原来所有的默认配置,将冲突的通过@ComponentScan的excludeFilters属性移除掉,然后自己去自定义配置。

登录权限问题

flowable-ui-modeler-conf、flowable-ui-idm-conf、flowable-ui-task-conf、flowable-ui-admin-conf这四个包中都存在SecurityConfiguration配置类,顾名思义是安全配置,但是在集成的过程中,modeler-conf其实我们希望的是以idm的登录为主,其他模块自己的安全校验配置不需要,但是实际上由于其他模块存在安全配置以及默认的拦截器,导致idm自己的安全验证不能通过。解决方式和上面一样,通过包扫描路径,只扫描自己需要的包路径,而有影响的包要么移除掉,要么自己去实现其中的配置。

页面集成

页面集成一开始采用的是集成到后端工程,以后开发自己的页面时,也可直接调用集成好的流程设计器,但是由于其他模块的页面存在问题,故暂时放弃掉这种集成方式,采用Nginx来部署前端,正好满足前后端分离架构。

server {listen 8081;server_name flowable_ui;location / {root /user/local/nginx/flowable-ui;index index.html index.htm;}location /flowable_idm {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_idm;}location /flowable_task {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_task;}location /flowable_admin {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_admin;}location /flowable_modeler {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_modeler;}
}

注: 其实可以通过Nginx将静态资源和动态资源分开解析处理即可,但是我这边尝试的过程中有问题,只能采用简单粗暴的方式了。

然后在flowable-ui目录下新建modeler、idm、task、admin目录,将flowable-modeler.war、flowable-idm.war、flowable-task.war、flowable-admin.war中的flowable-xxx/WEB-INF/classes/static下的内容分别复制到对应目录下,此时通过http://localhost:8086/modeler…可看到对应的页面,但是由于动静资源路径一致,导致请求不能转发到后端,所以需要对动态请求和静态资源请求做区分,则需要修改官方页面源码,增加统一的请求路径前缀。

flowable-ui

统一请求路径修改:

在modeler/scripts/app-cfg.js文件中,修改contextRoot为flowable_modeler,与静态资源访问路径区分开。

'use strict'
;
var FLOWABLE = FLOWABLE || {
}
;
var pathname = window.location.pathname.replace(/^(\/[^\/]*)(\/.*)?$/
, '$1'
).replace(/\/$/
, ''
)
;
FLOWABLE.CONFIG = {
'onPremise' : true
,
'contextRoot' : "/flowable_modeler"
,
'webContextRoot' : pathname,
'datesLocalization' : false
}
;

在idm/scripts/app-cfg.js文件中,修改contextRoot为flowable_idm,与静态资源访问路径区分开。

'use strict'
;
var FLOWABLE = FLOWABLE || {
}
;
var pathname = window.location.pathname.replace(/^(\/[^\/]*)(\/.*)?$/
, '$1'
).replace(/\/$/
, ''
)
;
FLOWABLE.CONFIG = {
'onPremise' : true
,
'contextRoot' : "/flowable_idm"
,
'webContextRoot' : pathname,
'datesLocalization' : false
}
;

在task/scripts/app-cfg.js文件中,修改contextRoot为flowable_task,与静态资源访问路径区分开。

'use strict'
;
var FLOWABLE = FLOWABLE || {
}
;
var pathname = window.location.pathname.replace(/^(\/[^\/]*)(\/.*)?$/
, '$1'
).replace(/\/$/
, ''
)
;
FLOWABLE.CONFIG = {
'onPremise' : true
,
'contextRoot' : "/flowable_task"
,
'webContextRoot' : pathname,
'datesLocalization' : false
}
;

admin和其他的不一样,所以我作为一个后端人员修改前端,采取的方式是在admin/scripts/config.js文件中,增加上面类似配置。

FlowableAdmin.webContextRoot = '/flowable_admin'
;

然后通过开发工具,给所有的REST请求的增加FlowableAdmin.webContextRoot + 前缀。

如:

url: '/app/

替换为

url: FlowableAdmin.webContextRoot + '/app/

其他非这种格式的URL,可自行手动修改。

至此前后端基本集成完毕。

执行后端SpringBoot启动类,启动后端服务。

启动Nginx。

此时通过以下四个链接,即可访问Flowable官方提供的四个操作页面,不过在第一次访问时,由于没有登录,会跳转到登录页面,在后端工程初次启动时,会初始化两个账号,可通过ACT_ID_USER表查询用户名密码。

http://localhost:8081/idm/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高密哪里做网站好许昌建设网站哪家好

使用python爬虫实现百度翻译功能 python爬虫实现百度翻译&#xff1a; python解释器【模拟浏览器】&#xff0c;发送【post请求】&#xff0c;传入待【翻译的内容】作为参数&#xff0c;获取【百度翻译的结果】 通过开发者工具&#xff0c;获取发送请求的地址 提示&#xff1a;…

网站推广论坛网络营销策划

自定义取出第几个分割字符前的字符串&#xff0c;默认位置&#xff08;0&#xff09;格式&#xff1a;dbo.split(字段名,分隔字符,取出的第几个字符串)如果没有分隔的字符&#xff0c;则返回整个字符串。如果取出的位置字符串的位置超出Index则返回空。CREATE FUNCTION [dbo].[…

开网站要多少钱中国铁道建设协会网站

图像的灰度处理的三种方法&#xff1a; 1.imread的方法将像素值修改为0 2.调用一个RGB转灰度的方法实现灰度转化&#xff08;cv2.COLOR_BGR2GRAY&#xff09; 3.R G B 的均值取灰度值来灰度转化&#xff08;原理&#xff09; 处理结果 如下: 转载于:https://www.cnblogs.com/Ja…

个人建网站步骤wordpress+订单号位数

目录 单词搜索&#xff08;搜索&#xff09; 题目解析 讲解算法原理 编写代码 杨辉三⻆&#xff08;动态规划&#xff09; 题目解析 讲解算法原理 编写代码 单词搜索&#xff08;搜索&#xff09; 题目解析 1.题目链接&#xff1a;单词搜索_牛客题霸_牛客网 2.题目描…

25fall做题记录-October - Amy

2025.10.5 Sale n,m=map(int,input().split()) a=list(map(int,input().split())) a.sort() s=0 for i in range(len(a)):if(a[i]<0 and i+1<=m):s-=a[i]if(a[i]>=0):break print(s)Maya Calendar 这题很难评…

嗯嗯

https://www.luogu.com.cn/problem/CF1874F 考虑容斥。发现当 \([l_1,r_1]\) 和 \([l_2,r_2]\) 有交且不包含,且均为坏区间时,\([l_1,l_2-1]\) 也是坏区间。所以在容斥时,只要钦定了 \([l_1,r_1]\) 和 \([l_2,r_2]\…

什么网站可以接单做设计方案外贸公司怎么做网站

本节书摘来华章计算机《深入理解Elasticsearch&#xff08;原书第2版&#xff09;》一书中的第2章 &#xff0c;第2.3.3节&#xff0c;[美]拉斐尔酷奇&#xff08;Rafal Ku&#xff09; 马雷克罗戈任斯基&#xff08;Marek Rogoziski&#xff09;著 张世武 余洪淼 商旦 译 …

完整教程:HTTPS

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

桂林市中考信息网官网苏州市优化网站推广哪家好

Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius&#xff0c;Kotlin 这里 Android挖取原图中心区域RectF(并框线标记)放大到ImageView宽高&#xff0c;Kotlin-CSDN博客 实现的是把原图中心区域的一片小图挖取出来放大放到下面的ImageView里面…

PCIe扫盲——AckNak 机制详解(二)

这一篇文章来简单地分析几个Ack/Nak机制的例子。 Example 1. Example of AckStep1 设备A准备依次向设备B发送5个TLP,其对应的序列号分别为3,4,5,6,7; Step2 设备B成功的接收到了TLP3,并将NEXT_RCV_SEQ从3加到4,但…

万宁网站建设公司360网站收录提交入口

1)对于.ziplinux下提供了zip和unzip程序&#xff0c;zip是压缩程序&#xff0c;unzip是解压程序。它们的参数选项很多&#xff0c;可用命令zip -help和unzip -help查看&#xff0c;这里只做简单介绍&#xff0c;举例说明一下其用法&#xff1a;# zip test.zip test.jpg test.pn…

2025桩基检测机构最新企业咨询服务推荐排行榜,海上桩基检测,水上桩基检测服务推荐这十家公司!

在建筑工程领域,桩基作为建筑物的基础支撑,其质量直接关系到整个工程的安全稳定性与使用寿命。随着我国建筑业的持续发展,桩基检测需求日益增长,但行业内也逐渐暴露出诸多问题。部分检测机构技术水平不足,缺乏先进…

算法坑点

后续补充完善点双连通分量缩点后建的新图点的数量会增加,如果原图是一条链的话每个点双开个新点,加上割点,总点数要开两倍; 无向基环树用拓扑剥叶子的时候,记得防止剥父亲节点的出度void topsort(){queue<int&…

完整教程:56、Ocelot 概述

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

互联网招聘网站排行网络广告网站怎么做

单元测试(Unit Testing):单元测试是一种软件测试方法,用于验证软件中最小的可测试单元(通常是函数或方法)是否按照预期工作。它通过编写测试用例来检查单元的输入和输出,以确保其功能正确性和稳定性。用例图(Use Case Diagram):用例图是一种UML(统一建模语言)图表,…

Windows系统安装MySQL Connector 利用C++ VS2022连接MySQL

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

ASP.NET Core SignalR 身份认证集成指南(Identity + JWT) - 详解

ASP.NET Core SignalR 身份认证集成指南(Identity + JWT) - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "…

utorrent 2.2.1

http://www.oldversion.com/windows/utorrent/ http://www.oldversion.com/windows/utorrent-2-2-1-build-25273-1 怎么下载?

青岛建站公司电话郑州网站建设公司电话多少

摘要&#xff1a;12个C语言面试题&#xff0c;涉及指针、进程、运算、结构体、函数、内存&#xff0c;看看你能做出几个&#xff01; 1.gets()函数 问&#xff1a;请找出下面代码里的问题&#xff1a; #include<stdio.h> int main(void) { char buff[10]; memset…

市场交易反心理特征之八:劣仓驱逐良仓

核心总结:“劣仓驱逐良仓”的问题其实很好解决,两个方面其一是要首先做到遵守信号,是否出现阴线?砖型图是否翻绿?如果没有就踏踏实实的拿着。其二,在持有期间,是否出现了大幅拉升?拉升后是否减仓了?主动减仓后…