[Ionic 2從入門到精通] 5.4 使用相機拍照

本課的目標是整合Camera這樣我們可以用他來拍照了,但是要達到這個目標需要下點功夫踏堡。
除了要出發(fā)相機拍照之外,我們還要:

  • 將照片移動到手機上的持久儲存
  • 在模板中展示這些照片
  • 顯示其他的照片
  • 允許刪除照片
    這樣看來本課程還是蠻大的。在本應(yīng)用的開始部分我們設(shè)置了Ionic Native锅尘,也就是基礎(chǔ)部分里面的內(nèi)容,Ionic Native是Ionic包裝好的Cordova插件布蔗,使用更簡單藤违。
    本課程中將用到Ionic Native中的Camera插件和File插件。
    讓我們愉快的開始吧纵揍!

創(chuàng)建一個Photo數(shù)據(jù)模型

在我們添加相片功能之前顿乒,我們需要創(chuàng)建一個數(shù)據(jù)模型來代表照片對象。當我們想要存放照片存儲路徑泽谨,照片拍攝日期的時候璧榄。數(shù)據(jù)模型就能夠很輕松的處理這樣的事情,像這樣:

let photo = new PhotoModel('path/to/image', new Date());
rather than this:
let photo = {
    image: 'path/to/image',
    date: newDate
};

區(qū)別不是太明顯吧雹,也不是所有的原因都需要用到骨杂,但是是一個很好的模式,特別是當數(shù)據(jù)越來越復雜的時候吮炕。舉個復雜數(shù)據(jù)模型的例子腊脱,去看看Quick List課程,如果你還沒看過的話龙亲。
> 修改 src/models/photo-model.ts 為如下:

export class PhotoModel {
    constructor(public image: string, public date: Date){
        
    }
}

這個模型很直白陕凹,我們傳入了圖片和日期。如果想要在home.ts中使用他的話鳄炉,得先導入杜耙。
> 修改 src/pages/home/home.ts 為如下:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { PhotoModel } from '../../models/photo-model';

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})

export class HomePage {
    constructor(public navCtrl: NavController) {
    }
}

制作一個簡單的Alert服務(wù)

Surprise!(譯者:驚喜拂盯!好像不大好聽)在進入開心環(huán)節(jié)之前佑女,我們還有一個要做的事情。由于很多地方可能會有錯誤提示(拍照谈竿,移動照片)团驱,所以我們出發(fā)大量的警告框,當然空凸,事情處理好了之后我們也要告訴用戶一聲不是嚎花。
創(chuàng)建警告提示的語法是這樣的:

let alert = this.alertCtrl.create({
    title: "My Title",
    message: "My Message",
    buttons: [
        {
            text: 'Ok'
        }
    ]
});

alert.present();

代碼量還是有點的,如果我們在同一個文件里多次調(diào)用這個代碼呀洲,看起來會很亂紊选。所以我們新建另一個服務(wù)來處理這樣的事情啼止,就像數(shù)據(jù)模型一樣。創(chuàng)建完之后兵罢,我們就可以像下面這樣去彈出警告框:

let alert = this.simpleAlert.createAlert('Oops!', 'Something went wrong.');
alert.present();

> 修改 src/providers/simple-alert.ts 為如下:

import { Injectable } from '@angular/core';
import { AlertController } from 'ionic-angular';

@Injectable()
export class SimpleAlert {

    constructor(public alertCtrl: AlertController){
    }
    createAlert(title: string, message: string): any {
        return this.alertCtrl.create({
            title: title,
            message: message,
            buttons: [
                {
                    text: 'Ok'
                }
            ]
        });
    }
}

這里我們導入了AlertController服務(wù)用來創(chuàng)建警告框献烦,然后創(chuàng)建了一個函數(shù),結(jié)束一個title和一個message卖词,然后返回一個用這些信息組裝的的警告框巩那。這雖然給我們創(chuàng)建了警告提示框,但是展示還是要為我們手動去展示出來坏平。
> 修改 src/pages/home/home.ts 如下:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { PhotoModel } from '../../models/photo-model';
import { SimpleAlert } from '../../providers/simple-alert/simple-alert';

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})
export class HomePage {
    constructor(public navCtrl: NavController, public simpleAlert: SimpleAlert)
    {

    }
}

注意我們在構(gòu)造器里面注入了SimpleAlert和NavController拢操,但是沒有注入照片數(shù)據(jù)模型。這是因為每次我們要用到PhotoModel的時候舶替,我們都是通過new新建一個實例的令境,但是對于SimpleAlert而言我們都是一次一次調(diào)用他統(tǒng)一實例的同一函數(shù)的。

