目录

  • 1. 前言
  • 2. 流程历史数据查询
    • 2.1. 查询历史流程实例信息
    • 2.2. 查询历史活动信息
    • 2.3. 查询历史任务信息
    • 2.4. 查询历史流程变量

1. 前言

上篇文章 和大家分享的流程操作主要是正在执行的流程,我们有一个非常常见的场景是查询执行过的流程信息,在上篇文章中,小伙伴们已经知道,对于正在执行的流程,会在 act_ru_execution 表中保存一条对应的记录,不过流程执行结束之后,act_ru_execution 表中的记录会被删除掉,此时要是想查询已经执行过的流程信息,去哪里查询呢?今天我们就来看看 HistoryService 的使用

本文使用的流程图依然是上篇文章中使用过的,如下

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.flowable.org/processdef" exporter="Flowable Open Source Modeler"exporterVersion="6.7.2"><process id="MyLeave" name="MyLeave" isExecutable="true"><documentation>员工请假流程</documentation><startEvent id="sid-159DD77D-9878-4288-AC29-B898E08DC216" flowable:formFieldValidation="true"></startEvent><userTask id="zgID" name="主管审批" flowable:assignee="张主管" flowable:formFieldValidation="true"><extensionElements><modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements></userTask><sequenceFlow id="sid-1E8F84D7-6C11-4D88-84C9-B818474F880E" sourceRef="sid-159DD77D-9878-4288-AC29-B898E08DC216"targetRef="zgID"></sequenceFlow><exclusiveGateway id="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"></exclusiveGateway><sequenceFlow id="sid-08020782-2DDE-4C56-BFC0-224DC99FB50E" sourceRef="zgID"targetRef="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"></sequenceFlow><endEvent id="sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB"></endEvent><userTask id="jlID" name="经理审批" flowable:assignee="李经理" flowable:formFieldValidation="true"><extensionElements><modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements></userTask><exclusiveGateway id="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"></exclusiveGateway><sequenceFlow id="sid-833DAA1C-F1C2-41A1-8455-3FAB79893C14" sourceRef="jlID"targetRef="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"></sequenceFlow><endEvent id="sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F"></endEvent><endEvent id="sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1"></endEvent><sequenceFlow id="sid-A74937CE-02B1-493B-8033-08CA2D652771" name="同意"sourceRef="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0" targetRef="jlID"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='YES'}]]></conditionExpression></sequenceFlow><sequenceFlow id="sid-BE2005E1-26F7-4E42-8AC2-7C4F25274F1A" name="同意"sourceRef="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"targetRef="sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='YES'}]]></conditionExpression></sequenceFlow><sequenceFlow id="sid-67F146AA-C9F5-4A21-AF26-A77A349D80B7" name="拒绝"sourceRef="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"targetRef="sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='NO'}]]></conditionExpression></sequenceFlow><sequenceFlow id="sid-4CC613DD-7789-408B-AFA0-1241261A4E79" name="拒绝"sourceRef="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"targetRef="sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${executeType=='NO'}]]></conditionExpression></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_MyLeave"><bpmndi:BPMNPlane bpmnElement="MyLeave" id="BPMNPlane_MyLeave"><bpmndi:BPMNShape bpmnElement="sid-159DD77D-9878-4288-AC29-B898E08DC216"id="BPMNShape_sid-159DD77D-9878-4288-AC29-B898E08DC216"><omgdc:Bounds height="30.0" width="30.0" x="45.0" y="105.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="zgID" id="BPMNShape_zgID"><omgdc:Bounds height="80.0" width="100.0" x="165.0" y="80.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"id="BPMNShape_sid-A6E285DA-5C65-4BA7-8BB4-5F4D97AC12E0"><omgdc:Bounds height="40.0" width="40.0" x="360.0" y="100.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB"id="BPMNShape_sid-5BFB0FC6-B2A5-4F6E-9BDB-8785F2883AEB"><omgdc:Bounds height="28.0" width="28.0" x="366.0" y="225.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="jlID" id="BPMNShape_jlID"><omgdc:Bounds height="80.0" width="100.0" x="495.0" y="80.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"id="BPMNShape_sid-0DA07C30-2930-40F5-A887-FA1C5BF307EF"><omgdc:Bounds height="40.0" width="40.0" x="690.0" y="100.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F"id="BPMNShape_sid-8941849E-B17F-4848-BFC8-C6B05CC21A9F"><omgdc:Bounds height="28.0" width="28.0" x="696.0" y="225.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1"id="BPMNShape_sid-3596170A-0E0F-4C07-BD32-F04AFB375EB1"><omgdc:Bounds height="28.0" width="28.0" x="825.0" y="106.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="sid-1E8F84D7-6C11-4D88-84C9-B818474F880E"id="BPMNEdge_sid-1E8F84D7-6C11-4D88-84C9-B818474F880E" flowable:sourceDockerX="15.0"flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0"><omgdi:waypoint x="74.94999923927439" y="120.0"></omgdi:waypoint><omgdi:waypoint x="164.99999999991007" y="120.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-08020782-2DDE-4C56-BFC0-224DC99FB50E"id="BPMNEdge_sid-08020782-2DDE-4C56-BFC0-224DC99FB50E" flowable:sourceDockerX="50.0"flowable:sourceDockerY="40.0" flowable:targetDockerX="20.5" flowable:targetDockerY="20.5"><omgdi:waypoint x="264.9499999999992" y="120.1509063444109"></omgdi:waypoint><omgdi:waypoint x="360.43939393938865" y="120.43939393939392"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-4CC613DD-7789-408B-AFA0-1241261A4E79"id="BPMNEdge_sid-4CC613DD-7789-408B-AFA0-1241261A4E79" flowable:sourceDockerX="20.5"flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0"><omgdi:waypoint x="710.4194915254237" y="139.52220575783235"></omgdi:waypoint><omgdi:waypoint x="710.0588602435497" y="225.00012270930887"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-833DAA1C-F1C2-41A1-8455-3FAB79893C14"id="BPMNEdge_sid-833DAA1C-F1C2-41A1-8455-3FAB79893C14" flowable:sourceDockerX="50.0"flowable:sourceDockerY="40.0" flowable:targetDockerX="20.5" flowable:targetDockerY="20.5"><omgdi:waypoint x="594.9499999999981" y="120.15090634441087"></omgdi:waypoint><omgdi:waypoint x="690.4393939393933" y="120.43939393939394"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-BE2005E1-26F7-4E42-8AC2-7C4F25274F1A"id="BPMNEdge_sid-BE2005E1-26F7-4E42-8AC2-7C4F25274F1A" flowable:sourceDockerX="20.5"flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0"><omgdi:waypoint x="729.516569086651" y="120.42578125"></omgdi:waypoint><omgdi:waypoint x="825.0001009915921" y="120.054279921789"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-67F146AA-C9F5-4A21-AF26-A77A349D80B7"id="BPMNEdge_sid-67F146AA-C9F5-4A21-AF26-A77A349D80B7" flowable:sourceDockerX="20.5"flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0"><omgdi:waypoint x="380.4194915254237" y="139.52220575783235"></omgdi:waypoint><omgdi:waypoint x="380.05886024354976" y="225.00012270930887"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="sid-A74937CE-02B1-493B-8033-08CA2D652771"id="BPMNEdge_sid-A74937CE-02B1-493B-8033-08CA2D652771" flowable:sourceDockerX="20.5"flowable:sourceDockerY="20.5" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0"><omgdi:waypoint x="399.50196526507943" y="120.44207317073172"></omgdi:waypoint><omgdi:waypoint x="494.9999999999935" y="120.15182370820669"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>

