wangyunpeng 3 viikkoa sitten
vanhempi
commit
e452aaa273
26 muutettua tiedostoa jossa 3283 lisäystä ja 100 poistoa
  1. 30 0
      core/src/main/java/com/tzld/supply/common/enums/EnumUploadFileType.java
  2. 386 0
      core/src/main/java/com/tzld/supply/config/AliOssConfig.java
  3. 43 0
      core/src/main/java/com/tzld/supply/config/RedisConfig.java
  4. 0 63
      core/src/main/java/com/tzld/supply/config/RedisTemplateConfig.java
  5. 18 0
      core/src/main/java/com/tzld/supply/model/param/FileUploadParam.java
  6. 15 0
      core/src/main/java/com/tzld/supply/model/param/OssUploadSignParam.java
  7. 19 0
      core/src/main/java/com/tzld/supply/model/param/StsTokenParam.java
  8. 196 0
      core/src/main/java/com/tzld/supply/model/param/VideoApiBaseParam.java
  9. 25 0
      core/src/main/java/com/tzld/supply/model/vo/FileInfo.java
  10. 49 0
      core/src/main/java/com/tzld/supply/model/vo/PolicyDetailVO.java
  11. 13 0
      core/src/main/java/com/tzld/supply/model/vo/SignatureVO.java
  12. 20 0
      core/src/main/java/com/tzld/supply/model/vo/StsTokenVO.java
  13. 1492 0
      core/src/main/java/com/tzld/supply/util/AliOssFileTool.java
  14. 72 0
      core/src/main/java/com/tzld/supply/util/BasePropertiesUtils.java
  15. 169 0
      core/src/main/java/com/tzld/supply/util/CdnUtil.java
  16. 15 0
      core/src/main/java/com/tzld/supply/util/DateUtils.java
  17. 92 0
      core/src/main/java/com/tzld/supply/util/PropertiesUtils.java
  18. 64 0
      core/src/main/java/com/tzld/supply/util/RandomUtil.java
  19. 257 0
      core/src/main/java/com/tzld/supply/util/RedisUtils.java
  20. 161 0
      core/src/main/java/com/tzld/supply/util/http/HttpClientUtils.java
  21. 3 1
      core/src/main/resources/generator/mybatis-spider-generator-config.xml
  22. 102 0
      server/src/main/java/com/tzld/supply/controller/FileController.java
  23. 2 12
      server/src/main/resources/application-dev.yml
  24. 2 12
      server/src/main/resources/application-prod.yml
  25. 2 12
      server/src/main/resources/application-test.yml
  26. 36 0
      server/src/main/resources/application.yml

+ 30 - 0
core/src/main/java/com/tzld/supply/common/enums/EnumUploadFileType.java

@@ -0,0 +1,30 @@
+package com.tzld.supply.common.enums;
+
+public enum EnumUploadFileType {
+	PICTURE(1,"1"),
+	VIDEO(2,"2"),
+	VOICE(3,"3"),
+	FILE(4,"4"),
+	GIF(5,"5"),
+	SUBTITLE(6,"6"),
+	;
+
+	private Integer intType;
+	private String strType;
+	EnumUploadFileType(Integer intType, String strType){
+		this.intType = intType;
+		this.strType = strType;
+	}
+	public Integer getIntType() {
+		return intType;
+	}
+	public void setIntType(Integer intType) {
+		this.intType = intType;
+	}
+	public String getStrType() {
+		return strType;
+	}
+	public void setStrType(String strType) {
+		this.strType = strType;
+	}
+}

+ 386 - 0
core/src/main/java/com/tzld/supply/config/AliOssConfig.java

@@ -0,0 +1,386 @@
+package com.tzld.supply.config;
+
+import com.aliyun.oss.ClientConfiguration;
+import com.aliyun.oss.OSSClient;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.profile.DefaultProfile;
+import com.tzld.supply.model.vo.PolicyDetailVO;
+import com.tzld.supply.util.AliOssFileTool;
+import com.tzld.supply.util.PropertiesUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+
+/**
+ * @author zhaoyuchun
+ */
+@Configuration
+public class AliOssConfig {
+	/** 图片服务域名 **/
+	// public String picEndPoint;
+	/** 对象存储域名 **/
+	private static String ossEndPoint;
+	/** 阿里云accesskeyId **/
+	private static String accessKeyId;
+	/** 过期时间,单位秒 **/
+	private static long expiration;
+	/** 阿里云accessKeySecret **/
+	private static String accessKeySecret;
+	/** 文件系统配置文件地址 **/
+	public String configPath;
+	private static Boolean needPress;
+	private static String projectName;
+	private static String videoEndPoint;
+	private static String internalEndPoint;
+	private static OSSClient ossClient;
+	private static OSSClient priClient;
+	private static OSSClient videoClient;
+	private static OSSClient internalOssClient;
+
+	private static String snapshotLocation;
+	private static OSSClient ossReadOnlyClient;
+	private static IAcsClient mAcsClient;
+
+	private static DefaultAcsClient defaultAcsClient;
+	public static final String PIPELINEID = "abe6a0b9b9334858913eb416974485d2";
+	public static final String MTS_REGION = "cn-hangzhou";
+	public static final String OSS_REGION = "oss-cn-hangzhou";
+	private static PolicyDetailVO policyDetail;
+	static {
+		policyDetail = new PolicyDetailVO();
+		policyDetail.setVersion("1");
+		List<PolicyDetailVO.PolicyVO> statement = new ArrayList<PolicyDetailVO.PolicyVO>();
+		PolicyDetailVO.PolicyVO policy = new PolicyDetailVO.PolicyVO();
+		List<String> action = new ArrayList<String>();
+		List<String> resource = new ArrayList<String>();
+		action.add("oss:PutObject");
+		action.add("oss:AbortMultipartUpload");
+		action.add("oss:ListParts");
+		action.add("oss:AbortMultipartUpload");
+		action.add("oss:ListObjects");
+		resource.add("*");
+		policy.setEffect("Allow");
+		policy.setAction(action);
+		policy.setResource(resource);
+		statement.add(policy);
+		policyDetail.setStatement(statement);
+
+	}
+
+
+	public static OSSClient getVideoClient() {
+		return videoClient;
+	}
+
+	public void setVideoClient(OSSClient videoClient) {
+		AliOssConfig.videoClient = videoClient;
+	}
+
+	public static String cdnDomain;
+	public static String imgDomain;
+	public static String videoDomain;
+	public static String uploadDomain;
+	public static String lvvideoDomain;
+	public static String pubBucket;
+	public static String priBucket;
+	public static String priEndPoint;
+	public static HashMap<String, String> bucketes = new HashMap<String, String>();
+	private static Logger logger = Logger.getLogger(AliOssFileTool.class);
+	public static String SUFFIX = "https://";
+	private String tmpStr;
+	@PostConstruct
+	public void init() throws Exception {
+		logger.info("初始化oss参数");
+		try {
+			setOssEndPoint(ossEndPoint);
+			setProjectName(projectName);
+			setExpiration(Long.valueOf(expiration));
+			setVideoEndPoint(videoEndPoint);
+			setAccessKeyId(accessKeyId);
+			setAccessKeySecret(accessKeySecret);
+			setCdnDomain(cdnDomain);
+			setImgDomain(imgDomain);
+			setVideoDomain(videoDomain);
+			setUploadDomain(uploadDomain);
+			setInternalEndPoint(internalEndPoint);
+			setPubBucket(pubBucket);
+			try{
+				String[] buckets = pubBucket.split(",");
+				for (String bucket : buckets) {
+					String[] bucketParms = bucket.split(":");
+					String bucketKey = bucketParms[0];
+					String bucketName = bucketParms[1];
+					AliOssConfig.bucketes.put(bucketKey, bucketName);
+				}
+			}catch(Exception e){
+				e.printStackTrace();
+			}
+			setPriBucket(priBucket);
+			String[] buckets = priBucket.split(",");
+			for (String bucket : buckets) {
+				String[] bucketParms = bucket.split(":");
+				String bucketKey = bucketParms[0];
+				String bucketName = bucketParms[1];
+				AliOssConfig.bucketes.put(bucketKey, bucketName);
+			}
+			setNeedPress(needPress);
+			setLvvideoDomain(lvvideoDomain);
+			setpriEndPoint(priEndPoint);
+			setSnapshotLocation("");
+
+			setOssClient(new OSSClient(SUFFIX + ossEndPoint, accessKeyId, accessKeySecret));
+			setInternalOssClient(new OSSClient(SUFFIX + internalEndPoint, accessKeyId, accessKeySecret));
+			setPriClient(new OSSClient(SUFFIX + priEndPoint, accessKeyId, accessKeySecret));
+			setVideoClient(new OSSClient(SUFFIX + videoEndPoint, accessKeyId, accessKeySecret));
+			DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
+			setDefaultAcsClient(new DefaultAcsClient(profile));
+		} catch (Exception e) {
+			logger.error("配置文件读取失败");
+			throw e;
+		}
+
+	}
+	@Value("${oss.supply.priEndPoint}")
+	public void setpriEndPoint(String priEndPoint) {
+		AliOssConfig.priEndPoint = priEndPoint;
+	}
+
+	public static OSSClient getOssReadOnlyClient() {
+		if (AliOssConfig.ossReadOnlyClient == null) {
+			ClientConfiguration conf = new ClientConfiguration();
+			// 设置OSSClient允许打开的最大HTTP连接数,默认为1024个。
+			conf.setMaxConnections(500);
+			// 设置Socket层传输数据的超时时间,默认为50000毫秒。
+			conf.setSocketTimeout(40000);
+			// 设置建立连接的超时时间,默认为50000毫秒。
+			conf.setConnectionTimeout(10000);
+			// 设置从连接池中获取连接的超时时间(单位:毫秒),默认不超时。
+			conf.setConnectionRequestTimeout(1000);
+			// 设置连接空闲超时时间。超时则关闭连接,默认为60000毫秒。
+			conf.setIdleConnectionTime(10000);
+			// 设置失败请求重试次数,默认为3次。
+			conf.setMaxErrorRetry(5);
+			AliOssConfig.ossReadOnlyClient = new OSSClient(SUFFIX + getOssEndPoint(), 
+					PropertiesUtils.getReadOnlyAccessKeyId(),
+					PropertiesUtils.getReadOnlyAccessKeySecret(),
+					conf );
+		}
+		return AliOssConfig.ossReadOnlyClient;
+	}
+	@Value("${oss.supply.internal.endPoint}")
+	public void setInternalEndPoint(String internalEndPoint) {
+		AliOssConfig.internalEndPoint = internalEndPoint;
+	}
+
+	public static String getInternalEndPoint() {
+		return internalEndPoint;
+	}
+	public static String getBucket(String key) {
+		String bucket = AliOssConfig.bucketes.get(key);
+		if (StringUtils.isEmpty(bucket)) {
+			logger.error(String.format("bucket key[%s]不存在", key));
+		}
+		return bucket;
+	}
+
+	public static String getSnapshotLocation() {
+		return snapshotLocation;
+	}
+
+	public void setSnapshotLocation(String snapshotLocation ) {
+		AliOssConfig.snapshotLocation = snapshotLocation;
+	}
+	
+	public static String getProjectName() {
+		return projectName;
+	}
+
+	@Value("${oss.supply.projectName}")
+	public void setProjectName(String projectName) {
+		AliOssConfig.projectName = projectName;
+	}
+
+
+	public static OSSClient getOssClient() {
+		return ossClient;
+	}
+
+	public void setOssClient(OSSClient ossClient) {
+		AliOssConfig.ossClient = ossClient;
+	}
+
+	public static OSSClient getInternalOssClient() {
+		return internalOssClient;
+	}
+
+	public void setInternalOssClient(OSSClient internalOssClient) {
+		AliOssConfig.internalOssClient = internalOssClient;
+	}
+
+	public static String getOssEndPoint() {
+		return ossEndPoint;
+	}
+
+	@Value("${oss.supply.ossEndPoint}")
+	public void setOssEndPoint(String ossEndPoint) {
+		AliOssConfig.ossEndPoint = ossEndPoint;
+	}
+
+	public static String getAccessKeyId() {
+		return accessKeyId;
+	}
+	@Value("${oss.supply.accessKey}")
+	public void setAccessKeyId(String accessKeyId) {
+		AliOssConfig.accessKeyId = accessKeyId;
+	}
+
+
+
+	public static String getAccessKeySecret() {
+		return accessKeySecret;
+	}
+	@Value("${oss.supply.secretKey}")
+	public void setAccessKeySecret(String accessKeySecret) {
+		AliOssConfig.accessKeySecret = accessKeySecret;
+	}
+
+	public String getConfigPath() {
+		return configPath;
+	}
+
+	public void setConfigPath(String configPath) {
+		this.configPath = configPath;
+	}
+
+	public static String getCdnDomain() {
+		return cdnDomain;
+	}
+	@Value("${oss.supply.cdnDomain}")
+	public void setCdnDomain(String cdnDomain) {
+		AliOssConfig.cdnDomain = cdnDomain;
+	}
+
+	public static String getImgDomain() {
+		return imgDomain;
+	}
+
+	@Value("${oss.supply.imgDomain}")
+	public void setImgDomain(String imgDomain) {
+		AliOssConfig.imgDomain = imgDomain;
+	}
+	@Value("${oss.supply.pubBucket}")
+	public void setPubBucket(String pubBucket) {
+		AliOssConfig.pubBucket = pubBucket;
+	}
+	@Value("${oss.supply.priBucket}")
+	public void setPriBucket(String priBucket) {
+		AliOssConfig.priBucket = priBucket;
+	}
+
+	public static HashMap<String, String> getBucketes() {
+		return bucketes;
+	}
+
+	public void setBucketes(HashMap<String, String> bucketes) {
+		AliOssConfig.bucketes = bucketes;
+	}
+
+
+	public static Boolean getNeedPress() {
+		return needPress;
+	}
+	@Value("${oss.supply.needPress}")
+	public void setNeedPress(Boolean needPress) {
+		AliOssConfig.needPress = needPress;
+	}
+
+	public static String getVideoDomain() {
+		return videoDomain;
+	}
+	@Value("${oss.supply.videoDomain}")
+	public void setVideoDomain(String videoDomain) {
+		AliOssConfig.videoDomain = videoDomain;
+	}
+
+	public static String getVideoEndPoint() {
+		return videoEndPoint;
+	}
+	@Value("${oss.supply.videoEndPoint}")
+	public void setVideoEndPoint(String videoEndPoint) {
+		AliOssConfig.videoEndPoint = videoEndPoint;
+	}
+
+
+	public static long getExpiration() {
+		return expiration;
+	}
+	@Value("${oss.supply.expiration}")
+	public void setExpiration(long expiration) {
+		AliOssConfig.expiration = expiration;
+	}
+
+	public static String getUploadDomain() {
+		return uploadDomain;
+	}
+	@Value("${cdn.upload.domain}")
+	public void setUploadDomain(String uploadDomain) {
+		AliOssConfig.uploadDomain = uploadDomain;
+	}
+
+	public static PolicyDetailVO getPolicyDetail() {
+		return policyDetail;
+	}
+
+	public void setPolicyDetail(PolicyDetailVO policyDetail) {
+		AliOssConfig.policyDetail = policyDetail;
+	}
+
+	public static OSSClient getPriClient() {
+		return priClient;
+	}
+
+	public void setPriClient(OSSClient priClient) {
+		AliOssConfig.priClient = priClient;
+	}
+
+	public static DefaultAcsClient getDefaultAcsClient() {
+		return defaultAcsClient;
+	}
+
+	public void setDefaultAcsClient(DefaultAcsClient defaultAcsClient) {
+		AliOssConfig.defaultAcsClient = defaultAcsClient;
+	}
+
+	public static String getLvvideoDomain() {
+		return lvvideoDomain;
+	}
+	@Value("${oss.supply.lvvideoDomain}")
+	public void setLvvideoDomain(String lvvideoDomain) {
+		AliOssConfig.lvvideoDomain = lvvideoDomain;
+	}
+	
+	public static OSSClient getShangHaiInternalOssClient() {
+		return new OSSClient(SUFFIX + "oss-cn-shanghai.aliyuncs.com", accessKeyId, accessKeySecret);
+	} 
+	
+	public static IAcsClient getIAcsClient() {
+		if (AliOssConfig.mAcsClient == null) {
+			DefaultProfile profile = DefaultProfile.getProfile(getMpsRegionId(), // 地域ID
+					getAccessKeyId(), // RAM账号的AccessKey ID
+					getAccessKeySecret()); // RAM账号Access Key Secret
+			mAcsClient = new DefaultAcsClient(profile);
+		}
+		return AliOssConfig.mAcsClient;
+	}
+	public static String getMpsRegionId() {
+		return PropertiesUtils.getValue("oss.longvideo.transcode.mpsRegionId");
+	}
+}

