一, 软件开发整体介绍
软件开发流程
- 需求分析
- 产品原型,需求规格说明书
- 设计
- 产品文档,UI界面设计,概要设计,详细设计,数据库设计
- 编码
- 项目代码,单元测试
- 测试
- 测试用例,测试报告
- 上线运维
- 软件环境安装,配置
角色分工
- 项目经理:对整个项目负责,任务分配、把控进度
- 产品经理:进行需求调研,输出需求调研文档、产品原型等
- UI设计师:根据产品原型输出界面效果图
- 架构师:项目整体架构设计、技术选型等
- 开发工程师:代码实现
- 测试工程师:编写测试用例,输出测试报告
- 运维工程师:软件环境搭建、项目上线
环境
软件环境
- 开发环境
- 测试环境:专门给测试人员使用的环境,用于测试项目,一般外部用户无法访问
- 生产环境(production):即线上环境,正式提供对外服务的环境
二,瑞吉外卖项目介绍
展示
技术选型
功能架构
角色
三,开发环境搭建
数据库环境搭建
- 建立reggie库
- 导入表结构
- 数据表
maven环境配置
导入pom文件
- 导入父工程
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.5</version> <relativePath/> <!-- lookup parent from repository --> </parent>
- 指定jdk版本 ```xml <properties> <java.version>1.8</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.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</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.1.23</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.4.5</version> </plugin> </plugins> </build>
- 导入配置文件 ```yml server: port: 8080 spring: application: #应用的名称:可选 name: reggie_take_out datasource: 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: root mybatis-plus: configuration: #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: ASSIGN_ID
- 导入静态资源
1
[!danger]
默认情况下是访问不到这些文件夹里面的静态资源的,所以需要配置资源映射
@Configuration public class WebMvcConfig extends WebMvcConfigurationSupport{ // 设置静态资源映射 @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/"); registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/"); } }
默认配置的资源映射 [[springboot-web#资源处理的默认规则]] (可以参考)
四,后台登录功能开发
需求分析
前端的登录按键和 handleLogin这个方法绑定,这个方法调用loginApi上产loginForm中的信息也就是账号密码,如果返回1就代表登陆成功,然后把数据转成JSON的格式保存到主页面,如果返回的不是1的话就设置一个错误信息,并且把登陆中改成登录
function loginApi(data) { return $axios({ 'url': '/employee/login', 'method': 'post', data }) } function logoutApi(){ return $axios({ 'url': '/employee/logout', 'method': 'post', }) }
代码开发
- 导入实体类
mapper
@Mapper public interface EmployeeMapper extends BaseMapper<Employee> { }
- service
@Service public interface EmployeeService extends IService<Employee> { }
@Service public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService { }
- 导入返回结果类,服务端响应的所有结果都会包装成此类型返回给前端页面
public class R<T> { private Integer code; //编码:1成功,0和其它数字为失败 private String msg; //错误信息 private T data; //数据 private Map map = new HashMap(); //动态数据 第一个<T>是为了标注此方法是泛型方法 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; }
在Controller中创建登录方法
处理逻辑如下;
- 将页面提示的密码password进行md5加密
- 根据页面提交的username查询数据库
- 如果没有查询到返回登陆失败结果
- 密码比对,比对不一致返回登陆失败
- 查看员工状态,如果为已禁用状态,则返回已禁用结果
- 登陆成功,将员工的id存入session并返回登陆成功结果
- Controller ^3yec7p
@Slf4j @RestController @RequestMapping("/employee") public class EmployeeController { @Autowired private EmployeeService employeeService; public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee ){ String password = employee.getPassword(); password= DigestUtils.md5DigestAsHex(password.getBytes()); LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Employee::getUsername,employee.getUsername()); Employee emp = employeeService.getOne(queryWrapper); if(emp==null){ return R.error("登陆失败"); } if(!emp.getPassword().equals((password))){ return R.error("登陆失败"); } if(emp.getStatus()==0){ return R.error("账号已禁用"); } request.getSession().setAttribute("emp",emp.getId()); return R.success(emp); } }
完善登录功能-问题分析并创建过滤器
实现步骤:
1、创建自定义过滤器LoginCheckFilter
2、在启动类上加入注解@ServletComponentScan==(开启主件扫描去扫描过滤器)==
3、完善过滤器的处理逻辑
代码实现
过滤器具体的处理逻辑:
- 获取本次请求的url
- 判断本次请求是否需要处理
- 如果不需要处理,则直接放行
- 判断登录状态,如果已经登录,则直接放行
- 如果未登录则返回未登录结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A7lJIMV4-1686059761210)(null)]
前端的逻辑是:如果msg是NOTLOGIN那么久自动跳转到登录页面
@Slf4j @WebFilter( filterName="LoginCheckFilter",urlPatterns = "/*") public class LoginCheckFilter implements Filter { public static final AntPathMatcher PATH_MATHER = new AntPathMatcher(); @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String uri = request.getRequestURI(); String[] urls= new String[] { "/employee/login", "/employee/logout", "/backend/**", "front/**" }; if(check(urls,uri)){ filterChain.doFilter(request,response); return; } if (request.getSession().getAttribute("employee")!=null){ filterChain.doFilter(request,response); return; } //controller里面直接返回R对象是因为框架自动帮我们转换成Json了,这里是filter需要我们手动转成Json数据传回前端 response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN"))); log.info("拦截到请求",uri); } public boolean check(String[] urls,String requesturl){ for (String url : urls) { boolean match = PATH_MATHER.match(url,requesturl); if (match) { return true; } } return false; } }
五, 后台系统退出功能
需求分析
员工登录成功后,页面跳转到后台系统首页面(backend/index.html),此时会显示当前登录用户的姓名:
如果员工需要退出系统,直接点击右侧的退出按钮即可退出系统,退出系统后页面应跳转回登录页面
代码开发
用户点击页面中退出按钮,发送请求,请求地址为/employee/logout,请求方式为POST。我们只需要在Controller中创建对应的处理方法即可,具体的处理逻辑:
1、清理Session中的用户id
2、返回结果
/** * 员工退出 * @param request * @return */ @PostMapping("/logout") public R<String> logout(HttpServletRequest request) { request.getSession().removeAttribute("employee"); return R.success("退出成功"); }
前端判断code为1进行页面跳转
前端进行页面切换部分
调用的是menuHandle方法
用iframe的方式显示一个页面
页面上有个iframe相当月页面上有一个坑,用来展示页面的,外面的来源那就是:src里面的url
六,新增员工
需求分析
后台系统中可以查看管理员工信息,通过新增员工来添加后台系统用户,点击[添加员工]跳转到新增页面,如下
瑞吉外卖业务开发(2)https://developer.aliyun.com/article/1530403