From 885290e4d0d0c7fad3f538d901c616e49c3d6985 Mon Sep 17 00:00:00 2001
From: 胡仁荣 <897853850@qq.com>
Date: 星期二, 18 七月 2023 18:15:58 +0800
Subject: [PATCH] oss分块上传

---
 src/main/java/com/qxueyou/scc/teach/live/utils/RedisCache.java                  |  270 +++++++++++++++++++
 src/main/java/com/qxueyou/scc/controller/HweiYunOBSController.java              |   79 ++++-
 src/main/java/com/qxueyou/scc/teach/res/service/impl/FileService.java           |   28 ++
 pom.xml                                                                         |    6 
 src/main/java/com/qxueyou/scc/teach/res/service/HweiYunOBSService.java          |   22 +
 src/main/resources/application.properties                                       |   14 
 src/main/java/com/qxueyou/scc/teach/res/model/Res.java                          |    2 
 src/main/java/com/qxueyou/scc/base/service/ICacheService.java                   |    3 
 src/main/java/com/qxueyou/scc/base/model/Result.java                            |   14 
 src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java             |    6 
 src/main/java/com/qxueyou/scc/teach/res/service/impl/HweiYunOBSServiceImpl.java |  226 +++++++++++++++
 src/main/java/com/qxueyou/scc/teach/res/service/impl/ResService.java            |   20 +
 src/main/java/com/qxueyou/scc/teach/live/model/AccessLog.java                   |   50 +++
 src/main/java/com/qxueyou/scc/stucontroller/StuLiveController.java              |   51 +++
 src/main/java/com/qxueyou/scc/teach/res/service/IFileService.java               |    5 
 15 files changed, 760 insertions(+), 36 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2732c81..ac828c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -435,6 +435,12 @@
 			<classifier>jdk15</classifier><!-- 鎸囧畾jdk鐗堟湰 -->
 		</dependency>
 
+		<dependency>
+			<groupId>com.aliyun.oss</groupId>
+			<artifactId>aliyun-sdk-oss</artifactId>
+			<version>2.8.3</version>
+		</dependency>
+
 
 		<dependency>
 			<groupId>org.apache.httpcomponents</groupId>
diff --git a/src/main/java/com/qxueyou/scc/base/model/Result.java b/src/main/java/com/qxueyou/scc/base/model/Result.java
index d29db52..d1188a2 100644
--- a/src/main/java/com/qxueyou/scc/base/model/Result.java
+++ b/src/main/java/com/qxueyou/scc/base/model/Result.java
@@ -1,5 +1,7 @@
 package com.qxueyou.scc.base.model;
 
+import com.qxueyou.scc.base.util.CollectionUtils;
+
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
@@ -31,7 +33,10 @@
 	
 	/** 缁撴灉鏁版嵁  */
 	private Object data;
-	
+
+	public static final String MSG_SUCCESS = "success";
+
+	public static final String MSG_FAIL = "fail";
 	/**
 	 * 闈炴硶璇锋眰鐘舵�佺爜
 	 */
@@ -40,7 +45,7 @@
 	public static final Result SUCCESS = new Result(true);
 	
 	public static final Result FAIL = new Result(false);
-	
+
 	public Result() {
 		super();
 	}
@@ -70,6 +75,11 @@
 		this.msg=msg;
 		this.data=data;
 	}
+	public Result(boolean success, Object... objs) {
+		this.success = success;
+		this.msg = success ? MSG_SUCCESS : MSG_FAIL;
+		this.data = CollectionUtils.newObjectMap(objs);
+	}
 	
 	public boolean isSuccess() {
 		return success;
diff --git a/src/main/java/com/qxueyou/scc/base/service/ICacheService.java b/src/main/java/com/qxueyou/scc/base/service/ICacheService.java
index 88b279a..c943ace 100644
--- a/src/main/java/com/qxueyou/scc/base/service/ICacheService.java
+++ b/src/main/java/com/qxueyou/scc/base/service/ICacheService.java
@@ -1,5 +1,7 @@
 package com.qxueyou.scc.base.service;
 
+import org.springframework.data.redis.core.RedisTemplate;
+
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -179,5 +181,6 @@
 	 */
 	boolean setIfAbsent(String key, Object obj);
 
+	<K,V> RedisTemplate<K,V> template();
 
 }
diff --git a/src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java b/src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java
index 9669bbe..5472539 100644
--- a/src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java
+++ b/src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java
@@ -209,5 +209,9 @@
 		redisTemplate.opsForHash().put(key, hashKey, value);
 
 	}
-
+	@SuppressWarnings("unchecked")
+	@Override
+	public <K, V> RedisTemplate<K, V> template() {
+		return redisTemplate;
+	}
 }
diff --git a/src/main/java/com/qxueyou/scc/controller/HweiYunOBSController.java b/src/main/java/com/qxueyou/scc/controller/HweiYunOBSController.java
index 02cd660..9c8516a 100644
--- a/src/main/java/com/qxueyou/scc/controller/HweiYunOBSController.java
+++ b/src/main/java/com/qxueyou/scc/controller/HweiYunOBSController.java
@@ -6,11 +6,16 @@
 import cn.hutool.core.util.StrUtil;
 
 //import cn.hutool.core.io.FileUtil;
+import com.aliyun.oss.OSSException;
 import com.obs.services.exception.ObsException;
 import com.obs.services.model.PutObjectResult;
 import com.qxueyou.scc.base.model.FileMeta;
 import com.qxueyou.scc.base.model.Result;
