酒店管理|基于Springboot+Vue前后端分离实现酒店管理系统

news2024/11/17 3:37:28

作者主页:编程指南针

作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师

主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助

收藏点赞不迷路  关注作者有好处

文末获取源码 

项目编号:BS-XX-166        

一,项目简介

随着我国经济发展水平的迅速提高,酒店行业作为服务行业出的重要组成部分,已经越来越显示出其强劲的发展势头。纵观国内外酒店业信息化发展轨迹和趋势,我们不难看出,随着洒店业竞争的加剧,酒店之间客源的争夺越来越激烈,客房销售的利润空间越来越小,酒店需要使用更有效的信息化手段,拓展经营空间,降低运营成本,提高管理和决策效率。而经济型酒店通过信息化管理提高收益的需求更加突出。尤其是在疫情的影响下,酒店之间的竞争更加激烈,而线上预定能够使中小型酒店在同类型酒店更具竞争。

本系统分为前台、后台两部分。前台用户需要通过手机短信验证,进行注册后,再通过手机号、密码进行登录。未登录时,可以看到展示的酒店信息,包括酒店环境、客房展示图;登陆前台后,用户可以进行客房预定,预定后进行订单支付、订单查询,还可以点击右上角查看用户中心,在用户中心,用户可以修改头像、密码等信息。后台用户分为两种角色:酒店员工与酒店管理员。员工可以进行房间信息的管理,例如添加新的房间、修改房间状态、房间信息批量导入等,也可以进行房客登记、退房、查看订单等操作。前台系统功能图如图3-1所示吗,后台系统功能图如图3-2所示。

 

图3-1  前台系统功能图

 图3-2  后台系统功能图

二,环境介绍

语言环境:Java:  jdk1.8

数据库:Mysql: mysql5.7

应用服务器:Tomcat:  tomcat8.5.31

开发工具:IDEA或eclipse

后台开发技术:Mybatis-plus持久层框架处理数据+SpringBoot整合依赖;

前端页面开发技术:Vue+ElementUI

三,系统展示

5.1 前台用户登录注册模块

5.1.1 注册

用户在浏览器进入注册界面,按照提示输入用户名、密码、手机号后,发起短信验证。这个过程,前台会判断输入是否为空、以及两次密码输入是否一致。用户接收到短信验证码后,输入验证码,点击注册,向后台注册接口/register发起请求。后台接收到数据后,进行验证码验证,通过验证后再查询手机号是否已经注册。如果都通过,则注册成功,页面跳转至登陆界面。界面实现效果如图5-1所示。

 

图5-1  注册界面

5.1.2 登录

用户在注册完毕后,进入酒店登陆界面。输入自己的注册所用的手机号、密码,以及程序生成的验证码,点击登录按钮。前端先验证验证码是否正确,确定正确之后,向后台接口地址/lo/login发起ajax请求,后台验证手机号是否存在,手机号对应密码是否正确。手机号、密码验证正确后,登陆成功,反之失败。

界面实现效果如图5-2所示。

 

图5-2  登录界面

5.2 用户中心模块

5.2.1 查看用户信息

用户进行登录后,点击右上角用户名出现的下拉框内中户中心选项,进入用户中心界面。在这个界面,用户可以查看到用户名、性别、头像等信息。界面实现效果如图5-3所示。

 图5-3  查看用户信息界面

5.2.2 修改用户信息

在用户中心界面,用户可以对自己的用户名、性别、头像等信息进行修改。点击资料框中的头像,弹出文件选择框,选择图片文件,上传到阿里云oss文件存储服务器,返回一个图片地址。点击更改资料后,前端向后端发起请求前判断用户名是否为空,非空就继续发起请求。后端将数据库数据更改后,返回成功码,前端接受修改成功信息,弹出提示框,刷新页面。界面实现效果如图5-4所示。

 

图5-4  修改用户信息界面

5.3 客房预定模块

5.3.1 预定客房

用户查看客房类型详细信息时,可在此页面填写入住日期、退房日期、姓名、预留手机号等预定信息。点击预定,前端对信息进行非空判定,如果为空则无法向后端发起请求。通过判定后,向/createOrder接口发起请求,生成预定订单。

界面实现效果如图5-5所示。

 

