当前位置: 首页 > news >正文

Flowable7.x学习笔记(二十一)查看我的发起

前言

        “查看我的发起”功能,就是将当前用户作为流程发起人启动的所有流程实例集中展示,帮助用户随时跟踪自己提交的业务请求的状态与历史,提升透明度与可控性。

        业务人员通常不知道流程引擎底层如何运转,只关心“我提交的报销/申请到了哪一步”,该功能就能满足业务人员不再需反复向审批人或管理员打听流程状态,系统自助查询即可,未来可在该视图上附加流程重启、批量操作、AI 预测审批结果等高级功能,具备良好的扩展性。

一、后端服务搭建

① 定义请求参数

        在实际查询过程中,可以从系统的认证信息中获取当前业务员信息,就只要传递分页的信息即可。

package com.ceair.entity.request;import lombok.Data;import java.io.Serial;
import java.io.Serializable;/*** @author wangbaohai* @ClassName PageReq* @description: 分页请求参数* @date 2025年02月16日* @version: 1.0.0*/
@Data
public class PageReq implements Serializable {@Serialprivate static final long serialVersionUID = 1L;/*** 分页查询的页码和每页大小。** pageNo: 当前页码,默认为1。* pageSize: 每页显示的记录数,默认为10。*/private Long current = 1L;private Long size = 10L;}

② 定义响应参数

        查询结束之后,我们需要考虑的是到底要传递哪些信息以供前端展示,目前只定义了发起人/流程定义/节点时间等信息,可以自行扩展。

package com.ceair.entity.vo;import lombok.Data;import java.io.Serial;
import java.io.Serializable;
import java.util.List;/*** @author wangbaohai* @ClassName MyStartTaskListInfoVO* @description: 我发起的流程任务清单VO* @date 2025年05月07日* @version: 1.0.0*/
@Data
public class MyStartTaskListInfoVO implements Serializable {@Serialprivate static final long serialVersionUID = 1L;// 我的发起流程任务清单private List<MyStartTaskVO> myStartTaskList;// 我的发起流程任务总数private Long myStartTaskCount;}
package com.ceair.entity.vo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;/*** @author wangbaohai* @ClassName MyStartTaskVO* @description: 我发起的流程任务VO* @date 2025年05月07日* @version: 1.0.0*/
@Data
public class MyStartTaskVO implements Serializable {@Serialprivate static final long serialVersionUID = 1L;// 流程定义IDprivate String processDefinitionId;// 流程定义名称private String processDefinitionName;// 流程实例IDprivate String processInstanceId;// 发起人名称private String startUserName;// 发起时间@DateTimeFormat(pattern = "yyyy-MM-dd")@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")private LocalDateTime startTime;// 结束时间@DateTimeFormat(pattern = "yyyy-MM-dd")@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")private LocalDateTime endTime;// 审批状态(0:审批中 1:审批通过  2:审批拒绝)private Integer status;// 审批备注private String comment;}

③ 定义服务接口

/*** 查询我发起的任务列表信息* <p>* 该方法用于获取用户发起的任务列表,根据分页请求进行数据检索* 主要解决了用户需要查看自己发起的所有任务的需求** @param pageReq 分页请求对象,包含分页查询的必要信息,如当前页码、每页大小等* @return 返回一个对象,其中包含查询到的任务列表信息以及相关的分页细节*/
MyStartTaskListInfoVO queryMyStartTaskList(PageReq pageReq);

④ 实现服务接口

(1)初始化与分页参数校验

        初始化 VO:用于最终封装返回结果。

        空值校验:若 pageReq 为 null,记录日志并抛出 IllegalArgumentException。

        默认值设置:确保 current >= 1、size >= 1,否则分别设为 1 和 10。

// 初始化返回 VO
MyStartTaskListInfoVO myStartTaskListInfoVO = new MyStartTaskListInfoVO();// 分页信息判空
if (pageReq == null) {log.error("查询我的已启动任务列表失败,原因:分页信息不能为空");throw new IllegalArgumentException("查询我的已启动任务列表失败,原因:分页信息不能为空");
}// 获取当前页与页大小,默认 1 页,每页 10 条
long current = (Objects.nonNull(pageReq.getCurrent()) && pageReq.getCurrent() > 0)? pageReq.getCurrent() : 1L;
long size = (Objects.nonNull(pageReq.getSize()) && pageReq.getSize() > 0)? pageReq.getSize() : 10L;

(2)获取当前登录用户

        从自定义工具 userInfoUtils 获取当前认证用户信息,自定义工具是脚手架中提供的获取认证信息中的登陆人信息的,与本文无关代码没贴出来,可以在文末的代码仓库中找到完整代码。

