提交 53461d99 编写于 作者: ZC~Reunion's avatar ZC~Reunion

Spring Cloud 整合!

上级 a68d2815
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### idea ###
idea
target
test/
/*.iml
### resource ###
data/
logs/
\ No newline at end of file
<?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>GuLi_mall</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<packaging>pom</packaging>
<modules>
<module>service_base</module>
<module>tool_utils</module>
</modules>
<dependencies>
<!-- redis -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- </dependency>-->
<!-- spring2.X集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided </scope>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<scope>provided</scope>
</dependency>
<!-- redis -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- </dependency>-->
<!-- spring2.X集成redis所需common-pool2
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
<?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>common</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service_base</artifactId>
</project>
\ No newline at end of file
//package com.zy.servicebase.config;
//
//import com.fasterxml.jackson.annotation.JsonAutoDetect;
//import com.fasterxml.jackson.annotation.PropertyAccessor;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import org.springframework.cache.CacheManager;
//import org.springframework.cache.annotation.CachingConfigurerSupport;
//import org.springframework.cache.annotation.EnableCaching;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.data.redis.cache.RedisCacheConfiguration;
//import org.springframework.data.redis.cache.RedisCacheManager;
//import org.springframework.data.redis.connection.RedisConnectionFactory;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
//import org.springframework.data.redis.serializer.RedisSerializationContext;
//import org.springframework.data.redis.serializer.RedisSerializer;
//import org.springframework.data.redis.serializer.StringRedisSerializer;
//
//import java.time.Duration;
//
//@EnableCaching
//@Configuration
//public class RedisConfig extends CachingConfigurerSupport {
//
// @Bean
// public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// RedisTemplate<String, Object> template = new RedisTemplate<>();
// RedisSerializer<String> redisSerializer = new StringRedisSerializer();
// Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// ObjectMapper om = new ObjectMapper();
// om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// jackson2JsonRedisSerializer.setObjectMapper(om);
// template.setConnectionFactory(factory);
// //key序列化方式
// template.setKeySerializer(redisSerializer);
// //value序列化
// template.setValueSerializer(jackson2JsonRedisSerializer);
// //value hashmap序列化
// template.setHashValueSerializer(jackson2JsonRedisSerializer);
// return template;
// }
//
// @Bean
// public CacheManager cacheManager(RedisConnectionFactory factory) {
// RedisSerializer<String> redisSerializer = new StringRedisSerializer();
// Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// //解决查询缓存转换异常的问题
// ObjectMapper om = new ObjectMapper();
// om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// jackson2JsonRedisSerializer.setObjectMapper(om);
// // 配置序列化(解决乱码的问题),过期时间600秒
// RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
// .entryTtl(Duration.ofSeconds(600))
// .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
// .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
// .disableCachingNullValues();
// RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
// .cacheDefaults(config)
// .build();
// return cacheManager;
// }
//}
package com.zy.servicebase.config;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author zhangyu
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket webApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
// .paths(Predicates.not(PathSelectors.regex("/admin/.*")))
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build();
}
private ApiInfo webApiInfo(){
return new ApiInfoBuilder()
.title("网站-课程中心API文档")
.description("本文档描述了课程中心微服务接口定义")
.version("1.0")
.contact(new Contact("Gardenia", "http://zyGardenia.com", "1511502172@qq.com"))
.build();
}
}
\ No newline at end of file
<?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>common</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>tool_utils</artifactId>
<dependencies>
<!-- JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.zy.commonutils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* 日期操作工具类
*
* @author qy
* @since 1.0
*/
public class DateUtil {
private static final String dateFormat = "yyyy-MM-dd";
/**
* 格式化日期
*
* @param date
* @return
*/
public static String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
return sdf.format(date);
}
/**
* 在日期date上增加amount天 。
*
* @param date 处理的日期,非null
* @param amount 要加的天数,可能为负数
*/
public static Date addDays(Date date, int amount) {
Calendar now =Calendar.getInstance();
now.setTime(date);
now.set(Calendar.DATE,now.get(Calendar.DATE)+amount);
return now.getTime();
}
public static void main(String[] args) {
System.out.println(DateUtil.formatDate(new Date()));
System.out.println(DateUtil.formatDate(DateUtil.addDays(new Date(), -1)));
}
}
package com.zy.commonutils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* @author zy
* @since 2019/10/16
*/
public class JwtUtils {
public static final long EXPIRE = 1000 * 60 * 60 * 24;
public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";
public static String getJwtToken(String id, String nickname){
String JwtToken = Jwts.builder()
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setSubject("guli-user")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
.claim("id", id)
.claim("nickname", nickname)
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效
* @param jwtToken
* @return
*/
public static boolean checkToken(String jwtToken) {
if(StringUtils.isEmpty(jwtToken)) {return false;}
try {
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
* @param request
* @return
*/
public static boolean checkToken(HttpServletRequest request) {
try {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) {return false;}
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据token获取会员id
* @param request
* @return
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) {return "";}
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
Claims claims = claimsJws.getBody();
return (String)claims.get("id");
}
}
package com.zy.commonutils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author zhangyu
*/
public final class MD5 {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错!!+" + e);
}
}
public static void main(String[] args) {
System.out.println(MD5.encrypt("111111"));
}
}
package com.zy.commonutils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhangyu
*/
@Data
public class R {
@ApiModelProperty(value = "是否成功")
private Boolean success;
@ApiModelProperty(value = "返回码")
private Integer code;
@ApiModelProperty(value = "返回消息")
private String message;
@ApiModelProperty(value = "返回数据")
private Map<String, Object> data = new HashMap<String, Object>();
/**
* 构造器私有化
*/
private R() { }
//成功静态方法
public static R ok() {
R r = new R();
r.setSuccess(true);
r.setCode(ResultCode.SUCCESS);
r.setMessage("成功");
return r;
}
//失败静态方法
public static R error() {
R r = new R();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("失败");
return r;
}
public R success(Boolean success) {
this.setSuccess(success);
return this;
}
public R message(String message) {
this.setMessage(message);
return this;
}
public R code(Integer code) {
this.setCode(code);
return this;
}
public R data(String key, Object value) {
this.data.put(key, value);
return this;
}
public R data(Map<String, Object> map) {
this.setData(map);
return this;
}
}
package com.zy.commonutils;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
/**
* 获取随机数
*
* @author zy
*
*/
public class RandomUtil {
private static final Random random = new Random();
private static final DecimalFormat fourdf = new DecimalFormat("0000");
private static final DecimalFormat sixdf = new DecimalFormat("000000");
public static String getFourBitRandom() {
return fourdf.format(random.nextInt(10000));
}
public static String getSixBitRandom() {
return sixdf.format(random.nextInt(1000000));
}
/**
* 给定数组,抽取n个数据
* @param list
* @param n
* @return
*/
public static ArrayList getRandom(List list, int n) {
Random random = new Random();
HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
// 生成随机数字并存入HashMap
for (int i = 0; i < list.size(); i++) {
int number = random.nextInt(100) + 1;
hashMap.put(number, i);
}
// 从HashMap导入数组
Object[] robjs = hashMap.values().toArray();
ArrayList r = new ArrayList();
// 遍历数组并打印数据
for (int i = 0; i < n; i++) {
r.add(list.get((int) robjs[i]));
System.out.print(list.get((int) robjs[i]) + "\t");
}
System.out.print("\n");
return r;
}
}
package com.zy.commonutils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author zhangyu
*/
public class ResponseUtil {
public static void out(HttpServletResponse response, R r) {
ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
try {
mapper.writeValue(response.getWriter(), r);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.zy.commonutils;
/**
* @author zhangyu
*/
public interface ResultCode {
/**
* SuccessFul
*/
public static Integer SUCCESS = 20000;
/**
* Failed
*/
public static Integer ERROR = 20001;
}
package com.zy.commonutils.exception;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/18 9:41
*/
public class ExceptionUtil {
public static String getMessage(Exception e){
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
e.printStackTrace(pw);
pw.flush();
sw.flush();
}finally {
if(sw != null){
try {
sw.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
if(pw != null){
pw.close();
}
}
return sw.toString();
}
}
package com.zy.commonutils.exception;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/18 20:56
*/
public class FileException extends RuntimeException {
// 状态码
private Integer code;
// 输出消息
private String msg;
public static final String FILE_UPLOAD_ERROR = "文件上传失败!!!";
}
package com.zy.commonutils.exception;
import com.zy.commonutils.R;
import com.zy.commonutils.exception.ExceptionUtil;
import com.zy.commonutils.exception.GuliException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author zhangyu
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理文件上传 及 下载异常
* @param e 异常
* @return 返回异常数据
*/
@ExceptionHandler(FileException.class)
@ResponseBody
public R error(FileException e){
e.printStackTrace();
return R.error().message("文件上传失败!!!");
}
/**
* 自定义的异常处理
* @param e 异常
* @return 返回数据
*/
@ExceptionHandler(GuliException.class)
@ResponseBody
public R error(GuliException e){
log.error(ExceptionUtil.getMessage(e));
e.printStackTrace();
return R.error().code(e.getCode()).message(e.getMsg());
}
}
package com.zy.commonutils.exception;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 自定义异常类
* @author zhangyu
*
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GuliException extends RuntimeException {
// 状态码
private Integer code;
// 输出消息
private String msg;
}
package com.zy.commonutils.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author zhangyu
*/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("gmtCreate", new Date(), metaObject);
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
}
package com.zy.commonutils.user;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhangyu
*/
@Data
public class CourseWebVoOrder implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
@ApiModelProperty(value = "课程标题")
private String title;
@ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
private BigDecimal price;
@ApiModelProperty(value = "总课时")
private Integer lessonNum;
@ApiModelProperty(value = "课程封面图片路径")
private String cover;
@ApiModelProperty(value = "销售数量")
private Long buyCount;
@ApiModelProperty(value = "浏览数量")
private Long viewCount;
@ApiModelProperty(value = "课程简介")
private String description;
@ApiModelProperty(value = "讲师ID")
private String teacherId;
@ApiModelProperty(value = "讲师姓名")
private String teacherName;
@ApiModelProperty(value = "讲师资历,一句话说明讲师")
private String intro;
@ApiModelProperty(value = "讲师头像")
private String avatar;
@ApiModelProperty(value = "课程类别ID")
private String subjectLevelOneId;
@ApiModelProperty(value = "类别名称")
private String subjectLevelOne;
@ApiModelProperty(value = "课程类别ID")
private String subjectLevelTwoId;
@ApiModelProperty(value = "类别名称")
private String subjectLevelTwo;
}
package com.zy.commonutils.user;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 会员表
* </p>
*
* @author zhangyu
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="UcenterMember对象", description="会员表")
public class UcenterMemberOrder implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "会员id")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "微信openid")
private String openid;
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "性别 1 女,2 男")
private Integer sex;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "用户头像")
private String avatar;
@ApiModelProperty(value = "用户签名")
private String sign;
@ApiModelProperty(value = "是否禁用 1(true)已禁用, 0(false)未禁用")
private Boolean isDisabled;
@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
private Boolean isDeleted;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
\ No newline at end of file
{
"name": "node_crx",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"license": "ISC"
}
}
}
{
"name": "node_crx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
var http = require('http')
var fs = require('fs')
var { result } = require('../utils/commonUtil')
var { dirIsExist } = require('../utils/fsUtil');
const { stringify } = require('querystring');
var port = 8889
var solveErr = function (res, result){
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
result.msg = '文件读取失败, 请稍后重试!'
}
var server = http.createServer();
server.on('request', function(req, res){
var typeUrl = req.url.substr(21, 3);
var fileUrl = req.url.substring(25);
if(typeUrl === 'img'){
fs.readFile('../../data/img/' + fileUrl, "binary", function(err, data){
if(err){
solveErr(res, result)
res.end(JSON.stringify(result))
}else{
res.writeHead(200, {'Content-Type': 'image/jpeg'});
// 会直接下载图片
// res.setHeader('Content-Type', 'application/x-img');
res.write(data, "binary")
res.end()
}
})
}else if(typeUrl === 'mp4'){
console.log(fileUrl)
fs.readFile('../../data/mp4/' + fileUrl, "binary", function(err, data){
if(!err){
res.writeHead(200, {'Content-Type': 'audio/mp4'});
res.write(data, "binary")
res.end()
}else{
solveErr(res, result)
res.end(JSON.stringify(result))
}
})
}
else { // 处理 404 等状态异常
fs.readFile('./views/error.html', function(err, data){
if(err){
res.end('404 NOT FOUND !')
}else{
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.end(data);
}
})
}
})
server.listen(port, function(){
console.log('Server is listening...')
})
\ No newline at end of file
@font-face {
font-family: 'iconfont';
src: url('../fonts/iconfont.eot');
src: url('../fonts/iconfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/iconfont.woff') format('woff'),
url('../fonts/iconfont.ttf') format('truetype'),
url('../fonts/iconfont.svg#iconfont') format('svg');
}
.iconfont{
font-family:"iconfont" !important;
font-size:16px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
@charset "utf-8";
@import url(../lib/layui/css/layui.css);
*{
margin: 0px;
padding: 0px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
a{
text-decoration: none;
}
html{
width: 100%;
height: 100%;
overflow-x:hidden;
overflow-y:auto;
}
body{
width: 100%;
min-height: 100%;
background: #f1f1f1;
/*background: #fff;*/
}
.x-red{
color: red;
}
.layui-form-switch{
margin-top: 0px;
}
.layui-input:focus, .layui-textarea:focus {
border-color: #189f92!important;
}
.layui-fluid{
padding:15px;
}
.x-nav{
padding: 0 20px;
position: relative;
z-index: 99;
border-bottom: 1px solid #e5e5e5;
line-height: 39px;
height: 39px;
overflow: hidden;
background: #fff;
}
.page{
text-align: center;
}
.page a{
display: inline-block;
background: #fff;
color: #888;
padding: 5px;
min-width: 15px;
border: 1px solid #E2E2E2;
}
.page span{
display: inline-block;
padding: 5px;
min-width: 15px;
border: 1px solid #E2E2E2;
}
.page span.current{
display: inline-block;
background: #009688;
color: #fff;
padding: 5px;
min-width: 15px;
border: 1px solid #009688;
}
.page .pagination li{
display: inline-block;
margin-right: 5px;
text-align: center;
}
.page .pagination li.active span{
background: #009688;
color: #fff;
border: 1px solid #009688;
}
/*登录样式*/
/*头部*/
.container{
width: 100%;
height: 45px;
background-color: #222;
}
.container a,.layui-nav .layui-nav-item a{
color: #fff;
}
.container .logo a{
background-color: rgba(0,0,0,0);
}
.container .logo a{
float: left;
font-size: 18px;
padding-left: 20px;
line-height: 45px;
width: 200px;
}
.container .right{
background-color:rgba(0,0,0,0);
float: right;
}
.container .left_open{
height: 45px;
float: left;
margin-left: 10px;
}
.container .left_open i{
display: block;
background: rgba(255,255,255,0.1);
width: 32px;
height: 32px;
line-height: 32px;
border-radius: 3px;
text-align: center;
margin-top: 7px;
cursor: pointer;
}
.container .left_open i:hover{
background: rgba(255,255,255,0.3);
}
.container .left{
background-color:rgba(0,0,0,0);
float: left;
}
.container .layui-nav-item{
line-height: 45px;
}
.container .layui-nav-more{
top: 20px;
}
.container .layui-nav-child{
top: 50px;
}
.container .layui-nav-child i{
margin-right: 10px;
}
.layui-nav .layui-nav-item a{
cursor: pointer;
}
.layui-nav .layui-nav-child a{
color: #333;
cursor: pointer;
}
.left-nav{
position: absolute;
top: 45px;
bottom: 0px;
/*bottom: 42px;*/
left: 0;
z-index: 2;
padding-top: 10px;
background-color: #EEEEEE;
width: 220px;
max-width: 220px;
overflow: auto;
overflow-x:hidden;
overflow: hidden;
/*width: 0px;*/
}
#side-nav{
width: 220px;
}
.left-nav #nav li:hover > a{
/*color: blue;*/
}
.left-nav #nav .current{
background-color: rgba(0, 0, 0, 0.3);
}
.left-nav #nav li a{
font-size: 14px;
padding: 10px 15px 10px 15px;
display: block;
cursor: pointer;
border-left: 4px solid transparent;
transition: all 0.3s;
}
.left-nav a:hover{
background: #009688 !important;
color: #fff;
border-color: #04564e !important;
}
.left-nav a.active{
background: #009688 !important;
color: #fff;
border-color: #04564e !important;
}
.left-nav #nav li a cite{
font-size: 14px;
}
.left-nav #nav li .sub-menu{
display: none;
}
.left-nav #nav li .opened{
display: block;
}
.left-nav #nav li .opened:hover{
/*background: #fff ;*/
}
.left-nav #nav li .opened .current{
}
.left-nav #nav li .sub-menu li:hover{
/*color: blue;*/
/*background: #fff ;*/
}
.left-nav #nav li .sub-menu li a{
padding: 12px 15px 12px 30px;
font-size: 14px;
cursor: pointer;
}
.left-nav #nav li .sub-menu li .sub-menu li a{
padding-left: 45px;
}
/*.left-nav #nav li .sub-menu li a:hover{
color: #148cf1;
}*/
.left-nav #nav li .sub-menu li a i{
font-size: 12px;
}
.left-nav #nav li a i{
padding-right: 10px;
line-height: 14px;
}
.left-nav #nav li .nav_right{
float: right;
font-size: 16px;
}
.x-slide_left {
width: 17px;
height: 61px;
background: url(../images/icon.png) 0 0 no-repeat;
position: absolute;
top: 200px;
left: 220px;
cursor: pointer;
z-index: 3;
}
.page-content{
position: absolute;
top: 45px;
right: 0;
/*bottom: 42px;*/
bottom: 0px;
left: 220px;
overflow: hidden;
z-index: 1;
}
.page-content-bg{
position: absolute;
top: 45px;
right: 0;
/*bottom: 42px;*/
bottom: 0px;
left: 220px;
background: rgba(0,0,0,0.5);
overflow: hidden;
z-index: 100;
display: none;
}
.page-content .tab{
height: 100%;
width: 100%;
/*background: #EFEEF0;*/
margin: 0px;
}
.page-content .layui-tab-title{
/*padding-top: 5px;*/
height: 35px;
background: #EFEEF0 ;
position: relative;
z-index: 100;
}
.page-content .layui-tab-title li.home i{
padding-right: 5px;
}
.page-content .layui-tab-title li.home .layui-tab-close{
display: none;
}
.page-content .layui-tab-title li{
line-height: 35px;
}
.page-content .layui-tab-title .layui-this:after{
height: 36px;
}
.page-content .layui-tab-title li .layui-tab-close{
border-radius: 50%;
}
.page-content .layui-tab-title .layui-this{
background: #fff ;
}
.page-content .layui-tab-bar{
height:34px;
line-height: 35px;
}
.page-content .layui-tab-content{
position: absolute;
top: 36px;
bottom: 0px;
width: 100%;
padding: 0px;
overflow: hidden;
}
.page-content .layui-tab-content .layui-tab-item{
width: 100%;
height: 100%;
}
.page-content .layui-tab-content .layui-tab-item iframe{
width: 100%;
height: 100%;
}
.x-admin-carousel,.layui-carousel,.x-admin-carousel>[carousel-item]>* {
background-color:#fff
}
.x-admin-backlog .x-admin-backlog-body {
display:block;
padding:10px 15px;
background-color:#f8f8f8;
color:#999;
border-radius:2px;
transition:all .3s;
-webkit-transition:all .3s
}
.x-admin-backlog-body h3 {
padding-bottom:10px;
font-size:12px
}
.x-admin-backlog-body p cite {
font-style:normal;
font-size:30px;
font-weight:300;
color:#009688
}
.x-admin-backlog-body:hover {
background-color:#CFCFCF;
color:#888
}
.layui-table td, .layui-table th{
min-width: 80px;
}
table th, table td {
word-break: break-all;
}
/*404页面样式*/
.fly-panel {
margin-bottom: 15px;
border-radius: 2px;
/*background-color: #fff;*/
box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
}
.fly-none {
min-height: 600px;
text-align: center;
padding-top: 50px;
color: #999;
}
.fly-none .layui-icon {
line-height: 300px;
font-size: 300px;
color: #393D49;
}
.fly-none p {
margin-top: 50px;
padding: 0 15px;
font-size: 20px;
color: #999;
font-weight: 300;
}
#tab_right{
display: none;
width: 80px;
position: absolute;
top: 35px;
left: 0px;
}
#tab_right dl{
top: 0px;
}
#tab_show{
position: absolute;
top: 36px;
bottom: 0px;
width: 100%;
background:rgb(255, 255, 255,0);
padding: 0px;
overflow: hidden;
display: none;
}
@media screen and (max-width: 768px){
.fast-add{
display: none;
}
.layui-nav .to-index{
display: none;
}
.container .logo a{
width: 140px;
}
.container .left_open {
/*float: right;*/
}
.left-nav{
width: 60px;
}
.left-nav #nav li a i{
font-size: 18px;
}
.left-nav cite,.left-nav .nav_right{
display: none;
}
.page-content{
left: 60px;
}
.page-content .layui-tab-content .layui-tab-item{
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
}
.x-so input.layui-input{
width: 100%;
margin: 10px;
}
}
/*精细版样式*/
.x-admin-sm{
font-size: 12px;
}
.x-admin-sm body{
font-size: 12px;
}
/*登录页面样式*/
.x-admin-sm .login input[type=submit],.x-admin-sm .login input[type=button]{
font-size: 14px;
}
.x-admin-sm .login input[type=text],
.x-admin-sm .login input[type=file],
.x-admin-sm .login input[type=password],
.x-admin-sm .login input[type=email], .x-admin-sm select {
font-size: 12px;
}
.x-admin-sm .login .message{
font-size: 14px;
}
.x-admin-sm .layui-table td, .x-admin-sm .layui-table th{
font-size: 12px;
}
.x-admin-sm .layui-elem-field legend{
font-size: 18px;
}
.x-admin-sm .x-admin-backlog-body p cite{
font-size: 24px;
}
.x-admin-sm .left-nav #nav li a cite{
font-size: 12px;
}
.x-admin-sm .iconfont{
font-size: 14px;
}
.x-admin-sm .layui-tab-title li{
font-size: 12px;
}
.x-admin-sm .layui-icon{
font-size: 14px;
}
.x-admin-sm .layui-nav *{
font-size: 12px;
}
.x-admin-sm .layui-breadcrumb>*{
font-size: 12px;
}
.x-admin-sm .layui-btn,.x-admin-sm .layui-btn-xs,.x-admin-sm .layui-btn-sm{
font-size: 12px;
}
.x-admin-sm .layui-laydate{
font-size: 12px;
}
.x-admin-sm .layui-btn{
height: 30px;
line-height: 30px;
padding: 0 10px;
}
.x-admin-sm .layui-btn-lg{
height: 38px;
line-height: 38px;
padding: 0 18px;
font-size: 14px;
}
.x-admin-sm .layui-layer-title,.x-admin-sm .layui-layer-dialog .layui-layer-content{
font-size: 12px;
}
.x-admin-sm .layui-input,.x-admin-sm .layui-select,.x-admin-sm .layui-textarea{
height: 30px;
}
.x-admin-sm .layui-form-pane .layui-form-label{
height: 30px;
line-height: 14px;
}
.x-admin-sm .layui-form-checkbox span{
font-size: 12px;
}
.x-admin-sm .fly-none .layui-icon {
line-height: 300px;
font-size: 300px;
color: #393D49;
}
<!doctype html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>404 Not Found!</title>
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" href="../static/css/font.css">
<link rel="stylesheet" href="../static/css/xadmin.css">
</head>
<body>
<div class="layui-container">
<div class="fly-panel">
<div class="fly-none">
<h2><i class="layui-icon layui-icon-404"></i></h2>
<p>页面或者数据被<a href="http://39.98.107.99/"> 纸飞机 </a>运到火星了,啥都看不到了…</p>
</div>
</div>
</div>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://baidu.com";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</body>
</html>
\ No newline at end of file
const result = {
'code' : 200,
'msg' : '',
'data' : null
}
// 导出
module.exports = {
result
}
\ No newline at end of file
var fs = require('fs')
const dirIsExist = function(dirNamem,res){
fs.readdir(dirNamem, function(err, files){
if(err){
res.code = 10000
res.msg = '目录不存在!'
}else{
res.code = 20000
res.msg = '成功!'
res.data = files
}
})
}
// 导出
// exports.dirIsExist = dirIsExist;
module.exports = {
dirIsExist
}
\ No newline at end of file
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>
<packaging>pom</packaging>
<groupId>com.zy</groupId>
<artifactId>GuLi_mall</artifactId>
<version>1.0.0</version>
<name>GuLi_mall</name>
<modules>
<module>service</module>
<module>common</module>
</modules>
<description>Gu Li Mall Base on SpringBoot!!!</description>
<properties>
<java.version>1.8</java.version>
<guli.version>0.0.1-SNAPSHOT</guli.version>
<mysql.version>8.0.28</mysql.version>
<mybatis-plus.version>3.0.5</mybatis-plus.version>
<velocity.version>2.0</velocity.version>
<swagger.version>2.7.0</swagger.version>
<aliyun.oss.version>3.14.0</aliyun.oss.version>
<jodatime.version>2.10.1</jodatime.version>
<poi.version>5.2.1</poi.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-io.version>2.6</commons-io.version>
<httpclient.version>4.5.1</httpclient.version>
<jwt.version>0.7.0</jwt.version>
<aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version>
<aliyun-java-sdk-vod.version>2.15.2</aliyun-java-sdk-vod.version>
<aliyun-java-vod-upload.version>1.4.14</aliyun-java-vod-upload.version>
<aliyun-sdk-vod-upload.version>1.4.14</aliyun-sdk-vod-upload.version>
<fastjson.version>1.2.28</fastjson.version>
<gson.version>2.8.2</gson.version>
<json.version>20170516</json.version>
<commons-dbutils.version>1.7</commons-dbutils.version>
<canal.client.version>1.1.0</canal.client.version>
<docker.image.prefix>zx</docker.image.prefix>
<cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version>
<easyexcel.version>3.0.5</easyexcel.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 阿里巴巴 提供的简洁方便的 excel 操作工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
</dependency>
<!--Spring Cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--mybatis-plus 持久层-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<!--aliyun OSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.oss.version}</version>
</dependency>
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime.version}</version>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<!--xlsx-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--aliyun OSS 存储 此次项目没有使用,氪不起,有点小贵!!!-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-vod</artifactId>
<version>${aliyun-java-sdk-vod.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-vod-upload</artifactId>
<version>${aliyun-java-vod-upload.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-sdk-vod-upload</artifactId>
<version>${aliyun-sdk-vod-upload.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>${commons-dbutils.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>${canal.client.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.1.RELEASE</version>
</plugin>
</plugins>
</build>
</project>
<?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>GuLi_mall</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service</artifactId>
<packaging>pom</packaging>
<modules>
<module>service_edu</module>
<module>service_msg</module>
<module>service_oss</module>
</modules>
<dependencies>
<!-- 引入 公共工具包-->
<dependency>
<groupId>com.zy</groupId>
<artifactId>service_base</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.zy</groupId>
<artifactId>tool_utils</artifactId>
<version>1.0.0</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>-->
<!-- </dependency>-->
<!--hystrix依赖,主要是用 @HystrixCommand -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>-->
<!-- </dependency>-->
<!--服务注册-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
\ No newline at end of file
<?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>service</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service_edu</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.zy.eduservice;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/17 19:18
*/
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(basePackages = {"com.zy"})
public class EduApplication {
public static void main(String[] args) {
SpringApplication.run(EduApplication.class, args);
}
}
package com.zy.eduservice.client;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author zhangyu
*/
@Component
//@FeignClient("service-order")
public interface OrderClient {
@GetMapping("/edeorder/order/isBuyCourse/{courseId}/{memberId}")
public boolean isBuyCourse(@PathVariable("courseId") String courseId, @PathVariable("memberId") String memberId);
}
package com.zy.eduservice.client;
import com.zy.commonutils.R;
import com.zy.eduservice.client.impl.VodClientImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @author zhangyu
*
*/
@FeignClient(name = "service-oss", fallback = VodClientImpl.class)
@Component
public interface VodClient {
@DeleteMapping(value = "/fileoss/upload/{videoId}")
R removeVideo(@PathVariable("videoId") String videoId);
@DeleteMapping("/fileoss/upload/deleteBatch")
R deleteBatch(@RequestParam("videoIdList") List<String> videoIdList);
}
package com.zy.eduservice.client.impl;
import com.zy.commonutils.R;
import com.zy.eduservice.client.VodClient;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author zhangyu
*/
@Component
public class VodClientImpl implements VodClient {
@Override
public R removeVideo(String videoId) {
return R.error().message("删除视频出错了");
}
@Override
public R deleteBatch(List<String> videoIdList) {
return R.error().message("删除多个视频出错了");
}
}
package com.zy.eduservice.config;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/17 19:20
*/
@MapperScan("com.zy.eduservice.mapper.xml")
@Configuration
public class EduConfig {
/**
* 逻辑删除插件
*/
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
package com.zy.eduservice.controller;
import com.zy.commonutils.R;
import com.zy.eduservice.entity.EduChapter;
import com.zy.eduservice.entity.chapter.ChapterVo;
import com.zy.eduservice.service.EduChapterService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 课程 前端控制器
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Api("章节小节管理")
@CrossOrigin
@RestController
@RequestMapping("/eduservice/chapter")
public class EduChapterController {
@Autowired
private EduChapterService chapterService;
//添加课程基本信息的方法
@GetMapping("getChapterVideo/{courseId}")
public R getChapterVo(@PathVariable String courseId) {
List<ChapterVo> list = chapterService.getChapterVoByCourseId(courseId);
return R.ok().data("allChapterVideo", list);
}
//添加课程章节
@PostMapping("addChapter")
public R addChapter(@RequestBody EduChapter eduChapter) {
chapterService.save(eduChapter);
return R.ok();
}
//查询根据id课程章节
@GetMapping("getChapterInfo/{chapterId}")
public R getChapterInfo(@PathVariable String chapterId) {
EduChapter chapterById = chapterService.getById(chapterId);
return R.ok().data("chapter", chapterById);
}
//修改课程章节
@PostMapping("updateChapter")
public R updateChapter(@RequestBody EduChapter eduChapter) {
chapterService.updateById(eduChapter);
return R.ok();
}
//删除课程章节
@DeleteMapping("{chapterId}")
public R deleteChapter(@PathVariable String chapterId) {
boolean result = chapterService.deleteChapterById(chapterId);
if (result) {
return R.ok();
} else {
return R.error();
}
}
}
package com.zy.eduservice.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zy.commonutils.R;
import com.zy.eduservice.entity.EduCourse;
import com.zy.eduservice.entity.vo.CourseInfoVo;
import com.zy.eduservice.entity.vo.CoursePublishVo;
import com.zy.eduservice.entity.vo.CourseQuery;
import com.zy.eduservice.service.EduCourseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
/**
* <p>
* 课程 前端控制器
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Api("添加课程信息")
@CrossOrigin
@RestController
@RequestMapping("/eduservice/course")
public class EduCourseController {
@Autowired
private EduCourseService eduCourseService;
@ApiModelProperty("查询所有课程信息")
@GetMapping()
public R getCourseList() {
List<EduCourse> list = eduCourseService.list(null);
return R.ok().data("list", list);
}
@PostMapping("addCourseInfo")
public R addCourseInfo(@RequestBody CourseInfoVo courseInfoVo) {
String id = eduCourseService.saveCourseInfo(courseInfoVo);
return R.ok().data("courseId", id);
}
// 根据课程id查询课程基本信息
@GetMapping("getCourseInfo/{courseId}")
public R getCourseInfo(@PathVariable String courseId) {
CourseInfoVo courseInfoVo = eduCourseService.getCourseInfo(courseId);
return R.ok().data("courseInfoVo", courseInfoVo);
}
// 修改课程信息
@PostMapping("updateCourseInfo")
public R updateCourseInfo(@RequestBody CourseInfoVo courseInfoVo) {
eduCourseService.updateCourseInfo(courseInfoVo);
return R.ok();
}
// 根据课程 id 查询课程确认信息
@GetMapping("getPublishCourseInfo/{id}")
public R getPublishCourseInfo(@PathVariable String id) {
CoursePublishVo coursePublishVo = eduCourseService.getPublishCourseInfo(id);
return R.ok().data("publishCourse", coursePublishVo);
}
//根据课程id发布课程
@PostMapping("publishCourse/{id}")
public R publishCourse(@PathVariable String id) {
EduCourse eduCourse = new EduCourse();
eduCourse.setId(id);
eduCourse.setStatus("Normal");
eduCourseService.updateById(eduCourse);
return R.ok();
}
//根据id删除课程
@DeleteMapping("{courseId}")
public R removeCourse(@PathVariable String courseId) {
eduCourseService.removeCourse(courseId);
return R.ok();
}
//条件查询带分页
//根据课程id查询课程基本信息
@ApiOperation(value = "分页查询课程")
@GetMapping("pageCourse/{current}/{limit}")
public R pageTeacher(@PathVariable Long current,
@PathVariable Long limit) {
//创建page
Page<EduCourse> pageTeacher = new Page<>(current, limit);
IPage<EduCourse> page = eduCourseService.page(pageTeacher, null);
List<EduCourse> records = page.getRecords();
long total = page.getTotal();
return R.ok().data("total", total).data("records", records);
}
//4.条件查询分页方法
@ApiOperation(value = "条件查询分页方法")
@PostMapping("pageCourseCondition/{current}/{limit}")
public R pageCourseCondition(@PathVariable Long current,
@PathVariable Long limit,
@RequestBody(required = false) CourseQuery courseQuery) {
//创建page
Page<EduCourse> pageCondition = new Page<>(current, limit);
//QueryWrapper,构建
QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
//多条件组合查询,动态sql
String status = courseQuery.getStatus();
String title = courseQuery.getTitle();
if (!StringUtils.isEmpty(title)) {
wrapper.like("title", title);
}
if (!StringUtils.isEmpty(status)) {
wrapper.eq("status", status);
}
wrapper.orderByDesc("gmt_create");
//调用方法,实现分页查询
IPage<EduCourse> page = eduCourseService.page(pageCondition, wrapper);
long total = page.getTotal();
List<EduCourse> records = page.getRecords();
HashMap<String, Object> map = new HashMap<>();
map.put("total", total);
map.put("rows", records);
return R.ok().data(map);
}
}
package com.zy.eduservice.controller;
import com.zy.commonutils.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author zhangyu
*/
@RestController
@RequestMapping("/eduservice/user")
@CrossOrigin
public class EduLoginController {
//Login
@PostMapping("login")
public R login() {
return R.ok().data("token", "admin");
}
//info
@GetMapping("info")
public R info() {
return R.ok().data("roles", "admin").data("avatar", "https://cdn.jsdelivr.net/gh/Rainbow503/PicGo/img/f778738c-e4f8-4870-b634-56703b4acafe.gif");
}
}
package com.zy.eduservice.controller;
import com.zy.commonutils.R;
import com.zy.eduservice.entity.subject.OneSubject;
import com.zy.eduservice.service.EduSubjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* <p>
* 课程科目 前端控制器
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@CrossOrigin
@RestController
@RequestMapping("/eduservice/subject")
public class EduSubjectController {
@Autowired
private EduSubjectService eduSubjectService;
@PostMapping("addSubject")
public R addSubject(MultipartFile file) {
eduSubjectService.saveSubject(file, eduSubjectService);
return R.ok();
}
// 课程分类返回结构(树形)
@GetMapping("getAllSubject")
public R getAllSubject() {
List<OneSubject> list = eduSubjectService.getAllSubject();
return R.ok().data("list", list);
}
}
package com.zy.eduservice.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zy.commonutils.R;
import com.zy.eduservice.entity.EduTeacher;
import com.zy.eduservice.entity.vo.TeachQuery;
import com.zy.eduservice.service.EduTeacherService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
/**
* <p>
* 讲师 前端控制器
* </p>
*
* @author zyGardenia
* @since 2022-03-17
*/
@Api("讲师管理")
@CrossOrigin
@RestController
@RequestMapping("/eduservice/teacher")
public class EduTeacherController {
@Autowired
private EduTeacherService teacherService;
@ApiOperation(value = "所有讲师列表")
@GetMapping("findAll")
public R findAllTeacher() {
List<EduTeacher> list = teacherService.list(null);
return R.ok().data("items", list);
}
@ApiOperation(value = "逻辑删除讲师")
@DeleteMapping("{id}")
public R deleteTeacher(@ApiParam(name = "id", value = "讲师id", required = true) @PathVariable String id) {
boolean removeById = teacherService.removeById(id);
if (removeById) {
return R.ok();
} else {
return R.error();
}
}
@ApiOperation(value = "分页查询讲师")
@GetMapping("pageTeacher/{current}/{limit}")
public R pageTeacher(@PathVariable Long current,
@PathVariable Long limit) {
// 创建page
Page<EduTeacher> pageTeacher = new Page<>(current, limit);
//调用方法,把所有数据封装到 pageTeacher 中
teacherService.page(pageTeacher, null);
// 获取总记录数
long total = pageTeacher.getTotal();
// 获取分页后的list集合
List<EduTeacher> records = pageTeacher.getRecords();
HashMap<String, Object> map = new HashMap<>();
map.put("total", total);
map.put("rows", records);
return R.ok().data(map);
}
@ApiOperation(value = "条件查询分页方法")
@PostMapping("pageTeacherCondition/{current}/{limit}")
public R pageTeacherCondition(@PathVariable Long current,
@PathVariable Long limit,
@RequestBody(required = false) TeachQuery teachQuery) {
// 创建page
Page<EduTeacher> pageCondition = new Page<>(current, limit);
// QueryWrapper 条件构建
QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();
//多条件组合查询,动态sql
String name = teachQuery.getName();
Integer level = teachQuery.getLevel();
String begin = teachQuery.getBegin();
String end = teachQuery.getEnd();
//判断条件是否为空,拼接条件
if (!StringUtils.isEmpty(level)) {
wrapper.eq("level", level);
}
if (!StringUtils.isEmpty(name)) {
wrapper.like("name", name);
}
if (!StringUtils.isEmpty(begin)) {
wrapper.ge("gmt_create", begin);
}
if (!StringUtils.isEmpty(end)) {
wrapper.le("gmt_create", end);
}
wrapper.orderByDesc("gmt_create");
//调用方法,实现分页查询
teacherService.page(pageCondition, wrapper);
long total = pageCondition.getTotal();
List<EduTeacher> records = pageCondition.getRecords();
HashMap<String, Object> map = new HashMap<>();
map.put("total", total);
map.put("rows", records);
return R.ok().data(map);
}
@ApiOperation("添加教师")
@PostMapping("addTeacher")
public R addTeacher(@RequestBody EduTeacher eduTeacher) {
boolean save = teacherService.save(eduTeacher);
if (save) {
return R.ok();
} else {
return R.error();
}
}
@ApiOperation("根据ID查询教师")
@GetMapping("getTeacher/{id}")
public R getTeacher(@PathVariable String id) {
EduTeacher byId = teacherService.getById(id);
return R.ok().data("teacher", byId);
}
@ApiOperation("修改教师")
@PostMapping("updateTeacher")
public R updateTeacher(@RequestBody EduTeacher eduTeacher) {
boolean b = teacherService.updateById(eduTeacher);
if (b) {
return R.ok();
} else {
return R.error();
}
}
}
package com.zy.eduservice.controller;
import com.zy.commonutils.R;
import com.zy.eduservice.client.VodClient;
import com.zy.eduservice.entity.EduVideo;
import com.zy.eduservice.service.EduVideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
/**
* <p>
* 课程视频 前端控制器
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@RestController
@RequestMapping("/eduservice/video")
@CrossOrigin
public class EduVideoController {
@Autowired
private EduVideoService eduVideoService;
@Autowired
private VodClient vodClient;
//添加小节
@PostMapping("addVideo")
public R addVideo(@RequestBody EduVideo eduVideo) {
eduVideoService.save(eduVideo);
return R.ok();
}
/**
* 刪除视频
*/
@DeleteMapping("{id}")
public R deleteVideo(@PathVariable String id) {
eduVideoService.removeById(id);
return vodClient.removeVideo(id);
}
/**
* 删除小节同时把小节中的视频删除
*/
@DeleteMapping("/chapter/{id}")
public R deleteChapter(@PathVariable String id) {
//根据小节 id 查询出视频id,进行删除
EduVideo eduVideobyId = eduVideoService.getById(id);
String videoSourceId = eduVideobyId.getVideoSourceId();
//判断是否有视频,有就删除
if (!StringUtils.isEmpty(videoSourceId)) {
//远程调用vod删除视频
vodClient.removeVideo(videoSourceId);
}
//删除小节
eduVideoService.removeById(id);
return R.ok();
}
}
package com.zy.eduservice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 课程
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduChapter对象", description="课程")
public class EduChapter implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "章节ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "课程ID")
private String courseId;
@ApiModelProperty(value = "章节名称")
private String title;
@ApiModelProperty(value = "显示排序")
private Integer sort;
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
package com.zy.eduservice.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 课程
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduCourse对象", description="课程")
public class EduCourse implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "课程讲师ID")
private String teacherId;
@ApiModelProperty(value = "课程专业ID")
private String subjectId;
private String subjectParentId;
@ApiModelProperty(value = "课程标题")
private String title;
@ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
private BigDecimal price;
@ApiModelProperty(value = "总课时")
private Integer lessonNum;
@ApiModelProperty(value = "课程封面图片路径")
private String cover;
@ApiModelProperty(value = "销售数量")
private Long buyCount;
@ApiModelProperty(value = "浏览数量")
private Long viewCount;
@ApiModelProperty(value = "乐观锁")
private Long version;
@ApiModelProperty(value = "课程状态 Draft未发布 Normal已发布")
private String status;
@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
private Integer isDeleted;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
package com.zy.eduservice.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 课程简介
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduCourseDescription对象", description="课程简介")
public class EduCourseDescription implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程ID")
@TableId(value = "id", type = IdType.INPUT)
private String id;
@ApiModelProperty(value = "课程简介")
private String description;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
package com.zy.eduservice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 课程科目
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduSubject对象", description="课程科目")
public class EduSubject implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程类别ID")
private String id;
@ApiModelProperty(value = "类别名称")
private String title;
@ApiModelProperty(value = "父ID")
private String parentId;
@ApiModelProperty(value = "排序字段")
private Integer sort;
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
package com.zy.eduservice.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.util.Date;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 讲师
* </p>
*
* @author zyGardenia
* @since 2022-03-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduTeacher对象", description="讲师")
public class EduTeacher implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "讲师ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "讲师姓名")
private String name;
@ApiModelProperty(value = "讲师简介")
private String intro;
@ApiModelProperty(value = "讲师资历,一句话说明讲师")
private String career;
@ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
private Integer level;
@ApiModelProperty(value = "讲师头像")
private String avatar;
@ApiModelProperty(value = "排序")
private Integer sort;
@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
@TableLogic
private Integer isDeleted;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
package com.zy.eduservice.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 课程视频
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduVideo对象", description="课程视频")
public class EduVideo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "视频ID")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "课程ID")
private String courseId;
@ApiModelProperty(value = "章节ID")
private String chapterId;
@ApiModelProperty(value = "节点名称")
private String title;
@ApiModelProperty(value = "云端视频资源")
private String videoSourceId;
@ApiModelProperty(value = "原始文件名称")
private String videoOriginalName;
@ApiModelProperty(value = "排序字段")
private Integer sort;
@ApiModelProperty(value = "播放次数")
private Long playCount;
@ApiModelProperty(value = "是否可以试听:0收费 1免费")
private Integer isFree;
@ApiModelProperty(value = "视频时长(秒)")
private Float duration;
@ApiModelProperty(value = "Empty未上传 Transcoding转码中 Normal正常")
private String status;
@ApiModelProperty(value = "视频源文件大小(字节)")
private Long size;
@ApiModelProperty(value = "乐观锁")
private Long version;
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
package com.zy.eduservice.entity.chapter;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhangyu
*/
@Data
public class ChapterVo {
private String id;
private String title;
private List<VideoVo> children = new ArrayList<>();
}
package com.zy.eduservice.entity.chapter;
import lombok.Data;
/**
* @author zhangyu
*/
@Data
public class VideoVo {
private String id;
private String title;
private String videoSourceId;
}
package com.zy.eduservice.entity.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author zhangyu
*/
@Data
public class SubjectData {
@ExcelProperty(index = 0)
private String oneSubjectName;
@ExcelProperty(index = 1)
private String twoSubjectName;
}
package com.zy.eduservice.entity.frontVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
public class CourseQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程名称")
private String title;
@ApiModelProperty(value = "讲师id")
private String teacherId;
@ApiModelProperty(value = "一级类别id")
private String subjectParentId;
@ApiModelProperty(value = "二级类别id")
private String subjectId;
@ApiModelProperty(value = "销量排序")
private String buyCountSort;
@ApiModelProperty(value = "最新时间排序")
private String gmtCreateSort;
@ApiModelProperty(value = "价格排序")
private String priceSort;
}
package com.zy.eduservice.entity.frontVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class CourseWebVo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
@ApiModelProperty(value = "课程标题")
private String title;
@ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
private BigDecimal price;
@ApiModelProperty(value = "总课时")
private Integer lessonNum;
@ApiModelProperty(value = "课程封面图片路径")
private String cover;
@ApiModelProperty(value = "销售数量")
private Long buyCount;
@ApiModelProperty(value = "浏览数量")
private Long viewCount;
@ApiModelProperty(value = "课程简介")
private String description;
@ApiModelProperty(value = "讲师ID")
private String teacherId;
@ApiModelProperty(value = "讲师姓名")
private String teacherName;
@ApiModelProperty(value = "讲师资历,一句话说明讲师")
private String intro;
@ApiModelProperty(value = "讲师头像")
private String avatar;
@ApiModelProperty(value = "课程类别ID")
private String subjectLevelOneId;
@ApiModelProperty(value = "类别名称")
private String subjectLevelOne;
@ApiModelProperty(value = "课程类别ID")
private String subjectLevelTwoId;
@ApiModelProperty(value = "类别名称")
private String subjectLevelTwo;
}
package com.zy.eduservice.entity.subject;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class OneSubject {
private String id;
private String title;
private List<TwoSubject> children = new ArrayList<>();
}
package com.zy.eduservice.entity.subject;
import lombok.Data;
/**
* @author zhangyu
*/
@Data
public class TwoSubject {
private String id;
private String title;
}
package com.zy.eduservice.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author zhangyu
*/
@Data
public class CourseInfoVo {
@ApiModelProperty(value = "课程ID")
private String id;
@ApiModelProperty(value = "课程讲师ID")
private String teacherId;
@ApiModelProperty(value = "课程专业ID")
private String subjectId;
@ApiModelProperty(value = "课程专业父级ID")
private String subjectParentId;
@ApiModelProperty(value = "课程标题")
private String title;
// New
@ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
private BigDecimal price;
@ApiModelProperty(value = "总课时")
private Integer lessonNum;
@ApiModelProperty(value = "课程封面图片路径")
private String cover;
@ApiModelProperty(value = "课程简介")
private String description;
}
package com.zy.eduservice.entity.vo;
import lombok.Data;
import java.io.Serializable;
/**
* @author zhangyu
*/
@Data
public class CoursePublishVo implements Serializable {
private String id;
private String title;
private String cover;
private Integer lessonNum;
private String subjectLevelOne;
private String subjectLevelTwo;
private String teacherName;
private String price;
}
package com.zy.eduservice.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author zhangyu
*/
@Data
public class CourseQuery implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程名称")
private String title;
@ApiModelProperty(value = "二级类别id")
private String status;
}
\ No newline at end of file
package com.zy.eduservice.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author zhangyu
*/
@Data
public class TeachQuery {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "教师名称,模糊查询")
private String name;
@ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
private Integer level;
@ApiModelProperty(value = "查询开始时间", example = "2019-01-01 10:10:10")
private String begin;
//注意,这里使用的是String类型,前端传过来的数据无需进行类型转换
@ApiModelProperty(value = "查询结束时间", example = "2019-12-01 10:10:10")
private String end;
}
package com.zy.eduservice.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.commonutils.exception.GuliException;
import com.zy.eduservice.entity.EduSubject;
import com.zy.eduservice.entity.excel.SubjectData;
import com.zy.eduservice.service.EduSubjectService;
import java.util.Map;
/**
* @author zhangyu
*/
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {
public EduSubjectService eduSubjectService;
public SubjectExcelListener(EduSubjectService eduSubjectService) {
this.eduSubjectService = eduSubjectService;
}
public SubjectExcelListener() {
}
@Override
public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
if (subjectData == null) {
throw new GuliException(20001, "文件数据为空");
}
//判断一级分类
EduSubject oneSubject = this.existOneSubject(eduSubjectService, subjectData.getOneSubjectName());
if (oneSubject == null) {
// 没有相同的一级分类,进行添加
oneSubject = new EduSubject();
oneSubject.setParentId("0");
oneSubject.setTitle(subjectData.getOneSubjectName());
eduSubjectService.save(oneSubject);
}
//判断二级分类
String pid = oneSubject.getId();
EduSubject twoSubject = this.existTwoSubject(eduSubjectService, subjectData.getTwoSubjectName(), pid);
if (twoSubject == null) {
//没有相同的一级分类,进行添加
twoSubject = new EduSubject();
twoSubject.setParentId(pid);
twoSubject.setTitle(subjectData.getTwoSubjectName());
eduSubjectService.save(twoSubject);
}
}
//判断一级分类,不能重复添加
private EduSubject existOneSubject(EduSubjectService eduSubjectService, String name) {
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("title", name);
wrapper.eq("parent_id", "0");
EduSubject one = eduSubjectService.getOne(wrapper);
return one;
}
//判断二级分类,不能重复添加
private EduSubject existTwoSubject(EduSubjectService eduSubjectService, String name, String pid) {
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("title", name);
wrapper.eq("parent_id", pid);
EduSubject one = eduSubjectService.getOne(wrapper);
return one;
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
super.invokeHeadMap(headMap, context);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
package com.zy.eduservice.mapper;
import com.zy.eduservice.entity.EduChapter;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程 Mapper 接口
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Mapper
public interface EduChapterMapper extends BaseMapper<EduChapter> {
}
package com.zy.eduservice.mapper;
import com.zy.eduservice.entity.EduCourseDescription;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程简介 Mapper 接口
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Mapper
public interface EduCourseDescriptionMapper extends BaseMapper<EduCourseDescription> {
}
package com.zy.eduservice.mapper;
import com.zy.eduservice.entity.EduCourse;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zy.eduservice.entity.frontVo.CourseWebVo;
import com.zy.eduservice.entity.vo.CoursePublishVo;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程 Mapper 接口
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Mapper
public interface EduCourseMapper extends BaseMapper<EduCourse> {
CoursePublishVo getPublishCourseInfo(String id);
CourseWebVo getBaseCourseInfo(String courseId);
}
package com.zy.eduservice.mapper;
import com.zy.eduservice.entity.EduSubject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程科目 Mapper 接口
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Mapper
public interface EduSubjectMapper extends BaseMapper<EduSubject> {
}
package com.zy.eduservice.mapper;
import com.zy.eduservice.entity.EduTeacher;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 讲师 Mapper 接口
* </p>
*
* @author zyGardenia
* @since 2022-03-17
*/
@Mapper
public interface EduTeacherMapper extends BaseMapper<EduTeacher> {
}
package com.zy.eduservice.mapper;
import com.zy.eduservice.entity.EduVideo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程视频 Mapper 接口
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Mapper
public interface EduVideoMapper extends BaseMapper<EduVideo> {
}
<?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.zy.eduservice.mapper.EduChapterMapper">
</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="com.zy.eduservice.mapper.EduCourseDescriptionMapper">
</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="com.zy.eduservice.mapper.EduCourseMapper">
<select id="getPublishCourseInfo" resultType="com.zy.eduservice.entity.vo.CoursePublishVo">
SELECT ec.id,ec.title,ec.price,ec.lesson_num AS lessonNum,ec.cover,
et.name AS teacherName,
es1.title AS subjectLevelOne,
es2.title AS subjectLevelTwo
FROM edu_course ec LEFT OUTER JOIN edu_course_description ecd ON ec.id=ecd.id
LEFT OUTER JOIN edu_teacher et ON ec.teacher_id=et.id
LEFT OUTER JOIN edu_subject es1 ON ec.subject_parent_id=es1.id
LEFT OUTER JOIN edu_subject es2 ON ec.subject_id=es2.id
WHERE ec.id=#{courseId}
</select>
<!-- 根据课程id,编写sql语句查询课程信息-->
<select id="getBaseCourseInfo" resultType="com.zy.eduservice.entity.frontVo.CourseWebVo">
SELECT ec.id,ec.title,ec.price,ec.lesson_num AS lessonNum,ec.cover,
ec.buy_count AS buyCount,ec.view_count AS viewCount,
ecd.description,
et.id AS teacherId,et.name AS teacherName,et.intro,et.avatar,
es1.id AS subjectLevelOneId,es1.title AS subjectLevelOne,
es2.id AS subjectLevelTwoId,es2.title AS subjectLevelTwo
FROM edu_course ec LEFT OUTER JOIN edu_course_description ecd ON ec.id=ecd.id
LEFT OUTER JOIN edu_teacher et ON ec.teacher_id=et.id
LEFT OUTER JOIN edu_subject es1 ON ec.subject_parent_id=es1.id
LEFT OUTER JOIN edu_subject es2 ON ec.subject_id=es2.id
WHERE ec.id=#{courseId}
</select>
</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="com.zy.eduservice.mapper.EduSubjectMapper">
</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="com.zy.eduservice.mapper.EduTeacherMapper">
</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="com.zy.eduservice.mapper.EduVideoMapper">
</mapper>
package com.zy.eduservice.service;
import com.zy.eduservice.entity.EduChapter;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zy.eduservice.entity.chapter.ChapterVo;
import java.util.List;
/**
* <p>
* 课程 服务类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
public interface EduChapterService extends IService<EduChapter> {
List<ChapterVo> getChapterVoByCourseId(String courseId);
boolean deleteChapterById(String chapterId);
void removeChapterByCourseId(String courseId);
}
package com.zy.eduservice.service;
import com.zy.eduservice.entity.EduCourseDescription;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 课程简介 服务类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
public interface EduCourseDescriptionService extends IService<EduCourseDescription> {
}
package com.zy.eduservice.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zy.eduservice.entity.EduCourse;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zy.eduservice.entity.frontVo.CourseQueryVo;
import com.zy.eduservice.entity.frontVo.CourseWebVo;
import com.zy.eduservice.entity.vo.CourseInfoVo;
import com.zy.eduservice.entity.vo.CoursePublishVo;
import java.util.Map;
/**
* <p>
* 课程 服务类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
public interface EduCourseService extends IService<EduCourse> {
String saveCourseInfo(CourseInfoVo courseInfoVo);
CourseInfoVo getCourseInfo(String courseId);
void updateCourseInfo(CourseInfoVo courseInfoVo);
CoursePublishVo getPublishCourseInfo(String id);
void removeCourse(String courseId);
Map<String, Object> getTeacherInfo(Page<EduCourse> queryVoPage, CourseQueryVo courseQueryVo);
CourseWebVo getBaseCourseInfo(String courseId);
}
package com.zy.eduservice.service;
import com.zy.eduservice.entity.EduSubject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zy.eduservice.entity.subject.OneSubject;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* <p>
* 课程科目 服务类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
public interface EduSubjectService extends IService<EduSubject> {
void saveSubject(MultipartFile file, EduSubjectService eduSubjectService);
List<OneSubject> getAllSubject();
}
package com.zy.eduservice.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.zy.eduservice.entity.EduTeacher;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 讲师 服务类
* </p>
*
* @author zyGardenia
* @since 2022-03-17
*/
public interface EduTeacherService extends IService<EduTeacher> {
}
package com.zy.eduservice.service;
import com.zy.eduservice.entity.EduVideo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 课程视频 服务类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
public interface EduVideoService extends IService<EduVideo> {
void removeByCourseId(String courseId);
}
package com.zy.eduservice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.commonutils.exception.GuliException;
import com.zy.eduservice.entity.EduChapter;
import com.zy.eduservice.entity.EduVideo;
import com.zy.eduservice.entity.chapter.ChapterVo;
import com.zy.eduservice.entity.chapter.VideoVo;
import com.zy.eduservice.mapper.EduChapterMapper;
import com.zy.eduservice.service.EduChapterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.eduservice.service.EduVideoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 课程 服务实现类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Transactional
@Service
public class EduChapterServiceImpl extends ServiceImpl<EduChapterMapper, EduChapter> implements EduChapterService {
@Autowired
private EduVideoService eduVideoService;
@Override
public List<ChapterVo> getChapterVoByCourseId(String courseId) {
//1根据课程id查询课程里面所有的章节
QueryWrapper<EduChapter> chapterQueryWrapper = new QueryWrapper<>();
chapterQueryWrapper.eq("course_id", courseId);
List<EduChapter> eduChapterList = baseMapper.selectList(chapterQueryWrapper);
//2根据课程id查询课程里面所有的小节
QueryWrapper<EduVideo> videoQueryWrapper = new QueryWrapper<>();
videoQueryWrapper.eq("course_id", courseId);
List<EduVideo> eduVideoList = eduVideoService.list(videoQueryWrapper);
//创建list集合进行最终封装
ArrayList<ChapterVo> finalList = new ArrayList<>();
//3遍历查询章节list集合进行封装
for (int i = 0; i < eduChapterList.size(); i++) {
EduChapter eduChapter = eduChapterList.get(i);
ChapterVo chapterVo = new ChapterVo();
BeanUtils.copyProperties(eduChapter, chapterVo);
finalList.add(chapterVo);
ArrayList<VideoVo> finalVideoVoList = new ArrayList<>();
//4遍历查询小节list集合进行封装
for (int j = 0; j < eduVideoList.size(); j++) {
EduVideo eduVideo = eduVideoList.get(j);
if (eduVideo.getChapterId().equals(chapterVo.getId())) {
VideoVo videoVo = new VideoVo();
BeanUtils.copyProperties(eduVideo, videoVo);
finalVideoVoList.add(videoVo);
}
}
chapterVo.setChildren(finalVideoVoList);
}
return finalList;
}
//删除章节的方法
@Override
public boolean deleteChapterById(String chapterId) {
//根据章节id,如果有小节数据则不能删除
QueryWrapper<EduVideo> eduVideoWrapper = new QueryWrapper<>();
eduVideoWrapper.eq("chapter_id", chapterId);
int count = eduVideoService.count(eduVideoWrapper);
if (count > 0) {
//有小节
throw new GuliException(20001, "有小节,无法删除");
}
int i = baseMapper.deleteById(chapterId);
return i > 0;
}
@Override
public void removeChapterByCourseId(String courseId) {
QueryWrapper<EduChapter> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("course_id", courseId);
baseMapper.delete(queryWrapper);
}
}
package com.zy.eduservice.service.impl;
import com.zy.eduservice.entity.EduCourseDescription;
import com.zy.eduservice.mapper.EduCourseDescriptionMapper;
import com.zy.eduservice.service.EduCourseDescriptionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 课程简介 服务实现类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Service
public class EduCourseDescriptionServiceImpl extends ServiceImpl<EduCourseDescriptionMapper, EduCourseDescription> implements EduCourseDescriptionService {
}
package com.zy.eduservice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zy.commonutils.exception.GuliException;
import com.zy.eduservice.entity.EduCourse;
import com.zy.eduservice.entity.EduCourseDescription;
import com.zy.eduservice.entity.frontVo.CourseQueryVo;
import com.zy.eduservice.entity.frontVo.CourseWebVo;
import com.zy.eduservice.entity.vo.CourseInfoVo;
import com.zy.eduservice.entity.vo.CoursePublishVo;
import com.zy.eduservice.mapper.EduCourseMapper;
import com.zy.eduservice.service.EduChapterService;
import com.zy.eduservice.service.EduCourseDescriptionService;
import com.zy.eduservice.service.EduCourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.eduservice.service.EduVideoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 课程 服务实现类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Transactional
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {
@Autowired
private EduCourseDescriptionService eduCourseDescriptionService;
@Autowired
private EduChapterService eduChapterService;
@Autowired
private EduVideoService eduVideoService;
//添加课程信息
@Override
public String saveCourseInfo(CourseInfoVo courseInfoVo) {
//向课程表添加课程信息
EduCourse eduCourse = new EduCourse();
BeanUtils.copyProperties(courseInfoVo, eduCourse);
int insert = baseMapper.insert(eduCourse);
if (insert <= 0) {
throw new GuliException(20001, "添加课程信息失败");
}
// 获取保存后的id,与课程描述建立关系
String CourseId = eduCourse.getId();
// 向课程简介添加课程简介
EduCourseDescription description = new EduCourseDescription();
BeanUtils.copyProperties(courseInfoVo, description);
description.setId(CourseId);
eduCourseDescriptionService.save(description);
return CourseId;
}
@Override
public CourseInfoVo getCourseInfo(String courseId) {
// 查询课程表类容
EduCourse eduCourse = baseMapper.selectById(courseId);
// 封装到CourseInfoVo中
CourseInfoVo courseInfoVo = new CourseInfoVo();
BeanUtils.copyProperties(eduCourse, courseInfoVo);
// 查询描述表
EduCourseDescription eduCourseDescription = eduCourseDescriptionService.getById(courseId);
courseInfoVo.setDescription(eduCourseDescription.getDescription());
return courseInfoVo;
}
@Override
public void updateCourseInfo(CourseInfoVo courseInfoVo) {
// 修改课程表
EduCourse eduCourse = new EduCourse();
BeanUtils.copyProperties(courseInfoVo, eduCourse);
int update = baseMapper.updateById(eduCourse);
if (update == 0) {
throw new GuliException(20001, "修改课程信息失败");
}
// 修改描述表
EduCourseDescription description = new EduCourseDescription();
description.setId(courseInfoVo.getId());
description.setDescription(courseInfoVo.getDescription());
eduCourseDescriptionService.updateById(description);
}
@Override
public CoursePublishVo getPublishCourseInfo(String id) {
CoursePublishVo coursePublishVo = baseMapper.getPublishCourseInfo(id);
return coursePublishVo;
}
/**
* 删除课程
*/
@Override
public void removeCourse(String courseId) {
//根据课程id删除小节和视频
eduVideoService.removeByCourseId(courseId);
//根据课程id删除章节
eduChapterService.removeChapterByCourseId(courseId);
//根据课程id删除课程描述
eduCourseDescriptionService.removeById(courseId);
//根据课程id删除课程本身
int i = baseMapper.deleteById(courseId);
if (i == 0) {
throw new GuliException(20001, "删除失败");
}
}
@Override
public Map<String, Object> getTeacherInfo(Page<EduCourse> queryVoPage, CourseQueryVo courseQueryVo) {
QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
//判断条件是否为空
if (!StringUtils.isEmpty(courseQueryVo.getSubjectParentId())){
//一级分类
queryWrapper.eq("subject_parent_id",courseQueryVo.getSubjectParentId());
}
if (!StringUtils.isEmpty(courseQueryVo.getSubjectId())){
//二级分类
queryWrapper.eq("subject_id",courseQueryVo.getSubjectId());
}
if (!StringUtils.isEmpty(courseQueryVo.getBuyCountSort())) {
//销量排序
queryWrapper.orderByDesc("buy_count");
}
if (!StringUtils.isEmpty(courseQueryVo.getGmtCreateSort())) {
//时间排序
queryWrapper.orderByDesc("gmt_create");
}
if (!StringUtils.isEmpty(courseQueryVo.getPriceSort())) {
//价格排序
queryWrapper.orderByDesc("price");
}
//封装到page里面
baseMapper.selectPage(queryVoPage, queryWrapper);
long total = queryVoPage.getTotal();
List<EduCourse> records = queryVoPage.getRecords();
long current = queryVoPage.getCurrent();
long size = queryVoPage.getSize();
boolean hasNext = queryVoPage.hasNext();
boolean hasPrevious = queryVoPage.hasPrevious();
long pages = queryVoPage.getPages();
HashMap<String, Object> map = new HashMap<>();
map.put("items", records);
map.put("current", current);
map.put("pages", pages);
map.put("size", size);
map.put("total", total);
map.put("hasNext", hasNext);
map.put("hasPrevious", hasPrevious);
return map;
}
@Override
public CourseWebVo getBaseCourseInfo(String courseId) {
return baseMapper.getBaseCourseInfo(courseId);
}
}
package com.zy.eduservice.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.eduservice.entity.EduSubject;
import com.zy.eduservice.entity.excel.SubjectData;
import com.zy.eduservice.entity.subject.OneSubject;
import com.zy.eduservice.entity.subject.TwoSubject;
import com.zy.eduservice.listener.SubjectExcelListener;
import com.zy.eduservice.mapper.EduSubjectMapper;
import com.zy.eduservice.service.EduSubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 课程科目 服务实现类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Service
@Transactional
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
// 添加课程分类
@Override
public void saveSubject(MultipartFile file, EduSubjectService eduSubjectService) {
// 获取输入流
try {
InputStream is = file.getInputStream();
EasyExcel.read(is, SubjectData.class, new SubjectExcelListener(eduSubjectService)).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public List<OneSubject> getAllSubject() {
// 查询出所有一级分类 parent_id=0
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("parent_id", "0");
List<EduSubject> oneSubjectList = baseMapper.selectList(wrapper);
// 查询出所有二级分类 parent_id!=0
QueryWrapper<EduSubject> wrapper2 = new QueryWrapper<>();
wrapper2.ne("parent_id", "0");
List<EduSubject> twoSubjectList = baseMapper.selectList(wrapper2);
// 封装一级分类
List<OneSubject> finnalList = new ArrayList<>();
for (int i = 0; i < oneSubjectList.size(); i++) {
EduSubject eduSubject = oneSubjectList.get(i);
// new OneSubject设置值,add加入list
OneSubject oneSubject = new OneSubject();
// 复制操作
BeanUtils.copyProperties(eduSubject, oneSubject);
finnalList.add(oneSubject);
// 封装二级分类
// 创建list集合封装每一个一级分类的二级分类
ArrayList<TwoSubject> twoFinnalList = new ArrayList<>();
for (int j = 0; j < twoSubjectList.size(); j++) {
EduSubject eduSubject2 = twoSubjectList.get(j);
if (eduSubject.getId().equals(eduSubject2.getParentId())) {
TwoSubject twoSubject = new TwoSubject();
//如过一级分类的id==二级分类的parent_id,进行封装
BeanUtils.copyProperties(eduSubject2, twoSubject);
twoFinnalList.add(twoSubject);
}
}
oneSubject.setChildren(twoFinnalList);
}
return finnalList;
}
}
package com.zy.eduservice.service.impl;
import com.zy.eduservice.entity.EduTeacher;
import com.zy.eduservice.mapper.EduTeacherMapper;
import com.zy.eduservice.service.EduTeacherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 讲师 服务实现类
* </p>
*
* @author zyGardenia
* @since 2022-03-17
*/
@Service
public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService {
}
package com.zy.eduservice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.commonutils.R;
import com.zy.commonutils.exception.GuliException;
import com.zy.eduservice.client.VodClient;
import com.zy.eduservice.entity.EduVideo;
import com.zy.eduservice.mapper.EduVideoMapper;
import com.zy.eduservice.service.EduVideoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 课程视频 服务实现类
* </p>
*
* @author zyGardenia
* @since 2022-03-19
*/
@Transactional
@Service
public class EduVideoServiceImpl extends ServiceImpl<EduVideoMapper, EduVideo> implements EduVideoService {
@Autowired
private VodClient vodClient;
@Override
public void removeByCourseId(String courseId) {
//根据课程id查出所有视频的id
QueryWrapper<EduVideo> wrapper = new QueryWrapper<>();
wrapper.eq("course_id", courseId);
wrapper.select("video_source_id");
List<EduVideo> eduVideos = baseMapper.selectList(wrapper);
//封装video_source_id 1,2,3
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < eduVideos.size(); i++) {
EduVideo eduVideo = eduVideos.get(i);
String videoSourceId = eduVideo.getVideoSourceId();
if (!videoSourceId.isEmpty()) {
list.add(videoSourceId);
}
}
//list不为空
if (list.size() > 0) {
// 删除小节里的所有视频
R result = vodClient.deleteBatch(list);
if (result.getCode() == 20001) {
throw new GuliException(20001, "删除视频失败,熔断器...");
}
}
QueryWrapper<EduVideo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("course_id", courseId);
baseMapper.delete(queryWrapper);
}
}
# elasticsearch 配置
spring:
data:
elasticsearch:
client: 106.14.45.61
reactive:
connection-timeout: 1s
\ No newline at end of file
# mysql 配置
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://39.98.107.99:3306/mall?a=fllowPublicKeyRetrieval=true&useSSLalse&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 151613
## Redis 配置
spring:
redis:
## Redis数据库索引(默认为0)
database: 0
## Redis服务器地址
host: 39.98.107.99
## Redis服务器连接端口
port: 6379
## Redis服务器连接密码(默认为空)
password: 151613
jedis:
pool:
## 连接池最大连接数(使用负值表示没有限制)
#spring.redis.pool.max-active=8
max-active: 8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
#spring.redis.pool.max-wait=-1
max-wait: -1
## 连接池中的最大空闲连接
#spring.redis.pool.max-idle=8
max-idle: 8
## 连接池中的最小空闲连接
#spring.redis.pool.min-idle=0
min-idle: 0
## 连接超时时间(毫秒)
timeout: 2400
\ No newline at end of file
# \u670D\u52A1\u7AEF\u53E3
server.port=9001
# \u670D\u52A1\u540D
spring.application.name=service-edu
# \u73AF\u5883\u8BBE\u7F6E\uFF1Adev\u3001test\u3001prod
spring.profiles.active=dev
# mysql\u6570\u636E\u5E93\u8FDE\u63A5
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://39.98.107.99:3306/mall?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=151613
# mybatis\u65E5\u5FD7
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# mybatis xml \u6587\u4EF6\u4F4D\u7F6E
mybatis-plus.mapper-locations=classpath:com/zy/eduservice/mapper/xml/*.xml
# \u8FD4\u56DEjson\u7684\u5168\u5C40\u65F6\u95F4\u683C\u5F0F
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
# nacos\u670D\u52A1\u5730\u5740
spring.cloud.nacos.discovery.server-addr=106.14.45.61:8848
#\u5F00\u542F\u7194\u65AD\u673A\u5236
#feign.hystrix.enabled=true
# \u8BBE\u7F6Ehystrix\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA41000ms
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
\ No newline at end of file
# mysql 配置
#spring:
# datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://39.98.107.99:3306/mall?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
# username: root
# password: 151613
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<property name="log.path" value="logs/edu"/>
<!-- 彩色日志 -->
<!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 -->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
如果未设置此属性,那么当前logger将会继承上级的级别。
-->
<!--
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:
-->
<!--开发环境:打印控制台-->
<springProfile name="dev">
<!--可以输出项目中的debug日志,包括mybatis的sql日志-->
<logger name="com.guli" level="INFO"/>
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG
可以包含零个或多个appender元素。
-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</springProfile>
<!--生产环境:输出到文件-->
<springProfile name="pro">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="WARN_FILE"/>
</root>
</springProfile>
</configuration>
\ No newline at end of file
<?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>service</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service_msg</artifactId>
<dependencies>
<!-- SpringBoot 提供的 email 服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.zy.cmsservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
/**
* @author zhangyu
*/
@EnableDiscoveryClient
@ComponentScan("com.zy")
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MsmApplication {
public static void main(String[] args) {
SpringApplication.run(MsmApplication.class,args);
}
}
package com.zy.cmsservice.controller;
import com.zy.cmsservice.entity.QQEmailMsg;
import com.zy.cmsservice.utils.VerCodeGenerateUtil;
import com.zy.commonutils.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/19 18:00
*/
@CrossOrigin
@RestController
@RequestMapping("/email/qq/")
public class EmailController {
@Resource
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String sendUsername;
@RequestMapping("sendEmail")
public R commonEmail(QQEmailMsg qqEmailMsg, HttpServletRequest request) {
// 创建邮件消息
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(sendUsername);
message.setTo(qqEmailMsg.getTos());
message.setSubject("您本次的验证码是");
// 生成随机验证码
String verCode = VerCodeGenerateUtil.generateVerCode();
message.setText("尊敬的xxx,您好:\n"
+ "\n本次请求的邮件验证码为:" + verCode + ",本验证码 5 分钟内效,请及时输入。(请勿泄露此验证码)\n"
+ "\n如非本人操作,请忽略该邮件。\n(这是一封通过自动发送的邮件,请不要直接回复)");
mailSender.send(message);
// SysUser user = Context.getUser(request.getHeader("token"));
// user.setVerCode(verCode);
return R.ok().message("发送成功");
}
}
package com.zy.cmsservice.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/19 17:59
* @Description 邮件类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QQEmailMsg {
// 邮件接收方
private String[] tos;
// 邮件主题
private String subject;
// 邮件内容
private String content;
}
package com.zy.cmsservice.utils;
import java.security.SecureRandom;
import java.util.Random;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/19 17:37
* @Description 生成验证码工具类
*/
public class VerCodeGenerateUtil {
//验证码包含的字段,可自己设置
private static final String SYMBOLS = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
// 生成 6 位数的随机数字
public static String generateVerCode() {
//如果是六位,就生成大小为 6 的数组
char[] numbers = new char[6];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
}
return new String(numbers);
}
}
# \u670D\u52A1\u7AEF\u53E3
server.port=9005
# \u670D\u52A1\u540D
spring.application.name=service-msg
# mysql\u6570\u636E\u5E93\u8FDE\u63A5
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://39.98.107.99:3306/mall?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=151613
spring.redis.host=106.14.45.61
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#\u6700\u5927\u963B\u585E\u7B49\u5F85\u65F6\u95F4(\u8D1F\u6570\u8868\u793A\u6CA1\u9650\u5236)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
#\u6700\u5C0F\u7A7A\u95F2
# nacos \u670D\u52A1\u5730\u5740
spring.cloud.nacos.discovery.server-addr=106.14.45.61:8848
#\u8FD4\u56DEjson\u7684\u5168\u5C40\u65F6\u95F4\u683C\u5F0F
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#\u914D\u7F6Emapper xml\u6587\u4EF6\u7684\u8DEF\u5F84
mybatis-plus.mapper-locations=classpath:com/zy/cmsservice/mapper/xml/*.xml
#mybatis\u65E5\u5FD7
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
\ No newline at end of file
spring:
mail:
# smtp服务主机 qq邮箱则为smtp.qq.com
host: smtp.qq.com
# 服务协议
protocol: smtp
# 编码集
default-encoding: UTF-8
# 发送邮件的账户
username: 2892333477@qq.com
# 授权码
password: jkmwldlrokjpdgeb
test-connection: true
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
<?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>service</artifactId>
<groupId>com.zy</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service_oss</artifactId>
</project>
\ No newline at end of file
package com.zy.ossservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/19 20:13
*/
@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(basePackages = {"com.zy"})
public class OssApplication {
public static void main(String[] args) {
SpringApplication.run(OssApplication.class, args);
}
}
package com.zy.ossservice.controller;
import com.zy.commonutils.R;
import com.zy.ossservice.service.FileSolveService;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author 张雨 - 栀
* @version 1.0
* @create 2022/3/19 20:15
*/
@RestController
@CrossOrigin
@RequestMapping("/fileoss/upload")
public class FileSolveController {
@Autowired
private FileSolveService fileSolveService;
@PostMapping("img")
public R uploadImgFile(MultipartFile file) {
//返回上传 本地oss 的url
String url = fileSolveService.saveImgs(file);
return R.ok().data("url", url);
}
@PostMapping("mp4")
public R uploadMp4File(MultipartFile file) {
//返回上传 本地oss 的url
String url = fileSolveService.savemp4(file);
return R.ok().data("VideoId", url);
}
@DeleteMapping("{videoId}")
public R removeVideo(@ApiParam(name = "videoId", value = "云端视频id", required = true)
@PathVariable String videoId) {
return R.ok().message("视频删除成功!");
}
/**
* 删除多个阿里云视频
*/
@DeleteMapping("deleteBatch")
public R deleteBatch(@RequestParam List<String> videoIdList) {
return R.ok();
}
/**
* 根据视频id获得视频凭证
*/
@GetMapping("getPlayAuth/{id}")
public R getPlayAuth(@PathVariable String id) {
return R.ok().data("playAuth", id);
}
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册