学成在线(后端开发)第一天

学完以下技术栈后,可进行本项目的学习
应用到的技术
开始学习:

项目的简单介绍

从在线教育的火热到如今,在线教育的模式出现多种多样,包括:B2C、C2C、B2B2C等业务模式。学成在线采用B2B2C业务模式,即向企业或个人在线教育平台提供教学服务,老师和学生通过平台完成整个教学和学习的过程,市场上类似的平台有:网易云课堂、腾讯课堂等,学成在线的特点是IT职业课程在线教学。

学成在线包括在线教育平台、业务支持系统、基础服务来构建整个功能架构

架构图:
在这里插入图片描述
技术栈列表:

在这里插入图片描述

模块功能列表:

1.在线教育平台

功能模块名称功能说明
门户在首页、活动页、专题页等页面提供课程学习入口。
教学管理平台教学机构登录系统的入口,通过此来管理机构中的课程相关的数据。
运营平台教师登录教学管理中心进行课程管理、资源管理、考试管理等教学活动。

2.业务系统支撑

功能模块名称功能说明
内容管理系统内容管理中对教学机构的课程、课程计划、课程教师、课程营销数据进行管理
教学管理中心对平台的入住教学机构数据进行管理和审核,以及课程中设计到的课程作业。
学习中心对课程中的学员学习课程的记录数据来进行管理。
社交系统论坛系统、问答系统、消息系统、评论系统等信息的管理
媒资管理课程计划所关联的课程流媒体资源数据进行管理(直播、录播)。

3.基础服务

功能模块名称功能说明
系统管理对学成在线后端服务提供系统的基础数据。
支付系统管理收费课程的交易记录和订单数据。
文件服务管理系统中的文件资源,包括课程图片、教师图片等。
验证码服务生成系统中的验证码并通过短息服务发送验证码、校验验证码等。
统一认证服务对系统中的所有用户资源进行管理,并提供服务中用户资源的认证功能
视频点直播在课程学习时需要通过此服务来对视频资源进行播放。

剩下的流程图、UML我就不介绍了,直接开始实战

环境搭建

导入linux镜像,并使用docker容器开启组件:
在这里插入图片描述
启动nginx导入前端页面:
在这里插入图片描述
配置访问host
前端项目中,各个页面跳转都是由域名构成。为了方便需要修改本机host地址。

进入C:\Windows\System32\drivers\etc目录,修改hosts文件。添加如下内容。温馨提示:做好备份

#门户网站域名
127.0.0.1 www.xuecheng.com
#企业管理后台
127.0.0.1 admin.xuecheng.com
#机构管理后台
127.0.0.1 manage.xuecheng.com

配置成功后,在浏览器打开http://admin.xuecheng.com即可进入企业管理后台页面

后端环境搭建

在这里插入图片描述
在这里插入图片描述
项目基于前后端分离的架构进行开发,前后端分离架构总体上包括前端和服务端,通常是多人协作开发

  • 前后端分离开发基于HTTP+JSON交互

  • 通过接口文档(API文档)定义规范

  • 前后端按照文档定义请求及响应数据

这里我们使用YAPI接口文档管理

登录功能

在写代码前,我们可以回想一下以前是怎么进行身份验证的?
没错 cookie 或session,但是对于前端来说,有移动端页面,h5页面,VUE页面,对于手机端页面可能就没有session,所以用这俩存登录信息,权限检验,就不行了
下面介绍一个新的身份校验工具——JWT
在这里插入图片描述
在这里插入图片描述
小实例:
首先导入依赖:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

测试类:

@Test
public void testCreateToken() {
    //生成token
    //1 准备数据
    Map map = new HashMap();
    map.put("id",1);
    map.put("mobile","13800138000");
    //2 使用JWT的工具类生成token
    long now = System.currentTimeMillis();
    String token = Jwts.builder()
            .signWith(SignatureAlgorithm.HS512, "zjf") //指定加密算法
            .setClaims(map) //写入数据
            .setExpiration(new Date(now + 30000)) //失效时间
            .compact();
    System.out.println(token);
}

