<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>
|