2. 流程历史数据查询

2.1. 查询历史流程实例信息

@Test
public void QueryHistoryProcess() {// 获取流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();HistoryService historyService = processEngine.getHistoryService();HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId("2c495021-55bf-11ed-a800-005056c00001").orderByProcessInstanceStartTime().asc().singleResult();System.out.println("流程实例ID:" + historicProcessInstance.getId());System.out.println("流程定义ID:" + historicProcessInstance.getProcessDefinitionId());System.out.println("流程开始时间:" + historicProcessInstance.getStartTime());System.out.println("流程结束时间:" + historicProcessInstance.getEndTime());
}

控制台打印结果如下

==>  Preparing: select distinct RES.* , DEF.KEY_ as PROC_DEF_KEY_, DEF.NAME_ as PROC_DEF_NAME_, DEF.VERSION_ as PROC_DEF_VERSION_, DEF.DEPLOYMENT_ID_ as DEPLOYMENT_ID_ from ACT_HI_PROCINST RES left outer join ACT_RE_PROCDEF DEF on RES.PROC_DEF_ID_ = DEF.ID_ WHERE RES.PROC_INST_ID_ = ? order by RES.START_TIME_ asc
==> Parameters: 2c495021-55bf-11ed-a800-005056c00001(String)
<==      Total: 1流程实例ID:2c495021-55bf-11ed-a800-005056c00001
流程定义ID:MyLeave:1:8c16935c-5544-11ed-b9df-005056c00001
流程开始时间:Thu Oct 27 14:18:28 CST 2022
流程结束时间:Thu Oct 27 16:40:51 CST 2022
  • 可以看到是将 ACT_HI_PROCINST 历史流程实例表和 ACT_RE_PROCDEF 流程定义表两张表进行了关联查询

