初始化
commit
f27d8cdb7d
|
@ -0,0 +1,39 @@
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
logs
|
||||||
|
.idea
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,18 @@
|
||||||
|
#起始镜像
|
||||||
|
FROM anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/openjdk:17-8.6
|
||||||
|
#暴露端口号
|
||||||
|
EXPOSE 10010
|
||||||
|
#挂载目录的位置
|
||||||
|
VOLUME /home/logs/health-video
|
||||||
|
#构建复制外部文件到docker
|
||||||
|
COPY health-video-server/target/health-video-server.jar /home/app.jar
|
||||||
|
#工作目录 exec -it 进入容器内部后的默认的起始目录
|
||||||
|
WORKDIR /home
|
||||||
|
ENV TIME_ZONE Asia/Shanghai
|
||||||
|
#指定东八区
|
||||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
|
||||||
|
#启动java 程序
|
||||||
|
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-jar","/home/app.jar"]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-video</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</parent>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
<artifactId>health-video-common</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-common-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>dragon-public</id>
|
||||||
|
<name>dragon-maven</name>
|
||||||
|
<url>http://10.100.1.7:8081/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>dragon-release</id>
|
||||||
|
<name>dragon-releases</name>
|
||||||
|
<url>http://10.100.1.7:8081/repository/maven-releases/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
</project>
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.health.video.common.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 21:22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Comments {
|
||||||
|
/**
|
||||||
|
* 评论表主键
|
||||||
|
*/
|
||||||
|
private Integer commentsId;
|
||||||
|
/**
|
||||||
|
* 评论内容
|
||||||
|
*/
|
||||||
|
private String commentContent;
|
||||||
|
/**
|
||||||
|
* 发布评论用户ID
|
||||||
|
*/
|
||||||
|
private Integer commentsUserId;
|
||||||
|
/**
|
||||||
|
* 评论时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date createTime;
|
||||||
|
/**
|
||||||
|
* 视频表主键
|
||||||
|
*/
|
||||||
|
private Integer videoId;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.health.video.common.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 21:17
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class Video {
|
||||||
|
/**
|
||||||
|
* 视频表主键
|
||||||
|
*/
|
||||||
|
private Integer videoId;
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 详情内容
|
||||||
|
*/
|
||||||
|
private String details;
|
||||||
|
/**
|
||||||
|
* 完整视频
|
||||||
|
*/
|
||||||
|
private String fullVideo;
|
||||||
|
/**
|
||||||
|
* 被购买数
|
||||||
|
*/
|
||||||
|
private Integer purchaseNumber;
|
||||||
|
/**
|
||||||
|
* 视频分类表主键
|
||||||
|
*/
|
||||||
|
private Integer videoTypeId;
|
||||||
|
/**
|
||||||
|
* 视频价格
|
||||||
|
*/
|
||||||
|
private Integer price;
|
||||||
|
/**
|
||||||
|
* 发布视频的作者
|
||||||
|
*/
|
||||||
|
private Integer founder;
|
||||||
|
/**
|
||||||
|
* 发布时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date releaseTime;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.health.video.common.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/24 20:03
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VideoBuy {
|
||||||
|
/**
|
||||||
|
* 视频购买表
|
||||||
|
*/
|
||||||
|
private Integer videoBuyId;
|
||||||
|
/**
|
||||||
|
* 视频表主键
|
||||||
|
*/
|
||||||
|
private Integer videoId;
|
||||||
|
/**
|
||||||
|
* 用户表主键
|
||||||
|
*/
|
||||||
|
private Integer buyUserId;
|
||||||
|
/**
|
||||||
|
* 是否购买 1-是
|
||||||
|
*/
|
||||||
|
private Integer isBuy;
|
||||||
|
/**
|
||||||
|
* 购买时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date buyTime;
|
||||||
|
/**
|
||||||
|
* 是否删除购买视频 1-是 2-否
|
||||||
|
*/
|
||||||
|
private Integer isDeleteBuy;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.health.video.common.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/24 20:05
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VideoCollection {
|
||||||
|
/**
|
||||||
|
* 视频收藏表主键
|
||||||
|
*/
|
||||||
|
private Integer videoCollectionId;
|
||||||
|
/**
|
||||||
|
* 视频表主键
|
||||||
|
*/
|
||||||
|
private Integer videoId;
|
||||||
|
/**
|
||||||
|
* 用户表主键
|
||||||
|
*/
|
||||||
|
private Integer collectionUserId;
|
||||||
|
/**
|
||||||
|
* 是否收藏视频 1-是
|
||||||
|
*/
|
||||||
|
private Integer isCollection;
|
||||||
|
/**
|
||||||
|
* 收藏时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date collectTime;
|
||||||
|
/**
|
||||||
|
* 是否删除收藏视频 1-是 2-否
|
||||||
|
*/
|
||||||
|
private Integer isDeleteCollection;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.health.video.common.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 21:18
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VideoType {
|
||||||
|
/**
|
||||||
|
* 视频分类表主键
|
||||||
|
*/
|
||||||
|
private Integer videoTypeId;
|
||||||
|
/**
|
||||||
|
* 分类名称
|
||||||
|
*/
|
||||||
|
private String videoTypeName;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.health.video.common.domain.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/21 11:25
|
||||||
|
* 发送评论请求参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RequestInsertComments {
|
||||||
|
/**
|
||||||
|
* 视频表主键
|
||||||
|
*/
|
||||||
|
private Integer videoId;
|
||||||
|
/**
|
||||||
|
* 评论内容
|
||||||
|
*/
|
||||||
|
private String commentContent;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.health.video.common.domain.request;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/31 13:27
|
||||||
|
* 发布视频请求参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RequestPostVideos {
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 详情内容
|
||||||
|
*/
|
||||||
|
private String details;
|
||||||
|
/**
|
||||||
|
* 完整视频
|
||||||
|
*/
|
||||||
|
private String fullVideo;
|
||||||
|
/**
|
||||||
|
* 被购买数
|
||||||
|
*/
|
||||||
|
private Integer purchaseNumber;
|
||||||
|
/**
|
||||||
|
* 视频分类表主键
|
||||||
|
*/
|
||||||
|
private Integer videoTypeId;
|
||||||
|
/**
|
||||||
|
* 视频价格
|
||||||
|
*/
|
||||||
|
private BigDecimal price;
|
||||||
|
/**
|
||||||
|
* 发布视频的作者
|
||||||
|
*/
|
||||||
|
private Integer founder;
|
||||||
|
/**
|
||||||
|
* 发布时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date releaseTime;
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.health.video.common.domain.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 21:45
|
||||||
|
* 视频列表响应参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ResponseVideo {
|
||||||
|
/**
|
||||||
|
* 视频表主键
|
||||||
|
*/
|
||||||
|
private Integer videoId;
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 详情内容
|
||||||
|
*/
|
||||||
|
private String details;
|
||||||
|
/**
|
||||||
|
* 完整视频
|
||||||
|
*/
|
||||||
|
private String fullVideo;
|
||||||
|
/**
|
||||||
|
* 被购买数
|
||||||
|
*/
|
||||||
|
private Integer purchaseNumber;
|
||||||
|
/**
|
||||||
|
* 视频分类表主键
|
||||||
|
*/
|
||||||
|
private Integer videoTypeId;
|
||||||
|
/**
|
||||||
|
* 分类名称
|
||||||
|
*/
|
||||||
|
private String videoTypeName;
|
||||||
|
/**
|
||||||
|
* 视频价格
|
||||||
|
*/
|
||||||
|
private BigDecimal price;
|
||||||
|
/**
|
||||||
|
* 视频购买表
|
||||||
|
*/
|
||||||
|
private Integer videoBuyId;
|
||||||
|
/**
|
||||||
|
* 是否购买 1-是
|
||||||
|
*/
|
||||||
|
private Integer isBuy;
|
||||||
|
/**
|
||||||
|
* 购买时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date buyTime;
|
||||||
|
/**
|
||||||
|
* 是否删除购买视频 1-是 2-否
|
||||||
|
*/
|
||||||
|
private Integer isDeleteBuy;
|
||||||
|
/**
|
||||||
|
* 视频收藏表主键
|
||||||
|
*/
|
||||||
|
private Integer videoCollectionId;
|
||||||
|
/**
|
||||||
|
* 是否收藏视频 1-是
|
||||||
|
*/
|
||||||
|
private Integer isCollection;
|
||||||
|
/**
|
||||||
|
* 收藏时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date collectTime;
|
||||||
|
/**
|
||||||
|
* 是否删除收藏视频 1-是 2-否
|
||||||
|
*/
|
||||||
|
private Integer isDeleteCollection;
|
||||||
|
/**
|
||||||
|
* 发布视频的作者
|
||||||
|
*/
|
||||||
|
private Integer founder;
|
||||||
|
/**
|
||||||
|
* 发布时间
|
||||||
|
*/
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||||
|
private Date releaseTime;
|
||||||
|
/**
|
||||||
|
* 收藏视频用户表主键
|
||||||
|
*/
|
||||||
|
private Integer collectionUserId;
|
||||||
|
/**
|
||||||
|
* 购买视频用户表主键
|
||||||
|
*/
|
||||||
|
private Integer buyUserId;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-video</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</parent>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
<artifactId>health-video-remote</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,197 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-video</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</parent>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
<artifactId>health-video-server</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-video-common</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-wallet-common</artifactId>
|
||||||
|
<version>3.6.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-wallet-remote</artifactId>
|
||||||
|
<version>3.6.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-common-security</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>4.5.16</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>base-file-remote</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>base-system-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Swagger UI -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.springfox</groupId>
|
||||||
|
<artifactId>springfox-swagger-ui</artifactId>
|
||||||
|
<version>${swagger.fox.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Mysql Connector -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- RuoYi Common DataSource -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-common-datasource</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- RuoYi Common DataScope -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-common-datascope</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-common-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.amazonaws</groupId>
|
||||||
|
<artifactId>aws-java-sdk-core</artifactId>
|
||||||
|
<version>1.11.813</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
<artifactId>s3</artifactId>
|
||||||
|
<version>2.18.30</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.amazonaws</groupId>
|
||||||
|
<artifactId>aws-java-sdk-s3</artifactId>
|
||||||
|
<version>1.11.813</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson</artifactId>
|
||||||
|
<version>3.16.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>dragon-public</id>
|
||||||
|
<name>dragon-maven</name>
|
||||||
|
<url>http://10.100.1.7:8081/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>dragon-release</id>
|
||||||
|
<name>dragon-releases</name>
|
||||||
|
<url>http://10.100.1.7:8081/repository/maven-releases/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!--当deploy时候忽略此model-->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.health.video.server;
|
||||||
|
|
||||||
|
import com.health.common.security.annotation.EnableRyFeignClients;
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 20:01
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableRyFeignClients
|
||||||
|
public class VideoApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(VideoApplication.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.health.video.server.config;
|
||||||
|
|
||||||
|
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送确认配置 消息发送到交换机的确认
|
||||||
|
*
|
||||||
|
* @author 唐文康
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
|
||||||
|
* @PostConstruct bean 被初始化的时候执行的方法的注解
|
||||||
|
* @PreDestory bean 被销毁的时候执行的方法的注解
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
rabbitTemplate.setConfirmCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交换机不管是否收到消息的一个回调方法(生产者消息不丢失)
|
||||||
|
*
|
||||||
|
* @param correlationData 消息相关数据
|
||||||
|
* @param ack 交换机是否收到消息
|
||||||
|
* @param cause 失败原因
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
|
||||||
|
if (ack) {
|
||||||
|
// 消息投递到 broker 的状态,true表示成功
|
||||||
|
System.out.println("消息发送成功!");
|
||||||
|
} else {
|
||||||
|
// 发送异常
|
||||||
|
System.out.println("发送异常原因 = " + cause);
|
||||||
|
// TODO 可以将消息 内容 以及 失败的原因 记录到 日志表中
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.health.video.server.config;
|
||||||
|
|
||||||
|
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||||
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
|
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RabbitAdmin是RabbitMQ的一个Java客户端库,它提供了管理RabbitMQ资源的功能。它是通过与RabbitMQ服务器进行交互来执行管理操作的。
|
||||||
|
*
|
||||||
|
* @author 唐文康
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RabbitAdminConfig {
|
||||||
|
|
||||||
|
@Value("${spring.rabbitmq.host}")
|
||||||
|
private String host;
|
||||||
|
@Value("${spring.rabbitmq.username}")
|
||||||
|
private String username;
|
||||||
|
@Value("${spring.rabbitmq.password}")
|
||||||
|
private String password;
|
||||||
|
@Value("${spring.rabbitmq.virtualhost}")
|
||||||
|
private String virtualhost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建 RabbitMQ的连接工厂
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ConnectionFactory connectionFactory() {
|
||||||
|
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||||
|
connectionFactory.setAddresses(host);
|
||||||
|
connectionFactory.setUsername(username);
|
||||||
|
connectionFactory.setPassword(password);
|
||||||
|
connectionFactory.setVirtualHost(virtualhost);//虚拟主机
|
||||||
|
// 配置发送确认回调时,次配置必须配置,否则即使在RabbitTemplate配置了ConfirmCallback也不会生效
|
||||||
|
connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);//开启confirm机制 消息到达MQ的确认机制
|
||||||
|
connectionFactory.setPublisherReturns(true);//开启消息返回机制 消息无法送到Exchange时返回到生产者
|
||||||
|
return connectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自己初始化 RabbitAdmin
|
||||||
|
*
|
||||||
|
* @param connectionFactory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
|
||||||
|
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
|
||||||
|
rabbitAdmin.setAutoStartup(true);
|
||||||
|
return rabbitAdmin;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.health.video.server.config;
|
||||||
|
|
||||||
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 唐文康
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RabbitmqConfig {
|
||||||
|
// 消息转换配置
|
||||||
|
@Bean
|
||||||
|
public MessageConverter jsonMessageConverter() {
|
||||||
|
return new Jackson2JsonMessageConverter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.health.video.server.config;
|
||||||
|
|
||||||
|
import org.redisson.Redisson;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.redisson.config.Config;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 唐文康
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@Component
|
||||||
|
public class RedissonConfig {
|
||||||
|
|
||||||
|
@Bean(destroyMethod = "shutdown") // 服务停止后调用 shutdown 方法。
|
||||||
|
public RedissonClient redisson() {
|
||||||
|
System.out.println("Redisson配置类初始加载......");
|
||||||
|
// 1.创建配置
|
||||||
|
Config config = new Config();
|
||||||
|
// 集群模式
|
||||||
|
// config.useClusterServers().addNodeAddress("127.0.0.1:6379", "127.0.0.1:6378");
|
||||||
|
// 2.根据 Config 创建出 RedissonClient 实例。
|
||||||
|
config.useSingleServer().setAddress("redis://10.100.1.2:6379");
|
||||||
|
return Redisson.create(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.health.video.server.config;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.ReturnedMessage;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送到 队列的 确认 【 只有消息发送失败的时候执行 】
|
||||||
|
*
|
||||||
|
* @author 唐文康
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
rabbitTemplate.setReturnsCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只要消息发送失败 就会执行
|
||||||
|
*
|
||||||
|
* @param returnedMessage the returned message and metadata.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void returnedMessage(ReturnedMessage returnedMessage) {
|
||||||
|
System.out.println("消息" + returnedMessage.getMessage().toString() + "被交换机" + returnedMessage.getExchange() + "回退!"
|
||||||
|
+ "退回原因为:" + returnedMessage.getReplyText());
|
||||||
|
// TODO 回退了所有的信息,可做补偿机制 记录日志
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
package com.health.video.server.controller;
|
||||||
|
|
||||||
|
import com.health.common.core.domain.Result;
|
||||||
|
import com.health.video.common.domain.Comments;
|
||||||
|
import com.health.video.common.domain.VideoType;
|
||||||
|
import com.health.video.common.domain.request.RequestInsertComments;
|
||||||
|
import com.health.video.common.domain.request.RequestPostVideos;
|
||||||
|
import com.health.video.common.domain.response.ResponseVideo;
|
||||||
|
import com.health.video.server.service.VideoService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 20:02
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/video")
|
||||||
|
public class VideoController {
|
||||||
|
@Autowired
|
||||||
|
private VideoService videoService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询视频类型列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/listVideoType")
|
||||||
|
public Result<List<VideoType>> listVideoType() {
|
||||||
|
List<VideoType> videoTypes = videoService.listVideoType();
|
||||||
|
return Result.success(videoTypes, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频列表
|
||||||
|
*
|
||||||
|
* @param videoTypeId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/listVideo/{videoTypeId}")
|
||||||
|
public Result<List<ResponseVideo>> listVideo(@PathVariable Integer videoTypeId) {
|
||||||
|
List<ResponseVideo> responseVideos = videoService.listVideo(videoTypeId);
|
||||||
|
return Result.success(responseVideos, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送评论
|
||||||
|
*
|
||||||
|
* @param requestInsertComments
|
||||||
|
*/
|
||||||
|
@PostMapping("/insertComments")
|
||||||
|
public Result insertComments(@RequestBody RequestInsertComments requestInsertComments) {
|
||||||
|
videoService.insertComments(requestInsertComments);
|
||||||
|
return Result.success(null, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏视频
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
@PostMapping("/insertVideoCollection/{videoId}")
|
||||||
|
public Result insertVideoCollection(@PathVariable Integer videoId) {
|
||||||
|
videoService.insertVideoCollection(videoId);
|
||||||
|
return Result.success(null, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买视频
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
@PostMapping("/insertVideoBuy/{videoId}")
|
||||||
|
public void insertVideoBuy(@PathVariable Integer videoId) {
|
||||||
|
videoService.insertVideoBuy(videoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我收藏的视频
|
||||||
|
*
|
||||||
|
* @param collectionUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/listVideoCollection/{collectionUserId}")
|
||||||
|
public Result<List<ResponseVideo>> listVideoCollection(@PathVariable Integer collectionUserId) {
|
||||||
|
List<ResponseVideo> responseVideos = videoService.listVideoCollection(collectionUserId);
|
||||||
|
return Result.success(responseVideos, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除我收藏的视频
|
||||||
|
*
|
||||||
|
* @param videoCollectionId
|
||||||
|
*/
|
||||||
|
@PostMapping("/deleteVideoCollection/{videoCollectionId}")
|
||||||
|
public Result deleteVideoCollection(@PathVariable Integer videoCollectionId) {
|
||||||
|
videoService.deleteVideoCollection(videoCollectionId);
|
||||||
|
return Result.success(null, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我购买的视频
|
||||||
|
*
|
||||||
|
* @param buyUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/listVideoBuy/{buyUserId}")
|
||||||
|
public Result<List<ResponseVideo>> listVideoBuy(@PathVariable Integer buyUserId) {
|
||||||
|
List<ResponseVideo> responseVideos = videoService.listVideoBuy(buyUserId);
|
||||||
|
return Result.success(responseVideos, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传视频
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/uploadVideo")
|
||||||
|
public Result uploadVideo(@RequestParam MultipartFile file) throws IOException, InterruptedException {
|
||||||
|
return videoService.uploadVideo(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布视频
|
||||||
|
*
|
||||||
|
* @param requestPostVideos
|
||||||
|
*/
|
||||||
|
@PostMapping("/PostVideos")
|
||||||
|
public Result postVideos(@RequestBody RequestPostVideos requestPostVideos) {
|
||||||
|
return videoService.postVideos(requestPostVideos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询评论列表
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/listComments/{videoId}")
|
||||||
|
public Result<List<Comments>> listComments(@PathVariable Integer videoId) {
|
||||||
|
List<Comments> commentsList = videoService.listComments(videoId);
|
||||||
|
return Result.success(commentsList, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.health.video.server.mapper;
|
||||||
|
|
||||||
|
import com.health.video.common.domain.*;
|
||||||
|
import com.health.video.common.domain.request.RequestPostVideos;
|
||||||
|
import com.health.video.common.domain.response.ResponseVideo;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 20:03
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface VideoMapper {
|
||||||
|
/**
|
||||||
|
* 查询视频类型列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<VideoType> listVideoType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ResponseVideo> listVideo(@Param("videoTypeId") Integer videoTypeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送评论
|
||||||
|
*
|
||||||
|
* @param comments
|
||||||
|
*/
|
||||||
|
void insertComments(Comments comments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据videoId查询视频表
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
Video getVideoByVideoId(@Param("videoId") Integer videoId);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏视频
|
||||||
|
*
|
||||||
|
* @param videoCollection
|
||||||
|
*/
|
||||||
|
void insertVideoCollection(VideoCollection videoCollection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频添加视频购买列表中
|
||||||
|
*
|
||||||
|
* @param videoBuy
|
||||||
|
*/
|
||||||
|
void insertVideoBuy(VideoBuy videoBuy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我收藏的视频
|
||||||
|
*
|
||||||
|
* @param collectionUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ResponseVideo> listVideoCollection(@Param("collectionUserId") Integer collectionUserId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除我收藏的视频
|
||||||
|
*
|
||||||
|
* @param videoCollection
|
||||||
|
*/
|
||||||
|
void deleteVideoCollection(VideoCollection videoCollection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我购买的视频
|
||||||
|
*
|
||||||
|
* @param buyUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ResponseVideo> listVideoBuy(@Param("buyUserId") Integer buyUserId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布视频
|
||||||
|
*
|
||||||
|
* @param requestPostVideos
|
||||||
|
*/
|
||||||
|
void postVideos(RequestPostVideos requestPostVideos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询评论列表
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<Comments> listComments(@Param("videoId") Integer videoId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改购买后的视频购买总人数
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
void updateVideo(@Param("videoId") Integer videoId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询视频价格
|
||||||
|
* @param videoId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Video getVideoPrice(@Param("videoId") Integer videoId);
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package com.health.video.server.service;
|
||||||
|
|
||||||
|
import com.health.common.core.domain.Result;
|
||||||
|
import com.health.video.common.domain.Comments;
|
||||||
|
import com.health.video.common.domain.VideoType;
|
||||||
|
import com.health.video.common.domain.request.RequestInsertComments;
|
||||||
|
import com.health.video.common.domain.request.RequestPostVideos;
|
||||||
|
import com.health.video.common.domain.response.ResponseVideo;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 20:03
|
||||||
|
*/
|
||||||
|
public interface VideoService {
|
||||||
|
/**
|
||||||
|
* 查询视频类型列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<VideoType> listVideoType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频列表
|
||||||
|
*
|
||||||
|
* @param videoTypeId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ResponseVideo> listVideo(Integer videoTypeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送评论
|
||||||
|
*
|
||||||
|
* @param requestInsertComments
|
||||||
|
*/
|
||||||
|
void insertComments(RequestInsertComments requestInsertComments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏视频
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
void insertVideoCollection(Integer videoId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买视频
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
void insertVideoBuy(Integer videoId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我收藏的视频
|
||||||
|
*
|
||||||
|
* @param collectionUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ResponseVideo> listVideoCollection(Integer collectionUserId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除我收藏的视频
|
||||||
|
*
|
||||||
|
* @param videoCollectionId
|
||||||
|
*/
|
||||||
|
void deleteVideoCollection(Integer videoCollectionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我购买的视频
|
||||||
|
*
|
||||||
|
* @param buyUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ResponseVideo> listVideoBuy(Integer buyUserId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传视频
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Result uploadVideo(MultipartFile file) throws InterruptedException, IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布视频
|
||||||
|
*
|
||||||
|
* @param requestPostVideos
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Result postVideos(RequestPostVideos requestPostVideos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询评论列表
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<Comments> listComments(Integer videoId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.health.video.server.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.health.video.common.domain.VideoBuy;
|
||||||
|
import com.health.video.server.mapper.VideoMapper;
|
||||||
|
import com.rabbitmq.client.Channel;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.Queue;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/24 10:51
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
@Service
|
||||||
|
public class InsertUserVideoQueue {
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
@Autowired
|
||||||
|
private VideoMapper videoMapper;
|
||||||
|
|
||||||
|
@RabbitListener(queuesToDeclare = {@Queue("insert_video_buy")})
|
||||||
|
public void insertUserVideo(String msg, Message message, Channel channel) {
|
||||||
|
try {
|
||||||
|
log.info("消费者接收到消息,消息是:{}", msg);
|
||||||
|
String messageId = message.getMessageProperties().getMessageId();
|
||||||
|
Long insertUserVideo = redisTemplate.opsForSet().add("insert_video_buy", messageId);//消息不重复
|
||||||
|
if (null != insertUserVideo && 0 < insertUserVideo) {
|
||||||
|
VideoBuy videoBuy = JSONObject.parseObject(msg, VideoBuy.class);
|
||||||
|
videoMapper.insertVideoBuy(videoBuy);
|
||||||
|
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);//消息成功消费后发送消息给生产者
|
||||||
|
log.info("消费者成功消费消息,消息是:{}", msg);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("消费者消费消息异常,消息内容是:{},异常信息是:{}", msg, e);
|
||||||
|
try {
|
||||||
|
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);//消费失败 消息回退到队列 ,其他消费者继续消费
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("消费者回退消息异常,消息内容是:{},异常信息是:{}", msg, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,334 @@
|
||||||
|
package com.health.video.server.service.impl;
|
||||||
|
|
||||||
|
import com.health.common.core.constant.SecurityConstants;
|
||||||
|
import com.health.wallet.common.domain.req.MoneyChangeRecordReq;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.amazonaws.AmazonClientException;
|
||||||
|
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||||
|
import com.amazonaws.auth.BasicSessionCredentials;
|
||||||
|
import com.amazonaws.client.builder.AwsClientBuilder;
|
||||||
|
import com.amazonaws.event.ProgressEventType;
|
||||||
|
import com.amazonaws.event.ProgressListener;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||||
|
import com.amazonaws.services.s3.model.PutObjectRequest;
|
||||||
|
import com.amazonaws.services.s3.transfer.TransferManager;
|
||||||
|
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
|
||||||
|
import com.amazonaws.services.s3.transfer.Upload;
|
||||||
|
import com.health.common.core.domain.Result;
|
||||||
|
import com.health.common.security.utils.SecurityUtils;
|
||||||
|
import com.health.video.common.domain.*;
|
||||||
|
import com.health.video.common.domain.request.RequestInsertComments;
|
||||||
|
import com.health.video.common.domain.request.RequestPostVideos;
|
||||||
|
import com.health.video.common.domain.response.ResponseVideo;
|
||||||
|
import com.health.video.server.mapper.VideoMapper;
|
||||||
|
import com.health.video.server.service.VideoService;
|
||||||
|
import com.health.wallet.remote.RemoteWalletService;
|
||||||
|
import org.redisson.api.RLock;
|
||||||
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.amqp.core.MessageDeliveryMode;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import com.health.video.server.utils.DogeUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/20 20:03
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@SuppressWarnings("ALL")
|
||||||
|
public class VideoServiceImpl implements VideoService {
|
||||||
|
@Autowired
|
||||||
|
private VideoMapper videoMapper;
|
||||||
|
@Autowired
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
@Autowired
|
||||||
|
private RedissonClient redissonClient;
|
||||||
|
@Autowired
|
||||||
|
private RemoteWalletService remoteWalletService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询视频类型列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<VideoType> listVideoType() {
|
||||||
|
return videoMapper.listVideoType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<ResponseVideo> listVideo(Integer videoTypeId) {
|
||||||
|
return videoMapper.listVideo(videoTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送评论
|
||||||
|
*
|
||||||
|
* @param requestInsertComments
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertComments(RequestInsertComments requestInsertComments) {
|
||||||
|
Comments comments = new Comments();//创建Comments对象
|
||||||
|
//赋值
|
||||||
|
comments.setCommentsUserId(Math.toIntExact(SecurityUtils.getUserId()));
|
||||||
|
comments.setCommentContent(requestInsertComments.getCommentContent());
|
||||||
|
comments.setVideoId(requestInsertComments.getVideoId());
|
||||||
|
videoMapper.insertComments(comments);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏视频
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertVideoCollection(Integer videoId) {
|
||||||
|
VideoCollection videoCollection = new VideoCollection();//创建VideoCollection对象
|
||||||
|
videoCollection.setVideoId(videoId);
|
||||||
|
videoCollection.setCollectionUserId(Math.toIntExact(SecurityUtils.getUserId()));//获取当前登录人ID给用户ID赋值
|
||||||
|
videoCollection.setIsCollection(1);
|
||||||
|
videoCollection.setIsDeleteCollection(2);
|
||||||
|
videoMapper.insertVideoCollection(videoCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购买视频
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void insertVideoBuy(Integer videoId) {
|
||||||
|
Video video = videoMapper.getVideoPrice(videoId);//查询视频价格
|
||||||
|
//创建分布式锁对象
|
||||||
|
RLock myLock = redissonClient.getLock("myLock");
|
||||||
|
try {
|
||||||
|
//加锁 最多等待5秒 10秒后自动释放
|
||||||
|
boolean tryLock = myLock.tryLock(5, 10, TimeUnit.SECONDS);
|
||||||
|
if (Boolean.TRUE.equals(tryLock)) { //获取锁成功
|
||||||
|
//创建VideoBuy对象
|
||||||
|
VideoBuy videoBuy = new VideoBuy();
|
||||||
|
videoBuy.setVideoId(videoId);
|
||||||
|
videoBuy.setIsBuy(1);
|
||||||
|
videoBuy.setIsDeleteBuy(2);
|
||||||
|
videoBuy.setBuyUserId(Math.toIntExact(SecurityUtils.getUserId()));
|
||||||
|
|
||||||
|
//rabbitMq发送消息
|
||||||
|
rabbitTemplate.convertAndSend("insert_video_buy", JSONObject.toJSONString(videoBuy), msg -> {
|
||||||
|
msg.getMessageProperties().setMessageId(UUID.randomUUID().toString().replaceAll("-", ""));
|
||||||
|
msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);//生产者开启消息持久化
|
||||||
|
return msg;
|
||||||
|
});
|
||||||
|
|
||||||
|
//修改用户余额
|
||||||
|
MoneyChangeRecordReq moneyChangeRecordReq = new MoneyChangeRecordReq();
|
||||||
|
moneyChangeRecordReq.setChangeAmount(video.getPrice());
|
||||||
|
moneyChangeRecordReq.setChangeOrigin("视频购买");
|
||||||
|
moneyChangeRecordReq.setChangeType(0);
|
||||||
|
moneyChangeRecordReq.setCreateUser(SecurityUtils.getUserId());
|
||||||
|
remoteWalletService.moneyChangeByOtherOperate(moneyChangeRecordReq, SecurityConstants.INNER);
|
||||||
|
|
||||||
|
//异步修改购买后的视频购买总人数
|
||||||
|
CompletableFuture.runAsync(()->{
|
||||||
|
videoMapper.updateVideo(videoId);
|
||||||
|
});
|
||||||
|
} else {//获取锁失败
|
||||||
|
throw new RuntimeException("等待时间过长,请重试!");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("异常内容:"+e);
|
||||||
|
} finally {
|
||||||
|
//释放锁
|
||||||
|
myLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我收藏的视频
|
||||||
|
*
|
||||||
|
* @param collectionUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<ResponseVideo> listVideoCollection(Integer collectionUserId) {
|
||||||
|
return videoMapper.listVideoCollection(collectionUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除我收藏的视频
|
||||||
|
*
|
||||||
|
* @param videoCollectionId
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void deleteVideoCollection(Integer videoCollectionId) {
|
||||||
|
VideoCollection videoCollection = new VideoCollection();//创建VideoCollection对象
|
||||||
|
videoCollection.setVideoCollectionId(videoCollectionId);
|
||||||
|
videoCollection.setIsCollection(2);
|
||||||
|
videoCollection.setIsDeleteCollection(1);
|
||||||
|
videoMapper.deleteVideoCollection(videoCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询我购买的视频
|
||||||
|
*
|
||||||
|
* @param buyUserId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<ResponseVideo> listVideoBuy(Integer buyUserId) {
|
||||||
|
return videoMapper.listVideoBuy(buyUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传视频
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Result uploadVideo(MultipartFile file) {
|
||||||
|
// 初始化JSONObject对象
|
||||||
|
JSONObject vodConfig = new JSONObject();
|
||||||
|
// 获取文件名称
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
int dotIndex = originalFilename.lastIndexOf(".");
|
||||||
|
String result = originalFilename.substring(0, dotIndex);
|
||||||
|
// 获取文件后缀,因此此后端代码可接收一切文件,上传格式前端限定
|
||||||
|
String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
|
||||||
|
// 重构文件名称
|
||||||
|
String newVideoName = UUID.randomUUID().toString().replaceAll("-", "") + "." + fileExt;// 新的文件名
|
||||||
|
|
||||||
|
vodConfig.put("filename", originalFilename + fileExt); // 此参数不重要,只要能保留文件后缀名如 a.mp4 即可
|
||||||
|
vodConfig.put("vn", newVideoName); // .. . 分组配置、回调参数
|
||||||
|
JSONObject body = new JSONObject();// 构建body对象
|
||||||
|
body.put("channel", "VOD_UPLOAD");
|
||||||
|
body.put("vodConfig", vodConfig);
|
||||||
|
|
||||||
|
JSONObject api = DogeUtil.dogeAPIGet("/auth/tmp_token.json", body);//获取临时密码和上传信息
|
||||||
|
JSONObject credentials = api.getJSONObject("Credentials"); // 包含本次上传视频使用的临时密钥,下面初始化 S3 实例时会用到
|
||||||
|
JSONObject uploadInfo = api.getJSONObject("VodUploadInfo"); // 包含本次上传视频的目标信息(s3Bucket、s3Endpoint、key,系统提供,无需修改)以及本次上传的唯一 ID:did ,下面上传时会用到
|
||||||
|
System.out.println(uploadInfo);
|
||||||
|
|
||||||
|
// 使用临时密钥信息初始化 BasicSessionCredentials 对象
|
||||||
|
BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
|
||||||
|
credentials.getString("accessKeyId"),
|
||||||
|
credentials.getString("secretAccessKey"),
|
||||||
|
credentials.getString("sessionToken"));
|
||||||
|
|
||||||
|
// 使用上传信息中的S3配置信息和认证信息初始化 AmazonS3 对象
|
||||||
|
AmazonS3 s3 = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).
|
||||||
|
withEndpointConfiguration(new AwsClientBuilder.
|
||||||
|
EndpointConfiguration(uploadInfo.getString("s3Endpoint"), "automatic")).build();
|
||||||
|
try {
|
||||||
|
// 利用 s3 初始化,并配置上传进度回调
|
||||||
|
TransferManager tm = TransferManagerBuilder
|
||||||
|
.standard()
|
||||||
|
.withS3Client(s3)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 获取上传的文件名
|
||||||
|
String filename = file.getOriginalFilename();
|
||||||
|
// 设置本地存储路径
|
||||||
|
String localPath = "/tmp/tomcat.10010.12973406643068623510/work/Tomcat/localhost/ROOT";
|
||||||
|
// 拼接本地文件路径,使用了文件分隔符来保证路径的正确性
|
||||||
|
String filePath = localPath + File.separator + "D:\\uploadVideo" + File.separator + filename;
|
||||||
|
// 创建本地文件对象
|
||||||
|
File localFile = new File(filePath);
|
||||||
|
// 检查目录是否存在,如果不存在则创建
|
||||||
|
File localDirectory = localFile.getParentFile();
|
||||||
|
if (!localDirectory.exists()) {
|
||||||
|
localDirectory.mkdirs();
|
||||||
|
}
|
||||||
|
// 将上传的文件保存到本地文件
|
||||||
|
file.transferTo(localFile);
|
||||||
|
// 获取本地文件的大小
|
||||||
|
long fileSize = localFile.length();
|
||||||
|
|
||||||
|
System.out.println("开始分片上传");
|
||||||
|
|
||||||
|
// 指定上传的目标空间路径、目标文件名和本地文件
|
||||||
|
PutObjectRequest req = new PutObjectRequest(
|
||||||
|
uploadInfo.getString("s3Bucket"),
|
||||||
|
uploadInfo.getString("key"),
|
||||||
|
localFile);
|
||||||
|
// 目标空间路径,由上面获取到的 VodUploadInfo 指定,不可更改
|
||||||
|
|
||||||
|
// 设置各过程进度回调
|
||||||
|
req.setGeneralProgressListener(new ProgressListener() {
|
||||||
|
Long totalByteRead = 0L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) {
|
||||||
|
if (progressEvent.getEventType() == ProgressEventType.REQUEST_BYTE_TRANSFER_EVENT && totalByteRead < fileSize) {
|
||||||
|
totalByteRead += progressEvent.getBytesTransferred();
|
||||||
|
System.out.println("传输中:" + totalByteRead + "/" + fileSize + " (" + ((totalByteRead * 100.0F / fileSize)) + "%)");
|
||||||
|
} else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_COMPLETED_EVENT) {
|
||||||
|
System.out.println("传输完成");
|
||||||
|
} else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_FAILED_EVENT) {
|
||||||
|
System.out.println("传输失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TransferManager 的处理默认是异步的,下面的 upload 方法调用完成后不会等待
|
||||||
|
// 调用 tm.upload(req) 方法开始上传文件
|
||||||
|
Upload upload = tm.upload(req);
|
||||||
|
// 不过,你也可以使用 waitForCompletion 来等待上传完成
|
||||||
|
upload.waitForCompletion();
|
||||||
|
System.out.println("分片上传完成");
|
||||||
|
// 向多吉云汇报此次上传已完成并获得本次上传的视频 ID,did 参数来自上面获取临时密钥时获取到的 VodUploadInfo 。
|
||||||
|
JSONObject cbapi = DogeUtil.dogeAPIGet("/callback/upload.json?did=" + uploadInfo.getString("did"));
|
||||||
|
System.out.println(cbapi);
|
||||||
|
Integer vid = cbapi.getInteger("vid");
|
||||||
|
System.out.println("上传完成,视频 ID:" + vid);
|
||||||
|
// 获取视频的详细信息
|
||||||
|
JSONObject msg = DogeUtil.dogeAPIGet("/video/info.json?vid=" + vid);
|
||||||
|
System.out.println("视频详细信息:" + msg);
|
||||||
|
return Result.success(msg.get("vcode"), "操作成功!");
|
||||||
|
} catch (AmazonClientException | InterruptedException | IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布视频
|
||||||
|
*
|
||||||
|
* @param requestPostVideos
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Result postVideos(RequestPostVideos requestPostVideos) {
|
||||||
|
Video video = new Video();// 创建Video对象
|
||||||
|
video.setFounder(Math.toIntExact(SecurityUtils.getUserId()));
|
||||||
|
//发布视频
|
||||||
|
videoMapper.postVideos(requestPostVideos);
|
||||||
|
return Result.success(null, "成功发布视频!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询评论列表
|
||||||
|
*
|
||||||
|
* @param videoId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Comments> listComments(Integer videoId) {
|
||||||
|
return videoMapper.listComments(videoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.health.video.server.utils;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.Binding;
|
||||||
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
|
import org.springframework.amqp.core.DirectExchange;
|
||||||
|
import org.springframework.amqp.core.Queue;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DLXQueue {
|
||||||
|
// routingKey
|
||||||
|
private static final String DEAD_ROUTING_KEY = "dead.routingkey";
|
||||||
|
private static final String ROUTING_KEY = "routingkey";
|
||||||
|
private static final String DEAD_EXCHANGE = "dead.exchange";
|
||||||
|
private static final String EXCHANGE = "common.exchange";
|
||||||
|
@Autowired
|
||||||
|
RabbitTemplate rabbitTemplate;
|
||||||
|
@Resource
|
||||||
|
RabbitAdmin rabbitAdmin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送死信队列,过期后进入死信交换机,进入死信队列
|
||||||
|
*
|
||||||
|
* @param queueName 队列名称
|
||||||
|
* @param deadQueueName 死信队列名称
|
||||||
|
* @param params 消息内容
|
||||||
|
* @param expiration 过期时间 毫秒
|
||||||
|
*/
|
||||||
|
public void sendDLXQueue(String queueName, String deadQueueName, Object params, Integer expiration) {
|
||||||
|
/**
|
||||||
|
* ----------------------------------先创建一个ttl队列和死信队列--------------------------------------------
|
||||||
|
*/
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
// 队列设置存活时间,单位ms, 必须是整形数据。
|
||||||
|
map.put("x-message-ttl", expiration);
|
||||||
|
// 设置死信交换机
|
||||||
|
map.put("x-dead-letter-exchange", DEAD_EXCHANGE);
|
||||||
|
// 设置死信交换器路由
|
||||||
|
map.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY);
|
||||||
|
/*参数1:队列名称 参数2:持久化 参数3:是否排他 参数4:自动删除队列 参数5:队列参数*/
|
||||||
|
Queue queue = new Queue(queueName, true, false, false, map);
|
||||||
|
rabbitAdmin.declareQueue(queue);
|
||||||
|
/**
|
||||||
|
* ---------------------------------创建交换机---------------------------------------------
|
||||||
|
*/
|
||||||
|
DirectExchange directExchange = new DirectExchange(EXCHANGE, true, false);
|
||||||
|
rabbitAdmin.declareExchange(directExchange);
|
||||||
|
/**
|
||||||
|
* ---------------------------------队列绑定交换机---------------------------------------------
|
||||||
|
*/
|
||||||
|
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(ROUTING_KEY);
|
||||||
|
rabbitAdmin.declareBinding(binding);
|
||||||
|
/**
|
||||||
|
* ---------------------------------在创建一个死信交换机和队列,接收死信队列---------------------------------------------
|
||||||
|
*/
|
||||||
|
DirectExchange deadExchange = new DirectExchange(DEAD_EXCHANGE, true, false);
|
||||||
|
rabbitAdmin.declareExchange(deadExchange);
|
||||||
|
|
||||||
|
Queue deadQueue = new Queue(deadQueueName, true, false, false);
|
||||||
|
rabbitAdmin.declareQueue(deadQueue);
|
||||||
|
/**
|
||||||
|
* ---------------------------------队列绑定死信交换机---------------------------------------------
|
||||||
|
*/
|
||||||
|
// 将队列和交换机绑定
|
||||||
|
Binding deadbinding = BindingBuilder.bind(deadQueue).to(deadExchange).with(DEAD_ROUTING_KEY);
|
||||||
|
rabbitAdmin.declareBinding(deadbinding);
|
||||||
|
// 发送消息
|
||||||
|
rabbitTemplate.convertAndSend(EXCHANGE, ROUTING_KEY, params);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.health.video.server.utils;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.Binding;
|
||||||
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
|
import org.springframework.amqp.core.CustomExchange;
|
||||||
|
import org.springframework.amqp.core.Queue;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送延迟队列的工具类
|
||||||
|
* @author 唐文康
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DelayedQueue {
|
||||||
|
|
||||||
|
// routingKey
|
||||||
|
private static final String DELAYED_ROUTING_KEY = "delayed.routingkey";
|
||||||
|
|
||||||
|
// 延迟队列交换机
|
||||||
|
private static final String DELAYED_EXCHANGE = "delayed.exchange";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
RabbitAdmin rabbitAdmin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送延迟队列
|
||||||
|
*
|
||||||
|
* @param queueName 队列名称
|
||||||
|
* @param params 消息内容
|
||||||
|
* @param expiration 延迟时间 毫秒
|
||||||
|
*/
|
||||||
|
public void sendDelayedQueue(String queueName, Object params, Integer expiration) {
|
||||||
|
// 先创建一个队列
|
||||||
|
Queue queue = new Queue(queueName);
|
||||||
|
rabbitAdmin.declareQueue(queue);
|
||||||
|
|
||||||
|
// 创建延迟队列交换机
|
||||||
|
CustomExchange customExchange = createCustomExchange();
|
||||||
|
rabbitAdmin.declareExchange(customExchange);
|
||||||
|
|
||||||
|
// 将队列和交换机绑定
|
||||||
|
Binding binding = BindingBuilder.bind(queue).to(customExchange).with(DELAYED_ROUTING_KEY).noargs();
|
||||||
|
rabbitAdmin.declareBinding(binding);
|
||||||
|
|
||||||
|
// 发送延迟消息
|
||||||
|
rabbitTemplate.convertAndSend(DELAYED_EXCHANGE, DELAYED_ROUTING_KEY, params, msg -> {
|
||||||
|
// 发送消息的时候 延迟时长
|
||||||
|
msg.getMessageProperties().setMessageId(UUID.randomUUID().toString().replaceAll("-", ""));
|
||||||
|
msg.getMessageProperties().setDelay(expiration);
|
||||||
|
return msg;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CustomExchange createCustomExchange() {
|
||||||
|
Map<String, Object> arguments = new HashMap<>();
|
||||||
|
/**
|
||||||
|
* 参数说明:
|
||||||
|
* 1.交换机的名称
|
||||||
|
* 2.交换机的类型
|
||||||
|
* 3.是否需要持久化
|
||||||
|
* 4.是否自动删除
|
||||||
|
* 5.其它参数
|
||||||
|
*/
|
||||||
|
arguments.put("x-delayed-type", "direct");
|
||||||
|
return new CustomExchange(DELAYED_EXCHANGE, "x-delayed-message", true, false, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
package com.health.video.server.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.apache.http.impl.io.ChunkedOutputStream;
|
||||||
|
import org.apache.http.io.SessionOutputBuffer;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wenkang Tang
|
||||||
|
* @date 2023/10/27 20:33
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@Component
|
||||||
|
public class DogeUtil {
|
||||||
|
// 普通 API 请使用这个方法
|
||||||
|
public static JSONObject dogeAPIGet(String apiPath, Map<String, String> params) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> hm : params.entrySet()) {
|
||||||
|
try {
|
||||||
|
sb.append(URLEncoder.encode(hm.getKey(), String.valueOf(StandardCharsets.UTF_8))).append('=').append(URLEncoder.encode(hm.getValue(), String.valueOf(StandardCharsets.UTF_8))).append("&");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String bodyText = sb.toString().replace("&$", "");
|
||||||
|
try {
|
||||||
|
return dogeAPIGet(apiPath, bodyText, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 要求请求内容 Body 是一个 JSON 的 API,请使用这个方法
|
||||||
|
public static JSONObject dogeAPIGet(String apiPath, JSONObject params) {
|
||||||
|
String bodyText = params.toString();
|
||||||
|
try {
|
||||||
|
return dogeAPIGet(apiPath, bodyText, true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无参数 API
|
||||||
|
public static JSONObject dogeAPIGet(String apiPath) {
|
||||||
|
try {
|
||||||
|
return dogeAPIGet(apiPath, "", true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject dogeAPIGet(String apiPath, String paramsText, Boolean jsonMode) throws IOException {
|
||||||
|
// 这里返回值类型是 JSONObject,你也可以根据你的具体情况使用不同的 JSON 库并修改最下方 JSON 处理代码
|
||||||
|
|
||||||
|
// 这里替换为你的多吉云永久 AccessKey 和 SecretKey,可在用户中心 - 密钥管理中查看
|
||||||
|
// 请勿在客户端暴露 AccessKey 和 SecretKey,那样恶意用户将获得账号完全控制权
|
||||||
|
String accessKey = "02a4810cb73129c4";
|
||||||
|
String secretKey = "4d9a1342fcee91d96698ce9425d5a23a";
|
||||||
|
|
||||||
|
String signStr = apiPath + "\n" + paramsText;
|
||||||
|
String sign = "";
|
||||||
|
try {
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA1");
|
||||||
|
mac.init(new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"));
|
||||||
|
sign = new String(new Hex().encode(mac.doFinal(signStr.getBytes())), StandardCharsets.UTF_8); // 这里 Hex 来自 org.apache.commons.codec.binary.Hex
|
||||||
|
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
String authorization = "TOKEN " + accessKey + ':' + sign;
|
||||||
|
|
||||||
|
URL u = new URL("https://api.dogecloud.com" + apiPath);
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.setRequestProperty("Content-Type", jsonMode ? "application/json" : "application/x-www-form-urlencoded");
|
||||||
|
conn.setRequestProperty("Authorization", authorization);
|
||||||
|
conn.setRequestProperty("Content-Length", String.valueOf(paramsText.length()));
|
||||||
|
OutputStream os = conn.getOutputStream();
|
||||||
|
os.write(paramsText.getBytes());
|
||||||
|
os.flush();
|
||||||
|
os.close();
|
||||||
|
StringBuilder retJSON = new StringBuilder();
|
||||||
|
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
|
String readLine = "";
|
||||||
|
try (BufferedReader responseReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
|
||||||
|
while ((readLine = responseReader.readLine()) != null) {
|
||||||
|
retJSON.append(readLine).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject ret = JSONObject.parseObject(retJSON.toString());
|
||||||
|
if (ret.getInteger("code") != 200) {
|
||||||
|
System.err.println("{\"error\":\"API 返回错误:" + ret.getString("msg") + "\"}");
|
||||||
|
} else {
|
||||||
|
return ret.getJSONObject("data");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.err.println("{\"error\":\"网络错误:" + conn.getResponseCode() + "\"}");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.health.video.server.utils;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.Binding;
|
||||||
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
|
import org.springframework.amqp.core.DirectExchange;
|
||||||
|
import org.springframework.amqp.core.Queue;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送TTL队列 设置 消息的存活时间 如果超过了存活时间
|
||||||
|
* 该条消息还没有被消费 则自动从队列中消息 ,如果配置了死信队列则消息会进入死信队列
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TtlQueue {
|
||||||
|
// routingKey
|
||||||
|
private static final String TTL_KEY = "ttl.routingkey";
|
||||||
|
private static final String TTL_EXCHANGE = "ttl.exchange";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
RabbitAdmin rabbitAdmin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送TTL队列
|
||||||
|
*
|
||||||
|
* @param queueName 队列名称
|
||||||
|
* @param params 消息内容
|
||||||
|
* @param expiration 过期时间 毫秒
|
||||||
|
*/
|
||||||
|
public void sendTtlQueue(String queueName, Object params, Integer expiration) {
|
||||||
|
/**
|
||||||
|
* ----------------------------------先创建一个ttl队列--------------------------------------------
|
||||||
|
*/
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
// 队列设置存活时间,单位ms,必须是整形数据。
|
||||||
|
map.put("x-message-ttl", expiration);
|
||||||
|
/*参数1:队列名称 参数2:持久化 参数3:是否排他 参数4:自动删除队列 参数5:队列参数*/
|
||||||
|
Queue queue = new Queue(queueName, true, false, false, map);
|
||||||
|
rabbitAdmin.declareQueue(queue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ---------------------------------创建交换机---------------------------------------------
|
||||||
|
*/
|
||||||
|
DirectExchange directExchange = new DirectExchange(TTL_EXCHANGE, true, false);
|
||||||
|
rabbitAdmin.declareExchange(directExchange);
|
||||||
|
/**
|
||||||
|
* ---------------------------------队列绑定交换机---------------------------------------------
|
||||||
|
*/
|
||||||
|
// 将队列和交换机绑定
|
||||||
|
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(TTL_KEY);
|
||||||
|
rabbitAdmin.declareBinding(binding);
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
rabbitTemplate.convertAndSend(TTL_EXCHANGE, TTL_KEY, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 10010
|
||||||
|
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
jackson:
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
time-zone: GMT+8
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 50MB
|
||||||
|
max-request-size: 300MB
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: health-video
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 10.100.1.5:8848
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 10.100.1.5:8848
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
rabbitmq:
|
||||||
|
host: 10.100.1.3
|
||||||
|
port: 5072
|
||||||
|
username: guest
|
||||||
|
password: guest
|
||||||
|
virtual-host: /
|
||||||
|
publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
|
||||||
|
publisher-returns: true #确认消息已发送到队列(Queue)
|
||||||
|
listener:
|
||||||
|
simple:
|
||||||
|
prefetch: 1 # 每次只能获取一条,处理完成才能获取下一条
|
||||||
|
acknowledge-mode: manual # 设置消费端手动ack确认
|
||||||
|
retry:
|
||||||
|
enabled: true # 是否支持重试
|
||||||
|
template:
|
||||||
|
# 只要消息抵达Queue,就会异步发送优先回调return firm
|
||||||
|
mandatory: true
|
||||||
|
redis:
|
||||||
|
host: 10.100.1.2
|
||||||
|
# 关闭健康检查
|
||||||
|
management:
|
||||||
|
health:
|
||||||
|
rabbit:
|
||||||
|
enabled: false
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
<!-- 日志存放路径 -->
|
||||||
|
<property name="log.path" value="./logs/health-video" />
|
||||||
|
<!-- 日志输出格式 -->
|
||||||
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.health" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,138 @@
|
||||||
|
<?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.health.video.server.mapper.VideoMapper">
|
||||||
|
|
||||||
|
<!-- 发送评论 -->
|
||||||
|
<insert id="insertComments">
|
||||||
|
INSERT INTO `health-video`.`t_comments` (`comments_id`, `comment_content`, `comments_user_id`, `create_time`,
|
||||||
|
`video_id`)
|
||||||
|
VALUES (0, #{commentContent}, #{commentsUserId}, NOW(), #{videoId});
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 收藏视频 -->
|
||||||
|
<insert id="insertVideoCollection">
|
||||||
|
INSERT INTO `health-video`.`t_video_collection` (`video_collection_id`, `video_id`, `collection_user_id`,
|
||||||
|
`is_collection`, `collect_time`, `is_delete_collection`)
|
||||||
|
VALUES (0, #{videoId}, #{collectionUserId}, #{isCollection}, NOW(), #{isDeleteCollection});
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 发布视频 -->
|
||||||
|
<insert id="postVideos" useGeneratedKeys="true" keyProperty="purchaseNumber">
|
||||||
|
INSERT INTO `health-video`.`t_video` (`video_id`, `title`, `details`, `full_video`, `purchase_number`,
|
||||||
|
`video_type_id`, `price`, `founder`, `release_time`)
|
||||||
|
VALUES (0, #{title}, #{details}, #{fullVideo}, 0, #{videoTypeId}, #{price}, #{founder}, NOW());
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 视频添加视频购买列表中 -->
|
||||||
|
<insert id="insertVideoBuy">
|
||||||
|
INSERT INTO `health-video`.`t_video_buy` (`video_buy_id`, `video_id`, `buy_user_id`, `is_buy`, `buy_time`,
|
||||||
|
`is_delete_buy`)
|
||||||
|
VALUES (0, #{videoId}, #{buyUserId}, #{isBuy}, now(), #{isDeleteBuy});
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 删除我收藏的视频 -->
|
||||||
|
<update id="deleteVideoCollection">
|
||||||
|
UPDATE `health-video`.`t_video_collection`
|
||||||
|
SET `is_collection` = 2,
|
||||||
|
`is_delete_collection` = 1
|
||||||
|
WHERE `video_collection_id` = #{videoCollectionId};
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 修改购买后的视频购买总人数 -->
|
||||||
|
<update id="updateVideo">
|
||||||
|
UPDATE `health-video`.`t_video`
|
||||||
|
SET `purchase_number` = purchase_number + 1
|
||||||
|
WHERE `video_id` = #{videoId};
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<!-- 查询视频类型列表 -->
|
||||||
|
<select id="listVideoType" resultType="com.health.video.common.domain.VideoType">
|
||||||
|
select *
|
||||||
|
from t_video_type
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 视频列表 -->
|
||||||
|
<select id="listVideo" resultType="com.health.video.common.domain.response.ResponseVideo">
|
||||||
|
select
|
||||||
|
v.*,
|
||||||
|
vb.video_buy_id,
|
||||||
|
vb.is_buy,
|
||||||
|
vb.buy_time,
|
||||||
|
vb.is_delete_buy,
|
||||||
|
vb.buy_user_id,
|
||||||
|
vc.video_collection_id,
|
||||||
|
vc.is_collection,
|
||||||
|
vc.collect_time,
|
||||||
|
vc.is_delete_collection,
|
||||||
|
vc.collection_user_id,
|
||||||
|
vt.video_type_name
|
||||||
|
from t_video v
|
||||||
|
left join t_video_buy vb on vb.video_id = v.video_id
|
||||||
|
left join t_video_collection vc on vc.video_id = v.video_id
|
||||||
|
left join t_video_type vt on vt.video_type_id = v.video_type_id
|
||||||
|
<where>
|
||||||
|
<if test="null != videoTypeId">
|
||||||
|
and v.video_type_id = #{videoTypeId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据videoId查询视频表 -->
|
||||||
|
<select id="getVideoByVideoId" resultType="com.health.video.common.domain.Video">
|
||||||
|
select *
|
||||||
|
from t_video
|
||||||
|
where video_id = #{videoId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询我收藏的视频 -->
|
||||||
|
<select id="listVideoCollection" resultType="com.health.video.common.domain.response.ResponseVideo">
|
||||||
|
select v.*,
|
||||||
|
vc.video_collection_id,
|
||||||
|
vc.is_collection,
|
||||||
|
vc.collect_time,
|
||||||
|
vc.is_delete_collection,
|
||||||
|
vc.collection_user_id,
|
||||||
|
vt.video_type_name,
|
||||||
|
tvb.video_buy_id,
|
||||||
|
tvb.is_buy,
|
||||||
|
tvb.buy_time,
|
||||||
|
tvb.is_delete_buy
|
||||||
|
from t_video_collection vc
|
||||||
|
left join t_video v on v.video_id = vc.video_id
|
||||||
|
left join t_video_type vt on vt.video_type_id = v.video_type_id
|
||||||
|
left join t_video_buy tvb on tvb.video_id = v.video_id
|
||||||
|
where vc.collection_user_id = #{collectionUserId}
|
||||||
|
and vc.is_delete_collection = 2
|
||||||
|
and vc.is_collection = 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询我购买的视频 -->
|
||||||
|
<select id="listVideoBuy" resultType="com.health.video.common.domain.response.ResponseVideo">
|
||||||
|
select tv.*,
|
||||||
|
tvb.video_buy_id,
|
||||||
|
tvb.buy_user_id,
|
||||||
|
tvb.is_buy,
|
||||||
|
tvb.buy_time,
|
||||||
|
tvb.is_delete_buy,
|
||||||
|
tvt.video_type_name
|
||||||
|
from t_video_buy tvb
|
||||||
|
left join t_video tv on tv.video_id = tvb.video_id
|
||||||
|
left join t_video_type tvt on tvt.video_type_id = tv.video_type_id
|
||||||
|
where tvb.buy_user_id = #{buyUserId}
|
||||||
|
and tvb.is_buy = 1
|
||||||
|
and tvb.is_delete_buy = 2
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询评论列表 -->
|
||||||
|
<select id="listComments" resultType="com.health.video.common.domain.Comments">
|
||||||
|
select *
|
||||||
|
from t_comments
|
||||||
|
where video_id = #{videoId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询视频价格 -->
|
||||||
|
<select id="getVideoPrice" resultType="com.health.video.common.domain.Video">
|
||||||
|
select * from t_video where video_id = #{videoId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.health</groupId>
|
||||||
|
<artifactId>health-modules</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>health-video</artifactId>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>health-video-common</module>
|
||||||
|
<module>health-video-remote</module>
|
||||||
|
<module>health-video-server</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>dragon-public</id>
|
||||||
|
<name>dragon-maven</name>
|
||||||
|
<url>http://10.100.1.7:8081/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>dragon-release</id>
|
||||||
|
<name>dragon-releases</name>
|
||||||
|
<url>http://10.100.1.7:8081/repository/maven-releases/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
</project>
|
Loading…
Reference in New Issue