好久不見(jiàn)!鴻蒙畫分時(shí)圖第一彈享扔。

學(xué)吧啊趟庄,學(xué)無(wú)止境。若干年前伪很,我啟動(dòng)的Flutter版本的豆瓣戚啥,因?yàn)椴豢煽沽υ蛲8恕:苓z憾锉试!今天猫十,我決定用鴻蒙來(lái)開發(fā)一個(gè)證券版本的App,全面對(duì)標(biāo)同花順呆盖。
為什么選擇證券類拖云?第一,證券里面有很多自定義分時(shí)圖/K線等应又,學(xué)會(huì)這些宙项,基本完全了解了自定義View。第二株扛,證券類的api網(wǎng)上有很多尤筐,這是很關(guān)鍵的。第三洞就,常用的列表盆繁、數(shù)據(jù)庫(kù)等,都會(huì)涉及到旬蟋。
當(dāng)然油昂,因?yàn)楹芏鄶?shù)據(jù)源問(wèn)題,不可能百分百一致倾贰,盡力而為冕碟。本文,作為先啟篇匆浙,先亮出我目前完成的核心之一---分時(shí)圖安寺。

Gif圖片可能略卡,可以忽略吞彤。大家可以猜一猜這是哪支股票我衬。。

jphwp-ewpwg.gif

本篇饰恕,先放出代碼挠羔,以及很多很多注釋,下一篇會(huì)詳細(xì)講解思路以及對(duì)應(yīng)的API講解埋嵌。

import http from '@ohos.net.http'
import { DrawRect } from './DrawRect'
import { StockDataBean, StockItemData } from './StockDataBean'


