整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Dubbo分布式架构搭建教育PC站-后端:用户模块,

Dubbo分布式架构搭建教育PC站-后端:用户模块,课程模块

户模块

实体类的编写没有任何技术含量,而且还浪费时间。

生成代码的解决方案有很多种:企业中比较常见的还有 MyBatis 的逆向工程。

修改 Easy Code 插件的作者名称:IDEA 的 Settings -> Other Settings -> Easy Code -> 修改新的作者名称。

使用 EASY CODE 插件可以快速生成 entitydaoservicemapper 等文件:

  • IDEA 安装最新版的 Easy Code 插件来自动生成代码;
  • 在 IDEA 的 Database --> 选择 edu 数据库的 user 表 --> 右键 --> EasyCode --> Generate Code;
  • 弹出对话框询问是否添加数据库类型 bit(1) 的映射关系,选择 No;
  • Group 为 Default,Module 为 lagou-edu-service,Template 勾选 entity.java、dao.java、service.java、serviceImpl.java、mapper.xml;
  • 点击 OK,开始自动生成代码。
  • 把自动生成的 User 实体类移动到 lagou-edu-eneitysrc/main/java 目录下,包名为 com.renda.entity
  • 把自动生成的 UserDao 移动到 lagout-edu-daosrc/main/java 目录下,包名为 com.renda.mapper;把自动生成的 resources 目录下的 mapper/UserDao.xml 移动到 lagout-edu-daosrc/main/resources/com/renda 的目录下。
  • 把 service 目录下自动生成的文件移动到 lagout-edu-servicecom.renda.user 包下,以形成包名 com.renda.user
  • 根据报错修改一下自动生成的代码,Maven Compile 一下看看是否报错。

用户登录 / 注册

功能描述:用户输入手机号、密码,点击登录,调用后端接口开始登录;如果该手机号未注册,则自动注册并登录。

功能接口:/user/login

lagou-edu-entity

使用 Lombok 小辣椒,使用注解取代原来冗余的 get 和 set、空构造、全参数构造。

pom.xml

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>

com.renda.entity.User

把原来的 getter 和 setter 删除,保留成员变量,然后使用 Lombok 注解来取代:

@Data // 生成 getter 和 setter
@AllArgsConstructor // 生成全参数的构造方法
@NoArgsConstructor // 生成空构造方法
@ToString // 生成 toString 方法
public class User implements Serializable {

    private static final long serialVersionUID=-48156882162112782L;
    ...   
}

用户数据响应的封装类 com.renda.entity.UserDTO

package com.renda.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
?
import java.io.Serializable;
?
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserDTO<User> implements Serializable {
?
    private static final long serialVersionUID=1L;
    private int state;  // 操作状态
    private String message;  // 状态描述
    private User content;  // 响应内容
?
}

lagou-edu-dao

src\main\resources\mybatis\mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 后台的日志输出:针对开发者-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

src\main\resources\spring\spring-dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
?
    <!-- 1.扫描包 -->
    <context:component-scan base-package="com.renda.mapper"/>
?
    <!-- 2.数据连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="jdbc:mysql://192.168.186.128:3306/edu?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="RendaZhang@666"/>
        <property name="maxActive" value="10"/>
        <property name="minIdle" value="5"/>
    </bean>
?
    <!-- 3.sqlsessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
    </bean>
?
    <!-- 4.事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
?
    <!-- 5.开启事务 -->
    <tx:annotation-driven/>
?
    <!-- 整合 MyBatis -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.renda.mapper"/>
    </bean>
?
</beans>

删除掉 UserDao 自动生成的代码,增加用户登录注册方法:

@Service
public interface UserDao {
?
    /**
     * 用户登录
     *
     * @param phone    手机号
     * @param password 密码
     * @return 用户对象
     */
    User login(@Param("phone") String phone, @Param("password") String password);
?
    /**
     * 检查手机号是否注册过
     *
     * @param phone 手机号
     * @return 0:未注册 , 1:已注册
     */
    Integer checkPhone(String phone);
?
    /**
     * 用户注册
     *
     * @param phone    手机号
     * @param password 密码
     * @param nickname 昵称
     * @param headimg  头像
     * @return 受影响的行数
     */
    Integer register(@Param("phone") String phone, @Param("password") String password,
                     @Param("nickname") String nickname, @Param("headimg") String headimg);
?
}

保留 resultMapper,删除掉 UserDao.xml 自动生成的代码,增加登录注册查询:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.renda.mapper.UserDao">
?
    <resultMap type="com.renda.entity.User" id="UserMap">
        <result property="id" column="id" jdbcType="INTEGER"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="portrait" column="portrait" jdbcType="VARCHAR"/>
        <result property="phone" column="phone" jdbcType="VARCHAR"/>
        <result property="password" column="password" jdbcType="VARCHAR"/>
        <result property="regIp" column="reg_ip" jdbcType="VARCHAR"/>
        <result property="accountNonExpired" column="account_non_expired" jdbcType="OTHER"/>
        <result property="credentialsNonExpired" column="credentials_non_expired" jdbcType="OTHER"/>
        <result property="accountNonLocked" column="account_non_locked" jdbcType="OTHER"/>
        <result property="status" column="status" jdbcType="VARCHAR"/>
        <result property="isDel" column="is_del" jdbcType="OTHER"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