+ 43 - 0
core/src/main/java/com/tzld/supply/config/RedisConfig.java

@@ -0,0 +1,43 @@
+package com.tzld.supply.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(redisConnectionFactory);
+        //设置value的序列化方式json
+        redisTemplate.setValueSerializer(redisSerializer());
+        //设置key序列化方式String
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        //设置hash key序列化方式String
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+        //设置hash value序列化json
+        redisTemplate.setHashValueSerializer(redisSerializer());
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
+    public RedisSerializer<Object> redisSerializer() {
+        //创建JSON序列化器
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        //必须设置,否则无法序列化实体类对象
+        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
+        return new GenericJackson2JsonRedisSerializer(objectMapper);
+    }
+
+}

+ 0 - 63
core/src/main/java/com/tzld/supply/config/RedisTemplateConfig.java

@@ -1,63 +0,0 @@
-package com.tzld.supply.config;
-
-import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
-import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
-import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
-import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-
-@Configuration
-public class RedisTemplateConfig {
-
-    @Bean("redisPool")
-    @ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
-    public GenericObjectPoolConfig<LettucePoolingClientConfiguration> redisPool() {
-        return new GenericObjectPoolConfig<>();
-    }
-
-    @Bean("redisConfig")
-    @ConfigurationProperties(prefix = "spring.redis")
-    public RedisStandaloneConfiguration tairConfig() {
-        return new RedisStandaloneConfiguration();
-    }
-
-    @Bean("redisFactory")
-    @Primary
-    public LettuceConnectionFactory factory(@Qualifier("redisPool") GenericObjectPoolConfig<LettucePoolingClientConfiguration> redisPool,
-                                            @Qualifier("redisConfig") RedisStandaloneConfiguration redisConfig) {
-        LettuceClientConfiguration lettuceClientConfiguration =
-                LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build();
-        return new LettuceConnectionFactory(redisConfig, lettuceClientConfiguration);
-    }
-
-    @Bean(name = "redisTemplate")
-    public RedisTemplate<String, String> getRedisTemplate(@Qualifier("redisFactory") RedisConnectionFactory factory) {
-        return buildRedisTemplateByString(factory);
-    }
-
-    /**
-     * 构建redisTemplate 使用string序列化
-     *
-     * @param factory
-     * @return
-     */
-    public RedisTemplate<String, String> buildRedisTemplateByString(RedisConnectionFactory factory) {
-        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
-        redisTemplate.setConnectionFactory(factory);
-        // key的序列化类型 保证可读性
-        redisTemplate.setKeySerializer(new StringRedisSerializer());
-        redisTemplate.setValueSerializer(new StringRedisSerializer());
-        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
-        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
-        return redisTemplate;
-    }
-
-}

+ 18 - 0
core/src/main/java/com/tzld/supply/model/param/FileUploadParam.java

@@ -0,0 +1,18 @@
+package com.tzld.supply.model.param;
+
+import com.stuuudy.commons.external.filestorage.enums.EnumFileType;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class FileUploadParam {
+    @NotNull(message = "文件不能为空")
+    private MultipartFile file;
+
+    private String fileUri;
+
+    @NotNull(message = "文件类型不能为空")
+    private EnumFileType fileType;
+}

+ 15 - 0
core/src/main/java/com/tzld/supply/model/param/OssUploadSignParam.java

@@ -0,0 +1,15 @@
+package com.tzld.supply.model.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class OssUploadSignParam extends VideoApiBaseParam {
+
+	@ApiModelProperty(value = "文件类型1:picture 2:视频 3:声音 4:文件  5:gif 6:字幕", required = true)
+	@NotNull
+	private Integer fileType;
+
+}

+ 19 - 0
core/src/main/java/com/tzld/supply/model/param/StsTokenParam.java

@@ -0,0 +1,19 @@
+package com.tzld.supply.model.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.NotEmpty;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class StsTokenParam extends VideoApiBaseParam {
+	
+	@NotEmpty(message = "fileType不能为空")
+	@NotNull(message = "fileType不能为空")
+	@ApiModelProperty(value = "文件类型:(1:PICTURE, 2:VIDEO, 3:VOICE, 4:FILE, 5:GIF)")
+	private Integer fileType;
+	@ApiModelProperty(value = "第一次获取token时返回的唯一标识字符串,用来在上传大文件时若签名快失效时重新获取对应文件的token")
+	private String uploadId;
+
+}

+ 196 - 0
core/src/main/java/com/tzld/supply/model/param/VideoApiBaseParam.java

@@ -0,0 +1,196 @@
+package com.tzld.supply.model.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class VideoApiBaseParam {
+
+	//用户登陆相关的参数
+	@ApiModelProperty(value = "公共参数-登录用户ID")
+	private Long loginUid;
+	@ApiModelProperty(value = "公共参数-token值")
+	private String token;
+
+	//APP相关的参数
+	@ApiModelProperty(value = "公共参数-版本号")
+	private Integer versionCode;
+	@ApiModelProperty(value = "公共参数-app发布版本")
+	private String versionName;
+	@ApiModelProperty(value = "公共参数-产品类型:0-VLOG,1-轻趣视频,2-搞笑视频,3-爱电影,4-爱生活,5-长视频,6-短视频,7-惊奇视频,8-PC端,9-票圈长视频APP,10-票圈长视频lite,11-票圈相册,12-H5,13-票圈视频APP,14-小程序极速版,15-闪音卡点APP,16-社区APP")
+	private Integer appType;
+	@ApiModelProperty(value = "公共参数-appid")
+	private String appId;
+
+	//手机设备信息相关的参数
+	@ApiModelProperty(value = "公共参数-手机设备的唯一码")
+	private String machineCode;
+	@ApiModelProperty(value = "公共参数-ios,android")
+	private String platform;
+	@ApiModelProperty(value = "公共参数-精确到ios,android的哪个版本")
+	private String system;
+	@ApiModelProperty(value = "公共参数-手机信息")
+	private String machineInfo;
+	@ApiModelProperty(value = "公共参数-网络类型")
+	private String networkType;
+	@ApiModelProperty(value = "公共参数-客户端ip")
+	private String clientIp;
+
+	//pageSource相关的参数
+	@ApiModelProperty(value = "公共参数-页面来源")
+	private String pageSource;
+	@ApiModelProperty(value = "公共参数-页面分类ID,只在首页分发列表中才有")
+	private Long pageCategoryId;
+	@ApiModelProperty(value = "公共参数-root页面来源")
+	private String rootPageSource;
+	@ApiModelProperty(value = "公共参数-root页面分类ID")
+	private Long rootPageCategoryId;
+	@ApiModelProperty(value = "公共参数-root页面时间戳")
+	private Long rootPageTimestamp;
+
+	//某次操作相关的参数
+	@ApiModelProperty(value = "公共参数-小程序打开类型")
+	private String openType;
+	@ApiModelProperty(value = "公共参数-前端请求时间")
+	private Long clientTimestamp;
+	@ApiModelProperty(value = "公共参数-sessionId")
+	private String sessionId;
+
+	//视频相关的参数
+	@ApiModelProperty(value = "公共参数-视频加载时长,毫秒")
+	private Long videoLoadTime;
+	@ApiModelProperty(value = "公共参数-视频事件发生的时间点,相对于视频时长,秒")
+	private Long videoEventTime;
+	@ApiModelProperty(value = "公共参数-videoPlayError事件,播放器返回的错误信息")
+	private String errorMsg;
+
+	//分享相关的参数
+	@ApiModelProperty(value = "公共参数-分享的深度")
+	private Integer shareDepth;
+	@ApiModelProperty(value = "公共参数-分享者手机设备的唯一码,只有在分享页才有")
+	private String shareMachineCode;
+	@ApiModelProperty(value = "公共参数-分享者uid,只有在分享页才有")
+	private Long shareUid;
+	@ApiModelProperty(value = "公共参数-是否为分享页标识,0:不是分享页,1:是分享页")
+	private Integer sharePageFlag;
+	@ApiModelProperty(value = "公共参数-分享按钮类型")
+	private Integer shareButtonType;
+	@ApiModelProperty(value = "公共参数-从哪个产品分享出来的")
+	private Integer shareAppType;
+
+	@ApiModelProperty(value = "公共参数-0 综合模块 1 feed流 ")
+	private String sharePageType;
+	@ApiModelProperty(value = "公共参数-分享页跳转")
+	private String videoShareJumpModel;
+	//推荐相关的参数
+	@ApiModelProperty(value = "公共参数-推荐来源 0 默认")
+	private Integer recommendSource = 0;
+
+	@ApiModelProperty(value = "公共参数-视频上报数据,使用后端返回的原样数据")
+	private String videoReportMeta;
+
+	@ApiModelProperty(value = "公共参数-事件ID")
+	private String eventId;
+	@ApiModelProperty(value = "公共参数-root事件ID")
+	private String rootEventId;
+
+	@ApiModelProperty(value = "公共参数-root分享页面类型")
+	private String rootSharePageType;
+	@ApiModelProperty(value = "公共参数-自动标志位类型")
+	private String autoType;
+	@ApiModelProperty(value = "公共参数-动作发生的页面位置")
+	private String actionPosition;
+
+	@ApiModelProperty(value = "公共参数-运营消息ID")
+	private String operationMsgId;
+	@ApiModelProperty(value = "公共参数-playId")
+	private String playId;
+	@ApiModelProperty(value = "公共参数-活动id")
+	private String activityId;
+
+	@ApiModelProperty(value = "公共参数-AB信息")
+	private String abInfoData;
+
+	// h5
+	@ApiModelProperty(value = "公共参数-h5分享id")
+	private String h5ShareId;
+	@ApiModelProperty(value = "公共参数-h5打开场景")
+	private String h5OpenFrom;
+	@ApiModelProperty(value = "公共参数-h5分享场景")
+	private String h5ShareFrom;
+	@ApiModelProperty(value = "公共参数-h5页面-小程序分享根源rootPageSource")
+	private String h5WxRootPageSource;
+
+	@ApiModelProperty(value = "公共参数-搜索上报")
+	private String searchActionCode;
+
+	@ApiModelProperty(value = "公共参数-AB的根实验集合")
+	private String rootEventIds;
+
+	@ApiModelProperty(value = "公共参数-returnId")
+	private String returnId;
+	@ApiModelProperty(value = "公共参数-viewId")
+	private String viewId;
+	@ApiModelProperty(value = "公共参数-shareId")
+	private String shareId;
+	@ApiModelProperty(value = "公共参数-subSessionId")
+	private String subSessionId;
+
+	@ApiModelProperty(value = "公共参数-headVideoId")
+	private String headVideoId;
+    @ApiModelProperty(value = "公共参数-推荐链路ID")
+    private String recommendId;
+	@ApiModelProperty(value = "公共参数-推荐日志对象")
+	private String recommendLogVO;
+
+	@ApiModelProperty(value = "公共参数-分享ID")
+	private String jumpHomeVideoId;
+	@ApiModelProperty(value = "公共参数-根分享ID")
+	private String rootJumpHomeVideoId;
+
+	@ApiModelProperty(value = "公共参数-小程序打开场景")
+	private Integer senceType=-1;
+	@ApiModelProperty(value = "公共参数-小程序打开场景 热启动")
+	private Integer hotSenceType;
+	@ApiModelProperty(value = "公共参数-rootMid")
+	private String rootMid;
+	@ApiModelProperty(value = "公共参数-渠道:yybstore xmstore hwstore oppostore vivostore sougou bdstore mzstore store360 douyin kuaishou")
+	private String appChannel;
+	//	@ApiModelProperty(value = "微信AB实验参数 例如:22031801")
+//	private String wechatAbcode;
+	@ApiModelProperty(value = "通过微信实验分流获取到的对应数据")
+    private String abExpInfo; //Map<String, List<AbExpItemDTO>>
+    @ApiModelProperty(value = "H5")
+    private Long adBlockVideoId;
+
+    private Boolean showDistribute;
+
+    private Boolean showShare;
+
+    private Boolean showFocusExp;
+
+    private Boolean isFirstPageOrFirstPageFeed;
+
+	private String newExpGroup;
+
+	private Boolean isTest;
+	/**
+	 * 代表用户来自哪个外部来源,包括:公众号文章、投流等等,
+	 */
+	private String rootSourceId;
+	/**
+	 * 代表一个通过分享卡片进入的用户,他最初来自哪个用户mid的分享
+	 */
+	private String rootShareMid;
+	/**
+	 * 代表一个通过分享卡片进入的用户,他最初来自哪个用户mid的哪次冷启动sessionId的分享
+	 */
+	private String rootSessionId;
+
+	private String rootShareId;
+	/**
+	 * 微信群ID
+	 */
+	private String openGId;
+
+}

+ 25 - 0
core/src/main/java/com/tzld/supply/model/vo/FileInfo.java

@@ -0,0 +1,25 @@
+package com.tzld.supply.model.vo;
+
+import lombok.Data;
+
+/**
+ * @author sunxy
+ */
+@Data
+public class FileInfo {
+
+    /**
+     * 文件名
+     */
+    private String fileName;
+
+    /**
+     * 文件URL
+     */
+    private String fileUrl;
+
+    /**
+     * 文件Size,单位KB
+     */
+    private Double fileSize;
+}

+ 49 - 0
core/src/main/java/com/tzld/supply/model/vo/PolicyDetailVO.java

@@ -0,0 +1,49 @@
+package com.tzld.supply.model.vo;
+
+import java.util.List;
+
+public class PolicyDetailVO {
+	public List<PolicyVO> Statement;
+	public String Version;
+
+	public List<PolicyVO> getStatement() {
+		return Statement;
+	}
+
+	public void setStatement(List<PolicyVO> statement) {
+		Statement = statement;
+	}
+
+	public String getVersion() {
+		return Version;
+	}
+
+	public void setVersion(String version) {
+		Version = version;
+	}
+
+	public static class PolicyVO {
+		public List<String> Action;
+		public String Effect;
+		public List<String> Resource;
+		public List<String> getAction() {
+			return Action;
+		}
+		public void setAction(List<String> action) {
+			Action = action;
+		}
+		public String getEffect() {
+			return Effect;
+		}
+		public void setEffect(String effect) {
+			Effect = effect;
+		}
+		public List<String> getResource() {
+			return Resource;
+		}
+		public void setResource(List<String> resource) {
+			Resource = resource;
+		}
+		
+	}
+}

+ 13 - 0
core/src/main/java/com/tzld/supply/model/vo/SignatureVO.java

@@ -0,0 +1,13 @@
+package com.tzld.supply.model.vo;
+
+import lombok.Data;
+
+@Data
+public class SignatureVO {
+    private String accessId;
+    private String policy;
+    private String signature;
+    private String fileName;
+    private String host;
+    private String expire;
+}

+ 20 - 0
core/src/main/java/com/tzld/supply/model/vo/StsTokenVO.java

@@ -0,0 +1,20 @@
+package com.tzld.supply.model.vo;
+
+import lombok.Data;
+
+@Data
+public class StsTokenVO {
+    private String Expiration;
+    private String AccessKeyId;
+    private String AccessKeySecret;
+    private String SecurityToken;
+    private String RequestId;
+    private String FileName;
+    private String Host;
+    private String[] Hosts;
+    private String Bucket;
+    private String Region;
+    private Boolean Cname;
+    private Long serverTimestamp;
+
+}

+ 1492 - 0
core/src/main/java/com/tzld/supply/util/AliOssFileTool.java