//解析token

/**
 * SignatureException : token不合法
 * ExpiredJwtException:token已过期
 */
@Test
public void testParseToken() {
    String token = "...";//这里面换成上面测试打印的token
    try {
        Claims claims = Jwts.parser()
                .setSigningKey("zjf")
                .parseClaimsJws(token)
                .getBody();
        Object id = claims.get("id");
        Object mobile = claims.get("mobile");
        System.out.println(id + "--" + mobile);
    }catch (ExpiredJwtException e) {
        System.out.println("token已过期");
    }catch (SignatureException e) {
        System.out.println("token不合法");
    }
}

基本介绍完毕, 下面完成登录功能:

在这里插入图片描述
接口文档:
在这里插入图片描述
在这里插入图片描述
需要使用的数据表:
在这里插入图片描述
后端代码显示:

web层:
在这里插入图片描述

package com.xuecheng.system.controller;

import com.xuecheng.commons.model.dto.LoginDto;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.system.service.UserService;
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.RestController;

@RestController
public class LoginController {
    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseResult organizationLogin(@RequestBody LoginDto loginDto){
        return userService.organizationLogin(loginDto);
    }

}

service层:
在这里插入图片描述

public interface UserService extends IService<User> {

    ResponseResult organizationLogin(LoginDto loginDto);
}

serviceImpl层:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public ResponseResult organizationLogin(LoginDto loginDto) {
        if (StrUtil.isBlank(loginDto.getUsername())) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        if (StrUtil.isBlank(loginDto.getPassword())) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        if (StrUtil.isBlank(loginDto.getUtype())) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhone, loginDto.getUsername());
        wrapper.eq(User::getUtype, loginDto.getUtype());
        User user = userMapper.selectOne(wrapper);
        if (BeanUtil.isEmpty(user)){
            User u = new User();
            u.setPhone(loginDto.getUsername());
            u.setPassword(DigestUtil.md5Hex(loginDto.getPassword()));
            u.setUtype(loginDto.getUtype());
            userMapper.insert(u);
        }
        if (!StrUtil.equals(DigestUtil.md5Hex(loginDto.getPassword()), user.getPassword())) {
            throw new BusinessException(ErrorCode.LOGINERROR);
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("userId",user.getId());
        map.put("companyId",user.getCompanyId());
        map.put("companyName",user.getCompanyName());
        String token = JwtUtils.createToken(map, 180);

        LoginVo loginVo = new LoginVo();
        loginVo.setAccess_token(token);
        loginVo.setUsername(user.getPhone());

        return ResponseResult.okResult(loginVo);

    }
}

mapper层:

public interface UserMapper extends BaseMapper<User> {

}

搭建网关

网关就是系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等。学成在线也是通过网关介入所有请求,进行路由转发在这里插入图片描述
在这里插入图片描述

统一异常处理

在这里插入图片描述
在这里插入图片描述

package com.xuecheng.web.exception;


import com.xuecheng.commons.enums.ErrorCode;
import lombok.Data;

@Data
public class BusinessException extends RuntimeException{

    private ErrorCode errorCode;

    public BusinessException(ErrorCode errorCode) {
        super(errorCode.getDesc());
        this.errorCode = errorCode;
    }
}
package com.xuecheng.web.exception;

import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.vo.ResponseResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalException {
    @ExceptionHandler(RuntimeException.class)
    public ResponseResult exception(RuntimeException e){
         e.printStackTrace();
         return ResponseResult.errorResult(ErrorCode.ERROR);
    }

    @ExceptionHandler(BusinessException.class)
    public ResponseResult  BusinessException(BusinessException e){
        ErrorCode errorCode = e.getErrorCode();
        return ResponseResult.errorResult(errorCode);
    }
}

结果展示:
登录成功会进入商家页面

在这里插入图片描述
创建git,以天为单位作为分支,提交到gitee上,用以练习git操作
在这里插入图片描述

第一天任务完成

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皇家小黄

创作不易!!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值