Skip to content

Commit 57241f5

Browse files
author
pedro
authored
Merge pull request #12 from TaleLin/feat/qiniu-upload
Feat/qiniu upload
2 parents da16a9c + 581e91d commit 57241f5

15 files changed

Lines changed: 525 additions & 187 deletions

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@
8484
<version>${hutool.version}</version>
8585
</dependency>
8686

87+
<dependency>
88+
<groupId>com.qiniu</groupId>
89+
<artifactId>qiniu-java-sdk</artifactId>
90+
<version>7.2.28</version>
91+
</dependency>
8792

8893
<dependency>
8994
<groupId>org.springframework.boot</groupId>

src/main/java/io/github/talelin/merak/common/utils/ResponseUtil.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package io.github.talelin.merak.common.utils;
22

3+
import io.github.talelin.merak.vo.PageResponseVO;
34
import io.github.talelin.merak.vo.UnifyResponseVO;
45
import io.github.talelin.autoconfigure.exception.HttpException;
56
import io.github.talelin.autoconfigure.response.Created;
67
import io.github.talelin.autoconfigure.response.Success;
78
import io.github.talelin.autoconfigure.beans.Code;
89
import io.github.talelin.autoconfigure.utils.RequestUtil;
910
import lombok.extern.slf4j.Slf4j;
11+
import org.springframework.web.context.request.RequestContextHolder;
12+
import org.springframework.web.context.request.ServletRequestAttributes;
13+
14+
import javax.servlet.http.HttpServletResponse;
15+
import java.util.List;
1016

1117

1218
/**
@@ -15,6 +21,19 @@
1521
@Slf4j
1622
public class ResponseUtil {
1723

24+
/**
25+
* 获得当前响应
26+
*
27+
* @return 响应
28+
*/
29+
public static HttpServletResponse getResponse() {
30+
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
31+
}
32+
33+
public static void setCurrentResponseHttpStatus(int httpStatus) {
34+
getResponse().setStatus(httpStatus);
35+
}
36+
1837
public static UnifyResponseVO generateUnifyResponse(HttpException e) {
1938
return UnifyResponseVO.builder()
2039
.message(e.getMessage())
@@ -41,6 +60,7 @@ public static <T> UnifyResponseVO<T> generateUnifyResponse(int code) {
4160

4261
public static <T> UnifyResponseVO<T> generateCreatedResponse(T data) {
4362
Created created = new Created();
63+
setCurrentResponseHttpStatus(created.getHttpCode());
4464
return (UnifyResponseVO<T>) UnifyResponseVO.builder()
4565
.message(data)
4666
.code(created.getCode())
@@ -49,10 +69,15 @@ public static <T> UnifyResponseVO<T> generateCreatedResponse(T data) {
4969
}
5070

5171
public static <T> UnifyResponseVO<T> generateUnifyResponse(Code code, int httpCode) {
72+
setCurrentResponseHttpStatus(httpCode);
5273
return (UnifyResponseVO<T>) UnifyResponseVO.builder()
5374
.code(code.getCode())
5475
.message(code.getDescription())
5576
.request(RequestUtil.getSimpleRequest())
5677
.build();
5778
}
79+
80+
public static PageResponseVO generatePageResult(long total, List items, long page, long count) {
81+
return new PageResponseVO(total, items, page, count);
82+
}
5883
}

src/main/java/io/github/talelin/merak/controller/cms/AdminController.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import io.github.talelin.merak.model.GroupDO;
1515
import io.github.talelin.merak.dto.admin.*;
1616
import io.github.talelin.merak.vo.UserInfoVO;
17-
import io.github.talelin.merak.dto.admin.*;
1817
import org.springframework.beans.factory.annotation.Autowired;
1918
import org.springframework.validation.annotation.Validated;
2019
import org.springframework.web.bind.annotation.*;
@@ -64,7 +63,7 @@ public PageResponseVO getUsers(
6463
List<GroupDO> groups = groupService.getUserGroupsByUserId(user.getId());
6564
return new UserInfoVO(user, groups);
6665
}).collect(Collectors.toList());
67-
return PageResponseVO.genPageResult(iPage.getTotal(), userInfos, page, count);
66+
return ResponseUtil.generatePageResult(iPage.getTotal(), userInfos, page, count);
6867
}
6968