@@ -0,0 +1,1492 @@
+package com.tzld.supply.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.opensearch.sdk.dependencies.org.apache.commons.codec.binary.Base64;
+import com.aliyun.oss.*;
+import com.aliyun.oss.common.utils.BinaryUtil;
+import com.aliyun.oss.model.*;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.exceptions.ServerException;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.http.ProtocolType;
+import com.aliyuncs.mts.model.v20140618.SubmitJobsRequest;
+import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse;
+import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobRequest;
+import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobResponse;
+import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobResponse.MediaInfoJob.Properties;
+import com.aliyuncs.profile.DefaultProfile;
+import com.aliyuncs.profile.IClientProfile;
+import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
+import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
+import com.stuuudy.commons.external.filestorage.alibaba.OSSFileDO;
+import com.stuuudy.commons.external.filestorage.enums.*;
+import com.stuuudy.commons.util.BlankUtil;
+import com.stuuudy.commons.util.CompressImage;
+import com.stuuudy.commons.util.MD5.Md5Util;
+import com.stuuudy.commons.util.exception.CommonsException;
+import com.stuuudy.commons.util.exception.EnumErrorException;
+import com.tzld.supply.common.enums.EnumUploadFileType;
+import com.tzld.supply.config.AliOssConfig;
+import com.tzld.supply.model.vo.SignatureVO;
+import com.tzld.supply.model.vo.StsTokenVO;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.imageio.ImageIO;
+import javax.xml.crypto.dsig.SignatureMethod;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.DigestInputStream;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
+/**
+ * (阿里对象存储工具类)<BR>
+ * AliOssFileTool<BR>
+ * 创建人:陈海 <BR>
+ * 时间:2016年7月18日-下午12:47:52 <BR>
+ *
+ * @version 1.0.0
+ */
+@Component
+public class AliOssFileTool extends AliOssConfig {
+
+    private static Logger logger = Logger.getLogger(AliOssFileTool.class);
+
+    private static final String ENCODE_TYPE = "UTF-8";
+    private static final String ALGORITHM = "HmacSHA1";
+    private static final String HTTP_METHOD = "GET";
+    private static final String SEPARATOR = "&";
+    private static final String EQUAL = "=";
+
+    public static String saveInPublicWithPress(InputStream inputStream, EnumPublicBuckets bucket, String key, EnumFileType type,
+                                               EnumFileSuffix fileSuffix) throws OSSException, ClientException {
+        inputStream = compressImg(inputStream, fileSuffix, type);
+        return saveInPublicNoPress(inputStream, bucket, key, type);
+    }
+
+    public static String saveInPublicReturnHost(InputStream inputStream, EnumPublicBuckets bucket, String fullKey,
+                                                EnumFileType type) {
+        String path = saveInPublic(inputStream, bucket, fullKey, type);
+        // 保存路径
+        return CdnUtil.getCdnUrlHost(type) + path;
+    }
+
+    public static String saveInPublic(InputStream inputStream, EnumPublicBuckets bucket, String fullKey, EnumFileType type) {
+        String bucketName = getBucket(bucket.getBucketName());
+        if (EnumFileType.VOICE.equals(type)) {
+            ObjectMetadata om = new ObjectMetadata();
+            om.setContentType("audio/mpeg");
+            getOssClient().putObject(bucketName, fullKey, inputStream, om);
+        } else if (EnumFileType.PICTURE.equals(type)) {
+            ObjectMetadata om = new ObjectMetadata();
+            om.setContentType("image/jpeg");
+            getOssClient().putObject(bucketName, fullKey, inputStream, om);
+        } else if (EnumFileType.VIDEO.equals(type)) {
+            ObjectMetadata om = new ObjectMetadata();
+            om.setContentType("video/mp4");
+            getOssClient().putObject(bucketName, fullKey, inputStream, om);
+        } else {
+            getOssClient().putObject(bucketName, fullKey, inputStream);
+        }
+        return fullKey;
+    }
+
+    public static String saveInPublic(String bucketName, String ossKey, InputStream inputStream, String contentType) {
+        bucketName = getBucket(bucketName);
+        ObjectMetadata om = new ObjectMetadata();
+        om.setContentType(contentType);
+        getOssClient().putObject(bucketName, ossKey, inputStream, om);
+        return ossKey;
+    }
+
+    public static void saveInPublic(String bucketName, String key, InputStream input) {
+        getOssClient().putObject(bucketName, key, input);
+    }
+
+    public static String moveFile(EnumPublicBuckets sourceBucket, String sourceKey, EnumPublicBuckets targetBucket, String targetKey) {
+        getOssClient().copyObject(getBucket(sourceBucket.getBucketName()), sourceKey,
+                getBucket(targetBucket.getBucketName()), targetKey);
+        if (!StringUtils.equals(sourceKey, targetKey)) {
+            getOssClient().deleteObject(getBucket(sourceBucket.getBucketName()), sourceKey);
+        }
+        return targetKey;
+    }
+
+    public static void deleteFile(EnumPublicBuckets bucket, String key) {
+        getOssClient().deleteObject(getBucket(bucket.getBucketName()), key);
+    }
+
+    public static String saveInPublicNoPress(InputStream inputStream, EnumPublicBuckets bucket, String key,
+                                             EnumFileType type) throws OSSException, ClientException {
+        String fullKey = getProjectName() + "/" + type.getLocation() + key;
+        saveInPublic(inputStream, bucket, fullKey, type);
+        return fullKey;
+    }
+
+    /**
+     * (网络资源上传) 方法名saveURLInPublicNoPress
+     *
+     * @param url        资源地址
+     * @param key
+     * @param type
+     * @param fileSuffix
+     * @return
+     * @throws OSSException
+     * @throws ClientException
+     * @throws IOException     String
+     * @throws @version        1.0
+     * @author 创建人:何振斌
+     * @time 创建日期:2018年3月12日 下午7:10:00
+     */
+    public static String saveURLInPublicNoPress(String url, String bucketName, String key, EnumFileType type,
+                                                EnumFileSuffix fileSuffix) throws OSSException, ClientException, IOException {
+        String fullKey = getProjectName() + "/" + type.getLocation() + key;
+        InputStream inputStream = null;
+        if (!BlankUtil.isBlank(url)) {
+            inputStream = new URL(url).openStream();
+        }
+        if (EnumFileType.VOICE.equals(type)) {
+            ObjectMetadata om = new ObjectMetadata();
+            om.setContentType("audio/mpeg");
+            getOssClient().putObject(bucketName, fullKey, inputStream, om);
+        } else {
+            getOssClient().putObject(bucketName, fullKey, inputStream);
+        }
+        return getProjectName() + "/" + type.getLocation() + key;
+    }
+
+    /**
+     * (根据名称和类型保存文件,返回是否成功)<BR>
+     * 方法名:saveWiteKeyAndType<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年7月18日-下午1:02:10 <BR>
+     *
+     * @param inputStream 文件流
+     * @param bucket      空间名称
+     * @param key         文件保存在服务器上的另存名
+     * @param type        枚举文件类型,声音或图片等
+     * @return boolean<BR>
+     * @throws IOException
+     * @throws ClientException
+     * @throws OSSException
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static boolean saveInPrivate(InputStream inputStream, EnumPrivateBuckets bucket, String key,
+                                        EnumFileType type, EnumFileSuffix suffix) throws OSSException, ClientException, IOException {
+        inputStream = compressImg(inputStream, suffix, type);
+        String bucketName = getBucket(bucket.getBucketName());
+        String fullKey = getProjectName() + "/" + type.getLocation() + key;
+        getOssClient().putObject(bucketName, fullKey, inputStream);
+        return true;
+    }
+
+    /**
+     * (获取前缀为prefix的全部文件)<BR>
+     * 方法名:listFileInFolder<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2017年1月20日-下午4:59:25 <BR>
+     *
+     * @param bucket
+     * @param prefix
+     * @return List<OSSObjectSummary><BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static List<OSSObjectSummary> listFileInFolder(EnumPublicBuckets bucket, String prefix) {
+        final int maxKeys = 200;
+        String nextMarker = null;
+        ObjectListing objectListing;
+        List<OSSObjectSummary> sums = new ArrayList<OSSObjectSummary>();
+        // 递归列出fun目录下的所有文件
+        do {
+            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(getBucket(bucket.getBucketName()));
+            listObjectsRequest.setPrefix(prefix);
+            listObjectsRequest.withMarker(nextMarker).withMaxKeys(maxKeys);
+            objectListing = getOssClient().listObjects(listObjectsRequest);
+            List<OSSObjectSummary> temp = objectListing.getObjectSummaries();
+            if (temp != null) {
+                sums.addAll(temp);
+            }
+            nextMarker = objectListing.getNextMarker();
+        } while (objectListing.isTruncated());
+        return sums;
+    }
+
+    /**
+     * (判断是否存在文件)<BR>
+     * 方法名:isExist<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年11月21日-下午3:54:36 <BR>
+     *
+     * @param bucket
+     * @param key
+     * @param type
+     * @return boolean<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static boolean isExist(EnumPrivateBuckets bucket, String key, EnumFileType type) {
+        String fullKey = getProjectName() + "/" + type.getLocation() + key;
+        return getOssClient().doesObjectExist(getBucket(bucket.getBucketName()), fullKey);
+    }
+
+    public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
+    public static final String STS_API_VERSION = "2015-04-01";
+
+    public static AssumeRoleResponse getTempUserToken(long durationSeconds, Integer uid)
+            throws com.aliyuncs.exceptions.ClientException {
+
+        // 只有 RAM用户(子账号)才能调用 AssumeRole 接口
+        // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
+        // 请首先在RAM控制台创建一个RAM用户,并为这个用户创建AccessKeys
+        String accessKeyId = "LTAIQLkVvDFXRO7j";
+        String accessKeySecret = "aOnxO0xyoa0lDmTxTI1cNmVLNotF15";
+
+        // RoleArn 需要在 RAM 控制台上获取
+        String roleArn = "acs:ram::1894469520484605:role/aliyunosstokengeneratorrole";
+        String policy = JSONObject.toJSONString(AliOssFileTool.getPolicyDetail());
+        // RoleSessionName 是临时Token的会话名称,自己指定用于标识你的用户,主要用于审计,或者用于区分Token颁发给谁
+        // 但是注意RoleSessionName的长度和规则,不要有空格,只能有'-' '_' 字母和数字等字符
+        // 具体规则请参考API文档中的格式要求
+        String roleSessionName = "uid_" + uid;
+
+        // 此处必须为 HTTPS
+        ProtocolType protocolType = ProtocolType.HTTPS;
+
+        try {
+            final AssumeRoleResponse stsResponse = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName,
+                    policy, protocolType, durationSeconds);
+            return stsResponse;
+            /*
+             * Map<String, String> respMap = new LinkedHashMap<String, String>();
+             * respMap.put("status", "200"); respMap.put("AccessKeyId",
+             * stsResponse.getCredentials().getAccessKeyId());
+             * respMap.put("AccessKeySecret",
+             * stsResponse.getCredentials().getAccessKeySecret());
+             * respMap.put("SecurityToken",
+             * stsResponse.getCredentials().getSecurityToken()); respMap.put("Expiration",
+             * stsResponse.getCredentials().getExpiration());
+             */
+
+        } catch (ClientException e) {
+            throw e;
+        }
+
+    }
+
+    protected static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn,
+                                                   String roleSessionName, String policy, ProtocolType protocolType, long durationSeconds)
+            throws com.aliyuncs.exceptions.ClientException {
+        try {
+            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
+            IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
+            DefaultAcsClient client = new DefaultAcsClient(profile);
+
+            // 创建一个 AssumeRoleRequest 并设置请求参数
+            final AssumeRoleRequest request = new AssumeRoleRequest();
+            request.setVersion(STS_API_VERSION);
+            request.setMethod(MethodType.POST);
+            request.setProtocol(protocolType);
+
+            request.setRoleArn(roleArn);
+            request.setRoleSessionName(roleSessionName);
+            request.setPolicy(policy);
+            request.setDurationSeconds(durationSeconds);
+
+            // 发起请求,并得到response
+            final AssumeRoleResponse response = client.getAcsResponse(request);
+
+            return response;
+        } catch (com.aliyuncs.exceptions.ClientException e) {
+            throw e;
+        }
+    }
+
+    /**
+     * (判断是否存在文件)<BR>
+     * 方法名:isExist<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年11月21日-下午3:54:36 <BR>
+     *
+     * @param bucket
+     * @param key
+     * @param type
+     * @return boolean<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    @Deprecated
+    public boolean isExist(EnumPublicBuckets bucket, String key, EnumFileType type) {
+        String fullKey = getProjectName() + "/" + type.getLocation() + key;
+        return getOssClient().doesObjectExist(getBucket(bucket.getBucketName()), fullKey);
+    }
+
+    /**
+     * (用bucket名称和完整key 判断文件是否存在)<BR>
+     * 方法名:isExist<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2017年5月12日-下午6:38:49 <BR>
+     *
+     * @param bucket
+     * @param fullKey
+     * @return boolean<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static boolean isExist(String bucket, String fullKey) {
+        return getOssClient().doesObjectExist(bucket, fullKey);
+    }
+
+    /**
+     * 文件是否存在 内网
+     *
+     * @param bucket
+     * @param fullKey
+     * @return
+     */
+    public static boolean isExistOfInternal(String bucket, String fullKey) {
+        return getInternalOssClient().doesObjectExist(bucket, fullKey);
+    }
+
+    /**
+     * (删除oss文件)<BR>
+     * 方法名:delFile<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年7月20日-上午10:44:52 <BR>
+     *
+     * @param bucket 存储空间名称
+     * @param key    文件保存在服务器上的另存名
+     * @param type   枚举文件类型,声音或图片等
+     * @return boolean<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static boolean delFile(EnumAllBuckets bucket, String key, EnumFileType type) {
+        getOssClient().deleteObject(getBucket(bucket.getBucketName()),
+                getProjectName() + "/" + type.getLocation() + key);
+        return true;
+    }
+
+    public static boolean deleteObject(String bucketName, String objectKey) {
+        getInternalOssClient().deleteObject(bucketName, objectKey);
+        return true;
+    }
+
+    public static boolean deleteObjects(String bucketName, List<String> objectKeys) {
+        if (objectKeys == null || objectKeys.size() == 0) {
+            return false;
+        }
+        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);
+        deleteObjectsRequest.setKeys(objectKeys);
+        deleteObjectsRequest.setQuiet(true);
+        getInternalOssClient().deleteObjects(deleteObjectsRequest);
+        return true;
+    }
+
+    /**
+     * (获取经处理的图片签名url)<BR>
+     * 方法名:getPicUrlWithSign<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年7月18日-下午1:07:23 <BR>
+     *
+     * @param bucket 空间名称
+     * @param key    文件保存在服务器上的名称
+     * @param type   枚举文件类型,声音或图片等
+     * @return String<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static String getPicUrl(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) {
+        if (expiresSec == null) {
+            expiresSec = getExpiration();
+        }
+        Date expires = new Date(new Date().getTime() + getExpiration() * 1000);
+        String picUrl = getPriClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
+                getProjectName() + "/" + type.getLocation() + key, expires).toString();
+        return picUrl;
+    }
+
+    /**
+     * (获取文件对象的签名url)<BR>
+     * 方法名:getUrlWithSign<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年7月18日-下午1:05:50 <BR>
+     *
+     * @param bucket 空间名称
+     * @param key    文件保存在服务器上的名称
+     * @param type   枚举文件类型,声音或图片等
+     * @return String<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static String getUrl(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) {
+        if (expiresSec == null) {
+            expiresSec = getExpiration();
+        }
+        Date expires = new Date(new Date().getTime() + expiresSec * 1000);
+        String url = "";
+        if (type.equals(EnumFileType.VIDEO)) {
+            url = getVideoClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
+                    getProjectName() + "/" + type.getLocation() + key, expires).toString();
+        } else {
+            url = getPriClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
+                    getProjectName() + "/" + type.getLocation() + key, expires).toString();
+        }
+        return url;
+    }
+
+    public static String getUrlWithOssEndPoint(EnumPrivateBuckets bucket, String key, EnumFileType type,
+                                               Long expiresSec) {
+        if (expiresSec == null) {
+            expiresSec = getExpiration();
+        }
+        Date expires = new Date(new Date().getTime() + expiresSec * 1000);
+        return getOssClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
+                getProjectName() + "/" + type.getLocation() + key, expires).toString();
+    }
+
+    /**
+     * (获取object)<BR>
+     * 方法名:getObject<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年12月28日-上午10:55:43 <BR>
+     *
+     * @param bucket
+     * @param key
+     * @param type
+     * @return OSSObject<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static OSSObject getObject(EnumPrivateBuckets bucket, String key, EnumFileType type) {
+        OSSObject ossObject = getOssClient().getObject(getBucket(bucket.getBucketName()),
+                getProjectName() + "/" + type.getLocation() + key);
+        return ossObject;
+    }
+
+    public static OSSObject getPubObject(EnumAllBuckets bucket, String key, EnumFileType type) {
+        OSSObject ossObject = getOssClient().getObject(getBucket(bucket.getBucketName()),
+                getProjectName() + "/" + type.getLocation() + key);
+        return ossObject;
+    }
+
+    public static OSSObject getPubObject(String bucketName, String fullKey) {
+        OSSObject ossObject = getOssClient().getObject(bucketName, fullKey);
+        return ossObject;
+    }
+
+    public static OSSObject getInternalPubObject(String bucketName, String fullKey) {
+        OSSObject ossObject = getInternalOssClient().getObject(bucketName, fullKey);
+        return ossObject;
+    }
+
+    public static ObjectMetadata getPubObjectMedeta(EnumAllBuckets bucket, String key, EnumFileType type) {
+        ObjectMetadata ossObjectMeta = getOssClient().getObjectMetadata(getBucket(bucket.getBucketName()),
+                getProjectName() + "/" + type.getLocation() + key);
+        return ossObjectMeta;
+    }
+
+    public static String calcFileMD5(String bucketName, String objectKey) {
+        try {
+            OSSObject ossObj = getOssClient().getObject(bucketName, objectKey);
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            try (DigestInputStream digestInputStream = new DigestInputStream(ossObj.getObjectContent(), md)) {
+                // 读取数据流并更新 MD5
+                byte[] buffer = new byte[8192];
+                while (digestInputStream.read(buffer) != -1) {
+                    // DigestInputStream 会自动更新 MessageDigest
+                }
+            } catch (Exception e) {
+                logger.info("读取oss文件异常: ", e);
+                return "";
+            }
+
+            // 获取最终的 MD5 值
+            byte[] md5Bytes = md.digest();
+            // 转换为十六进制字符串
+            StringBuilder sb = new StringBuilder();
+            for (byte b : md5Bytes) {
+                sb.append(String.format("%02x", b));
+            }
+
+            String md5 = sb.toString();
+            logger.info(String.format("buketName: %s, objectKey: %s, MD5: %s", bucketName, objectKey, md5));
+
+            return md5;
+        } catch (Exception e) {
+            logger.error("计算文件MD5异常: ", e);
+        }
+        return "";
+    }
+
+    /**
+     * (重命名文件,实现是先拷贝文件,再删掉旧的文件)<BR>
+     * 方法名:renameFile<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2016年8月1日-下午4:03:09 <BR>
+     *
+     * @param srcBucket
+     * @param srckey
+     * @param destkey
+     * @return boolean<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    @Deprecated
+    public boolean renameFile(EnumAllBuckets srcBucket, String srckey, String destkey, EnumFileType srcType,
+                              EnumFileType destType) {
+
+        // 拷贝Object
+        getOssClient().copyObject(getBucket(srcBucket.getBucketName()),
+                getProjectName() + "/" + srcType.getLocation() + srckey, getBucket(srcBucket.getBucketName()),
+                getProjectName() + "/" + destType.getLocation() + destkey);
+        delFile(srcBucket, srckey, srcType);
+        return true;
+    }
+
+    /**
+     * (将oss srckey 命名为 destkey)<BR>
+     * 方法名:renameFileWithFullKey<BR>
+     * 创建人:陈海 <BR>
+     * 时间:2017年9月16日-下午5:24:39 <BR>
+     *
+     * @param srcBucket
+     * @param srckey
+     * @param destkey
+     * @return boolean<BR>
+     * @throws <BR>
+     * @since 1.0.0
+     */
+    public static boolean renameFileWithFullKey(EnumAllBuckets srcBucket, String srckey, String destkey) {
+
+        // 拷贝Object
+        getOssClient().copyObject(getBucket(srcBucket.getBucketName()), srckey, getBucket(srcBucket.getBucketName()),
+                destkey);
+        getOssClient().deleteObject(getBucket(srcBucket.getBucketName()), srckey);
+        return true;
+    }
+
+    public static boolean renameFileWithFullKeyFromInternal(EnumAllBuckets srcBucket, String srckey, String destkey, long size) {
+        // 拷贝Object
+        if (size < 1024 * 1024 * 1024) {
+            getInternalOssClient().copyObject(getBucket(srcBucket.getBucketName()), srckey,
+                    getBucket(srcBucket.getBucketName()), destkey);
+        } else {
+            multipartCopyObjectFromInternal(getBucket(srcBucket.getBucketName()), srckey,
+                    getBucket(srcBucket.getBucketName()), destkey);
+        }
+        getInternalOssClient().deleteObject(getBucket(srcBucket.getBucketName()), srckey);
+        return true;
+    }
+
+    // 分片拷贝object,大于1G的文件需要分片拷贝
+    public static void multipartCopyObjectFromInternal(String sourceBucketName, String sourceObjectName,
+                                                       String destinationBucketName, String destinationObjectName) {
+        OSSClient ossClient = getInternalOssClient();
+        ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName);
+        // 获取被拷贝文件的大小。
+        long contentLength = objectMetadata.getContentLength();
+
+        // 设置分片大小为10MB。
+        long partSize = 1024 * 1024 * 10;
+
+        // 计算分片总数。
+        int partCount = (int) (contentLength / partSize);
+        if (contentLength % partSize != 0) {
+            partCount++;
+        }
+        logger.info("oss 分片拷贝开始,sourceObjectName:" + sourceObjectName + ",size:" + contentLength + ",partCount:" + partCount);
+        // 初始化拷贝任务。可以通过InitiateMultipartUploadRequest指定目标文件元信息。
+        InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(
+                destinationBucketName, destinationObjectName);
+        InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient
+                .initiateMultipartUpload(initiateMultipartUploadRequest);
+        String uploadId = initiateMultipartUploadResult.getUploadId();
+
+        // 分片拷贝。
+        List<PartETag> partETags = new ArrayList<PartETag>();
+        for (int i = 0; i < partCount; i++) {
+            // 计算每个分片的大小。
+            long skipBytes = partSize * i;
+            long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;
+
+            // 创建UploadPartCopyRequest。可以通过UploadPartCopyRequest指定限定条件。
+            UploadPartCopyRequest uploadPartCopyRequest = new UploadPartCopyRequest(sourceBucketName, sourceObjectName,
+                    destinationBucketName, destinationObjectName);
+            uploadPartCopyRequest.setUploadId(uploadId);
+            uploadPartCopyRequest.setPartSize(size);
+            uploadPartCopyRequest.setBeginIndex(skipBytes);
+            uploadPartCopyRequest.setPartNumber(i + 1);
+            UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
+
+            // 将返回的分片ETag保存到partETags中。
+            partETags.add(uploadPartCopyResult.getPartETag());
+        }
+
+        // 提交分片拷贝任务。
+        CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
+                destinationBucketName, destinationObjectName, uploadId, partETags);
+        ossClient.completeMultipartUpload(completeMultipartUploadRequest);
+        logger.info("oss 分片拷贝结束,sourceObjectName:" + sourceObjectName + ",size:" + contentLength + ",partCount:" + partCount);
+    }
+
+    public static void copyObject(String srcBucketName, String srcObjectKey,
+                                  String destBucketName, String destObjectKey) {
+        getOssClient().copyObject(srcBucketName, srcObjectKey, destBucketName, destObjectKey);
+    }
+
+    public static void copyObjectFromInternal(String srcBucketName, String srcObjectKey,
+                                              String destBucketName, String destObjectKey) {
+        getInternalOssClient().copyObject(srcBucketName, srcObjectKey, destBucketName, destObjectKey);
+    }
+
+    private static InputStream compressImg(InputStream stream, EnumFileSuffix suffix, EnumFileType fileType) {
+        if (!getNeedPress()) {
+            return stream;
+        }
+        if (suffix == EnumFileSuffix.JPG || suffix == EnumFileSuffix.PNG || suffix == EnumFileSuffix.JPEG
+                || suffix == EnumFileSuffix.BMP) {
+            try {
+                byte[] file = CompressImage.compress(stream, 1080);
+                if (file != null) {
+                    stream = new ByteArrayInputStream(file);
+                } else {
+                    logger.warn("图片上传有误");
+                    return null;
+                }
+            } catch (Exception e) {
+                logger.error("图片压缩失败", e);
+                if (null != stream) {
+                    try {
+                        stream.close();
+                    } catch (IOException e1) {
+                    }
+                }
+                throw new CommonsException(EnumErrorException.PIC_FORMAT_ERROR);
+            }
+        }
+        return stream;
+    }
+
+    public static String submitPubTranscodeJob(EnumPublicBuckets inputBucket, EnumAllBuckets outputBucket,
+                                               String fullKey, String outPutKey, String templateId) {
+        OSSFileDO inputFile = new OSSFileDO(OSS_REGION, getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName()),
+                fullKey);
+        JSONArray outputs = new JSONArray();
+        JSONObject outPutConfig = new JSONObject();
+        outPutConfig.put("OutputObject", outPutKey);
+        outPutConfig.put("TemplateId", templateId);
+        outputs.add(outPutConfig);
+        SubmitJobsRequest request = new SubmitJobsRequest();
+        request.setInput(inputFile.toJsonString());
+        request.setOutputs(outputs.toJSONString());
+        request.setPipelineId(PIPELINEID);
+        request.setOutputBucket(getBucket(outputBucket.getBucketName()));
+        request.setOutputLocation(OSS_REGION);
+        Integer outputJobCount = 1;
+
+        SubmitJobsResponse response = null;
+        try {
+            response = getDefaultAcsClient().getAcsResponse(request);
+            if (response.getJobResultList().size() != outputJobCount) {
+                throw new RuntimeException("SubmitJobsRequest Size failed");
+            }
+            return response.getJobResultList().get(0).getJob().getJobId();
+        } catch (ServerException e) {
+            logger.error("submitTranscodeJob Server failed", e);
+            throw new CommonsException(EnumErrorException.TRANS_CODE_SERVER_ERROR);
+        } catch (com.aliyuncs.exceptions.ClientException e) {
+            logger.error("submitTranscodeJob Client failed", e);
+            throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR);
+        }
+    }
+
+    public static String getPubPicAverageColor(EnumAllBuckets bucket, String key) {
+        String style = "image/average-hue";
+        try {
+            GetObjectRequest request = new GetObjectRequest(getBucket(bucket.getBucketName()), key);
+            request.setProcess(style);
+            OSSObject obj = getOssClient().getObject(request);
+            if (obj != null) {
+                String a = IOUtils.toString(obj.getObjectContent());
+                JSONObject jo = (JSONObject) JSONObject.parse(a);
+                String rgb = jo.getString("RGB");
+                if (rgb != null) {
+                    rgb = rgb.replace("0x", "#");
+                }
+                return rgb;
+            }
+        } catch (Exception e) {
+            throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR);
+        }
+        return null;
+    }
+
+    public static Properties getPubObjMediaInfoData(String bucketName, String fullKey) {
+        DefaultAcsClient client = getDefaultAcsClient();
+        SubmitMediaInfoJobRequest request = new SubmitMediaInfoJobRequest();
+        request.setReadTimeout(Integer.MAX_VALUE);
+        SubmitMediaInfoJobResponse response = new SubmitMediaInfoJobResponse();
+        JSONObject json = new JSONObject();
+        json.put("Location", "oss-cn-hangzhou");
+        json.put("Bucket", bucketName);
+        json.put("Object", fullKey);
+        request.setInput(json.toJSONString());
+        try {
+            response = client.getAcsResponse(request);
+            // String width = response.getMediaInfoJob().getProperties().getWidth();
+            // String height = response.getMediaInfoJob().getProperties().getHeight();
+            return response.getMediaInfoJob().getProperties();
+
+        } catch (Exception e) {
+            throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR, e);
+        }
+    }
+
+    public static SignatureVO getUploadPolicy(Integer fileType) throws Exception {
+        // 后台随机生成唯一文件名
+        String env = PropertiesUtils.getProjectEnv();
+        if (StringUtils.isEmpty(env)) {
+            env = "qa";
+        }
+        String fileName = RandomUtil.generate18String();
+        String contentType = "";
+        if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) {
+            fileName = "/video/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
+        } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) {
+            fileName = "/voice/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
+        } else {
+            fileName = "/pic/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
+        }
+        long expireTime = 60 * 60 * 4;
+        long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
+        Date expiration = new Date(expireEndTime);
+        PolicyConditions policyConds = new PolicyConditions();
+        //4.95G  上限是5个G
+        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 5261334938l);
+        policyConds.addConditionItem(MatchMode.Exact, PolicyConditions.COND_KEY,
+                AliOssConfig.getProjectName() + fileName);
+        if (!StringUtils.isEmpty(contentType)) {
+            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_TYPE, contentType);
+        }
+
+        String postPolicy = AliOssConfig.getOssClient().generatePostPolicy(expiration, policyConds);
+        byte[] binaryData = postPolicy.getBytes("utf-8");
+        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
+        String postSignature = AliOssConfig.getOssClient().calculatePostSignature(postPolicy);
+        SignatureVO signatureVO = new SignatureVO();
+        signatureVO.setAccessId(AliOssConfig.getAccessKeyId());
+        signatureVO.setPolicy(encodedPolicy);
+        signatureVO.setSignature(postSignature);
+        signatureVO.setFileName(AliOssConfig.getProjectName() + fileName);
+        signatureVO.setHost(AliOssConfig.getUploadDomain());
+        signatureVO.setExpire(String.valueOf(expireEndTime / 1000));
+        return signatureVO;
+    }
+
+    public static String getSignaturedUrl(String fileName, Boolean isPrivate) {
+
+        if (StringUtils.isBlank(fileName)) {
+            return fileName;
+        }
+        if (StringUtils.startsWith(fileName, "https")) {
+            return fileName;
+        }
+        String host = AliOssConfig.getVideoDomain();
+        fileName = host + fileName;
+        return fileName;
+    }
+
+    public static String getSignaturedInternalUrl(String fileName, Boolean isPrivate) throws Exception {
+        if (StringUtils.isBlank(fileName)) {
+            return fileName;
+        }
+        if (StringUtils.startsWith(fileName, "https")) {
+            return fileName;
+        }
+        String bucket = getBucket(isPrivate);
+        String host = "http://" + bucket + "." + AliOssConfig.getInternalEndPoint();
+        fileName = host + "/" + fileName;
+        return fileName;
+    }
+
+    public static String saveVideoCoverImagFromInternal(File file, Integer fileType, Boolean isPrivate, Long videoId)
+            throws Exception {
+        Date begin = new Date();
+        logger.info(String.format("开始往阿里云OSS上传封面图片,当前时间为:%s", begin.getTime()));
+        String bucketName = getBucket(isPrivate);
+
+        String fullKey = getVideoCoverImagPath(fileType, isPrivate, videoId.toString(), null);
+        AliOssConfig.getInternalOssClient().putObject(bucketName, fullKey, file);
+        Date end = new Date();
+        logger.info(String.format("阿里云OSS上传封面图片完成,总耗时为 %s 毫秒。图片地址为:%s, 正在执行下一步。。", end.getTime() - begin.getTime(),
+                fullKey));
+        return fullKey;
+    }
+
+    public static String saveVideoCoverImagFromInternal(InputStream input, Integer fileType, Boolean isPrivate,
+                                                        String filePrex, String dic) throws Exception {
+        Date begin = new Date();
+        logger.info(String.format("开始往阿里云OSS上传图片,当前时间为:%s", begin.getTime()));
+        String bucketName = getBucket(isPrivate);
+
+        String fullKey = getVideoCoverImagPath(fileType, isPrivate, filePrex, dic);
+        // AliOssConfig.getOssClient().putObject(bucketName, fullKey, file);
+        AliOssConfig.getInternalOssClient().putObject(bucketName, fullKey, input);
+        Date end = new Date();
+        logger.info(
+                String.format("阿里云OSS上传图片完成,总耗时为 %s 毫秒。图片地址为:%s, 正在执行下一步。。", end.getTime() - begin.getTime(), fullKey));
+        return fullKey;
+    }
+
+    public static String getVideoCoverImagPath(Integer fileType, Boolean isPrivate, String filePrex, String dic)
+            throws Exception {
+        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + Calendar.getInstance().getTimeInMillis()
+                + "_" + filePrex;
+        if (StringUtils.isNotBlank(dic)) {
+            fileName = (dic + "/" + fileName);
+        }
+        if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) {
+            fileName = "/video/" + fileName;
+        } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) {
+            fileName = "/voice/" + fileName;
+        } else {
+            fileName = "/pic/" + fileName;
+        }
+        String fullKey = AliOssConfig.getProjectName() + fileName;
+        return fullKey;
+    }
+
+    public static String getBucket(boolean isPrivate) {
+        if (isPrivate) {
+            return AliOssFileTool.getBucket(EnumAllBuckets.PRIVIDEOBUCKET.getBucketName());
+        } else {
+            return AliOssFileTool.getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName());
+        }
+    }
+
+    public static ObjectMetadata getObjectMetadata(String fileName) throws Exception {
+
+        // Endpoint以杭州为例,其它Region请按实际情况填写。
+        // 创建OSSClient实例。
+        OSSClient ossClient = new OSSClient(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(),
+                AliOssConfig.getAccessKeySecret());
+        // // 获取文件的部分元信息。
+        // SimplifiedObjectMeta objectMeta = ossClient.getSimplifiedObjectMeta(
+        // getBucket(false), fileName);
+        // logger.info( "SimplifiedObjectMeta==="+ JSON.toJSONString(objectMeta));
+        // 获取文件的全部元信息。
+        ObjectMetadata metadata = ossClient.getObjectMetadata(getBucket(false), fileName);
+        // logger.info( "metadata==="+ JSON.toJSONString(metadata));
+        return metadata;
+    }
+
+    /**
+     * 获取部分元信息
+     *
+     * @param bucketName
+     * @param fileName
+     * @return
+     * @throws Exception
+     */
+    public static SimplifiedObjectMeta getSimpleObjectMetadata(String bucketName, String fileName) throws Exception {
+        OSS ossClient = new OSSClientBuilder().build(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(),
+                AliOssConfig.getAccessKeySecret());
+        SimplifiedObjectMeta metadata = ossClient.getSimplifiedObjectMeta(bucketName, fileName);
+        ossClient.shutdown();
+        return metadata;
+    }
+
+    /**
+     * 获取全部元信息
+     *
+     * @param bucketName
+     * @param fileName
+     * @return
+     * @throws Exception
+     */
+    public static ObjectMetadata getObjectMetadata(String bucketName, String fileName) throws Exception {
+//		OSS ossClient = new OSSClientBuilder().build(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(),
+//				AliOssConfig.getAccessKeySecret());
+//		// 获取文件的全部元信息
+//		ObjectMetadata metadata = ossClient.getObjectMetadata(bucketName, fileName);
+//		ossClient.shutdown();
+//		return metadata;
+        ObjectMetadata metadata = getInternalOssClient().getObjectMetadata(bucketName, fileName);
+        return metadata;
+    }
+
+//    public static void main(String[] args) throws Exception {
+////		String a = JSONObject.toJSONString(AliOssFileTool.getDefaultAcsClient());
+////		System.out.println(a);
+//    }
+
+    public static Map<String, String> buildCommonParameters() {
+        Map<String, String> parameterMap = new HashMap<>();
+        // 请求公共参数
+        parameterMap.put("Version", "2014-06-18");
+        parameterMap.put("AccessKeyId", AliOssConfig.getAccessKeyId()); // 此处请替换成您自己的AccessKeyId
+        // parameterMap.put("Timestamp",
+        // "2018-07-27T13:03:45Z");//此处将时间戳固定只是测试需要,这样此示例中生成的签名值就不会变,方便您对比验证,可变时间戳的生成需要用下边这句替换
+        parameterMap.put("Timestamp", DateUtils.formatIso8601Date(new Date()));
+        parameterMap.put("SignatureMethod", "HMAC-SHA1");
+        parameterMap.put("SignatureVersion", "1.0");
+        // parameterMap.put("SignatureNonce", "4902260a-516a-4b6a-a455-45b653cf6150");
+        // //此处将唯一随机数固定只是测试需要,这样此示例中生成的签名值就不会变,方便您对比验证,可变唯一随机数的生成需要用下边这句替换
+        parameterMap.put("SignatureNonce", UUID.randomUUID().toString());
+        parameterMap.put("Format", "JSON"); // 另外支持JSON格式
+        return parameterMap;
+    }
+
+    /**
+     * @Title: sendAsyncSnapshotJob @Description: 获取发送视频批量截图的任务的URL,此接口为异步任务 @param
+     * fileName 要截图的视频的路径,如 longvideo/video/XXXXX,其中XXXXX为视频名称 @param
+     * snapshotPath 截图后的图片输出路径,如
+     * longvideo/snapshot/XXXXX,截图时会自动在文件名后面加序号,输出路径为空时,自动指定为longvideo/snapshot/XXXXX @param
+     * startMillseconds 截图时间,单位毫秒 @param interval
+     * 截图间隔时间,若指定则表示异步模式序列截图,Interval必须大于等于0,默认10,单位秒。其中Interval=0表示根据视频时长平均截图。 @param
+     * snapshotNumber
+     * 截图数量,若指定则表示异步模式序列截图,且必须大于0,当Time+Interval*Num的截取点超过视频时长时,后续截图自动失效,截图完成时返回实际截取的个数;当Num=1,忽略Interval参数,表示异步单张截图 @return @throws
+     * Exception @author 王树杞 @date 2018年7月27日 下午5:17:31 @version 2.0 @throws
+     */
+    public static String sendAsyncSnapshotJob(String fileName, String snapshotPath, Integer startMillseconds,
+                                              Integer interval, Integer snapshotNumber) throws Exception {
+
+        // 首先获取公众参数
+        Map<String, String> parameterMap = buildCommonParameters();
+        parameterMap.put("Action", "SubmitSnapshotJob");
+
+        Map<String, String> inputParamsMap = new HashMap<>();
+        inputParamsMap.put("Bucket", AliOssFileTool.getBucket(false));
+        inputParamsMap.put("Location", AliOssFileTool.getSnapshotLocation());
+        inputParamsMap.put("Object", URLEncoder.encode(fileName, "UTF-8"));
+        parameterMap.put("Input", JSON.toJSONString(inputParamsMap));
+        Map<String, String> snapshotConfig = new HashMap<>();
+        Map<String, String> outPutFile = new HashMap<>();
+        outPutFile.put("Bucket", AliOssFileTool.getBucket(false));
+        outPutFile.put("Location", AliOssFileTool.getSnapshotLocation());
+        if (StringUtils.isBlank(snapshotPath)) {
+            snapshotPath = fileName.replace("/video/", "/snapshot/");
+        }
+        outPutFile.put("Object", URLEncoder.encode(snapshotPath + "_{Count}", "UTF-8"));
+        snapshotConfig.put("Interval", interval.toString());
+        snapshotConfig.put("Num", snapshotNumber.toString());
+        parameterMap.put("PipelineId", "abe6a0b9b9334858913eb416974485d2");
+
+        snapshotConfig.put("OutputFile", JSON.toJSONString(outPutFile));
+        parameterMap.put("SnapshotConfig", JSON.toJSONString(snapshotConfig));
+
+        String canonicalizedQueryString = buildCanonicalizedQueryString(parameterMap);
+        String stringToSign = buildStringToSign(canonicalizedQueryString);
+        String signature = buildSignature(AliOssConfig.getAccessKeySecret(), stringToSign);
+
+        return buildRequestURL(signature, parameterMap);
+
+    }
+
+    /**
+     * @Title: sendSyncSnapshotJob @Description: 获取发送某个视频的同步截图的任务URL地址 @param
+     * fileName 视频路径 @param snapshotPath 输出的截图路径 @param startMillseconds
+     * 截图的时间戳 @return 某个视频的同步截图的任务URL地址 @throws Exception @author 王树杞 @date
+     * 2018年7月27日 下午8:07:47 @version 2.0 @throws
+     */
+    public static String sendSyncSnapshotJob(String fileName, String snapshotPath, Integer startMillseconds)
+            throws Exception {
+
+        // 首先获取公众参数
+        Map<String, String> parameterMap = buildCommonParameters();
+        parameterMap.put("Action", "SubmitSnapshotJob");
+
+        Map<String, String> inputParamsMap = new HashMap<>();
+        inputParamsMap.put("Bucket", AliOssFileTool.getBucket(false));
+        inputParamsMap.put("Location", AliOssFileTool.getSnapshotLocation());
+        inputParamsMap.put("Object", URLEncoder.encode(fileName, "UTF-8"));
+        parameterMap.put("Input", JSON.toJSONString(inputParamsMap));
+        Map<String, String> snapshotConfig = new HashMap<>();
+        Map<String, String> outPutFile = new HashMap<>();
+        outPutFile.put("Bucket", AliOssFileTool.getBucket(false));
+        outPutFile.put("Location", AliOssFileTool.getSnapshotLocation());
+        if (StringUtils.isBlank(snapshotPath)) {
+            snapshotPath = fileName.replace("/video/", "/snapshot/");
+        }
+        outPutFile.put("Object", URLEncoder.encode(snapshotPath, "UTF-8"));
+        snapshotConfig.put("Time", startMillseconds.toString());
+        snapshotConfig.put("OutputFile", JSON.toJSONString(outPutFile));
+        parameterMap.put("SnapshotConfig", JSON.toJSONString(snapshotConfig));
+
+        String canonicalizedQueryString = buildCanonicalizedQueryString(parameterMap);
+        String stringToSign = buildStringToSign(canonicalizedQueryString);
+        String signature = buildSignature(AliOssConfig.getAccessKeySecret(), stringToSign);
+
+        return buildRequestURL(signature, parameterMap);
+
+    }
+
+    private static String percentEncode(String value) throws UnsupportedEncodingException {
+        return URLEncoder.encode(value, ENCODE_TYPE).replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
+    }
+
+    private static String buildCanonicalizedQueryString(Map<String, String> parameterMap)
+            throws UnsupportedEncodingException {
+        // 对参数进行排序
+        List<String> sortedKeys = new ArrayList<String>(parameterMap.keySet());
+        Collections.sort(sortedKeys);
+        StringBuilder temp = new StringBuilder();
+        for (String key : sortedKeys) {
+            // 此处需要对key和value进行编码
+            String value = parameterMap.get(key);
+            temp.append(SEPARATOR).append(percentEncode(key)).append(EQUAL).append(percentEncode(value));
+        }
+        return temp.toString().substring(1);
+    }
+
+    private static String buildStringToSign(String canonicalizedQueryString) throws UnsupportedEncodingException {
+        // 生成stringToSign字符
+        StringBuilder temp = new StringBuilder();
+        temp.append(HTTP_METHOD).append(SEPARATOR);
+        temp.append(percentEncode("/")).append(SEPARATOR);
+        // 此处需要对canonicalizedQueryString进行编码
+        temp.append(percentEncode(canonicalizedQueryString));
+        return temp.toString();
+    }
+
+    private static String buildSignature(String keySecret, String stringToSign)
+            throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
+        SecretKey key = new SecretKeySpec((keySecret + SEPARATOR).getBytes(ENCODE_TYPE), SignatureMethod.HMAC_SHA1);
+        Mac mac = Mac.getInstance(ALGORITHM);
+        mac.init(key);
+        byte[] hashBytes = mac.doFinal(stringToSign.toString().getBytes(ENCODE_TYPE));
+        byte[] base64Bytes = new Base64().encode(hashBytes);
+        String base64UTF8String = new String(base64Bytes, "utf-8");
+        return URLEncoder.encode(base64UTF8String, ENCODE_TYPE);
+    }
+
+    private static String buildRequestURL(String signature, Map<String, String> parameterMap)
+            throws UnsupportedEncodingException {
+        // 生成请求URL
+        StringBuilder temp = new StringBuilder("http://mts.cn-hangzhou.aliyuncs.com?");
+        temp.append(URLEncoder.encode("Signature", ENCODE_TYPE)).append("=").append(signature);
+        for (Map.Entry<String, String> e : parameterMap.entrySet()) {
+            temp.append("&").append(percentEncode(e.getKey())).append("=").append(percentEncode(e.getValue()));
+        }
+        return temp.toString();
+    }
+
+    public static String saveInputStreamPic(InputStream inputStream, String bucket, String project, String dir,
+                                            String key) throws OSSException, ClientException, IOException {
+        String fullKey = project + "/" + dir + "/" + key;
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+        objectMetadata.setContentType("image/jpg");
+        getOssClient().putObject(bucket, fullKey, inputStream, objectMetadata);
+        return fullKey;
+    }
+
+    public static String sendImageToAliOss(BufferedImage image) throws Exception {
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        ImageIO.write(image, "jpg", os);
+        InputStream is = new ByteArrayInputStream(os.toByteArray());
+        // 将生成的图片往OSS里面上传
+        String random = UUID.randomUUID().toString().replaceAll("-", "") + new Random().nextLong();
+        String key = Md5Util.encoderByMd5(random);
+        String coverImgPath = AliOssFileTool.saveVideoCoverImagFromInternal(is, key);
+        return coverImgPath;
+    }
+
+    public static String saveVideoCoverImagFromInternal(InputStream inputStream, String key)
+            throws OSSException, ClientException, IOException {
+        String bucketName = AliOssConfig.getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName());
+        String fullKey = getProjectName() + "/pic/video/cover/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/"
+                + key;
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+        objectMetadata.setContentType("image/jpg");
+        getInternalOssClient().putObject(bucketName, fullKey, inputStream, objectMetadata);
+        return fullKey;
+
+    }
+
+    /**
+     * @param duration   时长,如果是图片则传0,视频则传视频时长
+     * @param isInternal 是否内网访问
+     * @return
+     * @return String
+     * @Title: generatePresignedUrl
+     * @Description:得到对象的临时访问URL
+     * @author 王树杞
+     * @date 2019年2月25日 上午11:04:22
+     * @version 2.0
+     */
+    public static String generatePresignedUrl(String filePath, Integer duration, boolean isInternal) {
+
+        if (StringUtils.isEmpty(filePath)) {
+            return null;
+        }
+
+        if (filePath.startsWith("http")) {
+            filePath = filePath.replace(PropertiesUtils.getDownloadDomain(), "");
+            filePath = filePath.replace("https://weappupload.piaoquantv.com/", "");
+            filePath = filePath.replace("https://testweappupload.yishihui.com/", "");
+            filePath = filePath.replace("https://lvupload.piaoquantv.com/", "");
+        }
+
+        if (filePath.contains("Signature") && filePath.contains("OSSAccessKeyId")) {
+            return filePath;
+        }
+
+        if (duration == null) {
+            duration = 0;
+        }
+        // 设置URL过期时间为视频时长+3天。
+        // 单位为秒;
+        Date expiration = new Date(new Date().getTime() + (duration + (3 * 24 * 60 * 60)) * 1000);
+//		//一分钟
+//		Date expiration = new Date(new Date().getTime() +( 60) * 1000);
+        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
+
+        URL url = getOssReadOnlyClient().generatePresignedUrl(BasePropertiesUtils.getVideoBucket(),
+                filePath, expiration, HttpMethod.GET);
+        String path = url.getFile();
+        if (StringUtils.startsWith(path, "/")) {
+            return StringUtils.substring(path, 1);
+        }
+        return path;
+
+    }
+
+    public static String saveObjectFromInternal(InputStream inputStream, String fullKey)
+            throws OSSException, ClientException, IOException {
+        String bucketName = BasePropertiesUtils.getVideoBucket();
+        getInternalOssClient().putObject(bucketName, fullKey, inputStream);
+        return fullKey;
+    }
+
+    public static String saveObjectFromInternal(String bucketName, String url, String fullKey)
+            throws Exception {
+        InputStream inputStream = new URL(url).openStream();
+        getInternalOssClient().putObject(bucketName, fullKey, inputStream);
+        if (inputStream != null) {
+            inputStream.close();
+        }
+        return fullKey;
+    }
+
+    public static boolean checkObjectExistFromInternal(String bucketName, String fullKey) {
+        return getInternalOssClient().doesObjectExist(bucketName, fullKey);
+    }
+
+    public static String uploadShangHaiVideo(InputStream inputStream, String key, String bucketName) {
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+        objectMetadata.setContentType("video/mp4");
+        getShangHaiInternalOssClient().putObject(bucketName, key, inputStream, objectMetadata);
+        return key;
+    }
+
+    public static boolean isShangHaiExist(String bucket, String fullKey) {
+        return getShangHaiInternalOssClient().doesObjectExist(bucket, fullKey);
+    }
+
+    public static Boolean isStorageClassArchive(String bucket, String key) throws OSSException, ClientException {
+        ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key);
+        StorageClass storageClass = objectMetadata.getObjectStorageClass();
+        return storageClass == StorageClass.Archive;
+    }
+
+    public static boolean isStorageClassColdArchive(String bucket, String key) throws OSSException, ClientException {
+        ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key);
+        StorageClass storageClass = objectMetadata.getObjectStorageClass();
+        return storageClass == StorageClass.ColdArchive;
+    }
+
+    public static void setStorageClassToArchive(String bucket, String key) throws OSSException, ClientException {
+        // 创建CopyObjectRequest对象。
+        CopyObjectRequest request = new CopyObjectRequest(bucket, key, bucket, key);
+
+        // 创建ObjectMetadata对象。
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+
+        // 封装header,此处以设置存储类型为归档类型为例。
+        objectMetadata.setHeader("x-oss-storage-class", StorageClass.Archive);
+        request.setNewObjectMetadata(objectMetadata);
+
+        // 更改文件存储类型。
+        CopyObjectResult result = getInternalOssClient().copyObject(request);
+    }
+
+    public static void recoverVideoAsync(String bucket, String srckey) {
+        OSSClient ossInternalClient = getInternalOssClient();
+        ObjectMetadata objectMetadata = ossInternalClient.getObjectMetadata(bucket, srckey);
+        // 校验文件是否为归档文件。
+        StorageClass storageClass = objectMetadata.getObjectStorageClass();
+        if (storageClass == StorageClass.Archive) {
+            // 解冻文件。
+            try {
+                ossInternalClient.restoreObject(bucket, srckey);
+            } catch (Exception e) {
+                // TODO OSS Auto-generated catch blockvideo-common/src/main/java/com/weiqu/video/common/enums/ExceptionCodeEnum.java
+//				e.printStackTrace();
+                logger.error("视频可能在解冻中");
+            }
+        } else if (storageClass == StorageClass.ColdArchive) {
+            // 解冻文件。
+            try {
+                RestoreJobParameters parameters = new RestoreJobParameters(RestoreTier.RESTORE_TIER_EXPEDITED);
+                RestoreConfiguration configuration = new RestoreConfiguration(3, parameters);
+                ossInternalClient.restoreObject(bucket, srckey, configuration);
+            } catch (Exception ex) {
+                logger.error("视频可能在解冻中", ex);
+            }
+        }
+    }
+
+    public static Boolean isRestoreCompleted(String bucket, String key) throws OSSException, ClientException {
+        ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key);
+        Boolean isRestoreCompleted = false;
+        try {
+            isRestoreCompleted = objectMetadata.isRestoreCompleted();
+        } catch (Exception e) {
+            // TODO OSS Auto-generated catch block
+//			e.printStackTrace();
+            logger.error("视频可能在解冻中");
+        }
+
+        return isRestoreCompleted;
+    }
+
+    /**
+     * @param path
+     * @param path
+     * @return
+     * @ApiModelProperty(value="冻结状态: -1:无须解冻  0:待解冻  1:解冻中  2:解冻完成")
+     */
+    public static Integer getFrozenStatus(String path) {
+        if (path.startsWith("http") && !path.startsWith(PropertiesUtils.getDownloadDomain())) {
+            logger.info("getFrozenStatus-outer size video, path :" + path);
+            return -1;
+        }
+        String realPath = path.replace(PropertiesUtils.getDownloadDomain(), "");
+        String bucketName = BasePropertiesUtils.getVideoBucket();
+        ObjectMetadata objectMetadata = null;
+        try {
+            objectMetadata = getInternalOssClient().getObjectMetadata(bucketName, realPath);
+        } catch (Exception ex) {
+            logger.error("getFrozenStatus-error", ex);
+            return -1;
+        }
+
+        if (Objects.isNull(objectMetadata)) {
+            logger.error("getFrozenStatus-error, path :" + path + " do not has metaData");
+            return -1;
+        }
+        StorageClass storageClass = objectMetadata.getObjectStorageClass();
+        if (storageClass != StorageClass.Archive && storageClass != StorageClass.ColdArchive) {
+            logger.info("getFrozenStatus, path :" + path + " do not in Archive status");
+            return -1;
+        }
+        try {
+            // 解冻完成
+            boolean isRestoreCompleted = objectMetadata.isRestoreCompleted();
+            if (isRestoreCompleted) {
+                return 2;
+            } else {
+                return 1;
+            }
+        } catch (NullPointerException e) {
+            logger.info("getFrozenStatus, path :" + path + " waiting for forzed!");
+            return 0;
+        }
+    }
+
+
+    public static Map<String, Object> getMediaAllInfo(String inPath) {
+        return getMediaAllInfo(inPath, BasePropertiesUtils.getVideoBucket());
+    }
+
+    public static Map<String, Object> getMediaAllInfo(String inPath, String bucketName) {
+        Map<String, Object> map = new HashMap<String, Object>();
+        String encodedInput;
+        try {
+            encodedInput = URLEncoder.encode(inPath, "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            logger.error("获取元数据输入流解析错误", e);
+            map.put("status", "1");
+            return map;
+        }
+        SubmitMediaInfoJobRequest request = new SubmitMediaInfoJobRequest();
+        JSONObject input = new JSONObject();
+        input.put("Bucket", bucketName);
+        input.put("Location", PropertiesUtils.getTranscodeLocation());
+        input.put("Object", encodedInput);
+        request.setInput(input.toJSONString());
+        request.setPipelineId(PropertiesUtils.getTranscodePipelineId());
+        try {
+            SubmitMediaInfoJobResponse response = new SubmitMediaInfoJobResponse();
+            response = AliOssConfig.getIAcsClient().getAcsResponse(request);
+            if (response.getMediaInfoJob().getState() != null
+                    && response.getMediaInfoJob().getState().equalsIgnoreCase("Fail")) {
+                logger.error("获取元数据错误:" + JSONObject.toJSONString(response.getMediaInfoJob())
+                        + ",requestId:" + response.getRequestId());
+                map.put("status", "2");
+                return map;
+            }
+            Properties properties = response.getMediaInfoJob().getProperties();
+            Properties.Streams.VideoStream videoStream = null;
+            if (CollectionUtils.isNotEmpty(properties.getStreams().getVideoStreamList())) {
+                videoStream = properties.getStreams().getVideoStreamList().get(0);
+            }
+            Properties.Format format = properties.getFormat();
+            logger.info("videoStream:" + JSONObject.toJSONString(videoStream));
+            logger.info("format:" + JSONObject.toJSONString(format));
+            map.put("status", "0");
+            if (properties.getWidth() != null) {
+                map.put("width", Integer.parseInt(properties.getWidth()) + "");
+            }
+            if (properties.getHeight() != null) {
+                map.put("height", Integer.parseInt(properties.getHeight()) + "");
+            }
+            if (videoStream != null) {
+                map.put("rotate", videoStream.getRotate());
+                map.put("codeName", videoStream.getCodecName());
+            }
+            if (format != null) {
+                map.put("size", format.getSize());
+                //设置成long类型的 大于0少于1的设置成1
+                if (Double.parseDouble(format.getDuration()) > 0 && Double.parseDouble(format.getDuration()) < 1) {
+                    map.put("duration", new Double(1).longValue());
+                } else {
+                    map.put("duration", StringUtils.isEmpty(format.getDuration()) ? 0 : new Double(Double.parseDouble(format.getDuration())).longValue());
+                }
+                map.put("bitRate", StringUtils.isEmpty(format.getBitrate()) ? 0 : new Double(Double.parseDouble(format.getBitrate())).longValue() * 1000);
+            }
+        } catch (ServerException e) {
+            logger.error("获取元数据服务器异常", e);
+            map.put("status", "3");
+        } catch (ClientException e) {
+            logger.error("获取元数据客户端异常", e);
+            map.put("status", "4");
+        } catch (Exception e) {
+            logger.error("获取元数据异常", e);
+            map.put("status", "5");
+        }
+        return map;
+    }
+
+    public static CopyObjectResult setStorageClassToColdArchive(String bucket, String key) {
+        CopyObjectRequest request = new CopyObjectRequest(bucket, key, bucket, key);
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+
+        // 封装header,此处以设置存储类型为归档类型为例。
+        objectMetadata.setHeader("x-oss-storage-class", StorageClass.ColdArchive);
+        request.setNewObjectMetadata(objectMetadata);
+
+        // 更改文件存储类型。
+        return getInternalOssClient().copyObject(request);
+    }
+
+    public static String getRandomObjectKey(Integer fileType) {
+        String env = PropertiesUtils.getProjectEnv();
+        if (StringUtils.isEmpty(env)) {
+            env = "qa";
+        }
+        String fileName = RandomUtil.generate18String();
+        if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) {
+            fileName = "/video/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
+        } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) {
+            fileName = "/voice/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
+        } else {
+            fileName = "/pic/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
+        }
+        return getProjectName() + fileName;
+    }
+
+    public static StsTokenVO getStsToken(String fileName, Long durationSeconds) {
+
+        String endpoint = BasePropertiesUtils.getLongvideoStsEndpoint();
+        String accessKeyId = BasePropertiesUtils.getLongvideoStsAccessKeyId();
+        String accessKeySecret = BasePropertiesUtils.getLongvideoStsAccessKeySecret();
+        String roleArn = BasePropertiesUtils.getLongvideoStsRoleArn();
+        String roleSessionName = BasePropertiesUtils.getLongvideoStsSessionName();
+        StsTokenVO result = new StsTokenVO();
+        try {
+            String region = "cn-hangzhou";
+            DefaultProfile.addEndpoint("", "", "Sts", endpoint);
+            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
+            DefaultAcsClient client = new DefaultAcsClient(profile);
+            final AssumeRoleRequest request = new AssumeRoleRequest();
+            request.setMethod(MethodType.POST);
+            request.setRoleArn(roleArn);
+            request.setRoleSessionName(roleSessionName);
+            //设置过期时间 临时访问凭证的有效时间,单位为秒。最小值为900,最大值以当前角色设定的最大会话时间为准。角色最大会话时间取值范围为3600秒~43200秒
+            if (Objects.nonNull(durationSeconds)) {
+                request.setDurationSeconds(durationSeconds);
+            }
+            JSONObject policy = getUploadFileStsPolicy(BasePropertiesUtils.getVideoBucket(), fileName);
+            request.setPolicy(policy.toJSONString());
+
+            final AssumeRoleResponse response = client.getAcsResponse(request);
+            result.setExpiration(response.getCredentials().getExpiration());
+            result.setAccessKeyId(response.getCredentials().getAccessKeyId());
+            result.setAccessKeySecret(response.getCredentials().getAccessKeySecret());
+            result.setSecurityToken(response.getCredentials().getSecurityToken());
+            result.setRequestId(response.getRequestId());
+            result.setFileName(fileName);
+            result.setHost(AliOssConfig.getUploadDomain());
+
+            String host0 = BasePropertiesUtils.getOssaccelerateUploadDomain();
+            String host1 = "https://" + AliOssConfig.getBucket(EnumPublicBuckets.PUBBUCKET.getBucketName()) + "." + AliOssConfig.getOssEndPoint() + "/";
+            result.setHosts(new String[]{host0, host1});
+
+            result.setBucket(BasePropertiesUtils.getVideoBucket());
+            result.setRegion(region);
+            result.setCname(true);
+
+            // 返回服务器当前时间
+            result.setServerTimestamp(System.currentTimeMillis());
+
+        } catch (com.aliyuncs.exceptions.ClientException e) {
+            logger.error(String.format("获取临时令牌失败,errorCode:%s;errorMessage:%s;requestId:%s",
+                    e.getErrCode(), e.getErrMsg(), e.getRequestId()));
+        } catch (Exception e) {
+            logger.error("获取临时令牌失败", e);
+        }
+        return result;
+    }
+
+    private static JSONObject getUploadFileStsPolicy(String bucketName, String fileName) {
+
+        JSONObject policy = new JSONObject();
+        policy.put("Version", "1");
+
+        JSONArray statements = new JSONArray();
+        JSONObject statement = new JSONObject();
+        statement.put("Effect", "Allow");
+
+        JSONArray action = new JSONArray();
+        action.add("oss:PutObject");
+
+        statement.put("Action", action);
+        JSONArray resource = new JSONArray();
+        resource.add("acs:oss:*:1894469520484605:" + bucketName + "/" + fileName);
+        statement.put("Resource", resource);
+
+        statements.add(statement);
+        policy.put("Statement", statements);
+
+        logger.info(String.format("Policy:%s", JSON.toJSONString(policy)));
+        return policy;
+    }
+
+}

