https://blog.csdn.net/weixin_43715214/category_12022798.html
大佬记录
项目介绍day01
功能架构
(1)用户层
本项目中在构建系统管理后台的前端页面,我们会用到H5、Vue.js、ElementUI等技术。而在构建移动端应用时,我们会使用到微信小程序。
(2)网关层
Nginx是一个服务器,主要用来作为Http服务器,部署静态资源,访问性能高。在Nginx中还有两个比较重要的作用: 反向代理和负载均衡, 在进行项目部署时,要实现Tomcat的负载均衡,就可以通过Nginx来实现。
(3)应用层
SpringBoot: 快速构建Spring项目, 采用 "约定优于配置" 的思想, 简化Spring项目的配置开发。
Spring: 统一管理项目中的各种资源(bean), 在web开发的各层中都会用到。
SpringMVC:SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合,可以无缝集成。
SpringSession: 主要解决在集群环境下的Session共享问题。
lombok:能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法。
Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。
(4)数据层
MySQL: 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。
MybatisPlus: 本项目持久层将会使用MybatisPlus来简化开发, 基本的单表增删改查直接调用框架提供的方法即可。
Redis: 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存(降低数据库访问压力, 提供访问效率), 在后面的性能优化中会使用。
(5)工具
git: 版本控制工具, 在团队协作中, 使用该工具对项目中的代码进行管理。
maven: 项目构建工具。
junit:单元测试工具,开发人员功能实现完毕后,需要通过junit对功能进行单元测试。
软件开发介绍
第1阶段: 需求分析
完成产品原型、需求规格说明书的编写。
产品原型,一般是通过网页(html)的形式展示当前的页面展示什么样的数据, 页面的布局是什么样子的,点击某个菜单,打开什么页面,点击某个按钮,出现什么效果,都可以通过产品原型看到。
需求规格说明书, 一般来说就是使用 Word 文档来描述当前项目有哪些功能,每一项功能的需求及业务流程是什么样的,都会在文档中描述。
第2阶段: 设计
设计的内容包含 产品设计、UI界面设计、概要设计、详细设计、数据库设计。
在设计阶段,会出具相关的UI界面、及相关的设计文档。比如数据库设计,需要设计当前项目中涉及到哪些数据库,每一个数据库里面包含哪些表,这些表结构之间的关系是什么样的,表结构中包含哪些字段,字段类型都会在文档中描述清楚。
第3阶段: 编码
编写项目代码、并完成单元测试。
作为软件开发工程师,我们主要的工作就是在该阶段, 对分配给我们的模块功能,进行编码实现。编码实现完毕后,进行单元测试,单元测试通过后再进入到下一阶段。
第4阶段: 测试
在该阶段中主要由测试人员, 对部署在测试环境的项目进行功能测试, 并出具测试报告。
第5阶段: 上线运维
在项目上线之前, 会由运维人员准备服务器上的软件环境安装、配置, 配置完毕后, 再将我们开发好的项目,部署在服务器上运行。
我们作为软件开发工程师, 我们主要的任务是在编码阶段, 但是在一些小的项目组当中, 也会涉及到数据库的设计、测试等方面的工作。
角色分工
开发环境搭建
需求
后台系统
菜品管理(批量删除、起售停售)
• 套餐管理(修改、起售停售)
• 订单明细
移动端
个人中心(退出登录、最新订单查询、历史订单、地址管理-修改地址、地址管理-删除地址)
• 购物车(删除购物车中的商品)
https://blog.csdn.net/weixin_43715214/article/details/126920640
精力全用在写注释上了,笔记黑马没给,懒得截图,就直接看别人的吧
https://blog.csdn.net/weixin_43715214/article/details/126945226?ops_request_misc=&request_id=&biz_id=102&utm_term=%E9%BB%91%E9%A9%AC%E7%91%9E%E5%90%89%E5%A4%96%E5%8D%96ppt&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-126945226.142^v71^one_line,201^v4^add_ask&spm=1018.2226.3001.4187
员工登录
//EmployeeController
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){
// 通过request获取Session,把登录成功的信息传进去;@RequestBody用于接受JSON数据
//1、将页面提交的密码password进行md5加密处理
String password = employee.getPassword();//拿到密码
password = DigestUtils.md5DigestAsHex(password.getBytes());//工具类md5加密
//2、根据页面提交的用户名username查询数据库
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);//数据库有唯一索引,用getOne
//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);
}
退出后台
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前登录员工的id
request.getSession().removeAttribute("employee");
return R.success("退出成功");
}
Day02员工管理业务开发
2.1完善登录功能
http://t.csdn.cn/GkgbY
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
//要过滤的东西(过滤器名字,拦截哪些路径)
@Slf4j
public class LoginCheckFilter implements Filter{
//AntPathMatcher路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;//两个转型
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1、获取本次请求的URI
String requestURI = request.getRequestURI();// /backend/index.html
log.info("拦截到请求:{}",requestURI);//{}表示占位符 代表,后面的东西
String[] urls = new String[]{ //定义不需要处理的请求路径
"/employee/login",//登录请求路径
"/employee/logout",//员工退出系统
"/backend/**",//后端页面静态资源
"/front/**",//移动端页面静态资源
"/common/**", "/user/sendMsg", "/user/login"
};
//2、判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//3、如果不需要处理,则直接放行
if(check){
log.info("本次请求{}不需要处理,直接放行",requestURI);
filterChain.doFilter(request,response);
return;
}
//4-1、需要处理,判断 员工 登录状态,如果已登录,则直接放行filterChain.doFilter
if(request.getSession().getAttribute("employee") != null){
log.info("员工已登录,员工id为:{}",request.getSession().getAttribute("employee"));
Long empId = (Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(empId);
filterChain.doFilter(request,response);
return;
}
//4-2、判断 用户 登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("user") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));
Long userId = (Long) request.getSession().getAttribute("user");
BaseContext.setCurrentId(userId);
filterChain.doFilter(request,response);
return;
}
log.info("用户未登录");
//5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
//把R转成JSON 输出’NOTLOGIN‘和request.js里面响应拦截器的条件匹配
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;
}
}
2.2新增员工
@ControllerAdvice(annotations = {RestController.class, Controller.class})
//AOP通知(annotations={拦截加了 XX.class的注解的Controller} )
@ResponseBody//返回JSON数据的方法需要加这个注解
@Slf4j
public class GlobalExceptionHandler {
/**
* 异常处理方法
* @return
*/
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)//(要处理的异常类)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
log.error(ex.getMessage());
if(ex.getMessage().contains("Duplicate entry")){//异常信息包含这个字段就是重复错误
String[] split = ex.getMessage().split(" ");
String msg = split[2] + "已存在";//根据字段输出得知name在[2]
return R.error(msg);
}
return R.error("未知错误");
}
}
@PostMapping
public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
log.info("新增员工,员工信息:{}",employee.toString());
//设置初始密码123456,需要进行md5加密处理
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
//employee.setCreateTime(LocalDateTime.now());//LocalDateTime.now():获取系统当前time
//employee.setUpdateTime(LocalDateTime.now());
//获得当前登录用户的id
//Long empId = (Long) request.getSession().getAttribute("employee");
//employee.setCreateUser(empId);
//employee.setUpdateUser(empId);
employeeService.save(employee);
//继承了MabatisPlus的IService接口写的save
return R.success("新增员工成功");
}
2.3员工信息分页查询
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
log.info("page = {},pageSize = {},name = {}" ,page,pageSize,name);
//构造分页构造器
Page pageInfo = new Page(page,pageSize);
//构造条件构造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();
//添加过滤条件
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
//添加排序条件
queryWrapper.orderByDesc(Employee::getUpdateTime);
//执行查询
employeeService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}