«

折叠面板使用时拿到后端数据渲染的处理(错误状态:数据循环渲染时,折叠面板展开时一起展开,收起一起收起。本文用于评论回复场景!)

yang 发布于 阅读:413 项目


<template>
  <div class="discuss" v-loading="tableLoading">
    <div class="discuss-body-wrap" ref="discussBody" v-if="dataList.length">
      <section class="discuss-body" v-for="(v, i) in dataList" :key="i">
        <div style="margin-bottom: 15px;">
          <section class="discuss-content">
            <div class="content-top">
              <!-- 头像 -->
              <div class="avatar">{{ v.sendUserName.slice(0, 1) }}</div>
              <!-- 时间名字 -->
              <div class="comment_detail">
                <div class="content-header">
                  <div>
                    <span class="nickName">{{ v.sendUserName }}</span>
                    <span class="time">{{ v.createTime }}</span>
                  </div>

                  <div class="content-btn">
                    <el-tooltip content="回复" placement="top">
                      <i
                        v-if="v.sendUserId !=userId"
                        @click="replyComment(v)"
                        style="cursor:pointer; margin-right: 5px;"
                        class="el-icon-chat-dot-round">
                      </i>
                    </el-tooltip>

                    <el-tooltip content="删除" placement="top">
                      <i v-if="v.sendUserId ==userId" @click="delComment(v)" style="cursor: pointer; color: #f56c6c;" class="el-icon-delete"> </i>
                    </el-tooltip>
                  </div>
                </div>
                <span class="message">{{ v.messageInfo }}</span>
              </div>
            </div>
          </section>

          <!-- 子评论的折叠面板 -->
          <el-collapse v-if="v.whetherReply > 0" v-model="comments[v.id].active" @change="active=>handleChange(v,active)" accordion>
            <el-collapse-item :title="comments[v.id].active ? '收起回复' : '更多回复'" :name="v.id">
              <section class="discuss-body" v-for="(v2) in comments[v.id].list" :key="v2.id+'-'+v.id">
                <div style="margin-bottom: 15px;">
                  <section class="discuss-content">
                    <div class="content-top">
                      <!-- 头像 -->
                      <div class="avatar">{{ v2.sendUserName.slice(0, 1) }}</div>
                      <!-- 时间名字 -->
                      <div class="comment_detail">
                        <div class="content-header">
                          <div>
                            <span class="nickNamerole">
                              {{ v2.sendUserName }} <span class="nickName">回复</span> <span>{{ v2.replyUserName }}</span>
                            </span>
                            <span class="time">{{ v2.createTime }}</span>
                          </div>

                          <div class="content-btn">
                            <el-tooltip content="回复" placement="top">
                              <i
                                v-if="v2.sendUserId !=userId"
                                @click="replyComment(v2,v)"
                                style="cursor:pointer; margin-right: 5px;"
                                class="el-icon-chat-dot-round">
                              </i>
                            </el-tooltip>

                            <el-tooltip content="删除" placement="top">
                              <i
                                v-if="v2.sendUserId ==userId"
                                @click="delComment(v2,v)"
                                style="cursor: pointer; color: #f56c6c;"
                                class="el-icon-delete">
                              </i>
                            </el-tooltip>
                          </div>
                        </div>
                        <span class="message">{{ v2.messageInfo }}</span>
                      </div>
                    </div>
                  </section>
                </div>
              </section>
            </el-collapse-item>
          </el-collapse>
        </div>
      </section>
    </div>

    <div v-if="!dataList.length" class="discuss-body-wrap" ref="discussBody">
      <el-empty description="暂无评论" />
    </div>

    <!-- 底部输入区域 -->
    <section class="discuss-input">
      <!-- 分页代码 -->
      <div style="margin: 5px 0;">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="requestStr.page"
          :page-sizes="[10, 20, 30, 40]"
          :page-size="requestStr.size"
          layout="prev, pager, next,sizes"
          :total="requestStr.total"
          :pagerCount="pagerCount">
        </el-pagination>
      </div>

      <!-- 回复消息时的显示 -->
      <div class="title" v-if="infoData.sendUserName">
        <!-- <span class="text" v-if="infoData.sendUserName.length > 8">
          <span class="title-nickName">回复 : </span>
          {{ infoData.sendUserName.length > 8 ? infoData.sendUserName.slice(0,8) + "..." : infoData.sendUserName}}
        </span> -->

        <span class="text">
          <span class="title-nickName">回复 : </span>
          {{ infoData.sendUserName }}
        </span>

        <span class="title-data">
          <span class="title-info">内容 :</span>
          {{ infoData.messageInfo.length > 9 ? infoData.messageInfo.slice(0,9) +  "..." : infoData.messageInfo}}
        </span>
      </div>

      <!-- 文本输入组件 -->
      <InputText
        :maxlength="maxnum"
        :rows="row"
        :placeholder="placeholder"
        v-model="values"
        :values="values"
        :clearable="true"
        :input-change="inputChangeMethod"
        :focusMethod="focusMethod" />

      <div class="foot-btn">
        <el-button v-if="CancelBtn" @click="Cancel">取 消</el-button>
        <el-button v-if="showBtn" type="primary" @click="onSubmit">发 送</el-button>
        <el-button v-if="replyBtn" type="primary" @click="replyInfo">回 复</el-button>
      </div>
    </section>
  </div>
