diff --git a/pom.xml b/pom.xml
index f1362f2e3..5d1d6ff81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -372,6 +372,7 @@
ruoyi-common
ruoyi-extend
ruoyi-modules
+ ruoyi-front
pom
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index c15d89c02..bf0dd0b95 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -138,7 +138,7 @@ mybatis-plus:
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
- typeAliasesPackage: org.dromara.**.domain
+ typeAliasesPackage: org.dromara.**.domain,com.wzj.soopin.**
global-config:
dbConfig:
# 主键类型
diff --git a/ruoyi-front/pom.xml b/ruoyi-front/pom.xml
new file mode 100644
index 000000000..4749b6e32
--- /dev/null
+++ b/ruoyi-front/pom.xml
@@ -0,0 +1,18 @@
+
+
+
+ ruoyi-vue-plus
+ org.dromara
+ ${revision}
+
+ 4.0.0
+ ruoyi-front
+ pom
+
+
+ ruoyi-consumer
+ ruoyi-manager
+
+
diff --git a/ruoyi-front/ruoyi-consumer/pom.xml b/ruoyi-front/ruoyi-consumer/pom.xml
new file mode 100644
index 000000000..e8d6a814f
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/pom.xml
@@ -0,0 +1,103 @@
+
+
+
+ org.dromara
+ ruoyi-front
+ ${revision}
+
+ 4.0.0
+
+ ruoyi-consumer
+
+
+ system系统模块
+
+
+
+
+
+ org.dromara
+ ruoyi-common-core
+
+
+
+ org.dromara
+ ruoyi-common-doc
+
+
+
+ org.dromara
+ ruoyi-common-mybatis
+
+
+
+ org.dromara
+ ruoyi-common-translation
+
+
+
+
+ org.dromara
+ ruoyi-common-oss
+
+
+
+ org.dromara
+ ruoyi-common-log
+
+
+
+
+ org.dromara
+ ruoyi-common-excel
+
+
+
+
+ org.dromara
+ ruoyi-common-sms
+
+
+
+ org.dromara
+ ruoyi-common-tenant
+
+
+
+ org.dromara
+ ruoyi-common-security
+
+
+
+ org.dromara
+ ruoyi-common-web
+
+
+
+ org.dromara
+ ruoyi-common-idempotent
+
+
+
+ org.dromara
+ ruoyi-common-sensitive
+
+
+
+ org.dromara
+ ruoyi-common-encrypt
+
+
+
+ org.dromara
+ ruoyi-common-websocket
+
+
+
+ org.dromara
+ ruoyi-common-sse
+
+
+
+
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/InterceptorConfig.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/InterceptorConfig.java
new file mode 100644
index 000000000..2498b7c32
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/InterceptorConfig.java
@@ -0,0 +1,117 @@
+package com.wzj.soopin.consumer.content.config;
+
+import com.imooc.intercepter.PassportInterceptor;
+import com.imooc.intercepter.UserTokenInterceptor;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContexts;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.net.ssl.SSLContext;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+@Configuration
+public class InterceptorConfig implements WebMvcConfigurer {
+
+ private String[] CORS_HTTP_METHODS = { HttpMethod.HEAD.name(), HttpMethod.GET.name(), HttpMethod.POST.name(),
+ HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.OPTIONS.name(), HttpMethod.PATCH.name() };
+
+ private static final long CORS_MAX_AGE = 30 * 24 * 60 * 60;
+
+ @Bean
+ public PassportInterceptor passportInterceptor() {
+ return new PassportInterceptor();
+ }
+
+ @Bean
+ public UserTokenInterceptor userTokenInterceptor() {
+ return new UserTokenInterceptor();
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(passportInterceptor()).addPathPatterns("/passport/getSMSCode");
+
+ registry.addInterceptor(userTokenInterceptor()).addPathPatterns("/userInfo/modifyUserInfo")
+ .addPathPatterns("/userInfo/modifyImage");
+ }
+
+ @Order(Ordered.HIGHEST_PRECEDENCE)
+ @Bean
+ public CorsFilter corsFilter() {
+ // 添加跨域配置信息
+ CorsConfiguration config = new CorsConfiguration();
+ // 设置访问源地址
+ config.addAllowedOriginPattern("*");
+ // 设置访问源请求头
+ config.addAllowedHeader("*");
+ // 设置是否发送Cookie信息
+ config.setAllowCredentials(true);
+ // 设置访问源请求方法
+ Arrays.stream(CORS_HTTP_METHODS).forEach(method -> config.addAllowedMethod(method));
+ // 设置请求最大有效时长
+ config.setMaxAge(CORS_MAX_AGE);
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ // 配置跨域
+ source.registerCorsConfiguration("/**", config);
+ return new CorsFilter(source);
+ }
+
+ @Primary
+ @Bean
+ public RestTemplate restTemplate() {
+ PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
+ // 连接池最大连接数
+ connManager.setMaxTotal(1000);
+ // 每个主机的并发
+ connManager.setDefaultMaxPerRoute(500);
+
+ CloseableHttpClient httpClient = HttpClients.custom()//
+ .setConnectionManager(connManager)// 设置HTTP连接管理器
+ .build();
+ return buildRestTemplate(httpClient);
+ }
+
+ @Bean
+ public RestTemplate restTemplateIgnoreSSL()
+ throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
+ SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, (chain, authType) -> true).build();
+ SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext,
+ NoopHostnameVerifier.INSTANCE);
+
+ CloseableHttpClient httpClient = HttpClients.custom()//
+ .setSSLSocketFactory(sslSocketFactory)//
+ .build();
+ return buildRestTemplate(httpClient);
+ }
+
+ private RestTemplate buildRestTemplate(CloseableHttpClient httpClient) {
+ HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(
+ httpClient);
+ // 获取链接超时时间
+ httpRequestFactory.setConnectionRequestTimeout(3000);
+ // 指客户端和服务器建立连接的timeout
+ httpRequestFactory.setConnectTimeout(3000);
+ // 读取数据的超时时间
+ httpRequestFactory.setReadTimeout(120000);
+ return new RestTemplate(httpRequestFactory);
+ }
+}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/MinIOConfig.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/MinIOConfig.java
new file mode 100644
index 000000000..91340f0ef
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/MinIOConfig.java
@@ -0,0 +1,33 @@
+package com.wzj.soopin.consumer.content.config;
+
+import com.imooc.utils.MinIOUtils;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@Data
+public class MinIOConfig {
+
+ @Value("${minio.endpoint}")
+ private String endpoint;
+ @Value("${minio.fileHost}")
+ private String fileHost;
+ @Value("${minio.bucketName}")
+ private String bucketName;
+ @Value("${minio.accessKey}")
+ private String accessKey;
+ @Value("${minio.secretKey}")
+ private String secretKey;
+
+ @Value("${minio.imgSize}")
+ private Integer imgSize;
+ @Value("${minio.fileSize}")
+ private Integer fileSize;
+
+ @Bean
+ public MinIOUtils creatMinioClient() {
+ return new MinIOUtils(endpoint, bucketName, accessKey, secretKey, imgSize, fileSize);
+ }
+}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/RedisConfig.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/RedisConfig.java
new file mode 100644
index 000000000..91281bbf6
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/RedisConfig.java
@@ -0,0 +1,56 @@
+package com.wzj.soopin.consumer.content.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RedissonClient;
+import org.redisson.spring.data.connection.RedissonConnectionFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Slf4j
+@Configuration
+@ConditionalOnClass(RedissonClient.class)
+public class RedisConfig {
+
+ private static final RedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
+
+ @Bean
+ RedissonConnectionFactory redisConnectionFactory(RedissonClient redisson) {
+ log.info("------------->>>配置自定义RedissonConnectionFactory");
+ return new RedissonConnectionFactory(redisson);
+ }
+
+ @Bean
+ RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ log.info("------------->>>配置自定义RedisTemplate");
+ return buildRedisTemplate(redisConnectionFactory);
+ }
+
+ /**
+ * 配置redisTemplate
+ *
+ * @param redisConnectionFactory
+ * @param enableTransactionSupport
+ * @return
+ */
+ private RedisTemplate buildRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ // 配置redisTemplate
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(redisConnectionFactory);
+ // key序列化
+ redisTemplate.setKeySerializer(STRING_SERIALIZER);
+ // value序列化
+ redisTemplate.setValueSerializer(STRING_SERIALIZER);
+ // Hash key序列化
+ redisTemplate.setHashKeySerializer(STRING_SERIALIZER);
+ // Hash value序列化
+ redisTemplate.setHashValueSerializer(STRING_SERIALIZER);
+ // 初始化RedisTemplate
+ redisTemplate.afterPropertiesSet();
+ return redisTemplate;
+ }
+}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/SpringSecurityConfig.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/SpringSecurityConfig.java
new file mode 100644
index 000000000..10273d059
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/SpringSecurityConfig.java
@@ -0,0 +1,30 @@
+package com.wzj.soopin.consumer.content.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+/**
+ * spring security配置类.
+ *
+ * @author lzc
+ * @version 1.0
+ */
+@Configuration
+public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests().antMatchers("/**").permitAll() // 所有请求都可以访问
+ .and().csrf().disable() // 跨域请求关闭
+ .headers().frameOptions().disable(); // 资源下载权限关闭
+ }
+
+ @Bean
+ PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/knife4jConfig.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/knife4jConfig.java
new file mode 100644
index 000000000..0415e4d9f
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/config/knife4jConfig.java
@@ -0,0 +1,40 @@
+package com.wzj.soopin.consumer.content.config;
+
+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.builders.RequestHandlerSelectors;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
+
+/**
+ * @author vercen
+ * @version 1.0
+ * @date 2023/5/20 19:55
+ */
+@Configuration
+@EnableSwagger2WebMvc
+public class knife4jConfig {
+ @Bean
+ public Docket defaultApi2() {
+ Docket docket=new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(new ApiInfoBuilder()
+ //.title("swagger-bootstrap-ui-demo RESTful APIs")
+ .description("短视频实战接口文档")
+ .termsOfServiceUrl("http://www.xx.com/")
+ .contact(new Contact("lee", "http://www.imooc.com/", "abc@imooc.com"))
+ .version("1.0")
+ .build())
+ //分组名称
+ .groupName("2.X版本")
+ .select()
+ //这里指定Controller扫描包路径
+ .apis(RequestHandlerSelectors.basePackage("com.imooc.controller"))
+ .paths(PathSelectors.any())
+ .build();
+ return docket;
+ }
+}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/BaseController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/BaseController.java
new file mode 100644
index 000000000..c4a0937b3
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/BaseController.java
@@ -0,0 +1,12 @@
+package com.wzj.soopin.consumer.content.controller;
+
+//public class BaseController {
+//
+// @Autowired
+// public RedisOperator redis;
+//
+// public static final String MOBILE_SMSCODE = "mobile:smscode";
+// public static final String REDIS_USER_TOKEN = "redis_user_token";
+// public static final String REDIS_USER_INFO = "redis_user_info";
+//
+//}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/BaseInfoProperties.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/BaseInfoProperties.java
new file mode 100644
index 000000000..a5ceef8cd
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/BaseInfoProperties.java
@@ -0,0 +1,46 @@
+package com.wzj.soopin.consumer.content.controller;//package com.imooc.controller;
+//
+//import com.github.pagehelper.PageInfo;
+//import com.imooc.utils.RedisOperator;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.validation.BindingResult;
+//import org.springframework.validation.FieldError;
+//
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//
+//public class BaseInfoProperties {
+//
+// @Autowired
+// public RedisOperator redis;
+//
+// public static final Integer COMMON_START_PAGE = 1;
+// public static final Integer COMMON_PAGE_SIZE = 10;
+//
+// public static final String MOBILE_SMSCODE = "mobile:smscode";
+// public static final String REDIS_USER_TOKEN = "redis_user_token";
+// public static final String REDIS_USER_INFO = "redis_user_info";
+//
+//
+// //我的关注总数
+// public static final String REDIS_MY_FOLLOWS_COUNTS = "redis_my_follows_counts";
+// // 我的粉丝总数
+// public static final String REDIS_MY_FANS_COUNTS = "redis_my_fans_counts";
+//
+// // 视频和发布者获赞数
+// public static final String REDIS_VLOG_BE_LIKED_COUNTS = "redis_vlog_be_liked_counts";
+// public static final String REDIS_VLOGER_BE_LIKED_COUNTS = "redis_vloger_be_liked_counts";
+//
+// public PagedGridResult setterPagedGrid(List> list,
+// Integer page) {
+// PageInfo> pageList = new PageInfo<>(list);
+// PagedGridResult gridResult = new PagedGridResult();
+// gridResult.setRows(list);
+// gridResult.setPage(page);
+// gridResult.setRecords(pageList.getTotal());
+// gridResult.setTotal(pageList.getPages());
+// return gridResult;
+// }
+//
+//}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java
new file mode 100644
index 000000000..c00cbd42e
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/CommentController.java
@@ -0,0 +1,114 @@
+package com.wzj.soopin.consumer.content.controller;
+
+import com.imooc.base.BaseInfoProperties;
+import com.imooc.bo.CommentBO;
+import com.imooc.enums.MessageEnum;
+import com.imooc.grace.result.GraceJSONResult;
+import com.imooc.pojo.Comment;
+import com.imooc.pojo.Vlog;
+import com.imooc.service.CommentService;
+import com.imooc.service.MsgService;
+import com.imooc.service.VlogService;
+import com.imooc.vo.CommentVO;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@Api(tags = "CommentController 评论模块的接口")
+@RequestMapping("comment")
+@RestController
+public class CommentController extends BaseInfoProperties {
+
+ @Autowired
+ private CommentService commentService;
+ @Autowired
+ private MsgService msgService;
+ @Autowired
+ private VlogService vlogService;
+//
+ @PostMapping("create")
+ public GraceJSONResult create(@RequestBody @Valid CommentBO commentBO)
+ throws Exception {
+
+ CommentVO commentVO = commentService.createComment(commentBO);
+ return GraceJSONResult.ok(commentVO);
+ }
+//
+ @GetMapping("counts")
+ public GraceJSONResult counts(@RequestParam String vlogId) {
+
+ String countsStr = redis.get(REDIS_VLOG_COMMENT_COUNTS + ":" + vlogId);
+ if (StringUtils.isBlank(countsStr)) {
+ countsStr = "0";
+ }
+
+ return GraceJSONResult.ok(Integer.valueOf(countsStr));
+ }
+
+ @GetMapping("list")
+ public GraceJSONResult list(@RequestParam String vlogId,
+ @RequestParam(defaultValue = "") String userId,
+ @RequestParam Integer page,
+ @RequestParam Integer pageSize) {
+
+ return GraceJSONResult.ok(
+ commentService.queryVlogComments(
+ vlogId,
+ userId,
+ page,
+ pageSize));
+ }
+
+ @DeleteMapping("delete")
+ public GraceJSONResult delete(@RequestParam String commentUserId,
+ @RequestParam String commentId,
+ @RequestParam String vlogId) {
+ commentService.deleteComment(commentUserId,
+ commentId,
+ vlogId);
+ return GraceJSONResult.ok();
+ }
+
+ @PostMapping("like")
+ public GraceJSONResult like(@RequestParam String commentId,
+ @RequestParam String userId) {
+
+ // 故意犯错,bigkey
+ redis.incrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);
+ redis.setHashValue(REDIS_USER_LIKE_COMMENT, userId + ":" + commentId, "1");
+// redis.hset(REDIS_USER_LIKE_COMMENT, userId, "1");
+
+
+ // 系统消息:点赞评论
+ Comment comment = commentService.getComment(commentId);
+ Vlog vlog = vlogService.getVlog(comment.getVlogId());
+ Map msgContent = new HashMap();
+ msgContent.put("vlogId", vlog.getId());
+ msgContent.put("vlogCover", vlog.getCover());
+ msgContent.put("commentId", commentId);
+ msgService.createMsg(userId,
+ comment.getCommentUserId(),
+ MessageEnum.LIKE_COMMENT.type,
+ msgContent);
+
+
+ return GraceJSONResult.ok();
+ }
+
+ @PostMapping("unlike")
+ public GraceJSONResult unlike(@RequestParam String commentId,
+ @RequestParam String userId) {
+
+ redis.decrementHash(REDIS_VLOG_COMMENT_LIKED_COUNTS, commentId, 1);
+ redis.hdel(REDIS_USER_LIKE_COMMENT, userId + ":" + commentId);
+
+ return GraceJSONResult.ok();
+ }
+}
diff --git a/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java
new file mode 100644
index 000000000..59f231cd1
--- /dev/null
+++ b/ruoyi-front/ruoyi-consumer/src/main/java/com/wzj/soopin/consumer/content/controller/FansController.java
@@ -0,0 +1,298 @@
+package com.wzj.soopin.consumer.content.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.imooc.base.BaseInfoProperties;
+import com.imooc.grace.result.GraceJSONResult;
+import com.imooc.grace.result.ResponseStatusEnum;
+import com.imooc.pojo.Users;
+import com.imooc.service.FansService;
+import com.imooc.service.UserService;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Api(tags = "FansController 粉丝相关业务功能的接口")
+@RequestMapping("fans")
+@RestController
+public class FansController extends BaseInfoProperties {
+
+ @Autowired
+ private UserService userService;
+ @Autowired
+ private FansService fansService;
+
+ @PostMapping("follow")
+ public GraceJSONResult follow(@RequestParam String myId,
+ @RequestParam String vlogerId) {
+ // 从redis中获取拉黑信息
+ String redisKey = REDIS_USER_BLOCK + ":" + myId;
+ Boolean hasKey = redis.keyIsExist(redisKey);
+ if(hasKey){
+ List blockUserList = new ArrayList<>();
+ ObjectMapper objectMapper = new ObjectMapper();
+ List reports = redis.lrange(redisKey, 0, -1); // 查询用户的所有举报记录
+
+ for (String report : reports) {
+ try {
+ Map reportMap = objectMapper.readValue(report, new TypeReference