文章目录






| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 20 | 0 | 是 | 主键 |
| name | varchar | 50 | 0 | 否 | 姓名 |
| phone | varchar | 100 | 0 | 否 | 主键 |
| sex | varchar | 2 | 0 | 否 | 主键 |
| id_number | varchar | 18 | 0 | 否 | 主键 |
| avatar | varchar | 500 | 0 | 否 | 主键 |
| status | int | 11 | 0 | 否 | 状态 0:停用 1:启用 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| name | varchar | 50 | 0 | 否 | 名称 |
| image | varchar | 100 | 0 | 否 | 图片 |
| user_id | bigint | 0 | 0 | 否 | 主键 |
| dish_id | bigint | 0 | 0 | 否 | 菜品id |
| setmeal_id | bigint | 0 | 0 | 否 | 套餐id |
| dish_flavor | varchar | 50 | 0 | 否 | 口味 |
| number | int | 0 | 0 | 否 | 数量 |
| amount | decimal | 10 | 2 | 否 | 金额 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| setmeal_id | varchar | 32 | 0 | 否 | 套餐id |
| dish_id | varchar | 32 | 0 | 否 | 菜品id |
| name | varchar | 32 | 0 | 否 | 菜品名称 |
| price | decimal | 10 | 2 | 否 | 菜品原价 |
| copies | int | 0 | 0 | 否 | 份数 |
| sort | int | 0 | 0 | 否 | 排序 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| is_deleted | int | 0 | 0 | 否 | 是否删除 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| category_id | bigint | 0 | 0 | 否 | 菜品分类 |
| name | varchar | 64 | 0 | 否 | 套餐名称 |
| price | decimal | 10 | 2 | 否 | 套餐价格 |
| status | int | 18 | 0 | 否 | 状态 0:停用 1:启用 |
| code | varchar | 32 | 0 | 否 | 编码 |
| description | varchar | 512 | 0 | 否 | 描述信息 |
| image | varchar | 255 | 0 | 是 | 图片 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| is_deleted | int | 0 | 0 | 否 | 是否删除 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| name | varchar | 50 | 0 | 否 | 名字 |
| image | varchar | 100 | 0 | 否 | 图片 |
| order_id | bigint | 0 | 0 | 否 | 订单id |
| dish_id | bigint | 0 | 0 | 否 | 菜品id |
| setmeal_id | bigint | 0 | 0 | 否 | 套餐id |
| dish_flavor | varchar | 50 | 0 | 否 | 口味 |
| number | int | 0 | 0 | 否 | 数量 |
| amount | decimal | 10 | 2 | 否 | 金额 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| name | varchar | 50 | 0 | 是否 | 订单号 |
| status | int | 0 | 0 | 否 | 订单状态 1待付款,2待派送,3已派送,4已完成,5已取消 |
| user_id | bigint | 0 | 0 | 否 | 下单用户 |
| address_book_id | bigint | 0 | 0 | 否 | 地址id |
| order_time | datetime | 0 | 0 | 否 | 下单时间 |
| checkout_time | datetime | 0 | 0 | 否 | 结账时间 |
| pay_method | int | 0 | 0 | 否 | 支付方式 1微信,2支付宝 |
| amount | decimal | 10 | 2 | 否 | 实收金额 |
| remark | varchar | 100 | 0 | 否 | 备注 |
| phone | varchar | 255 | 0 | 否 | 手机号 |
| address | varchar | 255 | 0 | 否 | 地址 |
| user_name | varchar | 255 | 0 | 否 | 用户名 |
| consignee | varchar | 255 | 0 | 否 | 接收人 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| name | varchar | 32 | 0 | 否 | 姓名 |
| username | varchar | 32 | 0 | 否 | 用户名 |
| password | varchar | 64 | 0 | 否 | 密码 |
| phone | varchar | 11 | 0 | 否 | 手机号 |
| sex | varchar | 2 | 0 | 否 | 性别 |
| id_number | varchar | 18 | 0 | 否 | 身份证号 |
| status | int | 0 | 0 | 否 | 状态 0:禁用,1:正常 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| dish_id | varchar | 0 | 0 | 否 | 菜品 |
| name | varchar | 64 | 0 | 否 | 口味名称 |
| value | varchar | 500 | 0 | 否 | 口味数据 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| is_deleted | int | 0 | 0 | 否 | 是否删除 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| name | varchar | 64 | 0 | 否 | 菜品名称 |
| category_id | bigint | 0 | 0 | 否 | 菜品分类id |
| price | decimal | 10 | 2 | 否 | 菜品价格 |
| code | varchar | 64 | 0 | 否 | 商品码 |
| image | varchar | 200 | 0 | 否 | 图片 |
| description | varchar | 400 | 0 | 否 | 描述信息 |
| status | int | 0 | 0 | 否 | 0 停售 1 起售 |
| sort | int | 0 | 0 | 否 | 顺序 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| is_deleted | int | 0 | 0 | 否 | 是否删除 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| type | varchar | 0 | 0 | 否 | 类型 1 菜品分类 2 套餐分类 |
| name | varchar | 0 | 否 | 分类名称 | |
| sort | int | 0 | 0 | 否 | 顺序 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| 字段名 | 类型 | 宽度 | 小数位数 | 是否主键 | 备注 |
|---|---|---|---|---|---|
| id | bigint | 0 | 0 | 是 | 主键 |
| user_id | bigint | 0 | 0 | 是否 | 用户id |
| consignee | varchar | 50 | 0 | 否 | 收货人 |
| sex | tinyint | 0 | 0 | 否 | 性别 0 女 1 男 |
| phone | varchar | 11 | 0 | 否 | 手机号 |
| province_code | varchar | 12 | 0 | 否 | 省级区划编号 |
| province_name | varchar | 32 | 0 | 否 | 省级名称 |
| city_code | varchar | 12 | 0 | 否 | 市级区划编号 |
| city_name | varchar | 32 | 0 | 否 | 市级名称 |
| district_code | varchar | 12 | 0 | 否 | 区级区划编号 |
| district_name | varchar | 32 | 0 | 否 | 区级名称 |
| detail | varchar | 200 | 0 | 否 | 详细地址 |
| label | varchar | 100 | 0 | 否 | 标签 |
| label | tinyint | 1 | 0 | 否 | 默认 0 否 1是 |
| create_time | datetime | 0 | 0 | 否 | 创建时间 |
| update_time | datetime | 0 | 0 | 否 | 更新时间 |
| create_user | bigint | 0 | 0 | 否 | 创建人 |
| update_user | bigint | 0 | 0 | 否 | 修改人 |
| is_deleted | int | 0 | 0 | 否 | 是否删除 |














