Vue3实战六:客房管理

实现功能:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值