@Entry
@Component
struct CanvasLinePage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  private canvasDrawMargin: number = 20 //畫布的邊距
  @State stockData: StockDataBean = new StockDataBean()
  private canvasW: number //整個(gè)畫布的寬度
  private canvasH: number //整個(gè)畫布的高度
  private controller: TextInputController = new TextInputController()
  private searchStockCode: string = ''
  private maxPriceTxtWidth: number = 0 //當(dāng)日的最高價(jià)格文本的寬度
  private singleTxtWidth: number = 0 //普通文本的寬度
  private singleTxtHeight: number = 0 //普通文本的高度
  private minuteRect: DrawRect //分時(shí)的區(qū)域
  private chengJiaoLiangRect: DrawRect //分時(shí)下面量比的區(qū)域
  private lineRect: DrawRect //分時(shí)+量比的所有繪制內(nèi)容的區(qū)域

  aboutToAppear() {

  }

  build() {
    Column() {
      Canvas(this.context)
        .onReady(() => {
          this.canvasW = this.context.width
          this.canvasH = this.context.height
          this.lineRect = new DrawRect(this.canvasDrawMargin, this.canvasDrawMargin, this.canvasW - this.canvasDrawMargin * 2, this.canvasH - this.canvasDrawMargin * 2)
          this.minuteRect = new DrawRect(this.canvasDrawMargin, this.canvasDrawMargin, this.lineRect.width, this.lineRect.height * 0.7)

          this.context.font = '40px'
          this.singleTxtWidth = this.context.measureText("價(jià)").width
          this.singleTxtHeight = this.context.measureText("價(jià)").height
          // this.singleTxtHeight * 2 留給分時(shí)跟量比中間的區(qū)域
          let liangBiStartY = this.minuteRect.getEndY() + this.singleTxtHeight
          this.chengJiaoLiangRect = new DrawRect(this.lineRect.startX, liangBiStartY, this.lineRect.width, this.lineRect.height - this.minuteRect.height - this.singleTxtHeight * 2)
          this.reDrawAllCanvas()
        })
        .backgroundColor('#ffffff')
        .width('100%')
        .height('50%')
        .onTouch((event) => {
          this._handlerCanvasTouchEvent(event)
        })
      Row() {
        TextInput({ placeholder: 'Stock Code', controller: this.controller })
          .onChange((value: string) => {
            console.info(value);
            this.searchStockCode = value
          })
          .type(InputType.Number)
          .width('50%')

        Button("Search")
          .onClick(() => {
            requestData(this.searchStockCode, (value) => {
              if (value != null) {
                console.log("解析成功")
                this.stockData = value
                this.context.font = '40px'
                this.maxPriceTxtWidth = this.context.measureText(roundUpToTwoDecimalPlaces(this.stockData.lineHighest))
                  .width
                this.reDrawAllCanvas()
              }
            })
          })
      }
      .justifyContent(FlexAlign.SpaceAround)
      .width('100%')
    }
    .width('100%')
    .height('100%')
  }

  _handlerCanvasTouchEvent(event?: TouchEvent) {
    if (event.type == TouchType.Move) {
      let touchedY = event.touches[0].y
      if (touchedY < this.canvasDrawMargin || touchedY > this.context.height - this.canvasDrawMargin) {
        return
      }
      var x = event.touches[0].x
      //遍歷離自己最新的X軸位置的數(shù)據(jù)索引
      var minDistanceIndex = 0
      //上次計(jì)算到的最靠近的X位置
      var lastXData = 0
      //上次計(jì)算的差距
      var lastDistance = this.stockData.line[minDistanceIndex].lineX
      this.stockData.line.forEach((item, index) => {
        if (Math.abs(item.lineX - x) < lastDistance) {
          lastXData = item.lineX
          minDistanceIndex = index
          lastDistance = Math.abs(item.lineX - x)
        }
      })
      //當(dāng)前觸摸位置的分時(shí)數(shù)據(jù)
      x = lastXData
      this._clearCanvas()
      this._drawMinuteLine()
      this._drawChengJiaoLiang()
      let touchStockData = this.stockData.line[minDistanceIndex]
      this._drawJiaFuJunLiang(touchStockData)
      if (touchedY >= this.minuteRect.startY && touchedY <= this.minuteRect.getEndY()) {
        //繪制分時(shí)區(qū)域價(jià)格

        //繪制水平十字軸線
        this.context.strokeStyle = '#666666'
        this.context.lineWidth = 0.8600009
        this.context.beginPath()
        this.context.moveTo(this.minuteRect.startX, touchedY)
        this.context.lineTo(this.minuteRect.getEndX(), touchedY)
        this.context.stroke()
        //繪制水平十字軸線左側(cè)的分時(shí)價(jià)格
        let txtYValue = roundUpToTwoDecimalPlaces(this.stockData.lineHighest - (touchedY - this.minuteRect.startY) / this.minuteRect.height * (this.stockData.lineHighest - this.stockData.lineLowest))
        let textMetrics2 = this.context.measureText(txtYValue)
        let txtW2 = textMetrics2.width
        let txtH2 = textMetrics2.height
        this.context.fillStyle = '#364d92'
        this.context.fillRect(this.minuteRect.startX, touchedY - txtH2 / 2, txtW2, txtH2)
        this.context.font = '40px'
        this.context.fillStyle = '#ffffff'
        this.context.textAlign = 'center'
        this.context.textBaseline = 'middle'
        this.context.fillText(txtYValue, this.minuteRect.startX + txtW2 / 2, touchedY)
      } else if (touchedY >= this.chengJiaoLiangRect.startY && touchedY <= this.chengJiaoLiangRect.getEndY()) {
        //繪制成交量

        //繪制水平十字軸線
        this.context.strokeStyle = '#666666'
        this.context.lineWidth = 0.8600009
        this.context.beginPath()
        this.context.moveTo(this.minuteRect.startX, touchedY)
        this.context.lineTo(this.minuteRect.getEndX(), touchedY)
        this.context.stroke()
        //繪制水平十字軸線左側(cè)的成交量
        let txtYValue = parseInt((((this.stockData.maxChengJiaoLiang - (touchedY - this.chengJiaoLiangRect.startY) / this.chengJiaoLiangRect.height * (this.stockData.maxChengJiaoLiang - this.stockData.minChengJiaoLiang))) / 100).toString())
          .toString()
        let textMetrics2 = this.context.measureText(txtYValue)
        let txtW2 = textMetrics2.width
        let txtH2 = textMetrics2.height
        this.context.fillStyle = '#364d92'
        this.context.fillRect(this.minuteRect.startX, touchedY - txtH2 / 2, txtW2, txtH2)
        this.context.font = '40px'
        this.context.fillStyle = '#ffffff'
        this.context.textAlign = 'center'
        this.context.textBaseline = 'middle'
        this.context.fillText(txtYValue, this.minuteRect.startX + txtW2 / 2, touchedY)
      }
      //繪制垂直十字軸線
      this.context.beginPath()
      this.context.moveTo(x, this.minuteRect.startY)
      this.context.lineTo(x, this.chengJiaoLiangRect.getEndY())
      this.context.stroke()
      //計(jì)算底部時(shí)間文本香瓜數(shù)據(jù)
      this.context.font = '40px'
      let txt = '' + touchStockData.time
      if (txt.length <= 0) {
        return
      }
      if (txt.length == 5) {
        txt = '0' + txt
      }
      if (txt.length < 6) {
        return
      }
      txt = txt.substring(0, 2) + ":" + txt.substring(2, 4)
      let textMetrics = this.context.measureText(txt)
      let txtW = textMetrics.width
      let txtH = textMetrics.height
      this.context.fillStyle = '#364d92'
      //繪制底部時(shí)間文本框
      this.context.fillRect(x - txtW / 2, this.minuteRect.getEndY(), txtW, txtH)
      // 繪制底部時(shí)間文本
      this.context.fillStyle = '#ffffff'
      this.context.textAlign = 'center'
      this.context.textBaseline = 'middle'
      this.context.fillText(txt, x, this.minuteRect.getEndY() + txtH / 2)
    }
  }

  //重新繪制
  reDrawAllCanvas() {
    this._clearCanvas()
    let lastMinJiaFujunLiang = this.stockData.line[this.stockData.line.length-1]
    if (lastMinJiaFujunLiang != null && lastMinJiaFujunLiang != undefined) {
      this._drawJiaFuJunLiang(lastMinJiaFujunLiang)
    }
    this._drawMinuteLine()
    this._drawChengJiaoLiang()
  }

  //清空畫布的所有內(nèi)容
  _clearCanvas() {
    this.context.clearRect(0, 0, this.canvasW, this.canvasH)
  }

  _drawJiaFuJunLiang(stockData: StockItemData) {
    //---------繪制觸摸時(shí)刻分鐘線對(duì)應(yīng)的時(shí)刻的 價(jià)格/漲跌幅/均價(jià)-----start------
    this.context.font = '40px'
    let price = stockData.price
    let priceColor = ''
    if (price > this.stockData.prev_close) {
      priceColor = '#e2233e'
    } else if (price == this.stockData.prev_close) {
      priceColor = '#fcfcfc'
    } else {
      priceColor = '#228B22'
    }
    //這里文本left-align
    this.context.textAlign = 'left'
    this.context.textBaseline = 'middle'
    let txtColor = '#666666'
    let valueY = this.canvasDrawMargin - this.singleTxtHeight / 2
    let jia_fu_jun_liang_data: Array<Array<string>> = [
      ['價(jià)', '' + price],
      ['幅', '' + roundUpToTwoDecimalPlaces((price - this.stockData.prev_close) * 100 / this.stockData.prev_close) + "%"],
      ['均', '' + roundUpToTwoDecimalPlaces(stockData.junjia)],
      ['量', '' + stockData.chengJiaoLiang / 100 + '']
    ]
    jia_fu_jun_liang_data.forEach((item, index) => {
      this.context.fillStyle = txtColor
      this.context.fillText(item[0], this.minuteRect.startX + (12 + this.singleTxtWidth + this.maxPriceTxtWidth) * index, valueY)
      this.context.fillStyle = priceColor
      this.context.fillText(item[1], this.minuteRect.startX + (12 + this.singleTxtWidth + this.maxPriceTxtWidth) * index + this.singleTxtWidth, valueY)
    })
    //---------繪制觸摸時(shí)刻分鐘線對(duì)應(yīng)的時(shí)刻的 價(jià)格/漲跌幅/均價(jià)-----end------
  }

  //繪制背景的方格線
  drawBackgroundLine() {
    let w = this.minuteRect.width
    //-------------繪制背景的分時(shí)方格線-------start---------
    let h = this.minuteRect.height
    //繪制4x4方格背景矩形
    this._drawStrokeRect(this.minuteRect, '#ececec')

    this.context.strokeStyle = '#ececec'
    let itemDistanceY = h / 4
    //3條水平線
    let startY = this.minuteRect.startY + itemDistanceY
    for (let i = 0; i < 3; i++) {
      this.context.beginPath();
      this.context.moveTo(this.minuteRect.startX, startY)
      this.context.lineTo(this.minuteRect.getEndX(), startY)
      startY = startY + itemDistanceY
      this.context.stroke()
    }
    let itemDistanceX = w / 4
    //3條垂直線
    this.context.beginPath()
    let startX = this.minuteRect.startX + itemDistanceX
    for (let i = 0; i < 3; i++) {
      this.context.beginPath()
      this.context.moveTo(startX, this.minuteRect.startX)
      this.context.lineTo(startX, this.minuteRect.getEndY())
      startX = startX + itemDistanceX
      this.context.stroke()
    }
    //-------------繪制背景的分時(shí)方格線-------end---------

    //-------------繪制背景的量比方格線-------start---------
    //矩形
    this._drawStrokeRect(this.chengJiaoLiangRect, '#ececec')
    //水平
    startY = this.chengJiaoLiangRect.startY + this.chengJiaoLiangRect.height / 2
    this.context.beginPath();
    this.context.moveTo(this.chengJiaoLiangRect.startX, startY)
    this.context.lineTo(this.chengJiaoLiangRect.getEndX(), startY)
    this.context.stroke()
    //-------------繪制背景的量比方格線-------end---------
  }

  //繪制分鐘線
  _drawMinuteLine() {
    this.drawBackgroundLine()
    this.drawMinuteLine()
    this.drawAveragePriceLine()
    this.context.font = '40px'
    this.context.textAlign = 'center'
    this.context.textBaseline = 'middle'
    //繪制左側(cè)最高價(jià)格
    if (this.stockData.lineHighest != null) {
      this.context.fillStyle = '#e2233e'
      let txtH = roundUpToTwoDecimalPlaces(this.stockData.lineHighest)
      this.context.fillText(txtH, this.minuteRect.startX + this.maxPriceTxtWidth / 2, this.minuteRect.startY + this.singleTxtHeight)
    }
    //繪制昨收價(jià)格
    if (this.stockData.prev_close != null) {
      this.context.fillStyle = '#6c6c6c'
      let txtH = roundUpToTwoDecimalPlaces(this.stockData.prev_close)
      this.context.fillText(txtH, this.minuteRect.startX + this.maxPriceTxtWidth / 2, this.minuteRect.height / 2 + this.singleTxtHeight)
    }
    //繪制左側(cè)最低價(jià)格
    if (this.stockData.lineLowest != null) {
      this.context.fillStyle = '#228B22'
      let txtH = roundUpToTwoDecimalPlaces(this.stockData.lineLowest)
      this.context.fillText(txtH, this.minuteRect.startX + this.maxPriceTxtWidth / 2, this.minuteRect.getEndY() - this.singleTxtHeight / 2)
    }
  }

  //繪制均價(jià)
  drawAveragePriceLine() {
    this.context.strokeStyle = '#e99a4c'
    this.context.lineWidth = 0.8600009
    this.context.beginPath()
    let itemCount = Math.max(this.stockData.line.length, 240)
    //按照分時(shí)數(shù)據(jù)量平分兩個(gè)分時(shí)數(shù)據(jù)之間的間距
    let itemDistance = this.minuteRect.width / itemCount
    let path = new Path2D()
    this.stockData.line.forEach((value, index) => {
      if (index >= itemCount) {
        return
      }
      let x = this.minuteRect.startX + index * itemDistance
      let y = this.minuteRect.height / 2 - (value.junjia - this.stockData.prev_close) / this.stockData.maxDistancePrice * (this.minuteRect.height / 2) + this.minuteRect.startY
      if (index == 0) {
        path.moveTo(x, y)
      } else {
        path.lineTo(x, y)
      }
    })
    this.context.stroke(path)
  }

  //繪制分時(shí)線
  drawMinuteLine() {
    this.context.strokeStyle = '#364d92'
    this.context.lineWidth = 0.8600009
    this.context.beginPath()
    let itemCount = Math.max(this.stockData.line.length, 240)
    let itemDistance = this.minuteRect.width / itemCount
    let path = new Path2D()
    this.stockData.line.forEach((value, index) => {
      if (index >= itemCount) {
        return
      }
      let x = this.minuteRect.startX + index * itemDistance
      value.lineX = x
      let y = this.minuteRect.height / 2 - (value.price - this.stockData.prev_close) / this.stockData.maxDistancePrice * (this.minuteRect.height / 2) + this.minuteRect.startY
      if (index == 0) {
        path.moveTo(x, y)
      } else {
        path.lineTo(x, y)
      }

    })
    this.context.stroke(path)
  }

  //繪制成交量
  _drawChengJiaoLiang() {
    this.context.strokeStyle = '#e99a4c'
    this.context.lineWidth = 0.8600009
    this.stockData.line.forEach((value, index) => {
      if (value.price)
        this.context.beginPath()
      this.context.moveTo(value.lineX, ((this.stockData.maxChengJiaoLiang - value.chengJiaoLiang) / this.stockData.maxChengJiaoLiang) * this.chengJiaoLiangRect.height + this.chengJiaoLiangRect.startY)
      this.context.lineTo(value.lineX, this.chengJiaoLiangRect.getEndY())
      this.context.stroke()
    })
  }

  _drawStrokeRect(rect: DrawRect, color: string) {
    this.context.strokeStyle = color
    this.context.strokeRect(rect.startX, rect.startY, rect.width, rect.height)
  }
}

