<template> 
 | 
  <TableLayout> 
 | 
    <div slot="search-form" class="data"> 
 | 
        <div class="item-title">数据看板</div> 
 | 
        <div class="data-summary"> 
 | 
          <div class="data-item"> 
 | 
            <div>今日会议数量</div> 
 | 
            <div class="data-num">{{ countData.todayBookingsNum }}</div> 
 | 
          </div> 
 | 
          <div class="parting"></div> 
 | 
          <div class="data-item"> 
 | 
            <div>今日会议时长(小时)</div> 
 | 
            <div class="data-num">{{ countData.todayBookingsTime }}</div> 
 | 
          </div> 
 | 
          <div class="parting"></div> 
 | 
          <div class="data-item"> 
 | 
            <div>今日参会人数</div> 
 | 
            <div class="data-num">{{ countData.bookingUser }}</div> 
 | 
          </div> 
 | 
          <div class="parting"></div> 
 | 
          <div class="data-item"> 
 | 
            <div>今日会议室利用率</div> 
 | 
            <div class="data-num">{{ (countData.todayLyl * 100).toFixed(2) }}%</div> 
 | 
          </div> 
 | 
          <div class="parting"></div> 
 | 
          <div class="data-item"> 
 | 
            <div>会议室数量</div> 
 | 
            <div class="data-num">{{ countData.roomNum }}</div> 
 | 
          </div> 
 | 
          <div class="parting"></div> 
 | 
          <div class="data-item"> 
 | 
            <div>员工数量</div> 
 | 
            <div class="data-num">{{ countData.memberNum }}</div> 
 | 
          </div> 
 | 
        </div> 
 | 
      </div> 
 | 
    <template v-slot:table-wrap> 
 | 
      <div class="bottom"> 
 | 
        <div class="item-box calendar"> 
 | 
          <div class="calendar-header"> 
 | 
            <div>会议日历</div> 
 | 
            <el-select 
 | 
              v-model="searchForm.roomId" 
 | 
              filterable 
 | 
              clearable 
 | 
              placeholder="请选择会议室" 
 | 
              @change="selectRoom" 
 | 
            > 
 | 
              <el-option v-for="item in rooms" :key="item.id" :value="item.id" :label="item.name" /> 
 | 
            </el-select> 
 | 
          </div> 
 | 
           
 | 
          <FullCalendar ref="fullCalendar" :options="calendarOptions"> 
 | 
            <template v-slot:eventContent='{event}'> 
 | 
              <!--  { 
 | 
                  "allDay": true, 
 | 
                  "title": "关于对小米的收购方案会议", 
 | 
                  "start": "2023-05-11", 
 | 
                  "backgroundColor": "#ffcc99", 
 | 
                  "borderColor": "#ffcc99", 
 | 
                  "extendedProps": { 
 | 
                    "timeText": "15:00" 
 | 
                  } 
 | 
                }  --> 
 | 
              <!-- <b>{{ arg.event.extendedProps.timeText }}</b> --> 
 | 
              <el-popover 
 | 
                v-if="event.title=='z'" 
 | 
                placement="top" 
 | 
                width="350" 
 | 
                trigger="hover" 
 | 
                :tabindex="10" 
 | 
                > 
 | 
                <!-- v-model="event.extendedProps.data.isShow" --> 
 | 
                <div style="display: flex; justify-content: space-between;"> 
 | 
                  <div style="font-size: 14px; font-weight: 600;  height: 24px; line-height: 22px;">{{ days[event.start.getMonth()] }}日会议安排</div> 
 | 
                  <!-- <div 
 | 
                    @click="event.extendedProps.data.isShow=false" 
 | 
                    style="font-size: 16px; width: 24px; height: 24px; line-height: 26px; text-align: center;border-radius: 50%;border: 1px solid #444;" 
 | 
                  >X</div> --> 
 | 
                </div> 
 | 
                <div style="height: 200px; overflow-y: scroll;"> 
 | 
                  <div v-for="item in event.extendedProps.data.resource" :key="item.id"> 
 | 
                    <el-popover 
 | 
                      placement="top" 
 | 
                      width="300" 
 | 
                      trigger="hover" 
 | 
                      :open-delay="500" 
 | 
                    > 
 | 
                      <div> 
 | 
                        <div>会议主题:{{ item.name }}</div> 
 | 
                        <div>会议时间:{{ `${item.startHour}-${item.endHour}` }}</div> 
 | 
                        <div>会议室:{{ item.roomName }}</div> 
 | 
                        <div>预约部门:{{ item.departmentName }}</div> 
 | 
                        <div>预约人:{{ item.realName }}</div> 
 | 
                      </div> 
 | 
                      <div slot="reference" style="color: #111; display: flex;"> 
 | 
                        <div style="width: 75px;">{{ `${item.startHour}-${item.endHour}` }}</div> 
 | 
                        <div style="width: 3px;"></div> 
 | 
                        <div class="long-title-style" style="flex: 1; color: #216EEE" :title="`${item.name} (${item.roomName})`">{{ `${item.name} (${item.roomName})` }}</div> 
 | 
                      </div> 
 | 
                    </el-popover> 
 | 
                  </div> 
 | 
                </div> 
 | 
                <div slot="reference" @click="event.extendedProps.data.isShow=true" style="color: #111;" class="long-title-style">{{ event.extendedProps.data.name }}</div> 
 | 
              </el-popover> 
 | 
              <el-popover 
 | 
                v-else 
 | 
                placement="top-start" 
 | 
                width="300" 
 | 
                trigger="hover" 
 | 
                :open-delay="500" 
 | 
              > 
 | 
                <div> 
 | 
                  <div>会议主题:{{ event.extendedProps.data.name }}</div> 
 | 
                  <div>会议时间:{{ `${event.extendedProps.data.startHour}-${event.extendedProps.data.endHour}` }}</div> 
 | 
                  <div>会议室:{{ event.extendedProps.data.roomName }}</div> 
 | 
                  <div>预约部门:{{ event.extendedProps.data.departmentName }}</div> 
 | 
                  <div>预约人:{{ event.extendedProps.data.realName }}</div> 
 | 
                </div> 
 | 
                <div slot="reference" style="color: #111; flex: 1;" class="long-title-style">{{ `${event.extendedProps.data.name}(${event.extendedProps.data.roomName})` }}</div> 
 | 
              </el-popover> 
 | 
            </template> 
 | 
          </FullCalendar> 
 | 
        </div> 
 | 
        <div class="notice-meeting"> 
 | 
          <div class="notice item-box"> 
 | 
            <div class="notice-header" @click="showMorNotify"> 
 | 
              <div>通知公告</div> 
 | 
              <div class="more">更多</div> 
 | 
            </div> 
 | 
            <div v-for="item in notice" :key="item.id" class="notice-item"> 
 | 
              <div style="flex: 1;" class="long-title-style" :title="item.title">{{ item.title }}</div> 
 | 
              <div>{{ item.createDate.split(' ')[0] }}</div> 
 | 
            </div> 
 | 
          </div> 
 | 
          <div class="meeting item-box"> 
 | 
            <div class="meeting-header"> 
 | 
              <div>会议安排</div> 
 | 
              <div class="action"> 
 | 
                <div :class="type==1?'type-sel':''" @click="selectType(1)">今日</div> 
 | 
                <div style="width:3px;"></div> 
 | 
                <div :class="type==2?'type-sel':''" @click="selectType(2)">本周</div> 
 | 
              </div> 
 | 
            </div> 
 | 
              <div class="meeting-list"> 
 | 
              <el-popover 
 | 
                placement="top-start" 
 | 
                width="300" 
 | 
                trigger="hover" 
 | 
                :open-delay="500" 
 | 
                v-for="(item, index) in meetings" :key="index" 
 | 
              > 
 | 
                <div> 
 | 
                  <div>会议主题:{{ item.name }}</div> 
 | 
                  <div>会议时间:{{ `${item.startHour}-${item.endHour}` }}</div> 
 | 
                  <div>会议室:{{ item.roomName }}</div> 
 | 
                  <div>预约部门:{{ item.departmentName }}</div> 
 | 
                  <div>预约人:{{ item.realName }}</div> 
 | 
                </div> 
 | 
                <div slot="reference" class="meeting-item"> 
 | 
                  <div v-if="type==1" style="width: 75px;">{{ `${item.startHour}-${item.endHour}` }}</div> 
 | 
                  <div v-if="type==2" style="width: 110px;">{{ `${item.weekday} ${item.startHour}-${item.endHour}` }}</div> 
 | 
                  <div style="width: 3px;"></div> 
 | 
                  <div class="type-sel long-title-style" :title="`${item.name} (${item.roomName})`">{{ `${item.name} (${item.roomName})` }}</div> 
 | 
                </div> 
 | 
              </el-popover> 
 | 
            </div> 
 | 
          </div> 
 | 
        </div> 
 | 
      </div> 
 | 
    </template> 
 | 
     
 | 
  </TableLayout> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import TableLayout from '@/layouts/TableLayout' 
 | 
  
 | 