?
    <select id="login" resultMap="UserMap">
        select * from `user` where phone=#{phone} and password=#{password}
    </select>
?
    <select id="checkPhone" resultType="integer">
        select count(*) from `user` where phone=#{phone}
    </select>
?
    <insert id="register">
        insert  into `user`
        (`name`,portrait,phone,password,create_time,update_time)
        values
        (#{nickname},#{headimg},#{phone},#{password},sysdate(),sysdate())
    </insert>
?
</mapper>

增加测试类测试登录注册方法 src\test\java\user\TestUser.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/spring-dao.xml"})
public class TestUser {
?
    @Autowired
    private UserDao userDao;
?
    @Test
    public void login(){
        User user=userDao.login("110", "123");
        System.out.println("user=" + user);
    }
?
    @Test
    public void checkPhone(){
        Integer i=userDao.checkPhone("110");
        // 0:未注册 , 1:已注册
        System.out.println("i=" + i);
    }
?
    @Test
    public void register(){
        Integer i=userDao.register("114", "123", "renda", "");
        // 0:注册失败 , 1:注册成功
        System.out.println("i=" + i);
    }
?
}

lagou-edu-service

src\main\resources\spring\spring-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
?
    <!-- 服务提供方在 zookeeper 中的“别名” -->
    <dubbo:application name="lagou-edu-service"/>
?
    <!-- 注册中心的地址 -->
    <dubbo:registry address="zookeeper://192.168.186.128:2181"/>
?
    <!-- 扫描类(将什么包下的类作为服务提供类)-->
    <dubbo:annotation package="com.renda"/>
?
    <dubbo:provider timeout="60000"/>
?
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
    </bean>
?
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="192.168.186.128"/>
        <property name="port" value="6379"/>
    </bean>
?
</beans>

删除掉 UserServiceUserServiceImpl 自动生成的代码,增加用户登录注册方法:

public interface UserService {
    User login(String phone, String password);
    
    Integer checkPhone(String phone);
?
    Integer register(String phone, String password, String nickname, String headimg);
}
?
@Service // dubbo 暴露服务:让消费者能够找到我
public class UserServiceImpl implements UserService {
?
    @Autowired
    private UserDao userDao;
?
    @Override
    public User login(String phone, String password) {
        return userDao.login(phone, password);
    }
?
    @Override
    public Integer checkPhone(String phone) {
        return userDao.checkPhone(phone);
    }
?
    @Override
    public Integer register(String phone, String password, String nickname, String headimg) {
        return userDao.register(phone, password, nickname, headimg);
    }
?
}

增加测试类测试登录注册方法 src\test\java\user\TestUser.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:spring/spring-*.xml"})
public class TestUser {
?
    @Autowired
    private UserService userService;
?
    @Test
    public void login(){
        User user=userService.login("110", "123");
        System.out.println("user=" + user);
    }
?
    @Test
    public void checkPhone() {
        Integer i=userService.checkPhone("110");
        System.out.println("i=" + i); //0:未注册 , 1:已注册
    }
?
}

src\main\webapp\WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID" version="3.1">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/spring-*.xml</param-value>
    </context-param>
</web-app>

使用 Tomcat 插件 8001 端口:

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
                <port>8001</port>
                <path>/</path>
            </configuration>
            <executions>
                <execution>
                    <!-- 打包完成后,运行服务 -->
                    <phase>package</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
...

使用 Maven 在 lagou-edu-parent 下执行 install 命令在本地安装部署好需要依赖的 jar 包,然后在 lagou-edu-service 下执行 package 命令启动服务。

lagou-edu-web

创建对应的接口来引用要消费的服务 com.renda.user.UserService(确保包名与提供的服务的包名一致,否则会出现空指针异常):

public interface UserService {
    User login(String phone, String password);
?
    Integer checkPhone(String phone);
?
    Integer register(String phone, String password,String nickname,String headimg);
}

com.renda.user.controller.UserController

@RestController
@RequestMapping("/user")
public class UserController {
?
    @Reference // dubbo 远程消费
    private UserService userService;
?
    @GetMapping("/login")
    public UserDTO login(String phone, String password, String nickname, String heading) {
        UserDTO userDTO=new UserDTO();
        User user;
?
        if (nickname==null || nickname.isEmpty()) {
            nickname=phone;
        }
?
        System.out.println(phone);
        System.out.println(password);
        System.out.println(nickname);
?
        // 检测手机号是否注册
        if (0==userService.checkPhone(phone)) {
            // 未注册,先自动注册,然后登录
            userService.register(phone, password, nickname, heading);
            userDTO.setMessage("手机号没有被注册,现已自动注册");
            user=userService.login(phone, password);
        } else {
            // 已经注册,直接进行登录
            user=userService.login(phone, password);
            if (user==null) {
                userDTO.setState(300);
                userDTO.setMessage("帐号密码不匹配,登录失败!");
            } else {
                userDTO.setState(200);
                userDTO.setMessage("登录成功!");
            }
        }
?
        userDTO.setContent(user);
        return userDTO;
    }
?
}

src\main\webapp\index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login">
    <p><input type="text" placeholder="请输入手机号..." name="phone"></p>
    <p><input type="text" placeholder="请输入密码..." name="password"></p>
    <p>
        <button>登录</button>
    </p>
</form>
</body>
</html>

使用 Tomcat 插件 8002 端口:

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
                <port>8002</port>
                <path>/</path>
            </configuration>
            <executions>
                <execution>
                    <!-- 打包完成后,运行服务 -->
                    <phase>package</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
...

启动 dubbo-admin 来监控消费者和提供者的状态。

使用 Maven 在 lagou-edu-web 下执行 package 命令启动消费者;同时确保服务提供者也启动完毕。

浏览器访问:http://localhost:8002/,输入已有的用户名和密码测试登录功能,输入新的用户名和密码测试注册功能,控制台和网页查看输出结果。


课程模块

course 课程

teacher 老师

activity_course 课程活动

course_section 章节

course_lesson 课时

course_media 课节视频

一个 course 对一个 teacher

一个 course 对一个 activity_course

一个 course 对多个 course_section

一个 course_section 对多个 course_lesson

一个 course_lesson 对多个 course_media

全部课程

功能描述:用户在未登录状态,获取所有上架的课程,课程顺序为 - 配置活动信息标签的优先显示,再根据课程显示序列号顺序显示;序列号相同按照创建时间倒序显示,课程都是未购买状态。

功能接口:/course/getAllCourse

lagou-edu-entity

使用 Easy Code 快速生成对应的实体类,再使用 Lombok 注解取代原来冗余的 get 和 set、空构造、全参数构造。

com.renda.entity.Course

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Course implements Serializable {
?
    private static final long serialVersionUID=337303050449398216L;
?
    // 一门课程对应一个讲师
    private Teacher teacher;
    //一门课程对应多个章节
    private List<CourseSection> courseSections;
    // 一门课对一个活动
    private ActivityCourse activityCourse;
?
    ...
}

com.renda.entity.Teacher

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Teacher implements Serializable {
    private static final long serialVersionUID=-97051504830274283L;
?
    ...
}

com.renda.entity.ActivityCourse

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class ActivityCourse implements Serializable {
    private static final long serialVersionUID=576079752103902168L;
?
    ...   
}

com.renda.entity.CourseSection

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class CourseSection implements Serializable {
    private static final long serialVersionUID=-40082782487572703L;
?
    // 一章对应多个小节
    private List<CourseLesson> courseLessons;
?
    ...
}

com.renda.entity.CourseLesson

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class CourseLesson implements Serializable {
    private static final long serialVersionUID=-29342440566142798L;
?
    // 一小节课对应一个视频
    private CourseMedia courseMedia;
?
    ...
}

com.renda.entity.CourseMedia

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class CourseMedia implements Serializable {
    private static final long serialVersionUID=-93086504227451781L;
?
    ...
}

lagou-edu-dao

使用 Easy Code 快速生成 Course 的 mapper 文件,然后进行修改。

src\main\resources\com\renda\mapper\CourseDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.renda.mapper.CourseDao">
?
    <resultMap type="com.renda.entity.Course" id="CourseMap">
        <result property="id" column="c_id" jdbcType="OTHER"/>
        <result property="courseName" column="course_name" jdbcType="VARCHAR"/>
        <result property="brief" column="brief" jdbcType="VARCHAR"/>
        <result property="price" column="price" jdbcType="OTHER"/>
        <result property="priceTag" column="price_tag" jdbcType="VARCHAR"/>
        <result property="discounts" column="discounts" jdbcType="OTHER"/>
        <result property="discountsTag" column="discounts_tag" jdbcType="VARCHAR"/>
        <result property="courseDescriptionMarkDown" column="course_description_mark_down" jdbcType="OTHER"/>
        <result property="courseDescription" column="course_description" jdbcType="OTHER"/>
        <result property="courseImgUrl" column="course_img_url" jdbcType="VARCHAR"/>
        <result property="isNew" column="is_new" jdbcType="OTHER"/>
        <result property="isNewDes" column="is_new_des" jdbcType="VARCHAR"/>
        <result property="lastOperatorId" column="last_operator_id" jdbcType="INTEGER"/>
        <result property="autoOnlineTime" column="auto_online_time" jdbcType="TIMESTAMP"/>
        <result property="createTime" column="c_create_time" jdbcType="TIMESTAMP"/>
        <result property="updateTime" column="c_update_time" jdbcType="TIMESTAMP"/>
        <result property="isDel" column="c_is_del" jdbcType="OTHER"/>
        <result property="totalDuration" column="total_duration" jdbcType="INTEGER"/>
        <result property="courseListImg" column="course_list_img" jdbcType="VARCHAR"/>
        <result property="status" column="c_status" jdbcType="INTEGER"/>
        <result property="sortNum" column="sort_num" jdbcType="INTEGER"/>
        <result property="previewFirstField" column="preview_first_field" jdbcType="VARCHAR"/>
        <result property="previewSecondField" column="preview_second_field" jdbcType="VARCHAR"/>
        <result property="sales" column="sales" jdbcType="INTEGER"/>
        <!-- 一个老师 -->
        <association property="teacher" javaType="com.renda.entity.Teacher">
            <result property="id" column="t_id" jdbcType="OTHER"/>
            <result property="courseId" column="t_course_id" jdbcType="INTEGER"/>
            <result property="teacherName" column="teacher_name" jdbcType="VARCHAR"/>
            <result property="position" column="position" jdbcType="VARCHAR"/>
            <result property="description" column="t_description" jdbcType="VARCHAR"/>
            <result property="createTime" column="t_create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="t_update_time" jdbcType="TIMESTAMP"/>
            <result property="isDel" column="t_is_del" jdbcType="OTHER"/>
        </association>
        <!-- 一个活动课程 -->
        <association property="activityCourse" javaType="com.renda.entity.ActivityCourse">
            <result property="id" column="ac_id" jdbcType="INTEGER"/>
            <result property="courseId" column="ac_course_id" jdbcType="INTEGER"/>
            <result property="beginTime" column="begin_time" jdbcType="TIMESTAMP"/>
            <result property="endTime" column="end_time" jdbcType="TIMESTAMP"/>
            <result property="amount" column="amount" jdbcType="OTHER"/>
            <result property="stock" column="stock" jdbcType="INTEGER"/>
            <result property="status" column="ac_status" jdbcType="OTHER"/>
            <result property="isDel" column="ac_is_del" jdbcType="OTHER"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
            <result property="createTime" column="ac_create_time" jdbcType="TIMESTAMP"/>
            <result property="createUser" column="create_user" jdbcType="VARCHAR"/>
            <result property="updateTime" column="ac_update_time" jdbcType="TIMESTAMP"/>
            <result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
        </association>
        <!-- 多个章节 -->
        <collection property="courseSections" ofType="com.renda.entity.CourseSection">
            <result property="id" column="cs_id" jdbcType="OTHER"/>
            <result property="courseId" column="cs_course_id" jdbcType="INTEGER"/>
            <result property="sectionName" column="section_name" jdbcType="VARCHAR"/>
            <result property="description" column="cs_description" jdbcType="VARCHAR"/>
            <result property="createTime" column="cs_create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="cs_update_time" jdbcType="TIMESTAMP"/>
            <result property="isDe" column="is_de" jdbcType="OTHER"/>
            <result property="orderNum" column="cs_order_num" jdbcType="INTEGER"/>
            <result property="status" column="cs_status" jdbcType="INTEGER"/>
            <!-- 多个小节 -->
            <collection property="courseLessons" ofType="com.renda.entity.CourseLesson">
                <result property="id" column="cl_id" jdbcType="OTHER"/>
                <result property="courseId" column="cl_course_id" jdbcType="INTEGER"/>
                <result property="sectionId" column="cl_section_id" jdbcType="INTEGER"/>
                <result property="theme" column="theme" jdbcType="VARCHAR"/>
                <result property="duration" column="cl_duration" jdbcType="INTEGER"/>
                <result property="isFree" column="is_free" jdbcType="OTHER"/>
                <result property="createTime" column="cl_create_time" jdbcType="TIMESTAMP"/>
                <result property="updateTime" column="cl_update_time" jdbcType="TIMESTAMP"/>
                <result property="isDel" column="cl_is_del" jdbcType="OTHER"/>
                <result property="orderNum" column="cl_order_num" jdbcType="INTEGER"/>
                <result property="status" column="cl_status" jdbcType="INTEGER"/>
                <!-- 一个小节视频 -->
                <association property="courseMedia" javaType="com.renda.entity.CourseMedia">
                    <result property="id" column="cm_id" jdbcType="INTEGER"/>
                    <result property="courseId" column="cm_course_id" jdbcType="INTEGER"/>
                    <result property="sectionId" column="cm_section_id" jdbcType="INTEGER"/>
                    <result property="lessonId" column="cm_lesson_id" jdbcType="INTEGER"/>
                    <result property="coverImageUrl" column="cover_image_url" jdbcType="VARCHAR"/>
                    <result property="duration" column="cm_duration" jdbcType="VARCHAR"/>
                    <result property="fileEdk" column="file_edk" jdbcType="VARCHAR"/>
                    <result property="fileSize" column="file_size" jdbcType="OTHER"/>
                    <result property="fileName" column="file_name" jdbcType="VARCHAR"/>
                    <result property="fileDk" column="file_dk" jdbcType="VARCHAR"/>
                    <result property="createTime" column="cm_create_time" jdbcType="TIMESTAMP"/>
                    <result property="updateTime" column="cm_update_time" jdbcType="TIMESTAMP"/>
                    <result property="isDel" column="cm_is_del" jdbcType="OTHER"/>
                    <result property="durationNum" column="duration_num" jdbcType="INTEGER"/>
                    <result property="fileId" column="file_id" jdbcType="VARCHAR"/>
                </association>
            </collection>
        </collection>
    </resultMap>
?
    <sql id="courseInfo">
    select
        c.id c_id,`course_name`,`brief`,`price`,`price_tag`,`discounts`,`discounts_tag`,`course_description_mark_down`,
        `course_description`,`course_img_url`,`is_new`,`is_new_des`,`last_operator_id`,`auto_online_time`,
        c.create_time c_create_time,c.update_time c_update_time,c.is_del c_is_del,`total_duration`,`course_list_img`,
        c.status c_status,`sort_num`,`preview_first_field`,`preview_second_field`,`sales`,
        t.id t_id, t.course_id t_course_id,`teacher_name`,`position`,t.description t_description,t.create_time t_create_time,
        t.update_time t_update_time,t.is_del t_is_del,
        cs.id cs_id, cs.course_id cs_course_id,`section_name`, cs.description cs_description,cs.create_time cs_create_time,
        cs.update_time cs_update_time,`is_de`,cs.order_num cs_order_num ,cs.status cs_status,
        cl.id cl_id,cl.course_id cl_course_id,cl.section_id cl_section_id, `theme`,cl.duration cl_duration,`is_free`,
        cl.create_time cl_create_time,cl.update_time cl_update_time, cl.is_del cl_is_del,cl.order_num cl_order_num,
        cl.status cl_status,
        cm.id cm_id,cm.course_id cm_course_id, cm.section_id cm_section_id ,cm.lesson_id cm_lesson_id,`cover_image_url`,
        cm.duration cm_duration,`file_edk`, `file_size`,`file_name`,`file_dk`,cm.create_time cm_create_time,
        cm.update_time cm_update_time,cm.is_del cm_is_del, `duration_num`,`file_id`, `begin_time`,`end_time`,`amount`,`stock`,
        ac.status ac_status,ac.is_del ac_is_del,`remark`,ac.create_time ac_create_time,`create_user`,ac.update_time ac_update_time,`update_user`
    from activity_course ac right join course c on c.id=ac.course_id
                            inner join teacher t on c.id=t.course_id
                            inner join course_section cs on c.id=cs.course_id
                            inner join course_lesson cl on cl.section_id=cs.id
                            left join course_media cm on cm.lesson_id=cl.id
    </sql>
?
    <select id="getAllCourse" resultMap="CourseMap">
        <include refid="courseInfo"/>
        order by amount desc, c_id, ac_create_time desc
    </select>
?
</mapper>

com.renda.mapper.CourseDao

public interface CourseDao {
    /**
     * 查询全部课程信息
     */
    List<Course> getAllCourse();
}

src\test\java\course\TestCourse.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/spring-dao.xml"})
public class TestCourse {
?
    @Autowired
    private CourseDao courseDao;
?
    @Test
    public void getAllCourse() {
        List<Course> list=courseDao.getAllCourse();
        for (Course course : list) {
            String flag=course.getActivityCourse() !=null ? "【火爆活动中】" : "";
            System.out.println("课程:" + flag + course.getId() + "->" + course.getCourseName());
            for (CourseSection cs : course.getCourseSections()) {
                System.out.println("\t\t章节" + cs.getId() + "--->" + cs.getSectionName());
                for (CourseLesson cl : cs.getCourseLessons()) {
                    if (cl.getCourseMedia() !=null) {
                        System.out.println("\t\t\t小节" + cl.getId() + "--->" + cl.getTheme()
                                + ",视频:" + cl.getCourseMedia().getFileId() + ",时长:【"
                                + cl.getCourseMedia().getDuration() + "】");
                    } else {
                        System.out.println("\t\t\t小节" + cl.getId() + "--->" + cl.getTheme()
                                + ",视频:【待上传】,时长:【00:00】");
                    }
                }
            }
        }
    }
?
}

lagou-edu-service

com.renda.course.CourseService

public interface CourseService {
    /**
     * 查询全部课程信息
     */
    List<Course> getAllCourse();
}

com.renda.course.impl.CourseServiceImpl

@Service
public class CourseServiceImpl implements CourseService {
    @Autowired
    private CourseDao courseDao;
?
    @Override
    public List<Course> getAllCourse() {
        return courseDao.getAllCourse();
    }
}

lagou-edu-web

com.renda.course.CourseService

public interface CourseService {
    List<Course> getAllCourse();
}

com.renda.course.controller.CourseController

@RestController
@RequestMapping("/course")
public class CourseController {
    // 远程消费
    @Reference
    private CourseService courseService;
?
    @GetMapping("/getAllCourse")
    public List<Course> getAllCourse() {
        return courseService.getAllCourse();
    }
}

浏览器访问:http://localhost:8002/course/getAllCourse

已购课程

功能描述:1、用户未登录则显示为空;2、用户登录,通过用户 ID 调用服务获取已购课程。

功能接口:/course/getCourseByUserId/{userid}

lagou-edu-dao

src\main\resources\com\renda\mapper\CourseDao.xml

...
<select id="getCourseByUserId" resultMap="CourseMap">
    <include refid="courseInfo"/>
    where c.id in
    (select course_id from user_course_order where status=20 and is_del=0 and user_id=#{userId})
    order by amount desc, c_id, ac_create_time desc
</select>
...

com.renda.mapper.CourseDao

public interface CourseDao {
    ...
?
    /**
     * 查询已登录用户购买的全部课程信息
     * @return
     */
    List<Course> getCourseByUserId(@Param("userId") String userId);
}

src\test\java\course\TestCourse.java

...
@Test
public void getCoursesByUserid() {
    List<Course> list=courseDao.getCourseByUserId("100030018");
    for (Course course : list) {
        String flag=course.getActivityCourse() !=null ? "【火爆活动中】" : "";
        System.out.println("课程:" + flag + course.getId() + "->" + course.getCourseName());
        for (CourseSection cs : course.getCourseSections()) {
            System.out.println("\t\t章节" + cs.getId() + "--->" + cs.getSectionName());
            for (CourseLesson cl : cs.getCourseLessons()) {
                if (cl.getCourseMedia() !=null) {
                    System.out.println("\t\t\t小节" + cl.getId() + "--->" + cl.getTheme()
                                       + ",视频:" + cl.getCourseMedia().getFileId()
                                       + ",时长:【" + cl.getCourseMedia().getDuration() + "】");
                } else {
                    System.out.println("\t\t\t小节" + cl.getId() + "--->" + cl.getTheme()
                                       + ",视频:【待上传】,时长:【00:00】");
                }
            }
        }
    }
}
...

lagou-edu-service

com.renda.course.CourseService

public interface CourseService {
    ...
    List<Course> getCourseByUserId(String userId);
}

com.renda.course.impl.CourseServiceImpl

@Service
public class CourseServiceImpl implements CourseService {
    ...
    @Override
    public List<Course> getCourseByUserId(String userId) {
        return courseDao.getCourseByUserId(userId);
    }
}

lagou-edu-web

com.renda.course.CourseService

public interface CourseService {
    ...
    List<Course> getCourseByUserId(String userId);
}

com.renda.course.controller.CourseController

@RestController
@RequestMapping("/course")
public class CourseController {
    ...
?
    @GetMapping("getCourseByUserId/{userid}")
    public List<Course> getCourseByUserId(@PathVariable("userid") String userid) {
        return courseService.getCourseByUserId(userid);
    }
}

浏览器访问:http://localhost:8002/course/getCourseByUserId/100030018

课程详情

功能描述:

1、用户如果没有登录,通过课程 ID 获取课程的详细信息中会显示“立即购买”按钮。点击够买按钮会显示登录。同时会展示课程目录,课程信息和老师信息。注意课程信息是展示字段course_description 中的信息。

2、用户登录后,我们通过课程Id获取课程信息后,会通过用户 ID 和课程 ID 调用订单服务来获取来判断用户是否购买,如果够买则显示“立即学习”,否则显示“立即够买”,同时会展示课程目录,课程信息和老师信息。注意课程信息是展示字段 course_description 中的信息。

功能接口:/course/getCourseById/{courseid}

lagou-edu-dao

src\main\resources\com\renda\mapper\CourseDao.xml

...
<select id="getCourseById" resultMap="CourseMap">
    <include refid="courseInfo"/>
    where c.id=#{courseid}
</select>
...

com.renda.mapper.CourseDao

public interface CourseDao {
    ...
?
    /**
     * 查询某门课程的详细信息
     *
     * @param courseid 课程编号
     */
    Course getCourseById(@Param("courseid") Integer courseid);
}

src\test\java\course\TestCourse.java

...
@Test
public void getCourseById() {
    Course course=courseDao.getCourseById(7);
    String flag=course.getActivityCourse() !=null ? "【火爆活动中】" : "";
    System.out.println("课程:" + flag + course.getId() + "->" + course.getCourseName());
    for (CourseSection cs : course.getCourseSections()) {
        System.out.println("\t\t章节" + cs.getId() + "--->" + cs.getSectionName());
        for (CourseLesson cl : cs.getCourseLessons()) {
            if (cl.getCourseMedia() !=null) {
                System.out.println("\t\t\t小节" + cl.getId() + "--->" + cl.getTheme()
                                   + ",视频:" + cl.getCourseMedia().getFileId()
                                   + ",时长:【" + cl.getCourseMedia().getDuration() + "】");
            } else {
                System.out.println("\t\t\t小节" + cl.getId() + "--->" + cl.getTheme()
                                   + ",视频:【待上传】,时长:【00:00】");
            }
        }
    }
}
...

lagou-edu-service

com.renda.course.CourseService

public interface CourseService {
    ...
    Course getCourseById(Integer courseid);
}

com.renda.course.impl.CourseServiceImpl

@Service
public class CourseServiceImpl implements CourseService {
    ...
    @Override
    public Course getCourseById(Integer courseid) {
        return courseDao.getCourseById(courseid);
    }
}

lagou-edu-web

com.renda.course.CourseService

public interface CourseService {
    ...
    Course getCourseById(Integer courseid);
}

com.renda.course.controller.CourseController

@RestController
@RequestMapping("/course")
public class CourseController {
    ...
    @GetMapping("getCourseById/{courseid}")
    public Course getCourseById(@PathVariable("courseid") Integer courseid) {
        return courseService.getCourseById(courseid);
    }
}

浏览器访问:http://localhost:8002/course/getCourseById/7

课程播放

功能描述:

前端通过课时 ID 调用接口
1、获取课程阿里的 fileId,然后通过 fileId 调用接口
2、获取视频播放的 playAuth,前端会通过 playAuth 调用阿里的播放器,阿里会回调接口
3、通过阿里的回调来判断是否是合法用户,用户是否购买课程,这样可以防止播放链接被盗后也不能被播放,确保课程版权的安全。

功能接口:

1、通过课时ID获取媒体信息 /front/course/media/getByLessonId 2、获取阿里播放 key /front/course/media/alikey 3、获取阿里播放 key (用于阿里的回调) /front/course/media/alikey

想了解更多,欢迎关注我的微信公众号:Renda_Zhang

置学历是指在办理自考本科毕业手续前,考生所持有的国民教育序列的专科(或以上)的学历。 申请自考本科专业毕业的考生,须在上半年5月20日前、下半年11月20日前,登录广东省自学考试管理系统(以下称“系统”,网址:http://www.stegd.edu.cn/selfec/),提交前置学历信息及学历认证信息。如何填写?快收好这份前置学历填写指南吧!

1

第一种类型:《教育部学历证书电子注册备案表》

填写具体步骤:

1.登陆学信网https://my.chsi.com.cn/archive/index.jsp、

2.请先注册学信网账号



若已注册,请直接选择登录



3. 登录后,点击“申请”



4.点击页面右边的“查看”



5.点击“申请中文版”,若已申请,请略过第五和第六步骤。



6.报告有效期设置为2个月(或以上),然后点击“申请”。



7.点击“查看”。



8. 登录广东省自学考试管理系统

(网址:http://www.stegd.edu.cn/selfec/login/login.jsp ),点击系统左边栏“考籍管理”的“前置学历信息管理”。

注:若出现系统无法登录或信息无法提交等问题,可尝试使用QQ浏览器,或者将电脑浏览器改成ie兼容模式和急速模式,或者使用手机登录。



9.点击“新增”,若需修改,请点击“修改”。

10. 根据《教育部学历证书电子注册备案表》的相关内容,在系统上填写对应信息。



注意事项:

(1) 前置学历姓名:请填写备案表上的姓名,若备案表上的姓名为曾用名,请将显示曾用名的户口本或公安局出具的证明和毕业申请的材料一起上交;

(2) 证件类型:请选择前置学历毕业时所用的证件,并填写证件号;

(3) 毕业证号数字之间请勿添加空格;

(4) 前置学历专业名称请与备案表上的专业名称保持一致,标点符号请使用半角符号。例: 工程造价(造价管理),请勿简写成工程造价。

(5) 毕业时间格式为:201706;

(6) 前置学历层次请按备案表上的填写;

(7) 认证类型:请选择“《教育部学历证书电子注册备案表》在线验证码”;



(8) 在线验证码的数字之间请勿添加空格;

(9) 本科结业,亦可用于申请前置学历。

2

第二种类型:《中国高等教育学历认证报告》

选择此方式填写的考生,可向广东省学历认证中心咨询办理。(联系电话:020-37626800)

取得《中国高等教育学历认证报告》后,即可登录系统填写。

登录系统方式,可参照第一种类型的第8点和第9点。

《中国高等教育学历认证报告》格式多样,以下仅举两例,请参照填写。

范例一:



范例二:



注意事项:

(1) 前置学历姓名:请填写认证报告上的姓名,若认证报告上的姓名为曾用名,请将显示曾用名的户口本或公安局出具的证明和毕业申请的材料一起上交;

(2) 证件类型:请选择前置学历毕业时所用的证件,并填写证件号;

(3) 毕业证号数字之间请勿添加空格;

(4) 毕业证号必须与报告显示的证书编号一致,若报告显示的证书编号含文字,填写时也请保留文字;

(5) 前置学历专业名称的内容请与认证报告上的专业名称保持一致,标点符号请使用半角符号。例: 工程造价(造价管理),请勿简写成工程造价;

(6) 毕业时间格式为:201706;

(7) 前置学历层次请按认证报告上的填写;

(8) 认证类型:请选择“《中国高等教育学历认证报告》报告编号”;



(9) 认证报告编号为7位纯数字;

(10) 本科结业,亦可用于申请前置学历;

(11)广东省教育厅出具的《学历证书鉴定证明》。持此类报告的考生,请选择在学信网申请《教育部学历证书电子注册备案表》或重新办理《中国高等教育学历认证报告》。

3

第三种类型:《国外学位学历认证书》

持有国外学历的考生,请登录教育部留学服务中心网站

(网址:http://renzheng.cscse.edu.cn/Login.aspx)申请国(境)外学历学位认证书。

取得《国外学位学历认证书》后,即可登录系统填写。

登录系统方式,可参照第一种类型的第8点和第9点。

根据《国外学位学历认证书》的相关内容,在系统上填写对应信息。

因认证书格式众多,以下仅为示例:



注意事项:

(1) 前置学历姓名:请填写认证书上的姓名,若认证书上的姓名为曾用名,请将显示曾用名的户口本或公安局出具的证明和毕业申请的材料一起上交;

(2) 证件类型:请选择前置学历毕业时所用的证件,并填写证件号;

(3) 前置学历毕业证号可为空;

(4) 前置学历专业名称的内容请与认证书上的专业名称保持一致,标点符号请使用半角符号。例: 工程造价(造价管理),请勿简写成工程造价;

(5) 毕业时间格式为:201706;

(6) 认证类型:请选择“《国外学位学历认证书》认证书编号”;



(7) 国外学历证书编号的填写格式为:教留服认XX[XXXX]…号。请填写完整。

4

第四种类型:自考专科及本科同时申请毕业(即专本同办)

专本同办:同时申请办理广东省自考专科和本科毕业的考生。

此类考生填写前置学历时,请使用办理本科毕业的准考证号登录系统,按照系统指引正确填写专科相关信息。



注意事项:

(1)毕业证号为空;

(2)专业名称填写正确示例:行政管理;错误示例:A030301行政管理;

(3)毕业时间填写示例:201812;

(4)认证类型:请选择“自考专科及本科同时申请毕业”;



(5)专科准考证号:请填写广东自考的12位准考证号;

(6)填写专本同办的前置学历类型时,请确保专科准考证下的成绩已符合毕业条件。

2

第五种类型:普通全日制高校应届毕业生

在登记前置学历信息时尚未取得前置学历毕业证的普通全日制高校毕业生,须选择“普通高校应届毕业生”类型。

考生若选择此类型,无需向省考办提供学校出具的在读专业及预计毕业时间的纸质证明。

注意:此类考生取得前置学历毕业证后,须于7月5日前登录自考管理系统补填前置学历认证信息。认证申请及填写方法,请参考第一、第二种类型。未按时补填的,视为放弃本次毕业申请。



注意事项:

(1) 毕业证号可为空;

(2) 专业名称:请勿添加某系某班字样,直接填写专业名称;

(3) 前置学历毕业时间不能晚于本科毕业时间(上半年6月30日),否则不能申请本科毕业;

(4) 前置学历类型为“非自考”;

(5) 认证类型:请选择“普通高校应届毕业生,未取得毕业证”。

来源:粤考研究所talk自考。转载请联系皮皮。

海县教育局关于2020年春季学期延迟开学的公告

  为贯彻落实省教育厅《关于启动江苏省教育系统突发公共卫生事件一级响应的紧急通知》和市、县人民政府关于实施新型冠状病毒感染的肺炎疫情一级响应措施的通告要求,接市教育局通知,我县中小学、幼儿园春季学期开学时间由原定的2月10日暂延至2月17日,如有变化,另行通知。

  在延迟春季学期开学期间,各中小学、幼儿园要在引导学生不离家、不返校的同时,充分利用市“云海在线”、省“名师空中课堂”等平台,有效指导学生在家在线学习。

  (一)连云港市智慧教育云服务平台——“云海在线”登录方式:云海在线提供web版和手机客户端两种登录。

  电脑端登录:打开浏览器(建议使用谷歌或者火狐浏览器),在地址栏中输入网址:http://ren.lyge.cn,进入系统首页,点击首页右上角“登录”按钮进入登录界面,在登录界面中输入账号(手机号,身份证号)和密码,再点击“登录”即可。

  手机端登录:可以在应用市场下载“云海在线”手机APP或用手机浏览器的“扫一扫”功能,按照手机类别,扫描下方二维码,下载云海在线手机App,下载安装好App后,点击运行,进入登录界面,在登录界面输入云海在线的账号和密码,即可登录。

  学习内容:1、完成学校布置的寒假作业;2、选读学校推荐的课外名著等;3、利用“云海在线”的“微课中心”模块观看微课,完成任务单布置的学习任务。所有应用和服务均是免费公益性的。4、2月10日起,学生通过线上学习新学期预授课程,完成“任务单”学习任务。技术支持:朱老师,电话13675223895。

  (二)江苏省名师空中课堂登录方式:学生、家长可以通过手机端、电脑端登录省名师空中课堂学习及在线提问。

  电脑端登录:用注册的手机号登录。https://mskzkt.jse.edu.cn进行在线学习和在线提问。

  手机端登录:手机扫描如下二维码,注册登录进行在线学习以及在线提问。(注册需要用学籍号,

请登录https://xjgl.jse.edu.cn/studman2/cidGetInfo.jsp)

  学习内容:利用“名师空中课堂”视频资源进行线上学习。可进行在线提问,名师在线即时答疑。技术支持:郑老师,电话13705136801。

  (三)各学校利用自有网络平台提供线上服务。各校要提前制定好学生假期课业辅导工作应急预案,要求教师通过电话、微信等网络等平台开展线上咨询和辅导,指导学生在家自主学习,科学布置假期作业。同时要全面禁止有偿、友情家教等集体性线下活动行为发生。

  处在湖北等疫情重点防控地区的师生员工等待通知返校。

东海县教育局

2020年1月27日