diff --git a/litemall-core/src/main/resources/notify.properties b/litemall-core/src/main/resources/notify.properties index 313e3278..9606a29e 100644 --- a/litemall-core/src/main/resources/notify.properties +++ b/litemall-core/src/main/resources/notify.properties @@ -1,19 +1,19 @@ -# \u90AE\u4EF6\u53D1\u9001\u914D\u7F6E +# 邮件发送配置 sprint.mail.enable=false spring.mail.host=smtp.exmail.qq.com spring.mail.username=xxxxxx spring.mail.password=xxxxxx spring.mail.sendto=example@qq.com -# \u77ED\u4FE1\u53D1\u9001\u914D\u7F6E +# 短信发送配置 spring.sms.enable=false spring.sms.appid=111111 spring.sms.appkey=xxxxxx spring.sms.sign=xxxxxx -# \u77ED\u4FE1\u6A21\u677F\u6D88\u606F\u914D\u7F6E -# \u8BF7\u5728\u817E\u8BAF\u77ED\u4FE1\u5E73\u53F0\u914D\u7F6E\u901A\u77E5\u6D88\u606F\u6A21\u677F\uFF0C\u7136\u540E\u8FD9\u91CC\u8BBE\u7F6E\u4E0D\u540C\u77ED\u4FE1\u6A21\u677FID -# \u8BF7\u53C2\u8003LitemallNotifyService.notifySMSTemplate +# 短信模板消息配置 +# 请在腾讯短信平台配置通知消息模板,然后这里设置不同短信模板ID +# 请参考LitemallNotifyService.notifySMSTemplate spring.sms.template.paySucceed=111111 spring.sms.template.captcha=222222 diff --git a/litemall-os-api/.gitignore b/litemall-os-api/.gitignore index ee0b013a..63b6b474 100644 --- a/litemall-os-api/.gitignore +++ b/litemall-os-api/.gitignore @@ -1,3 +1,4 @@ /target/ /litemall-os-api.iml +/storage/ diff --git a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/FileSystemStorageService.java b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/LocalOsService.java similarity index 81% rename from litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/FileSystemStorageService.java rename to litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/LocalOsService.java index 3fef0c31..ebe2af6b 100644 --- a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/FileSystemStorageService.java +++ b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/LocalOsService.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 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); } diff --git a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/StorageService.java b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/ObjectStorageService.java similarity index 94% rename from litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/StorageService.java rename to litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/ObjectStorageService.java index 2354e9c1..6b2df45b 100644 --- a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/StorageService.java +++ b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/ObjectStorageService.java @@ -10,7 +10,7 @@ import java.util.stream.Stream; /** * 对象存储接口 */ -public interface StorageService { +public interface ObjectStorageService { /** * 存储一个文件对象 diff --git a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/tencent/TencentOSService.java b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/TencentOsService.java similarity index 90% rename from litemall-os-api/src/main/java/org/linlinjava/litemall/os/tencent/TencentOSService.java rename to litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/TencentOsService.java index a3d02501..eefce850 100644 --- a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/tencent/TencentOSService.java +++ b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/service/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(); } } diff --git a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/web/OsStorageController.java b/litemall-os-api/src/main/java/org/linlinjava/litemall/os/web/OsStorageController.java index 451ce81c..13a31105 100644 --- a/litemall-os-api/src/main/java/org/linlinjava/litemall/os/web/OsStorageController.java +++ b/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; diff --git a/litemall-os-api/src/main/resources/application.properties b/litemall-os-api/src/main/resources/application.properties index 59eb1f3b..cb2d82a3 100644 --- a/litemall-os-api/src/main/resources/application.properties +++ b/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 diff --git a/litemall-os-api/src/main/resources/tencent.properties b/litemall-os-api/src/main/resources/tencent.properties index 435d03ba..6d9052b6 100644 --- a/litemall-os-api/src/main/resources/tencent.properties +++ b/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" diff --git a/litemall-os-api/src/test/java/org/linlinjava/litemall/os/LosTest.java b/litemall-os-api/src/test/java/org/linlinjava/litemall/os/LosTest.java new file mode 100644 index 00000000..002c90a2 --- /dev/null +++ b/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"); + + } + +} \ No newline at end of file diff --git a/litemall-os-api/src/test/java/org/linlinjava/litemall/os/TosTest.java b/litemall-os-api/src/test/java/org/linlinjava/litemall/os/TosTest.java new file mode 100644 index 00000000..c84d3d2e --- /dev/null +++ b/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"); + } + +} \ No newline at end of file diff --git a/litemall-os-api/src/test/resources/litemall.png b/litemall-os-api/src/test/resources/litemall.png new file mode 100644 index 00000000..d16e9afa Binary files /dev/null and b/litemall-os-api/src/test/resources/litemall.png differ