实现功能:
1、客房增删改查、房型列表、房间状态列表
2、图片添加、管理和浏览
3、数据Excel导出
一、api文件
room.js
import { $post, $get } from "../utils/request";
import { $msg_e, $msg_s, $confirm } from "../utils/msg";
import { pa } from "element-plus/es/locale";
//房间列表
export let list = async (params) => {
let ret = await $get('Room/List', params)
return ret
}
//添加房间信息的方法
export let add = async (params) => {
if (!checkInput(params)) return false
let { success, message } = await $post('Room/Add', params)
if (success) {
$msg_s(message)
} else {
$msg_e(message)
}
return success
}
//修改房间信息的方法
export let update = async (params) => {
if (!checkInput(params)) return false
let { success, message } = await $post('Room/Update', params)
if (success) {
$msg_s(message)
} else {
$msg_e(message)
}
return success
}
//删除房间信息
export let del = async (params) => {
await $confirm('是否确认删除')
let { success, massage } = $post('Room/Delete', params)
if (success) {
$msg_s(massage)
} else {
$msg_e(massage)
}
return success
}
//验证输入方法
let checkInput = (params) => {
if (!params.roomId) {
$msg_e('请输入房间号')
} else if (params.roomStateId == 0) {
$msg_e('请选择房间状态')
} else if (params.roomTypeId == 0) {
$msg_e('请选择房间类型')
} else {
return true
}
return false
}
roomImg.js
//房间照片操作API
//导入请求函数
import { $get, $post } from "../utils/request";
//导入消息框
import { $msg_e, $msg_w, $msg_s, $confirm } from "../utils/msg";
//添加房间照片的方法
export let add = async (params) => {
let { success } = await $post('RoomImg/Add', params)
return success
}
//查询指定房间对应的房间图片
export let imgList = async (params) => {
let ret = await $get('RoomImg/List', params)
return ret
}
//删除房间图片
export let delImg = async (params) => {
let { success } = await $post('RoomImg/Delete', params)
return success
}
roomState.js
//房间状态API
//导入请求函数
import { $get, $post } from "../utils/request";
//导入消息框
import { $msg_e, $msg_w, $msg_s, $confirm } from "../utils/msg";
export let list = async () => {
let ret = await $get('RoomState/List')
return ret
}
//获取所有房间状态的方法(没有入住信息)
export let listToUpdate = async () => {
let ret = await $get('RoomState/ListToUpdate')
return ret
}
二、Room.vue 组件
<template>
<div class="search">
<span>房间类型:</span>
<el-select v-model="roomTypeId" size="small">
<el-option v-for="item in roomTypeList" :key="item.roomTypeId" :label="item.roomTypeName"
:value="item.roomTypeId" />
</el-select>
<span>房间状态:</span>
<el-select v-model="roomStateId" size="small">
<el-option v-for="item in roomStateList" :key="item.roomStateId" :label="item.roomStateName"
:value="item.roomStateId" />
</el-select>
<el-button size="small" type="success" @click="loadTable">查询</el-button>
<el-button size="small" type="info" @click="toExcel">导出</el-button>
<el-button size="small" type="primary" @click="openDrawer = true">添加</el-button>
</div>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="roomId" label="房间号" width="100" />
<el-table-column prop="roomType.roomTypeName" label="房间类型" width="120" />
<el-table-column prop="roomType.roomTypePrice" label="房间价格" width="100" />
<el-table-column prop="roomType.bedNum" label="床位数" width="100" />
<el-table-column label="房间状态" width="80">
<template #default="scope">
<el-tag size="mini" v-if="scope.row.roomState.roomStateId == 1" type="success">{{
scope.row.roomState.roomStateName
}}</el-tag>
<el-tag size="mini" v-if="scope.row.roomState.roomStateId == 2" type="warning">{{
scope.row.roomState.roomStateName
}}</el-tag>
<el-tag size="mini" v-if="scope.row.roomState.roomStateId == 3" type="danger">{{ scope.row.roomState.roomStateName
}}</el-tag>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="240">
<template #default="scope">
<el-button size="small" type="primary" @click="openDialog(scope.row)">照片</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
<el-button v-if="scope.row.roomStateId != 2" size="small" type="warning"
@click="handleEdit(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="total"
v-model:current-page="pageIndex" />
</div>
<el-drawer v-model="openDrawer" :title="isAdd ? '添加房间' : '修改房间'" size="40%" direction="rtl" :before-close="drawerClose">
<div class="edititem">
<span>房间编号:</span>
<div>
<el-input v-model="formData.roomId" placeholder="请输入房间编号" />
</div>
</div>
<div class="edititem">
<span>房间类型:</span>
<div>
<el-select v-model="formData.roomTypeId" size="small">
<el-option v-for="item in roomTypeList" :key="item.roomTypeId" :label="item.roomTypeName"
:value="item.roomTypeId" />
</el-select>
</div>
</div>
<div class="edititem">
<span>房间状态:</span>
<div>
<el-select v-model="formData.roomStateId" size="small">
<el-option v-for="item in roomStateLisl2" :key="item.roomStateId" :label="item.roomTStateName"
:value="item.roomStateId" />
</el-select>
</div>
</div>
<div class="edititem">
<span>房间描述:</span>
<div>
<QuillEditor v-if="openDrawer" content-type="html" v-model:content="formData.description" theme="snow"
style="height: 300px" />
</div>
</div>
<div class="edititem">
<span></span>
<div>
<el-button size="small" type="primary" @click="editForm">{{ isAdd ? '添加' : '修改' }}</el-button>
<el-button size="small" type="default" @click="clearFormData">取消</el-button>
</div>
</div>
</el-drawer>
<el-dialog v-model="dialogVisible" title="房间照片" width="60%">
<el-upload v-model:file-list="fileList" :action="room_upload_url" list-type="picture-card" :file-list="imgList"
:limit="9" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<el-icon>
<Plus />
</el-icon>
</el-upload>
<el-dialog v-model="dialogVisible2" width="50%">
<img style="width:100%" :src="dialogImageUrl" alt="Preview Image" />
</el-dialog>
</el-dialog>
</template>
<script>
import { list, add, update, del } from '../../api/room'
import { reactive, toRefs, watch } from 'vue'
//导入操作房间类型的API
import { list as roomTypeList } from '../../api/roomType'
//房间状态API
import { list as roomStateList, listToUpdate as roomStateList2 } from '../../api/roomState'
import { Plus } from '@element-plus/icons-vue'
//导入上传和查看房间照片地址
import { room_upload_url, room_photo_base_url } from '../../config/conster'
import { add as addRoomImg, imgList, delImg } from '../../api/roomImg'
export default {
name: 'Room',
setup() {
let data = reactive({
//表格数据
tableData: [],
roomTypeId: '',
roomStateId: 0,
//是否打开抽屉
openDrawer: false,
//当前页
pageIndex: 1,
//每页条数
pageSize: 3,
//总数量
total: 5,
//房间类型数组
roomTypeList: [],
//房间状态数组,用户查询
roomStateList: [],
//房间状态数组,用户添加
roomStateLisl2: [],
//是否是添加操作
isAdd: true,
//表单数据
formData: {
roomId: '',
roomStateId: '0',
description: '',
roomTypeId: '0'
},
dialogVisible: false,
room_upload_url,
room_photo_base_url,
//指定房间图片列表
imgList: [],
//大图显示
dialogVisible2: false,
//大图地址
dialogImageUrl: ''
})
data.tableData = [
{ 'roomId': '101', 'roomState': { 'roomStateId': 1, 'roomStateName': '空闲' }, 'description': '', 'roomType': { 'roomTypeId': '1', 'roomTypeName': '标准间', 'roomTypePrice': '200', 'bedNum': '2' } },
{ 'roomId': '102', 'roomState': { 'roomStateId': 2, 'roomStateName': '空闲' }, 'description': '', 'roomType': { 'roomTypeId': '2', 'roomTypeName': '大床间', 'roomTypePrice': '250', 'bedNum': '2' } },
{ 'roomId': '103', 'roomState': { 'roomStateId': 3, 'roomStateName': '空闲' }, 'description': '', 'roomType': { 'roomTypeId': '1', 'roomTypeName': '标准间', 'roomTypePrice': '200', 'bedNum': '2' } },
{ 'roomId': '104', 'roomState': { 'roomStateId': 1, 'roomStateName': '空闲' }, 'description': '', 'roomType': { 'roomTypeId': '3', 'roomTypeName': '单人间', 'roomTypePrice': '150', 'bedNum': '1' } },
{ 'roomId': '105', 'roomState': { 'roomStateId': 1, 'roomStateName': '空闲' }, 'description': '', 'roomType': { 'roomTypeId': '3', 'roomTypeName': '单人间', 'roomTypePrice': '150', 'bedNum': '1' } },
]
//加载房间状态,用户添加
let loadRoomStateList2 = async () => {
let ret = await roomStateList2()
ret.unshift({ roomStateId: 0, roomStateName: '请选择房间状态' })
data.roomStateLisl2 = ret
}
//调用加载房间状态的方法,用于添加
loadRoomStateList2()
//加载房间状态,用户查询
let loadRoomStateList = async () => {
let ret = await roomStateList()
ret.unshift({ roomStateId: 0, roomStateName: '请选择房间状态' })
data.roomStateList = ret
}
//加载房间类型的方法
let loadRoomTypeList = async () => {
let ret = await roomTypeList()
ret.unshift({ roomTypeId: 0, roomTypeName: '请选择输入房间类型' })
data.roomTypeList = ret
}
//调用查询房间类型的方法
loadRoomTypeList()
//加载数据表方法
let loadTable = async () => {
let params = {
pageIndex: data.pageIndex,
pageSize: data.pageSize,
roomStateId: data.roomStateId,
roomTypeId: roomTypeId
}
//获取查询结果
// let {data:roomData,count} = await list(params)
// data.tableData = roomData
data.total = count
data.formData
console.log(data.formData)
}
//执行加载表格数据的方法
loadTable()
//监听当前页码是否发生变化
watch(() => data.pageIndex, () => {
//执行加载表格数据的方法
loadTable()
})
let editForm = async () => {
let r = false
//判断是执行添加还是修改
if (data.isAdd) {
r = await add(data.formData)
if (r) {
clearFormData()
}
} else {
r = await update(data.formData)
}
if (r) {
loadTable();
}
}
//关闭抽屉
let drawerClose = () => {
data.openDrawer = false
add.isAdd = true
clearFormData()
}
//执行修改
let handleEdit = (row) => {
//当前客房信息
data.formData = { ...row }
//在表单数据中,添加ID属性,备份房间号
data.formData.id = row.roomId
data.isAdd = false
data.openDrawer = true
}
//执行删除
let handleDelete = async (row) => {
//获取房间编号
let { roomId } = row
let r = await del({ roomId })
//删除成功,刷新页面
if (r) {
loadTable
}
}
//清空表单数据
let clearFormData = () => {
data.formData = {
roomId: '',
roomStateId: '0',
description: '',
roomTypeId: '0'
}
//清空富文本内容
document.querySelector('.ql-editor').innerHTML
}
//当前房间ID
let currentRoomId = ""
//打开图片管理对话框
let openDialog = async (row) => {
let { roomId } = row
currentRoomId = roomId
data.dialogVisible = true
//根据房间号,查询该房间的所有图片
let ret = await imgList({ roomId })
//转成指定格式数组
let imgList = ret.map(r => {
r.roomImgId
name: r.imgUrl
url: room_photo_base_url + r.imgUrl
})
data.imgList = imgList
}
//删除房间图片
const handleRemove = async (file, files) => {
//获取图片ID
let { roomImgId, name } = file
//删除
let r = await delImg({ roomImgId, filename: name })
}
//上传成功指定函数
let handleAvatarSuccess = async (res) => {
let { filename, success } = res
if (success) {
let params = {
roomId: currentRoomId,
imgUrl: filename
}
let r = await addRoomImg(params)
}
}
//头像上传之前调用函数
let beforeAvatarUpload = (file) => {
let imgType = ['image/jpeg', 'image/png', 'image/gif']
const isJPG = imgType.includes(file.type)
const islt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
$msg_e('请选择正确的图片格式')
return false
} else if (!islt2M) {
$msg_e('图片大小不能超过2M')
return false
}
return true
}
//预览图片
const handlePictureCardPreview = (file) => {
//设置大图地址
data.dialogImageUrl = file.url
//显示大图对话框
data.dialogVisible2 = true
}
watch(() => data.dialogVisible, (val) => {
//监听到关闭对话框
if (!val) {
data.imgList = []
}
})
// let toExcel=()=>{
// let excelData =data.tableData.map(r=>{
// roomId:r.roomId
// roomTypeName: r.roomType.roomTypeName
// roomTypePrice: r.roomType.roomTypePrice
// bedNum:r.roomType.bedNum
// roomStateName:r.roomState.roomStateName
// })
// let header= {
// roomId:'房间号',
// roomTypeName: '房间类型',
// roomTypePrice: '房间价格',
// bedNum:'床位数',
// roomStateName:'房间状态'
// }
// xlsx(JSON.stringfy(excelData),excelHeader,'房间.xlsx')
// }
return {
...toRefs(data),
editForm,
drawerClose,
handleEdit,
handleDelete,
clearFormData,
loadTable,
handleAvatarSuccess,
beforeAvatarUpload,
openDialog,
handleRemove,
handlePictureCardPreview,
// toExcel
}
}
}
</script>
<style scoped lang="scss"></style>
安装xlsx和file-saver 文件