图5-5  预定客房界面

5.3.2 支付订单

用户在点击预定后,进入订单核对页面,核对后点击支付订单,进行支付宝沙箱支付。扫码或登录支付宝沙箱账号支付成功后,发起异步通知,修改数据库订单状态,页面跳至成功支付界面。界面实现效果如图5-6所示。

 

图5-6  预定客房界面

5.4 订单管理模块

5.4.1 订单查询

进入订单列表,页面查询所有订单,分页展示。后台用户可以在搜索条件框中输入想要查询的条件,店家查询按钮进行条件分页查询。后端收到查询请求,对数据库查询数据,得到数据后,返回给前端,前端进行数据展示。界面实现效果如图5-7所示。

 

图5-7  订单查询界面

5.4.2 订单管理

在订单列表,后台用户点击不同的操作按钮,可以对订单进行不同的操作。对于已经支付完成的订单,点击退款操作按钮,输入小于房费的金额,发起退款请求,退款成功后,修改订单状态为已退款。对于待支付的订单,点击关闭操作按钮,将订单状态改为已取消。对于任意订单记录点击删除,可以将选中记录逻辑删除。点击修改按钮,可以修改订单中的房费信息。退款界面实现效果如图5-8所示;关闭界面实现效果如图5-9所示;

图5-8  订单退款界面

图5-9  订单关闭界面

 

5.5 入住管理模块

5.5.1 查询入住信息

后台用户点击入住信息,分页查看入住信息列表。在此页面的条件搜索框中输入条件信息,点击查询按钮,进行条件分页查询。界面实现效果如图5-10所示。

 

图5-10  查询入住信息界面

5.5.2 添加入住信息

后台用户点击新增用户,跳转至入住信息新增界面。用户在此输入房客登记的信息,点击保存,即可将此条入住信息传至后端,由后端程序将数据插入数据库保存。界面实现效果如图5-11所示。

 

 

5.5.3 添加随客信息

当入住一间房的房客大于一人时,在添加一条入住记录后,后台用户可以点击添加随客按钮,为此条入住记录添加随客记录。输入随客信息,视入住人数情况,选择保存或是保存并再次添加,将数据通过后端代码插入数据库。界面实现效果如图5-12所示。

 

图5-12  添加随客信息界面

5.6 房间管理模块

5.6.1 房间信息添加

后台用户在进入房间添加界面,可以填写房间信息,如房间号、房间类型、备注信息等。点击保存,将数据传输到后端,保存至数据库。界面实现效果如图5-13所示。

 

图5-13  房间信息添加界面

5.6.2 房间信息导入

在进入房间信息导入界面后,后台用户可以点击下载模板,查看模板,然后编写一份与模板格式相同的excel文件,选取该文件,提交。后端程序将读取文件内容,将数据库不存在的房间信息存入。界面实现效果如图5-14所示。

 

图5-14  房间信息导入界面

四,核心代码展示

package com.tsx.boot.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tsx.boot.entity.Admin;
import com.tsx.boot.entity.query.adminQuery;
import com.tsx.boot.entity.vo.admin.adminVo;
import com.tsx.boot.service.AdminService;
import com.tsx.boot.utils.R;
import io.swagger.annotations.ApiOperation;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author testjava
 * @since 2022-07-21
 */
@RestController
@RequestMapping("/admin")
@CrossOrigin
public class AdminController {

    @Autowired
    private AdminService adminService;

    @DeleteMapping("/delete/{id}")//通过路径传id值(逻辑删除需要在实体类的逻辑删除的成员属性上加注解@TableLogic)
    //效果:在字段上加上这个注解再执行BaseMapper的删除方法时,删除方法就会变成修改
    public  R removeAdmin(@PathVariable String id){
        boolean flag = adminService.removeById(id);
        if(flag){
            return R.ok();
        }
        else {
            return R.error();
        }
    }
    //修改
    @PostMapping("/updateAdmin")
    public R updateAdmin(@RequestBody Admin admin){
        boolean flag = adminService.updateById(admin);
        if(flag){
            return R.ok();
        }else {
            return R.error();
        }
    }
    //添加方法
    @PostMapping("/addAdmin")
    public R addMember(@RequestBody Admin admin){
        boolean flag=adminService.save(admin);
        if(flag){
            return R.ok();
        }else {
            return R.error();
        }
    }
    //根据id获取信息,用于回显修改
    @GetMapping("/getInfo/{id}")
    public R getInfoById(@PathVariable String id){

        QueryWrapper<Admin> wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);
        Admin admin = adminService.getOne(wrapper);