2.2. 查询历史活动信息

@Test
public void QueryHistoryActivity() {// 获取流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();HistoryService historyService = processEngine.getHistoryService();List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId("2c495021-55bf-11ed-a800-005056c00001").orderByHistoricActivityInstanceStartTime().asc().list();if (list != null && list.size() > 0) {for (HistoricActivityInstance hai : list) {System.out.println("历史活动ID:" + hai.getId());System.out.println("流程定义ID:" + hai.getProcessDefinitionId());System.out.println("流程开始时间:" + DateUtil.format(hai.getStartTime(), "yyyy-MM-dd HH:mm:ss"));System.out.println("流程结束时间:" + DateUtil.format(hai.getEndTime(), "yyyy-MM-dd HH:mm:ss"));System.out.println("流程的处理人是:" + hai.getAssignee());System.out.println("#####################");}}
}

控制台打印结果如下

==>  Preparing: select RES.* from ACT_HI_ACTINST RES WHERE RES.PROC_INST_ID_ = ? order by START_TIME_ asc
==> Parameters: 2c495021-55bf-11ed-a800-005056c00001(String)
<==      Total: 11历史活动ID:2c4a1376-55bf-11ed-a800-005056c00001
流程定义ID:MyLeave:1:8c16935c-5544-11ed-b9df-005056c00001
流程开始时间:2022-10-27 14:18:28
流程结束时间:2022-10-27 14:18:28
流程的处理人是:null
#####################
历史活动ID:2c4cd298-55bf-11ed-a800-005056c00001
流程定义ID:MyLeave:1:8c16935c-5544-11ed-b9df-005056c00001
流程开始时间:2022-10-27 14:18:28
流程结束时间:2022-10-27 15:16:27
流程的处理人是:张主管
#####################
历史活动ID:4608ad88-55c7-11ed-80ee-005056c00001
流程定义ID:MyLeave:1:8c16935c-5544-11ed-b9df-005056c00001
流程开始时间:2022-10-27 15:16:28
流程结束时间:2022-10-27 16:40:51
流程的处理人是:李经理
#####################
  • 可以看到是直接从历史活动信息表 ACT_HI_ACTINST 中查询数据

2.3. 查询历史任务信息

