From 7676cdcdffa925c857a0c3de83911cd056dfabd5 Mon Sep 17 00:00:00 2001 From: Junling Bu Date: Sat, 28 Jul 2018 15:48:14 +0800 Subject: [PATCH] =?UTF-8?q?litemall-admin=E5=92=8Clitemall-wx=E7=9A=84?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0=E4=B8=8D=E5=86=8D=E4=BE=9D?= =?UTF-8?q?=E8=B5=96os=E6=A8=A1=E5=9D=97=EF=BC=8C=E8=80=8C=E6=98=AFlitemal?= =?UTF-8?q?l-admin-api=E5=92=8Clitemall-wx-api=E6=A8=A1=E5=9D=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/web/AdminStorageController.java | 113 ++++++++++++++++++ litemall-admin/config/dep.env.js | 3 +- litemall-admin/config/dev.env.js | 3 +- litemall-admin/config/prod.env.js | 3 +- litemall-admin/src/api/storage.js | 35 ++---- .../litemall/core/storage/LocalStorage.java | 5 +- .../src/main/resources/application-core.yml | 2 +- .../litemall/wx/web/WxStorageController.java | 107 +++++++++++++++++ litemall-wx/config/api.js | 16 +-- 9 files changed, 235 insertions(+), 52 deletions(-) create mode 100644 litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminStorageController.java create mode 100644 litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java diff --git a/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminStorageController.java b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminStorageController.java new file mode 100644 index 00000000..aaf512a0 --- /dev/null +++ b/litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminStorageController.java @@ -0,0 +1,113 @@ +package org.linlinjava.litemall.admin.web; + +import org.linlinjava.litemall.core.storage.StorageService; +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/admin/storage") +public class AdminStorageController { + + @Autowired + private StorageService storageService; + @Autowired + private LitemallStorageService litemallStorageService; + + private String generateKey(String originalFilename){ + int index = originalFilename.lastIndexOf('.'); + String suffix = originalFilename.substring(index); + + String key = null; + LitemallStorage storageInfo = null; + + do{ + key = CharUtil.getRandomString(20) + suffix; + storageInfo = litemallStorageService.findByKey(key); + } + while(storageInfo != null); + + return key; + } + + @GetMapping("/list") + public Object list(String key, String name, + @RequestParam(value = "page", defaultValue = "1") Integer page, + @RequestParam(value = "limit", defaultValue = "10") Integer limit, + String sort, String order){ + List storageList = litemallStorageService.querySelective(key, name, page, limit, sort, order); + int total = litemallStorageService.countSelective(key, name, page, limit, sort, order); + Map data = new HashMap<>(); + data.put("total", total); + data.put("items", storageList); + + return ResponseUtil.ok(data); + } + + @PostMapping("/create") + public Object create(@RequestParam("file") MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + InputStream inputStream = null; + try { + inputStream = file.getInputStream(); + } catch (IOException e) { + e.printStackTrace(); + return ResponseUtil.badArgumentValue(); + } + String key = generateKey(originalFilename); + storageService.store(file, key); + + String url = storageService.generateUrl(key); + LitemallStorage storageInfo = new LitemallStorage(); + storageInfo.setName(originalFilename); + storageInfo.setSize((int)file.getSize()); + storageInfo.setType(file.getContentType()); + storageInfo.setAddTime(LocalDateTime.now()); + storageInfo.setModified(LocalDateTime.now()); + storageInfo.setKey(key); + storageInfo.setUrl(url); + litemallStorageService.add(storageInfo); + return ResponseUtil.ok(storageInfo); + } + + @PostMapping("/read") + public Object read(Integer id) { + if(id == null){ + return ResponseUtil.badArgument(); + } + LitemallStorage storageInfo = litemallStorageService.findById(id); + if(storageInfo == null){ + return ResponseUtil.badArgumentValue(); + } + return ResponseUtil.ok(storageInfo); + } + + @PostMapping("/update") + public Object update(@RequestBody LitemallStorage litemallStorage) { + + litemallStorageService.update(litemallStorage); + return ResponseUtil.ok(litemallStorage); + } + + @PostMapping("/delete") + public Object delete(@RequestBody LitemallStorage litemallStorage) { + litemallStorageService.deleteByKey(litemallStorage.getKey()); + storageService.delete(litemallStorage.getKey()); + return ResponseUtil.ok(); + } +} diff --git a/litemall-admin/config/dep.env.js b/litemall-admin/config/dep.env.js index 512f55d7..db4d9480 100644 --- a/litemall-admin/config/dep.env.js +++ b/litemall-admin/config/dep.env.js @@ -1,6 +1,5 @@ module.exports = { NODE_ENV: '"production"', ENV_CONFIG: '"dep"', - BASE_API: '"http://122.152.206.172:8083/admin"', - OS_API: '"http://122.152.206.172:8081/os"' + BASE_API: '"http://122.152.206.172:8083/admin"' } diff --git a/litemall-admin/config/dev.env.js b/litemall-admin/config/dev.env.js index b82f20da..4629bf88 100644 --- a/litemall-admin/config/dev.env.js +++ b/litemall-admin/config/dev.env.js @@ -1,6 +1,5 @@ module.exports = { NODE_ENV: '"development"', ENV_CONFIG: '"dev"', - BASE_API: '"http://localhost:8083/admin"', - OS_API: '"http://localhost:8081/os"' + BASE_API: '"http://localhost:8083/admin"' } diff --git a/litemall-admin/config/prod.env.js b/litemall-admin/config/prod.env.js index c41e0a37..7477e14b 100644 --- a/litemall-admin/config/prod.env.js +++ b/litemall-admin/config/prod.env.js @@ -1,6 +1,5 @@ module.exports = { NODE_ENV: '"production"', ENV_CONFIG: '"prod"', - BASE_API: '"https://www.example.com/admin"', - OS_API: '"https://www.example.com/os"' + BASE_API: '"https://www.example.com/admin"' } diff --git a/litemall-admin/src/api/storage.js b/litemall-admin/src/api/storage.js index 07547fc8..be0307ed 100644 --- a/litemall-admin/src/api/storage.js +++ b/litemall-admin/src/api/storage.js @@ -1,28 +1,7 @@ -import axios from 'axios' -import { Message } from 'element-ui' - -// create an axios instance -const service = axios.create({ - baseURL: process.env.OS_API, // api的base_url - timeout: 5000 // request timeout -}) - -// respone interceptor -service.interceptors.response.use( - response => { - return response - }, error => { - console.log('err' + error)// for debug - Message({ - message: '对象存储服务访问超时,请检查链接是否能够访问。', - type: 'error', - duration: 5 * 1000 - }) - return Promise.reject(error) - }) +import request from '@/utils/request' export function listStorage(query) { - return service({ + return request({ url: '/storage/list', method: 'get', params: query @@ -30,7 +9,7 @@ export function listStorage(query) { } export function createStorage(data) { - return service({ + return request({ url: '/storage/create', method: 'post', data @@ -38,7 +17,7 @@ export function createStorage(data) { } export function readStorage(data) { - return service({ + return request({ url: '/storage/read', method: 'get', data @@ -46,7 +25,7 @@ export function readStorage(data) { } export function updateStorage(data) { - return service({ + return request({ url: '/storage/update', method: 'post', data @@ -54,12 +33,12 @@ export function updateStorage(data) { } export function deleteStorage(data) { - return service({ + return request({ url: '/storage/delete', method: 'post', data }) } -const uploadPath = process.env.OS_API + '/storage/create' +const uploadPath = process.env.BASE_API + '/storage/create' export { uploadPath } diff --git a/litemall-core/src/main/java/org/linlinjava/litemall/core/storage/LocalStorage.java b/litemall-core/src/main/java/org/linlinjava/litemall/core/storage/LocalStorage.java index e2922546..345fff5b 100644 --- a/litemall-core/src/main/java/org/linlinjava/litemall/core/storage/LocalStorage.java +++ b/litemall-core/src/main/java/org/linlinjava/litemall/core/storage/LocalStorage.java @@ -110,10 +110,7 @@ public class LocalStorage implements Storage { @Override public String generateUrl(String keyName) { - String url = address + ":" + port + "/os/storage/fetch/" + keyName; - if (!url.startsWith("http")) { - url = "http://" + url; - } + String url = address + keyName; return url; } } \ No newline at end of file diff --git a/litemall-core/src/main/resources/application-core.yml b/litemall-core/src/main/resources/application-core.yml index 1e2bd9f8..69b561c0 100644 --- a/litemall-core/src/main/resources/application-core.yml +++ b/litemall-core/src/main/resources/application-core.yml @@ -88,7 +88,7 @@ litemall: # 本地对象存储配置信息 local: storagePath: storage - address: http://127.0.0.1 + address: http://localhost:8082/wx/storage/fetch/ port: 8081 # 阿里云对象存储配置信息 aliyun: diff --git a/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java new file mode 100644 index 00000000..6f19df9d --- /dev/null +++ b/litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxStorageController.java @@ -0,0 +1,107 @@ +package org.linlinjava.litemall.wx.web; + +import org.linlinjava.litemall.core.storage.StorageService; +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/wx/storage") +public class WxStorageController { + + @Autowired + private StorageService storageService; + @Autowired + private LitemallStorageService litemallStorageService; + + private String generateKey(String originalFilename){ + int index = originalFilename.lastIndexOf('.'); + String suffix = originalFilename.substring(index); + + String key = null; + LitemallStorage storageInfo = null; + + do{ + key = CharUtil.getRandomString(20) + suffix; + storageInfo = litemallStorageService.findByKey(key); + } + while(storageInfo != null); + + return key; + } + + @PostMapping("/upload") + public Object upload(@RequestParam("file") MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + InputStream inputStream = null; + try { + inputStream = file.getInputStream(); + } catch (IOException e) { + e.printStackTrace(); + return ResponseUtil.badArgumentValue(); + } + String key = generateKey(originalFilename); + storageService.store(file, key); + + String url = storageService.generateUrl(key); + LitemallStorage storageInfo = new LitemallStorage(); + storageInfo.setName(originalFilename); + storageInfo.setSize((int)file.getSize()); + storageInfo.setType(file.getContentType()); + storageInfo.setAddTime(LocalDateTime.now()); + storageInfo.setModified(LocalDateTime.now()); + storageInfo.setKey(key); + storageInfo.setUrl(url); + litemallStorageService.add(storageInfo); + return ResponseUtil.ok(storageInfo); + } + + @GetMapping("/fetch/{key:.+}") + public ResponseEntity fetch(@PathVariable String key) { + LitemallStorage litemallStorage = litemallStorageService.findByKey(key); + if(key == null){ + ResponseEntity.notFound(); + } + String type = litemallStorage.getType(); + MediaType mediaType = MediaType.parseMediaType(type); + + Resource file = storageService.loadAsResource(key); + if(file == null) { + ResponseEntity.notFound(); + } + return ResponseEntity.ok().contentType(mediaType).body(file); + } + + @GetMapping("/download/{key:.+}") + public ResponseEntity download(@PathVariable String key) { + LitemallStorage litemallStorage = litemallStorageService.findByKey(key); + if(key == null){ + ResponseEntity.notFound(); + } + String type = litemallStorage.getType(); + MediaType mediaType = MediaType.parseMediaType(type); + + Resource file = storageService.loadAsResource(key); + if(file == null) { + ResponseEntity.notFound(); + } + return ResponseEntity.ok().contentType(mediaType).header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"" + file.getFilename() + "\"").body(file); + } + +} diff --git a/litemall-wx/config/api.js b/litemall-wx/config/api.js index be425adc..9f722565 100644 --- a/litemall-wx/config/api.js +++ b/litemall-wx/config/api.js @@ -1,23 +1,13 @@ // 以下是业务服务器API地址 // 本机开发时使用 -// var WxApiRoot = 'http://localhost:8082/wx/'; + var WxApiRoot = 'http://localhost:8082/wx/'; // 局域网测试使用 // var WxApiRoot = 'http://192.168.0.101:8082/wx/'; // 云平台部署时使用 -var WxApiRoot = 'http://122.152.206.172:8082/wx/'; +// var WxApiRoot = 'http://122.152.206.172:8082/wx/'; // 云平台上线时使用 // var WxApiRoot = 'https://www.menethil.com.cn/wx/'; -// 以下是图片存储服务器API地址 -// 本机开发时使用 -// var StorageApi = 'http://localhost:8081/os/storage/create'; -// 局域网测试时使用 -// var StorageApi = 'http://192.168.0.101:8081/os/storage/create'; -// 云平台部署时使用 -var StorageApi = 'http://122.152.206.172:8081/os/storage/create'; -// 云平台上线时使用 -// var StorageApi = 'https://www.menethil.com.cn/os/storage/create'; - module.exports = { IndexUrl: WxApiRoot + 'home/index', //首页数据接口 CatalogList: WxApiRoot + 'catalog/index', //分类目录全部分类数据接口 @@ -89,5 +79,5 @@ module.exports = { UserFormIdCreate: WxApiRoot + 'formid/create', //用户FromId,用于发送模版消息 - StorageUpload: StorageApi, //图片上传 + StorageUpload: WxApiRoot + 'storage/upload' //图片上传 }; \ No newline at end of file