Detail.vue 6.88 KB
<template>
  <div>
    <p class="sub_back" @click="handleBack">&#60;返回</p>
    <p class="sub_title">解忧杂货铺</p>
    <div class="experience_detail">
      <div class="control">
        <p class="control_name">{{messageTitle}}</p>
        <el-button type="primary" @click="handleAdd" style="margin-right:20px;">回复</el-button>
      </div>
      <p class="content">{{messageContent}}</p>
      <div class="reply_item" v-for="item in tableData" :key="item.id">
        <p class="reply_name">{{item.name}}</p>
        <p class="reply_time">{{formatTime(item.createTime)}}</p>
        <p class="reply_content">{{item.replyContent}}</p>
        <el-popconfirm title="确定删除?" confirmButtonText="确认" cancelButtonText="取消" @confirm="handleDel(item)">
          <template #reference>
            <span class="del" v-show="UserId==item.userId||userType==3">删除</span>
          </template>
        </el-popconfirm>
      </div>
      <el-empty description="暂无回复" v-if="tableData.length==0"></el-empty>
      <el-pagination :hide-on-single-page="total<=10" background layout="prev, pager, next" v-model="currentPage" :total="total" @current-change="handleCurrentChange">
      </el-pagination>
      <el-dialog :title="editTitle" v-model="editBoxShow">
        <el-form :model="form" :rules="rules" ref="formRef">
          <el-form-item label="" prop="ReplyContent">
            <el-input type="textarea" v-model="form.ReplyContent" :autosize="{ minRows: 4, maxRows: 10 }"></el-input>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="hideEditBox">取 消</el-button>
            <el-button type="primary" @click="submitForm">确 定</el-button>
          </span>
        </template>
      </el-dialog>
      <transition name="el-fade-in">
        <div class="iframe_mask" v-if="iframeMaskShow" @click="handleIframeMask">
          <iframe :src="iframeUrl" frameborder="0"></iframe>
        </div>
      </transition>
    </div>
  </div>
</template>

<script>
import { nextTick, onMounted, reactive, ref, toRefs } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'
import { formatTime } from '@/utils'
import axios from '@/utils/axios'
export default {
  name: 'ExperienceDetail',
  setup () {
    const formRef = ref(null)
    const route = useRoute()
    const router = useRouter()
    const store = useStore()
    const { PostId } = route.query
    const urlReg = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;

    const state = reactive({
      messageTitle: '',
      messageContent: '',
      tableData: [],
      total: 0,
      currentPage: 1,
      loading: false,
      editBoxShow: false,//编辑框显示
      iframeMaskShow: false,//iframe显示
      iframeUrl: '',//iframe链接
      editTitle: '',
      form: {
        id: '0',
        ReplyContent: '',
      },
      rules: {
        ReplyContent: [
          { required: 'true', message: '回复内容不能为空', trigger: ['change'] }
        ]
      },
      UserId:store.state.userInfo?.userId,
      userType: store.state.userInfo?.userType,
    })
    onMounted(() => {
      getReply()
    })
    // 问题回复列表
    const getReply = () => {
      state.loading = true
      axios.post('/Exchange/Reply/List', {
        "PostId": PostId,
        "CheckStatus":2,
        "PageIndex": state.currentPage,
        "PageSize": 1000
      }).then(res => {
        // console.log('问题回复列表:', res.result)
        state.tableData = res.result.data
        state.messageTitle = res.messageTitle
        state.messageContent = res.messageContent
        state.total = res.result.count
        state.loading = false
      }).catch(err => {
        console.log('err', err)

      })
    }
    // 搜索
    const searchChange = (e) => {
      getReply()
    }
    // 回复
    const handleAdd = () => {
      state.editTitle = '回复';
      state.form = {
        id: '0',
        ReplyContent: '',
      };

      state.editBoxShow = true
    }
    // 删除
    const handleDel = (e) => {
      axios.delete('/Exchange/Reply', {
        params: {
          "id": e.id,
        }
      }).then(() => {
        ElMessage.success('删除成功')
        state.currentPage = 1;
        getReply()
      })
    }
    // 回复
    const submitForm = () => {
      if(!state.UserId)return;
      formRef.value.validate((vaild) => {
        if (vaild) {
          axios.post('/Exchange/Reply', {
            "Id": 0,
            "PostId": PostId,
            "UserId": state.UserId,
            "ReplyContent": state.form.ReplyContent,
            "CheckStatus": state.userType == 3 ? 2 : 1,//老师提问无需审核
          }).then(() => {
            ElMessage.success(state.userType == 3?'回复成功':'回复成功,审核通过后会显示')
            state.editBoxShow = false
            getReply()
          })

        }
      })
    }
    // 页码改变时
    const handleCurrentChange = (e) => {
      state.currentPage = e;
      getReply()
    }
    // 点击iframe遮罩
    const handleIframeMask = () => {
      state.iframeMaskShow = false;
    }
    // 编辑窗点取消
    const hideEditBox = () => {
      state.editBoxShow = false
      resetForm()
    }
    // 点击查看
    const handleView = (e) => {
      const url = e.url;
      console.log(url)
      if (urlReg.test(url)) {
        state.iframeUrl = url
        state.iframeMaskShow = true;
      } else {
        ElMessage.error('请检查文章链接,以http://或https://开头')
      }
    }
    const handleBack = () => {
      router.back()
    }
    // 重置表单
    const resetForm = () => {
      formRef.value.resetFields();
      state.form = {
        id: '0',
        ReplyContent: '',
      };
    }
    return {
      ...toRefs(state),
      formRef,
      searchChange,
      handleAdd,
      handleDel,
      handleView,
      submitForm,
      handleCurrentChange,
      handleIframeMask,
      hideEditBox,
      handleBack,
      formatTime
    }
  }
}
</script>
<style lang="scss" scoped>
.control {
  display: flex;
  align-items: center;
  justify-content: space-between;
  .control_name {
    font-size: 23px;
    font-weight: bold;
  }
  .el-input {
    width: 300px;
  }
}
.experience_detail {
  background: #fff;
  padding: 0 20px;
  padding-bottom: 40px;
  .content {
    font-size: 16px;
  }
  .reply_item {
    font-size: 16px;
    padding: 36px 0;
    border-bottom: 1px solid #edf2f5;
    position: relative;
    // &:nth-of-type() {
    //   border-bottom: 1px solid red;
    //   // border:0;
    // }
    p {
      margin: 0;
    }
    .reply_name {
    }
    .reply_time {
      color: #999;
      margin-top: 12px;
    }
    .reply_content {
      margin-top: 28px;
    }
    .del {
      position: absolute;
      bottom: 36px;
      right: 0;
      cursor: pointer;
      color: rgb(249, 62, 62);
    }
  }
}
</style>