@Test
public void QueryHistoryTask() {// 获取流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();HistoryService historyService = processEngine.getHistoryService();List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId("2c495021-55bf-11ed-a800-005056c00001").orderByHistoricTaskInstanceStartTime().asc().list()if (list != null && list.size() > 0) {for (HistoricTaskInstance hti : list) {System.out.println("历史任务ID:" + hti.getId());System.out.println("流程定义ID:" + hti.getProcessDefinitionId());System.out.println("流程执行实例ID:" + hti.getExecutionId());System.out.println("流程结束时间:" + DateUtil.format(hti.getEndTime(), "yyyy-MM-dd HH:mm:ss"));System.out.println("流程的处理人是:" + hti.getAssignee());System.out.println("################################");}}
}

控制台打印结果如下

==>  Preparing: select distinct RES.* from ACT_HI_TASKINST RES WHERE RES.PROC_INST_ID_ = ? order by RES.START_TIME_ asc
==> Parameters: 2c495021-55bf-11ed-a800-005056c00001(String)
<==      Total: 2历史任务ID:2c5277e9-55bf-11ed-a800-005056c00001
流程定义ID:MyLeave:1:8c16935c-5544-11ed-b9df-005056c00001
流程执行实例ID:2c4a1375-55bf-11ed-a800-005056c00001
流程结束时间:2022-10-27 15:16:27
流程的处理人是:张主管
################################
历史任务ID:4608d499-55c7-11ed-80ee-005056c00001
流程定义ID:MyLeave:1:8c16935c-5544-11ed-b9df-005056c00001
流程执行实例ID:2c4a1375-55bf-11ed-a800-005056c00001
流程结束时间:2022-10-27 16:40:51
流程的处理人是:李经理
################################
  • 可以看到是直接从历史任务信息表 ACT_HI_TASKINST 中查询数据

2.4. 查询历史流程变量

@Test
public void QueryHistoryVariables() {// 获取流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();HistoryService historyService = processEngine.getHistoryService();List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().processInstanceId("2c495021-55bf-11ed-a800-005056c00001").list();if (list != null && list.size() > 0) {for (HistoricVariableInstance hvi : list) {System.out.println("流程变量ID:" + hvi.getId());System.out.println("流程实例ID:" + hvi.getProcessInstanceId());System.out.println("变量名称:" + hvi.getVariableName());System.out.println("变量的值:" + hvi.getValue());System.out.println("变量的创建时间:" + DateUtil.format(hvi.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));System.out.println("###############################################");}}
}

控制台打印结果如下

流程变量ID:2c499e42-55bf-11ed-a800-005056c00001
流程实例ID:2c495021-55bf-11ed-a800-005056c00001
变量名称:nrOfHolidays
变量的值:3
变量的创建时间:2022-10-27 14:18:28
###############################################
流程变量ID:2c49ec63-55bf-11ed-a800-005056c00001
流程实例ID:2c495021-55bf-11ed-a800-005056c00001
变量名称:description
变量的值:工作累了,想出去玩玩
变量的创建时间:2022-10-27 14:18:28
###############################################
流程变量ID:2c49ec64-55bf-11ed-a800-005056c00001
流程实例ID:2c495021-55bf-11ed-a800-005056c00001
变量名称:employee
变量的值:小王
变量的创建时间:2022-10-27 14:18:28
###############################################
流程变量ID:45f4b054-55c7-11ed-80ee-005056c00001
流程实例ID:2c495021-55bf-11ed-a800-005056c00001
变量名称:executeType
变量的值:YES
变量的创建时间:2022-10-27 15:16:27
###############################################

