Newer
Older
smart-metering-front / src / views / workbench.vue
<!-- 总工作台 -->
<route lang="yaml">
name: workbench
meta:
  title: 总工作台
</route>

<script lang="ts" setup>
import type { Ref } from 'vue'
import { ref } from 'vue'
import dayjs from 'dayjs'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getNoticeeApi } from '@/api/system/notice'
import editScheduleDialog from '@/views/workbench/editSchedule.vue'
import { delSchedule, getApprovalMessageList, getCalendarList, getWorkMessageList } from '@/api/workbench/workbench'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import type { IApprovalMessageListQuery, IWorkMessageListQuery } from '@/views/workbench/workbench-interface'
import useUserStore from '@/store/modules/user'
import messageScrolling from '@/views/workbench/components/messageScrolling.vue'
const user = useUserStore()// 用户信息
// ------------------------------------UI------------------------------------------
const blockHeight = ref(300) // 每个展示块高度
const bigBlockHeight = ref(300) // 大展示块的高度
const blockWidth = ref(400)
// 计算工作台区域高度 - 顶部-面包屑-边距
const benchDivHeight = ref()
function calcBlockSize() { // 36是消息滚动栏的高度
  const bodyHeight = document.body.clientHeight - 60 - 20 - 50 - 36
  bigBlockHeight.value = bodyHeight
  blockHeight.value = bodyHeight > 610 ? (bodyHeight - 10) / 2 : 300
  blockWidth.value = (document.body.clientWidth - 180 - 20 - 20) / 3
  console.log(blockHeight.value, blockWidth.value - 20)
  benchDivHeight.value = blockHeight.value - 60
}
// --------------------------------------审批提醒-----------------------------------
const approvalMessageList = ref([]) // 审批提醒列表
const approvalMessageTotal = ref(0) // 审批提醒列表数据总量
const approvalMessageListQuery: Ref<IApprovalMessageListQuery> = ref({
  endTime: '', // 通知结束时间
  messageSourceModule: '', // 来源模块(字典code)
  startTime: '', // 通知开始时间
  status: 0, // 已读1未读0
  offset: 1,
  limit: 20,
})
const approvalMessageLoadingTable = ref(false) // 表格loading
// 表头
const approvalMessageColumns = ref<TableColumn[]>([
  { text: '审批名称', value: 'messageTitle', align: 'center' },
  { text: '时间', value: 'createTime', align: 'center', width: '180px' },
])
// 获取审批提醒列表页
function fetchApprovalMessageData(isNowPage = false) {
  approvalMessageLoadingTable.value = true
  if (!isNowPage) {
    // 是否显示当前页,否则跳转第一页
    approvalMessageListQuery.value.offset = 1
  }
  getApprovalMessageList(approvalMessageListQuery.value).then((response) => {
    approvalMessageList.value = response.data.rows
    approvalMessageTotal.value = parseInt(response.data.total)
    approvalMessageLoadingTable.value = false
  }).catch(() => {
    approvalMessageLoadingTable.value = false
  })
}

// 审批提醒页数发生变化后的操作,可能是页码变化,可能是每页容量变化,此函数必写
const changeApprovalMessagePage = (val: { size?: number; page?: number }) => {
  if (val && val.size) {
    approvalMessageListQuery.value.limit = val.size
  }
  if (val && val.page) {
    approvalMessageListQuery.value.offset = val.page
  }
  fetchApprovalMessageData(true)
}
// --------------------------------------工作提醒-------------------------------------------
const workMessageList = ref([]) // 工作提醒列表
const workMessageTotal = ref(0) // 工作提醒列表数据总量
const workMessageListQuery: Ref<IWorkMessageListQuery> = ref({
  endTime: '', // 消息提醒结束时间
  messageSourceModule: '', // 来源模块(字典code)
  messageType: '', // 消息提醒的业务类型(字典code)
  remindDeptId: '', // 消息提醒的用户部门id
  remindId: '', // 消息提醒的用户id
  startTime: '', // 消息提醒开始时间
  status: 0, // 已读1未读0
  offset: 1,
  limit: 20,
})
const workMessageLoadingTable = ref(false) // 表格loading
// 表头
const workMessageColumns = ref<TableColumn[]>([
  { text: '名称', value: 'messageTitle', align: 'center' },
  { text: '时间', value: 'createTime', align: 'center', width: '180px' },
])
// 获取审批提醒列表页
function fetchWorkMessageData(isNowPage = false) {
  workMessageLoadingTable.value = true
  if (!isNowPage) {
    // 是否显示当前页,否则跳转第一页
    workMessageListQuery.value.offset = 1
  }
  getWorkMessageList(workMessageListQuery.value).then((response) => {
    workMessageList.value = response.data.rows
    workMessageTotal.value = parseInt(response.data.total)
    workMessageLoadingTable.value = false
  }).catch(() => {
    workMessageLoadingTable.value = false
  })
}