-








<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.cch</groupId>
<artifactId>ReggieTakeOut</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- <properties>-->
<!-- <maven.compiler.source>11</maven.compiler.source>-->
<!-- <maven.compiler.target>11</maven.compiler.target>-->
<!-- </properties>-->
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.14</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.4</version>
</plugin>
</plugins>
</build>
</project>

#配置服务器
server:
port: 8080
#配置spring框架
spring:
application:
name: ReggieTakeOut #应用名称
datasource: #数据源
druid: #druid数据源
driver-class-name: com.mysql.cj.jdbc.Driver #驱动程序
url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root #用户名
password: 123 #密码
mybatis-plus:
configuration:
# address_book---->AddressBook
# user_name---->userName
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志实现类
global-config: #全局配置
db-config: #数据库配置
id-type: ASSIGN_ID #id-type: auto #数据ID自增


package net.cch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 功能: 项目启动类
* 作者: 陈春宏
* 时间: 2022/10/20 11:16
*/
@Slf4j
@SpringBootApplication
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class,args);
log.info("项目启动成功!");
}
}

查看项目启动页面

log对象的五个方法
| 方法名 | 作用 |
|---|---|
| info() | 输出普通信息 |
| debug() | 输出调试信息 |
| error() | 输出错误信息 |
| warn() | 输出调试信息 |





package net.cch.reggie.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* 功能: 静态资源映射
* 作者: 陈春宏
* 时间: 2022/10/26 21:23
*/
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry){
log.info("开始启动静态资源!");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
}