        return R.ok().data("admin",admin);
    }

    //登陆
    @PostMapping("/login")
    public R login(@RequestBody adminVo adminVo){
        Admin admin = adminService.login(adminVo);
        if(admin != null){
            return R.ok().data("token",admin.getId());
        }else {
            return R.error();
        }
    }
    //退出登录
    @PostMapping("/logout")
    public R logout(){
        return R.ok();
    }

    @GetMapping("/info/{id}")
    public R info(@PathVariable String id){

        List<String> list=new ArrayList<>();
        QueryWrapper<Admin> wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);
        Admin admin=adminService.getOne(wrapper);
        if(admin.getStatus()==1){
            list.add("admin");
        }else {
            list.add("staff");
        }

        return R.ok().data("roles",list).data("name",admin.getName()).data("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
    }

    //分页查询后台用户
    @ApiOperation(value = "用户分页查询")
    @PostMapping("/pageAdmin/{current}/{limit}")//当前页与每页数目
    public R pageListTeacher(@PathVariable long current,
                             @PathVariable long limit,
                             @RequestBody(required = false) adminQuery adminQuery){
        Page<Admin> pageAdmin = new Page<>(current, limit);
        //构建条件
        QueryWrapper<Admin> wrapper=new QueryWrapper<>();
        //wrapper.
        String name = adminQuery.getName();
        Integer status = adminQuery.getStatus();
        String begin = adminQuery.getBegin();
        String end = adminQuery.getEnd();
        if(!StringUtils.isEmpty(name)){
            wrapper.like("name",name);
        }
        if(!StringUtils.isEmpty(status)){
            wrapper.eq("status",status);
        }
        if(!StringUtils.isEmpty(begin)){
            wrapper.ge("create_time",begin);//大于表中起始时间字段
        }
        if(!StringUtils.isEmpty(end)){
            wrapper.le("update_time",end);//小于表中起始时间字段
        }
        //排序
        wrapper.orderByDesc("update_time");
        //实现条件分页查询
        adminService.page(pageAdmin,wrapper);
        long total=pageAdmin.getTotal();
        List<Admin> records=pageAdmin.getRecords();
        return R.ok().data("total",total).data("rows",records);
    }

}

package com.tsx.boot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tsx.boot.entity.Checkin;
import com.tsx.boot.entity.other.Pie;
import com.tsx.boot.service.CheckinService;
import com.tsx.boot.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/charts")
@CrossOrigin
public class ChartController {

    @Autowired
    private CheckinService checkinService;


    @GetMapping("/getWeekIncome")
    public R getWeekIncome() throws ParseException {
        List<Float> list=checkinService.countWeekIncount();
        List<String> timeList=checkinService.getTimeWeek();
        return R.ok().data("list",list).data("times",timeList);
    }
    /*
        获取当月的不同房型入住情况
     */
    @GetMapping("/getMonthType")
    public R getMonthType(){
        //获取所有房型集合
        List<String> types =checkinService.countype();
        //获取不同房型在当月的入住次数
        List<Integer> Typelist=checkinService.countMonthTypeNum(types);

        //封装成图标需要的数据形式
        List<Pie> list=new ArrayList<>();

        for(int i=0;i<types.size();i++){
            Pie pie=new Pie();
            pie.setName(types.get(i));
            pie.setValue(Typelist.get(i));
            list.add(pie);
        }
        return R.ok().data("list",list).data("types",types);
    }

    /*
        计算今日收入
     */
    @GetMapping("/getToDayMoney")
    public R getToDayMoney(){
        Date date=new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String day=formatter.format(date);
        String day_start=day+" 00:00:00";
        String day_end=day+" 23:59:59";
        System.out.println(day_start);
        QueryWrapper<Checkin> wrapper=new QueryWrapper<>();
        wrapper.select("sum(money) as sumAll");
        try{
            wrapper.ge("create_time",formatter1.parse(day_start));
            wrapper.le("create_time",formatter1.parse(day_end));
            Checkin checkin=checkinService.getOne(wrapper);
            System.out.println(checkin.getSumAll());
        }catch (Exception e){
            e.printStackTrace();
            return R.error();

        }
        return R.ok();
    }

}

