243 lines
7.3 KiB
Vue
243 lines
7.3 KiB
Vue
<template>
|
|
<page-layout :title="room.name + ' 概览'">
|
|
<a-card>
|
|
<date-picker-bar @change="handleDateChange" :default-date="getDefaultDate()"></date-picker-bar>
|
|
<div style="text-align: center;">
|
|
<a-spin :spinning="status.loading">
|
|
<a-row class="booking-status-timetable-wrapper" v-if="room.seat_list">
|
|
<table class="booking-status-timetable">
|
|
<tr>
|
|
<th></th>
|
|
<th
|
|
v-for="(item, index) in room.seat_list[0].booking_status_list"
|
|
:key="index">
|
|
{{item.start_time.slice(0, 5)}} {{item.end_time.slice(0, 5)}}
|
|
</th>
|
|
</tr>
|
|
<tr
|
|
v-for="(seat, seatIndex) in room.seat_list"
|
|
:key="seat.id">
|
|
<td>
|
|
{{seat.name}}
|
|
</td>
|
|
<td
|
|
v-for="(item, itemIndex) in seat.booking_status_list"
|
|
:key="itemIndex"
|
|
:class="[
|
|
{
|
|
'booked-cell': item.booking,
|
|
'selected-cell': selected[seatIndex.toString() + ' ' + itemIndex.toString()],
|
|
},
|
|
'cell'
|
|
]">
|
|
<a-popover placement="top" v-if="item.booking">
|
|
<div style="width: 100%; height: 20px;"></div>
|
|
<template slot="title">预约 {{item.booking.id}}</template>
|
|
<template slot="content">
|
|
<div>用户: {{item.booking.user.username}}</div>
|
|
<div>预约时间: {{item.booking.start_time}}-{{item.booking.end_time}}</div>
|
|
<div>到达时间: {{item.booking.arrive_time}}</div>
|
|
<div>离开时间: {{item.booking.leave_time}}</div>
|
|
<router-link :to="{name: 'bookingEdit', params:{id: item.booking.id}}">查看</router-link>
|
|
</template>
|
|
</a-popover>
|
|
<div v-else style="width: 100%; height: 20px;" @click="handleSelect(seatIndex, itemIndex)"></div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</a-row>
|
|
</a-spin>
|
|
</div>
|
|
<a-row class="btn-row">
|
|
<a-button
|
|
style="float: right;"
|
|
type="primary"
|
|
:disabled="Object.keys(selected).length === 0"
|
|
@click="handleCreate">
|
|
新建预约
|
|
</a-button>
|
|
</a-row>
|
|
<a-row>
|
|
<span>总计: {{room.booked_count_total}} / {{room.count_total}}</span>
|
|
<a-tooltip placement="top" title="每分钟自动">
|
|
<div style="float: right;">
|
|
<span style="vertical-align: -2px;">更新时间: {{updateTime}} 自动更新 </span>
|
|
<a-switch
|
|
checkedChildren="开"
|
|
unCheckedChildren="关"
|
|
defaultChecked
|
|
@change="handleAutoChange">
|
|
</a-switch>
|
|
</div>
|
|
</a-tooltip>
|
|
</a-row>
|
|
</a-card>
|
|
</page-layout>
|
|
</template>
|
|
|
|
<script>
|
|
import PageLayout from '../../components/page/PageLayout'
|
|
import api from '../../api/dashboard'
|
|
import DatePickerBar from './components/DatePickerBar'
|
|
import moment from 'moment'
|
|
import _ from 'lodash'
|
|
|
|
export default {
|
|
name: 'DashboardDetail',
|
|
components: {
|
|
PageLayout,
|
|
DatePickerBar
|
|
},
|
|
props: {
|
|
id: String,
|
|
date: String
|
|
},
|
|
data () {
|
|
return {
|
|
params: {
|
|
date: this.date ? new moment(this.date).format('YYYY-MM-DD') : new moment().format('YYYY-MM-DD')
|
|
},
|
|
status: {
|
|
loading: false
|
|
},
|
|
room: {},
|
|
updateTime: '',
|
|
intervalID: null,
|
|
selected: {},
|
|
firstSelected: null
|
|
}
|
|
},
|
|
mounted () {
|
|
this.getData()
|
|
},
|
|
methods: {
|
|
getData () {
|
|
this.status.loading = true
|
|
api.getRoomBookingStatusDetail(this.id, this.params)
|
|
.then(data => {
|
|
this.room = data
|
|
this.updateTime = new moment().format('YYYY-MM-DD hh:mm:ss')
|
|
this.selected = {}
|
|
this.firstSelected = null
|
|
this.status.loading = false
|
|
})
|
|
},
|
|
handleDateChange (date) {
|
|
this.params.date = date.format('YYYY-MM-DD')
|
|
this.getData()
|
|
},
|
|
getDefaultDate () {
|
|
return new moment(this.date)
|
|
},
|
|
handleAutoChange (checked) {
|
|
if (checked) {
|
|
this.intervalID = setInterval(this.getData, 1000 * 60)
|
|
} else {
|
|
clearInterval(this.intervalID)
|
|
}
|
|
},
|
|
handleSelect (x, y) {
|
|
let newData = {}
|
|
if (!this.firstSelected) {
|
|
this.firstSelected = { x, y }
|
|
newData[x.toString() + ' ' + y.toString()] = true
|
|
} else {
|
|
if (this.firstSelected.x === x) {
|
|
newData = _.cloneDeep(this.selected)
|
|
if (this.firstSelected.y === y) {
|
|
this.selected = {}
|
|
newData = {}
|
|
} else if (this.firstSelected.y < y) {
|
|
for (let i = this.firstSelected.y; i <= y; i++) {
|
|
if (!this.room.seat_list[x].booking_status_list[i].booking) {
|
|
newData[x.toString() + ' ' + i.toString()] = true
|
|
} else {
|
|
this.selected = {}
|
|
newData = {}
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
for (let i = y; i <= this.firstSelected.y; i++) {
|
|
if (!this.room.seat_list[x].booking_status_list[i].booking) {
|
|
newData[x.toString() + ' ' + i.toString()] = true
|
|
} else {
|
|
this.selected = {}
|
|
newData = {}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this.selected = {}
|
|
}
|
|
this.firstSelected = null
|
|
}
|
|
this.selected = newData
|
|
},
|
|
handleCreate () {
|
|
let key_list = Object.keys(this.selected)
|
|
let x = key_list[0].split(' ')[0]
|
|
let key_y_list = key_list.map((item) => {
|
|
return item.split(' ')[1]
|
|
})
|
|
let y1 = Math.min.apply(null, key_y_list)
|
|
let y2 = Math.max.apply(null, key_y_list)
|
|
let seats = []
|
|
let seat = this.room.seat_list[x]
|
|
let start_time = this.room.seat_list[x].booking_status_list[y1].start_time
|
|
let end_time = this.room.seat_list[x].booking_status_list[y2].end_time
|
|
seats.push({
|
|
id: seat.id,
|
|
name: seat.name
|
|
})
|
|
let bookingCreate = {
|
|
date: this.params.date,
|
|
room: {
|
|
id: this.room.id,
|
|
name: this.room.name
|
|
},
|
|
seats,
|
|
start_time,
|
|
end_time
|
|
}
|
|
this.$router.push({ name: 'bookingCreate', params: { bookingCreate } })
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
@import '../../../public/color';
|
|
|
|
.booking-status-timetable-wrapper {
|
|
margin: 20px 0;
|
|
overflow-x: scroll;
|
|
|
|
.booking-status-timetable {
|
|
|
|
|
|
th, td {
|
|
border: solid 1px rgba(128, 128, 128, 0.3);
|
|
padding: 5px 2px;
|
|
}
|
|
|
|
.cell {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.booked-cell {
|
|
background-color: @success-color;
|
|
}
|
|
|
|
.selected-cell {
|
|
background-color: @primary-color;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.btn-row {
|
|
margin-bottom: 20px;
|
|
}
|
|
</style> |