+ 72 - 0
core/src/main/java/com/tzld/supply/util/BasePropertiesUtils.java

@@ -0,0 +1,72 @@
+package com.tzld.supply.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+@Slf4j
+public class BasePropertiesUtils {
+
+    public static Properties properties;
+
+    static {
+        Properties mainProperties = new Properties();
+        properties = new Properties();
+        try {
+            InputStream mainStream = BasePropertiesUtils.class.getClassLoader().getResourceAsStream("application.properties");
+            mainProperties.load(mainStream);
+            // 先通过虚拟机参数 -Denv=value去取配置文件的值
+            // 如果没有设置-Denv的虚拟机参数则说明是本地开发环境,则读取application.properties文件中spring.profiles.active的值
+            String env = System.getProperty("env");
+            if (StringUtils.isEmpty(env)) {
+                env = mainProperties.getProperty("spring.profiles.active");
+            }
+            if (StringUtils.isEmpty(env)) {
+                log.error("设置spring.profiles.active or 设置虚拟机启动参数 -Denv错误!!!");
+                System.exit(1);
+            }
+            InputStream activeStream = BasePropertiesUtils.class.getClassLoader().getResourceAsStream("application.properties");
+            properties.load(activeStream);
+            log.info("开发环境为: " + env);
+        } catch (IOException e) {
+            log.error(e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    public static Properties getProperties() {
+        return properties;
+    }
+
+    public static String getVideoBucket() {
+        return getProperties().getProperty("oss.video.bucket");
+    }
+
+    public static String getLongvideoStsEndpoint() {
+        return getProperties().getProperty("oss.longvideo.video.sts.endpoint");
+    }
+
+    public static String getLongvideoStsAccessKeyId() {
+        return getProperties().getProperty("oss.longvideo.video.sts.accessKeyId");
+    }
+
+    public static String getLongvideoStsAccessKeySecret() {
+        return getProperties().getProperty("oss.longvideo.video.sts.accessKeySecret");
+    }
+
+    public static String getLongvideoStsRoleArn() {
+        return getProperties().getProperty("oss.longvideo.video.sts.roleArn");
+    }
+
+    public static String getLongvideoStsSessionName() {
+        return getProperties().getProperty("oss.longvideo.video.sts.roleSessionName");
+    }
+
+    public static String getOssaccelerateUploadDomain() {
+        return getProperties().getProperty("oss.accelerate.upload.domain");
+    }
+
+}

+ 169 - 0
core/src/main/java/com/tzld/supply/util/CdnUtil.java

@@ -0,0 +1,169 @@
+package com.tzld.supply.util;
+
+import cn.hutool.core.net.URLEncodeUtil;
+import com.alibaba.fastjson.JSON;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.cdn.model.v20141111.DescribeDomainBpsDataRequest;
+import com.aliyuncs.cdn.model.v20141111.DescribeDomainBpsDataResponse;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.exceptions.ServerException;
+import com.aliyuncs.profile.DefaultProfile;
+import com.stuuudy.commons.external.filestorage.enums.EnumFileType;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+
+public class CdnUtil {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CdnUtil.class);
+
+//    public static final String VIDEO_CDN_URL_HOST = "https://xycdn.yishihui.com/";
+    public static final String VIDEO_CDN_URL_HOST = "http://rescdn.yishihui.com/";
+
+    public static final String PICTURE_CDN_URL_HOST_PICTURE = "http://rescdn.yishihui.com/";
+    public static final String DOWNLOAD_CDN_URL_HOST_PICTURE = "https://rescdn.yishihui.com/";
+
+
+    private static IAcsClient client;
+
+    static {
+        if (Objects.isNull(client)) {
+            DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAInlg8tWvBeiJe", "hDu5v2nrOmdY0AjlqGnZkW57mxCOLO");
+            /** use STS Token
+             DefaultProfile profile = DefaultProfile.getProfile(
+             "<your-region-id>",           // The region ID
+             "<your-access-key-id>",       // The AccessKey ID of the RAM account
+             "<your-access-key-secret>",   // The AccessKey Secret of the RAM account
+             "<your-sts-token>");          // STS Token
+             **/
+            client = new DefaultAcsClient(profile);
+        }
+    }
+
+
+    public static Double getDescribeDomainBpsData() {
+        DescribeDomainBpsDataRequest request = new DescribeDomainBpsDataRequest();
+        //需要时区为GMT
+        LocalDateTime endTime = LocalDateTime.now().plusHours(-8);
+        LocalDateTime startTime = endTime.plusMinutes(-10);
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String[] starts = startTime.format(df).split(" ");
+        String[] ends = endTime.format(df).split(" ");
+        String start = starts[0] + "T" + starts[1] + "Z";
+        String end = ends[0] + "T" + ends[1] + "Z";
+        request.setStartTime(start);
+        request.setEndTime(end);
+        LOGGER.info("getDescribeDomainBpsData request = {}", JSON.toJSONString(request));
+        try {
+            DescribeDomainBpsDataResponse response = client.getAcsResponse(request);
+            LOGGER.info("getDescribeDomainBpsData response = {}", JSON.toJSONString(response));
+            if (Objects.isNull(response) || Objects.isNull(response.getBpsDataPerInterval())
+                    || response.getBpsDataPerInterval().isEmpty() || response.getBpsDataPerInterval().size() <= 1) {
+                //只有1条可能不准确
+                return null;
+            }
+            DescribeDomainBpsDataResponse.DataModule module1 = response.getBpsDataPerInterval().get(1);
+            if (Objects.nonNull(module1) && Objects.equals("0", module1.getValue())) {
+                return null;
+            }
+            DescribeDomainBpsDataResponse.DataModule module = response.getBpsDataPerInterval().get(0);
+            if (Objects.nonNull(module) && Objects.nonNull(module.getValue())) {
+                return Double.parseDouble(module.getValue()) / 1000 / 1000 / 1000;
+            }
+        } catch (ServerException e) {
+            LOGGER.error("getDescribeDomainBpsData ServerException", e);
+        } catch (ClientException e) {
+            LOGGER.error("getDescribeDomainBpsData ClientException", e);
+        }
+        return null;
+    }
+
+    public static String getCdnUrlHost(EnumFileType fileType) {
+        if (Objects.isNull(fileType)) {
+            return null;
+        }
+        switch (fileType) {
+            case VIDEO:
+                return VIDEO_CDN_URL_HOST;
+            case PICTURE:
+                return PICTURE_CDN_URL_HOST_PICTURE;
+        }
+        return null;
+    }
+
+
+    public static String getOssHttpUrl(String key) {
+        if (StringUtils.isBlank(key)) {
+            return key;
+        }
+        if (org.springframework.util.StringUtils.startsWithIgnoreCase(key, "http")) {
+            return key;
+        } else {
+            String url = DOWNLOAD_CDN_URL_HOST_PICTURE + key;
+            return URLEncodeUtil.encode(url);
+        }
+    }
+
+//    public static void main(String[] args_) throws Exception {
+//        DescribeDomainBpsDataRequest request = new DescribeDomainBpsDataRequest();
+//        //需要时区为GMT
+//        LocalDateTime endTime = LocalDateTime.now().plusHours(-8);
+//        LocalDateTime startTime = endTime.plusMinutes(-10);
+//        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+//        String[] starts = startTime.format(df).split(" ");
+//        String[] ends = endTime.format(df).split(" ");
+//        String start = starts[0] + "T" + starts[1] + "Z";
+//        String end = ends[0] + "T" + ends[1] + "Z";
+//        request.setStartTime(start);
+//        request.setEndTime(end);
+//        System.out.println("---" + JSON.toJSONString(request));
+//        try {
+//            DescribeDomainBpsDataResponse response = client.getAcsResponse(request);
+//
+//            System.out.println("---" + JSON.toJSONString(response));
+//            DescribeDomainBpsDataResponse.DataModule module = response.getBpsDataPerInterval().get(0);
+//
+//            System.out.println("---" + module.getValue());
+//            double d = Double.valueOf(module.getValue()) / 1000 / 1000 / 1000;
+//            System.out.println(d);
+//
+////            System.out.println(new Gson().toJson(response));
+//        } catch (ServerException e) {
+//            e.printStackTrace();
+//        } catch (ClientException e) {
+//            System.out.println("ErrCode:" + e.getErrCode());
+//            System.out.println("ErrMsg:" + e.getErrMsg());
+//            System.out.println("RequestId:" + e.getRequestId());
+//        }
+//
+//    }
+
+    public static String getFileExtensionFromUrl(String uri) {
+        if (StringUtils.isBlank(uri)) {
+            return "";
+        }
+        String fileExtension = "";
+        try {
+            if (uri.contains(".")) {
+                int lastDotIndex = uri.lastIndexOf('.');
+                if (lastDotIndex > 0) {
+                    fileExtension = uri.substring(lastDotIndex + 1);
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error("getFileExtensionFromURL error", e);
+        }
+        return fileExtension;
+    }
+
+    public static void main(String[] args) {
+        String url = "ad/material_1564536000000.mp4";
+        System.out.println(getFileExtensionFromUrl(url));
+    }
+
+}

+ 15 - 0
core/src/main/java/com/tzld/supply/util/DateUtils.java

@@ -315,4 +315,19 @@ public final class DateUtils {
         ZoneId zone = ZoneId.of("Asia/Shanghai");
         return Date.from(localDate.atStartOfDay(zone).toInstant());
     }
+
+    /**
+     * 日期型转化成字符串类型
+     * @param date
+     * @return
+     */
+    public static String dateToStringyyyyMMdd(Date date) {
+        return new SimpleDateFormat("yyyyMMdd").format(date);
+    }
+
+    public static String formatIso8601Date(Date date) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        df.setTimeZone(new SimpleTimeZone(8, "GMT"));
+        return df.format(date);
+    }
 }

+ 92 - 0
core/src/main/java/com/tzld/supply/util/PropertiesUtils.java

@@ -0,0 +1,92 @@
+package com.tzld.supply.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+@Slf4j
+public class PropertiesUtils {
+
+    public static Properties properties;
+
+    static {
+        Properties mainProperties = new Properties();
+        properties = new Properties();
+        try {
+            InputStream mainStream = PropertiesUtils.class.getClassLoader().getResourceAsStream("application.properties");
+            mainProperties.load(mainStream);
+            // 先通过虚拟机参数 -Denv=value去取配置文件的值
+            // 如果没有设置-Denv的虚拟机参数则说明是本地开发环境,则读取application.properties文件中spring.profiles.active的值
+            String env = System.getProperty("env");
+            if (StringUtils.isEmpty(env)) {
+                env = mainProperties.getProperty("spring.profiles.active");
+            }
+            if (StringUtils.isEmpty(env)) {
+                log.error("设置spring.profiles.active or 设置虚拟机启动参数 -Denv错误!!!");
+                System.exit(1);
+            }
+            InputStream activeStream = PropertiesUtils.class.getClassLoader().getResourceAsStream("application-" + env + ".properties");
+            properties.load(activeStream);
+            properties.put("spring.profiles.active", env);
+            log.info("开发环境为: " + env);
+        } catch (IOException e) {
+            log.error(e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    public static Properties getProperties() {
+        return properties;
+    }
+
+    public static String getProjectEnv() {
+        return getProperties().getProperty("spring.profiles.active");
+    }
+
+    public static String getValue(String key) {
+        return PropertiesUtils.getProperties().getProperty(key);
+    }
+
+
+    public static boolean getSwaggerEnabled() {
+        return Boolean.parseBoolean(getProperties().getProperty("swagger.enabled"));
+    }
+
+    public static String getSwaggerBasePath() {
+        return getProperties().getProperty("swagger.basePath");
+    }
+
+
+    public static String getSwaggerProtocols() {
+        return getProperties().getProperty("swagger.protocols");
+    }
+
+
+    public static String getVideoBucket() {
+        return getProperties().getProperty("oss.longvideo.bucket");
+    }
+
+    public static String getDownloadDomain() {
+        return getProperties().getProperty("oss.longvideo.cdnDomain");
+    }
+
+    public static String getTranscodeLocation() {
+        return getProperties().getProperty("oss.longvideo.transcode.location");
+    }
+
+    public static String getTranscodePipelineId() {
+        return getProperties().getProperty("oss.longvideo.transcode.PipelineId");
+    }
+
+    public static String getReadOnlyAccessKeyId() {
+        return getProperties().getProperty("oss.video.readonly.accessKey");
+    }
+
+    public static String getReadOnlyAccessKeySecret() {
+        return getProperties().getProperty("oss.video.readonly.secretKey");
+    }
+
+}

+ 64 - 0
core/src/main/java/com/tzld/supply/util/RandomUtil.java

@@ -0,0 +1,64 @@
+package com.tzld.supply.util;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Random;
+import java.util.UUID;
+
+public class RandomUtil {
+
+	public static final String ALLNUMBER = "0123456789";  
+	public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";  
+	public static final Integer FIXLENG=18;
+    /** 
+     * 返回一个定长的随机字符串(只包含大小写字母、数字)
+     *  随机字符串长度
+     * @return 随机字符串 
+     */  
+    public static String generate18String() {  
+        StringBuffer sb = new StringBuffer();  
+        Random random = new Random();  
+        for (int i = 0; i < FIXLENG; i++) {  
+            sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));  
+        }  
+        return sb.toString();  
+    } 
+    
+    public static void main(String[] args) {
+		//System.out.println(generate18String())
+        String proportion="0.01";
+        Long price=150l;
+        Double incomeMoney=price*(Double.valueOf(proportion));
+        System.out.println(incomeMoney);
+
+
+        BigDecimal b = new BigDecimal(incomeMoney);
+        Long t = b.setScale(0,BigDecimal.ROUND_HALF_UP).longValue();
+        System.out.println(t);
+
+    	
+	}
+    
+    public static String generateString(int length) {  
+        StringBuffer sb = new StringBuffer();  
+        Random random = new Random();  
+        for (int i = 0; i < length; i++) {  
+            sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));  
+        }  
+        return sb.toString();  
+    }
+    
+    public static String generateNumber(int length) {  
+        StringBuffer sb = new StringBuffer();  
+        Random random = new Random();  
+        for (int i = 0; i < length; i++) {  
+            sb.append(ALLNUMBER.charAt(random.nextInt(ALLNUMBER.length())));  
+        }  
+        return sb.toString();  
+    } 
+    
+    public static String getRandomUUIDStr() {
+		return UUID.randomUUID().toString().replaceAll("-", "")+Calendar.getInstance().getTimeInMillis();
+	}
+
+}

+ 257 - 0
core/src/main/java/com/tzld/supply/util/RedisUtils.java

@@ -0,0 +1,257 @@
+package com.tzld.supply.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class RedisUtils {
+
+    private final static Logger log = LoggerFactory.getLogger(RedisUtils.class);
+
+    public final static Long DEFAULT_EXPIRE_TIME = 7L * 24 * 60 * 60; // 默认过期7天,单位秒
+
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
+
+
+    public boolean containsKey(String key) {
+        if (StringUtils.isBlank(key)) {
+            log.error("containsKey is empty key:" + key);
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
+    }
+
+    public String getString(String key) {
+        Object obj = redisTemplate.opsForValue().get(key);
+        return Objects.isNull(obj) ? null : obj.toString();
+    }
+
+    public Long getLong(String key) {
+        long longVal = 0L;
+        Object obj = redisTemplate.opsForValue().get(key);
+        if (Objects.nonNull(obj)) {
+            try {
+                longVal = Long.parseLong(obj.toString());
+            } catch (Exception e) {
+                e.printStackTrace();
+                return longVal;
+            }
+
+        }
+        return longVal;
+    }
+
+    public void setValueWithExpire(String key, String value, Long expireTime) {
+        redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);
+    }
+
+    public void setIncrementValue(String key, long value, Date date) {
+        Long expireTime;
+        if (date != null) {
+            expireTime = (date.getTime() - System.currentTimeMillis()) / 1000;
+            if (expireTime < 0) {
+                expireTime = DEFAULT_EXPIRE_TIME;
+            }
+        } else { // date为null
+            expireTime = DEFAULT_EXPIRE_TIME;
+        }
+        // 只在第一次进行设置过期时间
+        if (!containsKey(key)) {
+            redisTemplate.opsForValue().increment(key, value);
+            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.opsForValue().increment(key, value);
+        }
+    }
+
+    public void setIncrementValue(String key, Integer value, Long expireTime) {
+        // 只在第一次进行设置过期时间
+        if (!containsKey(key)) {
+            redisTemplate.opsForValue().increment(key, value);
+            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.opsForValue().increment(key, value);
+        }
+    }
+
+    public void setDecrementValue(String key, double value) {
+        redisTemplate.opsForValue().increment(key, -value);
+    }
+
+    public void setIncrementValue(String key, double value, Date date) {
+        Long expireTime;
+        if (date != null) {
+            expireTime = (date.getTime() - System.currentTimeMillis()) / 1000;
+            if (expireTime < 0) {
+                expireTime = DEFAULT_EXPIRE_TIME;
+            }
+        } else { // date为null
+            expireTime = DEFAULT_EXPIRE_TIME;
+        }
+        // 只在第一次进行设置过期时间
+        if (!containsKey(key)) {
+            redisTemplate.opsForValue().increment(key, value);
+            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.opsForValue().increment(key, value);
+        }
+    }
+
+    public int getInteger(String key) {
+        Object obj = redisTemplate.opsForValue().get(key);
+        if (Objects.isNull(obj)) {
+            return 0;
+        }
+        return Integer.valueOf(obj.toString());
+    }
+
+    public Integer getIntegerO(String key) {
+        Object obj = redisTemplate.opsForValue().get(key);
+        if (Objects.isNull(obj)) {
+            return null;
+        }
+        return Integer.valueOf(obj.toString());
+    }
+
+    public void putDealyQueueMsg(String key, String value) {
+        redisTemplate.opsForZSet().add(key, value, System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);
+    }
+
+    public Set<String> processDelayQueue(String key) {
+        long currentTimeMillis = System.currentTimeMillis();
+        Set<String> values = redisTemplate.opsForZSet().rangeByScore(key, 0, currentTimeMillis);
+        if (!CollectionUtils.isEmpty(values)) {
+            redisTemplate.opsForZSet().removeRangeByScore(key, 0, currentTimeMillis);
+        }
+        return values;
+    }
+
+    public void addVal(String key, String val) {
+        redisTemplate.opsForValue().set(key, val);
+    }
+
+    public Long getKeyExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    public void expire(String key, Long time) {
+        redisTemplate.expire(key, time, TimeUnit.SECONDS);
+    }
+
+    public Long countExistingKeys(List<String> keys) {
+        return redisTemplate.countExistingKeys(keys);
+    }
+
+    public boolean del(String key) {
+        return redisTemplate.delete(key);
+    }
+
+    public boolean set(String key, String value, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+            } else {
+                redisTemplate.opsForValue().set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * Redis 分布式锁
+     *
+     * @param key        锁键
+     * @param value      锁值,可以为随机数或者 UUID 等唯一标识符
+     * @param expireTime 锁过期时间,单位为秒
+     * @return true:获取锁成功,false:获取锁失败
+     */
+    public boolean tryLock(String key, String value, long expireTime) {
+        Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.SECONDS);
+        if (result != null && result) {
+            // 获取锁成功
+            return true;
+        }
+        return false;
+    }
+
+    public void listLeftPush(String key, String value) {
+        redisTemplate.opsForList().leftPush(key, value);
+
+    }
+
+    public String listRightPop(String key) {
+        return redisTemplate.opsForList().rightPop(key);
+    }
+
+    public Double getDouble(String key) {
+        try {
+            String val = redisTemplate.opsForValue().get(key);
+            if (StringUtils.isNotBlank(val)) {
+                return Double.valueOf(val);
+            }
+        } catch (Exception e) {
+            log.error("getDouble error redis key:" + key + "----" + e);
+        }
+        return null;
+    }
+
+    public String get(String key) {
+        String val = redisTemplate.opsForValue().get(key);
+        if (StringUtils.isNotBlank(val)) {
+            return val;
+        }
+        return null;
+    }
+
+    public void sAdd(String key, String val) {
+        redisTemplate.opsForSet().add(key, val);
+    }
+
+    public Set<String> sMembers(String key) {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+
+    public Boolean sIsMember(String key, String val) {
+        return redisTemplate.opsForSet().isMember(key, val);
+    }
+
+    public void setBit(String key, long val, boolean flag) {
+        redisTemplate.opsForValue().setBit(key, val, flag);
+    }
+
+    public void setBitList(String key, Set<Long> indexs, boolean flag) {
+        RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
+        redisTemplate.executePipelined((RedisCallback<Object>) redisConnection -> {
+            indexs.forEach(x -> {
+                redisConnection.setBit(key.getBytes(), x, flag);
+            });
+            return null;
+        }, serializer);
+    }
+
+    public Boolean getBitMap(String key, long offset) {
+        return redisTemplate.opsForValue().getBit(key, offset);
+    }
+
+    public List<String> mGet(List<String> keys) {
+        return redisTemplate.opsForValue().multiGet(keys);
+    }
+}

+ 161 - 0
core/src/main/java/com/tzld/supply/util/http/HttpClientUtils.java

@@ -14,8 +14,11 @@ import org.apache.http.config.*;
 import org.apache.http.conn.socket.ConnectionSocketFactory;
 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
@@ -26,6 +29,7 @@ import org.apache.http.util.EntityUtils;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
+import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
@@ -105,6 +109,13 @@ public class HttpClientUtils {
 
     }
 
+
+    public static HttpResponseContent head(String url) {
+        HttpRequestBase request = new HttpHead(url);
+        HttpResponseContent hrc = executeHeadHttpRequest(request, connectTimeoutDefault, readTimeoutDefault);
+        return hrc;
+    }
+
     /**
      * get请求
      *
@@ -333,6 +344,36 @@ public class HttpClientUtils {
 
     }
 
+    /**
+     * post请求,请求数据在data中
+     *
+     * @param url            请求的url
+     * @param msgpackBytes   请求数据
+     * @param headerMap      http请求头,key-value放在map中
+     * @param connectTimeout 连接超时设置,毫秒
+     * @param readTimeout    读取超时设置,毫秒
+     * @return HttpResponseContent对象,如果http请求出现异常,返回null
+     */
+    public static HttpResponseContent postMsgpackDataAddHeader(String url, byte[] msgpackBytes, Map<String, String> headerMap,
+                                                        int connectTimeout, int readTimeout) {
+        HttpRequestBase request = null;
+        HttpResponseContent hrc = null;
+        HttpPost httpPost = new HttpPost(url);
+        ByteArrayEntity entity = new ByteArrayEntity(msgpackBytes);
+        entity.setContentType("application/msgpack");
+        httpPost.setEntity(entity);
+        request = httpPost;
+        // 设置header
+        if (headerMap != null) {
+            for (Entry<String, String> entry : headerMap.entrySet()) {
+                request.addHeader(entry.getKey(), entry.getValue());
+            }
+        }
+        hrc = executeHttpRequest(request, connectTimeout, readTimeout);
+        return hrc;
+
+    }
+
     /**
      * post请求,form表单,不能包含二进制数据
      *
@@ -400,6 +441,62 @@ public class HttpClientUtils {
         return hrc;
     }
 
+    /**
+     * post请求,multipart,支持File,byte[]这两种二进制数据
+     *
+     * @param url       请求的url
+     * @param paramsMap 请求参数map
+     * @return HttpResponseContent对象,如果http请求出现异常,返回null
+     */
+    public static HttpResponseContent postMultipart(String url, Map<String, Object> paramsMap) {
+        return postMultipart(url, paramsMap, connectTimeoutDefault, readTimeoutDefault, null);
+    }
+
+    public static HttpResponseContent postMultipart(String url, Map<String, Object> paramsMap, Map<String, String> headerMap) {
+        return postMultipart(url, paramsMap, connectTimeoutDefault, readTimeoutDefault, headerMap);
+    }
+
+    /**
+     * post请求,multipart,支持File,byte[]这两种二进制数据
+     *
+     * @param url            请求的url
+     * @param paramsMap      请求参数map
+     * @param connectTimeout 连接超时设置,毫秒
+     * @param readTimeout    读取超时设置,毫秒
+     * @return HttpResponseContent对象,如果http请求出现异常,返回null
+     */
+    public static HttpResponseContent postMultipart(String url, Map<String, Object> paramsMap, int connectTimeout,
+                                                    int readTimeout, Map<String, String> headerMap) {
+        HttpRequestBase request = null;
+        HttpResponseContent hrc = null;
+        HttpPost httpPost = new HttpPost(url);
+        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
+        multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
+        Iterator<String> iterator = paramsMap.keySet().iterator();
+        while (iterator.hasNext()) {
+            String key = iterator.next();
+            Object value = paramsMap.get(key);
+            if (value instanceof File) {
+                multipartEntityBuilder.addBinaryBody(key, (File) value);
+            } else if (value instanceof byte[]) {
+                multipartEntityBuilder.addBinaryBody(key, (byte[]) value);
+            } else {
+                multipartEntityBuilder.addTextBody(key, String.valueOf(value),
+                        ContentType.create("text/plain", charsetDefault));
+            }
+        }
+        httpPost.setEntity(multipartEntityBuilder.build());
+        // 设置header
+        if (headerMap != null) {
+            for (Entry<String, String> entry : headerMap.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+        }
+        request = httpPost;
+        hrc = executeHttpRequest(request, connectTimeout, readTimeout);
+        return hrc;
+    }
+
     public static HttpResponseContent postRequestBody(String url, Object s, Map<String, String> headerMap) {
         HttpRequestBase request = null;
         HttpResponseContent hrc = null;
@@ -545,6 +642,70 @@ public class HttpClientUtils {
 
     }
 
+    /**
+     * 执行Http请求
+     *
+     * @param request
+     * @param connectTimeout
+     * @param readTimeout
+     * @return HttpResponseContent对象,如果http请求出现异常,返回null
+     */
+    private static HttpResponseContent executeHeadHttpRequest(HttpRequestBase request, int connectTimeout,
+                                                          int readTimeout) {
+        CloseableHttpResponse response = null;
+        HttpResponseContent hrc = null;
+        try {
+            // 设置请求配置
+            RequestConfig.Builder configBuilder = RequestConfig.custom();
+            // 设置连接超时
+            configBuilder.setConnectTimeout(connectTimeout);
+            // 设置读取超时
+            configBuilder.setSocketTimeout(readTimeout);
+            // 设置从连接池获取连接实例的超时
+            configBuilder.setConnectionRequestTimeout(getConnectionTimeoutDefault);
+            RequestConfig requestConfig = configBuilder.build();
+            request.setConfig(requestConfig);
+            log.debug("开始执行Http请求, uri:" + request.getURI());
+            response = client.execute(request);
+            hrc = getHeadHttpResponseContent(response);
+            return hrc;
+        } catch (Exception e) {
+            log.error("执行Http请求异常, uri:" + request.getURI(), e);
+        } finally {
+            close(request, response);
+        }
+        return hrc;
+
+    }
+
+    /**
+     * 封装HTTP响应报文
+     *
+     * @param response
+     * @return
+     */
+    private static HttpResponseContent getHeadHttpResponseContent(CloseableHttpResponse response) {
+        HttpResponseContent hrc = new HttpResponseContent();
+        hrc.setHeaders(response.getAllHeaders());
+        hrc.setStatusCode(response.getStatusLine().getStatusCode());
+        HttpEntity entity = response.getEntity();
+        if (entity != null) {
+            ContentType contentType = ContentType.getOrDefault(entity);
+            hrc.setMimeType(contentType.getMimeType());
+            if (contentType.getCharset() != null) {
+                hrc.setCharsetName(contentType.getCharset().name());
+            }
+            try {
+                hrc.setContentBytes(EntityUtils.toByteArray(entity));
+            } catch (IOException e) {
+                log.error("封装HTTP响应报文异常", e);
+            }
+        }
+
+        return hrc;
+
+    }
+
     /**
      * 关闭资源
      *

+ 3 - 1
core/src/main/resources/generator/mybatis-spider-generator-config.xml

@@ -47,7 +47,9 @@
         </javaClientGenerator>
 
 <!--        <table tableName="spider_task" domainObjectName="" alias=""/>-->
-        <table tableName="spider_content" domainObjectName="" alias=""/>
+<!--        <table tableName="spider_content" domainObjectName="" alias=""/>-->
+        <table tableName="spider_content_media" domainObjectName="" alias=""/>
+        <table tableName="tools_audio_trans_record" domainObjectName="" alias=""/>
     </context>
 
 </generatorConfiguration>

+ 102 - 0
server/src/main/java/com/tzld/supply/controller/FileController.java

@@ -0,0 +1,102 @@
+package com.tzld.supply.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.stuuudy.commons.external.filestorage.enums.EnumPublicBuckets;
+import com.tzld.supply.common.base.CommonResponse;
+import com.tzld.supply.common.enums.ExceptionEnum;
+import com.tzld.supply.common.exception.CommonException;
+import com.tzld.supply.config.AliOssConfig;
+import com.tzld.supply.model.param.FileUploadParam;
+import com.tzld.supply.model.param.OssUploadSignParam;
+import com.tzld.supply.model.param.StsTokenParam;
+import com.tzld.supply.model.vo.FileInfo;
+import com.tzld.supply.model.vo.SignatureVO;
+import com.tzld.supply.model.vo.StsTokenVO;
+import com.tzld.supply.util.AliOssFileTool;
+import com.tzld.supply.util.RandomUtil;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+@RestController
+@RequestMapping("/file")
+@Slf4j
+public class FileController {
+
+    @CrossOrigin(origins = "*")
+    @PostMapping("/upload")
+    public CommonResponse<FileInfo> fileUpload(@Validated FileUploadParam param, BindingResult bindingResult) throws IOException {
+        if (bindingResult.hasErrors()) {
+            return CommonResponse.create(ExceptionEnum.PARAM_ERROR.getCode(), bindingResult.getAllErrors().get(0).getDefaultMessage());
+        }
+        if (StringUtils.isBlank(param.getFileUri())) {
+            String fileName = param.getFile().getOriginalFilename();
+            // 获取文件名中的文件类型
+            if (StringUtils.isBlank(fileName)) {
+                param.setFileUri("temp/" + System.currentTimeMillis() + "_" + RandomUtil.generate18String());
+            } else {
+                String fileType = fileName.substring(fileName.lastIndexOf("."));
+                param.setFileUri("temp/" + System.currentTimeMillis() + "_" + RandomUtil.generate18String() + fileType);
+            }
+        }
+        String fileUrl = AliOssFileTool.saveInPublicReturnHost(param.getFile().getInputStream(),
+                EnumPublicBuckets.PUBBUCKET, param.getFileUri(), param.getFileType());
+        FileInfo fileInfo = new FileInfo();
+        fileInfo.setFileUrl(fileUrl);
+        String bucketName = AliOssConfig.getBucket(EnumPublicBuckets.PUBBUCKET.getBucketName());
+        boolean isExistFile = AliOssFileTool.getOssClient().doesObjectExist(bucketName, param.getFileUri());
+        if (!isExistFile) {
+            throw new CommonException(ExceptionEnum.PARAM_ERROR.getCode(), "上传文件不存在!!");
+        }
+        return CommonResponse.create(fileInfo);
+    }
+
+    @CrossOrigin(origins = "*")
+    @PostMapping("/signature")
+    @ApiOperation(value = "获取签名")
+    public CommonResponse<SignatureVO> signature(@Validated OssUploadSignParam ossUploadSignParam) {
+        log.info("获取OSS签名失败 param" + JSON.toJSONString(ossUploadSignParam));
+        SignatureVO signatureVO;
+        try {
+            signatureVO = AliOssFileTool.getUploadPolicy(ossUploadSignParam.getFileType());
+        } catch (Exception e) {
+            log.error("获取OSS签名失败", e);
+            return CommonResponse.create(ExceptionEnum.SYSTEM_ERROR.getCode(), "获取OSS签名失败");
+        }
+        return CommonResponse.success(signatureVO);
+    }
+
+    /**
+     * 尽量控制前端获取oss权限,降低安全风险
+     * 有效期为15分钟,getStsToken接口为1小时
+     *
+     * @param stsTokenParam
+     * @param request
+     * @return
+     * @throws Exception
+     */
+    @CrossOrigin(origins = "*")
+    @PostMapping("/getTempStsToken")
+    @ApiOperation(value = "获取STS临时令牌")
+    public CommonResponse<StsTokenVO> getTempStsToken(StsTokenParam stsTokenParam, HttpServletRequest request) throws Exception {
+        log.info("获取STS临时令牌 param" + JSON.toJSONString(stsTokenParam));
+        StsTokenVO stsTokenVO;
+        try {
+            String fileName = AliOssFileTool.getRandomObjectKey(stsTokenParam.getFileType());
+            stsTokenVO = AliOssFileTool.getStsToken(fileName, 15 * 60L);
+        } catch (Exception e) {
+            log.error("获取STS临时令牌", e);
+            return CommonResponse.create(ExceptionEnum.SYSTEM_ERROR.getCode(), "获取STS临时令牌失败");
+        }
+        return CommonResponse.success(stsTokenVO);
+    }
+}

+ 2 - 12
server/src/main/resources/application-dev.yml

@@ -15,19 +15,9 @@ spring:
         connection-test-query: SELECT 1
 
   redis:
-    hostName: r-t4n023zec9wyjeer0spd.redis.singapore.rds.aliyuncs.com
+    host: r-bp1ps6my7lzg8rdhwxpd.redis.rds.aliyuncs.com
     port: 6379
-    username: denet_crawler
-    password: denet_crawler2023
-    connect-timeout: 1000
-    timeout: 3000
-    lettuce:
-      pool:
-        max-active: 8
-        max-wait: -1
-        max-idle: 8
-        min-idle: 0
-    host: r-t4n023zec9wyjeer0spd.redis.singapore.rds.aliyuncs.com
+    password: Wqsd@2019
 
 xxl:
   job:

+ 2 - 12
server/src/main/resources/application-prod.yml

@@ -15,19 +15,9 @@ spring:
         connection-test-query: SELECT 1
 
   redis:
-    hostName: r-t4n1ff4vv1j0u6xm2y.redis.singapore.rds.aliyuncs.com
+    host: r-bp1rbmomeunfo3b3vppd.redis.rds.aliyuncs.com
     port: 6379
-    username: denet_crawler
-    password: denet_crawler2023
-    connect-timeout: 1000
-    timeout: 3000
-    lettuce:
-      pool:
-        max-active: 8
-        max-wait: -1
-        max-idle: 8
-        min-idle: 0
-    host: r-t4n1ff4vv1j0u6xm2y.redis.singapore.rds.aliyuncs.com
+    password: wqsd@2025
 
 xxl:
   job:

+ 2 - 12
server/src/main/resources/application-test.yml

@@ -15,19 +15,9 @@ spring:
         connection-test-query: SELECT 1
 
   redis:
-    hostName: r-t4n023zec9wyjeer0s.redis.singapore.rds.aliyuncs.com
+    host: r-bp1ps6my7lzg8rdhwxpd.redis.rds.aliyuncs.com
     port: 6379
-    username: denet_crawler
-    password: denet_crawler2023
-    connect-timeout: 1000
-    timeout: 3000
-    lettuce:
-      pool:
-        max-active: 8
-        max-wait: -1
-        max-idle: 8
-        min-idle: 0
-    host: r-t4n023zec9wyjeer0s.redis.singapore.rds.aliyuncs.com
+    password: Wqsd@2019
 
 xxl:
   job:

+ 36 - 0
server/src/main/resources/application.yml

@@ -62,3 +62,39 @@ logging:
     com.tzld.supply.dao.mapper.supply.spider: DEBUG  # 输出该包下所有 Mapper 的 SQL 日志
     # 可选:HikariCP 连接池日志(调试连接问题时开启)
     com.zaxxer.hikari: INFO  # 连接池基本信息(避免 DEBUG 级别日志过多)
+
+oss:
+  supply:
+    accessKey: LTAIP6x1l3DXfSxm
+    secretKey: KbTaM9ars4OX3PMS6Xm7rtxGr1FLon
+    ossEndPoint: oss-cn-hangzhou.aliyuncs.com
+    videoEndPoint: slicevideo.yishihui.com
+    expiration: 3600
+    projectName: supply
+    cdnDomain: http://rescdn.yishihui.com/
+    imgDomain: http://rescdn.yishihui.com/
+    videoDomain: http://rescdn.yishihui.com/
+    lvvideoDomain: https://lvupload.piaoquantv.com/
+    pubBucket: public:art-pubbucket,publicVideo:art-pubbucket
+    priBucket: private:art-pribucket,privateVideo:art-privideo,privateVideoIn:art-privideo-in
+    priEndPoint: pricdn.yishihui.com
+    needPress: true
+    internal:
+      endPoint: oss-cn-hangzhou.aliyuncs.com
+  longvideo:
+    video:
+      sts:
+        endpoint: sts.cn-hangzhou.aliyuncs.com
+        accessKeyId: LTAIfZYdxeQpq3YI
+        accessKeySecret: 1yISVWe5Gws2VAdTMc9XWIHpjPd7ja
+        roleArn: acs:ram::1894469520484605:role/oss-sts
+        roleSessionName: session-name
+  accelerate:
+    upload:
+      domain: https://ossaccelerateupload.piaoquantv.com/
+  video:
+    bucket: art-pubbucket
+
+cdn:
+  upload:
+    domain: https://weappupload.piaoquantv.com/