教育项目后端开发
1. 技术选型
- 前端技术
| 技术名称 | 说明 |
| Vue.js | 是一套用于构建用户界面的渐进式JavaScript框架 |
| Element UI库 |
element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库,方便程序员进行页面 快速布局和构建 |
| node.js | 简单的说 Node.js 就是运行在服务端的 JavaScript 运行环境 |
| axios | 对ajax的封装, 简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax 的封装 |
- 后端技术
| 技术名称 | 说明 |
| Web层 | 借助springmvc接收请求,进行视图跳转 |
| Service层 | 借助spring进行IOC、AOP、及事务管理 |
| dao层 | 借助mybatis进行数据库交互 |
| EasyCode插件 | IDEA快速生成实体类的插件 |
| Zookeeper | 服务注册与服务发现 |
| Dubbo | 分布式框架,远程RPC调用 |
| Redis | 内存数据库,缓存 |
| Lombok | 消除实体类中冗余的get和set |
| SpringSocial | SpringSocial (Spring社交),简单理解就是和第三方应用打交道,微信登录用 |
- 开发工具
- 后端: IDEA 2019
- 前端: VS code
- 数据库客户端工具: SQLYog
- 开发环境
- JDK 11
- Maven 3.6.3
- MySQL 5.7
- Zookeeper 3.6.0
- Dubbo 2.5.7
- Redis 5.0.4
2. 项目架构
后端项目架构,我们采用dubbo的生产者和消费者的理论,创建服务提供方和服务消费方两个工程,通过maven聚合工程来搭建,模块划分如下:
- 服务提供
- lagou-edu-parent:pom聚合父工程,统一依赖设置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>lagou-edu-parent</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>lagou-edu-entity</module> <module>lagou-edu-web</module> <module>lagou-edu-service</module> <module>lagou-edu-mapper</module> </modules> <properties> <spring.version>5.0.6.RELEASE</spring.version> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 跳过test maven package 时将不执行 test --> <maven.test.skip>true</maven.test.skip> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- Mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency> <!-- 数据库 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.32</version> </dependency> <!--dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.7</version> </dependency> <!--zookeeper --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <!--zookeeper客户端 --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.11.0.GA</version> </dependency> <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!--spring操作redis的工具类--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.3.2.RELEASE</version> </dependency> <!--redis客户端--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.1.0</version> </dependency> <!--json解析工具--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> </dependencies> </project>
- lagou-edu-entity:jar工程,封装实体类
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>lagou-edu-parent</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lagou-edu-entity</artifactId> <dependencies> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> </dependencies> </project>
- lagou-edu-mapper:jar工程,封装与数据库打交道的部分
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>lagou-edu-parent</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lagou-edu-mapper</artifactId> <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>lagou-edu-entity</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
-
- jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/edu?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT jdbc.username=root jsbc.password=123456 maxActive=10 minIdle=5
- mybatis.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>
- 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="mapper"/> <!--2.数据连接池--> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jsbc.password}"/> <property name="maxActive" value="${maxActive}"/> <property name="minIdle" value="${minIdle}"/> </bean> <!--3.sqlsessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis.xml"/> </bean> <!--4.事务管理器--> <!-- 事务处理--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--5.开启事务--> <tx:annotation-driven/> <!-- mapper自动映射--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="mapper"/> </bean> </beans>
- lagou-edu-service:web工程,暴露服务的接口和实现
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>lagou-edu-parent</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lagou-edu-service</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>lagou-edu-mapper</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <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> </project>
- spring/spring-service.xml
<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" 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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--1.服务提供方在zookeeper中的“别名”--> <dubbo:application name="edu-service"/> <!--2.注册中心的地址--> <dubbo:registry address="zookeeper://192.168.80.128:2181"/> <!--3.扫描类(将什么包下的类作为服务提供类)--> <dubbo:annotation package="user,course,order"/> <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="port" value="6379"/> <property name="hostName" value="192.168.80.128"/> </bean> </beans>
- web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <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>
- 服务消费
- lagou-edu-web:web工程,接收前端工程发来的请求,远程调用服务并消费
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>lagou-edu-parent</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lagou-edu-web</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.example</groupId> <artifactId>lagou-edu-mapper</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 因为有jsp页面,所以引用servlet依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <scope>provided</scope> <version>2.5</version> </dependency> <!-- 页面提交过来的请求,使用springmvc来处理--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.7.RELEASE</version> </dependency> <!-- java连接fastDFS的客户端工具--> <dependency> <groupId>net.oschina.zcx7878</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27.0.0</version> </dependency> <!-- 图片上传到FastDFS需要用的到IO工具--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> <!-- 图片保存到web服务器需要用到的IO工具--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!--用来转换java对象和json字符串,注意,2.7以上版本必须搭配spring5.0以上--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> </dependencies> <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> </project>
- spring-web.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" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--json转换器--> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json"/> <property name="features"> <array> <value>WriteMapNullValue</value> <value>WriteDateUseDateFormat</value> </array> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!--1.服务提供方在zookeeper中的“别名”--> <dubbo:application name="edu-web"/> <!--2.注册中心的地址--> <dubbo:registry address="zookeeper://192.168.80.128:2181"/> <!--3.扫描类(将什么包下的类作为服务提供类)--> <dubbo:annotation package="controller"/> <!--上传文件的解析器(规定上传文件的大小限制)--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上传文件最大限制:2GB--> <property name="maxUploadSize" value="2048000000"/> </bean> </beans>
- web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 解决post乱码 --> <filter> <filter-name>charset</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>charset</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-web.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
- fastdfs-client.properties
##fastdfs-client.properties fastdfs.connect_timeout_in_seconds = 5 fastdfs.network_timeout_in_seconds = 30 fastdfs.charset = UTF-8 fastdfs.http_anti_steal_token = false fastdfs.http_secret_key = FastDFS1234567890 fastdfs.http_tracker_http_port = 80 fastdfs.tracker_servers = 192.168.80.128:22122
- lagou-edu-web:web工程,接收前端工程发来的请求,远程调用服务并消费
3. 功能模块
- 用户模块:用户登录与自动注册
- entity
package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.io.Serializable; import java.util.Date; /** * 用户表(User)实体类 * * @author makejava * @since 2021-08-07 19:37:22 */ @Data //getter and setter @ToString//tostring @AllArgsConstructor//全参构造 @NoArgsConstructor//无参构造 public class User implements Serializable { private static final long serialVersionUID = -97254888032084895L; /** * 用户id */ private Integer id; /** * 用户昵称 */ private String name; /** * 用户头像地址 */ private String portrait; /** * 注册手机 */ private String phone; /** * 用户密码(可以为空,支持只用验证码注册、登录) */ private String password; /** * 注册ip */ private String regIp; /** * 是否有效用户 */ private Object accountNonExpired; /** * 账号是否未过期 */ private Object credentialsNonExpired; /** * 是否未锁定 */ private Object accountNonLocked; /** * 用户状态:ENABLE能登录,DISABLE不能登录 */ private String status; /** * 是否删除 */ private Object isDel; /** * 注册时间 */ private Date createTime; /** * 记录更新时间 */ private Date updateTime; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; @Data @AllArgsConstructor @NoArgsConstructor @ToString public class UserDTO<T> { private int state; private String message; private Boolean success; private T content; }
- mapper
<?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="mapper.UserDao"> <resultMap type="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="VARCHAR"/> <result property="credentialsNonExpired" column="credentials_non_expired" jdbcType="VARCHAR"/> <result property="accountNonLocked" column="account_non_locked" jdbcType="VARCHAR"/> <result property="status" column="status" jdbcType="VARCHAR"/> <result property="isDel" column="is_del" jdbcType="VARCHAR"/> <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="getUser" resultType="int"> select count(*) from user where phone=#{phone}; </select> <insert id="saveUser"> insert into user ( name, phone, password, create_time, update_time) values (#{phone},#{phone},#{password},sysdate(),sysdate()); </insert> <update id="updateUserInfo" > update user set name=#{name},portrait=#{portrait} where id=#{userid} </update> <update id="updatePassword"> update user set password=#{password} where id=#{userid} </update> </mapper>
package mapper; import entity.User; import org.apache.ibatis.annotations.Param; /** * 用户表(User)表数据库访问层 * * @author makejava * @since 2021-08-07 19:37:26 */ public interface UserDao { /** * 用户登录和注册 * @param phone 手机 * @param password 密码 * @return 返回用户 */ User login(@Param("phone") String phone, @Param("password") String password); /** * 根据电话查看用户是否注册 * @param phone 手机 * @return */ Integer getUser(@Param("phone") String phone); /** * 若无该用户 实现用户注册 * @param phone 手机 * @param password 密码 * @return 1代表注册成功,0代表失败 */ Integer saveUser(@Param("phone") String phone, @Param("password") String password); /** * 修改个人信息 * @param userid 用户ID * @param portrait 用户头像地址,fileid * @param name 用户昵称 * @return */ Integer updateUserInfo(@Param("userid") Integer userid, @Param("portrait") String portrait, @Param("name") String name); /** * 修改密码 * @param userid 用户ID * @param password 用户密码 * @return */ Integer updatePassword(@Param("userid") Integer userid, @Param("password") String password); }
- service
package user.service; import entity.User; import org.apache.ibatis.annotations.Param; /** * 用户表(User)表服务接口 * * @author makejava * @since 2021-08-07 19:37:28 */ public interface UserService { /** * 用户登录和注册 * @param phone 手机 * @param password 密码 * @return 返回用户 */ User login(String phone,String password); /** * 根据电话查看用户是否注册 * @param phone 手机 * @return */ Integer getUser(String phone); /** * 若无该用户 实现用户注册 * @param phone 手机 * @param password 密码 * @return 1代表注册成功,0代表失败 */ Integer saveUser(String phone, String password); /** * 修改个人信息 * @param userid 用户ID * @param portrait 用户头像地址,fileid * @param name 用户昵称 * @return */ Integer updateUserInfo(Integer userid,String portrait, String name); /** * 修改密码 * @param userid 用户ID * @param password 用户密码 * @return */ Integer updatePassword(Integer userid,String password); } package user.service.impl; import com.alibaba.dubbo.config.annotation.Service; import mapper.UserDao; import org.springframework.beans.factory.annotation.Autowired; import user.service.UserService; import entity.User; /** * 用户表(User)表服务实现类 * * @author makejava * @since 2021-08-07 19:37:29 */ @Service 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 getUser(String phone) { return userDao.getUser(phone); } @Override public Integer saveUser(String phone, String password) { return userDao.saveUser(phone,password); } @Override public Integer updateUserInfo(Integer userid, String portrait, String name) { return userDao.updateUserInfo(userid,portrait,name); } @Override public Integer updatePassword(Integer userid, String password) { return userDao.updatePassword(userid,password); } }
- web
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2021/8/7 Time: 21:39 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登陆</title> </head> <body> <form action="/user/login" method="post"> 电话<input type="text" name="phone"><br> 密码<input type="text" name="password"><br> <input type="submit" value="登陆"> </form> </body> </html> <%-- Created by IntelliJ IDEA. User: Administrator Date: 2021/8/8 Time: 17:32 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>修改密码</title> </head> <body> <form action="/user/updatePassword" method="post"> 用户ID<input type="text" name="userid"> 密码<br> <input type="password" name="password"><br> <input type="submit" value="提交"> </form> </body> </html> <%-- Created by IntelliJ IDEA. User: Administrator Date: 2021/8/8 Time: 17:07 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>更新用户头像与昵称</title> </head> <body> <form action="/user/updateUserInfo" method="post" enctype="multipart/form-data"> 用户ID<input type="text" name="userid"> 头像<br> <input type="file" name="portrait"> <br> 昵称<br> <input type="text" name="name"><br> <input type="submit" value="提交"> </form> </body> </html>
package controller; import com.alibaba.dubbo.config.annotation.Reference; import entity.User; import entity.UserDTO; import org.csource.common.NameValuePair; import org.csource.fastdfs.*; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import user.service.UserService; import java.io.File; import java.util.UUID; /** * 用户表(User)表控制层 * * @author makejava * @since 2021-08-07 19:37:30 */ @RestController @CrossOrigin(origins = "*") @RequestMapping("/user") public class UserController { @Reference private UserService userService; @RequestMapping("/login") public UserDTO<User> login( String phone, String password) { UserDTO<User> userDTO = new UserDTO<>(); User user = null; //判断用户是否注册 Integer flag = userService.getUser(phone); if (flag == 0) { // 用户不存在,进行注册 Integer i = userService.saveUser(phone, password); if (i == 1) { userDTO.setMessage("已自动帮用户注册,请牢记密码"); userDTO.setState(200); } user = userService.login(phone, password); } else { // 用户存在,已经注册过 user = userService.login(phone, password); if (user != null) { userDTO.setMessage("成功登陆"); userDTO.setState(200); } } if (user == null) { userDTO.setMessage("登陆失败"); userDTO.setState(404); } userDTO.setContent(user); return userDTO; } @RequestMapping("/updateUserInfo") public UserDTO<User> updateUserInfo(Integer userid, String name, MultipartFile portrait) throws Exception{ UserDTO<User> userDTO = new UserDTO<>(); /* 1、把文件保存到web服务器*/ // 从文件对象中获取 文件的原始名称 String oldname = portrait.getOriginalFilename(); // 通过字符串截取的方式,从文件原始名中获取文件的后缀 1.jpg String suffix = oldname.substring(oldname.lastIndexOf(".") + 1); // 为了避免文件因为同名而覆盖,生成全新的文件名 String newName= UUID.randomUUID().toString()+"."+suffix; // 创建web服务器保存文件的目录(预先创建好D:/upload目录,否则系统找不到路径,会抛异常) File tosave=new File("D:/upload/"+newName); // 将路径转换成文件 portrait.transferTo(tosave); // 获取服务器的绝对路径 String filepath=tosave.getAbsolutePath(); /* 2、把文件从web服务器上传到FastDFS*/ ClientGlobal.initByProperties("fastdfs-client.properties"); TrackerClient trackerClient=new TrackerClient(); TrackerServer trackerServer = trackerClient.getConnection(); StorageServer storageServer=null; StorageClient1 client = new StorageClient1(trackerServer, storageServer); NameValuePair[] list=new NameValuePair[1]; list[0]=new NameValuePair("filename",oldname); String fileId = client.upload_file1(filepath, suffix, list); trackerServer.close(); // 将信息保存到数据库 Integer integer = userService.updateUserInfo(userid, fileId, name); if(integer==1){ //上传成功 userDTO.setState(200); userDTO.setMessage("修改成功"); userDTO.setSuccess(true); }else { //上传失败 userDTO.setState(404); userDTO.setMessage("修改失败"); userDTO.setSuccess(false); } return userDTO; } @RequestMapping("/updatePassword") public UserDTO<User> updatePassword( Integer userid, String password) { Integer integer = userService.updatePassword(userid, password); UserDTO<User> userDTO = new UserDTO<>(); if (integer == 1) { userDTO.setState(200); userDTO.setMessage("修改成功"); userDTO.setSuccess(true); } else { userDTO.setState(404); userDTO.setMessage("修改失败"); userDTO.setSuccess(false); } return userDTO; } }
package user.service; import com.alibaba.dubbo.config.annotation.Service; import entity.User; import org.apache.ibatis.annotations.Param; /** * 用户表(User)表服务接口 * * @author makejava * @since 2021-08-07 19:37:28 */ @Service public interface UserService { User login(String phone,String password); Integer getUser(String phone); Integer saveUser(String phone,String password); Integer updateUserInfo(Integer userid,String portrait, String name); Integer updatePassword(Integer userid,String password); }
- entity
- 课程模块(全部课程、课程详情和已购课程)
- entity
package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; import java.util.List; /** * 课程(Course)实体类 * * @author rf * @since 2021-08-08 09:42:05 */ @ToString @AllArgsConstructor @NoArgsConstructor @Data public class Course implements Serializable { private static final long serialVersionUID = 445636495595519664L; /** * id */ private Object id; /** * 课程名 */ private String courseName; /** * 课程一句话简介 */ private String brief; /** * 原价 */ private Object price; /** * 原价标签 */ private String priceTag; /** * 优惠价 */ private Object discounts; /** * 优惠标签 */ private String discountsTag; /** * 描述markdown */ private Object courseDescriptionMarkDown; /** * 课程描述 */ private Object courseDescription; /** * 课程分享图片url */ private String courseImgUrl; /** * 是否新品 */ private Object isNew; /** * 广告语 */ private String isNewDes; /** * 最后操作者 */ private Integer lastOperatorId; /** * 自动上架时间 */ private Date autoOnlineTime; /** * 记录创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除 */ private Object isDel; /** * 总时长(分钟) */ private Integer totalDuration; /** * 课程列表展示图片 */ private String courseListImg; /** * 课程状态,0-草稿,1-上架 */ private Integer status; /** * 课程排序,用于后台保存草稿时用到 */ private Integer sortNum; /** * 课程预览第一个字段 */ private String previewFirstField; /** * 课程预览第二个字段 */ private String previewSecondField; /** * 销量 */ private Integer sales; /** * 一个课程对应一个老师 */ private Teacher teacher; /** * 一个课程对应多个章节 */ private List<CourseSection> courseSections; /** * 一门课程对应一个活动 */ private ActivityCourse activityCourse; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; /** * 课程节内容(CourseLesson)实体类 * * @author rf * @since 2021-08-08 09:40:51 */ @ToString @AllArgsConstructor @NoArgsConstructor @Data public class CourseLesson implements Serializable { private static final long serialVersionUID = 520529912835263208L; /** * id */ private Object id; /** * 课程id */ private Integer courseId; /** * 章节id */ private Integer sectionId; /** * 课时主题 */ private String theme; /** * 课时时长(分钟) */ private Integer duration; /** * 是否免费 */ private Object isFree; /** * 记录创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除 */ private Object isDel; /** * 排序字段 */ private Integer orderNum; /** * 课时状态,0-隐藏,1-未发布,2-已发布 */ private Integer status; /** * 一个课时对应一个视频 */ private CourseMedia courseMedia; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; /** * 课节视频表(CourseMedia)实体类 * * @author rf * @since 2021-08-08 09:41:12 */ @ToString @AllArgsConstructor @NoArgsConstructor @Data public class CourseMedia implements Serializable { private static final long serialVersionUID = 155066115199022003L; /** * 课程媒体主键ID */ private Integer id; /** * 课程Id */ private Integer courseId; /** * 章ID */ private Integer sectionId; /** * 课时ID */ private Integer lessonId; /** * 封面图URL */ private String coverImageUrl; /** * 时长(06:02) */ private String duration; /** * 媒体资源文件对应的EDK */ private String fileEdk; /** * 文件大小MB */ private Object fileSize; /** * 文件名称 */ private String fileName; /** * 媒体资源文件对应的DK */ private String fileDk; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除,0未删除,1删除 */ private Object isDel; /** * 时长,秒数(主要用于音频在H5控件中使用) */ private Integer durationNum; /** * 媒体资源文件ID */ private String fileId; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; import java.util.List; /** * 课程章节表(CourseSection)实体类 * * @author rf * @since 2021-08-08 09:41:23 */ @ToString @AllArgsConstructor @NoArgsConstructor @Data public class CourseSection implements Serializable { private static final long serialVersionUID = -66412570985265991L; /** * id */ private Object id; /** * 课程id */ private Integer courseId; /** * 章节名 */ private String sectionName; /** * 章节描述 */ private String description; /** * 记录创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除 */ private Object isDe; /** * 排序字段 */ private Integer orderNum; /** * 状态,0:隐藏;1:待更新;2:已发布 */ private Integer status; /** * 一个章节对应多个课时 */ private List<CourseLesson> courseLessons; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; /** * 活动课程表(ActivityCourse)实体类 * * @author rf * @since 2021-08-08 09:41:56 */ @ToString @AllArgsConstructor @NoArgsConstructor @Data public class ActivityCourse implements Serializable { private static final long serialVersionUID = -56925806434053935L; /** * 主键ID */ private Integer id; /** * 课程ID */ private Integer courseId; /** * 活动开始时间 */ private Date beginTime; /** * 活动结束时间 */ private Date endTime; /** * 活动价格 */ private Object amount; /** * 库存值 */ private Integer stock; /** * 状态 0未上架 10已上架 */ private Object status; /** * 逻辑删除 0未删除 1删除 */ private Object isDel; /** * 备注 */ private String remark; /** * 创建时间 */ private Date createTime; /** * 创建人 */ private String createUser; /** * 更新时间 */ private Date updateTime; /** * 更新人 */ private String updateUser; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; /** * 讲师表(Teacher)实体类 * * @author rf * @since 2021-08-08 09:41:42 */ @ToString @AllArgsConstructor @NoArgsConstructor @Data public class Teacher implements Serializable { private static final long serialVersionUID = 160268292591285816L; /** * id */ private Object id; /** * 课程ID */ private Integer courseId; /** * 讲师姓名 */ private String teacherName; /** * 职务 */ private String position; /** * 讲师介绍 */ private String description; /** * 记录创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除 */ private Object isDel; }
- mapper
package mapper; import entity.Course; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 课程(Course)表数据库访问层 * * @author rf * @since 2021-08-08 09:42:06 */ public interface CourseDao { /** * 获取所有课程 * @return */ List<Course> getAllCourse(); /** * 查询已登录用户购买的全部课程信息 * @param userId 用户id * @return */ List<Course> getCourseByUserId(@Param("userId") String userId); /** * 根据课程ID查询课程详情 * @param courseId 课程ID * @return */ Course getCourseById(@Param("courseId") String courseId); }
<?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="mapper.UserDao"> <resultMap type="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="VARCHAR"/> <result property="credentialsNonExpired" column="credentials_non_expired" jdbcType="VARCHAR"/> <result property="accountNonLocked" column="account_non_locked" jdbcType="VARCHAR"/> <result property="status" column="status" jdbcType="VARCHAR"/> <result property="isDel" column="is_del" jdbcType="VARCHAR"/> <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="getUser" resultType="int"> select count(*) from user where phone=#{phone}; </select> <insert id="saveUser"> insert into user ( name, phone, password, create_time, update_time) values (#{phone},#{phone},#{password},sysdate(),sysdate()); </insert> <update id="updateUserInfo" > update user set name=#{name},portrait=#{portrait} where id=#{userid} </update> <update id="updatePassword"> update user set password=#{password} where id=#{userid} </update> </mapper>
- service
-
package course.service.impl; import com.alibaba.dubbo.config.annotation.Service; import course.service.CourseCommentService; import entity.CourseComment; import mapper.CourseCommentDao; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * 课程留言表(CourseComment)表服务实现类 * * @author rf * @since 2021-08-08 15:22:18 */ @Service public class CourseCommentServiceImpl implements CourseCommentService { @Autowired private CourseCommentDao courseCommentDao; @Override public Integer saveCourseComment(CourseComment courseComment) { return courseCommentDao.saveCourseComment(courseComment); } @Override public List<CourseComment> getCourseCommentList(Integer courseId, int offset, int pageSize) { return courseCommentDao.getCourseCommentList(courseId, offset, pageSize); } @Override public Integer saveFavorite(Integer userId, int commentId) { Integer existsflag = courseCommentDao.existsFavourite(userId, commentId); int i1 = 0; int i2 = 0; if(existsflag==0){ i1 = courseCommentDao.saveCommentFavourite(userId, commentId); }else { i1=courseCommentDao.updateCommentFavourite(userId,commentId,0); } i2=courseCommentDao.updateCommentLikeCount(commentId,1); if(i1==0||i2==0){ throw new RuntimeException("点赞失败!"); } return commentId; } @Override public Integer cancelFavorite(Integer userId, int commentId) { int i1 = courseCommentDao.updateCommentFavourite(userId,commentId,1); int i2=courseCommentDao.updateCommentLikeCount(commentId,-1); if(i1==0||i2==0){ throw new RuntimeException("取消点赞失败!"); } return commentId; } } package course.service; import entity.Course; import entity.CourseComment; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 课程(Course)表服务接口 * * @author rf * @since 2021-08-08 09:42:06 */ public interface CourseService { /** * 获取所有课程 * @return */ List<Course> getAllCourse(); /** * 查询已登录用户购买的全部课程信息 * @param userid * @return */ List<Course> getCourseByUserId(String userid); /** * 根据课程ID查询课程详情 * @param courseId 课程ID * @return */ Course getCourseById(String courseId); }
-
- web
package controller; import com.alibaba.dubbo.config.annotation.Reference; import course.service.CourseService; import entity.Course; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 课程(Course)表控制层 * * @author rf * @since 2021-08-08 09:42:06 */ @RestController @CrossOrigin(origins = "*") @RequestMapping("/course") public class CourseController { @Reference private CourseService courseService; @RequestMapping("/getAllCourse") public List<Course> getAllCourse(){ List<Course> courseList = courseService.getAllCourse(); return courseList; } @RequestMapping("/getCourseByUserId/{userid}") public List<Course> getCourseByUserId(@PathVariable("userid") String userid){ List<Course> courseList = courseService.getCourseByUserId(userid); return courseList; } @RequestMapping("/getCourseById/{courseid}") public Course getCourseById(@PathVariable("courseid") String courseid){ Course course = courseService.getCourseById(courseid); return course; } }
package course.service; import com.alibaba.dubbo.config.annotation.Service; import entity.Course; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 课程(Course)表服务接口 * * @author rf * @since 2021-08-08 09:42:06 */ public interface CourseService { /** * 获取所有课程 * @return */ List<Course> getAllCourse(); /** * 查询已登录用户购买的全部课程信息 * @param userid * @return */ List<Course> getCourseByUserId(String userid); /** * 根据课程ID查询课程详情 * @param courseId 课程ID * @return */ Course getCourseById(String courseId); }
- entity
- 留言模块(保存留言、留言列表和点赞取消赞)
- entity
package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; import java.util.List; /** * 课程留言表(CourseComment)实体类 * * @author rf * @since 2021-08-08 15:05:10 */ @Data @AllArgsConstructor @NoArgsConstructor @ToString public class CourseComment implements Serializable { private static final long serialVersionUID = -20052680386644151L; /** * 主键 */ private Object id; /** * 课程id */ private Integer courseId; /** * 章节id */ private Integer sectionId; /** * 课时id */ private Integer lessonId; /** * 用户id */ private Integer userId; /** * 运营设置用户昵称 */ private String userName; /** * 父级评论id */ private Integer parentId; /** * 是否置顶:0不置顶,1置顶 */ private Object isTop; /** * 评论 */ private String comment; /** * 点赞数 */ private Integer likeCount; /** * 是否回复留言:0普通留言,1回复留言 */ private Object isReply; /** * 留言类型:0用户留言,1讲师留言,2运营马甲 3讲师回复 4小编回复 5官方客服回复 */ private Integer type; /** * 留言状态:0待审核,1审核通过,2审核不通过,3已删除 */ private Integer status; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除 */ private Object isDel; /** * 最后操作者id */ private Integer lastOperator; /** * 是否发送了通知,1表示未发出,0表示已发出 */ private Object isNotify; /** * 标记归属 */ private Object markBelong; /** * 回复状态 0 未回复 1 已回复 */ private Object replied; /** * 一条评论对应多条点赞信息 */ private List<CourseCommentFavoriteRecord> favoriteRecordList; } package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; /** * 课程留言点赞表(CourseCommentFavoriteRecord)实体类 * * @author rf * @since 2021-08-08 16:01:10 */ @Data @AllArgsConstructor @NoArgsConstructor @ToString public class CourseCommentFavoriteRecord implements Serializable { private static final long serialVersionUID = -77878555306759427L; /** * 用户评论点赞j记录ID */ private Integer id; /** * 用户ID */ private Integer userId; /** * 用户评论ID */ private Integer commentId; /** * 是否删除,0:未删除(已赞),1:已删除(取消赞状态) */ private Object isDel; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; }
- mapper
package mapper; import entity.CourseComment; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 课程留言表(CourseComment)表数据库访问层 * * @author rf * @since 2021-08-08 15:06:55 */ public interface CourseCommentDao { /** * 保存留言 * @param courseComment 留言内容对象 * @return 受影响的行数 */ Integer saveCourseComment(CourseComment courseComment); /** * 通过课程Id、页号/分页获取留言信息 * @param courseId 课程Id * @param pageSize 每页条数 * @return 留言信息 */ List<CourseComment> getCourseCommentList(@Param("courseId") Integer courseId, @Param("offset") int offset, @Param("pageSize") int pageSize); /** * 根据用户ID和留言ID查看留言是否存在点赞信息 * @param userId 用户ID * @param commentId 留言ID * @return 是否存在点赞信息,>0存在 */ Integer existsFavourite(@Param("userId") Integer userId, @Param("commentId") int commentId); /** * 保存点赞信息 * @param userId 用户ID * @param commentId 留言ID * @return 1保存成功 0 保存失败 */ Integer saveCommentFavourite(@Param("userId") Integer userId, @Param("commentId") int commentId); /** * 更新点赞信息的状态(将is_del=0,表示已赞) * @param userId 用户ID * @param commentId 留言ID * @param isDel 点赞信息状态 * @return */ Integer updateCommentFavourite(@Param("userId") Integer userId, @Param("commentId") int commentId, @Param("isDel") int isDel); /** * 更新对应留言的点赞数量。 * @param commentId 某条留言的编号 * @param x 更新的点赞数量,正为+,负为- * @return */ Integer updateCommentLikeCount(@Param("commentId") int commentId, @Param("x") Integer x); }
<?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="mapper.CourseCommentDao"> <resultMap type="entity.CourseComment" id="CourseCommentMap"> <result property="id" column="cc_id" jdbcType="VARCHAR"/> <result property="courseId" column="course_id" jdbcType="INTEGER"/> <result property="sectionId" column="section_id" jdbcType="INTEGER"/> <result property="lessonId" column="lesson_id" jdbcType="INTEGER"/> <result property="userId" column="cc_user_id" jdbcType="INTEGER"/> <result property="userName" column="user_name" jdbcType="VARCHAR"/> <result property="parentId" column="parent_id" jdbcType="INTEGER"/> <result property="isTop" column="is_top" jdbcType="VARCHAR"/> <result property="comment" column="comment" jdbcType="VARCHAR"/> <result property="likeCount" column="like_count" jdbcType="INTEGER"/> <result property="isReply" column="is_reply" jdbcType="VARCHAR"/> <result property="type" column="type" jdbcType="INTEGER"/> <result property="status" column="status" jdbcType="INTEGER"/> <result property="createTime" column="cc_create_time" jdbcType="TIMESTAMP"/> <result property="updateTime" column="cc_update_time" jdbcType="TIMESTAMP"/> <result property="isDel" column="cc_is_del" jdbcType="VARCHAR"/> <result property="lastOperator" column="last_operator" jdbcType="INTEGER"/> <result property="isNotify" column="is_notify" jdbcType="VARCHAR"/> <result property="markBelong" column="mark_belong" jdbcType="VARCHAR"/> <result property="replied" column="replied" jdbcType="VARCHAR"/> <collection property="favoriteRecordList" ofType="entity.CourseCommentFavoriteRecord"> <result property="id" column="ccfr_id" jdbcType="INTEGER"/> <result property="userId" column="ccfr_user_id" jdbcType="INTEGER"/> <result property="commentId" column="comment_id" jdbcType="INTEGER"/> <result property="isDel" column="ccfr_is_del" jdbcType="VARCHAR"/> <result property="createTime" column="ccfr_create_time" jdbcType="TIMESTAMP"/> <result property="updateTime" column="ccfr_update_time" jdbcType="TIMESTAMP"/> </collection> </resultMap> <insert id="saveCourseComment"> -- `parent_id` int(11) DEFAULT NULL COMMENT '父级评论id', -- `is_top` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否置顶:0不置顶,1置顶', -- `like_count` int(11) NOT NULL DEFAULT '0' COMMENT '点赞数', -- `is_reply` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否回复留言:0普通留言,1回复留言', -- `type` int(1) NOT NULL COMMENT '留言类型:0用户留言,1讲师留言,2运营马甲 3讲师回复 4小编回复 5官方客服回复', -- `status` int(1) NOT NULL COMMENT '留言状态:0待审核,1审核通过,2审核不通过,3已删除', -- `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',0未删除 1已删除 -- `is_notify` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否发送了通知,1表示未发出,0表示已发出', -- `mark_belong` tinyint(1) DEFAULT '0' COMMENT '标记归属', -- `replied` tinyint(1) DEFAULT '0' COMMENT '回复状态 0 未回复 1 已回复', insert into course_comment(course_id,section_id,lesson_id,user_id,user_name,parent_id,is_top,comment,like_count,is_reply,type,status,create_time,update_time,is_del,last_operator,is_notify,mark_belong,replied) values (#{courseId},#{sectionId},#{lessonId},#{userId},#{userName},#{parentId},0,#{comment},0,0,#{type},0,sysdate(),sysdate(),0,#{lastOperator},1,0,0) </insert> <select id="getCourseCommentList" resultMap="CourseCommentMap"> select cc.id cc_id, cc.course_id, cc.section_id, cc.lesson_id, cc.user_id cc_user_id, cc.user_name, cc.parent_id, cc.is_top, cc.comment, cc.like_count, cc.is_reply, cc.type, cc.status, cc.create_time cc_create_time, cc.update_time cc_update_time, cc.is_del cc_is_del, cc.last_operator, cc.is_notify, cc.mark_belong, cc.replied, ccfr.id ccfr_id, ccfr.user_id ccfr_user_id, ccfr.comment_id, ccfr.is_del ccfr_is_del, ccfr.create_time ccfr_create_time, ccfr.update_time ccfr_update_time from course_comment cc left join (select * from course_comment_favorite_record where is_del=0) ccfr on cc.id=ccfr.comment_id where cc.course_id= #{courseId} and cc.is_del= 0 order by cc.is_top desc,cc.like_count desc,cc.create_time desc limit #{offset},#{pageSize} </select> <!--查看某个用户的某条留言是否存在点赞信息--> <select id="existsFavourite" resultType="int"> select count(*) from course_comment_favorite_record where user_id=#{userId} and comment_id=#{commentId} </select> <!--没有点赞信息,保存点赞信息--> <insert id="saveCommentFavourite"> insert into course_comment_favorite_record (user_id, comment_id, is_del, create_time, update_time) values (#{userId},#{commentId},0,sysdate(),sysdate()) </insert> <!--修改点赞的状态,0表示点赞,1表示取消赞--> <update id="updateCommentFavourite"> update course_comment_favorite_record set is_del=#{isDel} where comment_id=#{commentId} and user_id=#{userId} </update> <!--点赞之后,赞的数量+1;取消赞之后,赞的数量-1--> <update id="updateCommentLikeCount"> update course_comment set like_count =like_count+ #{x} where id=#{commentId} </update> </mapper>
- service
package course.service.impl; import com.alibaba.dubbo.config.annotation.Service; import course.service.CourseCommentService; import entity.CourseComment; import mapper.CourseCommentDao; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * 课程留言表(CourseComment)表服务实现类 * * @author rf * @since 2021-08-08 15:22:18 */ @Service public class CourseCommentServiceImpl implements CourseCommentService { @Autowired private CourseCommentDao courseCommentDao; @Override public Integer saveCourseComment(CourseComment courseComment) { return courseCommentDao.saveCourseComment(courseComment); } @Override public List<CourseComment> getCourseCommentList(Integer courseId, int offset, int pageSize) { return courseCommentDao.getCourseCommentList(courseId, offset, pageSize); } @Override public Integer saveFavorite(Integer userId, int commentId) { Integer existsflag = courseCommentDao.existsFavourite(userId, commentId); int i1 = 0; int i2 = 0; if(existsflag==0){ i1 = courseCommentDao.saveCommentFavourite(userId, commentId); }else { i1=courseCommentDao.updateCommentFavourite(userId,commentId,0); } i2=courseCommentDao.updateCommentLikeCount(commentId,1); if(i1==0||i2==0){ throw new RuntimeException("点赞失败!"); } return commentId; } @Override public Integer cancelFavorite(Integer userId, int commentId) { int i1 = courseCommentDao.updateCommentFavourite(userId,commentId,1); int i2=courseCommentDao.updateCommentLikeCount(commentId,-1); if(i1==0||i2==0){ throw new RuntimeException("取消点赞失败!"); } return commentId; } } package course.service; import entity.CourseComment; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 课程留言表(CourseComment)表服务接口 * * @author rf * @since 2021-08-08 15:22:18 */ public interface CourseCommentService { /** * 保存留言 * @param courseComment 留言内容对象 * @return 受影响的行数 */ Integer saveCourseComment(CourseComment courseComment); /** * 通过课程Id、页号/分页获取留言信息 * @param courseId 课程Id * @param pageSize 每页条数 * @return 留言信息 */ List<CourseComment> getCourseCommentList( Integer courseId, int offset,int pageSize); /** * 点赞 * @param commentId 留言编号 * @param userId 用户编号 * @return 0:保存失败,1:保存成功 */ Integer saveFavorite(Integer userId,int commentId); /** * 取消点赞 * @param commentId 留言编号 * @param userId 用户编号 * @return 0:保存失败,1:保存成功 */ Integer cancelFavorite(Integer userId,int commentId); }
- web
package controller; import com.alibaba.dubbo.config.annotation.Reference; import course.service.CourseCommentService; import entity.CourseComment; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.UnsupportedEncodingException; import java.util.List; /** * 课程留言表(CourseComment)表控制层 * * @author rf * @since 2021-08-08 15:24:35 */ @RestController @CrossOrigin(origins = "*") @RequestMapping("/course/comment") public class CourseCommentController { @Reference private CourseCommentService courseCommentService; @RequestMapping("/saveCourseComment") public CourseComment saveCourseComment(Integer courseId,Integer userId,String username,String comment) throws UnsupportedEncodingException { username = new String( username.getBytes("ISO-8859-1"),"UTF-8" ); comment = new String( comment.getBytes("ISO-8859-1"),"UTF-8" ); CourseComment courseComment = new CourseComment(); courseComment.setCourseId(courseId); // 课程编号 courseComment.setSectionId(0); // 章节编号,保留版本 courseComment.setLessonId(0);// 小节编号,保留版本 courseComment.setUserId(userId); // 用户编号 courseComment.setUserName(username); // 用户昵称 courseComment.setParentId(0); //没有父id,保留版本 courseComment.setComment(comment);// 留言内容 courseComment.setType(0); // 0用户留言,保留版本 courseComment.setLastOperator(userId); //最后操作的用户编号 Integer i = courseCommentService.saveCourseComment(courseComment); System.out.println(i); return courseComment; } @RequestMapping("/getCourseCommentList/{courseid}/{pageIndex}/{pageSize}") public List<CourseComment> getCommentsByCourseId(@PathVariable("courseid") Integer courseid, @PathVariable("pageIndex")Integer pageIndex,@PathVariable("pageSize")Integer pageSize){ int offset=(pageIndex-1)*pageSize; List<CourseComment> list = courseCommentService.getCourseCommentList(courseid, offset, pageSize); return list; } // 点赞 @RequestMapping("/saveFavorite/{commentid}/{userid}") public Integer saveFavorite(@PathVariable("commentid") Integer commentid,@PathVariable("userid") Integer userid){ Integer integer = courseCommentService.saveFavorite(userid,commentid); return integer; } // 取消赞 @RequestMapping("/cancelFavorite/{commentid}/{userid}") public Integer cancelFavorite(@PathVariable("commentid") Integer commentid,@PathVariable("userid") Integer userid){ Integer integer = courseCommentService.cancelFavorite(userid, commentid); return integer; } }
package course.service; import entity.CourseComment; import java.util.List; /** * 课程留言表(CourseComment)表服务接口 * * @author rf * @since 2021-08-08 15:22:18 */ public interface CourseCommentService { /** * 保存留言 * @param courseComment 留言内容对象 * @return 受影响的行数 */ Integer saveCourseComment(CourseComment courseComment); /** * 通过课程Id、页号/分页获取留言信息 * @param courseId 课程Id * @param pageSize 每页条数 * @return 留言信息 */ List<CourseComment> getCourseCommentList(Integer courseId, int offset, int pageSize); /** * 点赞 * @param commentId 留言编号 * @param userId 用户编号 * @return 0:保存失败,1:保存成功 */ Integer saveFavorite(Integer userId,int commentId); /** * 取消点赞 * @param commentId 留言编号 * @param userId 用户编号 * @return 0:保存失败,1:保存成功 */ Integer cancelFavorite(Integer userId,int commentId); }
- entity
- 订单模块(购买、生成订单和订单增删改查操作)
- entity
package entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.util.Date; import java.io.Serializable; /** * 用户课程订单表(UserCourseOrder)实体类 * * @author rf * @since 2021-08-08 14:12:19 */ @Data @AllArgsConstructor @NoArgsConstructor @ToString public class UserCourseOrder implements Serializable { private static final long serialVersionUID = 767604293699407462L; /** * 主键 */ private Long id; /** * 订单号 */ private String orderNo; /** * 用户id */ private Object userId; /** * 课程id,根据订单中的课程类型来选择 */ private Object courseId; /** * 活动课程id */ private Integer activityCourseId; /** * 订单来源类型: 1 用户下单购买 2 后台添加专栏 */ private Object sourceType; /** * 当前状态: 0已创建 10未支付 20已支付 30已取消 40已过期 */ private Object status; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; /** * 是否删除 */ private Object isDel; }
- mapper
package mapper; import entity.UserCourseOrder; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 用户课程订单表(UserCourseOrder)表数据库访问层 * * @author rf * @since 2021-08-08 14:12:49 */ public interface UserCourseOrderDao { /** * * @param orderNo 随机生成的订单号 * @param userId 用户ID * @param courseId 课程ID * @param activityCourseId 是否为活动课程 * @param sourceType '订单来源类型: 1 用户下单购买 2 后台添加专栏', * @return */ Integer saveOrder(@Param("orderNo") String orderNo, @Param("userId") String userId, @Param("courseId") String courseId, @Param("activityCourseId") String activityCourseId, @Param("sourceType") String sourceType); /** * 修改订单状态 * @param orderNo 订单号 * @return */ Integer updateOrder(@Param("orderNo") String orderNo, @Param("status") int status); /** * 删除订单信息 * @param orderNo 订单号 */ Integer deleteOrder(@Param("orderNo") String orderNo); /** * 根据用户ID查看订单信息 * @param userid 用户ID * @return */ List<UserCourseOrder> getOrdersByUserId(@Param("userid") String userid); }
<?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="mapper.UserCourseOrderDao"> <resultMap type="entity.UserCourseOrder" id="UserCourseOrderMap"> <result property="id" column="id" jdbcType="INTEGER"/> <result property="orderNo" column="order_no" jdbcType="VARCHAR"/> <result property="userId" column="user_id" jdbcType="VARCHAR"/> <result property="courseId" column="course_id" jdbcType="VARCHAR"/> <result property="activityCourseId" column="activity_course_id" jdbcType="INTEGER"/> <result property="sourceType" column="source_type" jdbcType="VARCHAR"/> <result property="status" column="status" jdbcType="VARCHAR"/> <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/> <result property="isDel" column="is_del" jdbcType="VARCHAR"/> </resultMap> <insert id="saveOrder"> -- '当前状态: 0已创建 10未支付 20已支付 30已取消 40已过期 ', insert into user_course_order (order_no,user_id,course_id,activity_course_id,source_type,status,create_time,update_time,is_del) values (#{orderNo},#{userId},#{courseId},#{activityCourseId},#{sourceType},0,SYSDATE(),SYSDATE(),0) </insert> <update id="updateOrder"> update user_course_order set status=#{status} where order_no=#{orderNo} and is_del=0 </update> <update id="deleteOrder"> update user_course_order set is_del=1 where order_no=#{orderNo} </update> <select id="getOrdersByUserId" resultMap="UserCourseOrderMap"> select * from user_course_order where user_id=#{userid} and is_del=0 </select> </mapper>
- service
package order.service.impl; import com.alibaba.dubbo.config.annotation.Service; import entity.UserCourseOrder; import mapper.UserCourseOrderDao; import order.service.UserCourseOrderService; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * 用户课程订单表(UserCourseOrder)表服务实现类 * * @author rf * @since 2021-08-08 14:24:37 */ @Service public class UserCourseOrderServiceImpl implements UserCourseOrderService { @Autowired private UserCourseOrderDao userCourseOrderDao; @Override public Integer saveOrder(String orderNo, String userId, String courseId, String activityCourseId, String sourceType) { return userCourseOrderDao.saveOrder(orderNo, userId, courseId, activityCourseId, sourceType); } @Override public Integer updateOrder(String orderNo, int status) { return userCourseOrderDao.updateOrder(orderNo,status); } @Override public Integer deleteOrder(String orderNo) { return userCourseOrderDao.deleteOrder(orderNo); } @Override public List<UserCourseOrder> getOrdersByUserId(String userid) { return userCourseOrderDao.getOrdersByUserId(userid); } } package order.service; import entity.UserCourseOrder; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 用户课程订单表(UserCourseOrder)表服务接口 * * @author rf * @since 2021-08-08 14:24:35 */ public interface UserCourseOrderService { /** * * @param orderNo 随机生成的订单号 * @param userId 用户ID * @param courseId 课程ID * @param activityCourseId 是否为活动课程 * @param sourceType '订单来源类型: 1 用户下单购买 2 后台添加专栏', * @return 0创建订单失败 1 创建订单成功 */ Integer saveOrder( String orderNo, String userId, String courseId, String activityCourseId, String sourceType); /** * 修改订单状态 * @param orderNo 订单号 * @return */ Integer updateOrder( String orderNo,int status); /** * 删除订单信息 * @param orderNo 订单号 */ Integer deleteOrder( String orderNo); /** * 根据用户ID查看订单信息 * @param userid 用户ID * @return */ List<UserCourseOrder> getOrdersByUserId( String userid); }
- web
package controller; import com.alibaba.dubbo.config.annotation.Reference; import entity.UserCourseOrder; import order.service.UserCourseOrderService; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.UUID; /** * 用户课程订单表(UserCourseOrder)表控制层 * * @author rf * @since 2021-08-08 14:32:15 */ @RestController @CrossOrigin(origins = "*") @RequestMapping("/order") public class UserCourseOrderController { @Reference private UserCourseOrderService userCourseOrderService; @RequestMapping("/saveOrder/{userid}/{courseid}/{acid}/{stype}") public String saveOrder(@PathVariable("userid")String userid,@PathVariable("courseid")String courseid,@PathVariable("acid")String acid,@PathVariable("stype")String stype){ String orderNo= UUID.randomUUID().toString(); Integer integer = userCourseOrderService.saveOrder(orderNo, userid, courseid, acid, stype); if(integer!=0){ return orderNo; }return "创建订单失败"; } @RequestMapping("/updateOrder/{orderNo}/{status}") public String updateOrder(@PathVariable("orderNo")String orderNo,@PathVariable("status")int status){ Integer integer = userCourseOrderService.updateOrder(orderNo, status); if(integer!=0){ return "状态修改成功"; }return "状态修改失败"; } @RequestMapping("/deleteOrder/{orderNo}") public String deleteOrder(@PathVariable("orderNo")String orderNo){ Integer integer = userCourseOrderService.deleteOrder(orderNo); if(integer!=0){ return "订单删除成功"; }return "订单删除失败"; } @RequestMapping("/getOrdersByUserId/{userid}") public List<UserCourseOrder> getOrdersByUserId(@PathVariable("userid")String userid){ List<UserCourseOrder> orders = userCourseOrderService.getOrdersByUserId(userid); return orders; } }
package order.service; import entity.UserCourseOrder; import java.util.List; /** * 用户课程订单表(UserCourseOrder)表服务接口 * * @author rf * @since 2021-08-08 14:24:35 */ public interface UserCourseOrderService { /** * * @param orderNo 随机生成的订单号 * @param userId 用户ID * @param courseId 课程ID * @param activityCourseId 是否为活动课程 * @param sourceType '订单来源类型: 1 用户下单购买 2 后台添加专栏', * @return 0创建订单失败 1 创建订单成功 */ Integer saveOrder(String orderNo, String userId, String courseId, String activityCourseId, String sourceType); /** * 修改订单状态 * @param orderNo 订单号 * @return */ Integer updateOrder( String orderNo,int status); /** * 删除订单信息 * @param orderNo 订单号 */ Integer deleteOrder( String orderNo); /** * 根据用户ID查看订单信息 * @param userid 用户ID * @return */ List<UserCourseOrder> getOrdersByUserId(String userid); }
- entity
- entity
- mapper
- service
- web
浙公网安备 33010602011771号