Flowable工作流之查询历史流程信息相关推荐

  1. Flowable工作流之核心流程操作的本质

    目录 1. 前言 2. 捋清三个概念 2.1. 流程定义 2.2. 流程实例 2.3. 执行实例 3. 流程启动方式 4. `Flowable` 完整流程操作 4.1. 流程部署 4.1.1. 部署实 ...

  2. flowable工作流简单请假流程,自定义完成的流程图表颜色字体以及连接线的颜色字体。

    效果图 代码 1.bpmn文件ExpenseProcess.bpmn20.xml(通过可视化工具生成[非常熟悉也可以手动编写]) <?xml version="1.0" en ...

  3. 初识flowable工作流-实现简单请假流程SpringBoot+VUE

    一.前言 大家好,因为目前手里需要用到flowable工作流,之前没有接触过,所以在这里记录一下学习的进度,开始后台使用SpringCloud分布式框架和前端Vue框架实现一个简单的请假流程. 二.代 ...

  4. flowable工作流 流程变量_业务流程 BPM、工作流引擎、Flowable、Activiti

    特点 基于 Flowable(Activiti)生来具有的稳定工作流引擎 支持在线流程设计器,流程导入导出,符合 BPMN 规范,中国式工作流 支持流程办理.退回.自由流.会签.并行.串行.服务任务等 ...

  5. flowable工作流子流程调用

    flowable工作流子流程介绍 工作流提供了子流程的调用,一种是内部子流程,可以让用户主要看主流程,保持业务清晰,另一种是引用外部子流程(call activity),复用外部流程功能. 工作中有用 ...

  6. Flowable工作流入门

    Flowable工作流入门 本文链接:https://blog.csdn.net/qq_37059838/article/details/83576097 原作者:吕小小布 下载地址:Flowable ...

  7. Flowable工作流引擎

    Flowable工作流引擎 Flowable-基础篇(根据BV1Pb4y1p7Ku整理) 一.简介 Flowable是BPMN的一个基于java的软件实现,不过Flowable不仅仅包括BPMN,还有 ...

  8. SpringBoot整合Flowable工作流引擎框架

    Flowable工作流引擎框架介绍 一个Java编写的轻量级业务流程引擎,为开发人员.系统管理员和业务用户提供工作流和业务流程管理(BPM)平台. 不仅包括BPMN,还有DMN决策表和CMMN Cas ...

  9. flowable工作流技术学习

    一.flowable工作流引擎中文文档 Flowable BPMN 用户手册 (v 6.3.0) 这个文档内容太多,稍微看看就好,具体学习还得从demo里面去学习. 二.flowable项目下载地址与 ...

最新文章

  1. 以python入门教程新世界-Python打开新世界的大门-入门篇1
  2. SDK,JDK,API的区别
  3. 前端传值后端接收不到_解决vue get请求传参后端接收不到参数值(java sptingboot)
  4. 【Python CheckiO 题解】All the Same
  5. 火狐浏览器中文乱码怎么办 Firefox中文乱码解决方法
  6. Python Numpy 数组的初始化和基本操作
  7. DNS配置,主从,子域,转发
  8. 每日学习笔记(20)
  9. PHP脚本memcache类的源码
  10. vue.js2.0视频教程
  11. ISP之色差增益抑制(Chroma Gain Suppression)
  12. 面试java程序员hr问你职业规划,2022最新
  13. dos下的for命令详解(zz)
  14. idear右边的依赖视图没了_APP开发中出现提到的Idear是什么意思
  15. 论文阅读:Semantic Aware Attention Based Deep Object Co-segmentation(ACCV2018)
  16. html 屏幕旋转,屏幕旋转与Transform
  17. houdini 求出曲线的法向 切线以及副法线
  18. Netcat的使用教程
  19. TerraBuilder 操作制作MPT
  20. Android智能手机安全解决方案

热门文章

  1. Uniswap v3 详解(五):Oracle 预言机
  2. 圣诞节蓝牙耳机选哪款作为礼物比较好?耐用的蓝牙耳机推荐
  3. 如何查看支付宝商户ID(支付宝pid)?
  4. 快速拿下CKA认证考试,这些要求和tips你得知道
  5. 诊断和解决row chained and migrated
  6. 批处理删除指定名称的打印机
  7. 面试中常考的数学题——截木棍、圆上取点、赛马、红蓝墨水,测试毒药、坐到正确座位问题
  8. 学习笔记【基金】【理财】【定投】...
  9. 一文带你了解什么是云计算网络运维工程师,以及2023年的就业前景
  10. 一些计算机模拟人脑项目