使用Camera照相

好了顾瞪,完成了照片模型和彈窗服務(wù)之后 -- 我們終于來到了有趣的部分了舔庶,也就是拍照陈醒。我們現(xiàn)在要使用Ionic Native的Camera插件惕橙,我們得先進行導入:
> 在 src/pages/home/home.ts 中加入以下導入語句:

import { Camera, File } from 'ionic-native';

現(xiàn)在钉跷,我們可以通過Camera對象來訪問這個功能了弥鹦。我們將一下如何使用這個插件,但是記住所有Ionic Native里面的插件都可以在這里找到文檔:http://ionicframework.com/docs/native/Camera/
在寫拍照相關(guān)的代碼之前膝晾,我們將要到構(gòu)造器里面添加一些變量臊旭,這樣后面就不要老是導入這個導入那個领跛,我們把應(yīng)用后面會用到的全部都導入進來好了。我們將要加入一些新的函數(shù)撤奸,一些引用了其他函數(shù)的函數(shù)吠昭。這樣我們就不會遇到函數(shù)undefined的問題,我們?nèi)慷x好胧瓜,但是都留空矢棚。我們后續(xù)會詳細實現(xiàn)他們(不全部是在本課中)。
> 修改 src/pages/home/home.ts 為如下:

import { Component } from '@angular/core';
import { ModalController, AlertController, Platform } from 'ionic-angular';
import { PhotoModel } from '../../models/photo-model';
import { SimpleAlert } from '../../providers/simple-alert';
import { SlideshowPage } from '../slideshow/slideshow';
import { Data } from '../../providers/data'
import { Camera, File } from 'ionic-native';

declare var cordova;

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})

export class HomePage {
    loaded: boolean = false;
    photoTaken: boolean = false;
    photos: PhotoModel[] = [];

    constructor(public dataService: Data, public platform: Platform, public  simpleAlert: SimpleAlert, public modalCtrl: ModalController, public  alertCtrl: AlertController) {

    }

    ionViewDidLoad(){
        // Uncomment to use test data
        /*this.photos = [
        new PhotoModel('http://placehold.it/100x100', new Date()),
        new PhotoModel('http://placehold.it/100x100', new Date()),
        new PhotoModel('http://placehold.it/100x100', new Date())
        ]*/
        this.platform.ready().then(() => {
            this.loadPhotos();
        });

        document.addEventListener('resume', () => {
            if(this.photos.length > 0){
                let today = new Date();
                if(this.photos[0].date.setHours(0,0,0,0) === today.setHours(0,0,0,0)){
                    this.photoTaken = true;
                } else {
                    this.photoTaken = false;
                }
            }
        }, false);
    }

    loadPhotos(): void {
    }

    takePhoto(): any {
    }

    createPhoto(photo): void {
    }

    removePhoto(photo): void {
    }

    playSlideshow(): void {
    }

    sharePhoto(image): void {
    }

    save(): void {
    }
}

上面的代碼中府喳,我們新增了一個成員變量loaded用于保持追蹤照片是否都從存儲中加載完成(下節(jié)課要做的)蒲肋,photoTaken用于標記今天是否有拍照,photos用于持有所有的照片數(shù)據(jù)钝满。由于照片只會在應(yīng)用運行在真實設(shè)備的情況下才會加載兜粘,所以我們在ionViewDidLoad中加入了一些測試數(shù)據(jù),我們在此處給this.photos添加了一個測試數(shù)據(jù)這樣就可以在瀏覽器中進行測試弯蚜。如果你想在測試的時候看到相片呈現(xiàn)孔轴,解除其中的注釋即可。(記得后面刪掉K檗唷)
我們已經(jīng)設(shè)置好了所有需要用到的服務(wù)的引用路鹰,包括稍后要用到的數(shù)據(jù)服務(wù)和平臺服務(wù)。
在這里我們也添加了一個奇怪的resume監(jiān)聽器收厨。resume事件的觸發(fā)時機是用戶把應(yīng)用發(fā)配到后臺然后重新使用的時候?qū)|發(fā)晋柱。例如,當用戶打開了你的應(yīng)用诵叁,然后去玩Facebook雁竞,然后有回到我們應(yīng)用的時候。我們這么做的原因是因為我們的photoTaken變量有一些極端的特例拧额。想象一下碑诉,某人今天拍照了,但是當他們關(guān)閉應(yīng)用但是沒有全部關(guān)閉的時候势腮,他只是被發(fā)配后臺联贩。第二天我們使用這個應(yīng)用的時候,我們在loadPhoto函數(shù)中運行的用于判斷當日是否拍照的邏輯將不會執(zhí)行捎拯,因為只是恢復而不是重新加載泪幌。所以當應(yīng)用恢復的時候,我們都要檢查最后照片拍攝日期是否跟今日日期椅子署照,然后根據(jù)他去設(shè)置photoTaken變量祸泪。
注意:我們這里加上來declare var cordova,這樣TypeScript不會抱怨:我根本不知道cordova是啥建芙。
現(xiàn)在我們將實現(xiàn)takePhoto函數(shù)没隘,這個函數(shù)是用來拍照的,所以我們先來個基礎(chǔ)版禁荸。
> 修改 takePhoto 函數(shù)為如下:

takePhoto(): any {

    if(!this.loaded || this.photoTaken){
        return false;
    }

    if(!this.platform.is('cordova')){
        console.log("You can only take photos on a device!");
        return false;
    }

    let options = {
        quality: 100,
        destinationType: 1, //return a path to the image on the device
        sourceType: 1, //use the camera to grab the image
        encodingType: 0, //return the image in jpeg format
        cameraDirection: 1, //front facing camera
        saveToPhotoAlbum: true //save a copy to the users photo album as well
    };

    Camera.getPicture(options).then((imagePath) => {
        console.log(imagePath);
    },
    (err) => {
        let alert = this.simpleAlert.createAlert('Oops!', 'Something went wrong.');
        alert.present();
    });
}

執(zhí)行Camera代碼之前右蒲,我們檢查了一系列的條件檢查阀湿。如果之前創(chuàng)建的變量顯示數(shù)據(jù)沒有加載完成的話,或者今日已拍照的話瑰妄,函數(shù)內(nèi)后面的代碼就不會執(zhí)行了陷嘴。我們也檢查了我們是否是運行在‘cordova’平臺上,也就是真機上间坐,如果沒有的話就直接退出函數(shù)灾挨。因為啊,你只能在真實設(shè)備上訪問這些插件竹宋,如果不是在真實設(shè)備上運行的話劳澄,那么除了報錯就只能報錯了。
接著我們設(shè)置了一些選項傳入Camera插件蜈七,這些配置了我們要干啥秒拔,我們要返回啥。這些值可以配置的東西包括宪潮,是否要用攝像頭或者用戶的照片庫溯警,返回圖片的格式,用前置攝像頭呢狡相,還是用后置攝像頭等等梯轻。我在每個選項后面都添加了注釋,來解釋他們分別是干啥的尽棕。
創(chuàng)建好了選項對象之后喳挑,我們調(diào)用了Camera對象的getPicture函數(shù)然后傳入其中。這個函數(shù)講會返回一個Promise滔悉,在執(zhí)行完成之后伊诵,這個Promise將會給我們返回一個圖片在設(shè)備上的存儲路徑。現(xiàn)在我們只是用日志輸出這個值回官,但是這個值后續(xù)會好好用上的曹宴。如果返回的是一個錯誤值的話,我們就用SimpleAlert來展示錯誤信息給用戶了歉提。
照片照好了笛坦,存放路徑也返回了,臨時文件夾里苔巨。這樣圖片臨時顯示出來了版扩,照片不會長久的保存,因為臨時目錄會被隨時清理掉侄泽。為解決此問題礁芦,我們需要把照片移動其他地方去,然后再次存儲這個照片的新路徑。我們可以用File插件來完成這個柿扣。

將照片移動到永久存儲中

為了用上File插件肖方,我們需要對takePhoto函數(shù)進行一些修改:

  • 通過返回的 imagePath 來找到臨時存儲里面的照片
  • 重命名,然后移動到設(shè)備上的‘snapaday’文件夾(也就是永久存儲)
  • 基于這個新的位置新建一個照片對象

看來takePhoto函數(shù)會變得復雜了好多未状。因為要寫這么多代碼窥妇。我會對代碼詳細添加注釋流译,當然也會一步步的去講解牲尺。
> 修改 takePhoto里的 getPicture 調(diào)用如下:

Camera.getPicture(options).then((imagePath) => {
    //Grab the file name
    let currentName = imagePath.replace(/^.*[\\\/]/, '');
    //Create a new file name
    let d = new Date(),
    n = d.getTime(),
    newFileName = n + ".jpg";
    if(this.platform.is('ios')){
        //Move the file to permanent storage
        File.moveFile(cordova.file.tempDirectory, currentName,cordova.file.dataDirectory, newFileName).then((success: any)=> {
            this.photoTaken = true;
            this.createPhoto(success.nativeURL);
            this.sharePhoto(success.nativeURL);
        }, (err) => {
            console.log(err);
            let alert = this.simpleAlert.createAlert('Oops!', 'Something went wrong.');
            alert.present();
        });
    } else {
        this.photoTaken = true;
        this.createPhoto(imagePath);
        this.sharePhoto(imagePath);
    }
},(err) => {
    let alert = this.simpleAlert.createAlert('Oops!', 'Something went wrong.');
    alert.present();
});

希望上面添加的注釋可以讓后面將要進行的東西變得簡單些陪腌,這里有一個高級別的手把手的講解,從camera返回imagePath后發(fā)生了什么:

  1. 移除 imagePath 最后一個 / 前面的所有內(nèi)容得到當前文件名
  2. 使用日期新建一個唯一的文件名翻伺,這樣我們不會覆蓋任何東西
  3. 如果我們是在iOS上運行的話,我們將照片從臨時存儲移動到持續(xù)存儲中
  4. photoTaken 設(shè)為 true沮焕,將新路徑傳給圖片然后傳到 createPhotosharePhoto吨岭。

做完這些的話咱們的相片就存儲到永久存儲空間去了。記住峦树,咱們現(xiàn)在還沒有定義createPhotosharePhoto函數(shù)辣辫。我們現(xiàn)在來創(chuàng)建createPhoto函數(shù),對于sharePhoto的話魁巩,我們留到整合社交分享插件的時候再來實現(xiàn)急灭。
createPhoto函數(shù)接受一個路徑參數(shù)(nativeURL本地路徑)并在應(yīng)用中持有他的引用。
> 修改 createPhoto 函數(shù)為如下:

createPhoto(photo): void {
    let newPhoto = new PhotoModel(photo, new Date());
    this.photos.unshift(newPhoto);
    this.save();
}

你也看到了好簡單的說谷遂。我們在使用Photo Model新建相片實例的時候傳入了一個相片的本地路徑和創(chuàng)建日期葬馋,然后將新建的相片對象加入到this.photos數(shù)組。我們沒有用push方法(因為是將相片添加到數(shù)組尾部)肾扰,我們通過unshift將他添加到數(shù)組頭部畴嘶。我們這部做的原因是我們需要以反向的方式來展示圖片(最新的最先顯示),這么做我們的生活就更輕松集晚。
同時我們也調(diào)用了save函數(shù)窗悯,他會將我們的數(shù)據(jù)保存到數(shù)據(jù)存儲中,但是我們目前還沒有實現(xiàn)這個函數(shù)偷拔。

更新模板

我們現(xiàn)在將相片添加到了this.photos數(shù)組蒋院,我們現(xiàn)在可以將模板更新為循環(huán)顯示他們了。由于你可能是想通過瀏覽器測試条摸,不能通過照相機來添加照片悦污,那么請隨意打開測試數(shù)據(jù)的注釋,這樣就可以看到本部分代碼的效果钉蒲。
我們現(xiàn)在來更新模板切端。
> 修改 src/pages/home/home.html 為如下:

<ion-header>
    <ion-navbar color="danger">
        <ion-title>
            <img src="assets/images/logo.png" />
        </ion-title>

        <ion-buttons end>
            <button ion-button icon-only (click)="playSlideshow()"><ion-icon name="play"></ion-icon></button>
        </ion-buttons>
    </ion-navbar>
</ion-header>

<ion-content>
    <ion-list>
        <button ion-item *ngIf="!photoTaken" detail-none (click)="takePhoto()">
        <img src="assets/images/smile.png" />
        </button>

        <ion-item-sliding *ngFor="let photo of photos">
            <ion-item>
            <img [src]="photo.image" />
            <ion-badge item-right light>0 days ago</ion-badge>
            </ion-item>

            <ion-item-options>
            <button ion-button icon-only color="light" (click)="removePhoto(photo)"><ion-icon name="trash"></ion-icon></button>
            </ion-item-options>
        </ion-item-sliding>
    </ion-list>
</ion-content>

