《探索 HarmonyOS NEXT(5.0):開(kāi)啟構(gòu)建模塊化項(xiàng)目架構(gòu)奇幻之旅 ——第三方庫(kù)的使用:網(wǎng)絡(luò)請(qǐng)求RCP、二次封裝上下拉刷新沦零、彈窗》-CSDN博客

1祭隔、ef_rcp簡(jiǎn)介:是基于rcp封裝的網(wǎng)絡(luò)請(qǐng)求相關(guān)包.提供了rcp的上傳,下載,post,get,cancel,delete,put等操作。
ef_rcp出處ef_rcp蠢终;
2序攘、PullToRefresh簡(jiǎn)介:采用的裝飾器有V1,V2,作者緊跟時(shí)代的潮流寻拂。功能上:實(shí)現(xiàn)垂直列表下拉刷新,上拉加載程奠,橫向列表左拉刷新,右拉加載等操作祭钉。
PullToRefresh出處PullToRefresh瞄沙;
3、SmartDialog簡(jiǎn)介:鴻蒙版本的SmartDialog慌核,優(yōu)雅距境,極簡(jiǎn)的用法;非UI區(qū)域內(nèi)使用垮卓,自定義Component垫桂;返回事件處理,優(yōu)化的跨頁(yè)面交互粟按;多彈窗能力诬滩,多位置彈窗:上下左右中間霹粥;
定位彈窗:自動(dòng)定位目標(biāo)Component;極簡(jiǎn)用法的loading彈窗疼鸟。
SmartDialog出處SmartDialog后控;
非常感謝大佬們出的庫(kù),方便我們開(kāi)發(fā),提高我們開(kāi)發(fā)效率空镜,更詳細(xì)的介紹和使用請(qǐng)看官方出處浩淘。
其它
RCP官網(wǎng)

RCP網(wǎng)絡(luò)請(qǐng)求配置

1、增加BaseResponse吴攒。

export class BaseResponse<T> {
  //成功失敗標(biāo)識(shí)
  private success: boolean;
  //返回提示信息
  private msg: string;
  //響應(yīng)編碼
  private code: string | number;
  //返回?cái)?shù)據(jù)
  private data: T;

  /**
   * 構(gòu)造函數(shù)
   * @param success  是否成功標(biāo)識(shí)
   * @param msg   提示消息
   * @param data  數(shù)據(jù)
   */
  constructor(success: boolean, msg: string, data: T, code: string | number) {
    this.msg = msg;
    this.success = success;
    this.code = code;
    this.data = data;
  }

  /**
   * 創(chuàng)建空實(shí)例
   * @returns
   */
  static create(): BaseResponse<string> {
    let baseResponse = new BaseResponse<string>(true, '', '', 200);
    return baseResponse;
  }


  /**
   * 成功-只包含消息
   * @param msg   提示消息
   * @returns
   */
  static OK(msg: string): BaseResponse<string> {
    let baseResponse = new BaseResponse<string>(true, msg, '', 200);
    return baseResponse;
  }

  /**
   * 成功-包含單行數(shù)據(jù)
   * @param msg  提示消息
   * @param data  單行數(shù)據(jù)
   * @returns
   */
  static OKByData<T>(msg: string, data: T): BaseResponse<T> {
    let dto = new BaseResponse<T>(true, msg, data, 200);
    return dto;
  }


  /**
   * 失敗-包含提示消息
   * @param msg 提示消息
   * @returns
   */
  static Error(msg: string): BaseResponse<string> {
    let dto = new BaseResponse<string>(false, msg, '', 400);
    return dto;
  }

  /**
   * 失敗-包含單行數(shù)據(jù)
   * @param msg 提示消息
   * @param data 單行數(shù)據(jù)
   * @returns
   */
  static ErrorByData<T>(msg: string, data: T): BaseResponse<T> {
    let dto = new BaseResponse<T>(false, msg, data, 400);
    return dto;
  }

  public setSuccess(success: boolean) {
    this.success = success;
  }

  public getSuccess(): boolean {
    return this.success;
  }


  public getCode(): string | number {
    return this.code;
  }

  public setCode(code: string | number) {
    this.code = code;
  }


  public getMsg(): string {
    return this.msg;
  }

  public setMsg(msg: string) {
    this.msg = msg;
  }


  public getData(): T {
    return this.data;
  }

  public setData(data: T) {
    this.data = data;
  }
}

2张抄、增加不同接口返回不同數(shù)據(jù)結(jié)構(gòu)的響應(yīng)內(nèi)容攔截器,保持輸出一致洼怔。

