瑞吉外卖过程

1. 软件开发流程

2. 瑞吉外卖项目概述

3. 开发环境搭建

(一)启动Navicat

启动Navicat,创建mysql连接

(二)数据库设计

  • 数据库设计:概念设计(E-R图)、逻辑设计、物理设计

    1、概念设计

  • 概念设计是数据库设计的核心环节。通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型。
  • (1)明确建模目标(模型覆盖范围)

    (2)定义实体集(自底向上标识和定义实体集)

    (3)定义联系(实体间关联关系)

    (4)建立信息模型(构造ER模型)

    (5)确定实体集属性(属性描述一个实体集的特征或性质)

    (6)对信息模型进行集成与优化(检查和消除命名不一致、结构不一致等)

  • 概念设计目前采用最广泛的是ER建模方法。将现实世界抽象为具有属性的实体及联系。1976年,Peter.Chen提出E-R模型(Entity- Relationship Model),即实体联系模型,用E-R图来描述数据库的概念模型。
  • 观点:世界是由一组称作实体的基本对象和这些对象之间的联系构成的。
  • 实体间的联系有三类:一对一联系(1:1)、一对多联系(1:n )、多对多联系(m:n)
  • E-R图示例(部分)

  • 思维导图直观呈现

2、逻辑设计

  • 将概念模型(如ER图)转化为DBMS支持的数据模型(如关系模型),并对其进行优化。

(1)用户信息表

字段名

类型

宽度

小数位数

是否主键

备注

id

bigint

20

0

主键

name

varchar

50

姓名

phone

varchar

100

手机号

sex

varchar

2

性别

id_number

varchar

18

身份证号

avatar

varchar

500

头像

status

int

11

0

状态(0:禁用;1:正常)


●log对象的四个方法

方法名

作用

info()

输出普通信息

debug()

输出调试信息

error()

输出错误信息

warn()

输出警告信息

(三)创建数据库

  • 创建项目需要的数据库 - reggie,字符集采用utf8mb4

 

 

 (四)导入数据库脚本

 

 (五)查看数据库中的表

 

二、Maven项目搭建

两种常用项目构建工具

 (一)创建Maven项目

创建Maven项目,配置项目信息

 

(二)检查检查项目编码、maven仓库配置以及jdk配置

创建完项目之后,我们应该检查项目编码、maven仓库配置以及jdk配置

安装maven软件 

配置maven的环境变量

检验maven环境变量是否配置成功

在maven配置文件添加阿里镜像源

 

检查IntelliJ IDEA里maven仓库的配置 

检查jdk配置情况

(三)添加项目相关依赖和插件

在pom.xml文件里添加相关依赖和构建插件

<?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>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.7.4</version>

<relativePath/>

</parent>

<groupId>net.hw</groupId>

<artifactId>ReggieTakeOut</artifactId>

<version>1.0-SNAPSHOT</version>

<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.2.0</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>

(四)创建应用属性文件

在resources目录下创建应用属性文件 - application.yml

 

mybatis-plus的IdType枚举类型 - 定义生成ID的类型

(五)安装lombok插件

在设置对话框里找到plugins,搜索lombok,单击绿色的Install按钮

 单击绿色的Restart IDE按钮

(六)创建启动主类

创建net.hw包,然后在包里创建ReggieTakeOutApplication

 

 

(七)拷贝静态资源和模板页面

 

 

 

 

 (八)创建MVC配置类,做静态资源映射

 

 

 

 

4. 后台登录功能开发

 

<!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>

 

 

 

 

 

 

(四)数据模型 - 雇员表代码开发 

 

 (一)创建雇员实体类

 

 

 

package net.hw.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年11月03日

*/

@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; // 对应字段 - create_time

private LocalDateTime updateTime; // 对应字段 - update_time

@TableField(fill = FieldFill.INSERT) // mybatis-plus注解,填充策略

private Long createUser; // 对应字段 - create_user

@TableField(fill = FieldFill.INSERT_UPDATE) // mybatis-plus注解,填充策略

private Long updateUser; // 对应字段 - update_user

}

(二)创建雇员映射器接口

 

 

 

package net.hw.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.hw.entity.Employee;
import org.apache.ibatis.annotations.Mapper;

/**
 * 功能:雇员映射器接口
 * 作者:华卫
 * 日期:2022年11月03日
 */
