Flowable流程引擎学习

先学习使用flowable-ui的Demo

这个可以帮助我们生成bpmn20.xml文件
也就是使用flowable自带的flowable-ui制作流程图

使用docker运行

docker run -p 8080:8080 flowable/flowable-ui

运行成功后访问

http://localhost:8080/flowable-ui

user: admin
password: test

创建流程得到bpmn20.xml






导出xml


<?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.8.0">
  <process id="leave_approve" name="请假审批" isExecutable="true">
    <documentation>请假审批</documentation>
    <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
    <userTask id="sid-7361D568-A832-478D-B31E-770B6508F0EC" name="学生" flowable:formFieldValidation="true"></userTask>
    <sequenceFlow id="sid-7EDC7758-DF02-4ED4-9EA8-1E169B31107E" sourceRef="startEvent1" targetRef="sid-7361D568-A832-478D-B31E-770B6508F0EC"></sequenceFlow>
    <userTask id="sid-D858C90B-1391-4E58-A715-13FCBBD13498" name="老师" flowable:formFieldValidation="true"></userTask>
    <sequenceFlow id="sid-96173B13-7480-43F0-9B3E-EC1CA76D5446" name="请假" sourceRef="sid-7361D568-A832-478D-B31E-770B6508F0EC" targetRef="sid-D858C90B-1391-4E58-A715-13FCBBD13498"></sequenceFlow>
    <sequenceFlow id="sid-624203DD-6504-480B-8558-8D3E929D50AB" name="审批" sourceRef="sid-D858C90B-1391-4E58-A715-13FCBBD13498" targetRef="sid-9263F9A7-58B4-4C62-8ECF-93B4FD76626F"></sequenceFlow>
    <userTask id="sid-E27E9FD3-50EE-44B5-BE83-D199A794394E" name="校长" flowable:formFieldValidation="true"></userTask>
    <exclusiveGateway id="sid-DB230500-F8E7-4796-866E-80AE4F5759D5"></exclusiveGateway>
    <sequenceFlow id="sid-FC660276-FC1E-4D66-8E70-0D32D2843014" name="审批" sourceRef="sid-E27E9FD3-50EE-44B5-BE83-D199A794394E" targetRef="sid-DB230500-F8E7-4796-866E-80AE4F5759D5"></sequenceFlow>
    <endEvent id="sid-D9764532-4C6A-4087-A440-B3F3F032A077"></endEvent>
    <exclusiveGateway id="sid-9263F9A7-58B4-4C62-8ECF-93B4FD76626F"></exclusiveGateway>
    <sequenceFlow id="sid-3918DA4F-F9CA-4A67-847F-D7934807ECED" name="拒绝" sourceRef="sid-9263F9A7-58B4-4C62-8ECF-93B4FD76626F" targetRef="sid-7361D568-A832-478D-B31E-770B6508F0EC">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${action='N'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-91377CDC-8D11-4E59-BE0D-C186C658D62E" name="同意" sourceRef="sid-DB230500-F8E7-4796-866E-80AE4F5759D5" targetRef="sid-D9764532-4C6A-4087-A440-B3F3F032A077">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${action='Y'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-84B59206-7F5E-43C5-BDB8-EB7D0F822160" name="拒绝" sourceRef="sid-DB230500-F8E7-4796-866E-80AE4F5759D5" targetRef="sid-7361D568-A832-478D-B31E-770B6508F0EC">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${action='N'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-65EE4768-D3FD-49E8-8A1E-190A06207DF9" name="同意" sourceRef="sid-9263F9A7-58B4-4C62-8ECF-93B4FD76626F" targetRef="sid-E27E9FD3-50EE-44B5-BE83-D199A794394E">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${action='Y'}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_leave_approve">
    <bpmndi:BPMNPlane bpmnElement="leave_approve" id="BPMNPlane_leave_approve">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7361D568-A832-478D-B31E-770B6508F0EC" id="BPMNShape_sid-7361D568-A832-478D-B31E-770B6508F0EC">
        <omgdc:Bounds height="80.0" width="100.0" x="175.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-D858C90B-1391-4E58-A715-13FCBBD13498" id="BPMNShape_sid-D858C90B-1391-4E58-A715-13FCBBD13498">
        <omgdc:Bounds height="80.0" width="100.0" x="320.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-E27E9FD3-50EE-44B5-BE83-D199A794394E" id="BPMNShape_sid-E27E9FD3-50EE-44B5-BE83-D199A794394E">
        <omgdc:Bounds height="80.0" width="100.0" x="550.0" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-DB230500-F8E7-4796-866E-80AE4F5759D5" id="BPMNShape_sid-DB230500-F8E7-4796-866E-80AE4F5759D5">
        <omgdc:Bounds height="40.0" width="40.0" x="695.0" y="158.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-D9764532-4C6A-4087-A440-B3F3F032A077" id="BPMNShape_sid-D9764532-4C6A-4087-A440-B3F3F032A077">
        <omgdc:Bounds height="28.0" width="28.0" x="780.0" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-9263F9A7-58B4-4C62-8ECF-93B4FD76626F" id="BPMNShape_sid-9263F9A7-58B4-4C62-8ECF-93B4FD76626F">
        <omgdc:Bounds height="40.0" width="40.0" x="465.0" y="158.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-96173B13-7480-43F0-9B3E-EC1CA76D5446" id="BPMNEdge_sid-96173B13-7480-43F0-9B3E-EC1CA76D5446" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
        <omgdi:waypoint x="274.9499999999907" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="319.9999999999807" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-FC660276-FC1E-4D66-8E70-0D32D2843014" id="BPMNEdge_sid-FC660276-FC1E-4D66-8E70-0D32D2843014" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="20.5" flowable:targetDockerY="20.5">
        <omgdi:waypoint x="649.9499999999977" y="178.21623376623376"></omgdi:waypoint>
        <omgdi:waypoint x="695.4130434782554" y="178.41304347826085"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-91377CDC-8D11-4E59-BE0D-C186C658D62E" id="BPMNEdge_sid-91377CDC-8D11-4E59-BE0D-C186C658D62E" flowable:sourceDockerX="20.5" flowable:sourceDockerY="20.5" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">
        <omgdi:waypoint x="734.5591869398207" y="178.3782051282051"></omgdi:waypoint>
        <omgdi:waypoint x="780.0002755524838" y="178.08885188426407"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-84B59206-7F5E-43C5-BDB8-EB7D0F822160" id="BPMNEdge_sid-84B59206-7F5E-43C5-BDB8-EB7D0F822160" flowable:sourceDockerX="20.5" flowable:sourceDockerY="20.5" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
        <omgdi:waypoint x="715.5" y="158.5"></omgdi:waypoint>
        <omgdi:waypoint x="715.5" y="65.5"></omgdi:waypoint>
        <omgdi:waypoint x="225.0" y="65.5"></omgdi:waypoint>
        <omgdi:waypoint x="225.0" y="138.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-65EE4768-D3FD-49E8-8A1E-190A06207DF9" id="BPMNEdge_sid-65EE4768-D3FD-49E8-8A1E-190A06207DF9" flowable:sourceDockerX="20.5" flowable:sourceDockerY="20.5" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
        <omgdi:waypoint x="504.5247370727428" y="178.41666666666663"></omgdi:waypoint>
        <omgdi:waypoint x="549.9999999999953" y="178.21812227074236"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-3918DA4F-F9CA-4A67-847F-D7934807ECED" id="BPMNEdge_sid-3918DA4F-F9CA-4A67-847F-D7934807ECED" flowable:sourceDockerX="20.5" flowable:sourceDockerY="20.5" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
        <omgdi:waypoint x="485.5" y="197.4418389319552"></omgdi:waypoint>
        <omgdi:waypoint x="485.5" y="294.5"></omgdi:waypoint>
        <omgdi:waypoint x="225.0" y="294.5"></omgdi:waypoint>
        <omgdi:waypoint x="225.0" y="217.95000000000002"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-7EDC7758-DF02-4ED4-9EA8-1E169B31107E" id="BPMNEdge_sid-7EDC7758-DF02-4ED4-9EA8-1E169B31107E" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">
        <omgdi:waypoint x="129.9499984899576" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="174.9999999999917" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-624203DD-6504-480B-8558-8D3E929D50AB" id="BPMNEdge_sid-624203DD-6504-480B-8558-8D3E929D50AB" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="20.5" flowable:targetDockerY="20.5">
        <omgdi:waypoint x="419.94999999999806" y="178.21623376623378"></omgdi:waypoint>
        <omgdi:waypoint x="465.4130434782609" y="178.4130434782609"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

后台系统搭建

maven引入

<dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-engine</artifactId>
            <version>6.4.2</version>
</dependency>
 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
</dependency>

数据库信息配置

server.port=8081
## ==============================
## MySQL connection config
## ==============================
spring.datasource.url=jdbc:mysql://localhost:3306/flowable_db?useUnicode=true&characeterEncoding=utf-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=*****

Flowable引擎在使用前需要先通过配置来初始化ProcessEngine。

初始化ProcessEngineConfiguration一般有两种方式:
1.通过Spinrg配置文件进行依赖注入,通过flowable.cfg.xml文件来初始化ProcessEngineConfiguration(这里的文件名必须为flowable.cfg.xml,否则Flowable识别不到)
2.通过编写程序的方式来构造ProcessEngineConfiguration对象



ProcessEngineConfiguration在初始化过程中会同时初始化数据库,如果数据库已经存在,则不会做创建更新操作,如果数据库不存在,则会默认执行数据库创建脚本


flowable.cfg.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 生成流程图参数 -->
    <bean id="processDiagramGenerator" class="org.flowable.image.impl.DefaultProcessDiagramGenerator" />

    <bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/flowable_db?useUnicode=true&amp;characeterEncoding=utf-8&amp;serverTimezone=UTC" />
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="***" />
        <property name="databaseSchemaUpdate" value="true" />
        <property name="asyncExecutorActivate" value="false" />
        <!-- 流程部署时自动生成对应的图片 -->
        <property name="createDiagramOnDeploy" value="true" />
        <!-- 生成流程图参数 -->
        <property name="processDiagramGenerator" ref="processDiagramGenerator" />
        <!-- 流程图字体 -->
        <property name="activityFontName" value="宋体" />
        <property name="labelFontName" value="宋体" />
        <property name="annotationFontName" value="宋体" />
    </bean>
</beans>

执行下面的程序自动生成相关的表

package com.example.flowabledemo;

import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FlowabledemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FlowabledemoApplication.class, args);
        //如果配置文件位于resources/flowable.cfg.xml,则可以这样获取引擎
        //获取引擎时就会自动在数据库中创建相关的表
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    }

}