對模板主要有兩大變更。首先顷啼,我們用上了ngFor來村換相片數(shù)組踏枣,然后為每個項創(chuàng)建了一個<ion-item-sliding>入口昌屉。通過在let photo of photos中的let photo,我們可以得到當前渲染的照片的應(yīng)用茵瀑,即:photo.image訪問照片的存儲路徑间驮。
由于我們可以訪問到每張照片的路徑,我們就可以設(shè)置img元素來展示他了马昨。注意我們用來方括號[src]竞帽,他允許我們將photo.image設(shè)置到image元素上來。這意味著會先評估photo.image鸿捧,然后蛇之都奧src屹篓。如果我們不用方括號的話,src將是字符串"photo.image"匙奴。
我們也有一個刪除按鈕堆巧,他會將相片(也就是let photo)傳入到removePhoto函數(shù)。我們現(xiàn)在就來實現(xiàn)這個方法吧泼菌。
> 修改 src/pages/home/home.ts 里的 removePhoto 函數(shù):*

removePhoto(photo): void {
    let today = new Date();
    if(photo.date.setHours(0,0,0,0) === today.setHours(0,0,0,0)){
        this.photoTaken = false;
    }

    let index = this.photos.indexOf(photo);
    if(index > -1){
        this.photos.splice(index, 1);
        this.save();
    }
}

這個函數(shù)的第二部分夠直白了谍肤,我們在photos數(shù)組中找到photo,移除他哗伯,觸發(fā)save荒揣。第一部分看起來有點迷。這里搞事的是笋颤,如果用戶拍勒個照乳附,然后刪除這個照片,他們就可以另外拍一張了(因為當日無照哇)伴澄。但是當他們刪除了較早的照片的時候赋除,他們就沒法拍照。
所以啦非凌,我們就獲取被刪除的照片的拍攝日期举农,然后跟今天日期進行對比。如果刪除的是今日的照片敞嗡,那么我們就把this.photoTaken設(shè)置為false這樣用戶今天有可以開心的拍另一張照片了颁糟。

總結(jié)

這節(jié)課實在是...!:磴病棱貌!這節(jié)課設(shè)計了相當復雜的東西,但是我們在這節(jié)課中實現(xiàn)了應(yīng)用的核心功能箕肃。還剩下一點點東西婚脱,但是我們現(xiàn)在可以拍照了,可以在將他們在一個列表中展示出來了,酷不酷障贸!如果你想看看效果的話错森,到真機上去跑一下吧。如果你不知道我們做了些啥篮洁,可以直接跳到本書的 測試與調(diào)試部分去了解如何在設(shè)備上安裝應(yīng)用涩维,然后回來完成應(yīng)用剩余部分。
重要:如果現(xiàn)在想要在真機上測試拍照袁波,那么你就需要將loadPhotos更新一下:

loadPhotos(): void {
    this.loaded = true;
}

你不能在數(shù)據(jù)加載完成之前拍照瓦阐,所以我們得先偽造一下。在接下來的課程中篷牌,我們將學習如何創(chuàng)建一個數(shù)據(jù)服務(wù)來永久存儲我們的照片垄分,這樣在用戶后面回到應(yīng)用的時候可以獲取他們。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末娃磺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子叫倍,更是在濱河造成了極大的恐慌偷卧,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吆倦,死亡現(xiàn)場離奇詭異听诸,居然都是意外死亡,警方通過查閱死者的電腦和手機蚕泽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門晌梨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人须妻,你說我怎么就攤上這事仔蝌。” “怎么了荒吏?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵敛惊,是天一觀的道長。 經(jīng)常有香客問我绰更,道長瞧挤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任儡湾,我火速辦了婚禮特恬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘徐钠。我一直安慰自己癌刽,他們只是感情好,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妒穴,像睡著了一般宋税。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上讼油,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天杰赛,我揣著相機與錄音,去河邊找鬼矮台。 笑死乏屯,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的瘦赫。 我是一名探鬼主播辰晕,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼确虱!你這毒婦竟也來了含友?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤校辩,失蹤者是張志新(化名)和其女友劉穎窘问,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宜咒,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡惠赫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了故黑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片儿咱。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖场晶,靈堂內(nèi)的尸體忽然破棺而出混埠,到底是詐尸還是另有隱情,我是刑警寧澤诗轻,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布岔冀,位于F島的核電站,受9級特大地震影響概耻,放射性物質(zhì)發(fā)生泄漏使套。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一鞠柄、第九天 我趴在偏房一處隱蔽的房頂上張望侦高。 院中可真熱鬧,春花似錦厌杜、人聲如沸奉呛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞧壮。三九已至登馒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咆槽,已是汗流浹背陈轿。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留秦忿,地道東北人麦射。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像灯谣,于是被迫代替她去往敵國和親潜秋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

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