官方攔截器鏈接 2.1.考慮幾種常見(jiàn)數(shù)據(jù)返回的

 // {"code":200,"message":"success","data":{"isCheck":"0"}}
 // {"status":"1","msg":"success","result":{"data":{"ticket":"ST-2c2fd56bad7f49259edbb4b00ccc6cbe"}}}

2.2.修改響應(yīng)內(nèi)容

  • 先獲取響應(yīng)結(jié)果
const response = await next.handle(context);
  • 把接口返回不同的code欣鳖,msg,data轉(zhuǎn)為一致。例子中code為200和0代表成功茴厉,可根據(jù)公司規(guī)定修改。
  • 考慮幾種常見(jiàn)數(shù)據(jù)返回的
      // {"code":200,"message":"success","data":{"isCheck":"0"}}
      // {"status":"1","msg":"success","result":{"data":{"ticket":"xxxxx"}}}
      // {"data": ..., "errorCode": 0, "errorMsg": ""} errorCode = 0 代表執(zhí)行成功.errorCode = -1001 代表登錄失效什荣,需要重新登錄
 //轉(zhuǎn)換成object
      let result = response.toJSON();
 //考慮幾種常見(jiàn)數(shù)據(jù)返回的
      // {"code":200,"message":"success","data":{"isCheck":"0"}}
      // {"status":"1","msg":"success","result":{"data":{"ticket":"ST-2c2fd56bad7f49259edbb4b00ccc6cbe"}}}
      // {"data": ..., "errorCode": 0, "errorMsg": ""} errorCode = 0 代表執(zhí)行成功.errorCode = -1001 代表登錄失效矾缓,需要重新登錄

      //1.成功失敗標(biāo)識(shí)
      let success: boolean = true;
      //2.返回的消息提示
      let message: string = '';
      //3.返回的數(shù)據(jù)
      let data: Record<string, Object> = {};
      //4.返回請(qǐng)求狀態(tài)碼
      let code = response.statusCode + '';

      if (result) {
        Object.entries(result).forEach((item: object) => {

          if (["errorCode", "code", "status"].includes(String(item[0]))) {
            code = String(item[1])
            success = disposeCode(String(item[1]));
          }
          if (["errorMsg", "message", "msg"].includes(String(item[0]))) {
            message = String(item[1]);
          }
          if (["data", "result"].includes(String(item[0]))) {
            data = item[1];
          }
        })
      }
      // HTTP status code
      if (response.statusCode != 200) {
        success = false;
        message = (response.toString() as string) ? response.toString() as string : "網(wǎng)絡(luò)錯(cuò)誤";
      }
  • 成功失敗標(biāo)識(shí)用success表示。
if (["code", "status"].includes(String(item[0]))) {
          code = String(item[1])
          success = disposeCode(String(item[1]));
        }
  • disposeCode的作用稻爬,處理不同接口返回的碼
/** 處理不同接口返回的碼.errorCode = 0 || code==200 || status==1 為成功 */
export function disposeCode(s: string): boolean {
let isSuccess: boolean = false;
if ("0" == s || "200" == s || "1" == s) {
 isSuccess = true;
}
return isSuccess;
}
  • 返回統(tǒng)一格式
    let baseResponse = new BaseResponse(success, disposeMsg(code, message), data, code);
  • disposeMsg的作用嗜闻,表示處理信息,比如針對(duì)于特定的code碼桅锄,返回指定的msg琉雳。


/** 處理信息 */
export function disposeMsg(code: string, msg: string): string {
  let message = "";
  switch (code) {
    case '-1001':
    case '401':
      message = "登陸信息過(guò)期,請(qǐng)重新登陸";
      break;
    case '403':
      message = "賬號(hào)異常友瘤,請(qǐng)聯(lián)系客服";
      break;
    case '429':
      message = "您的操作過(guò)于頻繁翠肘,請(qǐng)稍后再試!";
      break;
    case '500':
      message = "服務(wù)器錯(cuò)誤(500)";
      break;
    default:
      message = `${msg}`;
  }
  const errorCodes = ['401', '403', '429', '500'];
  if (errorCodes.includes(code)) {
    //吐司
    ToastUtil.showToast(message);
  }
  return message;
}
  • 修改響應(yīng)后辫秧,給rcp.Response傳過(guò)去束倍。
      //對(duì)響應(yīng)修改
      const toReturn: rcp.Response = {
        request: response.request,
        statusCode: response.statusCode,
        headers: response.headers,
        effectiveUrl: response.effectiveUrl,
        body: response.body,
        downloadedTo: response.downloadedTo,
        timeInfo: response.timeInfo,
        httpVersion: response.httpVersion,
        reasonPhrase: response.reasonPhrase,
        toString: () => response.toString(),
        toJSON: () => baseResponse
      };
      return toReturn;

