<template>
  <div style="height: 100%; width: 100%; background-color: #ededed">
    <div class="wrap">
      <!-- 头部 -->
      <div class="titleBox">
        <!-- <img
          src="https://img-qn-2.51miz.com/preview/element/00/01/27/97/E-1279706-3813EBF9.jpg!/quality/90/unsharp/true/compress/true/format/jpg/fh/320"
          alt=""
          class="head_portrait"
          style="margin-left: 20px; margin-right: 20px"
        />-->
        <div class="ai">AI 问答</div>
      </div>
      <!-- 底部 -->
      <div class="infoBox">
        <!-- 左边用户列表 -->

        <!-- 右边输入框和信息展示 -->
        <div class="infoList">
          <!-- 信息 -->
          <div class="infoTop" ref="scrollBox" id="box">
            <div
              :class="
                item.position == 'left' ? 'chatInfoLeft' : 'chatInfoRight'
              "
              v-for="(item, index) in userInfoList"
              :key="index"
            >
              <!-- <img :src="item.url" alt="头像" class="head_portrait2" v-if="item.position == 'left'&&loading"/> -->
              <img :src="item.url" alt="头像" class="head_portrait2" />
              <div :class="item.position == 'left' ? 'chatLeft' : 'chatRight'">
                <div class="text" id="text-container" v-html="item.info" v-if="item.info!==''"></div>
                <div class="bounce" v-if="item.info===''&&item.position == 'left'&&loading">
                  <div></div>
                  <div></div>
                  <div></div>
                </div>
              </div>
            </div>
          </div>
          <!-- 输入框 -->
          <div class="infoBottom">
            <div class="infoIcon"></div>
            <textarea
              type="textarea"
              :disabled="disabled"
              class="infoInput"
              v-model="textarea"
              @keydown.enter.exact="handlePushKeyword($event)"
              @keyup.ctrl.enter="lineFeed"
            />
            <div class="fasong" @click="setUp">发送</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
