index.vue 8.96 KB
<template>
  <!-- 内部消息 -->
  <div class="message-container">
    <div class="top-content">
      <div class="content__left">
        <el-select
          v-model="messageType"
          style="width: 88px; margin-right: 10px"
          @change="search"
        >
          <el-option
            v-for="item in readOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>

        <el-button
          :disabled="!selectedRows.length"
          icon="el-icon-delete"
          @click="handleDelete"
        >
          删除
        </el-button>

        <el-button
          v-show="messageType == 1"
          :disabled="!selectedRows.length"
          @click="handleMark"
        >
          <i class="icon-read1" style="font-size: 12px"></i>
          标记为已读
        </el-button>

        <el-button
          v-show="messageType == 1"
          :disabled="!tableData.length"
          @click="handleAllMark"
        >
          <i class="icon-read1" style="font-size: 12px"></i>
          全部标记为已读
        </el-button>
      </div>

      <div class="content__right">
        <el-input
          v-model="searchKey"
          clearable
          placeholder="请输入标题"
          @focus="handleFocus"
          @blur="handleBlur"
          @keyup.enter.native="search"
        ></el-input>
        <i ref="icon" class="icon-flow-center-search" @click="search"></i>
      </div>
    </div>

    <!-- 表格 -->
    <div class="table">
      <el-table
        v-loading="loading"
        border
        :data="tableData"
        :height="tableHeight + 'px'"
        @sort-change="columnSort"
        @selection-change="selectionChange"
      >
        <el-table-column align="center" type="selection"></el-table-column>

        <el-table-column label="标题">
          <template #default="{ row }">
            <div class="msg-subject" @click="checkMsgDetail(row)">
              {{ row.subject }}
            </div>
          </template>
        </el-table-column>

        <el-table-column label="发信人" prop="owner"></el-table-column>

        <el-table-column label="发信时间" prop="createTime"></el-table-column>

        <el-table-column
          v-if="messageType === 2"
          sortable="custom"
          label="收信时间"
          prop="receiveTime"
        >
          <template #default="{ row: { receiveTime } }">
            {{ receiveTime ? receiveTime : '未读消息' }}
          </template>
        </el-table-column>
        <template slot="empty">
          <el-image :src="tableNoDataImg"></el-image>
          <p class="no-data-text">暂无数据</p>
        </template>
      </el-table>

      <el-row type="flex" justify="end" class="my-pagination">
        <el-pagination
          background
          :current-page="pagination.page"
          :page-sizes="[10, 20, 30, 50, 100]"
          :page-size="pagination.pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="pagination.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        ></el-pagination>
      </el-row>
    </div>

    <message-dialog :id="msgId" :message-visible.sync="messageVisible" />
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'
  import {
    getMessageList,
    delInnerMessage,
    markInnerMessage,
    markAllInnerMessage,
  } from '@/api/personal'
  import MessageDialog from './components/MessageDialog'
  export default {
    name: 'Message',
    components: {
      MessageDialog,
    },
    data() {
      return {
        msgId: '',
        loading: false,
        messageVisible: false,
        searchKey: '',
        messageType: 1,
        tableData: [],
        selectedRows: [],
        pagination: {
          page: 1,
          pageSize: 30,
          total: 0,
        },
        readOptions: [
          { label: '未读', value: 1 },
          { label: '已读', value: 2 },
        ],

        sorter: 'desc',
        filterQuery: {},
        tableNoDataImg: require('@/assets/nodata_images/table-no-data.png'),
      }
    },
    computed: {
      ...mapGetters({
        themeColor: 'settings/themeColor',
      }),
      tableHeight() {
        return this.$baseTableHeight(-30)
      },
    },
    mounted() {
      this.search()
      this.$store.dispatch('navHeader/setUnreadMsgCount')
    },
    methods: {
      columnSort({ order }) {
        this.sorter = order ? (order == 'ascending' ? 'asc' : 'desc') : ''
        this.search()
      },
      selectionChange(selection) {
        this.selectedRows = selection
      },
      checkMsgDetail({ id }) {
        this.msgId = id
        this.messageVisible = true
      },
      handleMark() {
        if (!this.selectedRows.length) {
          this.$message.warning('请选择要标记的数据')
          return
        }
        const ids = this.selectedRows.map((item) => item.id)
        markInnerMessage(ids).then((res) => {
          if (res.state) {
            this.search()
            this.$message.success(res.message)
            // 标记消息后,更新未读消息数量
            this.$store.dispatch('navHeader/setUnreadMsgCount')
          }
        })
      },
      handleAllMark() {
        this.loading = true
        markAllInnerMessage().then((res) => {
          if (res.state) {
            this.search()
            this.$message.success(res.message)
            // 标记消息后,更新未读消息数量
            this.$store.dispatch('navHeader/setUnreadMsgCount')
            setTimeout(() => {
              this.loading = false
            }, 300)
          }
        })
      },
      handleDelete() {
        if (!this.selectedRows.length) {
          this.$message.warning('请选择要删除的数据')
          return
        }
        const delIds = this.selectedRows.map((item) => item.id)
        const tips = '确定删除所选中的数据吗?'
        this.$confirm(tips, '提示', {
          type: 'warning',
        })
          .then(() => {
            delInnerMessage(delIds).then((res) => {
              if (res.state) {
                this.search()
                this.$message.success(res.message)
                // 删除消息后,更新未读消息数量
                this.$store.dispatch('navHeader/setUnreadMsgCount')
              }
            })
          })
          .catch(() => {})
      },
      handleFocus() {
        this.$refs.icon.style.color = this.themeColor
      },
      handleBlur() {
        this.$refs.icon.style.color = '#c0c4cc'
      },
      handleSizeChange(size) {
        this.pagination.pageSize = size
        this.search()
      },
      handleCurrentChange(currentPage) {
        this.pagination.page = currentPage
        this.search('pageChange')
      },
      search(isPageChange) {
        this.loading = true
        if (!isPageChange) {
          this.pagination.page = 1
        }
        const queryFilter = {
          pageBean: this.pagination,
          querys: [
            {
              property: 'receiveTime',
              value: this.messageType,
              operation: 'EQUAL',
              relation: 'AND',
              group: 'filterTime',
            },
          ],
        }
        if (this.messageType === 2) {
          queryFilter.params = {
            receiveTimeOrder: this.sorter,
          }
        }
        if (this.searchKey !== '') {
          queryFilter.querys.push({
            property: 'subject',
            value: '%' + this.searchKey + '%',
            group: 'main',
            operation: 'LIKE',
            relation: 'OR',
          })
        }
        getMessageList(queryFilter).then((data) => {
          if (data) {
            this.pagination = {
              page: data.page,
              pageSize: data.pageSize,
              total: data.total,
            }
            this.tableData = data.rows ? data.rows : []
          }
          setTimeout(() => {
            this.loading = false
          }, 300)
        })
      },
    },
  }
</script>

<style lang="scss" scoped>
  .message-container {
    width: 100%;
    height: calc(100% - #{$base-margin});
    background: $base-color-white !important;
    .top-content {
      display: flex;
      align-items: center;
      justify-content: space-between;
      flex-wrap: wrap;
      padding: $base-padding;
      .content__right {
        position: relative;
        i {
          font-size: 14px;
          width: 30px;
          height: 32px;
          line-height: 32px;
          position: absolute;
          top: 0px;
          right: 0px;
          color: #c0c4cc;
          text-align: center;
          cursor: pointer;
        }
        ::v-deep .el-input {
          width: 268px;
          .el-input__inner {
            padding-right: 60px;
          }
          .el-input__suffix {
            right: 30px;
          }
        }
      }
    }
    .table {
      padding: 0 $base-padding;
      .msg-subject {
        color: var(--themeColor);
        cursor: pointer;
      }
    }
  }
</style>