3、初始化參數(shù)配置盟戏,在EntryAbility的onWindowStageCreate寫(xiě)

    // if(運(yùn)行環(huán)境===debug){
   efRcp
     .setBaseURL("https://www.wanandroid.com") //設(shè)置請(qǐng)求路徑
     .enableLogInterceptor()//設(shè)置為false即可關(guān)閉
     .setLoadingContent('正在加載中...')//更改loading文本
     .convertError(true)//表示如果response.toJSON()異常時(shí)將響應(yīng)字符串返回,false則表示值返回異常提醒而不返回結(jié)果
     .addCommonHeaders({//設(shè)置公共頭
       "version": `V1.0.0`
     })// .setLoadingImg(wrapBuilder(loadingImg)) //設(shè)置loading為gif圖片
     .addCustomInterceptors([new ResponseInterceptor()])
     .addSysCodeEvent({//添加統(tǒng)一系統(tǒng)框架級(jí)別編碼處理邏輯,如超時(shí)等
       listener: (code: number) => {
         // Log.d('---------addSysCodeEvent監(jiān)聽(tīng)事件-----' + code)
         switch (code) {
         case -1001:
           case 401:
             console.log(`xxx : ---跳轉(zhuǎn)登錄頁(yè)面绪妹,清空一些數(shù)據(jù)等`)
             //跳轉(zhuǎn)登錄頁(yè)面,清空一些數(shù)據(jù)等
             // ZRouter.replacePathByName('LoginPage')
             break;
         }
       }
     })//創(chuàng)建session對(duì)象,需要再設(shè)置為一系列操作后再調(diào)用柿究,否則設(shè)置不生效,可在特殊情況處設(shè)置其他操作后重新創(chuàng)建session
     .create()//獲取統(tǒng)一的session對(duì)象邮旷,必須在create后調(diào)用 .設(shè)置了全局的配置比如攔截器  超時(shí)時(shí)間  session本身的配置 ,需要再次create
     .builder();
   // }

4蝇摸、如何使用婶肩,更多詳細(xì)內(nèi)容可以參考ef_rcp作者的主頁(yè)

  • post請(qǐng)求為例办陷,例子在 TestNetView 頁(yè)面
 //登錄
          let login = await PhoneService.login({
            'username': '鴻蒙',
            'password': '5.0'
          })
          console.log('xxxlogin--' + '' + json.stringify(login))
          if (login.data?.getSuccess()) {
            this.message = json.stringify(login.data.getData())
            console.log('xxxxxdata參數(shù)--' + '' + json.stringify(login.data.getData()))
          } else {
            console.log('xxx--' + login.data?.getMsg())
            ToastUtil.showToast(login.data?.getMsg())
          }
          
PhoneService類
export class PhoneService {
  static login(query: Record<string, Object>): Promise<EfRcpResponse<BaseResponse<object>>> {
    return efRcpClientApi.post<BaseResponse<object>>({
      url: 'user/login',
      query: query,
      loadingTxt: '正在登錄中...',
      loading: false
    });
  }
}

5、自帶的loading( 圖一 ) 如果不符合可以自定義一個(gè)builder,參考下面的彈窗設(shè)置狡孔。

PullToRefresh上下拉刷新配置懂诗,采用V2裝飾器版本

1、下載安裝苗膝,目前版本是 “^2.0.1”

ohpm install @zhongrui/pull_to_refresh_v2
  • 1

2殃恒、每個(gè)項(xiàng)目的上下拉刷新頭部,尾部都不一樣辱揭,所以我這里采用了個(gè)性化定制,請(qǐng)使用RefreshLayout

  • 上下拉刷新例子–>TestRefreshView
