简单宿舍管理系统(springboot+vue)

简单宿舍管理系统(springboot+vue)

  • 1.创建项目
    • 1.前端
    • 2.数据库
    • 3.后端
  • 2.登陆
    • 1.前端
      • 1.准备工作
      • 2.登陆组件
      • 3.配置
    • 2.后端
      • 1.链接数据库
      • 2.创建用户实体类
      • 3.数据操作持久层
        • 1.配置
        • 2.内容
        • 3.测试
      • 4.中间业务层
        • 1.异常
        • 2.业务实现
        • 3.测试
      • 5.响应前端控制层
    • 3.前后对接
    • 4.效果
  • 3.后台管理

最近看了springboot和vue,为了练一下把前后端打通就自己手动写个简单的系统,测试一下,把代码放在仓库。

1.创建项目

1.前端

我的前端项目名叫Dormitory,然后添加插件element-plus(页面设计)和axios(后端交互)。

npm init vue@latest#这里插件下载我都选no,之后自己会手动下载使用
cd Dormitory
npm install
npm install element-plus
npm install axios
npm run dev

2.数据库

首先创建库,第一个是登陆功能,我就顺便创建一个简单的用户表t_user。

mysql -u root -p
create database dormitory;
use dormitory;
use store
CREATE TABLE t_user (uid INT AUTO_INCREMENT COMMENT '用户id',username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名',password CHAR(32) NOT NULL COMMENT '密码',role INT COMMENT '角色',name VARCHAR(20) NOT NULL UNIQUE COMMENT '姓名',gender INT COMMENT '性别:0-女,1-男',telephone VARCHAR(50) COMMENT '手机号',PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.后端

创建项目名叫dormitory_b,依赖库我用了三个(spring web,mybatis framework,mysql driver),然后配置一下jdk和maven环境和xml即可。

2.登陆

登陆这里我把uid和role保存到后端session中,username保存到前端cookie中,而且密码啥的我也没加密,就怎么简单怎么来。

1.前端

1.准备工作

这里我用到element-plus和icon,而且我是按需引入,所以首先下载插件:

npm install -D unplugin-vue-components unplugin-auto-import
npm install @element-plus/icons-vue

然后在vite.config.ts按需引入element-plus:

import { fileURLToPath, URL } from 'node:url'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'export default defineConfig({plugins: [vue(),AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
});

在main.ts里将icon全局注册到App上:

import * as ElementPlusIconsVue from '@element-plus/icons-vue'
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}

就可以使用svg方式使用:

 <el-icon><Menu /></el-icon>

然后配置路由用到了router,所以先下载:

npm install vue-router 

然后在src里面建一个router文件夹,里面建一个index.js写路由配置文件,然后在main.js里面挂载一下:

import router from './router';
app.use(router)

2.登陆组件

这里登陆页面我写在了LoginView里面,后面我会配置路由和组件。

