Browse Source

添加腾讯对象存储的实现

Menethil 7 years ago
parent
commit
691ac1cbd3

+ 6 - 3
CHANGELOG.md

@@ -2,12 +2,15 @@
 
 ## V 0.7.0
  
-*2018-06-30*,数据库再次简化
+*2018-07-16*,数据库再次简化,同时支持短信提醒、邮件提醒、腾讯对象存储服务
  
+  * `管理后台`页面查询时默认基于创建时间排序
+  * `管理后台`多个页面完善页面效果
   * `管理后台`支持商品上架和商品编辑
-  * `项目`数据库再次简化、小商城和管理后台代码进行相应调整
+  * `基础系统`支持腾讯云短信提醒和邮件提醒,感谢[Menethil](https://github.com/linlinjava/litemall/pull/23)
+  * `基础系统`支持腾讯对象存储,感谢[Menethil](https://github.com/linlinjava/litemall/pull/24)
+  * `项目`数据库再次简化,同时小商城和管理后台代码进行相应调整
 
-  
 ## V 0.6.0
  
 *2018-06-30*,项目支持商品上架和统计功能

+ 3 - 3
README.md

@@ -90,7 +90,7 @@ V 2.0.0 完成以下目标:
 
 1. 小商城能够完成基本的业务功能;
 2. 管理后台实现较好的业务操作和交互效果,而不是简单的CRUD;
-3. 管理后台实现统计功能、日志功能
+3. 管理后台实现统计功能、日志功能、权限功能
 
 V 3.0.0 完成以下目标:
 
@@ -114,7 +114,7 @@ V 3.0.0 完成以下目标:
 
 查看[更新日志](CHANGELOG.md)
 
-目前V0.6.0
+目前V0.7.0
 
 ## 警告
 
@@ -158,4 +158,4 @@ V 3.0.0 完成以下目标:
 
 ## 相关项目
 
-[HubertYoung](https://github.com/HubertYoung)正在开发Android端[Litemall-Android](https://github.com/HubertYoung/Litemall-Android)
+HubertYoung正在开发Android端[Litemall-Android](https://github.com/HubertYoung/Litemall-Android)

+ 1 - 0
litemall-os-api/.gitignore

@@ -1,3 +1,4 @@
 
 /target/
 /litemall-os-api.iml
+/storage/

+ 9 - 8
litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/FileSystemStorageService.java

@@ -2,7 +2,6 @@ package org.linlinjava.litemall.os.service;
 
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.nio.file.*;
 import java.util.stream.Stream;
@@ -15,10 +14,12 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
- * 服务器本地文件存储
+ * 服务器本地对象存储服务
+ *
+ * 缩写los(local object storage)
  */
-@Service("localStorage")
-public class FileSystemStorageService implements StorageService {
+@Service("los")
+public class LocalOsService implements ObjectStorageService {
 
     @Autowired
     private ObjectStorageConfig osConfig;
@@ -35,7 +36,7 @@ public class FileSystemStorageService implements StorageService {
     @Override
     public void store(MultipartFile file, String keyName) {
         try {
-            Files.copy(file.getInputStream(), this.rootLocation.resolve(keyName), StandardCopyOption.REPLACE_EXISTING);
+            Files.copy(file.getInputStream(), LocalOsService.rootLocation.resolve(keyName), StandardCopyOption.REPLACE_EXISTING);
         } catch (IOException e) {
             throw new RuntimeException("Failed to store file " + keyName, e);
         }
@@ -44,9 +45,9 @@ public class FileSystemStorageService implements StorageService {
     @Override
     public Stream<Path> loadAll() {
         try {
-            return Files.walk(this.rootLocation, 1)
-                    .filter(path -> !path.equals(this.rootLocation))
-                    .map(path -> this.rootLocation.relativize(path));
+            return Files.walk(LocalOsService.rootLocation, 1)
+                    .filter(path -> !path.equals(LocalOsService.rootLocation))
+                    .map(path -> LocalOsService.rootLocation.relativize(path));
         } catch (IOException e) {
             throw new RuntimeException("Failed to read stored files", e);
         }

+ 1 - 1
litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/StorageService.java

@@ -10,7 +10,7 @@ import java.util.stream.Stream;
 /**
  * 对象存储接口
  */
-public interface StorageService {
+public interface ObjectStorageService {
 
     /**
      * 存储一个文件对象

+ 7 - 11
litemall-os-api/src/main/java/org/linlinjava/litemall/os/tencent/TencentOSService.java

@@ -1,4 +1,4 @@
-package org.linlinjava.litemall.os.tencent;
+package org.linlinjava.litemall.os.service;
 
 import com.qcloud.cos.COSClient;
 import com.qcloud.cos.ClientConfig;
@@ -8,7 +8,6 @@ import com.qcloud.cos.model.ObjectMetadata;
 import com.qcloud.cos.model.PutObjectRequest;
 import com.qcloud.cos.model.PutObjectResult;
 import com.qcloud.cos.region.Region;
-import org.linlinjava.litemall.os.service.StorageService;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.PropertySource;
 import org.springframework.core.io.Resource;
@@ -22,11 +21,13 @@ import java.nio.file.Path;
 import java.util.stream.Stream;
 
 /**
- * 腾讯对象存储服务类
+ * 腾讯对象存储服务
+ *
+ * 注意:虽然腾讯对象存储英文缩写是cos(cloud object storage),但这里称之为tos(tencent object storage)
  */
 @PropertySource(value = "classpath:tencent.properties")
-@Service("tencent")
-public class TencentOSService implements StorageService {
+@Service("tos")
+public class TencentOsService implements ObjectStorageService {
 
     @Value("${tencent.os.secretId}")
     private String accessKey;
@@ -39,10 +40,6 @@ public class TencentOSService implements StorageService {
 
     private COSClient cosClient;
 
-    public TencentOSService() {
-
-    }
-
     private COSClient getCOSClient() {
         if (cosClient == null) {
             // 1 初始化用户身份信息(secretId, secretKey)
@@ -56,7 +53,6 @@ public class TencentOSService implements StorageService {
     }
 
     private String getBaseUrl() {
-        //https://litemall-1256968571.cos-website.ap-guangzhou.myqcloud.com
         return "https://" + bucketName + ".cos-website." + region + ".myqcloud.com/";
     }
 
@@ -71,7 +67,7 @@ public class TencentOSService implements StorageService {
             PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, keyName, file.getInputStream(), objectMetadata);
             PutObjectResult putObjectResult = getCOSClient().putObject(putObjectRequest);
         } catch (Exception ex) {
-            System.console().printf(ex.getMessage());
+            ex.printStackTrace();
         }
     }
 

+ 2 - 2
litemall-os-api/src/main/java/org/linlinjava/litemall/os/web/OsStorageController.java

@@ -4,7 +4,7 @@ import org.linlinjava.litemall.core.util.CharUtil;
 import org.linlinjava.litemall.core.util.ResponseUtil;
 import org.linlinjava.litemall.db.domain.LitemallStorage;
 import org.linlinjava.litemall.db.service.LitemallStorageService;
-import org.linlinjava.litemall.os.service.StorageService;
+import org.linlinjava.litemall.os.service.ObjectStorageService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.Resource;
 import org.springframework.http.HttpHeaders;
@@ -25,7 +25,7 @@ import java.util.Map;
 public class OsStorageController {
 
     @javax.annotation.Resource(name="${activeStorage}")
-    private StorageService storageService;
+    private ObjectStorageService storageService;
     @Autowired
     private LitemallStorageService litemallStorageService;
 

+ 5 - 3
litemall-os-api/src/main/resources/application.properties

@@ -3,6 +3,8 @@ server.port=8081
 logging.level.org.linlinjava.litemall.os.Application=DEBUG
 
 
-# \u5B58\u50A8\u5B9E\u73B0\uFF0C\u53EF\u9009\u62E9 localStorage \u6216\u8005 tencent \uFF0C\u5982\u679C\u9009\u62E9 tencent\uFF0C\u9700\u8981\u5F00\u901A\u817E\u8BAF\u5BF9\u8C61\u5B58\u50A8\u5E76\u914D\u7F6E tencent.properties
-activeStorage=localStorage
-#activeStorage=tencent
+# 当前存储模式
+# los,本地对象存储模式,上传图片保存在服务器中
+# tos,腾讯对象存储模式,上传图片保存在腾讯云存储服务器中,请在tencent.properties配置相关信息
+activeStorage=los
+#activeStorage=tos

+ 6 - 6
litemall-os-api/src/main/resources/tencent.properties

@@ -1,6 +1,6 @@
-
-# \u817E\u8BAF\u4E91\u5B58\u50A8\u76F8\u5173\u914D\u7F6E,\u817E\u8BAF\u4E91\u5FC5\u987B\u6253\u5F00 #\u9759\u6001\u7F51\u7AD9(https://cloud.tencent.com/document/product/436/6249) \u652F\u6301\uFF0C\u5426\u5219\u56FE\u7247\u4F1A\u76F4\u63A5\u4E0B\u8F7D\u800C\u4E0D\u662F\u663E\u793A
-tencent.os.secretId=""
-tencent.os.secretKey=""
-tencent.os.region=""
-tencent.os.bucketName=""
+# 腾讯对象存储配置信息
+# 请参考 https://cloud.tencent.com/document/product/436/6249
+tencent.os.secretId="xxxxxx"
+tencent.os.secretKey="xxxxxx"
+tencent.os.region="xxxxxx"
+tencent.os.bucketName="xxxxxx"

+ 42 - 0
litemall-os-api/src/test/java/org/linlinjava/litemall/os/LosTest.java

@@ -0,0 +1,42 @@
+package org.linlinjava.litemall.os;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.linlinjava.litemall.os.service.LocalOsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.Resource;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.util.FileCopyUtils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+@WebAppConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class LosTest {
+    @Autowired
+    private LocalOsService localOsService;
+
+    @Test
+    public void test() throws IOException {
+        String test = getClass().getClassLoader().getResource("litemall.png").getFile();
+        byte[] content =  (byte[])FileCopyUtils.copyToByteArray(new FileInputStream(test));
+        MockMultipartFile mockMultipartFile = new MockMultipartFile("litemall.png", "litemall.png", "image/jpeg", content);
+        localOsService.store(mockMultipartFile, "los.png");
+        Resource resource = localOsService.loadAsResource("los.png");
+        String url = localOsService.generateUrl("los.png");
+        System.out.println("test file " + test);
+        System.out.println("store file " + resource.getURI());
+        System.out.println("generate url " + url);
+
+//        localOsService.delete("los.png");
+
+    }
+
+}

+ 42 - 0
litemall-os-api/src/test/java/org/linlinjava/litemall/os/TosTest.java

@@ -0,0 +1,42 @@
+package org.linlinjava.litemall.os;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.linlinjava.litemall.os.config.ObjectStorageConfig;
+import org.linlinjava.litemall.os.service.TencentOsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.Resource;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.util.FileCopyUtils;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+@WebAppConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class TosTest {
+    @Autowired
+    private TencentOsService tencentOsService;
+
+    @Test
+    public void test() throws IOException {
+        String test = getClass().getClassLoader().getResource("litemall.png").getFile();
+        byte[] content =  (byte[])FileCopyUtils.copyToByteArray(new FileInputStream(test));
+        MockMultipartFile mockMultipartFile = new MockMultipartFile("litemall.png", "litemall.png", "image/png", content);
+        tencentOsService.store(mockMultipartFile, "tos.png");
+        Resource resource = tencentOsService.loadAsResource("tos.png");
+        String url = tencentOsService.generateUrl("tos.png");
+        System.out.println("test file " + test);
+        System.out.println("store file " + resource.getURI());
+        System.out.println("generate url " + url);
+
+//        tencentOsService.delete("tos.png");
+    }
+
+}

BIN
litemall-os-api/src/test/resources/litemall.png