activiti學(xué)習(xí)筆記(一)hello world

工作中需要使用到activiti工作流引擎狭郑,于是在業(yè)余時(shí)間學(xué)習(xí)activiti相關(guān)的內(nèi)容腹暖,今天分享一個(gè)使用activiti來(lái)實(shí)現(xiàn)的請(qǐng)假流程,其中涉及分支條件的判斷和表單的填寫翰萨,下面就來(lái)分享下這個(gè)簡(jiǎn)單程序的內(nèi)容脏答。

環(huán)境搭建

使用maven來(lái)搭建工程,需要依賴如下:

<dependencies>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.197</version>
        </dependency>
    </dependencies>

使用h2數(shù)據(jù)庫(kù)的原因是activiti的默認(rèn)數(shù)據(jù)庫(kù)就是H2,方便簡(jiǎn)單測(cè)試亩鬼,此處加上h2的驅(qū)動(dòng)殖告。

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

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1536107421286" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="second_approve" isClosed="false" isExecutable="true" name="二級(jí)審批" processType="None">
    <startEvent id="startEvent" name="開(kāi)始"/>
    <userTask activiti:exclusive="true" id="submitForm" name="填寫審批信息">
      <extensionElements>
        <activiti:formProperty id="message" name="申請(qǐng)信息" required="true" type="string"/>
        <activiti:formProperty id="name" name="申請(qǐng)人姓名" required="true" type="string"/>
        <activiti:formProperty datePattern="yyyy-MM-dd" id="submitTime" name="提交時(shí)間" required="true" type="date"/>
        <activiti:formProperty id="submitType" name="提交類型" required="true" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow1" sourceRef="startEvent" targetRef="submitForm"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="decideSubmit" name="提交或取消"/>
    <sequenceFlow id="flow2" sourceRef="submitForm" targetRef="decideSubmit"/>
    <userTask activiti:exclusive="true" id="tl_approve" name="主管審批">
      <extensionElements>
        <activiti:formProperty id="tlApprove" name="主管審批結(jié)果" type="string"/>
        <activiti:formProperty id="tlMessage" name="主管備注" required="true" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow3" sourceRef="decideSubmit" targetRef="tl_approve">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "y" || submitType == "Y"}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway gatewayDirection="Unspecified" id="decideTLApprove" name="主管審批校驗(yàn)"/>
    <sequenceFlow id="flow4" sourceRef="tl_approve" targetRef="decideTLApprove"/>
    <userTask activiti:exclusive="true" id="hr_approve" name="人事審批">
      <extensionElements>
        <activiti:formProperty id="hrApprove" name="人事審批結(jié)果" required="true" type="string"/>
        <activiti:formProperty id="hrMessage" name="人事審批備注" required="true" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow5" sourceRef="decideTLApprove" targetRef="hr_approve">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${tlApprove == "y" || tlApprove == "Y"}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endEventCancel" name="取消"/>
    <sequenceFlow id="flow7" sourceRef="decideSubmit" targetRef="endEventCancel">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "n" || submitType == "N"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow8" sourceRef="decideTLApprove" targetRef="submitForm">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${tlApprove == "n" || tlApprove == "N"}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway gatewayDirection="Unspecified" id="decideHRApprove" name="人事審批校驗(yàn)"/>
    <sequenceFlow id="flow9" sourceRef="hr_approve" targetRef="decideHRApprove"/>
    <endEvent id="endEvent" name="結(jié)束"/>
    <sequenceFlow id="flow10" sourceRef="decideHRApprove" targetRef="endEvent">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApprove == "y" || hrApprove == "Y"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow11" sourceRef="decideHRApprove" targetRef="submitForm">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApprove == "n" || hrApprove == "N"}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="second_approve">
      <bpmndi:BPMNShape bpmnElement="startEvent" id="Shape-startEvent">
        <omgdc:Bounds height="32.0" width="32.0" x="-17.5" y="-17.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="submitForm" id="Shape-submitForm">
        <omgdc:Bounds height="55.0" width="105.0" x="-52.5" y="-27.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decideSubmit" id="Shape-decideSubmit" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="-20.0" y="-20.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="tl_approve" id="Shape-tl_approve">
        <omgdc:Bounds height="55.0" width="105.0" x="-52.5" y="-27.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decideTLApprove" id="Shape-decideTLApprove" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="-20.0" y="-20.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="hr_approve" id="Shape-hr_approve">
        <omgdc:Bounds height="55.0" width="105.0" x="-52.5" y="-27.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endEventCancel" id="Shape-endEventCancel">
        <omgdc:Bounds height="32.0" width="32.0" x="-17.5" y="-17.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decideHRApprove" id="Shape-decideHRApprove" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="-20.0" y="-20.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endEvent" id="Shape-endEvent">
        <omgdc:Bounds height="32.0" width="32.0" x="-17.5" y="-17.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1" sourceElement="startEvent" targetElement="submitForm">
        <omgdi:waypoint x="14.992185591719476" y="-1.5"/>
        <omgdi:waypoint x="-1.5" y="-27.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2" sourceElement="submitForm" targetElement="decideSubmit">
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3" sourceElement="decideSubmit" targetElement="tl_approve">
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4" sourceElement="tl_approve" targetElement="decideTLApprove">
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5" sourceElement="decideTLApprove" targetElement="hr_approve">
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7" sourceElement="decideSubmit" targetElement="endEventCancel">
        <omgdi:waypoint x="12.0" y="-4.0"/>
        <omgdi:waypoint x="480.0" y="427.0"/>
        <omgdi:waypoint x="14.992185591719476" y="-1.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10" sourceElement="decideHRApprove" targetElement="endEvent">
        <omgdi:waypoint x="-4.0" y="-4.0"/>
        <omgdi:waypoint x="14.904008928568928" y="-2.75"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8" sourceElement="decideTLApprove" targetElement="submitForm">
        <omgdi:waypoint x="12.0" y="-4.0"/>
        <omgdi:waypoint x="714.0" y="466.0"/>
        <omgdi:waypoint x="362.0" y="466.0"/>
        <omgdi:waypoint x="53.0" y="0.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11" sourceElement="decideHRApprove" targetElement="submitForm">
        <omgdi:waypoint x="12.0" y="-4.0"/>
        <omgdi:waypoint x="997.0" y="290.0"/>
        <omgdi:waypoint x="410.0" y="290.0"/>
        <omgdi:waypoint x="53.0" y="0.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9" sourceElement="hr_approve" targetElement="decideHRApprove">
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