</template>
<script >
import { ApiBugcreate, ApiqueryAllmodule, ApiTaskCreate, ApiTaskDelete, ApiTaskReply } from "@/api/fillingGroups/projectTaskApi.js";

export default {
  data() {
    return {
      collapseTitle: "更多回复",
      tableLoading: false,
      pagerCount: 5,
      userId: this.$store.state.user.user.id, //当前登录用户id
      requestStr: {
        page: 1,
        size: 10,
        total: 0
      },

      Expandcomment: [], //子评论
      activeNames: "",
      totalCount: null,
      maxnum: 2500,
      row: 1,
      values: "",
      placeholder: "请输入内容",

      CancelBtn: false,
      infoData: {},
      replyBtn: false,
      news: "",
      Infotask: {},
      dataList: [], //父评论
      showBtn: false,

      comments: {},
      parentData: {}
    };
  },

  props: {
    itemGuid: {
      type: String,
      default: true
    },

    taskIntel: {
      type: Object,
      default: true
    }
  },

  watch: {
    itemGuid(newVal, oldVal) {
      if (newVal) {
        this.itemGuid = newVal;
      }
    },

    taskIntel(newVal, oldVal) {
      if (newVal) {
        this.Infotask = newVal;
        // this.$nextTick(() => {
        //   this.getDataList();
        // });
      }
    }
  },

  mounted() {
    // this.$nextTick(() => {
    //   this.getDataList();
    // });
    this.Infotask = this.taskIntel;
    // console.log("🚀 ~ taskIntel ~ newVal:", this.taskIntel);
    // console.log("🚀 ~ taskIntel ~ newVal:", this.itemGuid);
  },

  methods: {
    // 问题: 获取评论列表
    async getDataList(val) {
      this.tableLoading = true;
      let oParam = {
        ...(val !== undefined && { createBoolean: val }), //获取排序的参数
        moduleType: "bug",
        proId: this.Infotask.affiliatedProject,
        moduleId: this.Infotask.id,
        page: this.requestStr.page - 1,
        size: this.requestStr.size
      };

      await ApiqueryAllmodule(oParam).then((res) => {
        // console.log("🚀 ~ awaitApiqueryAllmodule ~ res:", res);
        if (res.code == "200") {
          this.tableLoading = false;
          this.$set(this, "dataList", res.rows);
          // this.dataList = res.rows;
          this.dataList.forEach((v, i) => {
            if (!this.comments[v.id]) {
              this.$set(this.comments, v.id, {
                active: "",
                list: []
              });
            }
          });

          this.requestStr.total = res.totalCount; //获取总数
          //this.totalCount = res.totalCount; //获取总数
          this.$emit("update:total-count", this.requestStr.total); //获取总数传到父组件去
        }
      });
    },

    // 聚焦时的操作
    focusMethod() {
      //判断显示操作按钮
      if (this.CancelBtn == false) {
        this.showBtn = true;
      }
      if (this.showBtn == true) {
        this.CancelBtn == true;
      }

      this.CancelBtn = true; //显示取消按钮
      this.row = 4;

      //计算滚动条高度
      this.$nextTick(() => {
        const el = this.$refs.discussBody;
        // console.log(el.scrollHeight, el.clientHeight);
        el.scrollTop = el.scrollHeight - el.clientHeight;
      });
    },

    // 拿到输入框的值
    inputChangeMethod() {
      this.news = this.values;
    },

    //删除
    delComment(val, parent) {
      this.$confirm("此操作将永久删除该评论, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          let oParam = {
            id: val.id
          };
          // console.log(333, val, this.infoData);
          ApiTaskDelete(oParam).then((res) => {
            if (res.code == "200") {
              this.$message.success("删除成功!");

              // 判断子评论与父评论的调用刷新
              if (val.replyId) {
                this.handleChange(parent);
              } else {
                this.getDataList();
              }
            }
          });
        })
        .catch(() => {
          this.$message.info("已取消删除!");
        });
    },

    //回复
    replyComment(val, parentData) {
      // console.log("🚀 ~ replyComment ~ val:", val);
      // console.log("🚀 ~ replyComment ~ parentData:", parentData);
      this.CancelBtn = true;
      this.showBtn = false;
      this.replyBtn = true;
      this.row = 4;
      this.infoData = val;
      this.parentData = parentData;

      //获取滚动条的高度
      this.$nextTick(() => {
        const el = this.$refs.discussBody;
        el.scrollTop = el.scrollHeight - el.clientHeight;
      });
    },

    // 回复消息请求
    async replyInfo() {
      let oParam = {
        messageInfo: this.news,
        replyId: this.infoData.id
      };

      await ApiTaskReply(oParam).then((res) => {
        if (res.code == "200") {
          this.news = "";
          this.values = "";
          this.row = 1;
          this.replyBtn = false;
          this.CancelBtn = false;
          this.$message.success("评论成功!");
          // console.log(222, this.infoData, this.parentData);

          // 判断子评论与父评论的调用刷新
          if (this.infoData.replyId) {
            this.handleChange(this.parentData);
          } else {
            this.getDataList();
          }

          this.infoData = {};
        }
      });
    },

    //提交
    async onSubmit() {
      this.infoData = {};
      this.CancelBtn = true;
      this.replyBtn = false;
      if (!this.news) {
        this.$message.error("请输入内容");
        return;
      }

      let oParam = {
        messageInfo: this.news,
        proId: this.Infotask.affiliatedProject,
        moduleId: this.Infotask.id
      };

      await ApiBugcreate(oParam).then((res) => {
        if (res.code == "200") {
          this.getDataList();
          this.news = "";
          this.values = "";
          this.showBtn = false;
          this.CancelBtn = false;
          this.row = 1;
        }
      });
    },

    // 取消
    Cancel() {
      this.infoData = {};
      this.news = "";
      this.values = "";
      this.showBtn = false;
      this.replyBtn = false;
      this.CancelBtn = false;
      this.row = 1;
    },

    //获取回复内容
    async handleChange(val, active) {
      if (active !== undefined) {
        this.comments[val.id].active = active;
      }
      // 判断没有值时收起时不触发接口
      if (active === "") {
        return;
      }

      this.Expandcomment = [];
      let oParam = {
        moduleType: "bug",
        proId: this.Infotask.affiliatedProject,
        moduleId: this.Infotask.id,
        replyId: val.id
      };
      // console.log(444, this.comments, val.id, this.comments[val.id]);
      await ApiqueryAllmodule(oParam).then((res) => {
        if (res.code == "200") {
          this.comments[val.id].list = res.rows;
          //   this.$set(this, "Expandcomment", res.rows);
          // this.Expandcomment = res.rows;
        }
        // console.log(res, "获取回复内容评论列表");
      });
    },

    //分页
    handleCurrentChange(val) {
      this.requestStr.page = val;
      this.getDataList();
    },

    //每页
    handleSizeChange(val) {
      this.requestStr.size = val;
      this.getDataList();
    }
  },

  components: {
    InputText: () => import("@/views/components/taskDetails/input-text.vue") //文本输入组件
  }
};
</script>
<style lang="scss" scoped>
::v-deep .el-collapse-item__content {
  padding-bottom: 0;
}
::v-deep .el-pagination .el-select .el-input .el-input__inner {
  padding-right: 21px;
  border-radius: 3px;
}