        若返回 null,表示未登录,抛出业务异常。

UserInfo userInfo = userInfoUtils.getUserInfoFromAuthentication();
if (userInfo == null) {log.error("查询我的已启动任务列表失败,原因:用户未登录");throw new BusinessException("查询我的已启动任务列表失败,原因:用户未登录");
}

(3)查询历史流程实例并分页

        构造查询条件:startedBy(...):只查询当前用户启动的实例。
        orderByProcessInstanceStartTime().desc():按启动时间倒序。
        执行分页listPage(offset, limit):计算偏移量 offset = (current-1)*size。
        获取总数query.count():用于分页组件展示或前端分页控件。

HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().startedBy(userInfo.getId().toString()).orderByProcessInstanceStartTime().desc();// 分页查询
List<HistoricProcessInstance> list = query.listPage((int) ((current - 1) * size), (int) size);// 总数统计
long count = query.count();

(4)结果转换:VO 组装

        类型转换:将 HistoricProcessInstance 转为其实现类 HistoricProcessInstanceEntityImpl,以便调用 getStartTime()、getEndTime() 等方法。
        关联查询:通过 processDefinitionId 查询 ProcessDefinition,获取流程定义名称。
        VO 填充:将基础信息(定义 ID/名称、实例 ID、发起人、开始/结束时间)写入 MyStartTaskVO。

List<MyStartTaskVO> myStartTaskList = new ArrayList<>();
for (HistoricProcessInstance inst : list) {// 实例转换为内部实现以获取更多字段HistoricProcessInstanceEntityImpl impl =(HistoricProcessInstanceEntityImpl) inst;// 查询流程定义,获取名称等信息ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(impl.getProcessDefinitionId()).singleResult();// 填充 VOMyStartTaskVO vo = new MyStartTaskVO();vo.setProcessDefinitionId(pd.getId());vo.setProcessDefinitionName(pd.getName());vo.setProcessInstanceId(impl.getId());vo.setStartUserName(userInfo.getAccount());vo.setStartTime(DateUtil.toLocalDateTime(impl.getStartTime()));vo.setEndTime(DateUtil.toLocalDateTime(impl.getEndTime()));myStartTaskList.add(vo);
}

(5)封装返回与异常处理