<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>瑞吉外卖管理端</title>
<link rel="shortcut icon" href="../../favicon.ico">
<!-- 引入样式 -->
<link rel="stylesheet" href="../../plugins/element-ui/index.css" />
<link rel="stylesheet" href="../../styles/common.css">
<link rel="stylesheet" href="../../styles/login.css">
<link rel="stylesheet" href="../../styles/icon/iconfont.css" />
<style>
.body{
min-width: 1366px;
}
</style>
</head>
<body>
<div class="login" id="login-app">
<div class="login-box">
<img src="../../images/login/login-l.png" alt="">
<div class="login-form">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" >
<div class="login-form-title">
<img src="../../images/login/logo.png" style="width:139px;height:42px;" alt="" />
</div>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号" maxlength="20"
prefix-icon="iconfont icon-user" />
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" placeholder="密码" prefix-icon="iconfont icon-lock" maxlength="20"
@keyup.enter.native="handleLogin" />
</el-form-item>
<el-form-item style="width:100%;">
<el-button :loading="loading" class="login-btn" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin">
<span v-if="!loading">登录</span>
<span v-else>登录中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="../../plugins/vue/vue.js"></script>
<!-- 引入组件库 -->
<script src="../../plugins/element-ui/index.js"></script>
<!-- 引入axios -->
<script src="../../plugins/axios/axios.min.js"></script>
<script src="../../js/request.js"></script>
<script src="../../js/validate.js"></script>
<script src="../../api/login.js"></script>
<script>
new Vue({
el: '#login-app',
data() {
return {
loginForm:{
username: 'admin',
password: '123456'
},
loading: false
}
},
computed: {
loginRules() {
const validateUsername = (rule, value, callback) => {
if (value.length < 1 ) {
callback(new Error('请输入用户名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码必须在6位以上'))
} else {
callback()
}
}
return {
'username': [{ 'validator': validateUsername, 'trigger': 'blur' }],
'password': [{ 'validator': validatePassword, 'trigger': 'blur' }]
}
}
},
created() {
},
methods: {
async handleLogin() {
this.$refs.loginForm.validate(async (valid) => {
if (valid) {
this.loading = true
let res = await loginApi(this.loginForm)
if (String(res.code) === '1') {
localStorage.setItem('userInfo',JSON.stringify(res.data))
window.location.href= '/backend/index.html'
} else {
this.$message.error(res.msg)
this.loading = false
}
}
})
}
}
})
</script>
</body>
</html>



res变量里,里面有三个数据:res.code、res.data、res.msg,这就要求后端处理函数返回JSON数据必须要包含这三项内容
admin与123456(MD5加密之后就成了e10adc3949ba59abbe56e057f20f883e)

F12键进入浏览器的调试模式
http://localhost:8080/employee/login@RestController // 交给Spring容器管理
@RequestMapping("/employee")
public class EmployeeController {
@PostMapping("/login")
public R<Employee> login(HttpRequest request, @RequestBody Employee employee) {
return null;
}
}


| 序号 | 实体属性名 | 关系字段名 |
|---|---|---|
| 1 | id | id |
| 2 | name | name |
| 3 | username | username |
| 4 | password | password |
| 5 | phone | phone |
| 6 | sex | sex |
| 7 | idNumber | id_number |
| 8 | status | satus |
| 9 | createTime | create_time |
| 10 | status | status |
| 11 | createUser | create_user |
| 12 | updateUser | update_user |
entity子包在里面创建雇员实体类 - Employee
package net.cch.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 功能: 员工实体类
* 作者: 陈春宏
* 时间: 2022/10/27 11:16
*/
@Data //Lombok注解,注在类上,提供类的get、set、equals、hashCode、CanEqual、toString方法
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String name;
private String password;
private String phone;
private String sex;
private String idNumber; //对应id_number
private Integer status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT) //mybatis-plus注解,填充策略
private Long createUser;//对应字段 -create_user
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;//对应字段 -update_user
}


