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

flowable汇总查询方式

背景:小程序开发申请流程。使用flowable流程框架。用户需要在后台统揽用户申请的汇总表。
设计思路:通过查询流程实例分页查询获取数据其中可以通过查询条件进行查询查询条件是流程申请时添加到流程变量当中的,方便进行查询

具体内容。

  • 涉及到前端页面和后端代码,还有导出部分实现。
  • PC页面
    在这里插入图片描述
  • 后端代码:此部分为具体实现流程。
@Override
public TableDataInfo<WfTaskVo> selectPageInitiatorProcessList(ProcessQuery processQuery, PageQuery pageQuery) {Page<WfTaskVo> page = new Page<>();HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().orderByProcessInstanceStartTime().desc();// 使用buildProcessSearch拼接查询条件ProcessUtils.buildProcessSearch(historicProcessInstanceQuery, processQuery);int offset = pageQuery.getPageSize() * (pageQuery.getPageNum() - 1);List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.includeProcessVariables().listPage(offset, pageQuery.getPageSize());page.setTotal(historicProcessInstanceQuery.count());List<WfTaskVo> taskVoList = new ArrayList<>();for (HistoricProcessInstance hisIns : historicProcessInstances) {WfTaskVo taskVo = new WfTaskVo();taskVo.setProcInsId(hisIns.getId());taskVo.setProcDefId(hisIns.getProcessDefinitionId());taskVo.setProcDefName(hisIns.getProcessDefinitionName());taskVo.setCreateTime(hisIns.getStartTime());taskVo.setFinishTime(hisIns.getEndTime());// 计算耗时if (Objects.nonNull(hisIns.getEndTime())) {taskVo.setDuration(DateUtils.getDatePoor(hisIns.getEndTime(), hisIns.getStartTime()));} else {taskVo.setDuration(DateUtils.getDatePoor(DateUtils.getNowDate(), hisIns.getStartTime()));}// 获取发起人信息Long userId = Long.parseLong(hisIns.getStartUserId());String nickName = userService.selectNickNameById(userId);taskVo.setStartUserId(userId);taskVo.setStartUserName(nickName);Object name = hisIns.getProcessVariables().get("name");if (name != null) {taskVo.setName(name.toString());}Object projectId = hisIns.getProcessVariables().get(BusiConstants.PROJECT_ID);if (projectId != null) {taskVo.setProjectId(projectId.toString());}taskVoList.add(taskVo);}page.setRecords(taskVoList);return TableDataInfo.build(page);
}
  • 此部分为添加的查询条件处理。ProcessUtils.buildProcessSearch(historicProcessInstanceQuery, processQuery);对入参进行处理
public static void buildProcessSearch(Query<?, ?> query, ProcessQuery process) {if (query instanceof ProcessDefinitionQuery) {buildProcessDefinitionSearch((ProcessDefinitionQuery) query, process);} else if (query instanceof TaskQuery) {buildTaskSearch((TaskQuery) query, process);} else if (query instanceof HistoricTaskInstanceQuery) {buildHistoricTaskInstanceSearch((HistoricTaskInstanceQuery) query, process);} else if (query instanceof HistoricProcessInstanceQuery) {buildHistoricProcessInstanceSearch((HistoricProcessInstanceQuery) query, process);}
}
...
public static void buildHistoricProcessInstanceSearch(HistoricProcessInstanceQuery query, ProcessQuery process) {Map<String, Object> params = process.getParams();// 流程标识if (StringUtils.isNotBlank(process.getProcessKey())) {query.processDefinitionKey(process.getProcessKey());}// 流程名称if (StringUtils.isNotBlank(process.getProcessName())) {query.processDefinitionName(process.getProcessName());}// 流程名称if (StringUtils.isNotBlank(process.getCategory())) {query.processDefinitionCategory(process.getCategory());}if (params.get("beginTime") != null && params.get("endTime") != null) {query.startedAfter(DateUtils.parseDate(params.get("beginTime")));query.startedBefore(DateUtils.parseDate(params.get("endTime")));}// 判断项目idif (ObjectUtil.isNotEmpty(params.get("projectId"))) {query.variableValueEquals("projectId", params.get("projectId"));}// 判断病种idif (ObjectUtil.isNotEmpty(params.get("diseaseInfoId"))) {query.variableValueEquals("diseaseInfoId", params.get("diseaseInfoId"));}// 模糊查询姓名if (ObjectUtil.isNotEmpty(params.get("name"))) {query.variableValueLike("name", "%" + params.get("name").toString() + "%");}// 查询省份if (ObjectUtil.isNotEmpty(params.get("provinceCode"))) {query.variableValueEquals("provinceCode", params.get("provinceCode"));}// 流程状态(已完成未完成)if (ObjectUtil.isNotEmpty(params.get("status"))) {if ("1".equals(params.get("status"))) {query.finished();}else {query.unfinished();}}
}

