fetch-event-source

<template>
  <view class="content">
    <view class="bottom">
      <view class="input-box">
        <view class="input">
          <view class="i-box">
            <view class="i">
              <u-icon style="margin-top: 2px;" name="edit-pen" color="#b6b6b6" size="22"></u-icon>
              <u--input :readonly="!!raw_text.value" v-model="value" :placeholder="!!raw_text.value ? '小AI正在作答,请稍后' : '有什么问题尽管问我'" border="surround"></u--input>
            </view>
          </view>
        </view>
        <view class="send" @click="send">发送</view>
      </view>
    </view>
    <view :prop="raw_text" :change:prop="renderScript.onChange" id="renderjs-view" v-show="false"></view>
  </view>
</template>

<script>
export default {
  components:{},
  data() {
    return {
      value: '',
      raw_text: {
        doc_content: '',
        value: ''
      }
    }
  },
  async onLoad (e) {

  },
  onUnload() {

  },
  onReady() {},
  methods: {
    async send () {
      this.raw_text.value = this.value
      this.value = ''
    },
    acceptDataFromRenderjs(options) {
      console.log(options);
    },
    fetchErr() {
      console.log(2);
    },
    async save_flashcard () {
      this.raw_text.value = ''
    }
  }
}
</script>
<script module="renderScript" lang="renderjs">
	import { fetchEventSource } from '@microsoft/fetch-event-source'
	export default {
		data() {
			return {
				source: null,
				controller: null,
				messageData: ''
			}
		},
		created() {},
		mounted() {},
		methods: {
			onChange(newValue, oldValue, ownerVm) {
				if (newValue.value) {
            let text = ''
            this.controller = new AbortController()
            this.source = fetchEventSource('', {
              method: 'POST',
              headers: {
                "Content-Type": 'application/json',
              },
              body: JSON.stringify({
                "doc_content": newValue.doc_content,
                "question": newValue.value,
                "stream": true
              }),
              signal: this.controller.signal,
              onmessage:(event) => {
                  if (event.event === 'end') {
                    ownerVm.callMethod('save_flashcard')
                    if (this.controller && this.source) {
                       this.controller.abort()
                       this.source.close();
                    }
                  } else {
                    //监听信息的传输
                     if (event.data) {
                       const v = JSON.parse(event.data)
                       if (v.content !== '```' && v.content !== 'markdown') {
                        text += v.content
                        ownerVm.callMethod('acceptDataFromRenderjs', text)
                       }
                     }
                  }
              },
              onclose:() => {
                console.log('服务端连接被关闭')
                ownerVm.callMethod('save_flashcard')
                if (this.controller && this.source) {
                   this.controller.abort()
                   this.source.close();
                }
              },
              onerror:(error) => {
                console.log('错误信息')
                console.log(error)
                ownerVm.callMethod('fetchErr')
                if (this.controller && this.source) {
                   this.controller.abort()
                   this.source.close();
                }
              }
            })
        }
      }
		}
	}
</script>
<style>
page {
  height: 100%;
  background: #f8f8f8;
}

</style>
<style lang="stylus" scoped>
/deep/ .parse {
  h1 {
    font-size: 16px
  }
  h2, h3, ul {
    font-size: 14px
  }
  ol, ul {
    padding-inline-start: 30px
  }
}
.content {
  height 100%
  overflow hidden
  display: flex;
  flex-direction: column;
  background: #f8f8f8;
  .xx {
    display flex
    align-items center
    font-weight: bold
    line-height 1
    color #627efe
    padding 10px
    box-sizing border-box
    background #fff
    .dd {
      width 40px
      justify-content flex-end
  image {
        width 20px
        height 20px
      }

      .ai {
        width 25 ppx
        height 10px
      }
    }
  }
  .scroll-Y {
    flex 1
    overflow hidden
    .item-box {
      padding 10px
      box-sizing border-box
	  padding-bottom: 30px;
    }
    .yz {
      font-size 14px
      padding 10px
      border-radius 8px
      box-shadow 0px 0px 19px 1px rgba(211, 211, 211, 0.52);
      background #fff
      .t {
        margin-bottom 4px
      }
      .z {
      	color: #627efe;
        text-decoration: underline;
        line-height: 2
      }
    }
    .chat {
      .right {
        display flex
        align-items flex-start
        font-size 14px
        margin 16px 0
        justify-content flex-end
        .user_avatar {
          max-width 30px
          min-width 30px
          height 30px
          border-radius 50%
        }
        .msg {
          max-width 260px
          background #fff
          margin-right 10px
          padding 5px 10px
          border-radius 8px
          view {
            line-height 1.8
          }
        }
      }
      .left {
        display flex
        align-items flex-start
        font-size 14px
        margin 16px 0
        justify-content flex-start
        .more {
          color: #627efe;
          text-align: center;
          margin-top: 10px;
        }
        .user_avatar {
          max-width 30px
          min-width 30px
          height 30px
          border-radius 50%
        }
        .a + .a {
          margin-top 10px
        }
        .msg {
          max-width 260px
          background #fff
          margin-left 10px
          padding 5px 10px
          border-radius 8px
          view {
            line-height 1.8
          }
          .link {
            text-decoration underline
          }
          .h1 {
            color #666
            font-size 16px
            font-weight bold
            border-bottom 1px dashed #666
          }
          .h2 {
            color #666
            font-size 14px
            font-weight bold
            line-height 1.5
          }
          .btn {
            color #627efe
            text-align right
          }
        }
      }
    }
  }
  .btn-boxs {
	  width: 100%;
	  box-sizing border-box
	  padding: 0 20px;
	  height 30px
	  display: flex;
	  align-items center
	  justify-content space-between
	  font-size: 14px
	  color: #627efe;
	  position: absolute
	  left: 0
	  bottom: 50px
	  view {
		box-shadow 0px 0px 2px 1px rgba(98, 126, 254, 0.42);
		color: #fff
		width: 70px;
		background: #627efe
		border: 1px solid #627efe
		padding: 0 6px
		border-radius: 21px
		text-align: center
	  }
  }
  .bottom {
    height 50px
    background #fff
    display flex
    align-items center
    justify-content center
    .input-box {
      flex 1
      padding 0 6px
      display flex
      align-items center
      justify-content center
      .send {
        font-size 14px
        color #627efe
        padding 0 30rpx
      }
      .input {
        flex 1
        height 32px
        background #f7f8fb
        border-radius 32px
        padding 0 10px
        display flex
        align-items center
        justify-content space-between
        .i-box {
          width 100%
          height 100%
          display flex
          align-items center
          justify-content space-between
          .i {
            display flex
            align-items center
            .e {
              margin-left 10px
              font-size 14px
              color #b6b6b6
            }
          }
          .chat {
            background #f83e3e
            color #fff
            font-size 10px
            line-height 1
            padding 2px 4px
            border-radius 14px
            min-width 8px
            text-align center
          }
        }
      }
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值