+import com.qxueyou.scc.base.util.ClientUtils;
 import com.qxueyou.scc.teach.res.service.HweiYunOBSService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -35,6 +40,7 @@
 @RestController
 @RequestMapping("/file")// @RequestMapping("/file")
 public class HweiYunOBSController {
+    private final Logger log = LogManager.getLogger("FileController");
 
     @Resource
     private HweiYunOBSService hweiYunOBSService;
@@ -45,7 +51,6 @@
         if (ObjectUtils.isEmpty(file) || file.getSize() <= 0) {
             return null;
         }
-
 //        if (FileUtil.isEmpty(file)) {
 //            return new Result(false,"鏂囦欢涓虹┖");
 //        }
@@ -54,21 +59,63 @@
         return test;
     }
 
-//    @RequestMapping(value = "fenpian", method = RequestMethod.POST)
-//    public  Map<String, Object>  fpsave(@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
-//
-//        if (ObjectUtils.isEmpty(file) || file.getSize() <= 0) {
-//            return null;
-//        }
-//
-////        if (FileUtil.isEmpty(file)) {
-////            return new Result(false,"鏂囦欢涓虹┖");
-////        }
-////        final List<FileMeta> test = hweiYunOBSService.fileUpload(file, file.getOriginalFilename());
-//        Map<String, Object> fnepian = hweiYunOBSService.fnepian(file, file.getOriginalFilename());
-////        return ResponseVO.ok("鎵ц鎴愬姛",test);
-//        return fnepian;
-//    }
+    /**
+     * 鏂囦欢涓婁紶鎺ュ彛:涓哄鎴风鎻愪緵澶氱嚎绋嬪垎鐗囦笂浼犳帴鍙�
+     * 杩斿洖鐘舵�佸��:200浠h〃鎴愬姛锛�500浠h〃涓婁紶澶辫触锛�205浠h〃闇�閲嶆柊灏濊瘯
+     *
+     * @param identifier 鍞竴id锛岄渶瀹㈡埛绔繚璇佸敮涓�鎬э紝鐩稿悓鏂囦欢淇濊瘉鍞竴鍗冲彲锛岄潪MD5
+     * @return
+     * @TODO : 鐩墠缂哄皯瀵� 鍚勬ā鍧楁枃浠朵釜鏁般�佹枃浠舵牸寮忋�佹枃浠跺ぇ灏忕殑涓婁紶鎺у埗,缁熶竴澧炲姞鍦╟onfigFileModule琛ㄩ噷闈㈠嵆鍙疄鐜� 1 鍥剧墖锛� 2 鏂囨。 3 瑙嗛 4 闊抽
+     */
+    @RequestMapping(value = "/uploadChunk", headers = "content-type=multipart/*", method = RequestMethod.POST)
+    public @ResponseBody FileMeta doUploadPublic(MultipartFile file, HttpServletResponse response,
+                            Integer chunkNumber, Integer totalChunks, long chunkSize, long totalSize, String identifier, String filename, Integer currentChunkSize) {
+
+        FileMeta fileMeta = new FileMeta();
+        try {
+
+            Result uploadResult = null;
+
+            uploadResult = hweiYunOBSService.uploadChunk(file.getInputStream(), identifier.concat(ClientUtils.getUserId()), chunkNumber, currentChunkSize, totalChunks, filename);
+
+
+            fileMeta.setFileId(uploadResult.getDataT("fileId"));
+            fileMeta.setPath(uploadResult.getDataT("path"));
+
+            if (!uploadResult.isSuccess()) {
+                response.setStatus(205);
+            }
+
+        } catch (OSSException e) {
+            response.setStatus(500);
+            log.error(e, e);
+        } catch (Exception e) {
+            log.error("涓婁紶妯″潡瑙f瀽鍑洪敊锛�" + e.getMessage(), e);
+            response.setStatus(500);
+        }
+
+        fileMeta.setFileName(filename);
+        fileMeta.setFileSize(String.valueOf(totalSize));
+        fileMeta.setFileType(null);
+
+        return fileMeta;
+    }
+
+    /**
+     * 鍒濆鍖栧垎鐗囦笂浼犱换鍔�
+     *
+     * @return
+     */
+    @RequestMapping(value = "/uploadChunk/init", method = RequestMethod.POST)
+    public @ResponseBody
+    Result initUploadChunk(String identifier, String fileName,String md5) {
+
+        //濡傛灉MD5鐨勫搴旀枃浠跺瓨鍦ㄥ垯鐩存帴杩斿洖
+//        Result result = fileService.checkMd5(md5,fileName);
+
+        return hweiYunOBSService.initUploadChunk(identifier.concat(ClientUtils.getUserId()), fileName,md5);
+
+    }
 
     @RequestMapping(value = "delete", method = RequestMethod.POST)
     public Result delete(@RequestParam(value = "fileName", required = false)  String fileName) {
diff --git a/src/main/java/com/qxueyou/scc/stucontroller/StuLiveController.java b/src/main/java/com/qxueyou/scc/stucontroller/StuLiveController.java
index 481c30d..b465015 100644
--- a/src/main/java/com/qxueyou/scc/stucontroller/StuLiveController.java
+++ b/src/main/java/com/qxueyou/scc/stucontroller/StuLiveController.java
@@ -1,10 +1,15 @@
 package com.qxueyou.scc.stucontroller;
 
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.qxueyou.scc.base.dao.CommonDAO;
 import com.qxueyou.scc.sdk.MTCloud;
+import com.qxueyou.scc.teach.live.model.AccessLog;
+import com.qxueyou.scc.teach.live.utils.RedisCache;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.CrossOrigin;
@@ -27,6 +32,7 @@
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 
+@Slf4j
 @Api(tags="鐩存挱鎺ュ彛-瀛﹀憳绔�")
 @RestController
 @CrossOrigin
@@ -41,6 +47,12 @@
 	
 	@Autowired
 	MediaLiveDAO dao;
+
+	@Autowired
+	RedisCache redisCache;
+
+	@Autowired
+	CommonDAO commonDAO;
 	
 	private final static short[] PUBLIC_LIVE_STATUS = new short[] {
 			MediaVideoLive.STATUS_LIVE_LIVE,MediaVideoLive.STATUS_LIVE_PAUSE,
@@ -120,28 +132,51 @@
 	 * @return
 	 */
 	@GetMapping(value = "view")
-	public Result view(String couresId,String userId,String userName) throws Exception {
-
-
+	public Result view(String couresId,String userId,String userName,String logId) throws Exception {
+		AccessLog log=new AccessLog();
+		if(StringUtils.isEmpty(logId)){
+//			String ip = IpUtils.getIpAddr(request);
+//			String cityInfo = null;
+//			try {
+//				cityInfo = IpUtils.getCityInfo(ip);
+//			} catch (Exception e) {
+//				log.error("鑾峰彇ip褰掑睘鍦颁俊鎭け璐ワ紒");
+//			}
+			log.setCourseId(couresId);
+			log.setEnterTime(new Date());
+			log.setType("guangxi");
+			log.setName(userName);
+//			log.setIp(ip);
+//			log.setIpAttribution(cityInfo);
+			commonDAO.save(log);
+		}else {
+			String liveUrl = redisCache.getCacheObject("LIVE_URL" + userId);
+			return new Result(true, "success",liveUrl);
+		}
 		MTCloud client = new MTCloud();
-
+		String userRole = null;
 		HashMap<Object,Object> options = new HashMap<Object, Object>();
 		if(userId.equals("")){
 			userId= randomId();
 		}
         if(userName.equals("") || userName==null){
             userName= "娓稿";
-        }
+            userRole=MTCloud.ROLE_GUEST;
+        }else {
+			userRole=MTCloud.ROLE_USER;
+		}
+		String res = client.courseAccess(couresId,userId,userName,userRole, 10000, options);
 
-		String res = client.courseAccess(couresId,userId,userName, MTCloud.ROLE_USER, 10000, options);
 		JSONObject jsonObject = JSON.parseObject(res);
 
-
 		if(jsonObject.getString("code").equals("0")){
+
 			JSONObject data = jsonObject.getJSONObject("data");
 
 			String liveUrl = (String) data.get("liveUrl");
-
+			StringBuffer redisLiveUrl = new StringBuffer("LIVE_URL");
+			redisLiveUrl=redisLiveUrl.append(userId);
+			redisCache.setCacheObject(redisLiveUrl.toString(),liveUrl,5, TimeUnit.MINUTES);
 			return new Result(true, "success",liveUrl);
 		}
 
diff --git a/src/main/java/com/qxueyou/scc/teach/live/model/AccessLog.java b/src/main/java/com/qxueyou/scc/teach/live/model/AccessLog.java
new file mode 100644
index 0000000..eb8c195
--- /dev/null
+++ b/src/main/java/com/qxueyou/scc/teach/live/model/AccessLog.java
@@ -0,0 +1,50 @@
+package com.qxueyou.scc.teach.live.model;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Table;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 璁块棶鏃ュ織
+ */
+@Data
+@NoArgsConstructor//鏃犲弬鏋勯�犳柟娉�
+@AllArgsConstructor//鍏ㄥ弬鏋勯�犳柟娉�
+//@EqualsAndHashCode(callSuper = true)
+@Table(name="sa_access_log")
+public class AccessLog implements Serializable {
+
+    private static final long serialVersionUID = -1979488824632702882L;
+
+    @ApiModelProperty(value = "缂栧彿")
+    private  String logId;
+    @ApiModelProperty(value = "濮撳悕")
+    private  String name;
+    @ApiModelProperty(value = "鐩存挱闂磇d")
+    private String courseId;
+    @ApiModelProperty(value = "璁块棶ip")
+    private String ip;
+    @ApiModelProperty(value = "杩涘叆鐩存挱寮�濮嬫椂闂�")
+    private Date enterTime;
+    @ApiModelProperty(value = "绂诲紑鐩存挱鏃堕棿")
+    private Date leaveTime;
+    @ApiModelProperty(value = "濡傛灉鏄痷serId鍦ㄥ钩鍙版煡璇笉鍒板垯鏄父瀹�")
+    private String userId;
+    @ApiModelProperty(value = "ip褰掑睘鍦颁俊鎭�")
+    private String ipAttribution;
+    @ApiModelProperty(value = "roadShow:璺紨锛宑onference:浼氳")
+    private String type;
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    private Date updateTime;
+    //鏄惁鍒犻櫎锛�0鏈垹闄� 1鍒犻櫎
+    @ApiModelProperty(value = "鍒犻櫎鏍囪瘑")
+    private Integer deleteFlag;
+
+}
diff --git a/src/main/java/com/qxueyou/scc/teach/live/utils/RedisCache.java b/src/main/java/com/qxueyou/scc/teach/live/utils/RedisCache.java
new file mode 100644
index 0000000..13552d2
--- /dev/null
+++ b/src/main/java/com/qxueyou/scc/teach/live/utils/RedisCache.java
@@ -0,0 +1,270 @@
+package com.qxueyou.scc.teach.live.utils;
+
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+@SuppressWarnings(value = { "unchecked", "rawtypes" })
+@Component
+public class RedisCache
+{
+    @Resource
+    public RedisTemplate redisTemplate;
+
+    public Long getIncrValue(String key) {
+        return redisTemplate.opsForValue().increment(key, 0l);
+    }
+
+    public Long incr(String key) {
+        return redisTemplate.opsForValue().increment(key, 1l);
+    }
+
+    public void expire(String key, Long timeout, TimeUnit unit) {
+        redisTemplate.expire(key, timeout, unit);
+    }
+
+    public void delete(String key) {
+        redisTemplate.delete(key);
+    }
+
+    /**
+     * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛�
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @param value 缂撳瓨鐨勫��
+     */
+    public <T> void setCacheObject(final String key, final T value)
+    {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛�
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @param value 缂撳瓨鐨勫��
+     * @param timeout 鏃堕棿
+     * @param timeUnit 鏃堕棿棰楃矑搴�
+     */
+    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
+    {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 璁剧疆鏈夋晥鏃堕棿
+     *
+     * @param key Redis閿�
+     * @param timeout 瓒呮椂鏃堕棿
+     * @return true=璁剧疆鎴愬姛锛沠alse=璁剧疆澶辫触
+     */
+    public boolean expire(final String key, final long timeout)
+    {
+        return expire(key, timeout, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 璁剧疆鏈夋晥鏃堕棿
+     *
+     * @param key Redis閿�
+     * @param timeout 瓒呮椂鏃堕棿
+     * @param unit 鏃堕棿鍗曚綅
+     * @return true=璁剧疆鎴愬姛锛沠alse=璁剧疆澶辫触
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit)
+    {
+        return redisTemplate.expire(key, timeout, unit);
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨勫熀鏈璞°��
+     *
+     * @param key 缂撳瓨閿��
+     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
+     */
+    public <T> T getCacheObject(final String key)
+    {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 鍒犻櫎鍗曚釜瀵硅薄
+     *
+     * @param key
+     */
+    public void deleteObject(final String key)
+    {
+         redisTemplate.delete(key);
+    }
+
+    /**
+     * 鍒犻櫎闆嗗悎瀵硅薄
+     *
+     * @param collection 澶氫釜瀵硅薄
+     * @return
+     */
+    public void deleteObject(final Collection collection)
+    {
+         redisTemplate.delete(collection);
+    }
+
+    /**
+     * 缂撳瓨List鏁版嵁
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @param dataList 寰呯紦瀛樼殑List鏁版嵁
+     * @return 缂撳瓨鐨勫璞�
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList)
+    {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨刲ist瀵硅薄
+     *
+     * @param key 缂撳瓨鐨勯敭鍊�
+     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
+     */
+    public <T> List<T> getCacheList(final String key)
+    {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缂撳瓨Set
+     *
+     * @param key 缂撳瓨閿��
+     * @param dataSet 缂撳瓨鐨勬暟鎹�
+     * @return 缂撳瓨鏁版嵁鐨勫璞�
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
+    {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        Iterator<T> it = dataSet.iterator();
+        while (it.hasNext())
+        {
+            setOperation.add(it.next());
+        }
+        return setOperation;
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨剆et
+     *
+     * @param key
+     * @return
+     */
+    public <T> Set<T> getCacheSet(final String key)
+    {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 缂撳瓨Map
+     *
+     * @param key
+     * @param dataMap
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
+    {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     *  缂撳瓨Map锛屽苟璁剧疆鏈夋晥鏈�
+     * @param key 閿�
+     * @param dataMap 閿�煎
+     * @param timeout 鏃堕棿
+     * @param unit  鏃堕棿鍗曚綅
+     * @param <T>
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap,long timeout, final TimeUnit unit)
+    {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+            redisTemplate.opsForHash().getOperations().expire(key,timeout,unit);
+        }
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨凪ap
+     *
+     * @param key
+     * @return
+     */
+    public <T> Map<String, T> getCacheMap(final String key)
+    {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * 寰�Hash涓瓨鍏ユ暟鎹�
+     *
+     * @param key Redis閿�
+     * @param hKey Hash閿�
+     * @param value 鍊�
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
+    {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 鑾峰彇Hash涓殑鏁版嵁
+     *
+     * @param key Redis閿�
+     * @param hKey Hash閿�
+     * @return Hash涓殑瀵硅薄
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey)
+    {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+    /**
+     * 鍒犻櫎Hash涓殑鏁版嵁
+     * 
+     * @param key
+     * @param hkey
+     */
+    public void delCacheMapValue(final String key, final String hkey)
+    {
+        HashOperations hashOperations = redisTemplate.opsForHash();
+        hashOperations.delete(key, hkey);
+    }
+
+    /**
+     * 鑾峰彇澶氫釜Hash涓殑鏁版嵁
+     *
+     * @param key Redis閿�
+     * @param hKeys Hash閿泦鍚�
+     * @return Hash瀵硅薄闆嗗悎
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
+    {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+    /**
+     * 鑾峰緱缂撳瓨鐨勫熀鏈璞″垪琛�
+     *
+     * @param pattern 瀛楃涓插墠缂�
+     * @return 瀵硅薄鍒楄〃
+     */
+    public Collection<String> keys(final String pattern)
+    {
+        return redisTemplate.keys(pattern);
+    }
+}
diff --git a/src/main/java/com/qxueyou/scc/teach/res/model/Res.java b/src/main/java/com/qxueyou/scc/teach/res/model/Res.java
index d191896..5415f36 100644
--- a/src/main/java/com/qxueyou/scc/teach/res/model/Res.java
+++ b/src/main/java/com/qxueyou/scc/teach/res/model/Res.java
@@ -33,7 +33,7 @@
 	private String creator;
 	private String createId;
 	private String updator;
-	private String updateId;
+		private String updateId;
 	private boolean deleteFlag;
 	private String coverPageUrl;
 	private String status;
diff --git a/src/main/java/com/qxueyou/scc/teach/res/service/HweiYunOBSService.java b/src/main/java/com/qxueyou/scc/teach/res/service/HweiYunOBSService.java
index 3b2a896..15a6eff 100644
--- a/src/main/java/com/qxueyou/scc/teach/res/service/HweiYunOBSService.java
+++ b/src/main/java/com/qxueyou/scc/teach/res/service/HweiYunOBSService.java
@@ -2,6 +2,7 @@
 
 import com.obs.services.model.PutObjectResult;
 import com.qxueyou.scc.base.model.FileMeta;
+import com.qxueyou.scc.base.model.Result;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
@@ -53,4 +54,25 @@
      * @return: java.io.InputStream
      */
     InputStream fileDownload(String objectKey);
+
+    /**
+     * oss 鍒嗙墖涓婁紶
+     *
+     * @param input
+     * @param uniqueId
+     * @param chunkNumber
+     * @param totalChunk
+     * @return
+     */
+    Result uploadChunk(InputStream input, String uniqueId, int chunkNumber, long chunkSize, int totalChunk, String fileName);
+
+    /**
+     * 鍒濆鍖�
+     *
+     * @param uniqueId
+     * @param fileName
+     * @param md5
+     * @return
+     */
+    Result initUploadChunk(String uniqueId, String fileName, String md5);
 }
diff --git a/src/main/java/com/qxueyou/scc/teach/res/service/IFileService.java b/src/main/java/com/qxueyou/scc/teach/res/service/IFileService.java
index 6249440..5afe654 100644
--- a/src/main/java/com/qxueyou/scc/teach/res/service/IFileService.java
+++ b/src/main/java/com/qxueyou/scc/teach/res/service/IFileService.java
@@ -35,5 +35,6 @@
 	 * @return
 	 */
 	InputStream readStreamById(String id);
-	
-}
\ No newline at end of file
+
+	Result checkMd5(String md5, String fileName);
+}
diff --git a/src/main/java/com/qxueyou/scc/teach/res/service/impl/FileService.java b/src/main/java/com/qxueyou/scc/teach/res/service/impl/FileService.java
index 6f14ba5..e67a090 100644
--- a/src/main/java/com/qxueyou/scc/teach/res/service/impl/FileService.java
+++ b/src/main/java/com/qxueyou/scc/teach/res/service/impl/FileService.java
@@ -239,4 +239,32 @@
 		}
 		return null;
 	}
+
+	@Override
+	public Result checkMd5(String md5, String fileName) {
+//		if(StringUtils.isBlank(md5)){
+//			return Result.FAIL;
+//		}
+//
+//
+//			Boolean objectExist;
+//			objectExist = authOssService.doseObjectExist(resFile.getPath());
+//
+//			if (objectExist) {
+//
+//				ResFileDO resFileToDB = new ResFileDO();
+//				BeanUtils.copyProperties(resFile, resFileToDB);
+//				resFileToDB.setId(null);
+//				TraceUtils.setCreateTrace(resFileToDB);
+//				ResFileDO resFileDB = save(resFileToDB);
+//
+//				Result result = new Result(true, "fileId", resFileDB.getId(), "path", resFileDB.getPath(),"fileName",fileName,
+//						"fileSize",resFileToDB.getSize(),"fileType",resFileToDB.getFileType(),"hit",true);
+//				result.setResultCode(201);
+//				return result;
+//
+//		}
+
+		return Result.FAIL;
+	}
 }
diff --git a/src/main/java/com/qxueyou/scc/teach/res/service/impl/HweiYunOBSServiceImpl.java b/src/main/java/com/qxueyou/scc/teach/res/service/impl/HweiYunOBSServiceImpl.java
index 3413b40..8964cf2 100644
--- a/src/main/java/com/qxueyou/scc/teach/res/service/impl/HweiYunOBSServiceImpl.java
+++ b/src/main/java/com/qxueyou/scc/teach/res/service/impl/HweiYunOBSServiceImpl.java
@@ -7,10 +7,12 @@
 import com.obs.services.model.*;
 import com.qxueyou.scc.base.model.FileMeta;
 import com.qxueyou.scc.base.model.Result;
-import com.qxueyou.scc.base.util.CollectionUtils;
-import com.qxueyou.scc.base.util.QFileUtils;
-import com.qxueyou.scc.base.util.UUIDUtils;
+import com.qxueyou.scc.base.service.ICacheService;
+import com.qxueyou.scc.base.service.impl.CommonAppService;
+import com.qxueyou.scc.base.util.*;
 import com.qxueyou.scc.config.HweiOBSConfig;
+import com.qxueyou.scc.teach.res.model.Res;
+import com.qxueyou.scc.teach.res.model.ResDir;
 import com.qxueyou.scc.teach.res.model.ResFile;
 import com.qxueyou.scc.teach.res.service.HweiYunOBSService;
 import com.qxueyou.scc.teach.res.service.IFileService;
@@ -21,6 +23,7 @@
 import org.apache.logging.log4j.Logger;
 import org.aspectj.util.FileUtil;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.HashOperations;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -42,7 +45,7 @@
  */
 @Slf4j
 @Service
-public class HweiYunOBSServiceImpl implements HweiYunOBSService {
+public class HweiYunOBSServiceImpl extends CommonAppService implements HweiYunOBSService {
 
     private final Logger log = LogManager.getLogger(HweiYunOBSServiceImpl.class);
     @Autowired
@@ -50,6 +53,13 @@
 
     @Autowired
     FileService fileService;
+
+    /**
+     * redis 妯℃澘
+     */
+    @Autowired
+    ICacheService cache;
+
 
     public final static String FILE_TYPE_VIDEO = "video";
 
@@ -315,4 +325,212 @@
         }
         return null;
     }
+
+    /**
+     * 鏂囦欢鍒嗙墖涓婁紶瀹炵幇閫昏緫锛屽悇鍒嗙墖鏄绾跨▼涓婁紶
+     *
+     * @param input       杈撳叆娴�
+     * @param uniqueId    璧勬簮鍞竴id(鍓嶇浼犲叆)
+     * @param chunkNumber 鍒嗙墖缂栧彿
+     * @param chunkSize   鍒嗙墖澶у皬
+     * @param totalChunk  鍒嗙墖鎬绘暟
+     * @param fileName    鏂囦欢鍚�
+     * @return
+     */
+    public Result uploadChunk(InputStream input, String uniqueId, int chunkNumber, long chunkSize, int totalChunk,
+                              String fileName) {
+
+        HashOperations<Object, Object, Object> _cacheMap = cache.template().opsForHash();
+
+        ObsClient obsClient = new ObsClient(hweiOBSConfig.getAccessKey(),hweiOBSConfig.getSecurityKey(),hweiOBSConfig.getEndPoint());
+
+        //缁欏垵濮嬪寲棰勭暀1.2绉掗挓鐨勬椂闂�
+        try {
+            if (chunkNumber < 4) {
+                Thread.sleep(1200l);
+            }
+        } catch (InterruptedException e) {
+            log.error(e.getMessage(), e);
+        }
+
+        //鑾峰彇鍒嗙墖涓婁紶id(闃块噷浜慜SS鍒濆鍖栧垎鐗囦笂浼犱换鍔¤繑鍥�,鍜寀niqueId鍙妅ey涓�涓�瀵瑰簲),鑻ヨ幏鍙栦笉鍒帮紝鍒�10绉掑唴寰幆鍗佹鐩磋嚦鑾峰彇鍒帮紝鍚﹀垯杩斿洖閿欒
+        String uploadId = getUploadId(uniqueId);
+
+        if (uploadId == null) {
+            return new Result(false);
+        }
+
+        String key = (String) _cacheMap.get(uniqueId + ClientUtils.getUserId(), "key");
+        boolean exists = true;
+
+        //涓婁紶鐗囨
+        if (!_cacheMap.hasKey(uploadId, String.valueOf(chunkNumber))) {
+            //寮�濮嬩笂浼�
+            UploadPartRequest uploadPartRequest = new UploadPartRequest(hweiOBSConfig.getBucketName(), key);
+            uploadPartRequest.setUploadId(uploadId);
+            // 璁剧疆鍒嗘鍙凤紝鑼冨洿鏄�1~10000
+            uploadPartRequest.setPartNumber(chunkNumber);
+            // 璁剧疆鍒嗘澶у皬
+            uploadPartRequest.setPartSize(chunkSize);
+            uploadPartRequest.setInput(input);
+
+            UploadPartResult partResult = obsClient.uploadPart(uploadPartRequest);
+            exists = false;
+
+            _cacheMap.put(uploadId, String.valueOf(chunkNumber), partResult.getEtag());
+        }
+
+
+        //鍏ㄩ儴鐗囨涓婁紶瀹屾垚,璋冪敤client complete鏂规硶瀹屾垚鍒嗙墖涓婁紶浠诲姟锛屽苟鎻掑叆鏁版嵁搴�
+        if (_cacheMap.size(uploadId) != null
+                && _cacheMap.size(uploadId) >= totalChunk
+                && !_cacheMap.hasKey(uniqueId + ClientUtils.getUserId(), "finish")) {
+            List<PartEtag> tags = new ArrayList<>(5);
+            _cacheMap.entries(uploadId).forEach((k, v) -> {
+                tags.add(new PartEtag((String) v, Integer.parseInt((String) k)));
+            });
+
+            CompleteMultipartUploadResult completeMultipartUploadResult = obsClient.completeMultipartUpload(new CompleteMultipartUploadRequest(hweiOBSConfig.getBucketName(), key, uploadId,
+                    tags));
+
+            System.out.println(completeMultipartUploadResult.getObjectUrl());
+
+            ObjectMetadata metadata = obsClient.getObjectMetadata(hweiOBSConfig.getBucketName(), key);
+
+
+
+
+//            obsClient.setObjectAcl(hweiOBSConfig.getBucketName(), key, AccessControlList.REST_CANNED_PUBLIC_READ);
+            //鏍囪瀹屾垚
+            _cacheMap.put(uniqueId + ClientUtils.getUserId(), "finish", "true");
+
+//            //鏇存柊鏁版嵁搴撲俊鎭�
+            updateFile((String) _cacheMap.get(uniqueId + ClientUtils.getUserId(), "fileId"), metadata.getContentLength(), metadata.getContentMd5(), key, fileName);
+
+            //閿�姣佺紦瀛�
+            cache.template().expire(uniqueId + ClientUtils.getUserId(), 1, TimeUnit.MINUTES);
+        }
+
+        return new Result(true, "hit", exists, "fileId", _cacheMap.get(uniqueId + ClientUtils.getUserId(), "fileId"), "path", _cacheMap.get(uniqueId + ClientUtils.getUserId(), "path"));
+    }
+
+    @Override
+    public Result initUploadChunk(String uniqueId, String fileName, String md5) {
+        String path = getDestPath(fileName);
+        String key = chopPath(path);
+
+        //娓呯紦瀛�
+        cache.template().delete(uniqueId + ClientUtils.getUserId());
+
+        InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(hweiOBSConfig.getBucketName(), key);
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+        objectMetadata.setObjectStorageClass(StorageClassEnum.STANDARD);
+        initiateMultipartUploadRequest.setMetadata(new ObjectMetadata());
+
+        //璋冪敤OSS SDK 鎺ュ彛杩斿洖uploadId
+        ObsClient obsClient = new ObsClient(hweiOBSConfig.getAccessKey(),hweiOBSConfig.getSecurityKey(),hweiOBSConfig.getEndPoint());
+
+        String uploadId = obsClient.initiateMultipartUpload(initiateMultipartUploadRequest).getUploadId();
+
+        //涓洪厤鍚堝垎鐗囦笂浼狅紝鍚庡彴鍏堟柊寤烘枃浠惰褰�
+
+        ResFile file = newFileToDB(fileName, path, getFileType(fileName), 0l, md5);
+
+        //娣诲姞鍒扮紦瀛�
+        cache.template().opsForHash().put(uniqueId + ClientUtils.getUserId(), "uploadId", uploadId);
+        cache.template().opsForHash().put(uniqueId + ClientUtils.getUserId(), "key", key);
+        cache.template().opsForHash().put(uniqueId + ClientUtils.getUserId(), "path", path);
+        cache.template().opsForHash().put(uniqueId + ClientUtils.getUserId(), "fileId", file.getFileId());
+
+        //闃叉浜х敓杩囧缂撳瓨鍨冨溇
+        cache.template().expire(uniqueId + ClientUtils.getUserId(), 1, TimeUnit.DAYS);
+        ResFile file1 = new ResFile();
+        file1.setUpdateId(uploadId);
+        file1.setFileId(file.getFileId());
+        file1.setPath(file.getPath());
+        return new Result(true,"cs",file1);
+    }
+
+    /**
+     * 鏇存柊鏂囦欢淇℃伅鍒版暟鎹簱
+     *
+     * @param fileId
+     * @param fileLength
+     * @param md5
+     * @param path
+     * @param fileName
+     * @return
+     */
+    private ResFile updateFile(String fileId, long fileLength, String md5, String path, String fileName) {
+
+        ResFile file = new ResFile();
+
+        file.setFileId(fileId);
+        file.setSize(fileLength);
+        file.setMd5Hash(md5);
+        file.setPath(path);
+        file.setFileName(fileName);
+
+        cache.template().opsForList().rightPush("BaseOssServiceUpdate", file);
+
+        return file;
+
+    }
+    /**
+     * 鎻掑叆鏂囦欢淇℃伅鍒版暟鎹簱
+     *
+     * @param name
+     * @param relativePath 鐩稿璺緞
+     * @param type         鏂囦欢绫诲瀷锛岄潪鏂囦欢鏍煎紡
+     * @return
+     */
+    private ResFile newFileToDB(String name, String relativePath, String type, Long fileSize, String md5) {
+        ResFile file = new ResFile();
+
+        TraceUtils.setCreateTrace(file);
+        file.setFileName(name);
+        file.setFileFormat(QFileUtils.getFileFormat(name));
+        file.setFileType(type);
+        file.setMd5Hash(md5);
+        file.setPath(relativePath);
+        file.setSize(fileSize == null ? 0 : fileSize);
+        file.setDeleteFlag(false);
+        save(file);
+        return file;
+
+    }
+
+    /**
+     * 濡傛灉璺緞浠� / 鎴� \ 寮�澶达紝闇�瑕佹埅鍙�
+     *
+     * @param destPath
+     * @return
+     */
+    public String chopPath(String destPath) {
+        if (destPath.startsWith("/") || destPath.startsWith("\\")) {
+            return destPath.substring(1);
+        }
+        return destPath;
+    }
+    /**
+     * 鑾峰彇鍒嗙墖涓婁紶id(闃块噷浜慜SS鍒濆鍖栧垎鐗囦笂浼犱换鍔¤繑鍥�,鍜寀niqueId鍙妅ey涓�涓�瀵瑰簲),鑻ヨ幏鍙栦笉鍒帮紝鍒�10绉掑唴寰幆鍗佹鐩磋嚦鑾峰彇鍒帮紝鍚﹀垯杩斿洖閿欒
+     *
+     * @param uniqueId
+     * @return
+     */
+    private String getUploadId(String uniqueId) {
+        HashOperations<Object, Object, Object> _cacheMap = cache.template().opsForHash();
+        String uploadId = (String) _cacheMap.get(uniqueId + ClientUtils.getUserId(), "uploadId");
+        int tryCount = 0;
+        while (uploadId == null && tryCount < 10) {
+            try {
+                Thread.sleep(1000l);
+                uploadId = (String) _cacheMap.get(uniqueId + ClientUtils.getUserId(), "uploadId");
+                tryCount++;
+            } catch (InterruptedException e) {
+                log.error(e, e);
+            }
+        }
+        return uploadId;
+    }
 }
diff --git a/src/main/java/com/qxueyou/scc/teach/res/service/impl/ResService.java b/src/main/java/com/qxueyou/scc/teach/res/service/impl/ResService.java
index 26db190..f15eb2d 100644
--- a/src/main/java/com/qxueyou/scc/teach/res/service/impl/ResService.java
+++ b/src/main/java/com/qxueyou/scc/teach/res/service/impl/ResService.java
@@ -6,6 +6,11 @@
 
 import javax.annotation.PostConstruct;
 
+import com.obs.services.ObsClient;
+import com.obs.services.model.HttpMethodEnum;
+import com.obs.services.model.TemporarySignatureRequest;
+import com.obs.services.model.TemporarySignatureResponse;
+import com.qxueyou.scc.config.HweiOBSConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -46,6 +51,9 @@
 
     @Autowired
     private ApplicationContext appContext;
+
+    @Autowired
+    private HweiOBSConfig hweiOBSConfig;
 
     @Autowired
     private IClassLectureService classLectureService;
@@ -313,8 +321,18 @@
 //                     CollectionUtils.newObjectMap("path", path, "name", res.getName(), "coverPageUrl", res.getCoverPageUrl(), "size",
 //                    		 this.classLectureService.readDocPageCount(res.getItemDestId())));//鏂囦欢鐨勯〉鏁�
 //        }else {
+        // URL鏈夋晥鏈燂紝3600绉�
+        long expireSeconds = 3600L;
+        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
+        //璁剧疆妗跺悕,涓�鑸兘鏄啓鍦ㄩ厤缃噷锛岃繖閲岀洿鎺ヨ祴鍊煎嵆鍙�
+        request.setBucketName(hweiOBSConfig.getBucketName());
+        //杩欓噷鐩稿綋浜庤缃綘涓婁紶鍒皁bs鐨勬枃浠惰矾
+        request.setObjectKey((String) path);
+
+        ObsClient obsClient = new ObsClient(hweiOBSConfig.getAccessKey(),hweiOBSConfig.getSecurityKey(),hweiOBSConfig.getEndPoint());
+        TemporarySignatureResponse temporarySignatureResponse=obsClient.createTemporarySignature(request);
         	 return new Result(true, "success",
-                     CollectionUtils.newObjectMap("path", path, "name", res.getName(), "coverPageUrl", res.getCoverPageUrl(), "size", 0));
+                     CollectionUtils.newObjectMap("path", temporarySignatureResponse.getSignedUrl(), "name", res.getName(), "coverPageUrl", res.getCoverPageUrl(), "size", 0));
 //        }
 
     }
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 2d6ba1d..a5a0e27 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -20,7 +20,7 @@
 
 #mysqldb.datasource.url=jdbc:mysql://rds88t2of1fi184y4s5wo.mysql.rds.aliyuncs.com:3306/scc?useUnicode=true&characterEncoding=GBK&characterSetResults=GBK&zeroDateTimeBehavior=convertToNull
 #mysqldb.datasource.url=jdbc:mysql://10.1.80.52:3306/rsdb?useUnicode=true&characterEncoding=GBK&characterSetResults=GBK&zeroDateTimeBehavior=convertToNull
-mysqldb.datasource.url=jdbc:mysql://110.41.147.200:3306/scc?useUnicode=true&characterEncoding=GBK&characterSetResults=GBK&zeroDateTimeBehavior=convertToNull
+mysqldb.datasource.url=jdbc:mysql://localhost:3306/scc?useUnicode=true&characterEncoding=GBK&characterSetResults=GBK&zeroDateTimeBehavior=convertToNull
 mysqldb.datasource.username=root
 #mysqldb.datasource.username=rs
 #######\uFFFD\uFFFD\uFFFD\uFFFD\u03AA\uFFFD\uFFFD\u05F0\uFFFD\uFFFD\u03F5\u0373\uFFFD\uFFFD\u012C\uFFFD\uFFFD\uFFFD\u00FB\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u02FF\uFFFD#############
@@ -102,3 +102,15 @@
 wx.app.secret=95c5470a52a2c4e037741f82246f4d86
 
 logging.config=classpath:log4j2.xml
+
+#oss.public
+oss.public.access-key-id=MPTI87UMKZLBSWK2DG4V
+oss.public.bucket-name=qxueyou
+oss.public.end-point=obs.cn-north-4.myhuaweicloud.com
+oss.public.secret-access-key=ziNypQwspMYQeIlM2mSHwlr9hS4Xw9VlH316Ur3C
+
+#oss.auth
+oss.auth.access-key-id=MPTI87UMKZLBSWK2DG4V
+oss.auth.bucket-name=qxueyou-video
+oss.auth.end-point=obs.cn-north-4.myhuaweicloud.com
+oss.auth.secret-access-key=ziNypQwspMYQeIlM2mSHwlr9hS4Xw9VlH316Ur3C

--
Gitblit v1.8.0