7069
@PutMapping("/user/{id}/password")
@@ -83,7 +82,6 @@ public UnifyResponseVO deleteUser(@PathVariable @Positive(message = "{id}") Long
8382
return ResponseUtil.generateUnifyResponse(3);
8483
}
8584

86-
8785
@PutMapping("/user/{id}")
8886
@AdminRequired
8987
@RouteMeta(permission = "管理员更新用户信息", module = "管理员")
@@ -101,10 +99,9 @@ public PageResponseVO getGroups(
10199
@RequestParam(name = "page", required = false, defaultValue = "0")
102100
@Min(value = 0, message = "{page}") Long page) {
103101
IPage<GroupDO> iPage = adminService.getGroupPage(page, count);
104-
return PageResponseVO.genPageResult(iPage.getTotal(), iPage.getRecords(), page, count);
102+
return ResponseUtil.generatePageResult(iPage.getTotal(), iPage.getRecords(), page, count);
105103
}
106104

107-
108105
@GetMapping("/group/all")
109106
@AdminRequired
110107
@RouteMeta(permission = "查询所有权限组", module = "管理员")
@@ -121,7 +118,6 @@ public GroupPermissionsBO getGroup(@PathVariable @Positive(message = "{id}") Lon
121118
return groupPermissions;
122119
}
123120

124-
125121
@PostMapping("/group")
126122
@AdminRequired
127123
@RouteMeta(permission = "新建权限组", module = "管理员")
@@ -130,7 +126,6 @@ public UnifyResponseVO createGroup(@RequestBody @Validated NewGroupDTO validator
130126
return ResponseUtil.generateUnifyResponse(13);
131127
}
132128

133-
134129
@PutMapping("/group/{id}")
135130
@AdminRequired
136131
@RouteMeta(permission = "更新一个权限组", module = "管理员")

src/main/java/io/github/talelin/merak/controller/cms/LogController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.baomidou.mybatisplus.core.metadata.IPage;
44
import io.github.talelin.core.annotation.GroupRequired;
55
import io.github.talelin.core.annotation.RouteMeta;
6+
import io.github.talelin.merak.common.utils.ResponseUtil;
67
import io.github.talelin.merak.model.LogDO;
78
import io.github.talelin.merak.vo.PageResponseVO;
89
import io.github.talelin.merak.service.LogService;
@@ -37,7 +38,7 @@ public PageResponseVO getLogs(
3738
@RequestParam(name = "page", required = false, defaultValue = "0")
3839
@Min(value = 0, message = "{page}") Long page) {
3940
IPage<LogDO> iPage = logService.getLogPage(page, count, name, start, end);
40-
return PageResponseVO.genPageResult(iPage.getTotal(), iPage.getRecords(), page, count);
41+
return ResponseUtil.generatePageResult(iPage.getTotal(), iPage.getRecords(), page, count);
4142
}
4243

4344
@GetMapping("/search")
@@ -53,7 +54,7 @@ public PageResponseVO searchLogs(
5354
@RequestParam(name = "page", required = false, defaultValue = "0")
5455
@Min(value = 0, message = "{page}") Long page) {
5556
IPage<LogDO> iPage = logService.searchLogPage(page, count, name, keyword, start, end);
56-
return PageResponseVO.genPageResult(iPage.getTotal(), iPage.getRecords(), page, count);
57+
return ResponseUtil.generatePageResult(iPage.getTotal(), iPage.getRecords(), page, count);
5758
}
5859