// 这里引了会报错 报啥错 你试下
export default {
  data() {
    return {
      //用户点击选中变色
      act: Number,
      loading: false,
      disabled: false,
      //模拟花间一壶酒用户的历史信息
      userInfoList2: [
        {
          url: require("@/assets/img/gpt.png"),
          username: "花间一壶酒",
          info: "您有什么需要了解的信息？",
          timer: "2022/8/9",
          position: "left"
        }

        // {
        //   url:
        //     "https://img2.baidu.com/it/u=2859542338,3761174075&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500",
        //   username: "超人不换内裤",
        //   info: "在吗在吗",
        //   timer: "2022/8/1",
        //   position: "right"
        // }
      ],
      TestData: "",
      //历史信息
      userInfoList: [],
      //输入框
      textarea: "",
      warn: false,
      //滚动条距离顶部距离
      scrollTop: 0,
      //发送和输入显隐
      isshow: 0
    };
  },
  mounted() {
    this.userInfoList = this.userInfoList2;
  },
  methods: {
    //发送
    setUp() {
      this.disabled = true;
      console.log("发送内容:", this.textarea);
      if (this.textarea.length < 1) {
        // this.warn = true;
        this.$message({
          message: "不能发送空白信息！",
          type: "warning"
        });
        this.textarea = "";
        setTimeout(() => {
          //   this.warn = false;
        }, 1000);
        return;
      }
      this.loading = true;
      this.userInfoList2.push({
        url:
          "https://img2.baidu.com/it/u=2859542338,3761174075&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500",
        username: "超人不换内裤",
        info: this.textarea,
        timer: "2022/8/1",
        position: "right"
      });

      this.userInfoList2.push({
        url: require("@/assets/img/gpt.png"),
        username: "花间一壶酒",
        info: "",
        timer: "2022/8/9",
        position: "left"
      });
      // 这个地方需要掉接口
      let textarea = this.textarea;
      this.textarea = "";
      fetch("http://192.168.40.45:5002/visit_record_summary_talk", {
        method: "POST",
        body: JSON.stringify({ message: textarea }),
        headers: {
          Accept: "text/event-stream",
          "Content-Type": "application/json"
        }
      })
        // this.TestData = "";
        // fetch("http://192.168.40.45:5005/stream_json_data", {
        //   method: "POST",
        //   body: JSON.stringify({ message: textarea }),
        //   headers: {
        //     Accept: "text/event-stream",
        //     "Content-Type": "application/json"
        //   }
        // })
        .then(response => {
          console.log(response, "respons");
          if (!response.ok) {
            throw new Error("Network response was not ok");
          }
          console.log(response.body, "response.text()response.text()");

          return response.body;
          // return response.json();
        })
        .then(stream => {
          const reader = stream.getReader();
          const encode = new TextDecoder("utf-8");
          this.loading = false;
          const that = this;
          that.TestData = "";
          function readChunk() {
            reader.read().then(({ value, done }) => {
              const decodeText = encode.decode(value);
              if (decodeText) {
                that.userInfoList2[
                  that.userInfoList2.length - 1
                ].info += JSON.parse(decodeText).text;
              }
              // const text = JSON.parse(decodeText).text; // 要显示的文字
              // const container = document.getElementById("text-container"); // 容器
              // container.textContent += text
              // that.TestData += JSON.parse(decodeText).text;

              // let index = 0; // 当前文字索引

              // function showText() {
              //   if (index < text.length) {
              //     container.textContent += text[index]; // 显示当前字符
              //     index++;
              //     setTimeout(showText, 100); // 设置下一次调用的延迟
              //   }
              // }

              // showText(); // 开始显示文字
              if (done) {
                that.disabled = false;
                console.log(that.TestData, "that.TestData");
                // 数据流结束
                console.log("Done reading the stream");
                return;
              }
              setTimeout(readChunk, 1000); // 延时1秒后继续读取下一个数据块
            });
          }

          readChunk(); // 启动读取流程
        })
        .catch(error => {
          console.error("Error:", error);
        })
        .finally(() => {
          console.log("KKKKKKKKKKKKKKKKKKKKKKKKK");

          // this.userInfoList = this.userInfoList2;
        });

      // axios({
      //   method: "POST",
      //   url: "http://192.168.40.45:5111/stream",
      //   // "http://localhost/admin-api/energy/monitor/getTopology",
      //   data: {
      //     message: textarea
      //   }
      // })
      //   .then(response => {
      //     this.loading = false;
      //     this.userInfoList2.pop();
      //     this.textarea = "";

      //     console.log(response, "hhhhhhhhhhhhhhh");
      //     this.userInfoList2.push({
      //       url: require("@/assets/img/gpt.png"),
      //       username: "花间一壶酒",
      //       info: response.data,
      //       timer: "2022/8/9",
      //       position: "left"
      //     });
      //   })
      //   .catch(error => {
      //     console.log(error);
      //   });

      // }, 2000);

      // 页面滚动到底部
      this.$nextTick(() => {
        // 一定要用nextTick
        this.setPageScrollTo();
        //页面滚动条距离顶部高度等于这个盒子的高度
        this.$refs.scrollBox.scrollTop = this.$refs.scrollBox.scrollHeight;
      });
    },
    // 监听键盘回车阻止换行并发送
    handlePushKeyword(event) {
      console.log(event);
      if (event.keyCode === 13) {
        event.preventDefault(); // 阻止浏览器默认换行操作
        this.setUp(); //发送文本
        return false;
      }
    },
    // 监听按的是ctrl + 回车，就换行
    lineFeed() {
      console.log("换行");
      this.textarea = this.textarea + "\n";
    },
    //滚动条默认滚动到最底部
    setPageScrollTo(s, c) {
      //获取中间内容盒子的可见区域高度
      this.scrollTop = document.querySelector("#box").offsetHeight;
      setTimeout(res => {
        //加个定时器，防止上面高度没获取到，再获取一遍。
        if (this.scrollTop != this.$refs.scrollBox.offsetHeight) {
          this.scrollTop = document.querySelector("#box").offsetHeight;
        }
      }, 100);
      //scrollTop：滚动条距离顶部的距离。
      //把上面获取到的高度座位距离，把滚动条顶到最底部
      this.$refs.scrollBox.scrollTop = this.scrollTop;
      //判断是否有滚动条,有滚动条就创建一个监听滚动事件，滚动到顶部触发srTop方法
      if (this.$refs.scrollBox.scrollTop > 0) {
        this.$refs.scrollBox.addEventListener("scroll", this.srTop);
      }
    },
    //滚动条到达顶部
    srTop() {
      //判断：当滚动条距离顶部为0时代表滚动到顶部了
      if (this.$refs.scrollBox.scrollTop == 0) {
        //逻辑简介：
        //到顶部后请求后端的方法，获取第二页的聊天记录，然后插入到现在的聊天数据前面。
        //如何插入前面：可以先把获取的数据保存在 A 变量内，然后 this.userInfoList=A.concat(this.userInfoList)把数组合并进来就可以了
        //拿聊天记录逻辑:
        //第一次调用一个请求拉历史聊天记录，发请求时参数带上页数 1 传过去，拿到的就是第一页的聊天记录，比如一次拿20条。你显示出来
        //然后向上滚动到顶部时，触发新的请求，在请求中把分页数先 +1 然后再请求，这就拿到了第二页数据，然后通过concat合并数组插入进前面，依次类推，功能完成！
        // alert("已经到顶部了");
      }
    }
  }
};
</script>

<style scoped>
.bounce {
  display: flex;
  justify-content: space-between;
  width: 70px;
  margin-top: 26px;
}

.bounce div {
  width: 15px;
  height: 15px;
  background-color: #3498db;
  border-radius: 50%;
  animation: bounce 0.6s infinite alternate;
}

.bounce div:nth-child(2) {
  animation-delay: 0.2s;
}

.bounce div:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes bounce {
  to {
    transform: translateY(-20px);
    opacity: 0.5;
  }
}
.wrap {
  height: 100%;
  width: 100%;
  background-color: #f2f2f2;
  /* margin: auto; */
  /* transform: translateY(10%); */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
  /* border-radius: 10px; */
}