package com.tsx.boot.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tsx.boot.entity.*;
import com.tsx.boot.entity.query.checkQuery;
import com.tsx.boot.service.CheckinService;
import com.tsx.boot.service.ChecksService;
import com.tsx.boot.service.RoomService;
import com.tsx.boot.service.RoomtypeService;
import com.tsx.boot.utils.R;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.nio.file.Watchable;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author testjava
 * @since 2022-07-27
 */
@RestController
@RequestMapping("/check")
@CrossOrigin
public class CheckinController {
    @Autowired
    private CheckinService checkService;
    @Autowired
    private ChecksService checksService;
    @Autowired
    private RoomService roomService;
    @Autowired
    private RoomtypeService roomtypeService;


    /*
        退房功能,当点击退房按钮,根据主客的入住记录id,将主客、从客入住状态转为已退房
        再将房间状态转换为空闲
     */
    @PostMapping("/checkOut/{id}")
    public R checkOut(@PathVariable String id){

        //根据id,将主客、从客入住状态转换为退房
        UpdateWrapper<Checkin> wrapper1=new UpdateWrapper<>();
        wrapper1.eq("id",id);
        wrapper1.set("state",0);
        checkService.update(null,wrapper1);

        UpdateWrapper<Checks> wrapper2=new UpdateWrapper<>();
        wrapper2.eq("zid",id);
        wrapper2.set("state",0);
        checksService.update(null,wrapper2);

        //将房间状态转换为空闲 先获取房间号,再将房间状态改为空闲
        QueryWrapper<Checkin> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",id);
        Checkin checkin=checkService.getOne(queryWrapper);

        UpdateWrapper<Room> wrapper=new UpdateWrapper<>();
        wrapper.eq("id",checkin.getRoomId());
        wrapper.set("state",1);
        roomService.update(null,wrapper);
        return R.ok().message("退房成功!");
    }

    /*
        通过房号查到房费
     */
    @GetMapping("/calculate/{roomId}")
    public R calculate(@PathVariable String roomId){
        QueryWrapper<Room> wrapper1=new QueryWrapper<>();
        wrapper1.eq("id",roomId);
        Room room = roomService.getOne(wrapper1);
        if(null==room){
            return R.error().message("房间号不存在!");
        }

        BigDecimal fee= roomService.getFeebyRoomId(roomId);

        return R.ok().data("money",fee);
    }

    /*
        通过id查询入住信息
     */
    @GetMapping("/getCheckInfoById/{id}")
    public R getCheckInfoById(@PathVariable String id){
        QueryWrapper<Checkin> wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);

