callMe.vue 6.5 KB
<template>
  <van-list v-model:loading="loading" :finished="finished" :finished-text="finishedTextStatus ? '没有更多了' : ''"
    @load="onLoad">
    <div v-for="(item, key) in commentList" :key="key">
      <div class="comment-wrapper">
        <van-row style="font-size: 0.9rem;">
          <van-col span="4">
            <van-image round width="3rem" height="3rem" :src="item.avatar ? item.avatar : icon_avatar" />
          </van-col>
          <van-col span="16">
            <p>{{ item.name }}</p>
            <p>{{ item.kg_name }}</p>
          </van-col>
          <van-col span="4" style="text-align: center;">
            <p style="color: #333333; position: relative; text-align: right;" @click="setComment(item, 'reply')">
              回复
              <span v-if="item.is_new" class="spot">·</span>
            </p>
            <p>2-25</p>
          </van-col>
        </van-row>
        <van-row>
          <van-col>
            <span style="color: #222222;">{{ item.c_action }}<span style="color: #0B3A72;">@{{ item.c_name }}</span>:{{
            item.note }}</span>
          </van-col>
        </van-row>
      </div>

      <div style="padding: 1rem; background-color: #F7F7F7;" @click="openComment(item)">
        <van-row>
          <van-col span="8" style="position: relative;">
            <van-image width="8rem" height="5rem" fit="cover" :src="item.cover" style="vertical-align: text-bottom;">
              <template #error>加载失败</template>
            </van-image>
            <!-- <div style="position: absolute; top: 2rem; left: 3rem;">
              <van-image width="2rem" height="2rem" :src="icon_player" style="vertical-align: text-bottom;" > </van-image>
            </div> -->
          </van-col>
          <van-col span="14" style="line-height: 2; margin-left: 1rem;">
            <p style="font-size: 1.15rem;">{{ item.perf_name }}</p>
            <p style="color: #999999;">{{ item.book_name }} | {{ item.localism_type }}</p>
          </van-col>
        </van-row>
      </div>
    </div>
  </van-list>

  <van-empty v-if="emptyStatus" class="custom-image" :image="no_image" description="暂无@我的" />

  <comment-box :show-popup="showCommentBoxPopup" :type="commentType" :replay-user="replayUser"
    @on-submit="submitCommentBox" @on-close="closeCommentBox" />
</template>

<script setup>
// import { mainStore } from '@/store'
import { no_image, icon_avatar } from '@/utils/generateIcons.js'
import CommentBox from '@/components/CommentBox/index.vue'
import { ref, onActivated } from 'vue'
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
// import axios from '@/utils/axios';
import _ from 'lodash'
import { Toast } from 'vant';
// import { addPages, store } from '@/hooks/useKeepAlive'
import { myAtmeAPI } from '@/api/C/me'
import { addCommentAPI, addReplyAPI } from '@/api/C/perf'
import { myCommentTimeAPI } from '@/api/C/perf'

const $route = useRoute();
const $router = useRouter();

onBeforeRouteLeave(async () => {
  // 更新留言阅读情况
  await myCommentTimeAPI({ optr_type: 'atme_comment' });
})

const loading = ref(false);
const finished = ref(false);
const commentList = ref([])
let limit = ref(10);
let offset = ref(0)
// 因为不能让空图标提前出来的写法
const finishedTextStatus = ref(false);
const emptyStatus = ref(false);
//
const onLoad = async () => {
  const { data } = await myAtmeAPI({ limit: limit.value, offset: offset.value });
  _.each(data, item => {
    let arr = _.split(item.target_name, '@'); // 分割评论的动作和姓名
    item.c_action = arr[0]; // 评论动作
    item.c_name = arr[1]; // 评论姓名
  })
  commentList.value = [...commentList.value, ...data];
  offset.value = commentList.value.length;
  loading.value = false;
  // 数据全部加载完成
  if (!data.length) {
    // 加载状态结束
    finished.value = true;
  }
  if (!commentList.value.length) {
    finishedTextStatus.value = false;
    emptyStatus.value = true;
  } else {
    emptyStatus.value = false;
  }
}

/******** 留言框相关操作 START *******/
// 回复评论控件
const showCommentBoxPopup = ref(false);
const commentType = ref(''); // 类型 comment 为评论 / 类型 reply 为回复

/**
 * 回复/评论 功能
 * @param {*} v 单行评论数据
 * @param {*} type 类型 comment 为评论/类型 reply 为回复
 */
const commentId = ref('')
const replayUser = ref('')
// 打开评论弹框组件
const setComment = (v, type) => {
  showCommentBoxPopup.value = true;
  commentType.value = type;
  replayUser.value = v.name;
  commentId.value = v.id;
}

/**
 * 留言/回复 回调
 * @param {*} note 留言内容
 * @param {*} prod_id 作品ID
 * @param {*} comment_id 评论ID
 */
const submitCommentBox = async (note) => {
  let params = { note };
  if (commentType.value === 'comment') {
    params.prod_id = $route.query.prod_id;
    const { msg } = await addCommentAPI(params);
    if (msg === 'OK') {
      Toast.success('发布成功')
      // 刷新列表
      location.reload()
    }
  }
  if (commentType.value === 'reply') {
    params.comment_id = commentId.value;
    const { msg } = await addReplyAPI(params);
    if (msg === 'OK') {
      Toast.success('发布成功')
      // 刷新列表
      location.reload()
    }
  }
}

const closeCommentBox = (v) => { // 关闭留言框
  showCommentBoxPopup.value = v;
}
/******** 留言框相关操作 START *******/

const onClick = (item) => {
  // 调整书籍详情页
  $router.push({
    path: '/client/videoDetail',
    query: {
      prod_id: item.prod_id,
      perf_id: item.perf_id,
      book_id: item.book_id
    }
  });
}

const openComment = (item) => {
  $router.push({
    path: '/client/videoDetail/comment',
    query: {
      prod_id: item.prod_id,
      perf_id: item.perf_id,
      book_id: item.book_id
    }
  });
}

/****************** keepAlive 模块 *******************/

// TAG: keepAlive 缓存页面
// addPages();

onActivated(() => { // keepAlive 重置后执行回调
});

/*********************************************************/
</script>

<script>
export default {
  name: 'callMe',
  data () {
    return {

    }
  },
  mounted () {

  },
  methods: {

  }
}
</script>

<style lang="less" scoped>
.comment-wrapper {
  color: #999999;
  padding: 1rem;
  line-height: 1.75;
  position: relative;
  .reply-wrapper {
    background: #F7F7F7;
    border-radius: 10px;
    padding: 0.5rem;
    margin-top: 0.5rem;
    color: #0B3A72;

    .content {
      color: #222222;
    }
  }
  .spot {
    color: red;
    font-size: 2rem;
    position: absolute;
    right: -0.5rem;
    top: -1.75rem;
  }
}
</style>