生成好了数据表


Flowable数据库解释

数据库

1、Flowable的所有数据库表都以ACT_开头。第二部分是说明表用途的两字符标示符。服务API的命名也大略符合这个规则。

2、ACT_RE_: 'RE’代表repository。带有这个前缀的表包含“静态”信息,例如流程定义与流程资源(图片、规则等)。

3、ACT_RU_: 'RU’代表runtime。这些表存储运行时信息,例如流程实例(process instance)、用户任务(user task)、变量(variable)、作业(job)等。Flowable只在流程实例运行中保存运行时数据,并在流程实例结束时删除记录。这样保证运行时表小和快。

4、ACT_HI_: 'HI’代表history。这些表存储历史数据,例如已完成的流程实例、变量、任务等。

5、ACT_GE_: 通用数据。在多处使用。

1)通用数据表(2个)

  • act_ge_bytearray:二进制数据表,如流程定义、流程模板、流程图的字节流文件;

  • act_ge_property:属性数据表(不常用);

2)历史表(8个,HistoryService接口操作的表)

  • act_hi_actinst:历史节点表,存放流程实例运转的各个节点信息(包含开始、结束等非任务节点);

  • act_hi_attachment:历史附件表,存放历史节点上传的附件信息(不常用);

  • act_hi_comment:历史意见表;

  • act_hi_detail:历史详情表,存储节点运转的一些信息(不常用);

  • act_hi_identitylink:历史流程人员表,存储流程各节点候选、办理人员信息,常用于查询某人或部门的已办任务;

  • act_hi_procinst:历史流程实例表,存储流程实例历史数据(包含正在运行的流程实例);

  • act_hi_taskinst:历史流程任务表,存储历史任务节点;

  • act_hi_varinst:流程历史变量表,存储流程历史节点的变量信息;