导出方案及实现

  • 核心内容: 大模型给的方案中,我使用了分批导出。相比于延长超时时间、分页导出等更合理。是使用前端进行导出的方式,只获取后端接口数据。
 /** 导出按钮操作 */async handleExport() {try {// 显示进度对话框this.exportProgress.visible = true;this.exportProgress.percentage = 0;this.exportProgress.currentBatch = 0;this.exportProgress.totalBatches = 0;this.exportProgress.currentCount = 0;this.exportProgress.totalCount = 0;const batchSize = 1000; // 每批1000条数据let allData = [];let currentPage = 1;let hasMore = true;// 构建基础查询参数const baseParams = {name: this.queryParams.name,projectId: this.queryParams.projectId,startUserName: this.queryParams.startUserName,status: this.queryParams.status};// 添加日期范围参数if (this.dateRange && this.dateRange.length === 2) {baseParams.beginTime = this.dateRange[0];baseParams.endTime = this.dateRange[1];} else {// 如果没有选择时间范围,设置默认值(最近30天)const endDate = new Date();const startDate = new Date();startDate.setDate(startDate.getDate() - 30);baseParams.beginTime = startDate.toISOString().slice(0, 19).replace('T', ' ');baseParams.endTime = endDate.toISOString().slice(0, 19).replace('T', ' ');}// 先获取总数,用于计算进度const countResponse = await fetchInitiatorList({pageNum: 1,pageSize: 1,params: baseParams});if (countResponse.code === 200) {this.exportProgress.totalCount = countResponse.total || 0;this.exportProgress.totalBatches = Math.ceil(this.exportProgress.totalCount / batchSize);}// 分批获取数据while (hasMore) {const batchParams = {pageNum: currentPage,pageSize: batchSize,params: baseParams};// 更新进度信息this.exportProgress.currentBatch = currentPage;this.exportProgress.currentCount = allData.length;this.exportProgress.percentage = Math.round((allData.length / this.exportProgress.totalCount) * 100);const response = await fetchInitiatorList(batchParams);if (response.code === 200 && response.rows && response.rows.length > 0) {allData = allData.concat(response.rows);currentPage++;// 检查是否还有更多数据hasMore = response.rows.length === batchSize;// 添加小延迟,避免请求过于频繁await new Promise((resolve) => setTimeout(resolve, 100));} else {hasMore = false;}}if (allData.length > 0) {// 更新最终进度this.exportProgress.currentCount = allData.length;this.exportProgress.percentage = 100;// 显示最终进度this.$message.info(`数据获取完成,共 ${allData.length} 条,正在生成Excel文件...`);// 格式化数据为Excel格式const excelData = this.formatDataForExcel(allData);// 生成Excel文件this.generateAndDownloadExcel(excelData);this.$message.success(`导出成功,共导出 ${allData.length} 条数据`);} else {this.$message.warning('没有数据可导出');}// 关闭进度对话框setTimeout(() => {this.exportProgress.visible = false;}, 2000);} catch (error) {console.error('导出失败:', error);// 关闭进度对话框this.exportProgress.visible = false;if (error.message && error.message.includes('timeout')) {this.$message.error('导出超时,请尝试缩小查询范围或联系管理员');} else {this.$message.error('导出失败,请重试');}}},
http://www.dtcms.com/a/334077.html

相关文章:

  • 计算机网络:(十五)TCP拥塞控制与拥塞控制算法深度剖析
  • MySQL的《Buffer-pool》和《连接池》介绍
  • Zotero 和 Zotero常见插件的安装
  • Vue组件生命周期钩子:深入理解组件的生命周期阶段
  • Qt— 布局综合项目(Splitter,Stacked,Dock)
  • 车载诊断架构 --- 怎么解决对已量产ECU增加具体DTC的快照信息?
  • Javar如何用RabbitMQ订单超时处理
  • 安卓11 12系统修改定制化_____修改运营商版本安装特定应用时的默认规则
  • 从依赖到自研:一个客服系统NLP能力的跃迁之路
  • ML307C 4G通信板:工业级DTU固件,多协议支持,智能配置管理
  • Boost.Asio学习(7):Boost.Beast实现简易http服务器
  • Rust学习笔记(四)|结构体与枚举(面向对象、模式匹配)
  • C++基础——内存管理
  • 基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
  • 零知开源——基于STM32F407VET6的TCS230颜色识别器设计与实现
  • 开源数据发现平台:Amundsen Frontend Service 推荐实践
  • Camx-Tuning参数加载流程分析
  • 【时时三省】(C语言基础)共用体类型数据的特点
  • 她的热情为何突然冷却?—— 解析 Kafka 吞吐量下降之谜
  • 智能合约:区块链时代的“数字契约革命”
  • 外出业务员手机自动添加报价单​——仙盟创梦IDE
  • 多商户商城系统源码选型指南:开源框架 vs 定制开发的优劣对比
  • Android RxJava 组合操作符实战:优雅处理多数据源
  • 12分区南排烟机,多线模块没电
  • Linux上管理Java的JDK版本
  • LeetCode 刷题【43. 字符串相乘】
  • 34 HTB Cat 机器 - 中等难度
  • 完整设计 之 智能合约系统:主题约定、代理协议和智能合约 (临时命名)----PromptPilot (助手)答问之2
  • Three.js三大组件:场景(Scene)、相机(Camera)、渲染器(Renderer)
  • 线性代数之两个宇宙文明关于距离的对话