// 更多回复的折叠面板颜色
::v-deep .el-collapse-item__wrap {
  background-color: #f2f2f2;
  border-radius: 8px;
  margin-top: 3px;
}

// 更多回复的折叠面板内容颜色
::v-deep .el-collapse-item__header {
  border-radius: 8px;
  background-color: #f2f2f2;
  color: #807b7b;
}
// 选择多少页的选择项
::v-deep .el-pagination .el-select .el-input {
  width: 79px;
  /* margin: 0 5px; */
}
//分页页码字
::v-deep .el-pager li {
  min-width: 26px;
}
//分页右边箭头
::v-deep .el-pagination .btn-next {
  padding-left: 0px;
}
//分页左边箭头
::v-deep .el-pagination .btn-prev {
  padding-right: 0px;
}

::v-deep .el-collapse {
  border: none;
  // border-top: 1px solid #ebeef5;
  // border-bottom: 1px solid #ebeef5;
}

.discuss {
  width: 100%;
  height: 100%;
  overflow-y: hidden;
  display: flex;
  flex-direction: column;
  // position: relative;
  // height: calc(100% - 160px);
  // overflow-y: auto;
  .discuss-body-wrap {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    //border: 1px solid #1f2329;
    // position: relative;
    // overflow: auto;
    // height: calc(100% - 160px);
  }

  //   .discuss-content:hover {
  //     border-radius: 5px;
  //     background-color: #eaeced; /* 设置悬停时的背景颜色 */
  //   }
  .discuss-content:hover .content-btn {
    display: block !important;
  }
  ::v-deep.el-divider--horizontal {
    margin: 3px 0;
  }

  .discuss-content {
    // width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .content-top {
      display: flex;
      align-items: center;

      .avatar {
        width: 32px;
        height: 32px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        font-size: 12px;
        background-color: #56abfb;
      }

      .comment_detail {
        width: 305px;
        color: #1f2329;
        font-size: 14px;
        margin-left: 10px;

        .content-header {
          display: flex;
          align-items: center;
          justify-content: space-between;

          margin-bottom: 3px;
          .nickNamerole {
            margin-right: 6px;
            color: #8f9a9e;
            .nickName {
              color: #1f2329;
              font-size: 15px;
            }
          }

          .time {
            margin-left: 4px;
            color: #8f9a9e;
            font-size: 12px;
          }
        }

        .message {
          font-size: 13px;
          letter-spacing: 2px;
          color: #666666;
          // word-break: break-all;
        }
      }
    }

    .content-btn {
      width: 36px;
      display: none;
    }
  }

  .discuss-input {
    width: 345px;
    bottom: 50px;
    box-sizing: border-box;
    // position: absolute;
    // height: 200px;
    .title {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      // overflow: hidden; /* 超出部分隐藏 */
      // text-overflow: ellipsis; /* 显示省略号 */
      // white-space: nowrap; /* 防止文本换行 */
      padding: 0 3px;
      margin-bottom: 0;
      color: #8f9a9e;
      width: 345px;
      height: 30px;
      line-height: 30px;
      border-radius: 6px;
      border: 1px solid #56abfb;
      border-bottom: 0;

      .text {
        margin-right: 9px;
      }

      .title-nickName {
        color: #1f2329;
        font-size: 15px;
      }
      .title-data {
        letter-spacing: 2px;

        .title-info {
          color: #1f2329;
          font-size: 15px;
        }
      }
    }

    .foot-btn {
      margin-top: 8px;
      float: right;
    }
  }
}
</style>

效果图:

折叠面板使用时拿到后端数据渲染的处理(错误状态:数据循环渲染时,折叠面板展开时一起展开,收起一起收起。本文用于评论回复场景!)

版权所有:微4e
文章标题:折叠面板使用时拿到后端数据渲染的处理(错误状态:数据循环渲染时,折叠面板展开时一起展开,收起一起收起。本文用于评论回复场景!)
除非注明,文章均为 微4e 原创,请勿用于任何商业用途,禁止转载

推荐阅读:


扫描二维码,在手机上阅读
请先 登录 再评论