程序?qū)崿F(xiàn)

這里使用main方法+命令行交互的方法來(lái)實(shí)現(xiàn)流程流轉(zhuǎn),main方法中的內(nèi)容如下:

        logger.info("啟動(dòng)程序");

        // 創(chuàng)建流程引擎
        ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
        ProcessEngine processEngine = cfg.buildProcessEngine();
        String name = processEngine.getName();
        String version = ProcessEngine.VERSION;

        logger.info("流程引擎名稱:{},版本:{}",name,version);

        // 部署流程定義文件
        RepositoryService repositoryService = processEngine.getRepositoryService();
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
        deploymentBuilder.addClasspathResource("second_approve.bpmn20.xml");
        Deployment deployment = deploymentBuilder.deploy();
        String deploymentId = deployment.getId();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
                deploymentId(deploymentId).singleResult();

        logger.info("流程文件:{},流程定義id:{}",processDefinition.getName(),processDefinition.getId());

        // 啟動(dòng)流程
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
        logger.info("流程實(shí)例id為:{}",processInstance.getId());

        // 處理任務(wù)
        Scanner scanner = new Scanner(System.in);
        while (processInstance != null && !processInstance.isEnded()){

            TaskService taskService = processEngine.getTaskService();
            List<Task> taskList = taskService.createTaskQuery().list();

            for(Task task : taskList){
                logger.info("待處理任務(wù):{}",task.getName());
                FormService formService = processEngine.getFormService();
                TaskFormData taskFormData = formService.getTaskFormData(task.getId());
                List<FormProperty> formPropertyList = taskFormData.getFormProperties();
                Map<String,Object> variables = new HashMap<String,Object>();
                for(FormProperty formProperty : formPropertyList){
                    String line = null;
                    if(StringFormType.class.isInstance(formProperty.getType())){
                        logger.info("請(qǐng)輸入{}:",formProperty.getName());
                        line = scanner.nextLine();
                        variables.put(formProperty.getId(),line);
                    } else if(DateFormType.class.isInstance(formProperty.getType())){
                        logger.info("請(qǐng)輸入{}:(格式:yyyy-MM-dd)",formProperty.getName());
                        line = scanner.nextLine();
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        Date date = new Date();
                        try {
                            date = dateFormat.parse(line);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        variables.put(formProperty.getId(),date);
                    }
                    logger.info("您輸入的內(nèi)容是:{}",line);
                }

                taskService.complete(task.getId(),variables);
            }
            logger.info("待處理任務(wù)數(shù)量有{}個(gè)",taskList.size());
        }

        logger.info("結(jié)束程序");

上述首先創(chuàng)建流程引擎配置類,接著使用配置類創(chuàng)建流程引擎雳锋,然后使用流程引擎獲得各個(gè)service黄绩,通過(guò)這些service來(lái)實(shí)現(xiàn)流程部署,創(chuàng)建流程實(shí)例玷过,執(zhí)行每個(gè)節(jié)點(diǎn)的任務(wù)直到流程結(jié)束爽丹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辛蚊,隨后出現(xiàn)的幾起案子粤蝎,更是在濱河造成了極大的恐慌,老刑警劉巖嚼隘,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诽里,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡飞蛹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門灸眼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)卧檐,“玉大人,你說(shuō)我怎么就攤上這事焰宣∶骨簦” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵匕积,是天一觀的道長(zhǎng)盈罐。 經(jīng)常有香客問(wèn)我榜跌,道長(zhǎng),這世上最難降的妖魔是什么盅粪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任钓葫,我火速辦了婚禮,結(jié)果婚禮上票顾,老公的妹妹穿的比我還像新娘础浮。我一直安慰自己,他們只是感情好奠骄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布豆同。 她就那樣靜靜地躺著,像睡著了一般含鳞。 火紅的嫁衣襯著肌膚如雪影锈。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天蝉绷,我揣著相機(jī)與錄音精居,去河邊找鬼。 笑死潜必,一個(gè)胖子當(dāng)著我的面吹牛靴姿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播磁滚,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼佛吓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了垂攘?” 一聲冷哼從身側(cè)響起维雇,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晒他,沒(méi)想到半個(gè)月后吱型,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陨仅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年津滞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灼伤。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡触徐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狐赡,到底是詐尸還是另有隱情撞鹉,我是刑警寧澤疆导,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布冷冗,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芬骄。R本人自食惡果不足惜膳殷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一坪圾、第九天 我趴在偏房一處隱蔽的房頂上張望可缚。 院中可真熱鬧,春花似錦惶室、人聲如沸温自。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)悼泌。三九已至,卻和暖如春夹界,著一層夾襖步出監(jiān)牢的瞬間馆里,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工可柿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸠踪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓复斥,卻偏偏與公主長(zhǎng)得像营密,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子目锭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容