@Preview
@ComponentV2
export struct TestRefreshView {}
  • 自定義刷新頭部
  @Builder
  defHeaderView() {
    Stack({ alignContent: Alignment.Center }) {
      if (this.pullDown?.status == PullStatus.PullDown || this.pullDown?.status == PullStatus.Refresh || this.pullDown?.status == PullStatus.PreRefresh) {
        Row() {
          Image($r("app.media.loading_refresh")).width(50).height(40)
        }.width('100%')
        .height(50)
        .justifyContent(FlexAlign.Center)
      } else if (this.pullDown?.status == PullStatus.RefreshSuccess) {
        // Text("刷新成功").textExtend()
      } else if (this.pullDown?.status == PullStatus.RefreshError) {
        Text("刷新失敗,請(qǐng)重新嘗試").textExtend()
      }

    }.height(50).width("100%")

  }
  • 自定義刷新尾部
  /** 自定義刷新尾部 */
  @Builder
  defFooterView() {
    Stack({ alignContent: Alignment.Center }) {
      if (this.pullDown?.status == PullStatus.PullUp || this.pullDown?.status == PullStatus.Load || this.pullDown?.status == PullStatus.PreLoad) {
        Row() {
          Image($r("app.media.loading_refresh"))
            .width(24)
            .height(24)
        }.width('100%')
        .height(60)
        .justifyContent(FlexAlign.Center)
      } else if (this.pullDown?.status == PullStatus.LoadSuccess) {
        // Text("加載完成").textExtend()
      } else if (this.pullDown?.status == PullStatus.LoadError) {
        Text('加載失敗,請(qǐng)重新嘗試').textExtend()
      }

    }.height(50).width("100%")

  }
  • 內(nèi)容視圖
  /** 內(nèi)容視圖 */
  @Builder
  _ContentView() {
    Text("contentView:()=>{your @Builder View}")
  }
  • loading視圖
  /** loading視圖 */
  @Builder
  loadingView() {
    this.layout($r('app.media.loading_refresh'), '正在加載...')
  }
  • 空視圖
  /** 空視圖 */
  @Builder
  _EmptyView() {
    this.layout($r('app.media.nodata'), '暫無(wú)數(shù)據(jù)')
  }
  • 錯(cuò)誤視圖
  /** 錯(cuò)誤視圖 */
  @Builder
  _ErrorView() {
    this.layout($r('app.media.no_network'), '暫無(wú)網(wǎng)絡(luò),請(qǐng)重新嘗試')
  }
  • 視圖公用
 /** 視圖公用 */
  @Builder
  layout(src: ResourceStr, text: ResourceStr) {
    Column() {
      Image(src).width(48).height(48)
      Text(text).fontSize(12).fontColor($r('app.color.color_999999')).padding(8)
    }.width(CommonConst.FULL_PARENT)
    .height(CommonConst.FULL_PARENT)
    .justifyContent(FlexAlign.Center)
  }
  • 底部暫無(wú)更多(目前只能往上拉才能看到离唐,如果不上拉也能看到,那就自定義一個(gè)Item放到最下面)问窃。
  /**
   * 暫無(wú)更多
   * @param isV 是否豎向
   */
  @Builder
  defFooterNoMoreView(isV: boolean) {
    Text('沒(méi)有更多數(shù)據(jù)了')
      .textAlign(TextAlign.Center)
      .height(isV ? 50 : CommonConst.FULL_PARENT)
      .width(isV ? CommonConst.FULL_PARENT : 50)
      .fontSize(14)
      .fontColor($r('app.color.color_999999'))
  }

  private isVerticalLayout(): boolean {
    return (this.config.isVertical || this.config.horizontalMode == 1 || this.config.horizontalMode == 2)
  }
}
  • 默認(rèn)帶彈性效果的列表需要關(guān)閉彈性滑動(dòng)
 .edgeEffect(EdgeEffect.None) 
  • BasicDataSource亥鬓,配合LazyForEach使用,數(shù)據(jù)太多的話建議用LazyForEach域庇;后期可以看看(Repeat:子組件復(fù)用)
源代碼請(qǐng)看項(xiàng)目中嵌戈,模塊uicomponents /src/main/ets/components/refresh/BasicDataSource

3、封裝請(qǐng)求返回的數(shù)據(jù)听皿,更加簡(jiǎn)潔

  • 如何使用

  /** 請(qǐng)求接口 */
  async loadData() {
    let data: Array<string> = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"]
    // let data:string[] = []// 空數(shù)據(jù)
    this.dataSource.pageRefresh(true, this.pageNum, data.length, data, this.controller,
      (pages: number) => {
        this.pageNum = pages
      })

  }
 /**
   * 列表頁(yè)數(shù) 處理
   * @param success  成功失敗標(biāo)識(shí)
   * @param page     頁(yè)數(shù)
   * @param total    總條數(shù)
   * @param data     數(shù)據(jù)
   * @param controller RefreshController
   * @param pageNums 返回的page
   */
  public pageRefresh(success: boolean, page: number, total: number, data: Array<T>, controller: RefreshController, pageNums: (pages: number) => void) {
    if (success) {
      if (page == 1) {
        this.setNewData(data)
        controller.refreshSuccess()
        pageNums(2)

        if (this.totalCount() == 0) {
          controller.viewEmpty()
        }
      } else {
        this.addAllData(data)
        controller.loadSuccess()
        pageNums(data.length == 0 ? page : (page + 1))
      }
      // 是否還有更多
      setTimeout(() => {
        controller.hasMore(this.totalCount() < total /*|| !(data.length < 10)*/)
      }, 800) //處理暫無(wú)更多數(shù)據(jù)視圖和列表同時(shí)顯示出來(lái)


    } else {
      if (controller.getStatus() == PullStatus.Refresh) {
        controller.refreshError()
      } else {
        controller.loadError()
      }
      if (page == 1) {
        controller.viewError()
      }
    }

  }