package net.cch.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.cch.reggie.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
/**
* 功能:EmployeeMapper接口
* 作者: 陈春宏
* 时间: 2022/10/27 21:20
*/
@Mapper //交给spring容器来管理
public interface EmployeeMapper extends BaseMapper<Employee> {
}
service子包 ,在service包里创建雇员服务接口 - EmployeeService
IService<Employee>接口package net.cch.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import net.cch.reggie.entity.Employee;
/**
* 功能: EmployeeService接口
* 作者: 陈春宏
* 时间: 2022/10/27 21:21
*/
public interface EmployeeService extends IService<Employee> {
}
在net.cch.service包里创建impl子包,在子包里创建雇员服务接口实体类 - EmployeeServiceImpl

package net.cch.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.cch.reggie.entity.Employee;
import net.cch.reggie.mapper.EmployeeMapper;
import net.cch.reggie.service.EmployeeService;
import org.springframework.stereotype.Service;
/**
* 功能: EmployeeService实现类
* 作者: 陈春宏
* 时间: 2022/10/27 21:26
*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
}
R
package net.cch.reggie.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* 通用返回结果,服务器响应的数据最终会封装成此对象
* @param <T>
*/
@Data
public class R<T> {
private Integer code; //编码:1成功,0和其它数字为失败
private String msg; //错误信息
private T data; //数据
private Map map = new HashMap(); //动态数据
public static <T> R<T> success(T object) {
R<T> r = new R<T>();
r.data = object;
r.code = 1;
return r;
}
public static <T> R<T> error(String msg) {
R r = new R();
r.msg = msg;
r.code = 0;
return r;
}
public R<T> add(String key, Object value) {
this.map.put(key, value);
return this;
}
}
EmployeeController
package net.cch.reggie.controller;
import
import lombok.extern.slf4j.Slf4j;
import net.cch.reggie.common.R;
import net.cch.reggie.entity.Employee;
import net.cch.reggie.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* 功能: 员工管理控制层
* 作者: 陈春宏
* 时间: 2022/10/27 21:28
*/
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
return null;
}
}
1、将页面提交的密码password进行md5加密处理
2、根据页面提交的用户名username查询数据库
3、如果没有查询到则返回登录失败结果
4、密码比对,如果不一致则返回登录失败结果
5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
6、登录成功,将员工id存入Session并返回登录成功结果


//1、将页面提交的密码进行md5加密处理
String password = employee.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());


//2、根据页面提交的用户名username查询数据库
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);

//3、如果没有查询到则返回登录失败的结果
if(emp == null){
return R.error("登录失败[用户名错误]");
}

//4、密码比对,如果不一致则返回密码错误的结果
if(!emp.getPassword().equals(password)){
return R.error("登录失败[密码错误]");
}

//5、查看员工状态,如果为禁用状态,则返回员工已禁用结果
if(emp.getStatus() == 0){
return R.error("账号已禁用!");
}

//6、登录成功,将员工id存入到Session并返回登录结果
request.getSession().setAttribute("Employee",emp.getId());
return R.success(emp);
resources/backend/js/request.js文件里设置超时为1000000毫秒,便于后面做断点调试
EmployeeController里设置断点

浏览器访问 http://localhost:8080/backend/page/login/login.html

按F12键,打开开发者工具

使用用户名和密码登录,admin : 123456 ,单击登录按钮

查看断点调试信息

单击[Step Over] 按钮3次,判断用户是否错误

单击【Step Over】按钮,判断密码是否错误

单击【Step Over】按钮,判断雇员状态是否已禁用

单击【Step Over】按钮3次,返回登录成功结果
此时,查看登录页面,登录成功,会本地存储用户信息
http://localhost:8080/backend/page/login/login.html



employee表的status字段改为0








/**
* 员工退出
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前员工的id
request.getSession().removeAttribute("employee");
return null;
}

/**
* 员工退出
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前员工的id
request.getSession().removeAttribute("employee");
return R.success("退出成功");
}




filter子包,在filter子包里创建LoginCheckFilter过滤器
package net.cch.reggie.filter;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 陈春宏
* @function 检查用户是否已经完成登录
* @create 2022/11/22 23:09
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
log.info("拦截到请求:{}",request.getRequestURI());
filterChain.doFilter(request,response);
}
}
package net.cch.reggie;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* 功能: 项目启动类
* 作者: 陈春宏
* 时间: 2022/10/20 11:16
*/
@Slf4j
@SpringBootApplication
@ServletComponentScan
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class,args);
log.info("项目启动成功!");
}
}