        Checkin checkin = checkService.getOne(wrapper);
        return R.ok().data("check",checkin);
    }

    /*
        逻辑删除入住信息(逻辑删除需要在实体类的逻辑删除的成员属性上加注解@TableLogic
                        在isDelete字段上加上这个注解再执行BaseMapper的删除方法时,删除方法就会变成修改)
            通过传id值,逻辑删除入住信息
     */
    @DeleteMapping("/deleteCheck/{id}")
    public  R removeCheck(@PathVariable String id){

        // 房间状态改为1,再删除
        roomService.updateRoomState(id);
        boolean flag = checkService.removeById(id);

        if(flag){
            //修改该类型剩余房间数量
            roomtypeService.updateAllSTypeNum();
            return R.ok();
        }
        else {
            return R.error();
        }
    }
    /*
        修改入住信息
     */
    @PostMapping("/updateCheck")
    public R updateCheck(@RequestBody Checkin checkin){

        boolean flag = checkService.updateById(checkin);

        if(flag){
            //修改该类型剩余房间数量
            roomtypeService.updateAllSTypeNum();
            return R.ok();
        }else {
            return R.error();
        }
    }

    //退房 需要修改房间状态、入住状态,剩余空闲房间数量
    @PostMapping("/tRoom")
    public R TRoom(@PathVariable String id){
        //修改入住状态为退房
        UpdateWrapper<Checkin> wrapper=new UpdateWrapper<>();
        wrapper.eq("id",id);
        wrapper.set("state",2);
        boolean flag = checkService.update(wrapper);
        if(flag){
            // 删除后,房间状态改为1
            roomService.updateRoomState(id);
            return R.ok();
        }else {
            return R.error();
        }
    }

    //添加方法
    @PostMapping("/addCheck")
    public R addCheck(@RequestBody Checkin checkin){
        //入住状态初始为:1 表示入住中
        checkin.setState(1);
        //查出房间信息、判断该记录的房间状态是否为1(空闲状态)
        QueryWrapper<Room> wrapper1=new QueryWrapper<>();
        wrapper1.eq("id",checkin.getRoomId());
        Room room = roomService.getOne(wrapper1);
        if(null==room){
            return R.error();
        }

        int state=room.getState();
        //初始化入住记录的类型名
        checkin.setTypeName(room.getTypeName());

        boolean flag;
        //如果该房间状态为1(空闲),才能够入住
        if(state==1){
            flag=checkService.save(checkin);
        }else {
            return R.error();
        }
        //新增

        if(flag){
            //添加入住记录,将该房间的状态修改为已经入住
            UpdateWrapper<Room> wrapper=new UpdateWrapper<>();
            wrapper.eq("id",checkin.getRoomId());
            wrapper.set("state",2);
            roomService.update(wrapper);

            //修改该类型剩余房间数量
            roomtypeService.updateAllSTypeNum();
            return R.ok();
        }else {
            return R.error();
        }
    }


   /*
    *  分页条件查询入住信息
    */
    @ApiOperation(value = "入住信息分页查询")
    @PostMapping("/pageCheck/{current}/{limit}")//当前页与每页数目
    public R pageListTeacher(@PathVariable long current,
                             @PathVariable long limit,
                             @RequestBody(required = false) checkQuery checkQuery){
        System.out.println(checkQuery);
        Page<Checkin> pageRoom = new Page<>(current, limit);
        //构建条件
        QueryWrapper<Checkin> wrapper=new QueryWrapper<>();
        //wrapper.
        String roomId = checkQuery.getRoomId();
        List<Date> dates = checkQuery.getDates();
        String name = checkQuery.getName();
        String idNumber=checkQuery.getIdNumber();
        Integer state=checkQuery.getState();

        if(!StringUtils.isEmpty(roomId)){
            wrapper.eq("room_id",roomId);
        }

        if(!StringUtils.isEmpty(name)){
            wrapper.like("name",name);
        }
        if(!StringUtils.isEmpty(idNumber)){
            wrapper.like("id_number",idNumber);
        }
        if(!StringUtils.isEmpty(state)){
            wrapper.eq("state",state);
        }
        if(!StringUtils.isEmpty(dates)){
            //前端日期传到后端出了问题,在此进行处理。将日期左右边界都加1
            long time1 = dates.get(0).getTime();
            long time2 = dates.get(1).getTime();
            Date DateStart = new Date();
            Date DateEnd = new Date();
            DateStart.setTime(time1 + 1000*60*60*10);
            DateEnd.setTime(time2 + 1000*60*60*34-1000);

            wrapper.between("create_time",new Date(DateStart.toString()),new Date(DateEnd.toString()));
        }
        //排序
        wrapper.orderByDesc("create_time");
        //实现条件分页查询
        checkService.page(pageRoom,wrapper);
        long total=pageRoom.getTotal();
        List<Checkin> records=pageRoom.getRecords();
        return R.ok().data("total",total).data("rows",records);
    }

}

五,项目总结

本系统分为前台与后台。前台采用Springboot+js、Jquery等技术实现了酒店信息展示、客房信息展示、客房预定、提交建议、用户中心等功能。后台采用Springboot+Vue实现了用户管理、房间管理、入住信息管理、订单管理、图表展示等诸多功能。数据存储使用的是MySQL。

因为使用的Springboot作为后端开发框架,简化了原本SSM框架的繁琐配置,让开发周期大大缩短。持久层框架采用MyBatisPlus这一Mybatis的增强工具,使SQL编写量大大减少。甚至可以在完成数据库表的创建后,使用代码生成器,将Controller、Mapper、Service等文件创建好。