// 工作提醒页数发生变化后的操作,可能是页码变化,可能是每页容量变化,此函数必写
const changeWorkMessagePage = (val: { size?: number; page?: number }) => {
  if (val && val.size) {
    workMessageListQuery.value.limit = val.size
  }
  if (val && val.page) {
    workMessageListQuery.value.offset = val.page
  }
  fetchWorkMessageData(true)
}
// -----------------------------------日历--------------------------------------------
const calendarValue = ref(new Date())
const selectedDate = ref('') // 选中的日期
const selectDateRecord = ref('') // 选中的日期记录--完整日期
const editScheduleRef = ref() // 编辑日程ref
const redCircleData = ref() // 日程列表
// 点击编辑日程
const editSchedule = () => {
  editScheduleRef.value.initDialog()
}
// 获取日程列表
const fetchCalendarList = () => {
  const param = {
    userId: user.id,
    calendarMonth: selectedDate.value,
  }
  getCalendarList(param).then((res) => {
    redCircleData.value = res.data
  })
}
// 点击日期
const clickDate = (day: string) => {
  selectDateRecord.value = day
  selectedDate.value = day.slice(0, 7)
  fetchCalendarList() // 获取日历列表
}
// 点击删除icon
const deleteData = () => {
  if (Object.keys(redCircleData.value).length && !redCircleData.value[selectDateRecord.value].length) {
    ElMessage.warning(`${selectDateRecord.value}没有日程,无法删除`)
    return false
  }
  ElMessageBox.confirm(
    `确定删除${selectDateRecord.value}的日程吗?`,
    '提示',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    },
  )
    .then(() => {
      const param = {
        userId: user.id,
        scheduleDate: selectDateRecord.value,
      }
      delSchedule(param).then((res) => {
        ElMessage({
          type: 'success',
          message: '删除成功',
        })
        fetchCalendarList() // 获取日历列表
      })
    })
}

// 编辑日程成功
const editScheduleSuccess = () => {
  fetchCalendarList() // 获取日历列表
}

// -------------------------------------通知公告-------------------------------------------
const noticeList = ref([]) // 审批提醒列表
const noticeTotal = ref(0) // 审批提醒列表数据总量
const searchQuery = ref({
  noticeNo: '', // 编号
  noticePublisher: '', // 发布人
  // noticeTime: '', // 发布时间
  noticeStartTime: '',
  noticeEndTime: '',
  noticeTitle: '', // 标题
  limit: 10,
  offset: 1,
}) // 查询参数
const noticeLoadingTable = ref(false) // 表格loading
// 表头
const noticeColumns = ref<TableColumn[]>([
  { text: '标题', value: 'noticeTitle', align: 'center' },
  { text: '发布时间', value: 'noticeTime', align: 'center', width: '180px' },
])
// 获取通知公告列表页
const fetchNoticeList = () => {
  noticeLoadingTable.value = true
  getNoticeeApi(searchQuery.value).then((res) => {
    // noticeTotal.value = res.data.total
    noticeList.value = res.data.rows
    noticeLoadingTable.value = false
  }).catch(() => {
    noticeLoadingTable.value = false
  })
}

// -------------------------------------------------------------------------------
onMounted(() => {
  calcBlockSize()
  selectedDate.value = dayjs().format('YYYY-MM')
  selectDateRecord.value = dayjs().format('YYYY-MM-DD')
  fetchApprovalMessageData() // 审批提醒
  fetchWorkMessageData() // 工作提醒
  fetchNoticeList() // 获取通知公告列表
  fetchCalendarList() // 获取日历列表

  // -------------------监听日历三个按钮操作(上个月、今天、下个月)------------------
  // 点击上个月
  const prevBtn = document.querySelector(
    '.el-calendar__button-group .el-button-group>button:nth-child(1)',
  )
  prevBtn!.addEventListener('click', (e) => {
    const day = dayjs(calendarValue.value).format('YYYY-MM')
    clickDate(day)
  })

  // 点击下一个月
  const nextBtn = document.querySelector(
    '.el-calendar__button-group .el-button-group>button:nth-child(3)',
  )
  nextBtn!.addEventListener('click', () => {
    const day = dayjs(calendarValue.value).format('YYYY-MM')
    clickDate(day)
  })

  // 点击今天
  const todayBtn = document.querySelector(
    '.el-calendar__button-group .el-button-group>button:nth-child(2)',
  )
  todayBtn!.addEventListener('click', () => {
    const day = dayjs(calendarValue.value).format('YYYY-MM')
    clickDate(day)
  })
  // ------------------------------------------------------------------------------
})
const go = () => {
  window.open(`https://share.shanhaibi.com/64914aad87721/?token=${localStorage.token}`)
}
</script>