/backend/index.html
1.获取本次请求的URL
2.判断本次请求是否需要处理
3.如果不需要处理,则直接放行
4.判断登录状态,如果已经登录,则直接放行
5.如果未登录则返回未登录的结果

package net.cch.reggie.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 陈春宏
* @function 检查用户是否已经完成登录
* @create 2022/11/22 23:09
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1.获取本次请求的URL
String requestURI = request.getRequestURI();
//定义不需要请求的URL
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
log.info("拦截到请求:{}", request.getRequestURI());
filterChain.doFilter(request, response);
}
}

package net.cch.reggie.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 陈春宏
* @function 检查用户是否已经完成登录
* @create 2022/11/22 23:09
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1.获取本次请求的URL
String requestURI = request.getRequestURI();
//定义不需要请求的URL
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2.判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//3.如果不需要处理,则直接放行
//4.判断登录状态,如果已经登录,则直接放行
//5.如果未登录则返回未登录的结果
log.info("拦截到请求:{}", request.getRequestURI());
filterChain.doFilter(request, response);
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
//封装一个check方法来判断
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if (match) {
return true;
}
}
return false;
}
}

//3.如果不需要处理,则直接放行
if (check) {
filterChain.doFilter(request, response);//放行
return;
}
//4.判断登录状态,如果已经登录,则直接放行
if(request.getSession().getAttribute("employee") != null){
filterChain.doFilter(request,response);
return;
}


package net.cch.reggie.filter;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import net.cch.reggie.common.R;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 陈春宏
* @function 检查用户是否已经完成登录
* @create 2022/11/22 23:09
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1.获取本次请求的URL
String requestURI = request.getRequestURI();
//定义不需要请求的URL
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2.判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//3.如果不需要处理,则直接放行
if (check) {
filterChain.doFilter(request, response);//放行
return;
}
//4.判断登录状态,如果已经登录,则直接放行
if(request.getSession().getAttribute("employee") != null){
filterChain.doFilter(request,response);
return;
}
//5.如果未登录则返回未登录的结果,通过输出䄦的方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
// log.info("拦截到请求:{}", request.getRequestURI());
// filterChain.doFilter(request, response);
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if (match) {
return true;
}
}
return false;
}
}

@Slf4j
package net.cch.reggie.filter;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import net.cch.reggie.common.R;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 陈春宏
* @function 检查用户是否已经完成登录
* @create 2022/11/22 23:09
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1.获取本次请求的URL
String requestURI = request.getRequestURI();
log.info("拦截到请求:{}",requestURI);
//定义不需要请求的URL
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2.判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//3.如果不需要处理,则直接放行
if (check) {
log.info("本次请求{}不需要处理",requestURI);
filterChain.doFilter(request, response);//放行
return;
}
//4.判断登录状态,如果已经登录,则直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("用户未登录");
//5.如果未登录则返回未登录的结果,通过输出䄦的方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if (match) {
return true;
}
}
return false;
}
}



[添加员工]按钮跳转到新增页面,如下图所示:


1、页面发送Ajax请求,将新增员工页面中输入的数据以json的形式提交到服务端
2、服务端Controller接收页面提交的数据并调研Service将数据进行保存
3、Service调用Mapper操做数据库,保存数据
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正
我一直在尝试使用nanoc用于生成静态网站。我需要组织一个复杂的排列页面,我想让我的内容保持干燥。包含或合并的概念在nanoc系统中如何运作?我已阅读文档,但似乎找不到我想要的内容。例如:我如何获取两个部分内容项并将它们合并到一个新的内容项中。在staticmatic您可以在您的页面中执行以下操作。=partial('partials/shared/navigation')类似的约定在nanoc中如何运作? 最佳答案 这里是nanoc的作者。在nanoc中,部分是布局。因此,您可以拥有layouts/partials/shared/
我安装了ruby、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom
我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每