.titleBox {
  height: 10%;
  width: 100%;
  /* background-image: linear-gradient(to right, #1e76bc, #69a3d5); */
  background-color: #313541;
  display: flex;
  align-items: center;
  border-top-right-radius: 10px;
  border-top-left-radius: 10px;
}
.titleBox .ai {
  width: 120px;
  height: 30px;
  text-align: center;
  font-size: 24px;
  margin-left: 20px;
  color: #fff;
}
.infoBottom {
  height: 20%;
  display: flex;
  flex-direction: column;
}
/* 输入框 */
.infoInput {
  height: 58%;
  width: 100%;
  padding-top: 10px;
  background: #f2f2f2;
  box-sizing: border-box;
  padding: 0 30px;
  height: 100%;
  width: 100%;
  border: none;
  outline: none;
  /* font-family: "Micrsofot Yahei"; */
  font-size: 16px;
  resize: none;
}
.fasong {
  height: 30px;
  width: 80px;
  background-color: #0fa47f;
  text-align: center;
  line-height: 30px;
  border-radius: 4px;
  color: #f0f4f0;
  margin-top: 1%;
  align-self: flex-end;
  margin-right: 20px;
  cursor: pointer;
}
.infoIcon {
  height: 30px;
  width: 100%;
  display: flex;
  align-items: center;
}
.infoIcon i {
  font-size: 24px;
  color: #676767;
  margin-left: 15px;
  cursor: pointer;
}
/* 头像 */
.head_portrait {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}
.head_portrait2 {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}
.stateBox {
  margin-left: 20px;
  padding: 1px 8px;
  background-color: #fff;
  border-radius: 10px;
  text-align: center;
  cursor: pointer;
}
.stateBox2 {
  margin-left: 20px;
  padding: 1px 8px;
  background-color: #fff;
  border-radius: 10px;
  text-align: center;
  cursor: pointer;
}
.stateBox2:hover {
  background-color: #dcdcdc;
}

.stateText {
  font-size: 14px;
  margin-left: 5px;
}
/* 列表和信息 */
.infoBox {
  height: 90%;
  width: 100%;
  display: flex;
}
/* 用户列表大盒子 */
.userList {
  height: 100%;
  width: 300px;
  border-right: 1px solid #ccc;
  display: flex;
  flex-direction: column;
}
/* 用户列表 */
.userListBox {
  flex: 1;
  width: 100%;
  overflow: auto;
}
/* 信息外层盒子 */
.infoList {
  height: 100%;
  width: 100%;
}
/* 信息列表 */
.infoTop {
  height: 78%;
  width: 100%;
  border-bottom: 1px solid #ccc;
  padding: 10px;
  box-sizing: border-box;
  overflow: auto;
}
/* 对方发的信息样式 */
.chatInfoLeft {
  min-height: 70px;
  margin-left: 10px;
  margin-top: 10px;
  display: flex;
}
.chatLeft {
  margin-left: 15px;
  flex: 1;
}
.chatLeft .text {
  color: #434343;
  /* margin-top: 8px; */
  background-color: #e3e3e3;
  display: inline-block;
  padding: 12px 16px;
  line-height: 24px;
  border-radius: 10px;
  max-width: 50%;
  /* 忽略多余的空白，只保留一个空白 */
  white-space: normal;
  /* 换行显示全部字符 */
  word-break: break-all;
  white-space: pre-wrap;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

/* 自己发的信息样式 */
.chatInfoRight {
  height: 70px;
  margin-left: 10px;
  margin-top: 10px;
  display: flex;
  flex-direction: row-reverse;
}
.chatRight {
  margin-right: 15px;
  flex: 1;
  /* 用align-items把元素靠右对齐 */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.chatRight .text {
  color: #f9f7f7;
  /* margin-top: 8px; */
  background-color: #0fa47f;
  display: inline-block;
  padding: 12px 16px;
  line-height: 24px;
  border-radius: 10px;
  max-width: 50%;
  /* 忽略多余的空白，只保留一个空白 */
  white-space: normal;
  /* 换行显示全部字符 */
  word-break: break-all;
  white-space: pre-wrap;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

.searchBox {
  padding: 4px 2px;
  border-bottom: 1px solid #ededed;
}
.input-with-select {
  width: 80%;
  margin-right: 2%;
}
/* 点击用户变色 */
.userFlexAct {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 70px;
  border-bottom: 1px solid #e8e8e8;
  cursor: pointer;
  background-color: #e8e8e8;
}
/* 用户默认颜色 */
.userFlex {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 70px;
  border-bottom: 1px solid #e8e8e8;
  cursor: pointer;
}
/* 用户名 */
.userName {
  width: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 简略信息 */
.userInfo {
  width: 100px;
  font-size: 14px;
  color: #ccc;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 3px;
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 5px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background-color: #dbd9d9;
  border-radius: 3px;
}
</style>