import FullCalendar from '@fullcalendar/vue' 
 | 
import dayGridPlugin from '@fullcalendar/daygrid' 
 | 
import timeGridPlugin from '@fullcalendar/timegrid' 
 | 
import interactionPlugin from '@fullcalendar/interaction' 
 | 
  
 | 
import 'ele-calendar/dist/vue-calendar.css' //引入css 
 | 
// import { fetchList } from '@/api/business/notice' 
 | 
// import { findList } from '@/api/business/rooms' 
 | 
// import { home } from '@/api/business/home' 
 | 
export default { 
 | 
  components: { 
 | 
    TableLayout, 
 | 
    FullCalendar 
 | 
  }, 
 | 
  data() { 
 | 
    return { 
 | 
      countData: { 
 | 
        bookingUser: 0, 
 | 
        memberNum: 0, 
 | 
        roomNum: 0, 
 | 
        todayBookingsNum: 0, 
 | 
        todayBookingsTime: 0, 
 | 
        todayLyl: 0 
 | 
      }, 
 | 
      searchForm: { 
 | 
        roomId: '', 
 | 
  
 | 
      }, 
 | 
      type: 1, // 1今日 2本周 
 | 
      notice: [], 
 | 
      meetings: [], 
 | 
      rooms: [], 
 | 
      tempDate: '', 
 | 
      month: ['01','02','03','04','05','06','07','08','09','10','11','12'], 
 | 
      days: ['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'], 
 | 
      dataList: [], 
 | 
      // 日历 
 | 
      calendarOptions: { 
 | 
        plugins: [ 
 | 
          dayGridPlugin, 
 | 
          timeGridPlugin, 
 | 
          interactionPlugin // needed for dateClick   
 | 
        ], 
 | 
        initialView: 'dayGridMonth', 
 | 
        locale: 'zh', 
 | 
        fixedWeekCount: false, 
 | 
        firstDay: 1, 
 | 
        buttonText: { 
 | 
          prev: '上月', 
 | 
          next: '下月', 
 | 
          today: '今天', 
 | 
          // month: '月', 
 | 
          // week: '周', 
 | 
          // day: '日', 
 | 
          // list: '周列表', 
 | 
        }, 
 | 
        headerToolbar: { 
 | 
          left: 'prev,next today', 
 | 
          center: 'title', 
 | 
          // right: 'dayGridMonth,timeGridWeek,timeGridDay listWeek', 
 | 
          right: '', 
 | 
        }, 
 | 
        height: 650, 
 | 
        validRange: this.validRange,  //设置可显示的总日期范围 
 | 
        events: [], //背景色 (添加相同时间的背景色时颜色会重叠)  
 | 
        datesSet: this.datesSet, //日期渲染;修改日期范围后触发 
 | 
        eventClick: this.handleEventClick, //点击日程触发 
 | 
        dateClick: this.handleDateClick, //点击日期触发 
 | 
        eventDrop: this.calendarEventDropOrResize, //拖动事件触发 
 | 
        eventResize: this.calendarEventDropOrResize, //缩放事件触发 
 | 
        displayEventTime: false, //不显示具体时间 
 | 
      }, 
 | 
      validRange: { 
 | 
        start: '2021-09-01', 
 | 
        end: '2999-09-01' 
 | 
      } 
 | 
       
 | 
    } 
 | 
  }, 
 | 
   
 | 
  mounted() { 
 | 
    this.getMeeting() 
 | 
    let date = new Date() 
 | 
    this.tempDate = `${date.getFullYear()}-${this.month[date.getMonth()]}` 
 | 
    // this.getData() 
 | 
    findList({}) 
 | 
      .then(res => { 
 | 
        this.rooms = res 
 | 
      }) 
 | 
    home({}) 
 | 
      .then(res => { 
 | 
        this.countData = res 
 | 
      }) 
 | 
    fetchList({ 
 | 
      page: 1, 
 | 
      capacity: 5, 
 | 
      model: {  }, 
 | 
    }) 
 | 
      .then(res => { 
 | 
        this.notice = res.records 
 | 
      }) 
 | 
     
 | 
  }, 
 | 
  methods: { 
 | 
    selectRoom(id) { 
 | 
      this.getData() 
 | 
    }, 
 | 
    selectType(type) { 
 | 
      this.type = type 
 | 
      this.getMeeting() 
 | 
    }, 
 | 
    getMeeting() { 
 | 
      reservationCancel(this.type) 
 | 
        .then(res => { 
 | 
          this.meetings = res 
 | 
        })  
 | 
    }, 
 | 
     
 | 
    getData() { 
 | 
      // console.log(this.tempDate); 
 | 
      this.dataList = [] 
 | 
      this.calendarOptions.events = [] 
 | 
      findMothBookingMeet({ 
 | 
        roomId: this.searchForm.roomId, 
 | 
        dateMonth: this.tempDate 
 | 
      }) 
 | 
        .then(res => { 
 | 
          // console.log(this.calendarOptions.events); 
 | 
          // debugger 
 | 
          this.dataList = res 
 | 
          this.dataList.forEach(item => { 
 | 
            if (item.resource.length) { 
 | 
              if (item.resource.length>3) { 
 | 
                this.calendarOptions.events.push({ 
 | 
                    title: 'z', 
 | 
                    date: item.localDate, 
 | 
                    // timeText: , 
 | 
                    data: { 
 | 
                      name: `另外${item.resource.length-2}个`, 
 | 
                      resource:item.resource, 
 | 
                      isShow: false 
 | 
                    }, 
 | 
                    color: '#fff', 
 | 
                  }) 
 | 
                this.calendarOptions.events.push({ 
 | 
                    title: 'a', 
 | 
                    date: item.localDate, 
 | 
                    // timeText: item.resource[0].name, 
 | 
                    data: item.resource[0], 
 | 
                    color: '#ffcc99', 
 | 
                  }) 
 | 
                this.calendarOptions.events.push({ 
 | 
                    title: 'a', 
 | 
                    date: item.localDate, 
 | 
                    data: item.resource[1], 
 | 
                    color: '#ffcc99', 
 | 
                  }) 
 | 
                 
 | 
              } else { 
 | 
                item.resource.forEach(event => { 
 | 
                  this.calendarOptions.events.push({ 
 | 
                    title: event.name, 
 | 
                    date: item.localDate, 
 | 
                    data: event, 
 | 
                    color: '#ffcc99', 
 | 
                  }) 
 | 
                }) 
 | 
              } 
 | 
            } 
 | 
          }) 
 | 
        }) 
 | 
    }, 
 | 
    datesSet(info) {   //注意:该方法在页面初始化时就会触发一次 
 | 
      console.log('datesSet',info.end.getTime()) 
 | 
      let date = new Date((info.end.getTime()+info.start.getTime())/2) 
 | 
      this.tempDate = `${date.getFullYear()}-${this.month[date.getMonth()]}` 
 | 
      this.getData() 
 | 
    }, 
 | 
    handleEventClick(info) { 
 | 
      console.log('handleEventClick',info) 
 | 
    }, 
 | 
    handleDateClick(info){ 
 | 
    }, 
 | 
    calendarEventDropOrResize(info){ 
 | 
      console.log('info',info) 
 | 
    }, 
 | 
    showMorNotify() { 
 | 
      this.$router.push('/business/notice') 
 | 
    } 
 | 
  }, 
 | 
} 
 | 