5960
@GetMapping("/users")
@@ -65,6 +66,6 @@ public PageResponseVO getUsers(
6566
@RequestParam(name = "page", required = false, defaultValue = "0")
6667
@Min(value = 0, message = "{page}") Long page) {
6768
IPage<String> iPage = logService.getUserNamePage(page, count);
68-
return PageResponseVO.genPageResult(iPage.getTotal(), iPage.getRecords(), page, count);
69+
return ResponseUtil.generatePageResult(iPage.getTotal(), iPage.getRecords(), page, count);
6970
}
7071
}

src/main/java/io/github/talelin/merak/controller/cms/UserController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public UnifyResponseVO updatePassword(@RequestBody @Validated ChangePasswordDTO
105105
*/
106106
@GetMapping("/refresh")
107107
@RefreshRequired
108-
public Tokens refreshToken() {
108+
public Tokens getRefreshToken() {
109109
UserDO user = LocalUser.getLocalUser();
110110
return jwt.generateTokens(user.getId());
111111
}
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
package io.github.talelin.merak.extensions.file;
2+
3+
import io.github.talelin.autoconfigure.exception.*;
4+
import org.springframework.util.MultiValueMap;
5+
import org.springframework.web.multipart.MultipartFile;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.UUID;
10+
11+
/**
12+
* 文件上传类的基类
13+
* 模版模式
14+
*/
15+
public abstract class AbstractUploader implements Uploader {
16+
17+
private PreHandler preHandler;
18+
19+
public List<File> upload(MultiValueMap<String, MultipartFile> fileMap) {
20+
checkFileMap(fileMap);
21+
// 得到单个文件的大小限制
22+
// 本地存储需先初始化存储文件夹
23+
return handleMultipartFiles(fileMap);
24+
}
25+
26+
public List<File> upload(MultiValueMap<String, MultipartFile> fileMap, PreHandler preHandler) {
27+
this.preHandler = preHandler;
28+
return this.upload(fileMap);
29+
}
30+
31+
protected List<File> handleMultipartFiles(MultiValueMap<String, MultipartFile> fileMap) {
32+
long singleFileLimit = getSingleFileLimit();
33+
List<File> res = new ArrayList<>();
34+
fileMap.keySet().forEach(key -> fileMap.get(key).forEach(file -> {
35+
if (!file.isEmpty()) {
36+
handleOneFile0(res, singleFileLimit, file);
37+
}
38+
}));
39+
return res;
40+
}
41+
42+
private void handleOneFile0(List<File> res, long singleFileLimit, MultipartFile file) {
43+
byte[] bytes = getFileBytes(file);
44+
String[] include = getFileProperties().getInclude();
45+
String[] exclude = getFileProperties().getExclude();
46+
String ext = checkOneFile(include, exclude, singleFileLimit, file.getOriginalFilename(), bytes.length);
47+
String newFilename = getNewFilename(ext);
48+
String storePath = getStorePath(newFilename);
49+
// 生成文件的md5值
50+
String md5 = FileUtil.getFileMD5(bytes);
51+
File fileData = File.builder().
52+
name(newFilename).
53+
md5(md5).
54+
path(storePath).
55+
size(bytes.length).
56+
type(getFileType()).
57+
extension(ext).
58+
build();
59+
// 如果预处理器不为空,且处理结果为false,直接返回, 否则处理
60+
if (preHandler != null && !preHandler.handle(fileData))
61+
return;
62+
boolean ok = handleOneFile(bytes, newFilename);
63+
if (ok) {
64+
res.add(fileData);
65+
}
66+
}
67+
68+
private long getSingleFileLimit() {
69+
String singleLimit = getFileProperties().getSingleLimit();
70+
return FileUtil.parseSize(singleLimit);
71+
}
72+
73+
/**
74+
* 得到文件配置
75+
*
76+
* @return 文件配置
77+
*/
78+
protected abstract FileProperties getFileProperties();
79+
80+
/**
81+
* 处理一个文件
82+
*/
83+
protected abstract boolean handleOneFile(byte[] bytes, String newFilename);
84+
85+
/**
86+
* 返回文件路径
87+
*
88+
* @param newFilename 文件名
89+
* @return 文件路径
90+
*/
91+
protected abstract String getStorePath(String newFilename);
92+
93+
/**
94+
* 返回文件存储位置类型
95+
*
96+
* @return LOCAL | REMOTE
97+
*/
98+
protected abstract String getFileType();
99+
100+
/**
101+
* 获得新文件的名称
102+
*
103+
* @param ext 文件后缀
104+
* @return 新名称
105+
*/
106+
protected String getNewFilename(String ext) {
107+
String uuid = UUID.randomUUID().toString().replace("-", "");
108+
return uuid + ext;
109+
}
110+
111+
/**
112+
* 检查文件
113+
*/
114+
protected void checkFileMap(MultiValueMap<String, MultipartFile> fileMap) {
115+
if (fileMap.isEmpty()) {
116+
throw new NotFoundException("file not found", 10026);
117+
}
118+
int nums = getFileProperties().getNums();
119+
if (fileMap.size() > nums) {
120+
throw new FileTooManyException("too many files, amount of files must less than" + nums, 10180);
121+
}
122+
}
123+
124+
/**
125+
* 获得文件的字节
126+
*
127+
* @param file 文件
128+
* @return 字节
129+
*/
130+
protected byte[] getFileBytes(MultipartFile file) {
131+
byte[] bytes;
132+
try {
133+
bytes = file.getBytes();
134+
} catch (Exception e) {
135+
throw new FailedException("read file date failed", 10190);
136+
}
137+
return bytes;
138+
}
139+
140+
/**
141+
* 单个文件检查
142+
*
143+
* @param singleFileLimit 单个文件大小限制
144+
* @param originName 文件原始名称
145+
* @param length 文件大小
146+
* @return 文件的扩展名,例如: .jpg
147+
*/
148+
protected String checkOneFile(String[] include, String[] exclude, long singleFileLimit, String originName, int length) {
149+
// 写到了本地
150+
String ext = FileUtil.getFileExt(originName);
151+
// 检测扩展
152+
if (!this.checkExt(include, exclude, ext)) {
153+
throw new FileExtensionException(ext + "文件类型不支持");
154+
}
155+
// 检测单个大小
156+
if (length > singleFileLimit) {
157+
throw new FileTooLargeException(originName + "文件不能超过" + singleFileLimit);
158+
}
159+
return ext;
160+
}
161+
162+
/**
163+
* 检查文件后缀
164+
*
165+
* @param ext 后缀名
166+
* @return 是否通过
167+
*/
168+
protected boolean checkExt(String[] include, String[] exclude, String ext) {
169+
int inLen = include == null ? 0 : include.length;
170+
int exLen = exclude == null ? 0 : exclude.length;
171+
// 如果两者都有取 include,有一者则用一者
172+
if (inLen > 0 && exLen > 0) {
173+
return this.findInInclude(include, ext);
174+
} else if (inLen > 0) {
175+
// 有include,无exclude
176+
return this.findInInclude(include, ext);
177+
} else if (exLen > 0) {
178+
// 有exclude,无include
179+
return this.findInExclude(exclude, ext);
180+
} else {
181+
// 二者都没有
182+
return true;
183+
}
184+
}
185+
186+
protected boolean findInInclude(String[] include, String ext) {
187+
for (String s : include) {
188+
if (s.equals(ext)) {
189+
return true;
190+
}
191+
}
192+
return false;
193+
}
194+
195+
protected boolean findInExclude(String[] exclude, String ext) {
196+
for (String s : exclude) {
197+
if (s.equals(ext)) {
198+
return true;
199+
}
200+
}
201+
return false;
202+
}
203+
}

0 commit comments

Comments
 (0)