        结果返回:将分页列表与总数写入 VO 并返回。
        统一异常封装:
            对于 IllegalArgumentException,记录日志后转换为 BusinessException,避免上层重复处理。
            对于已捕获的 BusinessException,简化日志并重抛。
            对其它所有异常,一律捕获、记录日志,并封装为 BusinessException。

// 封装结果
myStartTaskListInfoVO.setMyStartTaskList(myStartTaskList);
myStartTaskListInfoVO.setMyStartTaskCount(count);
return myStartTaskListInfoVO;

} catch (IllegalArgumentException e) {
    log.error("查询我的已启动任务列表失败:非法参数异常", e);
    throw new BusinessException("查询我的已启动任务列表失败:非法参数异常", e);
} catch (BusinessException e) {
    log.error("查询我的已启动任务列表失败:业务异常", e);
    throw new BusinessException("查询我的已启动任务列表失败:业务异常", e);
} catch (Exception e) {
    log.error("查询我的已启动任务列表失败:未知异常", e);
    throw new BusinessException("查询我的已启动任务列表失败:未知异常", e);
}
 

(6)完整代码

/*** 查询当前用户启动的任务列表** @param pageReq 分页请求对象,包含当前页码和每页大小* @return 返回一个包含任务列表和总数的VO对象* @throws IllegalArgumentException 如果分页信息为空,则抛出此异常* @throws BusinessException        如果用户未登录或其他业务逻辑异常,则抛出此异常*/
@Override
public MyStartTaskListInfoVO queryMyStartTaskList(PageReq pageReq) {try {// 初始化MyStartTaskListInfoVO myStartTaskListInfoVO = new MyStartTaskListInfoVO();// 分页信息判空if (pageReq == null) {log.error("查询我的已启动任务列表失败,原因:分页信息不能为空");throw new IllegalArgumentException("查询我的已启动任务列表失败,原因:分页信息不能为空");}// 获取分页信息,如果不存在默认查询第一页,每页10条数据long current = (Objects.nonNull(pageReq.getCurrent()) && pageReq.getCurrent() > 0) ? pageReq.getCurrent() :1L;long size = (Objects.nonNull(pageReq.getSize()) && pageReq.getSize() > 0) ? pageReq.getSize() : 10L;// 获取当前用户UserInfo userInfo = userInfoUtils.getUserInfoFromAuthentication();if (userInfo == null) {log.error("查询我的已启动任务列表失败,原因:用户未登录");throw new BusinessException("查询我的已启动任务列表失败,原因:用户未登录");}// 根据当前登录用户查询所有发起的流程HistoricProcessInstanceQuery historicProcessInstanceQuery =historyService.createHistoricProcessInstanceQuery().startedBy(userInfo.getId().toString()).orderByProcessInstanceStartTime().desc();// 分页查询List<HistoricProcessInstance> historicProcessInstanceList = historicProcessInstanceQuery.listPage((int) (current - 1) * (int) size, (int) size);// 记录数据总数long count = historicProcessInstanceQuery.count();// 遍历 historicProcessInstanceListList<MyStartTaskVO> myStartTaskList = new ArrayList<>();historicProcessInstanceList.stream().filter(Objects::nonNull).forEach(historicProcessInstance -> {// 初始化MyStartTaskVO myStartTaskVO = new MyStartTaskVO();// 转换实例获取implHistoricProcessInstanceEntityImpl historicProcessInstanceEntity =(HistoricProcessInstanceEntityImpl) historicProcessInstance;// 根据流程定义ID获取流程定义信息ProcessDefinition processDefinition =repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstanceEntity.getProcessDefinitionId()).singleResult();// 收集我的发起任务信息myStartTaskVO.setProcessDefinitionId(processDefinition.getId());myStartTaskVO.setProcessDefinitionName(processDefinition.getName());myStartTaskVO.setProcessInstanceId(historicProcessInstanceEntity.getId());myStartTaskVO.setStartUserName(userInfo.getAccount());myStartTaskVO.setStartTime(DateUtil.toLocalDateTime(historicProcessInstanceEntity.getStartTime()));myStartTaskVO.setEndTime(DateUtil.toLocalDateTime(historicProcessInstanceEntity.getEndTime()));myStartTaskList.add(myStartTaskVO);});// 收集结果数据myStartTaskListInfoVO.setMyStartTaskList(myStartTaskList);myStartTaskListInfoVO.setMyStartTaskCount(count);return myStartTaskListInfoVO;} catch (IllegalArgumentException e) {// 捕获参数非法异常并封装为业务异常重新抛出log.error("查询我的已启动任务列表失败:非法参数异常", e);throw new BusinessException("查询我的已启动任务列表失败:非法参数异常", e);} catch (BusinessException e) {// 捕获业务逻辑异常并重新抛出,避免重复日志输出log.error("查询我的已启动任务列表失败:业务异常", e);throw new BusinessException("查询我的已启动任务列表失败:业务异常", e);} catch (Exception e) {// 捕获未知异常并封装为业务异常抛出log.error("查询我的已启动任务列表失败:未知异常", e);throw new BusinessException("查询我的已启动任务列表失败:未知异常", e);}
}

⑤ 定义功能接口

/*** 分页查询我的发起任务列表。* <p>* 权限: /api/v1/myTask/queryMyStartTaskList* 参数: pageReq - 分页请求对象,用于指定分页信息(页码、页大小等)* 返回: Result<MyStartTaskListInfoVO> 返回封装后的分页任务列表信息* <p>* 异常处理:* - 业务层异常  返回查询任务列表失败信息* - 其他未知异常  系统异常提示*/
@PreAuthorize("hasAnyAuthority('/api/v1/myTask/queryMyStartTaskList')")
@Parameter(name = "pageReq", description = "分页请求对象", required = true)
@Operation(summary = "分页查询我的发起任务列表")
@PostMapping("/queryMyStartTaskList")
public Result<MyStartTaskListInfoVO> queryMyStartTaskList(@RequestBody PageReq pageReq) {try {// 调用业务层方法,查询出来的分页数据return Result.success(mayTaskService.queryMyStartTaskList(pageReq));} catch (Exception e) {log.error("查询我的发起任务列表失败,原因:{}", e.getMessage());return Result.error("查询我的发起任务列表失败,原因:" + e.getMessage());}
}

二、新建我的发起界面

① 定义数据类型

        由于我们采用ts语法规范,对数据都需要定义类型

// 我发起的流程任务 VO
export interface MyStartTaskVO {processDefinitionId: string // 流程定义ID (Java String)processDefinitionName: string // 流程定义名称processInstanceId: string // 流程实例IDstartUserName: string // 发起人名称startTime: string // 发起时间 (Java LocalDateTime → string)endTime: string // 结束时间 (Java LocalDateTime → string)status: number // 审批状态(0:审批中 1:通过 2:拒绝)(Java Integer → number)comment: string // 审批备注 (Java String)
}// 我发起的流程任务清单 VO
export interface MyStartTaskListInfoVO {myStartTaskList: MyStartTaskVO[] // 我的发起流程任务清单 (Java List<MyStartTaskVO> → MyStartTaskVO[])myStartTaskCount: number // 我的发起流程任务总数 (Java Long → number)
}

② 封装请求接口

        封装我们要请求的后端接口的工具api

/*** 分页查询我发起的任务*/
export function queryMyStartTaskList(data: PageReq) {return request.post<any>({url: '/pm-process/api/v1/myTask/queryMyStartTaskList',data,})
}

③ 绘制页面

        我们的页面简单一些,只要一个表格展示数据即可,查询动作在界面初始化的时候触发。

<script lang="ts" setup>
import type { MyStartTaskListInfoVO, MyStartTaskVO } from '@/api/task/taskType'
import { queryMyStartTaskList } from '@/api/task/taskApi'
import { ElMessage } from 'element-plus'
import { onMounted, ref } from 'vue'// 定义当前页码
const currentPage = ref<number>(1)
// 默认页行数
const pageSize = ref<number>(10)
// 数据总数
const total = ref<number>(0)
// 定义响应式数据 myStartTaskData 用于存放查询到的数据
const myStartTaskData = ref<MyStartTaskVO[]>([])
// 表格列定义
const tableColumns = [{ label: '#', type: 'index', align: 'center', width: '50px' },{ label: '流程定义ID', prop: 'processDefinitionId', align: 'center' },{ label: '流程定义名称', prop: 'processDefinitionName', align: 'center' },{ label: '流程实例ID', prop: 'processInstanceId', align: 'center' },{ label: '发起人名称', prop: 'startUserName', align: 'center' },{ label: '发起时间', prop: 'startTime', align: 'center' },{ label: '结束时间', prop: 'endTime', align: 'center' },{ label: '操作', align: 'center', width: '200px' },
]onMounted(() => {// 初始化分页参数并加载第一页任务数据currentPage.value = 1pageSize.value = 10// 调用获取我的任务分页数据的方法queryMyStartTaskListPage()
})/*** 异步函数:查询我的发起流程任务列表** 该函数通过调用后端API来获取当前用户发起的流程任务列表,并进行分页处理* 它首先设置分页参数,然后调用API,根据返回结果更新前端数据* 如果调用失败或返回错误,它将显示错误消息*/
async function queryMyStartTaskListPage() {try {// 设置分页参数const pageReq = {current: currentPage.value,size: pageSize.value,}// 调用查询我的发起流程任务列表接口const result: any = await queryMyStartTaskList(pageReq)// 如果接口调用成功且返回的状态码为200,则更新数据if (result.success && result.code === 200) {// 更新数据const data: MyStartTaskListInfoVO = result.datamyStartTaskData.value = data.myStartTaskListtotal.value = data.myStartTaskCount}else {// 显示操作失败的错误提示信息ElMessage({message: `查询失败: ${result.message || '未知错误'}`,type: 'error',})}}catch (error) {// 捕获异常并提取错误信息let errorMessage = '未知错误'if (error instanceof Error) {errorMessage = error.message}// 显示操作失败的错误提示信息ElMessage({message: `查询失败: ${errorMessage || '未知错误'}`,type: 'error',})}
}/*** 异步处理页面数据函数* 本函数主要用于处理页面初始化或数据更新时所需的操作* 目前函数中的具体实现是调用一个名为 queryMyStartTaskListPage 的方法* 该方法可能负责从服务器获取数据、处理数据或者更新页面显示* 注意:此函数没有显式地定义参数和返回值,可能依赖于外部状态或全局变量*/
async function handerPageData() {// 调用获取我的任务分页数据的方法queryMyStartTaskListPage()
}
</script><template><el-table style="margin: 10px 0px;" :border="true" :data="myStartTaskData"><!-- ID 区域 --><el-table-column type="selection" align="center" width="50px" /><!-- 表格数据 区域 --><el-table-columnv-for="(column, index) in tableColumns":key="index":type="column.type":label="column.label":prop="column.prop":align="column.align":width="column.width"/></el-table><!-- 分页器 --><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":page-sizes="[10, 20, 30, 40, 50]"layout="prev, pager, next, jumper,->, sizes, total":total="Math.max(total, 0)"@current-change="queryMyStartTaskListPage"@size-change="handerPageData"/>
</template>

三、增加菜单以及按钮

四、分配权限

        给当前admin用户分配新增的菜单和按钮权限,admin是超级管理员

五、查看界面

后记

       下一篇文章我们在操作列,增加审批节点-进度的展示。

本文的后端分支是 process-12

本文的前端分支是 process-14

相关文章:

Flowable7.x学习笔记(二十一)查看我的发起

前言 “查看我的发起”功能&#xff0c;就是将当前用户作为流程发起人启动的所有流程实例集中展示&#xff0c;帮助用户随时跟踪自己提交的业务请求的状态与历史&#xff0c;提升透明度与可控性。 业务人员通常不知道流程引擎底层如何运转&#xff0c;只关心“我提交的报销/申请…...

【Bootstrap V4系列】学习入门教程之 组件-折叠(Collapse)

Bootstrap V4系列 学习入门教程之 组件-折叠&#xff08;Collapse&#xff09; 折叠&#xff08;Collapse&#xff09;How it works一、Example二、Horizontal 水平的三、Multiple targets 多个目标四、Accordion example 手风琴示例 折叠&#xff08;Collapse&#xff09; 通…...

ROS1和ROS2使用桥接工具通信

前提&#xff1a;主从机在同一局域网内&#xff0c;可以互相ping通 我的两个设备其中一个无法连接wifi,ubuntu老生常谈的问题.....&#xff0c;获得新的技能&#xff1a;手机蓝牙提供网络&#xff0c;两个设备连接手机蓝牙就可以连接网络并且处于同一个局域网内。 我的主机为…...

尤雨溪宣布:Vue 生态正式引入 AI

在前端开发领域,Vue 框架一直以其易用性和灵活性受到广大开发者的喜爱。 而如今,Vue 生态在人工智能(AI)领域的应用上又迈出了重要的一步。 尤雨溪近日宣布,Vue、Vite 和 Rolldown 的文档网站均已添加了llms.txt文件,这一举措旨在让大型语言模型(LLM)更方便地理解这些…...

分布式id的两大门派!时钟回拨问题的解决方案!

2.1 两大门派 目前业界的分布式ID实现路径归结起来有两派&#xff1a;一派以雪花算法为代表&#xff0c;不强依赖DB能力&#xff0c;只使用分布式节点自身信息&#xff08;时间戳节点ID序列号&#xff09;的编码生成唯一序列&#xff0c;好处是去中心化、无单点风险&#xff1…...

QMK键盘固件配置详解

QMK键盘固件配置详解 前言 大家好&#xff01;今天给大家带来QMK键盘固件配置的详细指南。如果你正在DIY机械键盘或者想要给自己的键盘刷固件&#xff0c;这篇文章绝对不容错过。QMK是目前最流行的开源键盘固件框架之一&#xff0c;它允许我们对键盘进行高度自定义。接下来&a…...

Jenkins 服务器上安装 Git

安装 Git # 更新包列表 sudo apt update# 安装 Git sudo apt install git 验证安装 # 检查 Git 版本 git --version 查看所有全局配置 git config --global --list 查看特定配置项 # 查看用户名配置 git config --global user.name# 查看邮箱配置 git config --global u…...

自由浮动时间和总浮动时间对比

一、自由浮动时间的定义 在项目进度管理中&#xff0c;自由浮动时间&#xff08;Free Float&#xff09;是指在不推迟项目后续任务最早开始时间的前提下&#xff0c;一个任务能够延迟的时间长度。它是针对单个任务而言的&#xff0c;主要考虑该任务与其紧后任务之间的关系。 …...

2025.05.07-华为机考第二题200分

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 02. 社区智能安防系统设计 问题描述 随着智慧社区建设的发展,LYA小区需要设计一套高效的安防监控系统。该小区布局可以用一棵二叉树来表示,树的每个节点代表一户居民家庭。 为了…...

分布式架构详解

一、分布式架构的概念与设计目标 1. 基本概念 分布式架构&#xff08;Distributed Architecture&#xff09;是分布式计算技术的应用和工具,指将一个复杂系统拆分为多个独立的组件&#xff08;或服务&#xff09;&#xff0c;并将这些组件部署在不同物理节点&#xff08;服务…...

码蹄集——平方根X、整除幸运数

目录 MT1075 平方根X MT1078 整除幸运数 MT1075 平方根X 知识点&#xff1a; 上取整&#xff1a;ceil&#xff1b;下取整&#xff1a;floor&#xff1b;四舍五入&#xff1a;round 判断是否为完全平方数的方法&#xff1a;利用sqrt函数结果为double&#xff0c;将其结果相乘&a…...

【MATLAB源码-第277期】基于matlab的AF中继系统仿真,AF和直传误码率对比、不同中继位置误码率对比、信道容量、中继功率分配以及终端概率。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在AF&#xff08;放大转发&#xff09;中继通信系统中&#xff0c;信号的传输质量和效率受到多个因素的影响&#xff0c;理解这些因素对于系统的优化至关重要。AF中继通信的基本架构由发射端、中继节点和接收端组成。发射端负…...

ACE-Step - 20秒生成4分钟完整歌曲,音乐界的Stable Diffusion,支持50系显卡 本地一键整合包下载

ACE-Step 是由ACE Studio与StepFun联合开发的音乐生成模型&#xff0c;被誉为“音乐界的Stable Diffusion”。该模型以其惊人的生成速度和多样化功能引发行业热议&#xff0c;支持19种语言&#xff0c;可在短短20秒内生成一首长达4分钟的完整音乐作品&#xff0c;效率比主流模型…...

007 Linux 开发工具(上)—— vim、解放sudo、gc+

&#x1f984; 个人主页: 小米里的大麦-CSDN博客 &#x1f38f; 所属专栏: Linux_小米里的大麦的博客-CSDN博客 &#x1f381; GitHub主页: 小米里的大麦的 GitHub ⚙️ 操作环境: Visual Studio 2022 文章目录 Linux 开发工具&#xff08;上&#xff09;Linux 编辑器 —— vim…...

React学习路线图-Gemini版

前端开发学习路线图 (针对编程新手&#xff0c;主攻 React 框架) 总原则&#xff1a;先打好地基&#xff0c;再盖楼。 无论学习哪个框架&#xff0c;扎实的 HTML、CSS 和 JavaScript 基础是成功的关键。React 是基于 JavaScript 构建的&#xff0c;所以深入理解 JS 至关重要。…...

注意力(Attention)机制详解(附代码)

Attention机制是深度学习中的一种技术&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;和计算机视觉领域中得到了广泛的应用。它的核心思想是模仿人类的注意力机制&#xff0c;即人类在处理信息时会集中注意力在某些关键部分上&#xff0c;而忽略其他不那么重要的…...

国内外Agent产品进展汇总

MCP&#xff08;Model Context Protocol&#xff09;是一个开放标准协议&#xff0c;旨在标准化应用程序向大型语言模型提供上下文信息的方式。通过集成MCP扩展&#xff0c;Agent可以访问和利用各种外部工具和服务&#xff0c;丰富了Agent的功能范围&#xff0c;使其能够执行更…...

AI Workflow

AI Workflow&#xff08;人工智能工作流&#xff09;指的是在构建、部署和管理AI模型与应用时所涉及的一系列步骤和流程。它将数据处理、模型训练、评估、部署及监控等环节有机结合起来&#xff0c;以实现高效、可重复的AI解决方案开发过程。以下是对AI Workflow核心组成部分及…...

MySQL OCP 认证限时免费活动​ 7 月 31 日 前截止!!!

为庆祝 MySQL 数据库发布 30 周年&#xff0c;Oracle 官方推出限时福利&#xff1a;2025 年 4 月 20 日至 7 月 31 日期间&#xff0c;所有人均可免费报考 MySQL OCP&#xff08;Oracle Certified Professional&#xff09;认证考试。该认证验证持证者在 MySQL 数据库管理、优化…...

【无标题】MPC软件

MPC软件是一款先进的多变量预测控制解决方案 专为复杂工业过程优化设计 **核心功能** 实时动态建模 多变量协调控制 滚动时域优化 自适应调整策略 干扰抑制 鲁棒性强 适用于时变系统 **技术优势** 基于模型预测算法 提前计算最优控制序列 处理输入输出约束 保障系…...

【EasyPan】loadDataList方法及checkRootFilePid方法解析

【EasyPan】项目常见问题解答&#xff08;自用&持续更新中…&#xff09;汇总版 一、loadDataList方法概览 /*** 文件列表加载接口* param session HTTP会话对象* param shareId 必须参数&#xff0c;分享ID&#xff08;使用VerifyParam进行非空校验&#xff09;* param …...

Java程序题案例分析

目录 一、基础语法 1. 类与对象 2. 接口与抽象类 二、面向对象语法 1. 继承与多态 2. 四种访问修饰符 三、设计模式相关语法 一、策略模式&#xff08;接口回调实现&#xff09; 1. 完整实现与解析 二、工厂模式&#xff08;静态工厂方法实现&#xff09; 1. 完整实…...

【Lanqiao】数位翻转

题目&#xff1a; 思路&#xff1a; 写蓝桥不能不写dp&#xff0c;就像.... 题目数据给的不大&#xff0c;所以我们可以考虑一种 n*m 的做法&#xff0c;那么对于这种题目可以想到的是用dp来写&#xff0c;但是如何构造转移方程与状态是个难事 由于这题对于任意一个数我们有两…...

基于QT(C++)实现(图形界面)校园导览系统

校园导览系统 一、任务描述 大学校园充满着忙忙碌碌的学生和老师们&#xff0c;但是有时候用户宝贵的时间会被复杂的道路和愈来愈多的建筑物的阻碍而浪费&#xff0c;为了不让同学们在自己的目的地的寻路过程中花费更多的时间&#xff0c;我们着手开发这样一款校园导览系统。…...

【C/C++】虚函数

&#x1f4d8; C 虚函数详解&#xff08;Virtual Function&#xff09; &#x1f4cc; 什么是虚函数&#xff1f; 虚函数&#xff08;Virtual Function&#xff09; 是 C 中实现运行时多态&#xff08;Runtime Polymorphism&#xff09; 的核心机制。 它允许派生类 重写&…...

no main manifest attribute, in xxx.jar

1、问题&#xff1a; Spring Boot项目在idea中可以正常运行&#xff0c;但是运行Spring Boot生成的jar包&#xff0c;报错&#xff1a; 1、no main manifest attribute, in xxx.jar 2、xxx.jar中没有主清单属性 2、解决办法&#xff1a; 删除pom.xml中<configuration&g…...

使用 AI 如何高效解析视频内容?生成思维导图或分时段概括总结

一、前言 AI 发展的如此迅速&#xff0c;有人想通过 AI 提效对视频的解析&#xff0c;怎么做呢&#xff1f; 豆包里面有 AI 视频总结的功能&#xff0c;可以解析bilibili网站上部分视频&#xff0c;如下图所示&#xff1a; 但有的视频解析时提示&#xff1a; 所以呢&#x…...

比较入站和出站防火墙规则

组织需要仔细配置防火墙规则&#xff0c;监控网络的传入和传出流量&#xff0c;从而最大限度降低遭受攻击的风险。在有效管理入站和出站防火墙规则前&#xff0c;了解入站与出站流量的区别至关重要。 一、什么是入站流量&#xff1f; 入站流量指的是并非源自网络内部&#xf…...

开放式耳机什么品牌的好用?性价比高的开放式耳机品牌推荐一下

这几年蓝牙耳机发展得很快&#xff0c;从最早的入耳式&#xff0c;到现在流行的开放式&#xff0c;选择越来越多。我自己是比较偏向佩戴舒适的类型&#xff0c;用过开放式之后就回不去了。它不堵耳、不压迫&#xff0c;戴着轻松不累&#xff0c;对我这种耳朵容易不适的人来说太…...

WPF之高级绑定技术

文章目录 引言多重绑定&#xff08;MultiBinding&#xff09;基本概念实现自定义IMultiValueConverterMultiBinding在XAML中的应用示例使用StringFormat简化MultiBinding 优先级绑定&#xff08;PriorityBinding&#xff09;基本概念PriorityBinding示例实现PriorityBinding的后…...

k8s高可用集群,自动化更新证书脚本

#!/bin/bash # 切换到证书目录 cd /etc/kubernetes/pki || exit # 备份原有证书&#xff08;重要&#xff01;&#xff09; sudo cp -r apiserver.crt apiserver.key \ apiserver-etcd-client.crt apiserver-etcd-client.key \ apiserver-kubelet-client…...

【Python 函数】

Python 中的函数&#xff08;Function&#xff09;是可重复使用的代码块&#xff0c;用于封装特定功能并提高代码复用性。以下是函数的核心知识点&#xff1a; 一、基础语法 1. 定义函数 def greet(name):"""打印问候语""" # 文档字符串&…...

Filecoin矿工资金管理指南:使用lotus-shed actor withdraw工具

Filecoin矿工资金管理指南&#xff1a;使用lotus-shed actor withdraw工具 引言lotus-shed actor withdraw命令概述命令语法参数选项详解常见使用场景1. 提取全部可用余额2. 提取指定数量的FIL3. 通过受益人地址发送交易 最佳实践资金安全管理操作流程优化 常见问题与解决方案提…...

AI辅助DevOps与自动化测试:重构软件工程效率边界

随着AI技术渗透至软件开发生命周期&#xff0c;DevOps与自动化测试领域正经历颠覆性变革。本文系统性解析AI在需求分析、测试用例生成、部署决策、异常检测等环节的技术实现路径&#xff0c;结合微软Azure DevOps、Tesla自动驾驶测试等典型场景&#xff0c;探讨AI如何突破传统效…...

css内容省略——text-overflow: ellipsis

title: css内容省略 date: 2025-05-07 19:41:17 tags: css text-overflow: ellipsis text-overflow: ellipsis用于在文本溢出容器时显示省略号(…) 1.单行省略 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"&g…...

nginx性能优化与深度监控

一、性能调优方向 1. 系统层面优化 内核参数调整 TCP队列与连接管理&#xff1a; net.core.somaxconn&#xff08;最大连接队列长度&#xff0c;建议设为65535&#xff09;net.ipv4.tcp_max_syn_backlog&#xff08;SYN队列长度&#xff0c;建议65535&#xff09;net.ipv4.tc…...

leetcode 70.爬楼梯(c++详细最全解法+补充知识)

目录 题目 解答过程 补充哈希表知识 哈希表基本特性 常用成员函数 基本用法 实现代码 1.递归 2.循环遍历 3.哈希表 题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#…...

护照阅读器简介

护照阅读器简介 护照阅读器&#xff08;Passport Reader&#xff09;是一种专用设备&#xff0c;用于快速、准确地读取护照、身份证、签证等旅行证件的机读区&#xff08;MRZ&#xff09;和芯片&#xff08;ePassport&#xff09;信息&#xff0c;广泛应用于出入境管理、机场安…...

切片和边缘计算技术分析报告

切片和边缘计算技术分析报告 一、引言 随着 5G 通信技术的快速发展&#xff0c;网络切片和边缘计算技术逐渐成为通信领域的热点研究方向。网络切片技术通过将物理网络划分为多个逻辑上的虚拟网络&#xff0c;以满足不同业务场景对网络性能的差异化需求。边缘计算则将计算、存…...

vue3笔记(自存)

1. Vue3简介 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;n 经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者 官方发版地址&#xff1a;Release v3.0.0 One Piece vuejs/core 截止2023年10月&#xff0c;最…...

多线服务器具有什么优势

在当今数字化飞速发展的时代&#xff0c;多线服务器宛如一位低调的幕后英雄&#xff0c;默默为我们的网络世界提供着强大的支持。那么&#xff0c;多线服务器到底具有哪些令人瞩目的优势呢 首先&#xff0c;多线服务器的最大优势之一就是网络访问的高速与稳定。想象一下&#x…...

Azure OpenAI 聊天功能全解析:Java 开发者指南

Azure OpenAI 聊天功能全解析&#xff1a;Java 开发者指南 前言 在当今人工智能飞速发展的时代&#xff0c;AI 驱动的文本生成技术正深刻改变着众多应用场景。Azure OpenAI 作为这一领域的重要参与者&#xff0c;由 ChatGPT 提供支持&#xff0c;不仅具备传统 OpenAI 的功能&…...

【情感关系】健全自我

一些看到后深有感触的文字 请大家无论如何也不要相信这种&#xff1a;“童年/原生家庭经历决定人生走向”的论调。 过去可以影响我们但是无法主宰我们&#xff0c;人是有主观能动意识的&#xff0c;认识自己的问题就是改变人生轨迹的第一步。 后来我们会发现&#xff0c;对于…...

SLAM:单应矩阵,本质矩阵,基本矩阵详解和对应的c++实现

单应矩阵(Homography Matrix) 单应矩阵(Homography Matrix)是计算机视觉中描述同一平面在不同视角下投影变换的核心工具,广泛应用于图像校正、拼接、虚拟广告牌替换等场景。以下从原理、求解方法和C++实现三方面展开详解: 一、单应矩阵的数学原理 定义与作用 单应矩阵是…...

数据报(Datagram)与虚电路(Virtual Circuit)的区别

数据报&#xff08;Datagram&#xff09;与虚电路&#xff08;Virtual Circuit&#xff09;的区别 数据报和虚电路是计算机网络中两种不同的通信方式&#xff0c;主要区别体现在 连接方式、路由选择、可靠性、延迟和适用场景 等方面。以下是它们的详细对比&#xff1a; 1. 基本…...

工业现场ModbusTCP转EtherNETIP网关引领生物现场领新浪潮

生物质发生器是一种能够产生、培养生物的设备。客户现场需要将生物发生器连接到罗克韦尔系统&#xff0c;但是二者协议无法直接通讯&#xff0c;需要通过ModbusTCP转Ethernet/IP网关将两者进行通讯连接&#xff0c;生物质发生器以其独特的工作原理和优势&#xff0c;使得生物的…...

DeepSeek的100个应用场景

在春节前夕&#xff0c;浙江杭州的AI企业DeepSeek推出了其开源模型DeepSeek-R1&#xff0c;以仅相当于Open AI最新模型1/30的训练成本&#xff0c;在数学、编程等关键领域展现出媲美GPT-o1的出色性能。发布仅数日&#xff0c;DeepSeek-R1便迅速攀升至中美两国苹果应用商店免费榜…...

【Linux 系统调试】Linux 调试工具strip使用方法

‌ 目录 ‌ 一. strip 工具的定义与核心作用‌ ‌1. strip 是什么&#xff1f;‌ 2. strip 工具调试符号的作用‌ 3. strip 工具调试符号的重要性‌ 二. 如何确认文件是否被 strip 处理&#xff1f;‌ 1. 通过 file 命令检查文件状态 2. strip 的典型用法‌ ‌基础命…...

Solana批量转账教程:提高代币持有地址和生态用户空投代币

前言 Solana区块链因其高吞吐量和低交易费用成为批量操作&#xff08;如空投&#xff09;的理想选择。本教程将介绍几种在Solana上进行批量转账的方法&#xff0c;帮助您高效地向多个地址空投代币。 solana 账户模型 在Solana中有三类账户&#xff1a; 数据账户&#xff0c;…...

leetcode hot100 技巧

如有缺漏谬误&#xff0c;还请批评指正。 1.只出现一次的数字 利用异或运算相同得0的特点。所有出现过两次的数字都会在异或运算累加过程中被抵消。、 class Solution { public:int singleNumber(vector<int>& nums) {int res0;for(int i0;i<nums.size();i) re…...