</script> 
 | 
  
 | 
<style lang="scss" scoped> 
 | 
.data { 
 | 
  padding-bottom: 10px; 
 | 
} 
 | 
.item-title { 
 | 
  font-weight: 500; 
 | 
  
 | 
} 
 | 
.data-summary { 
 | 
  display: flex; 
 | 
  justify-content: space-between; 
 | 
  margin-top: 10px; 
 | 
  .data-item { 
 | 
    flex: 1; 
 | 
    height: 80px; 
 | 
    box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1) ; 
 | 
    box-sizing: border-box; 
 | 
    padding: 15px; 
 | 
    display: flex; 
 | 
    flex-direction: column; 
 | 
    justify-content: space-between; 
 | 
    .data-num { 
 | 
      font-size: 20px; 
 | 
      font-weight: 700; 
 | 
      color: #1457C7; 
 | 
      color: #216EEE; 
 | 
    } 
 | 
  } 
 | 
  .parting { 
 | 
    width: 20px; 
 | 
  } 
 | 
} 
 | 
.bottom { 
 | 
  // min-height: 500px; 
 | 
  height: 750px; 
 | 
  display: flex; 
 | 
  .item-box { 
 | 
    padding: 10px; 
 | 
    // border: 2px #ccc solid; 
 | 
    box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.1) ; 
 | 
    border-radius: 8px; 
 | 
  } 
 | 
  .calendar { 
 | 
    flex: 1; 
 | 
    margin-right: 10px; 
 | 
    .calendar-header { 
 | 
      display: flex; 
 | 
      justify-content: space-between; 
 | 
      // border-bottom: 5px rgb(232, 202, 122) solid; 
 | 
      padding: 10px 5px; 
 | 
      font-weight: 600; 
 | 
    } 
 | 
  } 
 | 
  .notice-meeting { 
 | 
    // flex: 0.3; 
 | 
    height: 150px; 
 | 
    width: 340px; 
 | 
    display: flex; 
 | 
    flex-direction: column; 
 | 
    .notice { 
 | 
      flex: 0.3; 
 | 
      margin-bottom: 10px; 
 | 
      .notice-header { 
 | 
        display: flex; 
 | 
        justify-content: space-between; 
 | 
        height: 30px; 
 | 
        line-height: 30px; 
 | 
        cursor: pointer; 
 | 
        // border-bottom: 5px rgb(232, 202, 122) solid; 
 | 
        // padding: 0 5px; 
 | 
        font-weight: 600; 
 | 
        .more { 
 | 
          font-weight: normal; 
 | 
          color: rgb(127, 127, 127); 
 | 
        } 
 | 
      } 
 | 
      .notice-item { 
 | 
        line-height: 24px; 
 | 
        font-size: 12px; 
 | 
        display: flex; 
 | 
        justify-content: space-between; 
 | 
        height: 24px; 
 | 
      } 
 | 
    } 
 | 
    .meeting { 
 | 
      flex: 0.7; 
 | 
      display: flex; 
 | 
      flex-direction: column; 
 | 
  
 | 
      // width: 100%; 
 | 
      .meeting-header { 
 | 
        display: flex; 
 | 
        justify-content: space-between; 
 | 
        padding: 10px 5px; 
 | 
        font-weight: 600; 
 | 
        line-height: 30px; 
 | 
        height: 30px; 
 | 
        .action { 
 | 
          font-weight: normal; 
 | 
          display: flex; 
 | 
          .type-sel { 
 | 
            color: rgb(84, 169, 235); 
 | 
            color: #216EEE; 
 | 
            text-decoration: underline; 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
      .meeting-list { 
 | 
        // flex: 1; 
 | 
        height: 500px; 
 | 
        overflow-y: scroll; 
 | 
      } 
 | 
      .meeting-item { 
 | 
        display: flex; 
 | 
        font-size: 12px; 
 | 
        line-height: 24px; 
 | 
        .type-sel { 
 | 
          flex: 1; 
 | 
          // color: rgb(84, 169, 235); 
 | 
          color: #216EEE; 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
} 
 | 
  
 | 
</style> 
 | 
  
 | 
<style> 
 | 
.available { 
 | 
  text-align: left; 
 | 
} 
 | 
.dateItem { 
 | 
  display: block; 
 | 
  /* display: flex; 
 | 
  flex-direction: column; 
 | 
  align-items: flex-start; */ 
 | 
  height: 100%; 
 | 
  min-height:100px; 
 | 
  padding:5px; 
 | 
  box-sizing: border-box; 
 | 
} 
 | 
.fc .fc-daygrid-day.fc-day-today { 
 | 
  background-color: #fff; 
 | 
} 
 | 
</style> 
 |