3)用户相关表(4个,IdentityService接口操作的表)

  • act_id_group:用户组信息表,对应节点选定候选组信息;

  • act_id_info:用户扩展信息表,存储用户扩展信息;

  • act_id_membership:用户与用户组关系表;

  • act_id_user:用户信息表,对应节点选定办理人或候选人信息;

4)流程定义、流程模板相关表(3个,RepositoryService接口操作的表)

  • act_re_deployment:部属信息表,存储流程定义、模板部署信息;

  • act_re_procdef:流程定义信息表,存储流程定义相关描述信息,但其真正内容存储在act_ge_bytearray表中,以字节形式存储;

  • act_re_model:流程模板信息表,存储流程模板相关描述信息,但其真正内容存储在act_ge_bytearray表中,以字节形式存储;

5)流程运行时表(6个,RuntimeService接口操作的表)

  • act_ru_task:运行时流程任务节点表,存储运行中流程的任务节点信息,重要,常用于查询人员或部门的待办任务时使用;

  • act_ru_event_subscr:监听信息表,不常用;

  • act_ru_execution:运行时流程执行实例表,记录运行中流程运行的各个分支信息(当没有子流程时,其数据与act_ru_task表数据是一一对应的);

  • act_ru_identitylink:运行时流程人员表,重要,常用于查询人员或部门的待办任务时使用;

  • act_ru_job:运行时定时任务数据表,存储流程的定时任务信息;

  • act_ru_variable:运行时流程变量数据表,存储运行中的流程各节点的变量信息;