在设计与实现的过程中,遇到了许多因为对业务没有接触过而产生的问题。例如订单数据库设计、预定流程等问题。还有因为技术选型的纠结,因为对Vue技术的不熟练,最终决定前台的实现不采用前后端分离。最后都通过百度查询资料,或与同学讨论勉强解决。系统至此实现了中小型酒店管理所需功能。

但此系统仍不可避免的有许多不足之处可以改进,例如比起电脑端的预定,大家更常用的是手机端小程序、app端上定房。还有就是,后台系统应当有一个能够看到后台用户的操作记录的日志模块。比起市面上已经完善的酒店系统,本系统还是有许多可以改进的地方,接下来若是有机会,也会不断参照,改进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

webpack5从入门到精通

前言 webpack是什么&#xff1f; 摘自官网的一段话&#xff1a;webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个或多个入口点构建一个 依赖图(dependency graph)&#xff0c;然后将你项目中所需的每…

[oeasy]python0072_修改字体前景颜色_foreground_color_font

修改颜色 回忆上次内容 m 可以改变字体样式 0-9 之间设置的都是字体效果0 重置为默认1 变亮2 变暗3 斜体4 下划线5 慢闪6 快闪7 前景背景互换8 隐藏9 中划线 叠加效果 \33[1;3moeasy;分割 取消效果 21 取消 122 取消 223 取消 3一直到 290 是全部取消&#xff0c;回到默认 最…

静态链接库与动态链接库

静态链接库与动态链接库的区别 静态链接库&#xff1a;在项目中引用了库函数&#xff0c;编译时链接器会将引用的函数代码或变量&#xff0c;链接到可执行文件里&#xff0c;和可执行程序组装在一起 动态链接库&#xff1a;在编译阶段不参与链接&#xff0c;不会和可执行文件…

【Unity】流式播放远端音频:WAV格式音频篇(一)

先了解一下wav的格式&#xff1a; 参考1&#xff1a;【音频】WAV 格式详解_tyustli的博客-CSDN博客_wav文件格式详解wav 文件支持多种不同的比特率、采样率、多声道音频。WAV 文件格式是 Microsoft 的 RIFF 规范的一个子集&#xff0c;用于存储多媒体文件。RIFF&#xff08;res…

git-secret:在 Git 存储库中加密和存储密钥(上)

目前市面上已经存在许多较为成熟的密钥管理产品&#xff0c;比如 HashiCorp Vault&#xff0c;AWS Secrets Manager 以及 GCP Secret Manager。由于这些产品需要集成和维护等服务&#xff0c;因此在项目中引入会增加一定成本和开销。阅读本文&#xff0c;将带你了解如何在 Dock…

numpy数值差分

文章目录diffediff1ddiff diff是numpy中用于求差分的函数&#xff0c;函数定义为 diff(a, n1, axis-1, prepend<no value>, append<no value>)其中a为数组&#xff0c;n为差分的阶数&#xff0c;axis为求导对应的坐标轴&#xff0c;默认-1表示最后一个轴。 例如…

提分必练,中创教育PMP全真模拟题分享

湖南中创教育每日五题分享来啦&#xff0c;“日日行&#xff0c;不怕千万里&#xff1b;常常做&#xff0c;不怕千万事。”&#xff0c;每日五题我们练起来&#xff01; 1、一个建筑项目所在的地区即将进入台风季节&#xff0c;恶劣的天气会严重影响项目的进度。高层管理者要求…

Java poi之word文本替换

目录结构前言文档准备引入Maven依赖代码块替换结果验证孤勇者替换结果对比青鸟替换结果对比前言 应公司需求&#xff0c;需实现以下功能 word文本内容的替换&#xff1b;word文本内容的提取&#xff1b;word文档中图片的提取存放 此文章将使用Apache POI实现Word文档中文本内…

【C++】揭开“引用”的庐山真面目

目录 一、引用的概念 二、引用的应用 1.特性 2.使用场景 2.1 引用作为函数参数 2.2 引用作为函数返回值 三、引用的权限问题 四、引用和指针的区别 一、引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟…

【数据结构之二叉树简介·顺序存储·应用:堆·堆排序·TOPK问题】

​ &#x1f57a;作者&#xff1a; 迷茫的启明星 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f383;相关文章 【数据结构从0到1之树的初识】 &#x1f3c7;家人们&#xff0c;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64…

Kotlin SharedFlowStateFlow 热流到底有多热?

前言 协程系列文章&#xff1a; 一个小故事讲明白进程、线程、Kotlin 协程到底啥关系&#xff1f;少年&#xff0c;你可知 Kotlin 协程最初的样子&#xff1f;讲真&#xff0c;Kotlin 协程的挂起/恢复没那么神秘(故事篇)讲真&#xff0c;Kotlin 协程的挂起/恢复没那么神秘(原理…

50条必背JAVA知识点(二)

16.强制类型转换&#xff1a;将容量大的数据类型转换为容量小的数据类型&#xff0c;但可能造成精度降低或溢出。 17.字符串不能直接转换为基本类型&#xff0c;但通过基本类型对应的包装类则可以实现把字符串转换成基本类型。 18.计算机底层都以二进制补码的方式来存储数据。…

将现实问题转换为编程问题

将现实问题转换为编程问题需要转换思维&#xff0c;不过孰能生巧&#xff0c;见多了就自然懂如何做了&#xff0c;所以动起手来是决没错的。1.猜名次问题改进一&#xff1a;改进二&#xff1a;改进三&#xff1a;2.猜凶手问题总结&#xff1a;1.猜名次问题 每个选手都说了两句话…

深入浅出学习透析Nginx服务器的架构分析及原理分析「底层技术原理+运作架构机制」

Nginx再次回顾 也许你已经忘记了Nginx是做什么的&#xff1f;我来再次给你夯实一下概念。 多协议反向代理 Nginx是个高性能的Web和反向代理服务器及HTTP服务器&#xff0c;它能反向代理HTTP&#xff0c;HTTPS和邮件相关(SMTP&#xff0c;POP3&#xff0c;IMAP)的协议链接&am…

四十、Kubernetes1.25中安全认证详解

1、访问控制概述Kubernetes作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。所谓的安全性其实就是保证对Kubernetes的各种客户端进行认证和鉴权操作。客户端在Kubernetes集群中&#xff0c;客户端通常有两类&#xff1a;User Account&#xff1a…

视频剪辑必备的6个免费素材库~

视频剪辑必备素材&#xff0c;那自然是视频、配乐、音效啦&#xff0c;但最重要的还是内容&#xff0c;这些素材只是点缀。 那要如何获取素材&#xff1f;很多朋友应该都知道&#xff0c;网上很多素材版权不明确&#xff0c;使用不当就会造成侵权&#xff0c;找素材成为了一大…

电脑重装系统装不了如何解决

重装系统装不了如何解决&#xff1f;当电脑出现故障时&#xff0c;大部分人都会选择重装系统来解决这个问题&#xff0c;但是有人出现系统重装不了&#xff0c;下面小编就来为大家解决系统重装不了的问题。 工具/原料&#xff1a; 系统版本&#xff1a;win7 品牌型号&#xff…

为什么 B 站的弹幕可以不挡人物?

那天在 B 站看视频的时候&#xff0c;偶然发现当字幕遇到人物的时候就被裁切了&#xff0c;不会挡住人物&#xff0c;觉得很神奇&#xff0c;于是决定一探究竟。 高端的效果&#xff0c;往往只需要采用最朴素的实现方式&#xff0c;忙碌了两个小时&#xff0c;陈师傅打开了 F1…

Spring Boot(二):第一种导入依赖方式的实战案例

文章目录 第一种导入依赖方式的实战案例 一、导入依赖 二、依赖传递结构图 三、开发案例代码 第一种导入依赖方式的实战案例 一、导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0…

Android开发——HOOK技术【解析】

1. 什么是 Hook Hook 英文翻译过来就是「钩子」的意思&#xff0c;那我们在什么时候使用这个「钩子」呢&#xff1f;在 Android 操作系统中系统维护着自己的一套事件分发机制。应用程序&#xff0c;包括应用触发事件和后台逻辑处理&#xff0c;也是根据事件流程一步步地向下执…