<template>
  <message-scrolling />
  <!-- <button @click="go">
    跳转
  </button> -->
  <app-container>
    <el-row :gutter="10">
      <el-col :span="8">
        <bench-col
          icon="icon-backlog"
          title="审批提醒"
          :height="bigBlockHeight"
          :pagination="true"
          path-url="/workbench/approve"
          :query="approvalMessageListQuery"
          :total="approvalMessageTotal"
          @change="changeApprovalMessagePage"
        >
          <el-table
            v-loading="approvalMessageLoadingTable"
            :data="approvalMessageList"
            :height="bigBlockHeight - 90"
            style="width: 100%; height: 100%;"
            stripe
            header-row-class-name="bench-table-header"
            row-class-name="bench-table-row"
            class="bench-table"
          >
            <el-table-column label="#" width="55" align="center">
              <template #default="scope">
                {{ (approvalMessageListQuery.offset - 1) * approvalMessageListQuery.limit + scope.$index + 1 }}
              </template>
            </el-table-column>
            <el-table-column
              v-for="item in approvalMessageColumns"
              :key="item.value"
              :prop="item.value"
              align="center"
              :label="item.text"
              show-overflow-tooltip
              :width="item.width"
            />
          </el-table>
        </bench-col>
      </el-col>
      <el-col :span="8">
        <bench-col
          icon="icon-backlog"
          title="工作提醒"
          path-url="/workbench/workList"
          :height="blockHeight"
          :pagination="true"
          :query="workMessageListQuery"
          :total="workMessageTotal"
          @change="changeWorkMessagePage"
        >
          <el-table
            v-loading="workMessageLoadingTable"
            :data="workMessageList"
            :height="blockHeight - 90"
            style="width: 100%; height: 100%;"
            stripe
            header-row-class-name="bench-table-header"
            row-class-name="bench-table-row"
            class="bench-table"
          >
            <el-table-column label="#" width="55" align="center">
              <template #default="scope">
                {{ (workMessageListQuery.offset - 1) * workMessageListQuery.limit + scope.$index + 1 }}
              </template>
            </el-table-column>
            <el-table-column
              v-for="item in workMessageColumns"
              :key="item.value"
              :prop="item.value"
              align="center"
              :label="item.text"
              show-overflow-tooltip
              :width="item.width"
            />
          </el-table>
        </bench-col>
        <bench-col
          style="margin-top: 10px;"
          icon="icon-notice"
          title="通知公告"
          path-url="/workbench/noticeList"
          :height="blockHeight"
        >
          <el-table
            v-loading="noticeLoadingTable"
            :data="noticeList"
            :height="blockHeight - 60"
            style="width: 100%; height: 100%;"
            stripe
            header-row-class-name="bench-table-header"
            row-class-name="bench-table-row"
            class="bench-table"
          >
            <el-table-column label="#" width="55" align="center">
              <template #default="scope">
                {{ (searchQuery.offset - 1) * searchQuery.limit + scope.$index + 1 }}
              </template>
            </el-table-column>
            <el-table-column
              v-for="item in noticeColumns"
              :key="item.value"
              :prop="item.value"
              align="center"
              :label="item.text"
              show-overflow-tooltip
              :width="item.width"
            />
          </el-table>
        </bench-col>
      </el-col>
      <el-col :span="8">
        <bench-col
          style="overflow: auto;"
          icon="icon-calendar"
          title="工作日历"
          :height="bigBlockHeight"
          :is-edit="true"
          :is-show-delete="true"
          @edit-data="editSchedule"
          @delete-data="deleteData"
        >
          <el-calendar v-model="calendarValue">
            <template #dateCell="{ data }">
              <div style="width: 100%;height: 100%;text-align: center;" @click="clickDate(data.day)">
                <span>
                  {{ data.day.split("-").slice(2).join() }}
                </span>
              </div>
              <div v-for="(value, key, index) in redCircleData" :key="index">
                <el-popover
                  v-if="key === data.day && value.length"
                  placement="top-start"
                  trigger="hover"
                  width="auto"
                >
                  <div class="popover-content-area-class">
                    <span style="font-weight: 600;">{{ key }}</span>
                    <li v-for="(e, i) in value" :key="i" class="calendar-li-item">
                      {{ e.scheduleMatters }}
                    </li>
                  </div>
                  <template #reference>
                    <div style="width: 100%;height: 100%;display: flex;flex-direction: column;align-items: center;" @click="clickDate(data.day)">
                      <!-- <span>
                        {{ data.day.split("-").slice(2).join() }}
                      </span> -->
                      <span style="margin-top: -30px;">
                        <el-icon :size="20" color="#f56c6c">
                          <alarm-clock />
                        </el-icon>
                        <!-- <span v-if="key === data.day" class="redCircle" /> -->
                      </span>
                    </div>
                  </template>
                </el-popover>
              </div>
            </template>
          </el-calendar>
        </bench-col>
      </el-col>
    </el-row>
    <!-- 编辑日程组件 -->
    <edit-schedule-dialog ref="editScheduleRef" @edit-schedule-success="editScheduleSuccess" />
  </app-container>
</template>

<style lang="scss">
.el-calendar {
  height: 100%;
}

.redCircle {
  display: inline-block;
  width: 22px;
  height: 4px;
  background-color: #f56c6c;
  border-radius: 10px;
  margin-top: -60px;
}

.calendar-li-item {
  padding: 4px 8px;
  margin-top: 8px;
  background-color: #f2f6ff;
  border-radius: 4px;
}

.popover-content-area-class {
  max-width: 600px;
  max-height: 300px;
  overflow-y: auto;
}

.el-calendar-table .el-calendar-day {
  padding: 0;
}
</style>