# 流程引擎API与服务

引擎API是与Flowable交互的最常用手段。总入口点是ProcessEngine。

1、RepositoryService很可能是使用Flowable引擎要用的第一个服务。这个服务提供了管理与控制部署(deployments)与流程定义(processdefinitions)的操作。管理静态信息,
2、RuntimeService用于启动流程定义的新流程实例。
3、IdentityService很简单。它用于管理(创建,更新,删除,查询……)组与用户。
4、FormService是可选服务。也就是说Flowable没有它也能很好地运行,而不必牺牲任何功能。
5、HistoryService暴露Flowable引擎收集的所有历史数据。要提供查询历史数据的能力。
6、ManagementService通常在用Flowable编写用户应用时不需要使用。它可以读取数据库表与表原始数据的信息,也提供了对作业(job)的查询与管理操作。
7、DynamicBpmnService可用于修改流程定义中的部分内容,而不需要重新部署它。例如可以修改流程定义中一个用户任务的办理人设置,或者修改一个服务任务中的类名。

部署流程

随便写一个test

public class FlowAbleCreateTest {
    @Test
    public void deploymentProcess() {
        //获取ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //部署流程
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("./请假审批.bpmn20.xml") //部署资源
                .name("请假审批") //部署名称
                .deploy();
        System.out.println("部署名:"+deployment.getName());
        System.out.println("部署id:"+deployment.getId());
    }
}


完成上面的部署后相关数据保存到如下3张表中:
1.流程部署表:每部署一次增加一条记录

2.流程定义表:部署每个新的流程就会在这张表中增加一条记录
-- 注意,KEY_ 这个字段是用来唯一识别不同流程的关键字
3.流程资源表
act_re_deployment和act_re_procdef一对多关系,一次部署在流程部署表生成一条记录,
但一次部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。
每一个流程定义在act_ge_bytearray会存在两个资源记录,bpmn和png。
建议:一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。

启动流程

    @Test
    public void runtimeProcess() {
        //获取ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //根据流程key启动对应的流程,创建流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave_approve");

        //流程部署id:1
        System.out.println("流程部署id:" + processInstance.getDeploymentId());
        //流程定义id:evectionProcess:1:4
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        //流程实例id:2501
        System.out.println("流程实例id:" + processInstance.getId());
    }

完成上面的启动流程后相关数据保存到如下7张表中:

act_hi_actinst 流程实例执行历史信息
act_hi_identitylink 流程参与用户的历史信息
act_hi_procinst 流程实例的历史信息
act_hi_taskinst 流程任务的历史信息
act_ru_execution 流程执行信息
act_ru_identitylink 流程的正在参与用户信息
act_ru_task 流程当前任务信息

更多详情:https://static.kancloud.cn/king_om/liuchengyiqin001/3023127

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容