SmartDialog彈窗配置

  • 更多細(xì)節(jié)請(qǐng)參考大佬寫(xiě)的

安裝

ohpm install ohos_smart_dialog 

全局設(shè)置一個(gè)loadding樣式

  • Index頁(yè)面
OhosSmartDialog({ loadingBuilder: customLoading })
/** 自定義頁(yè)面彈窗 */
@Builder
function customLoading(args: ResourceStr = '正在加載中...') {
  Column() {
    Image($r('app.media.loading_refresh')).width(50).height(50)
    Text(args)
      .fontSize(11)
      .fontColor($r('app.color.color_222222'))
      .margin({ top: 11 })
      .maxLines(1)
      .textOverflow({ overflow: TextOverflow.Ellipsis })

  }
  .width(120)
  .height(120)
  .justifyContent(FlexAlign.Center)
  .backgroundColor(Color.White)
  .borderRadius(12)
}

  • 路由子頁(yè)面一定要加熟呛,返回事件監(jiān)聽(tīng)
.onBackPressed(OhosSmartDialog.onBackPressed())

以往系列文章

  1. 《探索 HarmonyOS NEXT(5.0):開(kāi)啟構(gòu)建模塊化項(xiàng)目架構(gòu)奇幻之旅 —— 模塊化基礎(chǔ)篇》
  2. 《探索 HarmonyOS NEXT(5.0):開(kāi)啟構(gòu)建模塊化項(xiàng)目架構(gòu)奇幻之旅 —— 構(gòu)建基礎(chǔ)特性層》
  3. 《探索 HarmonyOS NEXT(5.0):開(kāi)啟構(gòu)建模塊化項(xiàng)目架構(gòu)奇幻之旅 —— 構(gòu)建公共能力層》
  4. 《探索 HarmonyOS NEXT(5.0):開(kāi)啟構(gòu)建模塊化項(xiàng)目架構(gòu)奇幻之旅 —— Tabs底部導(dǎo)航欄》
  5. 《探索 HarmonyOS NEXT (5.0):開(kāi)啟構(gòu)建模塊化項(xiàng)目架構(gòu)奇幻之旅 —— 動(dòng)態(tài)路由 ZRouter:引領(lǐng)高效模塊通信的智慧中樞》

若本文對(duì)您稍有幫助,誠(chéng)望您不吝點(diǎn)贊尉姨,多謝庵朝。

有興趣的同學(xué)可以點(diǎn)擊查看源碼

歡迎加我微信一起交流:+V:yinshiyuba

本文使用 文章同步助手 同步

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市又厉,隨后出現(xiàn)的幾起案子九府,更是在濱河造成了極大的恐慌,老刑警劉巖覆致,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侄旬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡煌妈,警方通過(guò)查閱死者的電腦和手機(jī)勾怒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)声旺,“玉大人笔链,你說(shuō)我怎么就攤上這事∪” “怎么了鉴扫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)澈缺。 經(jīng)常有香客問(wèn)我坪创,道長(zhǎng)炕婶,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任莱预,我火速辦了婚禮柠掂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘依沮。我一直安慰自己涯贞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布危喉。 她就那樣靜靜地躺著宋渔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辜限。 梳的紋絲不亂的頭發(fā)上皇拣,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音薄嫡,去河邊找鬼氧急。 笑死,一個(gè)胖子當(dāng)著我的面吹牛毫深,可吹牛的內(nèi)容都是我干的态蒂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼费什,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了手素?” 一聲冷哼從身側(cè)響起鸳址,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泉懦,沒(méi)想到半個(gè)月后稿黍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崩哩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年巡球,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邓嘹。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡酣栈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汹押,到底是詐尸還是另有隱情矿筝,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布棚贾,位于F島的核電站窖维,受9級(jí)特大地震影響榆综,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铸史,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一鼻疮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琳轿,春花似錦判沟、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至媚送,卻和暖如春中燥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背塘偎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工疗涉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吟秩。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓咱扣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親涵防。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闹伪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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