export interface Callback<T> {
  (data: T): void;
}

function requestData(stockCode: string, callback: Callback<StockDataBean>) {
  // callback('開始請(qǐng)求')
  //創(chuàng)建http請(qǐng)求
  let httpRequest = http.createHttp()
  //訂閱請(qǐng)求頭
  httpRequest.on('headersReceive', (header) => {
    // callback('獲取到請(qǐng)求頭信息')
    // callback("header:" + JSON.stringify(header))
  })
  //發(fā)起請(qǐng)求
  var market = stockCode.startsWith('0') ? 'sz' : 'sh'
  httpRequest.request("http://xxxx" {
    method: http.RequestMethod.GET,
    extraData: {},
    connectTimeout: 5000,
    readTimeout: 5000,
    header: {
      'Content-Type': 'application/json'
    }
  }).then((data) => {
    if (data.responseCode == http.ResponseCode.OK) {
      let response = data.result
      // console.log("接口返回:" + response)
      let obj = JSON.parse(response as string)
      let bean = new StockDataBean()
      bean.code = obj.code
      bean.prev_close = obj.prev_close
      bean.highest = obj.highest
      bean.lowest = obj.lowest
      bean.time = obj.time
      bean.total = obj.total
      bean.begin = obj.begin
      bean.date = obj.date
      bean.end = obj.end

      let lineList: Array<Array<number>> = obj.line
      var lineHighest = bean.highest
      var lineLowest = bean.lowest
      var currentTimePrice = bean.prev_close
      lineList.forEach((value: Array<number>, index) => {
        let item = new StockItemData()
        item.time = value[0]
        item.price = value[1]
        item.chengJiaoLiang = value[2]
        item.junjia = value[3]
        item.chengjiaoe = value[4]
        currentTimePrice = item.price
        if (item.price > lineHighest) {
          lineHighest = item.price
        }
        if (item.price < lineLowest) {
          lineLowest = item.price
        }
        bean.line.push(item)
        if (item.chengJiaoLiang > bean.maxChengJiaoLiang) {
          bean.maxChengJiaoLiang = item.chengJiaoLiang
        }
        if (item.chengJiaoLiang < bean.minChengJiaoLiang) {
          bean.minChengJiaoLiang = item.chengJiaoLiang
        }
      })
      if (Math.abs(lineHighest - bean.prev_close) > Math.abs(lineLowest - bean.prev_close)) {
        lineLowest = bean.prev_close - Math.abs(lineHighest - bean.prev_close)
        //獲取
        bean.maxDistancePrice = Math.abs(lineHighest - bean.prev_close)
      } else {
        bean.maxDistancePrice = Math.abs(lineLowest - bean.prev_close)
        lineHighest = bean.prev_close + Math.abs(lineLowest - bean.prev_close)
      }
      bean.lastNewPrice = currentTimePrice
      bean.lineLowest = lineLowest
      bean.lineHighest = lineHighest
      bean.maxDistancePrice = roundUpToTwoDecimal(bean.maxDistancePrice)
      callback(bean)
    } else {
      callback(null)
    }
  }).catch((error) => {
    callback(null)
    console.log('error:' + JSON.stringify(error));
  })


}

