x1ongzhu 7 years ago
parent
commit
17c0d6e0c9

+ 6 - 0
pom.xml

@@ -98,6 +98,12 @@
             <version>3.4.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>2.8.3</version>
+        </dependency>
+
         <!--test dependency-->
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 20 - 16
src/main/java/com/izouma/walkchina/configuration/WxMaRedisConfig.java → src/main/java/com/izouma/walkchina/configuration/MiniAppConfig.java

@@ -2,9 +2,11 @@ package com.izouma.walkchina.configuration;
 
 import cn.binarywang.wx.miniapp.config.WxMaConfig;
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import lombok.Data;
 import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
@@ -14,18 +16,20 @@ import java.util.Map;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+@Data
 @Component
-public class WxMaRedisConfig implements WxMaConfig {
+@ConfigurationProperties(prefix = "wx.miniapp")
+public class MiniAppConfig implements WxMaConfig {
     private final String REDIS_KEY = "miniAppAccessToken";
 
     @Autowired
     private RedisTemplate redisTemplate;
 
-    private volatile String msgDataFormat;
-    private volatile String appid;
-    private volatile String secret;
-    private volatile String token;
-    private volatile String aesKey;
+    private String appId;
+    private String appSecret;
+    private String msgToken;
+    private String msgAesKey;
+    private String msgFormat;
 
     private volatile String httpProxyHost;
     private volatile int    httpProxyPort;
@@ -158,20 +162,20 @@ public class WxMaRedisConfig implements WxMaConfig {
 
     @Override
     public String getSecret() {
-        return this.secret;
+        return this.appSecret;
     }
 
     public void setSecret(String secret) {
-        this.secret = secret;
+        this.appSecret = secret;
     }
 
     @Override
     public String getToken() {
-        return this.token;
+        return this.msgToken;
     }
 
     public void setToken(String token) {
-        this.token = token;
+        this.msgToken = token;
     }
 
     @Override
@@ -186,20 +190,20 @@ public class WxMaRedisConfig implements WxMaConfig {
 
     @Override
     public String getAesKey() {
-        return this.aesKey;
+        return this.msgAesKey;
     }
 
     public void setAesKey(String aesKey) {
-        this.aesKey = aesKey;
+        this.msgAesKey = aesKey;
     }
 
     @Override
     public String getMsgDataFormat() {
-        return this.msgDataFormat;
+        return this.msgFormat;
     }
 
     public void setMsgDataFormat(String msgDataFormat) {
-        this.msgDataFormat = msgDataFormat;
+        this.msgFormat = msgDataFormat;
     }
 
     @Override
@@ -259,10 +263,10 @@ public class WxMaRedisConfig implements WxMaConfig {
 
     @Override
     public String getAppid() {
-        return appid;
+        return appId;
     }
 
     public void setAppid(String appid) {
-        this.appid = appid;
+        this.appId = appid;
     }
 }

+ 5 - 17
src/main/java/com/izouma/walkchina/configuration/WechatConfig.java

@@ -2,32 +2,20 @@ package com.izouma.walkchina.configuration;
 
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
-@ConfigurationProperties(prefix = "wx.miniapp")
-@Data
 public class WechatConfig {
-    private String appId;
-    private String appSecret;
-    private String msgToken;
-    private String msgAesKey;
-    private String msgFormat;
+
+    @Autowired
+    private MiniAppConfig miniAppConfig;
 
     @Bean
     public WxMaService wxMaService() {
         WxMaService service = new WxMaServiceImpl();
-        WxMaRedisConfig config = new WxMaRedisConfig();
-        config.setAppid(appId);
-        config.setSecret(appSecret);
-        config.setToken(msgAesKey);
-        config.setAesKey(msgAesKey);
-        config.setMsgDataFormat(msgFormat);
-        service.setWxMaConfig(config);
+        service.setWxMaConfig(miniAppConfig);
         return service;
     }
-
 }

+ 8 - 0
src/main/java/com/izouma/walkchina/domain/UserInfo.java

@@ -76,6 +76,14 @@ public class UserInfo implements UserDetails {
     @Builder.Default
     private Boolean active = true;
 
+    @JsonInclude
+    @Transient
+    private String sessionKey;
+
+    @JsonInclude
+    @Transient
+    private String token;
+
     @Override
     @JsonIgnore
     public Collection<? extends GrantedAuthority> getAuthorities() {

+ 1 - 1
src/main/java/com/izouma/walkchina/exception/ServiceException.java

@@ -1,6 +1,6 @@
 package com.izouma.walkchina.exception;
 
-public class ServiceException extends Exception {
+public class ServiceException extends RuntimeException {
     private static final long serialVersionUID = 3779880207424189309L;
 
     public ServiceException(String message) {

+ 3 - 0
src/main/java/com/izouma/walkchina/repo/UserInfoRepository.java

@@ -3,5 +3,8 @@ package com.izouma.walkchina.repo;
 import com.izouma.walkchina.domain.UserInfo;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.Optional;
+
 public interface UserInfoRepository extends JpaRepository<UserInfo, Long> {
+    Optional<UserInfo> findByOpenId(String openId);
 }

+ 51 - 1
src/main/java/com/izouma/walkchina/service/UserInfoService.java

@@ -1,16 +1,23 @@
 package com.izouma.walkchina.service;
 
 import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
 import com.izouma.walkchina.domain.UserInfo;
 import com.izouma.walkchina.exception.ServiceException;
 import com.izouma.walkchina.repo.UserInfoRepository;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Example;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.PostConstruct;
+import java.util.UUID;
+
 
 @Service
 @Slf4j
@@ -28,7 +35,7 @@ public class UserInfoService implements UserDetailsService {
         return userInfoRepository.findOne(Example.of(userInfo)).orElse(null);
     }
 
-    public UserInfo registerByUserPwd(String username, String password) throws ServiceException {
+    public UserInfo registerByUserPwd(String username, String password) {
         UserInfo userInfo = userInfoRepository.findOne(Example.of(UserInfo.builder().username(username).build())).orElse(null);
         if (userInfo != null) {
             throw new ServiceException("该用户已存在");
@@ -40,4 +47,47 @@ public class UserInfoService implements UserDetailsService {
         userInfo = userInfoRepository.save(userInfo);
         return userInfo;
     }
+
+    public UserInfo loginMiniApp(String code) {
+        try {
+            WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
+            String openId = result.getOpenid();
+            String sessionKey = result.getSessionKey();
+            UserInfo userInfo = userInfoRepository.findByOpenId(openId).orElse(null);
+            if (userInfo != null) {
+                return userInfo;
+            }
+            userInfo = UserInfo.builder()
+                    .username(UUID.randomUUID().toString())
+                    .nickname("用户" + RandomStringUtils.randomAlphabetic(6))
+                    .openId(openId)
+                    .avatar("https://microball.oss-cn-hangzhou.aliyuncs.com/awesomeAdmin/user.png")
+                    .sex(0)
+                    .active(true)
+                    .sessionKey(sessionKey)
+                    .build();
+            return userInfoRepository.save(userInfo);
+        } catch (WxErrorException e) {
+            e.printStackTrace();
+        }
+        throw new ServiceException("登录失败");
+    }
+
+    public UserInfo getWxUserInfo(String sessionKey, String rawData, String signature,
+                                  String encryptedData, String iv) {
+        // 用户信息校验
+        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
+            throw new ServiceException("获取用户信息失败");
+        }
+
+        // 解密用户信息
+        WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
+        UserInfo userInfo = userInfoRepository.findByOpenId(wxUserInfo.getOpenId()).orElse(null);
+        if (userInfo == null) {
+
+        } else {
+
+        }
+        throw new ServiceException("获取用户信息失败");
+    }
 }

+ 67 - 0
src/main/java/com/izouma/walkchina/service/storage/AliStorageService.java

@@ -0,0 +1,67 @@
+package com.izouma.walkchina.service.storage;
+
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.izouma.walkchina.exception.ServiceException;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Data
+@Service
+@Slf4j
+@EnableConfigurationProperties
+@ConfigurationProperties(prefix = "aliyun")
+@ConditionalOnProperty(name = "storage.provider", havingValue = "aliyun")
+public class AliStorageService implements StorageService {
+    private String accessKeyId;
+    private String accessKeySecret;
+    private String ossBucketName;
+    private String ossEndPoint;
+    private String ossDomain;
+
+    @Override
+    public String uploadFromInputStream(InputStream inputStream, String path) {
+        log.info("阿里云OSS上传: inputStream -> {}", path);
+        try {
+            return upload(inputStream, path);
+        } catch (Exception e) {
+            log.error("阿里云OSS上传失败", e);
+        }
+        throw new ServiceException("上传失败");
+    }
+
+    @Override
+    public String uploadFromUrl(String url, String path) {
+        log.info("阿里云OSS上传: {} -> {}", url, path);
+        try {
+            InputStream inputStream = new URL(url).openStream();
+            return upload(inputStream, path);
+        } catch (Exception e) {
+            log.error("阿里云OSS上传失败", e);
+        }
+        throw new ServiceException("上传失败");
+    }
+
+    private String upload(InputStream inputStream, String path) {
+        OSSClient client = new OSSClient(ossEndPoint, accessKeyId, accessKeySecret);
+        client.putObject(ossBucketName, path, inputStream, new ObjectMetadata());
+        client.shutdown();
+        try {
+            inputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return ossDomain + "/" + path;
+    }
+
+}

+ 61 - 0
src/main/java/com/izouma/walkchina/service/storage/LocalStorageService.java

@@ -0,0 +1,61 @@
+package com.izouma.walkchina.service.storage;
+
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.izouma.walkchina.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Service
+@Slf4j
+@ConditionalOnProperty(name = "storage.provider", havingValue = "local")
+public class LocalStorageService implements StorageService {
+
+    @Override
+    public String uploadFromInputStream(InputStream fin, String path) {
+        log.info("本地上传: inputStream -> {}", path);
+        try {
+            return upload(fin, path);
+        } catch (IOException e) {
+            log.error("本地上传失败", e);
+        }
+        throw new ServiceException("上传失败");
+    }
+
+    @Override
+    public String uploadFromUrl(String url, String path) {
+        log.info("本地上传: {} -> {}", url, path);
+        try {
+            InputStream inputStream = new URL(url).openStream();
+            return upload(inputStream, path);
+        } catch (Exception e) {
+            log.error("本地上传失败", e);
+        }
+        throw new ServiceException("上传失败");
+    }
+
+    private String upload(InputStream inputStream, String path) throws IOException {
+        Path uploadPath = Paths.get(path).getParent();
+        if (Files.notExists(uploadPath, LinkOption.values())) {
+            Files.createDirectories(uploadPath);
+        }
+        FileUtils.copyToFile(inputStream, new File(path));
+        try {
+            inputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return "files" + "/" + path;
+    }
+}

+ 9 - 0
src/main/java/com/izouma/walkchina/service/storage/StorageService.java

@@ -0,0 +1,9 @@
+package com.izouma.walkchina.service.storage;
+
+import java.io.InputStream;
+
+public interface StorageService {
+    String uploadFromInputStream(InputStream fin, String path);
+
+    String uploadFromUrl(String url, String path);
+}

+ 80 - 0
src/main/java/com/izouma/walkchina/web/FileUploadController.java

@@ -0,0 +1,80 @@
+package com.izouma.walkchina.web;
+
+import com.izouma.walkchina.domain.Result;
+import com.izouma.walkchina.service.storage.StorageService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.util.Base64Utils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URLConnection;
+import java.text.SimpleDateFormat;
+import java.util.Base64;
+import java.util.Date;
+
+
+@RestController
+@RequestMapping("/upload")
+@Slf4j
+public class FileUploadController {
+
+    @Autowired
+    private StorageService storageService;
+
+    @PostMapping("/file")
+    public Result uploadFile(@RequestParam("file") MultipartFile file,
+                             @RequestParam(value = "path", required = false) String path) {
+        if (path == null) {
+            String basePath = "application";
+            try {
+                basePath = file.getContentType().split("/")[0];
+            } catch (Exception ignored) {
+            }
+            path = basePath + "/" + new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(new Date())
+                    + RandomStringUtils.randomAlphabetic(8)
+                    + "." + FilenameUtils.getExtension(file.getOriginalFilename());
+        }
+        InputStream is;
+        try {
+            is = file.getInputStream();
+        } catch (IOException e) {
+            log.error("上传失败", e);
+            return Result.error("上传失败");
+        }
+        String result = storageService.uploadFromInputStream(is, path);
+        return Result.ok(result);
+    }
+
+    @PostMapping("/base64")
+    public Result uploadImage(@RequestParam("base64") String base64,
+                              @RequestParam(value = "path", required = false) String path) {
+        base64 = base64.substring(base64.indexOf(',') + 1);
+        Base64.Decoder decoder = Base64.getDecoder();
+        if (path == null) {
+            String ext = ".jpg";
+            try {
+                InputStream is = new ByteArrayInputStream(decoder.decode(base64.getBytes()));
+                String type = URLConnection.guessContentTypeFromStream(is);
+                ext = type.replace("image/", ".").replace("jpeg", "jpg");
+            } catch (Exception ignored) {
+            }
+            path = "image/" + new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(new Date())
+                    + RandomStringUtils.randomAlphabetic(8) + ext;
+        }
+        InputStream is;
+        try {
+            is = new ByteArrayInputStream(decoder.decode(base64.getBytes()));
+        } catch (Exception e) {
+            log.error("上传失败", e);
+            return Result.error("上传失败");
+        }
+        String result = storageService.uploadFromInputStream(is, path);
+        return Result.ok(result);
+    }
+}

+ 0 - 1
src/main/java/com/izouma/walkchina/web/UserInfoController.java

@@ -4,7 +4,6 @@ import com.izouma.walkchina.domain.Result;
 import com.izouma.walkchina.domain.UserInfo;
 import com.izouma.walkchina.repo.UserInfoRepository;
 import org.springframework.data.domain.Example;
-import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;

+ 46 - 8
src/main/resources/application.yaml

@@ -1,18 +1,19 @@
 server:
   port: 8080
   servlet:
-    context-path: /
+    context_path: /
 spring:
+  profiles:
+    active: dev
   datasource:
-    url: jdbc:mysql://120.55.131.232:3306/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
     username: microball
     password: 2wsx@WSX#EDC
   jpa:
     database: MySQL
-    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
-    show-sql: true
+    database_platform: org.hibernate.dialect.MySQL5InnoDBDialect
+    show_sql: true
     hibernate:
-      ddl-auto: update
+      ddl_auto: update
     properties:
       hibernate:
         enable_lazy_load_no_trans: true
@@ -21,9 +22,13 @@ spring:
     port: 6379
     lettuce:
       pool:
-        max-active: 8
-        max-idle: 8
-        min-idle: 0
+        max_active: 8
+        max_idle: 8
+        min_idle: 0
+  servlet:
+    multipart:
+      max_file_size: 100MB
+      max_request_size: 100MB
 jwt:
   secret: javainuse
 wx:
@@ -33,5 +38,38 @@ wx:
     msg_token: msgToken
     msg_aes_key: aesKey
     msg_format: JSON
+storage:
+  provider: local
+  local_path:
+aliyun:
+  access_key_id: PXzJyah5rZfWHIIH
+  access_key_secret: e1MS6j0wypXJrw8CM0hObZu8qKbfah
+  oss_bucket_name: walk-china
+  oss_domain: http://walk-china.oss-cn-hangzhou.aliyuncs.com
+
+---
+
+spring:
+  profiles: dev
+  datasource:
+    url: jdbc:mysql://120.55.131.232:3306/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+aliyun:
+  oss_end_point: oss-cn-hangzhou.aliyuncs.com
 
+---
 
+spring:
+  profiles: test
+  datasource:
+    url: jdbc:mysql://rdsave1o67m1ido6gwp6.mysql.rds.aliyuncs.com/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+aliyun:
+  oss_end_point: oss-cn-hangzhou-internal.aliyuncs.com
+
+---
+
+spring:
+  profiles: prod
+  datasource:
+    url: jdbc:mysql://rdsave1o67m1ido6gwp6.mysql.rds.aliyuncs.com/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+aliyun:
+  oss_end_point: oss-cn-hangzhou-internal.aliyuncs.com

+ 18 - 0
src/main/resources/static/1.yaml

@@ -0,0 +1,18 @@
+server:
+  port: 8083
+  servlet:
+    context-path: /
+spring:
+  datasource:
+    url: jdbc:mysql://120.55.131.232:3306/walk_china?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
+    username: microball
+    password: 2wsx@WSX#EDC
+  jpa:
+    database: MySQL
+    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
+    show-sql: true
+    hibernate:
+      ddl-auto: update
+    properties:
+      hibernate:
+        enable_lazy_load_no_trans: true

+ 22 - 0
src/test/java/com/izouma/walkchina/StorageTest.java

@@ -0,0 +1,22 @@
+package com.izouma.walkchina;
+
+import com.izouma.walkchina.service.storage.AliStorageService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class StorageTest {
+    @Autowired
+    private AliStorageService aliStorageService;
+
+    @Test
+    public void testUpload() {
+        aliStorageService.uploadFromInputStream(null, "test/1.jpg");
+
+
+    }
+}