<template><div class="login-container"><div class="login-form"><el-form ref="login-form" :model="loginForm" label-width="80px" :rules="rules"><el-form-item label="用户名" prop="username"><el-input v-model="loginForm.username"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="loginForm.password"></el-input></el-form-item><el-form-item label="角色" prop="role"><el-radio-group v-model="loginForm.role"><el-radio label="admin">系统管理员</el-radio><el-radio label="dorm">宿舍管理员</el-radio></el-radio-group></el-form-item><el-form-item size="large"><el-button type="primary" @click="toLogin">登录</el-button></el-form-item></el-form></div></div></template><script>import { ref } from 'vue';import axios from 'axios';export default {setup() {const loginForm = ref({username: '',password: '',role: 'admin',});const rules = {username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' }],role: [{ required: true, message: '请选择角色', trigger: 'change' }],};const performLogin = async () => {try {const formData = new FormData();//axios默认是json格式发送数据,但我后端接受的是user,所以将数据放到表单formData.append('username', loginForm.value.username);formData.append('password', loginForm.value.password);formData.append('role',loginForm.value.role=='admin'?0:1);const response = await axios.post('http://localhost:8080/users/login', formData);const data = response.data;if (data.state === 200) {// 登录成功后,保存用户名到cookiedocument.cookie = `username=${loginForm.value.username}; expires=; path=/`;alert('登录成功');} else if (data.state === 400) {alert('用户名错误');} else if (data.state === 401) {alert('密码错误');}else if (data.state === 402) {alert('角色错误');}} catch (error) {console.error('An error occurred:', error);}};const toLogin = () => {performLogin();};return {loginForm,rules,toLogin,};},};</script><style scoped>.login-container {display: flex;align-items: center;justify-content: center;height: 100vh;}.login-form {padding: 80px;border-radius: 10px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);}</style>

3.配置

首先是在router/index.js里面写路由配置,将这个页面路由配置一下:

import { createRouter, createWebHistory } from 'vue-router'
import LoginView from '@/components/LoginView.vue'
const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/login',component: LoginView}]
})
export default router

然后在App.vue里面写一下这个路由出口

<template><RouterView></RouterView>
</template>

此时就可以通过http://localhost:5173/login/访问到这个页面。

2.后端

1.链接数据库

在application.properties中配置数据库。

spring.datasource.url=jdbc:mysql://localhost:3306/dormitory?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root

2.创建用户实体类

在entity/User类里面创建用户实体类,和getset,equal,tostring方法(mac的快捷键是command+n)。

public class User {private Integer uid;private String username;private String password;private Integer role;private String name;private Integer gender;private String phone;
}

3.数据操作持久层

1.配置

首先是配置一下mapper层,在启动类里面添加项目的mapper路径,让自动扫包。

@MapperScan("com.hckj.dormitory_b.mapper")

在application.properties中配置mapper地址。

mybatis.mapper-locations=classpath:mapper/*.xml
2.内容

在mapper/UserMapper接口里面写SQL语句的抽象方法(类添加@Mapper注解),然后resources/mapper/UserMapper.xml里面写抽象方法的映射文件(这里放在resource是因为xml是静态文件)。

User findByUsername(String username);//接口
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hckj.dormitory_b.mapper.UserMapper"><select id="findByUsername" resultType="com.hckj.dormitory_b.entity.User">select * from t_user where username=#{username}</select>
</mapper>
3.测试

为了登陆测试,这里先给数据库里面插入一条数据:

INSERT INTO t_user (username, password, name,role, gender, telephone)
VALUES ('zoe', '111', 'dz', 0, 0,'188');

然后测试(测试类加注解:@SpringBootTest和@RunWith(SpringRunner.class))

	@Autowiredprivate UserMapper userMapper;@Testpublic void findByUsername(){System.out.println(userMapper.findByUsername("zoe"));}

4.中间业务层

1.异常

在登录这个业务里会出现用户没有查询到和密码不匹配,所以在service的ex包里面创建UsernameNotFoundException和PasswordNotMatchException异常类,还有一个是角色不匹配RoleNotMatchException,并都继承RuntimeException,然后生成抛出异常的5种构造方法。

2.业务实现

然后写业务层的接口(加@Service注解)并写类实现这个接口。

User login(String username, String password,Integer role);//接口
@Service
public class UserServiceImpl implements IUserService{@Autowiredprivate UserMapper userMapper;@Overridepublic User login(String username, String password,Integer role) {User result = userMapper.findByUsername(username);if (result == null) {throw new UsernameNotFoundException("用户数据不存在");}String password_ = result.getPassword();if (!password_.equals(password)) {throw new PasswordNotMatchException("用户密码错误");}Integer role_=result.getRole();if (!role_.equals(role)) {throw new RoleNotMatchException("用户角色错误");}User user = new User();user.setUid(result.getUid());user.setUsername(result.getUsername());user.setRole(result.getRole());return user;}
}
3.测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTests {@Autowiredprivate IUserService userService;@Testpublic void login(){User user= userService.login("zoe","111",0);System.out.println(user);}
}

5.响应前端控制层

package com.hckj.dormitory_b.controller;import com.hckj.dormitory_b.entity.User;
import com.hckj.dormitory_b.service.IUserService;
import com.hckj.dormitory_b.service.ex.PasswordNotMatchException;
import com.hckj.dormitory_b.service.ex.RoleNotMatchException;
import com.hckj.dormitory_b.service.ex.UsernameNotFoundException;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;@RestController
@RequestMapping("users")
public class UserController {@Autowiredprivate IUserService userService;@PostMapping("login")public Map<String, Object> login(User user, HttpSession session) {String username = user.getUsername();String password = user.getPassword();Integer role=user.getRole();Map<String, Object> response = new HashMap<>();try {User loggedInUser = userService.login(username, password,role);session.setAttribute("uid",loggedInUser.getUid());//将用户的uid和role保存到sessionsession.setAttribute("role",loggedInUser.getRole());response.put("state", 200);response.put("message", "登陆成功");response.put("data", loggedInUser);} catch (UsernameNotFoundException e) {response.put("state", 400);response.put("message", "用户名未找到");response.put("data", null);} catch (PasswordNotMatchException e) {response.put("state", 401);response.put("message", "密码不正确");response.put("data", null);} catch (RoleNotMatchException e){response.put("state",402);response.put("message","角色不正确");response.put("data",null);}return response;}
}

3.前后对接

对接这里其实就只是一个跨域问题,这个就是在后端工程的config/WebMvcConfig类里面加入设置,这里我前端的地址是http://localhost:5173

package com.hckj.dormitory_b.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://localhost:5173").allowedMethods("GET", "POST", "PUT", "DELETE").allowCredentials(true);}
}

4.效果

在这里插入图片描述

3.后台管理

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

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

相关文章

大模型背景下软件工程的机遇与挑战

点击链接了解详情 本文作者&#xff1a;汪晟杰 导语:AISE&#xff08;AI Software Engineering&#xff09;有人说是软件工程 3.0&#xff0c;即基于大模型&#xff08;LLM - Large Language Model&#xff09;时代下的软件工程。那么究竟什么是 AISE&#xff0c;他的发展历程对…

简单的聊一聊如何使用CSS的父类Has选择器

最近的:has()选择器允许您对父元素和其他祖先应用样式&#xff0c;本文将向您展示如何在Web应用程序开发中使用它。 在CSS的世界中&#xff0c;选择器是驱动我们在网页上看到的美丽且响应式设计的工作的马。它们允许开发者根据元素的属性、位置和关系来选择和样式化HTML元素。 …

汽车屏类产品(五):中控IVI车载信息娱乐系统

前言: 车载信息娱乐系统(IVI)的起源可以追溯到20世纪,按钮调幅收音机被认为是第一个功能。从那以后,IVI系统在创造壮观的车内体验方面变得不可或缺,以至于汽车被称为“车轮上的智能手机”。但随着包括自动驾驶汽车在内的汽车技术的进步,以及对个性化体验的需求不断增长…

【合集】Redis——Redis的入门到进阶 结合实际场景的Redis的应用

前言 Redis是一个开源的内存数据结构存储系统&#xff0c;也被称为键值存储系统。它支持多种数据结构&#xff0c;如字符串、哈希表、列表、集合、有序集合等&#xff0c;并提供了丰富的操作命令&#xff0c;可以对这些数据结构进行快速的读写操作。Redis具有高性能、高可用性…

FreeSWITCH 1.10.10 简单图形化界面12 - 注册IMS

FreeSWITCH 1.10.10 简单图形化界面12 - 注册IMS 0、 界面预览1、IMS注册-SIP中继基本设置界面2、IMS注册-SIP中继呼叫设置3、IMS中继-代理设置界面4、IMS注册-SIP中继状态界面5、IMS注册-SIP中继详细状态界面6、IMS注册-SIP中继代拨号码优先界面 FreeSWITCH界面安装参考&#…

postgresql14-用户与角色(二)

介绍 查看 SELECT rolname FROM pg_roles;postgres是系统初始化时默认创建的角色&#xff0c;为超级管理员。 \duList of rolesRole name | Attributes | Member of ------------------------------------------------------…

RPA的尽头是超自动化?

超自动化在经过数年的发酵期后&#xff0c;已从一个科技概念崛起为市值近千亿元的新赛道&#xff0c;包括各大互联网巨头、科技公司都纷纷围绕超自动化进行战略布局。 一方面&#xff0c;是行业巨头选择纷纷跻身超自动化新赛道&#xff0c;另一方面&#xff0c;RPA行业的领军企…

软件测试(五)自动化 selenium

文章目录 自动化测试单元测试&#xff1a;单元测试&#xff1a;UI自动化 selenium工具定义特点&#xff1a;原理&#xff1a;seleniumjava环境搭建SeleniumAPI获取测试结果&#xff1a;添加等待浏览器操作键盘事件鼠标事件多层框架/窗口定位下拉框处理弹窗处理上传文件操作关闭…

怎样才能去除视频中的背景音乐,保留人声?

做视频剪辑&#xff0c;二次创作的朋友&#xff0c;需要去除视频中的背景音乐&#xff0c;保留人声&#xff1b;或者去除人声&#xff0c;保留背景音乐。如果请身边做视频的朋友帮忙&#xff0c;可有时不能沟通到位&#xff0c;完成后的效果并不是很理想&#xff0c;就很尴尬了…

26. 通过 cilium pwru了解网络包的来龙去脉

pwru是一种基于eBPF的工具,可跟踪Linux内核中的网络数据包,并具有先进的过滤功能。它允许对内核状态进行细粒度检查,以便通过调试网络连接问题来解决传统工具(如iptables TRACE或tcpdump)难以解决甚至无法解决的问题。在本文中,我将介绍pwru如何在不必事先了解所有内容的…

低代码助力软件开发

低代码开发工具正在日益变得强大&#xff0c;它正不断弥合着前后端开发之间的差距。对于后端来说&#xff0c;基于低代码平台开发应用时&#xff0c;完全不用担心前端的打包、部署等问题&#xff0c;也不用学习各种框架&#xff08;Vue、React、Angular等等&#xff09;&#x…

Mysql中的RR 隔离级别,到底有没有解决幻读问题

Mysql 中的 RR 事务隔离级别&#xff0c;在特定的情况下会出现幻读的问题。所谓的幻读&#xff0c;表示在同一个事务中的两次相同条件的查询得到的数据条数不一样。 在 RR 级别下&#xff0c;什么情况下会出现幻读 这样一种情况&#xff0c;在事务 1 里面通过 update 语句触发当…

一款简单漂亮的WPF UI - AduSkin

前言 经常会有同学会问&#xff0c;有没有好看简单的WPF UI库推荐的。今天就给大家推荐一款简单漂亮的WPF UI&#xff0c;融合多个开源框架组件&#xff1a;AduSkin。 WPF是什么&#xff1f; WPF 是一个强大的桌面应用程序框架&#xff0c;用于构建具有丰富用户界面的 Windo…

大模型基础——大模型范式

大模型背后的范式 整个预训练语言模型的使用范式&#xff1a; 对于预训练模型&#xff0c;最核心的要素是从无标注的数据中去学习&#xff0c;通过自监督的一些任务去做预训练&#xff0c;得到丰富的知识。在具体的应用中&#xff0c;会引入一些任务相关的数据&#xff0c;去调…

C++学习之多态详解

目录 多态的实现 例题 重载 重写 重定义的区别 抽象类 多态实现原理 多态的实现 C中的多态是指&#xff0c;当类之间存在层次结构&#xff0c;并且类之间是通过继承关联时&#xff0c;就会用到多态。多态意味着调用成员函数时&#xff0c;会根据调用函数的对象的类型来执…

万能DIY预约小程序源码系统 上门预约服务小程序搭建 适用于各种预约场景 自由DIY功能模块

在这个快节奏的时代&#xff0c;预约服务已经成为了我们日常生活的一部分。从看病挂号到餐厅预订&#xff0c;从美发美容到家政服务&#xff0c;预约已经深入到了各个领域。然而&#xff0c;传统的预约方式存在着许多不便&#xff0c;如电话预约、在线填写表格等&#xff0c;不…

MyBatis Generator - 快速生成 实体类 和 映射文件

目录 一、MyBatis Generator 的使用 1.1、生成类和映射文件 1.1.1、在 pom.xml 中引入依赖 1.1.2、根据 configurationFile 标签中配置的路径 创建 generatorConfig.xml 文件 1.1.3、自动生成类 和 映射文件 1.1.4、在 Insert 标签中添加获取主键值的选项 1.1.5、扫描配置…

Linux编译器-gcc/g++使用函数库

【Linux】系列文章目录 【Linux】基础常见指令&#xff1a;http://t.csdn.cn/hwLPb 【Linux】基本权限&#xff1a;http://t.csdn.cn/faFZg 【Linux】软件包管理器yum与环境开发工具vim&#xff1a;http://t.csdn.cn/LEqkm 目录 【Linux】系列文章目录 前言 一、gcc选项总…

[C++]类型转换

一、C语言中的类型转换 在C语言中&#xff0c;如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者返回值类型与 接收返回值类型不一致时&#xff0c;就需要发生类型转化。 C语言中总共有两种形式的类型转换&#xff1a;隐式类型转换和显式…

python astra相机驱动问题

报错问题&#xff1a; openni.utils.OpenNIError: (OniStatus.ONI_STATUS_ERROR, bDeviceOpen using default: no devices found, None) 解决办法&#xff1a; 1、从sdk中拷贝文件 2、修改openni源码 3、执行测试程序 from openni import openni2 import numpy as np impor…