深圳网站建设外包公司排名,php做网站的支付功能,杭州有哪些大公司,设计wordpress页面模板下载文章目录 1. 软件开发介绍1.1 软件开发流程1.2 角色分工1.3 软件环境1.4 系统的分类 2. 尚品甄选项目介绍2.1 电商基本概念2.1.1 电商简介2.1.2 电商模式B2BB2CB2B2CC2BC2CO2O 2.2 业务功能介绍2.3 系统架构介绍2.4 前后端分离开发 3. 前端工程搭建3.1 Element-Admin简介3.2 El… 文章目录 1. 软件开发介绍1.1 软件开发流程1.2 角色分工1.3 软件环境1.4 系统的分类 2. 尚品甄选项目介绍2.1 电商基本概念2.1.1 电商简介2.1.2 电商模式B2BB2CB2B2CC2BC2CO2O  2.2 业务功能介绍2.3 系统架构介绍2.4 前后端分离开发 3. 前端工程搭建3.1 Element-Admin简介3.2 Element-Admin部署3.3 项目目录介绍3.4 修改项目基本信息3.4.1 修改项目默认图标3.4.1.1 修改标题图标3.4.1.2 修改侧边栏图标 3.4.2 修改标题3.4.2.1 标题栏标题3.4.2.2 侧边栏标题   4. 登录功能说明4.1 登录流程介绍4.2 模板源码分析4.2.1 登录请求过程登录页面login.jsrequest.jsmock 4.2.2 响应结果分析app.jsstorage.js  4.3 总结 5. 后端项目搭建5.1 数据库环境准备5.1.1 安装Mysql数据库5.1.2 初始化数据库5.1.3 表结构介绍5.1.4 部署Redis 5.2 项目结构说明5.3 模块依赖说明5.4 项目模块创建5.4.1 spzx-parent5.4.2 spzx-common5.4.3 common-util5.4.4 spzx-model5.4.5 common-service5.4.6 spzx-manager 5.5 统一结果实体类5.5.1 响应结果分析5.5.2 Result实体类 5.6 登录接口开发5.6.1 基础环境配置5.6.2 SysUser5.6.3 LoginDto5.6.4 LoginVo5.6.5 IndexController5.6.6 SysUserService5.6.7 SysUserMapper5.6.8 SysUserMapper.xml 5.7 Postman测试  1. 软件开发介绍 
作为一名软件开发工程师,我们需要了解在软件开发过程中的开发流程 以及软件开发过程中涉及到的岗位角色角色的分工、职责 并了解软件开发中涉及到的三种软件环境。那么本章节我们将从软件开发流程、角色分工、软件环境 三个方面来整体上介绍一下软件开发。 
1.1 软件开发流程 
软件的开发流程如下所示 第1阶段: 需求分析 完成产品原型、需求规格说明书的编写。 
产品原型: 一般是通过网页(html)的形式展示当前的页面展示什么样的数据, 页面的布局是什么样子的点击某个菜单打开什么页面点击某个按钮出现什么效果都可以通过产品原型看到。 可以通过墨刀网查看产品原型样例https://modao.cc/community 
需求规格说明书: 一般来说就是使用 Word 文档来描述当前项目有哪些功能每一项功能的需求及业务流程是什么样的都会在文档中描述。 第2阶段: 设计 设计的内容包含 产品设计、UI界面设计、概要设计、详细设计、数据库设计。 
在设计阶段会出具相关的UI界面、及相关的设计文档。比如数据库设计需要设计当前项目中涉及到哪些数据库每一个数据库里面包含哪些表这些表结构之间的关系是什么样的表结构中包含哪些字段字段类型都会在文档中描述清楚。 第3阶段: 编码 编写项目代码、并完成单元测试。 
作为软件开发工程师我们主要的工作就是在该阶段 对分配给我们的模块功能进行编码实现。编码实现完毕后进行单元测试单元测试通过后再进入到下一阶段。 第4阶段: 测试 在该阶段中主要由测试人员, 对部署在测试环境的项目进行功能测试, 并出具测试报告。 第5阶段: 上线运维 在项目上线之前 会由运维人员准备服务器上的软件环境安装、配置 配置完毕后 再将我们开发好的项目部署在服务器上运行。 
我们作为软件开发工程师 我们主要的任务是在编码阶段 但是在一些小的项目组当中 也会涉及到数据库的设计、测试等方面的工作。 
1.2 角色分工 
学习了软件开发的流程之后 我们还有必要了解一下在整个软件开发过程中涉及到的岗位角色以及各个角色的职责分工。 如下表所示 
岗位/角色职责/分工项目经理对整个项目负责任务分配、把控进度产品经理进行需求调研输出需求调研文档、产品原型等UI设计师根据产品原型输出界面效果图架构师项目整体架构设计、技术选型等开发工程师功能代码实现测试工程师编写测试用例输出测试报告运维工程师软件环境搭建、项目上线 
上述我们讲解的角色分工, 是在一个项目组中比较标准的角色分工, 但是在实际的项目中, 有一些项目组由于人员配置紧张, 可能并没有专门的架构师或测试人员, 这个时候可能需要有项目经理或者程序员兼任。 
1.3 软件环境 
在我们日常的软件开发中会涉及到软件开发中的三套环境 那么这三套环境分别是: 开发环境、测试环境、生产环境。 接下来我们分别介绍一下这三套环境的作用和特点。 开发环境(development) 我们作为软件开发人员在开发阶段使用的环境就是开发环境一般外部用户无法访问。 
比如我们在开发中使用的MySQL数据库和其他的一些常用软件我们可以安装在本地 也可以安装在一台专门的服务器中 这些应用软件仅仅在软件开发过程中使用 项目测试、上线时我们不会使用这套环境了这个环境就是开发环境。 测试环境(testing) 当软件开发工程师将项目的功能模块开发完毕并且单元测试通过后就需要将项目部署到测试服务器上让测试人员对项目进行测试。那这台测试服务器就是专门给测试人员使用的环境 也就是测试环境用于项目测试一般外部用户无法访问。 生产环境(production) 当项目开发完毕并且由测试人员测试通过之后就可以上线项目将项目部署到线上环境并正式对外提供服务这个线上环境也称之为生产环境。 
准生产环境: 对于有的公司来说项目功能开发好, 并测试通过以后并不是直接就上生产环境。为了保证我们开发的项目在上线之后能够完全满足要求就需要把项目部署在真实的环境中, 测试一下是否完全符合要求啊这时候就诞生了准生产环境你可以把他当做生产环境的克隆体准生产环境的服务器配置, 安装的应用软件(JDK、Tomcat、数据库、中间件 …) 的版本都一样这种环境也称为 “仿真环境”。 
注意由于项目的性质和类型不同有的项目可能不需要这个环境 
1.4 系统的分类 
一个项目所包含的系统大致是为了两种 
1、后台系统给公司的业务人员进行使用 
2、前台系统给普通用户所使用 
而每一个系统又可以分为前端和后端 
前端主要负责进行数据的展示包含的技术html、cssJavaScript、vue、element plus、node.js 、vite… 
后端主要负责业务逻辑的处理包含的技术Java 
2. 尚品甄选项目介绍 
尚品甄选是一个电子B2C的电子商务平台。 
2.1 电商基本概念 
2.1.1 电商简介 
电商是指利用互联网技术将商品信息、交易、支付等业务进行电子化处理实现线上购买和线下物流配送的商业活动。它将传统的商业活动转化为了电子商务活动使得消费者可以足不出户地浏览、挑选商品并通过电子支付方式完成付款最终实现商品的快速配送。 
常见的电商平台京东、天猫、阿里巴巴、咸鱼、淘宝… 
2.1.2 电商模式 
电商模式是指电子商务平台和线上商家之间进行业务合作的方式主要包括以下几种 
B2B 
B2B  Business to Business是指进行电子商务交易的供需双方都是商家或企业、公司她他们使用了互联网的技术或各种商务网络平台 
完成商务交易的过程。电子商务是现代 B2B marketing的一种具体主要的表现形式。 
案例阿里巴巴1688 
B2C 
B2C是Business-to-Customer的缩写而其中文简称为“商对客”。“商对客”是电子商务的一种模式也就是通常说的直接面向消费者销售产品和服务商 
业零售模式。这种形式的电子商务一般以网络零售业为主主要借助于互联网开展在线销售活动。B2C即企业通过互联网为消费者提供一个新型的购物环境——网上商店消费者通过网络在网上购物、网上支付等消费行为。 
案例唯品会、乐蜂网、京东 
B2B2C 
B2B2C是一种电子商务类型的网络购物商业模式B是BUSINESS的简称C是CUSTOMER的简称第一个B指的是商品或服务的供应商第二个B指的是从事电子商务的企业C则是表示消费者。 
案例淘宝 
C2B 
C2BConsumer to Business即消费者到企业是互联网经济时代新的商业模式。这一模式改变了原有生产者企业和机构和消费者的关系是一种消费者贡献价值Create Value 企业和机构消费价值Consume Value。 
C2B模式和我们熟知的供需模式DSM, Demand SupplyModel恰恰相反真正的C2B 应该先有消费者需求产生而后有企业生产即先有消费者提出需求后有生产企业按需求组织生产。通常情况为消费者根据自身需求定制产品和价格或主动参与产品设计、生产和定价产品、价格等彰显消费者的个性化需求生产企业进行定制化生产。 
案例猪八戒 
C2C 
C2C即 CustomerConsumer to CustomerConsumer意思就是消费者个人间的电子商务行为。比如一个消费者有一台电脑通过网络进行交易把它出售给另外一个消费者此种交易类型就称为C2C电子商务。 
案例闲鱼、转转 
O2O 
O2O即Online To Offline在线离线/线上到线下是指将线下的商务机会与互联网结合让互联网成为线下交易的平台这个概念最早来源于美国。O2O的概念非常广泛既可涉及到线上又可涉及到线下,可以通称为O2O。主流商业管理课程均对O2O这种新型的商业模式有所介绍及关注。 
案例美团、饿了吗、猫眼 
2.2 业务功能介绍 
后台系统功能:(用户登录、系统管理员列表、角色管理、权限规则管理、商品管理、商品分类、商品规格、…) 
线上地址http://spzx-admin.atguigu.cn/ 
账号/密码admin/111111 
前台系统功能: (首页商品分类查询、分类模块分类查询、根据分类查询商品数据、登录功能、用户收货地址管理、购物车模块、订单模块…) 
线上地址http://spzx.atguigu.cn/ 
2.3 系统架构介绍 
后台管理系统后端采用的是单体架构【就是把所有的功能写在同一个项目中】如下所示  
前台系统的后端采用的是微服务系统架构【一个模块就是一个独立服务】如下图所示  
注意关于微服务系统架构后面会详细讲解这里简单了解一下 
项目使用技术栈(Spring Boot、Spring Cloud Alibaba、Minio、Redis、Docker、Nginx、MySQL、阿里云短信平台…) 
2.4 前后端分离开发 
尚品甄选采用的开发模式是前后端分离的开发模式。前后端分离开发是一种软件系统的设计和开发模式将用户界面、逻辑处理和数据层从一个整体应用程序中分离出来在前端和后端之间建立规范化接口使得前端和后端可以独立开发、测试、部署和升级。 
如下图所示  
注意 
1、接口就是一个http的请求地址接口就规定了请求方式、请求路径、请求参数、响应结果 
2、在当前的前后端分离开发中前端和后端传输的数据是json格式 
3. 前端工程搭建 
3.1 Element-Admin简介 
关于后端管理系统的前端工程我们没有必要从0~1去开发可以直接基于Vue3-Element-Admin项目模板进行二次开发在Vue3-Element-Admin已经提供了一些基础性的功能【登录首页布局、左侧导航菜单…】。 
官网地址https://huzhushan.gitee.io/vue3-element-admin/v1/guide/ 
源码仓库地址https://github.com/huzhushan/vue3-element-admin.git 
3.2 Element-Admin部署 
步骤如下将课件资料/day02目录下的vue3-element-admin.rar解压缩到前端工作空间下并通过VSCode打开项目  
# 在项目目录下配置淘宝镜像
npm install -g --registryhttps://registry.npm.taobao.org
# 启动服务
npm start修改页面项目bug 
# src目录下permission.js文件
# 原代码import { TOKEN } from /store/modules/app
# 更改为如下代码
import { TOKEN } from /pinia/modules/app3.3 项目目录介绍 
部署好的前端工程的核心目录结构如下所示 
mock					// 用于测试模拟后端接口地址
public					// 存储公共的静态资源图片
src						// 源代码目录非常重要| api				// 提供用于请求后端接口的js文件| assets			// 存储静态资源图片、css| components		// 存储公共组件,可重用的一些组件| directive			// 存储自定义的一些指令| hooks				// 存储自定义的钩子函数| i18n				// 存储用于国际化的js文件| layout			// 存储首页布局组件| pinia				// 用于进行全局状态管理| router			// 存储用于进行路由的js文件| utils				// 存储工具类的js文件| views				// 和路由绑定的组件| App.vue			// 根组件| default-settings.js // 默认设置的js文件| error-log.js		// 错误日志js文件| global-components.js // 全局组件的js文件| main.js			// 入口js文件(非常重要)| permission.js		// 权限相关的js文件(路由前置守卫、路由后置守卫)
vite.config.js			// vite的配置文件可以在该配置文件中配置前端工程的端口号3.4 修改项目基本信息 
3.4.1 修改项目默认图标 
拷贝课件 资料/day02/favicon.ico 到前端项目public下 3.4.1.1 修改标题图标 
修改index.html link标签图标地址 
link relicon href/public/favicon.ico /3.4.1.2 修改侧边栏图标 
修改src/layout/components/sidebar/Logo.vue页面的图标地址 
img classlogo src/public/favicon.ico clickgoHome /3.4.2 修改标题 
3.4.2.1 标题栏标题 
参考下图修改 src/layout//pinia/modules/app.js 中的title 3.4.2.2 侧边栏标题 
修改src/layout/components/sidebar/Logo.vue中的标题 4. 登录功能说明 
我们借助登录功能来了解前后端分离项目整合并对后端项目进行统一环境配置。 
在Element-Admin项目模板中已经将登陆的功能实现了本小章节就来给大家介绍一下前后端分离项目中如何实现登录功能。 
4.1 登录流程介绍 
前后端分离开发的登录如下所示 注意 
1、令牌登录成功以后系统给当前登录用户分配的唯一标识 
2、前端前端系统获取到后端返回的令牌的时候就会把令牌存储起来 
验证用户是否登录的流程后端系统中所提供的一些请求地址(接口)中有一些是必须要求用户登录才可以访问。 Vue3-Element-Admin的登录功能实现当登录成功以后会将登录成功以后返回的数据存储到pinia的useApp模块中同时会把数据存储到localStorage中。 4.2 模板源码分析 
4.2.1 登录请求过程 
登录页面 
登录页面src/views/login/index.vue 
script
import {defineComponent,getCurrentInstance,reactive,toRefs,ref,computed,watch,
} from vue
import { Login } from /api/login   // 导入登录发送请求所需要的js文件
import { useRouter, useRoute } from vue-router		// 导入路由组件
import { useApp } from /pinia/modules/app	// 从pinia中导入useApp模块
export default defineComponent({name: login,setup() {const route  useRoute()	// 获取当前路由对象const state  reactive({model: {  // 登录表单默认的用户名和密码userName: admin,password: 123456,},submit: ()  { // 登录方法state.loginForm.validate(async valid  {if (valid) {  // 校验数据的合法性合法执行下述代码state.loading  trueconst { code, data, message }  await Login(state.model)  // 调用登录方法if (code  200) {  // 返回的状态码如果为200给出登录成功提示信息ctx.$message.success({message: ctx.$t(login.loginsuccess),	// 读取i18n中locals/zh-cn/login.js中的内容duration: 1000,})const targetPath  decodeURIComponent(route.query.redirect)	if (targetPath.startsWith(http)) {// 如果是一个url地址window.location.href  targetPath} else if (targetPath.startsWith(/)) {// 如果是内部路由地址router.push(targetPath)} else {router.push(/)  // 登录成功以后进行路由 , 查看src/router/index.js的路由配置}useApp().initToken(data)  // 保存后端返回给前端的数据} else {  // 登录失败给出错误提示信息ctx.$message.error(message)}state.loading  false}})},})return {...toRefs(state),}},
})
/scriptlogin.js 
/api/login.js文件源码分析 
import request from /utils/request		// 导入utils中的request.js// 登录接口
export const Login  data  {return request({url: /api/login,		// 请求的后端地址可以可以将其更改为真实的后端地址method: post,			// 请求方式data,					// 请求的数据})
}request.js 
/utils/request.js文件 
import axios from axios		// 导入axios
const service  axios.create({	// 创建axios对象baseURL: /,					// 后期需要将这个地址更改为后端真实服务地址timeout: 10000,withCredentials: true,        //请求时携带cookie
})
export default service			// 导出axios对象mock 
当前登录请求时通过mock模拟的后端地址请求的是mock/login.js模拟的后端接口源码如下所示 
export default [{url: /api/login,method: post,timeout: 1000,statusCode: 200,response: ({ body })  {// 响应内容return body.password  123456? {code: 200,message: 登录成功,data: {token: word(50, 100), // word()是mockjs的语法refresh_token: word(50, 100), // refresh_token是用来重新生成token的},}: {code: 400,message: 密码错误请输入123456,}},},
]4.2.2 响应结果分析 
app.js 
登录请求成功以后那么此时会调用useApp().initToken(data) 将后端返回的数据保存起来。useApp导入的是pinia/modules/app.js文件核心源码如 
下所示 
import { defineStore } from pinia
import { getItem, setItem, removeItem } from /utils/storage //getItem和setItem是封装的操作localStorage的方法
import { useAccount } from ./account	// pinia的account模块
import { useTags } from ./tags		// pinia的标签栏模块
import { useMenus } from ./menu		// pinia的menu模块
export const TOKEN  VEA-TOKEN
const COLLAPSE  VEA-COLLAPSEexport const useApp  defineStore(app, {  state: ()  ({		// 当前pinia模块中所存储的状态数据title: Vue3 Element Admin,authorization: getItem(TOKEN),sidebar: {collapse: getItem(COLLAPSE),},device: desktop,}),actions: {  // pinia中定义的方法用来操作pinia中所存储的数据setToken(data) {this.authorization  data		// 把后端返回的数据存到useApp模块的authorization变量中setItem(TOKEN, data)			// 保存到localStorage},initToken(data) {	// 初始化token的方法this.clearToken()	// 清空tokenthis.setToken(data) // 设置token数据},clearToken() {this.authorization  	// 将authorization数据设置为空字符串removeItem(TOKEN)			// 删除localStorage中的tokenuseAccount().clearUserinfo()	// 清除pinia的account模块中存储的用户信息useTags().clearAllTags()		// 清除pinia的useTags模块中存储的标签栏数据useMenus().setMenus([])		// 清空pinia的menu模块中存储的菜单数据},},
}) 
storage.js 
setItem方法和removeItem方法都是来自于/utils/storage.js中的源码如下所示 
export const setItem  (name, value)  {		// 设置数据到localStorage中if (typeof value  object) {	// 判断数据的类型是否为对象类型value  JSON.stringify(value)	// 将对象转换成json字符串}window.localStorage.setItem(name, value)	// 存储数据到localStorage中
}export const removeItem  name  {		// 从localStorage中删除数据window.localStorage.removeItem(name)
}4.3 总结 
综合上面的登录流程和源码分析 
前端以post方式提交登录请求访问接口/api/login后端需要返回json字符串 {token:xxx,refresh_token:xxxx}代表登录成功的状态。 
前端将登录成功的状态缓存到localStorage中。 
后续再获取localStorage中的token值访问接口/api/userinfo获取用户登录信息回显后端返回用户信息的json字符串如下:{id: 1, name: zhangsan , avatar: xx} 
5. 后端项目搭建 
本章节通过开发尚品甄选项目中的登录接口搭建后端环境。 
本次项目开发的时候所使用的软件环境版本如下所示 
软件名称版本说明jdkjdk17spring boot3.0.5mybaits-spring-boot-starter3.0.1mysql8.0.29idea2022.2.2 
5.1 数据库环境准备 
5.1.1 安装Mysql数据库 
本地安装mysql数据库使用的是docker安装对应的步骤如下所示 
1、准备一个虚拟机centos7.x配置固定ip地址 
# 编辑网卡文件
vim /etc/sysconfig/network-scripts/ifcfg-ens33# 按照一下配置配置网卡信息其余不变
ONBOOTyes
IPADDR192.168.136.142
GATEWAY192.168.136.2
NETMASK255.255.255.0
BOOTPROTOstatic
DNS1114.114.114.114
DNS28.8.8.8
# 重启网卡服务
systemctl restart network# 检测是否可以连接外网
ping www.baidu.com注意如果不能连接外网可以尝试添加一块新的虚拟网卡 
2、部署mysql 
# 拉取镜像
docker pull mysql:8# 创建容器
docker run -d --name spzx-mysql -p 3306:3306 -v mysql_data:/var/lib/mysql -v mysql_conf:/etc/mysql --restartalways --privilegedtrue -e MYSQL_ROOT_PASSWORD123456 mysql:8 
5.1.2 初始化数据库 
具体步骤如下所示 
1、连接mysql创建数据库db_spzx 
2、导入课程资料中的db_spzx.sql文件 
5.1.3 表结构介绍 
登录功能相关的表sys_user【后台管理系统用户表】 
CREATE TABLE sys_user (id bigint NOT NULL AUTO_INCREMENT COMMENT 会员id,username varchar(20) NOT NULL DEFAULT  COMMENT 用户名,password varchar(32) NOT NULL DEFAULT  COMMENT 密码,name varchar(50) DEFAULT NULL COMMENT 姓名,phone varchar(11) DEFAULT NULL COMMENT 手机,avatar varchar(255) DEFAULT NULL COMMENT 头像,description varchar(255) DEFAULT NULL COMMENT 描述,status tinyint NOT NULL DEFAULT 1 COMMENT 状态1正常 0停用,create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,is_deleted tinyint NOT NULL DEFAULT 0 COMMENT 删除标记0:未删除 1:已删除,PRIMARY KEY (id),UNIQUE KEY idx_username (username)
) ENGINEInnoDB AUTO_INCREMENT6 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT用户表;5.1.4 部署Redis 
使用docker部署Redis具体的操作如下所示 
# 拉取镜像
docker pull redis# 创建容器
docker run -d -p 6379:6379 --restartalways \
-v spzx-redis-config:/etc/redis/config \
-v spzx-redis-data:/data \
--name spzx-redis redis \
redis-server /etc/redis/config/redis.conf# 在宿主机的 /var/lib/docker/volumes/redis-config/_data/目录下创建一个redis的配置文件redis.conf
vim /var/lib/docker/volumes/spzx-redis-config/_data/redis.conf
#内容如下所示
#开启持久化:后面的购物车数据会存到redis中 所以需要保证redis数据的可靠性
appendonly yes
port 6379
requirepass 123456
bind 0.0.0.0安装课件资料中的redis图形化工具redis-desktop-manager 
连接redis测试 
5.2 项目结构说明 
尚品甄选的项目结构如下所示 模块说明 
spzx-parent 尚品甄选项目的父工程进行项目依赖的统一管理打包方式为pom 
spzx-common: 尚品甄选项目公共模块的管理模块父工程为spzx-parrnt 
common-util: 工具类模块父工程为spzx-common 
common-service公共服务模块父工程为spzx-common 
spzx-model: 尚品甄选实体类模块 
spzx-manager 尚品甄选项目后台管理系统的后端服务 
一个项目中所涉及到的实体类往往有三种 
1、封装请求参数的实体类这种实体类在定义的时候往往会携带到dto【数据传输对象Data Transfer Object】字样会定义在dto包中 
2、与数据库对应的实体类这种实体类往往和数据表名称保证一致会定义在domain、entity、pojo包中 
3、封装响应结果的实体类这种实体类在定义的时候往往会携带到vo【视图对象View Object】字样会定义在vo包中 
5.3 模块依赖说明 
模块之间的依赖关系如下图所示 common-service会依赖common-util、spzx-common 
spzx-manager会依赖common-service 
5.4 项目模块创建 
5.4.1 spzx-parent 
创建一个maven项目导入如下依赖 
!-- 指定父工程 --
parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.0.5/version
/parent
packagingpom/packaging
propertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmysql.verison8.0.29/mysql.verisonfastjson.version1.2.29/fastjson.versionjodatime.version2.10.1/jodatime.versionlombok.version1.18.20/lombok.versionmybatis.version3.0.1/mybatis.versionpagehelper.version1.3.0/pagehelper.versionhutool.version5.5.2/hutool.versionminio.version8.5.2/minio.versioneasyexcel.version3.1.0/easyexcel.versionlogback.version1.4.6/logback.version
/properties!-- 管理依赖版本锁定 --
dependencyManagementdependencies!-- mybatis和spring boot整合的起步依赖 --dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion${mybatis.version}/version/dependency!-- hutool工具包包含了常用的工具类 --dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion${hutool.version}/version/dependencydependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion${minio.version}/version/dependency!-- mysql驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIdeasyexcel/artifactIdversion${easyexcel.version}/version/dependencydependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion${logback.version}/version/dependency!--fastjson--dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion${fastjson.version}/version/dependency!--日期时间工具--dependencygroupIdjoda-time/groupIdartifactIdjoda-time/artifactIdversion${jodatime.version}/version/dependency!-- lombok依赖 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/version/dependencydependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper-spring-boot-starter/artifactIdversion${pagehelper.version}/version/dependency/dependencies/dependencyManagement注意 
1、设置项目的字符集为utf-8 
2、删除src目录 
5.4.2 spzx-common 
在spzx-parent下面创建该子模块并导入如下依赖 
dependenciesdependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactId/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactId/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependency
/dependencies5.4.3 common-util 
在spzx-common下面创建该子模块并导入如下依赖 
dependencies!-- fastjson依赖 --dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactId/dependency/dependencies5.4.4 spzx-model 
在spzx-parent下面创建该子模块并导入如下依赖 
dependencies!-- lombok的依赖 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency/dependencies5.4.5 common-service 
在spzx-common下面创建该子模块并导入如下依赖util/model 
dependenciesdependencygroupIdcom.atguigu/groupIdartifactIdspzx-model/artifactIdversion1.0-SNAPSHOT/version/dependencydependencygroupIdcom.atguigu/groupIdartifactIdcommon-util/artifactIdversion1.0-SNAPSHOT/version/dependency
/dependencies5.4.6 spzx-manager 
在spzx-parent下面创建该子模块并导入如下依赖 
dependencies!-- spring boot web开发所需要的起步依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- redis的起步依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency!-- mybatis的起步依赖 --dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId/dependency!-- mysql驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependency!-- common-service依赖 --dependencygroupIdcom.atguigu.spzx/groupIdartifactIdcommon-service/artifactIdversion1.0-SNAPSHOT/version/dependency/dependencies5.5 统一结果实体类 
5.5.1 响应结果分析 
通过对前端登录功能的源码查看可以看到登录请求成功以后前端需要从返回结果中解析出来三部分的数据 
// code:自定义的业务状态码前端会根据具体的业务状态码给出不同的处理。比如200表示成功、非200都是失败
// message响应消息。比如登录成功、用户名或者密码错误、用户无权限访问
// data后端返回给前端的业务数据
const { code, data, message }  await Login(state.model)5.5.2 Result实体类 
针对上述的三部分的数据我们可以定义一个实体类来进行封装后期尚品甄选项目中所有的接口的返回值统一都会定义为Result。 
在spzx-model模块中定义Result实体类内容如下所示 
// com.atguigu.spzx.model.vo.common
Data
public class ResultT {//状态码 200代表成功private Integer code;//状态码的描述private String message;//成功的响应数据private T data;//私有化构造器private Result(){}//手动指定状态码信息构建 result对象public static T ResultT setResult(Integer code , String message , T data){ResultT result  new Result();result.setCode(code);result.setData(data);result.setMessage(message);return result;}//通过枚举对象构建 result对象public static T ResultT setResult(ResultCodeEnum codeEnum , T data){return setResult(codeEnum.getCode() , codeEnum.getMessage() , data);}//默认成功public staticT ResultT ok(){return setResult(ResultCodeEnum.SUCCESS , null);}//默认失败public staticT ResultT error(){return setResult(ResultCodeEnum.ERROR , null);}//链式调用设置属性值public ResultT code(Integer code){this.setCode(code);return this;}public ResultT message(String message){this.setMessage(message);return this;}public ResultT data(T data){this.setData(data);return this;}
}为了简化Result对象的构造可以定义一个枚举类在该枚举类中定义对应的枚举项来封装code、message的信息如下所示 
// com.atguigu.spzx.model.vo.common
Getter // 提供获取属性值的getter方法
public enum ResultCodeEnum {SUCCESS(200 , 操作成功) ,LOGIN_ERROR(201 , 用户名或者密码错误);private Integer code ;      // 业务状态码private String message ;    // 响应消息private ResultCodeEnum(Integer code , String message) {this.code  code ;this.message  message ;}}5.6 登录接口开发 
5.6.1 基础环境配置 
在spzx-manager服务的src/resources目录下创建application.yml、application-dev.yml文件文件的内容如下所示 
# application.yml文件内容
spring:application:name: service-managerprofiles:active: dev		# 激活的环境文件#  application-dev.yml文件内容
# 配置服务端口号
server:port: 8501# 配置数据库连接信息
spring:datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.136.142:3306/db_spzx?characterEncodingutf-8useSSLfalseallowPublicKeyRetrievaltrueusername: rootpassword: 123456# Redis的相关配置data:redis:host: 192.168.136.142port: 6379password: 123456# mybatis的配置
mybatis:config-location: classpath:/mybatis-config.xmlmapper-locations: classpath:/mapper/*.xml导入课程资料中提供的mybatis-config.xml和logback-spring.xml配置文件 
启动类创建 
SpringBootApplication
public class SpzxManagerApplication {public static void main(String[] args) {SpringApplication.run(SpzxManagerApplication.class , args) ;}}5.6.2 SysUser 
创建与数据库表对应的实体类 
BaseEntity: 
每张表都有一些固定字段所以定义一个BaseEntity实体类在该实体类中定义公共的属性 
// com.atguigu.spzx.model.entity.base
Data
public class BaseEntity implements Serializable {private Long id;private Date createTime;private Date updateTime;private Integer isDeleted;}SysUser实体类定义 
// com.atguigu.spzx.model.entity.system
Data
public class SysUser extends BaseEntity {private static final long serialVersionUID  1L;private String userName;  // 该字段的属性名称和数据表字段不一致private String password;private String name;private String phone;private String avatar;private String description;private Integer status;}5.6.3 LoginDto 
创建一个LoginDto实体类封装登录请求参数。 
// com.atguigu.spzx.model.dto.system
Data
public class LoginDto {private String userName ;private String password ;}5.6.4 LoginVo 
创建一个LoginVo实体类封装登录成以后响应结果数据。 
//com.atguigu.spzx.model.vo.system;
Data
public class LoginVo {private String token ;// 该字段不会存储对应的值private String refresh_token ;		}5.6.5 IndexController 
表现层代码实现 
// com.atguigu.spzx.manager.controller
RestController
RequestMapping(value  /admin/system/index)
public class IndexController {Autowiredprivate SysUserService sysUserService ;PostMapping(value  /login)public ResultLoginVo login(RequestBody LoginDto loginDto) {LoginVo loginVo  sysUserService.login(loginDto) ;return Result.ok().data(loginVo) ;}}5.6.6 SysUserService 
业务层代码实现 
// com.atguigu.spzx.manager.service
public interface SysUserService {/*** 根据用户名查询用户数据* return*/public abstract LoginVo login(LoginDto loginDto) ;}// com.atguigu.spzx.manager.service.impl
Service
public class SysUserServiceImpl implements SysUserService {Autowiredprivate SysUserMapper sysUserMapper ;Autowiredprivate RedisTemplateString , String redisTemplate ;Overridepublic LoginVo login(LoginDto loginDto) {// 根据用户名查询用户SysUser sysUser  sysUserMapper.selectByUserName(loginDto.getUserName());if(sysUser  null) {throw new RuntimeException(用户名或者密码错误) ;}// 验证密码是否正确String inputPassword  loginDto.getPassword();String md5InputPassword  DigestUtils.md5DigestAsHex(inputPassword.getBytes());if(!md5InputPassword.equals(sysUser.getPassword())) {throw new RuntimeException(用户名或者密码错误) ;}// 生成令牌保存数据到Redis中String token  UUID.randomUUID().toString().replace(-, );redisTemplate.opsForValue().set(user:login:  token , JSON.toJSONString(sysUser) , 30 , TimeUnit.MINUTES);// 构建响应结果对象LoginVo loginVo  new LoginVo() ;loginVo.setToken(token);loginVo.setRefresh_token();// 返回return loginVo;}}5.6.7 SysUserMapper 
持久层代码实现 
//com.atguigu.spzx.manager.mapper
Mapper
public interface SysUserMapper {/*** 根据用户名查询用户数据* param userName* return*/public abstract SysUser selectByUserName(String userName) ;}5.6.8 SysUserMapper.xml 
创建映射文件并且编写sql语句: 文件位置classpath: /mapper/system/SysUserMapper.xml 
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.atguigu.spzx.manager.mapper.SysUserMapper!-- 用于select查询公用抽取的列 --sql idcolumnsid,username userName ,password,name,phone,avatar,description,status,create_time,update_time,is_deleted/sqlselect idselectByUserName resultTypecom.atguigu.spzx.model.entity.system.SysUserselect include refidcolumns / from sys_user where username  #{userName} and is_deleted  0/select/mapper5.7 Postman测试 
使用Postman工具先对后端所开发的接口进行测试。