function roundUpToTwoDecimalPlaces(num: number): string {
  const roundedNumber = Math.ceil(num * 100) / 100; // 先將數(shù)字乘以 100破加,然后向上取整,再除以 100
  return roundedNumber.toFixed(2); // 將結(jié)果保留兩位小數(shù)并返回
}

function roundUpToTwoDecimal(num: number): number {
  const roundedNumber = Math.ceil(num * 100) / 100; // 先將數(shù)字乘以 100雹嗦,然后向上取整范舀,再除以 100
  return parseFloat(roundedNumber.toFixed(2)); // 將結(jié)果保留兩位小數(shù)并返回
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市了罪,隨后出現(xiàn)的幾起案子锭环,更是在濱河造成了極大的恐慌,老刑警劉巖泊藕,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辅辩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡娃圆,警方通過(guò)查閱死者的電腦和手機(jī)玫锋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)讼呢,“玉大人撩鹿,你說(shuō)我怎么就攤上這事≡闷粒” “怎么了节沦?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)础爬。 經(jīng)常有香客問(wèn)我散劫,道長(zhǎng),這世上最難降的妖魔是什么幕帆? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任获搏,我火速辦了婚禮,結(jié)果婚禮上失乾,老公的妹妹穿的比我還像新娘常熙。我一直安慰自己,他們只是感情好碱茁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布裸卫。 她就那樣靜靜地躺著,像睡著了一般纽竣。 火紅的嫁衣襯著肌膚如雪墓贿。 梳的紋絲不亂的頭發(fā)上茧泪,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音聋袋,去河邊找鬼队伟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛幽勒,可吹牛的內(nèi)容都是我干的嗜侮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼啥容,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锈颗!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起咪惠,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤击吱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后遥昧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姨拥,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年渠鸽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叫乌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡徽缚,死狀恐怖憨奸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凿试,我是刑警寧澤排宰,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站那婉,受9級(jí)特大地震影響板甘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜详炬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一盐类、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呛谜,春花似錦在跳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至聚凹,卻和暖如春割坠,著一層夾襖步出監(jiān)牢的瞬間齐帚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工彼哼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留对妄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓沪羔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親象浑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔫饰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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