开发工具:IDEA
服务器:Tomcat9.0, jdk1.8
项目构建:maven
数据库:mysql5.7
系统分前后台,项目采用前后端分离
前端技术:vue+elementUI
服务端技术:springboot+mybatis
本系统功能包括:
一、前台功能:
1、用户注册模块:用户可以输入用户名、密码、昵称、姓名、手机来 进行注册。
2、用户登录模块:用户可以根据用户名、密码进行登录。
3、前台首页模块:包括广告、房间信息、酒店新闻。
4、酒店新闻模块:展示酒店标题,创建时间,详情。
5、酒店预订模块:展示了客房的详情以及评价,用户输入入住日期以及入住天数进行预订。
6、用户信息模块:展示了用户的头像、昵称、姓名、手机号码、性别并可进行修改。
7、个人订单模块:展示了全部订单、待付款订单、待入住、已入住,已退房的客房信息。
二、后台功能:
1、管理员登录模块:管理员可以根据用户名、密码进行登录。
2、统计分析模块:管理员可以直观的查看近一周的客房数量、订单数量、用户数量。
3、会员管理模块:管理员可以查看用户的基本信息。
4、广告管理模块:管理员可以对酒店广告进行新增修改删除。
5、分类管理模块:管理员可以对客房的分类进行新增修改删除。
6、客房管理模块: 管理员可以对客房信息行增删改查。
7、房间管理模块:管理员可以查看目前所有房间的状态并对其进行增删改查。
8、订单管理模块:管理员可以找到用户提交的预订信息并进行开房和退房、查看的操作。
9、评价管理模块:管理员可以对用户的评价进行查询删除。
10、新闻管理模块:管理员可以对用户端新闻进行增删改查。
11、管理员管理模块:管理员可以对管理员的账号行增删改查。
文档截图:
N-128基于springboot,vue酒店管理系统
前台截图:
后台截图:
- package com.wfuhui.modules.order.controller;
-
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.RestController;
-
- import com.wfuhui.common.utils.DateUtils;
- import com.wfuhui.common.utils.Query;
- import com.wfuhui.common.utils.R;
- import com.wfuhui.modules.room.service.HouseService;
- import com.wfuhui.modules.member.service.MemberService;
- import com.wfuhui.modules.order.entity.OrderEntity;
- import com.wfuhui.modules.order.service.OrderService;
-
-
- /**
- * 订单
- *
- */
- @RestController
- @RequestMapping("/order")
- public class OrderController {
- @Autowired
- private OrderService orderService;
- @Autowired
- private HouseService roomService;
- @Autowired
- private MemberService memberService;
-
- /**
- * 列表
- */
- @RequestMapping("/list")
- public R list(@RequestParam Map
params) { - //查询列表数据
- Query query = new Query(params);
-
- List
orderList = orderService.queryList(query); - int total = orderService.queryTotal(query);
-
- return R.ok().put("rows", orderList).put("total", total);
- }
-
-
- /**
- * 信息
- */
- @RequestMapping("/info/{id}")
- public R info(@PathVariable("id") Integer id){
- OrderEntity order = orderService.queryObject(id);
- return R.ok().put("order", order);
- }
-
- /**
- * 保存
- */
- @RequestMapping("/save")
- public R save(@RequestBody OrderEntity order){
- orderService.save(order);
- return R.ok();
- }
-
- /**
- * 修改
- */
- @RequestMapping("/update")
- public R update(@RequestBody OrderEntity order){
- orderService.update(order);
-
- return R.ok();
- }
-
- /**
- * 删除
- */
- @RequestMapping("/delete")
- public R delete(@RequestBody Integer[] ids){
- orderService.deleteBatch(ids);
-
- return R.ok();
- }
-
- /**
- * 预订房间
- * @param orderId
- * @param roomNumber
- * @return
- */
- @RequestMapping("/orderRoom/{id}")
- public R orderRoom(@PathVariable("id")Integer id, String roomNumber) {
- OrderEntity order = new OrderEntity();
- order.setId(id);
- order.setOrderStatus(3);
- order.setRoomNumber(roomNumber);
- orderService.orderRoom(order);
- return R.ok();
- }
-
- /**
- * 退房
- * @param orderId
- * @param roomNumber
- * @return
- */
- @RequestMapping("/returnRoom/{id}")
- public R returnRoom(@PathVariable("id")Integer id) {
- OrderEntity order = new OrderEntity();
- order.setId(id);
- order.setOrderStatus(4);
- orderService.returnRoom(order);
- //减少已售
- orderService.delHouseVolume(order.getId());
- return R.ok();
- }
-
- }
- <template>
- <div>
- <el-container>
- <el-header><mainHeader>mainHeader>
- el-header>
- <el-container>
- <mainSidebar :active="active">mainSidebar>
- <el-main>
- <div v-if="showList">
- <el-form :inline="true" :model="q" class="demo-form-inline">
- <el-form-item label="客房名称">
- <el-input v-model="q.houseName" placeholder="客房名称">el-input>
- el-form-item>
- <el-form-item>
- <el-button type="primary" @click="query">查询el-button>
- <el-button type="success" @click="add">新增el-button>
- <el-button type="warning" @click="update">修改el-button>
- <el-button type="danger" @click="del">删除el-button>
- el-form-item>
- el-form>
- <el-table
- :data="houseList"
- style="width: 100%"
- @selection-change="handleSelectionChange">
- <el-table-column
- type="selection"
- width="55">
- el-table-column>
- <el-table-column
- prop="picUrl"
- label="图片"
- >
- <template slot-scope="scope">
- <el-image
- style="width: 100px; height: 80px"
- :src="scope.row.picUrl">el-image>
- template>
- el-table-column>
- <el-table-column
- prop="houseName"
- label="客房名称"
- >
- el-table-column>
- <el-table-column
- prop="category.categoryName"
- label="分类">
- el-table-column>
- <el-table-column
- prop="price"
- label="价格">
- el-table-column>
- <el-table-column
- prop="stock"
- label="房间数量">
- el-table-column>
- <el-table-column
- prop="createTime"
- label="创建时间">
- el-table-column>
- el-table>
- <el-pagination
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- :current-page="q.page"
- :page-sizes="[10, 50, 100]"
- :page-size="q.limit"
- layout="total, sizes, prev, pager, next, jumper"
- :total="total">
- el-pagination>
- div>
- <div v-if="!showList">
- <el-form :model="house" label-width="120px">
- <el-form-item label="图片">
- <el-upload
- class="avatar-uploader"
- action="http://127.0.0.1:10001/api/fileupload/upload"
- list-type="picture-card"
- multiple
- :file-list="fileList"
- :on-success="handleAvatarSuccess"
- :on-remove="imgRemove"
- :before-upload="beforeAvatarUpload">
- <i class="el-icon-plus avatar-uploader-icon">i>
- el-upload>
-
- el-form-item>
- <el-form-item label="客房名称">
- <el-input v-model="house.houseName">el-input>
- el-form-item>
- <el-form-item label="分类">
- <el-select v-model="house.categoryId" placeholder="请选择">
- <el-option
- v-for="item in categoryList"
- :key="item.id"
- :label="item.categoryName"
- :value="item.id">
- el-option>
- el-select>
- el-form-item>
- <el-form-item label="价格">
- <el-input v-model="house.price">el-input>
- el-form-item>
- <el-form-item label="房间数量">
- <el-input v-model="house.stock">el-input>
- el-form-item>
- <el-form-item label="详情">
- <quill-editor ref="text" v-model="house.describe" :options="editorOption" style="height: 300px; margin-bottom: 50px;" />
- el-form-item>
- <el-form-item>
- <el-button type="primary" @click="onSubmit">保存el-button>
- <el-button @click="cancel">取消el-button>
- el-form-item>
- el-form>
- div>
- el-main>
- el-container>
- el-container>
- div>
- template>
- <script>
- import { quillEditor } from 'vue-quill-editor'
- import {quillRedefine} from 'vue-quill-editor-upload'
- import 'quill/dist/quill.core.css'
- import 'quill/dist/quill.bubble.css'
- import 'quill/dist/quill.snow.css'
- import mainHeader from '../../../components/admin-main-header'
- import mainSidebar from '../../../components/admin-main-sidebar'
- export default {
- name: "House",
- data() {
- return {
- total: 0,
- houseList: [],
- categoryList: [],
- q: {
- houseName: '',
- page: this.currentPage,
- limit: this.pageSize
- },
- asideStyle: {
- height: '500px'
- },
- house: {
- picUrl: ''
- },
- active: '5',
- showList: true,
- editorOption: {},
- fileList: [],
- ids: []
- };
- },
- components: {
- quillEditor,
- quillRedefine,
- mainHeader,
- mainSidebar
- },
- methods:{
- handleSizeChange(e){
- //console.log(e)
- this.q.limit = e;
- this.query();
- },
- handleCurrentChange(e){
- //console.log(e)
- this.q.page = e;
- this.query();
- },
- query(){
- var that = this;
- this.$axios.get(this.domain + '/house/list',
- { headers:{ token: localStorage.getItem("atoken") },
- params: that.q
- }).then(function(res){
- if(res.data.code == 0){//成功
- that.houseList = res.data.rows
- that.total = res.data.total
- }else{
-
- }
- })
- },
- queryCategory(){
- var that = this;
- this.$axios.get(this.domain + '/category/listAll',
- {
- headers:{ token: localStorage.getItem("atoken") }
- }).then(function(res){
- if(res.data.code == 0){//成功
- that.categoryList = res.data.categoryList
- }else{
-
- }
- })
- },
- queryHouse(id){
- var that = this;
- this.$axios.get(this.domain + '/house/info/'+id,
- {
- headers:{ token: localStorage.getItem("atoken") }
- }).then(function(res){
- if(res.data.code == 0){//成功
- that.house = res.data.house
- that.initImage(res.data.house.picUrls)
- }else{
-
- }
- })
- },
- initImage(picUrls){
- this.fileList=[];
- let urlList = picUrls.map(function(item, index){
- return {url: picUrls[index]}
- });
- for (let url in urlList){
- this.fileList.push(urlList[url]);
- }
- },
- onSubmit(e){
- var that = this;
- var data = this.house;
- data.picUrls = this.fileList.map(function(item, index){
- return item.url
- })
- data.picUrl = data.picUrls[0]
- var action = data.id == null ? "save" : "update";
- this.$axios.post(this.domain + '/house/'+action,
- data,
- {
- headers: {'token': localStorage.getItem("atoken")}
- }
- ).then(function(res){
- //console.log(res)
- if(res.data.code == 0){//成功
- that.showList = true;
- that.query();
- }else{
- that.errorMsg = res.data.msg;
- that.$message.error(res.data.msg);
- }
- })
- },
- add(){
- this.showList = false
- this.fileList = []
- this.house = {
- picUrls: []
- }
- },
- cancel(){
- this.showList = true
- },
- update(){
- if(this.ids.length != 1){
- this.$message.info("请选择一条数据");
- return;
- }
- this.showList = false;
- this.queryHouse(this.ids[0]);
- },
- del(){
- if(this.ids.length == 0){
- this.$message.info("请选择数据");
- return;
- }
- var that = this;
- this.$axios.post(this.domain + '/house/delete',
- that.ids, {
- headers: {'token': localStorage.getItem("atoken")}
- }).then(function(res){
- //console.log(res)
- if(res.data.code == 0){//成功
- that.query();
- }else{
- that.errorMsg = res.data.msg;
- that.$message.error(res.data.msg);
- }
- })
- },
- handleAvatarSuccess(e){
- this.fileList.push({
- url: e.url
- });
- },
- imgRemove(file, fileList){
- this.fileList = fileList;
- },
- beforeAvatarUpload(e){
-
- },
- handleSelectionChange(e){
- var ids = [];
- for(var i = 0; i < e.length; i++){
- ids.push(e[i].id)
- }
- this.ids = ids;
- }
- },
- created(){
- var docHeight = document.documentElement.clientHeight;
- this.asideStyle.height = docHeight - 76 + "px";
- var user = localStorage.getItem("auser");
- if(user){
- this.user = JSON.parse(user);
- }else{
- this.$router.push("admin_login");
- }
- this.query();
- this.queryCategory();
- this.editorOption = quillRedefine(
- {
- // 图片上传的设置
- uploadConfig: {
- action: this.domain + '/api/fileupload/upload', // 必填参数 图片上传地址
- size: 500, // 可选参数 图片限制大小,单位为Kb, 1M = 1024Kb
- accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon', // 可选参数 可上传的图片格式
- // 必选参数 res是一个函数,函数接收的response为上传成功时服务器返回的数据
- // 你必须把返回的数据中所包含的图片地址 return 回去
- res: (respnse) => {
- return respnse.url
- },
- name: 'file' // 图片上传参数名
- }
- }
- )
- //console.log(this.editorOption)
-
- }
- };
- script>
-
- <style scoped>
-
- style>