日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Activiti 工作流引擎的初步使用

發(fā)布時(shí)間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Activiti 工作流引擎的初步使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近領(lǐng)導(dǎo)讓我研究下工作流,于是查啊查就查到了Activiti,特么剛開(kāi)始一直查的是Activity,查出來(lái)一堆Android的東西,我也是醉了。話不多說(shuō),下面就記錄下這2天的研究成果吧。

所用環(huán)境

Maven工程
 JDK:jdk1.8.0_73
 IDE:eclipse Mars.2 Release (4.5.2)
 數(shù)據(jù)庫(kù):mysql 5.1.39-ndb-7.0.9-cluster-gpl
 SSM框架:(spring + spring-mvc)4.3.2.RELEASE + mybatis3.4.1
 Activiti:5.21.0

spring+mvc+mybatis整合就不貼了,網(wǎng)上一大堆了

eclipse安裝流程設(shè)計(jì)插件

eclipse依次點(diǎn)擊 Help -> Install New Software -> Add:
 Name:Activiti Designer
 Location:http://activiti.org/designer/update/
 點(diǎn)擊OK選中插件安裝即可

添加 Activiti 到項(xiàng)目中

  • 在 pom.xml 中添加 Activiti 依賴
    <activiti.version>5.21.0</activiti.version>

    <dependency><groupId>org.activiti</groupId><artifactId>activiti-engine</artifactId><version>${activiti.version}</version></dependency><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring</artifactId><version>${activiti.version}</version></dependency><dependency><groupId>org.activiti</groupId><artifactId>activiti-rest</artifactId><version>${activiti.version}</version></dependency>
  • 2.新建 applicationContext-activiti.xml,別忘了在主配置文件中將其import
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

    <!-- 流程配置 --><bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"><property name="dataSource" ref="dataSource" /><property name="transactionManager" ref="transactionManager" /><property name="databaseSchemaUpdate" value="true" /><property name="jobExecutorActivate" value="true" /><!-- 以下2個(gè)是為了防止生成流程圖片時(shí)出現(xiàn)亂碼 --><property name="activityFontName" value="宋體"/> <property name="labelFontName" value="宋體"/> </bean><!-- 流程引擎 --><bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean"><property name="processEngineConfiguration" ref="processEngineConfiguration" /></bean><!-- 流程服務(wù) --><bean id="repositoryService" factory-bean="processEngine"factory-method="getRepositoryService" /><bean id="runtimeService" factory-bean="processEngine"factory-method="getRuntimeService" /><bean id="taskService" factory-bean="processEngine"factory-method="getTaskService" /><bean id="historyService" factory-bean="processEngine"factory-method="getHistoryService" /><bean id="managementService" factory-bean="processEngine"factory-method="getManagementService" /><bean id="IdentityService" factory-bean="processEngine"factory-method="getIdentityService" /></beans>

    3.啟動(dòng)項(xiàng)目,如果未出現(xiàn)錯(cuò)誤,Activiti會(huì)在連接的數(shù)據(jù)庫(kù)中自動(dòng)新建25張表,如下:

    25張表.png

    至此Activiti流程引擎添加完畢,下面開(kāi)始使用Activiti,實(shí)現(xiàn)一次請(qǐng)假流程

    設(shè)計(jì)流程

    流程設(shè)計(jì)插件安裝成功后會(huì)在eclipse新建向?qū)е谐霈F(xiàn)Activiti向?qū)?如圖

    Paste_Image.png

    1.我們新建一個(gè) Activiti Diagram 命名為 leave.bpmn,完成時(shí)如下圖:

    Paste_Image.png

    主要就是拖拖拉拉,從左至右控件分別為
    StartEvent,UserTask,ExlusiveGateway,UserTask,EndEvent;連線都是SequenceFlow

    屬性可在Properties視圖中設(shè)置,如果沒(méi)有這個(gè)視圖,可在 eclipse 中依次點(diǎn)擊
    Window->Show View->Other 搜索Properties點(diǎn)擊OK即可

    • 流程屬性:一般設(shè)置一個(gè)Id,Name,NameSpace就可以了,此處為分別為leaveProcess、Leave Process、http://www.mario.com; 這個(gè)Id在之后啟動(dòng)流程時(shí)會(huì)用到,不同流程Id不可相同
    • 開(kāi)始事件(StartEvent):流程開(kāi)始
    • 結(jié)束事件(EndEvent):流程結(jié)束
    • 用戶任務(wù)(UserTask):主要用到Id,Name,Assignee
      Assignee為此任務(wù)的辦理人,在查找任務(wù)時(shí)需要用到,三個(gè)任務(wù)分別指派給 apply,pm,boss

    Paste_Image.png

    Paste_Image.png

    • 排他網(wǎng)關(guān)(ExlusiveGateway):只會(huì)尋找唯一一條能走完的順序流
    • 順序流(SequenceFlow):主要用到Id,Name,Condition
      Condition用于指定該順序流表達(dá)式 ,day的值會(huì)在調(diào)用執(zhí)行任務(wù)方法時(shí)傳入

    Paste_Image.png

    除了使用可視化組件,我們也可以通過(guò)xml來(lái)設(shè)計(jì)流程,以上流程的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:activiti="http://activiti.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.mario.com"><process id="leaveProcess" name="Leave Process" isExecutable="true"><startEvent id="startevent1" name="開(kāi)始"></startEvent><userTask id="usertask1" name="請(qǐng)假申請(qǐng)" activiti:assignee="apply"></userTask><exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway><sequenceFlow id="flow2" name="天數(shù)判斷" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow><userTask id="usertask2" name="審批(項(xiàng)目經(jīng)理)" activiti:assignee="pm"></userTask><sequenceFlow id="flow3" name="小于等于三天" sourceRef="exclusivegateway1" targetRef="usertask2"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${day<=3}]]></conditionExpression></sequenceFlow><userTask id="usertask3" name="審批(老板)" activiti:assignee="boss"></userTask><sequenceFlow id="flow4" name="大于三天" sourceRef="exclusivegateway1" targetRef="usertask3"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${day>3}]]></conditionExpression></sequenceFlow><endEvent id="endevent1" name="End"></endEvent><sequenceFlow id="flow5" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow><sequenceFlow id="flow6" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow><sequenceFlow id="flow7" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_leaveProcess"><bpmndi:BPMNPlane bpmnElement="leaveProcess" id="BPMNPlane_leaveProcess"><bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"><omgdc:Bounds height="35.0" width="35.0" x="30.0" y="211.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"><omgdc:Bounds height="55.0" width="105.0" x="110.0" y="201.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"><omgdc:Bounds height="40.0" width="40.0" x="285.0" y="208.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"><omgdc:Bounds height="55.0" width="105.0" x="400.0" y="120.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3"><omgdc:Bounds height="55.0" width="105.0" x="400.0" y="290.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"><omgdc:Bounds height="35.0" width="35.0" x="560.0" y="211.0"></omgdc:Bounds></bpmndi:BPMNShape><bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"><omgdi:waypoint x="215.0" y="228.0"></omgdi:waypoint><omgdi:waypoint x="285.0" y="228.0"></omgdi:waypoint><bpmndi:BPMNLabel><omgdc:Bounds height="14.0" width="48.0" x="230.0" y="228.0"></omgdc:Bounds></bpmndi:BPMNLabel></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"><omgdi:waypoint x="305.0" y="208.0"></omgdi:waypoint><omgdi:waypoint x="452.0" y="175.0"></omgdi:waypoint><bpmndi:BPMNLabel><omgdc:Bounds height="14.0" width="100.0" x="295.0" y="180.0"></omgdc:Bounds></bpmndi:BPMNLabel></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"><omgdi:waypoint x="305.0" y="248.0"></omgdi:waypoint><omgdi:waypoint x="452.0" y="290.0"></omgdi:waypoint><bpmndi:BPMNLabel><omgdc:Bounds height="14.0" width="48.0" x="285.0" y="257.0"></omgdc:Bounds></bpmndi:BPMNLabel></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"><omgdi:waypoint x="452.0" y="175.0"></omgdi:waypoint><omgdi:waypoint x="577.0" y="211.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"><omgdi:waypoint x="452.0" y="290.0"></omgdi:waypoint><omgdi:waypoint x="577.0" y="246.0"></omgdi:waypoint></bpmndi:BPMNEdge><bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7"><omgdi:waypoint x="65.0" y="228.0"></omgdi:waypoint><omgdi:waypoint x="110.0" y="228.0"></omgdi:waypoint></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram> </definitions>

    流程部署

    有了流程圖,我們就可以部署該流程了,Activiti提供多種部署方法(有自動(dòng)部署,手動(dòng)部署等),這里演示兩種手動(dòng)部署方法

    Workflow.java代碼片段

    private static ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); /*** 通過(guò)定義好的流程圖文件部署,一次只能部署一個(gè)流程*/ public static void deploy() {RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deployment = repositoryService.createDeployment().addClasspathResource("death/note/lawliet/web/workflow/leave.bpmn").deploy(); } /*** 將多個(gè)流程文件打包部署,一次可以部署多個(gè)流程*/ public void deployByZip() {InputStream is = this.getClass().getClassLoader().getResourceAsStream("diagrams/bpm.zip");ZipInputStream zip = new ZipInputStream(is);Deployment deployment = processEngine.getRepositoryService().createDeployment().addZipInputStream(zip).deploy(); }

    方便起見(jiàn),通過(guò)一個(gè)Deploy按鈕來(lái)部署流程

    Paste_Image.png

    部署成功后,會(huì)分別在 act_ge_bytearray,act_re_deployment,act_re_procdef三張表插入相應(yīng)數(shù)據(jù),多次部署同一流程的話會(huì)增加版本號(hào),以此獲取最新的流程

    啟動(dòng)流程

    我們通過(guò)一個(gè)表單來(lái)用于請(qǐng)假申請(qǐng)

    Paste_Image.png

    我們定義一個(gè) Leave 對(duì)象用于保存請(qǐng)假信息,相應(yīng)的數(shù)據(jù)表為 leave 。Result 對(duì)象用于封裝一些返回信息。這里的 "leaveProcess" 就是在流程屬性中定義的Id。啟動(dòng)成功后會(huì)返回一個(gè) ProcessInstance 對(duì)象,這個(gè)對(duì)象主要是一些流程的基本信息,具體可以查看文檔或源碼。這里將返回的流程實(shí)例 id 存入到我們的 leave 表,以便以后可以通過(guò)這個(gè) id 查詢相關(guān)的流程。

    @ResponseBody @RequestMapping(value = "/save", method = RequestMethod.POST) public Result save(@RequestBody Leave user) {Result result = new Result();ProcessInstance pi = Workflow.startInstanceByKey("leaveProcess");user.setInstaceId(pi.getId());leaveService.insert(user);result.info(true, 0, "保存成功");return result; }

    Workflow.java代碼片段

    public static ProcessInstance startInstanceByKey(String instanceByKey) {RuntimeService runtimeService = processEngine.getRuntimeService();ProcessInstance instance = runtimeService.startProcessInstanceByKey(instanceByKey);return instance; }

    流程啟動(dòng)成功后會(huì)在 act_hi_actinst,act_hi_identitylink,act_hi_procinst,act_hi_taskinst,act_ru_execution,act_ru_identitylink,act_ru_task 表中插入相應(yīng)數(shù)據(jù)。我們比較關(guān)心的就是 act_ru_task 表了,它存儲(chǔ)了任務(wù)的相關(guān)信息。

    查看任務(wù)

    流程啟動(dòng)完畢后,應(yīng)該就是進(jìn)入了請(qǐng)假申請(qǐng)任務(wù),我們可以通過(guò)請(qǐng)假申請(qǐng)的辦理人 apply 來(lái)查詢?cè)撊蝿?wù)(當(dāng)然還有其他方法),這里可以指定不同查詢條件和過(guò)濾條件。返回 taskList 就是當(dāng)前的任務(wù)列表了,Task是Activiti為我們定義好的接口對(duì)象,主要封裝了任務(wù)的信息。
     這里由于 Activiti 的Task是接口對(duì)象無(wú)法轉(zhuǎn)換為json,所以自定義了一個(gè)Task對(duì)象,來(lái)轉(zhuǎn)換成json

    @ResponseBody @RequestMapping(value = "/data/{assignee}") public List<death.note.lawliet.web.model.Task> data(@PathVariable String assignee){List<Task> tasks = Workflow.findTaskByAssignee(assignee);List<death.note.lawliet.web.model.Task> list = new ArrayList<>();for(Task task : tasks){death.note.lawliet.web.model.Task t = new death.note.lawliet.web.model.Task();t.setTaskId(task.getId());t.setName(task.getName());t.setAssignee(task.getAssignee());t.setExecutionId(task.getExecutionId());t.setProcessInstanceId(task.getProcessInstanceId());t.setProcessDefinitionId(task.getProcessDefinitionId());list.add(t);}return list; }

    Workflow.java代碼片段

    public static List<Task> findTaskByAssignee(String assignee) {TaskService taskService = processEngine.getTaskService();List<Task> taskList = taskService.createTaskQuery().taskAssignee(assignee).list();return taskList; }

    Paste_Image.png

    查看流程圖

    我們可以通過(guò)流程定義ID(processDefinitionId)來(lái)獲取流程圖

    @RequestMapping(value = "/shwoImg/{procDefId}") public void shwoImg(@PathVariable String procDefId,HttpServletResponse response){ try { InputStream pic = Workflow.findProcessPic(procDefId); byte[] b = new byte[1024]; int len = -1; while((len = pic.read(b, 0, 1024)) != -1) { response.getOutputStream().write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); } }

    Workflow.java代碼片段

    public static InputStream findProcessPic(String procDefId) throws Exception {RepositoryService repositoryService = processEngine.getRepositoryService();ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();String diagramResourceName = procDef.getDiagramResourceName();InputStream imageStream = repositoryService.getResourceAsStream(procDef.getDeploymentId(), diagramResourceName);return imageStream; }

    然后通過(guò)processDefinitionId,executionId 來(lái)獲取當(dāng)前正在執(zhí)行任務(wù)的位置坐標(biāo),以便用于標(biāo)識(shí)流程圖上的位置。ActivityImpl 對(duì)象封裝了任務(wù)的位置信息,包括xy坐標(biāo),長(zhǎng)和寬。自定義 Rect 對(duì)象用于轉(zhuǎn)換json

    @ResponseBody @RequestMapping(value = "/showImg/{procDefId}/{executionId}") public Rect showImg(@PathVariable String procDefId,@PathVariable String executionId ) {Rect rect = new Rect();try {ActivityImpl img = Workflow.getProcessMap(procDefId,executionId );rect.setX(img.getX());rect.setY(img.getY());rect.setWidth(img.getWidth());rect.setHeight(img.getHeight());} catch (Exception e) {e.printStackTrace();}return rect; }

    Workflow.java代碼片段

    public static ActivityImpl getProcessMap(String procDefId, String executionId) throws Exception {ActivityImpl actImpl = null;RepositoryService repositoryService = processEngine.getRepositoryService();//獲取流程定義實(shí)體ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(procDefId);RuntimeService runtimeService = processEngine.getRuntimeService();//獲取執(zhí)行實(shí)體ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery().executionId(executionId).singleResult();// 獲取當(dāng)前任務(wù)執(zhí)行到哪個(gè)節(jié)點(diǎn)String activitiId = execution.getActivityId();// 獲得當(dāng)前任務(wù)的所有節(jié)點(diǎn)List<ActivityImpl> activitiList = def.getActivities();for (ActivityImpl activityImpl : activitiList) {String id = activityImpl.getId();if (id.equals(activitiId)) {actImpl = activityImpl;break;}}return actImpl; }

    最終生成圖片時(shí)分別調(diào)用2個(gè) showImg 方法即可,紅框可以根據(jù)返回的 Rect 來(lái)繪制,起始坐標(biāo)根據(jù)自己的布局自行調(diào)整

    LeavePicController.js片段

    var pic.rect = {}; var pic.procDefId = $stateParams.procDefId; $http.get('workflow/showImg/'+$stateParams.procDefId +'/'+$stateParams.executionId) .success(function(data) {pic.rect.x = data.x;pic.rect.y = data.y;pic.rect.width = data.width;pic.rect.height = data.height;});

    picture.html

    <div class="container-fluid" ng-controller="LeavePicController as pic"><img src="workflow/showImg/{{pic.procDefId}}"><div style="position:absolute; border:2px solid red;left:{{pic.rect.x + 20 }}px;top:{{pic.rect.y + 88 }}px;width:{{pic.rect.width }}px;height:{{pic.rect.height }}px;"></div> </div>

    Paste_Image.png

    流程審批

    通過(guò) taskId 就可以對(duì)當(dāng)前執(zhí)行的任務(wù)進(jìn)行審批,這里的 day 應(yīng)該從 leave 表中查詢出來(lái),方便起見(jiàn)就寫(xiě)死了,這個(gè)day也就是在順序流的Condition中指定的變量,小于等于3就會(huì)流向項(xiàng)目經(jīng)理(pm)審批任務(wù)了

    @ResponseBody @RequestMapping(value = "/check/{taskId}") public Result check(@PathVariable String taskId) {Result result = new Result();Map<String, Object> map = new HashMap<>();map.put("day", 3);Workflow.completeTask(taskId,map);result.info(true, 0, "審批成功");return result; }

    Workflow.java代碼片段

    public static void completeTask(String taskid,Map<String, Object> map map) {TaskService taskService = processEngine.getTaskService();taskService.complete(taskid, map); }

    審批成功后,就需要通過(guò)辦理人(pm)來(lái)查詢?nèi)蝿?wù)了,并且請(qǐng)假辦理(apply)中的任務(wù)被移除了

    Paste_Image.png

    Paste_Image.png

    同時(shí)流程圖也流向了下一節(jié)點(diǎn)

    Paste_Image.png

    項(xiàng)目經(jīng)理再執(zhí)行一次審批方法,這個(gè)流程就算走完了

    最后

    以上就是一次相對(duì)簡(jiǎn)單的流程:部署,啟動(dòng),查詢?nèi)蝿?wù),顯示流程圖,審批。Activiti流程引擎還有很多核心操作,包括駁回、會(huì)簽、轉(zhuǎn)辦、中止、掛起等,等有空的時(shí)候再深入研究吧
     最后的最后,初來(lái)乍到,不喜勿噴或輕噴 - -!Thanks...



    作者:影秋
    鏈接:https://www.jianshu.com/p/bdc9c9fa719d
    來(lái)源:簡(jiǎn)書(shū)
    ?

    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的Activiti 工作流引擎的初步使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产精品久久777777换脸 | 欧美日韩精品一区二区在线观看 | 黄色大片儿. | 新91视频在线观看 | 黄色大片91| 色老大网站 | 成人黄色视屏 | 亚洲精品国产视频 | 97se亚洲国产综合在线 | 6080福利| 黑鬼大战白妞高潮喷白浆 | 在线观看a网站 | 国产黄色高清 | 成人在线免费视频 | 成人综合激情 | 伊人操 | 超碰五月天 | 日本免费三片在线播放 | 国产伦理精品 | www.三区| 成年人黄色av | 黄色精彩视频 | 久久久888 | 99久久精品免费视频 | a∨鲁丝一区鲁丝二区鲁丝三区 | 精品美女一区 | 亚洲欧美乱综合图片区小说区 | 涩涩的视频在线观看 | 久热国产在线 | 99爱视频在线 | 午夜精品福利一区二区三区蜜桃 | 一区二区不卡视频在线观看 | 九色91porny | 精品国产av一区二区三区 | 欧美精品一级二级三级 | 涩涩天堂 | 国产女大学生av | 色噜噜在线观看 | 99一区二区三区 | 欧美成人一区二区三区高清 | 日韩香蕉视频 | 国产天堂久久 | 欧美日韩免费一区二区 | 在线观看色网站 | 重口变态虐黄网站 | 一本久道视频一本久道 | 好色艳妇小说 | 91在线精品视频 | 成人免费在线小视频 | 九九综合视频 | 欧美一区二区激情 | 色妹子综合 | 欧美黑人又粗又大的性格特点 | 91在线观看免费高清完整版在线观看 | 肉色丝袜脚交一区二区 | 久草免费福利 | 性欧美1819性猛交 | 三上悠亚痴汉电车 | h视频在线免费观看 | 日本h片在线观看 | 亚洲一区视频在线播放 | 日韩在线中文 | 91精品久久久久久粉嫩 | 一区二区在线观看免费视频 | 国产美女无遮挡网站 | 网站黄色在线观看 | 国产成人精品久久二区二区 | xxxwww国产 | 91丨九色丨蝌蚪丨丝袜 | 久草手机在线观看 | 在线理论视频 | 殴美毛片 | 久久影院视频 | 免费的av网址 | 日本美女啪啪 | 日本精品国产 | 日本美女影院 | 制服.丝袜.亚洲.中文.综合 | 亚洲成人第一 | 欧美亚洲视频一区 | 国产三级国产精品国产国在线观看 | 亚洲 欧美 另类 综合 偷拍 | 欧产日产国产69 | 小罗莉极品一线天在线 | 国产第一草草影院 | 中文字幕日韩无 | 久久国产情侣 | 欧美不卡一区二区三区 | 国产精品免费网站 | 欧美黄视频 | 校园春色在线观看 | 欧美极品少妇xxxxⅹ喷水 | 蜜桃av噜噜一区二区三区小说 | 日本性网站 | 有码视频在线观看 | 苏晴忘穿内裤坐公交车被揉到视频 | 日韩大片在线观看 | 精品人妻无码一区二区三 | 一区二区三区日韩视频 |