修改vlog
This commit is contained in:
parent
3bc7d53106
commit
daf3886672
@ -47,6 +47,11 @@
|
||||
<groupId>p6spy</groupId>
|
||||
<artifactId>p6spy</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara.warm</groupId>
|
||||
<artifactId>warm-flow-core</artifactId>
|
||||
<version>1.6.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -1,117 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.wzj.soopin.consumer.content.config;
|
||||
|
||||
import com.imooc.utils.MinIOUtils;
|
||||
|
||||
import com.wzj.soopin.content.utils.MinIOUtils;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -1,30 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ package com.wzj.soopin.consumer.content.controller;
|
||||
import com.wzj.soopin.content.domain.base.RabbitMQConfig;
|
||||
import com.wzj.soopin.content.domain.exceptions.GraceException;
|
||||
import com.wzj.soopin.content.domain.mo.MessageMO;
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
import com.wzj.soopin.content.enums.MessageEnum;
|
||||
import com.wzj.soopin.content.service.MsgService;
|
||||
import com.wzj.soopin.content.utils.JsonUtils;
|
||||
|
@ -11,6 +11,7 @@ import com.wzj.soopin.content.enums.UserInfoModifyType;
|
||||
import com.wzj.soopin.content.result.GraceJSONResult;
|
||||
import com.wzj.soopin.content.result.ResponseStatusEnum;
|
||||
import com.wzj.soopin.content.service.UserService;
|
||||
import com.wzj.soopin.content.utils.MinIOUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -5,8 +5,11 @@ package com.wzj.soopin.consumer.content.controller;
|
||||
import com.wzj.soopin.consumer.content.config.MinIOConfig;
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.enums.YesOrNo;
|
||||
import com.wzj.soopin.content.result.GraceJSONResult;
|
||||
import com.wzj.soopin.content.service.VlogService;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
import com.wzj.soopin.content.utils.QcCloud;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -22,7 +25,7 @@ import java.util.Map;
|
||||
@Api(tags = "VlogController 短视频相关业务功能的接口")
|
||||
@RequestMapping("vlog")
|
||||
@RestController
|
||||
@RefreshScope
|
||||
|
||||
public class VlogController extends BaseInfoProperties {
|
||||
@Autowired
|
||||
private VlogService vlogService;
|
||||
|
@ -2,6 +2,9 @@ package com.wzj.soopin.consumer.content.intercepter;
|
||||
|
||||
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.exceptions.GraceException;
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
import com.wzj.soopin.content.utils.IPUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -2,6 +2,8 @@ package com.wzj.soopin.consumer.content.intercepter;
|
||||
|
||||
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.exceptions.GraceException;
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -14,6 +14,21 @@
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.4</version>
|
||||
<classifier>jdk15</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>8.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
|
@ -4,6 +4,7 @@ package com.wzj.soopin.content.domain.base;
|
||||
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
import com.wzj.soopin.content.utils.RedisOperator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.wzj.soopin.content.domain.exceptions;
|
||||
|
||||
import com.imooc.grace.result.ResponseStatusEnum;
|
||||
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
|
||||
/**
|
||||
* 优雅的处理异常,统一封装
|
||||
|
@ -1,7 +1,8 @@
|
||||
package com.wzj.soopin.content.domain.exceptions;
|
||||
|
||||
import com.imooc.grace.result.GraceJSONResult;
|
||||
import com.imooc.grace.result.ResponseStatusEnum;
|
||||
|
||||
import com.wzj.soopin.content.domain.result.GraceJSONResult;
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.wzj.soopin.content.domain.exceptions;
|
||||
|
||||
import com.imooc.grace.result.ResponseStatusEnum;
|
||||
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.wzj.soopin.content.enums;
|
||||
|
||||
import com.imooc.exceptions.GraceException;
|
||||
import com.imooc.grace.result.ResponseStatusEnum;
|
||||
import com.wzj.soopin.content.domain.exceptions.GraceException;
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
|
||||
/**
|
||||
* @Desc: 修改用户信息类型 枚举
|
||||
|
@ -1,35 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
import org.n3r.idworker.strategy.DefaultRandomCodeStrategy;
|
||||
|
||||
public class Code {
|
||||
private static RandomCodeStrategy strategy;
|
||||
|
||||
static {
|
||||
RandomCodeStrategy strategy = new DefaultRandomCodeStrategy();
|
||||
strategy.init();
|
||||
configure(strategy);
|
||||
}
|
||||
|
||||
public static synchronized void configure(RandomCodeStrategy custom) {
|
||||
if (strategy == custom) return;
|
||||
if (strategy != null) strategy.release();
|
||||
|
||||
strategy = custom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next Unique code.
|
||||
* The max length will be 1024-Integer.MAX-Integer.MAX(2147483647) which has 4+10+10+2*1=26 characters.
|
||||
* The min length will be 0-0.
|
||||
*
|
||||
* @return unique string code.
|
||||
*/
|
||||
public static synchronized String next() {
|
||||
long workerId = Id.getWorkerId();
|
||||
int prefix = strategy.prefix();
|
||||
int next = strategy.next();
|
||||
|
||||
return String.format("%d-%03d-%06d", workerId, prefix, next);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
import org.n3r.idworker.strategy.DayPrefixRandomCodeStrategy;
|
||||
|
||||
public class DayCode {
|
||||
static RandomCodeStrategy strategy;
|
||||
|
||||
static {
|
||||
DayPrefixRandomCodeStrategy dayPrefixCodeStrategy = new DayPrefixRandomCodeStrategy("yyMM");
|
||||
dayPrefixCodeStrategy.setMinRandomSize(7);
|
||||
dayPrefixCodeStrategy.setMaxRandomSize(7);
|
||||
strategy = dayPrefixCodeStrategy;
|
||||
strategy.init();
|
||||
}
|
||||
|
||||
public static synchronized String next() {
|
||||
return String.format("%d-%04d-%07d", Id.getWorkerId(), strategy.prefix(), strategy.next());
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
import org.n3r.idworker.strategy.DefaultWorkerIdStrategy;
|
||||
|
||||
public class Id {
|
||||
private static WorkerIdStrategy workerIdStrategy;
|
||||
private static IdWorker idWorker;
|
||||
|
||||
static {
|
||||
configure(DefaultWorkerIdStrategy.instance);
|
||||
}
|
||||
|
||||
public static synchronized void configure(WorkerIdStrategy custom) {
|
||||
if (workerIdStrategy == custom) return;
|
||||
|
||||
if (workerIdStrategy != null) workerIdStrategy.release();
|
||||
workerIdStrategy = custom;
|
||||
workerIdStrategy.initialize();
|
||||
idWorker = new IdWorker(workerIdStrategy.availableWorkerId());
|
||||
}
|
||||
|
||||
public static long next() {
|
||||
return idWorker.nextId();
|
||||
}
|
||||
|
||||
public static long getWorkerId() {
|
||||
return idWorker.getWorkerId();
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class IdWorker {
|
||||
protected long epoch = 1288834974657L;
|
||||
// protected long epoch = 1387886498127L; // 2013-12-24 20:01:38.127
|
||||
|
||||
|
||||
protected long workerIdBits = 10L;
|
||||
protected long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
||||
protected long sequenceBits = 11L;
|
||||
|
||||
protected long workerIdShift = sequenceBits;
|
||||
protected long timestampLeftShift = sequenceBits + workerIdBits;
|
||||
protected long sequenceMask = -1L ^ (-1L << sequenceBits);
|
||||
|
||||
protected long lastMillis = -1L;
|
||||
|
||||
protected final long workerId;
|
||||
protected long sequence = 0L;
|
||||
protected Logger logger = LoggerFactory.getLogger(IdWorker.class);
|
||||
|
||||
public IdWorker(long workerId) {
|
||||
this.workerId = checkWorkerId(workerId);
|
||||
|
||||
logger.debug("worker starting. timestamp left shift {}, worker id {}", timestampLeftShift, workerId);
|
||||
}
|
||||
|
||||
public long getEpoch() {
|
||||
return epoch;
|
||||
}
|
||||
|
||||
private long checkWorkerId(long workerId) {
|
||||
// sanity check for workerId
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
int rand = new SecureRandom().nextInt((int) maxWorkerId + 1);
|
||||
logger.warn("worker Id can't be greater than {} or less than 0, use a random {}", maxWorkerId, rand);
|
||||
return rand;
|
||||
}
|
||||
|
||||
return workerId;
|
||||
}
|
||||
|
||||
public synchronized long nextId() {
|
||||
long timestamp = millisGen();
|
||||
|
||||
if (timestamp < lastMillis) {
|
||||
logger.error("clock is moving backwards. Rejecting requests until {}.", lastMillis);
|
||||
throw new InvalidSystemClock(String.format(
|
||||
"Clock moved backwards. Refusing to generate id for {} milliseconds", lastMillis - timestamp));
|
||||
}
|
||||
|
||||
if (lastMillis == timestamp) {
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
if (sequence == 0)
|
||||
timestamp = tilNextMillis(lastMillis);
|
||||
} else {
|
||||
sequence = 0;
|
||||
}
|
||||
|
||||
lastMillis = timestamp;
|
||||
long diff = timestamp - getEpoch();
|
||||
return (diff << timestampLeftShift) |
|
||||
(workerId << workerIdShift) |
|
||||
sequence;
|
||||
}
|
||||
|
||||
protected long tilNextMillis(long lastMillis) {
|
||||
long millis = millisGen();
|
||||
while (millis <= lastMillis)
|
||||
millis = millisGen();
|
||||
|
||||
return millis;
|
||||
}
|
||||
|
||||
protected long millisGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getLastMillis() {
|
||||
return lastMillis;
|
||||
}
|
||||
|
||||
public long getWorkerId() {
|
||||
return workerId;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
public class InvalidSystemClock extends RuntimeException {
|
||||
public InvalidSystemClock(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
public interface RandomCodeStrategy {
|
||||
void init();
|
||||
|
||||
int prefix();
|
||||
|
||||
int next();
|
||||
|
||||
void release();
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
import org.n3r.idworker.strategy.DefaultWorkerIdStrategy;
|
||||
import org.n3r.idworker.utils.Utils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class Sid {
|
||||
private static WorkerIdStrategy workerIdStrategy;
|
||||
private static IdWorker idWorker;
|
||||
|
||||
static {
|
||||
configure(DefaultWorkerIdStrategy.instance);
|
||||
}
|
||||
|
||||
|
||||
public static synchronized void configure(WorkerIdStrategy custom) {
|
||||
if (workerIdStrategy != null) {
|
||||
workerIdStrategy.release();
|
||||
}
|
||||
workerIdStrategy = custom;
|
||||
idWorker = new IdWorker(workerIdStrategy.availableWorkerId()) {
|
||||
@Override
|
||||
public long getEpoch() {
|
||||
return Utils.midnightMillis();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 一天最大毫秒86400000,最大占用27比特
|
||||
* 27+10+11=48位 最大值281474976710655(15字),YK0XXHZ827(10字)
|
||||
* 6位(YYMMDD)+15位,共21位
|
||||
*
|
||||
* @return 固定21位数字字符串
|
||||
*/
|
||||
|
||||
public static String next() {
|
||||
long id = idWorker.nextId();
|
||||
String yyMMdd = new SimpleDateFormat("yyMMdd").format(new Date());
|
||||
return yyMMdd + String.format("%014d", id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回固定16位的字母数字混编的字符串。
|
||||
*/
|
||||
public String nextShort() {
|
||||
long id = idWorker.nextId();
|
||||
String yyMMdd = new SimpleDateFormat("yyMMdd").format(new Date());
|
||||
return yyMMdd + Utils.padLeft(Utils.encode(id), 10, '0');
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String aa = new Sid().nextShort();
|
||||
String bb = new Sid().next();
|
||||
|
||||
System.out.println(aa);
|
||||
System.out.println(bb);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
for (int i = 0 ; i < 1000 ; i ++) {
|
||||
// System.out.println(Sid.nextShort());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker;
|
||||
|
||||
public interface WorkerIdStrategy {
|
||||
void initialize();
|
||||
|
||||
long availableWorkerId();
|
||||
|
||||
void release();
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker.strategy;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class DayPrefixRandomCodeStrategy extends DefaultRandomCodeStrategy {
|
||||
private final String dayFormat;
|
||||
private String lastDay;
|
||||
|
||||
public DayPrefixRandomCodeStrategy(String dayFormat) {
|
||||
this.dayFormat = dayFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
String day = createDate();
|
||||
if (day.equals(lastDay))
|
||||
throw new RuntimeException("init failed for day unrolled");
|
||||
|
||||
lastDay = day;
|
||||
|
||||
availableCodes.clear();
|
||||
release();
|
||||
|
||||
prefixIndex = Integer.parseInt(lastDay);
|
||||
if (tryUsePrefix()) return;
|
||||
|
||||
throw new RuntimeException("prefix is not available " + prefixIndex);
|
||||
}
|
||||
|
||||
private String createDate() {
|
||||
return new SimpleDateFormat(dayFormat).format(new Date());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int next() {
|
||||
if (!lastDay.equals(createDate())) init();
|
||||
|
||||
return super.next();
|
||||
}
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker.strategy;
|
||||
|
||||
import org.n3r.idworker.Id;
|
||||
import org.n3r.idworker.RandomCodeStrategy;
|
||||
import org.n3r.idworker.utils.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.BitSet;
|
||||
import java.util.Queue;
|
||||
|
||||
public class DefaultRandomCodeStrategy implements RandomCodeStrategy {
|
||||
public static final int MAX_BITS = 1000000;
|
||||
|
||||
Logger log = LoggerFactory.getLogger(DefaultRandomCodeStrategy.class);
|
||||
|
||||
File idWorkerHome = Utils.createIdWorkerHome();
|
||||
volatile FileLock fileLock;
|
||||
BitSet codesFilter;
|
||||
|
||||
int prefixIndex = -1;
|
||||
File codePrefixIndex;
|
||||
|
||||
int minRandomSize = 6;
|
||||
int maxRandomSize = 6;
|
||||
|
||||
public DefaultRandomCodeStrategy() {
|
||||
destroyFileLockWhenShutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
release();
|
||||
|
||||
while (++prefixIndex < 1000) {
|
||||
if (tryUsePrefix()) return;
|
||||
}
|
||||
|
||||
throw new RuntimeException("all prefixes are used up, the world maybe ends!");
|
||||
}
|
||||
|
||||
public DefaultRandomCodeStrategy setMinRandomSize(int minRandomSize) {
|
||||
this.minRandomSize = minRandomSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultRandomCodeStrategy setMaxRandomSize(int maxRandomSize) {
|
||||
this.maxRandomSize = maxRandomSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean tryUsePrefix() {
|
||||
codePrefixIndex = new File(idWorkerHome, Id.getWorkerId() + ".code.prefix." + prefixIndex);
|
||||
|
||||
if (!createPrefixIndexFile()) return false;
|
||||
if (!createFileLock()) return false;
|
||||
if (!createBloomFilter()) return false;
|
||||
|
||||
log.info("get available prefix index file {}", codePrefixIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean createFileLock() {
|
||||
if (fileLock != null) fileLock.destroy();
|
||||
fileLock = new FileLock(codePrefixIndex);
|
||||
return fileLock.tryLock();
|
||||
}
|
||||
|
||||
private boolean createBloomFilter() {
|
||||
codesFilter = fileLock.readObject();
|
||||
if (codesFilter == null) {
|
||||
log.info("create new bloom filter");
|
||||
codesFilter = new BitSet(MAX_BITS); // 2^24
|
||||
} else {
|
||||
int size = codesFilter.cardinality();
|
||||
if (size >= MAX_BITS) {
|
||||
log.warn("bloom filter with prefix file {} is already full", codePrefixIndex);
|
||||
return false;
|
||||
}
|
||||
log.info("recreate bloom filter with cardinality {}", size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void destroyFileLockWhenShutdown() {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
release();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean createPrefixIndexFile() {
|
||||
try {
|
||||
codePrefixIndex.createNewFile();
|
||||
return codePrefixIndex.exists();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.warn("create file {} error {}", codePrefixIndex, e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int prefix() {
|
||||
return prefixIndex;
|
||||
}
|
||||
|
||||
static final int CACHE_CODES_NUM = 1000;
|
||||
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
Queue<Integer> availableCodes = new ArrayDeque<Integer>(CACHE_CODES_NUM);
|
||||
|
||||
@Override
|
||||
public int next() {
|
||||
if (availableCodes.isEmpty()) generate();
|
||||
|
||||
return availableCodes.poll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void release() {
|
||||
if (fileLock != null) {
|
||||
fileLock.writeObject(codesFilter);
|
||||
fileLock.destroy();
|
||||
fileLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void generate() {
|
||||
for (int i = 0; i < CACHE_CODES_NUM; ++i)
|
||||
availableCodes.add(generateOne());
|
||||
|
||||
fileLock.writeObject(codesFilter);
|
||||
}
|
||||
|
||||
private int generateOne() {
|
||||
while (true) {
|
||||
int code = secureRandom.nextInt(max(maxRandomSize));
|
||||
boolean existed = contains(code);
|
||||
|
||||
code = !existed ? add(code) : tryFindAvailableCode(code);
|
||||
if (code >= 0) return code;
|
||||
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
private int tryFindAvailableCode(int code) {
|
||||
int next = codesFilter.nextClearBit(code);
|
||||
if (next != -1 && next < max(maxRandomSize)) return add(next);
|
||||
|
||||
next = codesFilter.previousClearBit(code);
|
||||
if (next != -1) return add(next);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int add(int code) {
|
||||
codesFilter.set(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
private boolean contains(int code) {
|
||||
return codesFilter.get(code);
|
||||
}
|
||||
|
||||
|
||||
private int max(int size) {
|
||||
switch (size) {
|
||||
case 1: // fall through
|
||||
case 2: // fall through
|
||||
case 3: // fall through
|
||||
case 4:
|
||||
return 10000;
|
||||
case 5:
|
||||
return 100000;
|
||||
case 6:
|
||||
return 1000000;
|
||||
case 7:
|
||||
return 10000000;
|
||||
case 8:
|
||||
return 100000000;
|
||||
case 9:
|
||||
return 1000000000;
|
||||
default:
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker.strategy;
|
||||
|
||||
import org.n3r.idworker.WorkerIdStrategy;
|
||||
import org.n3r.idworker.utils.HttpReq;
|
||||
import org.n3r.idworker.utils.Ip;
|
||||
import org.n3r.idworker.utils.Props;
|
||||
import org.n3r.idworker.utils.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
public class DefaultWorkerIdStrategy implements WorkerIdStrategy {
|
||||
static long workerIdBits = 10L;
|
||||
static long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
||||
static Random random = new SecureRandom();
|
||||
|
||||
public static final WorkerIdStrategy instance = new DefaultWorkerIdStrategy();
|
||||
|
||||
private final Properties props =
|
||||
Props.tryProperties("idworker-client.properties", Utils.DOT_IDWORKERS);
|
||||
private final String idWorkerServerUrl =
|
||||
props.getProperty("server.address", "http://id.worker.server:18001");
|
||||
|
||||
String userName = System.getProperty("user.name");
|
||||
|
||||
String ipDotUsername = Ip.ip + "." + userName;
|
||||
String ipudotlock = ipDotUsername + ".lock.";
|
||||
int workerIdIndex = ipudotlock.length();
|
||||
long workerId;
|
||||
FileLock fileLock;
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(DefaultWorkerIdStrategy.class);
|
||||
private boolean inited;
|
||||
|
||||
|
||||
private void init() {
|
||||
workerId = findAvailWorkerId();
|
||||
if (workerId >= 0) {
|
||||
destroyFileLockWhenShutdown();
|
||||
startSyncThread();
|
||||
} else {
|
||||
syncWithWorkerIdServer();
|
||||
workerId = findAvailWorkerId();
|
||||
if (workerId < 0) workerId = increaseWithWorkerIdServer();
|
||||
}
|
||||
|
||||
if (workerId < 0) workerId = tryToCreateOnIp();
|
||||
if (workerId < 0) {
|
||||
logger.warn("DANGEROUS!!! Try to use random worker id.");
|
||||
workerId = tryToRandomOnIp(); // Try avoiding! it could cause duplicated
|
||||
}
|
||||
|
||||
if (workerId < 0) {
|
||||
logger.warn("the world may be ended!");
|
||||
throw new RuntimeException("the world may be ended");
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyFileLockWhenShutdown() {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
fileLock.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startSyncThread() {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
syncWithWorkerIdServer();
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private long increaseWithWorkerIdServer() {
|
||||
String incId = HttpReq.get(idWorkerServerUrl)
|
||||
.req("/inc")
|
||||
.param("ipu", ipDotUsername)
|
||||
.exec();
|
||||
if (incId == null || incId.trim().isEmpty()) return -1L;
|
||||
|
||||
long lid = Long.parseLong(incId);
|
||||
|
||||
return checkAvail(lid);
|
||||
}
|
||||
|
||||
private long tryToCreateOnIp() {
|
||||
long wid = Ip.lip & maxWorkerId;
|
||||
|
||||
return checkAvail(wid);
|
||||
}
|
||||
|
||||
private long tryToRandomOnIp() {
|
||||
long avaiWorkerId = -1L;
|
||||
long tryTimes = -1;
|
||||
|
||||
while (avaiWorkerId < 0 && ++tryTimes < maxWorkerId) {
|
||||
long wid = Ip.lip & random.nextInt((int) maxWorkerId);
|
||||
|
||||
avaiWorkerId = checkAvail(wid);
|
||||
}
|
||||
return avaiWorkerId;
|
||||
}
|
||||
|
||||
private long checkAvail(long wid) {
|
||||
long availWorkerId = -1L;
|
||||
try {
|
||||
File idWorkerHome = Utils.createIdWorkerHome();
|
||||
new File(idWorkerHome, ipudotlock + String.format("%04d", wid)).createNewFile();
|
||||
availWorkerId = findAvailWorkerId();
|
||||
} catch (IOException e) {
|
||||
logger.warn("checkAvail error", e);
|
||||
}
|
||||
|
||||
return availWorkerId;
|
||||
}
|
||||
|
||||
private void syncWithWorkerIdServer() {
|
||||
String syncIds = HttpReq.get(idWorkerServerUrl).req("/sync")
|
||||
.param("ipu", ipDotUsername).param("ids", buildWorkerIdsOfCurrentIp())
|
||||
.exec();
|
||||
if (syncIds == null || syncIds.trim().isEmpty()) return;
|
||||
|
||||
String[] syncIdsArr = syncIds.split(",");
|
||||
File idWorkerHome = Utils.createIdWorkerHome();
|
||||
for (String syncId : syncIdsArr) {
|
||||
try {
|
||||
new File(idWorkerHome, ipudotlock + syncId).createNewFile();
|
||||
} catch (IOException e) {
|
||||
logger.warn("create workerid lock file error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String buildWorkerIdsOfCurrentIp() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
File idWorkerHome = Utils.createIdWorkerHome();
|
||||
for (File lockFile : idWorkerHome.listFiles()) {
|
||||
// check the format like 10.142.1.151.lock.0001
|
||||
if (!lockFile.getName().startsWith(ipudotlock)) continue;
|
||||
|
||||
String workerId = lockFile.getName().substring(workerIdIndex);
|
||||
if (!workerId.matches("\\d\\d\\d\\d")) continue;
|
||||
|
||||
if (sb.length() > 0) sb.append(',');
|
||||
sb.append(workerId);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the local available worker id.
|
||||
*
|
||||
* @return -1 when N/A
|
||||
*/
|
||||
private long findAvailWorkerId() {
|
||||
File idWorkerHome = Utils.createIdWorkerHome();
|
||||
|
||||
for (File lockFile : idWorkerHome.listFiles()) {
|
||||
// check the format like 10.142.1.151.lock.0001
|
||||
if (!lockFile.getName().startsWith(ipudotlock)) continue;
|
||||
|
||||
String workerId = lockFile.getName().substring(workerIdIndex);
|
||||
if (!workerId.matches("\\d\\d\\d\\d")) continue;
|
||||
|
||||
FileLock fileLock = new FileLock(lockFile);
|
||||
if (!fileLock.tryLock()) {
|
||||
fileLock.destroy();
|
||||
continue;
|
||||
}
|
||||
|
||||
this.fileLock = fileLock;
|
||||
return Long.parseLong(workerId);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
if (inited) return;
|
||||
init();
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long availableWorkerId() {
|
||||
return workerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
if (fileLock != null) fileLock.destroy();
|
||||
inited = false;
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker.strategy;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.OverlappingFileLockException;
|
||||
|
||||
/**
|
||||
* A file lock a la flock/funlock
|
||||
* <p/>
|
||||
* The given path will be created and opened if it doesn't exist.
|
||||
*/
|
||||
public class FileLock {
|
||||
private final File file;
|
||||
private FileChannel channel;
|
||||
private java.nio.channels.FileLock flock = null;
|
||||
Logger logger = LoggerFactory.getLogger(FileLock.class);
|
||||
|
||||
public FileLock(File file) {
|
||||
this.file = file;
|
||||
|
||||
try {
|
||||
file.createNewFile(); // create the file if it doesn't exist
|
||||
channel = new RandomAccessFile(file, "rw").getChannel();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lock the file or throw an exception if the lock is already held
|
||||
*/
|
||||
public void lock() {
|
||||
try {
|
||||
synchronized (this) {
|
||||
logger.trace("Acquiring lock on {}", file.getAbsolutePath());
|
||||
flock = channel.lock();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to lock the file and return true if the locking succeeds
|
||||
*/
|
||||
public boolean tryLock() {
|
||||
synchronized (this) {
|
||||
logger.trace("Acquiring lock on {}", file.getAbsolutePath());
|
||||
try {
|
||||
// weirdly this method will return null if the lock is held by another
|
||||
// process, but will throw an exception if the lock is held by this process
|
||||
// so we have to handle both cases
|
||||
flock = channel.tryLock();
|
||||
return flock != null;
|
||||
} catch (OverlappingFileLockException e) {
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the lock if it is held
|
||||
*/
|
||||
public void unlock() {
|
||||
synchronized (this) {
|
||||
logger.trace("Releasing lock on {}", file.getAbsolutePath());
|
||||
if (flock == null) return;
|
||||
try {
|
||||
flock.release();
|
||||
} catch (ClosedChannelException e) {
|
||||
// Ignore
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy this lock, closing the associated FileChannel
|
||||
*/
|
||||
public void destroy() {
|
||||
synchronized (this) {
|
||||
unlock();
|
||||
if (!channel.isOpen()) return;
|
||||
|
||||
try {
|
||||
channel.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T readObject() {
|
||||
try {
|
||||
InputStream is = Channels.newInputStream(channel);
|
||||
ObjectInputStream objectReader = new ObjectInputStream(is);
|
||||
return (T) objectReader.readObject();
|
||||
} catch (EOFException e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public synchronized boolean writeObject(Object object) {
|
||||
if (!channel.isOpen()) return false;
|
||||
|
||||
try {
|
||||
channel.position(0);
|
||||
OutputStream out = Channels.newOutputStream(channel);
|
||||
ObjectOutputStream objectOutput = new ObjectOutputStream(out);
|
||||
objectOutput.writeObject(object);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker.utils;
|
@ -1,118 +0,0 @@
|
||||
package com.wzj.soopin.content.idworker.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Serializes {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> readObjects(File file) {
|
||||
ArrayList<T> objects = new ArrayList<T>();
|
||||
ObjectInputStream objectReader = null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
objectReader = new ObjectInputStream(fis);
|
||||
while (true)
|
||||
objects.add((T) objectReader.readObject());
|
||||
|
||||
} catch (EOFException e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
closeQuietly(objectReader);
|
||||
closeQuietly(fis);
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T readObject(File file) {
|
||||
ObjectInputStream objectReader = null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
objectReader = new ObjectInputStream(fis);
|
||||
return (T) objectReader.readObject();
|
||||
|
||||
} catch (EOFException e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
closeQuietly(objectReader);
|
||||
closeQuietly(fis);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void writeObject(File file, Object object) {
|
||||
ObjectOutputStream objectOutput = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
objectOutput = new ObjectOutputStream(fos);
|
||||
objectOutput.writeObject(object);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
closeQuietly(objectOutput);
|
||||
closeQuietly(fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeObject(FileOutputStream fos, Object object) {
|
||||
FileChannel channel = fos.getChannel();
|
||||
if (!channel.isOpen()) throw new RuntimeException("channel is closed");
|
||||
|
||||
try {
|
||||
channel.position(0);
|
||||
ObjectOutputStream objectOutput = new ObjectOutputStream(fos);
|
||||
objectOutput.writeObject(object);
|
||||
fos.flush();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeObjects(File file, Object... objects) {
|
||||
ObjectOutputStream objectOutput = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
objectOutput = new ObjectOutputStream(fos);
|
||||
|
||||
for (Object object : objects)
|
||||
objectOutput.writeObject(object);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
closeQuietly(objectOutput);
|
||||
closeQuietly(fos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void closeQuietly(OutputStream os) {
|
||||
if (os != null) try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void closeQuietly(InputStream is) {
|
||||
if (is != null) try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -7,4 +7,7 @@ import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CommentMapper extends BaseMapperPlus<Comment, CommentVO> {
|
||||
Comment selectByPrimaryKey(String id);
|
||||
|
||||
void delete(Comment pendingDelete);
|
||||
}
|
||||
|
@ -13,6 +13,12 @@ import java.util.Map;
|
||||
|
||||
|
||||
public interface FansMapper extends BaseMapperPlus<Fans, FansVO> {
|
||||
int updateByPrimaryKeySelective(Fans record);
|
||||
public List<Map<String, Object>> getFollowedVlogerIds(@Param("currentUserId")String currentUserId,@Param("vlogerIds")List<String> vlogerIds);
|
||||
|
||||
int insert(@Param("fansData") Map<String, Object> vlogData);
|
||||
|
||||
public List<VlogerVO> selectByExample(@Param("paramMap") Map<String, Object> map);
|
||||
|
||||
int delete(@Param("id") String id);
|
||||
}
|
||||
|
@ -1,18 +1,20 @@
|
||||
package com.wzj.soopin.content.mapper.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.wzj.soopin.content.domain.bo.UpdatedUserBO;
|
||||
import com.wzj.soopin.content.domain.po.Users;
|
||||
import com.wzj.soopin.content.domain.vo.UsersVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UsersMapper extends BaseMapperPlus<Users, UsersVO> {
|
||||
public interface UsersMapper extends BaseMapper<Users> {
|
||||
|
||||
@Select("SELECT * FROM t_users WHERE nickname LIKE CONCAT('%', #{nickname}, '%')")
|
||||
List<UsersVO> searchByNickname(String nickname);
|
||||
@ -30,4 +32,8 @@ public interface UsersMapper extends BaseMapperPlus<Users, UsersVO> {
|
||||
int updateVnum(UpdatedUserBO user);
|
||||
@Select("SELECT * FROM t_users WHERE imooc_num = #{imoocNum}")
|
||||
List<UsersVO> selectByImoocNum(@Param("imoocNum") String imoocNum);
|
||||
|
||||
Users selectByPrimaryKey(String userId);
|
||||
|
||||
void updateByPrimaryKeySelective(Users users);
|
||||
}
|
||||
|
@ -1,20 +1,56 @@
|
||||
package com.wzj.soopin.content.mapper.mapper;
|
||||
|
||||
import com.wzj.soopin.content.domain.po.Vlog;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.domain.vo.VlogerVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
//@Repository
|
||||
//public interface VlogMapper extends MyMapper<Vlog> {
|
||||
//}
|
||||
@Repository
|
||||
public interface VlogMapper extends BaseMapperPlus<Vlog, VlogerVO> {
|
||||
public interface VlogMapper {
|
||||
// public List<IndexVlogVO> updateVlogStatus(@Param("paramMap") Map<String, Object> map);
|
||||
/**
|
||||
* 通用动态更新方法
|
||||
* @param primaryKey 主键字段名
|
||||
* @param idValue 主键值
|
||||
* @param updateFields 待更新的字段Map(key=字段名, value=字段值)
|
||||
* @return 影响的行数
|
||||
*/
|
||||
int dynamicUpdate(
|
||||
@Param("primaryKey") String primaryKey,
|
||||
@Param("idValue") Object idValue,
|
||||
@Param("updateFields") Map<String, Object> updateFields
|
||||
);
|
||||
|
||||
/**
|
||||
* Vlog表多条件动态更新
|
||||
* @param updateFields 需要更新的字段及值(Map结构)
|
||||
* @param conditions 更新条件(Map结构)
|
||||
* @return 受影响的行数
|
||||
*/
|
||||
int updateVlogByConditions(
|
||||
@Param("updates") Map<String, Object> updateFields,
|
||||
@Param("conditions") Map<String, Object> conditions
|
||||
);
|
||||
|
||||
/**
|
||||
* 单条插入vlog记录
|
||||
* @param vlogData 插入数据的键值对(key=列名, value=列值)
|
||||
* @return 影响的行数
|
||||
*/
|
||||
int dynamicInsert(@Param("vlogData") Map<String, Object> vlogData);
|
||||
|
||||
/**
|
||||
* 批量插入vlog记录
|
||||
* @param vlogList 插入数据列表(每个Map代表一行数据)
|
||||
* @return 影响的行数
|
||||
*/
|
||||
int dynamicBatchInsert(@Param("vlogList") List<Map<String, Object>> vlogList);
|
||||
|
||||
public List<IndexVlogVO> selectMyPublic(@Param("paramMap")Map<String, Object> map);
|
||||
public List<IndexVlogVO> getVlogDetailFromId(@Param("paramMap")Map<String, Object> map);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.wzj.soopin.content.mapper.repository;
|
||||
|
||||
import com.wzj.soopin.content.domain.mo.MessageMO;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
@ -4,7 +4,7 @@ package com.wzj.soopin.content.service;
|
||||
import com.wzj.soopin.content.domain.bo.CommentBO;
|
||||
import com.wzj.soopin.content.domain.po.Comment;
|
||||
import com.wzj.soopin.content.domain.vo.CommentVO;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
|
||||
public interface CommentService {
|
||||
|
||||
@ -16,10 +16,10 @@ public interface CommentService {
|
||||
/**
|
||||
* 查询评论的列表
|
||||
*/
|
||||
public TableDataInfo<CommentVO> queryVlogComments(String vlogId,
|
||||
String userId,
|
||||
Integer page,
|
||||
Integer pageSize);
|
||||
public PagedGridResult queryVlogComments(String vlogId,
|
||||
String userId,
|
||||
Integer page,
|
||||
Integer pageSize);
|
||||
|
||||
/**
|
||||
* 删除评论
|
||||
|
@ -1,8 +1,7 @@
|
||||
package com.wzj.soopin.content.service;
|
||||
|
||||
|
||||
import com.wzj.soopin.content.domain.vo.FansVO;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
|
||||
public interface FansService {
|
||||
|
||||
@ -24,14 +23,14 @@ public interface FansService {
|
||||
/**
|
||||
* 查询我关注的博主列表
|
||||
*/
|
||||
public TableDataInfo<FansVO> queryMyFollows(String myId,
|
||||
Integer page,
|
||||
Integer pageSize);
|
||||
public PagedGridResult queryMyFollows(String myId,
|
||||
Integer page,
|
||||
Integer pageSize);
|
||||
|
||||
/**
|
||||
* 查询我的粉丝列表
|
||||
*/
|
||||
public TableDataInfo<FansVO> queryMyFans(String myId,
|
||||
Integer page,
|
||||
Integer pageSize);
|
||||
public PagedGridResult queryMyFans(String myId,
|
||||
Integer page,
|
||||
Integer pageSize);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.wzj.soopin.content.service;
|
||||
|
||||
import com.imooc.mo.MessageMO;
|
||||
|
||||
import com.wzj.soopin.content.domain.mo.MessageMO;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,10 +1,9 @@
|
||||
package com.wzj.soopin.content.service;
|
||||
|
||||
import com.imooc.bo.VlogBO;
|
||||
import com.imooc.pojo.Vlog;
|
||||
import com.imooc.utils.PagedGridResult;
|
||||
import com.imooc.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.domain.po.Vlog;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
|
||||
public interface VlogService {
|
||||
/**
|
||||
|
@ -2,16 +2,21 @@ package com.wzj.soopin.content.service.impl;
|
||||
|
||||
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.bo.CommentBO;
|
||||
import com.wzj.soopin.content.domain.po.Comment;
|
||||
import com.wzj.soopin.content.domain.po.Vlog;
|
||||
import com.wzj.soopin.content.domain.vo.CommentVO;
|
||||
import com.wzj.soopin.content.enums.MessageEnum;
|
||||
import com.wzj.soopin.content.enums.YesOrNo;
|
||||
import com.wzj.soopin.content.mapper.mapper.CommentMapper;
|
||||
import com.wzj.soopin.content.mapper.mapper.CommentMapperCustom;
|
||||
import com.wzj.soopin.content.service.CommentService;
|
||||
import com.wzj.soopin.content.service.MsgService;
|
||||
import com.wzj.soopin.content.service.VlogService;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
import com.wzj.soopin.content.utils.Sid;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
@ -1,34 +1,39 @@
|
||||
package com.wzj.soopin.content.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.base.RabbitMQConfig;
|
||||
import com.wzj.soopin.content.domain.mo.MessageMO;
|
||||
import com.wzj.soopin.content.domain.po.Fans;
|
||||
import com.wzj.soopin.content.domain.vo.FansVO;
|
||||
import com.wzj.soopin.content.domain.vo.VlogerVO;
|
||||
import com.wzj.soopin.content.enums.MessageEnum;
|
||||
import com.wzj.soopin.content.mapper.mapper.FansMapper;
|
||||
import com.wzj.soopin.content.mapper.mapper.FansMapperCustom;
|
||||
import com.wzj.soopin.content.service.FansService;
|
||||
import com.wzj.soopin.content.service.MsgService;
|
||||
import com.wzj.soopin.content.utils.JsonUtils;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
import com.wzj.soopin.content.utils.Sid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dromara.common.core.enums.YesOrNo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.wzj.soopin.content.domain.base.BaseInfoProperties.REDIS_FANS_AND_VLOGGER_RELATIONSHIP;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class FansServiceImpl implements FansService {
|
||||
public class FansServiceImpl extends BaseInfoProperties implements FansService {
|
||||
|
||||
private final FansMapper fansMapper;
|
||||
|
||||
@ -133,18 +138,20 @@ public class FansServiceImpl implements FansService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDataInfo<VlogerVO> queryMyFollows(String myId,
|
||||
Integer page,
|
||||
Integer pageSize) {
|
||||
public PagedGridResult queryMyFollows(String myId,
|
||||
Integer page,
|
||||
Integer pageSize) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("myId", myId);
|
||||
|
||||
Page<VlogerVO> pageData = fansMapperCustom.selectVoPage(new PageQuery(pageSize,page).build(),
|
||||
new QueryWrapper<Fans>().eq("myId",myId));
|
||||
return TableDataInfo.build(pageData);
|
||||
PageHelper.startPage(page, pageSize);
|
||||
|
||||
List<VlogerVO> list = fansMapperCustom.queryMyFollows(map);
|
||||
|
||||
return setterPagedGrid(list, page);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PagedGridResult queryMyFans(String myId,
|
||||
Integer page,
|
||||
|
@ -1,13 +1,13 @@
|
||||
package com.wzj.soopin.content.service.impl;
|
||||
|
||||
import com.imooc.base.BaseInfoProperties;
|
||||
import com.imooc.enums.MessageEnum;
|
||||
import com.imooc.mo.MessageMO;
|
||||
import com.imooc.pojo.Users;
|
||||
import com.imooc.repository.MessageRepository;
|
||||
import com.imooc.service.MsgService;
|
||||
import com.imooc.service.UserService;
|
||||
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.mo.MessageMO;
|
||||
import com.wzj.soopin.content.domain.po.Users;
|
||||
import com.wzj.soopin.content.enums.MessageEnum;
|
||||
import com.wzj.soopin.content.mapper.repository.MessageRepository;
|
||||
import com.wzj.soopin.content.service.MsgService;
|
||||
import com.wzj.soopin.content.service.UserService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
@ -1,7 +1,8 @@
|
||||
package com.wzj.soopin.content.service.impl;
|
||||
|
||||
import com.imooc.mapper.UserMemberMapper;
|
||||
import com.imooc.service.UserMemberService;
|
||||
|
||||
import com.wzj.soopin.content.mapper.mapper.UserMemberMapper;
|
||||
import com.wzj.soopin.content.service.UserMemberService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -2,27 +2,32 @@ package com.wzj.soopin.content.service.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.imooc.base.BaseInfoProperties;
|
||||
import com.imooc.bo.UpdatedUserBO;
|
||||
import com.imooc.enums.Sex;
|
||||
import com.imooc.enums.UserInfoModifyType;
|
||||
import com.imooc.enums.YesOrNo;
|
||||
import com.imooc.exceptions.GraceException;
|
||||
import com.imooc.grace.result.ResponseStatusEnum;
|
||||
import com.imooc.mapper.FansMapper;
|
||||
import com.imooc.mapper.FansMapperCustom;
|
||||
import com.imooc.mapper.UserMemberMapper;
|
||||
import com.imooc.mapper.UsersMapper;
|
||||
import com.imooc.mo.Token;
|
||||
import com.imooc.pojo.UserMember;
|
||||
import com.imooc.pojo.Users;
|
||||
import com.imooc.service.FansService;
|
||||
import com.imooc.service.UserService;
|
||||
import com.imooc.utils.*;
|
||||
import com.imooc.vo.UsersVO;
|
||||
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.bo.UpdatedUserBO;
|
||||
import com.wzj.soopin.content.domain.exceptions.GraceException;
|
||||
import com.wzj.soopin.content.domain.mo.Token;
|
||||
import com.wzj.soopin.content.domain.po.UserMember;
|
||||
import com.wzj.soopin.content.domain.po.Users;
|
||||
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
|
||||
import com.wzj.soopin.content.domain.vo.UsersVO;
|
||||
import com.wzj.soopin.content.enums.Sex;
|
||||
import com.wzj.soopin.content.enums.UserInfoModifyType;
|
||||
import com.wzj.soopin.content.enums.YesOrNo;
|
||||
import com.wzj.soopin.content.mapper.mapper.FansMapper;
|
||||
import com.wzj.soopin.content.mapper.mapper.FansMapperCustom;
|
||||
import com.wzj.soopin.content.mapper.mapper.UserMemberMapper;
|
||||
import com.wzj.soopin.content.mapper.mapper.UsersMapper;
|
||||
import com.wzj.soopin.content.service.FansService;
|
||||
import com.wzj.soopin.content.service.UserService;
|
||||
import com.wzj.soopin.content.utils.DateUtil;
|
||||
import com.wzj.soopin.content.utils.DesensitizationUtil;
|
||||
import com.wzj.soopin.content.utils.GsonUtil;
|
||||
import com.wzj.soopin.content.utils.Sid;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.n3r.idworker.Sid;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
@ -32,13 +37,11 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.imooc.base.BaseInfoProperties.REDIS_USER_TOKEN;
|
||||
|
||||
|
||||
/**
|
||||
* @author vercen
|
||||
@ -105,8 +108,8 @@ public class UserServiceImpl extends BaseInfoProperties implements UserService {
|
||||
user.setDistrict("");
|
||||
user.setDescription("这家伙很懒,什么都没留下~");
|
||||
user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
|
||||
user.setCreatedTime(new Date());
|
||||
user.setUpdatedTime(new Date());
|
||||
// user.setCreatedTime(new Date());
|
||||
// user.setUpdatedTime(new Date());
|
||||
|
||||
usersMapper.insert(user);
|
||||
|
||||
@ -215,10 +218,10 @@ public class UserServiceImpl extends BaseInfoProperties implements UserService {
|
||||
user.setDescription("这家伙很懒,什么都没留下~");
|
||||
user.setBgImg("");
|
||||
user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
|
||||
user.setCreatedTime(new Date());
|
||||
user.setUpdatedTime(new Date());
|
||||
// user.setCreatedTime(new Date());
|
||||
// user.setUpdatedTime(new Date());
|
||||
|
||||
int row = usersMapper.insert(user);
|
||||
int row = usersMapper.inset(user);
|
||||
|
||||
if (row > 0) {
|
||||
Map<String, Object> result = Maps.newHashMap();
|
||||
@ -292,8 +295,8 @@ public class UserServiceImpl extends BaseInfoProperties implements UserService {
|
||||
user.setDistrict("");
|
||||
user.setDescription("这家伙很懒,什么都没留下~");
|
||||
user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
|
||||
user.setCreatedTime(new Date());
|
||||
user.setUpdatedTime(new Date());
|
||||
// user.setCreatedTime(new Date());
|
||||
// user.setUpdatedTime(new Date());
|
||||
|
||||
// 短视频用户与商城账号关系
|
||||
UserMember userMember = new UserMember();
|
||||
|
@ -4,23 +4,24 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.imooc.base.BaseInfoProperties;
|
||||
import com.imooc.bo.VlogBO;
|
||||
import com.imooc.enums.MessageEnum;
|
||||
import com.imooc.enums.YesOrNo;
|
||||
import com.imooc.mapper.MyLikedVlogMapper;
|
||||
import com.imooc.mapper.VlogMapper;
|
||||
import com.imooc.mapper.VlogMapperCustom;
|
||||
import com.imooc.pojo.MyLikedVlog;
|
||||
import com.imooc.pojo.Vlog;
|
||||
import com.imooc.service.FansService;
|
||||
import com.imooc.service.MsgService;
|
||||
import com.imooc.service.VlogService;
|
||||
import com.imooc.utils.PagedGridResult;
|
||||
import com.imooc.vo.IndexVlogVO;
|
||||
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.domain.po.MyLikedVlog;
|
||||
import com.wzj.soopin.content.domain.po.Vlog;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.enums.MessageEnum;
|
||||
import com.wzj.soopin.content.enums.YesOrNo;
|
||||
import com.wzj.soopin.content.mapper.mapper.MyLikedVlogMapper;
|
||||
import com.wzj.soopin.content.mapper.mapper.VlogMapper;
|
||||
import com.wzj.soopin.content.mapper.mapper.VlogMapperCustom;
|
||||
import com.wzj.soopin.content.service.FansService;
|
||||
import com.wzj.soopin.content.service.MsgService;
|
||||
import com.wzj.soopin.content.service.VlogService;
|
||||
import com.wzj.soopin.content.utils.PagedGridResult;
|
||||
import com.wzj.soopin.content.utils.Sid;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.n3r.idworker.Sid;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -493,7 +494,7 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
|
||||
likedVlog.setVlogId(vlogId);
|
||||
likedVlog.setUserId(userId);
|
||||
|
||||
myLikedVlogMapper.delete(likedVlog);
|
||||
myLikedVlogMapper.deleteById(likedVlog);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,436 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 通用工具类
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Leon
|
||||
*
|
||||
*/
|
||||
public final class CommonUtil {
|
||||
|
||||
private CommonUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断数组是否为空
|
||||
*
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
public static <T> boolean isEmpty(T[] array) {
|
||||
return array == null || (array != null && array.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断集合是否为空
|
||||
*
|
||||
* @param collection
|
||||
* @return
|
||||
*/
|
||||
public static <T> boolean isEmpty(Collection<T> collection) {
|
||||
return collection == null || collection.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断映射是否为空
|
||||
*
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> boolean isEmpty(Map<K, V> map) {
|
||||
return map == null || map.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否为空
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEmpty(MultipartFile file) {
|
||||
return file == null || file.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断引用类型是否为空
|
||||
*
|
||||
* @param <T>
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <T> boolean isEmpty(T val) {
|
||||
return Optional.ofNullable(val).map(t -> false).orElseGet(() -> true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得线程安全的List
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> syncList(List<T> list) {
|
||||
if (isEmpty(list)) {
|
||||
return Collections.synchronizedList(Lists.newArrayList());
|
||||
}
|
||||
return Collections.synchronizedList(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得线程安全的Set
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static <T> Set<T> syncSet(Set<T> set) {
|
||||
if (isEmpty(set)) {
|
||||
return Collections.synchronizedSet(Sets.newHashSet());
|
||||
}
|
||||
return Collections.synchronizedSet(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得线程安全的Map
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> Map<K, V> syncMap(Map<K, V> map) {
|
||||
if (isEmpty(map)) {
|
||||
return new ConcurrentHashMap<>();
|
||||
}
|
||||
return Collections.synchronizedMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断与目标值是否相等
|
||||
*
|
||||
* @param value
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEquals(Short val, short target) {
|
||||
return Optional.ofNullable(val).map(t -> t.shortValue() == target).orElseGet(() -> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断与目标值是否相等
|
||||
*
|
||||
* @param value
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEquals(Integer val, int target) {
|
||||
return Optional.ofNullable(val).map(t -> t.intValue() == target).orElseGet(() -> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断与目标值是否相等
|
||||
*
|
||||
* @param value
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEquals(Long val, long target) {
|
||||
return Optional.ofNullable(val).map(t -> t.longValue() == target).orElseGet(() -> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断与目标值是否相等
|
||||
*
|
||||
* @param value
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEquals(Float val, float target) {
|
||||
return Optional.ofNullable(val).map(t -> t.floatValue() == target).orElseGet(() -> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断与目标值是否相等
|
||||
*
|
||||
* @param value
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEquals(Double val, double target) {
|
||||
return Optional.ofNullable(val).map(t -> t.doubleValue() == target).orElseGet(() -> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断与目标值是否相等
|
||||
*
|
||||
* @param value
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEquals(Boolean val, boolean target) {
|
||||
return Optional.ofNullable(val).map(t -> t.booleanValue() == target).orElseGet(() -> false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取map中的值,null值转换为空字符串
|
||||
*
|
||||
* @param map
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getValue(Map<String, Object> map, String key) {
|
||||
if (isEmpty(map)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return Optional.ofNullable(map.get(key)).map(t -> StringUtils.trim(t.toString()))
|
||||
.orElseGet(() -> StringUtils.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* String转int类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static int getIntValue(String val) {
|
||||
if (StringUtils.isNotBlank(val)) {
|
||||
return Integer.parseInt(StringUtils.trim(val));
|
||||
}
|
||||
throw new NumberFormatException("String转int异常");
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer类型转int类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static int getIntValue(Integer val) {
|
||||
return Optional.ofNullable(val).map(t -> t.intValue())
|
||||
.orElseThrow(() -> new NumberFormatException("Integer类型转int异常"));
|
||||
}
|
||||
|
||||
/**
|
||||
* String转double类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static double getDoubleValue(String val) {
|
||||
if (StringUtils.isNotBlank(val)) {
|
||||
return Double.parseDouble(StringUtils.trim(val));
|
||||
}
|
||||
throw new NumberFormatException("String转double异常");
|
||||
}
|
||||
|
||||
/**
|
||||
* Double类型转double类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static double getDoubleValue(Double val) {
|
||||
return Optional.ofNullable(val).map(t -> t.doubleValue())
|
||||
.orElseThrow(() -> new NumberFormatException("Double类型转double异常"));
|
||||
}
|
||||
|
||||
/**
|
||||
* String转float类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static float getFloatValue(String val) {
|
||||
if (StringUtils.isNotBlank(val)) {
|
||||
return Float.parseFloat(StringUtils.trim(val));
|
||||
}
|
||||
throw new NumberFormatException("String转float异常");
|
||||
}
|
||||
|
||||
/**
|
||||
* Float类型转float类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static float getFloatValue(Float val) {
|
||||
return Optional.ofNullable(val).map(t -> t.floatValue())
|
||||
.orElseThrow(() -> new NumberFormatException("Float类型转float异常"));
|
||||
}
|
||||
|
||||
/**
|
||||
* String转long类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static long getLongValue(String val) {
|
||||
if (StringUtils.isNotBlank(val)) {
|
||||
return Long.parseLong(StringUtils.trim(val));
|
||||
}
|
||||
throw new NumberFormatException("String转long异常");
|
||||
}
|
||||
|
||||
/**
|
||||
* Long类型转long类型
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static long getLongValue(Long val) {
|
||||
return Optional.ofNullable(val).map(t -> t.longValue())
|
||||
.orElseThrow(() -> new NumberFormatException("Long类型转long异常"));
|
||||
}
|
||||
|
||||
/**
|
||||
* String转byte数组
|
||||
*
|
||||
* @param val 字符串
|
||||
* @param cs
|
||||
* @return
|
||||
*/
|
||||
public static byte[] stringToBytes(String val, Charset charset) {
|
||||
if (StringUtils.isBlank(val)) {
|
||||
return new byte[0];
|
||||
}
|
||||
return Optional.ofNullable(charset).map(t -> val.getBytes(t)).orElseGet(() -> val.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* byte数组转String
|
||||
*
|
||||
* @param bytes
|
||||
* @param cs
|
||||
* @return
|
||||
*/
|
||||
public static String bytesToString(byte[] bytes, Charset charset) {
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
return Optional.ofNullable(charset).map(t -> new String(bytes, t)).orElseGet(() -> new String(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* List转数组
|
||||
*
|
||||
* @param list
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public static <T> T[] listToArray(List<T> list, T[] t) {
|
||||
if (isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
return list.toArray(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set转数组
|
||||
*
|
||||
* @param set
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
public static <T> T[] setToArray(Set<T> set, T[] t) {
|
||||
if (isEmpty(set)) {
|
||||
return null;
|
||||
}
|
||||
return set.toArray(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set转List
|
||||
*
|
||||
* @param set
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> setToList(Set<T> set) {
|
||||
if (isEmpty(set)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return set.stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组转List
|
||||
*
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> arrayToList(T[] array) {
|
||||
if (isEmpty(array)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.stream(array).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* List转Set
|
||||
*
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static <T> Set<T> listToSet(List<T> list) {
|
||||
if (isEmpty(list)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return list.stream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 数组转Set
|
||||
*
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
public static <T> Set<T> arrayToSet(T[] array) {
|
||||
if (isEmpty(array)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return Arrays.stream(array).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接字符串
|
||||
*
|
||||
* @param list
|
||||
* @param regex
|
||||
* @param parallel
|
||||
* @param function
|
||||
* @return
|
||||
*/
|
||||
public static <T> String concatString(Collection<T> list, String regex, boolean parallel, Function<T, String> fn) {
|
||||
if (isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isEmpty(regex)) {
|
||||
regex = ",";
|
||||
}
|
||||
Stream<T> stream = parallel ? list.parallelStream() : list.stream();
|
||||
if (fn != null) {
|
||||
return stream.map(t -> fn.apply(t)).collect(Collectors.joining(regex));
|
||||
}
|
||||
return stream.map(String::valueOf).collect(Collectors.joining(regex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接url参数字符串
|
||||
*
|
||||
* @param paramMap
|
||||
* @return
|
||||
*/
|
||||
public static String getUrlParamStr(Map<String, String> paramMap) {
|
||||
return isEmpty(paramMap) ? "" : Joiner.on("&").withKeyValueSeparator("=").join(paramMap);
|
||||
}
|
||||
|
||||
public static String getSimpleUUID() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
|
||||
import com.wzj.soopin.content.idworker.utils.Utils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
|
||||
import com.wzj.soopin.content.idworker.utils.HttpReq;
|
||||
import com.wzj.soopin.content.idworker.utils.Ip;
|
||||
import com.wzj.soopin.content.idworker.utils.Props;
|
||||
import com.wzj.soopin.content.idworker.utils.Utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.wzj.soopin.content.idworker.utils;
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,4 +1,4 @@
|
||||
package com.wzj.soopin.content.idworker.utils;
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
@ -0,0 +1,432 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import io.minio.*;
|
||||
import io.minio.http.Method;
|
||||
import io.minio.messages.Bucket;
|
||||
import io.minio.messages.DeleteObject;
|
||||
import io.minio.messages.Item;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* MinIO工具类
|
||||
*/
|
||||
@Slf4j
|
||||
public class MinIOUtils {
|
||||
|
||||
private static MinioClient minioClient;
|
||||
|
||||
private static String endpoint;
|
||||
private static String bucketName;
|
||||
private static String accessKey;
|
||||
private static String secretKey;
|
||||
private static Integer imgSize;
|
||||
private static Integer fileSize;
|
||||
|
||||
|
||||
private static final String SEPARATOR = "/";
|
||||
|
||||
public MinIOUtils() {
|
||||
}
|
||||
|
||||
public MinIOUtils(String endpoint, String bucketName, String accessKey, String secretKey, Integer imgSize, Integer fileSize) {
|
||||
MinIOUtils.endpoint = endpoint;
|
||||
MinIOUtils.bucketName = bucketName;
|
||||
MinIOUtils.accessKey = accessKey;
|
||||
MinIOUtils.secretKey = secretKey;
|
||||
MinIOUtils.imgSize = imgSize;
|
||||
MinIOUtils.fileSize = fileSize;
|
||||
createMinioClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建基于Java端的MinioClient
|
||||
*/
|
||||
public void createMinioClient() {
|
||||
try {
|
||||
if (null == minioClient) {
|
||||
log.info("开始创建 MinioClient...");
|
||||
minioClient = MinioClient
|
||||
.builder()
|
||||
.endpoint(endpoint)
|
||||
.credentials(accessKey, secretKey)
|
||||
.build();
|
||||
createBucket(bucketName);
|
||||
log.info("创建完毕 MinioClient...");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("MinIO服务器异常:{}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传文件前缀路径
|
||||
* @return
|
||||
*/
|
||||
public static String getBasisUrl() {
|
||||
return endpoint + SEPARATOR + bucketName + SEPARATOR;
|
||||
}
|
||||
|
||||
/****************************** Operate Bucket Start ******************************/
|
||||
|
||||
/**
|
||||
* 启动SpringBoot容器的时候初始化Bucket
|
||||
* 如果没有Bucket则创建
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void createBucket(String bucketName) throws Exception {
|
||||
if (!bucketExists(bucketName)) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断Bucket是否存在,true:存在,false:不存在
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean bucketExists(String bucketName) throws Exception {
|
||||
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得Bucket的策略
|
||||
* @param bucketName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getBucketPolicy(String bucketName) throws Exception {
|
||||
String bucketPolicy = minioClient
|
||||
.getBucketPolicy(
|
||||
GetBucketPolicyArgs
|
||||
.builder()
|
||||
.bucket(bucketName)
|
||||
.build()
|
||||
);
|
||||
return bucketPolicy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得所有Bucket列表
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<Bucket> getAllBuckets() throws Exception {
|
||||
return minioClient.listBuckets();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据bucketName获取其相关信息
|
||||
* @param bucketName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Optional<Bucket> getBucket(String bucketName) throws Exception {
|
||||
return getAllBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据bucketName删除Bucket,true:删除成功; false:删除失败,文件或已不存在
|
||||
* @param bucketName
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void removeBucket(String bucketName) throws Exception {
|
||||
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
|
||||
/****************************** Operate Bucket End ******************************/
|
||||
|
||||
|
||||
/****************************** Operate Files Start ******************************/
|
||||
|
||||
/**
|
||||
* 判断文件是否存在
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名
|
||||
* @return
|
||||
*/
|
||||
public static boolean isObjectExist(String bucketName, String objectName) {
|
||||
boolean exist = true;
|
||||
try {
|
||||
minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
|
||||
} catch (Exception e) {
|
||||
exist = false;
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件夹是否存在
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件夹名称
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFolderExist(String bucketName, String objectName) {
|
||||
boolean exist = false;
|
||||
try {
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
|
||||
for (Result<Item> result : results) {
|
||||
Item item = result.get();
|
||||
if (item.isDir() && objectName.equals(item.objectName())) {
|
||||
exist = true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exist = false;
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件前缀查询文件
|
||||
* @param bucketName 存储桶
|
||||
* @param prefix 前缀
|
||||
* @param recursive 是否使用递归查询
|
||||
* @return MinioItem 列表
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<Item> getAllObjectsByPrefix(String bucketName,
|
||||
String prefix,
|
||||
boolean recursive) throws Exception {
|
||||
List<Item> list = new ArrayList<>();
|
||||
Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
|
||||
if (objectsIterator != null) {
|
||||
for (Result<Item> o : objectsIterator) {
|
||||
Item item = o.get();
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件流
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名
|
||||
* @return 二进制流
|
||||
*/
|
||||
public static InputStream getObject(String bucketName, String objectName) throws Exception {
|
||||
return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 断点下载
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名称
|
||||
* @param offset 起始字节的位置
|
||||
* @param length 要读取的长度
|
||||
* @return 二进制流
|
||||
*/
|
||||
public InputStream getObject(String bucketName, String objectName, long offset, long length)throws Exception {
|
||||
return minioClient.getObject(
|
||||
GetObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.offset(offset)
|
||||
.length(length)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路径下文件列表
|
||||
* @param bucketName 存储桶
|
||||
* @param prefix 文件名称
|
||||
* @param recursive 是否递归查找,false:模拟文件夹结构查找
|
||||
* @return 二进制流
|
||||
*/
|
||||
public static Iterable<Result<Item>> listObjects(String bucketName, String prefix,
|
||||
boolean recursive) {
|
||||
return minioClient.listObjects(
|
||||
ListObjectsArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.prefix(prefix)
|
||||
.recursive(recursive)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用MultipartFile进行文件上传
|
||||
* @param bucketName 存储桶
|
||||
* @param file 文件名
|
||||
* @param objectName 对象名
|
||||
* @param contentType 类型
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static ObjectWriteResponse uploadFile(String bucketName, MultipartFile file,
|
||||
String objectName, String contentType) throws Exception {
|
||||
InputStream inputStream = file.getInputStream();
|
||||
return minioClient.putObject(
|
||||
PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.contentType(contentType)
|
||||
.stream(inputStream, inputStream.available(), -1)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地文件
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 对象名称
|
||||
* @param fileName 本地文件路径
|
||||
*/
|
||||
public static ObjectWriteResponse uploadFile(String bucketName, String objectName,
|
||||
String fileName) throws Exception {
|
||||
return minioClient.uploadObject(
|
||||
UploadObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.filename(fileName)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过流上传文件
|
||||
*
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件对象
|
||||
* @param inputStream 文件流
|
||||
*/
|
||||
public static ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) throws Exception {
|
||||
return minioClient.putObject(
|
||||
PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.stream(inputStream, inputStream.available(), -1)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件夹或目录
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 目录路径
|
||||
*/
|
||||
public static ObjectWriteResponse createDir(String bucketName, String objectName) throws Exception {
|
||||
return minioClient.putObject(
|
||||
PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件信息, 如果抛出异常则说明文件不存在
|
||||
*
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名称
|
||||
*/
|
||||
public static String getFileStatusInfo(String bucketName, String objectName) throws Exception {
|
||||
return minioClient.statObject(
|
||||
StatObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.build()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
*
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名
|
||||
* @param srcBucketName 目标存储桶
|
||||
* @param srcObjectName 目标文件名
|
||||
*/
|
||||
public static ObjectWriteResponse copyFile(String bucketName, String objectName,
|
||||
String srcBucketName, String srcObjectName) throws Exception {
|
||||
return minioClient.copyObject(
|
||||
CopyObjectArgs.builder()
|
||||
.source(CopySource.builder().bucket(bucketName).object(objectName).build())
|
||||
.bucket(srcBucketName)
|
||||
.object(srcObjectName)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名称
|
||||
*/
|
||||
public static void removeFile(String bucketName, String objectName) throws Exception {
|
||||
minioClient.removeObject(
|
||||
RemoveObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除文件
|
||||
* @param bucketName 存储桶
|
||||
* @param keys 需要删除的文件列表
|
||||
* @return
|
||||
*/
|
||||
public static void removeFiles(String bucketName, List<String> keys) {
|
||||
List<DeleteObject> objects = new LinkedList<>();
|
||||
keys.forEach(s -> {
|
||||
objects.add(new DeleteObject(s));
|
||||
try {
|
||||
removeFile(bucketName, s);
|
||||
} catch (Exception e) {
|
||||
log.error("批量删除失败!error:{}",e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件外链
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名
|
||||
* @param expires 过期时间 <=7 秒 (外链有效时间(单位:秒))
|
||||
* @return url
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {
|
||||
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();
|
||||
return minioClient.getPresignedObjectUrl(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件外链
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @return url
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPresignedObjectUrl(String bucketName, String objectName) throws Exception {
|
||||
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.method(Method.GET).build();
|
||||
return minioClient.getPresignedObjectUrl(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将URLDecoder编码转成UTF8
|
||||
* @param str
|
||||
* @return
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {
|
||||
String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
|
||||
return URLDecoder.decode(url, "UTF-8");
|
||||
}
|
||||
|
||||
/****************************** Operate Files End ******************************/
|
||||
|
||||
|
||||
}
|
@ -11,39 +11,39 @@ import java.util.List;
|
||||
*/
|
||||
public class PagedGridResult {
|
||||
|
||||
private int page; // 当前页数
|
||||
private long total; // 总页数
|
||||
private long records; // 总记录数
|
||||
private List<?> rows; // 每行显示的内容
|
||||
private int page; // 当前页数
|
||||
private long total; // 总页数
|
||||
private long records; // 总记录数
|
||||
private List<?> rows; // 每行显示的内容
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
public long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
public long getRecords() {
|
||||
return records;
|
||||
}
|
||||
public void setRecords(long records) {
|
||||
this.records = records;
|
||||
}
|
||||
public List<?> getRows() {
|
||||
return rows;
|
||||
}
|
||||
public void setRows(List<?> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
public long getRecords() {
|
||||
return records;
|
||||
}
|
||||
public void setRecords(long records) {
|
||||
this.records = records;
|
||||
}
|
||||
public List<?> getRows() {
|
||||
return rows;
|
||||
}
|
||||
public void setRows(List<?> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.wzj.soopin.content.idworker.utils;
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -6,8 +6,9 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
import static com.squareup.okhttp.internal.Util.closeQuietly;
|
||||
import static java.io.File.separator;
|
||||
import static org.n3r.idworker.utils.Serializes.closeQuietly;
|
||||
|
||||
|
||||
public class Props {
|
||||
static Logger log = LoggerFactory.getLogger(Props.class);
|
@ -0,0 +1,60 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import com.qcloud.vod.VodUploadClient;
|
||||
import com.qcloud.vod.model.VodUploadRequest;
|
||||
import com.qcloud.vod.model.VodUploadResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
|
||||
|
||||
@Component
|
||||
public class QcCloud {
|
||||
@Autowired
|
||||
private TencentCloudProperties tencentCloudProperties;
|
||||
public String getSecretId() {
|
||||
return tencentCloudProperties.getSecretId();
|
||||
}
|
||||
|
||||
public String getSecretKey() {
|
||||
return tencentCloudProperties.getSecretKey();
|
||||
}
|
||||
|
||||
public String getRegion() {
|
||||
return "ap-guangzhou";// 腾讯云 VOD 和 COS 使用相同区域
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String uploadViaTempFile(String fileName) throws Exception {
|
||||
//确保 vlogdata 目录存在
|
||||
// String storagePath = new File(System.getProperty("user.dir"), "vlogdata").getAbsolutePath();
|
||||
// String storagePath = "/Users/wuzhongjie/Desktop/vlog-1.0.0/vlogdata"; // 本地
|
||||
String storagePath = "/data/vlogdata"; // 生产
|
||||
|
||||
System.out.println("腾讯云服务:绝对路径: " + storagePath);
|
||||
File storageDir = new File(storagePath);
|
||||
// 组装完整的文件路径
|
||||
File sourceFile = new File(storageDir, fileName);
|
||||
System.out.println("腾讯云服务:完整文件路径: " + sourceFile.toPath());
|
||||
|
||||
if (!sourceFile.exists()) {
|
||||
throw new RuntimeException("腾讯云服务:文件不存在: " + sourceFile.getAbsolutePath());
|
||||
}
|
||||
try {
|
||||
VodUploadClient client = new VodUploadClient(getSecretId(), getSecretKey());
|
||||
VodUploadRequest request = new VodUploadRequest();
|
||||
request.setMediaFilePath(sourceFile.getAbsolutePath());// 指定本地文件路径
|
||||
request.setProcedure("视频处理"); // 智能审核+水印
|
||||
// 上传文件
|
||||
VodUploadResponse response = client.upload(getRegion(), request);
|
||||
// return response;
|
||||
return response.getFileId();
|
||||
} finally {
|
||||
// 删除本地文件
|
||||
Files.deleteIfExists(sourceFile.toPath());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,211 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import net.sf.json.JSONObject;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.wzj.soopin.content.utils.CommonUtil.getUrlParamStr;
|
||||
import static org.apache.commons.collections4.MapUtils.isEmpty;
|
||||
|
||||
|
||||
/**
|
||||
* RestTemplate工具类
|
||||
*
|
||||
* @version 1.0.0
|
||||
* @author Leon
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public final class RestTemplateUtil {
|
||||
|
||||
private static RestTemplate TEMPLATE;
|
||||
|
||||
private static RestTemplate TEMPLATE_IGNORE_SSL;
|
||||
|
||||
@Resource(name = "restTemplate")
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Resource(name = "restTemplateIgnoreSSL")
|
||||
private RestTemplate restTemplateIgnoreSSL;
|
||||
|
||||
private RestTemplateUtil() {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
TEMPLATE = this.restTemplate;
|
||||
TEMPLATE_IGNORE_SSL = this.restTemplateIgnoreSSL;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
*
|
||||
* @param <T>
|
||||
* @param mediaType
|
||||
* @param headerHandler
|
||||
* @param headerData
|
||||
* @param url
|
||||
* @param param
|
||||
* @param valueType
|
||||
* @param responseHandler
|
||||
*/
|
||||
public static <T> void get(MediaType mediaType, Consumer<HttpHeaders> headerHandler, Map<String, String> headerData,
|
||||
String url, Map<String, String> param, Class<T> valueType, Consumer<ResponseEntity<T>> responseHandler) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
Optional.ofNullable(mediaType).ifPresent(t -> headers.setContentType(t));
|
||||
// 请求头信息
|
||||
buildHttpHeaders(headers, headerHandler, headerData);
|
||||
// 构建请求
|
||||
HttpEntity<T> entity = new HttpEntity<>(headers);
|
||||
ResponseEntity<T> responseEntity = buildRestTemplate(url).exchange(buildUrl(url, param), HttpMethod.GET, entity,
|
||||
valueType);
|
||||
// 处理响应
|
||||
responseHandler(responseEntity, responseHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求
|
||||
*
|
||||
* @param <T>
|
||||
* @param mediaType
|
||||
* @param headerHandler
|
||||
* @param headerData
|
||||
* @param url
|
||||
* @param param
|
||||
* @param valueType
|
||||
* @param responseHandler
|
||||
*/
|
||||
public static <T> void post(MediaType mediaType, Consumer<HttpHeaders> headerHandler,
|
||||
Map<String, String> headerData, String url, JSONObject param, Class<T> valueType,
|
||||
Consumer<ResponseEntity<T>> responseHandler) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (mediaType == null) {
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
} else {
|
||||
headers.setContentType(mediaType);
|
||||
}
|
||||
// 请求头信息
|
||||
buildHttpHeaders(headers, headerHandler, headerData);
|
||||
// 构建请求
|
||||
HttpEntity<JSONObject> entity = new HttpEntity<>(param, headers);
|
||||
ResponseEntity<T> responseEntity = buildRestTemplate(url).exchange(url, HttpMethod.POST, entity, valueType);
|
||||
// 处理响应
|
||||
responseHandler(responseEntity, responseHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求
|
||||
*
|
||||
* @param <T>
|
||||
* @param mediaType
|
||||
* @param headerHandler
|
||||
* @param headerData
|
||||
* @param url
|
||||
* @param param
|
||||
* @param valueType
|
||||
* @param responseHandler
|
||||
*/
|
||||
public static <T> void post(MediaType mediaType, Consumer<HttpHeaders> headerHandler,
|
||||
Map<String, String> headerData, String url, MultiValueMap<String, Object> param, Class<T> valueType,
|
||||
Consumer<ResponseEntity<T>> responseHandler) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (mediaType == null) {
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
} else {
|
||||
headers.setContentType(mediaType);
|
||||
}
|
||||
// 请求头信息
|
||||
buildHttpHeaders(headers, headerHandler, headerData);
|
||||
// 构建请求
|
||||
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(param, headers);
|
||||
ResponseEntity<T> responseEntity = buildRestTemplate(url).postForEntity(url, entity, valueType);
|
||||
// 处理响应
|
||||
responseHandler(responseEntity, responseHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT请求
|
||||
*
|
||||
* @param <T>
|
||||
* @param headerHandler
|
||||
* @param headerData
|
||||
* @param url
|
||||
* @param jsonBody
|
||||
* @param valueType
|
||||
* @param responseHandler
|
||||
*/
|
||||
public static <T> void put(Consumer<HttpHeaders> headerHandler, Map<String, String> headerData, String url,
|
||||
String jsonBody, Class<T> valueType, Consumer<ResponseEntity<T>> responseHandler) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
// 请求头信息
|
||||
buildHttpHeaders(headers, headerHandler, headerData);
|
||||
// 构建请求
|
||||
HttpEntity<String> entity = new HttpEntity<>(jsonBody, headers);
|
||||
ResponseEntity<T> responseEntity = buildRestTemplate(url).exchange(url, HttpMethod.PUT, entity, valueType);
|
||||
// 处理响应
|
||||
responseHandler(responseEntity, responseHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求模板
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
private static RestTemplate buildRestTemplate(String url) {
|
||||
boolean ssl = StringUtils.startsWithIgnoreCase(url, "https");
|
||||
return ssl ? TEMPLATE_IGNORE_SSL : TEMPLATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求头信息
|
||||
*
|
||||
* @param headers
|
||||
* @param headerHandler
|
||||
* @param headerData
|
||||
*/
|
||||
private static void buildHttpHeaders(HttpHeaders headers, Consumer<HttpHeaders> headerHandler,
|
||||
Map<String, String> headerData) {
|
||||
Optional.ofNullable(headerHandler).ifPresent(t -> t.accept(headers));
|
||||
if (!isEmpty(headerData)) {
|
||||
headerData.forEach((k, v) -> headers.add(k, v));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求url
|
||||
*
|
||||
* @param url
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
private static String buildUrl(String url, Map<String, String> param) {
|
||||
if (isEmpty(param)) {
|
||||
return url;
|
||||
}
|
||||
String paramStr = getUrlParamStr(param);
|
||||
return url + "?" + paramStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应处理
|
||||
*
|
||||
* @param <T>
|
||||
* @param responseEntity
|
||||
* @param responseHandler
|
||||
*/
|
||||
private static <T> void responseHandler(ResponseEntity<T> responseEntity,
|
||||
Consumer<ResponseEntity<T>> responseHandler) {
|
||||
Optional.ofNullable(responseHandler).ifPresent(t -> t.accept(responseEntity));
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import com.wzj.soopin.content.idworker.utils.Utils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.wzj.soopin.content.idworker.utils;
|
||||
package com.wzj.soopin.content.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.Timestamp;
|
Loading…
x
Reference in New Issue
Block a user