@Mapper // 交给Spring容器来管理
public interface EmployeeMapper extends BaseMapper<Employee> {

}

(三)创建雇员服务

 

package net.hw.service;

import com.baomidou.mybatisplus.extension.service.IService;

import net.hw.entity.Employee;

/**

* 功能:雇员服务接口

* 作者:华卫

* 日期:2022年11月03日

*/

public interface EmployeeService extends IService<Employee> {

}

 

package net.hw.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import net.hw.entity.Employee;

import net.hw.mapper.EmployeeMapper;

import net.hw.service.EmployeeService;

import org.springframework.stereotype.Service;

/**

* 功能:雇员服务接口实现类

* 作者:华卫

* 日期:2022年11月03日

*/

@Service // 交给Spring容器管理

public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee>

implements EmployeeService {

}

(四)创建返回结果类 

 

 

package net.hw.common;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;


@Data // Lombok注解,精简代码
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;
    }
}

 (五)创建雇员控制器

 

 

package net.hw.controller;

import lombok.extern.slf4j.Slf4j;

import net.hw.common.R;

import net.hw.entity.Employee;

import net.hw.service.EmployeeService;

import org.springframework.beans.factory.annotation.Autowired;

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;

@Slf4j // 日志注解

@RestController // 交给Spring容器管理

@RequestMapping("/employee")

public class EmployeeController {

@Autowired

private EmployeeService employeeService;

@PostMapping("/login")

public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {

return null;

}

}

1、将页面提交的密码password进行md5加密处理

2、根据页面提交的用户名username查询数据库

3、如果没有查询到则返回登录失败结果

4、密码比对,如果不一致则返回登录失败结果

5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果

6、登录成功,将员工id存入Session并返回登录成功结果

 

 

 

 

 

 

 

 

 三、功能测试

 

(三)采用调试模式启动应用 

 

 

 

(四)测试登录 - 成功

 

 

 

 

 

 

 

 

 

 

 

 

 四、哈希加密

 

# 哈希加密是单向加密

# 导入加密模块
import hashlib

# 采用md5加密算法
obj = hashlib.md5()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('md5加密字符长度:{}'.format(len(cryptotext)))

# 哈希加密是单向加密

# 导入加密模块
import hashlib

# 采用sha256加密算法
obj = hashlib.sha256()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha256加密字符长度:{}'.format(len(cryptotext)))

 

# 哈希加密是单向加密

# 导入加密模块
import hashlib

# 采用sha512加密算法
obj = hashlib.sha512()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha512加密字符长度:{}'.format(len(cryptotext)))

 

# 哈希加密是单向加密

# 导入加密模块
import hashlib

# 采用sha1加密算法
obj = hashlib.sha1()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha1加密字符长度:{}'.format(len(cryptotext)))

# 哈希加密是单向加密

# 导入加密模块
import hashlib

# 采用sha224加密算法
obj = hashlib.sha224()
# 输入待加密字符串 - 明文 [plaintext]
plaintext = input('输入待加密字符串:')
# 转换成二进制数据
obj.update(plaintext.encode('utf-8'))
# 获得密文 [cryptotext]
cryptotext = obj.hexdigest()
# 打印密文及密文长度
print('加密之后的字符串:{}'.format(cryptotext))
print('sha224加密字符长度:{}'.format(len(cryptotext)))

5. 后台退出功能开发 

 

 

 二、代码开发

 

 

 (二)编写代码

 

package net.hw.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.hw.common.R;
import net.hw.entity.Employee;
import net.hw.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;
import javax.servlet.http.HttpSession;

/**
 * 功能:雇员控制器类
 * 作者:华卫
 * 日期:2022年11月03日
 */
@Slf4j // 日志注解
@RestController // 交给Spring容器管理
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @PostMapping("/login")
    public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
        // 1. 将页面提交的密码password进行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并返回登录成功结果
        HttpSession session = request.getSession(); // 通过请求对象获取会话
        session.setAttribute("employee", emp.getId()); // 将雇员id保存到会话里
        return R.success(emp); // 返回登录成功结果
    }

    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request) {
        // 清除雇员信息
        request.getSession().removeAttribute("employee");
        // 返回成功结果
        return R.success("退出成功");
    }
}

三、功能测试

猜你喜欢

转载自blog.csdn.net/zaqaaaa/article/details/128398564